summaryrefslogtreecommitdiff
path: root/users
diff options
context:
space:
mode:
Diffstat (limited to 'users')
-rw-r--r--users/bbaserdem/.gitignore2
-rw-r--r--users/bbaserdem/README.md51
-rw-r--r--users/bbaserdem/bb-audio.c82
-rw-r--r--users/bbaserdem/bb-audio.h28
-rw-r--r--users/bbaserdem/bb-backlight.c30
-rw-r--r--users/bbaserdem/bb-backlight.h23
-rw-r--r--users/bbaserdem/bb-encoder.c514
-rw-r--r--users/bbaserdem/bb-encoder.h29
-rw-r--r--users/bbaserdem/bb-macro.c156
-rw-r--r--users/bbaserdem/bb-macro.h113
-rw-r--r--users/bbaserdem/bb-oled-extra.c796
-rw-r--r--users/bbaserdem/bb-oled-extra.h25
-rw-r--r--users/bbaserdem/bb-oled.c216
-rw-r--r--users/bbaserdem/bb-oled.h32
-rw-r--r--users/bbaserdem/bb-rgb.c130
-rw-r--r--users/bbaserdem/bb-rgb.h28
-rw-r--r--users/bbaserdem/bb-underglow.c116
-rw-r--r--users/bbaserdem/bb-underglow.h28
-rw-r--r--users/bbaserdem/bbaserdem.c915
-rw-r--r--users/bbaserdem/bbaserdem.h767
-rw-r--r--users/bbaserdem/config.h137
-rw-r--r--users/bbaserdem/keymap-bitmaps/.gitignore4
-rwxr-xr-xusers/bbaserdem/keymap-bitmaps/cropBmp38
-rw-r--r--users/bbaserdem/readme.md131
-rw-r--r--users/bbaserdem/rules.mk100
25 files changed, 3592 insertions, 899 deletions
diff --git a/users/bbaserdem/.gitignore b/users/bbaserdem/.gitignore
new file mode 100644
index 0000000000..57bd0e43b4
--- /dev/null
+++ b/users/bbaserdem/.gitignore
@@ -0,0 +1,2 @@
+/secrets.h
+/secrets.c
diff --git a/users/bbaserdem/README.md b/users/bbaserdem/README.md
deleted file mode 100644
index eb8f33d422..0000000000
--- a/users/bbaserdem/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# Overview
-
-I have mostly ortholinear keyboards, which share a lot of functions.
-For this purpose, I collected them here.
-
-I have the following keymaps:
-
-* Gherkin (Does not use the user space)
-* XD75RE (Uses different keymap)
-* Let's Split
-* Let's Split It Up
-* Planck
-
-# Layout
-
-I use DVORAK with an unorthodox Turkish layout.
-If you wanna grab my code, and you used a layout with a persistent base
-layer change, change it to layer 0 before proceeding.
-
-# Layers
-
-* **Dvorak**: Base layer,with dvorak layout.
-* **Alternative**: Has alternate characters.
-* **Game**: Toggled from *Function*, comfortable for gaming use.
-* **Numeric**: Has numericals and symbols. Can be locked.
-* **Function**: Layer has media and function keys.
-* **Mouse**: Manipulates mouse. Can be locked.
-* **Music** Allows playing sounds.
-
-# Functionality
-
-* **RGB Backlight**: With layer indication, and ability to change base layer lighting mode.
-* **Secrets**: By placing a secrets.h, and not tracking it, passwords can be stored.
-* **Mouse**: Mouse emulation, complete with diagonal keys.
-* **Turkish**: An AltGr-like overlay that allows some non-common letters, in unicode.
-
-I suggest checking out how I enabled Turkish keys,
-how I planned out RGB lighting,
-and my mouse implementation;
-they might offer some insight into fringe user cases.
-
-# Issues
-
-All features are too big for the 32kB bootloader.
-Offenders are audio and rgb lights; it comes down to one or the other.
-
-~The Proton board, and rev 6 might fix that.~
-
-# Credits
-
-I have previously written my keymap by myself before, but I rewrote it here,
diff --git a/users/bbaserdem/bb-audio.c b/users/bbaserdem/bb-audio.c
new file mode 100644
index 0000000000..eef0cdf2f6
--- /dev/null
+++ b/users/bbaserdem/bb-audio.c
@@ -0,0 +1,82 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-audio.h"
+/* AUDIO
+ * This contains some audio related stuff.
+ * There is no need to wrap this up with preprocessor commands;
+ * This is only called if audio is enabled
+ */
+
+float tone_game_intro[][2] = GAME_ON_SONG;
+float tone_game_outro[][2] = GAME_OFF_SONG;
+
+// Audio playing when layer changes
+layer_state_t layer_state_set_audio(layer_state_t state) {
+ // Get this layer
+ static bool prev_game = false;
+
+ // If entering the game layer; play the intro sound
+ if (layer_state_cmp(state, _GAME) && (!prev_game)) {
+ stop_all_notes();
+ PLAY_SONG(tone_game_intro);
+ prev_game = true;
+ }
+ // If exiting the game layer; play the outro sound
+ if ((!layer_state_cmp(state, _GAME)) && prev_game) {
+ stop_all_notes();
+ PLAY_SONG(tone_game_outro);
+ prev_game = false;
+ }
+ return state;
+}
+
+// Audio layer switch; add the music layer on top of this
+bool process_record_audio(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case MU_TOG:
+ if (!record->event.pressed) {
+ // On release, exit music mode if enabled
+ if (layer_state_is(_MUSI)) {
+ layer_off(_MUSI);
+ // If not enabled; turn off all layers and load music layer
+ } else {
+ layer_clear();
+ layer_on(_MUSI);
+ }
+ }
+ return true;
+ break;
+ case MU_ON:
+ if (!record->event.pressed) {
+ // On release, enter music mode
+ layer_clear();
+ layer_on(_MUSI);
+ }
+ return true;
+ break;
+ case MU_OFF:
+ if (!record->event.pressed) {
+ // On release, exit music mode
+ layer_off(_MUSI);
+ }
+ return true;
+ break;
+ }
+ return true;
+}
diff --git a/users/bbaserdem/bb-audio.h b/users/bbaserdem/bb-audio.h
new file mode 100644
index 0000000000..351061ab9a
--- /dev/null
+++ b/users/bbaserdem/bb-audio.h
@@ -0,0 +1,28 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+/* AUDIO
+ * Some functions to hook to some modes
+ */
+
+// Hook to layer change effects
+layer_state_t layer_state_set_audio(layer_state_t state);
+
+// Hook to audio keycodes
+bool process_record_audio(uint16_t keycode, keyrecord_t *record);
diff --git a/users/bbaserdem/bb-backlight.c b/users/bbaserdem/bb-backlight.c
new file mode 100644
index 0000000000..5eca1f2c11
--- /dev/null
+++ b/users/bbaserdem/bb-backlight.c
@@ -0,0 +1,30 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-backlight.h"
+/* Replaced functions with noeeprom varieties; I don't need retention across
+ * booting.
+ */
+
+// Backlight LEDs
+void keyboard_post_init_backlight(void) {
+ backlight_enable();
+ backlight_level(2);
+# ifdef BACKLIGHT_BREATHING
+ breathing_enable();
+# endif // BACKLIGHT_BREATHING
+}
diff --git a/users/bbaserdem/bb-backlight.h b/users/bbaserdem/bb-backlight.h
new file mode 100644
index 0000000000..3af3137d9a
--- /dev/null
+++ b/users/bbaserdem/bb-backlight.h
@@ -0,0 +1,23 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+/* Hooks for backlight definitions
+ */
+
+void keyboard_post_init_backlight(void);
diff --git a/users/bbaserdem/bb-encoder.c b/users/bbaserdem/bb-encoder.c
new file mode 100644
index 0000000000..eea9751051
--- /dev/null
+++ b/users/bbaserdem/bb-encoder.c
@@ -0,0 +1,514 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-encoder.h"
+
+// Need this to call velocikey activation
+#ifdef VELOCIKEY_ENABLE
+# include "velocikey.h"
+#endif // VELOCIKEY_ENABLE
+// Need memcpy and memcmp from string.h along with transfer stuff
+#ifdef OLED_ENABLE
+# include <string.h>
+#endif // OLED_ENABLE
+
+/* ROTARY ENCODER
+ * This contains my general rotary encoder code
+ * Encoders each have a list of different modes they can be in.
+ * Each mode also have an on click action as well.
+ * Modes can be cycled using either shift-click or ctrl-click
+ * Modes can be reset using OS click
+ * Some modes are only accessible through some keymap layers
+ */
+
+// Default state for the encoders
+void reset_encoder_state(void) {
+ userspace_config.e0base = 0;
+ userspace_config.e0point = 0;
+ userspace_config.e0rgb = 0;
+ userspace_config.e1base = 1;
+ userspace_config.e1point = 1;
+ userspace_config.e1rgb = 1;
+}
+
+// Encoder scroll functionality
+bool encoder_update_user(uint8_t index, bool clockwise) {
+ uint8_t this_number;
+ // Differentiate layer roles
+ switch (get_highest_layer(layer_state)) {
+# ifdef RGB_MATRIX_ENABLE
+ case _MEDI:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0rgb;
+ } else if (index == 1) {
+ this_number = userspace_config.e1rgb;
+ } else {
+ this_number = 128;
+ }
+ switch(this_number) {
+ case 0: // Effect the RGB mode
+ if (clockwise) {
+ rgb_matrix_step_noeeprom();
+ } else {
+ rgb_matrix_step_reverse_noeeprom();
+ }
+ break;
+ case 1: // Effect the RGB hue
+ if (clockwise) {
+ rgb_matrix_increase_hue_noeeprom();
+ } else {
+ rgb_matrix_decrease_hue_noeeprom();
+ }
+ break;
+ case 2: // Effect the RGB saturation
+ if (clockwise) {
+ rgb_matrix_increase_sat_noeeprom();
+ } else {
+ rgb_matrix_decrease_sat_noeeprom();
+ }
+ break;
+ case 3: // Effect the RGB brightness
+ if (clockwise) {
+ rgb_matrix_increase_val_noeeprom();
+ } else {
+ rgb_matrix_decrease_val_noeeprom();
+ }
+ break;
+ case 4: // Effect the RGB effect speed
+ if (clockwise) {
+ rgb_matrix_increase_speed_noeeprom();
+ } else {
+ rgb_matrix_decrease_speed_noeeprom();
+ }
+ break;
+ }
+ break;
+# endif // RGB_MATRIX_ENABLE
+# ifdef MOUSEKEY_ENABLE
+ case _MOUS:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0point;
+ } else if (index == 1) {
+ this_number = userspace_config.e1point;
+ } else {
+ this_number = 128;
+ }
+ switch(this_number) {
+ case 0: // Move mouse on horizontal axis
+ if (clockwise) {
+ tap_code(KC_MS_R);
+ } else {
+ tap_code(KC_MS_L);
+ }
+ break;
+ case 1: // Move mouse on vertical axis
+ if (clockwise) {
+ tap_code(KC_MS_D);
+ } else {
+ tap_code(KC_MS_U);
+ }
+ break;
+ case 2: // Move mouse wheel on vertical axis
+ if (clockwise) {
+ tap_code(KC_WH_D);
+ } else {
+ tap_code(KC_WH_U);
+ }
+ break;
+ case 3: // Move mouse on horizontal axis
+ if (clockwise) {
+ tap_code(KC_WH_R);
+ } else {
+ tap_code(KC_WH_L);
+ }
+ break;
+ }
+ break;
+# endif // MOUSEKEY_ENABLE
+ default:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0base;
+ } else if (index == 1) {
+ this_number = userspace_config.e1base;
+ } else {
+ this_number = 128;
+ }
+ switch(this_number) {
+ case 0: // Volume
+ if (clockwise) {
+ tap_code16(KC_VOLU);
+ } else {
+ tap_code16(KC_VOLD);
+ }
+ break;
+ case 1: // Song change
+ if (clockwise) {
+ tap_code16(KC_MNXT);
+ } else {
+ tap_code16(KC_MPRV);
+ }
+ break;
+ case 2: // Move to audio sink
+ if (clockwise) {
+ tap_code16(KC_F13);
+ } else {
+ tap_code16(S(KC_F13));
+ }
+ break;
+ case 3: // Volume of source
+ if (clockwise) {
+ tap_code16(S(KC_VOLU));
+ } else {
+ tap_code16(C(KC_VOLD));
+ }
+ break;
+ case 4: // Move to audio source
+ if (clockwise) {
+ tap_code16(C(KC_F13));
+ } else {
+ tap_code16(C(S(KC_F13)));
+ }
+ break;
+ case 5: // Left-right
+ if (clockwise) {
+ tap_code16(KC_RGHT);
+ } else {
+ tap_code16(KC_LEFT);
+ }
+ break;
+ case 6: // Up-down
+ if (clockwise) {
+ tap_code16(KC_DOWN);
+ } else {
+ tap_code16(KC_UP);
+ }
+ break;
+ case 7: // Page Up-down
+ if (clockwise) {
+ tap_code16(KC_PGDN);
+ } else {
+ tap_code16(KC_PGUP);
+ }
+ break;
+ case 8: // Delete
+ if (clockwise) {
+ tap_code16(KC_DEL);
+ } else {
+ tap_code16(KC_BSPC);
+ }
+ break;
+ }
+ break;
+ }
+ return false;
+}
+
+void encoder_click_action(uint8_t index) {
+ uint8_t this_number;
+ // Differentiate layer roles
+ switch (get_highest_layer(layer_state)) {
+# ifdef RGB_MATRIX_ENABLE
+ case _MEDI:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0rgb;
+ } else if (index == 1) {
+ this_number = userspace_config.e1rgb;
+ } else {
+ this_number = 128;
+ }
+ switch(this_number) {
+ case 0: // Return to no animation
+ rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
+ break;
+ case 1:
+ case 2:
+ case 3: // Toggle
+ rgb_matrix_increase_val_noeeprom();
+ break;
+ case 4: // Toggle velocikey
+# ifdef VELOCIKEY_ENABLE
+ velocikey_toggle();
+# endif // VELOCIKEY_ENABLE
+ break;
+ }
+ break;
+# endif // RGB_MATRIX_ENABLE
+# ifdef MOUSEKEY_ENABLE
+ case _MOUS:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0point;
+ } else if (index == 1) {
+ this_number = userspace_config.e1point;
+ } else {
+ this_number = 128;
+ }
+ switch(this_number) {
+ case 0: // Left click
+ tap_code16(KC_BTN1);
+ break;
+ case 1: // Right click
+ tap_code16(KC_BTN2);
+ break;
+ case 2:
+ case 3: // Middle click
+ tap_code16(KC_BTN2);
+ break;
+ }
+ break;
+# endif // MOUSEKEY_ENABLE
+ default:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0base;
+ } else if (index == 1) {
+ this_number = userspace_config.e1base;
+ } else {
+ this_number = 128;
+ }
+ switch(this_number) {
+ case 0: // Toggle mute
+ case 2:
+ tap_code16(KC_MUTE);
+ break;
+ case 1: // Pause
+ tap_code16(KC_MPLY);
+ break;
+ case 3: // Mute source
+ case 4:
+ tap_code16(A(KC_MUTE));
+ break;
+ case 5: // Insert
+ tap_code16(KC_INS);
+ break;
+ case 6: // Capslock
+ tap_code16(KC_CAPS);
+ break;
+ case 7: // Redo
+ tap_code16(BB_REDO);
+ break;
+ case 8: // Undo
+ tap_code16(BB_UNDO);
+ break;
+ }
+ break;
+ }
+}
+
+bool process_record_encoder(uint16_t keycode, keyrecord_t *record) {
+ // Check if and which encoder
+ int encoder_index = -1;
+
+ // Get the pressed encoder
+ switch (keycode) {
+ case BB_ENC0:
+ encoder_index = 0;
+ break;
+ case BB_ENC1:
+ encoder_index = 1;
+ break;
+ }
+
+ // Activate encoder function of button
+ if ((encoder_index >= 0) & (!record->event.pressed)) {
+ // If shifted, move mode one point forward
+ if (get_mods() & MOD_MASK_SHIFT) {
+ switch (get_highest_layer(layer_state)) {
+# ifdef RGB_MATRIX_ENABLE
+ case _MEDI:
+ if (encoder_index == 0) {
+ userspace_config.e0rgb = (userspace_config.e0rgb + 1) % 5;
+ } else {
+ userspace_config.e1rgb = (userspace_config.e1rgb + 1) % 5;
+ }
+ break;
+# endif // RGB_MATRIX_ENABLE
+# ifdef MOUSEKEY_ENABLE
+ case _MOUS:
+ if (encoder_index == 0) {
+ userspace_config.e0point = (userspace_config.e0point + 1) % 4;
+ } else {
+ userspace_config.e1point = (userspace_config.e1point + 1) % 4;
+ }
+ break;
+# endif // MOUSEKEY_ENABLE
+ default:
+ if (encoder_index == 0) {
+ userspace_config.e0base = (userspace_config.e0base + 1) % 9;
+ } else {
+ userspace_config.e1base = (userspace_config.e1base + 1) % 9;
+ }
+ break;
+ }
+ // If ctrl is active, move mode one point backwards
+ } else if (get_mods() & MOD_MASK_CTRL) {
+ switch (get_highest_layer(layer_state)) {
+# ifdef RGB_MATRIX_ENABLE
+ case _MEDI:
+ if (encoder_index == 0) {
+ userspace_config.e0rgb = (userspace_config.e0rgb + 5 - 1) % 5;
+ } else {
+ userspace_config.e1rgb = (userspace_config.e1rgb + 5 - 1) % 5;
+ }
+ break;
+# endif // RGB_MATRIX_ENABLE
+# ifdef MOUSEKEY_ENABLE
+ case _MOUS:
+ if (encoder_index == 0) {
+ userspace_config.e0point = (userspace_config.e0point + 4 - 1) % 4;
+ } else {
+ userspace_config.e1point = (userspace_config.e1point + 4 - 1) % 4;
+ }
+ break;
+# endif // MOUSEKEY_ENABLE
+ default:
+ if (encoder_index == 0) {
+ userspace_config.e0base = (userspace_config.e0base + 9 - 1) % 9;
+ } else {
+ userspace_config.e1base = (userspace_config.e1base + 9 - 1) % 9;
+ }
+ break;
+ }
+ // If meta is active, reset the encoder states
+ } else if (get_mods() & MOD_MASK_GUI) {
+ reset_encoder_state();
+ eeconfig_update_user(userspace_config.raw);
+ // If nothing else; just perform the click action
+ } else {
+ encoder_click_action(encoder_index);
+ }
+ }
+ return true;
+}
+
+// For printing status to OLED
+#ifdef OLED_ENABLE
+void encoder_state_string(uint8_t index, uint8_t layer, char* buffer) {
+ uint8_t this_number;
+ // Get the layer straight from the main function
+ switch (layer) {
+ // If RGB control mode is enabled
+# ifdef RGB_MATRIX_ENABLE
+ case _MEDI:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0rgb;
+ } else if (index == 1) {
+ this_number = userspace_config.e1rgb;
+ } else {
+ this_number = 128;
+ }
+ switch (this_number) {
+ case 0:
+ strcpy(buffer, "ani mode");
+ break;
+ case 1:
+ strcpy(buffer, "hue ");
+ break;
+ case 2:
+ strcpy(buffer, "saturat.");
+ break;
+ case 3:
+ strcpy(buffer, "bright. ");
+ break;
+ case 4:
+ strcpy(buffer, "ani. spd");
+ break;
+ default:
+ strcpy(buffer, " -N/A- ");
+ break;
+ }
+ break;
+# endif // RGB_MATRIX_ENABLE
+ // If pointer control is enabled
+# ifdef MOUSEKEY_ENABLE
+ case _MOUS:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0point;
+ } else if (index == 1) {
+ this_number = userspace_config.e1point;
+ } else {
+ this_number = 128;
+ }
+ switch (this_number) {
+ case 0:
+ strcpy(buffer, "Lateral ");
+ break;
+ case 1:
+ strcpy(buffer, "Vertical");
+ break;
+ case 2:
+ strcpy(buffer, "Scr. Ver");
+ break;
+ case 3:
+ strcpy(buffer, "Scr. Lat");
+ break;
+ default:
+ strcpy(buffer, " -N/A- ");
+ break;
+ }
+ break;
+# endif // MOUSEKEY_ENABLE
+ default:
+ // Get correct index
+ if (index == 0) {
+ this_number = userspace_config.e0base;
+ } else if (index == 1) {
+ this_number = userspace_config.e1base;
+ } else {
+ this_number = 128;
+ }
+ switch (this_number) {
+ case 0:
+ strcpy(buffer, "Volume ");
+ break;
+ case 1:
+ strcpy(buffer, "Song ");
+ break;
+ case 2:
+ strcpy(buffer, "Sink ");
+ break;
+ case 3:
+ strcpy(buffer, "Src. Vol");
+ break;
+ case 4:
+ strcpy(buffer, "Source ");
+ break;
+ case 5:
+ strcpy(buffer, "Arrow LR");
+ break;
+ case 6:
+ strcpy(buffer, "Arrow UD");
+ break;
+ case 7:
+ strcpy(buffer, "Page U/D");
+ break;
+ case 8:
+ strcpy(buffer, "Erase ");
+ break;
+ default:
+ strcpy(buffer, " -N/A- ");
+ break;
+ }
+ break;
+ }
+}
+#endif // OLED_ENABLE
diff --git a/users/bbaserdem/bb-encoder.h b/users/bbaserdem/bb-encoder.h
new file mode 100644
index 0000000000..dce08cd3d5
--- /dev/null
+++ b/users/bbaserdem/bb-encoder.h
@@ -0,0 +1,29 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+// Hook to encoder stuff
+bool encoder_update_user(uint8_t index, bool clockwise);
+// Complicated code for what the encoder keys do when pressed
+bool process_record_encoder(uint16_t keycode, keyrecord_t *record);
+// Clear the encoder settings
+void reset_encoder_state(void);
+// This is so that encoder state is synched between two halves
+void housekeeping_task_encoder(void);
+// This is purely for oled; should it want to use it
+void encoder_state_string(uint8_t index, uint8_t layer, char* buffer);
diff --git a/users/bbaserdem/bb-macro.c b/users/bbaserdem/bb-macro.c
new file mode 100644
index 0000000000..a84a7bbc21
--- /dev/null
+++ b/users/bbaserdem/bb-macro.c
@@ -0,0 +1,156 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-macro.h"
+
+/* MACRO Definitions
+ * This file has my macros/unicodes
+ * Hooks for other functionality to inject itself into the process_record
+ */
+
+// Tap dance definitons
+#ifdef AUDIO_ENABLE
+#ifdef TAP_DANCE_ENABLE
+qk_tap_dance_action_t tap_dance_actions[] = {
+ // Music playback speed modulator
+ [TD_AUDIO_TEMPO] = ACTION_TAP_DANCE_DOUBLE(MU_SLOW, MU_FAST),
+};
+#endif // AUDIO_ENABLE
+#endif // TAP_DANCE_ENABLE
+
+// Unicode definitions; for single character keys
+// We mask their definitions if unicode is not enabled
+#ifdef UNICODEMAP_ENABLE
+const uint32_t PROGMEM unicode_map[] = {
+ [UPC_A_CIRC] = 0x00C2, [LOW_A_CIRC] = 0x00E2, // Â â
+ [UPC_C_CEDI] = 0x00C7, [LOW_C_CEDI] = 0x00E7, // Ç ç
+ [UPC_G_BREV] = 0x011E, [LOW_G_BREV] = 0x001F, // Ğ ğ
+ [UPC_I_CIRC] = 0x00CE, [LOW_I_CIRC] = 0x00EE, // Î î
+ [UPC_I_DOTL] = 0x0049, [LOW_I_DOTL] = 0x0131, // I ı
+ [UPC_I_DOTT] = 0x0130, [LOW_I_DOTT] = 0x0069, // İ i
+ [UPC_O_DIAE] = 0x00D6, [LOW_O_DIAE] = 0x00F6, // Ö ö
+ [UPC_S_CEDI] = 0x015E, [LOW_S_CEDI] = 0x015F, // Ş ş
+ [UPC_U_CIRC] = 0x00DB, [LOW_U_CIRC] = 0x00FB, // Û û
+ [UPC_U_DIAE] = 0x00DC, [LOW_U_DIAE] = 0x00FC, // Ü ü
+ [UPC_ALPHA] = 0x0391, [LOW_ALPHA] = 0x03B1, // Α α
+ [UPC_BETA] = 0x0392, [LOW_BETA] = 0x03B2, // Β β
+ [UPC_GAMMA] = 0x0393, [LOW_GAMMA] = 0x03B3, // Γ γ
+ [UPC_DELTA] = 0x0394, [LOW_DELTA] = 0x03B4, // Δ δ
+ [UPC_EPSILON] = 0x0395, [LOW_EPSILON] = 0x03B5, // Ε ε
+ [UPC_ZETA] = 0x0396, [LOW_ZETA] = 0x03B6, // Ζ ζ
+ [UPC_ETA] = 0x0397, [LOW_ETA] = 0x03B7, // Η η
+ [UPC_THETA] = 0x0398, [LOW_THETA] = 0x03B8, // Θ θ
+ [UPC_IOTA] = 0x0399, [LOW_IOTA] = 0x03B9, // Ι ι
+ [UPC_KAPPA] = 0x039A, [LOW_KAPPA] = 0x03BA, // Κ κ
+ [UPC_LAMBDA] = 0x039B, [LOW_LAMBDA] = 0x03BB, // Λ λ
+ [UPC_MU] = 0x039C, [LOW_MU] = 0x03BC, // Μ μ
+ [UPC_NU] = 0x039D, [LOW_NU] = 0x03BD, // Ν ν
+ [UPC_XI] = 0x039E, [LOW_XI] = 0x03BE, // Ξ ξ
+ [UPC_OMICRON] = 0x039F, [LOW_OMICRON] = 0x03BF, // Ο ο
+ [UPC_PI] = 0x03A0, [LOW_PI] = 0x03C0, // Π π
+ [UPC_RHO] = 0x03A1, [LOW_RHO] = 0x03C1, // Ρ ρ
+ [UPC_SIGMA] = 0x03A3, [LOW_SIGMA] = 0x03C3, // Σ σ
+ [UPC_TAU] = 0x03A4, [LOW_TAU] = 0x03C4, // Τ τ
+ [UPC_UPSILON] = 0x03A5, [LOW_UPSILON] = 0x03C5, // Υ υ
+ [UPC_PHI] = 0x03A6, [LOW_PHI] = 0x03C6, // Φ φ
+ [UPC_CHI] = 0x03A7, [LOW_CHI] = 0x03C7, // Χ χ
+ [UPC_PSI] = 0x03A8, [LOW_PSI] = 0x03C8, // Ψ ψ
+ [UPC_OMEGA] = 0x03A9, [LOW_OMEGA] = 0x03C9, // Ω ω
+ [ELLIPSIS] = 0x2026, // …
+ [PLANCK_CON] = 0x210F, // ℏ
+ [ANGSTROM] = 0x212B, // Å
+ [BITCOIN] = 0x20BF // ₿
+};
+#endif // UNICODEMAP_ENABLE
+
+// Keycodes
+bool process_record_macro(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ // AltGr + Caps should change the oled layout variable
+ case KC_CAPSLOCK:
+ if (record->event.pressed) {
+ if (get_mods() & MOD_BIT(KC_RALT)) {
+ userspace_config.layout = (userspace_config.layout + 1) % 3;
+ }
+ }
+ return true;
+ break;
+ case BB_OLED:
+ if (record->event.pressed) {
+ if (get_mods() & MOD_MASK_SHIFT) {
+ // Scroll in opposite direction
+ userspace_config.layout = (userspace_config.layout + 4) % 3;
+ } else {
+ userspace_config.layout = (userspace_config.layout + 1) % 3;
+ }
+ }
+ return false;
+ break;
+ // Plain macros
+ case BB_PGPK:
+ // My public PGP key
+ if (record->event.pressed) {
+ SEND_STRING("0B7151C823559DD8A7A04CE36426139E2F4C6CCE");
+ }
+ return false; break;
+ case DBL_ANG:
+ // Double angular bracket
+ if (record->event.pressed) {
+ SEND_STRING("<>"SS_TAP(X_LEFT));
+ }
+ return false; break;
+ case DBL_PAR:
+ // Double paranthesis
+ if (record->event.pressed) {
+ SEND_STRING("()"SS_TAP(X_LEFT));
+ }
+ return false; break;
+ case DBL_BRC:
+ // Double square brackets
+ if (record->event.pressed) {
+ SEND_STRING("[]"SS_TAP(X_LEFT));
+ }
+ return false; break;
+ case DBL_CBR:
+ // Double curly brackets
+ if (record->event.pressed) {
+ SEND_STRING("{}"SS_TAP(X_LEFT));
+ }
+ return false; break;
+ // Unicode macros
+# ifdef UNICODEMAP_ENABLE
+ case TR_FLAG:
+ // Turkish flag
+ if (record->event.pressed) {
+ send_unicode_string("🇹🇷");
+ }
+ return false; break;
+ case BB_LENY:
+ // Lenny face: ( ͡° ͜ʖ ͡°)
+ if (record->event.pressed) {
+ send_unicode_string("( ͡° ͜ʖ ͡°)");
+ }
+ return false; break;
+ case BB_TABL:
+ // Table flip: ┻━┻︵ \(°□°)/ ︵ ┻━┻
+ if (record->event.pressed) {
+ send_unicode_string("┻━┻︵ \\(°□°)/ ︵ ┻━┻");
+ }
+ return false; break;
+# endif // UNICODEMAP_ENABLE
+ }
+ return true;
+}
diff --git a/users/bbaserdem/bb-macro.h b/users/bbaserdem/bb-macro.h
new file mode 100644
index 0000000000..3dc14e7a8a
--- /dev/null
+++ b/users/bbaserdem/bb-macro.h
@@ -0,0 +1,113 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+/* This header file contains definitons regarding custom keycodes.
+ * - Both regular and unicode macros are dealt with in this file
+ */
+
+// These will be delegated to keymap specific stuff (weak definition)
+bool process_record_macro(uint16_t keycode, keyrecord_t *record);
+
+// Unicodemap implementation
+#ifdef UNICODEMAP_ENABLE
+enum userspace_unicodemap {
+ UPC_A_CIRC,
+ UPC_C_CEDI,
+ UPC_G_BREV,
+ UPC_I_CIRC,
+ UPC_I_DOTL,
+ UPC_I_DOTT,
+ UPC_O_DIAE,
+ UPC_S_CEDI,
+ UPC_U_CIRC,
+ UPC_U_DIAE,
+ LOW_A_CIRC,
+ LOW_C_CEDI,
+ LOW_G_BREV,
+ LOW_I_CIRC,
+ LOW_I_DOTL,
+ LOW_I_DOTT,
+ LOW_O_DIAE,
+ LOW_S_CEDI,
+ LOW_U_CIRC,
+ LOW_U_DIAE,
+ ELLIPSIS,
+ PLANCK_CON,
+ ANGSTROM,
+ MATHPI,
+ BITCOIN,
+ UPC_ALPHA,
+ UPC_BETA,
+ UPC_GAMMA,
+ UPC_DELTA,
+ UPC_EPSILON,
+ UPC_ZETA,
+ UPC_ETA,
+ UPC_THETA,
+ UPC_IOTA,
+ UPC_KAPPA,
+ UPC_LAMBDA,
+ UPC_MU,
+ UPC_NU,
+ UPC_XI,
+ UPC_OMICRON,
+ UPC_PI,
+ UPC_RHO,
+ UPC_SIGMA,
+ UPC_TAU,
+ UPC_UPSILON,
+ UPC_PHI,
+ UPC_CHI,
+ UPC_PSI,
+ UPC_OMEGA,
+ LOW_ALPHA,
+ LOW_BETA,
+ LOW_GAMMA,
+ LOW_DELTA,
+ LOW_EPSILON,
+ LOW_ZETA,
+ LOW_ETA,
+ LOW_THETA,
+ LOW_IOTA,
+ LOW_KAPPA,
+ LOW_LAMBDA,
+ LOW_MU,
+ LOW_NU,
+ LOW_XI,
+ LOW_OMICRON,
+ LOW_PI,
+ LOW_RHO,
+ LOW_SIGMA,
+ LOW_TAU,
+ LOW_UPSILON,
+ LOW_PHI,
+ LOW_CHI,
+ LOW_PSI,
+ LOW_OMEGA,
+};
+#endif // UNICODEMAP_ENABLE
+
+// Tap dance stuff
+#ifdef AUDIO_ENABLE
+#ifdef TAP_DANCE_ENABLE
+enum {
+ TD_AUDIO_TEMPO,
+};
+#endif // AUDIO_ENABLE
+#endif // TAP_DANCE_ENABLE
diff --git a/users/bbaserdem/bb-oled-extra.c b/users/bbaserdem/bb-oled-extra.c
new file mode 100644
index 0000000000..b52c4b335a
--- /dev/null
+++ b/users/bbaserdem/bb-oled-extra.c
@@ -0,0 +1,796 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-oled.h"
+#include "bb-oled-extra.h"
+
+// Helper function that draws images
+void draw_image(uint8_t row, uint8_t col, const char image[4][42]) {
+ // Draw this image iteratively
+ for (int i = 0; i < 4; i++) {
+ oled_set_cursor(col, row + i);
+ oled_write_raw_P(image[i], 42);
+ }
+}
+
+// Write modifiers to the screen
+void render_modifiers(uint8_t row, uint8_t col, uint8_t mods) {
+ static const char PROGMEM mod_meta[12] = {0x00,0x01,0x01,0x01,0x01,0x06,0x18,0x60,0x81,0x81,0x81,0x81};
+ static const char PROGMEM mod_altL[12] = {0x00,0x80,0x80,0x80,0x40,0x20,0x10,0x08,0x84,0x95,0x8e,0x84};
+ static const char PROGMEM mod_altR[12] = {0x00,0x86,0x8f,0x8f,0x46,0x20,0x10,0x08,0x84,0x95,0x8e,0x84};
+ static const char PROGMEM mod_ctrl[12] = {0x00,0x00,0xbd,0x42,0xa5,0x99,0x99,0xa5,0x42,0xbd,0x00,0x00};
+ static const char PROGMEM mod_shft[12] = {0x00,0x20,0x30,0x28,0xe4,0x02,0x01,0x02,0xe4,0x28,0x30,0x20};
+ // Looks like Mods: <OS> <Alt/Gr> <Ctrl> <Shift>
+ oled_set_cursor(col, row);
+ oled_write("Mods: ", false);
+ // Meta
+ if (mods & MOD_MASK_GUI) {
+ oled_write_raw_P(mod_meta, 12);
+ oled_set_cursor(col + 8, row);
+ } else {
+ oled_write(" ", false);
+ }
+ // Alt(Gr)
+ if (mods & MOD_BIT(KC_RALT)) {
+ oled_write_raw_P(mod_altR, 12);
+ oled_set_cursor(col + 10, row);
+ } else if (mods & MOD_MASK_ALT) {
+ oled_write_raw_P(mod_altL, 12);
+ oled_set_cursor(col + 10, row);
+ } else {
+ oled_write(" ", false);
+ }
+ // Ctrl
+ if (mods & MOD_MASK_CTRL) {
+ oled_write_raw_P(mod_ctrl, 12);
+ oled_set_cursor(col + 12, row);
+ } else {
+ oled_write(" ", false);
+ }
+ // Shift
+ if (mods & MOD_MASK_SHIFT) {
+ oled_write_raw_P(mod_shft, 12);
+ oled_set_cursor(col + 14, row);
+ } else {
+ oled_write(" ", false);
+ }
+}
+
+// Draws the image of the currently used layout
+void render_layout(uint8_t row, uint8_t col, uint8_t mods, bool isLeft) {
+ // DVORAK
+ static const char PROGMEM base0_L_dvor_nomod[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x04,0x08,0x10,0x00,0x00,0x00,
+ 0x00,0x0e,0x00,0x00,0x00,0x00,0x60,0xe0,0x00,0x00,0x00,0x00,0xc0,0xc0,
+ 0x00,0x00,0x00,0xf8,0x90,0x88,0x88,0x70,0x00,0x78,0x80,0x80,0x40,0xf8
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x00,0x00,
+ 0x40,0x40,0x40,0x80,0x00,0x80,0x41,0x40,0x40,0x80,0x00,0x80,0x40,0x40,
+ 0x40,0x80,0x00,0xc3,0x00,0x00,0x00,0xc0,0x00,0x00,0x42,0xd2,0x02,0x01
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0xd8,0x06,0x01,0x00,0x00,0x00,0x02,
+ 0x05,0x05,0x05,0x07,0x00,0x03,0x04,0x04,0x04,0x03,0x00,0x03,0x05,0x05,
+ 0x85,0x05,0x00,0xc3,0x04,0x04,0x02,0x07,0x00,0x00,0x00,0x07,0x04,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x03,0x0c,0x30,0xc0,0x00,0x00,
+ 0xb6,0x76,0x00,0x00,0x00,0x1c,0x22,0x22,0x12,0xfe,0x00,0x00,0x80,0x82,
+ 0x7e,0x00,0x00,0x3f,0x08,0x0c,0x12,0x20,0x00,0x22,0x14,0x08,0x14,0x22}};
+ static const char PROGMEM base0_L_dvor_shift[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x20,0x10,0x20,0x40,0x20,0x00,0x00,
+ 0x07,0x00,0x07,0x00,0x00,0x10,0x28,0x44,0x82,0x00,0x00,0x82,0x44,0x28,
+ 0x10,0x00,0x00,0xfe,0x12,0x12,0x12,0x0c,0x00,0x06,0x08,0xf0,0x08,0x06
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0xe0,
+ 0x90,0x90,0x90,0xe0,0x00,0xe0,0x10,0x10,0x10,0xe0,0x00,0xf0,0x90,0x90,
+ 0x90,0x10,0x00,0xf0,0x00,0x00,0x00,0xf0,0x00,0x00,0x10,0xf0,0x10,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x80,0x87,0x80,0x00,0x00,0x07,
+ 0x00,0x00,0x00,0x07,0x00,0x03,0x84,0x84,0x84,0x03,0x00,0x07,0x04,0x04,
+ 0x04,0x84,0x00,0x83,0x04,0x04,0x04,0x83,0x00,0x80,0x04,0x07,0x04,0x80
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x01,0x00,0x28,0x04,0x03,0x00,0x00,
+ 0x36,0x36,0x00,0x00,0x00,0x1f,0x20,0x28,0x10,0x6f,0x00,0x18,0x20,0x20,
+ 0x20,0x1f,0x00,0x3f,0x04,0x0a,0x11,0x20,0x00,0x31,0x0a,0x04,0x0a,0x31}};
+ static const char PROGMEM base0_R_dvor_nomod[4][42] = {
+ { 0x00,0xfc,0x12,0x12,0x00,0x00,0x70,0x88,0x88,0x48,0xf8,0x00,0x70,0x88,
+ 0x88,0x88,0x88,0x00,0xf8,0x10,0x08,0x08,0x10,0x00,0x00,0x02,0x7e,0x80,
+ 0x80,0x00,0x10,0x28,0x44,0x82,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x00,0x80,0x80,0x80,0xf0,0x00,0xf0,0x02,0x82,0x82,0x01,0x00,0x00,0x80,
+ 0xf0,0x80,0x80,0x00,0xc0,0x40,0x40,0x40,0x80,0x00,0x80,0x40,0x40,0x40,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x83,0x04,0x04,0x02,0x07,0x00,0x07,0x01,0x00,0x00,0x07,0x00,0x00,0x00,
+ 0x03,0x04,0x04,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x04,0x05,0x05,0x05,
+ 0x02,0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x3f,0x24,0x22,0x22,0x1c,0x00,0x3e,0x02,0x3e,0x02,0x3c,0x00,0x1e,0x20,
+ 0x1c,0x20,0x1e,0x00,0x06,0x18,0x20,0x18,0x06,0x00,0x22,0x32,0x2a,0x26,
+ 0x22,0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM base0_R_dvor_shift[4][42] = {
+ { 0xfe,0x12,0x12,0x12,0x02,0x00,0xfc,0x02,0x12,0x12,0xf4,0x00,0xfc,0x02,
+ 0x02,0x02,0x84,0x00,0xfe,0x12,0x12,0x32,0xcc,0x00,0xfe,0x00,0x00,0x00,
+ 0x00,0x00,0x04,0x88,0x50,0x20,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0xf1,0x10,0x10,0x10,0xe0,0x00,0xf0,0x81,0x81,0x81,0xf0,0x00,0x10,0x11,
+ 0xf1,0x11,0x10,0x00,0xf1,0x60,0x80,0x00,0xf1,0x00,0x61,0x91,0x91,0x91,
+ 0x21,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x8f,0x88,0x88,0x88,0x07,0x00,0x8f,0x00,0x00,0x00,0x8f,0x00,0x80,0x00,
+ 0x0f,0x00,0x80,0x00,0x8f,0x00,0x01,0x06,0x8f,0x00,0x84,0x88,0x88,0x88,
+ 0x87,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x7f,0x44,0x44,0x44,0x3b,0x00,0x7f,0x01,0x06,0x01,0x7f,0x00,0x1f,0x60,
+ 0x1c,0x60,0x1f,0x00,0x07,0x18,0x60,0x18,0x07,0x00,0x70,0x48,0x44,0x42,
+ 0x41,0x00,0x08,0x08,0x3e,0x08,0x08,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM symb5_R_dvor[4][42] = {
+ { 0x00,0x02,0x04,0x08,0x00,0x00,0x20,0x20,0xdc,0x02,0x02,0x00,0x02,0x02,
+ 0xdc,0x20,0x20,0x00,0x00,0xc0,0x30,0x0c,0x03,0x00,0x50,0x50,0x50,0x50,
+ 0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0xf0,0x11,0x12,0x02,0x00,0x02,0x12,
+ 0x11,0xf0,0x00,0x00,0x43,0x20,0x20,0x20,0xc0,0x00,0x00,0x00,0xc0,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x01,0x80,0x41,0x82,0x01,0x00,0x00,0x1f,0x10,0x90,0x00,0x00,0x00,0x90,
+ 0x10,0x1f,0x00,0x00,0xc0,0x00,0x14,0x03,0x00,0x00,0x01,0x01,0x87,0x01,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x22,0xf3,0x0a,0xf3,0x22,0x00,0x00,0x1c,0x63,0x80,0x00,0x00,0x00,0x80,
+ 0x63,0x1c,0x00,0x00,0x00,0x03,0x0c,0x30,0xc0,0x00,0x00,0x00,0x7f,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM numb6_L_dvor_nomod[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,
+ 0x50,0x88,0x04,0x00,0x00,0x04,0x04,0xc4,0x34,0x0c,0x00,0xd8,0x24,0x24,
+ 0x24,0xd8,0x00,0x18,0x24,0x24,0x24,0xf8,0x00,0xf8,0x44,0x24,0x14,0xf8
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x80,0x41,0xe0,0x00,0x00,0xe0,0xa1,0xa1,
+ 0xa1,0x20,0x00,0xc0,0xa1,0xa1,0xa1,0x00,0x00,0x00,0x01,0x01,0x01,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
+ 0x08,0x08,0x08,0x08,0x00,0x03,0x02,0x02,0x0f,0x02,0x00,0x04,0x08,0x08,
+ 0x08,0x07,0x00,0x07,0x08,0x08,0x08,0x07,0x00,0x01,0x01,0x01,0x01,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,
+ 0x22,0x14,0x08,0x00,0x00,0x00,0x04,0x02,0x7f,0x00,0x00,0x42,0x61,0x51,
+ 0x49,0x46,0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x5e,0x61,0x01,0x61,0x5e}};
+ static const char PROGMEM numb6_L_dvor_shift[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xd8,0x24,0x54,0x88,0x40,0x00,0x50,0x20,0xf8,
+ 0x20,0x50,0x00,0x00,0x38,0xc6,0x01,0x00,0x00,0x00,0x01,0xc6,0x38,0x00
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x60,0x91,0xf9,0x90,0x21,0x00,0x20,0x50,0x20,
+ 0x80,0x60,0x00,0x40,0x20,0x10,0x21,0x40,0x00,0x00,0x01,0x00,0x00,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x8f,0x04,0x03,0x00,0x0c,0x02,0x09,
+ 0x14,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x00,0x00,0x00,0x3e,0x41,0x5d,
+ 0x55,0x5e,0x00,0x14,0x7f,0x14,0x7f,0x14,0x00,0x00,0x00,0x00,0x00,0x00}};
+ // Turkish F
+ static const char PROGMEM base0_L_turf_nomod[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x10,0x10,0x7c,0x10,0x10,0x00,0x00,
+ 0xfe,0x09,0x09,0x00,0x00,0x70,0x88,0x88,0x48,0xf8,0x00,0x51,0xaa,0xaa,
+ 0x92,0x09,0x00,0x00,0x88,0xf8,0x80,0x00,0x00,0x70,0x88,0x88,0x88,0x70
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x40,0x80,0x00,0x80,0x40,0x00,0xc0,
+ 0x00,0x00,0x00,0xc0,0x00,0x00,0x42,0xd2,0x02,0x01,0x00,0x81,0x42,0x42,
+ 0x42,0x81,0x00,0x00,0x40,0x40,0x40,0x80,0x00,0xc0,0x10,0x00,0x10,0xc0
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x03,
+ 0x04,0x04,0x82,0x07,0x00,0x00,0x80,0x07,0x84,0x00,0x00,0x03,0x05,0x05,
+ 0x05,0x05,0x00,0x02,0x05,0x05,0x05,0x07,0x00,0x03,0x04,0x04,0x02,0x07
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x1c,0x22,0x22,0x12,0xfe,0x00,0x00,
+ 0x80,0x82,0x7e,0x00,0x00,0x1c,0x22,0x22,0x22,0x1c,0x00,0x06,0x18,0x20,
+ 0x18,0x06,0x00,0x1c,0x22,0x22,0x22,0x22,0x00,0x1c,0xa2,0x62,0x22,0x22}};
+ static const char PROGMEM base0_L_turf_shift[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x28,0x10,0x7c,0x10,0x28,0x00,0xfe,
+ 0x12,0x12,0x12,0x02,0x00,0xfc,0x02,0x12,0x12,0xf4,0x00,0xf1,0x0a,0x4a,
+ 0x4a,0xd1,0x00,0x00,0x02,0xfe,0x02,0x00,0x00,0xfc,0x02,0x02,0x02,0xfc
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x30,0x40,0x80,0x40,0x30,0x00,0xf1,
+ 0x00,0x00,0x00,0xf0,0x00,0x00,0x21,0xe9,0x21,0x00,0x00,0xf1,0x92,0x92,
+ 0x92,0x11,0x00,0xe0,0x91,0x91,0x91,0xe0,0x00,0xe0,0x09,0x01,0x09,0xe0
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x0e,0x81,0x80,0x81,0x0e,0x00,0x07,
+ 0x08,0x08,0x08,0x87,0x00,0x00,0x50,0x1f,0x50,0x00,0x00,0x8f,0x08,0x08,
+ 0x08,0x88,0x00,0x0f,0x80,0x80,0x80,0x0f,0x00,0x8f,0x50,0x50,0x50,0x8f
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x3f,0x40,0x50,0x20,0xdf,0x00,0x30,
+ 0x40,0x40,0x40,0x3f,0x00,0x7e,0x81,0x81,0x81,0x7e,0x00,0x07,0x18,0x60,
+ 0x18,0x07,0x00,0x3f,0x40,0x40,0x40,0x21,0x00,0x1f,0xa0,0x60,0x20,0x10}};
+ static const char PROGMEM base0_L_turf_altgr[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x10,0x10,0x10,0x30,0x00,0x00,0xf0,
+ 0x08,0xe8,0xa8,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x0c,0x1e,0xfe,0x02,0xfe,0x00,0x70,0x8a,0x89,0x8a,0x70
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x10,0x20,0x40,0x00,0x00,0xc1,
+ 0x12,0x0a,0x12,0xc2,0x00,0x00,0x10,0xc8,0x10,0x00,0x00,0x40,0xe0,0x50,
+ 0x10,0x20,0x00,0x00,0x50,0x48,0x50,0x80,0x00,0xc0,0x10,0x08,0x10,0xc0
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x00,0x03,
+ 0x04,0x04,0x02,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x83,0x05,
+ 0x04,0x82,0x00,0x02,0x05,0x05,0x05,0x07,0x00,0x83,0x84,0x04,0x82,0x87
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x3e,0x3e,0x3e,0x00,0x08,0x14,
+ 0x22,0x08,0x14,0x22,0x00,0x22,0x14,0x08,0x22,0x14,0x08,0x03,0x02,0x00,
+ 0x03,0x02,0x00,0x1c,0x22,0x7f,0x22,0x22,0x00,0x02,0x01,0x00,0x02,0x01}};
+ static const char PROGMEM base0_L_turf_shfgr[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x90,0x90,0xfc,0x90,0x90,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,0xf0,0x0a,0x09,0x0a,0xf0
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x88,0x90,0xa0,0x00,0x00,0xc0,
+ 0x10,0x08,0x10,0xc0,0x00,0x00,0x50,0xc8,0x50,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x80,0x50,0x48,0x50,0x80,0x00,0xc1,0x12,0x0a,0x12,0xc1
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x8f,0x4f,0x8f,0x00,0x00,0x0f,
+ 0x10,0x10,0x90,0x0f,0x00,0x80,0x10,0x1f,0x10,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x1f,0x82,0x82,0x82,0x1f,0x00,0x0f,0x10,0x10,0x10,0x0f
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x7c,0x7d,0x7c,0x00,0x00,0x04,
+ 0x0a,0x11,0x20,0x00,0x00,0x20,0x11,0x0a,0x04,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x1f,0x24,0x2a,0x20,0x1f,0x00,0x00,0x00,0x00,0x00,0x00}};
+ static const char PROGMEM base0_R_turf_nomod[4][42] = {
+ { 0x70,0x88,0x88,0x48,0xff,0x00,0xf8,0x10,0x08,0x08,0x10,0x00,0xf8,0x08,
+ 0x08,0x08,0xf0,0x00,0xff,0x10,0x08,0x08,0xf0,0x00,0xf8,0x90,0x88,0x88,
+ 0x70,0x00,0x10,0x28,0x44,0x82,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x40,0xf8,0x40,0x40,0x00,0x00,0xf8,0x00,0x80,0x40,0x00,0x00,0xc0,0x40,
+ 0xc0,0x40,0x80,0x00,0x08,0xf8,0x00,0x00,0x00,0x00,0xc3,0x00,0x00,0x00,
+ 0xc0,0x00,0x80,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x00,0x03,0x04,0x04,0x00,0x00,0x07,0x01,0x01,0x02,0x04,0x00,0xc7,0x00,
+ 0x07,0x00,0x07,0x00,0x00,0x03,0x04,0x04,0x00,0x00,0x03,0x14,0x14,0x12,
+ 0x0f,0x00,0x04,0x15,0x0d,0x05,0x02,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x22,0x32,0x2a,0x26,0x22,0x00,0x24,0x2a,0x2a,0x2a,0x10,0x00,0x3f,0x24,
+ 0x22,0x22,0x1c,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0xb0,0x70,0x00,
+ 0x00,0x00,0x1e,0x20,0x1c,0x20,0x1e,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM base0_R_turf_shift[4][42] = {
+ { 0xfe,0x02,0x02,0x02,0xfc,0x00,0xfe,0x12,0x12,0x32,0xcc,0x00,0xfe,0x0c,
+ 0x30,0xc0,0xfe,0x00,0xfe,0x10,0x10,0x10,0xfe,0x00,0xfe,0x12,0x12,0x12,
+ 0x0c,0x00,0x82,0x44,0x28,0x10,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x11,0x11,0xf1,0x11,0x10,0x00,0xf1,0x80,0x40,0x20,0x11,0x00,0xf1,0x20,
+ 0xc0,0x20,0xf1,0x00,0xf1,0x00,0x00,0x00,0x01,0x00,0x31,0x40,0x80,0x40,
+ 0x30,0x00,0x30,0x48,0x48,0x48,0x90,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x80,0x80,0x8f,0x80,0x80,0x00,0x0f,0x80,0x81,0x82,0x0c,0x00,0x8f,0x80,
+ 0x80,0x80,0x0f,0x00,0x0f,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x0f,0x00,
+ 0x00,0x00,0x82,0x14,0x0c,0x04,0x83,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x70,0x48,0x44,0x42,0x41,0x00,0x23,0x44,0x44,0x44,0x39,0x00,0x7f,0x44,
+ 0x44,0x44,0x3b,0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,0xb6,0x76,0x00,
+ 0x00,0x00,0x1f,0x60,0x1c,0x60,0x1f,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM base0_R_turf_altgr[4][42] = {
+ { 0x53,0x54,0xf8,0x54,0x53,0x00,0x7c,0xba,0x8a,0x8a,0x7c,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x0c,0x12,0x12,0x0c,0x00,0x00,0x20,0xfc,0x22,0x02,
+ 0x84,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x80,0x80,0xf1,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,
+ 0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x20,0x11,0x01,
+ 0x00,0x00,0x40,0xf0,0x41,0xf0,0x40,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x02,0x01,0x0f,0x08,0x08,0x06,0x83,0x40,0x40,0x40,0x00,0x00,0x0f,0x02,
+ 0x04,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x01,0x07,0x01,0x07,0x01,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x47,0x4a,0x4a,0x3c,0x00,0x00,0x11,0x0a,
+ 0x04,0x0a,0x11,0x00,0x04,0x04,0x15,0x04,0x04,0x00,0x00,0x00,0x04,0x00,
+ 0x00,0x00,0x04,0x02,0x04,0x08,0x04,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM base0_R_turf_shfgr[4][42] = {
+ { 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,0xef,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,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,0xa0,0x90,0x88,
+ 0x00,0x00,0x00,0x90,0xa1,0x90,0x00,0x00,0x00,0x00,0x9c,0xce,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,0x0f,0x0f,0x0f,
+ 0x00,0x00,0x00,0x0f,0x0f,0x0f,0x00,0x00,0x00,0x00,0x73,0x39,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,0x7c,0x7d,0x7c,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM symb5_R_turf_nomod[4][42] = {
+ { 0x20,0x20,0xf8,0x20,0x20,0x00,0x00,0xc0,0x30,0x0c,0x03,0x00,0x20,0x20,
+ 0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x80,0x00,0xc0,0x00,0x80,0x00,0x43,0x20,0x20,0x20,0xc0,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,0x9c,0xce,0x00,0x00
+ },{ 0x02,0x81,0x47,0x81,0x02,0x00,0x00,0x00,0x0a,0x01,0x00,0x00,0x04,0x04,
+ 0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x22,0xf3,0x0a,0xf3,0x22,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,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM symb5_R_turf_altgr[4][42] = {
+ { 0x10,0x10,0x10,0x30,0x00,0x00,0x03,0x0c,0x30,0xc0,0x00,0x00,0x00,0x00,
+ 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x80,0x80,0xe0,0x80,0x80,0x00,0x00,0x00,0xa0,0x00,0x03,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x04,0x84,0x47,0x84,0x04,0x00,0x06,0x09,0x08,0x08,0x04,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,0x73,0x39,0x00,0x00
+ },{ 0x22,0xf3,0x0a,0xf3,0x22,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,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM numb6_L_turf_nomod[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,
+ 0x50,0x88,0x04,0x00,0x00,0x04,0x04,0xc4,0x34,0x0c,0x00,0xd8,0x24,0x24,
+ 0x24,0xd8,0x00,0x18,0x24,0x24,0x24,0xf8,0x00,0xf8,0x44,0x24,0x14,0xf8
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x01,0x00,0x00,0x00,0x80,0x41,0xe0,0x00,0x00,0xe0,0xa1,0xa1,
+ 0xa1,0x20,0x00,0xc0,0xa1,0xa1,0xa1,0x00,0x00,0x00,0x01,0x01,0x01,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x0f,0x02,0x00,0x04,0x08,0x08,
+ 0x08,0x07,0x00,0x07,0x08,0x08,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,
+ 0x22,0x14,0x08,0x00,0x00,0x00,0x04,0x02,0x7f,0x00,0x00,0x42,0x61,0x51,
+ 0x49,0x46,0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x5e,0x61,0x01,0x61,0x5e}};
+ static const char PROGMEM numb6_L_turf_shift[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
+ 0x88,0x50,0x20,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x00,0x38,0xc6,
+ 0x01,0x00,0x00,0x00,0x01,0xc6,0x38,0x00,0x00,0x50,0x50,0x50,0x50,0x50
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x60,0x90,0xf8,0x90,0x20,0x00,0x20,0x50,0x20,
+ 0x81,0x60,0x00,0x70,0x89,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x8f,0x04,0x03,0x00,0x0c,0x82,0x09,
+ 0x94,0x08,0x00,0x07,0x08,0x89,0x06,0x09,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,
+ 0x22,0x14,0x08,0x00,0x00,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,0x03,0x00,
+ 0x03,0x00,0x00,0x02,0x01,0x00,0x01,0x02,0x00,0x5e,0x61,0x01,0x61,0x5e}};
+ static const char PROGMEM numb6_L_turf_altgr[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xff,0x00,0x00,0x00,0x10,0x10,0xee,0x01,0x01,0x00,0x00,0xff,0x01,
+ 0x01,0x00,0x00,0x00,0x01,0x01,0xff,0x00,0x00,0x01,0x01,0xee,0x10,0x10
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01,0x00,0x00,0x00,0x10,0xf8,0x00,0x01,0x01,0x00,0x10,0xf9,0x01,
+ 0x01,0x00,0x00,0x88,0xa9,0x51,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x08,0x8c,0x0a,0x1f,0x00,0x00,0x00,0x90,
+ 0x90,0x10,0x00,0x00,0x08,0x0c,0x0a,0x1f,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x7b,0x00,0x00,0x00,0x00,0x09,0x0f,0x08,0x00,0x00,0x00,0x09,0x0c,
+ 0x0a,0x09,0x00,0x14,0x7f,0x14,0x7f,0x14,0x00,0x5e,0x61,0x01,0x61,0x5e}};
+ static const char PROGMEM numb6_L_turf_shfgr[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xef,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x90,0xfc,
+ 0x90,0x90,0x00,0x06,0x09,0x09,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0xa8,0x50,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x0a,
+ 0x15,0x0a,0x00,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x7b,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x04,0x05,0x05,0x02,0x00,0x00,0x5e,0x61,0x01,0x61,0x5e}};
+ // QWERTY
+ static const char PROGMEM base0_L_qwer_nomod[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x04,0x08,0x10,0x00,0x00,0x70,
+ 0x88,0x88,0x48,0xf8,0x00,0x78,0x80,0x70,0x80,0x78,0x00,0x70,0xa8,0xa8,
+ 0xa8,0xb0,0x00,0xf8,0x10,0x08,0x08,0x10,0x00,0x08,0x7f,0x88,0x88,0x00
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x18,0x60,0x80,0x00,0x00,0x00,0x00,
+ 0x40,0x40,0x40,0x83,0x00,0x80,0x40,0x40,0x40,0x00,0x00,0x80,0x40,0x40,
+ 0x40,0xf8,0x00,0x00,0xf0,0x48,0x48,0x00,0x00,0x80,0x40,0x40,0x40,0xc0
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0xc0,0x41,0x46,0x18,0x00,0x02,
+ 0x05,0x05,0x05,0x07,0x00,0x04,0x05,0x05,0x05,0x02,0x00,0x03,0x04,0x04,
+ 0x02,0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0xc3,0x14,0x14,0x12,0x0f
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0xff,0x80,0x80,0x00,0x00,0x22,
+ 0x32,0x2a,0x26,0x22,0x00,0x22,0x14,0x08,0x14,0x22,0x00,0x1c,0x22,0x22,
+ 0x22,0x22,0x00,0x06,0x18,0x20,0x18,0x06,0x00,0x3f,0x24,0x22,0x22,0x1c}};
+ static const char PROGMEM base0_L_qwer_shift[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x20,0x10,0x20,0x40,0x20,0x00,0xfc,
+ 0x02,0x42,0x82,0x7c,0x00,0x7e,0x80,0x70,0x80,0x7e,0x00,0xfe,0x12,0x12,
+ 0x12,0x02,0x00,0xfe,0x12,0x12,0x32,0xcc,0x00,0x02,0x02,0xfe,0x02,0x02
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0xe0,
+ 0x91,0x91,0x90,0xe3,0x00,0x60,0x91,0x90,0x91,0x20,0x00,0xf1,0x11,0x11,
+ 0x11,0xe1,0x00,0xf1,0x90,0x90,0x90,0x11,0x00,0xe0,0x10,0x91,0x90,0xa0
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x9f,0x40,0x40,0x00,0x8f,
+ 0x80,0x80,0x80,0x8f,0x00,0x84,0x08,0x08,0x08,0x87,0x00,0x0f,0x88,0x88,
+ 0x88,0x07,0x00,0x8f,0x00,0x00,0x00,0x80,0x00,0x87,0x88,0x88,0x88,0x07
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x04,0x04,0x7b,0x80,0x80,0x00,0x70,
+ 0x48,0x44,0x42,0x41,0x00,0x71,0x0a,0x04,0x0a,0x71,0x00,0x3f,0x40,0x40,
+ 0x40,0x21,0x00,0x07,0x18,0x60,0x18,0x07,0x00,0x7f,0x44,0x44,0x44,0x3b}};
+ static const char PROGMEM base0_R_qwer_nomod[4][42] = {
+ { 0x78,0x80,0x80,0x40,0xf8,0x00,0x78,0x80,0x80,0x40,0xf8,0x00,0x00,0x08,
+ 0xfa,0x80,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0xf8,0x90,0x88,0x88,
+ 0x70,0x00,0x10,0x28,0x44,0x82,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0xf8,0x82,0x42,0x42,0x81,0x00,0x00,0x00,0x40,0xd0,0x00,0x00,0xf8,0x00,
+ 0x80,0x40,0x00,0x00,0x08,0xf8,0x00,0x00,0x00,0x00,0x03,0xc0,0xc0,0x00,
+ 0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x10,0x10,0x0f,0x00,0x00,0x07,0x01,
+ 0x01,0x02,0x04,0x00,0x00,0x03,0x04,0x04,0x00,0x00,0x00,0x16,0x0e,0x00,
+ 0xc0,0x00,0x00,0x40,0x40,0xc0,0x00,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x3e,0x02,0x02,0x02,0x3c,0x00,0x3e,0x02,0x3e,0x02,0x3c,0x00,0x00,0xb0,
+ 0x70,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0xc0,0x30,0x0c,0x03,
+ 0x00,0x00,0x00,0x80,0x80,0xff,0x00,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM base0_R_qwer_shift[4][42] = {
+ { 0x06,0x08,0xf0,0x08,0x06,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x02,
+ 0xfe,0x02,0x00,0x00,0xfc,0x02,0x02,0x02,0xfc,0x00,0xfe,0x12,0x12,0x12,
+ 0x0c,0x00,0x82,0x44,0x28,0x10,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0xf0,0x80,0x81,0x80,0xf0,0x00,0x00,0x01,0x01,0x01,0xf0,0x00,0xf0,0x81,
+ 0x41,0x21,0x10,0x00,0xf0,0x01,0x01,0x01,0x00,0x00,0x01,0xc0,0xc0,0x00,
+ 0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x8f,0x00,0x00,0x00,0x8f,0x00,0x86,0x08,0x08,0x08,0x87,0x00,0x0f,0x00,
+ 0x01,0x82,0x0c,0x00,0x8f,0x08,0x08,0x08,0x08,0x00,0x00,0x86,0x86,0x80,
+ 0x00,0x00,0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x7f,0x03,0x0c,0x30,0x7f,0x00,0x7f,0x01,0x06,0x01,0x7f,0x00,0x04,0x0a,
+ 0x11,0x20,0x00,0x00,0x20,0x11,0x0a,0x04,0x00,0x00,0x01,0x00,0x28,0x04,
+ 0x03,0x00,0x00,0x80,0x80,0x7b,0x04,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM symb5_R_qwer[4][42] = {
+ { 0x00,0x04,0x08,0x10,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x50,0x50,
+ 0x50,0x50,0x50,0x00,0x10,0x10,0xee,0x01,0x01,0x00,0x01,0x01,0xee,0x10,
+ 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xc0,0x00,0x00,0x00,0x00,0xf8,0x09,0x0a,0x02,0x00,0x02,0x0a,0x09,0xf8,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x01,0x80,0x41,0x82,0x01,0x00,0x04,0x04,0x84,0x44,0x04,0x00,0x01,0x41,
+ 0x87,0x01,0x01,0x00,0xc0,0x1f,0x10,0x10,0x00,0x00,0x00,0x10,0xd0,0x1f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x22,0xf3,0x0a,0xf3,0x22,0x00,0x00,0x1e,0x61,0x80,0x00,0x00,0x00,0x80,
+ 0x61,0x1e,0x00,0x00,0x00,0x03,0x0c,0x30,0xc0,0x00,0x00,0x00,0xff,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM numb6_L_qwer_nomod[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,
+ 0x50,0x88,0x04,0x00,0x00,0x04,0x04,0xc4,0x34,0x0c,0x00,0xd8,0x24,0x24,
+ 0x24,0xd8,0x00,0x18,0x24,0x24,0x24,0xf8,0x00,0xf8,0x44,0x24,0x14,0xf8
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x70,0x00,0x71,0x00,0x00,0x00,0x80,0x41,0xe0,0x00,0x00,0xe0,0xa1,0xa1,
+ 0xa1,0x20,0x00,0xc0,0xa1,0xa1,0xa1,0x00,0x00,0x00,0x01,0x71,0x01,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x0f,0x02,0x00,0x04,0x08,0x08,
+ 0x08,0x07,0x00,0x07,0x08,0x08,0x08,0x07,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,
+ 0x22,0x14,0x08,0x00,0x00,0x00,0x04,0x02,0x7f,0x00,0x00,0x42,0x61,0x51,
+ 0x49,0x46,0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x5e,0x61,0x01,0x61,0x5e}};
+ static const char PROGMEM numb6_L_qwer_shift[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0xd8,0x24,0x54,0x88,0x40,0x00,0x50,0x20,0xf8,
+ 0x20,0x50,0x00,0x00,0x38,0xc6,0x01,0x00,0x00,0x00,0x01,0xc6,0x38,0x00
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x70,0x00,0x70,0x00,0x00,0x60,0x91,0xf9,0x90,0x21,0x00,0x20,0x50,0x20,
+ 0x80,0x60,0x00,0x40,0x20,0x10,0x21,0x40,0x00,0x00,0x71,0x00,0x70,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x8f,0x04,0x03,0x00,0x0c,0x02,0x09,
+ 0x14,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x00,0x00,0x00,0x3e,0x41,0x5d,
+ 0x55,0x5e,0x00,0x14,0x7f,0x14,0x7f,0x14,0x00,0x00,0x00,0x00,0x00,0x00}};
+
+ // UNIVERSAL
+ static const char PROGMEM char1_L[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe2,0xae,0x42,0x00,0x00,0x20,0x44,0x40,0x4c,0x20,0x00,0x12,0xa4,0x88,
+ 0xa4,0x12,0x00,0x08,0xf8,0x08,0xf8,0x08,0x00,0x78,0x80,0x80,0x80,0x78
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x41,0x40,0x41,0x80,0x00,0x80,0x40,0x40,0x40,0x80,0x00,0x81,0x40,0x40,
+ 0x40,0x81,0x00,0xc0,0x00,0xc0,0x00,0xc0,0x00,0x00,0xc0,0x00,0x00,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,
+ 0xc4,0x84,0xc2,0x07,0x00,0x03,0x04,0x04,0x04,0x03,0x00,0x02,0x85,0x05,
+ 0x04,0x82,0x00,0x03,0x04,0x1f,0x04,0x03,0x00,0x80,0x83,0x84,0x82,0x80
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,
+ 0xc4,0x44,0xef,0x3b,0x00,0x3e,0x49,0x49,0x49,0x3e,0x00,0x02,0x7f,0x09,
+ 0x09,0x78,0x00,0x3e,0x08,0x08,0x14,0x22,0x00,0x20,0x24,0x24,0x24,0x20}};
+ static const char PROGMEM char1_R[4][42] = {
+ { 0x70,0x88,0xf0,0x88,0x70,0x00,0xfe,0x02,0x02,0x02,0x06,0x00,0x88,0x48,
+ 0x70,0x90,0x88,0x00,0xf0,0x88,0x88,0x88,0x70,0x00,0xc0,0x30,0x0c,0x30,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0xa0,0x50,0x53,0x90,0x20,0x00,0xc0,0x80,0x40,0x40,0x80,0x00,0x40,0x40,
+ 0xc0,0x40,0x40,0x00,0xc3,0x00,0x00,0x00,0xc0,0x00,0x80,0x40,0xc0,0x40,
+ 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x03,0x84,0x84,0x04,0x03,0x00,0x07,0x00,0x00,0x00,0x1f,0x00,0x00,0x80,
+ 0x83,0x84,0x00,0x00,0x00,0x83,0x54,0x8b,0x00,0x00,0x83,0x84,0x84,0x83,
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0xff,0x24,0x24,0x27,0x18,0x00,0x7e,0x10,0x20,0x20,0x1e,0x00,0x2f,0x30,
+ 0x00,0x30,0x2f,0x00,0xe0,0x38,0x25,0x38,0xe0,0x00,0x18,0x26,0xa1,0xa0,
+ 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM game2_L[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,
+ 0x82,0xa2,0x42,0xbc,0x00,0x3e,0xc0,0x30,0xc0,0x3e,0x00,0xfe,0x92,0x92,
+ 0x92,0x82,0x00,0xfe,0x12,0x12,0x32,0xcc,0x00,0x02,0x02,0xfe,0x02,0x02
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0xe0,0x00,0xe0,
+ 0x90,0x90,0x90,0xe1,0x00,0x60,0x90,0x90,0x90,0x20,0x00,0xf0,0x10,0x10,
+ 0x10,0xe0,0x00,0xf0,0x90,0x90,0x90,0x10,0x00,0xe0,0x10,0x90,0x90,0xa0
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x00,0x87,
+ 0x80,0x80,0x80,0x87,0x00,0x82,0x04,0x04,0x04,0x83,0x00,0x07,0x84,0x84,
+ 0x84,0x03,0x00,0x87,0x00,0x00,0x00,0x80,0x00,0x83,0x84,0x84,0x84,0x03
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x08,0x3c,0x02,0x3c,0x08,0x00,0x30,
+ 0x28,0x24,0x22,0x21,0x00,0x31,0x0a,0x04,0x0a,0x31,0x00,0x1f,0x20,0x20,
+ 0x20,0x11,0x00,0x03,0x0c,0x30,0x0c,0x03,0x00,0x3f,0x24,0x24,0x24,0x1b}};
+ static const char PROGMEM medi3_R_nomod[4][42] = {
+ { 0x03,0x0c,0xb0,0x0c,0x03,0x00,0x3f,0x02,0x9c,0x02,0x3f,0x00,0x3f,0x04,
+ 0x84,0x04,0x3f,0x00,0x22,0x25,0xa5,0x25,0x18,0x00,0x3f,0x25,0xa5,0x25,
+ 0x1a,0x00,0x00,0xe0,0x8f,0x02,0x31,0x49,0xfa,0x00,0xe7,0x73,0x00,0x00
+ },{ 0xc0,0x01,0x73,0x01,0xc0,0x00,0xf0,0x81,0xc3,0xe1,0xf0,0x00,0x00,0x71,
+ 0x03,0x71,0x00,0x00,0x00,0xc1,0xc3,0xc1,0x00,0x00,0xf0,0xe1,0xc3,0x81,
+ 0xf0,0x00,0x00,0x03,0xe2,0x21,0xe0,0x21,0xc0,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x01,0x02,0x02,0x02,0x01,0x00,0x07,0x00,0x01,0x03,0x87,0x00,0x00,0x1f,
+ 0x0e,0x04,0x80,0x00,0x00,0x03,0x03,0x03,0x00,0x00,0x07,0x03,0x01,0x00,
+ 0x87,0x00,0x00,0x40,0xa6,0xa8,0x08,0x04,0x8e,0x00,0x73,0x39,0x00,0x00
+ },{ 0x3e,0x31,0x01,0x31,0x3e,0x00,0x00,0x46,0x46,0x4f,0x1f,0x00,0x00,0xa6,
+ 0x46,0xaf,0x1f,0x00,0x28,0x2c,0x2e,0x2c,0x28,0x00,0x00,0x46,0xe6,0x4f,
+ 0x1f,0x00,0x00,0x02,0x72,0x8a,0x89,0x00,0x1e,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM medi3_R_shift[4][42] = {
+ { 0x03,0x0c,0x30,0x0c,0x03,0x00,0x3f,0x02,0x1c,0x02,0x3f,0x00,0x3f,0x04,
+ 0x04,0x04,0x3f,0x00,0x22,0x25,0x25,0x25,0x18,0x00,0x3f,0x25,0x25,0x25,
+ 0x1a,0x00,0x00,0xe0,0x8f,0x02,0x31,0x49,0xfa,0x00,0xe7,0x73,0x00,0x00
+ },{ 0xc0,0x01,0x71,0x01,0xc0,0x00,0xf0,0x81,0xc1,0xe1,0xf0,0x00,0x00,0x71,
+ 0x01,0x71,0x00,0x00,0x00,0xc1,0xc1,0xc1,0x00,0x00,0xf0,0xe1,0xc1,0x81,
+ 0xf0,0x00,0x00,0x03,0xe2,0x21,0xe0,0x21,0xc0,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x01,0x02,0x02,0x02,0x01,0x00,0x07,0x00,0x01,0x03,0x87,0x00,0x00,0x1f,
+ 0x0e,0x04,0x80,0x00,0x00,0x03,0x03,0x03,0x00,0x00,0x07,0x03,0x01,0x00,
+ 0x87,0x00,0x00,0x40,0xa6,0xa8,0x08,0x04,0x8e,0x00,0x73,0x39,0x00,0x00
+ },{ 0x3e,0x31,0x01,0x31,0x3e,0x00,0x00,0x46,0x46,0x4f,0x1f,0x00,0x00,0xa6,
+ 0x46,0xaf,0x1f,0x00,0x28,0x2c,0x2e,0x2c,0x28,0x00,0x00,0x46,0xe6,0x4f,
+ 0x1f,0x00,0x00,0x02,0x72,0x8a,0x89,0x00,0x1e,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM navi4_R[4][42] = {
+ { 0xe0,0x10,0x54,0x38,0x10,0x00,0xfc,0x24,0x24,0x24,0x18,0x00,0x0c,0x10,
+ 0xe0,0x10,0x0c,0x00,0x8c,0x50,0x20,0x50,0x8c,0x00,0xc0,0xbe,0xa2,0xbe,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x80,0xc1,0xa1,0x81,0x00,0x00,0x01,0x80,0x40,0x20,0x00,0x00,0x00,0x00,
+ 0xf1,0x00,0x00,0x00,0x41,0x20,0xd0,0x20,0x41,0x00,0x01,0x21,0x41,0x81,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x00,0x49,0x4a,0x48,0x87,0x00,0x81,0x82,0x85,0x89,0x01,0x00,0x01,0x02,
+ 0x85,0x02,0x01,0x00,0x40,0x40,0x47,0x40,0x40,0x00,0x81,0x09,0x05,0x02,
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x39,0x00,0x00
+ },{ 0x12,0x65,0x85,0x65,0x17,0x00,0x07,0x01,0x06,0x18,0x60,0x00,0x88,0x90,
+ 0xaf,0x90,0x88,0x00,0x04,0x02,0x7d,0x02,0x04,0x00,0x01,0x46,0x58,0x60,
+ 0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ static const char PROGMEM func7_L[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0xff,0x09,0xe9,0xc9,0x01,0x00,0xe0,0x00,
+ 0x10,0x08,0xfc,0x00,0x00,0x08,0x84,0x44,0x24,0x18,0x00,0x88,0x04,0x24,
+ 0x24,0xd8,0x00,0x60,0x50,0x48,0xfc,0x40,0x00,0x70,0x80,0x9c,0x80,0x70
+ },{ 0x00,0x00,0xce,0x9c,0x00,0xf0,0x00,0x00,0x9f,0x00,0x03,0x0c,0x1f,0x00,
+ 0xe0,0xa0,0xa1,0x20,0x00,0xc1,0xa1,0xa1,0xa1,0x01,0x00,0x20,0x21,0x21,
+ 0xa1,0x60,0x00,0xc0,0x20,0x20,0x21,0xc0,0x00,0x40,0xe0,0x50,0x40,0x80
+ },{ 0x00,0x00,0x39,0x73,0x00,0xef,0x02,0x83,0xe4,0x00,0x0e,0x15,0x16,0x00,
+ 0x04,0x08,0x08,0x07,0x00,0x07,0x48,0xc8,0x08,0x07,0x00,0x00,0x40,0xce,
+ 0x01,0x00,0x00,0x06,0x49,0xc9,0x09,0x06,0x00,0x06,0x08,0x49,0x08,0x07
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x05,0x04,0x03,0x90,0xa8,0xa8,0x40,0x06,
+ 0x49,0x49,0x49,0x3e,0x00,0x7c,0xa2,0x93,0x8a,0x7c,0x00,0x00,0x08,0x07,
+ 0xfe,0x00,0x00,0x84,0xc2,0xa3,0x92,0x8c,0x00,0x70,0x38,0x0d,0x38,0x70}};
+ static const char PROGMEM mous8_L[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x3c,0x84,0xbc,0x84,0x38,0x00,0x00,0x00,0x10,
+ 0x28,0x92,0xc5,0x82,0x00,0xfe,0x1f,0x1f,0x01,0xfe,0x00,0xfe,0x01,0x19,
+ 0x01,0xfe,0x00,0xfe,0x01,0x1f,0x1f,0xfe,0x00,0x10,0x38,0x92,0xc7,0x82
+ },{ 0x00,0x00,0xce,0x9c,0x00,0xe7,0x08,0x08,0x08,0xe7,0x00,0x00,0x00,0x00,
+ 0x00,0x80,0x01,0x00,0x00,0x01,0x01,0x81,0x01,0x01,0x00,0x01,0x01,0x81,
+ 0x01,0x01,0x00,0x01,0x01,0x81,0x01,0x01,0x00,0x60,0x50,0xf8,0x41,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x91,0xaa,0xaa,0xa9,0x43,0x00,0x00,0x00,0x02,
+ 0x07,0xca,0x02,0x02,0x00,0x02,0x01,0xcf,0x01,0x02,0x00,0x02,0x04,0x0f,
+ 0x04,0x02,0x00,0x02,0x02,0xca,0x07,0x02,0x00,0xdc,0x58,0x5c,0x18,0x1f
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x1c,0x2a,0x2a,0x2a,0x2c,0x00,0x00,0x00,0x0c,
+ 0x33,0xc0,0x00,0x00,0x00,0x0c,0x03,0x00,0x03,0x0c,0x00,0x0c,0x30,0xc0,
+ 0x30,0x0c,0x00,0x00,0x00,0xc0,0x33,0x0c,0x00,0xe5,0xc9,0xe6,0xc0,0xf8}};
+ static const char PROGMEM musi9_L[4][42] = {
+ { 0x00,0x00,0x73,0xe7,0x00,0x00,0x00,0x00,0x00,0xfe,0x04,0x18,0x04,0xfe,
+ 0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x8c,0x12,0x12,0x12,0xe4,0x00,
+ 0x00,0x02,0xfe,0x02,0x00,0x00,0xfc,0x02,0x02,0x02,0x84,0x00,0x00,0x00
+ },{ 0x00,0x00,0xce,0x9c,0x00,0x00,0xc0,0xe0,0xf0,0xf9,0xf8,0xf8,0xf8,0xf9,
+ 0xf0,0xe0,0xc0,0x01,0x01,0x01,0x00,0xf0,0xf0,0x01,0x01,0xf1,0xf0,0x00,
+ 0x00,0x01,0x01,0x01,0x00,0x00,0xf8,0xf1,0xe1,0xc1,0x80,0x00,0x00,0x00
+ },{ 0x00,0x00,0x39,0x73,0x00,0x00,0x07,0x0f,0x1f,0x3f,0x3f,0x3f,0x3f,0x3f,
+ 0x1f,0x0f,0x07,0x00,0x00,0x00,0x00,0x1f,0x1f,0x00,0x00,0x1f,0x1f,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00,0x00
+ },{ 0x00,0x00,0xe7,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x08,
+ 0xf8,0x08,0xf0,0x00,0x70,0x88,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x48,
+ 0xff,0x00,0x70,0xa8,0xa8,0xa8,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};
+ static const char PROGMEM musi9_R[4][42] = {
+ { 0x00,0x00,0x00,0xfe,0x04,0x18,0x04,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,
+ 0xfe,0x00,0x8c,0x12,0x12,0x12,0xe4,0x00,0x00,0x02,0xfe,0x02,0x00,0x00,
+ 0xfc,0x02,0x02,0x02,0x84,0x00,0x00,0x00,0x00,0x00,0xe7,0x73,0x00,0x00
+ },{ 0x00,0x00,0x00,0x81,0x60,0x10,0x60,0x81,0x60,0x10,0x00,0x01,0x01,0x01,
+ 0xe0,0xe0,0x60,0x61,0x61,0x61,0x60,0xf8,0x70,0x21,0x01,0x01,0xc0,0xe0,
+ 0x60,0x01,0xf9,0xf9,0x00,0x60,0xe0,0xc0,0x00,0x00,0x9c,0xce,0x00,0x00
+ },{ 0x18,0x24,0x4b,0x48,0x48,0x4c,0x4b,0x48,0x4b,0x2c,0x18,0x00,0x00,0x00,
+ 0x4f,0xe7,0xf0,0x60,0x60,0x60,0x60,0x60,0x7e,0x7f,0x00,0x0f,0x3f,0x70,
+ 0x60,0xc0,0xc1,0xc1,0xc0,0x60,0x70,0x3f,0x0f,0x00,0x73,0x39,0x00,0x00
+ },{ 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x08,0xf8,0x08,0xf0,0x00,0x70,0x88,
+ 0x88,0x88,0x71,0x00,0x70,0x88,0x88,0x48,0xff,0x00,0x70,0xa8,0xa8,0xa8,
+ 0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xe7,0x00,0x00}};
+ uint8_t this_layout = userspace_config.layout % 3;
+
+ // Render the requested image on the given column and row
+ // Don't grab highest layer; instead compare from top to bottom.
+ // Highest layer might be on the other side
+ if (isLeft) {
+ if (layer_state_cmp(layer_state, _MUSI)) {
+ draw_image(row, col, musi9_L);
+ } else if (layer_state_cmp(layer_state, _MOUS)) {
+ draw_image(row, col, mous8_L);
+ } else if (layer_state_cmp(layer_state, _FUNC)) {
+ draw_image(row, col, func7_L);
+ } else if (layer_state_cmp(layer_state, _NUMB)) {
+ switch (this_layout) {
+ case 0: // Dvorak
+ if (mods & MOD_MASK_SHIFT) {
+ draw_image(row, col, numb6_L_dvor_shift);
+ } else {
+ draw_image(row, col, numb6_L_dvor_nomod);
+ }
+ break;
+ case 1: // Turkish F
+ if ((mods & MOD_MASK_SHIFT) && (mods & MOD_BIT(KC_RALT))) {
+ // Shift + AltGr
+ draw_image(row, col, numb6_L_turf_shfgr);
+ } else if (mods & MOD_MASK_SHIFT) {
+ // Shift
+ draw_image(row, col, numb6_L_turf_shift);
+ } else if (mods & MOD_BIT(KC_RALT)) {
+ // AltGr
+ draw_image(row, col, numb6_L_turf_altgr);
+ } else {
+ // Normal
+ draw_image(row, col, numb6_L_turf_nomod);
+ }
+ break;
+ case 2: // Qwerty
+ if (mods & MOD_MASK_SHIFT) {
+ draw_image(row, col, numb6_L_qwer_shift);
+ } else {
+ draw_image(row, col, numb6_L_qwer_nomod);
+ }
+ break;
+ }
+ } else if (layer_state_cmp(layer_state, _GAME)) {
+ draw_image(row, col, game2_L);
+ } else if (layer_state_cmp(layer_state, _CHAR)) {
+ draw_image(row, col, char1_L);
+ } else {
+ switch (this_layout) {
+ case 0: // Dvorak
+ if (mods & MOD_MASK_SHIFT) {
+ draw_image(row, col, base0_L_dvor_shift);
+ } else {
+ draw_image(row, col, base0_L_dvor_nomod);
+ }
+ break;
+ case 1: // Turkish F
+ if ((mods & MOD_MASK_SHIFT) && (mods & MOD_BIT(KC_RALT))) {
+ // Shift + AltGr
+ draw_image(row, col, base0_L_turf_shfgr);
+ } else if (mods & MOD_MASK_SHIFT) {
+ // Shift
+ draw_image(row, col, base0_L_turf_shift);
+ } else if (mods & MOD_BIT(KC_RALT)) {
+ // AltGr
+ draw_image(row, col, base0_L_turf_altgr);
+ } else {
+ // Normal
+ draw_image(row, col, base0_L_turf_nomod);
+ }
+ break;
+ case 2: // Qwerty
+ if (mods & MOD_MASK_SHIFT) {
+ draw_image(row, col, base0_L_qwer_shift);
+ } else {
+ draw_image(row, col, base0_L_qwer_nomod);
+ }
+ break;
+ }
+ }
+ } else {
+ if (layer_state_cmp(layer_state, _MUSI)) {
+ draw_image(row, col, musi9_R);
+ } else if (layer_state_cmp(layer_state, _SYMB)) {
+ switch (this_layout) {
+ case 0: // Dvorak
+ draw_image(row, col, symb5_R_dvor);
+ break;
+ case 1: // Turkish f
+ if (mods & MOD_BIT(KC_RALT)) {
+ // AltGr
+ draw_image(row, col, symb5_R_turf_altgr);
+ } else {
+ // Normal
+ draw_image(row, col, symb5_R_turf_nomod);
+ }
+ break;
+ case 2: // Qwerty
+ draw_image(row, col, symb5_R_qwer);
+ break;
+ }
+ } else if (layer_state_cmp(layer_state, _NAVI)) {
+ draw_image(row, col, navi4_R);
+ } else if (layer_state_cmp(layer_state, _MEDI)) {
+ if (mods & MOD_MASK_SHIFT) {
+ draw_image(row, col, medi3_R_shift);
+ } else {
+ draw_image(row, col, medi3_R_nomod);
+ }
+ } else if (layer_state_cmp(layer_state, _CHAR)) {
+ draw_image(row, col, char1_R);
+ } else {
+ switch (this_layout) {
+ case 0: // Dvorak
+ if (mods & MOD_MASK_SHIFT) {
+ draw_image(row, col, base0_R_dvor_shift);
+ } else {
+ draw_image(row, col, base0_R_dvor_nomod);
+ }
+ break;
+ case 1: // Turkish F
+ if ((mods & MOD_MASK_SHIFT) && (mods & MOD_BIT(KC_RALT))) {
+ // Shift + AltGr
+ draw_image(row, col, base0_R_turf_shfgr);
+ } else if (mods & MOD_MASK_SHIFT) {
+ // Shift
+ draw_image(row, col, base0_R_turf_shift);
+ } else if (mods & MOD_BIT(KC_RALT)) {
+ // AltGr
+ draw_image(row, col, base0_R_turf_altgr);
+ } else {
+ // Normal
+ draw_image(row, col, base0_R_turf_nomod);
+ }
+ break;
+ case 2: // Qwerty
+ if (mods & MOD_MASK_SHIFT) {
+ draw_image(row, col, base0_R_qwer_shift);
+ } else {
+ draw_image(row, col, base0_R_qwer_nomod);
+ }
+ break;
+ }
+ }
+ }
+}
+
+// Render the RGB state on the given column and row
+void render_rgb(uint8_t row, uint8_t col) {
+ static const char PROGMEM rgb_enab[12] = {0x08,0x81,0x3c,0x42,0x99,0xbd,0xbd,0x99,0x42,0x3c,0x81,0x10};
+ static const char PROGMEM rgb_disa[12] = {0x08,0x81,0x3c,0x42,0x81,0x81,0x81,0x81,0x42,0x3c,0x81,0x10};
+ static char rgb_temp4[4] = {0};
+ static char rgb_temp3[3] = {0};
+
+ oled_set_cursor(col, row);
+# ifdef RGB_MATRIX_ENABLE
+ if (rgb_matrix_is_enabled()) {
+ oled_write_raw_P(rgb_enab, 12);
+ } else {
+ oled_write_raw_P(rgb_disa, 12);
+ }
+ oled_set_cursor(col + 2, row);
+ oled_write(" hue sat val", false);
+ oled_set_cursor(col, row + 1);
+ itoa(rgb_matrix_get_mode(), rgb_temp3, 10);
+ oled_write(rgb_temp3, false);
+ oled_write(" ", false);
+ itoa(rgb_matrix_get_hue(), rgb_temp4, 10);
+ oled_write(rgb_temp4, false);
+ oled_write(" ", false);
+ itoa(rgb_matrix_get_sat(), rgb_temp4, 10);
+ oled_write(rgb_temp4, false);
+ oled_write(" ", false);
+ itoa(rgb_matrix_get_val(), rgb_temp4, 10);
+ oled_write(rgb_temp4, false);
+# else // RGB_MATRIX_ENABLE
+ oled_write("-RGB disabled-", false);
+# endif // RGB_MATRIX_ENABLE
+}
+
+void render_status_left(uint8_t row, uint8_t col) {
+ // Left side looks like this on the left half
+ // (Should be 14 characters per line)
+ // Mods: <OS> <Alt/Gr> <Ctrl> <Shift>
+ // Enc: <8 len str>
+ // Wpm: <wpm here>
+ // Layout: <dvorak/qwerty/tur. f>
+ // Right half is whatever layer image needs be
+ uint8_t this_mod = get_mods();
+ uint8_t this_layer = get_highest_layer(layer_state);
+
+ // MODIFIERS
+ render_modifiers(row + 0, col + 0, this_mod);
+ // Encoders
+ render_encoder(row + 1, col + 0, 0, this_layer);
+ // WPM text
+ render_wpm(row + 2, col + 0);
+ // Visual layout
+ render_keymap(row + 3, col + 0, false);
+ // Draw the image after 14'th character
+ render_layout(row + 0, col + 14, this_mod, true);
+}
+
+void render_status_right(uint8_t row, uint8_t col) {
+ // Right half is whatever layer image needs be on the left
+ // Right side looks like this on the right half
+ // (Should be after the 12'th character; max 14 characters per line)
+ // Mods: <OS> <Alt/Gr> <Ctrl> <Shift>
+ // Enc: <8 len str>
+ // Wpm: <wpm here>
+ // Layout: <dvorak/qwerty/tur. f>
+ uint8_t this_mod = get_mods();
+ uint8_t this_layer = get_highest_layer(layer_state);
+
+ // Draw the image
+ render_layout(row + 0, col + 0, this_mod, false);
+ // Modifiers
+ render_modifiers(row + 0, col + 7, this_mod);
+ // Encoder
+ render_encoder(row + 1, col + 7, 1, this_layer);
+ // RGB State (2 rows)
+ render_rgb(row + 2, col + 7);
+}
diff --git a/users/bbaserdem/bb-oled-extra.h b/users/bbaserdem/bb-oled-extra.h
new file mode 100644
index 0000000000..c051e6226c
--- /dev/null
+++ b/users/bbaserdem/bb-oled-extra.h
@@ -0,0 +1,25 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+// OLED layout images writer function
+void render_modifiers(uint8_t row, uint8_t col, uint8_t mods);
+void render_layout(uint8_t row, uint8_t col, uint8_t mods, bool isLeft);
+void render_rgb(uint8_t row, uint8_t col);
+void render_status_left(uint8_t row, uint8_t col);
+void render_status_right(uint8_t row, uint8_t col);
diff --git a/users/bbaserdem/bb-oled.c b/users/bbaserdem/bb-oled.c
new file mode 100644
index 0000000000..cf00193c03
--- /dev/null
+++ b/users/bbaserdem/bb-oled.c
@@ -0,0 +1,216 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-oled.h"
+
+#include <string.h>
+// Grab the print function
+#ifdef ENCODER_ENABLE
+# include "bb-encoder.h"
+#endif // ENCODER_ENABLE
+
+/* OLED
+ * This contains general purpose oled code
+ */
+
+// Allow default to be overwritten by keymap if they return false
+__attribute__ ((weak)) bool oled_task_keymap(void) {return true;}
+
+// Do sane defaults for regular oled rendering
+void oled_task_user(void) {
+ if (is_oled_on()) {
+ if (oled_task_keymap()) {
+ render_status_lite(0, 0);
+ }
+ }
+}
+
+/*-------------------------*\
+|*---RENDERING FUNCTIONS---*|
+\*-------------------------*/
+void render_qmk_logo(uint8_t row, uint8_t col) {
+ static const char PROGMEM qmk_logo[] = {
+ 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,0};
+ oled_set_cursor(col, row);
+ oled_write_P(qmk_logo, false);
+}
+
+void render_layer(uint8_t row, uint8_t col, uint8_t top_layer) {
+ // Write the layer state; 17 chars
+ oled_set_cursor(col, row);
+ oled_write("Layer: ", false);
+ switch (top_layer) {
+ case _BASE:
+ oled_write("Default ", false);
+ break;
+ case _CHAR:
+ oled_write("Sp. Chars ", false);
+ break;
+ case _GAME:
+ oled_write("Gaming ", false);
+ break;
+ case _MEDI:
+ oled_write("Media Ctr ", false);
+ break;
+ case _NAVI:
+ oled_write("Navigation", false);
+ break;
+ case _SYMB:
+ oled_write("Symbols ", false);
+ break;
+ case _NUMB:
+ oled_write("Numpad ", false);
+ break;
+ case _FUNC:
+ oled_write("Funct Keys", false);
+ break;
+ case _MOUS:
+ oled_write("Mouse Keys", false);
+ break;
+ case _MUSI:
+ oled_write("Music Mode", false);
+ break;
+ default:
+ oled_write("?? N/A ?? ", false);
+ }
+}
+
+void render_modifiers_lite(uint8_t row, uint8_t col, uint8_t mods) {
+ // Write the modifier state, 16 characters
+ oled_set_cursor(col, row);
+ oled_write((mods & MOD_MASK_SHIFT ) ? "Shft " : " ", false);
+ oled_write((mods & MOD_MASK_CTRL ) ? "Ctrl " : " ", false);
+ oled_write((mods & MOD_MASK_ALT ) ? "Alt" : " ", false);
+ oled_write((mods & MOD_BIT(KC_RALT)) ? "G " : " ", false);
+ oled_write((mods & MOD_MASK_GUI ) ? "Meta " : " ", false);
+}
+
+void render_encoder(uint8_t row, uint8_t col, uint8_t index, uint8_t layer) {
+ // Renders the encoder state, 14 characters
+ oled_set_cursor(col, row);
+
+# ifdef ENCODER_ENABLE
+ static char encoder_temp9[9] = {0};
+ oled_write("Enc: ", false);
+ encoder_state_string(index, layer, encoder_temp9);
+ oled_write(encoder_temp9, false);
+# else // ENCODER_ENABLE
+ oled_write("No enc. avail.", false);
+# endif // ENCODER_ENABLE
+}
+
+void render_wpm(uint8_t row, uint8_t col) {
+ // Renders the WPM, 8 characters
+ oled_set_cursor(col, row);
+# ifdef WPM_ENABLE
+ static char wpm_temp4[4] = {0};
+ oled_write("WPM: ", false);
+ itoa(get_current_wpm(), wpm_temp4, 10);
+ oled_write(wpm_temp4, false);
+ oled_write(" ", false);
+# else // WPM_ENABLE
+ oled_write("WPM: N/A", false);
+# endif // WPM_ENABLE
+}
+
+// Writes the currently used OLED display layout
+void render_keymap(uint8_t row, uint8_t col, bool isLite) {
+ // Render the oled layout; lite is 11, regular is 14 characters
+ oled_set_cursor(col, row);
+ if (isLite) {
+ oled_write("KM: ", false);
+ } else {
+ oled_write("Layout: ", false);
+ }
+ switch (userspace_config.layout % 3) {
+ case 0:
+ oled_write("Dvorak", false);
+ break;
+ case 1:
+ oled_write("Tur. F", false);
+ break;
+ case 2:
+ oled_write("Qwerty", false);
+ break;
+ }
+ if (isLite) {
+ oled_write(" ", false);
+ }
+}
+
+// Writes the currently used OLED display layout
+#ifdef RGB_MATRIX_ENABLE
+void render_rgb_lite(uint8_t row, uint8_t col) {
+ // Writes the currently used OLED display layout, 19 characters
+ static char rgb_temp4[4] = {0};
+ // Render the oled layout
+ oled_set_cursor(col, row);
+ oled_write("m", false);
+ itoa(rgb_matrix_get_mode(), rgb_temp4, 10);
+ oled_write(rgb_temp4, false);
+ oled_write(" h", false);
+ itoa(rgb_matrix_get_hue(), rgb_temp4, 10);
+ oled_write(rgb_temp4, false);
+ oled_write(" s", false);
+ itoa(rgb_matrix_get_sat(), rgb_temp4, 10);
+ oled_write(rgb_temp4, false);
+ oled_write(" v", false);
+ itoa(rgb_matrix_get_val(), rgb_temp4, 10);
+ oled_write(rgb_temp4, false);
+}
+#endif // RGB_MATRIX_ENABLE
+
+void render_status_lite(uint8_t row, uint8_t col) {
+ // Function to print state information; for low flash memory
+ uint8_t this_layer = get_highest_layer(layer_state);
+ uint8_t this_mod = get_mods();
+
+ // Line 1: Layer State
+ render_layer(row + 0, col + 0, this_layer);
+
+ // Line 2: Mod or info
+ switch (this_layer) {
+ // Show RGB mode as an overlay in media mode.
+# ifdef RGB_MATRIX_ENABLE
+ case _MEDI:
+ render_rgb_lite(row + 1, col + 0);
+ break;
+# endif // RGB_MATRIX_ENABLE
+ // Show the modifier if nothing else is doing anything
+ default:
+ render_modifiers_lite(row + 1, col + 0, this_mod);
+ break;
+ }
+
+ // Line 3: WPM and layout
+ render_keymap(row + 2, col + 0, true);
+ render_wpm(row + 2, col + 11);
+
+ // Line 4: Encoder states
+# ifdef SPLIT_KEYBOARD
+ if (is_keyboard_left()) {
+ render_encoder(row + 3, col + 0, 0, this_layer);
+ } else {
+ render_encoder(row + 3, col + 0, 1, this_layer);
+ }
+# else // SPLIT_KEYBOARD
+ render_encoder(row + 3, col + 0, 0, this_layer);
+# endif // SPLIT_KEYBOARD
+}
diff --git a/users/bbaserdem/bb-oled.h b/users/bbaserdem/bb-oled.h
new file mode 100644
index 0000000000..a355c88ca9
--- /dev/null
+++ b/users/bbaserdem/bb-oled.h
@@ -0,0 +1,32 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+// Contain the main oled writer here
+void oled_task_user(void);
+// Some generic rendering functions
+void render_qmk_logo(uint8_t row, uint8_t col);
+void render_layer(uint8_t row, uint8_t col, uint8_t top_layer);
+void render_modifiers_lite(uint8_t row, uint8_t col, uint8_t mods);
+void render_encoder(uint8_t row, uint8_t col, uint8_t index, uint8_t layer);
+void render_wpm(uint8_t row, uint8_t col);
+void render_keymap(uint8_t row, uint8_t col, bool isLite);
+#ifdef RGB_MATRIX_ENABLE
+void render_rgb_lite(uint8_t row, uint8_t col);
+#endif // RGB_MATRIX_ENABLE
+void render_status_lite(uint8_t row, uint8_t col);
diff --git a/users/bbaserdem/bb-rgb.c b/users/bbaserdem/bb-rgb.c
new file mode 100644
index 0000000000..bdb7f12bbd
--- /dev/null
+++ b/users/bbaserdem/bb-rgb.c
@@ -0,0 +1,130 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-rgb.h"
+#include "color.h"
+
+#define X_DIV 224/2
+/* Code relating to per-key RGB LED stuff
+ */
+
+// Allow hooking into the RGB matrix indications using keymap code
+
+// Modulates the brightness of indicator
+RGB helper_dimmer(uint8_t r, uint8_t g, uint8_t b) {
+ RGB output;
+ output.r = r / 2;
+ output.g = g / 2;
+ output.b = b / 2;
+ return output;
+}
+// x range from 0-left to 224-right
+// y range from 0-top to 64-bottom
+void helper_painter(uint8_t led_min, uint8_t led_max, RGB col, uint8_t side) {
+ if (side == 1) {
+ // Left
+ for(uint8_t i = led_min; i <= led_max; i++) {
+ if((g_led_config.point[i].x < X_DIV) && (g_led_config.flags[i] & LED_FLAG_INDICATOR)) {
+ rgb_matrix_set_color(i, col.r, col.g, col.b);
+ }
+ }
+ } else if (side == 2) {
+ // Right
+ for(uint8_t i = led_min; i <= led_max; i++) {
+ if((g_led_config.point[i].x > X_DIV) && (g_led_config.flags[i] & LED_FLAG_INDICATOR)) {
+ rgb_matrix_set_color(i, col.r, col.g, col.b);
+ }
+ }
+ } else if (side == 0) {
+ // Both
+ for(uint8_t i = led_min; i <= led_max; i++) {
+ if(g_led_config.flags[i] & LED_FLAG_INDICATOR) {
+ rgb_matrix_set_color(i, col.r, col.g, col.b);
+ }
+ }
+ }
+}
+
+// Allow to turn off global handling
+__attribute__ ((weak)) bool rgb_matrix_indicators_advanced_keymap(uint8_t led_min, uint8_t led_max) {
+ return false;
+}
+// Set RGB state depending on layer
+void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
+ uint8_t thisInd = 3;
+ RGB thisCol;
+ // Load keymap hooks
+ if(rgb_matrix_indicators_advanced_keymap(led_min, led_max)) {
+ return;
+ }
+ // Grab color info
+ switch (get_highest_layer(layer_state)) {
+ case _GAME: // Set left side as purple
+ thisCol = helper_dimmer(RGB_PURPLE);
+ thisInd = 1;
+ break;
+ case _CHAR: // Set full board as gold
+ thisCol = helper_dimmer(RGB_GOLD);
+ thisInd = 0;
+ break;
+ case _MEDI: // Set right side as pink
+ thisCol = helper_dimmer(RGB_MAGENTA);
+ thisInd = 2;
+ break;
+ case _NAVI: // Set right side as green
+ thisCol = helper_dimmer(RGB_GREEN);
+ thisInd = 2;
+ break;
+ case _SYMB: // Set right side as yellow
+ thisCol = helper_dimmer(RGB_YELLOW);
+ thisInd = 2;
+ break;
+ case _NUMB: // Set left side as blue
+ thisCol = helper_dimmer(RGB_BLUE);
+ thisInd = 1;
+ break;
+ case _FUNC: // Set left side as red
+ thisCol = helper_dimmer(RGB_RED);
+ thisInd = 1;
+ break;
+ case _MOUS: // Set left side as blue-green
+ thisCol = helper_dimmer(RGB_SPRINGGREEN);
+ thisInd = 1;
+ break;
+ case _MUSI: // Set full board as orange
+ thisCol = helper_dimmer(RGB_ORANGE);
+ thisInd = 0;
+ break;
+ }
+ helper_painter(led_min, led_max, thisCol, thisInd);
+}
+
+// Hook into shutdown code to make all perkey LED's red on hitting reset
+void shutdown_rgb(void) {
+ // Flash all the key LED's red on shutdown
+ uint16_t timer_start = timer_read();
+ rgb_matrix_set_color_all(RGB_CORAL);
+ // Delay until this registers
+ while(timer_elapsed(timer_start) < 250) {wait_ms(1);}
+}
+
+// Hook into suspend code
+void suspend_power_down_rgb(void) {
+ rgb_matrix_set_suspend_state(true);
+}
+void suspend_wakeup_init_rgb(void) {
+ rgb_matrix_set_suspend_state(false);
+}
diff --git a/users/bbaserdem/bb-rgb.h b/users/bbaserdem/bb-rgb.h
new file mode 100644
index 0000000000..62b6da9f2f
--- /dev/null
+++ b/users/bbaserdem/bb-rgb.h
@@ -0,0 +1,28 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+/* Hooks involving perkey RGB LEDs
+ */
+
+// For custom indicators
+void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max);
+// Hook into shutdown code
+void shutdown_rgb(void);
+void suspend_wakeup_init_rgb(void);
+void suspend_power_down_rgb(void);
diff --git a/users/bbaserdem/bb-underglow.c b/users/bbaserdem/bb-underglow.c
new file mode 100644
index 0000000000..69aae439f4
--- /dev/null
+++ b/users/bbaserdem/bb-underglow.c
@@ -0,0 +1,116 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bb-underglow.h"
+
+/* UNDERGLOW IMPLEMENTATION
+ */
+
+// Define the layer switching code
+
+// An empty layer on the base
+const rgblight_segment_t PROGMEM bb_base_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {0, 0, HSV_WHITE}
+);
+// Gaming layer is turquoise
+const rgblight_segment_t PROGMEM bb_game_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {RGBLIGHT_LEFT_BEG, RGBLIGHT_LEFT_NUM, HSV_PURPLE}
+);
+// Character overlay is chartereuse
+const rgblight_segment_t PROGMEM bb_char_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {0, RGBLED_NUM, HSV_GOLD}
+);
+
+// Right-hand layers
+
+// Media layer is orange
+const rgblight_segment_t PROGMEM bb_medi_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {RGBLIGHT_RIGHT_BEG, RGBLIGHT_RIGHT_NUM, HSV_MAGENTA}
+);
+// Navigation layer is green
+const rgblight_segment_t PROGMEM bb_navi_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {RGBLIGHT_RIGHT_BEG, RGBLIGHT_RIGHT_NUM, HSV_GREEN}
+);
+// Symbol layer is purple
+const rgblight_segment_t PROGMEM bb_symb_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {RGBLIGHT_RIGHT_BEG, RGBLIGHT_RIGHT_NUM, HSV_YELLOW}
+);
+
+// Left-hand layers
+
+// Number layer is blue
+const rgblight_segment_t PROGMEM bb_numb_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {RGBLIGHT_LEFT_BEG, RGBLIGHT_LEFT_NUM, HSV_BLUE}
+);
+// Function layer is red
+const rgblight_segment_t PROGMEM bb_func_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {RGBLIGHT_LEFT_BEG, RGBLIGHT_LEFT_NUM, HSV_RED}
+);
+// Pointer layer is yellow
+const rgblight_segment_t PROGMEM bb_mous_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {RGBLIGHT_LEFT_BEG, RGBLIGHT_LEFT_NUM, HSV_SPRINGGREEN}
+);
+
+// Music playback layer is magenta
+const rgblight_segment_t PROGMEM bb_musi_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {0, RGBLED_NUM, HSV_ORANGE}
+);
+
+const rgblight_segment_t* const PROGMEM bb_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
+ bb_base_layer,
+ bb_char_layer,
+ bb_game_layer,
+ bb_medi_layer,
+ bb_navi_layer,
+ bb_symb_layer,
+ bb_numb_layer,
+ bb_func_layer,
+ bb_mous_layer,
+ bb_musi_layer
+);
+
+// Enable the LED switching layers
+void keyboard_post_init_underglow(void) {
+ rgblight_layers = bb_rgb_layers;
+ // Default rgb mode is rainbow swirl; set this
+ rgblight_sethsv_noeeprom(100, 255, 255);
+ rgblight_mode_noeeprom(RGBLIGHT_MODE_RAINBOW_SWIRL + 0);
+}
+
+// Set RGBLIGHT state depending on layer
+layer_state_t layer_state_set_underglow(layer_state_t state) {
+ // Activate layers if on that region
+ rgblight_set_layer_state(_BASE, layer_state_cmp(state, _BASE));
+ rgblight_set_layer_state(_GAME, layer_state_cmp(state, _GAME));
+ rgblight_set_layer_state(_CHAR, layer_state_cmp(state, _CHAR));
+ rgblight_set_layer_state(_MEDI, layer_state_cmp(state, _MEDI));
+ rgblight_set_layer_state(_NAVI, layer_state_cmp(state, _NAVI));
+ rgblight_set_layer_state(_SYMB, layer_state_cmp(state, _SYMB));
+ rgblight_set_layer_state(_NUMB, layer_state_cmp(state, _NUMB));
+ rgblight_set_layer_state(_FUNC, layer_state_cmp(state, _FUNC));
+ rgblight_set_layer_state(_MOUS, layer_state_cmp(state, _MOUS));
+ rgblight_set_layer_state(_MUSI, layer_state_cmp(state, _MUSI));
+ // Return so other stuff can be done
+ return state;
+}
+
+// Hook into shutdown code
+void shutdown_underglow(void) {
+ // Make the LED's red on shutdown
+ rgblight_enable_noeeprom();
+ rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
+ rgblight_sethsv(HSV_WHITE);
+}
diff --git a/users/bbaserdem/bb-underglow.h b/users/bbaserdem/bb-underglow.h
new file mode 100644
index 0000000000..9cc1db3757
--- /dev/null
+++ b/users/bbaserdem/bb-underglow.h
@@ -0,0 +1,28 @@
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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 "bbaserdem.h"
+
+/* UNDERGLOW IMPLEMENTATION
+ */
+
+// Used to initialize layer switching overlay
+void keyboard_post_init_underglow(void);
+// Used to change RGB underglow layers on keymap layer change
+layer_state_t layer_state_set_underglow(layer_state_t state);
+// Hook into shutdown to show effect on shutdown
+void shutdown_underglow(void);
diff --git a/users/bbaserdem/bbaserdem.c b/users/bbaserdem/bbaserdem.c
index cdacda12ee..08346c3d64 100644
--- a/users/bbaserdem/bbaserdem.c
+++ b/users/bbaserdem/bbaserdem.c
@@ -1,633 +1,360 @@
-#include "bbaserdem.h"
-
-/*---------------*\
-|*-----MOUSE-----*|
-\*---------------*/
-#ifdef MOUSEKEY_ENABLE
-#include "mousekey.h"
-#endif
-
-/*-------------*\
-|*-----RGB-----*|
-\*-------------*/
-#ifdef RGBLIGHT_ENABLE
-#include "rgblight.h"
-#endif
-
-/*-------------*\
-|*---UNICODE---*|
-\*-------------*/
-#ifdef UNICODE_ENABLE
-#endif
-
-/*-----------------*\
-|*-----SECRETS-----*|
-\*-----------------*/
-// Enabled by adding a non-tracked secrets.h to this dir.
-#if (__has_include("secrets.h"))
-#include "secrets.h"
-#endif
-
-/*---------------*\
-|*-----MUSIC-----*|
-\*---------------*/
-#ifdef AUDIO_ENABLE
-float tone_game[][2] = SONG(ZELDA_PUZZLE);
-float tone_return[][2] = SONG(ZELDA_TREASURE);
-float tone_linux[][2] = SONG(UNICODE_LINUX);
-float tone_windows[][2] = SONG(UNICODE_WINDOWS);
-#endif
-
-/*-------------------*\
-|*-----TAP-DANCE-----*|
-\*-------------------*/
-#ifdef TAP_DANCE_ENABLE
-qk_tap_dance_action_t tap_dance_actions[] = {
- // Shift on double tap of semicolon
- [SCL] = ACTION_TAP_DANCE_DOUBLE( KC_SCLN, KC_COLN )
-};
-#endif
-
-/* In keymaps, instead of writing _user functions, write _keymap functions
- * The __attribute__((weak)) allows for empty definitions here, and during
- * compilation, if these functions are defined elsewhere, they are written
- * over. This allows to include custom code from keymaps in the generic code
- * in this file.
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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/>.
*/
-__attribute__ ((weak)) void matrix_init_keymap(void) { }
-__attribute__ ((weak)) void matrix_scan_keymap(void) { }
-__attribute__ ((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
- return true;
+
+#include "bbaserdem.h"
+// Language imports
+#include <sendstring_dvorak.h>
+// Need memcpy and memcmp from string.h along with transfer stuff
+#ifdef SPLIT_KEYBOARD
+#include "transactions.h"
+#include <string.h>
+#endif // SPLIT_KEYBOARD
+
+/*-------------------------*\
+|*-----KEYBOARD CONFIG-----*|
+\*-------------------------*/
+userspace_config_t userspace_config;
+userspace_runtime_t userspace_runtime;
+
+/*---------------------------------*\
+|*----SPLIT KEYBOARD TRANSPORT-----*|
+\*---------------------------------*/
+#ifdef SPLIT_KEYBOARD
+userspace_config_t transport_userspace_config;
+userspace_runtime_t transport_userspace_runtime;
+
+// Translate the RPC data to the local variable
+void userspace_config_sync(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
+ // Copy incoming data to local variable
+ if (in_buflen == sizeof(transport_userspace_config)) {
+ memcpy(&transport_userspace_config, in_data, in_buflen);
+ }
+ // There is no data to send back; so no output handling
}
-__attribute__ ((weak)) uint32_t layer_state_set_keymap (uint32_t state) {
- return state;
+void userspace_runtime_sync(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
+ // Copy incoming data to local variable
+ if (in_buflen == sizeof(transport_userspace_runtime)) {
+ memcpy(&transport_userspace_runtime, in_data, in_buflen);
+ }
+ // There is no data to send back; so no output handling
}
-__attribute__ ((weak)) void led_set_keymap(uint8_t usb_led) { }
-/* ----------------------- *\
- * -----RGB Functions----- *
-\* ----------------------- */
-#ifdef RGBLIGHT_ENABLE
-// Storage variables
-extern rgblight_config_t rgblight_config;
-bool base_sta; // Keeps track if in saveable state
-bool base_tog; // Whether base state is active or not
-int base_hue; // Hue value of base state
-int base_sat; // Saturation value of base state
-int base_val; // Brightness value of base state
-uint8_t base_mod; // Animation mode of the base state
-
-// Save the current state of the rgb mode
-void rgblight_saveBase(void) {
- base_hue = rgblight_config.hue;
- base_sat = rgblight_config.sat;
- base_val = rgblight_config.val;
- base_mod = rgblight_config.mode;
- base_tog = rgblight_config.enable;
- base_sta = false; // If saving, that means base layer is being left
+// Either send or receive the correct data
+void userspace_transport_update(void) {
+ if (is_keyboard_master()) {
+ // If we are the main device; we want to send info.
+ transport_userspace_config.raw = userspace_config.raw;
+ transport_userspace_runtime.raw = userspace_runtime.raw;
+ } else {
+ // If we are the secondary device; we want to receive info, and save to eeprom.
+ userspace_config.raw = transport_userspace_config.raw;
+ userspace_runtime.raw = transport_userspace_runtime.raw;
+ }
}
-// Load the base state back
-void rgblight_loadBase(void) {
- // Don't do anything if not enabled
- if ( !base_sta ) {
- if ( base_tog ) {
- rgblight_enable();
- rgblight_mode( base_mod );
- rgblight_sethsv( base_hue, base_sat, base_val );
- } else {
- rgblight_disable();
+// Initiate the protocol on sync
+void userspace_transport_sync(bool force_sync) {
+ if (is_keyboard_master()) {
+ // Keep track of the last state
+ static userspace_config_t last_userspace_config;
+ static userspace_runtime_t last_userspace_runtime;
+ bool needs_sync = false;
+
+ // Check if the config values are different
+ if (memcmp(&transport_userspace_config, &last_userspace_config, sizeof(transport_userspace_config))) {
+ needs_sync = true;
+ memcpy(&last_userspace_config, &transport_userspace_config, sizeof(transport_userspace_config));
+ }
+ // Perform the sync if requested
+ if (needs_sync || force_sync) {
+ transaction_rpc_send(RPC_ID_CONFIG_SYNC, sizeof(transport_userspace_config), &transport_userspace_config);
+ needs_sync = false;
}
- }
- // Mark that base is loaded, and to be saved before leaving
- base_sta = true;
-}
-// Set to plain HSV color
-void rgblight_colorStatic( int hu, int sa, int va ) {
- // First, it must be enabled or color change is not written
- rgblight_enable();
- rgblight_mode(1);
- rgblight_sethsv(hu,sa,va);
-}
-/* HSV values
- * white ( 0, 0, 255)
- * red ( 0, 255, 255)
- * coral ( 16, 176, 255)
- * orange ( 39, 255, 255)
- * goldenrod ( 43, 218, 218)
- * gold ( 51, 255, 255)
- * yellow ( 60, 255, 255)
- * chartreuse ( 90, 255, 255)
- * green (120, 255, 255)
- * springgreen (150, 255, 255)
- * turquoise (174, 90, 112)
- * teal (180, 255, 128)
- * cyan (180, 255, 255)
- * azure (186, 102, 255)
- * blue (240, 255, 255)
- * purple (270, 255, 255)
- * magenta (300, 255, 255)
- * pink (330, 128, 255)
- */
+ // Check if the runtime values are different
+ if (memcmp(&transport_userspace_runtime, &last_userspace_runtime, sizeof(transport_userspace_runtime))) {
+ needs_sync = true;
+ memcpy(&last_userspace_runtime, &transport_userspace_runtime, sizeof(transport_userspace_runtime));
+ }
-// Set RGBLIGHT state depending on layer
-void rgblight_change( uint8_t this_layer ) {
- // Save state, if saving is requested
- if ( base_sta ) {
- rgblight_saveBase();
- }
- // Change RGB light
- switch ( this_layer ) {
- case _DV:
- // Load base layer
- rgblight_loadBase();
- break;
- case _AL:
- // Do yellow for alternate
- rgblight_colorStatic( 60,255,255);
- break;
- case _GA:
- // Do purple for game
- rgblight_colorStatic(285,255,255);
- break;
- case _NU:
- // Do azure for number
- rgblight_colorStatic(186,200,255);
- break;
- case _SE:
- // Do red for settings
- rgblight_colorStatic( 16,255,255);
- break;
- case _MO:
- // Do green for mouse
- rgblight_colorStatic(120,255,255);
- break;
- case _MU:
- // Do orange for music
- rgblight_colorStatic( 39,255,255);
- break;
- default:
- // Something went wrong
- rgblight_colorStatic( 0,255,255);
- break;
+ // Perform the sync if requested
+ if (needs_sync || force_sync) {
+ transaction_rpc_send(RPC_ID_RUNTIME_SYNC, sizeof(transport_userspace_runtime), &transport_userspace_runtime);
+ needs_sync = false;
+ }
}
}
+#endif // SPLIT_KEYBOARD
-#endif
+/*---------------------------*\
+|*-----KEYBOARD PRE INIT-----*|
+\*---------------------------*/
+/* This code runs before anything is started.
+ * Good for early hardware setup
+ */
+__attribute__ ((weak)) void keyboard_pre_init_keymap(void) {}
+__attribute__ ((weak)) void keyboard_pre_init_user(void) {
+ // Keymap specific stuff
+ keyboard_pre_init_keymap();
+}
/*---------------------*\
|*-----MATRIX INIT-----*|
\*---------------------*/
+/* This code runs once midway thru the firmware process.
+ * So far, sets the base layer and fixes unicode mode
+ */
+__attribute__ ((weak)) void matrix_init_keymap(void) {}
void matrix_init_user (void) {
-
- // Keymap specific things, do it first thing to allow for delays etc
+ // Keymap specific things
matrix_init_keymap();
+}
+
+/*----------------------------*\
+|*-----KEYBOARD POST INIT-----*|
+\*----------------------------*/
+/* This code runs after anything is started.
+ * Good for late hardware setup, like setting up layer specifications
+ */
+__attribute__ ((weak)) void keyboard_post_init_keymap(void) {}
+__attribute__ ((weak)) void keyboard_post_init_user(void) {
+ // Fix beginning base layer, in case some other firmware was flashed
+ // set_single_persistent_default_layer(_BASE);
- // Correct unicode
-#ifdef UNICODE_ENABLE
+ // Unicode mode
+# ifdef UNICODEMAP_ENABLE
set_unicode_input_mode(UC_LNX);
-#endif
+# endif // UNICODEMAP_ENABLE
+
+ // Split keyboard halves communication
+# ifdef SPLIT_KEYBOARD
+ // Register the transactions
+ transaction_register_rpc( RPC_ID_CONFIG_SYNC, userspace_config_sync );
+ transaction_register_rpc(RPC_ID_RUNTIME_SYNC, userspace_runtime_sync);
+ // Load default config values
+ if (is_keyboard_master()) {
+ // If we are main; load from eeconfig
+ userspace_config.raw = eeconfig_read_user();
+ // And update the transport variable
+ userspace_transport_update();
+ // Do one forced transfer to sync halves
+ userspace_transport_sync(true);
+ } else {
+ // Just sync the data received
+ userspace_transport_update();
+ }
+# else // SPLIT_KEYBOARD
+ // If we are not split; just load from eeprom
+ userspace_config.raw = eeconfig_read_user();
+# endif // SPLIT_KEYBOARD
+
+ // Backlight LED
+# ifdef BACKLIGHT_ENABLE
+ keyboard_post_init_backlight();
+# endif // BACKLIGHT_ENABLE
+
+ // RGB underglow
+# ifdef RGBLIGHT_ENABLE
+ keyboard_post_init_underglow();
+# endif // RGBLIGHT_ENABLE
+
+ // Keymap specific stuff
+ keyboard_post_init_keymap();
+}
- // Make beginning layer DVORAK
- set_single_persistent_default_layer(_DV);
+/*---------------------------*\
+|*-----HOUSEKEEPING TASK-----*|
+\*---------------------------*/
+/* I have no idea what this does
+ */
+__attribute__ ((weak)) void housekeeping_task_keymap(void) {}
+void housekeeping_task_user(void) {
+ // Check eeprom every now and then
+ static userspace_config_t prev_userspace_config;
+ static fast_timer_t throttle_timer = 0;
+ static bool init_flag = true;
+
+ // Read this if we never read it before
+ if (init_flag) {
+ init_flag = false;
+ prev_userspace_config.raw = eeconfig_read_user();
+ }
-//--RGB light initialize base layer
-#ifdef RGBLIGHT_ENABLE
- // Base hue is white, and RGB disabled
- base_hue = 100;
- base_sat = 0;
- base_val = 255;
- base_mod = 2;
- base_tog = false;
- rgblight_enable();
- rgblight_mode(base_mod);
- rgblight_sethsv(base_hue,base_sat,base_val);
- rgblight_disable();
- rgblight_loadBase();
-#endif
+ // Throttled tasks here
+ if (timer_elapsed_fast(throttle_timer) >= HOUSEKEEPING_THROTTLE_INTERVAL_MS) {
+ // Refresh timer
+ throttle_timer = timer_read_fast();
+ // Check userspace config for eeprom updates
+ if (memcmp(&prev_userspace_config, &userspace_config, sizeof(userspace_config))) {
+ memcpy(&prev_userspace_config, &userspace_config, sizeof(userspace_config));
+ eeconfig_update_user(userspace_config.raw);
+ }
+ }
+
+ // Do transport stuff
+# ifdef SPLIT_KEYBOARD
+ userspace_transport_update();
+ userspace_transport_sync(false);
+# endif // SPLIT_KEYBOARD
+ // Hook to keymap code
+ housekeeping_task_keymap();
+}
+
+/*-----------------------*\
+|*-----EECONFIG INIT-----*|
+\*-----------------------*/
+/* Default values to send to the eeprom
+ */
+void eeconfig_init_user(void) {
+ // Set everything to default
+ userspace_config.raw = 0;
+ // Set encoder states to sane defaults if enabled
+# ifdef ENCODER_ENABLE
+ reset_encoder_state();
+# endif // ENCODER_ENABLE
+}
+
+/*------------------------*\
+|*-----PROCESS RECORD-----*|
+\*------------------------*/
+/* Process record: custom keycodes to process here
+ * Allow also the following codes to hook here as well;
+ * Macro definitions
+ * Audio hooks
+ */
+__attribute__ ((weak))
+bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
+ return true;
+}
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ // Return after running through all individual hooks
+ return
+ process_record_keymap(keycode, record) &&
+# ifdef AUDIO_ENABLE
+ process_record_audio(keycode, record) &&
+# endif // AUDIO_ENABLE
+# ifdef ENCODER_ENABLE
+ process_record_encoder(keycode, record) &&
+# endif // ENCODER_ENABLE
+ process_record_macro(keycode, record);
}
/*---------------------*\
|*-----MATRIX SCAN-----*|
\*---------------------*/
+/* This code runs every frame
+ * I used to check for layer switching here, but layer state is better used.
+ * Try to not put anything here; as it runs hundreds time per second-ish
+ */
+__attribute__ ((weak)) void matrix_scan_keymap(void) { }
void matrix_scan_user (void) {
- // Keymap specific, do it first
+ // Keymap specific scan function
matrix_scan_keymap();
}
-/*------------------*\
-|*-----KEYCODES-----*|
-\*------------------*/
-bool process_record_user(uint16_t keycode, keyrecord_t *record) {
-
- // Shift check
- bool is_capital = ( keyboard_report->mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
- static bool lock_flag = false;
- uint8_t layer = biton32 (layer_state);
-
- switch (keycode) {
- // Secrets implementation
-#if (__has_include("secrets.h"))
- case SECRET1:
- if( !record->event.pressed ) {
- send_string_P( secret[ keycode - SECRET1 ] );
- }
- return false;
- break;
- case SECRET2:
- if( !record->event.pressed ) {
- send_string_P( secret[ keycode - SECRET2 ] );
- }
- return false;
- break;
- case SECRET3:
- if( !record->event.pressed ) {
- send_string_P( secret[ keycode - SECRET3 ] );
- }
- return false;
- break;
-#endif
-
- // If these keys are pressed, load base layer config, and mark saving
-#ifdef RGBLIGHT_ENABLE
- case RGB_TOG:
- case RGB_MOD:
- case RGB_VAI:
- case RGB_VAD:
- case RGB_SAI:
- case RGB_SAD:
- case RGB_HUI:
- case RGB_HUD:
- if ( !base_sta ) {
- rgblight_loadBase();
- }
- return true;
- break;
-#endif
-
- // Lock functionality: These layers are locked if the LOCKED buttons are
- // pressed. Otherwise, they are momentary toggles
- case K_LOCK:
- if (record->event.pressed) {
- lock_flag = !lock_flag;
- }
- return false;
- break;
- case K_MOUSE:
- if (record->event.pressed) {
- layer_on(_MO);
- lock_flag = false;
- } else {
- if ( lock_flag ) {
- lock_flag = false;
- } else {
- layer_off(_MO);
- }
- }
- return false;
- break;
- case K_NUMBR:
- if (record->event.pressed) {
- layer_on(_NU);
- lock_flag = false;
- } else {
- if ( lock_flag ) {
- lock_flag = false;
- } else {
- layer_off(_NU);
- }
- }
- return false;
- break;
-
- // Layer switches with sound
- case K_GAMES:
- if (record->event.pressed) {
- // On press, turn off layer if active
- if ( layer == _GA ) {
-#ifdef AUDIO_ENABLE
- stop_all_notes();
- PLAY_SONG(tone_return);
-#endif
- layer_off(_GA);
- }
- } else {
- // After click, turn on layer if accessed from setting
- if ( layer == _SE ) {
-#ifdef AUDIO_ENABLE
- stop_all_notes();
- PLAY_SONG(tone_game);
-#endif
- layer_on(_GA);
- layer_off(_SE);
- }
- }
- return false;
- break;
- case MU_TOG:
- if (record->event.pressed) {
- // On press, turn off layer if active
- if ( layer == _SE ) {
- layer_off(_SE);
- layer_on(_MU);
- } else {
- layer_off(_MU);
- }
- }
- return true;
- break;
-
-//------UNICODE
- // Unicode switches with sound
-#ifdef UNICODE_ENABLE
- case UNI_LI:
- if (record->event.pressed) {
-#ifdef AUDIO_ENABLE
- stop_all_notes();
- PLAY_SONG(tone_linux);
-#endif
- set_unicode_input_mode(UC_LNX);
- }
- return false;
- break;
- case UNI_WN:
- if (record->event.pressed) {
-#ifdef AUDIO_ENABLE
- stop_all_notes();
- PLAY_SONG(tone_windows);
-#endif
- set_unicode_input_mode(UC_WIN);
- }
- return false;
- break;
-
- // Turkish letters, with capital functionality
- case TUR_A:
- if (record->event.pressed) {
- if ( is_capital ) {
- unicode_input_start();
- register_hex(0x00c2);
- unicode_input_finish();
- } else {
- unicode_input_start();
- register_hex(0x00e2);
- unicode_input_finish();
- }
- }
- return false;
- break;
- case TUR_O:
- if (record->event.pressed) {
- if ( is_capital ) {
- unicode_input_start();
- register_hex(0x00d6);
- unicode_input_finish();
- } else {
- unicode_input_start();
- register_hex(0x00f6);
- unicode_input_finish();
- }
- }
- return false;
- break;
- case TUR_U:
- if (record->event.pressed) {
- if ( is_capital ) {
- unicode_input_start();
- register_hex(0x00dc);
- unicode_input_finish();
- } else {
- unicode_input_start();
- register_hex(0x00fc);
- unicode_input_finish();
- }
- }
- return false;
- break;
- case TUR_I:
- if (record->event.pressed) {
- if ( is_capital ) {
- unicode_input_start();
- register_hex(0x0130);
- unicode_input_finish();
- } else {
- unicode_input_start();
- register_hex(0x0131);
- unicode_input_finish();
- }
- }
- return false;
- break;
- case TUR_G:
- if (record->event.pressed) {
- if ( is_capital ) {
- unicode_input_start();
- register_hex(0x011e);
- unicode_input_finish();
- } else {
- unicode_input_start();
- register_hex(0x011f);
- unicode_input_finish();
- }
- }
- return false;
- break;
- case TUR_C:
- if (record->event.pressed) {
- if ( is_capital ) {
- unicode_input_start();
- register_hex(0x00c7);
- unicode_input_finish();
- } else {
- unicode_input_start();
- register_hex(0x00e7);
- unicode_input_finish();
- }
- }
- return false;
- break;
- case TUR_S:
- if (record->event.pressed) {
- if ( is_capital ) {
- unicode_input_start();
- register_hex(0x015e);
- unicode_input_finish();
- } else {
- unicode_input_start();
- register_hex(0x015f);
- unicode_input_finish();
- }
- }
- return false;
- break;
-#endif
+/*---------------------*\
+|*-----LAYER STATE-----*|
+\*---------------------*/
+/* This code runs after every layer change
+ * State represents the new layer state.
+ */
+__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) {
+ // Keymap layer state setting
+ state = layer_state_set_keymap(state);
+ // For underglow stuff
+# ifdef RGBLIGHT_ENABLE
+ state = layer_state_set_underglow(state);
+# endif // RGBLIGHT_ENABLE
+ // Audio playback
+# ifdef AUDIO_ENABLE
+ state = layer_state_set_audio(state);
+# endif // AUDIO_ENABLE
-//-------Diagonal mouse movements
-#ifdef MOUSEKEY_ENABLE
- case MO_NE:
- if( record->event.pressed ) {
- mousekey_on(MO_N);
- mousekey_on(MO_E);
- mousekey_send();
- } else {
- mousekey_off(MO_N);
- mousekey_off(MO_E);
- mousekey_send();
- }
- return false;
- break;
- case MO_NW:
- if( record->event.pressed ) {
- mousekey_on(MO_N);
- mousekey_on(MO_W);
- mousekey_send();
- } else {
- mousekey_off(MO_N);
- mousekey_off(MO_W);
- mousekey_send();
- }
- return false;
- break;
- case MO_SE:
- if( record->event.pressed ) {
- mousekey_on(MO_S);
- mousekey_on(MO_E);
- mousekey_send();
- } else {
- mousekey_off(MO_S);
- mousekey_off(MO_E);
- mousekey_send();
- }
- return false;
- break;
- case MO_SW:
- if( record->event.pressed ) {
- mousekey_on(MO_S);
- mousekey_on(MO_W);
- mousekey_send();
- } else {
- mousekey_off(MO_S);
- mousekey_off(MO_W);
- mousekey_send();
- }
- return false;
- break;
- case MO_S_NE:
- if( record->event.pressed ) {
- mousekey_on(MO_S_N);
- mousekey_on(MO_S_E);
- mousekey_send();
- } else {
- mousekey_off(MO_S_N);
- mousekey_off(MO_S_E);
- mousekey_send();
- }
- return false;
- break;
- case MO_S_NW:
- if( record->event.pressed ) {
- mousekey_on(MO_S_N);
- mousekey_on(MO_S_W);
- mousekey_send();
- } else {
- mousekey_off(MO_S_N);
- mousekey_off(MO_S_W);
- mousekey_send();
- }
- return false;
- break;
- case MO_S_SE:
- if( record->event.pressed ) {
- mousekey_on(MO_S_S);
- mousekey_on(MO_S_E);
- mousekey_send();
- } else {
- mousekey_off(MO_S_S);
- mousekey_off(MO_S_E);
- mousekey_send();
- }
- return false;
- break;
- case MO_S_SW:
- if( record->event.pressed ) {
- mousekey_on(MO_S_S);
- mousekey_on(MO_S_W);
- mousekey_send();
- } else {
- mousekey_off(MO_S_S);
- mousekey_off(MO_S_W);
- mousekey_send();
- }
- return false;
- break;
-#endif
+ return state;
+}
-//------DOUBLE PRESS, with added left navigation
- case DBL_SPC:
- if( record->event.pressed ) {
- SEND_STRING(" "SS_TAP(X_LEFT));
- }
- return false;
- break;
- case DBL_ANG:
- if( record->event.pressed ) {
- SEND_STRING("<>"SS_TAP(X_LEFT));
- }
- return false;
- break;
- case DBL_PAR:
- if( record->event.pressed ) {
- SEND_STRING("()"SS_TAP(X_LEFT));
- }
- return false;
- break;
- case DBL_SQR:
- if( record->event.pressed ) {
- SEND_STRING("[]"SS_TAP(X_LEFT));
- }
- return false;
- break;
- case DBL_BRC:
- if( record->event.pressed ) {
- SEND_STRING("{}"SS_TAP(X_LEFT));
- }
- return false;
- break;
- case DBL_QUO:
- if( record->event.pressed ) {
- SEND_STRING("\'\'"SS_TAP(X_LEFT));
- }
- return false;
- break;
- case DBL_DQT:
- if( record->event.pressed ) {
- SEND_STRING("\"\""SS_TAP(X_LEFT));
- }
- return false;
- break;
- case DBL_GRV:
- if( record->event.pressed ) {
- SEND_STRING("``"SS_TAP(X_LEFT));
- }
- return false;
- break;
-// END OF KEYCODES
- }
- return process_record_keymap(keycode, record);
+/*-----------------------------*\
+|*-----DEFAULT LAYER STATE-----*|
+\*-----------------------------*/
+/* This code runs after every time default base layer is changed
+ */
+__attribute__ ((weak))
+layer_state_t default_layer_state_set_keymap (layer_state_t state) {
+ return state;
+}
+layer_state_t default_layer_state_set_user(layer_state_t state) {
+ // Keymap level code
+ state = default_layer_state_set_keymap(state);
+ return state;
}
-/*----------------------*\
-|*-----LAYER CHANGE-----*|
-\*----------------------*/
+/*------------------------*\
+|*-----LED SET KEYMAP-----*|
+\*------------------------*/
+/* Code for LED indicators
+ * I'm not sure when exactly does this code run
+ */
+__attribute__ ((weak)) void led_set_keymap(uint8_t usb_led) {}
+void led_set_user(uint8_t usb_led) {
+ led_set_keymap(usb_led);
+}
-layer_state_t layer_state_set_user(layer_state_t state) {
+/*-----------------*\
+|*-----SUSPEND-----*|
+\*-----------------*/
+/* Suspend stuff here, mostly for the rgb lighting.
+ */
+__attribute__ ((weak)) void suspend_power_down_keymap (void) { }
+void suspend_power_down_user(void) {
+ suspend_power_down_keymap();
+ // RGB matrix sleep hook
+# ifdef RGB_MATRIX_ENABLE
+ suspend_power_down_rgb();
+# endif // RGB_MATRIX_ENABLE
+}
+__attribute__ ((weak)) void suspend_wakeup_init_keymap (void) { }
+void suspend_wakeup_init_user(void) {
+ suspend_wakeup_init_keymap();
+ // RGB matrix sleep hook
+# ifdef RGB_MATRIX_ENABLE
+ suspend_wakeup_init_rgb();
+# endif // RGB_MATRIX_ENABLE
+}
- state = layer_state_set_keymap (state);
-#ifdef RGBLIGHT_ENABLE
- // Change RGB lighting depending on the last layer activated
- rgblight_change( biton32(state) );
-#endif
- return state;
+/*------------------*\
+|*-----SHUTDOWN-----*|
+\*------------------*/
+/* Shutdown stuff here; for when entering bootmode.
+ */
+__attribute__ ((weak)) void shutdown_keymap (void) { }
+void shutdown_user(void) {
+ // Underglow LED hook on boot
+# ifdef RGBLIGHT_ENABLE
+ shutdown_underglow();
+# endif // RGBLIGHT_ENABLE
+ // Perkey led hook on boot
+# ifdef RGB_MATRIX_ENABLE
+ shutdown_rgb();
+# endif // RGB_MATRIX_ENABLE
+ // Keymap hooks
+ shutdown_keymap();
}
diff --git a/users/bbaserdem/bbaserdem.h b/users/bbaserdem/bbaserdem.h
index 3a405f2a47..4792d5c2d7 100644
--- a/users/bbaserdem/bbaserdem.h
+++ b/users/bbaserdem/bbaserdem.h
@@ -1,268 +1,573 @@
-#ifndef USERSPACE
-#define USERSPACE
-
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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
#include "quantum.h"
+#include "keymap_dvorak.h"
+
+/* Besides loading libraries and definitions, this file has my layout defs
+ * LAYOUTS:
+ * This file has a couple layouts I use; so that the general changes can be
+ * propagated by only editing this file.
+ */
+
+// Macros to use, this has base level code so not affected by enabled features
+#include "bb-macro.h"
+// Audio from onboard speakers
+#ifdef AUDIO_ENABLE
+#include "bb-audio.h"
+#endif // AUDIO_ENABLE
+// Keycap backlight using non-rgb LEDs
+#ifdef BACKLIGHT_ENABLE
+#include "bb-backlight.h"
+#endif // BACKLIGHT_ENABLE
+// Underglow light using rgb LEDs
+#ifdef RGBLIGHT_ENABLE
+#include "bb-underglow.h"
+#endif // RGBLIGHT_ENABLE
+// Keycap backlight using rgb LEDs
+#ifdef RGB_MATRIX_ENABLE
+#include "bb-rgb.h"
+#endif // RGB_MATRIX_ENABLE
+// Rotary encoder
+#ifdef ENCODER_ENABLE
+#include "bb-encoder.h"
+#endif // ENCODER_ENABLE
+// Oled screen
+#ifdef OLED_ENABLE
+#include "bb-oled.h"
+#endif // OLED_ENABLE
+
+// Structure to keep runtime info on encoder state
+typedef union {
+ uint32_t raw;
+ struct {
+ bool rgb_sleep;
+ };
+} userspace_runtime_t;
-#define XXX KC_NO
+typedef union {
+ uint32_t raw;
+ struct {
+ uint8_t e0base :4; // ( 4:0) The encoder state on most layers; regular function
+ uint8_t e1base :4; // ( 8:1) 9 states for this; 4 bits
+ uint8_t e0point :2; // (10:1) The encoder state on mouse layer; moves pointer
+ uint8_t e1point :2; // (12:1) 4 states for this; 2 bits
+ uint8_t e0rgb :4; // (16:2) The encoder state on media layer; controls light
+ uint8_t e1rgb :4; // (20:2) 5 states for this; 3 bits but 4 is better
+ uint8_t layout :2; // (22:2) Stores keymap layout; 3 states is good on 2 bits
+ uint16_t :10; // (32:3) Padding here, free space for 10 more bits
+ };
+} userspace_config_t;
-// Layers
-#define _DV 0 // Base layer
-#define _AL 1 // Alt char overlay
-#define _GA 2 // Game layer
-#define _NU 3 // Numbers layer
-#define _SE 4 // Settings layer
-#define _MO 5 // Mouse emulation
-#define _MU 6 // Music mode
+// Broadcast us to everyone else
+extern userspace_runtime_t userspace_runtime;
+extern userspace_config_t userspace_config;
-// Define short macros
-#define UNDO LCTL(KC_Z)
-#define REDO LCTL(KC_Y)
-#define COPY LCTL(KC_C)
-#define CUT LCTL(KC_X)
-#define PASTE LCTL(KC_V)
+// Function definitions that can be accessed through specific keymaps
+// Runs before all initialization
+void keyboard_pre_init_keymap(void);
+// For code that launches once midway through initialization
+void matrix_init_keymap(void);
+// For code that launches after initialization is finished.
+void keyboard_post_init_keymap(void);
+// These will be delegated to keymap specific stuff (weak definition)
+bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
+// This code runs on every tick
+void matrix_scan_keymap(void);
+// This code runs after every layer change
+layer_state_t layer_state_set_keymap(layer_state_t state);
+// This code runs when the default layer changes
+layer_state_t default_layer_state_set_keymap (layer_state_t state);
+// Some code
+void housekeeping_task_user(void);
+// This code runs to set LED states
+void led_set_keymap(uint8_t usb_led);
+// For code that runs on suspend
+void suspend_power_down_keymap(void);
+void suspend_wakeup_init_keymap(void);
+// For code that runs on powerdown
+void shutdown_keymap(void);
-// Rename mouse keys with 7 letters
-#ifdef MOUSEKEY_ENABLE
-#define MO_S_N KC_MS_WH_UP
-#define MO_S_S KC_MS_WH_DOWN
-#define MO_S_E KC_MS_WH_RIGHT
-#define MO_S_W KC_MS_WH_LEFT
-#define MO_N KC_MS_UP
-#define MO_S KC_MS_DOWN
-#define MO_E KC_MS_RIGHT
-#define MO_W KC_MS_LEFT
-#define MO_CL_L KC_MS_BTN1
-#define MO_CL_R KC_MS_BTN2
-#define MO_CL_M KC_MS_BTN3
-#define MO_CL_4 KC_MS_BTN4
-#define MO_CL_5 KC_MS_BTN5
-#define MO_AC_0 KC_MS_ACCEL0
-#define MO_AC_1 KC_MS_ACCEL1
-#define MO_AC_2 KC_MS_ACCEL2
+// Make it so that keymaps can use KEYMAP_SAFE_RANGE for custom keycodes
+#ifdef KEYMAP_SAFE_RANGE
+#define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE
#else
-#define MO_S_N KC_NO
-#define MO_S_S KC_NO
-#define MO_S_E KC_NO
-#define MO_S_W KC_NO
-#define MO_N KC_NO
-#define MO_S KC_NO
-#define MO_E KC_NO
-#define MO_W KC_NO
-#define MO_CL_L KC_NO
-#define MO_CL_R KC_NO
-#define MO_CL_M KC_NO
-#define MO_CL_1 KC_NO
-#define MO_CL_2 KC_NO
-#define MO_AC_0 KC_NO
-#define MO_AC_1 KC_NO
-#define MO_AC_2 KC_NO
+#define PLACEHOLDER_SAFE_RANGE SAFE_RANGE
#endif
-// Rename music keys with <8 letters
+// Custom macro keycode ranges
+enum userspace_custom_keycodes {
+ // Safe stuff
+ BB_SAFE = PLACEHOLDER_SAFE_RANGE,
+ // Double entry macros
+ DBL_ANG,
+ DBL_PAR,
+ DBL_CBR,
+ DBL_BRC,
+ // Macro key
+ BB_PGPK,
+ // Unicode strings
+# ifdef UNICODEMAP_ENABLE
+ BB_LENY,
+ BB_TABL,
+ TR_FLAG,
+# endif // UNICODEMAP_ENABLE
+ // Encoder buttons
+# ifdef ENCODER_ENABLE
+ BB_ENC0,
+ BB_ENC1,
+# endif // ENCODER_ENABLE
+ // Oled editor
+# ifdef OLED_ENABLE
+ BB_OLED,
+# endif // OLED_ENABLE
+ //use for keymap specific codes
+ KEYMAP_SAFE_RANGE
+};
+// Mask these keycodes if required features are not enabled
+#ifndef UNICODEMAP_ENABLE
+#define BB_LENY KC_NO
+#define BB_TABL KC_NO
+#define TR_FLAG KC_NO
+#endif // UNICODEMAP_ENABLE
+#ifndef ENCODER_ENABLE
+#define BB_ENC0 KC_NO
+#define BB_ENC1 KC_NO
+#endif // ENCODER_ENABLE
+
+/// Enumerate of layers
+enum userspace_layers {
+ _BASE = 0, // Base layer
+ _CHAR, // Characters layer
+ _GAME, // Game layer
+ _MEDI, // R3: Media layer
+ _NAVI, // R3: Navigation layer
+ _SYMB, // R1: Symbols layer
+ _NUMB, // L1: Numbers layer
+ _FUNC, // L2: Function keys layer
+ _MOUS, // L3: Mouse keys layer
+ _MUSI // Music overlay
+};
+
+// Use 7 wide characters for keymaps, to keep things aligned with 4 tabs
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+
+// These defines allow multiple multi-parameter definitions to expand
+// for these boards
+#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__)
+#define LAYOUT_ortho_4x12_wrapper(...) LAYOUT_ortho_4x12(__VA_ARGS__)
+#define LAYOUT_ortho_5x15_wrapper(...) LAYOUT_ortho_5x15(__VA_ARGS__)
+#define LAYOUT_ortho_3x10_wrapper(...) LAYOUT_ortho_3x10(__VA_ARGS__)
+#define LAYOUT_split_3x6_3_wrapper(...) LAYOUT_split_3x6_3(__VA_ARGS__)
+#define LAYOUT_split_3x5_3_wrapper(...) LAYOUT_split_3x5_3(__VA_ARGS__)
+
+// Masks
+#define ___1___ _______
+#define ___2___ _______,_______
+#define ___3___ _______,_______,_______
+#define ___4___ _______,_______,_______,_______
+#define ___5___ _______,_______,_______,_______,_______
+#define ___6___ _______,_______,_______,_______,_______,_______
+#define xxx1xxx KC_NO
+#define xxx2xxx KC_NO, KC_NO
+#define xxx3xxx KC_NO, KC_NO, KC_NO
+#define xxx4xxx KC_NO, KC_NO, KC_NO, KC_NO
+#define xxx5xxx KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
+#define xxx6xxx KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
+#define xxx1xxx KC_NO
+#define xxx3xxx KC_NO, KC_NO, KC_NO
+#define xxx5xxx KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
+#define xxx6xxx KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
+
+// Quick macros: in dvorak
+#define BB_UNDO LCTL(KC_SLSH) // Ctrl + Z
+#define BB_REDO LCTL(KC_T) // Ctrl + Y
+#define BB_YANK LCTL(KC_I) // Ctrl + C
+#define BB_CUT LCTL(KC_B) // Ctrl + X
+#define BB_PSTE LCTL(KC_DOT) // Ctrl + V
+
+// Audio keys
#ifdef AUDIO_ENABLE
#define MU_REC KC_LCTL
#define MU_STOP KC_LALT
#define MU_PLAY KC_LGUI
-#define MU_PLAY KC_LGUI
#define MU_FAST KC_UP
#define MU_SLOW KC_DOWN
#define MU_MASK KC_A
-#else
+#define BB_SND MU_ON
+#ifdef TAP_DANCE_ENABLE
+#define MU_TEMP TD(TD_AUDIO_TEMPO)
+#else // TAP_DANCE_ENABLE
+#define MU_TEMP KC_DOWN
+#endif // TAP_DANCE_ENABLE
+#else // AUDIO_ENABLE
#define MU_REC KC_NO
#define MU_STOP KC_NO
#define MU_PLAY KC_NO
-#define MU_PLAY KC_NO
#define MU_FAST KC_NO
+#define MU_TEMP KC_NO
#define MU_SLOW KC_NO
#define MU_MASK KC_NO
-#endif
+#define BB_SND KC_MUTE
+#endif // AUDIO_ENABLE
-// Define non-capitalized UTF shortcuts here
-#ifdef UNICODE_ENABLE
-#define PHY_HBR UC(0x0127)
-#define PHY_DEG UC(0x00b0)
-#define CUR_LIR UC(0x20ba)
-#define CUR_BIT UC(0x20bf)
-#define CUR_EUR UC(0x20ac)
-#define CUR_BPN UC(0x00a3)
-#define CUR_YEN UC(0x00a5)
-#else
-#define PHY_HBR KC_NO
-#define PHY_DEG KC_NO
-#define CUR_LIR KC_NO
-#define CUR_BIT KC_NO
-#define CUR_EUR KC_NO
-#define CUR_BPN KC_NO
-#define CUR_YEN KC_NO
-#endif
+// Unicode keys
+#ifdef UNICODEMAP_ENABLE
+#define TR_ACIR XP(LOW_A_CIRC, UPC_A_CIRC )
+#define TR_CCED XP(LOW_C_CEDI, UPC_C_CEDI )
+#define TR_GBRE XP(LOW_G_BREV, LOW_G_BREV )
+#define TR_ICIR XP(LOW_I_CIRC, LOW_I_CIRC )
+#define TR_I_NO XP(LOW_I_DOTL, LOW_I_DOTL )
+#define TR_IDOT XP(LOW_I_DOTT, LOW_I_DOTT )
+#define TR_ODIA XP(LOW_O_DIAE, LOW_O_DIAE )
+#define TR_SCED XP(LOW_S_CEDI, LOW_S_CEDI )
+#define TR_UCIR XP(LOW_U_CIRC, LOW_U_CIRC )
+#define TR_UDIA XP(LOW_U_DIAE, LOW_U_DIAE )
+#define GR_ALP XP(LOW_ALPHA, UPC_ALPHA )
+#define GR_BET XP(LOW_BETA, UPC_BETA )
+#define GR_GAM XP(LOW_GAMMA, UPC_GAMMA )
+#define GR_DEL XP(LOW_DELTA, UPC_DELTA )
+#define GR_EPS XP(LOW_EPSILON,UPC_EPSILON)
+#define GR_ZET XP(LOW_ZETA, UPC_ZETA )
+#define GR_ETA XP(LOW_ETA, UPC_ETA )
+#define GR_THE XP(LOW_THETA, UPC_THETA )
+#define GR_IOT XP(LOW_IOTA, UPC_IOTA )
+#define GR_KAP XP(LOW_KAPPA, UPC_KAPPA )
+#define GR_LAM XP(LOW_LAMBDA, UPC_LAMBDA )
+#define GR_MU XP(LOW_MU, UPC_MU )
+#define GR_NU XP(LOW_NU, UPC_NU )
+#define GR_XI XP(LOW_XI, UPC_XI )
+#define GR_OMI XP(LOW_OMICRON,UPC_OMICRON)
+#define GR_PI XP(LOW_PI, UPC_PI )
+#define GR_RHO XP(LOW_RHO, UPC_RHO )
+#define GR_SIG XP(LOW_SIGMA, UPC_SIGMA )
+#define GR_TAU XP(LOW_TAU, UPC_TAU )
+#define GR_UPS XP(LOW_UPSILON,UPC_UPSILON)
+#define GR_PHI XP(LOW_PHI, UPC_PHI )
+#define GR_CHI XP(LOW_CHI, UPC_CHI )
+#define GR_PSI XP(LOW_PSI, UPC_PSI )
+#define GR_OME XP(LOW_OMEGA, UPC_OMEGA )
+#define BB_ELLI X(ELLIPSIS)
+#define BB_PLNK X(PLANCK_CON)
+#define BB_ANGS X(ANGSTROM)
+#define BB_BITC X(BITCOIN)
+#else // UNICODEMAP_ENABLE
+#define TR_ACIR KC_A
+#define TR_CCED KC_C
+#define TR_GBRE KC_G
+#define TR_ICIR KC_I
+#define TR_I_NO KC_I
+#define TR_IDOT KC_I
+#define TR_ODIA KC_O
+#define TR_SCED KC_S
+#define TR_UCIR KC_U
+#define TR_UDIA KC_U
+#define GR_ALP KC_NO
+#define GR_BET KC_NO
+#define GR_GAM KC_NO
+#define GR_DEL KC_NO
+#define GR_EPS KC_NO
+#define GR_ZET KC_NO
+#define GR_ETA KC_NO
+#define GR_THE KC_NO
+#define GR_IOT KC_NO
+#define GR_KAP KC_NO
+#define GR_LAM KC_NO
+#define GR_MU KC_NO
+#define GR_NU KC_NO
+#define GR_XI KC_NO
+#define GR_OMI KC_NO
+#define GR_PI KC_NO
+#define GR_RHO KC_NO
+#define GR_SIG KC_NO
+#define GR_TAU KC_NO
+#define GR_UPS KC_NO
+#define GR_PHI KC_NO
+#define GR_CHI KC_NO
+#define GR_PSI KC_NO
+#define GR_OME KC_NO
+#define BB_ELLI KC_NO
+#define BB_PLNK KC_NO
+#define BB_ANGS KC_NO
+#define BB_BITC KC_NO
+#endif // UNICODEMAP_ENABLE
-// Custom keycodes
-enum userspace_custom_keycodes {
- // Turkish letters, with shifting
- TUR_A = SAFE_RANGE,
- TUR_C,
- TUR_G,
- TUR_I,
- TUR_O,
- TUR_S,
- TUR_U,
- // Unicode mode switch
- UNI_LI,
- UNI_WN,
- // Double keys
- DBL_SPC,
- DBL_ANG,
- DBL_PAR,
- DBL_SQR,
- DBL_BRC,
- DBL_QUO,
- DBL_DQT,
- DBL_GRV,
- // Diagonal mouse movements
- MO_NE,
- MO_NW,
- MO_SE,
- MO_SW,
- MO_S_NE,
- MO_S_NW,
- MO_S_SE,
- MO_S_SW,
- // Layer switches and lock functionality
- K_MOUSE,
- K_NUMBR,
- K_LOCK,
- K_GAMES,
- // Secret macros
- SECRET1,
- SECRET2,
- SECRET3
-};
+// MOD-tap definitions
+#define GUI_A MT(MOD_LGUI, DV_A)
+#define ALT_O MT(MOD_LALT, DV_O)
+#define CTRL_E MT(MOD_LCTL, DV_E)
+#define SHIFT_U MT(MOD_LSFT, DV_U)
+#define ALTGR_Q MT(MOD_RALT, DV_Q)
+#define GUI_S MT(MOD_RGUI, DV_S)
+#define ALT_N MT(MOD_LALT, DV_N)
+#define CTRL_T MT(MOD_LCTL, DV_T)
+#define SHIFT_H MT(MOD_LSFT, DV_H)
+#define ALTGR_V MT(MOD_RALT, DV_V)
-// Do tap dancable semicolon key if available
-#ifdef TAP_DANCE_ENABLE
-enum {
- SCL = 0
-};
-#define MY_SCL TD(SCL)
-#else
-#define MY_SCL KC_SCLN
-#endif
+// Layer switches
+#define MED_DEL LT(_MEDI, KC_DEL )
+#define NAV_TAB LT(_NAVI, KC_TAB )
+#define SYM_SPC LT(_SYMB, KC_SPC )
+#define NUM_ENT LT(_NUMB, KC_ENT )
+#define FUN_ESC LT(_FUNC, KC_ESC )
+#define MOU_BSP LT(_MOUS, KC_BSPC)
+
+// Layer switches
+#define BB_CHAR OSL(_CHAR)
+#define BB_GAME TG(_GAME)
-// Shared keymaps
-#define LAYOUT_planck_wrapper(...) LAYOUT_planck_grid(__VA_ARGS__)
-#define LAYOUT_letssplit_wrapper(...) LAYOUT_ortho_4x12(__VA_ARGS__)
+/* Depending on how the layouts change with language; the keys are shown as;
+ * ┌────────────────────────────────────────────────┐
+ * │AltGr -none- Shift Shift+AltGr │
+ * └────────────────────────────────────────────────┘
+ * If there is an exclamation mark; it indicates a dead key on this map.
+ */
-/* Dvorak
- * ,------------------------------------------------------------------------.
- * | Esc | ' " | , | . | P | Y || F | G | C | R | L | Bkp |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | Tab | A | O | E | U | I || D | H | T | N | S | / ? |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | SYM | ; : | Q | J | K | X || B | M | W | V | Z | SET |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | TUR | OS | Ctrl| Alt | Shf | Spc || Ent | Lft | Dwn | Up | Rght| MSE |
- * `------------------------------------------------------------------------' */
-#define DVORAK \
- KC_ESC, KC_QUOT,KC_COMM,KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
- KC_TAB, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, \
- K_NUMBR,MY_SCL, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, MO(_SE), \
- MO(_AL),KC_LGUI,KC_LCTL,KC_LALT,KC_LSFT,KC_SPC, KC_ENT, KC_LEFT,KC_DOWN,KC_UP, KC_RGHT,K_MOUSE
+/* Base layout
+ * DVORAK
+ * ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐
+ * ` ~ │ ' " │ , < │ . > │ p P │ y Y │ │ f F │ g G │ c C │ r R │ l L │ < >
+ * ├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤
+ * \ | │ a A │ o O │ e E │ u U │ i I │ │ d D │ h H │ t T │ n N │ s S │ - _
+ * ├─Gui─┼─Alt─┼─Ctr─┼─Sft─┼─────┤ ├─────┼─Sft─┼─Ctr─┼─Alt─┼─Gui─┤
+ * / ? │ ; : │ q Q │ j J │ k K │ x X │ │ b B │ m M │ w W │ v V │ z Z │ = +
+ * └─────┴AltGr┴─────┼─────┼─────┼─────┐ ┌─────┼─────┼─────┼─────┴AltGr┴─────┘
+ * │ Del │ Tab │Space│ │Enter│ Esc │BkSpc│
+ * └─Med─┴─Nav─┴─Sym─┘ └─Num─┴─Fun─┴─Mou─┘
+ * TURKISH F
+ * ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐
+ * ¬+ *±│@f F │ g G │ ğ Ğ │¶ı I │ôo OÔ│ │¥d D │®r R │ n N │°h H │£p P │|< >¦
+ * !├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼────!┤ !
+ * `x Xà│ûu UÛ│îi İÎ│€e E │âa AÂ│ûü ÜÛ│ │₺t T │ k K │µm M │ l L │´y Yá│#ş Şǎ
+ * ! !├─Gui─┼─Alt─┼─Ctr─┼─Sft─┼─────┤ ├─────┼─Sft─┼─Ctr─┼─Alt!┼─Gui─┤
+ * äq Qå│«j J<│»ö Ö>│“v V │¢c C©│”ç Ç │ │ z Z │§s S │×b B │÷. :ȧ│·, ; │~w W
+ * └─────┴AltGr┴─────┼─────┼─────┼─────┐ ┌─────┼─────┼─────┼─────┴AltGr┴─────┘
+ * │ Del │ Tab │Space│ │Enter│ Esc │BkSpc│
+ * └─Med─┴─Nav─┴─Sym─┘ └─Num─┴─Fun─┴─Mou─┘
+ * The thing about this layout is that these will fit most boards I have.
+ */
+#define _BL1_5_ DV_QUOT,DV_COMM,DV_DOT, DV_P, DV_Y
+#define _BR1_5_ DV_F, DV_G, DV_C, DV_R, DV_L
+#define _BL2_5_ GUI_A, ALT_O, CTRL_E, SHIFT_U,DV_I
+#define _BR2_5_ DV_D, SHIFT_H,CTRL_T, ALT_N, GUI_S
+#define _BL3_5_ DV_SCLN,ALTGR_Q,DV_J, DV_K, DV_X
+#define _BR3_5_ DV_B, DV_M, DV_W, ALTGR_V,DV_Z
+#define _BL4_3_ MED_DEL,NAV_TAB,SYM_SPC
+#define _BR4_3_ NUM_ENT,FUN_ESC,MOU_BSP
+// The extra line for the 6th (or 0th) row
+#define _BL1_1_ DV_GRV
+#define _BR1_1_ KC_NUBS
+#define _BL2_1_ DV_BSLS
+#define _BR2_1_ DV_MINS
+#define _BL3_1_ DV_SLSH
+#define _BR3_1_ DV_EQL
-/* Alternative character overlay
- * ,------------------------------------------------------------------------.
- * | | ' ' | Undo| Redo|Pound| Yen || | G | C | |TLira| Del |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | A | O | Euro| U | I ||Degre|Plank| | | S | Ins |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | " " | Cut | Copy|Paste| || BTC | < > | ( ) | [ ] | { } | PgUp|
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | | | | | || | Home|PgDwn| PgUp| End | |
- * `------------------------------------------------------------------------' */
-#define ALTCHAR \
- _______,DBL_QUO,UNDO, REDO, CUR_BPN,CUR_YEN,_______,TUR_G, TUR_C, _______,CUR_LIR,KC_DEL , \
- _______,TUR_A, TUR_O, CUR_EUR,TUR_U, TUR_I, PHY_DEG,PHY_HBR,_______,_______,TUR_S, KC_INS , \
- _______,DBL_DQT,CUT, COPY, PASTE, DBL_GRV,CUR_BIT,DBL_ANG,DBL_PAR,DBL_SQR,DBL_BRC,_______, \
- _______,_______,_______,_______,_______,DBL_SPC,_______,KC_HOME,KC_PGDN,KC_PGUP,KC_END, _______
+/* Extra characters layer
+ * This is accessed using unicode; so IBus compatible apps only.
+ * ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐
+ * │TrFlg│Lenny│Table│ π │ υ │ │ φ │ γ │ χ │ ρ │ λ │
+ * ├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤
+ * │ α │ ο │ ε │ ψ │ ι │ │ δ │ η │ τ │ ν │ σ │
+ * ├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤
+ * │ ₿ │ θ │ ℏ │ κ │ ξ │ │ β │ μ │ ω │ Å │ ζ │
+ * └─────┴─────┴─────┼─────┼─────┼─────┐ ┌─────┼─────┼─────┼─────┴─────┴─────┘
+ * │ Shf │ ... │ GPG │ │ │ │ Shf │
+ * └─────┴─────┴─────┘ └─────┴─────┴─────┘
+ *
+ */
+#define _CL1_5_ TR_FLAG,BB_LENY,BB_TABL,GR_PI, GR_UPS
+#define _CR1_5_ GR_PHI, GR_GAM, GR_CHI, GR_RHO, GR_LAM
+#define _CL2_5_ GR_ALP, GR_OMI, GR_EPS, GR_PSI, GR_IOT
+#define _CR2_5_ GR_DEL, GR_ETA, GR_TAU, GR_NU, GR_SIG
+#define _CL3_5_ BB_BITC,GR_THE, BB_PLNK,GR_KAP, GR_XI
+#define _CR3_5_ GR_BET, GR_MU, GR_OME, BB_ANGS,GR_ZET
+#define _CL4_3_ KC_RSFT,BB_ELLI,BB_PGPK
+#define _CR4_3_ XXXXXXX,XXXXXXX,KC_LSFT
/* Game layer
- * ,------------------------------------------------------------------------.
- * | OFF | Q | W | E | R | T || Esc | 7 | 8 | 9 |NumLk|Bkspc|
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | Tab | A | S | D | F | G || F1 | 4 | 5 | 6 | \ | Ent |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | Z | X | C | V | B || F2 | 1 | 2 | 3 | ^ | |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | / | ` | | | | Spc || Spc | Ent | 0 | < | v | > |
- * `------------------------------------------------------------------------' */
-#define GAME \
- K_GAMES,KC_Q, KC_W, KC_E, KC_R, KC_T, KC_ESC, KC_P7, KC_P8, KC_P9, KC_NLCK,KC_BSPC, \
- KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_F1, KC_P4, KC_P5, KC_P6, KC_BSLS,KC_ENT , \
- _______,KC_Z, KC_X, KC_C, KC_V, KC_B, KC_F2, KC_P1, KC_P2, KC_P3, KC_UP, _______, \
- KC_SLSH,KC_GRV, _______,_______,_______,KC_SPC, KC_SPC, KC_ENT, KC_P0, KC_LEFT,KC_DOWN,KC_RGHT
+ * This layer turns off the tap-hold keys for the left half.
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │ Q │ W │ E │ R │ T │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * Tab │ A │ S │ D │ F │ G │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * Shift│ Z │ X │ C │ V │ B │
+ * └─────┴─────┴─────┼─────┼─────┼─────┐
+ * │ Esc │Enter│Space│
+ * └─────┴─────┴─────┘
+ */
+#define _GA1_5_ KC_Q, KC_W, KC_E, KC_R, KC_T
+#define _GA1_1_ _______
+#define _GA2_5_ KC_A, KC_S, KC_D, KC_F, KC_G
+#define _GA2_1_ KC_TAB
+#define _GA3_5_ KC_Z, KC_X, KC_C, KC_V, KC_B
+#define _GA3_1_ KC_LSFT
+#define _GA4_3_ KC_ESC, KC_ENT, KC_SPC
+
+/* Media layer
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │Speed│ Mod │ Hue │ Sat │ Bri │ RGB light control
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │Togg.│Prev.│MuTog│MuStp│Next │ Media control
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │Sink │Vol -│ Mut │Eject│Vol +│ Volume control
+ * ┌─────┼─────┼─────┼─────┴─────┴─────┘
+ * │OledL│Veloc│Music│ Feature control on keyboard
+ * └─────┴─────┴─────┘
+ */
+#define _ME1_5_ RGB_SPI,RGB_MOD,RGB_HUI,RGB_SAI,RGB_VAI
+#define _ME2_5_ RGB_TOG,KC_MPRV,KC_MPLY,KC_MSTP,KC_MNXT
+#define _ME3_5_ KC_F13, KC_VOLD,KC_MUTE,KC_EJCT,KC_VOLU
+#define _ME4_3_ BB_OLED,VLK_TOG,MU_TOG
+
+/* Navigation layer
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │Redo │Paste│Yank │ Cut │PrScr│
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │Undo │ < │ v │ ^ │ > │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ Ins │Home │PgDwn│PgUp │ End │
+ * ┌─────┼─────┼─────┼─────┴─────┴─────┘
+ * │Enter│ Esc │BkSpc│
+ * └─────┴─────┴─────┘
+ */
+#define _NA1_5_ BB_REDO,BB_PSTE,BB_YANK,BB_CUT, KC_PSCR
+#define _NA2_5_ BB_UNDO,KC_LEFT,KC_DOWN,KC_UP, KC_RGHT
+#define _NA3_5_ KC_INS, KC_HOME,KC_PGDN,KC_PGUP,KC_END
+#define _NA4_3_ KC_ENT, KC_ESC, KC_BSPC
/* Symbols layer
- * ,------------------------------------------------------------------------.
- * | OFF | ` | ~ | [ | ] | { || } | - | _ | = | + | |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | 1 | 2 | 3 | 4 | 5 || 6 | 7 | 8 | 9 | 0 | \ |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | ! | @ | # | $ | % || ^ | & | * | ( | ) | LCK |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | | | | | | || | | | | | |
- * `------------------------------------------------------------------------' */
-#define NUMBERS \
- K_NUMBR,KC_GRV, KC_TILD,KC_LBRC,KC_RBRC,KC_LCBR,KC_RCBR,KC_MINS,KC_UNDS,KC_EQL, KC_PLUS,_______, \
- _______,KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS, \
- _______,KC_EXLM,KC_AT, KC_HASH,KC_DLR, KC_PERC,KC_CIRC,KC_AMPR,KC_ASTR,KC_LPRN,KC_RPRN,K_LOCK , \
- KC_PIPE,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______
+ * This layer has the central columns shifted for convenience
+ * DVORAK
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │ ` │ { │ } │ / │ = │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ ~ │ [ │ ] │ ? │ + │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │CapsL│ ( │ ) │ \ │ | │
+ * ┌─────┼─────┼─────┼─────┴─────┴─────┘
+ * │Enter│ Esc │BkSpc│
+ * └─────┴─────┴─────┘
+ * Turkish F
+ * (AltGr is right on the central column, red. keys on main layer are omitted)
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │ + ¬ │ / \ │ - | │ │ │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ * ± │ ? ¿ │ _ │ │ │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │CapsL│ │ │ │ │
+ * ┌─────┼─────┼─────┼─────┴─────┴─────┘
+ * │Enter│ Esc │BkSpc│
+ * └─────┴─────┴─────┘
+ * QWERTY
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │ ` │ - │ = │ { │ } │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ ~ │ _ │ + │ [ │ ] │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │CapsL│ ( │ ) │ \ │ | │
+ * ┌─────┼─────┼─────┼─────┴─────┴─────┘
+ * │Enter│ Esc │BkSpc│
+ * └─────┴─────┴─────┘
+ */
+#define _SY1_5_ DV_GRV, DV_LCBR,DV_RCBR,DV_SLSH,DV_EQL
+#define _SY2_5_ DV_TILD,DV_LBRC,DV_RBRC,DV_QUES,DV_PLUS
+#define _SY3_5_ KC_CAPS,DV_LPRN,DV_RPRN,DV_BSLS,DV_PIPE
+#define _SY4_3_ KC_ENT, KC_ESC, KC_BSPC
-/* Settings layer
- * ,------------------------------------------------------------------------.
- * |BLLed| F1 | F2 | F3 | F4 | Lin || Win | Wake| |Hue -|Hue +|Reset|
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | F5 | F6 | F7 | F8 | || | |RGBto|Sat -|Sat +| |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | Game| F9 | F10 | F11 | F12 |Vol 0||PrtSc| |RGBan|Bri -|Bri +| |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * |Musir| | | | |Vol -||Vol +| Prev| Stop|TogMu| Next| |
- * `------------------------------------------------------------------------' */
-#define SETTINGS \
- BL_STEP,KC_F1, KC_F2, KC_F3, KC_F4, UNI_LI, UNI_WN, KC_WAKE,_______,RGB_HUD,RGB_HUI,RESET , \
- _______,KC_F5, KC_F6, KC_F7, KC_F8, _______,_______,_______,RGB_TOG,RGB_SAD,RGB_SAI,_______, \
- K_GAMES,KC_F9, KC_F10, KC_F11, KC_F12, KC_MUTE,KC_PSCR,_______,RGB_MOD,RGB_VAD,RGB_VAI,_______, \
- MU_TOG, _______,_______,_______,_______,KC_VOLD,KC_VOLU,KC_MPRV,KC_MSTP,KC_MPLY,KC_MNXT,_______
+/* Numbers layer
+ * This layer contains numbers and the associated symbols.
+ * DVORAK
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │ < │ 7 & │ 8 * │ 9 ( │ 0 ) │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ _ │ 4 $ │ 5 % │ 6 ^ │ - │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ > │ 1 ! │ 2 @ │ 3 # │Char.│
+ * └─────┴─────┴─────┼─────┼─────┼─────┐
+ * │ Del │ Tab │Space│
+ * └─────┴─────┴─────┘
+ * Turkish F
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │ < | │{7 ' │[8 ( │]9 )±│}0 =°│
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ │¼4 $ │½5 %⅜│¾6 & │ │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ > ¦ │¹1 !¡│²2 " │#3 ^³│Char.│
+ * └─────┴─────┴─────┼─────┼─────┼─────┐
+ * │ Del │ Tab │Space│
+ * └─────┴─────┴─────┘
+ */
+#define _NU1_5_ KC_NUBS,KC_7, KC_8, KC_9, KC_0
+#define _NU2_5_ DV_UNDS,KC_4, KC_5, KC_6, DV_MINS
+#define _NU3_5_ LSFT(KC_NUBS), KC_1, KC_2, KC_3, BB_CHAR
+#define _NU4_3_ KC_DEL, KC_TAB, KC_SPC
+
+/* Function layer
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │ F01 │ F02 │ F03 │ F04 │EEPRM│
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ F05 │ F06 │ F07 │ F08 │EEPRM│
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ F09 │ F10 │ F11 │ F12 │GameL│
+ * └─────┴─────┴─────┼─────┼─────┼─────┐
+ * │ Del │ Tab │Space│
+ * └─────┴─────┴─────┘
+ */
+#define _FU1_5_ KC_F1, KC_F2, KC_F3, KC_F4, RESET
+#define _FU2_5_ KC_F5, KC_F6, KC_F7, KC_F8, EEP_RST
+#define _FU3_5_ KC_F9, KC_F10, KC_F11, KC_F12, BB_GAME
+#define _FU4_3_ KC_DEL, KC_TAB, KC_SPC
/* Mouse layer
- * ,------------------------------------------------------------------------.
- * |Ulock| \ | ^ | / |.....|.....||.....|.....| |\|.| |^| | |/|.| |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | < | Mid | > |Btn 4|.....||.....|Btn 5| <-- | Mid | --> | |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | / | v | \ |.....|.....||.....|.....| |/| | |v| | |\| | LCK |
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | | | | | | Left||Right| | |Accl0|Accl1|Accl2|
- * `------------------------------------------------------------------------' */
-#define MOUSE \
- K_MOUSE,MO_NW, MO_N, MO_NE, XXX, XXX ,XXX, XXX, MO_S_NW,MO_S_N, MO_S_NE,_______, \
- _______,MO_W, MO_CL_M,MO_E, MO_CL_4,XXX ,XXX, MO_CL_5,MO_S_W, MO_CL_M,MO_S_E, _______, \
- _______,MO_SW, MO_S, MO_SE, XXX, XXX ,XXX, XXX, MO_S_SW,MO_S_S, MO_S_SE,K_LOCK , \
- _______,_______,_______,_______,_______,MO_CL_L,MO_CL_R,_______,MO_AC_0,MO_AC_1,MO_AC_2,_______
+ * ┌─────┬─────┬─────┬─────┬─────┐
+ * │Slow │Right│ Mid │ Lft │Fast │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ |<| │ |v| │ |^| │ |>| │ Bt4 │
+ * ├─────┼─────┼─────┼─────┼─────┤
+ * │ <<< │ vvv │ ^^^ │ >>> │ Bt5 │
+ * └─────┴─────┴─────┼─────┼─────┼─────┐
+ * │ Del │ Tab │Space│
+ * └─────┴─────┴─────┘
+ */
+#define _MO1_5_ KC_ACL0,KC_BTN1,KC_BTN2,KC_BTN3,KC_ACL2
+#define _MO2_5_ KC_MS_L,KC_MS_D,KC_MS_U,KC_MS_R,KC_BTN4
+#define _MO3_5_ KC_WH_L,KC_WH_D,KC_WH_U,KC_WH_R,KC_BTN5
+#define _MO4_3_ KC_DEL, KC_TAB, KC_SPC
/* Music layer
- * ,------------------------------------------------------------------------.
- * |.....|.....|.....|.....|.....|.....||.....|.....|.....|.....|.....|.....|
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * |.....|.....|.....|.....|.....|.....||.....|.....|.....|.....|.....|.....|
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * |.....|.....|.....|.....|.....|.....||.....|.....|.....|.....|.....|.....|
- * |-----+-----+-----+-----+-----+-----++-----+-----+-----+-----+-----+-----|
- * | togg| rec | stop| play| slow| fast||modes|.....|.....|.....|.....|.....|
- * `------------------------------------------------------------------------'
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └───┴───┴───┼───┼───┼───┼───┼───┼───┼───┴───┴───┘
+ * │Rec│Stp│Ply│Tmp│Mod│Off│
+ * └───┴───┴───┴───┴───┴───┘
*/
-#define MUSIC \
- MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK, \
- MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK, \
- MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK, \
- MU_TOG, MU_REC, MU_STOP,MU_PLAY,MU_SLOW,MU_FAST,MU_MOD, MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK
-
-#endif
+#define _MUL_3_ MU_REC, MU_STOP,MU_PLAY
+#define _MUR_3_ MU_TEMP,MU_MOD, MU_TOG
+#define _MU_01_ MU_MASK
+#define _MU_02_ MU_MASK,MU_MASK
+#define _MU_03_ MU_MASK,MU_MASK,MU_MASK
+#define _MU_06_ MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK
+#define _MU_08_ MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK
+#define _MU_10_ MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK
+#define _MU_12_ MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK,MU_MASK
diff --git a/users/bbaserdem/config.h b/users/bbaserdem/config.h
index 3dde5772cc..477378102b 100644
--- a/users/bbaserdem/config.h
+++ b/users/bbaserdem/config.h
@@ -1,9 +1,134 @@
-#ifndef USERSPACE_CONFIG_H
-#define USERSPACE_CONFIG_H
+/* Copyright 2021 Batuhan Başerdem
+ * <baserdem.batuhan@gmail.com> @bbaserdem
+ *
+ * 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
-#ifdef TAP_DANCE_ENABLE
- #define TAPPING_TERM 300
- #define TAPPING_TOGGLE 1
+/* CONFIG
+ * Common hardware configuration accross my boards
+ */
+// Space saving
+#ifdef LOCKING_SUPPORT_ENABLE
+# undef LOCKING_SUPPORT_ENABLE
#endif
+#ifdef LOCKING_RESYNC_ENABLE
+# undef LOCKING_RESYNC_ENABLE
+#endif
+#ifndef NO_DEBUG
+# define NO_DEBUG
+#endif
+
+#if !defined(NO_PRINT) && !defined(CONSOLE_ENABLE)
+# define NO_PRINT
+#endif
+
+// Some of my own settings
+# define HOUSEKEEPING_THROTTLE_INTERVAL_MS 250
+
+// Split transport settings
+#ifdef SPLIT_KEYBOARD
+# define SPLIT_TRANSPORT_MIRROR
+# define SPLIT_LAYER_STATE_ENABLE
+# define SPLIT_MODS_ENABLE
+# define SPLIT_TRANSACTION_IDS_USER RPC_ID_CONFIG_SYNC, RPC_ID_RUNTIME_SYNC, RPC_ID_KEYMAP_SYNC
+# define SPLIT_LED_STATE_ENABLE
+# ifdef WPM_ENABLE
+# define SPLIT_WPM_ENABLE
+# endif // WPM_ENABLE
+# ifdef OLED_ENABLE
+# define SPLIT_OLED_ENABLE
+# endif // OLED_ENABLE
+#endif // SPLIT_KEYBOARD
+
+// Unicode entry mode
+#ifdef UNICODEMAP_ENABLE
+# define UNICODE_SELECTED_MODES UC_LNX
+ // Adapt the unicode entry mode to dvorak
+# ifdef UNICODE_KEY_LNX
+# undef UNICODE_KEY_LNX
+# endif
+# define UNICODE_KEY_LNX LCTL(LSFT(KC_F))
+#endif // UNICODEMAP_ENABLE
+
+// Mousekey mode
+#ifdef MOUSEKEY_ENABLE
+# define MK_COMBINED
+#endif // MOUSEKEY_ENABLE
+
+// Tap-hold settings
+#define TAPPING_TERM 200
+#define TAP_CODE_DELAY 20
+#define IGNORE_MOD_TAP_INTERRUPT
+#define PERMISSIVE_HOLD
+#define TAPPING_FORCE_HOLD
+
+// Backlight settings
+#ifdef BACKLIGHT_ENABLE
+# define BACKLIGHT_BREATHING
+# define BREATHING_PERIOD 5
+#endif // BACKLIGHT_ENABLE
+
+// Audio definitions
+#ifdef AUDIO_ENABLE
+//# define AUDIO_ENABLE_TONE_MULTIPLEXING
+ // Make findable songs as defaults
+# ifdef HOROLOGY
+# define STARTUP_SONG SONG(HOROLOGY)
+# endif
+# ifdef PEOPLE_VULTURES
+# define GOODBYE_SONG SONG(PEOPLE_VULTURES)
+# endif
+# ifdef NONAGON_INFINITY
+# define MUSIC_ON_SONG SONG(NONAGON_INFINITY)
+# endif
+# ifdef WAH_WAH
+# define MUSIC_OFF_SONG SONG(WAH_WAH)
+# endif
+ // Audio code expects these to be defined
+# ifdef BIG_FIG_WASP
+# define GAME_ON_SONG SONG(BIG_FIG_WASP)
+# else
+# define GAME_ON_SONG SONG(USSR_ANTHEM)
+# endif
+# ifdef POLYGONDWANALAND
+# define GAME_OFF_SONG SONG(POLYGONDWANALAND)
+# else
+# define GAME_OFF_SONG SONG(NOCTURNE_OP_9_NO_1)
+# endif
+#endif // AUDIO_ENABLE
+
+// OLED definitions
+#ifdef OLED_ENABLE
+ // Timeout does not work for split secondary board; i implemented it myself
+# define OLED_TIMEOUT 30000
+ // Fade out the screen when timing out
+# define OLED_FADE_OUT
+# define OLED_FADE_OUT_INTERVAL 15
+#endif // OLED_ENABLE
-#endif // !USERSPACE_CONFIG_H
+// For perkey leds
+#ifdef RGB_MATRIX_ENABLE
+// This is not working
+//# define RGB_DISABLE_TIMEOUT 1800000
+# define RGB_DISABLE_WHEN_USB_SUSPENDED true
+ // Start using this mode
+# define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_RAINBOW_BEACON
+# define RGB_MATRIX_STARTUP_HUE 100
+# define RGB_MATRIX_STARTUP_SAT 255
+# define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS
+ // Some config options
+# define RGB_MATRIX_KEYRELEASES
+# define RGB_MATRIX_FRAMEBUFFER_EFFECTS // Enable framebuffer effects
+#endif // RGB_MATRIX_ENABLE
diff --git a/users/bbaserdem/keymap-bitmaps/.gitignore b/users/bbaserdem/keymap-bitmaps/.gitignore
new file mode 100644
index 0000000000..6448f593d6
--- /dev/null
+++ b/users/bbaserdem/keymap-bitmaps/.gitignore
@@ -0,0 +1,4 @@
+*.bmp
+splitImages
+templates
+!.gitignore
diff --git a/users/bbaserdem/keymap-bitmaps/cropBmp b/users/bbaserdem/keymap-bitmaps/cropBmp
new file mode 100755
index 0000000000..4a322b4175
--- /dev/null
+++ b/users/bbaserdem/keymap-bitmaps/cropBmp
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# Copyright 2021 Batuhan Başerdem
+# <baserdem.batuhan@gmail.com> @bbaserdem
+#
+# 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/>.
+
+# Goes through all the files and turns them into strips in their respective folder
+if [ -z "${1}" ] ; then
+ echo 'No argument; defaulting to script directory.'
+ target_dir="$(dirname "${0}")"
+elif [ -d "${1}" ] ; then
+ echo "Targeting files in '${1}'."
+ target_dir="${1}"
+else
+ echo 'Argument is not directory.'
+ exit 1
+fi
+
+output_dir="${target_dir}/splitImages"
+mkdir -p "${output_dir}"
+
+for this_image in "${target_dir}/"*.bmp ; do
+ echo "Found '${this_image}'."
+ this_name="$(basename "${this_image%%.bmp}")"
+ convert "${this_image}" -crop 'x8' "${output_dir}/${this_name}"_%d.bmp
+done
diff --git a/users/bbaserdem/readme.md b/users/bbaserdem/readme.md
new file mode 100644
index 0000000000..0a1b80cc74
--- /dev/null
+++ b/users/bbaserdem/readme.md
@@ -0,0 +1,131 @@
+# BBASERDEM userspace code for qmk
+
+My userspace code for my various keyboards; available here.
+
+## Builds
+
+These are my keyboard builds and info, it allows me to plan out my builds.
+
+### Planck SERVER
+
+* Board: `kprepublic/jj40`
+* Microcontroller: Embedded
+* Layout: `ortho_4x12`
+* Functionality: Underglow RGB Lighting, LED diode lighting.
+* Case: Clear Acrylic Top and Bottow, with Frosted Acrylic Diffuser (Smashing Acrylics)
+* Switches: BOX Navy
+* Keycaps: Datamancer Tall Deco Typewriter Keycaps
+
+Just a decorative planck replacement (for my rev4 PCB that died.)
+
+### Planck Light
+
+* Board: `planck/light`
+* Microcontroller: Embedded
+* Layout: `ortho_4x12`
+* Functionality: Per-key RGB Lighting, Audio.
+* Case: Clear Acrylic Top and Bottow, with Frosted Acrylic Diffuser (Smashing Acrylics)
+* Switches: BOX Navy
+* Keycaps: Datamancer Tall Deco Typewriter Keycaps
+
+Just a decorative planck replacement (for my rev4 PCB that died.)
+
+### Corne ARM
+
+* Board: `crkbd/rev1`
+* Microcontroller: Proton C (x2)
+* Layout: `split_3x6_3`
+* Functionality: OLED, Audio, Per-key RGB Lighting, Rotary Encoder (x2)
+* Case: IMK Corne Case v2 Polycarbonate
+* Switches: Healios V2
+* Keycaps: POM Jelly
+
+PCB is actually [Proton-C Compatible crkbd PCB](https://github.com/ItsWaffIe/waffle_corne).
+
+### Corne Lite
+
+* Board: `crkbd/rev1`
+* Microcontroller: Pro Micro (x2)
+* Layout: `split_3x5_3`
+* Functionality: Per-key RGB Lighting, OLED (No firmware space)
+* Case: Custom
+* Switches: Choc Low Burnt Orange
+* Keycaps: [Scooped Choc Keycaps](https://mkultra.click/collections/keycaps/products/scooped-choc-keycaps?variant=31223543365730)
+
+Maybe try adding a trackpad for this, as detailed
+[here](https://github.com/manna-harbour/crkbd/blob/master/trackpoint/readme.org).
+
+### Kyria
+
+* Board: `splitkb/kyria/rev1`
+* Microcontroller: Pro Micro (x2)
+* Layout: `split_3x6_6`
+* Functionality: OLED, Underglow RGB Lighting (No firmware space), Rotary Encoder (x2)
+* Case: Matte Black Acrylic High-Profile case
+* Switches: Gateron Ink Silent Black
+* Keycaps: Oblotzky SA Oblivion
+
+Main driver at work currently; love the switches and the board layout.
+
+# Firmware building
+
+## Archlinux
+
+On archlinux, the package *arm-none-eabi-gcc* is too new.
+To fix; add to the environment `CFLAGS="-Wno-error=deprecated"` to compilation commands.
+Also; says to run `avr-gcc` version `8.4.0` for smaller firmware,
+but I find that it only saves a few bytes.
+
+## Bootloader
+
+Needed to type this out from the QMK website.
+If I want to flash a new bootloader for a machine; here are steps;
+
+1. Flash the util/pro_micro_ISP_B6_10.hex to a spare promicro using;
+`avrdude -p atmega32u4 -P "$(ls /dev/ttyACM*)" -c avr109 -D -U flash:w:pro_micro_ISP_B6_10.hex`
+2. Wire the pins; (first is the ISP pro micro; second is the target)
+```
+Pro Micro 10 (B6) <-> Keyboard RESET
+Pro Micro 15 (B1) <-> Keyboard B1 (SCLK)
+Pro Micro 16 (B2) <-> Keyboard B2 (MOSI)
+Pro Micro 14 (B3) <-> Keyboard B3 (MISO)
+Pro Micro VCC <-> Keyboard VCC
+Pro Micro GND <-> Keyboard GND
+```
+I do have this on hand I believe; from massdrop's planck light firmware updater.
+3. Connect the flashed pro micro to my computer and run
+`avrdude -c avrisp -P "$(ls /dev/ttyACM*)" -p atmega32u4 -U flash:w:bootloader_atmega32u4_1.0.0.hex:i -U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m`
+
+The avrisp here refers to the firmware on the ISP flasher pro micro.
+The `atmega32u4` refers to the CPU used in the respective breakout boards.
+The `avrdude` command interacts with catalina bootloader.
+The shell call after the `-P` flag auto finds the port that the pro micro connects to.
+The last few arguments are some jumpers apparently.
+
+# Features
+
+My userspace has a lot of shared code between different keyboards.
+These files are prefixed with `sbp-` to remove any naming clash.
+
+* [bb-audio](bb-audio.c): Code dealing with audio playback using onboard sound.
+* [bb-encoder](bb-encoder.c): Rotary encoder sutff.
+* [bb-macro](bb-macro.c): My custom keycodes; macros, tap dances, etc.
+* [bb-oled](bb-oled.c): Controls OLED displays. For higher memory; there is also [bb-oled-extra](bb-oled-extra.c).
+* [bb-rgb](bb-rgb.c): Controls per-key RGB LED matrix stuff, and layer indication. Uses `RGB_MATRIX`.
+* [bb-underglaw](bb-underglow.c): Controls RGB LED strip, and layer indication. Uses `RGBLIGHT`.
+
+# Layout
+
+My personal layout is mostly inspired by the
+[Miryoku layout](../manna-harbour_miryoku/miryoku.org).
+There are some changes to make it friendlier to international keyboards.
+My board is compatible with software implementation of Dvorak and Turkish F.
+
+## Base
+
+Base layer uses tap-hold functionality to have access to modifiers.
+The modifiers are mirrored on each half of the layout;
+as to make those modifiers accessible to the keys that overlap them.
+Besides the Alt key; each side has the proper L/R version of the modifier.
+Since Right Alt key functions as AltGr key;
+both the L and R versions are available on each side.
diff --git a/users/bbaserdem/rules.mk b/users/bbaserdem/rules.mk
index 9c7e78e2f8..58f72bb110 100644
--- a/users/bbaserdem/rules.mk
+++ b/users/bbaserdem/rules.mk
@@ -1,21 +1,87 @@
+# Copyright 2021 Batuhan Başerdem
+# <baserdem.batuhan@gmail.com> @bbaserdem
+#
+# 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 compilation flags
+LTO_ENABLE = yes
+
+# These should be enabled in all boards
+MOUSEKEY_ENABLE = yes # Mouse emulation keys
+EXTRAKEY_ENABLE = yes # OS signals like volume control
+UNICODEMAP_ENABLE = yes # Used for unicode character emulation
+
+# These should be disabled in all boards
+BOOTMAGIC_ENABLE = no # Access to EEPROM settings, not needed
+CONSOLE_ENABLE = no # Allows console output with a command
+COMMAND_ENABLE = no # Some bootmagic thing i dont use
+SLEEP_LED_ENABLE = no # Breathes LED's when computer is asleep. Untested.
+MIDI_ENABLE = no # Midi driver (untested)
+UNICODE_ENABLE = no # We use unicodemap, not unicode
+UCIS_ENABLE = no # We use unicodemap, not ucis
+VARIABLE_TRACE = no # Allows debugging variables
+KEY_LOCK_ENABLE = no # Allows locking any key. Not used in general
+RGBLIGHT_ENABLE = no # LED strip, but there is RGB_MATRIX instead
+TAP_DANCE_ENABLE = no # Tap dance keys; i don't use tap dance
+
+# These features can be disabled at whim
+NKRO_ENABLE ?= yes # Default is 6KRO
+VELOCIKEY_ENABLE ?= yes # Speed effects change with typing speed
+WPM_ENABLE ?= yes # Get WPM reports as you type
+
+# Manually configure these on each keyboard individually
+# AUDIO_ENABLE # Audio stuff
+# BACKLIGHT_ENABLE # Switch LEDs
+# ENCODER_ENABLE # Rotary encoder
+# RGB_MATRIX_ENABLE # RGB LEDs
+# OLED_ENABLE # For OLED
+
+# Userspace code
SRC += bbaserdem.c
-EXTRAFLAGS += -flto # Used to make code smaller
-# ENABLE
-UNICODE_ENABLE = yes # Used for unicode character emulation
-EXTRAKEY_ENABLE = yes # OS signals like volume control
+# Macros
+SRC += bb-macro.c
+
+# Audio code
+ifeq ($(strip $(AUDIO_ENABLE)), yes)
+SRC += bb-audio.c
+endif
+
+# Rotary encoder stuff
+ifeq ($(strip $(ENCODER_ENABLE)), yes)
+SRC += bb-encoder.c
+endif
+
+# RGB LED (Underglow) code
+ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
+SRC += bb-underglow.c
+endif
+
+# RGB LED (Perkey) code
+ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
+SRC += bb-rgb.c
+endif
+
+# Backlight code
+ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
+SRC += bb-backlight.c
+endif
-# DISABLE
-ifndef BLUETOOTH_ENABLE
- BLUETOOTH_ENABLE = no # No bluetooth
+# OLED code
+ifeq ($(strip $(OLED_ENABLE)), yes)
+ SRC += bb-oled.c
+ ifeq ($(strip $(CTPC)), yes)
+ SRC += bb-oled-extra.c
+ endif
endif
-COMMAND_ENABLE = no # Some bootmagic thing i dont use
-BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
-CONSOLE_ENABLE = no # Allows console output with a command
-SLEEP_LED_ENABLE = no # Breathes LED's when computer is asleep. Untested.
-NKRO_ENABLE = no # Default is 6KRO which is plenty
-MIDI_ENABLE = no # Untested feature
-KEY_LOCK_ENABLE = no # Allows locking any key. Not used
-
-# Disabling this makes it compile, i dont know why
-# VARIABLE_TRACE = no # Allows debugging variables