Skip to content

Commit

Permalink
adjusted vortex lib and vortex cli to allow button selection (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
Unreal-Dan authored Dec 22, 2023
1 parent 9139d85 commit be2173e
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 58 deletions.
2 changes: 2 additions & 0 deletions VortexEngine/VortexCLI/VortexCLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const char *input_usage[] = {
"\n r rapid button click (ex: r15)",
"\n w wait 1 tick",
"\n <digits> repeat command n times (only single digits in -i mode)",
"\n b<index> select button index (ex: b0 for first button or b1 for second button)",
"\n q quit",
};

Expand All @@ -77,6 +78,7 @@ const char *input_usage_brief[NUM_USAGE] = {
"\n r rapid",
"\n w wait",
"\n <digits> repeat",
"\n b<index> button idx",
"\n q quit",
};

Expand Down
140 changes: 95 additions & 45 deletions VortexEngine/VortexLib/VortexLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -571,6 +572,7 @@ FILE *Vortex::m_logHandle = nullptr;
deque<Vortex::VortexButtonEvent> 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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
35 changes: 22 additions & 13 deletions VortexEngine/VortexLib/VortexLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions VortexEngine/src/Buttons/Buttons.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down

0 comments on commit be2173e

Please sign in to comment.