Draw basic menu on screen

This commit is contained in:
Frederik Walk 2023-07-09 18:19:41 +02:00
parent 79f768ecac
commit 65d0a7a551
3 changed files with 101 additions and 12 deletions

View File

@ -3,6 +3,7 @@
#include "usb/usb_driver.h"
#include "utils/InputState.h"
#include "utils/Menu.h"
#include <ssd1306/ssd1306.h>
@ -33,6 +34,8 @@ class Display {
usb_mode_t m_usb_mode;
uint8_t m_player_id;
Utils::Menu::State m_menu_state;
ssd1306_t m_display;
void drawIdleScreen();
@ -45,6 +48,8 @@ class Display {
void setUsbMode(usb_mode_t mode);
void setPlayerId(uint8_t player_id);
void setMenuState(const Utils::Menu::State &menu_state);
void showIdle();
void showMenu();

View File

@ -17,6 +17,7 @@
using namespace Doncon;
queue_t control_queue;
queue_t menu_display_queue;
queue_t drum_input_queue;
queue_t controller_input_queue;
@ -24,6 +25,8 @@ enum class ControlCommand {
SetUsbMode,
SetPlayerLed,
SetLedBrightness,
EnterMenu,
ExitMenu,
};
struct ControlMessage {
@ -49,9 +52,15 @@ void core1_task() {
Peripherals::Display display(Config::Default::display_config);
Utils::InputState input_state;
Utils::Menu::State menu_display_msg;
ControlMessage control_msg;
while (true) {
buttons.updateInputState(input_state);
queue_try_add(&controller_input_queue, &input_state.controller);
queue_try_remove(&drum_input_queue, &input_state.drum);
if (queue_try_remove(&control_queue, &control_msg)) {
switch (control_msg.command) {
case ControlCommand::SetUsbMode:
@ -66,13 +75,17 @@ void core1_task() {
case ControlCommand::SetLedBrightness:
led.setBrightness(control_msg.data.brightness);
break;
case ControlCommand::EnterMenu:
display.showMenu();
break;
case ControlCommand::ExitMenu:
display.showIdle();
break;
}
}
buttons.updateInputState(input_state);
queue_try_add(&controller_input_queue, &input_state.controller);
queue_try_remove(&drum_input_queue, &input_state.drum);
if (queue_try_remove(&menu_display_queue, &menu_display_msg)) {
display.setMenuState(menu_display_msg);
}
led.setInputState(input_state);
display.setInputState(input_state);
@ -86,6 +99,7 @@ void core1_task() {
int main() {
queue_init(&control_queue, sizeof(ControlMessage), 1);
queue_init(&menu_display_queue, sizeof(Utils::Menu::State), 1);
queue_init(&drum_input_queue, sizeof(Utils::InputState::Drum), 1);
queue_init(&controller_input_queue, sizeof(Utils::InputState::Controller), 1);
multicore_launch_core1(core1_task);
@ -125,13 +139,13 @@ int main() {
if (menu.active()) {
menu.update(input_state.controller);
if (menu.active()) {
// auto display_msg = menu.getState();
// queue_add_blocking(&menu_display_queue, &display_msg);
auto display_msg = menu.getState();
queue_add_blocking(&menu_display_queue, &display_msg);
} else {
settings_store->store();
// ControlMessage ctrl_message = {ControlCommand::ExitMenu, {}};
// queue_add_blocking(&control_queue, &ctrl_message);
ControlMessage ctrl_message = {ControlCommand::ExitMenu, {}};
queue_add_blocking(&control_queue, &ctrl_message);
}
readSettings();
@ -139,8 +153,8 @@ int main() {
} else if (input_state.checkHotkey()) {
menu.activate();
// ControlMessage ctrl_message{ControlCommand::EnterMenu, {}};
// queue_add_blocking(&control_queue, &ctrl_message);
ControlMessage ctrl_message{ControlCommand::EnterMenu, {}};
queue_add_blocking(&control_queue, &ctrl_message);
} else {
usb_driver_send_and_receive_report(input_state.getReport(mode));
}

View File

@ -176,6 +176,8 @@ void Display::setInputState(const Utils::InputState &state) { m_input_state = st
void Display::setUsbMode(usb_mode_t mode) { m_usb_mode = mode; };
void Display::setPlayerId(uint8_t player_id) { m_player_id = player_id; };
void Display::setMenuState(const Utils::Menu::State &menu_state) { m_menu_state = menu_state; }
void Display::showIdle() { m_state = State::Idle; }
void Display::showMenu() { m_state = State::Menu; }
@ -220,9 +222,77 @@ void Display::drawIdleScreen() {
if (m_input_state.drum.ka_right.triggered) {
ssd1306_bmp_show_image_with_offset(&m_display, ka_r_bmp.data(), ka_r_bmp.size(), 64 - 26, 12);
}
// Player "LEDs"
if (m_player_id != 0) {
for (uint8_t i = 0; i < 4; ++i) {
if (m_player_id & (1 << i)) {
ssd1306_draw_square(&m_display, ((127) - ((4 - i) * 6)) - 1, 2, 4, 4);
} else {
ssd1306_draw_square(&m_display, (127) - ((4 - i) * 6), 3, 2, 2);
}
}
}
// Menu hint
ssd1306_draw_line(&m_display, 0, 54, 128, 54);
ssd1306_draw_string(&m_display, 0, 56, 1, "Hold STA+SEL for Menu");
}
void Display::drawMenuScreen() {}
void Display::drawMenuScreen() {
auto descriptor_it = Utils::Menu::descriptors.find(m_menu_state.page);
if (descriptor_it == Utils::Menu::descriptors.end()) {
return;
}
// Background
switch (descriptor_it->second.type) {
case Utils::Menu::Descriptor::Type::Root:
// ssd1306_bmp_show_image(&m_display, menu_screen_top.data(), menu_screen_top.size());
break;
case Utils::Menu::Descriptor::Type::Selection:
case Utils::Menu::Descriptor::Type::Value:
// ssd1306_bmp_show_image(&m_display, menu_screen_sub.data(), menu_screen_sub.size());
break;
case Utils::Menu::Descriptor::Type::RebootInfo:
break;
}
// Heading
ssd1306_draw_string(&m_display, 0, 0, 1, descriptor_it->second.name.c_str());
// Current Selection
std::string selection;
switch (descriptor_it->second.type) {
case Utils::Menu::Descriptor::Type::Root:
case Utils::Menu::Descriptor::Type::Selection:
case Utils::Menu::Descriptor::Type::RebootInfo:
selection = descriptor_it->second.items.at(m_menu_state.selection).first;
break;
case Utils::Menu::Descriptor::Type::Value:
selection = std::to_string(m_menu_state.selection);
break;
}
ssd1306_draw_string(&m_display, (127 - (selection.length() * 12)) / 2, 15, 2, selection.c_str());
// Breadcrumbs
switch (descriptor_it->second.type) {
case Utils::Menu::Descriptor::Type::Root:
case Utils::Menu::Descriptor::Type::Selection: {
auto selection_count = descriptor_it->second.items.size();
for (uint8_t i = 0; i < selection_count; ++i) {
if (i == m_menu_state.selection) {
ssd1306_draw_square(&m_display, ((127) - ((selection_count - i) * 6)) - 1, 2, 4, 4);
} else {
ssd1306_draw_square(&m_display, (127) - ((selection_count - i) * 6), 3, 2, 2);
}
}
} break;
case Utils::Menu::Descriptor::Type::RebootInfo:
break;
case Utils::Menu::Descriptor::Type::Value:
break;
}
}
void Display::update() {
static const uint32_t interval_ms = 17; // Limit to ~60fps