remove userspace declarations

This commit is contained in:
Vineet K 2023-10-15 19:46:33 -04:00
parent 392a85e1f6
commit 7ed78a843d
1028 changed files with 0 additions and 89006 deletions

View File

@ -353,21 +353,6 @@ $(INTERMEDIATE_OUTPUT)/src/info_deps.d:
.INTERMEDIATE : generated-files
# Userspace setup and definitions
ifeq ("$(USER_NAME)","")
USER_NAME := $(KEYMAP)
endif
USER_PATH := users/$(USER_NAME)
# Pull in user level rules.mk
-include $(USER_PATH)/rules.mk
ifneq ("$(wildcard $(USER_PATH)/config.h)","")
CONFIG_H += $(USER_PATH)/config.h
endif
ifneq ("$(wildcard $(USER_PATH)/post_config.h)","")
POST_CONFIG_H += $(USER_PATH)/post_config.h
endif
# Disable features that a keyboard doesn't support
-include $(BUILDDEFS_PATH)/disable_features.mk
@ -419,7 +404,6 @@ SRC += \
# Search Path
VPATH += $(KEYMAP_PATH)
VPATH += $(USER_PATH)
VPATH += $(KEYBOARD_PATHS)
VPATH += $(COMMON_VPATH)
VPATH += $(INTERMEDIATE_OUTPUT)/src

View File

@ -1,144 +0,0 @@
/*
Copyright (c) 2020 Fred Silberberg
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.
*/
#include "333fred.h"
#include "quantum.h"
#include "action.h"
typedef enum {
SINGLE_TAP, SINGLE_HOLD, DOUBLE
} tap_dance_state_enum;
static tap_dance_state_enum tap_dance_state;
static bool tap_dance_active = false;
void tap_dance_sym_vim_finished(tap_dance_state_t *state, void *user_data) {
// Determine the current state
if (state->count == 1) {
if (state->interrupted || state->pressed == 0) tap_dance_state = SINGLE_TAP;
else tap_dance_state = SINGLE_HOLD;
} else {
// Handle any number of other taps as a VIM movement hold
tap_dance_state = DOUBLE;
}
switch (tap_dance_state) {
case SINGLE_TAP:
if (tap_dance_active) {
reset_oneshot_layer();
tap_dance_active = false;
} else {
set_oneshot_layer(SYMB, ONESHOT_START);
tap_dance_active = true;
}
break;
case SINGLE_HOLD:
layer_on(SYMB);
break;
case DOUBLE:
layer_on(VIM);
break;
}
}
void tap_dance_sym_vim_reset(tap_dance_state_t *state, void *user_data) {
switch(tap_dance_state) {
case SINGLE_TAP:
clear_oneshot_layer_state(ONESHOT_PRESSED);
break;
case SINGLE_HOLD:
layer_off(SYMB);
break;
case DOUBLE:
layer_off(VIM);
break;
}
}
void tap_dance_copy_paste_finished(tap_dance_state_t *state, void *user_data) {
bool is_paste = state->count == 2;
// If either the one-shot shift is set, or if shift is being held, count as shift being held.
// We'll clear the one-shot shift if it was held
uint8_t one_shot_mods = get_oneshot_mods();
bool is_shift = false;
if (get_mods() & MOD_MASK_SHIFT) {
is_shift = true;
} else if (one_shot_mods & MOD_MASK_SHIFT) {
set_oneshot_mods(one_shot_mods & ~MOD_MASK_SHIFT);
is_shift = true;
}
if (is_paste) {
if (is_shift) {
SEND_STRING(SS_LSFT(SS_TAP(X_INSERT)));
} else {
SEND_STRING(SS_LCTL("v"));
}
} else {
if (is_shift) {
SEND_STRING(SS_LCTL(SS_TAP(X_INSERT)));
} else {
SEND_STRING(SS_LCTL("c"));
}
}
}
tap_dance_action_t tap_dance_actions[] = {
[TD_SYM_VIM] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_sym_vim_finished, tap_dance_sym_vim_reset),
[TD_COPY_PASTE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_copy_paste_finished, NULL)
};
void tap_dance_process_keycode(uint16_t keycode) {
if (tap_dance_state == SINGLE_TAP && keycode != TD(TD_SYM_VIM)) {
tap_dance_active = false;
}
}
__attribute__ ((weak))
void layer_state_set_rgb(layer_state_t state) {}
layer_state_t layer_state_set_user(layer_state_t state) {
layer_state_set_rgb(state);
return state;
}
bool try_handle_macro(uint16_t keycode, keyrecord_t *record) {
switch (keycode)
{
case DLEFT:
if (record->event.pressed)
SEND_STRING(SS_LGUI(SS_LALT(SS_TAP(X_LEFT))));
return true;
case DRIGHT:
if (record->event.pressed)
SEND_STRING(SS_LGUI(SS_LALT(SS_TAP(X_RIGHT))));
return true;
case PSCREEN_APP:
if (record->event.pressed)
SEND_STRING(SS_LALT(SS_TAP(X_PRINT_SCREEN)));
return true;
default:
return false;
}
}

View File

@ -1,51 +0,0 @@
/*
Copyright (c) 2020 Fred Silberberg
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.
*/
#pragma once
#include "quantum.h"
#include "layout_macros.h"
#define BASE 0
#define CODEFLOW 1
#define SYMB 2
#define MDIA 3 // media keys
#define VIM 4
#define GAME 5
#define GAME_ARROW 6
// Tap dance config shared between my keyboards
enum tap_dance_declarations {
TD_SYM_VIM = 0,
TD_COPY_PASTE,
};
enum custom_keys {
DLEFT = SAFE_RANGE,
DRIGHT,
PSCREEN_APP
};
void tap_dance_sym_vim_finished(tap_dance_state_t*, void*);
void tap_dance_sym_vim_reset(tap_dance_state_t*, void*);
void tap_dance_process_keycode(uint16_t);
bool try_handle_macro(uint16_t keycode, keyrecord_t *record);

View File

@ -1,27 +0,0 @@
/*
Copyright (c) 2020 Fred Silberberg
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.
*/
#pragma once
#define PERMISSIVE_HOLD
#define NO_ACTION_MACRO
#undef ONESHOT_TAP_TOGGLE

View File

@ -1,66 +0,0 @@
/*
Copyright (c) 2020 Fred Silberberg
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.
*/
#pragma once
#define SIX_TRNS _______, _______, _______, _______, _______, _______
#define FOUR_TRNS _______, _______, _______, _______
// Row 5: 6 keys
#define ROW5_LEFT_BASE KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5
#define ROW5_RGHT_BASE KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS
#define ROW5_LEFT_SYMB _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5
#define ROW5_RGHT_SYMB KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11
#define ROW5_LEFT_VIM SIX_TRNS
#define ROW5_RGHT_VIM SIX_TRNS
// Row 4: 6 keys
#define ROW4_LEFT_BASE KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T
#define ROW4_RGHT_BASE KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS
#define ROW4_LEFT_SYMB _______, KC_EXLM, KC_AT, KC_LPRN, KC_RPRN, KC_PIPE
#define ROW4_RGHT_SYMB KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12
#define ROW4_LEFT_VIM SIX_TRNS
#define ROW4_RGHT_VIM SIX_TRNS
// Row 3: 6 keys
#define ROW3_LEFT_BASE CTL_T(KC_ESC), KC_A, KC_S, KC_D, KC_F, KC_G
#define ROW3_RGHT_BASE KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT
#define ROW3_LEFT_SYMB _______, KC_HASH, KC_DLR, KC_LCBR, KC_RCBR, KC_GRV
#define ROW3_RGHT_SYMB KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, _______
#define ROW3_LEFT_VIM _______, DLEFT, DRIGHT, KC_LCTL, KC_LGUI, _______
#define ROW3_RGHT_VIM KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______
// Row 2: 6 keys
#define ROW2_LEFT_BASE OSM(MOD_LSFT), CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B
#define ROW2_RGHT_BASE KC_N, KC_M, KC_COMM, KC_DOT, CTL_T(KC_SLSH), OSM(MOD_RSFT)
#define ROW2_LEFT_SYMB _______, KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_TILD
#define ROW2_RGHT_SYMB KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, _______
#define ROW2_LEFT_VIM _______, _______, KC_TAB, _______, _______, _______
#define ROW2_RGHT_VIM SIX_TRNS
// Row 1: 4 keys
#define ROW1_LEFT_BASE OSM(MOD_LCTL), KC_F4, KC_F5, KC_LALT
#define ROW1_RGHT_BASE KC_DOWN, KC_EQL, KC_RIGHT, KC_RGUI
#define ROW1_LEFT_SYMB _______, _______, _______, _______
#define ROW1_RGHT_SYMB KC_0, KC_DOT, KC_EQL, _______
#define ROW1_LEFT_VIM FOUR_TRNS
#define ROW1_RGHT_VIM FOUR_TRNS

View File

@ -1,50 +0,0 @@
/*
Copyright (c) 2020 Fred Silberberg
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.
*/
#include "quantum.h"
#include "333fred.h"
void layer_state_set_rgb(layer_state_t state) {
switch (get_highest_layer(state)) {
case BASE:
// purple
rgblight_sethsv_noeeprom(210, 255, 20);
break;
case SYMB:
// blue
rgblight_sethsv_noeeprom(191, 255, 20);
break;
case VIM:
// green
rgblight_sethsv_noeeprom(85, 255, 20);
break;
case GAME:
// red
rgblight_sethsv_noeeprom(0, 255, 20);
break;
}
}
void keyboard_post_init_user(void) {
rgblight_enable_noeeprom();
layer_state_set_rgb(1); // Set layer 0 (bit 1) on
}

View File

@ -1,10 +0,0 @@
SRC += 333fred.c
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
SRC += rgb.c
endif
TAP_DANCE_ENABLE=yes
NKRO_ENABLE = yes
PERMISSIVE_HOLD = yes
LTO_ENABLE = yes

View File

@ -1,5 +0,0 @@
#include "_example.h"
void my_custom_function(void) {
}

View File

@ -1,8 +0,0 @@
#ifndef USERSPACE
#define USERSPACE
#include "quantum.h"
void my_custom_function(void);
#endif

View File

@ -1,14 +0,0 @@
Copyright <year> <name> <email> @<github_username>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -1 +0,0 @@
SRC += _example.c

View File

@ -1,176 +0,0 @@
/* Copyright 2021 Alan Pocklington
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ajp10304.h"
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
set_single_persistent_default_layer(_QWERTY);
}
return false;
case COLEMAK:
if (record->event.pressed) {
set_single_persistent_default_layer(_COLEMAK);
}
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
case MLWR:
if (record->event.pressed) {
layer_on(_LOWER);
layer_on(_MLWR);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
layer_off(_MLWR);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
case MRSE:
if (record->event.pressed) {
layer_on(_RAISE);
layer_on(_MRSE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
layer_off(_MRSE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
case MFNC:
if (record->event.pressed) {
layer_on(_FUNC);
layer_on(_MFNC);
} else {
layer_off(_FUNC);
layer_off(_MFNC);
}
return false;
case MFNC2:
if (record->event.pressed) {
layer_on(_FUNC2);
layer_on(_MFNC2);
} else {
layer_off(_FUNC2);
layer_off(_MFNC2);
}
return false;
case M_CUSTOM:
if (record->event.pressed) {
SEND_STRING("Custom text here");
}
break;
case M_WORD_SEL:
if (record->event.pressed) {
register_mods(MOD_LCTL);
tap_code(KC_RGHT);
tap_code16(S(KC_LEFT));
unregister_mods(MOD_LCTL);
}
break;
case M_WORD_SEL_MAC:
if (record->event.pressed) {
register_mods(MOD_LALT);
tap_code(KC_RGHT);
tap_code16(S(KC_LEFT));
unregister_mods(MOD_LALT);
}
break;
case M_LINE_SEL:
if (record->event.pressed) {
tap_code(KC_HOME);
tap_code16(S(KC_END));
}
break;
case M_LINE_SEL_MAC:
if (record->event.pressed) {
tap_code16(C(KC_A));
tap_code16(C(S(KC_E)));
}
break;
case M_LINE_DEL:
if (record->event.pressed) {
tap_code(KC_HOME);
tap_code16(S(KC_END));
tap_code(KC_BSPC);
}
break;
case M_LINE_DEL_MAC:
if (record->event.pressed) {
tap_code16(C(KC_A));
tap_code16(C(S(KC_E)));
tap_code(KC_BSPC);
}
break;
case M_DUP:
if (record->event.pressed) {
tap_code16(C(KC_C));
tap_code(KC_RGHT);
tap_code16(C(KC_V));
}
break;
case M_DUP_MAC:
if (record->event.pressed) {
tap_code16(G(KC_C));
tap_code(KC_RGHT);
tap_code16(G(KC_V));
}
break;
case M_JOIN:
if (record->event.pressed) {
tap_code(KC_END);
tap_code(KC_DEL);
}
break;
case M_JOIN_MAC:
if (record->event.pressed) {
tap_code16(C(KC_E));
tap_code(KC_DEL);
}
break;
case M_MODE:
if (record->event.pressed) {
send_string("PC ");
send_string(get_highest_layer(default_layer_state) == _COLEMAK ? "COLEMAK" : "QWERTY");
}
break;
case M_MODE_MAC:
if (record->event.pressed) {
send_string("OSX ");
send_string(get_highest_layer(default_layer_state) == _COLEMAK ? "COLEMAK" : "QWERTY");
}
break;
}
return true;
}

View File

@ -1,63 +0,0 @@
/* Copyright 2021 Alan Pocklington
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
enum ajp10304_layers {
_QWERTY,
_COLEMAK,
_MAC,
_LOWER,
_MLWR,
_RAISE,
_MRSE,
_FUNC,
_MFNC,
_FUNC2,
_MFNC2,
_ADJUST,
_MOUSE,
_NUMPAD
};
enum ajp10304_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
MAC,
FUNC,
MFNC,
FUNC2,
MFNC2,
LOWER,
MLWR,
RAISE,
MRSE,
MOUSE,
NUMPAD,
M_CUSTOM,
M_WORD_SEL,
M_WORD_SEL_MAC,
M_LINE_SEL,
M_LINE_SEL_MAC,
M_LINE_DEL,
M_LINE_DEL_MAC,
M_DUP,
M_DUP_MAC,
M_JOIN,
M_JOIN_MAC,
M_MODE,
M_MODE_MAC
};

View File

@ -1,141 +0,0 @@
Copyright 2021 Alan Pocklington <ajp10304@gmail.com> @ajp10304
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
# AJP10304 Custom 40% Layout
# For the Planck, Shark, Quark, JJ40 and Atreus50
**Note:** In the tables below where there are two characters on a key,
the second is the output when shift is applied.
**Note:** The below tables assume a UK layout.
#### Flashing
Refer to the README.md of the keyboard you want to flash.
##### Main Qwerty Layer
* Tab: when held, operates as shift.
* Enter: when held, operates as shift.
* MENU: perform right-click
| | | | | | | | | | | | |
| ---- |:----:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| ----:|
| Esc | Q | W | E | R | T | Y | U | I | O | P | Bksp |
| Tab | A | S | D | F | G | H | J | K | L | ;: | Enter|
| Shft | Z | X | C | V | B | N | M | ,< | .> | /? | Shft |
| Fn | Ctrl | Alt | GUI |Lower | Bksp |Space |Raise | Shift| MENU | Ctrl | Fn2 |
##### Main Colemak-DHm Layer
| | | | | | | | | | | | |
| ---- |:----:| :---:|:---:|:-----:|:----:|:-----:|:-----:|:-----:|:----:|:----:| ----:|
| Esc | Q | W | F | P | B | J | L | U | Y | ;: | Bksp |
| Tab | A | R | S | T | G | M | N | E | I | O | Enter|
| Shft | Z | X | C | D | V | K | H | ,< | .> | /? | Shft |
| Fn | Ctrl | Alt | GUI | Lower | Bksp | Space | Raise | Shift | MENU | Ctrl | Fn2 |
##### Function Layer
Activated when `fn` held in the above `qwerty` layer.
| | | | | | | | | | | | |
| :---: |:----:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:|
| F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
| 1! | 2" | 3£ | 4$ | 5% | 6^ | 7& | 8* | 9( | 0) | ~ |INSERT|
| Shift | \| | `¬ | #~ | * | -_ | =+ | \| | [{ | ]} | '@ |Shift |
| Fn | Ctrl | Alt | GUI |Lower | Bksp |Space |Mouse | MENU | Alt | Ctrl | Fn2 |
##### Lower Layer
Activated when `Lower` is held in the above `qwerty` layer.
* Numbers are along the top row, their shifted counterparts are on row 2.
* WrdBks: `backspace` with `ctrl` applied. I.e. delete a word.
* WrdDel: `delete` with `ctrl` applied. I.e. forward delete a word.
| | | | | | | | | | | | |
| :---: |:----:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:|
| 1! | 2" | 3£ | 4$ | 5% | 6^ | 7& | 8* | 9( | 0) | DEL | Bksp |
| ! | " | £ | $ | % | ^ | & | * | ( | ) |WrdDel|WrdBks|
| Shift | \| | `¬ | #~ | '@ | -_ | =+ | #~ | [{ | ]} | '@ |Shift |
| | | | |Lower | Del |Space | | Next | Vol- | Vol+ | Play |
##### Raise Layer
Activated when `Raise` is held in the above `qwerty` layer.
* Preferred layer for typing brackets.
* Allows for cursor navigation to be used solely with the right hand.
* WRDSEL: Select the word where the cursor is.
* |< and >|: Apply `ctrl` to `left` and `right` respectively for word jumping.
| | | | | | | | | | | | |
| :---: |:----:| :---:| :---:| :---:| :---:| :---: | :---:| :---:| :---:| :---: | :---:|
| ` | |WRDSEL| [ | ] | | | PGUP | HOME |PGDOWN| |PRNTSC|
| ` | | | ( | ) | | | HOME | UP | END | |ZOOM +|
| | | | { | } | |&#124;<| LEFT | DOWN |RIGHT |>&#124;|ZOOM -|
| Mouse | | | | | Alt | Enter |Raise | | | | |
##### Lower + Raise
Activated when `Lower` and `Raise` are held together in the above `qwerty` layer.
* Audio controls in the same position as cursor keys from the `Raise` layer.
* ????: Runs a macro for outputting a text string. Do not use this store passwords.
* Reset: Enter bootloader for flashing firmware to the keyboard.
* CAPS: Toggle caps lock.
* Macro functions: Allows recording of macros. To start recording the macro, press either REC1 or REC2.
To finish the recording, press STOP. To replay the macro, press either PLAY1 or PLAY2.
* MAC: Toggle MAC OS extensions to layers. This allows MLWR to be enabled with LOWER,
MRSE with RAISE, MFNC with FUNC and MFNC2 with FUNC2 respectively.
| | | | | | | | | | | | |
| :---: |:----:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:|:-------:|
| ???? | Reset|Qwerty| | | REC1 | REC2 | | | | | Del |
| CAPS | | | | | PLAY1|PLAY2 | Mute | Vol+ | Play | | Qwerty |
| MAC | | | | | STOP1|STOP2 | Prev | Vol- | Next | | Colemak |
| | | | | | | | | DYN | | | |
##### Function 2 Layer
Activated when `fn` held in the above `qwerty` layer.
* WRDSEL: Select the word where the cursor is.
* LNDEL: Delete the line where the cursor is.
* LNSEL: Select the line where the cursor is.
* DUP: Duplicate the selected text.
* LNJOIN: Join the line where the cursor is with the following line.
* MODE: Print either `PC` or `OSX` depending on what layer mode is active.
| | | | | | | | | | | | |
| :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:|
| | |WRDSEL| | | | LNDEL| | | | | |
| | | LNSEL| DUP | | | | |LNJOIN| | | |
| | UNDO | CUT | COPY | PASTE| | | | | | | MODE |
| | | | | | | | | | | | |
##### Mouse Layer
Activated when `fn` and `raise` held together.
| | | | | | | | | | | | |
| :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:|
| ESC | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | |
| ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | |
| ACC0 | ACC1 | ACC2 | | | | | LEFT | DOWN | RIGHT| | |
| | | | | | | | | | | | |
##### Number Pad Layout
Activated when holding `Esc` key.
| | | | | | | | | | | | |
| :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:|
| | | | | | |NMLOCK| 7 | 8 | 9 | / | |
| | | | | | | | 4 | 5 | 6 | * | |
| | | | | | | | 1 | 2 | 3 | + | |
| | | | | | | | 0 | . | , | - | |

View File

@ -1 +0,0 @@
SRC += ajp10304.c

View File

@ -1,91 +0,0 @@
#include "alfrdmalr.h"
#include "muse.h"
bool muse_mode = false;
uint8_t last_muse_note = 0;
uint16_t muse_counter = 0;
uint8_t muse_offset = 70;
uint16_t muse_tempo = 50;
void leader_end_user(void) {
// reset keyboard to bootloader
if (leader_sequence_five_keys(KC_R, KC_E, KC_S, KC_E, KC_T)) {
reset_keyboard();
}
}
void matrix_scan_user(void) {
#ifdef AUDIO_ENABLE
if (muse_mode) {
if (muse_counter == 0) {
uint8_t muse_note = muse_offset + SCALE[muse_clock_pulse()];
if (muse_note != last_muse_note) {
stop_note(compute_freq_for_midi_note(last_muse_note));
play_note(compute_freq_for_midi_note(muse_note), 0xF);
last_muse_note = muse_note;
}
}
muse_counter = (muse_counter + 1) % muse_tempo;
} else {
if (muse_counter) {
stop_all_notes();
muse_counter = 0;
}
}
#endif
}
bool syml_pressed = false;
bool symr_pressed = false;
bool settings_active = false;
bool symbols_active = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch(keycode) {
case SYML:
if (record->event.pressed) {
syml_pressed = true;
} else {
syml_pressed = false;
}
break;
case SYMR:
if (record->event.pressed) {
symr_pressed = true;
} else {
symr_pressed = false;
}
break;
}
// trilayer-esque behavior. If both SYMBOL layer keys are held, then the
// settings layer is open. If only one is held, SYMBOL is active.
if (syml_pressed && symr_pressed) {
layer_on(_SETTINGS);
settings_active = true;
} else if (syml_pressed || symr_pressed) {
if (settings_active) {
layer_off(_SETTINGS);
settings_active = false;
}
layer_on(_SYMBOL);
symbols_active = true;
} else {
if (symbols_active) {
layer_off(_SYMBOL);
symbols_active = false;
}
}
return true;
}
// allow access to the settings layer to turn music mode back off
bool music_mask_user(uint16_t keycode) {
switch (keycode) {
case SYML:
case SYMR:
return false;
default:
return true;
}
}

View File

@ -1,286 +0,0 @@
/*
Copyright 2020 Alfred Maler @alfrdmalr
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu/org/licenses/>.
*/
#pragma once
#include QMK_KEYBOARD_H
enum shared_layers {
_QWERTY,
_SYMBOL,
_NAVIGATION,
_NUMPAD,
_SETTINGS
};
// KEYCODES ============================================================================
// the SYML and SYMR keycodes are just used to activate the symbols layer.
// they're distinct so that I can hit both of them to activate a trilayer
enum alfrdmalr_keycodes {
SYML = SAFE_RANGE,
SYMR
};
#define NUMSPACE LT(_NUMPAD, KC_SPC)
#define NAVLAYER MO(_NAVIGATION)
#define SYMLAYER MO(_SYMBOL)
#define SETLAYER MO(_SETTINGS)
#define CTRLSHFT C(KC_LSFT)
#define WINUNDO C(KC_Z)
#define WINCOPY C(KC_C)
#define WINCUT C(KC_X)
#define WINPASTE C(KC_V)
// convenience keycodes/aliases for base modifiers
// bottom row
#define K41 CTRLSHFT
#define K42 KC_LGUI
#define K43 KC_LALT
// #define K44 SYMLAYER
#define K44 SYML
#define K45 NUMSPACE
#define K46 NUMSPACE
// #define K47 SYMLAYER
#define K47 SYMR
#define K48 KC_RALT
#define K49 SETLAYER
#define K4A MU_TOGG
// leftmost column
#define K00 KC_ESC
#define K10 KC_TAB
#define K20 NAVLAYER
#define K30 KC_LSFT
#define K40 KC_LCTL
// rightmost column
#define K0B KC_BSPC
#define K1B KC_BSPC
#define K1B_ALT KC_DEL // for 5x12 boards, keep backspace as the top-left key and add delete key
#define K2B KC_QUOT
#define K3B KC_RSFT
#define K4B QK_LEAD
// LAYOUT WRAPPERS =====================================================================
#if (!defined(LAYOUT) && defined(KEYMAP))
# define LAYOUT KEYMAP
#endif
#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__)
#define LAYOUT_ortho_4x12_wrapper(...) LAYOUT_ortho_4x12(__VA_ARGS__)
#define LAYOUT_ortho_5x12_wrapper(...) LAYOUT_ortho_5x12(__VA_ARGS__)
// KEYCODE GROUPS ======================================================================
// MISC
#define ______TRANS______ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
#define ____NUMROW_L0____ KC_1, KC_2, KC_3, KC_4, KC_5
#define ____NUMROW_R0____ KC_6, KC_7, KC_8, KC_9, KC_0
#define _____BASE_L4_____ K41, K42, K43, K44, K45
#define _____BASE_R4_____ K46, K47, K48, K49, K4A
/* QWERTY ==============================================================================
* ,-----------------------------------------------------------------------------------.
* | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | BKSP |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TAB | Q | W | E | R | T | Y | U | I | O | P | BKSP |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | NAV | A | S | D | F | G | H | J | K | L | ; | " |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | SHFT | Z | X | C | V | B | N | M | , | . | / | SHFT |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | CTRL | C/S | LGUI | LALT | SYMB | NUM/SPACE | SYMB | RALT | SETT | MUTG | LEAD |
* `-----------------------------------------------------------------------------------'
*/
// LEFT
// - CORE
#define ____QWERTY_L1____ KC_Q, KC_W, KC_E, KC_R, KC_T
#define ____QWERTY_L2____ KC_A, KC_S, KC_D, KC_F, KC_G
#define ____QWERTY_L3____ KC_Z, KC_X, KC_C, KC_V, KC_B
// RIGHT
// - CORE
#define ____QWERTY_R1____ KC_Y, KC_U, KC_I, KC_O, KC_P
#define ____QWERTY_R2____ KC_H, KC_J, KC_K, KC_L, KC_SCLN
#define ____QWERTY_R3____ KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH
/* NUMPAD ==============================================================================
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | F9 | F10 | F11 | F12 | | NLCK | 7 | 8 | 9 | - | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ESC | F5 | F6 | F7 | F8 | SPC | SPC | 4 | 5 | 6 | + | ENTR |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | F1 | F2 | F3 | F4 | ALT | | 1 | 2 | 3 | / | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | TRNS | TRNS | TRNS | TRNS | TRNS | 0 | , | . | * | TRNS |
* `-----------------------------------------------------------------------------------'
*/
// LEFT
// - CORE
#define ____NUMPAD_L1____ KC_F9, KC_F10, KC_F11, KC_F12, KC_NO
#define ____NUMPAD_L2____ KC_F5, KC_F6, KC_F7, KC_F8, KC_SPC
#define ____NUMPAD_L3____ KC_F1, KC_F2, KC_F3, KC_F4, KC_LALT
// - MODS
#define ____NUMPAD_L4____ ______TRANS______
#define K00_NUM KC_TRNS
#define K10_NUM KC_TRNS
#define K20_NUM KC_TRNS
#define K30_NUM KC_TRNS
#define K40_NUM KC_TRNS
// RIGHT
// - CORE
#define ____NUMPAD_R1____ KC_NUM, KC_7, KC_8, KC_9, KC_MINS
#define ____NUMPAD_R2____ KC_SPC, KC_4, KC_5, KC_6, KC_PLUS
#define ____NUMPAD_R3____ KC_NO, KC_1, KC_2, KC_3, KC_SLSH
// - MODS
#define ____NUMPAD_R4____ KC_TRNS, KC_0, KC_COMM, KC_DOT, KC_ASTR
#define K0B_NUM KC_TRNS
#define K1B_NUM KC_TRNS
#define K2B_NUM KC_ENT
#define K3B_NUM KC_TRNS
#define K4B_NUM KC_TRNS
/* SYMBOL ==============================================================================
* ,-----------------------------------------------------------------------------------.
* | TRNS | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | ! | # | { | } | | | ^ | $ | & | | | DEL |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | < | > | ( | ) | | | - | + | = | \ | ` |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | ~ | @ | [ | ] | | | _ | * | % | / | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | TRNS | TRNS | TRNS | TRNS | TRNS | TRNS | TRNS | TRNS | TRNS | TRNS |
* `-----------------------------------------------------------------------------------'
*/
// LEFT
// - CORE
#define ____SYMBOL_L1____ KC_EXCLAIM, KC_HASH, KC_LCBR, KC_RCBR, KC_NO
#define ____SYMBOL_L2____ KC_LABK, KC_RABK, KC_LPRN, KC_RPRN, KC_NO
#define ____SYMBOL_L3____ KC_TILD, KC_AT, KC_LBRC, KC_RBRC, KC_NO
// - MODS
#define ____SYMBOL_L4____ ______TRANS______
#define K00_SYM KC_TRNS
#define K10_SYM KC_TRNS
#define K20_SYM KC_TRNS
#define K30_SYM KC_TRNS
#define K40_SYM KC_TRNS
// RIGHT
// - CORE
#define ____SYMBOL_R1____ KC_NO, KC_CIRC, KC_DOLLAR, KC_AMPR, KC_PIPE
#define ____SYMBOL_R2____ KC_NO, KC_MINS, KC_PLUS, KC_EQL, KC_BSLS
#define ____SYMBOL_R3____ KC_NO, KC_UNDS, KC_ASTR, KC_PERC, KC_SLSH
// - MODS
#define ____SYMBOL_R4____ ______TRANS______
#define K0B_SYM KC_TRNS
#define K1B_SYM KC_DEL
#define K2B_SYM KC_GRV
#define K3B_SYM KC_TRNS
#define K4B_SYM KC_TRNS
/* NAVIGATION ==========================================================================
* ,-----------------------------------------------------------------------------------.
* | TRNS | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | | | SPC | F5 | | INS | HOME | END | TAB | DEL | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | SHFT | CTRl | ALT | GUI | | LEFT | DOWN | UP | RGHT | | ENTR |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | UNDO | CUT | COPY | PSTE | | | PGDO | PGUP | CAPS | | TRNS |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | TRNS | TRNS | TRNS | TRNS | TRNS | ESC | TRNS | TRNS | TRNS | TRNS | TRNS |
* `-----------------------------------------------------------------------------------'
*/
// LEFT
// - CORE
#define __NAVIGATION_L1__ KC_NO, KC_NO, KC_SPC, KC_F5, KC_NO
#define __NAVIGATION_L2__ KC_LSFT, KC_LCTL, KC_LALT, KC_LGUI, KC_NO
#define __NAVIGATION_L3__ WINUNDO, WINCUT, WINCOPY, WINPASTE, KC_NO
// - MODS
#define __NAVIGATION_L4__ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_ESC
#define K00_NAV KC_TRNS
#define K10_NAV KC_TRNS
#define K20_NAV KC_TRNS
#define K30_NAV KC_TRNS
#define K40_NAV KC_TRNS
// RIGHT
// - CORE
#define __NAVIGATION_R1__ KC_INS, KC_HOME, KC_END, KC_TAB, KC_DEL
#define __NAVIGATION_R2__ KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, KC_NO
#define __NAVIGATION_R3__ KC_NO, KC_PGDN, KC_PGUP, KC_CAPS, KC_NO
// - MODS
#define __NAVIGATION_R4__ KC_ESC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
#define K0B_NAV KC_TRNS
#define K1B_NAV KC_TRNS
#define K2B_NAV KC_ENT
#define K3B_NAV KC_TRNS
#define K4B_NAV KC_TRNS
/* SETTINGS ============================================================================
* ,-----------------------------------------------------------------------------------.
* | | | | | | | | | | BRID | BRIU | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | MPRV | MPLY | MUTE | MNXT | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | ASTG | MUTO | AUOF | AUON | | | | VOLD | VOLU | | | ASTG |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | TRNS | | TRNS | | | | |
* `-----------------------------------------------------------------------------------'
*/
// LEFT
// - CORE
#define ___SETTINGS_L1___ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
#define ___SETTINGS_L2___ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
#define ___SETTINGS_L3___ MU_TOGG, AU_OFF, AU_ON, KC_NO, KC_NO
// - MODS
#define ___SETTINGS_L4___ KC_NO, KC_NO, KC_NO, KC_TRNS, KC_NO
#define K00_SET KC_NO
#define K10_SET KC_NO
#define K20_SET KC_NO
#define K30_SET AS_TOGG
#define K40_SET KC_NO
// RIGHT
// - CORE
#define ___SETTINGS_R1___ KC_NO, KC_NO, KC_NO, KC_BRID, KC_BRIU
#define ___SETTINGS_R2___ KC_MPRV, KC_MPLY, KC_MUTE, KC_MNXT, KC_NO
#define ___SETTINGS_R3___ KC_NO, KC_VOLD, KC_VOLU, KC_NO, KC_NO
// - MODS
#define ___SETTINGS_R4___ KC_NO, KC_TRNS, KC_NO, KC_NO, KC_NO
#define K0B_SET KC_NO
#define K1B_SET KC_NO
#define K2B_SET KC_NO
#define K3B_SET AS_TOGG
#define K4B_SET KC_NO

View File

@ -1,7 +0,0 @@
#pragma once
#define MUSIC_MASK (keycode != KC_NO)
#define MIDI_BASIC
#define LEADER_TIMEOUT 400
#define LEADER_PER_KEY_TIMING

View File

@ -1,46 +0,0 @@
# alfrdmalr's userspace
## Overview
The alphanumeric characters and symbols are spread between three main 'typing' layers: REGULAR, NUMPAD, and SYMBOL.
A fourth layer, NAVIGATION, contains useful modifiers, shortcuts, and navigation functions like the arrow keys and page up/down. This layer also provides access to the `ENTER` and `ESC` keys.
Finally, a SETTINGS layer can be used to adjust certain keyboard-related options.
A visual representation of each layer can be found in [alfrdmalr.h](./alfrdmalr.h)
### Layers
#### REGULAR
Right now this is just a QWERTY layer, but other layouts (DVORAK, COLEMAK, etc.) could easily be added. The REGULAR layer uses the default modifiers.
The default modifiers are defined in the style `K00`, where the first digit is the row index and the second digit is the column index. These indices are based on the Preonic's 5x12 grid, and are **not** adjusted for a board of different size; for instance, the upper-leftmost key in the preonic layout is `K00`, whereas the upper-leftmost key on a Planck would be `K10`.
This convention is designed to work nicely with layout wrappers.
#### NUMPAD
The NUMPAD layer puts a numpad under the right hand, surrounding the home row position. Several basic arithmetic operators are also provided, as well as comma/decimal symbols, to emulate a traditional numpad. The numlock/capslock keys are accessible from this layer as well, though it should be noted that the actual keycodes being sent by the numpad are NOT the numpad versions of the numbers - this is to prevent the normal numlock behavior from blocking numbers from being sent.
This layer also holds the first twelve function keys.
#### SYMBOL
This layer holds all the symbols that are not accessible from the REGULAR layer. There is some redundancy (for instance, `/` exists in both the REGULAR and SYMBOL layer; its position, however, remains consistent) but with the exception of single and double quotes, all symbols are available from this layer.
#### NAVIGATION
Over time, this layer has become a general utility layer, though its primary function of is still to provide arrow keys under hjkl. The surrounding keys contain similar functionality - for instance, the keys directly below `DOWN` and `UP` are `PAGEDOWN` and `PAGEUP`, respectively. `HOME` and `END` are inverted from this convention, simply because I kept hitting the wrong key when trying to jump to the beginning/end of lines when editing text.
To the immediate right of the NAVIGATION layer key are the following modifiers: `SHIFT`, `CONTROL`, `ALT`, `GUI`. All modifiers are the "left" variants. The idea is to use the left hand to hold different modifiers as necessary while using the right hand to navigate and format.
`ESCAPE` is located on the spacebar from this layer, and `DELETE` is placed next to `BACKSPACE`, for convenience when formatting text. There are also four Windows shortcuts for undo, cut, copy, and paste, located in the same position as the relevant keys on the base layer (undo, for example, is in the same place as the `Z` key). Again, this is for convenience when formatting text.
#### SETTINGS
The SETTINGS layer can be accessed by pressing both SYMBOL layer keys at once. This is functionally the same as a trilayer, though because both keys are activating the same layer it doesn't actually use the trilayer feature.
This layer contains things like feature toggles, media controls, and other infrequently-used options.
### Leader Key Sequences
A complete list of leader sequences can be found below. The LEAD key that begins each sequence has been omitted.
| Sequence | Function |
| :------: | -------------------------------- |
| R-E-S-E-T | Reset the keyboard into DFU mode |

View File

@ -1,8 +0,0 @@
SRC += alfrdmalr.c
ifdef AUDIO_ENABLE
SRC += muse.c
endif
AUTO_SHIFT_ENABLE = yes
LEADER_ENABLE = yes

View File

@ -1,46 +0,0 @@
#include "dmc12.h"
static uint32_t dmc12_color = 0;
static uint16_t dmc12_timer = 0;
static int8_t dmc12_current = 0;
static uint8_t dmc12_direction = 1;
void dmc12_start(uint32_t color, bool reset) {
dmc12_color = color;
if (reset) {
dmc12_timer = 0;
dmc12_current = 0;
dmc12_direction = 1;
}
}
void dmc12_process(void) {
if (!dmc12_timer) {
dmc12_timer = timer_read();
return;
}
float dist_from_center = ((float)abs(dmc12_current - RGBLED_NUM / 2)) / ((float)RGBLED_NUM);
if (timer_elapsed(dmc12_timer) > dist_from_center * LED_INTERVAL) {
dmc12_current += dmc12_direction;
if (dmc12_current == 0 || dmc12_current == RGBLED_NUM - 1) {
dmc12_direction *= -1;
}
dmc12_timer = timer_read();
for (int i = 0; i < RGBLED_NUM; i++) {
if (i > dmc12_current - LED_RADIUS && i < dmc12_current + LED_RADIUS) {
float intensity = (LED_RADIUS - abs(i - dmc12_current)) / ((float)LED_RADIUS);
if (i != dmc12_current) {
intensity /= 4.0;
}
rgblight_setrgb_at(
((dmc12_color >> 16) & 0xFF) * intensity,
((dmc12_color >> 8) & 0xFF) * intensity,
(dmc12_color & 0xFF) * intensity,
i
);
} else {
rgblight_setrgb_at(0, 0, 0, i);
}
}
}
}

View File

@ -1,9 +0,0 @@
// Sexy LED animation.
#include "quantum.h"
#define LED_INTERVAL 160
#define LED_RADIUS 6
void dmc12_start(uint32_t color, bool reset);
void dmc12_process(void);

View File

@ -1,38 +0,0 @@
#include "seq.h"
static char buffer[32];
static uint8_t buffer_size = 0;
void seq_start(void) {
buffer_size = 0;
SEND_STRING(":");
}
bool seq_feed(uint16_t keycode) {
if (keycode == KC_ENTER) {
for (int i = 0; i < buffer_size + 1; i++) {
tap_code(KC_BACKSPACE);
}
for (int i = 0; i < seq_config_size; i++) {
seq_t item = seq_config[i];
if (strncmp(item.sequence, buffer, buffer_size) == 0) {
send_unicode_string(item.result);
}
}
buffer_size = 0;
return false;
} else if (keycode == KC_BACKSPACE) {
if (buffer_size) {
buffer_size--;
tap_code(keycode);
}
return true;
} else {
if (keycode >= KC_A && keycode <= KC_Z) {
buffer[buffer_size++] = keycode - KC_A + 'a';
tap_code(keycode);
}
return true;
}
}

View File

@ -1,14 +0,0 @@
#include "quantum.h"
#include <string.h>
typedef struct seq_t {
const char *sequence;
const char *result;
} seq_t;
extern seq_t seq_config[];
extern uint16_t seq_config_size;
void seq_start(void);
bool seq_feed(uint16_t keycode);

View File

@ -1,34 +0,0 @@
#include <smoothled.h>
static uint32_t sourceColor = 0x000000;
static uint32_t currentColor = 0x000000;
static uint32_t targetColor = 0x000000;
static int32_t smoothledTimer = -1;
void smoothled_set(uint32_t color) {
smoothledTimer = timer_read32();
sourceColor = currentColor;
targetColor = color;
}
void smoothled_process(void) {
if (smoothledTimer < 0) {
return;
}
int32_t kb = timer_elapsed32(smoothledTimer);
int32_t ka = SMOOTH_DURATION - kb;
if (kb > SMOOTH_DURATION) {
kb = SMOOTH_DURATION;
ka = 0;
smoothledTimer = -1;
}
currentColor = 0;
for (int i = 2; i >= 0; i--) {
uint32_t shift = i * 8;
currentColor |= (ka * ((uint32_t)(sourceColor >> shift) & 0xFF) + kb * ((uint32_t)(targetColor >> shift) & 0xFF)) / SMOOTH_DURATION;
/*currentColor |= ((targetColor >> shift) & 0xFF);*/
currentColor <<= 8;
}
currentColor >>= 8;
rgblight_setrgb((currentColor >> 16) & 0xFF, (currentColor >> 8) & 0xFF, currentColor & 0xFF);
}

View File

@ -1,6 +0,0 @@
#include "quantum.h"
#define SMOOTH_DURATION 160
void smoothled_set(uint32_t color);
void smoothled_process(void);

View File

@ -1,456 +0,0 @@
#include "arkag.h"
#include "eeprom.h"
/*
Current Layout and Keeb:
https://github.com/arkag/qmk_firmware/blob/master/keyboards/mechmini/v2/keymaps/arkag/keymap.c
*/
#include <stdbool.h>
// Start: Written by Chris Lewis
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
#define TYPING_SPEED_MAX_VALUE 200
uint8_t typing_speed = 0;
void velocikey_accelerate(void) {
if (typing_speed < TYPING_SPEED_MAX_VALUE) typing_speed += (TYPING_SPEED_MAX_VALUE / 50);
}
void velocikey_decelerate(void) {
static uint16_t decay_timer = 0;
if (timer_elapsed(decay_timer) > 500 || decay_timer == 0) {
if (typing_speed > 0) typing_speed -= 1;
//Decay a little faster at half of max speed
if (typing_speed > TYPING_SPEED_MAX_VALUE / 2) typing_speed -= 1;
//Decay even faster at 3/4 of max speed
if (typing_speed > TYPING_SPEED_MAX_VALUE / 4 * 3) typing_speed -= 3;
decay_timer = timer_read();
}
}
uint8_t velocikey_match_speed(uint8_t minValue, uint8_t maxValue) {
return MAX(minValue, maxValue - (maxValue - minValue) * ((float)typing_speed / TYPING_SPEED_MAX_VALUE));
}
// End: Written by Chris Lewis
uint8_t current_os,
mod_primary_mask,
fade_interval,
num_extra_flashes_off = 0;
Color underglow,
flash_color,
saved_color,
hsv_none = {0,0,0};
flashState flash_state = no_flash;
fadeState fade_state = add_fade;
activityState state = boot;
float song_ussr[][2] = SONG(USSR_ANTHEM);
void set_color (Color new, bool update) {
rgblight_sethsv_eeprom_helper(new.h, new.s, new.v, update);
}
void save_color(Color to_save) {
saved_color = to_save;
}
void reset_color(void) {
underglow = saved_color;
}
Color mod_color(Color current_color, bool should_add, uint8_t change_amount) {
save_color(underglow);
int addlim = HUE_MAX - change_amount;
int sublim = change_amount;
int leftovers;
if (should_add) {
if (current_color.h <= addlim) {
current_color.h += change_amount;
} else {
leftovers = (HUE_MAX + change_amount) % HUE_MAX;
current_color.h = 0 + leftovers;
}
} else {
if (current_color.h >= sublim) {
current_color.h -= change_amount;
} else {
leftovers = change_amount - current_color.h;
current_color.h = HUE_MAX - leftovers;
}
}
return current_color;
}
void check_state (void) {
static uint16_t active_timer;
if (!active_timer) {active_timer = timer_read();}
static bool activated, deactivated, slept;
switch (state) {
case active:
if (!activated) {
if (slept) {rgblight_mode_noeeprom(1);}
activated = true;
deactivated = false;
}
fade_interval = velocikey_match_speed(1, 25);
if (timer_elapsed(active_timer) < INACTIVE_DELAY) {return;}
active_timer = timer_read();
state = inactive;
return;
case inactive:
if (!deactivated) {
deactivated = true;
activated = false;
}
velocikey_decelerate();
fade_interval = velocikey_match_speed(1, 25);
return;
case boot:
return;
}
}
void fade_rgb (void) {
static uint16_t fade_timer;
if (state == boot) {return;}
if (!fade_timer) {fade_timer = timer_read();}
if (timer_elapsed(fade_timer) < fade_interval) {return;}
switch (fade_state) {
case add_fade:
if (underglow.h == HUE_MAX) {
fade_state = sub_fade;
return;
}
underglow.h = underglow.h + 1;
break;
case sub_fade:
if (underglow.h == 0) {
fade_state = add_fade;
return;
}
underglow.h = underglow.h - 1;
break;
}
fade_timer = timer_read();
if (flash_state == no_flash) {
set_color(underglow, false);
}
}
void flash_rgb (void) {
static uint16_t flash_timer;
switch(flash_state) {
case no_flash:
return;
case flash_off:
if (!flash_timer) {flash_timer = timer_read();}
if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
set_color(hsv_none, false);
flash_timer = timer_read();
flash_state = flash_on;
}
return;
case flash_on:
if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
set_color(flash_color, false);
flash_timer = timer_read();
if (num_extra_flashes_off > 0) {
flash_state = flash_off;
num_extra_flashes_off--;
} else {
set_color(underglow, false);
flash_state = no_flash;
}
}
return;
}
}
void set_os (uint8_t os, bool update) {
current_os = os;
if (update) {
eeprom_update_byte(EECONFIG_USERSPACE, current_os);
}
switch (os) {
case OS_MAC:
set_unicode_input_mode(UNICODE_MODE_MACOS);
underglow = (Color){ 213, 255, 255 };
break;
case OS_WIN:
set_unicode_input_mode(UNICODE_MODE_WINCOMPOSE);
underglow = (Color){ 128, 255, 255 };
break;
case OS_NIX:
set_unicode_input_mode(UNICODE_MODE_LINUX);
underglow = (Color){ 43, 255, 255 };
break;
default:
underglow = (Color){ 0, 0, 255 };
}
set_color(underglow, update);
flash_color = underglow;
flash_state = flash_off;
state = boot;
num_extra_flashes_off = 3;
}
// register GUI if Mac or Ctrl if other
void pri_mod(bool press) {
if (press) {
if (current_os == OS_MAC) {
register_code(KC_LGUI);
} else {
register_code(KC_LCTL);
}
} else {
if (current_os == OS_MAC) {
unregister_code(KC_LGUI);
} else {
unregister_code(KC_LCTL);
}
}
}
// register Ctrl if Mac or GUI if other
void sec_mod(bool press) {
if (press) {
if (current_os == OS_MAC) {
register_code(KC_LCTL);
} else {
register_code(KC_LGUI);
}
} else {
if (current_os == OS_MAC) {
unregister_code(KC_LCTL);
} else {
unregister_code(KC_LGUI);
}
}
}
void multi_tap(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
if (use_shift) {
register_code(KC_LSFT);
}
for (int i = 0; i < num_of_chars; i++) {
tap_code(keycode);
}
if (use_shift) {
unregister_code(KC_LSFT);
}
}
void pair_surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
for (int i = 0; i < num_of_chars; i++) {
(use_shift) ? register_mods(MOD_BIT( KC_LSFT)) : NULL;
tap_code(keycode);
tap_code((keycode == KC_LCBR) ? KC_RCBR : (keycode == KC_LBRC) ? KC_RBRC : (keycode == KC_LPRN) ? KC_RPRN : KC_NO);
(use_shift) ? unregister_mods(MOD_BIT( KC_LSFT)) : NULL;
tap_code(KC_LEFT);
}
}
void surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
for (int i = 0; i < num_of_chars; i++) {
(use_shift) ? register_mods(MOD_BIT( KC_LSFT)) : NULL;
tap_code(keycode);
(use_shift) ? unregister_mods(MOD_BIT( KC_LSFT)) : NULL;
}
multi_tap(num_of_chars / 2, KC_LEFT, false);
}
void long_keystroke(size_t num_of_keys, uint16_t keys[]) {
for (int i = 0; i < num_of_keys-1; i++) {
register_code(keys[i]);
}
tap_code(keys[num_of_keys-1]);
for (int i = 0; i < num_of_keys-1; i++) {
unregister_code(keys[i]);
}
}
void pri_mod_keystroke(uint16_t key) {
pri_mod(true);
tap_code(key);
pri_mod(false);
}
void leader_end_user(void) {
// begin OS functions
if (leader_sequence_two_keys(KC_P, KC_B)) {
if (current_os == OS_WIN) {
long_keystroke(2, (uint16_t[]){KC_LGUI, KC_PAUSE});
} else {
return;
}
}
if (leader_sequence_two_keys(KC_S, KC_S)) {
if (current_os == OS_MAC) {
long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_4});
} else if (current_os == OS_WIN) {
long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_S});
} else {
return;
}
}
if (leader_sequence_three_keys(KC_C, KC_A, KC_D)) {
if (current_os == OS_WIN) {
long_keystroke(3, (uint16_t[]){KC_LCTL, KC_LALT, KC_DEL});
} else {
}
}
if (leader_sequence_three_keys(KC_C, KC_A, KC_E)) {
if (current_os == OS_WIN) {
long_keystroke(3, (uint16_t[]){KC_LCTL, KC_LALT, KC_END});
} else {
}
}
// end OS functions
// begin format functions
if (leader_sequence_one_key(KC_B)) {
surround_type(2, KC_8, true);
}
if (leader_sequence_one_key(KC_I)) {
surround_type(2, KC_MINS, true);
}
if (leader_sequence_one_key(KC_U)) {
surround_type(4, KC_MINS, true);
}
if (leader_sequence_one_key(KC_S)) {
surround_type(4, KC_GRAVE, true);
}
if (leader_sequence_one_key(KC_C)) {
register_unicode(0x00E7); // ç
}
if (leader_sequence_two_keys(KC_A, KC_V)) {
surround_type(2, KC_QUOT, true);
pair_surround_type(2, KC_LCBR, true);
surround_type(2, KC_SPC, false);
}
if (leader_sequence_two_keys(KC_M, KC_L)) {
pair_surround_type(1, KC_LBRC, false);
SEND_STRING("LINK_NAME");
tap_code(KC_RGHT);
pair_surround_type(1, KC_LPRN, true);
pri_mod_keystroke(KC_V);
}
if (leader_sequence_two_keys(KC_C, KC_C)) {
surround_type(2, KC_GRAVE, false);
}
if (leader_sequence_three_keys(KC_C, KC_C, KC_C)) {
surround_type(6, KC_GRAVE, false);
}
if (leader_sequence_one_key(KC_E)) {
register_unicode(0x00E8); // è
}
if (leader_sequence_two_keys(KC_E, KC_E)) {
register_unicode(0x00E9); // é
}
// end format functions
// start fancy functions
if (leader_sequence_two_keys(KC_V, KC_P)) {
SEND_STRING("ggvG}x:set paste\ni");
pri_mod_keystroke(KC_V);
}
if (leader_sequence_three_keys(KC_C, KC_C, KC_ENT)) {
surround_type(6, KC_GRAVE, false);
pri_mod_keystroke(KC_V);
multi_tap(3, KC_RGHT, false);
tap_code(KC_ENTER);
}
if (leader_sequence_three_keys(KC_T, KC_C, KC_ENT)) {
multi_tap(3, KC_GRAVE, false);
pri_mod_keystroke(KC_V);
multi_tap(2, KC_ENTER, false);
}
// end fancy functions
// start typing functions
if (leader_sequence_two_keys(KC_T, KC_M)) {
register_unicode(0x2122); // ™
}
if (leader_sequence_two_keys(KC_D, KC_D)) {
SEND_STRING(".\\Administrator");
}
if (leader_sequence_three_keys(KC_D, KC_D, KC_D)) {
SEND_STRING(".\\Administrator");
tap_code(KC_TAB);
pri_mod_keystroke(KC_V);
tap_code(KC_ENTER);
}
if (leader_sequence_three_keys(KC_L, KC_O, KC_D)) {
send_unicode_string("ಠ__ಠ");
}
if (leader_sequence_three_keys(KC_M, KC_A, KC_P)) {
SEND_STRING("https://github.com/qmk/qmk_firmware/tree/master/users/arkag");
}
if (leader_sequence_two_keys(KC_F, KC_F)) {
send_unicode_string("(╯‵Д′)╯彡┻━┻");
}
if (leader_sequence_three_keys(KC_F, KC_F, KC_F)) {
send_unicode_string("┬─┬ノ( º _ º )");
}
if (leader_sequence_three_keys(KC_L, KC_O, KC_L)) {
send_unicode_string("( ͡° ͜ʖ ͡°)");
}
if (leader_sequence_three_keys(KC_S, KC_S, KC_S)) {
send_unicode_string("¯\\_(ツ)_/¯");
}
// end typing functions
}
void matrix_init_user(void) {
current_os = eeprom_read_byte(EECONFIG_USERSPACE);
set_os(current_os, false);
}
void matrix_scan_user(void) {
check_state();
flash_rgb();
fade_rgb();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
#ifdef AUDIO_ENABLE
case M_USSR:
PLAY_SONG(song_ussr);
return false;
#endif
case M_OS:
if (record->event.pressed){
set_os((current_os+1) % _OS_COUNT, true);
}
return false;
case M_DASH:
if (record->event.pressed){
register_unicode(0x2014); // —
}
return false;
default:
if (record->event.pressed) {
state = active;
velocikey_accelerate();
}
return true;
}
}

View File

@ -1,105 +0,0 @@
#pragma once
#include QMK_KEYBOARD_H
#define EECONFIG_USERSPACE (uint8_t *)20
#define SYMBOL MO(_SYMBOL)
#define MEDIA MO(_MEDIA)
#define ARROW MO(_ARROW)
#define FUNCT MO(_FUNCT)
#define KEEB MO(_KEEB)
#define HITBOX TT(_HITBOX)
#define LED_FLASH_DELAY 150
#define ACCEL_DELAY 500
#define DEACCEL_DELAY 500
#define INACTIVE_DELAY 250
#define SLEEP_DELAY 180000
#define HUE_MAX 254
enum {
_QWERTY = 0,
_SYMBOL,
_MEDIA,
_ARROW,
_FUNCT,
_KEEB,
_HITBOX,
};
typedef enum {
OS_MAC, // Don't assign values
OS_WIN,
OS_NIX,
_OS_COUNT,
} OS;
typedef struct {
uint16_t h;
uint8_t s;
uint8_t v;
} Color;
typedef enum {
no_flash = 0,
flash_off,
flash_on,
} flashState;
typedef enum {
add_fade = 0,
sub_fade,
} fadeState;
typedef enum {
active = 0,
inactive,
boot,
} activityState;
enum custom_keycodes {
M_PMOD = SAFE_RANGE,
M_SMOD,
M_OS,
M_DASH,
M_USSR,
};
void velocikey_accelerate(void);
void velocikey_decelerate(void);
uint8_t velocikey_match_speed(uint8_t minValue, uint8_t maxValue);
void set_color (Color new, bool update);
void save_color(Color to_save);
void reset_color(void);
Color mod_color(Color current_color, bool should_add, uint8_t change_amount);
void reverse_fade (void);
void check_state (void);
void fade_rgb (void);
void flash_rgb (void);
void set_os (uint8_t os, bool update);
void tap_key(uint8_t keycode);
void pri_mod(bool press);
void sec_mod(bool press);
void meh_hyper(bool press);
void multi_tap(uint8_t num_of_chars, uint16_t keycode, bool use_shift);
void surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift);
void pair_surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift);
void long_keystroke(size_t num_of_keys, uint16_t keys[]);

View File

@ -1,22 +0,0 @@
/* Copyright 2021 Alex Kagno
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define TAPPING_TERM 200
#define LEADER_TIMEOUT 300
#define LEADER_PER_KEY_TIMING

View File

@ -1,42 +0,0 @@
# Shot on Pixel 2 XL with Cheap Lamp at Work
![mmm, tasty](mechmini2.jpg)
# I don't know what I'm doing
Some links:
* [Layout File: Mech Mini 2](layout_mm2)
* [Userspace Header](arkag_h)
* [Userspace Main](arkag_c)
Here's a list of some things I have working with my currently [keyboard](mm2_home):
* Reactive (sort of) fading while typing, ported from [Velocikey](https://github.com/qmk/qmk_firmware/pull/3754).
* OS Switching, storing to EEPROM
* OS Specific Macros and Shortcuts(WIN+SHIFT+S for Windows and CMD+SHIFT+4 for MacOS)
* Flashing RGB LED on OS change
* Hex Unicode Macros dependent on OS(half works on Windows due to [WinCompose](https://github.com/SamHocevar/wincompose) not functioning properly just yet).
* "Sleep" function activates after 3 minutes (breathing).
* Markdown style macros for surround type __eve__ ~~ryw~~ *her* **eee** (apparently only certain places support underline and strikethrough ಠ__ಠ)
# License Stuff
Copyright 2018 arkag arkag@pm.me
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
[arkag_c]: /users/arkag/arkag.c
[arkag_h]: /users/arkag/arkag.h
[layout_mm2]: /keyboards/mechmini/v2/keymaps/arkag/keymap.c
[mm2_home]: https://cartel.ltd/projects/mechmini2/

View File

@ -1,4 +0,0 @@
SRC += arkag.c
# save me space!
LTO_ENABLE = yes

View File

@ -1,3 +0,0 @@
*user_config.*
custom_definitions.h
secr.h

View File

@ -1,722 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "art.h"
#include "custom_definitions.h"
#include "secr.h"
#include "funcs/led_funcs.h"
#include "funcs/string_funcs.h"
static const int COPY_DELAY = 50;
static const int INCOGNITO_DELAY = 500;
static const int LMB_SPAM_INTERVAL = 30;
static const uint8_t OS_MOD_KEYS[2] = {MOD_LALT, MOD_LCTL};
bool mac_ctrl_on = false; //for switching tabs
bool mac_gui_on = false; //for switching languages
bool mac_alt_window_switching_on = false; //for switching windows
int char_to_bspace = 1;
int char_to_del = 0;
static bool sarcasm_on = false;
static bool sarcasm_key = false;
static bool full_caps_mode = false;
bool hw_caps_on;
static bool is_lmb_timer_active = false;
static uint16_t lmb_timer = 0;
__attribute__ ((weak))
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
void keyboard_post_init_user(void) {
led_show_variable_status(is_win);
layer_state_set_user(layer_state);
}
void matrix_scan_user(void) {
if (is_lmb_timer_active) {
if (timer_elapsed(lmb_timer) > LMB_SPAM_INTERVAL) {
SEND_STRING(SS_TAP(X_BTN1)); //do stuff that needs spamming
lmb_timer = timer_read();
}
}
}
bool caps_word_on(void) {
return hw_caps_on && !full_caps_mode;
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
if (sarcasm_on) {
sarcasm_key = ! sarcasm_key;
del_mods(MOD_LSFT);
if (sarcasm_key) {
add_mods(MOD_LSFT);
}
}
//Checking all other non-backspace keys to clear the backspace buffer. This is to prevent the bug of deleting N chars sometime after using a macro
switch (keycode) {
case LT(COMBOS,KC_BSPC):
case KC_BACKSPACE:
case KC_DEL:
case KC_LSFT:
case KC_RSFT:
case XXXXXXX:
break;
default:
char_to_bspace = 1;
char_to_del = 0;
break;
}
}
switch (keycode) {
case XXXXXXX:
if (record->event.pressed && !layer_state_is(BASE)) {
blink_leds(NUM_SCROLL_LED_ON);
return true;
}
break;
case KC_TAB:
if (record->event.pressed && is_mac_with_base_layer_off()) {
uint8_t mod_state = get_mods() & MOD_MASK_CTRL;
if (get_mods() & mod_state && !mac_alt_window_switching_on) {
del_mods(mod_state);
add_mods(MOD_LGUI);
mac_ctrl_on = true;
}
}
case KC_GRAVE:
if (record->event.pressed && is_mac_with_base_layer_off()) {
uint8_t mod_state = get_mods() & MOD_MASK_ALT;
if (get_mods() & mod_state) {
del_mods(mod_state);
add_mods(MOD_LCTL);
mac_alt_window_switching_on = true;
}
}
break;
case KC_LSFT:
if (record->event.pressed && is_mac_with_base_layer_off() && !mac_ctrl_on) {
uint8_t mod_state = get_mods() & MOD_MASK_AG;
if (get_mods() & mod_state) {
del_mods(mod_state);
add_mods(MOD_LGUI);
mac_gui_on = true;
send_string(lang_switch_combo);
return false;
} else {
return true;
}
}
break;
case KC_LEFT:
case KC_RIGHT:
if (record->event.pressed && is_mac_with_base_layer_off()) {
/* && !mac_ctrl_on/!mac_alt_tab_on are required since setting the state while holding the key changes
the modifier from OS's perspective. As a result, just the pressed key cannot be the single source
of truth to determine which state we're in, and a separate bool is required */
uint8_t alt_state = get_mods() & MOD_MASK_ALT;
uint8_t ctrl_state = get_mods() & MOD_MASK_CTRL;
//Allows Ctrl <-/-> on Mac if Ctrl Tab is already pressed
if (get_mods() & alt_state && mac_alt_window_switching_on && !mac_ctrl_on) {
del_mods(alt_state);
add_mods(MOD_LCTL);
}
if (get_mods() & ctrl_state && !mac_alt_window_switching_on && !mac_gui_on) {
del_mods(ctrl_state);
add_mods(MOD_LALT);
mac_ctrl_on = true;
}
}
break;
case KC_LALT:
if (!record->event.pressed && is_mac_with_base_layer_off()) {
if (mac_alt_window_switching_on) {
unregister_mods(MOD_LCTL);
mac_alt_window_switching_on = false;
return false;
} else if (mac_gui_on) {
unregister_mods(MOD_LGUI);
mac_gui_on = false;
return false;
}
return true;
}
break;
case KC_RALT:
if (!record->event.pressed && mac_alt_window_switching_on && is_mac_with_base_layer_off()) {
unregister_mods(MOD_LCTL);
mac_alt_window_switching_on = false;
return false;
}
break;
case KC_LCTL:
case KC_RCTL:
if (!record->event.pressed && mac_ctrl_on && is_mac_with_base_layer_off()) {
// Need to remove only previously set mods (e.g. WIN & ALT) to preserve Shift, etc
unregister_mods(MOD_LGUI);
unregister_mods(MOD_LALT);
mac_ctrl_on = false;
return false;
}
break;
case KC_HOME:
if (record->event.pressed && is_mac_with_base_layer_off()) {
SEND_STRING(SS_LCTL(SS_TAP(X_LEFT)));
return false;
}
break;
case KC_END:
if (record->event.pressed && is_mac_with_base_layer_off()) {
SEND_STRING(SS_LCTL(SS_TAP(X_RIGHT)));
return false;
}
break;
case KC_DEL:
case KC_BSPC:
if (record->event.pressed) {
return handle_del_bspace();
}
break;
case LT(COMBOS, KC_BSPC):
if (record->event.pressed && record->tap.count == 1) {
return handle_del_bspace();
}
break;
case LT(NAV,KC_APP):
if (!record->event.pressed && !is_win) {
mac_ctrl_on = false;
mac_gui_on = false;
mac_alt_window_switching_on = false;
clear_mods();
SEND_STRING(SS_TAP(X_LCTL) SS_TAP(X_LGUI) SS_TAP(X_LALT) SS_TAP(X_LSFT));
return true;
}
break;
/* -------------------------------------------------------------------------
* CAPS WORD
* ------------------------------------------------------------------------ */
case KC_CAPS:
if (record->event.pressed && !layer_state_is(BASE)) {
if (get_mods() & MOD_MASK_SHIFT) {
full_caps_mode = true;
led_show_variable_status(full_caps_mode);
if (hw_caps_on) {
SEND_STRING(SS_TAP(X_CAPS));
}
} else if (hw_caps_on) {
full_caps_mode = false;
}
}
break;
// case KC_SPACE:
case LT(MEDIA,KC_SPC):
case LT(NAV,KC_SPC):
if (record->event.pressed && caps_word_on() && !layer_state_is(BASE) && record->tap.count == 1) {
SEND_STRING(SS_TAP(X_CAPS));
}
break;
case KC_MINS:
if (record->event.pressed && caps_word_on() && !layer_state_is(BASE)) {
SEND_STRING("_");
return false;
}
break;
/* -------------------------------------------------------------------------
* CUSTOM MACROS
* ------------------------------------------------------------------------ */
case CTRL_CTV:
if (record->event.pressed) {
bool shifted = get_mods() & MOD_MASK_SHIFT;
clear_mods();
SEND_STRING(SS_LCTL("c"));
wait_ms(COPY_DELAY);
SEND_STRING(SS_LCTL("tv"));
if (!shifted) {
SEND_STRING(SS_TAP(X_ENTER));
}
}
break;
case BEAT_BROWSER:
if (record->event.pressed) {
SEND_STRING(SS_LCTL("c"));
wait_ms(COPY_DELAY);
SEND_STRING(SS_LGUI("1") SS_LCTL("tv") SS_TAP(X_ENTER));
}
break;
case CTRL_LCTV:
if (record->event.pressed) {
if (get_mods() & MOD_MASK_SHIFT) {
//Firefox
clear_mods();
SEND_STRING(SS_LCTL("lc"));
wait_ms(COPY_DELAY);
SEND_STRING(SS_LCTL("P"));
wait_ms(INCOGNITO_DELAY);
SEND_STRING(SS_LCTL("v") SS_TAP(X_ENTER));
} else if (get_mods() & MOD_MASK_CTRL) {
//Chrome
clear_mods();
SEND_STRING(SS_LCTL("lc"));
wait_ms(COPY_DELAY);
SEND_STRING(SS_LCTL("Nv") SS_TAP(X_ENTER));
} else {
SEND_STRING(SS_LCTL("lc"));
wait_ms(COPY_DELAY);
SEND_STRING(SS_LCTL("tv"));
}
}
break;
case CTRL_CAV:
if (record->event.pressed) {
SEND_STRING(SS_LCTL("c" SS_TAP(X_TAB)));
wait_ms(COPY_DELAY);
SEND_STRING(SS_LCTL("av"));
}
break;
case NEUTRAL_COPY:
if (record->event.pressed && is_win) {
uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
if (shifted) {
del_mods(shifted);
SEND_STRING(SS_LCTL("z"));
}
SEND_STRING(SS_LCTL("c"));
wait_ms(COPY_DELAY);
SEND_STRING(SS_LGUI("r") SS_LCTL("vac") SS_TAP(X_ESC));
}
break;
case SARCASM:
if (record->event.pressed) {
del_mods(MOD_LSFT);
sarcasm_on = !sarcasm_on;
led_show_variable_status(sarcasm_on);
}
break;
case LMB_SPAM:
if (record->event.pressed) {
is_lmb_timer_active = ! is_lmb_timer_active;
lmb_timer = timer_read();
}
break;
/* -------------------------------------------------------------------------
* OS TOGGLING
* ------------------------------------------------------------------------ */
case TOG_OS:
if (record->event.pressed) {
is_win = ! is_win;
led_show_variable_status(is_win);
}
break;
case CTR_ALT:
if (record->event.pressed) {
add_mods(OS_MOD_KEYS[is_win]);
} else {
unregister_mods(OS_MOD_KEYS[is_win]);
}
break;
case CTR_ALT_SHIFT:
if (record->event.pressed) {
add_mods(OS_MOD_KEYS[is_win]);
add_mods(MOD_RSFT);
} else {
unregister_mods(OS_MOD_KEYS[is_win]);
unregister_mods(MOD_RSFT);
}
break;
case OS_CTRL:
if (is_win) {
if (record->event.pressed) {
SEND_STRING(SS_DOWN(X_LCTL));
} else {
SEND_STRING(SS_UP(X_LCTL));
}
} else {
if (record->event.pressed) {
SEND_STRING(SS_DOWN(X_LGUI));
} else {
SEND_STRING(SS_UP(X_LGUI));
}
}
break;
case OS_WIN:
if (is_win) {
if (record->event.pressed) {
SEND_STRING(SS_DOWN(X_LGUI));
} else {
SEND_STRING(SS_UP(X_LGUI));
}
} else {
if (record->event.pressed) {
SEND_STRING(SS_DOWN(X_LCTL));
} else {
SEND_STRING(SS_UP(X_LCTL));
}
}
break;
/* -------------------------------------------------------------------------
* STRING MACROS
* ------------------------------------------------------------------------ */
// case :
// if (record->event.pressed) {
// send_string_remembering_length("");
// }
// break;
// case :
// if (record->event.pressed) {
// send_shifted_strings("", "");
// }
// break;
case TILD_BLOCK:
if (record->event.pressed) {
uint8_t alted = get_mods() & MOD_MASK_ALT;
uint8_t switch_lang_state = get_mods() & MOD_MASK_CTRL;
if (switch_lang_state) {
del_mods(switch_lang_state);
switch_lang();
}
if (alted) {
del_mods(alted);
SEND_STRING(SS_TAP(X_ESC) "```" SS_LSFT(SS_TAP(X_ENTER) SS_TAP(X_ENTER)) "```" SS_TAP(X_UP));
char_to_bspace = 4;
char_to_del = 4;
} else {
SEND_STRING("`` ");
uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
del_mods(shifted);
SEND_STRING(SS_TAP(X_LEFT) SS_TAP(X_LEFT));
add_mods(shifted);
char_to_bspace = 1;
char_to_del = 2;
}
if (switch_lang_state) {
switch_lang();
}
}
break;
case ALL_BEST:
if (record->event.pressed) {
send_shifted_strings_add("All the best,\nArt", "joms");
}
break;
case AT_EMAIL:
if (record->event.pressed) {
send_string_remembering_length("@gmail.com");
}
break;
case BRACES:
if (record->event.pressed) {
uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
uint8_t switch_lang_state = get_mods() & MOD_MASK_CTRL;
if (switch_lang_state) {
del_mods(switch_lang_state);
switch_lang();
}
add_mods(shifted);
SEND_STRING("[]");
del_mods(shifted);
SEND_STRING(SS_TAP(X_LEFT));
add_mods(shifted);
if (switch_lang_state) {
switch_lang();
}
char_to_bspace = 1;
char_to_del = 1;
}
break;
case DASHES:
if (record->event.pressed) {
SEND_STRING("--");
uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
del_mods(shifted);
SEND_STRING(" " SS_TAP(X_LEFT) SS_TAP(X_LEFT));
add_mods(shifted);
char_to_bspace = 1;
char_to_del = 2;
}
break;
case PARENTHS:
if (record->event.pressed) {
clear_mods();
SEND_STRING("() " SS_TAP(X_LEFT) SS_TAP(X_LEFT));
char_to_bspace = 1;
char_to_del = 2;
}
break;
case QUOTES:
if (record->event.pressed) {
uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
uint8_t switch_lang_state = get_mods() & MOD_MASK_CTRL;
if (switch_lang_state) {
del_mods(switch_lang_state);
switch_lang();
}
add_mods(shifted);
SEND_STRING("''");
del_mods(shifted);
wait_ms(LONG_TYPING_INTERVAL);
SEND_STRING(" " SS_TAP(X_LEFT) SS_TAP(X_LEFT));
add_mods(shifted);
if (switch_lang_state) {
switch_lang();
}
char_to_bspace = 1;
char_to_del = 2;
}
break;
case QUOTES_RU:
if (record->event.pressed) {
clear_mods();
SEND_STRING("@@ ");
wait_ms(LONG_TYPING_INTERVAL);
SEND_STRING(SS_TAP(X_LEFT) SS_TAP(X_LEFT));
char_to_bspace = 1;
char_to_del = 2;
}
break;
case STARS:
if (record->event.pressed) {
clear_mods();
SEND_STRING("** " SS_TAP(X_LEFT) SS_TAP(X_LEFT));
char_to_bspace = 1;
char_to_del = 2;
}
break;
case ADMINS:
if (record->event.pressed) {
send_string_remembering_length("admin");
}
break;
case G_ADD:
if (record->event.pressed) {
send_string_remembering_length("git add ");
}
break;
case G_BRCH:
if (record->event.pressed) {
send_shifted_strings_add("git branch ", "-d ");
}
break;
case G_C:
if (record->event.pressed) {
send_string_remembering_length("git c[Heckout/Ommit]");
layer_on(GIT_C);
}
break;
case G_CHEC:
if (!record->event.pressed) {
bool shifted = get_mods() & MOD_MASK_SHIFT;
clear_mods();
press_n_times(15, KC_BACKSPACE);
send_string_with_translation("heckout ");
char_to_bspace = 13;
if (shifted) {
send_string_with_translation("-b ");
char_to_bspace = 16;
}
layer_off(GIT_C);
}
break;
case G_COMM:
if (!record->event.pressed) {
bool ctrled = get_mods() & MOD_MASK_CTRL;
bool shifted = get_mods() & MOD_MASK_SHIFT;
clear_mods();
press_n_times(15, KC_BACKSPACE);
send_string_with_translation("ommit ");
char_to_bspace = 11;
layer_off(GIT_C);
if (ctrled) {
return false;
}
SEND_STRING("-");
char_to_bspace = 15;
if (shifted) {
send_string_with_translation("a");
char_to_bspace = 16;
}
send_string_with_translation("m");
SEND_STRING(" \"\"" SS_TAP(X_LEFT));
char_to_del = 1;
}
break;
case G_DEV:
if (record->event.pressed) {
send_shifted_strings("develop", "master");
}
break;
case G_DIFF:
if (record->event.pressed) {
send_string_remembering_length("git diff ");
}
break;
case G_FTCH:
if (record->event.pressed) {
send_string_remembering_length("git fetch ");
}
break;
case G_LOG:
if (record->event.pressed) {
send_string_remembering_length("git log ");
}
break;
case G_MERG:
if (record->event.pressed) {
send_string_remembering_length("git merge ");
}
break;
case G_PULL:
if (record->event.pressed) {
send_string_remembering_length("git pull ");
}
break;
case G_PUSH:
if (record->event.pressed) {
send_string_remembering_length("git push -u ");
}
break;
case G_R:
if (!record->event.pressed) {
send_string_remembering_length("git re[Set/Vert/Base -i]");
layer_on(GIT_R);
}
break;
case G_RBASE:
if (!record->event.pressed) {
press_n_times(18, KC_BACKSPACE);
send_string_with_translation("base -i ");
char_to_bspace = 14;
layer_off(GIT_R);
}
break;
case G_RVERT:
if (!record->event.pressed) {
press_n_times(18, KC_BACKSPACE);
send_string_with_translation("vert ");
char_to_bspace = 11;
layer_off(GIT_R);
}
break;
case G_RST:
if (!record->event.pressed) {
bool shifted = get_mods() & MOD_MASK_SHIFT;
clear_mods();
press_n_times(18, KC_BACKSPACE);
send_string_with_translation("set ");
char_to_bspace = 10;
if (shifted) {
send_string_with_translation("--hard ");
char_to_bspace = 17;
}
layer_off(GIT_R);
}
break;
case G_S:
if (!record->event.pressed) {
send_string_remembering_length("git s[taSh/How/taTus]");
layer_on(GIT_S);
}
break;
case G_SHOW:
if (!record->event.pressed) {
press_n_times(16, KC_BACKSPACE);
send_string_with_translation("how ");
char_to_bspace = 9;
layer_off(GIT_S);
}
break;
case G_STSH:
if (!record->event.pressed) {
bool shifted = get_mods() & MOD_MASK_SHIFT;
clear_mods();
press_n_times(16, KC_BACKSPACE);
send_string_with_translation("tash ");
char_to_bspace = 10;
if (shifted) {
clear_mods();
send_string_with_translation("apply ");
char_to_bspace = 16;
}
layer_off(GIT_S);
}
break;
case G_STAT:
if (!record->event.pressed) {
press_n_times(16, KC_BACKSPACE);
send_string_with_translation("tatus ");
char_to_bspace = 11;
layer_off(GIT_S);
}
break;
case K_CUST1 ... K_CUST3: // custom strings not stored in source control
if (!record->event.pressed) {
send_string_remembering_length(custom[keycode - K_CUST1]);
blink_leds(NUM_SCROLL_LED_ON);
}
break;
case K_SECR1 ... K_SECR4: // Secrets! Externally defined strings, not stored in repo
if (!record->event.pressed) {
send_string_remembering_length(secrets[keycode - K_SECR1]);
blink_leds(NUM_SCROLL_LED_ON);
}
break;
case CTL_ALT_START ... CTL_ALT_END:
if (record->event.pressed) {
if (is_win) {
register_code16(LCTL(keycode - CTL_ALT_START));
} else {
register_code16(LALT(keycode - CTL_ALT_START));
}
} else {
if (is_win) {
unregister_code16(LCTL(keycode - CTL_ALT_START));
} else {
unregister_code16(LALT(keycode - CTL_ALT_START));
}
}
break;
}
return process_record_keymap(keycode, record);
}

View File

@ -1,107 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include QMK_KEYBOARD_H
#define CTL_ALT(kc) (CTL_ALT_START + ((kc) & 0xff))
extern bool is_win;
#define TYPING_INTERVAL 20
#define LONG_TYPING_INTERVAL 50
enum layer_names {
#if SPLIT75_SETUP_FOR_PUBLIC_USE_BY_DEFAULT && defined(KEYBOARD_wheatfield_split75) // defined by "KEYBOARD" followed by folder structure
BASE,
QWERTY,
#else
QWERTY,
BASE,
#endif
WORKMAN,
#if defined(KEYBOARD_mt_split75)
CONFIG,
LAYOUT_CHG,
QWERTY_MOD,
#elif defined(KEYBOARD_ktec_ergodone)
FKEYS,
CTRL_NAV,
SHIFT_NAV,
#endif
MEDIA,
COMBOS,
//STRINGS,
NAV,
NUMPAD,
GIT,
GIT_C,
GIT_R,
GIT_S
};
enum custom_keycodes_art {
CTRL_CTV = SAFE_RANGE,
CTRL_LCTV,
CTRL_CAV,
BEAT_BROWSER,
NEUTRAL_COPY,
SARCASM,
LMB_SPAM,
TOG_OS,
CTR_ALT,
CTR_ALT_SHIFT,
OS_CTRL,
OS_WIN,
TILD_BLOCK,
ALL_BEST,
AT_EMAIL,
BRACES,
DASHES,
PARENTHS,
STARS,
QUOTES,
QUOTES_RU,
ADMINS,
PRESCRIPTION,
FOURS,
G_ADD,
G_BRCH,
G_C,
G_CHEC,
G_COMM,
G_DEV,
G_DIFF,
G_FTCH,
G_LOG,
G_MERG,
G_PULL,
G_PUSH,
G_R,
G_RBASE,
G_RVERT,
G_RST,
G_S,
G_STAT,
G_STSH,
G_SHOW,
K_CUST1,
K_CUST2,
K_CUST3,
K_SECR1,
K_SECR2,
K_SECR3,
K_SECR4,
CTL_ALT_START,
CTL_ALT_END = CTL_ALT_START + 0xff,
NEW_SAFE_RANGE //for keymap specific codes
};

View File

@ -1,7 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#define SPLIT75_SETUP_FOR_PUBLIC_USE_BY_DEFAULT true
#define WORKMAN_TO_QWERTY_HW_MAPPING false
#define lang_switch_combo SS_LGUI(SS_TAP(X_Z))

View File

@ -1,14 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#undef TAPPING_TOGGLE
#define TAPPING_TOGGLE 2
#define COMBO_SHOULD_TRIGGER
// saving space
#define LAYER_STATE_16BIT // remove if using more than 16 layers
#define NO_ACTION_ONESHOT
#define NO_MUSIC_MODE

View File

@ -1,8 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
static char * custom[] = {
"",
"",
""
};

View File

@ -1,55 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "led_funcs.h"
bool hw_caps_on;
__attribute__ ((weak)) void num_led_on(void) {}
__attribute__ ((weak)) void num_led_off(void) {}
__attribute__ ((weak)) void caps_led_on(void) {}
__attribute__ ((weak)) void caps_led_off(void) {}
__attribute__ ((weak)) void scroll_led_on(void) {}
__attribute__ ((weak)) void scroll_led_off(void) {}
void toggle_leds(int leds) {
if (NUM_LED_ON & leds) {
num_led_on();
} else {
num_led_off();
}
if (SCROLL_LED_ON & leds) {
scroll_led_on();
} else {
scroll_led_off();
}
}
bool led_update_user(led_t led_state) {
// only use caps LED - ignore Num & Scroll
if (led_state.caps_lock) {
caps_led_on();
} else {
caps_led_off();
}
hw_caps_on = led_state.caps_lock;
return false; // 'false' prevents led_update_kb from firing
}
void blink_leds(int leds) {
for (int i = 0; i < 3; i++) {
toggle_leds(leds);
wait_ms(BLINKING_INTERVAL);
toggle_leds(ALL_OFF);
wait_ms(BLINKING_INTERVAL);
}
}
void led_show_variable_status(bool value) {
if (value) {
blink_leds(NUM_LED_ON);
} else {
blink_leds(SCROLL_LED_ON);
}
}

View File

@ -1,17 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include QMK_KEYBOARD_H
#define NUM_LED_ON 4
#define SCROLL_LED_ON 1
#define NUM_SCROLL_LED_ON 5
#define ALL_OFF 0
#define BLINKING_INTERVAL 25
void toggle_leds(int leds);
bool led_update_user(led_t led_state);
void blink_leds(int leds);
void led_show_variable_status(bool value);

View File

@ -1,307 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "art.h"
#include "string_funcs.h"
#include "string.h"
bool mac_ctrl_on;
int char_to_bspace;
int char_to_del;
enum combo_events {
HOMEROW_UP,
HOMEROW_LEFT,
HOMEROW_RIGHT,
HOMEROW_DOWN,
HOMEROW_PREV_WORD,
HOMEROW_NEXT_WORD,
HOMEROW_HOME,
HOMEROW_END,
ED_F1,
ED_F2,
ED_F3,
ED_F4,
ED_F5,
ED_F6,
ED_F7,
ED_F8,
ED_F9,
ED_F10,
ED_F11,
ED_F12,
ED_PSCREEN,
ED_ENTER,
ED_CS_ENTER,
BSPC_LSFT_CLEAR
};
const uint16_t PROGMEM combo_up[] = {KC_W, KC_R, COMBO_END};
const uint16_t PROGMEM combo_left[] = {KC_S, KC_E, COMBO_END};
const uint16_t PROGMEM combo_right[] = {KC_F, KC_E, COMBO_END};
const uint16_t PROGMEM combo_down[] = {KC_S, KC_F, COMBO_END};
const uint16_t PROGMEM combo_prev_word[] = {KC_S, KC_LCTL, COMBO_END};
const uint16_t PROGMEM combo_next_word[] = {KC_F, KC_LCTL, COMBO_END};
const uint16_t PROGMEM combo_end[] = {KC_W, KC_E, COMBO_END};
const uint16_t PROGMEM combo_home[] = {KC_E, KC_R, COMBO_END};
const uint16_t PROGMEM combo_enter[] = {KC_BSPC, KC_INS, COMBO_END};
const uint16_t PROGMEM combo_f1[] = {KC_1, KC_Q, COMBO_END};
const uint16_t PROGMEM combo_f2[] = {KC_2, KC_W, COMBO_END};
const uint16_t PROGMEM combo_f3[] = {KC_3, KC_E, COMBO_END};
const uint16_t PROGMEM combo_f4[] = {KC_4, KC_R, COMBO_END};
const uint16_t PROGMEM combo_f5[] = {KC_5, KC_T, COMBO_END};
const uint16_t PROGMEM combo_f6[] = {KC_6, KC_Y, COMBO_END};
const uint16_t PROGMEM combo_f7[] = {KC_7, KC_U, COMBO_END};
const uint16_t PROGMEM combo_f8[] = {KC_8, KC_I, COMBO_END};
const uint16_t PROGMEM combo_f9[] = {KC_9, KC_O, COMBO_END};
const uint16_t PROGMEM combo_f10[] = {KC_0, KC_P, COMBO_END};
const uint16_t PROGMEM combo_f11[] = {LT(GIT,KC_SLSH), KC_RSFT, COMBO_END};
const uint16_t PROGMEM combo_f12[] = {KC_RALT, KC_RCTL, COMBO_END};
const uint16_t PROGMEM combo_pscreen[] = {TO(WORKMAN), KC_RALT, COMBO_END};
const uint16_t PROGMEM done_sm[] = {KC_LEFT, KC_RIGHT, COMBO_END};
const uint16_t PROGMEM clear_line_combo[] = {KC_BSPC, KC_LSFT, COMBO_END};
combo_t key_combos[] = {
[HOMEROW_UP] = COMBO(combo_up, KC_UP),
[HOMEROW_LEFT] = COMBO(combo_left, KC_LEFT),
[HOMEROW_RIGHT] = COMBO(combo_right, KC_RIGHT),
[HOMEROW_DOWN] = COMBO(combo_down, KC_DOWN),
[HOMEROW_PREV_WORD] = COMBO_ACTION(combo_prev_word),
[HOMEROW_NEXT_WORD] = COMBO_ACTION(combo_next_word),
[HOMEROW_HOME] = COMBO(combo_end, KC_HOME),
[HOMEROW_END] = COMBO(combo_home, KC_END),
#if defined(KEYBOARD_ktec_ergodone)
[ED_ENTER] = COMBO(combo_enter, KC_ENTER),
[ED_F1] = COMBO(combo_f1, KC_F1),
[ED_F2] = COMBO(combo_f2, KC_F2),
[ED_F3] = COMBO(combo_f3, KC_F3),
[ED_F4] = COMBO(combo_f4, KC_F4),
[ED_F5] = COMBO(combo_f5, KC_F5),
[ED_F6] = COMBO(combo_f6, KC_F6),
[ED_F7] = COMBO(combo_f7, KC_F7),
[ED_F8] = COMBO(combo_f8, KC_F8),
[ED_F9] = COMBO(combo_f9, KC_F9),
[ED_F10] = COMBO(combo_f10, KC_F10),
[ED_F11] = COMBO(combo_f11, KC_F11),
[ED_F12] = COMBO(combo_f12, KC_F12),
[ED_PSCREEN] = COMBO(combo_pscreen, KC_PRINT_SCREEN),
[ED_CS_ENTER] = COMBO_ACTION(done_sm),
#endif
[BSPC_LSFT_CLEAR] = COMBO_ACTION(clear_line_combo),
};
void process_combo_event(uint16_t combo_index, bool pressed) {
switch(combo_index) {
case HOMEROW_PREV_WORD:
if (pressed) {
if (is_win) {
tap_code16(C(KC_LEFT));
} else {
tap_code16(A(KC_LEFT));
}
}
break;
case HOMEROW_NEXT_WORD:
if (pressed) {
if (is_win) {
tap_code16(C(KC_RIGHT));
} else {
tap_code16(A(KC_RIGHT));
}
}
break;
case BSPC_LSFT_CLEAR:
if (pressed) {
tap_code16(KC_END);
tap_code16(S(KC_HOME));
tap_code16(KC_BSPC);
}
break;
case ED_CS_ENTER:
if (pressed) {
tap_code16(C(S(KC_ENTER)));
}
break;
}
}
bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) {
return !layer_state_is(BASE);
}
bool is_mac_with_base_layer_off(void) {
return !is_win && !layer_state_is(BASE);
}
void switch_lang(void) {
if (is_win) {
SEND_STRING(SS_LALT(SS_TAP(X_LSFT)));
} else {
send_string(lang_switch_combo);
wait_ms(10);
}
}
void press_n_times(int times, uint16_t key) {
for (int i=0; i<times; i++) {
// wait_ms(TYPING_INTERVAL);
tap_code16(key);
}
}
bool handle_del_bspace(void) {
if (char_to_bspace > 1 || char_to_del > 0) {
layer_off(GIT_C);
layer_off(GIT_R);
layer_off(GIT_S);
press_n_times(char_to_bspace, KC_BACKSPACE);
char_to_bspace = 1;
press_n_times(char_to_del, KC_DEL);
char_to_del = 0;
return false;
}
if (is_mac_with_base_layer_off()) {
uint8_t mod_state = get_mods() & MOD_MASK_CTRL;
if (get_mods() & mod_state) {
del_mods(mod_state);
add_mods(MOD_LALT);
mac_ctrl_on = true;
}
}
return true;
}
void send_string_with_translation(char *string) {
#if WORKMAN_TO_QWERTY_HW_MAPPING
if (layer_state_is(WORKMAN)) {
int isUpperCase = 0;
for (int i = 0; i < strlen(string); i++) {
char toPrint = string[i];
if (isupper(toPrint)) {
if (toPrint == 'P') {
SEND_STRING(":");
continue;
}
isUpperCase = 1;
toPrint = tolower(toPrint);
}
switch (toPrint) {
case ':':
toPrint = 'I';
break;
case 'w':
toPrint = 'd';
break;
case 'e':
toPrint = 'r';
break;
case 'r':
toPrint = 'w';
break;
case 't':
toPrint = 'b';
break;
case 'y':
toPrint = 'j';
break;
case 'u':
toPrint = 'f';
break;
case 'i':
toPrint = 'u';
break;
case 'o':
toPrint = 'p';
break;
case 'p':
toPrint = ';';
break;
case 'd':
toPrint = 'h';
break;
case 'f':
toPrint = 't';
break;
case 'h':
toPrint = 'y';
break;
case 'j':
toPrint = 'n';
break;
case 'k':
toPrint = 'e';
break;
case 'l':
toPrint = 'o';
break;
case ';':
toPrint = 'i';
break;
case 'b':
toPrint = 'm';
break;
case 'n':
toPrint = 'k';
break;
case 'm':
toPrint = 'l';
break;
}
if (isUpperCase) {
isUpperCase = 0;
toPrint = toupper(toPrint);
}
send_char(toPrint);
}
} else {
send_string(string);
}
#else
send_string(string);
#endif
}
void send_string_remembering_length(char *string) {
send_string_with_translation(string);
char_to_bspace = strlen(string);
}
void send_shifted_strings(char *string1, char *string2) {
if (get_mods() & MOD_MASK_SHIFT) {
clear_mods();
send_string_remembering_length(string2);
} else {
send_string_remembering_length(string1);
}
}
void send_shifted_strings_add(char *string1, char *string2) {
bool shifted = get_mods() & MOD_MASK_SHIFT;
clear_mods();
send_string_remembering_length(string1);
if (shifted) {
send_string(string2);
char_to_bspace = strlen(string1) + strlen(string2);
}
}

View File

@ -1,14 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include QMK_KEYBOARD_H
bool is_mac_with_base_layer_off(void);
void switch_lang(void);
void press_n_times(int times, uint16_t key);
bool handle_del_bspace(void);
void send_string_with_translation(char *string);
void send_string_remembering_length(char *string);
void send_shifted_strings(char *string1, char *string2);
void send_shifted_strings_add(char *string1, char *string2);

View File

@ -1,15 +0,0 @@
SRC += art.c
SRC += funcs/led_funcs.c
SRC += funcs/string_funcs.c
COMBO_ENABLE = yes
# saving space
COMMAND_ENABLE = no
CONSOLE_ENABLE = no
GRAVE_ESC_ENABLE = no
LTO_ENABLE = yes
MAGIC_ENABLE = no
# MOUSEKEY_ENABLE = no
MUSIC_ENABLE = no
SPACE_CADET_ENABLE = no

View File

@ -1,9 +0,0 @@
// Copyright 2022 Artjoms Rizihs (@artjomsR)
// SPDX-License-Identifier: GPL-2.0-or-later
static char * secrets[] = {
"",
"",
"",
""
};

View File

@ -1,31 +0,0 @@
# A multi-OS keyboard layout with support for both Linux (KDE) and MacOS-specific QWERTY layouts for many 60-ish% keyboards (
## Author: [BlueTufa](https://github.com/BlueTufa)
> Supported Keyboards: 1up RGB and HTE, Clueboard 66, dztech 60 RGB, and partial support for Preonic and Planck ortholinear keyboards.
## Layouts
### QWERTY
Default layer: Standard QWERTY layer with CAPS lock mapped to ESC. ESC is a Layer toggle, when held down it maps to KDE-specific MOVE layer. Dedicated Function key for ADJUST layer. I also take advantage of the AG_SWAP when using this keyboard on Linux, which swaps between ALT and GUI on both sides.
Mac layer: Mostly the same as the default layer, except that the ESC key maps to a MacOS specific set of MOVE layer shortcuts. These leverage a piece of software called Rectangle, which makes up for some of the tiling shortcomings of MacOS.
### MOVE layer
OS-specific convenience shortcuts. Macros are defined to make it easier to adapt these to other operating systems. The macros also help maintain the spacing that helps with the readability of the layers in source control.
The main goal of the MOVE layer is to manage window move and resize, and jump to a specific virtual desktop. The other function is to expose VIM-style move keys as arrow keys to other applications. Some keys from ADJUST layer are also redefined here.
Care was taken to keep the tiling and virtual desktop shortcuts as similar as possible between Linux and MacOS in this MOVE layer. The most notable difference is that I haven't found a good way to do corner tiling in Linux the way that it's supported in MacOS Rectangle.
REMINDER: The 9-key left-hand pattern requires the installation of the MacOS rectangle app:
```bash
brew cask install rectangle
```
### ADJUST layer
Access to function keys as well as media controls and keyboard settings. Some useful OS action keys are defined here as well.
### Config layer
Access to Quantum keyboard controls as well as RGB configuration. If audio is supported it would belong in this layer as well.

View File

@ -1,49 +0,0 @@
/*
Copyright 2020 Dan White <opensource@bluetufa.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "badger.h"
bool _capsLockState;
__attribute__ ((weak))
void keyboard_post_init_user(void) {
_capsLockState = false;
}
__attribute__ ((weak))
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case CS_RIGHT:
if (record->event.pressed) {
SEND_STRING(SS_LALT(SS_TAP(X_B)SS_TAP(X_ENTER)));
return false;
}
break;
case CS_DOWN:
if (record->event.pressed) {
SEND_STRING(SS_LALT(SS_TAP(X_V)SS_TAP(X_ENTER)));
return false;
}
break;
case KC_CAPS:
if (record->event.pressed) {
_capsLockState = !_capsLockState;
return true;
}
break;
default:
return true;
}
return true;
}

View File

@ -1,109 +0,0 @@
/*
Copyright 2020 Dan White <opensource@bluetufa.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include QMK_KEYBOARD_H
enum layers {
_QWERTY_MAC,
_MOVE_MAC,
_QWERTY_LINUX,
_MOVE_LINUX,
_ADJUST,
_CONFIG
};
enum CustomKeys {
CS_RIGHT = SAFE_RANGE,
CS_DOWN
};
#define OS_POP LCTL(KC_F10)
#define MAC_POP LCTL(KC_UP)
#define MAC_FRC LGUI(LALT(KC_ESC))
#define OS_COPY LSFT(LCTL(KC_C))
#define OS_PAST LSFT(LCTL(KC_V))
#define MAC_PST LGUI(KC_V)
#define MAC_CPY LGUI(KC_C)
#define KC_BACK LCTL(LSFT(KC_LBRC))
#define KC_NEXT LCTL(LSFT(KC_RBRC))
#define MOVE LT(_MOVE_LINUX, KC_ESC)
#define MOVE_MAC LT(_MOVE_MAC, KC_ESC)
#define ADJUST MO(_ADJUST)
#define CFG_MAC LT(_CONFIG, MAC_POP)
#define CFG_LNX LT(_CONFIG, OS_POP)
#define WD_BACK LALT(KC_LEFT)
#define WD_FRWD LALT(KC_RIGHT)
#define VD_1 LCTL(KC_F1)
#define VD_2 LCTL(KC_F2)
#define VD_3 LCTL(KC_F3)
#define WM_UH LGUI(KC_UP)
#define WM_BH LGUI(KC_DOWN)
#define WM_LH LGUI(KC_LEFT)
#define WM_RH LGUI(KC_RIGHT)
#define WM_MAX LGUI(KC_PGUP)
#define CM_RIGHT LGUI(KC_D)
#define CM_DOWN LGUI(LSFT(KC_D))
/* THESE are not defaults in KDE and must be set manually */
#define WM_VD1 HYPR(KC_1)
#define WM_VD2 HYPR(KC_2)
#define WM_VD3 HYPR(KC_3)
/* IntelliJ / JetBrains shortcuts with Mac keymap */
#define IJ_BACK LGUI(LALT(KC_LEFT))
#define IJ_FWD LGUI(LALT(KC_RIGHT))
#define IJ_UP LGUI(LALT(KC_UP))
#define IJ_DOWN LGUI(LALT(KC_DOWN))
#define IJ_IMPL LGUI(LALT(KC_B))
#define IJ_DECL LGUI(KC_B)
#define IJ_REN LSFT(KC_F6)
#define IJ_USAG LALT(KC_F7)
#define IJ_RUN KC_F9
#define IJ_STEP KC_F8
#define IJ_INTO LSFT(KC_F7)
#define IJ_OUT LSFT(KC_F8)
#define IJ_STOP LGUI(KC_F2)
#define IJ_IMPS LCTL(LALT(LSFT(KC_EQUAL)))
#define IJ_IMPH LCTL(LALT(LSFT(KC_MINUS)))
#define IJ_TOP LGUI(KC_HOME)
#define IJ_BOTT LGUI(KC_END)
#define IJ_FIND LGUI(LSFT(KC_F))
/* MacOS virtual desktop shortcuts */
#define M_VD1 LCTL(KC_1)
#define M_VD2 LCTL(KC_2)
#define M_VD3 LCTL(KC_3)
/* rectangle shortcuts */
#define MM_ULCN LCTL(LGUI(KC_LEFT))
#define MM_URCN LCTL(LGUI(KC_RIGHT))
#define MM_LLCN LCTL(LSFT(LGUI(KC_LEFT)))
#define MM_LRCN LCTL(LSFT(LGUI(KC_RIGHT)))
#define MM_MAX LALT(LGUI(KC_F))
#define MM_LH HYPR(KC_LBRC)
#define MM_RH HYPR(KC_RBRC)
#define MM_UH LALT(LGUI(KC_UP))
#define MM_BH LALT(LGUI(KC_DOWN))
#define MM_LEFT LCTL(LALT(LGUI(KC_LEFT)))
#define MM_RGHT LCTL(LALT(LGUI(KC_RIGHT)))
#define DF_1 DF(_QWERTY_MAC)
#define DF_2 DF(_QWERTY_LINUX)

View File

@ -1,151 +0,0 @@
/*
Copyright 2020 Dan White <opensource@bluetufa.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ortho.h"
#include "badger.h"
int _currentLayer;
bool _capsLock;
#ifdef AUDIO_ENABLE
float capsOnSong[][2] = SONG(CAPS_ON);
float capsOffSong[][2] = SONG(CAPS_OFF);
float defaultLayerSong[][2] = SONG(QWERTY_LAYER_SONG);
float moveLayerSong[][2] = SONG(MOVE_LAYER_SONG);
float macLayerSong[][2] = SONG(MAC_LAYER_SONG);
float raiseLayerSong[][2] = SONG(RAISE_LAYER_SONG);
float lowerLayerSong[][2] = SONG(LOWER_LAYER_SONG);
float agSwapSong[][2] = SONG(LONG_AG_SWAP);
float agNormSong[][2] = SONG(LONG_AG_NORM);
#endif
__attribute__ ((weak))
void keyboard_post_init_user(void) {
_capsLock = false;
_currentLayer = _QWERTY_MAC_ORTHO;
layer_on(_currentLayer);
}
__attribute__ ((weak))
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
dprintf("Key event recorded. KEYCODE: %u , event: %u\n", keycode, record->event.pressed);
switch (keycode) {
case CS_RIGHT:
if (record->event.pressed) {
SEND_STRING(SS_LALT(SS_TAP(X_B)SS_TAP(X_ENTER)));
return false;
}
break;
case CS_DOWN:
if (record->event.pressed) {
SEND_STRING(SS_LALT(SS_TAP(X_V)SS_TAP(X_ENTER)));
return false;
}
break;
case KC_CAPS:
if (record->event.pressed) {
dprintf("CAPS_LOCK state: %u\n", _capsLock);
_capsLock = !_capsLock;
#ifdef AUDIO_ENABLE
_capsLock ? PLAY_SONG(capsOnSong) : PLAY_SONG(capsOffSong);
#endif
return true;
}
break;
case AG_SWAP:
#ifdef AUDIO_ENABLE
PLAY_SONG(agSwapSong);
#endif
return true;
break;
case AG_NORM:
#ifdef AUDIO_ENABLE
PLAY_SONG(agNormSong);
#endif
return true;
break;
case KC_MAC2:
if (record->event.pressed) {
SEND_STRING("ll\n");
return false;
}
break;
case KC_MAC1:
if (record->event.pressed) {
SEND_STRING("open https://www.reddit.com/r/mechanicalkeyboards\n");
return false;
}
break;
case KC_FIRST:
if (record->event.pressed) {
// don't turn off the QWERTY layer
if (_currentLayer != _QWERTY_MAC_ORTHO) {
layer_off(_currentLayer);
}
_currentLayer = _QWERTY_MAC_ORTHO;
layer_on(_currentLayer);
playSongForLayer(_currentLayer);
return false;
}
break;
case KC_LYRC:
if (record->event.pressed) {
dprintf("LYR CYCLE pressed %u, CURRENT_LAYER: %u\n", keycode, _currentLayer);
// don't turn off the QWERTY layer or the ADJUST layer
if (_currentLayer != _QWERTY_MAC_ORTHO) {
layer_off(_currentLayer);
}
// don't lock the ADJUST layer
// since this key is accessible via the ADJUST
// layer, as it will require tricky state management
if (++_currentLayer == _ADJUST_ORTHO) {
_currentLayer = _QWERTY_MAC_ORTHO;
} else {
layer_on(_currentLayer);
}
playSongForLayer(_currentLayer);
return false;
}
break;
}
return true;
}
void playSongForLayer(int currentLayer) {
#ifdef AUDIO_ENABLE
switch (currentLayer) {
case _QWERTY_LINUX:
PLAY_SONG(defaultLayerSong);
break;
case _MOVE_LINUX:
PLAY_SONG(moveLayerSong);
break;
case _QWERTY_MAC:
PLAY_SONG(macLayerSong);
break;
case _MOVE_MAC:
PLAY_SONG(moveLayerSong);
break;
case _RAISE:
PLAY_SONG(raiseLayerSong);
break;
case _LOWER:
PLAY_SONG(lowerLayerSong);
break;
default:
break;
}
#endif
}

View File

@ -1,58 +0,0 @@
/*
Copyright 2020 Dan White <opensource@bluetufa.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "badger.h"
enum OrthoLayers {
_QWERTY_MAC_ORTHO,
_MOVE_MAC_ORTHO,
_QWERTY_LINUX_ORTHO,
_MOVE_LINUX_ORTHO,
_RAISE,
_LOWER,
_ADJUST_ORTHO
};
enum OrthoKeys {
KC_MAC1 = CS_DOWN + 1,
KC_MAC2,
KC_LYRC,
KC_FIRST
};
#define P_ADJ LT(_ADJUST_ORTHO, KC_BSPC)
#define RAISE MO(_RAISE)
#define LOWER MO(_LOWER)
#define MOMAC LT(_MOVE_MAC_ORTHO, KC_ESC)
#define MOLNX LT(_MOVE_LINUX_ORTHO, KC_ESC)
void playSongForLayer(int currentLayer);
#ifdef AUDIO_ENABLE
#define QWERTY_LAYER_SONG H__NOTE(_G6), H__NOTE(_D6), Q__NOTE(_A5), Q__NOTE(_E5),
#define MAC_LAYER_SONG H__NOTE(_E5), H__NOTE(_A5), Q__NOTE(_D6), Q__NOTE(_G6), \
ED_NOTE(_E7), E__NOTE(_CS7), E__NOTE(_E6), E__NOTE(_A6), M__NOTE(_CS7, 20),
#define LONG_AG_SWAP Q__NOTE(_G5), Q__NOTE(_D6), Q__NOTE(_A6), Q__NOTE(_E7), \
SD_NOTE(_B5), SD_NOTE(_A5), SD_NOTE(_B5), SD_NOTE(_A5),
#define LONG_AG_NORM Q__NOTE(_DS4), Q__NOTE(_DS4), B__NOTE(_C5),
#define MOVE_LAYER_SONG E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_E7), \
S__NOTE(_REST), ED_NOTE(_GS7),
#define RAISE_LAYER_SONG W__NOTE(_BF5), Q__NOTE(_A5), W__NOTE(_BF5), Q__NOTE(_A5), W__NOTE(_E6), Q__NOTE(_B5),
#define LOWER_LAYER_SONG Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS6), Q__NOTE(_DS5), \
E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_E5), E__NOTE(_E5), E__NOTE(_DS6), Q__NOTE(_DS5),
#define CAPS_ON W__NOTE(_E5), Q__NOTE(_BF5), W__NOTE(_E5), Q__NOTE(_BF5), W__NOTE(_E5), Q__NOTE(_BF5),
#define CAPS_OFF W__NOTE(_E5), Q__NOTE(_BF5),
#endif

View File

@ -1,2 +0,0 @@
SRC += badger.c
SRC += ortho.c

View File

@ -1,61 +0,0 @@
/* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bcat.h"
#include "quantum.h"
static int8_t alt_tab_layer = -1;
__attribute__((weak)) void process_record_oled(uint16_t keycode, const keyrecord_t *record) {}
__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
process_record_oled(keycode, record);
if (!process_record_keymap(keycode, record)) {
return false;
}
switch (keycode) {
/* Alt+Tab that holds Alt until current layer is released: */
case MC_ALTT:
if (record->event.pressed) {
if (alt_tab_layer < 0) {
alt_tab_layer = layer_switch_get_layer(record->event.key);
register_code(KC_LALT);
}
register_code(KC_TAB);
} else {
unregister_code(KC_TAB);
}
return false;
default:
return true;
}
}
__attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state) { return state; }
layer_state_t layer_state_set_user(layer_state_t state) {
state = layer_state_set_keymap(state);
#if defined(BCAT_ORTHO_LAYERS)
state = update_tri_layer_state(state, LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST);
#endif
if (alt_tab_layer >= 0 && !layer_state_cmp(state, alt_tab_layer)) {
unregister_code(KC_LALT);
alt_tab_layer = -1;
}
return state;
}

View File

@ -1,58 +0,0 @@
/* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdbool.h>
#include "quantum_keycodes.h"
/* Layer numbers shared across keymaps. */
enum user_layer {
/* Base layers: */
LAYER_DEFAULT,
#if defined(BCAT_ORTHO_LAYERS)
/* Function layers for ortho (and ergo) boards: */
LAYER_LOWER,
LAYER_RAISE,
LAYER_ADJUST,
#else
/* Function layers for traditional boards: */
LAYER_FUNCTION_1,
LAYER_FUNCTION_2,
#endif
};
/* Custom keycodes shared across keymaps. */
enum user_keycode {
MC_ALTT = SAFE_RANGE,
KEYMAP_SAFE_RANGE,
};
/* Keycode aliases shared across keymaps. */
#define KY_CSPC LCTL(KC_SPC)
#define KY_ZMIN LCTL(KC_EQL)
#define KY_ZMOUT LCTL(KC_MINS)
#define KY_ZMRST LCTL(KC_0)
#if defined(BCAT_ORTHO_LAYERS)
# define LY_LWR MO(LAYER_LOWER)
# define LY_RSE MO(LAYER_RAISE)
#else
# define LY_FN1 MO(LAYER_FUNCTION_1)
# define LY_FN2 MO(LAYER_FUNCTION_2)
#endif

View File

@ -1,216 +0,0 @@
/* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bcat_oled.h"
#include "quantum.h"
#include "bcat.h"
#if defined(BCAT_OLED_PET)
# include "bcat_oled_pet.h"
#endif
#define TRIANGLE_UP 0x1e
#define TRIANGLE_DOWN 0x1f
#if defined(BCAT_OLED_PET)
static bool oled_pet_should_jump = false;
#endif
/* Should be overridden by the keymap to render the OLED contents. For split
* keyboards, this function is only called on the master side.
*/
__attribute__((weak)) void oled_task_keymap(const oled_keyboard_state_t *keyboard_state) {}
bool oled_task_user(void) {
#if defined(SPLIT_KEYBOARD)
if (is_keyboard_master()) {
#endif
/* Custom OLED timeout implementation that only considers user activity.
* Allows the OLED to turn off in the middle of a continuous animation.
*/
static const uint16_t TIMEOUT_MILLIS = 60000 /* 1 min */;
if (last_input_activity_elapsed() < TIMEOUT_MILLIS) {
if (!is_oled_on()) {
oled_on();
}
oled_keyboard_state_t keyboard_state = {
.mods = get_mods(),
.leds = host_keyboard_led_state(),
.wpm = get_current_wpm(),
};
oled_task_keymap(&keyboard_state);
} else if (is_oled_on()) {
oled_off();
}
#if defined(SPLIT_KEYBOARD)
} else {
/* Display logo embedded at standard location in the OLED font on the
* slave side. By default, this is a "QMK firmware" logo, but many
* keyboards substitute their own logo. Occupies 21x3 character cells.
*
* Since the slave display buffer never changes, we don't need to worry
* about oled_render incorrectly turning the OLED on. Instead, we rely
* on SPLIT_OLED_ENABLE to propagate OLED on/off status from master.
*/
static const char PROGMEM logo[] = {
// clang-format off
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
0x00,
// clang-format on
};
oled_write_P(logo, /*invert=*/false);
}
#endif
return false;
}
void render_oled_layers(void) {
oled_advance_char();
oled_advance_char();
#if defined(BCAT_ORTHO_LAYERS)
oled_write_char(IS_LAYER_ON(LAYER_LOWER) ? TRIANGLE_DOWN : ' ', /*invert=*/false);
oled_advance_char();
oled_write_char(IS_LAYER_ON(LAYER_RAISE) ? TRIANGLE_UP : ' ', /*invert=*/false);
#else
switch (get_highest_layer(layer_state)) {
case LAYER_FUNCTION_1:
oled_write_P(PSTR("FN1"), /*invert=*/false);
break;
case LAYER_FUNCTION_2:
oled_write_P(PSTR("FN2"), /*invert=*/false);
break;
default:
oled_write_P(PSTR(" "), /*invert=*/false);
break;
}
#endif
}
void render_oled_indicators(led_t leds) {
oled_advance_char();
oled_advance_char();
oled_write_P(leds.num_lock ? PSTR("NUM") : PSTR(" "), /*invert=*/false);
oled_advance_char();
oled_advance_char();
oled_write_P(leds.caps_lock ? PSTR("CAP") : PSTR(" "), /*invert=*/false);
oled_advance_char();
oled_advance_char();
oled_write_P(leds.scroll_lock ? PSTR("SCR") : PSTR(" "), /*invert=*/false);
}
void render_oled_wpm(uint8_t wpm) {
static const uint16_t UPDATE_MILLIS = 100;
static uint32_t update_timeout = 0;
if (timer_expired32(timer_read32(), update_timeout)) {
oled_advance_char();
oled_advance_char();
oled_write_P(wpm > 0 ? PSTR("WPM") : PSTR(" "), /*invert=*/false);
if (wpm > 0) {
oled_advance_char();
oled_advance_char();
oled_write(get_u8_str(wpm, ' '), /*invert=*/false);
} else {
oled_advance_page(/*clearPageRemainder=*/true);
}
update_timeout = timer_read32() + UPDATE_MILLIS;
}
}
#if defined(BCAT_OLED_PET)
void process_record_oled(uint16_t keycode, const keyrecord_t *record) {
switch (keycode) {
case KC_SPACE:
if (oled_pet_can_jump()) {
oled_pet_should_jump = record->event.pressed;
}
break;
default:
break;
}
}
static void redraw_oled_pet(uint8_t col, uint8_t line, bool jumping, oled_pet_state_t state) {
oled_set_cursor(col, line);
if (jumping) {
oled_write_raw_P(oled_pet_frame(state), oled_pet_frame_bytes());
oled_set_cursor(col, line + oled_pet_frame_lines());
oled_advance_page(/*clearPageRemainder=*/true);
} else {
oled_advance_page(/*clearPageRemainder=*/true);
oled_write_raw_P(oled_pet_frame(state), oled_pet_frame_bytes());
}
}
void render_oled_pet(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state) {
/* Current animation to draw. We track changes to avoid redrawing the same
* frame repeatedly, allowing oled_pet_post_render to draw over the
* animation frame.
*/
static oled_pet_state_t state = 0;
static bool state_changed = true;
/* Minimum time until the pet comes down after jumping. */
static const uint16_t JUMP_MILLIS = 200;
static bool jumping = false;
/* Time until the next animation or jump state change. */
static uint32_t update_timeout = 0;
static uint32_t jump_timeout = 0;
/* If the user pressed the jump key, immediately redraw instead of waiting
* for the animation frame to update. That way, the pet appears to respond
* to jump commands quickly rather than lagging. If the user released the
* jump key, wait for the jump timeout to avoid overly brief jumps.
*/
bool redraw = state_changed;
if (oled_pet_should_jump && !jumping) {
redraw = true;
jumping = true;
jump_timeout = timer_read32() + JUMP_MILLIS;
} else if (!oled_pet_should_jump && jumping && timer_expired32(timer_read32(), jump_timeout)) {
redraw = true;
jumping = false;
}
/* Draw the actual animation, then move the cursor to the end of the
* rendered area. (Note that we take up an extra line to account for
* jumping, which shifts the animation up or down a line.)
*/
if (redraw) {
redraw_oled_pet(col, line, jumping, state);
}
oled_pet_post_render(col, line + !jumping, keyboard_state, redraw);
oled_set_cursor(col, line + oled_pet_frame_lines() + 1);
/* If the update timer expired, recompute the pet's animation state. */
if (timer_expired32(timer_read32(), update_timeout)) {
oled_pet_state_t new_state = oled_pet_next_state(state, keyboard_state);
state_changed = new_state != state;
state = new_state;
update_timeout = timer_read32() + oled_pet_update_millis(keyboard_state);
} else {
state_changed = false;
}
}
#endif

View File

@ -1,55 +0,0 @@
/* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "led.h"
/* Keyboard status passed to the oled_task_keymap function and used by the
* various keyboard pet implementations.
*/
typedef struct {
uint8_t mods;
led_t leds;
uint8_t wpm;
} oled_keyboard_state_t;
/* Note: Functions below assume a vertical OLED that is 32px (5 chars) wide. */
/* Renders layer status at the cursor. Occupies 5x1 character cells. */
void render_oled_layers(void);
/* Renders LED indicators (Num/Caps/Scroll Lock) at the cursor. Occupies 5x3
* character cells.
*/
void render_oled_indicators(led_t leds);
/* Renders calculated WPM count at the cursor. Occupies 5x2 character cells. */
void render_oled_wpm(uint8_t wpm);
#if defined(BCAT_OLED_PET)
/* Renders an animated critter at the cursor that can respond to keystrokes,
* typing speed, etc. Should be about 5 character cells wide, but exact height
* varies depending on the specific OLED pet implementation linked in.
*
* The rendered image will be one line taller than the OLED pet's animation
* frame height to accommodate pets that "jump" when the spacebar is pressed.
*/
void render_oled_pet(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state);
#endif

View File

@ -1,73 +0,0 @@
/* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Common interface for an OLED pet (animated critter that reacts to typing).
* Please link exactly one accompanying .c file to implement these functions.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "bcat_oled.h"
/* Opaque token representing a single frame of the OLED pet animation.
* Different pet implementations have different valid state values, but the
* zero value must always represent the default state of the pet at startup.
*/
typedef uint16_t oled_pet_state_t;
/* Returns the number of bytes used to represent the animation frame (in
* oled_write_raw_P format). Note that every state the pet supports is expected
* to have the same frame size.
*/
uint16_t oled_pet_frame_bytes(void);
/* Returns the number of lines of the OLED occupied by the animation. Note that
* every state the pet supports is expected to have the same frame size. The
* returned value does not include the one line of padding that render_oled_pet
* uses to account for "jumping".
*/
uint8_t oled_pet_frame_lines(void);
/* Returns whether or not the OLED pet should "jump" when the spacebar is
* pressed. (The render_oled_pet implementation shifts the animation frame up
* one line when this happens.)
*/
bool oled_pet_can_jump(void);
/* Returns the delay before the next animation frame should be displayed. */
uint16_t oled_pet_update_millis(const oled_keyboard_state_t *keyboard_state);
/* Returns the state of the pet to be animated on the next animation tick. */
oled_pet_state_t oled_pet_next_state(oled_pet_state_t state, const oled_keyboard_state_t *keyboard_state);
/* Called after the OLED pet is rendered during each OLED task invocation.
* Receives the same keyboard state as render_oled_pet. The redraw param
* indicates whether or not an OLED frame was just redrawn, allowing a specific
* pet implementation to draw custom things atop its animation frames.
*
* When this function is called, the cursor will be in an unspecified location,
* not necessarily the top-left corner of the OLED pet.
*/
void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool redraw);
/* Returns a PROGMEM pointer to the specified frame buffer for the specified
* state. The animation frame has length given by oled_pet_frame_bytes and is
* formatted as expected by oled_write_raw_P.
*/
const char *oled_pet_frame(oled_pet_state_t state);

View File

@ -1,134 +0,0 @@
/* Copyright 2018 sparrow666
* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* OLED pet "Isda" (animated unicorn) featuring artwork by OpenGameArt user
* sparrow666, licensed under GPL v2.0.
*
* The animation is 32x72 pixels (9 lines tall).
*
* Runs faster the quicker you type. Shows LED indicator (Num/Caps/Scroll Lock)
* status in the bottom-right corner.
*
* Named after the goddess Ehlonna's personal unicorn in the first D&D campaign
* I ever played. :)
*
* Artwork source: https://opengameart.org/content/unicorn-2
*/
#include "bcat_oled_pet.h"
#include <stdbool.h>
#include <stdint.h>
#include "bcat_oled.h"
#include "led.h"
#include "oled_driver.h"
#include "progmem.h"
#define NUM_FRAMES 4
#define FRAME_BYTES 288 /* (32 pixel) * (72 pixel) / (8 pixel/byte) */
uint16_t oled_pet_frame_bytes(void) { return FRAME_BYTES; }
uint8_t oled_pet_frame_lines(void) { return 9 /* (72 pixel) / (8 pixel/line) */; }
bool oled_pet_can_jump(void) { return false; }
uint16_t oled_pet_update_millis(const oled_keyboard_state_t *keyboard_state) {
static const uint16_t MIN_MILLIS = 75;
static const uint16_t MAX_MILLIS = 300;
static const uint8_t MAX_WPM = 150;
uint8_t wpm = keyboard_state->wpm;
if (wpm > MAX_WPM) {
wpm = MAX_WPM;
}
return MAX_MILLIS - (MAX_MILLIS - MIN_MILLIS) * wpm / MAX_WPM;
}
oled_pet_state_t oled_pet_next_state(oled_pet_state_t state, const oled_keyboard_state_t *keyboard_state) {
/* When the user stops typing, cycle the animation to frame 0 and stop. */
return state != 0 || keyboard_state->wpm > 0 ? (state + 1) % NUM_FRAMES : 0;
}
void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool redraw) {
/* Draws LED indicator status in the bottom-right corner of the OLED pet,
* atop the animation frame. Redrawn only when necessary, e.g., when LED
* status changes or the animation itself updated (which overwrites any
* previously drawn indicators).
*/
static led_t prev_leds = {.raw = 0};
led_t leds = keyboard_state->leds;
if (redraw || leds.raw != prev_leds.raw) {
oled_set_cursor(col + 4, line + 4);
oled_write_char(leds.num_lock ? 'N' : ' ', /*invert=*/false);
oled_set_cursor(col + 4, line + 6);
oled_write_char(leds.caps_lock ? 'C' : ' ', /*invert=*/false);
oled_set_cursor(col + 4, line + 8);
oled_write_char(leds.scroll_lock ? 'S' : ' ', /*invert=*/false);
prev_leds = leds;
}
}
const char *oled_pet_frame(oled_pet_state_t state) {
static const char PROGMEM FRAMES[NUM_FRAMES][FRAME_BYTES] = {
// clang-format off
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88, 0xd0, 0x78, 0x04, 0x28, 0x70, 0x60, 0x90, 0x88, 0xc4, 0x22, 0x19, 0x04, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x84, 0x8c, 0x08, 0x01, 0x01, 0x02, 0x02, 0x04, 0x88, 0xf0, 0x00,
0xc0, 0xe0, 0xe0, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff, 0xff, 0xff, 0x7f, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfc, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0x3c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x03, 0xc6, 0x3c, 0x00, 0x80, 0x70, 0x1c, 0x0f, 0x03, 0x0f, 0x3f, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0x7f, 0x1f, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x0e, 0x30, 0x40, 0x47, 0x4f, 0x77, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0xa0, 0xf0, 0x08, 0x50, 0xe0, 0xc0, 0x20, 0x10, 0x88, 0x44, 0x32, 0x09, 0x06, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x11, 0x03, 0x02, 0x04, 0x04, 0x08, 0x10, 0xe0, 0x00,
0xc0, 0xe0, 0xe0, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00,
0x00, 0x1f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x03, 0x00, 0x00, 0x80, 0xc0, 0x20, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0x3c, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0xc6, 0x3c, 0x00, 0x80, 0x70, 0x18, 0x0f, 0x03, 0x0f, 0x3f, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x38, 0x07, 0xc0, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x7f, 0xff, 0xff, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x21, 0x20, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x0f, 0x0f, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0xa0, 0xf0, 0x08, 0x50, 0xe0, 0xc0, 0x20, 0x10, 0x88, 0x44, 0x32, 0x09, 0x06, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x11, 0x03, 0x02, 0x04, 0x04, 0x08, 0x10, 0xe0, 0x00,
0xc0, 0xc0, 0xc0, 0x20, 0x20, 0x10, 0x08, 0x04, 0x03, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x00,
0x00, 0x1f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x03, 0x00, 0x00, 0x80, 0xc0, 0x20, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0xc3, 0xfe, 0xfe, 0xfc, 0x7c, 0x1c, 0x0c, 0x0c, 0x08, 0x10, 0x60, 0x83, 0x07, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x71, 0x0e, 0x80, 0x70, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x0f, 0x3f, 0x7f, 0x7f, 0x78, 0xe0, 0x90, 0x88, 0x66, 0x11, 0x08, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x88, 0xd0, 0x78, 0x04, 0x28, 0x70, 0x60, 0x90, 0x88, 0xc4, 0x22, 0x19, 0x04, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x84, 0x8c, 0x08, 0x01, 0x01, 0x02, 0x02, 0x04, 0x88, 0xf0, 0x00,
0xc0, 0xe0, 0xe0, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff, 0xff, 0xff, 0x7f, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xfc, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x03, 0xc6, 0xfc, 0xfc, 0xfc, 0x7c, 0x18, 0x08, 0x08, 0x08, 0x30, 0xc0, 0x03, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc0, 0xf8, 0xff, 0xff, 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x70, 0x80, 0x1f, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3e, 0x3f, 0x3f, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
// clang-format on
};
return FRAMES[state];
}

View File

@ -1,168 +0,0 @@
/* Copyright 2021 HellSingCoder
* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* OLED pet "Luna" (animated doggo) originally by HellSingCoder
* (https://www.simonepellegrino.com/) and licensed under GPL v2.0, adapted to
* fit the OLED pet framework in bcat's userspace.
*
* The animation is 32x24 pixels (3 lines tall).
*
* Walks or runs in response to typing speed. Sneaks when Ctrl is pressed and
* barks when Caps Lock is on. Jumps when space is pressed.
*
* Original source:
* https://github.com/qmk/qmk_firmware/blob/6dfe915e26d7147e6c2bed495d3b01cf5b21e6ec/keyboards/sofle/keymaps/helltm/keymap.c
*/
#include "bcat_oled_pet.h"
#include <stdbool.h>
#include <stdint.h>
#include "bcat_oled.h"
#include "keycode.h"
#include "progmem.h"
enum image {
IMAGE_IDLE,
IMAGE_WALK,
IMAGE_RUN,
IMAGE_SNEAK,
IMAGE_BARK,
};
typedef union {
oled_pet_state_t raw;
struct {
uint8_t image;
uint8_t frame;
};
} luna_state_t;
#define NUM_FRAMES 2
#define FRAME_BYTES 96 /* (32 pixel) * (24 pixel) / (8 pixel/byte) */
uint16_t oled_pet_frame_bytes(void) { return FRAME_BYTES; }
uint8_t oled_pet_frame_lines(void) { return 3 /* (24 pixel) / (8 pixel/line) */; }
bool oled_pet_can_jump(void) { return true; }
uint16_t oled_pet_update_millis(const oled_keyboard_state_t *keyboard_state) { return 200; }
oled_pet_state_t oled_pet_next_state(oled_pet_state_t state, const oled_keyboard_state_t *keyboard_state) {
luna_state_t luna_state = {.raw = state};
if (keyboard_state->leds.caps_lock) {
luna_state.image = IMAGE_BARK;
} else if (keyboard_state->mods & MOD_MASK_CTRL) {
luna_state.image = IMAGE_SNEAK;
} else if (keyboard_state->wpm >= 100) {
luna_state.image = IMAGE_RUN;
} else if (keyboard_state->wpm >= 25) {
luna_state.image = IMAGE_WALK;
} else {
luna_state.image = IMAGE_IDLE;
}
luna_state.frame = (luna_state.frame + 1) % NUM_FRAMES;
return luna_state.raw;
}
void oled_pet_post_render(uint8_t col, uint8_t line, const oled_keyboard_state_t *keyboard_state, bool redraw) {}
const char *oled_pet_frame(oled_pet_state_t state) {
static const char PROGMEM IDLE_FRAMES[NUM_FRAMES][FRAME_BYTES] = {
// clang-format off
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x02, 0x05, 0x02, 0x24, 0x04, 0x04, 0x02, 0xa9, 0x1e, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x08, 0x68, 0x10, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x82, 0x7c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0c, 0x10, 0x10, 0x20, 0x20, 0x20, 0x28, 0x3e, 0x1c, 0x20, 0x20, 0x3e, 0x0f, 0x11, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1c, 0x02, 0x05, 0x02, 0x24, 0x04, 0x04, 0x02, 0xa9, 0x1e, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x90, 0x08, 0x18, 0x60, 0x10, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x82, 0x7c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0c, 0x10, 0x10, 0x20, 0x20, 0x20, 0x28, 0x3e, 0x1c, 0x20, 0x20, 0x3e, 0x0f, 0x11, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
// clang-format on
};
static const char PROGMEM WALK_FRAMES[NUM_FRAMES][FRAME_BYTES] = {
// clang-format off
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x90, 0x90, 0x90, 0xa0, 0xc0, 0x80, 0x80, 0x80, 0x70, 0x08, 0x14, 0x08, 0x90, 0x10, 0x10, 0x08, 0xa4, 0x78, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0xea, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1c, 0x20, 0x20, 0x3c, 0x0f, 0x11, 0x1f, 0x03, 0x06, 0x18, 0x20, 0x20, 0x3c, 0x0c, 0x12, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x20, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x28, 0x10, 0x20, 0x20, 0x20, 0x10, 0x48, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x20, 0xf8, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x30, 0xd5, 0x20, 0x1f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x30, 0x0c, 0x02, 0x05, 0x09, 0x12, 0x1e, 0x02, 0x1c, 0x14, 0x08, 0x10, 0x20, 0x2c, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
// clang-format on
};
static const char PROGMEM RUN_FRAMES[NUM_FRAMES][FRAME_BYTES] = {
// clang-format off
{
0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x08, 0x08, 0xc8, 0xb0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x3c, 0x14, 0x04, 0x08, 0x90, 0x18, 0x04, 0x08, 0xb0, 0x40, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0xc4, 0xa4, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc8, 0x58, 0x28, 0x2a, 0x10, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x09, 0x04, 0x04, 0x04, 0x04, 0x02, 0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x10, 0x26, 0x2b, 0x32, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0xe0, 0x10, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x78, 0x28, 0x08, 0x10, 0x20, 0x30, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x10, 0x11, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0xb0, 0x50, 0x55, 0x20, 0x1f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x28, 0x37, 0x02, 0x1e, 0x20, 0x20, 0x18, 0x0c, 0x14, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
// clang-format on
};
static const char PROGMEM SNEAK_FRAMES[NUM_FRAMES][FRAME_BYTES] = {
// clang-format off
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x80, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1e, 0x21, 0xf0, 0x04, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x04, 0x04, 0x04, 0x03, 0x01, 0x00, 0x00, 0x09, 0x01, 0x80, 0x80, 0xab, 0x04, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1c, 0x20, 0x20, 0x3c, 0x0f, 0x11, 0x1f, 0x02, 0x06, 0x18, 0x20, 0x20, 0x38, 0x08, 0x10, 0x18, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xa0, 0x20, 0x40, 0x80, 0xc0, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0x41, 0xf0, 0x04, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x40, 0x55, 0x82, 0x7c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x30, 0x0c, 0x02, 0x05, 0x09, 0x12, 0x1e, 0x04, 0x18, 0x10, 0x08, 0x10, 0x20, 0x28, 0x34, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
},
// clang-format on
};
static const char PROGMEM BARK_FRAMES[NUM_FRAMES][FRAME_BYTES] = {
// clang-format off
{
0x00, 0xc0, 0x20, 0x10, 0xd0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x3c, 0x14, 0x04, 0x08, 0x90, 0x18, 0x04, 0x08, 0xb0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x04, 0x08, 0x10, 0x11, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc8, 0x48, 0x28, 0x2a, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x28, 0x37, 0x02, 0x02, 0x04, 0x08, 0x10, 0x26, 0x2b, 0x32, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
{
0x00, 0xe0, 0x10, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x2c, 0x14, 0x04, 0x08, 0x90, 0x18, 0x04, 0x08, 0xb0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x04, 0x08, 0x10, 0x11, 0xf9, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x48, 0x28, 0x2a, 0x10, 0x0f, 0x20, 0x4a, 0x09, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x28, 0x37, 0x02, 0x02, 0x04, 0x08, 0x10, 0x26, 0x2b, 0x32, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
// clang-format on
};
luna_state_t luna_state = {.raw = state};
switch (luna_state.image) {
case IMAGE_WALK:
return WALK_FRAMES[luna_state.frame];
case IMAGE_RUN:
return RUN_FRAMES[luna_state.frame];
case IMAGE_SNEAK:
return SNEAK_FRAMES[luna_state.frame];
case IMAGE_BARK:
return BARK_FRAMES[luna_state.frame];
default:
return IDLE_FRAMES[luna_state.frame];
}
}

View File

@ -1,22 +0,0 @@
/* Copyright 2021 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include "progmem.h"
/* Adjust RGB static hue ranges for shorter gradients than default. */
const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 127, 63, 31, 15};

View File

@ -1,52 +0,0 @@
#!/bin/bash
set -o errexit -o nounset
usage () {
printf "\
usage: ./users/bcat/compile.sh [-c] [-j N]
Compiles all keyboards for which bcat maintains keymaps.
optional arguments:
-c performs a clean build
-j N runs N make tasks in parallel
-v shows verbose output
"
}
compile () {
local keyboard=$1 layout=${2:-}
FORCE_LAYOUT="$layout" SILENT="$opt_silent" make -j "$opt_parallel" "$keyboard":bcat
}
opt_parallel=1
opt_silent=true
while getopts :chj:v opt; do
case $opt in
c) opt_clean=1 ;;
j) opt_parallel=$OPTARG ;;
v) opt_silent=false ;;
h) usage; exit 0 ;;
\?) usage >&2; exit 2 ;;
esac
done
if [[ -n ${opt_clean:-} ]]; then
SILENT="$opt_silent" make clean
fi
compile 9key
compile ai03/polaris 60_tsangan_hhkb
compile cannonkeys/an_c 60_tsangan_hhkb
compile cannonkeys/instant60 60_tsangan_hhkb
compile crkbd/rev1 split_3x6_3
compile dz60 60_ansi_split_bs_rshift
compile dz60 60_tsangan_hhkb
compile eco/rev2
compile kbdfans/kbd67/hotswap 65_ansi_blocker_split_bs
compile keebio/bdn9/rev1
compile keebio/quefrency/rev1
compile lily58/rev1
compile yanghu/unicorne/f411

View File

@ -1,150 +0,0 @@
/* Copyright 2020 Jonathan Rascher
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Enable NKRO by default. All my devices support this, and it enables me to
* dispense with the NK_TOGG key, thus saving firmware space by not compiling
* magic keycode support.
*/
#define FORCE_NKRO
/* Wait between tap_code register and unregister to fix flaky media keys. */
#undef TAP_CODE_DELAY
#define TAP_CODE_DELAY 20
/* Treat mod-tap keys as holds even if the mod-tap key and the key being
* modified are both released within TAPPING_TERM. This assumes the mod-tap key
* isn't usually pressed in quick succession with other tapped keys, which is
* good when the tap keycode is something like KC_ESC rather than a letter.
*/
#define PERMISSIVE_HOLD
/* Turn off key repeat support of the tap keycode for tap-hold keys, enabling
* holds to work correctly in quick succession after taps.
*/
#define QUICK_TAP_TERM 0
#if defined(OLED_ENABLE)
/* The built-in OLED timeout wakes the OLED screen every time the buffer is
* updated, even if no user activity has occurred recently. This prevents the
* OLED from ever turning off during a continuously running animation. To avoid
* this, we disable the default timeout and implement our own in
* oled_task_user.
*/
# undef OLED_TIMEOUT
# define OLED_DISABLE_TIMEOUT
# if defined(SPLIT_KEYBOARD)
/* Sync OLED on/off state between halves of split keyboards. */
# define SPLIT_OLED_ENABLE
# endif
#endif
#if defined(RGB_MATRIX_ENABLE)
/* Turn off per-key RGB when the host goes to sleep. */
# define RGB_DISABLE_WHEN_USB_SUSPENDED
/* Keep per-key RGB increments consistent across keyboards. */
# undef RGB_MATRIX_HUE_STEP
# undef RGB_MATRIX_SAT_STEP
# undef RGB_MATRIX_VAL_STEP
# undef RGB_MATRIX_SPD_STEP
# define RGB_MATRIX_HUE_STEP 8
# define RGB_MATRIX_SAT_STEP 17
# define RGB_MATRIX_VAL_STEP 17
# define RGB_MATRIX_SPD_STEP 17
/* Enable specific per-key animation modes. */
# define ENABLE_RGB_MATRIX_ALPHAS_MODS
# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
# define ENABLE_RGB_MATRIX_BAND_SAT
# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
# define ENABLE_RGB_MATRIX_BAND_VAL
# define ENABLE_RGB_MATRIX_BREATHING
# define ENABLE_RGB_MATRIX_CYCLE_ALL
# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
# define ENABLE_RGB_MATRIX_DUAL_BEACON
# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
# define ENABLE_RGB_MATRIX_HUE_BREATHING
# define ENABLE_RGB_MATRIX_HUE_PENDULUM
# define ENABLE_RGB_MATRIX_HUE_WAVE
# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
# define ENABLE_RGB_MATRIX_PIXEL_RAIN
# define ENABLE_RGB_MATRIX_RAINBOW_BEACON
# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
# define ENABLE_RGB_MATRIX_RAINDROPS
/* Enable additional per-key animation modes that require a copy of the
* framebuffer (with accompanying storage cost).
*/
# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
# define ENABLE_RGB_MATRIX_DIGITAL_RAIN
# define ENABLE_RGB_MATRIX_TYPING_HEATMAP
#endif
#if defined(RGBLIGHT_ENABLE)
/* Turn off RGB underglow when the host goes to sleep. */
# define RGBLIGHT_SLEEP
/* Keep RGB underglow level increments consistent across keyboards. */
# undef RGBLIGHT_HUE_STEP
# undef RGBLIGHT_SAT_STEP
# undef RGBLIGHT_VAL_STEP
# define RGBLIGHT_HUE_STEP 8
# define RGBLIGHT_SAT_STEP 17
# define RGBLIGHT_VAL_STEP 17
/* Enable specific underglow animation modes. (Skip TWINKLE because it seems to
* be broken on ARM: https://github.com/qmk/qmk_firmware/issues/15345.)
*/
# define RGBLIGHT_EFFECT_ALTERNATING
# define RGBLIGHT_EFFECT_BREATHING
# define RGBLIGHT_EFFECT_CHRISTMAS
# define RGBLIGHT_EFFECT_KNIGHT
# define RGBLIGHT_EFFECT_RAINBOW_MOOD
# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
# define RGBLIGHT_EFFECT_RGB_TEST
# define RGBLIGHT_EFFECT_SNAKE
# define RGBLIGHT_EFFECT_STATIC_GRADIENT
#endif
#if defined(BACKLIGHT_ENABLE)
/* Enable backlight breathing across the board. */
# define BACKLIGHT_BREATHING
/* Keep backlight level increments consistent across keyboards. */
# undef BACKLIGHT_LEVELS
# define BACKLIGHT_LEVELS 7
#endif
/* Turn off unused config options to reduce firmware size. */
#define LAYER_STATE_8BIT
#define NO_ACTION_ONESHOT
#undef LOCKING_RESYNC_ENABLE
#undef LOCKING_SUPPORT_ENABLE

View File

@ -1,51 +0,0 @@
# bcat's userspace
This is some code and config shared by all of [my](https://github.com/bcat)
keyboards. I use community layouts wherever possible, only writing
keyboard-specific keymaps for boards without standard layout support. I derive
my keymaps from two canonical ones (preferred for typing and gaming,
respectively).
You can build all keymaps I maintain at once using `./users/bcat/compile.sh`.
## Canonical keymaps
* [Split 3x6 + 3 thumb
keys](https://github.com/qmk/qmk_firmware/tree/master/layouts/community/split_3x6_3/bcat):
Columnar-staggered split ergo layout, preferred for typing. Used on Crkbd.
* [60% Tsangan
HHKB](https://github.com/qmk/qmk_firmware/tree/master/layouts/community/60_tsangan_hhkb/bcat):
Row-staggered layout, preferred for gaming. Used on ai03 Polaris, CannonKeys
AN-C, CannonKeys Instant60, DZ60.
## Other keymaps
### Ergo
* [Lily58](https://github.com/qmk/qmk_firmware/tree/master/keyboards/lily58/keymaps/bcat)
* [Unicorne](https://github.com/qmk/qmk_firmware/tree/master/keyboards/yanghu/unicorne/keymaps/bcat)
### Ortho
* [Eco](https://github.com/qmk/qmk_firmware/tree/master/keyboards/eco/keymaps/bcat)
### Traditional
* [60% ANSI split
backspace/right-shift](https://github.com/qmk/qmk_firmware/tree/master/layouts/community/60_ansi_split_bs_rshift/bcat).
Used on DZ60.
* [65% ANSI blocker split
backspace](https://github.com/qmk/qmk_firmware/tree/master/layouts/community/65_ansi_blocker_split_bs/bcat).
Used on KBDfans KBD67 hotswap.
* [Keebio
Quefrency](https://github.com/qmk/qmk_firmware/tree/master/keyboards/keebio/quefrency/keymaps/bcat)
### Macropads
* [9-Key](https://github.com/qmk/qmk_firmware/tree/master/keyboards/9key/keymaps/bcat)
* [Keebio
BDN9](https://github.com/qmk/qmk_firmware/tree/master/keyboards/keebio/bdn9/keymaps/bcat)

View File

@ -1,68 +0,0 @@
# Enable Bootmagic Lite for keyboards that don't have an easily accessible
# reset button, but keep it disabled for all others to reduce firmware size.
ifneq ($(filter $(strip $(KEYBOARD)),ai03/polaris dz60 kbdfans/kbd67/hotswap yanghu/unicorne/f411),)
BOOTMAGIC_ENABLE = yes
else
BOOTMAGIC_ENABLE = no
endif
# Enable media keys on all keyboards.
EXTRAKEY_ENABLE = yes
# Enable N-key rollover on all keyboards. In addition to its intended
# functionality, as of July 2020, this is required for Chrome OS to process
# media keys. (It appears that Chrome OS filters out key events from the second
# USB endpoint's consumer and system control devices unless that endpoint also
# reports a keyboard or mouse device.)
NKRO_ENABLE = yes
# Enable link-time optimization to reduce binary size.
LTO_ENABLE = yes
# Include common utilities shared across all our keymaps.
SRC += bcat.c
# Include additional utilities that extend optional QMK features only enabled
# on some keyboards.
ifeq ($(strip $(OLED_ENABLE)), yes)
SRC += bcat_oled.c
WPM_ENABLE = yes # for WPM and animated "keyboard pet" widgets
# OLED pets (animated critters that react to typing) take up a lot of
# firmware space, so only compile one, and only if requested.
BCAT_OLED_PET ?= no
ifneq ($(strip $(BCAT_OLED_PET)), no)
SRC += bcat_oled_pet_$(strip $(BCAT_OLED_PET)).c
OPT_DEFS += -DBCAT_OLED_PET
endif
endif
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
SRC += bcat_rgblight.c
endif
# Disable unwanted build options on all keyboards. (Mouse keys are turned off
# due to https://github.com/qmk/qmk_firmware/issues/8323, and the rest are
# turned off to reduce firmware size.)
COMMAND_ENABLE = no
CONSOLE_ENABLE = no
MOUSEKEY_ENABLE = no
# Disable unwanted hardware options on all keyboards. (Some keyboards turn
# these features on by default even though they aren't actually required.)
MIDI_ENABLE = no
SLEEP_LED_ENABLE = no
# Disable other unused options on all keyboards.
AUTO_SHIFT_ENABLE = no
COMBO_ENABLE = no
GRAVE_ESC_ENABLE = no
KEY_LOCK_ENABLE = no
LEADER_ENABLE = no
MAGIC_ENABLE = no
SPACE_CADET_ENABLE = no
SWAP_HANDS_ENABLE = no
TAP_DANCE_ENABLE = no
UCIS_ENABLE = no
UNICODEMAP_ENABLE = no
UNICODE_ENABLE = no

View File

@ -1,32 +0,0 @@
#include "billypython.h"
__attribute__((weak))
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keymap(keycode, record)) {
return false;
}
switch (keycode) {
case CLEAR:
if (record->event.pressed) {
SEND_STRING(SS_LCTL("a") SS_TAP(X_DELETE));
}
return false;
default:
return true;
}
}
__attribute__((weak))
layer_state_t layer_state_set_keymap(layer_state_t state) {
return state;
}
layer_state_t layer_state_set_user(layer_state_t state) {
return layer_state_set_keymap(state);
}

View File

@ -1,34 +0,0 @@
#pragma once
#include "quantum.h"
#ifdef TAP_DANCE_ENABLE
#include "tap_dance.h"
#endif
#ifdef LAYER_FN
#define FN MO(L_FN)
#define FN_CAPS LT(L_FN, KC_CAPS)
#define FN_FNLK TT(L_FN)
#endif
#define TOP LCTL(KC_HOME)
#define BOTTOM LCTL(KC_END)
enum keycodes_user {
CLEAR = SAFE_RANGE,
RANGE_KEYMAP,
};
enum layers_user {
L_BASE,
#ifdef LAYER_FN
L_FN,
#endif
L_RANGE_KEYMAP,
};
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
layer_state_t layer_state_set_keymap(layer_state_t state);

View File

@ -1,17 +0,0 @@
#pragma once
#define FORCE_NKRO
#define MOUSEKEY_DELAY 50
#define MOUSEKEY_INTERVAL 15
#define MOUSEKEY_MAX_SPEED 4
#define MOUSEKEY_TIME_TO_MAX 50
#define MOUSEKEY_WHEEL_MAX_SPEED 1
#define MOUSEKEY_WHEEL_TIME_TO_MAX 50
#define NO_ACTION_FUNCTION
#define NO_ACTION_MACRO
#define PERMISSIVE_HOLD
#define TAPPING_TERM 200
#define TAPPING_TOGGLE 2

View File

@ -1,6 +0,0 @@
SRC += billypython.c
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
SRC += tap_dance.c
endif
EXTRAFLAGS += -flto

View File

@ -1,33 +0,0 @@
#include "tap_dance.h"
#define ACTION_TAP_DANCE_DOUBLE_MODS(mod1, mod2) { \
.fn = { td_double_mods_each, NULL, td_double_mods_reset }, \
.user_data = &(tap_dance_pair_t){ mod1, mod2 }, \
}
void td_double_mods_each(tap_dance_state_t *state, void *user_data) {
tap_dance_pair_t *mods = (tap_dance_pair_t *)user_data;
// Single tap → mod1, double tap → mod2, triple tap etc. → mod1+mod2
if (state->count == 1 || state->count == 3) {
register_code(mods->kc1);
} else if (state->count == 2) {
unregister_code(mods->kc1);
register_code(mods->kc2);
}
// Prevent tap dance from sending kc1 and kc2 as weak mods
state->weak_mods &= ~(MOD_BIT(mods->kc1) | MOD_BIT(mods->kc2));
}
void td_double_mods_reset(tap_dance_state_t *state, void *user_data) {
tap_dance_pair_t *mods = (tap_dance_pair_t *)user_data;
if (state->count == 1 || state->count >= 3) {
unregister_code(mods->kc1);
}
if (state->count >= 2) {
unregister_code(mods->kc2);
}
}
tap_dance_action_t tap_dance_actions[] = {
[TD_RSF_RCT] = ACTION_TAP_DANCE_DOUBLE_MODS(KC_RSFT, KC_RCTL),
};

View File

@ -1,9 +0,0 @@
#pragma once
#include "quantum.h"
#define RSF_RCT TD(TD_RSF_RCT)
enum tap_dance {
TD_RSF_RCT,
};

View File

@ -1,214 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "brandonschlack.h"
user_config_t user_config;
#ifdef STOPLIGHT_LED
static stoplight_led_t stoplight_led;
#endif
/**
* Resets user config in EEPROM
*
* Default is use rgb for layer indication
*/
void eeconfig_init_user(void) {
user_config.raw = 0;
user_config.rgb_layer_change = true;
user_config.rgb_theme = 0;
eeconfig_update_user(user_config.raw);
}
__attribute__((weak))
void matrix_init_keymap(void){ }
void matrix_init_user(void) {
matrix_init_keymap();
}
__attribute__((weak))
void keyboard_post_init_keymap(void){ }
/**
* Reads user config from EEPROM,
* calls RGB init if RGBs enabled
*/
void keyboard_post_init_user(void){
// Read the user config from EEPROM
user_config.raw = eeconfig_read_user();
// Do Stoplight Animation if enabled
#ifdef STOPLIGHT_LED
led_stoplight_start();
#endif
// Do RGB things if RGBs enabled
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
keyboard_post_init_rgb();
#endif
keyboard_post_init_keymap();
}
__attribute__ ((weak))
void shutdown_keymap(void) {}
/**
* On shutdown,
* If RGBs enabled,
* then set RGB color to Red
*/
void shutdown_user (void) {
#ifdef RGBLIGHT_ENABLE
rgblight_enable_noeeprom();
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
rgblight_sethsv_noeeprom(0, 255, 127);
#endif // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
rgb_matrix_set_color_all( 0xFF, 0x00, 0x00 );
#endif //RGB_MATRIX_ENABLE
shutdown_keymap();
}
__attribute__ ((weak))
void suspend_power_down_keymap(void) {}
/**
* Set rgb_matrix suspend state to true if not already
*/
void suspend_power_down_user(void) {
#ifdef RGB_MATRIX_ENABLE
if (!g_suspend_state) {
rgb_matrix_set_suspend_state(true);
}
#endif //RGB_MATRIX_ENABLE
suspend_power_down_keymap();
}
__attribute__ ((weak))
void suspend_wakeup_init_keymap(void) {}
/**
* Set rgb_matrix suspend state to false if not already
*/
void suspend_wakeup_init_user(void) {
#ifdef RGB_MATRIX_ENABLE
if (g_suspend_state) {
rgb_matrix_set_suspend_state(false);
}
#endif //RGB_MATRIX_ENABLE
suspend_wakeup_init_keymap();
}
__attribute__ ((weak))
void matrix_scan_keymap(void) {}
/**
* Checks for Super CMDTAB
*/
void matrix_scan_user(void) {
matrix_scan_cmd_tab();
#ifdef STOPLIGHT_LED
matrix_scan_led_stoplight();
#endif
matrix_scan_keymap();
}
__attribute__ ((weak))
layer_state_t default_layer_state_set_keymap(layer_state_t state) {
return state;
}
/**
* For macropads, if a new default layer is set from DF()
* then automatically set that layer with layer_move()
*/
layer_state_t default_layer_state_set_user(layer_state_t state) {
#if defined(IS_MACROPAD)
layer_move(get_highest_layer(state));
#endif
return default_layer_state_set_keymap(state);
}
__attribute__ ((weak))
layer_state_t layer_state_set_keymap(layer_state_t state) {
return state;
}
/**
* Do RGB things (like layer indication) on layer change
*/
layer_state_t layer_state_set_user(layer_state_t state) {
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
state = layer_state_set_rgb(state);
#endif // RGBLIGHT_ENABLE
return layer_state_set_keymap(state);
}
__attribute__((weak)) bool led_update_keymap(led_t led_state) { return true; }
bool led_update_user(led_t led_state) {
#ifdef STOPLIGHT_LED
if (stoplight_led.is_active) {
return false;
}
#endif
return led_update_keymap(led_state);
}
#ifdef STOPLIGHT_LED
void led_stoplight_start(void) {
writePin(TOP_LED, LED_ON(false));
writePin(MIDDLE_LED, LED_ON(false));
writePin(BOTTOM_LED, LED_ON(false));
stoplight_led.is_active = true;
stoplight_led.timer = timer_read();
};
void led_stoplight_set(pin_t pin) {
writePin(pin, LED_ON(true));
};
void led_stoplight_end(void) {
// Reset timer and status variables
stoplight_led.is_active = false;
stoplight_led.index = 0;
stoplight_led.timer = 0;
led_update_kb(host_keyboard_led_state());
};
void matrix_scan_led_stoplight(void) {
if (stoplight_led.is_active) {
if (timer_elapsed(stoplight_led.timer) > (1000 * (stoplight_led.index + 1))) {
switch (stoplight_led.index){
case 0:
led_stoplight_set(TOP_LED);
stoplight_led.index++;
break;
case 1:
led_stoplight_set(MIDDLE_LED);
stoplight_led.index++;
break;
case 2:
led_stoplight_set(BOTTOM_LED);
stoplight_led.index++;
break;
default:
led_stoplight_end();
break;
}
}
}
};
#endif

View File

@ -1,84 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
#include "version.h"
#include "eeprom.h"
#include "process_records.h"
#ifdef TAP_DANCE_ENABLE
# include "tap_dances.h"
#endif // TAP_DANCE_ENABLE
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
# include "rgb_bs.h"
#endif
/* TODO Layer Names */
enum bs_layers {
_BASE = 0,
_M1 = 1,
_M2 = 2,
_M3 = 3,
_M4 = 4,
_FN1 = 5,
_M1_FN1 = 6,
_M2_FN1 = 7,
_M3_FN1 = 8,
_M4_FN1 = 9,
_FN2 = 10,
_M1_FN2 = 11,
_M2_FN2 = 12,
_M3_FN2 = 13,
_M4_FN2 = 14,
_ADJUST = 15 // 15: Change keyboard settings
};
#define _MACRO _M1
#define _LOWER _FN1
#define _RAISE _FN2
/* TODO User EECONFIG */
typedef union {
uint32_t raw;
struct {
bool rgb_layer_change :1;
uint8_t rgb_theme :4;
};
} user_config_t;
extern user_config_t user_config;
void matrix_init_keymap(void);
void keyboard_post_init_keymap(void);
void shutdown_keymap(void);
void suspend_power_down_keymap(void);
void suspend_wakeup_init_keymap(void);
void matrix_scan_keymap(void);
layer_state_t default_layer_state_set_keymap(layer_state_t state);
layer_state_t layer_state_set_keymap(layer_state_t state);
bool led_update_keymap(led_t led_state);
#ifdef STOPLIGHT_LED
typedef struct {
bool is_active :1;
uint8_t index :7;
uint16_t timer :16;
} stoplight_led_t;
void led_stoplight_start(void);
void led_stoplight_set(pin_t pin);
void led_stoplight_end(void);
void matrix_scan_led_stoplight(void);
#endif

View File

@ -1,55 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define TAPPING_TOGGLE 2
#define TAPPING_TERM 200
#define PERMISSIVE_HOLD
#define TAP_HOLD_CAPS_DELAY 200
#ifdef RGBLIGHT_ENABLE
# define RGBLIGHT_SLEEP
#endif
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) && !defined(RGBLIGHT_LAYERS)
# define RGB_THEME_ENABLE
#endif
#ifdef RGB_THEME_ENABLE
# define DISABLE_RGB_THEME_JAMON
# define DISABLE_RGB_THEME_OBLIQUE
#endif
#ifdef ENCODER_ENABLE
# define TAP_CODE_DELAY 10
#else
# define TAP_CODE_DELAY 5
#endif
/* Disable unused and unneeded features to reduce on firmware size */
#ifndef NO_ACTION_MACRO
# define NO_ACTION_MACRO
#endif
#ifndef NO_ACTION_FUNCTION
# define NO_ACTION_FUNCTION
#endif
#ifdef LOCKING_SUPPORT_ENABLE
# undef LOCKING_SUPPORT_ENABLE
#endif
#ifdef LOCKING_RESYNC_ENABLE
# undef LOCKING_RESYNC_ENABLE
#endif

View File

@ -1,172 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "brandonschlack.h"
// Super CMD↯TAB
bool is_cmd_tab_active = false;
uint16_t cmd_tab_timer = 0;
__attribute__ ((weak))
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
// Consolidated Macros
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QM_MAKE: // Sends 'qmk compile' or 'qmk flash'
if (record->event.pressed) {
bool flash = false;
// If is a keyboard and auto-flash is not set in rules.mk,
// then Shift will trigger the flash command
#if !defined(FLASH_BOOTLOADER) && !defined(IS_MACROPAD)
uint8_t temp_mod = get_mods();
uint8_t temp_osm = get_oneshot_mods();
clear_mods();
clear_oneshot_mods();
if ( (temp_mod | temp_osm) & MOD_MASK_SHIFT )
#endif
{
flash = true;
}
send_make_command(flash);
}
break;
case QM_FLSH: // Sends flash command instead of compile
if (record->event.pressed) {
clear_mods();
clear_oneshot_mods();
send_make_command(true);
}
break;
case QM_VRSN: // Prints firmware version
if (record->event.pressed) {
SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE);
}
break;
case QM_KYBD: // Prints keyboard path
if (record->event.pressed) {
SEND_STRING("keyboards/" QMK_KEYBOARD "/");
}
break;
case QM_KYMP: // Prints keymap path
if (record->event.pressed) {
SEND_STRING("keyboards/" QMK_KEYBOARD "/keymaps/" QMK_KEYMAP "/keymap.c");
}
break;
case CMD_TAB: // Super CMD↯TAB
if (record->event.pressed) {
if (!is_cmd_tab_active) {
is_cmd_tab_active = true;
register_code(KC_LGUI);
}
cmd_tab_timer = timer_read();
register_code(KC_TAB);
} else {
unregister_code(KC_TAB);
}
break;
#if defined(RGB_THEME_ENABLE)
case RGB_LYR:
if (record->event.pressed) {
user_config.rgb_layer_change ^= 1;
dprintf("rgb layer change [EEPROM]: %u\n", user_config.rgb_layer_change);
eeconfig_update_user(user_config.raw);
if (user_config.rgb_layer_change) {
layer_state_set(layer_state);
}
}
break;
case RGB_HUI ... RGB_SAD:
if (record->event.pressed) {
if (user_config.rgb_layer_change) {
user_config.rgb_layer_change = false;
dprintf("rgb layer change [EEPROM]: %u\n", user_config.rgb_layer_change);
eeconfig_update_user(user_config.raw);
}
}
break;
case RGB_THEME_FORWARD:
if (record->event.pressed) {
uint8_t shifted = get_mods() & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT));
if(shifted) {
rgb_theme_step_reverse();
} else {
rgb_theme_step();
}
layer_state_set(layer_state);
}
break;
case RGB_THEME_REVERSE:
if (record->event.pressed) {
uint8_t shifted = get_mods() & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT));
if(shifted) {
rgb_theme_step();
} else {
rgb_theme_step_reverse();
}
layer_state_set(layer_state);
}
break;
#endif
}
return process_record_keymap(keycode, record);
}
// Super CMD↯TAB
void matrix_scan_cmd_tab(void) {
if (is_cmd_tab_active) {
if (timer_elapsed(cmd_tab_timer) > 500) {
unregister_code(KC_LGUI);
is_cmd_tab_active = false;
}
}
}
/**
* Send Make Command
*
* Sends 'qmk compile -kb keyboard -km keymap' command to compile firmware
* Uses 'qmk flash' and resets keyboard, if flash_bootloader set to true
* Sends CONVERT_TO and/or FORCE_LAYOUT parameters if built with those options
*/
void send_make_command(bool flash_bootloader) {
#ifdef FORCE_LAYOUT // Add layout string if built with FORCE_LAYOUT
SEND_STRING("FORCE_LAYOUT=" FORCE_LAYOUT " ");
#endif
#ifdef CONVERT_TO_PROTON_C // Add CONVERT_TO if built with converter
SEND_STRING("CONVERT_TO=proton_c ");
#endif
SEND_STRING("qmk ");
if (flash_bootloader) {
#ifndef KEYBOARD_massdrop // Don't run flash for Massdrop boards
SEND_STRING("flash ");
} else {
#endif
SEND_STRING("compile ");
}
SEND_STRING("-kb " QMK_KEYBOARD " ");
SEND_STRING("-km " QMK_KEYMAP);
if (flash_bootloader) {
#if defined(KEYBOARD_massdrop) // only run for Massdrop boards
SEND_STRING(" && mdlflash " QMK_KEYBOARD " " QMK_KEYMAP);
#endif
}
SEND_STRING(SS_TAP(X_ENTER));
if (flash_bootloader) {
reset_keyboard();
}
}

View File

@ -1,152 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "brandonschlack.h"
// Macros
enum custom_keycodes {
QM_MAKE = SAFE_RANGE,
QM_FLSH,
QM_VRSN,
QM_KYBD,
QM_KYMP,
CMD_TAB,
RGB_LYR,
RGB_THEME_FORWARD,
RGB_THEME_REVERSE,
KEYMAP_SAFE_RANGE
};
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
void matrix_scan_cmd_tab(void);
/**
* QMK Defines
* Some meta aliases for QMK features such as Mod-Taps
* and for cleaner looking Layer Toggles
*/
/* Control Mod-Tap */
#define CTL_ESC CTL_T(KC_ESC) // Hold Escape for Control
#define CTL_TAB CTL_T(KC_TAB) // Hold Tab for Control
#define CTL_CAP CTL_T(KC_CAPS) // Hold Caps Lock for Control
/* Command Mod-Tap */
#define CMD_ESC CMD_T(KC_ESC) // Hold Escape for Command
#define CMD_CAP CMD_T(KC_CAPS) // Hold Caps Lock for Command
#define CMD_SPC CMD_T(KC_SPC) // Hold Space for Command
/* Hyper Mod-Tap */
#define HY_ESC ALL_T(KC_ESC) // Hold Escape for Hyper (Shift-Control-Option-Command)
#define HY_TAB ALL_T(KC_TAB) // Hold Tab for Hyper (Shift-Control-Option-Command)
#define HY_CAPS ALL_T(KC_CAPS) // Hold Caps Lock for Hyper (Shift-Control-Option-Command)
/* Shift Mod-Tap */
#define SF_CAPS LSFT_T(KC_CAPS) // Hold Caps Lock for Left Shift
#define SFT_ENT RSFT_T(KC_ENT) // Hold Enter for Right Shift
#define SF_SLSH RSFT_T(KC_SLSH) // Tap Right Shift for Slash (/)
#define SF_BSLS RSFT_T(KC_BSLS) // Tap Right Shift for Back Slash (\)
/* Layer Aliases */
#define FN_LYR MO(_FN1) // Hold for FN Layer
#define FN2_LYR MO(_FN2) // Hold for FN2 Layer
#define LOWER MO(_LOWER) // Hold for LOWER Layer
#define RAISE MO(_RAISE) // Hold for RAISE Layer
#define TT_FN TT(_FN1) // Hold for FN Layer, or Double-Tap to Toggle
#define TT_FN2 TT(_FN2) // Hold for FN2 Layer, or Double-Tap to Toggle
#define TT_LWR TT(_LOWER) // Hold for LOWER Layer, or Double-Tap to Toggle
#define TT_RAI TT(_RAISE) // Hold for RAISE Layer, or Double-Tap to Toggle
#define SPC_LWR LT(_LOWER, KC_SPC) // Tap for Space, Hold for LOWER Layer
#define SPC_RAI LT(_RAISE, KC_SPC) // Tap for Space, Hold for RAISE Layer
#define SLH_LWR LT(_LOWER, KC_SLSH) // Tap for /, Hold for LOWER Layer
#define BSL_LWR LT(_LOWER, KC_BSLS) // Tap for \, Hold for LOWER Layer
#define MCO_LYR MO(_MACRO) // Hold for MACRO Layer
#define TG_ADJT TG(_ADJUST) // Toggle ADJUST Layer
#define TG_LGHT TG(_LIGHT) // Toggle LIGHT Layer
/**
* Media Mod-Tap
* Use the Mod-Tap feature for easy media controls
* Used with >=65% layouts
*/
#define RWD_CMD RCMD_T(KC_MPRV) // Tap Right Command for Prev Track
#define PLY_CMD RCMD_T(KC_MPLY) // Tap Right Command for Play/Pause
#define FFD_OPT ROPT_T(KC_MNXT) // Tap Right Option for Next Track
#define PLY_FN1 LT(_FN1, KC_MPLY) // Tap Fn for Play/Pause
#define PLY_FN2 LT(_FN2, KC_MPLY) // Tap Fn2 for Play/Pause
#define MUT_SFT RSFT_T(KC_MUTE) // Tap Right Shift for Mute
/**
* Arrow Mod-Tap
* Use the Mod-Tap feature for arrow keys
* Mostly used for 40-60% layouts
*/
#define UP_RSFT RSFT_T(KC_UP) // Tap Right Shift for Up
#define LFT_OPT ROPT_T(KC_LEFT) // Tap Right Option for Left
#define LFT_CMD RCMD_T(KC_LEFT) // Tap Right Command for Left
#define DWN_FN1 LT(1, KC_DOWN) // Tap Fn for Down
#define DWN_LWR DWN_FN1 // Tap Lower for Down
#define DWN_FN2 LT(2, KC_DOWN) // Tap Fn2 for Down
#define DWN_RAI DWN_FN2 // Tap Raise for Down
#define DWN_OPT ROPT_T(KC_DOWN) // Tap Right Option for Down
#define RGT_SFT RSFT_T(KC_RGHT) // Tap Right Shift for Right
#define RGT_OPT ROPT_T(KC_RGHT) // Tap Right Option for Right
#define RGT_CTL RCTL_T(KC_RGHT) // Tap Right Ctrl for Right
/**
* Nav Mod-Tap
* Use the Mod-Tap feature for nav keys (Home/End, Page Up/Down)
* Mostly used for 40-60% layouts, on a function layer
*/
#define PGU_SFT RSFT_T(KC_PGUP) // Tap Right Shift for Page Up
#define HOM_OPT ROPT_T(KC_HOME) // Tap Right Option for Home
#define HOM_CMD RCMD_T(KC_HOME) // Tap Right Command for Home
#define PGD_OPT ROPT_T(KC_PGDN) // Tap Right Option for Page Down
#define PGD_FN1 LT(1, KC_PGDN) // Tap Fn for Page Down
#define PGD_LWR PGD_FN1 // Tap Lower for Page Down
#define PGD_FN2 LT(2, KC_PGDN) // Tap Fn2 for Page Down
#define PGD_RAI PGD_FN2 // Tap Raise for Page Down
#define END_OPT ROPT_T(KC_END) // Tap Right Option for End
#define END_CTL RCTL_T(KC_END) // Tap Right Control for End
/**
* MacOS
* Common shortcuts used in macOS
* Reference: https://support.apple.com/en-us/HT201236
*/
#define MC_POWR KC_PWR // Power (KC_PWR)
#define MC_SLEP LOPT(LCMD(KC_PWR)) // Sleep (Option-Command-Power)
#define MC_SLPD LCTL(LSFT(KC_PWR)) // Sleep Display (Control-Shift-Power)
#define MC_LOCK LCTL(LCMD(KC_Q)) // Lock Screen (Control-Command-Q)
#define MC_MSSN KC_FIND // Mission Control: Configure karabiner for find -> mission_control
#define MC_LHPD KC_MENU // Launchpad: Configure karabiner for menu -> launchpad
#define MC_CMTB LCMD(KC_TAB) // Command-Tab
#define MC_BACK LCMD(KC_LBRC) // Back (CommandLeft Bracket)
#define MC_FWRD LCMD(KC_RBRC) // Forward (CommandRight Bracket)
#define CLS_TAB LCMD(KC_W) // Close Tab (CommandW)
#define REO_TAB LSFT(LCMD(KC_T)) // Reopen Last Tab (Shift-Command-T)
#define NXT_TAB LCTL(KC_TAB) // Next Tab (Control-Tab)
#define PRV_TAB LSFT(LCTL(KC_TAB)) // Previous Tab (Shift-Control-Tab)
#define NXT_WIN LCMD(KC_GRV) // Next Window (Control-Grave)
#define PRV_WIN LCMD(KC_TILD) // Previous Window (Shift-Control-Grave)
#define MC_PLYR LCMD(KC_F8) // Focuses current Media Player
#define MC_UNDO LCMD(KC_Z) // Undo (Command-Z)
#define MC_REDO LSFT(LCMD(KC_Z)) // Redo (Shift-Command-Z)
#define OP_AFLL HYPR(KC_BSLS) // 1Password Autofill (Shift-Control-Option-Command-\)
#define PX_AFLL LSFT(LOPT(KC_X)) // 1PasswordX Autofill (Shift-Option-X)
// Reverse scrolling for using with macOS Natural Scrolling.
#define MC_WH_U KC_WH_D // Mouse Wheel Up
#define MC_WH_D KC_WH_U // Mouse Wheel Down
#define MC_WH_L KC_WH_R // Mouse Wheel Left
#define MC_WH_R KC_WH_L // Mouse Wheel Right
// RGB Theme
#define RGB_THM RGB_THEME_FORWARD // Cycle next RGB_THEME
#define RGB_RTHM RGB_THEME_REVERSE // Cycle previous RGB_THEME
void send_make_command(bool flash_bootloader);

View File

@ -1,48 +0,0 @@
# Overview
My QMK home. I feel as though I stand on the shoulders of giants, for a lot of my code here is borrowed and adapted from so many contributors here, and that I hope my code here can help or inspire others.
## Layers, Handlers, and Macros
### Layers
I have some predefined layer names for keyboards:
* **_BASE**: Default Layer, QWERTY layout.
* **_FN1**: Function Layer for 60% and above, and additional macros and shortcuts on 50% and below.
* **_LOWER** and **_RAISE**: Function layers for 40%
and macropads:
* **_REEDER**: Shortcuts for [Reeder.app](https://reederapp.com/), my RSS feed reader
* **_MEDIA**: Media controls
* **_NAVI**: Navigation macros, for changing tabs and scrolling
* **_KARABINER**: Generic macro keys, meant to be customized per app with [Karabiner](https://pqrs.org/osx/karabiner/)
#### Protected Layers
I have some named "protected" layers, meant to be at the end of the layer list for changing keyboard settings and features.
* **KEYMAP_LAYERS**: Add additional layers in keymap.
* **_AUDIO**: Audio feature controls.
* **_LIGHT**: RGB Light/Matrix feature controls.
* **_ADJUST**: General keyboard settings and toggles. Can also contain RGB and Audio controls on larger boards that don't need and extra layer for those controls.
### EEPROM User Config
I have a custom userspace config implemented to save settings on the board to persist across shutdowns. I currently store:
* rgb_layer_change - a toggle for using RGB themes for layer indication
* rgb_theme - a pointer to the currently set RGB Theme
### Process Handlers
### Keycode Aliases
I am a macOS user and so a lot of my aliases are
### Macros
## Tap Dances
### Tap Dance Trigger Layer
## RGB
### RGB Theme

View File

@ -1,146 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "brandonschlack.h"
#include "rgb_theme.h"
#include "rgb_bs.h"
#if defined(RGBLIGHT_ENABLE)
extern rgblight_config_t rgblight_config;
#elif defined(RGB_MATRIX_ENABLE)
extern rgb_config_t rgb_matrix_config;
extern bool g_suspend_state;
extern led_config_t g_led_config;
#endif
#if defined(RGB_THEME_ENABLE)
// Should be rgb_theme.c
#define RGB_THEME(name) const rgb_theme_t RGB_##name
#define RGB_THEME_IMPLS
#include "rgb_theme_user.inc"
#undef RGB_THEME_IMPLS
#undef RGB_THEME
#define RGB_THEME(name) [RGB_THEME_##name] = &RGB_##name,
const rgb_theme_t *themes[] = {
#include "rgb_theme_user.inc"
};
#undef RGB_THEME
// Userspace loose colors
rgb_theme_color_t default_adjust = { HSV_SPRINGGREEN };
#endif
void keyboard_post_init_rgb(void) {
layer_state_set_user(layer_state);
}
#if defined(RGB_THEME_ENABLE)
void set_rgb_theme(uint8_t index) {
if (!user_config.rgb_layer_change) {
user_config.rgb_layer_change = true;
}
user_config.rgb_theme = index;
dprintf("rgb theme [EEPROM]: %u\n", user_config.rgb_theme);
eeconfig_update_user(user_config.raw);
}
rgb_theme_t get_rgb_theme(void) {
return *themes[user_config.rgb_theme];
}
void rgb_theme_step(void) {
uint8_t current = user_config.rgb_theme;
current = (current + 1) % RGB_THEME_MAX;
set_rgb_theme(current);
}
void rgb_theme_step_reverse(void) {
uint8_t current = user_config.rgb_theme;
current = (current - 1) % RGB_THEME_MAX;
set_rgb_theme(current);
}
rgb_theme_color_t get_rgb_theme_color(uint8_t index) {
rgb_theme_t theme = get_rgb_theme();
size_t rgb_theme_color_max = ARRAY_SIZE(theme.colors);
if (index == _ADJUST) {
return default_adjust;
} else {
return **(theme.colors + (index % rgb_theme_color_max));
}
};
void rgb_theme_layer(layer_state_t state) {
uint8_t rgb_color_index = get_highest_layer(state);
HSV color = get_rgb_theme_color(rgb_color_index);
#if defined(RGBLIGHT_ENABLE)
color.v = rgblight_config.val;
#elif defined(RGB_MATRIX_ENABLE)
color.v = rgb_matrix_config.hsv.v;
#endif
rgb_layer_helper( color.h, color.s, color.v );
}
#endif
#ifdef RGB_MATRIX_ENABLE
void rgb_matrix_layer_helper (uint8_t red, uint8_t green, uint8_t blue, uint8_t led_type) {
for (int i = 0; i < RGB_MATRIX_LED_COUNT; i++) {
if (!HAS_ANY_FLAGS(g_led_config.flags[i], led_type)) {
rgb_matrix_set_color( i, red, green, blue );
}
}
}
void rgb_matrix_cycle_flag (void) {
switch (rgb_matrix_get_flags()) {
case LED_FLAG_ALL:
rgb_matrix_set_flags(LED_FLAG_KEYS);
rgb_matrix_set_color_all(0, 0, 0);
break;
case LED_FLAG_KEYS:
rgb_matrix_set_flags(LED_FLAG_UNDERGLOW);
rgb_matrix_set_color_all(0, 0, 0);
break;
case LED_FLAG_UNDERGLOW:
rgb_matrix_set_flags(LED_FLAG_NONE);
rgb_matrix_set_color_all(0, 0, 0);
break;
default:
rgb_matrix_set_flags(LED_FLAG_ALL);
rgb_matrix_enable();
break;
}
}
#endif
void rgb_layer_helper(uint8_t hue, uint8_t sat, uint8_t val) {
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
rgblight_sethsv_noeeprom(hue, sat, val);
#ifdef RGB_MATRIX_ENABLE
rgb_matrix_layer_helper(0, 0, 0, rgb_matrix_get_flags());
#endif
}
#endif
layer_state_t layer_state_set_rgb(layer_state_t state) {
#if defined(RGB_THEME_ENABLE)
if (user_config.rgb_layer_change) {
rgb_theme_layer(state);
}
#endif // RGBLIGHT_ENABLE
return state;
}

View File

@ -1,35 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
#ifdef RGB_THEME_ENABLE
# include "rgb_theme.h"
#endif
#ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix.h"
#endif
#ifdef RGB_MATRIX_ENABLE
#define LED_FLAG_KEYS (LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER)
void rgb_matrix_layer_helper(uint8_t red, uint8_t green, uint8_t blue, uint8_t led_type);
void rgb_matrix_cycle_flag(void);
#endif
void keyboard_post_init_rgb(void);
void rgb_layer_helper(uint8_t hue, uint8_t sat, uint8_t val);
layer_state_t layer_state_set_rgb(layer_state_t state);

View File

@ -1,50 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "brandonschlack.h"
#include "color.h"
/*TODO Update as RGBLIGHT Mode */
#ifndef RGB_THEME_COLORS_MAX
#define RGB_THEME_COLORS_MAX 5
#endif
enum rgb_themes {
#define RGB_THEME(name) RGB_THEME_##name,
#include "rgb_theme_user.inc"
#undef RGB_THEME
RGB_THEME_MAX
};
// RGB Theme Color
typedef const HSV rgb_theme_color_t;
#define RGB_THEME_COLOR(tname, tcolor,...) rgb_theme_color_t tname ## _ ## tcolor = { __VA_ARGS__ }
// RGB Theme
typedef struct {
const HSV *colors[RGB_THEME_COLORS_MAX];
} rgb_theme_t;
extern const rgb_theme_t *themes[];
void set_rgb_theme(uint8_t index);
rgb_theme_t get_rgb_theme(void);
void rgb_theme_step(void);
void rgb_theme_step_reverse(void);
rgb_theme_color_t get_rgb_theme_color(uint8_t index);
void rgb_theme_layer(layer_state_t state);

View File

@ -1,95 +0,0 @@
// Basic Theme
#ifndef DISABLE_RGB_THEME_BASIC
#ifndef RGB_THEME_IMPLS
RGB_THEME(BASIC)
#else
RGB_THEME_COLOR(BASIC, WHITE, HSV_WHITE);
RGB_THEME_COLOR(BASIC, BLUE, HSV_BLUE);
RGB_THEME_COLOR(BASIC, RED, HSV_RED);
RGB_THEME_COLOR(BASIC, GREEN, HSV_GREEN);
RGB_THEME_COLOR(BASIC, YELLOW, HSV_YELLOW);
RGB_THEME(BASIC) = { { &BASIC_WHITE, &BASIC_BLUE, &BASIC_RED, &BASIC_GREEN, &BASIC_YELLOW } };
#endif // RGB_THEME_IMPLS
#endif // DISABLE_RGB_THEME_BASIC
// Laser Theme
#ifndef DISABLE_RGB_THEME_LASER
#ifndef RGB_THEME_IMPLS
RGB_THEME(LASER)
#else
RGB_THEME_COLOR(LASER, PURPLE, 191, 255, 255);
RGB_THEME_COLOR(LASER, PINK, 237, 255, 255);
RGB_THEME_COLOR(LASER, BLUE, 165, 255, 255);
RGB_THEME_COLOR(LASER, CYAN, 133, 255, 255);
RGB_THEME_COLOR(LASER, MAGENTA, 213, 255, 255);
RGB_THEME(LASER) = { { &LASER_PURPLE, &LASER_PINK, &LASER_BLUE, &LASER_CYAN, &LASER_MAGENTA } };
#endif // RGB_THEME_IMPLS
#endif // DISABLE_RGB_THEME_LASER
// Metropolis Theme
#ifndef DISABLE_RGB_THEME_METROPOLIS
#ifndef RGB_THEME_IMPLS
RGB_THEME(METROPOLIS)
#else
RGB_THEME_COLOR(METROPOLIS, TEAL, 96, 207, 255);
RGB_THEME_COLOR(METROPOLIS, RED, HSV_RED);
RGB_THEME_COLOR(METROPOLIS, YELLOW, 24, 255, 255);
RGB_THEME_COLOR(METROPOLIS, BLUE, 168, 255, 255);
RGB_THEME_COLOR(METROPOLIS, WHITE, HSV_WHITE);
RGB_THEME(METROPOLIS) = { { &METROPOLIS_TEAL, &METROPOLIS_RED, &METROPOLIS_YELLOW, &METROPOLIS_BLUE, &METROPOLIS_WHITE } };
#endif // RGB_THEME_IMPLS
#endif // DISABLE_RGB_THEME_METROPOLIS
// Canvas Theme
#ifndef DISABLE_RGB_THEME_CANVAS
#ifndef RGB_THEME_IMPLS
RGB_THEME(CANVAS)
#else
RGB_THEME_COLOR(CANVAS, WHITE, HSV_WHITE);
RGB_THEME_COLOR(CANVAS, ORANGE, 10, 255, 255);
RGB_THEME_COLOR(CANVAS, RED, 0, 231, 255);
RGB_THEME_COLOR(CANVAS, GREEN, 74, 207, 255);
RGB_THEME_COLOR(CANVAS, BLUE, 170, 135, 255);
RGB_THEME(CANVAS) = { { &CANVAS_WHITE, &CANVAS_ORANGE, &CANVAS_RED, &CANVAS_GREEN, &CANVAS_BLUE } };
#endif // RGB_THEME_IMPLS
#endif // DISABLE_RGB_THEME_CANVAS
// Jamon Theme
#ifndef DISABLE_RGB_THEME_JAMON
#ifndef RGB_THEME_IMPLS
RGB_THEME(JAMON)
#else
RGB_THEME_COLOR(JAMON, RED, HSV_RED);
RGB_THEME_COLOR(JAMON, LIGHTRED, 4, 255, 255);
RGB_THEME_COLOR(JAMON, WHITE, HSV_WHITE);
RGB_THEME_COLOR(JAMON, YELLOW, HSV_GOLD);
RGB_THEME(JAMON) = { { &JAMON_RED, &JAMON_LIGHTRED, &JAMON_WHITE, &JAMON_YELLOW } };
#endif // RGB_THEME_IMPLS
#endif // DISABLE_RGB_THEME_JAMON
// Striker Theme
#ifndef DISABLE_RGB_THEME_STRIKER
#ifndef RGB_THEME_IMPLS
RGB_THEME(STRIKER)
#else
RGB_THEME_COLOR(STRIKER, BLUE, HSV_BLUE);
RGB_THEME_COLOR(STRIKER, AZURE, HSV_AZURE);
RGB_THEME_COLOR(STRIKER, WHITE, HSV_WHITE);
RGB_THEME_COLOR(STRIKER, RED, HSV_RED);
RGB_THEME(STRIKER) = { { &STRIKER_BLUE, &STRIKER_AZURE, &STRIKER_WHITE, &STRIKER_RED } };
#endif // RGB_THEME_IMPLS
#endif // DISABLE_RGB_THEME_STRIKER
// Oblique Theme
#ifndef DISABLE_RGB_THEME_OBLIQUE
#ifndef RGB_THEME_IMPLS
RGB_THEME(OBLIQUE)
#else
RGB_THEME_COLOR(OBLIQUE, WHITE, HSV_WHITE);
RGB_THEME_COLOR(OBLIQUE, PURPLE, 186, 143, 255);
RGB_THEME_COLOR(OBLIQUE, RED, 10, 200, 255);
RGB_THEME_COLOR(OBLIQUE, ORANGE, 26, 215, 255);
RGB_THEME_COLOR(OBLIQUE, GREEN, 58, 199, 255);
RGB_THEME(OBLIQUE) = { { &OBLIQUE_WHITE, &OBLIQUE_PURPLE, &OBLIQUE_RED, &OBLIQUE_ORANGE, &OBLIQUE_GREEN } };
#endif // RGB_THEME_IMPLS
#endif // DISABLE_RGB_THEME_OBLIQUE

View File

@ -1,34 +0,0 @@
SRC += brandonschlack.c \
process_records.c
SPACE_CADET_ENABLE = no
# Use LTO except for ChibiOS
ifneq ($(PLATFORM),CHIBIOS)
LTO_ENABLE = yes
endif
ifeq ($(strip $(IS_MACROPAD)), yes)
OPT_DEFS += -DIS_MACROPAD
endif
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
SRC += rgb_bs.c
endif
RGB_MATRIX_ENABLE ?= no
ifneq ($(strip $(RGB_MATRIX_ENABLE)), no)
SRC += rgb_bs.c
endif
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
SRC += tap_dances.c
endif
ifeq ($(strip $(FLASH_BOOTLOADER)), yes)
OPT_DEFS += -DFLASH_BOOTLOADER
endif
ifneq ($(FORCE_LAYOUT),)
OPT_DEFS += -DFORCE_LAYOUT=\"$(FORCE_LAYOUT)\"
endif

View File

@ -1,91 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tap_dances.h"
#include "process_keycode/process_tap_dance.h"
int cur_dance (tap_dance_state_t *state) {
if (state->count == 1) {
if (state->interrupted || !state->pressed) return SINGLE_TAP;
else return SINGLE_HOLD;
} else if (state->count == 2) {
if (state->interrupted) return DOUBLE_SINGLE_TAP;
else if (state->pressed) return DOUBLE_HOLD;
else return DOUBLE_TAP;
}
if (state->count == 3) {
if (state->interrupted || !state->pressed) return TRIPLE_TAP;
else return TRIPLE_HOLD;
}
else return 8;
}
__attribute__ ((weak))
void process_tap_dance_keycode (bool reset, uint8_t toggle_layer) { };
void td_trigger_layer_finished (tap_dance_state_t *state, void *user_data) {
tap_dance_trigger_layer_t *data = (tap_dance_trigger_layer_t *)user_data;
data->state = cur_dance(state);
if (data->state == data->trigger) {
layer_on(data->layer);
} else {
process_tap_dance_keycode(false, data->layer);
}
}
void td_trigger_layer_reset (tap_dance_state_t *state, void *user_data) {
tap_dance_trigger_layer_t *data = (tap_dance_trigger_layer_t *)user_data;
if (data->state == data->trigger) {
switch (data->trigger) {
case SINGLE_HOLD:
case DOUBLE_HOLD:
case TRIPLE_HOLD:
layer_off(data->layer);
break;
}
} else {
process_tap_dance_keycode(true, data->layer);
}
data->state = 0;
}
/* Tap Dance: Layer Mod. Toggles Layer when tapped, Mod when held. */
void td_layer_mod_each(tap_dance_state_t *state, void *user_data) {
tap_dance_dual_role_t *data = (tap_dance_dual_role_t *)user_data;
// Single tap → toggle layer, Single hold → mod
if (state->pressed) {
register_code(data->kc);
} else if (state->count == 1) {
state->finished = true;
}
}
void td_layer_mod_finished(tap_dance_state_t *state, void *user_data) {
tap_dance_dual_role_t *data = (tap_dance_dual_role_t *)user_data;
if (state->count == 1 && !state->pressed) {
layer_invert(data->layer);
}
}
void td_layer_mod_reset(tap_dance_state_t *state, void *user_data) {
tap_dance_dual_role_t *data = (tap_dance_dual_role_t *)user_data;
if (state->count == 1) {
unregister_code(data->kc);
}
}

View File

@ -1,52 +0,0 @@
/* Copyright 2020 Brandon Schlack
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "brandonschlack.h"
#ifdef TAP_DANCE_ENABLE
# include "process_keycode/process_tap_dance.h"
#endif
enum tap_dance_states {
SINGLE_TAP = 1,
SINGLE_HOLD = 2,
DOUBLE_TAP = 3,
DOUBLE_HOLD = 4,
DOUBLE_SINGLE_TAP = 5,
TRIPLE_TAP = 6,
TRIPLE_HOLD = 7
};
int cur_dance (tap_dance_state_t *state);
void process_tap_dance_keycode (bool reset, uint8_t toggle_layer);
/* Tap Dance: Trigger Layer
*
* Toggles Layer based on given trigger (Single Hold, Double Tap, Double Hold, etc).
* Uses process_tap_dance_keycode() to allow keycode defines based on layer
*/
typedef struct {
uint8_t trigger;
uint8_t layer;
uint8_t state;
} tap_dance_trigger_layer_t;
#define ACTION_TAP_DANCE_TRIGGER_LAYER(trigger, layer) { \
.fn = { NULL, td_trigger_layer_finished, td_trigger_layer_reset }, \
.user_data = (void *)&((tap_dance_trigger_layer_t) { trigger, layer, 0 }), \
}
void td_trigger_layer_finished (tap_dance_state_t *state, void *user_data);
void td_trigger_layer_reset (tap_dance_state_t *state, void *user_data);

View File

@ -1,61 +0,0 @@
#include "brett.h"
char * get_key(uint16_t keycode) {
switch (keycode) {
case FAT_ARROW:
return "=>";
case SKINNY_ARROW:
return "->";
case REVERSE_ARROW:
return "<-";
case CONCAT:
return "<>";
case MAP:
return "<$>";
case MAP_FLIPPED:
return "<#>";
case FLAP:
return "<@>";
case PIPE:
return "|>";
case ALT:
return "<|>";
case APPLY:
return "<*>";
case AND:
return "&&";
case OR:
return "||";
case BIND:
return ">>=";
case BIND_FLIPPED:
return "=<<";
case DOUBLE_COLON:
return "::";
case VOID_LEFT:
return "<$";
case VOID_RIGHT:
return "$>";
default:
return "";
}
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
bool pressed = record->event.pressed;
switch (keycode) {
case FAT_ARROW ... DOUBLE_COLON:
if (pressed) {
send_string(get_key(keycode));
}
return false;
case FLASH:
if (!pressed) {
SEND_STRING("make -j8 --output-sync " QMK_KEYBOARD ":" QMK_KEYMAP ":flash" SS_TAP(X_ENTER));
reset_keyboard();
}
return false;
default:
return true;
}
}

View File

@ -1,25 +0,0 @@
#pragma once
enum userspace_custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // Can always be here
FAT_ARROW, // =>
SKINNY_ARROW, // ->
REVERSE_ARROW, // <-
CONCAT, // <>
MAP, // <$>
MAP_FLIPPED, // <#>
FLAP, // <@>
PIPE, // |>
ALT, // <|>
APPLY, // <*>
AND, // &&
OR, // ||
BIND, // >>=
BIND_FLIPPED, // =<<
VOID_LEFT, // <$
VOID_RIGHT, // $>
DOUBLE_COLON, // ::
FLASH // Handle keyboard flashing
};
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);

View File

@ -1 +0,0 @@
SRC += brett.c

View File

@ -1,48 +0,0 @@
/* Copyright 2021 Choi Byungyoon <byungyoonc@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "byungyoonc.h"
#if (__has_include("secrets.h") && !defined(NO_SECRETS))
# include "secrets.h"
#else
static const char *const secrets[] = {"test1", "test2"};
#endif
#if !defined(MACRO_TIMER)
# define MACRO_TIMER 20
#endif
/* replicaJunction's process_record_user_kb */
__attribute__ ((weak))
bool process_record_user_kb(uint16_t keycode, keyrecord_t *record) {
return true;
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case KC_SEC1 ... KC_SEC2: /* Secrets! Externally defined strings, not stored in repo */
if (!record->event.pressed) {
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
send_string_with_delay(secrets[keycode - KC_SEC1], MACRO_TIMER);
}
return false;
break;
}
return process_record_user_kb(keycode, record);
};

View File

@ -1,27 +0,0 @@
/* Copyright 2021 Choi Byungyoon <byungyoonc@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
enum custom_keycodes {
KC_SEC1 = SAFE_RANGE,
KC_SEC2
};
#define KC_TASK LCTL(LSFT(KC_ESC))
#define KC_MMUT LSG(KC_A)
bool process_record_user_kb(uint16_t keycode, keyrecord_t *record);

View File

@ -1,14 +0,0 @@
byungyoonc QMK Userspace
========================
# Overview
Defines some custom keycodes, alongside with the Secrets feature. Also incorporates `process_record_user_kb()` for further controls.
Heavily influenced by the [Userspace code by replicaJunction](../replicaJunction/readme.md).
# Features
## Custom Keycodes
- `KC_SEC#` for the Secrets input
- `KC_TASK` for the Windows Task Manager shortcut `LCTL(LSFT(KC_ESC))`
- `KC_MMUT` for the Windows PowerToys Conference Mute microphone `LSG(KC_A)`

View File

@ -1 +0,0 @@
SRC += byungyoonc.c

View File

@ -1,50 +0,0 @@
/* Copyright 2021 Choi Byungyoon <byungyoonc@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(RGB_MATRIX_KEYPRESSES)
RGB_MATRIX_EFFECT(saturated_solid_multisplash)
# if defined(RGB_MATRIX_CUSTOM_EFFECT_IMPLS)
static bool saturated_solid_multisplash(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
uint8_t count = g_last_hit_tracker.count;
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
HSV hsv = rgb_matrix_config.hsv;
hsv.v = 0;
for (uint8_t j = 0; j < count; j++) {
int16_t dx = g_led_config.point[i].x - g_last_hit_tracker.x[j];
int16_t dy = g_led_config.point[i].y - g_last_hit_tracker.y[j];
uint8_t dist = sqrt16(dx * dx + dy * dy);
uint16_t tick = scale16by8(g_last_hit_tracker.tick[j], qadd8(rgb_matrix_config.speed, 1));
uint16_t effect = tick - dist;
if (effect > 255) effect = 255;
uint16_t vdiff = scale16by8(255 - effect, 255 - dist);
hsv.v = qadd8(hsv.v, vdiff);
hsv.s = qsub8(hsv.s, qsub8(127, effect));
}
hsv.v = scale8(hsv.v, rgb_matrix_config.hsv.v);
RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < RGB_MATRIX_LED_COUNT;
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif // RGB_MATRIX_KEYPRESSES

View File

@ -1,130 +0,0 @@
#include QMK_KEYBOARD_H
#include "oneshot.h"
#include "swapper.h"
#define HOME G(KC_LEFT)
#define END G(KC_RGHT)
#define FWD G(KC_RBRC)
#define BACK G(KC_LBRC)
#define TABL G(S(KC_LBRC))
#define TABR G(S(KC_RBRC))
#define SPCL A(G(KC_LEFT))
#define SPC_R A(G(KC_RGHT))
#define LA_SYM MO(SYM)
#define LA_NAV MO(NAV)
enum layers {
DEF,
SYM,
NAV,
NUM,
};
enum keycodes {
// Custom oneshot mod implementation with no timers.
OS_SHFT = SAFE_RANGE,
OS_CTRL,
OS_ALT,
OS_CMD,
SW_WIN, // Switch to next window (cmd-tab)
SW_LANG, // Switch to next input language (ctl-spc)
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[DEF] = LAYOUT_callum(
KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_QUOT,
KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O,
KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH,
LA_NAV, KC_LSFT, KC_SPC, LA_SYM
),
[SYM] = LAYOUT_callum(
KC_ESC, KC_LBRC, KC_LCBR, KC_LPRN, KC_TILD, KC_CIRC, KC_RPRN, KC_RCBR, KC_RBRC, KC_GRV,
KC_MINS, KC_ASTR, KC_EQL, KC_UNDS, KC_DLR, KC_HASH, OS_CMD, OS_ALT, OS_CTRL, OS_SHFT,
KC_PLUS, KC_PIPE, KC_AT, KC_BSLS, KC_PERC, XXXXXXX, KC_AMPR, KC_SCLN, KC_COLN, KC_EXLM,
_______, _______, _______, _______
),
[NAV] = LAYOUT_callum(
KC_TAB, SW_WIN, TABL, TABR, KC_VOLU, QK_BOOT, HOME, KC_UP, END, KC_DEL,
OS_SHFT, OS_CTRL, OS_ALT, OS_CMD, KC_VOLD, KC_CAPS, KC_LEFT, KC_DOWN, KC_RGHT, KC_BSPC,
SPCL, SPC_R, BACK, FWD, KC_MPLY, XXXXXXX, KC_PGDN, KC_PGUP, SW_LANG, KC_ENT,
_______, _______, _______, _______
),
[NUM] = LAYOUT_callum(
KC_7, KC_5, KC_3, KC_1, KC_9, KC_8, KC_0, KC_2, KC_4, KC_6,
OS_SHFT, OS_CTRL, OS_ALT, OS_CMD, KC_F11, KC_F10, OS_CMD, OS_ALT, OS_CTRL, OS_SHFT,
KC_F7, KC_F5, KC_F3, KC_F1, KC_F9, KC_F8, KC_F12, KC_F2, KC_F4, KC_F6,
_______, _______, _______, _______
),
};
bool is_oneshot_cancel_key(uint16_t keycode) {
switch (keycode) {
case LA_SYM:
case LA_NAV:
return true;
default:
return false;
}
}
bool is_oneshot_ignored_key(uint16_t keycode) {
switch (keycode) {
case LA_SYM:
case LA_NAV:
case KC_LSFT:
case OS_SHFT:
case OS_CTRL:
case OS_ALT:
case OS_CMD:
return true;
default:
return false;
}
}
bool sw_win_active = false;
bool sw_lang_active = false;
oneshot_state os_shft_state = os_up_unqueued;
oneshot_state os_ctrl_state = os_up_unqueued;
oneshot_state os_alt_state = os_up_unqueued;
oneshot_state os_cmd_state = os_up_unqueued;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
update_swapper(
&sw_win_active, KC_LGUI, KC_TAB, SW_WIN,
keycode, record
);
update_swapper(
&sw_lang_active, KC_LCTL, KC_SPC, SW_LANG,
keycode, record
);
update_oneshot(
&os_shft_state, KC_LSFT, OS_SHFT,
keycode, record
);
update_oneshot(
&os_ctrl_state, KC_LCTL, OS_CTRL,
keycode, record
);
update_oneshot(
&os_alt_state, KC_LALT, OS_ALT,
keycode, record
);
update_oneshot(
&os_cmd_state, KC_LCMD, OS_CMD,
keycode, record
);
return true;
}
layer_state_t layer_state_set_user(layer_state_t state) {
return update_tri_layer_state(state, SYM, NAV, NUM);
}

View File

@ -1,57 +0,0 @@
#include "oneshot.h"
void update_oneshot(
oneshot_state *state,
uint16_t mod,
uint16_t trigger,
uint16_t keycode,
keyrecord_t *record
) {
if (keycode == trigger) {
if (record->event.pressed) {
// Trigger keydown
if (*state == os_up_unqueued) {
register_code(mod);
}
*state = os_down_unused;
} else {
// Trigger keyup
switch (*state) {
case os_down_unused:
// If we didn't use the mod while trigger was held, queue it.
*state = os_up_queued;
break;
case os_down_used:
// If we did use the mod while trigger was held, unregister it.
*state = os_up_unqueued;
unregister_code(mod);
break;
default:
break;
}
}
} else {
if (record->event.pressed) {
if (is_oneshot_cancel_key(keycode) && *state != os_up_unqueued) {
// Cancel oneshot on designated cancel keydown.
*state = os_up_unqueued;
unregister_code(mod);
}
} else {
if (!is_oneshot_ignored_key(keycode)) {
// On non-ignored keyup, consider the oneshot used.
switch (*state) {
case os_down_unused:
*state = os_down_used;
break;
case os_up_queued:
*state = os_up_unqueued;
unregister_code(mod);
break;
default:
break;
}
}
}
}
}

View File

@ -1,31 +0,0 @@
#pragma once
#include QMK_KEYBOARD_H
// Represents the four states a oneshot key can be in
typedef enum {
os_up_unqueued,
os_up_queued,
os_down_unused,
os_down_used,
} oneshot_state;
// Custom oneshot mod implementation that doesn't rely on timers. If a mod is
// used while it is held it will be unregistered on keyup as normal, otherwise
// it will be queued and only released after the next non-mod keyup.
void update_oneshot(
oneshot_state *state,
uint16_t mod,
uint16_t trigger,
uint16_t keycode,
keyrecord_t *record
);
// To be implemented by the consumer. Defines keys to cancel oneshot mods.
bool is_oneshot_cancel_key(uint16_t keycode);
// To be implemented by the consumer. Defines keys to ignore when determining
// whether a oneshot mod has been used. Setting this to modifiers and layer
// change keys allows stacking multiple oneshot modifiers, and carrying them
// between layers.
bool is_oneshot_ignored_key(uint16_t keycode);

View File

@ -1,99 +0,0 @@
A keymap for 34 keys with 4 layers and no mod-tap.
![](https://raw.githubusercontent.com/callum-oakley/keymap/master/keymap.svg)
## Details
- Hold `sym` to activate the symbols layer.
- Hold `nav` to activate the navigation layer.
- Hold `sym` and `nav` together to activate the numbers layer.
- The home row modifiers are oneshot so that it's possible to modify the
keys on the base layer, where there are no dedicated modifiers.
- `swap win` sends `cmd-tab` for changing focus in macOS but holds `cmd`
between consecutive presses.
- `swap lang` behaves similarly but sends `ctrl-space`, for changing input
language in macOS.
## Oneshot modifiers
The home row modifiers can either be held and used as normal, or if no other
keys are pressed while a modifier is down, the modifier will be queued and
applied to the next non-modifier keypress. For example to type `shift-cmd-t`,
type `sym-o-n` (or `nav-a-t`), release, then hit `t`.
You can and should hit chords as fast as you like because there are no timers
involved.
Cancel unused modifiers by tapping `nav` or `sym`.
### Userspace oneshot implementation
For my usage patterns I was hitting stuck modifiers frequently with [`OSM`][]
(maybe related to [#3963][]?). I'd like to try to help fix this in QMK proper,
but implementing oneshot mods in userspace first was:
1. Fun.
2. A good exploration of how I think oneshot mods should work without timers.
So in the meantime, this [userspace oneshot implementation][] is working well
for me.
## Swapper
`swap win` sends `cmd-tab`, but holds `cmd` between consecutive keypresses.
`cmd` is released when some other key is hit or released. For example
nav down, swap win, swap win, nav up -> cmd down, tab, tab, cmd up
nav down, swap win, enter -> cmd down, tab, cmd up, enter
`swap lang` sends `ctrl-space` to swap input languages in macOS and behaves
similarly.
[Swapper implementation.][]
## Why no mod-tap?
[Mod-tap][] seems to be by far the most popular tool among users of tiny
keyboards to answer the question of where to put the modifiers, and in the
right hands it can clearly work brilliantly, but I've always found myself error
prone and inconsistent with it.
With dedicated modifiers, there are three ways one might type `ctrl-c`:
ctrl down, ctrl up, c down, c up
ctrl down, c down, ctrl up, c up
ctrl down, c down, c up, ctrl up
Basically, you never have to worry about the keyups, as long as the keydowns
occur in the correct order. Similarly, there are three ways one might type
`ac`:
a down, a up, c down, c up
a down, c down, a up, c up
a down, c down, c up, a up
Replace `a` with `ctrl` and this is exactly what we had before! So if we want
to put `a` and `ctrl` on the same key we have a problem, because without
considering timing these sequences become ambiguous. So let's consider timing.
The solution to the ambiguity that QMK employs is to configure the
`TAPPING_TERM` and consider a key held rather than tapped if it is held for
long enough. My problem with this is that it forces you to slow down to use
modifiers. By its very nature the tapping term must be longer than the longest
you would ever hold a key while typing on the slowest laziest Sunday afternoon.
I'm not typing at 100% speed at all times, but when I am, having to think about
timing and consciously slow down for certain actions never fails to trip me up.
So alas, mod-tap is not for me -- but if it works for you, more power to you.
:)
* * *
[My github][]
[`OSM`]: /docs/one_shot_keys.md
[#3963]: https://github.com/qmk/qmk_firmware/issues/3963
[userspace oneshot implementation]: oneshot.c
[swapper implementation.]: swapper.c
[Mod-tap]: https://github.com/qmk/qmk_firmware/blob/master/docs/mod_tap.md
[My github]: https://github.com/callum-oakley

View File

@ -1,3 +0,0 @@
SRC += callum.c
SRC += oneshot.c
SRC += swapper.c

View File

@ -1,27 +0,0 @@
#include "swapper.h"
void update_swapper(
bool *active,
uint16_t cmdish,
uint16_t tabish,
uint16_t trigger,
uint16_t keycode,
keyrecord_t *record
) {
if (keycode == trigger) {
if (record->event.pressed) {
if (!*active) {
*active = true;
register_code(cmdish);
}
register_code(tabish);
} else {
unregister_code(tabish);
// Don't unregister cmdish until some other key is hit or released.
}
} else if (*active) {
unregister_code(cmdish);
*active = false;
}
}

View File

@ -1,20 +0,0 @@
#pragma once
#include QMK_KEYBOARD_H
// Implements cmd-tab like behaviour on a single key. On first tap of trigger
// cmdish is held and tabish is tapped -- cmdish then remains held until some
// other key is hit or released. For example:
//
// trigger, trigger, a -> cmd down, tab, tab, cmd up, a
// nav down, trigger, nav up -> nav down, cmd down, tab, cmd up, nav up
//
// This behaviour is useful for more than just cmd-tab, hence: cmdish, tabish.
void update_swapper(
bool *active,
uint16_t cmdish,
uint16_t tabish,
uint16_t trigger,
uint16_t keycode,
keyrecord_t *record
);

View File

@ -1,66 +0,0 @@
/* Copyright 2022 Cameron Larsen <camjlarsen@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "oneshot.h"
void update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record) {
if (keycode == trigger) {
if (record->event.pressed) {
// Trigger keydown
if (*state == os_up_unqueued) {
register_code(mod);
}
*state = os_down_unused;
} else {
// Trigger keyup
switch (*state) {
case os_down_unused:
// If we didn't use the mod while trigger was held, queue it.
*state = os_up_queued;
break;
case os_down_used:
// If we did use the mod while trigger was held, unregister it.
*state = os_up_unqueued;
unregister_code(mod);
break;
default:
break;
}
}
} else {
if (record->event.pressed) {
if (is_oneshot_cancel_key(keycode) && *state != os_up_unqueued) {
// Cancel oneshot on designated cancel keydown.
*state = os_up_unqueued;
unregister_code(mod);
}
} else {
if (!is_oneshot_ignored_key(keycode)) {
// On non-ignored keyup, consider the oneshot used.
switch (*state) {
case os_down_unused:
*state = os_down_used;
break;
case os_up_queued:
*state = os_up_unqueued;
unregister_code(mod);
break;
default:
break;
}
}
}
}
}

View File

@ -1,41 +0,0 @@
// The GPLv2 License (GPLv2)
//
// Copyright (c) 2022 Cameron Larsen
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include QMK_KEYBOARD_H
// Represents the four states a oneshot key can be in
typedef enum {
os_up_unqueued,
os_up_queued,
os_down_unused,
os_down_used,
} oneshot_state;
// Custom oneshot mod implementation that doesn't rely on timers. If a mod is
// used while it is held it will be unregistered on keyup as normal, otherwise
// it will be queued and only released after the next non-mod keyup.
void update_oneshot(oneshot_state *state, uint16_t mod, uint16_t trigger, uint16_t keycode, keyrecord_t *record);
// To be implemented by the consumer. Defines keys to cancel oneshot mods.
bool is_oneshot_cancel_key(uint16_t keycode);
// To be implemented by the consumer. Defines keys to ignore when determining
// whether a oneshot mod has been used. Setting this to modifiers and layer
// change keys allows stacking multiple oneshot modifiers, and carrying them
// between layers.
bool is_oneshot_ignored_key(uint16_t keycode);

View File

@ -1,5 +0,0 @@
CUSTOM_ONESHOT_ENABLE ?= no
ifeq ($(strip $(CUSTOM_ONESHOT_ENABLE)), yes)
SRC += $(USER_PATH)/features/oneshot.c
OPT_DEFS += -DCUSTOM_ONESHOT_ENABLE
endif

View File

@ -1,39 +0,0 @@
#ifndef USERSPACE
#define USERSPACE
#ifdef BACKLIGHT_ENABLE
#include "backlight.h"
#endif
#include "quantum.h"
#include "config.h"
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#ifndef NO_DEBUG
#define NO_DEBUG
#endif
#ifndef NO_PRINT
#define NO_PRINT
#endif
/* cbbrowne user configuration */
#define randadd 53
#define randmul 181
#define randmod 167
/* Filler to make layering a bit clearer *
* borrowed from basic keymap */
#define _______ KC_TRNS
#define _____ KC_NO
#define LEADER_TIMEOUT 300
#ifndef LIGHT_CONFIG_H
#define BACKLIGHT_BREATHING
#endif
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More