menu.c (6663B)
1 /* 2 MNT Reform 2.0 Keyboard Firmware 3 See keyboard.c for Copyright 4 SPDX-License-Identifier: MIT 5 */ 6 7 #include "backlight.h" 8 #include "constants.h" 9 #include "keyboard.h" 10 #include "menu.h" 11 #include "oled.h" 12 #include "powersave.h" 13 #include "remote.h" 14 #include "scancodes.h" 15 16 int current_menu_y = 0; 17 int current_scroll_y = 0; 18 int current_menu_page = 0; 19 int8_t logo_timeout_ticks = 0; 20 21 #define KEYMODS_NUM_ITEMS 5 22 const MenuItem keymods_items[] = { 23 { " SHIFT ", KEY_ESCAPE }, 24 { " CNTRL ", KEY_ESCAPE }, 25 { " AGR ", KEY_ESCAPE }, 26 { " ALT ", KEY_ESCAPE }, 27 { " SUPER ", KEY_ESCAPE }, 28 }; 29 30 #define HYPER_HELP_NUM_ITEMS 4 31 const MenuItem help_items[] = { 32 { "Delete Backspace", KEY_ESCAPE }, 33 { "Home/End/Pg Arrows", KEY_ESCAPE }, 34 { "Player F7-F9", KEY_ESCAPE }, 35 { "Volume F10-F12", KEY_ESCAPE }, 36 }; 37 38 #ifdef KBD_MODE_STANDALONE 39 #define MENU_NUM_ITEMS 5 40 const MenuItem menu_items[] = { 41 { "Exit Menu ESC", KEY_ESCAPE }, 42 { "Key Backlight- F1", KEY_F1 }, 43 { "Key Backlight+ F2", KEY_F2 }, 44 { "System Status s", KEY_S }, 45 { "USB Flashing Mode x", KEY_X }, 46 }; 47 #else 48 #define MENU_NUM_ITEMS 9 49 const MenuItem menu_items[] = { 50 { "Exit Menu ESC", KEY_ESCAPE }, 51 { "Power On 1", KEY_1 }, 52 { "Power Off 0", KEY_0 }, 53 { "Reset r", KEY_R }, 54 { "Battery Status b", KEY_B }, 55 { "Key Backlight- F1", KEY_F1 }, 56 { "Key Backlight+ F2", KEY_F2 }, 57 { "Wake SPC", KEY_SPACE }, 58 { "System Status s", KEY_S }, 59 60 // Only needed for debugging. 61 // The keyboard will go to sleep when turning off 62 // main system power. 63 { "KBD Power-Off p", KEY_P }, 64 }; 65 #endif 66 67 void reset_menu() { 68 current_scroll_y = 0; 69 current_menu_y = 0; 70 current_menu_page = MENU_PAGE_NONE; 71 } 72 73 void reset_and_render_menu() { 74 reset_menu(); 75 render_menu(current_scroll_y); 76 } 77 78 void render_menu(int y) { 79 gfx_clear(); 80 gfx_invert_row(current_menu_y-y); 81 for (int i=0; i<MENU_NUM_ITEMS; i++) { 82 gfx_poke_str(0,i-y,menu_items[i].title); 83 } 84 gfx_on(); 85 gfx_flush(); 86 } 87 88 void render_keymods(int keymods) { 89 gfx_clear(); 90 int line=0; 91 for (int i=0; i<KEYMODS_NUM_ITEMS; i++) { 92 if ((int)(pow(2, i)+0.5) & keymods) { 93 gfx_poke_str(0,line++,keymods_items[i].title); 94 } 95 if (line>3) break; 96 } 97 gfx_on(); 98 gfx_flush(); 99 } 100 101 void render_help() { 102 gfx_clear(); 103 for (int i=0; i<HYPER_HELP_NUM_ITEMS; i++) { 104 gfx_poke_str(0,i,help_items[i].title); 105 } 106 gfx_on(); 107 gfx_flush(); 108 } 109 110 void clear_display() { 111 gfx_clear(); 112 gfx_flush(); 113 } 114 115 // automatically refresh the current menu page if needed 116 void refresh_menu_page() { 117 if (current_menu_page == MENU_PAGE_BATTERY_STATUS) { 118 remote_get_voltages(); 119 } else if (current_menu_page == MENU_PAGE_MNT_LOGO && --logo_timeout_ticks <= 0) { 120 gfx_clear(); 121 gfx_flush(); 122 reset_menu(); 123 } 124 } 125 126 int execute_menu_function(int y) { 127 current_menu_page = MENU_PAGE_NONE; 128 129 if (y>=0 && y<MENU_NUM_ITEMS) { 130 current_menu_page = MENU_PAGE_OTHER; 131 return execute_meta_function(menu_items[y].keycode); 132 } 133 return execute_meta_function(KEY_ESCAPE); 134 } 135 136 #define BOOTLOADER_START_ADDRESS ((0x8000-0x1000) >> 1) 137 void jump_to_bootloader(void) { 138 ((void (*)(void))BOOTLOADER_START_ADDRESS)(); 139 } 140 141 // returns 1 for navigation function (stay in meta mode), 0 for terminal function 142 int execute_meta_function(int keycode) { 143 if (keycode == KEY_0) { 144 // TODO: are you sure? 145 anim_goodbye(); 146 remote_turn_off_som(); 147 keyboard_power_off(); 148 reset_keyboard_state(); 149 // Directly enter menu again 150 return 2; 151 } 152 else if (keycode == KEY_1) { 153 kbd_brightness_init(); 154 if (remote_turn_on_som()) { 155 anim_hello(); 156 } 157 return 0; 158 } 159 else if (keycode == KEY_R) { 160 // TODO: are you sure? 161 remote_reset_som(); 162 } 163 else if (keycode == KEY_SPACE) { 164 remote_wake_som(); 165 } 166 /*else if (keycode == KEY_V) { 167 remote_turn_off_aux(); 168 }*/ 169 #ifndef KBD_MODE_STANDALONE 170 else if (keycode == KEY_B) { 171 current_menu_page = MENU_PAGE_BATTERY_STATUS; 172 remote_get_voltages(); 173 return 0; 174 } 175 #endif 176 else if (keycode == KEY_S) { 177 remote_get_status(); 178 return 0; 179 } 180 else if (keycode == KEY_F1) { 181 kbd_brightness_dec(); 182 return 1; 183 } 184 else if (keycode == KEY_F2) { 185 kbd_brightness_inc(); 186 return 1; 187 } 188 else if (keycode == HID_KEYBOARD_SC_UP_ARROW) { 189 current_menu_y--; 190 if (current_menu_y<0) current_menu_y = 0; 191 if (current_menu_y<=current_scroll_y) current_scroll_y--; 192 if (current_scroll_y<0) current_scroll_y = 0; 193 render_menu(current_scroll_y); 194 return 1; 195 } 196 else if (keycode == HID_KEYBOARD_SC_DOWN_ARROW) { 197 current_menu_y++; 198 if (current_menu_y>=MENU_NUM_ITEMS) current_menu_y = MENU_NUM_ITEMS-1; 199 if (current_menu_y>=current_scroll_y+3) current_scroll_y++; 200 render_menu(current_scroll_y); 201 return 1; 202 } 203 else if (keycode == KEY_ENTER) { 204 return execute_menu_function(current_menu_y); 205 } 206 else if (keycode == KEY_ESCAPE) { 207 clear_display(); 208 } 209 else if (keycode == KEY_X) { 210 gfx_clear(); 211 gfx_poke_str(1, 1, "Entered firmware"); 212 gfx_poke_str(1, 2, "update mode."); 213 gfx_on(); 214 gfx_flush(); 215 jump_to_bootloader(); 216 } 217 else if (keycode == KEY_L) { 218 anim_hello(); 219 return 0; 220 } 221 222 gfx_clear(); 223 gfx_flush(); 224 225 return 0; 226 } 227 228 #ifndef KBD_MODE_STANDALONE 229 void anim_kbd_hello(void) { 230 kbd_brightness_set(0); 231 for (int b = 0; b < 8; ++b) { 232 kbd_brightness_inc(); 233 Delay_MS(90); 234 } 235 for (int b = 0; b < 4; ++b) { 236 kbd_brightness_dec(); 237 Delay_MS(110); 238 } 239 } 240 #endif 241 242 void anim_hello(void) { 243 current_menu_page = MENU_PAGE_MNT_LOGO; 244 logo_timeout_ticks = 10; // ~30sec 245 gfx_clear(); 246 kbd_brightness_set(0); 247 gfx_on(); 248 for (int y=0; y<3; y++) { 249 for (int x=0; x<12; x++) { 250 gfx_poke(x+4,y+1,(5+y)*32+x); 251 gfx_flush(); 252 } 253 } 254 for (int y=0; y<0xff; y++) { 255 if ((y % 32) == 0) { 256 kbd_brightness_inc(); 257 } 258 gfx_contrast(y); 259 Delay_MS(2); 260 } 261 for (int y=0; y<0xff; y++) { 262 if ((y % 64) == 0) { 263 kbd_brightness_dec(); 264 } 265 gfx_contrast(0xff-y); 266 Delay_MS(2); 267 } 268 } 269 270 void anim_goodbye(void) { 271 gfx_clear(); 272 gfx_on(); 273 for (int y=0; y<3; y++) { 274 for (int x=0; x<12; x++) { 275 gfx_poke(x+4,y+1,(5+y)*32+x); 276 } 277 } 278 for (int y=0; y<3; y++) { 279 for (int x=0; x<12; x++) { 280 gfx_poke(x+4,y+1,' '); 281 gfx_flush(); 282 } 283 } 284 int16_t brt = kbd_brightness_get(); 285 while (brt--) { 286 kbd_brightness_dec(); 287 Delay_MS(64); 288 } 289 gfx_off(); 290 } 291 /* vim: set tabstop=2:softtabstop=2:shiftwidth=2:expandtab */