Skip to content

Instantly share code, notes, and snippets.

@BenJuan26
Created April 17, 2020 03:05
Show Gist options
  • Save BenJuan26/07acc860f2614f6dbe366bc2419c009d to your computer and use it in GitHub Desktop.
Save BenJuan26/07acc860f2614f6dbe366bc2419c009d to your computer and use it in GitHub Desktop.
// Global variable to hold the flags from the game state.
#define NO_FLAGS 0
unsigned long currentFlags = NO_FLAGS;
// Each button press will last about 100ms.
#define BUTTON_HOLD_TIME 100
struct Toggleswitch {
byte currState; // State of the physical switch.
byte lastState; // Last known state of the physical switch.
byte buttonState; // Whether the joystick button is pressed.
byte joyButton; // Which joystick button the switch belongs to.
unsigned long releaseTime; // The time after which to stop pressing the button.
long flag; // The flag assigned to this switch.
// Must have a default constructor in order to use these in an array.
Toggleswitch() {}
// Constructor supports an initial state.
Toggleswitch(byte _state, byte _button, long _flag) {
currState = _state;
lastState = _state;
buttonState = BUTTON_RELEASED;
joyButton = _button;
releaseTime = 0L;
flag = _flag;
}
// Is the game in the same state as the switch?
bool isInSync() {
// Always treat as in sync if there's no flag info.
if (currentFlags == NO_FLAGS) {
return true;
}
bool buttonPressed = lastState == BUTTON_PRESSED;
bool flagSet = currentFlags & flag;
// Need to account for the rollover of the millis() value.
// In that case this value will be huge, which is fine, as it
// will just try to sync up a little early.
unsigned long timeSinceReleased = abs(signed(releaseTime - millis()));
// Always assume things are in sync for a while after the button is pressed
// to give the game time to catch up.
return timeSinceReleased < BUTTON_SYNC_TIME || buttonPressed == flagSet;
}
// This will be called periodically for the switch to take care of its own updates.
void update() {
// If the switch is flipped, or the game comes out of sync, trigger a button press.
if (currState != lastState || !isInSync()) {
lastState = currState;
buttonState = BUTTON_PRESSED;
Joystick.button(joyButton, true);
releaseTime = millis() + BUTTON_HOLD_TIME;
}
// If the button is pressed and it's time to release it, release it.
else if (buttonState == BUTTON_PRESSED && millis() >= releaseTime) {
buttonState = BUTTON_RELEASED;
Joystick.button(joyButton, false);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment