diff options
18 files changed, 1979 insertions, 424 deletions
| diff --git a/keyboards/crkbd/keymaps/jpe230/config.h b/keyboards/crkbd/keymaps/jpe230/config.h index d8185d4253..57a0271e27 100644 --- a/keyboards/crkbd/keymaps/jpe230/config.h +++ b/keyboards/crkbd/keymaps/jpe230/config.h @@ -1,40 +1,47 @@ -/* -This is the c configuration file for the keymap +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later -Copyright 2012 Jun Wako <[email protected]> -Copyright 2015 Jack Humbert -Copyright 2022 Jose Pablo Ramirez <[email protected]> +#pragma once -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. +/* --------------------------- + * Common Spit Configuration + * --------------------------- + */ +#define SPLIT_OLED_ENABLE -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. +/* --------------------------- + * Common OLED Configuration + * --------------------------- + */ +#define OLED_TIMEOUT 0 +#define CUSTOM_OLED_TIMEOUT 10000 -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +/* --------------------------- + * Common Bootmagic Lite + * --------------------------- + */ +#define BOOTMAGIC_LITE_ROW 0 +#define BOOTMAGIC_LITE_COLUMN 0 -#pragma once +/* --------------------------- + * Common RGB Configuration + * --------------------------- + */ +#define RGB_DISABLE_WHEN_USB_SUSPENDED +#define RGB_DISABLE_TIMEOUT CUSTOM_OLED_TIMEOUT +#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 128 +#define RGB_MATRIX_STARTUP_HUE 215 +#define RGB_MATRIX_STARTUP_SAT 255 +#define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS -#ifndef RGB_MATRIX_ENABLE -#   define SPLIT_WPM_ENABLE -#endif +/* --------------------------- + * Common other Configuration + * --------------------------- + */ +#define ENABLE_COMPILE_KEYCODE -#ifdef RGB_MATRIX_ENABLE -#   define RGB_DISABLE_WHEN_USB_SUSPENDED -#   define RGB_MATRIX_MAXIMUM_BRIGHTNESS 128 -#   define RGB_MATRIX_STARTUP_HUE 215 -#   define RGB_MATRIX_STARTUP_SAT 255 -#   define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS -#   define ENABLE_RGB_MATRIX_ALPHAS_MODS -#   define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT -#   define ENABLE_RGB_MATRIX_BAND_VAL -#   define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON -#   define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL -#   define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS +#if defined CONVERT_TO_KB2040 || defined CONVERT_TO_PROMICRO_RP2040 +#    include "config_rp2040.h" +#else +#    include "config_avr.h"  #endif diff --git a/keyboards/crkbd/keymaps/jpe230/config_avr.h b/keyboards/crkbd/keymaps/jpe230/config_avr.h new file mode 100644 index 0000000000..67226d88f7 --- /dev/null +++ b/keyboards/crkbd/keymaps/jpe230/config_avr.h @@ -0,0 +1,15 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +/* --------------------------- + * AVR RGB Configuration + * --------------------------- + */ +#define ENABLE_RGB_MATRIX_ALPHAS_MODS +#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT +#define ENABLE_RGB_MATRIX_BAND_VAL +#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON +#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL +#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS diff --git a/keyboards/crkbd/keymaps/jpe230/config_rp2040.h b/keyboards/crkbd/keymaps/jpe230/config_rp2040.h new file mode 100644 index 0000000000..b26c14986a --- /dev/null +++ b/keyboards/crkbd/keymaps/jpe230/config_rp2040.h @@ -0,0 +1,73 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +/* --------------------------- + * RP2040 OLED Configuration + * --------------------------- + */ +#define I2C1_CLOCK_SPEED 400000 +#define OLED_UPDATE_INTERVAL 1 +#define OLED_I2C_TIMEOUT 1 + +/* --------------------------- + * RP2040 Split Configuration + * --------------------------- + */ +#define SPLIT_WPM_ENABLE + +/* --------------------------- + * RP2040 Debounce + * --------------------------- + */ +#undef DEBOUNCE +#define DEBOUNCE 1 + +/* --------------------------- + * RP2040 RGB Configuration + * --------------------------- + */ +#define ENABLE_RGB_MATRIX_ALPHAS_MODS +#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN +#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT +#define ENABLE_RGB_MATRIX_BREATHING +#define ENABLE_RGB_MATRIX_BAND_SAT +#define ENABLE_RGB_MATRIX_BAND_VAL +#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT +#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL +#define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT +#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL +#define ENABLE_RGB_MATRIX_CYCLE_ALL +#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT +#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN +#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON +#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN +#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL +#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL +#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL +#define ENABLE_RGB_MATRIX_DUAL_BEACON +#define ENABLE_RGB_MATRIX_RAINBOW_BEACON +#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS +#define ENABLE_RGB_MATRIX_RAINDROPS +#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS +#define ENABLE_RGB_MATRIX_HUE_BREATHING +#define ENABLE_RGB_MATRIX_HUE_PENDULUM +#define ENABLE_RGB_MATRIX_HUE_WAVE +#define ENABLE_RGB_MATRIX_PIXEL_RAIN +#define ENABLE_RGB_MATRIX_PIXEL_FLOW +#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL +#define ENABLE_RGB_MATRIX_TYPING_HEATMAP +#define ENABLE_RGB_MATRIX_DIGITAL_RAIN +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS +#define ENABLE_RGB_MATRIX_SPLASH +#define ENABLE_RGB_MATRIX_MULTISPLASH +#define ENABLE_RGB_MATRIX_SOLID_SPLASH +#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH diff --git a/keyboards/crkbd/keymaps/jpe230/jpe230.h b/keyboards/crkbd/keymaps/jpe230/jpe230.h new file mode 100644 index 0000000000..f5f098f5c5 --- /dev/null +++ b/keyboards/crkbd/keymaps/jpe230/jpe230.h @@ -0,0 +1,15 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include QMK_KEYBOARD_H + +/* --------------------------- + * Custom OLED Fncs Prototypes + * --------------------------- + */ +void render_slave_oled(void); +void render_master_oled(void); +void oled_timer_reset(void); +void set_keylog(uint16_t keycode, keyrecord_t *record); diff --git a/keyboards/crkbd/keymaps/jpe230/keymap.c b/keyboards/crkbd/keymaps/jpe230/keymap.c index 28bb6c1fe1..530c418be5 100644 --- a/keyboards/crkbd/keymaps/jpe230/keymap.c +++ b/keyboards/crkbd/keymaps/jpe230/keymap.c @@ -1,35 +1,9 @@ -/* -Copyright 2019 @foostan -Copyright 2020 Drashna Jaelre <@drashna> -Copyright 2022 Jose Pablo Ramirez <[email protected]> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later  #include QMK_KEYBOARD_H -#ifdef VIA_ENABLE -    #define USER_START USER00 -#else -    #define USER_START SAFE_RANGE -#endif - -// Keycode to toggle Sarcasm Mode -enum custom_keycodes { -    KC_SCASM = USER_START -}; - +// clang-format off  const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {    [0] = LAYOUT_split_3x6_3(    //,-----------------------------------------------------.                    ,-----------------------------------------------------. @@ -72,361 +46,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {    //,-----------------------------------------------------.                    ,-----------------------------------------------------.        KC_MUTE, KC_WBAK, KC_WFWD,   KC_F7,   KC_F8,   KC_F9,                      _______,    KC_7,    KC_8,    KC_9, _______, QK_BOOT,    //|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------| -      KC_VOLU, _______, KC_MNXT,   KC_F6,   KC_F5,   KC_F6,                      _______,    KC_6,    KC_5,    KC_4, _______, _______, +      KC_VOLU, _______, KC_MNXT,   KC_F6,   KC_F5,   KC_F6,                      _______,    KC_6,    KC_5,    KC_4, _______, QK_MAKE,    //|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------| -      KC_VOLD, KC_MPRV, KC_MNXT,   KC_F1,   KC_F2,   KC_F3,                      _______,    KC_1,    KC_2,    KC_3, _______, _______, +      KC_VOLD, KC_MPRV, KC_MNXT,   KC_F1,   KC_F2,   KC_F3,                      _______,    KC_1,    KC_2,    KC_3, _______, DB_TOGG,    //|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------| -                                          KC_LGUI, _______,KC_SCASM,      TG(3), _______, KC_RALT +                                          KC_LGUI, _______, _______,      TG(3), _______, KC_RALT                                        //`--------------------------'  `--------------------------'    )  }; - -#ifdef OLED_ENABLE -oled_rotation_t oled_init_user(oled_rotation_t rotation) { -#ifdef RGB_MATRIX_ENABLE -    if (!is_keyboard_master()) { -        return OLED_ROTATION_180;  // flips the display 180 degrees if offhand -    } -#endif -    return rotation; -} - -#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; -    } -} - - -static char logged_char = ' '; -static uint8_t logged_row = 0, logged_col = 0; -static uint16_t logged_keycode = 0; - -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 set_keylog(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]; -    } - -    // update keylog -    logged_row = record->event.key.row; -    logged_col = record->event.key.col; -    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_bootmagic_status(bool status) { -    /* Show Ctrl-Gui Swap options */ -    static const char PROGMEM logo[][2][3] = { -        {{0x97, 0x98, 0}, {0xb7, 0xb8, 0}}, -        {{0x95, 0x96, 0}, {0xb5, 0xb6, 0}}, -    }; -    if (status) { -        oled_write_ln_P(logo[0][0], false); -        oled_write_ln_P(logo[0][1], false); -    } else { -        oled_write_ln_P(logo[1][0], false); -        oled_write_ln_P(logo[1][1], false); -    } -} - -#ifndef RGB_MATRIX_ENABLE -// frame 0, 128x32px -const char PROGMEM cat_frame_0 [] PROGMEM = { -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 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, 0xc0, 0xc0, -	0x60, 0x60, 0x60, 0x60, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x70, 0x38, 0x18, 0xec, 0x3c, 0x02, 0x02, -	0x7a, 0x7a, 0xf2, 0xf2, 0x06, 0x04, 0x04, 0x0c, 0x0e, 0x0a, 0x1f, 0xfd, 0xf9, 0x39, 0x0f, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0xff, 0xff, 0x03, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc, 0xff, 0x01, 0x08, 0x3c, 0x00, -	0x00, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x7e, 0x00, 0x00, -	0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0xff, 0xff, 0x80, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x87, 0x83, 0xc0, 0x80, 0x88, -	0x1e, 0x1e, 0x0f, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0xc0, 0xe0, 0xfe, 0x87, 0xbe, 0xf0, 0x00, -	0x00, 0x00, 0x00, 0x01, 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, -	0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x07, 0x0f, -	0x12, 0x34, 0x34, 0x34, 0x34, 0x1e, 0x0e, 0x06, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, -	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 -}; -// frame 1, 128x32px -const char PROGMEM cat_frame_1 [] PROGMEM = { -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 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, 0xc0, 0xc0, 0xc0, 0x60, -	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0xe0, 0xf0, 0x90, -	0x18, 0x08, 0x08, 0x88, 0x88, 0x98, 0x10, 0x10, 0x30, 0x30, 0x70, 0xf8, 0x08, 0x88, 0xf8, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 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, 0x07, 0xff, 0xff, 0x01, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x04, 0x06, 0x07, 0x03, 0x01, -	0xc0, 0x00, 0x00, 0x87, 0x87, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1f, 0xf0, 0x00, -	0x00, 0x00, 0xc0, 0xe0, 0xf0, 0xf0, 0xf0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xf8, 0xff, 0xff, 0xc0, 0x80, -	0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x10, 0x30, 0xf0, 0xe0, 0x00, -	0x01, 0x00, 0x60, 0xf0, 0xf0, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xfc, 0xc7, 0x00, -	0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x06, -	0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x02, 0x02, 0x07, 0x07, 0x07, 0x04, 0x07, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -// frame 2, 128x32px -const char PROGMEM cat_frame_2 [] PROGMEM = { -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 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, 0xc0, 0xc0, 0x60, 0x30, -	0x38, 0x18, 0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x78, 0x48, 0x78, 0xc0, 0x80, 0xc0, 0x40, 0x40, -	0x40, 0x40, 0xc0, 0xc0, 0x80, 0x80, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 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, 0xff, 0xff, 0x03, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x20, 0xf0, 0x80, 0x80, 0x60, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x3c, -	0x7c, 0x38, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0x06, 0x3c, 0xff, 0xc3, 0x00, 0x00, 0x00, 0x00, -	0x00, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xf0, 0x80, 0x00, -	0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x00, 0x1e, 0x7f, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, -	0x8c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x00, 0x01, 0x01, 0x0f, 0x18, 0x10, 0x18, 0x0f, 0x0e, 0x18, 0x10, 0x30, 0x27, 0x2f, -	0x2f, 0x27, 0x20, 0x30, 0x10, 0x10, 0x10, 0x30, 0x3c, 0x2d, 0x27, 0x3c, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -const char* cat_frames[3] = { -	cat_frame_0, -	cat_frame_1, -	cat_frame_2 -}; - -#define FRAME_SIZE 528 - -static int      current_frame = 0; -static uint32_t frame_timer = 0; -static uint32_t anim_sleep = 0; -static uint8_t  anim_speed = 120; - -#endif - -void oled_render_logo(void) { -#ifdef RGB_MATRIX_ENABLE -    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); -#endif -#ifndef RGB_MATRIX_ENABLE -    if(get_current_wpm() != 000) { -        oled_on(); -        int8_t wpm_speed = (int8_t)(get_current_wpm() / 2); -        if(wpm_speed < 100) -        { -            anim_speed = 120 - wpm_speed; -        } -        if(timer_elapsed32(frame_timer) > anim_speed) { -            frame_timer = timer_read32();  // resets timer -            current_frame = (current_frame + 1) % 3; -        } -        oled_write_raw_P(cat_frames[current_frame], FRAME_SIZE); -        anim_sleep = timer_read32(); -    } else { -        anim_speed = 150; -        if(timer_elapsed32(anim_sleep) > OLED_TIMEOUT) { -            oled_off(); -        } else { -             if(timer_elapsed32(frame_timer) > anim_speed) { -                frame_timer = timer_read32();  // resets timer -                current_frame = (current_frame + 1) % 3; -            } -            oled_write_raw_P(cat_frames[current_frame], FRAME_SIZE); -        } -    } -#endif -} - -bool oled_task_user(void) { -    if (is_keyboard_master()) { -        oled_render_layer_state(); -        oled_render_keylog(); -    } else { -        oled_render_logo(); -    } -    return false; -} - -#endif // OLED_ENABLE - -// saRcASm MOde -bool tog_sarcasm = false; -bool uppercase = false; -uint8_t prev_upper = 0; -uint8_t prev_lower = 0; -uint8_t prev_mode = 0; -HSV prev_hsv; - - -bool process_record_sarcasm(uint16_t keycode, keyrecord_t *record) { -    if (keycode == KC_ENTER && record->event.pressed) { -        uppercase = false; -        return true; -    } - -    if (uppercase == false && record->event.pressed)  { // Dont start with an uppercase letter on new line -        uppercase = true; -        return true; -    } - -    if((KC_A <= keycode) && (keycode <= KC_Z)) { -        if ( record->event.pressed ) { -            bool press = rand() % 2; - -            if (prev_upper > 2) {           // if more than 3 lower's in a row print upper -                prev_upper = 0; -                press = false; -            } else if (prev_lower > 2) {    // if more than 3 upper's in a row print lower -                prev_lower = 0; -                press = true; -            } -            if (press) { -                prev_upper++; -                tap_code16(S(keycode)); -                clear_mods(); -            } else { -                prev_lower++; -                tap_code16(keycode); -            } -        } -        return false; -    } - -    return true; -} - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - -#ifdef OLED_ENABLE -    if (record->event.pressed) { -        set_keylog(keycode, record); -    } -#endif - -    switch (keycode) { -        case KC_SCASM: -            if (record->event.pressed) { -                tog_sarcasm = !tog_sarcasm; - -                if (tog_sarcasm) { -                    dprint("Enabling saRCaSm ModE\n"); - -                    #ifdef RGB_MATRIX_ENABLE -                    prev_hsv = rgb_matrix_get_hsv(); -                    prev_mode = rgb_matrix_get_mode(); -                    rgb_matrix_mode_noeeprom(RGB_MATRIX_ALPHAS_MODS); -                    rgb_matrix_sethsv_noeeprom(HSV_YELLOW); -                    #endif -                } -                else { -                    dprint("Disabling saRCaSm ModE\n"); -                    #ifdef RGB_MATRIX_ENABLE -                    rgb_matrix_mode_noeeprom(prev_mode); -                    rgb_matrix_sethsv_noeeprom(prev_hsv.h, prev_hsv.s, prev_hsv.v); -                    #endif -                } - -                uppercase = false; -                prev_upper = 0; -                prev_lower = 0; -            } -            return false; -    } - -    if (tog_sarcasm) { -        return process_record_sarcasm(keycode, record); -    } - -    return true; -} +// clang-format off 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;} diff --git a/keyboards/crkbd/keymaps/jpe230/process_record.c b/keyboards/crkbd/keymaps/jpe230/process_record.c new file mode 100644 index 0000000000..db10438d8f --- /dev/null +++ b/keyboards/crkbd/keymaps/jpe230/process_record.c @@ -0,0 +1,20 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "jpe230.h" + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { +    if (record->event.pressed) { +        oled_timer_reset(); +        set_keylog(keycode, record); + +        switch (keycode) { +            case QK_BOOT: +                rgb_matrix_set_color_all(30, 0, 0); +                rgb_matrix_driver.flush(); +                oled_off(); +                return true; +        } +    } +    return true; +} diff --git a/keyboards/crkbd/keymaps/jpe230/readme.md b/keyboards/crkbd/keymaps/jpe230/readme.md index 31bbc4ebd1..de5696116f 100644 --- a/keyboards/crkbd/keymaps/jpe230/readme.md +++ b/keyboards/crkbd/keymaps/jpe230/readme.md @@ -6,10 +6,18 @@ The four layers:  - LOWER Layer: Numbers + Arrows  - RAISE Layer: Symbols  - ADJUST Layer: Numpad + Media Keys + Fn keys -  ## OLED --Master: Renders layer state + keylog --Slave : Renders an animation of a cat that varies its animation speed based on the current WPM +The graphics for the OLED varies depending on the target platform: + +| Half   | RP2040                               | Pro Micro                            | +|--------|--------------------------------------|--------------------------------------| +| Master |  |  | +| Slave  |  |  | +  ## Flashing -Flash using `qmk compile -kb crkbd -km jpe230` for Pro Micro +For Arduino Pro Micro: +- `qmk compile -kb crkbd -km jpe230` + +For Pro Micro Compatible board (See [Converters](https://docs.qmk.fm/#/feature_converters?id=converters)): +- `qmk compile -kb crkbd -km jpe230 -e CONVERT_TO<target>` diff --git a/keyboards/crkbd/keymaps/jpe230/rules.mk b/keyboards/crkbd/keymaps/jpe230/rules.mk index 82d5eb321d..b78c1d45f3 100644 --- a/keyboards/crkbd/keymaps/jpe230/rules.mk +++ b/keyboards/crkbd/keymaps/jpe230/rules.mk @@ -1,12 +1,25 @@  # Shared rules for both of my Corne  OLED_ENABLE       = yes  OLED_DRIVER       = SSD1306 -LTO_ENABLE        = yes  VIA_ENABLE        = yes +RGB_MATRIX_ENABLE = yes -# Rules for my Corne without RGB -# WPM_ENABLE        = yes -# MOUSEKEY_ENABLE   = yes +SRC += oled/oled_handler.c process_record.c + +ifneq ($(CONVERT_TO),) +    # Asume ARM +    DEBUG_MATRIX_SCAN_RATE_ENABLE = yes +    WPM_ENABLE = yes +    CONSOLE_ENABLE = yes +    SRC +=  oled/rp2040/master/oled_master_handler.c \ +            oled/rp2040/master/indicators_down.c \ +            oled/rp2040/master/indicators_up.c \ +            oled/rp2040/slave/oled_slave_handler.c \ +            oled/rp2040/slave/ocean_dream.c +else +    # Asume AVR +    LTO_ENABLE = yes +    SRC +=  oled/avr/master/oled_master_handler.c \ +            oled/avr/slave/oled_slave_handler.c +endif -# Rules for my Corne with RGB -RGB_MATRIX_ENABLE = yes | 
