summaryrefslogtreecommitdiff
path: root/keyboards/crkbd/keymaps/jpe230/oled
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/crkbd/keymaps/jpe230/oled')
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/avr/master/oled_master_handler.c75
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/avr/slave/oled_slave_handler.c14
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/oled_handler.c41
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators.h13
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_down.c463
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_up.c461
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/oled_master_handler.c79
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.c533
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.h89
-rw-r--r--keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/oled_slave_handler.c11
10 files changed, 1779 insertions, 0 deletions
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/avr/master/oled_master_handler.c b/keyboards/crkbd/keymaps/jpe230/oled/avr/master/oled_master_handler.c
new file mode 100644
index 0000000000..9a75e9fa9a
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/avr/master/oled_master_handler.c
@@ -0,0 +1,75 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jpe230.h"
+
+extern uint8_t logged_row;
+extern uint8_t logged_col;
+extern uint32_t oled_timer;
+static char logged_char = ' ';
+static uint16_t logged_keycode = 0;
+
+#define L_BASE 0
+#define L_LOWER 2
+#define L_RAISE 4
+#define L_ADJUST 8
+
+void oled_render_layer_state(void) {
+ oled_write_P(PSTR("Layer: "), false);
+ switch (layer_state) {
+ case L_BASE:
+ oled_write_ln_P(PSTR("Default"), false);
+ break;
+ case L_LOWER:
+ oled_write_ln_P(PSTR("Lower"), false);
+ break;
+ case L_RAISE:
+ oled_write_ln_P(PSTR("Raise"), false);
+ break;
+ case L_ADJUST:
+ case L_ADJUST|L_LOWER:
+ case L_ADJUST|L_RAISE:
+ case L_ADJUST|L_LOWER|L_RAISE:
+ oled_write_ln_P(PSTR("Adjust"), false);
+ break;
+ }
+}
+
+const char code_to_name[60] = {
+ ' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ 'R', 'E', 'B', 'T', '_', '-', '=', '[', ']', '\\',
+ '#', ';', '\'', '`', ',', '.', '/', ' ', ' ', ' '};
+
+void handle_oled_keypress(uint16_t keycode, keyrecord_t *record) {
+ if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) ||
+ (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { keycode = keycode & 0xFF; }
+ if (keycode < 60) {
+ logged_char = code_to_name[keycode];
+ }
+
+ logged_keycode = keycode;
+}
+
+void oled_render_keylog(void) {
+ oled_write(get_u8_str(logged_row, '0'), false);
+ oled_write_P(PSTR(":"), false);
+ oled_write(get_u8_str(logged_col, '0'), false);
+ oled_write_P(PSTR(", "), false);
+ oled_write(get_u16_str(logged_keycode, ' '), false);
+ oled_write_P(PSTR(" : "), false);
+ oled_write((const char *)&logged_char, false);
+}
+
+void render_master_oled() {
+ if (timer_elapsed32(oled_timer) > CUSTOM_OLED_TIMEOUT) {
+ oled_off();
+ return;
+ }
+
+ oled_on();
+ oled_render_layer_state();
+ oled_render_keylog();
+}
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/avr/slave/oled_slave_handler.c b/keyboards/crkbd/keymaps/jpe230/oled/avr/slave/oled_slave_handler.c
new file mode 100644
index 0000000000..159413d083
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/avr/slave/oled_slave_handler.c
@@ -0,0 +1,14 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jpe230.h"
+
+void render_slave_oled() {
+ static const char PROGMEM crkbd_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_write_P(crkbd_logo, false);
+}
+
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/oled_handler.c b/keyboards/crkbd/keymaps/jpe230/oled/oled_handler.c
new file mode 100644
index 0000000000..67861e5b27
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/oled_handler.c
@@ -0,0 +1,41 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jpe230.h"
+
+uint8_t logged_row;
+uint8_t logged_col;
+uint32_t oled_timer = 0;
+
+__attribute__ ((weak)) void handle_oled_keypress(uint16_t keycode, keyrecord_t *record) {}
+
+__attribute__ ((weak)) oled_rotation_t rotate_master(oled_rotation_t rotation) {return rotation;}
+__attribute__ ((weak)) oled_rotation_t rotate_slave(oled_rotation_t rotation) {return rotation;}
+
+void oled_timer_reset() { oled_timer = timer_read32(); }
+
+oled_rotation_t oled_init_user(oled_rotation_t rotation) {
+
+ if (!is_keyboard_master()) {
+ return rotate_slave(rotation);
+ }
+
+ return rotate_master(rotation);
+}
+
+
+void set_keylog(uint16_t keycode, keyrecord_t *record) {
+ logged_row = record->event.key.row;
+ logged_col = record->event.key.col;
+
+ handle_oled_keypress(keycode, record);
+}
+
+bool oled_task_user(void) {
+ if (is_keyboard_master()) {
+ render_master_oled();
+ } else {
+ render_slave_oled();
+ }
+ return false;
+}
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators.h b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators.h
new file mode 100644
index 0000000000..038d9eff2c
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators.h
@@ -0,0 +1,13 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jpe230.h"
+#include <stdio.h>
+
+#define ANIM_SIZE 352 // number of bytes in array, max is 1024 (minimize where possible)
+#define IDLE_FRAMES 67 //number of total frames
+
+void change_frame_up(uint8_t frame_number);
+void change_frame_down(uint8_t frame_number);
+const char first_frame[ANIM_SIZE];
+const uint8_t key_frame[4];
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_down.c b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_down.c
new file mode 100644
index 0000000000..c5d70f2063
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_down.c
@@ -0,0 +1,463 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "indicators.h"
+
+const uint8_t key_frame[4] = {10, 30, 46, 61};
+
+static const uint16_t cumsum_inds[IDLE_FRAMES+1] = {
+ 0, 8, 50, 82, 113, 141, 199, 261, 283, 294, 294, 294, 294, 294, 294,
+ 294, 330, 332, 377, 478, 588, 741, 844, 970, 1085, 1172, 1219, 1235, 1242, 1242,
+ 1243, 1243, 1244, 1318, 1368, 1466, 1491, 1627, 1797, 1900, 2019, 2094, 2215, 2311, 2375,
+ 2404, 2404, 2404, 2404, 2477, 2479, 2515, 2560, 2614, 2728, 2884, 2961, 3072, 3143, 3164,
+ 3167, 3167, 3167, 3167, 3169, 3171, 3221, 3221,
+};
+
+static const uint16_t change_inds[3221] = {
+ 173, 174, 175, 176, 177, 207, 208, 209, 135, 136, 137, 138, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180, 206, 207, 208, 209, 210, 211, 212, 238, 239,
+ 240, 241, 242, 243, 244, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 166, 167, 168, 169, 171, 172, 181, 213, 238,
+ 239, 240, 241, 242, 243, 244, 245, 134, 135, 136, 137, 138, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 149, 166, 167, 168, 171, 172, 181, 213,
+ 238, 239, 240, 241, 242, 243, 244, 245, 39, 102, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 167, 169, 170, 171, 173, 238,
+ 239, 240, 241, 242, 243, 244, 0, 2, 3, 4, 5, 7, 8, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 39, 62, 94, 96, 97, 98, 100, 102, 126, 134, 136,
+ 137, 140, 148, 158, 166, 180, 190, 198, 212, 222, 230, 244, 254, 262, 286,
+ 294, 318, 326, 350, 0, 2, 3, 4, 5, 7, 8, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 62, 64, 65, 66, 67, 94, 96, 97, 98, 99, 100, 102, 126,
+ 131, 134, 158, 163, 166, 190, 195, 198, 222, 227, 230, 254, 259, 262, 286,
+ 291, 294, 318, 323, 326, 350, 32, 33, 64, 65, 66, 67, 97, 99, 129,
+ 131, 161, 163, 193, 195, 225, 227, 257, 259, 289, 291, 321, 323, 32, 33,
+ 65, 97, 129, 161, 193, 225, 257, 289, 321, 136, 137, 138, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 168, 169, 170, 171, 172, 173, 174, 175, 176,
+ 177, 178, 179, 206, 207, 208, 209, 210, 211, 238, 239, 240, 241, 242, 243,
+ 175, 176, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
+ 213, 214, 108, 109, 110, 111, 112, 113, 114, 132, 133, 134, 135, 136, 137,
+ 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
+ 153, 154, 155, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 196, 197, 198,
+ 199, 200, 201, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
+ 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 38, 39,
+ 40, 42, 43, 44, 45, 46, 47, 48, 50, 51, 54, 55, 56, 65, 66,
+ 67, 90, 91, 92, 97, 108, 109, 110, 111, 112, 113, 114, 120, 121, 122,
+ 123, 124, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 164, 165, 168, 169, 171,
+ 172, 174, 182, 186, 187, 193, 194, 196, 197, 198, 199, 203, 207, 208, 210,
+ 211, 213, 217, 218, 220, 221, 223, 228, 229, 230, 231, 232, 233, 234, 235,
+ 236, 237, 238, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 261,
+ 262, 264, 265, 38, 39, 40, 42, 43, 44, 45, 46, 47, 48, 50, 51,
+ 54, 55, 56, 65, 66, 67, 89, 90, 91, 92, 93, 94, 95, 97, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 132, 133,
+ 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 151, 152, 153, 154, 160, 161, 162, 163, 165, 166, 167, 168, 169,
+ 170, 172, 179, 183, 184, 185, 186, 193, 194, 197, 198, 202, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 220, 221, 223, 229,
+ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
+ 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 261, 262, 264, 265,
+ 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 290, 291, 292, 293,
+ 294, 295, 296, 297, 320, 321, 62, 63, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 128, 129, 130, 131, 132, 133, 134, 135, 136,
+ 137, 139, 140, 141, 142, 147, 150, 151, 152, 153, 160, 161, 162, 163, 181,
+ 184, 185, 230, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 266,
+ 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281,
+ 282, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 320,
+ 321, 322, 323, 324, 30, 31, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 250, 251, 252, 253, 254,
+ 255, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283,
+ 284, 285, 286, 287, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
+ 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 320, 321, 322, 323,
+ 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 146, 280, 281, 282, 283, 284, 285, 286, 287, 301, 302, 303, 304, 305,
+ 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 323,
+ 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338,
+ 339, 340, 341, 342, 343, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 146, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349,
+ 350, 351, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 64, 341, 342, 343, 344, 345, 346, 347,
+ 348, 349, 350, 351, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 32, 33, 351, 0, 1, 2, 3, 4, 5, 6, 146, 146, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179,
+ 180, 181, 182, 183, 184, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 230, 231, 232, 233, 234, 235,
+ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 137, 138,
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 168, 169, 170,
+ 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 200, 201, 202,
+ 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 237, 238, 239,
+ 240, 241, 242, 108, 109, 110, 111, 112, 113, 114, 132, 133, 134, 135, 136,
+ 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 181, 182, 183, 184, 185, 186, 195, 196, 197, 198, 199, 200,
+ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 213, 214, 215, 216,
+ 217, 218, 219, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 108, 109, 110, 111,
+ 112, 113, 114, 133, 134, 136, 144, 150, 154, 185, 195, 204, 211, 219, 231,
+ 234, 235, 243, 244, 247, 250, 34, 35, 36, 37, 38, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 52, 53, 55, 64, 65, 89, 90, 91, 92, 122,
+ 123, 124, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 161, 164,
+ 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 178, 182, 183, 184,
+ 185, 186, 193, 196, 203, 204, 205, 206, 207, 208, 209, 210, 211, 217, 218,
+ 225, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240,
+ 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 252, 285, 288, 289, 313,
+ 314, 315, 316, 317, 323, 324, 327, 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 339, 340, 342, 343, 26, 27, 28, 29, 30, 31, 34, 35,
+ 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 48, 49, 52, 53, 55,
+ 64, 65, 89, 90, 91, 92, 95, 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 119,
+ 120, 121, 122, 123, 124, 125, 126, 129, 130, 131, 132, 133, 134, 135, 136,
+ 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 161, 165, 171, 172, 177, 183, 184, 185, 193, 197, 198, 199, 200,
+ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 216, 217, 224, 225, 226,
+ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
+ 242, 243, 244, 245, 246, 247, 248, 249, 250, 252, 281, 282, 283, 284, 285,
+ 286, 287, 288, 289, 313, 314, 315, 316, 317, 323, 324, 327, 328, 329, 330,
+ 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 342, 343, 26, 27, 28,
+ 29, 30, 31, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 119, 120, 121, 122, 123, 124, 125, 126, 224,
+ 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 244, 245, 246, 247, 248, 256, 257, 258, 259, 260, 261, 262,
+ 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
+ 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 117, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
+ 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
+ 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295,
+ 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310,
+ 311, 312, 313, 314, 315, 316, 317, 318, 319, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 288, 289, 290, 291, 292, 293, 294, 295,
+ 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310,
+ 311, 312, 313, 314, 315, 316, 317, 318, 319, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+ 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311,
+ 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326,
+ 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341,
+ 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 320,
+ 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
+ 351, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331,
+ 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
+ 347, 348, 349, 350, 351, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 166, 167, 168, 169, 170, 171, 173,
+ 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 198, 199, 200, 201,
+ 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216,
+ 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245,
+ 246, 247, 175, 176, 140, 141, 142, 143, 144, 145, 169, 170, 171, 172, 173,
+ 174, 175, 176, 177, 178, 179, 180, 181, 199, 200, 201, 202, 203, 204, 205,
+ 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 137, 138, 139, 140, 141,
+ 142, 143, 144, 145, 166, 167, 168, 169, 170, 173, 174, 175, 176, 182, 183,
+ 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 214, 215,
+ 216, 217, 218, 241, 242, 243, 244, 245, 246, 247, 136, 137, 138, 139, 140,
+ 141, 142, 143, 144, 145, 165, 166, 167, 168, 174, 175, 178, 179, 180, 181,
+ 182, 183, 184, 195, 196, 197, 204, 216, 219, 227, 228, 229, 230, 231, 232,
+ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 20, 21, 22, 23, 49, 50, 51, 52, 78, 79, 80,
+ 107, 108, 109, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 165, 166,
+ 167, 168, 174, 175, 178, 179, 180, 181, 182, 183, 184, 193, 194, 195, 196,
+ 197, 204, 216, 219, 224, 225, 227, 228, 229, 230, 231, 232, 233, 234, 235,
+ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
+ 251, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
+ 270, 271, 272, 273, 274, 275, 276, 320, 321, 322, 323, 324, 325, 326, 327,
+ 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 15, 16,
+ 17, 18, 20, 21, 22, 23, 44, 45, 46, 47, 49, 50, 51, 52, 73,
+ 74, 75, 76, 78, 79, 80, 102, 103, 104, 107, 108, 109, 131, 132, 133,
+ 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 160, 161, 162, 165, 166,
+ 167, 168, 169, 173, 175, 181, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 216, 217, 218, 224, 225, 242, 243, 244, 245, 246, 247, 256, 257, 258,
+ 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
+ 274, 275, 276, 279, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
+ 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 320, 321,
+ 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336,
+ 337, 338, 339, 340, 13, 14, 15, 16, 17, 18, 42, 43, 44, 45, 46,
+ 47, 70, 71, 72, 73, 74, 75, 76, 99, 100, 101, 102, 103, 104, 128,
+ 129, 130, 131, 132, 133, 160, 161, 162, 183, 184, 185, 186, 187, 188, 189,
+ 190, 191, 208, 215, 216, 217, 247, 249, 279, 281, 288, 289, 290, 291, 292,
+ 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307,
+ 308, 309, 310, 311, 312, 313, 8, 9, 10, 11, 13, 14, 15, 16, 37,
+ 38, 39, 40, 42, 43, 44, 45, 66, 67, 68, 69, 70, 71, 72, 73,
+ 96, 97, 98, 99, 100, 101, 102, 128, 129, 130, 131, 156, 157, 158, 159,
+ 160, 185, 186, 187, 188, 189, 190, 191, 208, 216, 217, 220, 249, 252, 281,
+ 284, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301,
+ 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 316, 320, 321,
+ 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336,
+ 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 3, 4, 5,
+ 6, 8, 9, 10, 11, 32, 33, 34, 35, 37, 38, 39, 40, 64, 66,
+ 67, 68, 69, 96, 97, 98, 156, 157, 158, 159, 188, 189, 191, 206, 208,
+ 220, 223, 252, 255, 284, 287, 316, 319, 320, 321, 322, 323, 324, 325, 326,
+ 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341,
+ 342, 343, 344, 345, 346, 347, 348, 351, 0, 1, 2, 3, 4, 5, 6,
+ 32, 33, 34, 35, 64, 159, 191, 205, 206, 223, 255, 287, 319, 351, 0,
+ 1, 2, 205, 207, 207, 216, 138, 139, 140, 141, 142, 143, 144, 145, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 197,
+ 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
+ 213, 214, 215, 216, 217, 241, 242, 243, 244, 245, 246,
+};
+
+static const char change_vals[3221] = {
+ 0x18, 0x1C, 0xFC, 0xFC, 0xFC, 0x0F, 0x0F, 0x0F, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8,
+ 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFC, 0xFC, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x00, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, 0xFC,
+ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x80, 0x80, 0x00, 0xE0, 0xE0, 0xE0, 0xE0,
+ 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x03, 0x03, 0x03, 0x01, 0x03,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x80, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0xFC, 0x00, 0xFF, 0xFF, 0x08, 0x04, 0x04, 0x02, 0xFE, 0xFF, 0xFF, 0xC0,
+ 0xC0, 0xE0, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 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, 0x08, 0x08, 0x04, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
+ 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x80, 0x80, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
+ 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 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, 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, 0x60, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0,
+ 0x80, 0x06, 0x0F, 0x0F, 0x0F, 0x0F, 0x03, 0x81, 0xC1, 0xC1, 0xE1, 0xFB, 0xFF, 0x7F, 0x3F,
+ 0x1F, 0x06, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xF7, 0xF3, 0xF1, 0xF1, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xE0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF,
+ 0xFF, 0xFF, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE,
+ 0xFC, 0xF8, 0xC0, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x80, 0xC0, 0xC0,
+ 0xE0, 0xF0, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x03, 0x80, 0xE0, 0xF0,
+ 0xF8, 0xF8, 0xFC, 0xFE, 0xFF, 0xBF, 0x9F, 0x9F, 0x8F, 0x87, 0x87, 0x83, 0x81, 0x81, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x80, 0x40,
+ 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x40, 0x80, 0xC0, 0x18,
+ 0x04, 0x01, 0x04, 0xB0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20,
+ 0x08, 0x03, 0x00, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFE, 0x7E, 0x3E, 0x3F, 0xBF, 0x7F,
+ 0x7E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x43, 0x13, 0x0B, 0x07,
+ 0x02, 0x80, 0x7F, 0x07, 0x00, 0x02, 0x01, 0x00, 0xC0, 0xE0, 0xF0, 0xFE, 0x8F, 0x87, 0x83,
+ 0x81, 0x80, 0xC0, 0xA0, 0x10, 0x08, 0x04, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0x8F, 0x4F, 0x2F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x40,
+ 0x60, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x02, 0x00, 0x80,
+ 0x40, 0x40, 0x20, 0x10, 0x08, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFE, 0xFE, 0x7D, 0x7C, 0x7C, 0x7C, 0xFC, 0xFC, 0xF8,
+ 0xF8, 0xF8, 0xF0, 0xE0, 0x80, 0x00, 0x04, 0x02, 0x01, 0x01, 0x00, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x01, 0xFF, 0x3F, 0x1F, 0x07, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFC, 0xFF, 0xCF, 0xCF,
+ 0xC7, 0xC3, 0xC3, 0xC1, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x87, 0x87, 0x47, 0x27, 0x20, 0x10, 0x18, 0x08, 0x04, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x01, 0xC0, 0x60, 0x30, 0x18,
+ 0x0C, 0x04, 0x02, 0x01, 0x06, 0x01, 0x80, 0x40, 0x80, 0x80, 0x40, 0x20, 0x30, 0x18, 0x0C,
+ 0x04, 0x02, 0x01, 0x00, 0x00, 0x80, 0x80, 0x40, 0x60, 0x20, 0x10, 0x08, 0x0C, 0x04, 0x02,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x30, 0x10, 0x08, 0x0C, 0x04, 0xC2, 0xF1,
+ 0xF1, 0xF8, 0xF8, 0xFC, 0x7C, 0xF8, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
+ 0x0F, 0x00, 0x03, 0x07, 0x07, 0x07, 0x07, 0x00, 0x80, 0x80, 0x40, 0x60, 0x20, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x60, 0x20, 0x10, 0x18, 0x08, 0x04, 0x06, 0x02, 0x01,
+ 0x01, 0x00, 0x00, 0x80, 0x80, 0x40, 0x20, 0x10, 0x18, 0x0C, 0x04, 0x02, 0x03, 0x01, 0x18,
+ 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x80, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x18, 0x0C, 0x06,
+ 0x03, 0x01, 0x00, 0x80, 0x80, 0xC0, 0x60, 0x20, 0x30, 0x18, 0x0C, 0x04, 0x06, 0x03, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x60, 0x30, 0x30, 0x18, 0x0C,
+ 0x04, 0x06, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0x60,
+ 0x60, 0x30, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0,
+ 0x60, 0x60, 0x30, 0x18, 0x18, 0x0C, 0x06, 0x06, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x80,
+ 0xC0, 0x60, 0x30, 0x18, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x01, 0x80, 0x80, 0xC0, 0x60, 0x70,
+ 0x30, 0x18, 0x0C, 0x0E, 0x07, 0x03, 0x01, 0x80, 0x80, 0xC0, 0xE0, 0x60, 0x30, 0x18, 0x1C,
+ 0x0C, 0x06, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0x60, 0x70, 0x30, 0x18, 0x1C, 0x0C, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0x60, 0x30, 0x38, 0x18, 0x0C, 0x0C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0x60, 0x70, 0x30, 0x18, 0x0C,
+ 0x0E, 0x06, 0x03, 0x03, 0x01, 0x80, 0xC0, 0xE0, 0x60, 0x70, 0x38, 0x1C, 0x0C, 0x0E, 0x07,
+ 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x60,
+ 0x70, 0x38, 0x1C, 0x0C, 0x0E, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0x70, 0x30, 0x38, 0x1C, 0x0C,
+ 0x0E, 0x07, 0xC0, 0xE0, 0xE0, 0x70, 0x38, 0x3C, 0x1C, 0x0E, 0x0F, 0x07, 0x03, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x3C, 0x1E, 0x0E, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 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, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0,
+ 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0xE1, 0xE1, 0xE1, 0xE1, 0xF1, 0xFF, 0xFF, 0xFF, 0xBF, 0x1F, 0x38, 0x78, 0xFC,
+ 0xFC, 0xF8, 0xF0, 0xE1, 0xE0, 0xE1, 0xF1, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0xFC, 0xFE, 0xFE, 0xFF,
+ 0xFF, 0xFF, 0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+ 0xFC, 0xF8, 0xF0, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0xF8, 0xF8, 0xF8, 0xF8,
+ 0xF8, 0xF8, 0xFC, 0xFF, 0xFF, 0xBF, 0x9F, 0x1F, 0x07, 0x60, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x83, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x30, 0x03, 0x07, 0x0F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xF8, 0xFC, 0xFE, 0x3F, 0xFE, 0xE0, 0x0F, 0x00, 0x81, 0xD7, 0x00, 0x0F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x01, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x40, 0x80, 0x02, 0x01, 0x01, 0x02, 0x08, 0xE0, 0x40,
+ 0x20, 0x0F, 0xF8, 0x08, 0x08, 0x08, 0xC8, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0x7E, 0x7E,
+ 0x7E, 0x3E, 0x7E, 0x7E, 0xFE, 0xFC, 0xFC, 0xFC, 0xFC, 0xFA, 0xF1, 0x80, 0x00, 0xFF, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x60, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xBF, 0x9F, 0x1F,
+ 0x07, 0x00, 0xFF, 0x00, 0xE0, 0xC1, 0x81, 0x81, 0x81, 0x81, 0x81, 0xC3, 0xFF, 0xFE, 0x00,
+ 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x01, 0x08, 0x10, 0x40, 0xFF, 0x40, 0x80, 0x80,
+ 0x40, 0x20, 0x18, 0x07, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x0C, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10,
+ 0x10, 0x08, 0x08, 0x0C, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0,
+ 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7C, 0x7C, 0x7C, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xE0,
+ 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0xF0, 0x1F, 0x0F, 0x00, 0x00, 0x00, 0x78, 0xF8, 0xF8,
+ 0xF8, 0xF8, 0xF0, 0xC0, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xE3, 0x7E, 0x00, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x41, 0x43, 0x43, 0x43, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
+ 0x47, 0x07, 0x87, 0x83, 0x83, 0x81, 0x80, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x04, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xC0, 0x40, 0x40, 0x60, 0x20, 0x30, 0x10, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x18, 0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x30, 0x30, 0x20, 0x20, 0x20, 0x60, 0x40, 0x40, 0xC0, 0x80, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x04, 0x04, 0x06, 0x06, 0x02, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x08, 0x18, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0,
+ 0xC0, 0xC0, 0x40, 0x60, 0x60, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x10, 0x10, 0x10, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x20, 0x20, 0x60, 0x60, 0x60, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0x60, 0x60, 0x60,
+ 0x60, 0x60, 0x70, 0x70, 0x70, 0x30, 0x30, 0x30, 0x38, 0x38, 0x18, 0x18, 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, 0xE0,
+ 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xC0, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0x20, 0xE0, 0xF8, 0xFF, 0xFF, 0xFF,
+ 0x3F, 0x07, 0x01, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x18, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3C,
+ 0x3C, 0x3C, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0x3C, 0xC0, 0xF0, 0xFC, 0xFE, 0xFC,
+ 0xFE, 0xFE, 0x7E, 0x0C, 0xC0, 0xF0, 0xFE, 0xFF, 0xFF, 0x3F, 0x0F, 0x01, 0x00, 0xC0, 0xC0,
+ 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xF8, 0xF8, 0xF8, 0xF8, 0xFF, 0xFF,
+ 0xF8, 0xF8, 0xF8, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x80, 0xF0, 0xFE, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0x07, 0xC0, 0xF0, 0xFE, 0xFF, 0x07, 0x00, 0xE0, 0xE0, 0xE0, 0xE0,
+ 0xE0, 0xE0, 0xE0, 0xF8, 0xFE, 0xFF, 0xF8, 0xFF, 0xF8, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x01, 0x01, 0x01, 0x80, 0x30, 0x0C, 0x01, 0x80, 0x30, 0x04, 0x01, 0xC0, 0x10, 0x06,
+ 0xC0, 0x18, 0x06, 0x60, 0x98, 0xF3, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x7C, 0x0C, 0x60, 0x88,
+ 0xF3, 0xFC, 0x0F, 0x01, 0xC0, 0xC0, 0xC0, 0xF0, 0xC0, 0xC0, 0x00, 0x80, 0x20, 0x0C, 0xF1,
+ 0xFE, 0xF9, 0xF8, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80, 0x70,
+ 0x0C, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x30, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0x38, 0x06, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x07, 0x00, 0x00, 0x00, 0xE0, 0x18, 0x07,
+ 0x00, 0x00, 0xC0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0x78, 0x18, 0x60, 0x1C, 0x03, 0x00, 0x00,
+ 0xC0, 0xF8, 0xFE, 0x7F, 0x03, 0xC0, 0xFC, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7D, 0x7C, 0x7C, 0x7C,
+ 0x7C, 0xFC, 0x78, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x07, 0x01, 0x00, 0x00, 0xE0, 0x38, 0x07, 0x01, 0x00,
+ 0x00, 0x80, 0xE0, 0x1C, 0x07, 0x00, 0x00, 0x00, 0x80, 0x70, 0x1C, 0x03, 0x00, 0x00, 0x80,
+ 0x70, 0x0E, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x78, 0x7C, 0x7C, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x3F, 0xC0, 0x78, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0,
+ 0x78, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x3C, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x7C, 0x78, 0x78, 0xFF, 0x00, 0xFF, 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, 0x00, 0x00, 0x00, 0xFF, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3F, 0xC0, 0xF8, 0x1E,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x1F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xFF, 0x78, 0x78,
+ 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7C, 0x78, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+uint16_t index_start2 = 0;
+uint16_t index_end2 = 0;
+void change_frame_up(uint8_t frame_number){
+// for n changes this frame, change those bytes by change_inds and change_vals
+ index_start2 = cumsum_inds[frame_number-1];
+ index_end2 = cumsum_inds[frame_number];
+ if (index_start2 != index_end2){ // if a change in buffer
+ for (uint16_t i=index_start2; i < index_end2; i++){
+ oled_write_raw_byte(change_vals[i], change_inds[i]);
+ }
+ }
+}
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_up.c b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_up.c
new file mode 100644
index 0000000000..2912838012
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/indicators_up.c
@@ -0,0 +1,461 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "indicators.h"
+
+static const uint16_t cumsum_inds[IDLE_FRAMES+1] = {
+ 0, 50, 52, 54, 54, 54, 54, 57, 78, 149, 260, 337, 493, 607, 661,
+ 706, 742, 744, 817, 817, 817, 817, 846, 910, 1006, 1127, 1202, 1321, 1424, 1594,
+ 1730, 1755, 1853, 1903, 1977, 1978, 1978, 1979, 1979, 1986, 2002, 2049, 2136, 2251, 2377,
+ 2480, 2633, 2743, 2844, 2889, 2891, 2927, 2927, 2927, 2927, 2927, 2927, 2927, 2938, 2960,
+ 3022, 3080, 3108, 3139, 3171, 3213, 3221, 3221,
+};
+
+static const uint16_t change_inds[3221] = {
+ 138, 139, 140, 141, 142, 143, 144, 145, 167, 168, 169, 170, 171, 172, 173,
+ 174, 175, 177, 178, 179, 180, 181, 182, 197, 198, 199, 200, 201, 202, 203,
+ 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 241,
+ 242, 243, 244, 245, 246, 207, 216, 205, 207, 0, 1, 2, 0, 1, 2,
+ 3, 4, 5, 6, 32, 33, 34, 35, 64, 159, 191, 205, 206, 223, 255,
+ 287, 319, 351, 3, 4, 5, 6, 8, 9, 10, 11, 32, 33, 34, 35,
+ 37, 38, 39, 40, 64, 66, 67, 68, 69, 96, 97, 98, 156, 157, 158,
+ 159, 188, 189, 191, 206, 208, 220, 223, 252, 255, 284, 287, 316, 319, 320,
+ 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 351, 8,
+ 9, 10, 11, 13, 14, 15, 16, 37, 38, 39, 40, 42, 43, 44, 45,
+ 66, 67, 68, 69, 70, 71, 72, 73, 96, 97, 98, 99, 100, 101, 102,
+ 128, 129, 130, 131, 156, 157, 158, 159, 160, 185, 186, 187, 188, 189, 190,
+ 191, 208, 216, 217, 220, 249, 252, 281, 284, 288, 289, 290, 291, 292, 293,
+ 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
+ 309, 310, 311, 312, 313, 316, 320, 321, 322, 323, 324, 325, 326, 327, 328,
+ 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343,
+ 344, 345, 346, 347, 348, 13, 14, 15, 16, 17, 18, 42, 43, 44, 45,
+ 46, 47, 70, 71, 72, 73, 74, 75, 76, 99, 100, 101, 102, 103, 104,
+ 128, 129, 130, 131, 132, 133, 160, 161, 162, 183, 184, 185, 186, 187, 188,
+ 189, 190, 191, 208, 215, 216, 217, 247, 249, 279, 281, 288, 289, 290, 291,
+ 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306,
+ 307, 308, 309, 310, 311, 312, 313, 15, 16, 17, 18, 20, 21, 22, 23,
+ 44, 45, 46, 47, 49, 50, 51, 52, 73, 74, 75, 76, 78, 79, 80,
+ 102, 103, 104, 107, 108, 109, 131, 132, 133, 136, 137, 138, 139, 140, 141,
+ 142, 143, 144, 145, 160, 161, 162, 165, 166, 167, 168, 169, 173, 175, 181,
+ 183, 184, 185, 186, 187, 188, 189, 190, 191, 193, 194, 195, 196, 197, 198,
+ 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 216, 217, 218, 224, 225,
+ 242, 243, 244, 245, 246, 247, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 279, 288, 289,
+ 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 320, 321, 322, 323, 324, 325, 326, 327,
+ 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 20, 21,
+ 22, 23, 49, 50, 51, 52, 78, 79, 80, 107, 108, 109, 136, 137, 138,
+ 139, 140, 141, 142, 143, 144, 145, 165, 166, 167, 168, 174, 175, 178, 179,
+ 180, 181, 182, 183, 184, 193, 194, 195, 196, 197, 204, 216, 219, 224, 225,
+ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
+ 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 256, 257, 258, 259, 260,
+ 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
+ 276, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333,
+ 334, 335, 336, 337, 338, 339, 340, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 165, 166, 167, 168, 174, 175, 178, 179, 180, 181, 182, 183, 184,
+ 195, 196, 197, 204, 216, 219, 227, 228, 229, 230, 231, 232, 233, 234, 235,
+ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
+ 251, 137, 138, 139, 140, 141, 142, 143, 144, 145, 166, 167, 168, 169, 170,
+ 173, 174, 175, 176, 182, 183, 196, 197, 198, 199, 200, 201, 202, 203, 204,
+ 205, 206, 207, 208, 214, 215, 216, 217, 218, 241, 242, 243, 244, 245, 246,
+ 247, 140, 141, 142, 143, 144, 145, 169, 170, 171, 172, 173, 174, 175, 176,
+ 177, 178, 179, 180, 181, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
+ 209, 210, 211, 212, 213, 214, 215, 175, 176, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 166, 167,
+ 168, 169, 170, 171, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211,
+ 212, 213, 214, 215, 216, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240,
+ 241, 242, 243, 244, 245, 246, 247, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 320, 321, 322, 323, 324, 325, 326,
+ 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341,
+ 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 320,
+ 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
+ 351, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 288, 289,
+ 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319,
+ 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349,
+ 350, 351, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
+ 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317,
+ 318, 319, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 256, 257, 258,
+ 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
+ 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
+ 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303,
+ 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318,
+ 319, 26, 27, 28, 29, 30, 31, 85, 86, 87, 88, 89, 90, 91, 92,
+ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 119, 120, 121, 122, 123,
+ 124, 125, 126, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235,
+ 236, 237, 238, 239, 240, 241, 242, 244, 245, 246, 247, 248, 256, 257, 258,
+ 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
+ 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 26,
+ 27, 28, 29, 30, 31, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 52, 53, 55, 64, 65, 89, 90, 91, 92, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 119, 120, 121, 122, 123, 124, 125, 126, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 161, 165, 171, 172, 177, 183,
+ 184, 185, 193, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
+ 209, 210, 216, 217, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
+ 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
+ 250, 252, 281, 282, 283, 284, 285, 286, 287, 288, 289, 313, 314, 315, 316,
+ 317, 323, 324, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338,
+ 339, 340, 342, 343, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 52, 53, 55, 64, 65, 89, 90, 91, 92, 122, 123, 124,
+ 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 161, 164, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175, 176, 178, 182, 183, 184, 185, 186,
+ 193, 196, 203, 204, 205, 206, 207, 208, 209, 210, 211, 217, 218, 225, 227,
+ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 243, 244, 245, 246, 247, 248, 249, 250, 252, 285, 288, 289, 313, 314, 315,
+ 316, 317, 323, 324, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337,
+ 338, 339, 340, 342, 343, 108, 109, 110, 111, 112, 113, 114, 133, 134, 136,
+ 144, 150, 154, 185, 195, 204, 211, 219, 231, 234, 235, 243, 244, 247, 250,
+ 108, 109, 110, 111, 112, 113, 114, 132, 133, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
+ 181, 182, 183, 184, 185, 186, 195, 196, 197, 198, 199, 200, 201, 202, 203,
+ 204, 205, 206, 207, 208, 209, 210, 211, 213, 214, 215, 216, 217, 218, 219,
+ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 243, 244, 245, 246, 247, 248, 249, 250, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 237, 238, 239, 240, 241, 242, 135, 136,
+ 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180,
+ 181, 182, 183, 184, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
+ 209, 210, 211, 212, 213, 214, 215, 216, 230, 231, 232, 233, 234, 235, 236,
+ 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 146, 146, 0,
+ 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 32, 33, 351, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 341, 342,
+ 343, 344, 345, 346, 347, 348, 349, 350, 351, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 146, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319,
+ 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345,
+ 346, 347, 348, 349, 350, 351, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 146, 280, 281,
+ 282, 283, 284, 285, 286, 287, 301, 302, 303, 304, 305, 306, 307, 308, 309,
+ 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 323, 324, 325, 326, 327,
+ 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 30, 31, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 128, 129, 130,
+ 131, 132, 133, 134, 135, 136, 137, 250, 251, 252, 253, 254, 255, 270, 271,
+ 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+ 287, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305,
+ 306, 307, 308, 309, 310, 311, 312, 313, 320, 321, 322, 323, 324, 325, 326,
+ 327, 328, 329, 330, 331, 332, 333, 62, 63, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 105, 106, 107, 108, 109, 110, 111, 112, 113,
+ 114, 115, 116, 117, 118, 119, 120, 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 139, 140, 141, 142, 147, 150, 151, 152, 153, 160, 161, 162, 163,
+ 181, 184, 185, 230, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
+ 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
+ 281, 282, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
+ 320, 321, 322, 323, 324, 38, 39, 40, 42, 43, 44, 45, 46, 47, 48,
+ 50, 51, 54, 55, 56, 65, 66, 67, 89, 90, 91, 92, 93, 94, 95,
+ 97, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 154, 160, 161, 162, 163, 165, 166, 167,
+ 168, 169, 170, 172, 179, 183, 184, 185, 186, 193, 194, 197, 198, 202, 205,
+ 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 220, 221,
+ 223, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 261, 262,
+ 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 290, 291,
+ 292, 293, 294, 295, 296, 297, 320, 321, 38, 39, 40, 42, 43, 44, 45,
+ 46, 47, 48, 50, 51, 54, 55, 56, 65, 66, 67, 90, 91, 92, 97,
+ 108, 109, 110, 111, 112, 113, 114, 120, 121, 122, 123, 124, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 146, 147, 148, 149, 150,
+ 151, 152, 153, 154, 155, 164, 165, 168, 169, 171, 172, 174, 182, 186, 187,
+ 193, 194, 196, 197, 198, 199, 203, 207, 208, 210, 211, 213, 217, 218, 220,
+ 221, 223, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 241, 242,
+ 243, 244, 245, 246, 247, 248, 249, 250, 251, 261, 262, 264, 265, 108, 109,
+ 110, 111, 112, 113, 114, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 164,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 187, 196, 197, 198, 199, 200, 201, 202,
+ 203, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
+ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 243, 244, 245, 246, 247, 248, 249, 250, 251, 137, 138, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 149, 150, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180, 181, 182, 183, 200, 201, 202, 203, 204, 205,
+ 206, 207, 208, 209, 210, 211, 212, 213, 214, 175, 176, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 206, 207, 208, 209, 210, 211, 238, 239, 240, 241,
+ 242, 243, 32, 33, 65, 97, 129, 161, 193, 225, 257, 289, 321, 32, 33,
+ 64, 65, 66, 67, 97, 99, 129, 131, 161, 163, 193, 195, 225, 227, 257,
+ 259, 289, 291, 321, 323, 0, 2, 3, 4, 5, 7, 8, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 62, 64, 65, 66, 67, 94, 96, 97, 98, 99, 100, 102,
+ 126, 131, 134, 158, 163, 166, 190, 195, 198, 222, 227, 230, 254, 259, 262,
+ 286, 291, 294, 318, 323, 326, 350, 0, 2, 3, 4, 5, 7, 8, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 39, 62, 94, 96, 97, 98, 100, 102, 126, 134,
+ 136, 137, 140, 148, 158, 166, 180, 190, 198, 212, 222, 230, 244, 254, 262,
+ 286, 294, 318, 326, 350, 39, 102, 135, 136, 137, 138, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 167, 169, 170, 171, 173, 238, 239, 240, 241,
+ 242, 243, 244, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 166, 167, 168, 171, 172, 181, 213, 238, 239, 240, 241,
+ 242, 243, 244, 245, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 166, 167, 168, 169, 171, 172, 181, 213, 238, 239,
+ 240, 241, 242, 243, 244, 245, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
+ 177, 178, 179, 180, 206, 207, 208, 209, 210, 211, 212, 238, 239, 240, 241,
+ 242, 243, 244, 173, 174, 175, 176, 177, 207, 208, 209,
+};
+
+static const char change_vals[3221] = {
+ 0xC0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0x78, 0x18, 0xC0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F,
+ 0x0F, 0x03, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x78, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x7D, 0x7C, 0x7C, 0x7C, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0x7C, 0x78, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x78, 0x78, 0x78, 0x7C, 0x3F, 0x07, 0x01, 0x00, 0x00, 0x00,
+ 0xC0, 0xF8, 0x1E, 0x07, 0xE0, 0x78, 0x1F, 0x03, 0x03, 0xF0, 0xFF, 0x7C, 0x78, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x78, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0xC0, 0x78, 0x0F, 0x03, 0x00, 0xE0, 0x38, 0x0F, 0x01, 0x3C, 0x0F, 0x01, 0x80, 0x80, 0x80,
+ 0x80, 0xFF, 0x01, 0x00, 0x7C, 0x7C, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3F, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xC0, 0x38, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x07, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0x1C, 0x07, 0x00, 0x00, 0x00, 0x80, 0x70, 0x1C, 0x03,
+ 0x80, 0x70, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFE, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x78, 0x7C, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x70, 0x0C, 0x03, 0x00, 0x00, 0xC0, 0x30,
+ 0x0E, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x06, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x07,
+ 0x00, 0x00, 0x00, 0xE0, 0x18, 0x07, 0x60, 0x1C, 0x03, 0xFC, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x7C, 0xFF, 0xFC, 0x78, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x30, 0x0C, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x30, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x10, 0x06,
+ 0x00, 0x00, 0x00, 0xC0, 0x18, 0x06, 0x00, 0x00, 0x00, 0x60, 0x98, 0xF3, 0xFC, 0xFC, 0xFC,
+ 0xFC, 0xFC, 0x7C, 0x0C, 0x00, 0x00, 0x00, 0x60, 0x88, 0xF3, 0xFC, 0xFF, 0x3F, 0x01, 0xF0,
+ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x0C, 0xF1, 0xFE, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x0C, 0x01,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xFE,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x07, 0xC0, 0xF0, 0xFE, 0xFF, 0x07, 0x00, 0xE0, 0xE0,
+ 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0xF8, 0xFF, 0xF8, 0x00, 0x00,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xFC, 0xFE, 0xFC, 0xFE, 0xFE,
+ 0x7E, 0x0C, 0x00, 0xC0, 0xF0, 0xFE, 0x0F, 0x01, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
+ 0x00, 0xF8, 0xFE, 0xF9, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0x20, 0x00, 0x00, 0x00, 0xE0, 0xF8,
+ 0xFF, 0x3F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xF8,
+ 0xF8, 0x7C, 0x7C, 0x7C, 0x7C, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xE0, 0xC0, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xFF, 0xFF, 0xFF, 0xBF, 0x1F,
+ 0x0F, 0x78, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xC0, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xE3, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x01, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, 0x70,
+ 0x70, 0x30, 0x30, 0x30, 0x38, 0x38, 0x18, 0x18, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
+ 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 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, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xC0,
+ 0x40, 0x60, 0x60, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x10, 0x10, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x20, 0x60, 0x60, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x0C, 0x0C, 0x0C, 0x0C, 0x04, 0x04, 0x06, 0x06, 0x02, 0x03, 0x03, 0x01, 0x01,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x04, 0x0C, 0x0C, 0x0C,
+ 0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xC0, 0x40,
+ 0x40, 0x60, 0x20, 0x30, 0x10, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x18, 0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x30, 0x20, 0x20, 0x20, 0x60, 0x40, 0x40, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x01, 0x02, 0x04, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x0C,
+ 0x04, 0x02, 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x43, 0x43, 0x43, 0x47,
+ 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x87, 0x83, 0x83, 0x81, 0x80, 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, 0x01, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x40, 0x40, 0x80, 0x02, 0x01, 0x01, 0x02, 0x08, 0xE0, 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, 0x40, 0x20, 0x0F, 0x00, 0x00, 0xF8,
+ 0x08, 0x08, 0x08, 0xC8, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0x7E, 0x7E, 0x7E, 0x3E, 0x7E,
+ 0x7E, 0xFE, 0xFC, 0xFC, 0xFC, 0xFC, 0xFA, 0xF1, 0x80, 0xFF, 0x01, 0x01, 0x60, 0xF8, 0x9F,
+ 0x1F, 0x07, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xC1, 0x81, 0x81, 0x81, 0x81,
+ 0x81, 0xC3, 0xFF, 0xFE, 0x00, 0x01, 0x00, 0x02, 0x02, 0x02, 0x03, 0x03, 0x07, 0x07, 0x0F,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x01, 0x08,
+ 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x20, 0x18,
+ 0x07, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x3F, 0x3F, 0x1F, 0x1F,
+ 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC, 0xF8, 0xE0, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x00, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFC, 0xFF, 0xBF, 0x9F, 0x0F, 0x07,
+ 0x00, 0xF0, 0x80, 0x81, 0x01, 0x01, 0x01, 0x01, 0x03, 0x83, 0xD7, 0xFF, 0xFE, 0x00, 0x00,
+ 0x03, 0x07, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFC, 0xFE, 0xFF,
+ 0x1F, 0xFF, 0xF0, 0x1F, 0x60, 0x01, 0xC7, 0x30, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xE0,
+ 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0xE1, 0xE1, 0xE1, 0xE1, 0xF1, 0xFF,
+ 0xBF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78, 0xFC, 0xFC,
+ 0xF8, 0xF0, 0xE1, 0xE0, 0xE1, 0xF1, 0xFF, 0xFF, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0,
+ 0xF0, 0xF8, 0xF8, 0xF8, 0xFC, 0x7C, 0x7C, 0x7C, 0x7C, 0xFC, 0xF8, 0xF8, 0xF8, 0xF0, 0xE0,
+ 0xC0, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x01, 0x80, 0x80, 0xC0, 0xF0, 0xF8, 0xFF, 0xFF,
+ 0x7F, 0x7F, 0x3F, 0x0F, 0xC0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xCF, 0xCF, 0xC7,
+ 0xC3, 0xC3, 0xC1, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xF8, 0xFC, 0x3C,
+ 0x1E, 0x0E, 0x07, 0x07, 0x03, 0x01, 0xC0, 0xE0, 0xE0, 0x70, 0x38, 0x3C, 0x1C, 0x0E, 0x0F,
+ 0x07, 0x03, 0x01, 0x01, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x60, 0x70, 0x38, 0x1C, 0x0C, 0x0E, 0x07, 0x03, 0x01, 0x01,
+ 0xC0, 0xE0, 0x60, 0x70, 0x38, 0x1C, 0x0C, 0x0E, 0x07, 0x03, 0x03, 0x01, 0x01, 0x80, 0xC0,
+ 0xC0, 0xE0, 0x70, 0x30, 0x38, 0x1C, 0x0C, 0x0E, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0x60, 0x70, 0x30, 0x18, 0x0C, 0x0E, 0x07, 0x03,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0x60,
+ 0x30, 0x18, 0x1C, 0x0C, 0x06, 0x03, 0x03, 0x01, 0xC0, 0x60, 0x70, 0x30, 0x18, 0x1C, 0x0C,
+ 0x06, 0x07, 0x03, 0x01, 0xF8, 0x80, 0x80, 0xC0, 0xE0, 0x60, 0x30, 0x38, 0x18, 0x0C, 0x0C,
+ 0x80, 0xC0, 0xC0, 0x60, 0x70, 0x30, 0x18, 0x0C, 0x0E, 0x06, 0x03, 0x03, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x80, 0xC0, 0x60, 0x30, 0x18, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0x60, 0x20, 0x30, 0x18, 0x0C, 0x04, 0x06, 0x03,
+ 0x01, 0xC0, 0x60, 0x30, 0x30, 0x18, 0x0C, 0x04, 0x06, 0x03, 0x01, 0x01, 0xFC, 0x80, 0x80,
+ 0xC0, 0x60, 0x60, 0x30, 0x10, 0x18, 0x80, 0xC0, 0x60, 0x60, 0x30, 0x18, 0x18, 0x0C, 0x06,
+ 0x06, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x18,
+ 0x18, 0x0C, 0x06, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x20,
+ 0x30, 0x18, 0x0C, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x80, 0x40, 0x60, 0x20, 0x10, 0x08, 0x0C, 0x04, 0x02, 0x01, 0x01, 0x40, 0x20, 0x30,
+ 0x10, 0x08, 0x0C, 0x04, 0xC2, 0xF1, 0xF1, 0x80, 0x80, 0x40, 0x60, 0x20, 0x30, 0x80, 0x80,
+ 0x40, 0x60, 0x20, 0x10, 0x18, 0x08, 0x04, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x80, 0x40, 0x20, 0x10, 0x18, 0x0C, 0x04, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x40, 0x60, 0x30, 0x18, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40,
+ 0x20, 0x10, 0x08, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xC0, 0xE0,
+ 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0x7D, 0xFC, 0xF8, 0xF0, 0xE0, 0x80, 0x04, 0x02, 0x01, 0x01,
+ 0xFF, 0x1F, 0x07, 0x07, 0x87, 0x87, 0x47, 0x27, 0x20, 0x10, 0x18, 0x08, 0x04, 0x06, 0x02,
+ 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x40, 0x40, 0x80, 0xC0, 0x18, 0x04, 0x00, 0x01, 0x04, 0xB0, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x08, 0x03,
+ 0x00, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFE, 0x7E, 0x3E, 0x3F, 0xBF, 0x7F, 0x3F, 0x7E,
+ 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x43, 0x03, 0x03,
+ 0x13, 0x0B, 0x03, 0x02, 0xFC, 0x7F, 0x3F, 0x1F, 0x07, 0x02, 0x01, 0xC0, 0xE0, 0xFE, 0xBF,
+ 0x9F, 0x8F, 0x87, 0x87, 0x83, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xA0, 0x10, 0x08,
+ 0x04, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x8F, 0x4F, 0x2F, 0x1F, 0x1F, 0x0F, 0x0F,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60,
+ 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF8, 0xFC,
+ 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0xFE, 0xFC, 0xF8, 0xC0, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0xC0, 0xFF, 0x0F, 0x03,
+ 0x00, 0x00, 0x80, 0xE0, 0xF0, 0xF8, 0xFF, 0x9F, 0x8F, 0x87, 0x83, 0x81, 0x80, 0x80, 0x00,
+ 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0xE0,
+ 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x0F, 0x0F, 0x0F, 0x0F, 0x03, 0x81, 0xC1, 0xC1, 0xE1, 0xFB, 0xFF,
+ 0x7F, 0x3F, 0x1F, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF8, 0xFC,
+ 0xFE, 0xFF, 0xFF, 0xF7, 0xF3, 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xA0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xE0, 0xE0,
+ 0xE0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+ 0x08, 0x08, 0x04, 0xFC, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
+ 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x08, 0x04, 0x04, 0x00, 0x02, 0xFE,
+ 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
+ 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0xE0, 0xE0, 0xF0, 0xF8, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, 0xFC, 0xFE,
+ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x03, 0x01, 0x01, 0x01, 0x00, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0x0F, 0x0F, 0x0F, 0xF0, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE,
+ 0xFE, 0xFE, 0xFC, 0xFC, 0x00, 0x00, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x0F, 0x0F,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1C, 0xFC, 0xFC,
+ 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+uint16_t index_start = 0;
+uint16_t index_end = 0;
+void change_frame_down(uint8_t frame_number){
+// for n changes this frame, change those bytes by change_inds and change_vals
+ index_start = cumsum_inds[frame_number-1];
+ index_end = cumsum_inds[frame_number];
+ if (index_start != index_end){ // if a change in buffer
+ for (uint16_t i=index_start; i < index_end; i++){
+ oled_write_raw_byte(change_vals[i], change_inds[i]);
+ }
+ }
+}
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/oled_master_handler.c b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/oled_master_handler.c
new file mode 100644
index 0000000000..a2230e5ee1
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/master/oled_master_handler.c
@@ -0,0 +1,79 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jpe230.h"
+#include "indicators.h"
+
+extern uint8_t logged_row, logged_col;
+extern uint32_t oled_timer;
+extern const uint8_t key_frame[4];
+
+static uint32_t frame_limiter;
+
+void oled_render_layer_state(void) {
+ int current_layer_idx = get_highest_layer(layer_state | default_layer_state);
+ static int current_frame = 0;
+ static bool first_run = 1;
+
+ if(first_run){
+ first_run = 0;
+ char clear[ANIM_SIZE] = {0};
+ memset(clear, 0, ANIM_SIZE);
+ oled_write_raw_P(clear, ANIM_SIZE);
+ frame_limiter = timer_read();
+ return;
+ }
+
+ if (timer_elapsed(frame_limiter) < 12) {
+ return;
+ }
+
+ frame_limiter = timer_read();
+
+ if(current_frame < key_frame[current_layer_idx]){
+ current_frame = (current_frame + 1) % IDLE_FRAMES;
+ change_frame_up(current_frame);
+ }else if(current_frame > key_frame[current_layer_idx]) {
+ current_frame = (current_frame - 1) % IDLE_FRAMES;
+ change_frame_down(IDLE_FRAMES - current_frame - 1);
+ }
+
+}
+
+void render_master_oled() {
+ if (timer_elapsed32(oled_timer) > CUSTOM_OLED_TIMEOUT) {
+ oled_off();
+ return;
+ }
+
+ oled_on();
+
+ /* Render the layar state */
+ oled_render_layer_state();
+
+ /* Move cursor bellow the graphic */
+ oled_set_cursor(0, 12);
+
+ /* Print logged col and row
+ * Format: 00x00
+ */
+ char logged_matrix[9] = {0};
+ sprintf(logged_matrix, "%02dx%02d", logged_col, logged_row);
+
+ /* Write a separator char: ◆,
+ * make sure to add a NULL terminator otherwise strlen could fail
+ */
+ static const char PROGMEM separator[] = {4, 4, 4, 4, 4, 0};
+ oled_write(separator, false);
+
+ /* Write logged matrix position */
+ oled_write(logged_matrix, false);
+
+ /* Write another separator */
+ oled_write(separator, false);
+
+ /* Write scanrate */
+ oled_write(get_u16_str(get_matrix_scan_rate(), ' '), false);
+}
+
+oled_rotation_t rotate_master(oled_rotation_t rotation) {return OLED_ROTATION_270;}
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.c b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.c
new file mode 100644
index 0000000000..d2d452d03d
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.c
@@ -0,0 +1,533 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "ocean_dream.h"
+#include "quantum.h"
+#include "print.h"
+
+// Calculated Parameters
+#define TWINKLE_PROBABILITY_MODULATOR 100 / TWINKLE_PROBABILITY // CALCULATED: Don't Touch
+#define TOTAL_STARS STARS_PER_LINE *NUMBER_OF_STAR_LINES // CALCULATED: Don't Touch
+#define OCEAN_ANIMATION_MODULATOR NUMBER_OF_FRAMES / OCEAN_ANIMATION_SPEED // CALCULATED: Don't Touch
+#define SHOOTING_STAR_ANIMATION_MODULATOR NUMBER_OF_FRAMES / SHOOTING_STAR_ANIMATION_SPEED // CALCULATED: Don't Touch
+#define STAR_ANIMATION_MODULATOR NUMBER_OF_FRAMES / STAR_ANIMATION_SPEED // CALCULATED: Don't Touch
+
+uint8_t animation_counter = 0; // global animation counter.
+bool is_calm = false;
+uint32_t starry_night_anim_timer = 0;
+uint32_t starry_night_anim_sleep = 0;
+static int current_wpm = 0;
+
+static uint8_t increment_counter(uint8_t counter, uint8_t max) {
+ counter++;
+ if (counter >= max) {
+ return 0;
+ } else {
+ return counter;
+ }
+}
+
+#ifdef ENABLE_WAVE
+static uint8_t decrement_counter(uint8_t counter, uint8_t max) {
+ counter--;
+ if (counter < 0 || counter > max) {
+ return max;
+ } else {
+ return counter;
+ }
+}
+#endif
+
+#ifdef ENABLE_MOON // region
+# ifndef STATIC_MOON
+uint8_t moon_animation_frame = 0; // keeps track of current moon frame
+uint16_t moon_animation_counter = 0; // counts how many frames to wait before animating moon to next frame
+# endif
+
+# ifdef STATIC_MOON
+static const char PROGMEM moon[6] = {
+ 0x18, 0x7E, 0xFF, 0xC3, 0x81, 0x81,
+};
+# endif
+
+# ifndef STATIC_MOON
+static const char PROGMEM moon_animation[14][8] = {
+ // clang-format off
+ { 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, },
+ { 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x42, 0x00, },
+ { 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xC3, 0x00, 0x00, },
+ { 0x3C, 0x7E, 0xFF, 0xFF, 0xC3, 0x81, 0x00, 0x00, },
+ { 0x3C, 0x7E, 0xFF, 0xC3, 0x81, 0x00, 0x00, 0x00, },
+ { 0x3C, 0x7E, 0xC3, 0x81, 0x81, 0x00, 0x00, 0x00, },
+ { 0x3C, 0x42, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
+ { 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0x42, 0x3C, },
+ { 0x00, 0x00, 0x00, 0x81, 0x81, 0xC3, 0x7E, 0x3C, },
+ { 0x00, 0x00, 0x00, 0x81, 0xC3, 0xFF, 0x7E, 0x3C, },
+ { 0x00, 0x00, 0x81, 0xC3, 0xFF, 0xFF, 0x7E, 0x3C, },
+ { 0x00, 0x00, 0xC3, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, },
+ { 0x00, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, },
+ // clang-format on
+};
+# endif
+
+static void draw_moon(void) {
+# ifdef STATIC_MOON
+ oled_set_cursor(MOON_COLUMN, MOON_LINE);
+ oled_write_raw_P(moon, 6);
+# endif
+# ifndef STATIC_MOON
+ moon_animation_counter = increment_counter(moon_animation_counter, ANIMATE_MOON_EVERY_N_FRAMES);
+ if (moon_animation_counter == 0) {
+ moon_animation_frame = increment_counter(moon_animation_frame, 14);
+ oled_set_cursor(MOON_COLUMN, MOON_LINE);
+ oled_write_raw_P(moon_animation[moon_animation_frame], 8);
+ }
+# endif
+}
+#endif // endregion
+
+#ifdef ENABLE_WAVE // region
+uint8_t starry_night_wave_frame_width_counter = 31;
+uint8_t rough_waves_frame_counter = 0;
+
+// clang-format off
+static const char PROGMEM ocean_top[8][32] = {
+ // still ocean
+ {
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ },
+ // small ripples
+ {
+ 0x20, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x20, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x20, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x20, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ },
+ // level 2 ripples
+ {
+ 0x20, 0x60, 0x40, 0x40, 0x20, 0x60, 0x40, 0x40,
+ 0x20, 0x60, 0x40, 0x40, 0x20, 0x60, 0x40, 0x40,
+ 0x20, 0x60, 0x40, 0x40, 0x20, 0x60, 0x40, 0x40,
+ 0x20, 0x60, 0x40, 0x40, 0x20, 0x60, 0x40, 0x40,
+ },
+ // level 3 waves
+ {
+ 0x40, 0x20, 0x10, 0x20, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x20, 0x10, 0x20, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x20, 0x10, 0x20, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x20, 0x10, 0x20, 0x40, 0x40, 0x40, 0x40,
+ },
+ {
+ 0x40, 0x40, 0x20, 0x10, 0x28, 0x50, 0x40, 0x40,
+ 0x40, 0x40, 0x20, 0x10, 0x28, 0x50, 0x40, 0x40,
+ 0x40, 0x40, 0x20, 0x10, 0x28, 0x50, 0x40, 0x40,
+ 0x40, 0x40, 0x20, 0x10, 0x28, 0x50, 0x40, 0x40,
+ },
+ {
+ 0x40, 0x40, 0x40, 0x20, 0x10, 0x30, 0x70, 0x60,
+ 0x40, 0x40, 0x40, 0x20, 0x10, 0x30, 0x70, 0x60,
+ 0x40, 0x40, 0x40, 0x20, 0x10, 0x30, 0x70, 0x60,
+ 0x40, 0x40, 0x40, 0x20, 0x10, 0x30, 0x70, 0x60,
+ },
+};
+static const char PROGMEM ocean_bottom[8][32] = {
+ // still ocean
+ {
+ 0x00, 0x40, 0x40, 0x41, 0x01, 0x01, 0x01, 0x21,
+ 0x20, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x44,
+ 0x44, 0x40, 0x40, 0x00, 0x00, 0x08, 0x08, 0x00,
+ 0x01, 0x01, 0x01, 0x00, 0x40, 0x40, 0x00, 0x00,
+ },
+ // small ripples
+ {
+ 0x00, 0x00, 0x40, 0x40, 0x01, 0x01, 0x01, 0x20,
+ 0x20, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x01, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00,
+ },
+ // level 2 ripples
+ {
+ 0x00, 0x00, 0x40, 0x40, 0x01, 0x01, 0x01, 0x20,
+ 0x20, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04,
+ 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x01, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00,
+ },
+ // level 3 waves
+ {
+ 0x00, 0x40, 0x40, 0x42, 0x42, 0x03, 0x11, 0x11,
+ 0x20, 0x20, 0x00, 0x00, 0x08, 0x0C, 0x0C, 0x04,
+ 0x05, 0x41, 0x41, 0x21, 0x20, 0x00, 0x00, 0x08,
+ 0x0A, 0x0A, 0x0B, 0x41, 0x41, 0x41, 0x41, 0x00,
+ },
+ {
+ 0x10, 0x10, 0x00, 0x80, 0x84, 0xC4, 0x02, 0x06,
+ 0x84, 0x44, 0xC0, 0x80, 0x80, 0x20, 0x20, 0x10,
+ 0x08, 0x12, 0x91, 0x81, 0x42, 0x40, 0x00, 0x00,
+ 0x10, 0x12, 0x22, 0x22, 0x24, 0x04, 0x84, 0x80,
+ },
+ {
+ 0x08, 0x80, 0x80, 0x82, 0x82, 0x03, 0x21, 0x21,
+ 0x10, 0x10, 0x00, 0x00, 0x04, 0x04, 0x0C, 0x08,
+ 0x09, 0x41, 0x42, 0x22, 0x20, 0x00, 0x00, 0x08,
+ 0x0A, 0x0A, 0x0B, 0x41, 0x43, 0x42, 0x42, 0x00,
+ },
+};
+// clang-format on
+
+static void animate_waves(void) {
+ starry_night_wave_frame_width_counter = decrement_counter(starry_night_wave_frame_width_counter, WIDTH - 1); // only 3 frames for last wave type
+ rough_waves_frame_counter = increment_counter(rough_waves_frame_counter, 3); // only 3 frames for last wave type
+
+ void draw_ocean(uint8_t frame, uint16_t offset, uint8_t byte_index) {
+ oled_write_raw_byte(pgm_read_byte(ocean_top[frame] + byte_index), offset);
+ oled_write_raw_byte(pgm_read_byte(ocean_bottom[frame] + byte_index), offset + WIDTH);
+ }
+
+ for (int i = 0; i < WIDTH; ++i) {
+ uint16_t offset = OCEAN_LINE * WIDTH + i;
+ uint8_t byte_index = starry_night_wave_frame_width_counter + i;
+ if (byte_index >= WIDTH) {
+ byte_index = byte_index - WIDTH;
+ }
+ if (is_calm || current_wpm <= WAVE_CALM) {
+ draw_ocean(0, offset, byte_index);
+ } else if (current_wpm <= WAVE_HEAVY_STORM) {
+ draw_ocean(1, offset, byte_index);
+ } else if (current_wpm <= WAVE_HURRICANE) {
+ draw_ocean(2, offset, byte_index);
+ } else {
+ draw_ocean(3 + rough_waves_frame_counter, offset, byte_index);
+ }
+ }
+}
+#endif // endregion
+
+#ifdef ENABLE_ISLAND // region
+uint8_t island_frame_1 = 0;
+
+// clang-format off
+// only use 46 bytes (first 18 are blank, so we don't write them, makes it smaller and we can see the shooting stars properly!)
+
+// To save space and allow the shooting stars to be seen, only draw the tree on every frame.
+// Tree is only 14bytes wide so we save 108 bytes on just the first row. Second row, the
+// first 18 bytes is always the same piece of land, so only store that once, which saves 90 bytes
+static const char PROGMEM islandRightTop[6][14] = {
+ {0x84, 0xEC, 0x6C, 0x3C, 0xF8, 0xFE, 0x3F, 0x6B, 0xDB, 0xB9, 0x30, 0x40, 0x00, 0x00,},
+ {0x80, 0xC3, 0xEE, 0x7C, 0xB8, 0xFC, 0xFE, 0x6F, 0xDB, 0x9B, 0xB2, 0x30, 0x00, 0x00,},
+ {0x00, 0xC0, 0xEE, 0x7F, 0x3D, 0xF8, 0xFC, 0x7E, 0x57, 0xDB, 0xDB, 0x8A, 0x00, 0x00,},
+ {0x00, 0xC0, 0xE6, 0x7F, 0x3B, 0xF9, 0xFC, 0xFC, 0xB6, 0xB3, 0x33, 0x61, 0x00, 0x00,},
+ {0x00, 0x00, 0x00, 0x00, 0x80, 0xEE, 0xFF, 0xFB, 0xF9, 0xFC, 0xDE, 0xB6, 0xB6, 0x24,},
+ {0x00, 0x00, 0x00, 0x00, 0xC0, 0xEE, 0xFE, 0xFF, 0xFB, 0xFD, 0xEE, 0xB6, 0xB6, 0x92,},
+};
+static const char PROGMEM islandRightBottom[6][14] = {
+ {0x41, 0x40, 0x60, 0x3E, 0x3F, 0x23, 0x20, 0x60, 0x41, 0x43, 0x40, 0x40, 0x40, 0x80,},
+ {0x40, 0x41, 0x60, 0x3E, 0x3F, 0x23, 0x20, 0x60, 0x40, 0x40, 0x41, 0x41, 0x40, 0x80,},
+ {0x40, 0x40, 0x61, 0x3D, 0x3F, 0x27, 0x21, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80,},
+ {0x40, 0x43, 0x61, 0x3C, 0x3F, 0x27, 0x21, 0x60, 0x41, 0x43, 0x43, 0x42, 0x40, 0x80,},
+ {0x40, 0x40, 0x60, 0x3C, 0x3F, 0x27, 0x23, 0x63, 0x44, 0x40, 0x41, 0x41, 0x41, 0x81,},
+ {0x40, 0x40, 0x60, 0x3C, 0x3F, 0x27, 0x23, 0x63, 0x42, 0x42, 0x41, 0x41, 0x41, 0x80,},
+};
+static const char PROGMEM islandLeft[18] = {
+ 0x80, 0x40, 0x40, 0x40, 0x40, 0x60,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x60, 0x40, 0x40,
+};
+// clang-format on
+
+static void animate_island(void) {
+ if (animation_counter == 0) {
+ island_frame_1 = increment_counter(island_frame_1, 2);
+ }
+
+ void draw_island_parts(uint8_t frame) {
+ oled_set_cursor(ISLAND_COLUMN + 3, ISLAND_LINE);
+ oled_write_raw_P(islandRightTop[frame], 14);
+ oled_set_cursor(ISLAND_COLUMN + 0, ISLAND_LINE + 1);
+ oled_write_raw_P(islandLeft, 18);
+ oled_set_cursor(ISLAND_COLUMN + 3, ISLAND_LINE + 1);
+ oled_write_raw_P(islandRightBottom[frame], 14);
+ }
+
+ if (is_calm || current_wpm < ISLAND_CALM) {
+ draw_island_parts(0);
+ } else if (current_wpm >= ISLAND_CALM && current_wpm < ISLAND_HEAVY_STORM) {
+ draw_island_parts(island_frame_1 + 1);
+ } else if (current_wpm >= ISLAND_HEAVY_STORM && current_wpm < ISLAND_HURRICANE) {
+ draw_island_parts(island_frame_1 + 2);
+ } else {
+ draw_island_parts(island_frame_1 + 4);
+ }
+}
+#endif // endregion
+
+#ifdef ENABLE_STARS // region
+bool stars_setup = false; // only setup stars once, then we just twinkle them
+struct Coordinate {
+ int x;
+ int y;
+ bool exists;
+};
+
+struct Coordinate stars[TOTAL_STARS]; // tracks all stars/coordinates
+
+/**
+ * Setup all the initial stars on the screen
+ * This function divides the screen into regions based on STARS_PER_LINE and NUMBER_OF_STAR_LINES
+ * where each line is made up of 8x8 pixel groups, that are populated by a single star.
+ *
+ * Not sure how this function will work with larger or smaller screens.
+ * It should be fine, as long as the screen width is a multiple of 8
+ */
+static void setup_stars(void) {
+ // For every line, split the line into STARS_PER_LINE, find a random point in that region, and turn the pixel on
+ // 36% probability it will not be added
+ // (said another way, 80% chance it will start out lit in the x direction, then 80% chance it will start out lit in the y direction = 64% probability it will start out lit at all)
+ for (int line = 0; line < NUMBER_OF_STAR_LINES; ++line) {
+ for (int column_group = 0; column_group < STARS_PER_LINE; ++column_group) {
+ uint8_t rand_column = rand() % 10;
+ uint8_t rand_row = rand() % 10;
+ if (rand_column < 8 && rand_row < 8) {
+ int column_adder = column_group * 8;
+ int line_adder = line * 8;
+ int x = rand_column + column_adder;
+ int y = rand_row + line_adder;
+ oled_write_pixel(x, y, true);
+ stars[column_group + (line * STARS_PER_LINE)].x = x;
+ stars[column_group + (line * STARS_PER_LINE)].y = y;
+ stars[column_group + (line * STARS_PER_LINE)].exists = true;
+ } else {
+ stars[column_group + (line * STARS_PER_LINE)].exists = false;
+ }
+ }
+ }
+ stars_setup = true;
+}
+
+/**
+ * Twinkle the stars (move them one pixel in any direction) with a probability of 50% to twinkle any given star
+ */
+static void twinkle_stars(void) {
+ for (int line = 0; line < NUMBER_OF_STAR_LINES; ++line) {
+ for (int column_group = 0; column_group < STARS_PER_LINE; ++column_group) {
+ struct Coordinate star = stars[column_group + (line * STARS_PER_LINE)];
+
+ // skip stars that were never added
+ if (!star.exists) {
+ continue;
+ }
+ if (rand() % TWINKLE_PROBABILITY_MODULATOR == 0) {
+ oled_write_pixel(star.x, star.y, false); // black out pixel
+
+ // don't allow stars to leave their own region
+ if (star.x == (column_group * 8)) { // star is the farthest left it can go in its region
+ star.x++; // move it right immediately
+ } else if (star.x == (((column_group + 1) * 8) - 1)) { // star is farthest right it can go in its region
+ star.x--; // move it left immediately
+ }
+ if (star.y == (line * 8)) { // star is the farthest up it can go in its region
+ star.y++; // move it down immediately
+ } else if (star.y == (((line + 1) * 8) - 1)) { // star is farthest down it can go in its region
+ star.y--; // move it up immediately
+ }
+
+ // now decide direction
+ int new_x;
+ int x_choice = rand() % 3;
+ if (x_choice == 0) {
+ new_x = star.x - 1;
+ } else if (x_choice == 1) {
+ new_x = star.x + 1;
+ } else {
+ new_x = star.x;
+ }
+
+ int new_y;
+ int y_choice = rand() % 3;
+ if (y_choice == 0) {
+ new_y = star.y - 1;
+ } else if (y_choice == 1) {
+ new_y = star.y + 1;
+ } else {
+ new_y = star.y;
+ }
+
+ star.x = new_x;
+ star.y = new_y;
+ oled_write_pixel(new_x, new_y, true);
+ }
+
+ stars[column_group + (line * STARS_PER_LINE)] = star;
+ }
+ }
+}
+
+/**
+ * Setup the stars and then animate them on subsequent frames
+ */
+static void animate_stars(void) {
+ if (!stars_setup) {
+ setup_stars();
+ } else {
+ twinkle_stars();
+ }
+}
+#endif // endregion
+
+#ifdef ENABLE_SHOOTING_STARS // region
+bool shooting_stars_setup = false; // only setup shooting stars array once with defaults
+
+struct ShootingStar {
+ int x_1;
+ int y_1;
+ int x_2;
+ int y_2;
+ bool running;
+ int frame;
+ int delay;
+};
+
+struct ShootingStar shooting_stars[MAX_NUMBER_OF_SHOOTING_STARS]; // tracks all the shooting stars
+
+static void setup_shooting_star(struct ShootingStar *shooting_star) {
+ int column_to_start = rand() % (WIDTH / 2);
+ int row_to_start = rand() % (HEIGHT - 48); // shooting_stars travel diagonally 1 down, 1 across. So the lowest a shooting_star can start and not 'hit' the ocean is 32 above the ocean.
+
+ shooting_star->x_1 = column_to_start;
+ shooting_star->y_1 = row_to_start;
+ shooting_star->x_2 = column_to_start + 1;
+ shooting_star->y_2 = row_to_start + 1;
+ shooting_star->running = true;
+ shooting_star->frame++;
+ shooting_star->delay = rand() % SHOOTING_STAR_DELAY;
+}
+
+static void move_shooting_star(struct ShootingStar *shooting_star) {
+ oled_write_pixel(shooting_star->x_1, shooting_star->y_1, false);
+ oled_write_pixel(shooting_star->x_2, shooting_star->y_2, false);
+
+ shooting_star->x_1++;
+ shooting_star->y_1++;
+ shooting_star->x_2++;
+ shooting_star->y_2++;
+ shooting_star->frame++;
+
+ oled_write_pixel(shooting_star->x_1, shooting_star->y_1, true);
+ oled_write_pixel(shooting_star->x_2, shooting_star->y_2, true);
+}
+
+static void finish_shooting_star(struct ShootingStar *shooting_star) {
+ oled_write_pixel(shooting_star->x_1, shooting_star->y_1, false);
+ oled_write_pixel(shooting_star->x_2, shooting_star->y_2, false);
+ shooting_star->running = false;
+ shooting_star->frame = 0;
+}
+
+static void animate_shooting_star(struct ShootingStar *shooting_star) {
+ if (shooting_star->frame > SHOOTING_STAR_FRAMES) {
+ finish_shooting_star(shooting_star);
+ return;
+ } else if (!shooting_star->running) {
+ setup_shooting_star(shooting_star);
+ } else {
+ if (shooting_star->delay == 0) {
+ move_shooting_star(shooting_star);
+ } else {
+ shooting_star->delay--;
+ }
+ }
+}
+
+static void animate_shooting_stars(void) {
+ if (is_calm) {
+ return;
+ }
+ if (!shooting_stars_setup) {
+ for (int i = 0; i < MAX_NUMBER_OF_SHOOTING_STARS; ++i) {
+ shooting_stars[i].running = false;
+ }
+ shooting_stars_setup = true;
+ }
+ /**
+ * Fixes issue with stars that were falling _while_ the
+ * wpm dropped below the condition for them to keep falling
+ */
+ void end_extra_stars(uint8_t starting_index) {
+ for (int shooting_star_index = starting_index; shooting_star_index < MAX_NUMBER_OF_SHOOTING_STARS; ++shooting_star_index) {
+ struct ShootingStar shooting_star = shooting_stars[shooting_star_index];
+ if (shooting_star.running) {
+ finish_shooting_star(&shooting_star);
+ shooting_stars[shooting_star_index] = shooting_star;
+ }
+ }
+ }
+
+ int number_of_shooting_stars = current_wpm / SHOOTING_STAR_WPM_INCREMENT;
+ number_of_shooting_stars = (number_of_shooting_stars > MAX_NUMBER_OF_SHOOTING_STARS) ? MAX_NUMBER_OF_SHOOTING_STARS : number_of_shooting_stars;
+
+ if (number_of_shooting_stars == 0) {
+ // make sure all shooting_stars are ended
+ end_extra_stars(0);
+ } else {
+ for (int shooting_star_index = 0; shooting_star_index < number_of_shooting_stars; ++shooting_star_index) {
+ struct ShootingStar shooting_star = shooting_stars[shooting_star_index];
+ animate_shooting_star(&shooting_star);
+ shooting_stars[shooting_star_index] = shooting_star;
+ }
+ end_extra_stars(number_of_shooting_stars);
+ }
+}
+#endif // endregion
+
+/**
+ * Main rendering function
+ *
+ * Calls all different animations at different rates
+ */
+void render_stars(void) {
+ // // animation timer
+ if (timer_elapsed32(starry_night_anim_timer) > STARRY_NIGHT_ANIM_FRAME_DURATION) {
+ starry_night_anim_timer = timer_read32();
+ current_wpm = get_current_wpm();
+
+#ifdef ENABLE_ISLAND
+ animate_island();
+#endif
+
+#ifdef ENABLE_SHOOTING_STARS
+ if (animation_counter % SHOOTING_STAR_ANIMATION_MODULATOR == 0) {
+ animate_shooting_stars();
+ }
+#endif
+
+#ifdef ENABLE_STARS
+ // TODO offsetting the star animation from the wave animation would look better,
+ // but if I do that, then the stars appear in the water because
+ // the ocean animation has to wait a bunch of frames to overwrite it.
+ // Possible solutions:
+ // 1. Only draw stars to the top of the island/ocean.
+ // 2. Draw ocean every frame, only move ocean on frames matching modulus
+ // Problems:
+ // 1. What if someone wants to move the island up a bit, or they want to have the stars reflect in the water?
+ // 2. More cpu intensive. And I'm already running out of cpu as it is...
+ if (animation_counter % STAR_ANIMATION_MODULATOR == 0) {
+ animate_stars();
+ }
+#endif
+
+#ifdef ENABLE_WAVE
+ if (animation_counter % OCEAN_ANIMATION_MODULATOR == 0) {
+ animate_waves();
+ }
+#endif
+
+#ifdef ENABLE_MOON
+ draw_moon();
+#endif
+
+ animation_counter = increment_counter(animation_counter, NUMBER_OF_FRAMES);
+ }
+}
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.h b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.h
new file mode 100644
index 0000000000..8d3c505c33
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/ocean_dream.h
@@ -0,0 +1,89 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+#include "quantum.h"
+
+/**
+ * Features:
+ * You can turn on and off features in this section
+ */
+#define ENABLE_MOON // Uses 182 bytes
+#define ENABLE_WAVE // Uses 844 bytes
+#define ENABLE_SHOOTING_STARS // Uses 872 bytes
+#define ENABLE_ISLAND
+#define ENABLE_STARS // Uses 606 bytes
+
+/**
+ * Global Settings
+ */
+#define STARRY_NIGHT_ANIM_FRAME_DURATION 30 // how long each frame lasts in ms
+#define NUMBER_OF_FRAMES 20 // Self explanatory. Probably shouldn't touch this, not sure how stuff will work if it's changed. If changed should be multiple of 1, 2, 3, 4, and 5
+#define WIDTH OLED_DISPLAY_HEIGHT // for vertical displays
+#define HEIGHT OLED_DISPLAY_WIDTH // for vertical displays
+
+/**
+ * Moon Parameters
+ */
+#define MOON_LINE 4 // the line you want the moon to appear at
+#define MOON_COLUMN 4 // the column you want the moon to appear at
+//#define STATIC_MOON // uncomment this to make the moon a static image, no animation
+#ifndef STATIC_MOON
+# define ANIMATE_MOON_EVERY_N_FRAMES 100 // animate the moon every n frames
+#endif
+
+/**
+ * Wave Parameters
+ */
+#define OCEAN_LINE 14 // Line you want to render the ocean starting at (best at oled_max_lines() - 2)
+#define WAVE_CALM 20 // render calm ocean under this WPM and ripple ocean at this WPM
+#define WAVE_HEAVY_STORM 40 // render medium ocean at this WPM
+#define WAVE_HURRICANE 60 // render heavy waves above this WPM
+// What number of frames you want to animate the ocean at.
+// Should be equal to or smaller than NUMBER_OF_FRAMES, e.g. 30, would animate on every other frame, 20, every third frame, etc
+// Don't set equal to 0.
+#define OCEAN_ANIMATION_SPEED 1
+
+/**
+ * Shooting Star Parameters
+ */
+#define SHOOTING_STAR_DELAY 12 // delay modulus for time between shooting stars. Decides number of frames to delay, e.g. 12 means 0-11 frames of delay between each shooting star
+#define SHOOTING_STAR_FRAMES 16 // how many 2 pixel frames per shooting star. Increment this for longer shooting stars
+#define MAX_NUMBER_OF_SHOOTING_STARS 12 // maximum number of shooting stars that can be on screen at the same time
+#define SHOOTING_STAR_WPM_INCREMENT 10 // every n WPM increase, add an extra star, up to MAX_NUMBER_OF_SHOOTING_STARS, e.g. an increment of 5 would result in 1 shooting star at 5-9wpm, 2 at 10-14, etc.
+// What number of frames you want to animate the shooting stars at.
+// Should be equal to or smaller than NUMBER_OF_FRAMES, e.g. 30, would animate on every other frame, 20, every third frame, etc
+// Don't set equal to 0.
+#define SHOOTING_STAR_ANIMATION_SPEED 30
+
+/**
+ * Star Parameters
+ */
+#define STARS_PER_LINE 4 // number of stars per line (for a display that is 128x32, this would be 4 stars spread out evenly over the 32byte width, one every 8 bytes)
+#define NUMBER_OF_STAR_LINES 16 // number of lines to fill up with stars (for a display that is 128x32, 16 bytes are filled with the ocean animation, so that leaves 112 pixels left over. The number of lines depends on your OLED_FONT_HEIGHT)
+#define TWINKLE_PROBABILITY 25 // probability that any star twinkles on a given frame
+// What number of frames you want to animate the stars at.
+// Should be equal to or smaller than NUMBER_OF_FRAMES, e.g. 20, would animate on every frame, 10, every other frame, etc
+// Don't set equal to 0.
+#define STAR_ANIMATION_SPEED 1
+
+/**
+ * Island Parameters
+ */
+#define ISLAND_LINE 12 // line that the island starts at. Island is 2 lines tall
+#define ISLAND_COLUMN 0 // column that the island starts at
+#define ISLAND_CALM 20 // WPM at which the palm tree calmly moves
+#define ISLAND_HEAVY_STORM 40 // WPM at which the heavy storm occurs
+#define ISLAND_HURRICANE 60 // WPM at which THE HURRICANE STARTS
+
+/*
+ * DON'T TOUCH
+ */
+
+extern bool is_calm;
+
+// timers
+extern uint32_t starry_night_anim_timer;
+extern uint32_t starry_night_anim_sleep;
+
+void render_stars(void);
diff --git a/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/oled_slave_handler.c b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/oled_slave_handler.c
new file mode 100644
index 0000000000..ef38fd8c44
--- /dev/null
+++ b/keyboards/crkbd/keymaps/jpe230/oled/rp2040/slave/oled_slave_handler.c
@@ -0,0 +1,11 @@
+// Copyright 2022 Jose Pablo Ramirez (@jpe230)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jpe230.h"
+#include "ocean_dream.h"
+
+void render_slave_oled() {
+ render_stars();
+}
+
+oled_rotation_t rotate_slave(oled_rotation_t rotation) {return OLED_ROTATION_270;}