Initial commit

This commit is contained in:
2026-01-04 03:48:59 -05:00
commit a14368a0e8
5 changed files with 255 additions and 0 deletions

19
LICENCE Normal file
View File

@@ -0,0 +1,19 @@
(C) 2022-2024 Olive <hello@grasswren.net>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

36
README Normal file
View File

@@ -0,0 +1,36 @@
arcane - keyboard firmware
==========================
arcane is a qmk keyboard firmware configuration for ergodox ez keyboards.
arcane features a split, reactive backlighting mode and uses a querty layout
with macros, special keys, and key positions specialised for c programming
using vim.
requirements
------------
arcane requires teensy_loader_cli, avr-gcc, and qmk_firmware.
installation
------------
arcane can be downloaded, built, and flashed with the following commands:
git clone --recurse-submodules https://github.com/zsa/qmk_firmware/
pacman -S teensy_loader_cli avr-gcc qmk
# arch linux default installs it to a location different than qmk wants
ln -sf /usr/bin/teensy_loader_cli /usr/bin/teensy-loader-cli
cd qmk_firmware
cp util/udev/50-qmk.rules /etc/udev/rules.d/
# qmk activates -Werror then has code with warnings, so we need to fix it
sed -i 's/-Werror//g' builddefs/common_rules.mk
git clone https://git.arcnyxx.net/arcane
mkdir -p keyboards/ergodox_ez/shine/keymaps/
mv arcane keyboards/ergodox_ez/shine/keymaps/arcane
make ergodox_ez/shine:arcane:flash
configuration
-------------
arcane can be configured by editing the keymap.c file and (re)compiling the
source code.

13
config.h Normal file
View File

@@ -0,0 +1,13 @@
/* arcane - keyboard firmware
* Copyright (C) 2022-2024 Olive <hello@grasswren.net>
* see LICENCE file for licensing information */
/* decrease size */
#undef LOCKING_SUPPORT_ENABLE
#undef LOCKING_RESYNC_ENABLE
#define NO_ACTION_ONESHOT
#define NO_ACTION_TAPPING
#undef TAPPING_TERM /* increase buffer time after tap key */
#define TAPPING_TERM 270
#define ERGODOX_LED_30 /* force non-mirroring behaviour */

168
keymap.c Normal file
View File

@@ -0,0 +1,168 @@
/* arcane - keyboard firmware
* Copyright (C) 2022-2024 Olive <hello@grasswren.net>
* see LICENCE file for licensing information */
#include QMK_KEYBOARD_H
#include "version.h"
#define BASE(val, ind, mid) ((uint32_t)(val) * (val) * (val) / 255 / 255) * \
5 / (((ind) > (mid) ? (ind) - (mid) : (mid) - (ind)) + 5)
#define MKDANCE(num, key1, key2, key3) \
enum { DANCE ## num = num - 1 }; \
static void dance ## num ## _fin(qk_tap_dance_state_t *state, void *data); \
static void dance ## num ## _set(qk_tap_dance_state_t *state, void *data); \
\
static void \
dance ## num ## _fin(qk_tap_dance_state_t *state, void *data) \
{ \
if (state->count == 1) \
register_code16(key1); \
else if (state->count == 2) \
register_code16(key2); \
else if (state->count == 3) \
register_code16(key3); \
} \
\
static void \
dance ## num ## _set(qk_tap_dance_state_t *state, void *data) \
{ \
if (state->count == 1) \
unregister_code16(key1); \
else if (state->count == 2) \
unregister_code16(key2); \
else if (state->count == 3) \
unregister_code16(key3); \
}
MKDANCE(1, KC_F1, KC_F2, KC_F3)
MKDANCE(2, KC_F4, KC_F5, KC_F6)
MKDANCE(3, KC_F7, KC_F8, KC_F9)
MKDANCE(4, KC_F10, KC_F11, KC_F12)
qk_tap_dance_action_t tap_dance_actions[] = {
ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance1_fin, dance1_set),
ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance2_fin, dance2_set),
ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance3_fin, dance3_set),
ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance4_fin, dance4_set)
};
enum { MACRO = EZ_SAFE_RANGE, DISCO };
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_ergodox_pretty(
KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS,
KC_TRNS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
KC_GRV, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_EQL,
KC_MINS, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC,
KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
KC_LCTL, KC_LALT, DISCO, KC_CAPS, KC_LGUI,
KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_RCTL,
TD(DANCE1), TD(DANCE2), TD(DANCE3), TD(DANCE4),
KC_TRNS, KC_TRNS,
KC_SPC, KC_ESC, KC_UNDS, MACRO, KC_BSPC, KC_ENT
)
};
bool disco = false, last = false;
uint8_t lhue, lval = 0, lkeys = 0, lmid, rhue, rval = 0, rkeys = 0, rmid;
uint16_t timer;
void
keyboard_post_init_user(void)
{
rgblight_enable_noeeprom();
rgblight_sethsv_noeeprom(0, 0, 0);
}
void
led_set_user(uint8_t usb_led)
{
if (usb_led & (1 << USB_LED_CAPS_LOCK))
ergodox_right_led_3_on(), ergodox_right_led_3_set(150);
else
ergodox_right_led_3_off();
}
bool
process_record_user(uint16_t keycode, keyrecord_t *record)
{
if (!record->event.pressed)
return true;
switch (keycode) {
case KC_BSPC:
if (last)
unregister_code(KC_BSPC), register_code(KC_BSPC);
break;
case MACRO:
SEND_STRING(SS_TAP(X_MINUS) SS_LSFT(SS_TAP(X_DOT)));
break;
case DISCO:
disco = !disco, lkeys = rkeys = 0;
}
last = (keycode == MACRO);
return true;
}
void
post_process_record_user(uint16_t keycode, keyrecord_t *record)
{
if (!disco)
return;
if (!record->event.pressed) {
if (record->event.key.row < 7 && lkeys > 0)
--lkeys;
else if (record->event.key.row >= 7 && rkeys > 0)
--rkeys;
return;
}
if (record->event.key.row < 7) {
lhue = rand() % 255, lval = 255, ++lkeys, lmid = 15;
if (record->event.key.col != 5)
lmid = 28 - 2 * record->event.key.row;
for (uint8_t i = RGBLED_NUM / 2; i < RGBLED_NUM; ++i)
sethsv(lhue, 255, BASE(lval, i, lmid), &led[i]);
} else {
rhue = rand() % 255, rval = 255, ++rkeys, rmid = 14;
if (record->event.key.col != 5)
rmid = 27 - 2 * record->event.key.row;
for (uint8_t i = 0; i < RGBLED_NUM / 2; ++i)
sethsv(rhue, 255, BASE(rval, i, rmid), &led[i]);
}
rgblight_set();
}
void
matrix_init_user(void)
{
timer = timer_read();
}
void
matrix_scan_user(void)
{
if ((lval == 0 && rval == 0) || timer_elapsed(timer) < 20)
return;
timer = timer_read();
if (lkeys == 0 && lval > 0) {
lval -= 5;
for (uint8_t i = RGBLED_NUM / 2; i < RGBLED_NUM; ++i)
sethsv(lhue, 255, BASE(lval, i, lmid), &led[i]);
}
if (rkeys == 0 && rval > 0) {
rval -= 5;
for (uint8_t i = 0; i < RGBLED_NUM / 2; ++i)
sethsv(rhue, 255, BASE(rval, i, rmid), &led[i]);
}
rgblight_set();
}

19
rules.mk Normal file
View File

@@ -0,0 +1,19 @@
# arcane - keyboard firmware
# Copyright (C) 2022-2024 Olive <hello@grasswren.net>
# see LICENCE file for licensing information
# decrease size
LTO_ENABLE = yes
AVR_USE_MINIMAL_PRINTF = yes
CONSOLE_ENABLE = no
COMMAND_ENABLE = no
MOUSEKEY_ENABLE = no
EXTRAKEY_ENABLE = no
SPACE_CADET_ENABLE = no
GRAVE_ESC_ENABLE = no
MAGIC_ENABLE = no
TAP_DANCE_ENABLE = yes
RGBLIGHT_ENABLE = yes