#include "menu_settings.h" #include "menu_cmdr.h" #include "menus.h" #include "config.h" #include "state.h" #include "draw.h" #include "game.h" #include "ble.h" #include "events.h" #include static const uint8_t s_icon_cog[2][ICON_W] = { // Cog (settings) {0x00,0x80,0xDC,0xFC,0xFC,0xB8,0x9C,0xFE,0xFE,0x9C,0xB8,0xFC,0xFC,0xDC,0x80,0x00}, {0x00,0x01,0x3B,0x3F,0x3F,0x1D,0x39,0x7F,0x7F,0x39,0x1D,0x3F,0x3F,0x3B,0x01,0x00}, }; static void settings_nav_short(int d) { if (g_active_setting == SET_PLAYER_NAME) { if (d > 0) { g_name_cursor++; if (g_name_cursor >= PLAYER_NAME_LEN) { g_name_cursor = 0; g_active_setting = (g_active_setting + 1) % NUM_SETTINGS; g_game_id_cursor = 0; } } else { if (g_name_cursor > 0) { g_name_cursor--; } else { g_active_setting = (g_active_setting - 1 + NUM_SETTINGS) % NUM_SETTINGS; g_name_cursor = (g_active_setting == SET_PLAYER_NAME) ? PLAYER_NAME_LEN - 1 : 0; g_game_id_cursor = (g_active_setting == SET_GAME_ID) ? GAME_ID_DIGITS - 1 : 0; } } } else if (g_active_setting == SET_GAME_ID) { if (d > 0) { g_game_id_cursor++; if (g_game_id_cursor >= GAME_ID_DIGITS) { g_game_id_cursor = 0; g_active_setting = (g_active_setting + 1) % NUM_SETTINGS; } } else { if (g_game_id_cursor > 0) { g_game_id_cursor--; } else { g_active_setting = (g_active_setting - 1 + NUM_SETTINGS) % NUM_SETTINGS; g_name_cursor = (g_active_setting == SET_PLAYER_NAME) ? PLAYER_NAME_LEN - 1 : 0; g_game_id_cursor = (g_active_setting == SET_GAME_ID) ? GAME_ID_DIGITS - 1 : 0; } } } else { if (d > 0) { g_active_setting = (g_active_setting + 1) % NUM_SETTINGS; g_name_cursor = 0; g_game_id_cursor = 0; } else { g_active_setting = (g_active_setting - 1 + NUM_SETTINGS) % NUM_SETTINGS; g_name_cursor = (g_active_setting == SET_PLAYER_NAME) ? PLAYER_NAME_LEN - 1 : 0; g_game_id_cursor = (g_active_setting == SET_GAME_ID) ? GAME_ID_DIGITS - 1 : 0; } } } static void settings_lr_delta(int d) { mark_dirty(); switch (g_active_setting) { case SET_BRIGHTNESS: g_brightness_pct += d; if (g_brightness_pct < BRIGHTNESS_MIN) g_brightness_pct = BRIGHTNESS_MIN; if (g_brightness_pct > BRIGHTNESS_MAX) g_brightness_pct = BRIGHTNESS_MAX; g_led_max = (uint8_t)(255 * g_brightness_pct / 100); break; case SET_START_LIFE: g_start_life_index += d; if (g_start_life_index < 0) g_start_life_index = 0; if (g_start_life_index >= NUM_LIFE_OPTS) g_start_life_index = NUM_LIFE_OPTS - 1; break; case SET_NUM_OPP: g_num_opponents += d; if (g_num_opponents < 1) g_num_opponents = 1; if (g_num_opponents > MAX_OPPONENTS) g_num_opponents = MAX_OPPONENTS; if (g_active_opponent >= g_num_opponents) g_active_opponent = 0; break; case SET_PLAYER_NAME: { char curr = g_player_name[g_name_cursor]; const char *p = strchr(NAME_CHARS, curr); int idx = p ? (int)(p - NAME_CHARS) : 0; idx = (idx + d + NUM_NAME_CHARS) % NUM_NAME_CHARS; g_player_name[g_name_cursor] = NAME_CHARS[idx]; break; } case SET_BLE: g_ble_enabled += d; if (g_ble_enabled < 0) g_ble_enabled = 0; if (g_ble_enabled > 1) g_ble_enabled = 1; menus[MENU_CMDR] = g_ble_enabled ? &menu_cmdr_ble_vtable : &menu_cmdr_offline_vtable; ble_adv_update(); oled_draw_header(); break; case SET_GAME_ID: { int byte = g_game_id_cursor / 2; int nibble = g_game_id_cursor % 2; int val = nibble == 0 ? (g_game_id[byte] >> 4) & 0xF : g_game_id[byte] & 0xF; val = (val + d + NUM_HEX_CHARS) % NUM_HEX_CHARS; if (nibble == 0) g_game_id[byte] = (g_game_id[byte] & 0x0F) | ((uint8_t)val << 4); else g_game_id[byte] = (g_game_id[byte] & 0xF0) | (uint8_t)val; ble_adv_update(); break; } case SET_RESET: game_reset(); ble_adv_update(); break; case SET_RESET_ALL: game_reset(); g_reset_cmd_ticks = 1; start_reset_cmd_timer(); ble_adv_update(); break; case SET_MENU_HOLD: g_menu_hold_ms += d * 10; if (g_menu_hold_ms < HOLD_MS_MIN) g_menu_hold_ms = HOLD_MS_MIN; if (g_menu_hold_ms > HOLD_MS_MAX) g_menu_hold_ms = HOLD_MS_MAX; break; case SET_LR_HOLD: g_lr_hold_ms += d * 10; if (g_lr_hold_ms < HOLD_MS_MIN) g_lr_hold_ms = HOLD_MS_MIN; if (g_lr_hold_ms > HOLD_MS_MAX) g_lr_hold_ms = HOLD_MS_MAX; break; case SET_DISPLAY_FLIP: g_display_flip ^= 1; oled_set_flip(g_display_flip); break; case SET_DELTA_TIMEOUT: g_delta_timeout_ms += d * 100; if (g_delta_timeout_ms < DELTA_TIMEOUT_MIN) g_delta_timeout_ms = DELTA_TIMEOUT_MIN; if (g_delta_timeout_ms > DELTA_TIMEOUT_MAX) g_delta_timeout_ms = DELTA_TIMEOUT_MAX; break; case SET_AUTO_SLEEP: g_sleep_timeout_min += d; if (g_sleep_timeout_min < 0) g_sleep_timeout_min = 0; if (g_sleep_timeout_min > SLEEP_TIMEOUT_MAX) g_sleep_timeout_min = SLEEP_TIMEOUT_MAX; restart_idle_timer(); break; } } static void settings_draw(void) { oled_draw_settings(); } const menu_vtable_t menu_settings_vtable = { .nav_short = settings_nav_short, .lr_delta = settings_lr_delta, .draw = settings_draw, .on_tick = NULL, .icon = s_icon_cog, };