Skip to content

Commit

Permalink
Mostly implemented menu navigation, config change storage, and reboot…
Browse files Browse the repository at this point in the history
… events
  • Loading branch information
mikepparks committed Jan 8, 2025
1 parent c199b9e commit 582bbe5
Show file tree
Hide file tree
Showing 20 changed files with 452 additions and 95 deletions.
1 change: 1 addition & 0 deletions headers/addons/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class DisplayAddon : public GPAddon
virtual std::string name() { return DisplayName; }

void handleSystemRestart(GPEvent* e);
void handleMenuNavigation(GPEvent* e);
private:
bool updateDisplayScreen();
void drawStatusBar(Gamepad*);
Expand Down
4 changes: 4 additions & 0 deletions headers/display/ui/elements/GPWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class GPWidget : public GPGFX_UI {

double getScaleX() { return ((double)(this->getViewport().right - this->getViewport().left) / (double)(getRenderer()->getDriver()->getMetrics()->width)); }
double getScaleY() { return ((double)(this->getViewport().bottom - this->getViewport().top) / (double)(getRenderer()->getDriver()->getMetrics()->height)); }

void setVisibility(bool visible) { this->_visibility = visible; }
bool getVisibility() { return this->_visibility; }
protected:
uint16_t x = 0;
uint16_t y = 0;
Expand All @@ -36,6 +39,7 @@ class GPWidget : public GPGFX_UI {
uint16_t fillColor = 0;
uint16_t _ID;
uint16_t _priority = 0;
bool _visibility = true;

GPViewport _viewport;
};
Expand Down
26 changes: 23 additions & 3 deletions headers/display/ui/screens/MainMenuScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "GPGFX_UI_types.h"
#include "enums.pb.h"
#include "AnimationStation.hpp"
#include "eventmanager.h"

#define INPUT_MODE_XINPUT_NAME "XInput"
#define INPUT_MODE_SWITCH_NAME "Nintendo Switch"
Expand Down Expand Up @@ -65,6 +66,8 @@ class MainMenuScreen : public GPScreen {

void selectTurboMode();
int32_t currentTurboMode();

void updateMenuNavigation(GpioAction action);
protected:
virtual void drawScreen();
private:
Expand All @@ -77,6 +80,10 @@ class MainMenuScreen : public GPScreen {
Mask_t prevValues;
GPMenu* gpMenu;

bool screenIsPrompting = false;
bool promptChoice = false;

int8_t exitToScreenBeforePrompt = -1;
int8_t exitToScreen = -1;

GamepadButtonMapping *mapMenuUp;
Expand All @@ -88,7 +95,8 @@ class MainMenuScreen : public GPScreen {
GamepadButtonMapping *mapMenuToggle;

void saveOptions();
void updateMenuNavigation(GpioAction action);
bool changeRequiresReboot = false;
bool changeRequiresSave = false;

#define INPUT_MODE_ENTRIES(name, value) {name##_NAME, NULL, nullptr, std::bind(&MainMenuScreen::currentInputMode, this), std::bind(&MainMenuScreen::selectInputMode, this), value},
#define DPAD_MODE_ENTRIES(name, value) {name##_NAME, NULL, nullptr, std::bind(&MainMenuScreen::currentDpadMode, this), std::bind(&MainMenuScreen::selectDPadMode, this), value},
Expand All @@ -97,26 +105,38 @@ class MainMenuScreen : public GPScreen {
std::vector<MenuEntry> inputModeMenu = {
InputMode_VALUELIST(INPUT_MODE_ENTRIES)
};
InputMode prevInputMode;
InputMode updateInputMode;

std::vector<MenuEntry> dpadModeMenu = {
DpadMode_VALUELIST(DPAD_MODE_ENTRIES)
};
DpadMode prevDpadMode;
DpadMode updateDpadMode;

std::vector<MenuEntry> socdModeMenu = {
SOCDMode_VALUELIST(SOCD_MODE_ENTRIES)
};
SOCDMode prevSocdMode;
SOCDMode updateSocdMode;

std::vector<MenuEntry> profilesMenu = {};
uint8_t prevProfile;
uint8_t updateProfile;

std::vector<MenuEntry> focusModeMenu = {
{"On", NULL, nullptr, std::bind(&MainMenuScreen::currentFocusMode, this), std::bind(&MainMenuScreen::selectFocusMode, this), 1},
{"Off", NULL, nullptr, std::bind(&MainMenuScreen::currentFocusMode, this), std::bind(&MainMenuScreen::selectFocusMode, this), 0},
{"On", NULL, nullptr, std::bind(&MainMenuScreen::currentFocusMode, this), std::bind(&MainMenuScreen::selectFocusMode, this), 1},
};
bool prevFocus;
bool updateFocus;

std::vector<MenuEntry> turboModeMenu = {
{"On", NULL, nullptr, std::bind(&MainMenuScreen::currentTurboMode, this), std::bind(&MainMenuScreen::selectTurboMode, this), 1},
{"Off", NULL, nullptr, std::bind(&MainMenuScreen::currentTurboMode, this), std::bind(&MainMenuScreen::selectTurboMode, this), 0},
{"On", NULL, nullptr, std::bind(&MainMenuScreen::currentTurboMode, this), std::bind(&MainMenuScreen::selectTurboMode, this), 1},
};
bool prevTurbo;
bool updateTurbo;

std::vector<MenuEntry> mainMenu = {
{"Input Mode", NULL, &inputModeMenu, std::bind(&MainMenuScreen::modeValue, this), std::bind(&MainMenuScreen::testMenu, this)},
Expand Down
6 changes: 6 additions & 0 deletions headers/eventmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
#include "GPEvent.h"
#include "GPGamepadEvent.h"
#include "GPEncoderEvent.h"
#include "GPMenuNavigateEvent.h"
#include "GPProfileEvent.h"
#include "GPRestartEvent.h"
#include "GPStorageSaveEvent.h"
#include "GPSystemRebootEvent.h"
#include "GPUSBHostEvent.h"

#define EVENTMGR EventManager::getInstance()
Expand All @@ -33,6 +36,9 @@ class EventManager {
return instance;
}

void init();
void clearEventHandlers();

void registerEventHandler(GPEventType eventType, EventFunction handler);
void triggerEvent(GPEvent* event);
private:
Expand Down
21 changes: 21 additions & 0 deletions headers/events/GPMenuNavigateEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef _GPMENUNAVIGATEEVENT_H_
#define _GPMENUNAVIGATEEVENT_H_

#include "system.h"

class GPMenuNavigateEvent : public GPEvent {
public:
GPMenuNavigateEvent() {}
GPMenuNavigateEvent(GpioAction action) {
this->menuAction = action;
}
~GPMenuNavigateEvent() {}

GPEventType eventType() { return this->_eventType; }

GpioAction menuAction;
private:
GPEventType _eventType = GP_EVENT_MENU_NAVIGATE;
};

#endif
23 changes: 23 additions & 0 deletions headers/events/GPStorageSaveEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef _GPSTORAGESAVEEVENT_H_
#define _GPSTORAGESAVEEVENT_H_

#include "system.h"

class GPStorageSaveEvent : public GPEvent {
public:
GPStorageSaveEvent() {}
GPStorageSaveEvent(bool force, bool restart = false) {
this->forceSave = force;
this->restartAfterSave = restart;
}
~GPStorageSaveEvent() {}

GPEventType eventType() { return this->_eventType; }

bool forceSave = false;
bool restartAfterSave = false;
private:
GPEventType _eventType = GP_EVENT_STORAGE_SAVE;
};

#endif
21 changes: 21 additions & 0 deletions headers/events/GPSystemRebootEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef _GPSYSTEMREBOOTEVENT_H_
#define _GPSYSTEMREBOOTEVENT_H_

#include "system.h"

class GPSystemRebootEvent : public GPEvent {
public:
GPSystemRebootEvent() {}
GPSystemRebootEvent(System::BootMode mode) {
this->bootMode = mode;
}
~GPSystemRebootEvent() {}

GPEventType eventType() { return this->_eventType; }

System::BootMode bootMode = System::BootMode::DEFAULT;
private:
GPEventType _eventType = GP_EVENT_SYSTEM_REBOOT;
};

#endif
8 changes: 8 additions & 0 deletions headers/gp2040.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// GP2040 Classes
#include "gamepad.h"
#include "addonmanager.h"
#include "eventmanager.h"
#include "gpdriver.h"

#include "pico/types.h"
Expand Down Expand Up @@ -75,6 +76,13 @@ class GP2040 {

// input mask, action
std::map<uint32_t, int32_t> bootActions;

bool saveRequested = false;
bool saveSuccessful = false;
void handleStorageSave(GPEvent* e);

bool rebootRequested = false;
void handleSystemReboot(GPEvent* e);
};

#endif
2 changes: 2 additions & 0 deletions headers/storagemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "config.pb.h"
#include <atomic>
#include "pico/critical_section.h"
#include "eventmanager.h"
#include "GPStorageSaveEvent.h"

#define SI Storage::getInstance()

Expand Down
10 changes: 10 additions & 0 deletions proto/enums.proto
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,13 @@ enum GamepadHotkey
HOTKEY_DPAD_RIGHT = 41;
HOTKEY_PREVIOUS_PROFILE = 42;
HOTKEY_SAVE_CONFIG = 43;
HOTKEY_MENU_NAV_UP = 44;
HOTKEY_MENU_NAV_DOWN = 45;
HOTKEY_MENU_NAV_LEFT = 46;
HOTKEY_MENU_NAV_RIGHT = 47;
HOTKEY_MENU_NAV_SELECT = 48;
HOTKEY_MENU_NAV_BACK = 49;
HOTKEY_MENU_NAV_TOGGLE = 50;
}

// This has to be kept in sync with LEDFormat in NeoPico.hpp
Expand Down Expand Up @@ -497,4 +504,7 @@ enum GPEventType
GP_EVENT_BUTTON_PROCESSED_DOWN = 9;
GP_EVENT_ANALOG_MOVE = 10;
GP_EVENT_ANALOG_PROCESSED_MOVE = 11;
GP_EVENT_STORAGE_SAVE = 12;
GP_EVENT_SYSTEM_REBOOT = 13;
GP_EVENT_MENU_NAVIGATE = 14;
};
19 changes: 18 additions & 1 deletion src/addons/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void DisplayAddon::setup() {
updateDisplayScreen();

EventManager::getInstance().registerEventHandler(GP_EVENT_RESTART, GPEVENT_CALLBACK(this->handleSystemRestart(event)));
EventManager::getInstance().registerEventHandler(GP_EVENT_MENU_NAVIGATE, GPEVENT_CALLBACK(this->handleMenuNavigation(event)));
}

bool DisplayAddon::updateDisplayScreen() {
Expand Down Expand Up @@ -231,4 +232,20 @@ void DisplayAddon::handleSystemRestart(GPEvent* e) {
currDisplayMode = DisplayMode::RESTART;
bootMode = (uint32_t)((GPRestartEvent*)e)->bootMode;
updateDisplayScreen();
}
}

void DisplayAddon::handleMenuNavigation(GPEvent* e) {
if (currDisplayMode != MAIN_MENU) {
if (((GPMenuNavigateEvent*)e)->menuAction == GpioAction::MENU_NAVIGATION_TOGGLE) {
currDisplayMode = MAIN_MENU;
updateDisplayScreen();
}
} else {
if (((GPMenuNavigateEvent*)e)->menuAction != GpioAction::MENU_NAVIGATION_TOGGLE) {
((MainMenuScreen*)gpScreen)->updateMenuNavigation(((GPMenuNavigateEvent*)e)->menuAction);
} else {
currDisplayMode = BUTTONS;
updateDisplayScreen();
}
}
}
3 changes: 3 additions & 0 deletions src/addons/focus_mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ void FocusModeAddon::setup() {
void FocusModeAddon::process() {
Gamepad * gamepad = Storage::getInstance().GetGamepad();
Mask_t values = Storage::getInstance().GetGamepad()->debouncedGpio;

if (!Storage::getInstance().getAddonOptions().focusModeOptions.enabled) return;

if (values & mapFocusMode->pinMask) {
if (buttonLockMask & GAMEPAD_MASK_DU) {
gamepad->state.dpad &= ~GAMEPAD_MASK_UP;
Expand Down
2 changes: 2 additions & 0 deletions src/addons/turbo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ void TurboInput::process()
uint16_t buttonsPressed = gamepad->state.buttons & TURBO_BUTTON_MASK;
uint8_t dpadPressed = gamepad->state.dpad & GAMEPAD_MASK_DPAD;

if (!options.enabled) return;

// Check for TURBO pin enabled
if (gamepad->debouncedGpio & turboPinMask) {
if (buttonsPressed && (lastPressed != buttonsPressed)) {
Expand Down
68 changes: 35 additions & 33 deletions src/display/ui/elements/GPMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,43 @@
#include <string>

void GPMenu::draw() {
uint16_t baseX = this->x;
uint16_t baseY = this->y;

uint16_t menuWidth = this->menuSizeX * 6;
uint16_t menuHeight = this->menuSizeY * 8;

uint16_t dataSize = this->getDataSize();
uint16_t totalPages = (dataSize + this->menuSizeY - 1) / this->menuSizeY;
uint16_t itemPage = (this->menuIndex / this->menuSizeY);

int16_t currPageItems = (dataSize - (itemPage * this->menuSizeY));
if (currPageItems > this->menuSizeY) {
currPageItems = this->menuSizeY;
} else if (currPageItems <= 0) {
currPageItems = 0;
}

getRenderer()->drawText((21-this->menuTitle.length()) / 2, 0, this->menuTitle.c_str());

std::string pageDisplay = "";
pageDisplay += "Page: " + std::to_string(itemPage+1) + "/" + std::to_string(totalPages);
getRenderer()->drawText(11, 7, pageDisplay.c_str());
if (this->getVisibility()) {
uint16_t baseX = this->x;
uint16_t baseY = this->y;

uint16_t menuWidth = this->menuSizeX * 6;
uint16_t menuHeight = this->menuSizeY * 8;

uint16_t dataSize = this->getDataSize();
uint16_t totalPages = (dataSize + this->menuSizeY - 1) / this->menuSizeY;
uint16_t itemPage = (this->menuIndex / this->menuSizeY);

int16_t currPageItems = (dataSize - (itemPage * this->menuSizeY));
if (currPageItems > this->menuSizeY) {
currPageItems = this->menuSizeY;
} else if (currPageItems <= 0) {
currPageItems = 0;
}

if (this->menuEntryData->size() > 0) {
for (uint8_t menuLine = 0; menuLine < currPageItems; menuLine++) {
uint8_t pageLine = (this->menuSizeY * itemPage) + menuLine;
int32_t lineValue = this->menuEntryData->at(pageLine).optionValue;
bool showCurrentOption = false;
if (lineValue != -1) {
showCurrentOption = (this->menuEntryData->at(pageLine).currentValue() == this->menuEntryData->at(pageLine).optionValue);
getRenderer()->drawText((21-this->menuTitle.length()) / 2, 0, this->menuTitle.c_str());

std::string pageDisplay = "";
pageDisplay += "Page: " + std::to_string(itemPage+1) + "/" + std::to_string(totalPages);
getRenderer()->drawText(11, 7, pageDisplay.c_str());

if (this->menuEntryData->size() > 0) {
for (uint8_t menuLine = 0; menuLine < currPageItems; menuLine++) {
uint8_t pageLine = (this->menuSizeY * itemPage) + menuLine;
int32_t lineValue = this->menuEntryData->at(pageLine).optionValue;
bool showCurrentOption = false;
if (lineValue != -1) {
showCurrentOption = (this->menuEntryData->at(pageLine).currentValue() == this->menuEntryData->at(pageLine).optionValue);
}
getRenderer()->drawText(2, 2+menuLine, this->menuEntryData->at(pageLine).label + (showCurrentOption ? " *" : ""));
}
getRenderer()->drawText(2, 2+menuLine, this->menuEntryData->at(pageLine).label + (showCurrentOption ? " *" : ""));
}
}

// draw cursor
getRenderer()->drawText(1, 2+(this->menuIndex % this->menuSizeY), CHAR_RIGHT);
// draw cursor
getRenderer()->drawText(1, 2+(this->menuIndex % this->menuSizeY), CHAR_RIGHT);
}
}
Loading

0 comments on commit 582bbe5

Please sign in to comment.