diff --git a/assets/menu_screen_value.bmp b/assets/menu_screen_value.bmp index 78e3d93..02bf10e 100644 Binary files a/assets/menu_screen_value.bmp and b/assets/menu_screen_value.bmp differ diff --git a/include/GlobalConfiguration.h b/include/GlobalConfiguration.h index c539a36..6a240e0 100644 --- a/include/GlobalConfiguration.h +++ b/include/GlobalConfiguration.h @@ -20,7 +20,7 @@ struct I2c { namespace Default { -const usb_mode_t usb_mode = USB_MODE_XBOX360; +const usb_mode_t usb_mode = USB_MODE_SWITCH_TATACON; const I2c i2c_config = { 6, // SDA Pin @@ -39,10 +39,10 @@ const Peripherals::Drum::Config drum_config = { }, // Trigger thresholds { - 80, // Don Left - 50, // Ka Left - 80, // Don Right - 50, // Ka Right + 30, // Don Left + 10, // Ka Left + 30, // Don Right + 10, // Ka Right }, 16, // ADC sample count @@ -57,7 +57,7 @@ const Peripherals::Drum::Config drum_config = { 2, // SCLK Pin 1, // SCSn Pin spi0, // Block - 2000000, // Speed + 2000000, // Speed // TODO Does lowring help? }, }; @@ -103,7 +103,9 @@ const Peripherals::StatusLed::Config led_config = { 11, // LED Enable Pin, 12, // LED Pin false, // Is RGBW - 255, // Brightness + + 255, // Brightness + true, // Idle Color is DS4 light bar color }; const Peripherals::Display::Config display_config = { diff --git a/include/bitmaps/MenuScreens.h b/include/bitmaps/MenuScreens.h index f76d607..c62aedc 100644 --- a/include/bitmaps/MenuScreens.h +++ b/include/bitmaps/MenuScreens.h @@ -137,12 +137,12 @@ static const std::array menu_screen_value = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xed, 0xb1, - 0xff, 0xff, 0x8c, 0x31, 0xff, 0xff, 0xff, 0x8c, 0xda, 0xf5, 0xae, 0xff, 0xff, 0xff, 0xed, 0x2f, 0xff, 0xff, 0xb5, - 0xef, 0xff, 0xff, 0xff, 0x7b, 0x52, 0xf5, 0xae, 0xff, 0xff, 0xff, 0xed, 0x2f, 0xff, 0xff, 0xb5, 0xef, 0xff, 0xff, - 0xff, 0x7b, 0x52, 0xf5, 0xaa, 0xff, 0xff, 0xff, 0xec, 0xaf, 0xff, 0xff, 0xb4, 0x6f, 0xff, 0xff, 0xff, 0x7b, 0x4a, - 0x34, 0x6a, 0xff, 0xff, 0xff, 0xec, 0xaf, 0xff, 0xff, 0xb5, 0xef, 0xff, 0xff, 0xff, 0x7b, 0x4a, 0xf5, 0xa4, 0xff, - 0xff, 0xff, 0xed, 0xaf, 0xff, 0xff, 0xb5, 0xef, 0xff, 0xff, 0xff, 0x7b, 0x5a, 0xf5, 0xa4, 0xff, 0xff, 0xff, 0xed, - 0xb1, 0xff, 0xff, 0x8c, 0x31, 0xff, 0xff, 0xff, 0x8c, 0xda, 0x14, 0x6e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x8c, 0x31, 0xff, 0xfc, 0x6d, 0x8b, 0x7f, 0xed, 0x7b, 0xc3, 0xbf, 0xff, 0xed, 0x2f, 0xff, 0xff, 0xb5, + 0xef, 0xff, 0xfd, 0xad, 0x7b, 0x7f, 0xed, 0x7b, 0xdf, 0xbf, 0xff, 0xed, 0x2f, 0xff, 0xff, 0xb5, 0xef, 0xff, 0xfd, + 0xa1, 0x7a, 0xff, 0xe1, 0x7b, 0xdf, 0xbf, 0xff, 0xec, 0xaf, 0xff, 0xff, 0xb4, 0x6f, 0xff, 0xfc, 0x6d, 0x79, 0xff, + 0xed, 0x18, 0xdf, 0x5f, 0xff, 0xec, 0xaf, 0xff, 0xff, 0xb5, 0xef, 0xff, 0xfd, 0xad, 0x7a, 0xff, 0xed, 0x6b, 0x5e, + 0xef, 0xff, 0xed, 0xaf, 0xff, 0xff, 0xb5, 0xef, 0xff, 0xfd, 0xad, 0x7b, 0x7f, 0xed, 0x6b, 0x5e, 0xef, 0xff, 0xed, + 0xb1, 0xff, 0xff, 0x8c, 0x31, 0xff, 0xfc, 0x73, 0x8b, 0x7f, 0xf3, 0x18, 0xde, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfb, 0xdf, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xfb, 0xdf, 0xff, 0xff, 0xf6, 0x6f, 0xff, 0xff, 0xf1, 0x8f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf7, diff --git a/include/peripherals/StatusLed.h b/include/peripherals/StatusLed.h index 3a90685..a0a6744 100644 --- a/include/peripherals/StatusLed.h +++ b/include/peripherals/StatusLed.h @@ -3,6 +3,7 @@ #include "utils/InputState.h" +#include #include namespace Doncon::Peripherals { @@ -25,19 +26,24 @@ class StatusLed { uint8_t led_enable_pin; uint8_t led_pin; bool is_rgbw; + uint8_t brightness; + bool enable_player_color; }; private: Config m_config; Utils::InputState m_input_state; + std::optional m_player_color; public: StatusLed(const Config &config); - void setInputState(const Utils::InputState input_state); void setBrightness(const uint8_t brightness); + void setEnablePlayerColor(const bool do_enable); + + void setInputState(const Utils::InputState input_state); void setPlayerColor(const Config::Color color); void update(); diff --git a/include/utils/Menu.h b/include/utils/Menu.h index 386e192..719ec38 100644 --- a/include/utils/Menu.h +++ b/include/utils/Menu.h @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -17,29 +16,37 @@ class Menu { public: enum class Page { Main, + DeviceMode, - TriggerThreshold, - TriggerThresholdKaLeft, - TriggerThresholdDonLeft, - TriggerThresholdDonRight, - TriggerThresholdKaRight, - DebounceDelay, - LedBrightness, + Drum, + Led, Reset, Bootsel, + + DrumDebounceDelay, + DrumTriggerThresholdKaLeft, + DrumTriggerThresholdDonLeft, + DrumTriggerThresholdDonRight, + DrumTriggerThresholdKaRight, + + LedBrightness, + LedEnablePlayerColor, + BootselMsg, }; struct State { Page page; - uint16_t selection; + uint16_t selected_value; + uint16_t original_value; }; struct Descriptor { enum class Type { - Root, + Menu, Selection, Value, + Toggle, RebootInfo, }; @@ -48,38 +55,33 @@ class Menu { GotoParent, GotoPageDeviceMode, - GotoPageTriggerThreshold, - GotoPageTriggerThresholdKaLeft, - GotoPageTriggerThresholdDonLeft, - GotoPageTriggerThresholdDonRight, - GotoPageTriggerThresholdKaRight, - GotoPageDebounceDelay, - GotoPageLedBrightness, + GotoPageDrum, + GotoPageLed, GotoPageReset, GotoPageBootsel, - ChangeUsbModeSwitchTatacon, - ChangeUsbModeSwitchHoripad, - ChangeUsbModeDS3, - ChangeUsbModePS4Tatacon, - ChangeUsbModeDS4, - ChangeUsbModeKeyboardP1, - ChangeUsbModeKeyboardP2, - ChangeUsbModeXbox360, - ChangeUsbModeXbox360AnalogP1, - ChangeUsbModeXbox360AnalogP2, - ChangeUsbModeMidi, - ChangeUsbModeDebug, + GotoPageDrumDebounceDelay, + GotoPageDrumTriggerThresholdKaLeft, + GotoPageDrumTriggerThresholdDonLeft, + GotoPageDrumTriggerThresholdDonRight, + GotoPageDrumTriggerThresholdKaRight, + + GotoPageLedBrightness, + GotoPageLedEnablePlayerColor, + + SetUsbMode, + + SetDrumDebounceDelay, + SetDrumTriggerThresholdKaLeft, + SetDrumTriggerThresholdDonLeft, + SetDrumTriggerThresholdDonRight, + SetDrumTriggerThresholdKaRight, - SetTriggerThresholdKaLeft, - SetTriggerThresholdDonLeft, - SetTriggerThresholdDonRight, - SetTriggerThresholdKaRight, - SetDebounceDelay, SetLedBrightness, + SetLedEnablePlayerColor, - DoRebootToBootsel, DoReset, + DoRebootToBootsel, }; Type type; @@ -95,11 +97,11 @@ class Menu { bool m_active; std::stack m_state_stack; - uint16_t getCurrentSelection(Page page); + uint16_t getCurrentValue(Page page); void gotoPage(Page page); - void gotoParent(); - void performSelectionAction(Descriptor::Action action); - void performValueAction(Descriptor::Action action, uint16_t value); + void gotoParent(bool do_restore); + + void performAction(Descriptor::Action action, uint8_t value); public: Menu(std::shared_ptr settings_store); diff --git a/include/utils/SettingsStore.h b/include/utils/SettingsStore.h index 32888d4..5a888c3 100644 --- a/include/utils/SettingsStore.h +++ b/include/utils/SettingsStore.h @@ -21,10 +21,12 @@ class SettingsStore { usb_mode_t usb_mode; Peripherals::Drum::Config::Thresholds trigger_thresholds; uint8_t led_brightness; + bool led_enable_player_color; uint16_t debounce_delay; uint8_t _padding[m_store_size - sizeof(uint8_t) - sizeof(usb_mode_t) - - sizeof(Peripherals::Drum::Config::Thresholds) - sizeof(uint8_t) - sizeof(uint16_t)]; + sizeof(Peripherals::Drum::Config::Thresholds) - sizeof(uint8_t) - sizeof(bool) - + sizeof(uint16_t)]; }; static_assert(sizeof(Storecache) == m_store_size); @@ -54,6 +56,9 @@ class SettingsStore { void setLedBrightness(const uint8_t brightness); uint8_t getLedBrightness(); + void setLedEnablePlayerColor(const bool do_enable); + bool getLedEnablePlayerColor(); + void setDebounceDelay(const uint16_t delay); uint16_t getDebounceDelay(); diff --git a/src/main.cpp b/src/main.cpp index 8c154fd..7d82be2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,6 +25,7 @@ enum class ControlCommand { SetUsbMode, SetPlayerLed, SetLedBrightness, + SetLedEnablePlayerColor, EnterMenu, ExitMenu, }; @@ -35,6 +36,7 @@ struct ControlMessage { usb_mode_t usb_mode; usb_player_led_t player_led; uint8_t led_brightness; + bool led_enable_player_color; } data; }; @@ -81,6 +83,9 @@ void core1_task() { case ControlCommand::SetLedBrightness: led.setBrightness(control_msg.data.led_brightness); break; + case ControlCommand::SetLedEnablePlayerColor: + led.setEnablePlayerColor(control_msg.data.led_enable_player_color); + break; case ControlCommand::EnterMenu: display.showMenu(); break; @@ -112,7 +117,7 @@ int main() { auto settings_store = std::make_shared(); Utils::Menu menu(settings_store); - auto mode = settings_store->getUsbMode(); + const auto mode = settings_store->getUsbMode(); Peripherals::Drum drum(Config::Default::drum_config); @@ -120,13 +125,13 @@ int main() { usbd_driver_init(mode); usbd_driver_set_player_led_cb([](usb_player_led_t player_led) { - auto ctrl_message = ControlMessage{ControlCommand::SetPlayerLed, {.player_led = player_led}}; + const auto ctrl_message = ControlMessage{ControlCommand::SetPlayerLed, {.player_led = player_led}}; queue_add_blocking(&control_queue, &ctrl_message); }); stdio_init_all(); - auto readSettings = [&]() { + const auto readSettings = [&]() { ControlMessage ctrl_message; ctrl_message = {ControlCommand::SetUsbMode, {.usb_mode = mode}}; @@ -134,6 +139,9 @@ int main() { ctrl_message = {ControlCommand::SetLedBrightness, {.led_brightness = settings_store->getLedBrightness()}}; queue_add_blocking(&control_queue, &ctrl_message); + ctrl_message = {ControlCommand::SetLedEnablePlayerColor, + {.led_enable_player_color = settings_store->getLedEnablePlayerColor()}}; + queue_add_blocking(&control_queue, &ctrl_message); drum.setDebounceDelay(settings_store->getDebounceDelay()); drum.setThresholds(settings_store->getTriggerThresholds()); @@ -145,10 +153,12 @@ int main() { drum.updateInputState(input_state); queue_try_remove(&controller_input_queue, &input_state.controller); + const auto drum_message = input_state.drum; + if (menu.active()) { menu.update(input_state.controller); if (menu.active()) { - auto display_msg = menu.getState(); + const auto display_msg = menu.getState(); queue_add_blocking(&menu_display_queue, &display_msg); } else { settings_store->store(); @@ -170,8 +180,7 @@ int main() { usbd_driver_send_report(input_state.getReport(mode)); usbd_driver_task(); - // TODO don't send whole input_state - queue_try_add(&drum_input_queue, &input_state); + queue_try_add(&drum_input_queue, &drum_message); } return 0; diff --git a/src/peripherals/Display.cpp b/src/peripherals/Display.cpp index 9488f61..7f0afc4 100644 --- a/src/peripherals/Display.cpp +++ b/src/peripherals/Display.cpp @@ -93,15 +93,20 @@ void Display::drawMenuScreen() { // 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: - ssd1306_bmp_show_image(&m_display, menu_screen_sub.data(), menu_screen_value.size()); + case Utils::Menu::Descriptor::Type::Menu: + if (m_menu_state.page == Utils::Menu::Page::Main) { + ssd1306_bmp_show_image(&m_display, menu_screen_top.data(), menu_screen_top.size()); + } else { + ssd1306_bmp_show_image(&m_display, menu_screen_sub.data(), menu_screen_sub.size()); + } break; case Utils::Menu::Descriptor::Type::Value: ssd1306_bmp_show_image(&m_display, menu_screen_value.data(), menu_screen_value.size()); break; + case Utils::Menu::Descriptor::Type::Selection: + case Utils::Menu::Descriptor::Type::Toggle: + ssd1306_bmp_show_image(&m_display, menu_screen_sub.data(), menu_screen_sub.size()); + break; case Utils::Menu::Descriptor::Type::RebootInfo: break; } @@ -112,24 +117,27 @@ void Display::drawMenuScreen() { // Current Selection std::string selection; switch (descriptor_it->second.type) { - case Utils::Menu::Descriptor::Type::Root: + case Utils::Menu::Descriptor::Type::Menu: case Utils::Menu::Descriptor::Type::Selection: case Utils::Menu::Descriptor::Type::RebootInfo: - selection = descriptor_it->second.items.at(m_menu_state.selection).first; + selection = descriptor_it->second.items.at(m_menu_state.selected_value).first; break; case Utils::Menu::Descriptor::Type::Value: - selection = std::to_string(m_menu_state.selection); + selection = std::to_string(m_menu_state.selected_value); + break; + case Utils::Menu::Descriptor::Type::Toggle: + selection = m_menu_state.selected_value ? "On" : "Off"; 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::Menu: 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) { + if (i == m_menu_state.selected_value) { 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); @@ -139,6 +147,7 @@ void Display::drawMenuScreen() { case Utils::Menu::Descriptor::Type::RebootInfo: break; case Utils::Menu::Descriptor::Type::Value: + case Utils::Menu::Descriptor::Type::Toggle: break; } } diff --git a/src/peripherals/StatusLed.cpp b/src/peripherals/StatusLed.cpp index 3901eb3..baf5852 100644 --- a/src/peripherals/StatusLed.cpp +++ b/src/peripherals/StatusLed.cpp @@ -5,7 +5,7 @@ namespace Doncon::Peripherals { -StatusLed::StatusLed(const Config &config) : m_config(config) { +StatusLed::StatusLed(const Config &config) : m_config(config), m_input_state({}), m_player_color(std::nullopt) { gpio_init(m_config.led_enable_pin); gpio_set_dir(m_config.led_enable_pin, GPIO_OUT); gpio_put(m_config.led_enable_pin, 1); @@ -13,11 +13,11 @@ StatusLed::StatusLed(const Config &config) : m_config(config) { ws2812_init(config.led_pin, m_config.is_rgbw); } -void StatusLed::setInputState(const Utils::InputState input_state) { m_input_state = input_state; } - void StatusLed::setBrightness(const uint8_t brightness) { m_config.brightness = brightness; } +void StatusLed::setEnablePlayerColor(const bool do_enable) { m_config.enable_player_color = do_enable; } -void StatusLed::setPlayerColor(const Config::Color color) { m_config.idle_color = color; } +void StatusLed::setInputState(const Utils::InputState input_state) { m_input_state = input_state; } +void StatusLed::setPlayerColor(const Config::Color color) { m_player_color = color; } void StatusLed::update() { float brightness_factor = m_config.brightness / static_cast(UINT8_MAX); @@ -28,6 +28,7 @@ void StatusLed::update() { uint8_t num_colors = 0; + // TODO simply use max of each channel if (m_input_state.drum.don_left.triggered) { mixed_red += m_config.don_left_color.r; mixed_green += m_config.don_left_color.g; @@ -59,10 +60,13 @@ void StatusLed::update() { static_cast((mixed_green / num_colors) * brightness_factor), static_cast((mixed_blue / num_colors) * brightness_factor))); } else { + const auto idle_color = + m_config.enable_player_color ? m_player_color.value_or(m_config.idle_color) : m_config.idle_color; + ws2812_put_pixel( - ws2812_rgb_to_gamma_corrected_u32pixel(static_cast((m_config.idle_color.r) * brightness_factor), - static_cast((m_config.idle_color.g) * brightness_factor), - static_cast((m_config.idle_color.b) * brightness_factor))); + ws2812_rgb_to_gamma_corrected_u32pixel(static_cast((idle_color.r) * brightness_factor), + static_cast((idle_color.g) * brightness_factor), + static_cast((idle_color.b) * brightness_factor))); } } diff --git a/src/utils/Menu.cpp b/src/utils/Menu.cpp index 36849fa..569057d 100644 --- a/src/utils/Menu.cpp +++ b/src/utils/Menu.cpp @@ -3,72 +3,79 @@ namespace Doncon::Utils { const std::map Menu::descriptors = { - {Menu::Page::Main, // - {Menu::Descriptor::Type::Root, // - "Settings", // - {{"Mode", Menu::Descriptor::Action::GotoPageDeviceMode}, // - {"Brightness", Menu::Descriptor::Action::GotoPageLedBrightness}, // - {"Sensitvty", Menu::Descriptor::Action::GotoPageTriggerThreshold}, // - {"Hold Time", Menu::Descriptor::Action::GotoPageDebounceDelay}, // - {"Reset", Menu::Descriptor::Action::GotoPageReset}, // - {"USB Flash", Menu::Descriptor::Action::GotoPageBootsel}}, // - 0}}, // + {Menu::Page::Main, // + {Menu::Descriptor::Type::Menu, // + "Settings", // + {{"Mode", Menu::Descriptor::Action::GotoPageDeviceMode}, // + {"Drum", Menu::Descriptor::Action::GotoPageDrum}, // + {"Led", Menu::Descriptor::Action::GotoPageLed}, // + {"Reset", Menu::Descriptor::Action::GotoPageReset}, // + {"USB Flash", Menu::Descriptor::Action::GotoPageBootsel}}, // + 0}}, // - {Menu::Page::DeviceMode, // - {Menu::Descriptor::Type::Selection, // - "Mode", // - {{"Swtch Tata", Menu::Descriptor::Action::ChangeUsbModeSwitchTatacon}, // - {"Swtch Pro", Menu::Descriptor::Action::ChangeUsbModeSwitchHoripad}, // - {"Dualshock3", Menu::Descriptor::Action::ChangeUsbModeDS3}, // - {"PS4 Tata", Menu::Descriptor::Action::ChangeUsbModePS4Tatacon}, // - {"Dualshock4", Menu::Descriptor::Action::ChangeUsbModeDS4}, // - {"Keybrd P1", Menu::Descriptor::Action::ChangeUsbModeKeyboardP1}, // - {"Keybrd P2", Menu::Descriptor::Action::ChangeUsbModeKeyboardP2}, // - {"Xbox 360", Menu::Descriptor::Action::ChangeUsbModeXbox360}, // - {"Analog P1", Menu::Descriptor::Action::ChangeUsbModeXbox360AnalogP1}, // - {"Analog P2", Menu::Descriptor::Action::ChangeUsbModeXbox360AnalogP2}, // - {"MIDI", Menu::Descriptor::Action::ChangeUsbModeMidi}, // - {"Debug", Menu::Descriptor::Action::ChangeUsbModeDebug}}, // - 0}}, // + {Menu::Page::DeviceMode, // + {Menu::Descriptor::Type::Selection, // + "Mode", // + {{"Swtch Tata", Menu::Descriptor::Action::SetUsbMode}, // + {"Swtch Pro", Menu::Descriptor::Action::SetUsbMode}, // + {"Dualshock3", Menu::Descriptor::Action::SetUsbMode}, // + {"PS4 Tata", Menu::Descriptor::Action::SetUsbMode}, // + {"Dualshock4", Menu::Descriptor::Action::SetUsbMode}, // + {"Keybrd P1", Menu::Descriptor::Action::SetUsbMode}, // + {"Keybrd P2", Menu::Descriptor::Action::SetUsbMode}, // + {"Xbox 360", Menu::Descriptor::Action::SetUsbMode}, // + {"Analog P1", Menu::Descriptor::Action::SetUsbMode}, // + {"Analog P2", Menu::Descriptor::Action::SetUsbMode}, // + {"MIDI", Menu::Descriptor::Action::SetUsbMode}, // + {"Debug", Menu::Descriptor::Action::SetUsbMode}}, // + 0}}, // - {Menu::Page::TriggerThreshold, // - {Menu::Descriptor::Type::Selection, // - "Sensitivity", // - {{"Ka Left", Menu::Descriptor::Action::GotoPageTriggerThresholdKaLeft}, // - {"Don Left", Menu::Descriptor::Action::GotoPageTriggerThresholdDonLeft}, // - {"Don Right", Menu::Descriptor::Action::GotoPageTriggerThresholdDonRight}, // - {"Ka Right", Menu::Descriptor::Action::GotoPageTriggerThresholdKaRight}}, // - 0}}, // + {Menu::Page::Drum, // + {Menu::Descriptor::Type::Menu, // + "Drum Settings", // + {{"Hold Time", Menu::Descriptor::Action::GotoPageDrumDebounceDelay}, // + {"Left Ka", Menu::Descriptor::Action::GotoPageDrumTriggerThresholdKaLeft}, // + {"Left Don", Menu::Descriptor::Action::GotoPageDrumTriggerThresholdDonLeft}, // + {"Right Don", Menu::Descriptor::Action::GotoPageDrumTriggerThresholdDonRight}, // + {"Right Ka", Menu::Descriptor::Action::GotoPageDrumTriggerThresholdKaRight}}, // + 0}}, // - {Menu::Page::TriggerThresholdKaLeft, // - {Menu::Descriptor::Type::Value, // - "Trg Level Ka Left", // - {{"", Menu::Descriptor::Action::SetTriggerThresholdKaLeft}}, // + {Menu::Page::DrumDebounceDelay, // + {Menu::Descriptor::Type::Value, // + "Hit Hold Time (ms)", // + {{"", Menu::Descriptor::Action::SetDrumDebounceDelay}}, // + UINT8_MAX}}, + + {Menu::Page::DrumTriggerThresholdKaLeft, // + {Menu::Descriptor::Type::Value, // + "Trg Level Left Ka", // + {{"", Menu::Descriptor::Action::SetDrumTriggerThresholdKaLeft}}, // 4095}}, - {Menu::Page::TriggerThresholdDonLeft, // - {Menu::Descriptor::Type::Value, // - "Trg Level Don Left", // - {{"", Menu::Descriptor::Action::SetTriggerThresholdDonLeft}}, // + {Menu::Page::DrumTriggerThresholdDonLeft, // + {Menu::Descriptor::Type::Value, // + "Trg Level Left Don", // + {{"", Menu::Descriptor::Action::SetDrumTriggerThresholdDonLeft}}, // 4095}}, - {Menu::Page::TriggerThresholdDonRight, // - {Menu::Descriptor::Type::Value, // - "Trg Level Don Right", // - {{"", Menu::Descriptor::Action::SetTriggerThresholdDonRight}}, // + {Menu::Page::DrumTriggerThresholdDonRight, // + {Menu::Descriptor::Type::Value, // + "Trg Level Right Don", // + {{"", Menu::Descriptor::Action::SetDrumTriggerThresholdDonRight}}, // 4095}}, - {Menu::Page::TriggerThresholdKaRight, // - {Menu::Descriptor::Type::Value, // - "Trg Level Ka Right", // - {{"", Menu::Descriptor::Action::SetTriggerThresholdKaRight}}, // + {Menu::Page::DrumTriggerThresholdKaRight, // + {Menu::Descriptor::Type::Value, // + "Trg Level Right Ka", // + {{"", Menu::Descriptor::Action::SetDrumTriggerThresholdKaRight}}, // 4095}}, - {Menu::Page::DebounceDelay, // - {Menu::Descriptor::Type::Value, // - "Hit Hold Time (ms)", // - {{"", Menu::Descriptor::Action::SetDebounceDelay}}, // - 255}}, + {Menu::Page::Led, // + {Menu::Descriptor::Type::Menu, // + "LED Settings", // + {{"Brightness", Menu::Descriptor::Action::GotoPageLedBrightness}, // + {"Plyr Color", Menu::Descriptor::Action::GotoPageLedEnablePlayerColor}}, // + 0}}, // {Menu::Page::LedBrightness, // {Menu::Descriptor::Type::Value, // @@ -76,15 +83,21 @@ const std::map Menu::descriptors = { {{"", Menu::Descriptor::Action::SetLedBrightness}}, // UINT8_MAX}}, // + {Menu::Page::LedEnablePlayerColor, // + {Menu::Descriptor::Type::Toggle, // + "Player Color (PS4)", // + {{"", Menu::Descriptor::Action::SetLedEnablePlayerColor}}, // + 0}}, // + {Menu::Page::Reset, // - {Menu::Descriptor::Type::Selection, // + {Menu::Descriptor::Type::Menu, // "Reset all Settings?", // {{"No", Menu::Descriptor::Action::GotoParent}, // {"Yes", Menu::Descriptor::Action::DoReset}}, // 0}}, // {Menu::Page::Bootsel, // - {Menu::Descriptor::Type::Selection, // + {Menu::Descriptor::Type::Menu, // "Reboot to Flash Mode", // {{"Reboot?", Menu::Descriptor::Action::DoRebootToBootsel}}, // 0}}, // @@ -97,10 +110,10 @@ const std::map Menu::descriptors = { }; Menu::Menu(std::shared_ptr settings_store) - : m_store(settings_store), m_active(false), m_state_stack({{Page::Main, 0}}) {}; + : m_store(settings_store), m_active(false), m_state_stack({{Page::Main, 0, 0}}) {}; void Menu::activate() { - m_state_stack = std::stack({{Page::Main, 0}}); + m_state_stack = std::stack({{Page::Main, 0, 0}}); m_active = true; } @@ -181,31 +194,27 @@ static InputState::Controller checkPressed(const InputState::Controller &control return result; } -uint16_t Menu::getCurrentSelection(Menu::Page page) { +uint16_t Menu::getCurrentValue(Menu::Page page) { switch (page) { case Page::DeviceMode: return static_cast(m_store->getUsbMode()); - break; - case Page::TriggerThresholdKaLeft: - return m_store->getTriggerThresholds().ka_left; - break; - case Page::TriggerThresholdDonLeft: - return m_store->getTriggerThresholds().don_left; - break; - case Page::TriggerThresholdDonRight: - return m_store->getTriggerThresholds().don_right; - break; - case Page::TriggerThresholdKaRight: - return m_store->getTriggerThresholds().ka_right; - break; - case Page::DebounceDelay: + case Page::DrumDebounceDelay: return m_store->getDebounceDelay(); - break; + case Page::DrumTriggerThresholdKaLeft: + return m_store->getTriggerThresholds().ka_left; + case Page::DrumTriggerThresholdDonLeft: + return m_store->getTriggerThresholds().don_left; + case Page::DrumTriggerThresholdDonRight: + return m_store->getTriggerThresholds().don_right; + case Page::DrumTriggerThresholdKaRight: + return m_store->getTriggerThresholds().ka_right; case Page::LedBrightness: return m_store->getLedBrightness(); - break; + case Page::LedEnablePlayerColor: + return static_cast(m_store->getLedEnablePlayerColor()); case Page::Main: - case Page::TriggerThreshold: + case Page::Drum: + case Page::Led: case Page::Reset: case Page::Bootsel: case Page::BootselMsg: @@ -215,41 +224,85 @@ uint16_t Menu::getCurrentSelection(Menu::Page page) { return 0; } -void Menu::gotoPage(Menu::Page page) { m_state_stack.push({page, getCurrentSelection(page)}); } +void Menu::gotoPage(Menu::Page page) { + const auto current_value = getCurrentValue(page); -void Menu::gotoParent() { m_state_stack.pop(); } + m_state_stack.push({page, current_value, current_value}); +} -void Menu::performSelectionAction(Menu::Descriptor::Action action) { - auto descriptor_it = descriptors.find(m_state_stack.top().page); - if (descriptor_it == descriptors.end()) { - assert(false); - return; +void Menu::gotoParent(bool do_restore) { + const auto current_state = m_state_stack.top(); + + if (current_state.page == Page::Main) { + m_active = false; } + if (do_restore) { + switch (current_state.page) { + case Page::DeviceMode: + m_store->setUsbMode(static_cast(current_state.original_value)); + break; + case Page::DrumDebounceDelay: + m_store->setDebounceDelay(current_state.original_value); + break; + case Page::DrumTriggerThresholdKaLeft: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.ka_left = current_state.original_value; + m_store->setTriggerThresholds(thresholds); + } break; + case Page::DrumTriggerThresholdDonLeft: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.don_left = current_state.original_value; + m_store->setTriggerThresholds(thresholds); + } break; + case Page::DrumTriggerThresholdDonRight: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.don_right = current_state.original_value; + m_store->setTriggerThresholds(thresholds); + } break; + case Page::DrumTriggerThresholdKaRight: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.ka_right = current_state.original_value; + m_store->setTriggerThresholds(thresholds); + } break; + case Page::LedBrightness: + m_store->setLedBrightness(current_state.original_value); + break; + case Page::LedEnablePlayerColor: + m_store->setLedEnablePlayerColor(static_cast(current_state.original_value)); + break; + case Page::Main: + case Page::Drum: + case Page::Led: + case Page::Reset: + case Page::Bootsel: + case Page::BootselMsg: + break; + } + } + + m_state_stack.pop(); +} + +void Menu::performAction(Descriptor::Action action, uint8_t value) { switch (action) { + case Descriptor::Action::None: + break; + case Descriptor::Action::GotoParent: + gotoParent(false); + break; case Descriptor::Action::GotoPageDeviceMode: gotoPage(Page::DeviceMode); break; - case Descriptor::Action::GotoPageTriggerThreshold: - gotoPage(Page::TriggerThreshold); + case Descriptor::Action::GotoPageDrum: + gotoPage(Page::Drum); break; - case Descriptor::Action::GotoPageTriggerThresholdKaLeft: - gotoPage(Page::TriggerThresholdKaLeft); - break; - case Descriptor::Action::GotoPageTriggerThresholdDonLeft: - gotoPage(Page::TriggerThresholdDonLeft); - break; - case Descriptor::Action::GotoPageTriggerThresholdDonRight: - gotoPage(Page::TriggerThresholdDonRight); - break; - case Descriptor::Action::GotoPageTriggerThresholdKaRight: - gotoPage(Page::TriggerThresholdKaRight); - break; - case Descriptor::Action::GotoPageLedBrightness: - gotoPage(Page::LedBrightness); - break; - case Descriptor::Action::GotoPageDebounceDelay: - gotoPage(Page::DebounceDelay); + case Descriptor::Action::GotoPageLed: + gotoPage(Page::Led); break; case Descriptor::Action::GotoPageReset: gotoPage(Page::Reset); @@ -257,65 +310,62 @@ void Menu::performSelectionAction(Menu::Descriptor::Action action) { case Descriptor::Action::GotoPageBootsel: gotoPage(Page::Bootsel); break; - case Descriptor::Action::ChangeUsbModeSwitchTatacon: - m_store->setUsbMode(USB_MODE_SWITCH_TATACON); - gotoParent(); + case Descriptor::Action::GotoPageDrumDebounceDelay: + gotoPage(Page::DrumDebounceDelay); break; - case Descriptor::Action::ChangeUsbModeSwitchHoripad: - m_store->setUsbMode(USB_MODE_SWITCH_HORIPAD); - gotoParent(); + case Descriptor::Action::GotoPageDrumTriggerThresholdKaLeft: + gotoPage(Page::DrumTriggerThresholdKaLeft); break; - case Descriptor::Action::ChangeUsbModeDS3: - m_store->setUsbMode(USB_MODE_DUALSHOCK3); - gotoParent(); + case Descriptor::Action::GotoPageDrumTriggerThresholdDonLeft: + gotoPage(Page::DrumTriggerThresholdDonLeft); break; - case Descriptor::Action::ChangeUsbModePS4Tatacon: - m_store->setUsbMode(USB_MODE_PS4_TATACON); - gotoParent(); + case Descriptor::Action::GotoPageDrumTriggerThresholdDonRight: + gotoPage(Page::DrumTriggerThresholdDonRight); break; - case Descriptor::Action::ChangeUsbModeDS4: - m_store->setUsbMode(USB_MODE_DUALSHOCK4); - gotoParent(); + case Descriptor::Action::GotoPageDrumTriggerThresholdKaRight: + gotoPage(Page::DrumTriggerThresholdKaRight); break; - case Descriptor::Action::ChangeUsbModeKeyboardP1: - m_store->setUsbMode(USB_MODE_KEYBOARD_P1); - gotoParent(); + case Descriptor::Action::GotoPageLedBrightness: + gotoPage(Page::LedBrightness); break; - case Descriptor::Action::ChangeUsbModeKeyboardP2: - m_store->setUsbMode(USB_MODE_KEYBOARD_P2); - gotoParent(); + case Descriptor::Action::GotoPageLedEnablePlayerColor: + gotoPage(Page::LedEnablePlayerColor); break; - case Descriptor::Action::ChangeUsbModeXbox360: - m_store->setUsbMode(USB_MODE_XBOX360); - gotoParent(); + case Descriptor::Action::SetUsbMode: + m_store->setUsbMode(static_cast(value)); break; - case Descriptor::Action::ChangeUsbModeXbox360AnalogP1: - m_store->setUsbMode(USB_MODE_XBOX360_ANALOG_P1); - gotoParent(); - break; - case Descriptor::Action::ChangeUsbModeXbox360AnalogP2: - m_store->setUsbMode(USB_MODE_XBOX360_ANALOG_P2); - gotoParent(); - break; - case Descriptor::Action::ChangeUsbModeMidi: - m_store->setUsbMode(USB_MODE_MIDI); - gotoParent(); - break; - case Descriptor::Action::ChangeUsbModeDebug: - m_store->setUsbMode(USB_MODE_DEBUG); - gotoParent(); - break; - case Descriptor::Action::SetTriggerThresholdKaLeft: - case Descriptor::Action::SetTriggerThresholdDonLeft: - case Descriptor::Action::SetTriggerThresholdDonRight: - case Descriptor::Action::SetTriggerThresholdKaRight: - gotoParent(); - break; - case Descriptor::Action::SetDebounceDelay: - gotoParent(); + case Descriptor::Action::SetDrumDebounceDelay: + m_store->setDebounceDelay(value); break; + case Descriptor::Action::SetDrumTriggerThresholdKaLeft: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.ka_left = value; + m_store->setTriggerThresholds(thresholds); + } break; + case Descriptor::Action::SetDrumTriggerThresholdDonLeft: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.don_left = value; + m_store->setTriggerThresholds(thresholds); + } break; + case Descriptor::Action::SetDrumTriggerThresholdDonRight: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.don_right = value; + m_store->setTriggerThresholds(thresholds); + } break; + case Descriptor::Action::SetDrumTriggerThresholdKaRight: { + auto thresholds = m_store->getTriggerThresholds(); + + thresholds.ka_right = value; + m_store->setTriggerThresholds(thresholds); + } break; case Descriptor::Action::SetLedBrightness: - gotoParent(); + m_store->setLedBrightness(value); + break; + case Descriptor::Action::SetLedEnablePlayerColor: + m_store->setLedEnablePlayerColor(static_cast(value)); break; case Descriptor::Action::DoReset: m_store->reset(); @@ -324,51 +374,9 @@ void Menu::performSelectionAction(Menu::Descriptor::Action action) { m_store->scheduleReboot(true); gotoPage(Page::BootselMsg); break; - case Descriptor::Action::GotoParent: - gotoParent(); - break; - case Descriptor::Action::None: - break; - } -} - -void Menu::performValueAction(Menu::Descriptor::Action action, uint16_t value) { - auto descriptor_it = descriptors.find(m_state_stack.top().page); - if (descriptor_it == descriptors.end()) { - assert(false); - return; } - switch (action) { - case Descriptor::Action::SetTriggerThresholdKaLeft: { - auto thresholds = m_store->getTriggerThresholds(); - thresholds.ka_left = value; - m_store->setTriggerThresholds(thresholds); - } break; - case Descriptor::Action::SetTriggerThresholdDonLeft: { - auto thresholds = m_store->getTriggerThresholds(); - thresholds.don_left = value; - m_store->setTriggerThresholds(thresholds); - } break; - case Descriptor::Action::SetTriggerThresholdDonRight: { - auto thresholds = m_store->getTriggerThresholds(); - thresholds.don_right = value; - m_store->setTriggerThresholds(thresholds); - } break; - case Descriptor::Action::SetTriggerThresholdKaRight: { - auto thresholds = m_store->getTriggerThresholds(); - thresholds.ka_right = value; - m_store->setTriggerThresholds(thresholds); - } break; - case Descriptor::Action::SetDebounceDelay: - m_store->setDebounceDelay(value); - break; - case Descriptor::Action::SetLedBrightness: - m_store->setLedBrightness(value); - break; - default: - break; - } + return; } void Menu::update(const InputState::Controller &controller_state) { @@ -386,13 +394,22 @@ void Menu::update(const InputState::Controller &controller_state) { } else if (pressed.dpad.left) { switch (descriptor_it->second.type) { case Descriptor::Type::Value: + case Descriptor::Type::Toggle: break; case Descriptor::Type::Selection: - case Descriptor::Type::Root: - if (current_state.selection == 0) { - current_state.selection = descriptor_it->second.items.size() - 1; + if (current_state.selected_value == 0) { + current_state.selected_value = descriptor_it->second.items.size() - 1; } else { - current_state.selection--; + current_state.selected_value--; + } + performAction(descriptor_it->second.items.at(current_state.selected_value).second, + current_state.selected_value); + break; + case Descriptor::Type::Menu: + if (current_state.selected_value == 0) { + current_state.selected_value = descriptor_it->second.items.size() - 1; + } else { + current_state.selected_value--; } break; case Descriptor::Type::RebootInfo: @@ -401,13 +418,22 @@ void Menu::update(const InputState::Controller &controller_state) { } else if (pressed.dpad.right) { switch (descriptor_it->second.type) { case Descriptor::Type::Value: + case Descriptor::Type::Toggle: break; case Descriptor::Type::Selection: - case Descriptor::Type::Root: - if (current_state.selection == descriptor_it->second.items.size() - 1) { - current_state.selection = 0; + if (current_state.selected_value == descriptor_it->second.items.size() - 1) { + current_state.selected_value = 0; } else { - current_state.selection++; + current_state.selected_value++; + } + performAction(descriptor_it->second.items.at(current_state.selected_value).second, + current_state.selected_value); + break; + case Descriptor::Type::Menu: + if (current_state.selected_value == descriptor_it->second.items.size() - 1) { + current_state.selected_value = 0; + } else { + current_state.selected_value++; } break; case Descriptor::Type::RebootInfo: @@ -416,49 +442,60 @@ void Menu::update(const InputState::Controller &controller_state) { } else if (pressed.dpad.up) { switch (descriptor_it->second.type) { case Descriptor::Type::Value: - if (current_state.selection < descriptor_it->second.max_value) { - current_state.selection++; - performValueAction(descriptor_it->second.items.at(0).second, current_state.selection); + if (current_state.selected_value < UINT8_MAX) { + current_state.selected_value++; + performAction(descriptor_it->second.items.at(0).second, current_state.selected_value); } break; + case Descriptor::Type::Toggle: + current_state.selected_value = !current_state.selected_value; + performAction(descriptor_it->second.items.at(0).second, current_state.selected_value); + break; case Descriptor::Type::Selection: - case Descriptor::Type::Root: + case Descriptor::Type::Menu: case Descriptor::Type::RebootInfo: break; } } else if (pressed.dpad.down) { switch (descriptor_it->second.type) { case Descriptor::Type::Value: - if (current_state.selection > 0) { - current_state.selection--; - performValueAction(descriptor_it->second.items.at(0).second, current_state.selection); + if (current_state.selected_value > 0) { + current_state.selected_value--; + performAction(descriptor_it->second.items.at(0).second, current_state.selected_value); } break; + case Descriptor::Type::Toggle: + current_state.selected_value = !current_state.selected_value; + performAction(descriptor_it->second.items.at(0).second, current_state.selected_value); + break; case Descriptor::Type::Selection: - case Descriptor::Type::Root: + case Descriptor::Type::Menu: case Descriptor::Type::RebootInfo: break; } - } else if (pressed.buttons.south) { + } else if (pressed.buttons.south) { // Back/Exit switch (descriptor_it->second.type) { case Descriptor::Type::Value: + case Descriptor::Type::Toggle: case Descriptor::Type::Selection: - gotoParent(); + gotoParent(true); break; - case Descriptor::Type::Root: - m_active = false; + case Descriptor::Type::Menu: + gotoParent(false); break; case Descriptor::Type::RebootInfo: break; } - } else if (pressed.buttons.east) { + } else if (pressed.buttons.east) { // Select switch (descriptor_it->second.type) { case Descriptor::Type::Value: - performSelectionAction(descriptor_it->second.items.at(0).second); - break; + case Descriptor::Type::Toggle: case Descriptor::Type::Selection: - case Descriptor::Type::Root: - performSelectionAction(descriptor_it->second.items.at(current_state.selection).second); + gotoParent(false); + break; + case Descriptor::Type::Menu: + performAction(descriptor_it->second.items.at(current_state.selected_value).second, + current_state.selected_value); break; case Descriptor::Type::RebootInfo: break; diff --git a/src/utils/SettingsStore.cpp b/src/utils/SettingsStore.cpp index 6e88f6b..bfdb7ef 100644 --- a/src/utils/SettingsStore.cpp +++ b/src/utils/SettingsStore.cpp @@ -15,6 +15,7 @@ SettingsStore::SettingsStore() Config::Default::usb_mode, Config::Default::drum_config.trigger_thresholds, Config::Default::led_config.brightness, + Config::Default::led_config.enable_player_color, Config::Default::drum_config.debounce_delay_ms, {}}), m_dirty(true), m_scheduled_reboot(RebootType::None) { @@ -66,6 +67,14 @@ void SettingsStore::setLedBrightness(const uint8_t brightness) { } uint8_t SettingsStore::getLedBrightness() { return m_store_cache.led_brightness; } +void SettingsStore::setLedEnablePlayerColor(const bool do_enable) { + if (m_store_cache.led_enable_player_color != do_enable) { + m_store_cache.led_enable_player_color = do_enable; + m_dirty = true; + } +} +bool SettingsStore::getLedEnablePlayerColor() { return m_store_cache.led_enable_player_color; } + void SettingsStore::setDebounceDelay(const uint16_t delay) { if (m_store_cache.debounce_delay != delay) { m_store_cache.debounce_delay = delay;