summaryrefslogtreecommitdiffstats
path: root/keyboards/rocketboard_16/keymaps/via/keymap.c
diff options
context:
space:
mode:
authorSeth <fl3tching101@gmail.com>2021-09-11 00:32:29 -0700
committerGitHub <noreply@github.com>2021-09-11 00:32:29 -0700
commit35bff470f73e5041f4e969f5dae5f60d4c1ea3e0 (patch)
treef70195740edde70fe714102fa81398d390ab22a2 /keyboards/rocketboard_16/keymaps/via/keymap.c
parent5f941910755907ea300a526634c1269823477e7b (diff)
[Keyboard] Update rocketboard_16 with *most* of its final features (#12537)
Diffstat (limited to 'keyboards/rocketboard_16/keymaps/via/keymap.c')
-rw-r--r--keyboards/rocketboard_16/keymaps/via/keymap.c368
1 files changed, 333 insertions, 35 deletions
diff --git a/keyboards/rocketboard_16/keymaps/via/keymap.c b/keyboards/rocketboard_16/keymaps/via/keymap.c
index 0c3ee96d41..050ab9f5b1 100644
--- a/keyboards/rocketboard_16/keymaps/via/keymap.c
+++ b/keyboards/rocketboard_16/keymaps/via/keymap.c
@@ -12,29 +12,41 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
+#include "keycode_lookup.h"
+#include <string.h>
+#ifdef CONSOLE_ENABLE
+#include "print.h"
+#endif
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _BASE 0
+#define _SPEC 1 // Special layer
// Use the following format to create custom key codes to make macros out of and such
-/*
enum custom_keycodes {
- FOO = SAFE_RANGE,
+ KC_EXAM = SAFE_RANGE // "Examine" key code to show the keycode of a key pressed afterwards on the OLED
};
-*/
+
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- [_BASE] = LAYOUT_default(
- RGB_MODE_FORWARD, KC_NUMLOCK,
- KC_KP_7, KC_KP_8, KC_KP_9, KC_DELETE,
- KC_KP_4, KC_KP_5, KC_KP_6, KC_END,
- KC_KP_1, KC_KP_2, KC_KP_3, KC_AUDIO_VOL_UP,
- KC_KP_0, RGB_TOG, KC_AUDIO_MUTE, KC_AUDIO_VOL_DOWN
- )
+ [_BASE] = LAYOUT_default(
+ RGB_MODE_FORWARD, KC_NUMLOCK,
+ KC_KP_7, KC_KP_8, KC_KP_9, KC_DELETE,
+ KC_KP_4, KC_KP_5, KC_KP_6, KC_END,
+ KC_KP_1, KC_KP_2, KC_KP_3, KC_F13,
+ KC_KP_0, MO(1), KC_KP_DOT, KC_KP_ENTER
+ ),
+ [_SPEC] = LAYOUT_default(
+ RGB_MODE_REVERSE, KC_AUDIO_MUTE,
+ KC_NO, KC_NO, KC_NO, KC_EXAM,
+ KC_NO, KC_NO, KC_NO, KC_NO,
+ RESET, RGB_TOG, RGB_SPI, RGB_SPD,
+ KC_NO, _______, KC_NO, KC_NO
+ )
};
bool encoder_update_user(uint8_t index, bool clockwise){
@@ -56,35 +68,321 @@ bool encoder_update_user(uint8_t index, bool clockwise){
#ifdef OLED_ENABLE
-static void render_logo(void) {
- 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, 0x00
- };
+#define ANIM_FRAMES 3
+#define ANIM_FRAME_DURATION 110 // Number of milliseconds per frame (no faster than 110ms, last line struggles)
+#define BACKGROUND_FRAMES 21
+#define ROCKET_CENTER_POS 3
+#define SPLASH_DUR 100 // Measured in frames, see above for frame length (note, 231 is used as a key value later on, CTRL+F for uses of this to make sure everything is good)
+
+uint32_t anim_timer = 0;
+uint8_t current_frame = 0;
+uint8_t rocket_y_position = 3;
+uint8_t rocket_pos_change = 0;
+uint8_t background_frame = 0;
+uint8_t splash_dur_counter = 0;
+bool examine_engaged = false;
+uint16_t examined_keycode = KC_NO;
+char lastKeycodeString[32] = { 0 };
+
+const char star_background [8] [21] =
+{
+ {0x88, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x93},
+ {0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00},
+ {0x00, 0x8F, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00},
+ {0x8D, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x8B, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x8A, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x8F, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x8F, 0x00, 0x89, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x8F},
+ {0x00, 0x8B, 0x00, 0x00, 0x91, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8C, 0x00, 0x00},
+};
+
+static void oled_write_ln_centered(const char * data, bool inverted)
+{
+ if(strlen(data) >= 21) // If more than 1 line of text is passed in, return without doing anything
+ {
+ return;
+ }
+
+ // Character buffer to build up the string in
+ char line_buf[21];
+
+ // Amount to offset string from left side
+ uint8_t offset = (21 - strlen(data))/2;
+
+ // Formatted string centering... look, it works, don't ask how...
+ snprintf(line_buf, 21, "%*s%s%*s\0", offset, "", data, offset, ""); // Centers data within 21 character buffer with null termination
+
+ oled_write_ln(line_buf, inverted);
+}
- oled_write(qmk_logo, false);
+// Prints the exhaust characters in an order determined by the phase for animation purposes
+// startX - The x axis starting point in characters for the exhaust (3 behind the rocket)
+// startY - The y axis starting point in characters for the exhaust (middle of the rocket)
+// phase - The "phase" of the animation, no real rhyme or reason to the exact number, but each frame move +1 to make the animation work
+static void render_exhaust(uint8_t startX, uint8_t startY, uint8_t phase)
+{
+ oled_set_cursor(startX, startY);
+ oled_write_char(0x85 + (phase % 3), false);
+ phase++;
+ oled_write_char(0x85 + (phase % 3), false);
+ phase++;
+ oled_write_char(0x85 + (phase % 3), false);
+}
+
+// Renders the "stars" behind the rocket
+// startY - The starting Y location (in characters) of the rocket so that stars aren't rendered on top of the rocket
+static void render_stars(uint8_t startY, uint8_t phase)
+{
+ // Line 0
+ oled_set_cursor(0, 0);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[0][(i + phase) % 21], false);
+ }
+ // Line 1
+ oled_set_cursor(0, 1);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[1][(i + phase) % 21], false);
+ }
+ // Line 2
+ oled_set_cursor(0, 2);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[2][(i + phase) % 21], false);
+ }
+ // Line 3
+ oled_set_cursor(0, 3);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[3][(i + phase) % 21], false);
+ }
+ // Line 4
+ oled_set_cursor(0, 4);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[4][(i + phase) % 21], false);
+ }
+ // Line 5
+ oled_set_cursor(0, 5);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[5][(i + phase) % 21], false);
+ }
+ // Line 6
+ oled_set_cursor(0, 6);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[6][(i + phase) % 21], false);
+ }
+ // Line 7
+ oled_set_cursor(0, 7);
+ for(int i = 0; i < 21; i++)
+ {
+ oled_write_char(star_background[7][(i + phase) % 21], false);
+ }
+
+}
+
+static void render_logo(uint8_t startX, uint8_t startY)
+{
+ oled_set_cursor(startX, startY);
+ oled_write_char(0x80, false);
+ oled_write_char(0x81, false);
+ oled_write_char(0x82, false);
+ oled_write_char(0x83, false);
+ oled_write_char(0x84, false);
+ oled_set_cursor(startX, startY + 1);
+ oled_write_char(0xA0, false);
+ oled_write_char(0xA1, false);
+ oled_write_char(0xA2, false);
+ oled_write_char(0xA3, false);
+ oled_write_char(0xA4, false);
+ oled_write_char(0xA5, false);
+ oled_set_cursor(startX, startY + 2);
+ oled_write_char(0xC0, false);
+ oled_write_char(0xC1, false);
+ oled_write_char(0xC2, false);
+ oled_write_char(0xC3, false);
+ oled_write_char(0xC4, false);
}
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; }
-void oled_task_user(void) {
- uint8_t light_level = rgblight_get_val();
- light_level = (uint8_t)(100.0 * ((float)light_level/(float)RGBLIGHT_LIMIT_VAL)); // Convert to %
- char c_light_level[3];
- itoa(light_level, c_light_level, 10);
-
- render_logo(); // Render the QMK logo
- oled_write_ln(PSTR(""), false); // Add a newline
- // Host Keyboard LED Status
- led_t led_state = host_keyboard_led_state();
- oled_write(led_state.num_lock ? PSTR(" |NUM|") : PSTR(" | |"), false);
- oled_write(led_state.caps_lock ? PSTR("|CAP|") : PSTR("| |"), false);
- oled_write(led_state.scroll_lock ? PSTR("|SCR| ") : PSTR("| | "), false);
-
- oled_write_ln(PSTR(""), false); // Add a newline
- oled_write(PSTR(" BKLT: "), false);
- oled_write(c_light_level, false);
- oled_write_ln(PSTR("% "), false);
+void oled_task_user(void)
+{
+ // Playing the animation
+ if((timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) && (splash_dur_counter < SPLASH_DUR))
+ {
+ anim_timer = timer_read32(); // read the current timer value
+ current_frame = (current_frame + 1) % ANIM_FRAMES; // Frame in the exhaust animation
+ background_frame = (background_frame + 1) % BACKGROUND_FRAMES; // Frame in the star animation
+
+ // Move the rocket up and down
+ if((rocket_pos_change / 9) == 0)
+ {
+ rocket_y_position = ROCKET_CENTER_POS;
+ }
+ else if((rocket_pos_change / 9) == 1)
+ {
+ rocket_y_position = ROCKET_CENTER_POS + 1;
+ }
+ else if((rocket_pos_change / 9) == 2)
+ {
+ rocket_y_position = ROCKET_CENTER_POS;
+ }
+ if((rocket_pos_change / 9) == 3)
+ {
+ rocket_y_position = ROCKET_CENTER_POS - 1;
+ }
+
+ // Renders the scene piece by piece
+ render_stars(8, background_frame); // Render star background
+ render_exhaust(6, rocket_y_position + 1, current_frame); // Render exhaust
+ render_logo(9, rocket_y_position); // Render the rocket
+
+ // Timing for rocket position change
+ if(rocket_pos_change < 36)
+ {
+ rocket_pos_change++;
+ }
+ else
+ {
+ rocket_pos_change = 0;
+ }
+
+ splash_dur_counter++;
+ }
+ else if((splash_dur_counter >= SPLASH_DUR) && (splash_dur_counter != 231)) // Should only run once at end of splash screen duration
+ {
+ splash_dur_counter = 231; // Nice known value
+ oled_clear(); // Clear the screen
+ }
+
+
+ // After the splash screen
+ if(splash_dur_counter == 231)
+ {
+ uint8_t light_level = rgblight_get_val();
+ light_level = (uint8_t)(100.0 * ((float)light_level/(float)RGBLIGHT_LIMIT_VAL)); // Convert to %
+ char c_light_level[3];
+ itoa(light_level, c_light_level, 10);
+
+ // Display lock LED statuses
+ led_t led_state = host_keyboard_led_state();
+ if(led_state.num_lock)
+ {
+ oled_write(PSTR(" |"), false);
+ oled_write(PSTR("NUM"), true);
+ oled_write(PSTR("|"), false);
+ }
+ else
+ {
+ oled_write(PSTR(" |NUM|"), false);
+ }
+
+ if(led_state.caps_lock)
+ {
+ oled_write(PSTR("|"), false);
+ oled_write(PSTR("CAP"), true);
+ oled_write(PSTR("|"), false);
+ }
+ else
+ {
+ oled_write(PSTR("|CAP|"), false);
+ }
+
+ if(led_state.scroll_lock)
+ {
+ oled_write(PSTR("|"), false);
+ oled_write(PSTR("SCR"), true);
+ oled_write(PSTR("| "), false);
+ }
+ else
+ {
+ oled_write(PSTR("|SCR| "), false);
+ }
+
+ // Print the examine info
+ if(examine_engaged == true)
+ {
+ oled_set_cursor(0, 2);
+ oled_write_ln(PSTR(" Keycode: "), false);
+ oled_write_ln_centered(lastKeycodeString, false);
+ }
+ else
+ {
+ oled_set_cursor(0, 2);
+ oled_write_ln(PSTR(" "), false);
+ oled_write_ln(PSTR(" "), false);
+ }
+
+ // Print the backlight % bottom right
+ oled_set_cursor(11, 7);
+ oled_write(PSTR("BKLT: "), false);
+ oled_write(c_light_level, false);
+ oled_write(PSTR("%"), false);
+
+ // Print the layer number in bottom left
+ oled_set_cursor(0, 7);
+ oled_write(PSTR("L: "), false);
+ switch (get_highest_layer(layer_state))
+ {
+ case 0:
+ oled_write(PSTR("0"), false);
+ break;
+ case 1:
+ oled_write(PSTR("1"), false);
+ break;
+ case 2:
+ oled_write(PSTR("2"), false);
+ break;
+ case 3:
+ oled_write(PSTR("3"), false);
+ break;
+ default:
+ oled_write(PSTR("Und"), false);
+ break;
+ }
+
+
+ }
+
+}
+
+// Process the extra/extended keycode functionality
+bool process_record_user(uint16_t keycode, keyrecord_t *record)
+{
+ bool ret = true; // True will allow QMK to process the key as usual after the function runs, false skips QMK processing after this function runs
+
+ switch (keycode)
+ {
+ case KC_EXAM:
+ if(record->event.pressed) // On pressed, flip bool examine_engaged
+ {
+ if(examine_engaged == false)
+ {
+ examine_engaged = true;
+ }
+ else
+ {
+ examine_engaged = false;
+ }
+ ret = false;
+ }
+ else // On release do nothing
+ {
+ ret = false;
+ }
+ break;
+
+ default: // For any key other than EX, simply let QMK process after saving away what it was
+ memset(lastKeycodeString, 0, sizeof(lastKeycodeString));
+ memcpy(lastKeycodeString, translate_keycode_to_string(keycode), sizeof(((lookup_table_t *)0)->key_string));
+ ret = true;
+ break;
+ }
+
+ return ret;
}
#endif