diff --git a/VortexEngine/VortexCLI/VortexCLI.cpp b/VortexEngine/VortexCLI/VortexCLI.cpp index 9097f621a8..0d66810c64 100644 --- a/VortexEngine/VortexCLI/VortexCLI.cpp +++ b/VortexEngine/VortexCLI/VortexCLI.cpp @@ -59,6 +59,7 @@ const char *input_usage[] = { "\n r rapid button click (ex: r15)", "\n w wait 1 tick", "\n repeat command n times (only single digits in -i mode)", + "\n b select button index (ex: b0 for first button or b1 for second button)", "\n q quit", }; @@ -77,6 +78,7 @@ const char *input_usage_brief[NUM_USAGE] = { "\n r rapid", "\n w wait", "\n repeat", + "\n b button idx", "\n q quit", }; diff --git a/VortexEngine/VortexLib/Makefile b/VortexEngine/VortexLib/Makefile index d3e58ef22c..1081f57168 100644 --- a/VortexEngine/VortexLib/Makefile +++ b/VortexEngine/VortexLib/Makefile @@ -17,7 +17,12 @@ MAKE=make RM=rm -rf RANLIB=ranlib -CFLAGS=-O2 -g -Wall +CFLAGS=-O2 -Wall + +# add -g flag for debug symbols if we're not using wasm +ifndef WASM +CFLAGS += -g +endif # compiler defines DEFINES=\ @@ -31,7 +36,8 @@ INCLUDES=\ ifdef WASM DEFINES += -D WASM -CFLAGS += --bind -s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORT_NAME='VortexLib' +# this was used before but I think only the above is necessary +#CFLAGS += --bind -s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORT_NAME='VortexLib' endif ifdef TESTFRAMEWORK @@ -114,7 +120,7 @@ vortex.a: $(DEPS) $(AR) $@ $^ VortexLib.js: $(DEPS) - $(CC) $(CFLAGS) $^ -o $@ $(LLIBS) + $(CC) $(CFLAGS) --bind $^ -o $@ $(LLIBS) # catch-all make target to generate .o and .d files %.o: %.cpp diff --git a/VortexEngine/VortexLib/VortexLib.cpp b/VortexEngine/VortexLib/VortexLib.cpp index 53303add4a..839d9b41a2 100644 --- a/VortexEngine/VortexLib/VortexLib.cpp +++ b/VortexEngine/VortexLib/VortexLib.cpp @@ -3,6 +3,7 @@ // VortexEngine includes #include "VortexEngine.h" #include "Buttons/Button.h" +#include "Buttons/Buttons.h" #include "Serial/ByteStream.h" #include "Wireless/IRReceiver.h" #include "Wireless/VLReceiver.h" @@ -571,6 +572,7 @@ FILE *Vortex::m_logHandle = nullptr; deque Vortex::m_buttonEventQueue; bool Vortex::m_initialized = false; uint32_t Vortex::m_buttonsPressed = 0; +uint8_t Vortex::m_selectedButton = 0; string Vortex::m_commandLog; bool Vortex::m_commandLogEnabled = false; bool Vortex::m_lockstepEnabled = false; @@ -676,12 +678,12 @@ void Vortex::cleanup() m_initialized = false; } -void Vortex::handleRepeat(char c) +void Vortex::handleNumber(char c) { if (!isdigit(c) || !m_lastCommand) { return; } - int repeatAmount = c - '0'; + int number = c - '0'; char newc = 0; // read the digits into the repeatAmount while (1) { @@ -691,31 +693,35 @@ void Vortex::handleRepeat(char c) break; } // accumulate the digits into the repeat amount - repeatAmount = (repeatAmount * 10) + (newc - '0'); - } - if (repeatAmount > 0) { - // offset repeat amount by exactly 1 because it's already done - repeatAmount--; + number = (number * 10) + (newc - '0'); } // shove the last non-digit back into the stream ungetc(newc, stdin); - DEBUG_LOGF("Repeating last command (%c) x%u times", m_lastCommand, repeatAmount); - m_commandLog += to_string(repeatAmount); + DEBUG_LOGF("Repeating last command (%c) x%u times", m_lastCommand, number); + m_commandLog += to_string(number); // check to see if we are repeating a 'rapid click' which is a special case // because the rapid click command itself is composed or 'r' and a repeat count // to designate how many rapid clicks to deliver - if (m_lastCommand == 'r') { - // the repeat amount is normally decremented to account for the first command - // so we add 1 to counter-act that logic above because the initial 'r' does nothing - // unlike most other commands that are repeated - Vortex::rapidClick(repeatAmount + 1); - // don't actually repeat the command just return - return; - } - // repeat the last command that many times - while (repeatAmount > 0) { - doCommand(m_lastCommand); - repeatAmount--; + switch (m_lastCommand) { + case 'r': + // perform a rapid click number times + rapidClick(number); + break; + case 'b': + // select button index to target for click events + selectButton(number); + break; + default: // any other command + if (number > 0) { + // offset repeat amount by exactly 1 because it's already done + number--; + } + // repeat the last command that many times + while (number > 0) { + doCommand(m_lastCommand); + number--; + } + break; } } @@ -734,76 +740,81 @@ void Vortex::doCommand(char c) if (m_lastCommand != c) { DEBUG_LOG("Injecting short click"); } - Vortex::shortClick(); + shortClick(); break; case 'l': if (m_lastCommand != c) { DEBUG_LOG("Injecting long click"); } - Vortex::longClick(); + longClick(); break; case 'm': if (m_lastCommand != c) { DEBUG_LOG("Injecting menu enter click"); } - Vortex::menuEnterClick(); + menuEnterClick(); break; case 'a': if (m_lastCommand != c) { DEBUG_LOG("Injecting adv menu enter click"); } - Vortex::advMenuEnterClick(); + advMenuEnterClick(); break; case 'd': if (m_lastCommand != c) { DEBUG_LOG("Injecting adv menu enter click"); } - Vortex::deleteColClick(); + deleteColClick(); break; case 's': if (m_lastCommand != c) { DEBUG_LOG("Injecting sleep click"); } - Vortex::sleepClick(); + sleepClick(); break; case 'f': if (m_lastCommand != c) { DEBUG_LOG("Injecting force sleep click"); } - Vortex::forceSleepClick(); + forceSleepClick(); break; case 'q': //case '\n': if (m_lastCommand != c) { DEBUG_LOG("Injecting quit click\n"); } - Vortex::quitClick(); + quitClick(); break; case 't': - if (Vortex::isButtonPressed()) { + if (isButtonPressed()) { if (m_lastCommand != c) { DEBUG_LOG("Injecting release"); } - Vortex::releaseButton(); + releaseButton(); } else { if (m_lastCommand != c) { DEBUG_LOG("Injecting press"); } - Vortex::pressButton(); + pressButton(); } break; case 'r': - // do nothing for the initial 'r', handleRepeat() will handle the numeric + // do nothing for the initial 'r', handleNumber() will handle the numeric // repeat count that follows this letter and issue the rapidClick(amt) call break; + case 'b': + // button selector, same as rapid click, it's a little weird because the number + // it not a repeat amount but actually the button index to select -- but none + // the less it works the same as rapid click so it will be handled inside handleNumber() + break; case 'w': if (m_lastCommand != c) { DEBUG_LOG("Injecting wait"); } - Vortex::sendWait(); + sendWait(); break; default: - handleRepeat(c); + handleNumber(c); // return instead of break because this isn't a command return; } @@ -868,54 +879,93 @@ void Vortex::setInstantTimestep(bool timestep) Time::setInstantTimestep(timestep); } +// select the button to send clicks to (0 = first button) +void Vortex::selectButton(uint8_t buttonIndex) +{ + if (buttonIndex >= Buttons::numButtons()) { + return; + } + m_selectedButton = buttonIndex; +} + // send various clicks -void Vortex::shortClick(uint32_t buttonIndex) +void Vortex::shortClick(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonEventQueue.push_back(VortexButtonEvent(buttonIndex, EVENT_SHORT_CLICK)); } -void Vortex::longClick(uint32_t buttonIndex) +void Vortex::longClick(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonEventQueue.push_back(VortexButtonEvent(buttonIndex, EVENT_LONG_CLICK)); } -void Vortex::menuEnterClick(uint32_t buttonIndex) +void Vortex::menuEnterClick(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonEventQueue.push_back(VortexButtonEvent(buttonIndex, EVENT_MENU_ENTER_CLICK)); } -void Vortex::advMenuEnterClick(uint32_t buttonIndex) +void Vortex::advMenuEnterClick(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonEventQueue.push_back(VortexButtonEvent(buttonIndex, EVENT_ADV_MENU_ENTER_CLICK)); } -void Vortex::deleteColClick(uint32_t buttonIndex) +void Vortex::deleteColClick(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonEventQueue.push_back(VortexButtonEvent(buttonIndex, EVENT_DELETE_COL)); } -void Vortex::sleepClick(uint32_t buttonIndex) +void Vortex::sleepClick(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonEventQueue.push_back(VortexButtonEvent(buttonIndex, EVENT_SLEEP_CLICK)); } -void Vortex::forceSleepClick(uint32_t buttonIndex) +void Vortex::forceSleepClick(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonEventQueue.push_back(VortexButtonEvent(buttonIndex, EVENT_FORCE_SLEEP_CLICK)); } -void Vortex::pressButton(uint32_t buttonIndex) +void Vortex::pressButton(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonsPressed |= (1 << buttonIndex); } -void Vortex::releaseButton(uint32_t buttonIndex) +void Vortex::releaseButton(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } m_buttonsPressed &= ~(1 << buttonIndex); } -bool Vortex::isButtonPressed(uint32_t buttonIndex) +bool Vortex::isButtonPressed(uint8_t buttonIndex) { + if (!buttonIndex) { + buttonIndex = m_selectedButton; + } return (m_buttonsPressed & (1 << buttonIndex)) != 0; } diff --git a/VortexEngine/VortexLib/VortexLib.h b/VortexEngine/VortexLib/VortexLib.h index bb7750350b..52f0b5ef58 100644 --- a/VortexEngine/VortexLib/VortexLib.h +++ b/VortexEngine/VortexLib/VortexLib.h @@ -112,17 +112,24 @@ class Vortex // control whether the engine will tick instantly or not static void setInstantTimestep(bool timestep); - // send various clicks - static void shortClick(uint32_t buttonIndex = 0); - static void longClick(uint32_t buttonIndex = 0); - static void menuEnterClick(uint32_t buttonIndex = 0); - static void advMenuEnterClick(uint32_t buttonIndex = 0); - static void deleteColClick(uint32_t buttonIndex = 0); - static void sleepClick(uint32_t buttonIndex = 0); - static void forceSleepClick(uint32_t buttonIndex = 0); - static void pressButton(uint32_t buttonIndex = 0); - static void releaseButton(uint32_t buttonIndex = 0); - static bool isButtonPressed(uint32_t buttonIndex = 0); + // select the button to send clicks to by default (0 = first button, 1 = 2nd, etc) + static void selectButton(uint8_t buttonIndex); + + // send various clicks to the selected button, unless the button + // index is provided as an argument then whichever button is selected + // will receive the event. So if selectButton(1) is called then all of + // these will by default target the 2nd button, unless they are given a + // non-zero button index to target then they will target that one instead + static void shortClick(uint8_t buttonIndex = 0); + static void longClick(uint8_t buttonIndex = 0); + static void menuEnterClick(uint8_t buttonIndex = 0); + static void advMenuEnterClick(uint8_t buttonIndex = 0); + static void deleteColClick(uint8_t buttonIndex = 0); + static void sleepClick(uint8_t buttonIndex = 0); + static void forceSleepClick(uint8_t buttonIndex = 0); + static void pressButton(uint8_t buttonIndex = 0); + static void releaseButton(uint8_t buttonIndex = 0); + static bool isButtonPressed(uint8_t buttonIndex = 0); // send a wait event, will let the engine run a tick if running in lockstep // for example when running the testing system @@ -274,8 +281,8 @@ class Vortex // the last command to have been executed static char m_lastCommand; - // internal function to handle repeating commands - static void handleRepeat(char c); + // internal function to handle numeric values in commands + static void handleNumber(char c); // so that the buttons class can call handleInputQueue friend class Buttons; @@ -355,6 +362,8 @@ class Vortex // whether each button is pressed (bitflags) so technically this only // supports 32 buttons but idc whoever adds 33 buttons can fix this static uint32_t m_buttonsPressed; + // the selected button to target for input events + static uint8_t m_selectedButton; // keeps a log of all the commands issued static std::string m_commandLog; // whether to record commands diff --git a/VortexEngine/src/Buttons/Buttons.h b/VortexEngine/src/Buttons/Buttons.h index a17c90f5d6..a1315ca6bd 100644 --- a/VortexEngine/src/Buttons/Buttons.h +++ b/VortexEngine/src/Buttons/Buttons.h @@ -22,6 +22,8 @@ class Buttons // poll the buttons static void update(); + static uint8_t numButtons() { return NUM_BUTTONS; } + private: // feel free to add more I guess static Button m_buttons[NUM_BUTTONS]; diff --git a/VortexEngine/src/Leds/Leds.cpp b/VortexEngine/src/Leds/Leds.cpp index 57ee4b284a..027a3f4248 100644 --- a/VortexEngine/src/Leds/Leds.cpp +++ b/VortexEngine/src/Leds/Leds.cpp @@ -55,10 +55,10 @@ static void turnOffOnboardLED() } #endif -// array of led color values -RGBColor Leds::m_ledColors[LED_COUNT] = { RGB_OFF }; // global brightness uint8_t Leds::m_brightness = DEFAULT_BRIGHTNESS; +// array of led color values +RGBColor Leds::m_ledColors[LED_COUNT] = { RGB_OFF }; bool Leds::init() { diff --git a/VortexEngine/src/Menus/Menus.cpp b/VortexEngine/src/Menus/Menus.cpp index 9d0247047f..56823e853c 100644 --- a/VortexEngine/src/Menus/Menus.cpp +++ b/VortexEngine/src/Menus/Menus.cpp @@ -20,8 +20,8 @@ // static members Menus::MenuState Menus::m_menuState = MENU_STATE_NOT_OPEN; -uint32_t Menus::m_openTime = 0; uint8_t Menus::m_selection = 0; +uint32_t Menus::m_openTime = 0; Menu *Menus::m_pCurMenu = nullptr; // typedef for the menu initialization function