commeownder/main/menu_cmdr.c

96 lines
3.0 KiB
C

#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 <stdio.h>
// ── Offline vtable ────────────────────────────────────────────────────────────
static const uint8_t s_icon_shield[2][ICON_W] = {
// Shield (commander damage)
{0x00,0xFC,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFC,0x00,0x00},
{0x00,0x07,0x0F,0x1F,0x3F,0x3F,0x3F,0x7F,0x7F,0x3F,0x3F,0x1F,0x0F,0x07,0x00,0x00},
};
static const uint8_t s_icon_net[2][ICON_W] = {
// Signal bars (BLE commander)
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0xF8,0xF8,0x00,0xFE,0xFE,0x00,0x00},
{0x00,0x00,0x00,0x38,0x38,0x00,0x3F,0x3F,0x00,0x3F,0x3F,0x00,0x3F,0x3F,0x00,0x00},
};
static void cmdr_offline_nav_short(int d)
{
g_active_opponent = (g_active_opponent + d + g_num_opponents) % g_num_opponents;
}
static void cmdr_offline_lr_delta(int d)
{
g_cmdr_damage[g_active_opponent] += d;
if (g_cmdr_damage[g_active_opponent] < 0) g_cmdr_damage[g_active_opponent] = 0;
check_elimination();
mark_dirty();
}
static void cmdr_offline_draw(void)
{
char opponent_labels[MAX_OPPONENTS][PLAYER_NAME_LEN + 1];
const char *opponent_label_ptrs[MAX_OPPONENTS];
for (int i = 0; i < g_num_opponents; i++) {
snprintf(opponent_labels[i], sizeof(opponent_labels[i]), "CMD %d", i + 1);
opponent_label_ptrs[i] = opponent_labels[i];
}
oled_draw_list(opponent_label_ptrs, g_cmdr_damage, g_num_opponents, g_active_opponent);
}
const menu_vtable_t menu_cmdr_offline_vtable = {
.nav_short = cmdr_offline_nav_short,
.lr_delta = cmdr_offline_lr_delta,
.draw = cmdr_offline_draw,
.on_tick = NULL,
.icon = s_icon_shield,
};
// ── BLE vtable ────────────────────────────────────────────────────────────────
static void cmdr_ble_nav_short(int d)
{
int total = MAX_BLE_PEERS + 1;
int next = (g_active_player + d + total) % total;
while (next != g_active_player && next != 0 && !g_peers[next - 1].active)
next = (next + d + total) % total;
g_active_player = next;
}
static void cmdr_ble_lr_delta(int d)
{
if (g_active_player == 0) {
g_life += d;
g_life_delta += d;
restart_life_delta_timer();
check_elimination();
} else {
int slot = g_active_player - 1;
g_cmdr_damage[slot] += d;
if (g_cmdr_damage[slot] < 0) g_cmdr_damage[slot] = 0;
check_elimination();
}
mark_dirty();
}
static void cmdr_ble_draw(void)
{
oled_draw_players();
}
const menu_vtable_t menu_cmdr_ble_vtable = {
.nav_short = cmdr_ble_nav_short,
.lr_delta = cmdr_ble_lr_delta,
.draw = cmdr_ble_draw,
.on_tick = NULL,
.icon = s_icon_net,
};