diff --git a/headers/addons/i2cdisplay.h b/headers/addons/i2cdisplay.h index 225a9a5c1..441f3dc43 100644 --- a/headers/addons/i2cdisplay.h +++ b/headers/addons/i2cdisplay.h @@ -7,6 +7,8 @@ #define DISPLAY_H_ #include +#include +#include #include #include "OneBitDisplay.h" #include "BoardConfig.h" @@ -83,6 +85,7 @@ class I2CDisplayAddon : public GPAddon void drawWasdBox(int startX, int startY, int buttonRadius, int buttonPadding); void drawArcadeStick(int startX, int startY, int buttonRadius, int buttonPadding); void drawStatusBar(Gamepad*); + void drawHistory(Gamepad*); void drawText(int startX, int startY, std::string text); void initMenu(char**); //Adding my stuff here, remember to sort before PR @@ -128,6 +131,8 @@ class I2CDisplayAddon : public GPAddon std::string statusBar; Gamepad* gamepad; Gamepad* pGamepad; + std::deque history; + std::array last; private: DisplayPreviewMode displayPreviewMode; uint16_t prevButtonState; diff --git a/src/addons/i2cdisplay.cpp b/src/addons/i2cdisplay.cpp index fd0506928..7d800725c 100644 --- a/src/addons/i2cdisplay.cpp +++ b/src/addons/i2cdisplay.cpp @@ -101,34 +101,34 @@ void I2CDisplayAddon::process() { switch (Storage::getInstance().GetButtonLayout()) { case BUTTON_LAYOUT_STICK: - drawArcadeStick(8, 28, 8, 2); + drawArcadeStick(8, 22, 8, 2); break; case BUTTON_LAYOUT_STICKLESS: drawStickless(8, 20, 8, 2); break; case BUTTON_LAYOUT_BUTTONS_ANGLED: - drawWasdBox(8, 28, 7, 3); + drawWasdBox(8, 22, 7, 3); break; case BUTTON_LAYOUT_BUTTONS_BASIC: - drawUDLR(8, 28, 8, 2); + drawUDLR(8, 22, 8, 2); break; case BUTTON_LAYOUT_KEYBOARD_ANGLED: - drawKeyboardAngled(18, 28, 5, 2); + drawKeyboardAngled(18, 24, 5, 2); break; case BUTTON_LAYOUT_KEYBOARDA: - drawMAMEA(8, 28, 10, 1); + drawMAMEA(8, 22, 10, 1); break; case BUTTON_LAYOUT_DANCEPADA: - drawDancepadA(39, 12, 15, 2); + drawDancepadA(39, 10, 13, 2); break; case BUTTON_LAYOUT_TWINSTICKA: - drawTwinStickA(8, 28, 8, 2); + drawTwinStickA(8, 22, 8, 2); break; case BUTTON_LAYOUT_BLANKA: drawBlankA(0, 0, 0, 0); break; case BUTTON_LAYOUT_VLXA: - drawVLXA(7, 28, 7, 2); + drawVLXA(7, 22, 7, 2); break; case BUTTON_LAYOUT_FIGHTBOARD_STICK: drawArcadeStick(18, 22, 8, 2); @@ -141,46 +141,46 @@ void I2CDisplayAddon::process() { switch (Storage::getInstance().GetButtonLayoutRight()) { case BUTTON_LAYOUT_ARCADE: - drawArcadeButtons(8, 28, 8, 2); + drawArcadeButtons(8, 22, 8, 2); break; case BUTTON_LAYOUT_STICKLESSB: drawSticklessButtons(8, 20, 8, 2); break; case BUTTON_LAYOUT_BUTTONS_ANGLEDB: - drawWasdButtons(8, 28, 7, 3); + drawWasdButtons(8, 22, 7, 3); break; case BUTTON_LAYOUT_VEWLIX: - drawVewlix(8, 28, 8, 2); + drawVewlix(8, 22, 8, 2); break; case BUTTON_LAYOUT_VEWLIX7: - drawVewlix7(8, 28, 8, 2); + drawVewlix7(8, 22, 8, 2); break; case BUTTON_LAYOUT_CAPCOM: - drawCapcom(6, 28, 8, 2); + drawCapcom(6, 22, 8, 2); break; case BUTTON_LAYOUT_CAPCOM6: - drawCapcom6(16, 28, 8, 2); + drawCapcom6(16, 22, 8, 2); break; case BUTTON_LAYOUT_SEGA2P: - drawSega2p(8, 28, 8, 2); + drawSega2p(8, 22, 8, 2); break; case BUTTON_LAYOUT_NOIR8: - drawNoir8(8, 28, 8, 2); + drawNoir8(8, 22, 8, 2); break; case BUTTON_LAYOUT_KEYBOARDB: - drawMAMEB(68, 28, 10, 1); + drawMAMEB(68, 22, 10, 1); break; case BUTTON_LAYOUT_DANCEPADB: - drawDancepadB(39, 12, 15, 2); + drawDancepadB(39, 10, 13, 2); break; case BUTTON_LAYOUT_TWINSTICKB: - drawTwinStickB(100, 28, 8, 2); + drawTwinStickB(100, 22, 8, 2); break; case BUTTON_LAYOUT_BLANKB: drawSticklessButtons(0, 0, 0, 0); break; case BUTTON_LAYOUT_VLXB: - drawVLXB(6, 28, 7, 2); + drawVLXB(6, 22, 7, 2); break; case BUTTON_LAYOUT_FIGHTBOARD: drawFightboard(8, 22, 7, 3); @@ -191,6 +191,7 @@ void I2CDisplayAddon::process() { } } + drawHistory(gamepad); obdDumpBuffer(&obd, NULL); } @@ -289,7 +290,7 @@ void I2CDisplayAddon::drawStickless(int startX, int startY, int buttonRadius, in obdPreciseEllipse(&obd, startX, startY, buttonRadius, buttonRadius, 1, pressedLeft()); obdPreciseEllipse(&obd, startX + buttonMargin, startY, buttonRadius, buttonRadius, 1, pressedDown()); obdPreciseEllipse(&obd, startX + (buttonMargin * 1.875), startY + (buttonMargin / 2), buttonRadius, buttonRadius, 1, pressedRight()); - obdPreciseEllipse(&obd, startX + (buttonMargin * 2.25), startY + buttonMargin * 1.875, buttonRadius, buttonRadius, 1, pressedUp()); + obdPreciseEllipse(&obd, startX + (buttonMargin * 1.875), startY + (buttonMargin * 1.5), buttonRadius, buttonRadius, 1, pressedUp()); } void I2CDisplayAddon::drawWasdBox(int startX, int startY, int buttonRadius, int buttonPadding) @@ -784,6 +785,110 @@ void I2CDisplayAddon::drawStatusBar(Gamepad * gamepad) drawText(0, 0, statusBar); } +void I2CDisplayAddon::drawHistory(Gamepad *gamepad) +{ + std::deque pressed; + + // Get key states + std::array current = { + pressedUp(), + pressedDown(), + pressedLeft(), + pressedRight(), + gamepad->pressedB1(), + gamepad->pressedB2(), + gamepad->pressedR2(), + gamepad->pressedL2(), + gamepad->pressedB3(), + gamepad->pressedB4(), + gamepad->pressedR1(), + gamepad->pressedL1(), + gamepad->pressedL3(), + gamepad->pressedS1(), + gamepad->pressedA1(), + gamepad->pressedS2(), + gamepad->pressedR3(), + }; + + // Key names shown on display + std::string displayNames[][17] = { + { // DInput + "U", "D", "L", "R", + "2", "3", "8", "7", + "1", "4", "6", "5", + "11", "9", "13", "10", "12" + }, + { // Switch + "U", "D", "L", "R", + "B", "A", "ZR", "ZL", + "Y", "X", "R", "L", + "LS", "-", "H", "+", "RS" + }, + { // XInput + "U", "D", "L", "R", + "A", "B", "RT", "LT", + "X", "Y", "RB", "LB", + "L3", "S1", "A1", "S2", "R3" + } + }; + + uint8_t mode; + switch (gamepad->options.inputMode) + { + case INPUT_MODE_HID: mode=0; break; + case INPUT_MODE_SWITCH: mode=1; break; + case INPUT_MODE_XINPUT: mode=2; break; + } + + // Check if any new keys have been pressed + if (last != current) { + // Iterate through array + for (uint8_t x=0; x<17; x++) { + // Add any pressed keys to deque + if (current[x]) pressed.push_back(displayNames[mode][x]); + } + // Update the last keypress array + last = current; + } + + if (pressed.size() > 0) { + std::string newInput; + for(const auto &s : pressed) { + if(!newInput.empty()) + newInput += "+"; + newInput += s; + } + + history.push_back(newInput); + } + + if (history.size() > 10) { + history.pop_front(); + } + + std::string ret; + + for (auto it = history.crbegin(); it != history.crend(); ++it) { + if (ret.size() < 22) { + std::string newRet = ret; + if (!newRet.empty()) + newRet = " " + newRet; + + newRet = *it + newRet; + + if (newRet.size() < 22) { + ret = newRet; + } + else { + break; + } + } + } + + // Draw history at bottom of display + obdWriteString(&obd, 0, 0, 7, (char *)ret.c_str(), FONT_6x8, 0, 0); +} + bool I2CDisplayAddon::pressedUp() { switch (gamepad->options.dpadMode)