summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/crkbd/keymaps/ollyhayes/config.h96
-rw-r--r--keyboards/crkbd/keymaps/ollyhayes/keymap.c112
-rw-r--r--keyboards/crkbd/keymaps/ollyhayes/oled.c112
-rw-r--r--keyboards/crkbd/keymaps/ollyhayes/readme.md67
-rw-r--r--keyboards/crkbd/keymaps/ollyhayes/rules.mk17
-rw-r--r--users/ollyhayes/ollyhayes.c153
-rw-r--r--users/ollyhayes/ollyhayes.h41
-rw-r--r--users/ollyhayes/rules.mk1
8 files changed, 599 insertions, 0 deletions
diff --git a/keyboards/crkbd/keymaps/ollyhayes/config.h b/keyboards/crkbd/keymaps/ollyhayes/config.h
new file mode 100644
index 0000000000..b7653e1c9a
--- /dev/null
+++ b/keyboards/crkbd/keymaps/ollyhayes/config.h
@@ -0,0 +1,96 @@
+/* Copyright 2022 Olly Hayes (@ollyhayes)
+ *
+ * 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 EE_HANDS
+
+#define TAPPING_FORCE_HOLD
+#define TAPPING_TERM 100
+
+#define NO_ACTION_ONESHOT
+
+#define OLED_FONT_H "keyboards/crkbd/lib/glcdfont.c"
+
+#define UNICODE_SELECTED_MODES UC_LNX
+
+#ifdef RGB_MATRIX_ENABLE
+# define RGB_MATRIX_KEYPRESSES // reacts to keypresses
+// # define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses)
+// # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
+# define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
+# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
+// # define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness)
+// # define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness)
+# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150 // limits maximum brightness of LEDs to 150 out of 255. Higher may cause the controller to crash.
+# define RGB_MATRIX_HUE_STEP 8
+# define RGB_MATRIX_SAT_STEP 8
+# define RGB_MATRIX_VAL_STEP 8
+# define RGB_MATRIX_SPD_STEP 10
+
+
+// RGB Matrix Animation modes. Explicitly enabled
+// For full list of effects, see:
+// https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects
+# define ENABLE_RGB_MATRIX_SOLID_COLOR
+// # define ENABLE_RGB_MATRIX_ALPHAS_MODS
+// # define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
+// # define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
+// # define ENABLE_RGB_MATRIX_BREATHING
+// # define ENABLE_RGB_MATRIX_BAND_SAT
+// # define ENABLE_RGB_MATRIX_BAND_VAL
+// # define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
+// # define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
+// # define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
+// # define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
+// # define ENABLE_RGB_MATRIX_CYCLE_ALL
+// # define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
+// # define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
+// # define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
+// # 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_DUAL_BEACON
+// # define ENABLE_RGB_MATRIX_RAINBOW_BEACON
+# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
+// # define ENABLE_RGB_MATRIX_RAINDROPS
+// # define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
+// # define ENABLE_RGB_MATRIX_HUE_BREATHING
+// # define ENABLE_RGB_MATRIX_HUE_PENDULUM
+// # define ENABLE_RGB_MATRIX_HUE_WAVE
+// # define ENABLE_RGB_MATRIX_PIXEL_RAIN
+// # define ENABLE_RGB_MATRIX_PIXEL_FLOW
+// # define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
+// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined
+# define ENABLE_RGB_MATRIX_TYPING_HEATMAP
+# define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 200
+// # define ENABLE_RGB_MATRIX_DIGITAL_RAIN
+// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined
+# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
+// # define ENABLE_RGB_MATRIX_SOLID_REACTIVE
+// # define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
+// # define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
+// # define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
+// # define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
+// # define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
+// # define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
+// # define ENABLE_RGB_MATRIX_SPLASH
+// # define ENABLE_RGB_MATRIX_MULTISPLASH
+// # define ENABLE_RGB_MATRIX_SOLID_SPLASH
+// # define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
+
+#endif
diff --git a/keyboards/crkbd/keymaps/ollyhayes/keymap.c b/keyboards/crkbd/keymaps/ollyhayes/keymap.c
new file mode 100644
index 0000000000..80ce41df49
--- /dev/null
+++ b/keyboards/crkbd/keymaps/ollyhayes/keymap.c
@@ -0,0 +1,112 @@
+/* Copyright 2022 Olly Hayes (@ollyhayes)
+ *
+ * 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 "ollyhayes.h"
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [BASE] = LAYOUT_split_3x6_3(
+// +------------+------+------+---------+----------+---------+--------+----------+---------+--------+---------+---------+
+ NUM_SWITCH , KC_Q , KC_W , KC_F , KC_P , KC_G , KC_J , KC_L , KC_U , KC_Y , KC_SCLN , KC_BSPC ,
+ KC_ESC , KC_A , KC_R , KC_S , KC_T , KC_D , KC_H , KC_N , KC_E , KC_I , KC_O , KC_ENT ,
+ KC_LSFT , KC_Z , KC_X , KC_C , KC_V , KC_B , KC_K , KC_M , KC_COMM , KC_DOT , KC_SLSH , KC_RSFT ,
+ KC_LCTL , MO(PUNC) , MO(ARR) , KC_SPC , MO(PUNC) , KC_RCTL
+// +------------+------+------+---------+----------+---------+--------+----------+---------+--------+---------+---------+
+ ),
+
+ [QWERTY] = LAYOUT_split_3x6_3(
+// +---------+------+------+---------+---------+---------+---------+---------+---------+--------+---------+---------+
+ KC_TRNS , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_TRNS ,
+ KC_TRNS , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN , KC_TRNS ,
+ KC_TRNS , KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
+// +---------+------+------+---------+---------+---------+---------+---------+---------+--------+---------+---------+
+ ),
+
+ [GAMES] = LAYOUT_split_3x6_3(
+// +---------+------+------+---------+---------+----------+---------+---------+---------+--------+---------+---------+
+ KC_TRNS , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_TRNS ,
+ KC_TRNS , KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN , KC_TRNS ,
+ KC_TRNS , KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH , KC_TRNS ,
+ KC_TRNS , KC_LALT , KC_SPACE , MO(ARR) , KC_TRNS , KC_TRNS
+// +---------+------+------+---------+---------+----------+---------+---------+---------+--------+---------+---------+
+ ),
+
+ [NUM] = LAYOUT_split_3x6_3(
+// +---------+---------------+------+--------+---------+-----------+-----------+------+--------+------+---------+---------+
+ KC_TRNS , MO(FUNCTIONS) , KC_1 , KC_2 , KC_3 , DF(BASE) , C(KC_GRV) , KC_7 , KC_8 , KC_9 , KC_TRNS , KC_TRNS ,
+ KC_TRNS , MO(MEDIA) , KC_4 , KC_5 , KC_6 , DF(GAMES) , KC_NO , KC_4 , KC_5 , KC_6 , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_0 , KC_7 , KC_8 , KC_9 , DF(QWERTY), KC_NO , KC_1 , KC_2 , KC_3 , KC_TRNS , KC_TRNS ,
+ KC_DOT , KC_TRNS , KC_TAB , KC_TRNS , KC_0 , KC_DOT
+// +---------+---------------+------+--------+---------+-----------+-----------+------+--------+------+---------+---------+
+ ),
+
+ [FUNCTIONS] = LAYOUT_split_3x6_3(
+// +---------------+---------+---------+---------+---------+---------+---------+---------+---------+-------+---------+---------+
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_F8 , KC_F9 , KC_F12 , KC_F12 , KC_F7 , KC_F8 , KC_F9 , KC_TRNS , KC_TRNS ,
+ TG(FUNCTIONS) , KC_TRNS , KC_F4 , KC_F5 , KC_F6 , KC_F11 , KC_F11 , KC_F4 , KC_F5 , KC_F6 , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_F1 , KC_F2 , KC_F3 , KC_F10 , KC_F10 , KC_F1 , KC_F2 , KC_F3 , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
+// +---------------+---------+---------+---------+---------+---------+---------+---------+---------+-------+---------+---------+
+ ),
+
+ [ARR] = LAYOUT_split_3x6_3(
+// +---------+---------+-----------+---------+---------+------------+-----------+---------+---------+-----------+---------+---------+
+ KC_TRNS , KC_TRNS , KC_HOME , KC_PGUP , KC_PGDN , KC_END , KC_HOME , KC_PGDN , KC_PGUP , KC_END , KC_TRNS , KC_TRNS ,
+ KC_ENT , KC_DEL , KC_LEFT , KC_UP , KC_DOWN , KC_RGHT , KC_LEFT , KC_DOWN , KC_UP , KC_RGHT , KC_DEL , KC_TRNS ,
+ KC_TRNS , KC_INS , C(KC_LEFT), KC_LGUI , KC_LALT , C(KC_RGHT) , C(KC_LEFT), DOWN4 , UP4 , C(KC_RGHT), KC_INS , KC_TRNS ,
+ KC_TRNS , KC_F12 , KC_TRNS , KC_TRNS , KC_F12 , KC_TRNS
+// +---------+---------+-----------+---------+---------+------------+-----------+---------+---------+-----------+---------+---------+
+ ),
+
+ [PUNC] = LAYOUT_split_3x6_3(
+// +---------+------------+-----------+-----------+-------------+------------+------------+-------------+------------+------------+-----------+---------+
+ ALTTAB , S(KC_1) , S(KC_2) , UC(0x20ac), S(KC_4) , S(KC_5) , S(KC_6) , S(KC_7) , S(KC_8) , S(KC_9) , S(KC_0) , KC_TRNS ,
+ KC_TRNS , S(KC_NUBS) , S(KC_GRV) , KC_LBRC , KC_RBRC , S(KC_NUHS) , KC_QUOT , S(KC_LBRC) , S(KC_RBRC) , KC_MINS , S(KC_EQL) , KC_TRNS ,
+ KC_TRNS , KC_NUBS , KC_GRV , KC_LGUI , KC_LALT , KC_NUHS , S(KC_QUOT) , KC_LALT , KC_LGUI , S(KC_MINS) , KC_EQL , KC_TRNS ,
+ KC_TRNS , MO(DUBPUNC) , KC_MPLY , KC_TRNS , MO(DUBPUNC) , KC_TRNS
+// +---------+------------+-----------+-----------+-------------+------------+------------+-------------+------------+------------+-----------+---------+
+ ),
+
+ [MEDIA] = LAYOUT_split_3x6_3(
+// +------------+-----------+---------+---------+---------+----------------+----------------+---------+---------+---------+----------+---------+
+ RESET , RGB_RMOD , RGB_MOD , RGB_TOG , RGB_HUD , RGB_HUI , RGB_HUD , RGB_HUI , RGB_TOG , RGB_RMOD, RGB_MOD , KC_SLEP ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_VOLD , KC_VOLU , RGB_MODE_PLAIN , RGB_MODE_PLAIN , KC_VOLD , KC_VOLU , KC_TRNS , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , RGB_VAD , RGB_VAI , RGB_SAD , RGB_SAI , RGB_SAD , RGB_SAI , RGB_VAD , RGB_VAI , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
+// +------------+-----------+---------+---------+---------+----------------+----------------+---------+---------+---------+----------+---------+
+ ),
+
+ [DUBPUNC] = LAYOUT_split_3x6_3(
+// +---------+----------+-----------+-----------+------------+---------+-----------+---------+----------+---------+----------+---------+
+ KC_TRNS , KC_TRNS , KC_TRNS , UC(0x00a3), KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , U_UMLAUT , KC_TRNS , KC_TRNS , KC_TRNS ,
+ KC_TRNS , A_UMLAUT , KC_TRNS , UC(0x00df), UC(0x2713) , KC_TRNS , UC(0x00b0), KC_TRNS , KC_TRNS , KC_TRNS , O_UMLAUT , KC_TRNS ,
+ KC_TRNS , KC_TRNS , UC(0x2717), KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
+// +---------+----------+-----------+-----------+------------+---------+-----------+---------+----------+---------+----------+---------+
+ )
+};
+
+/*
+[TEMPLATE] = LAYOUT_split_3x6_3(
+// +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS ,
+ KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS , KC_TRNS
+// +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
+),
+*/
diff --git a/keyboards/crkbd/keymaps/ollyhayes/oled.c b/keyboards/crkbd/keymaps/ollyhayes/oled.c
new file mode 100644
index 0000000000..33db85fbb7
--- /dev/null
+++ b/keyboards/crkbd/keymaps/ollyhayes/oled.c
@@ -0,0 +1,112 @@
+/* Copyright 2022 Olly Hayes (@ollyhayes)
+ *
+ * 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 "ollyhayes.h"
+
+oled_rotation_t oled_init_user(oled_rotation_t rotation) {
+ if (!is_keyboard_master()) {
+ return OLED_ROTATION_180; // flips the display 180 degrees if offhand
+ }
+ return rotation;
+}
+
+#define L_BASE 0
+#define L_NUM 8
+#define L_FUNCTIONS 16
+#define L_ARR 32
+#define L_PUNC 64
+#define L_DUBPUNC 128
+#define L_MEDIA 256
+
+#define DL_COLEMAK 1
+#define DL_QWERTY 2
+#define DL_GAMES 4
+
+void oled_render_layer_state(void) {
+ oled_write_P(PSTR("Layer: "), false);
+ switch (layer_state) {
+ case L_BASE:
+ switch (default_layer_state) {
+ case DL_QWERTY:
+ oled_write_ln_P(PSTR("Qwerty"), false);
+ break;
+ case DL_GAMES:
+ oled_write_ln_P(PSTR("Games"), false);
+ break;
+ case DL_COLEMAK:
+ default:
+ oled_write_ln_P(PSTR("Colemak"), false);
+ break;
+ }
+ break;
+ case L_NUM:
+ oled_write_ln_P(PSTR("Numbers"), false);
+ break;
+ case L_FUNCTIONS:
+ case L_FUNCTIONS|L_NUM:
+ oled_write_ln_P(PSTR("Functions"), false);
+ break;
+ case L_ARR:
+ oled_write_ln_P(PSTR("Navigation"), false);
+ break;
+ case L_PUNC:
+ oled_write_ln_P(PSTR("Punctuation"), false);
+ break;
+ case L_MEDIA:
+ case L_MEDIA|L_NUM:
+ oled_write_ln_P(PSTR("Media"), false);
+ break;
+ case L_DUBPUNC:
+ case L_DUBPUNC|L_PUNC:
+ oled_write_ln_P(PSTR("Specials"), false);
+ break;
+ }
+}
+
+void oled_render_timer(void) {
+ static uint16_t microticks = 0;
+ static uint16_t ticks = 0;
+
+ if (microticks++ % 1000 == 0) {
+ ticks++;
+ }
+
+ oled_write_P(PSTR("Ticks: "), false);
+ oled_write_ln(get_u16_str(ticks, ' '), false);
+}
+
+void oled_render_presses(void) {
+ oled_write_P(PSTR("Presses: "), false);
+ oled_write_ln(get_u16_str(key_presses, ' '), false);
+}
+
+void oled_render_rgb_mode(void) {
+ oled_write_P(PSTR("Animation: "), false);
+ oled_write_ln(get_u8_str(rgb_matrix_get_mode(), ' '), false);
+}
+
+bool oled_task_user(void) {
+ if (is_keyboard_master()) {
+ oled_render_layer_state();
+ }
+ oled_render_timer();
+ if (is_keyboard_master()) {
+ oled_render_presses();
+ }
+ oled_render_rgb_mode();
+ return false;
+}
diff --git a/keyboards/crkbd/keymaps/ollyhayes/readme.md b/keyboards/crkbd/keymaps/ollyhayes/readme.md
new file mode 100644
index 0000000000..9e63f780ff
--- /dev/null
+++ b/keyboards/crkbd/keymaps/ollyhayes/readme.md
@@ -0,0 +1,67 @@
+# ollyhayes's keymap for [Corne Keyboard (crkbd)](https://github.com/foostan/crkbd)
+
+## Keymap
+
+After many years of changing my keymap often and reperatedly, I finally came to a stable version. I've been using this for a while now with only small tweaks every so often.
+
+All layers are activated only whilst the layer key is held, except the default layers.
+
+Lots of keys are repeated on both sides. I find this really useful for two reasons:
+
+* I like to have the option to use the opposite hand to hold modifiers shift/ctrl etc as the hand pressing the key, I find this really comfortable.
+* When using the mouse, I like to be able to do common things with just my left hand.
+
+### Colemak
+
+The base layer:
+
+![colemak](https://i.imgur.com/uxLJzul.png)
+
+### Navigation
+
+All things for moving the cursor around, inspired by vim.
+
+* `c←` is ctrl+left
+* `↓↓↓↓` is ↓ pressed four times
+
+![navigation](https://i.imgur.com/xfkA0ze.png)
+
+### Symbols
+
+The shifted number row and all brackets and other symbols.
+
+* `a/t` is alt-tab for window switching in windows/linux. Using some special code to release alt when the punc key is released, this works quite nicely.
+
+![symbols](https://i.imgur.com/t9Jygs1.png)
+
+### Specials
+
+Some extra symbols (linux only for now) that work by sending UTF sequences. Layer activated by holding both punctuation layer keys.
+
+![specials](https://i.imgur.com/AtPWKrA.png)
+
+### Numbers
+
+Numbpads (left version is reversed so 1, 2, 3 are easy to reach with one hand (like on a regular keyboard).
+
+Also the keys to switch the default layer are here.
+
+![numbers](https://i.imgur.com/9XXcAXK.png)
+
+### Functions
+
+Function keys, nothing too interesting.
+
+![functions](https://i.imgur.com/ttrw3FJ.png)
+
+### Games (default layer)
+
+Used for some games, qwerty with space bar and alt for the left hand.
+
+![games](https://i.imgur.com/zVvHWKd.png)
+
+### Qwerty (default layer)
+
+Mostly for guests.
+
+![qwerty](https://i.imgur.com/Bqs1bjV.png)
diff --git a/keyboards/crkbd/keymaps/ollyhayes/rules.mk b/keyboards/crkbd/keymaps/ollyhayes/rules.mk
new file mode 100644
index 0000000000..2dcd9007e5
--- /dev/null
+++ b/keyboards/crkbd/keymaps/ollyhayes/rules.mk
@@ -0,0 +1,17 @@
+SRC += oled.c
+
+OLED_ENABLE = yes
+OLED_DRIVER = SSD1306
+
+EXTRAKEY_ENABLE = yes
+UNICODE_ENABLE = yes
+
+RGBLIGHT_ENABLE = no
+RGB_MATRIX_ENABLE = yes
+# RGB_MATRIX_CUSTOM_USER = yes
+
+VIRTSER_ENABLE = yes
+
+LTO_ENABLE = yes
+
+MOUSEKEY_ENABLE = no
diff --git a/users/ollyhayes/ollyhayes.c b/users/ollyhayes/ollyhayes.c
new file mode 100644
index 0000000000..6dfd61b263
--- /dev/null
+++ b/users/ollyhayes/ollyhayes.c
@@ -0,0 +1,153 @@
+/* Copyright 2022 Olly Hayes (@ollyhayes)
+ *
+ * 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 "ollyhayes.h"
+
+#ifdef VIRTSER_ENABLE
+# include "virtser.h"
+#endif
+
+layer_state_t default_layer_state_set_kb(layer_state_t state) {
+ if (layer_state_cmp(state, BASE)) {
+ rgb_matrix_mode(3);
+ } else if (layer_state_cmp(state, GAMES)) {
+ rgb_matrix_mode(1);
+ }
+ return state;
+}
+
+uint16_t key_presses = 0;
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ // for tab/number layer switch
+ static bool key_pressed_since_switch = false;
+ static uint16_t switch_down_time = 0;
+
+ // for alt-tab on punc layer
+ static bool alt_tab_used = false;
+
+ // for capital umlauts
+ static bool shift_held = false;
+
+#ifdef VIRTSER_ENABLE
+ if (record->event.pressed) {
+ uint8_t key_index = 40 + record->event.key.col + record->event.key.row * 6;
+ virtser_send(key_index);
+ } else {
+ uint8_t key_index = 90 + record->event.key.col + record->event.key.row * 6;
+ virtser_send(key_index);
+ }
+#endif
+
+ if (record->event.pressed) {
+ key_pressed_since_switch = true;
+ key_presses++;
+ }
+
+ switch (keycode) {
+ case UP4:
+ if (record->event.pressed) {
+ tap_code(KC_UP);
+ tap_code(KC_UP);
+ tap_code(KC_UP);
+ tap_code(KC_UP);
+ return false;
+ }
+ break;
+
+ case DOWN4:
+ if (record->event.pressed) {
+ tap_code(KC_DOWN);
+ tap_code(KC_DOWN);
+ tap_code(KC_DOWN);
+ tap_code(KC_DOWN);
+ return false;
+ }
+ break;
+
+ case NUM_SWITCH:
+ if (record->event.pressed) {
+ layer_on(NUM);
+ key_pressed_since_switch = false;
+ switch_down_time = timer_read();
+ } else {
+ layer_off(NUM);
+
+ if (!key_pressed_since_switch && timer_elapsed(switch_down_time) < 200) {
+ tap_code(KC_TAB);
+ }
+ }
+ return false;
+
+ case MO(PUNC):
+ if (!record->event.pressed) {
+ if (alt_tab_used) {
+ unregister_code(KC_LALT);
+ alt_tab_used = false;
+ }
+ }
+ return true;
+
+ case MO(FUNCTIONS):
+ if (!record->event.pressed) {
+ // if NUM_SWITCH has been lifted first, toggle to that layer
+ // (4 = 2^NUM)
+ if ((layer_state & 4) != 0) {
+ layer_on(FUNCTIONS);
+ return false;
+ }
+ }
+ return true;
+
+ case ALTTAB:
+ if (record->event.pressed) {
+ alt_tab_used = true;
+ register_code(KC_LALT);
+ tap_code(KC_TAB);
+ }
+ return false;
+
+ case KC_LSFT:
+ case KC_RSFT:
+ shift_held = record->event.pressed;
+ break;
+
+ case A_UMLAUT:
+ if (record->event.pressed) {
+ if (shift_held)
+ register_unicode(0x00c4);
+ else
+ register_unicode(0x00e4);
+ }
+ break;
+ case O_UMLAUT:
+ if (record->event.pressed) {
+ if (shift_held)
+ register_unicode(0x00d6);
+ else
+ register_unicode(0x00f6);
+ }
+ break;
+ case U_UMLAUT:
+ if (record->event.pressed) {
+ if (shift_held)
+ register_unicode(0x00dc);
+ else
+ register_unicode(0x00fc);
+ }
+ break;
+ }
+ return true;
+}
diff --git a/users/ollyhayes/ollyhayes.h b/users/ollyhayes/ollyhayes.h
new file mode 100644
index 0000000000..c65422937c
--- /dev/null
+++ b/users/ollyhayes/ollyhayes.h
@@ -0,0 +1,41 @@
+/* Copyright 2022 Olly Hayes (@ollyhayes)
+ *
+ * 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 layers {
+ BASE,
+ QWERTY,
+ GAMES,
+ NUM,
+ FUNCTIONS,
+ ARR,
+ PUNC,
+ DUBPUNC,
+ MEDIA,
+};
+
+enum custom_keycodes {
+ DOWN4 = SAFE_RANGE,
+ UP4,
+ NUM_SWITCH,
+ ALTTAB,
+ A_UMLAUT,
+ O_UMLAUT,
+ U_UMLAUT,
+};
+
+extern uint16_t key_presses;
diff --git a/users/ollyhayes/rules.mk b/users/ollyhayes/rules.mk
new file mode 100644
index 0000000000..27752a5dee
--- /dev/null
+++ b/users/ollyhayes/rules.mk
@@ -0,0 +1 @@
+SRC += ollyhayes.c