retain the unaltered DPAD state in order to use it in display (#1392)

my build has both a lever (dpad mode) and buttons assigned to direct
digital, and a display that is intended to be input-pin-based rather
than output-based (so that the same things display in the viewer
regardless of which profile mode I am in). main works great for that,
for buttons, but the current GP_LEVER_MODEs all are looking at the
output, e.g. GP_LEVER_MODE_DIGITAL only shows the lever moving if the
dpad is set to digital output, not e.g. left analog output. meanwhile,
it would also show lever activity if I was pressing the direct digital
buttons even when I wasn't moving the lever.

this fixes that by adding a new GP_LEVER_MODE_DPAD, which is looking at
the unaltered dpad-mode input, regardless of how it is output, bringing
the display lever functionally equivalent to GPIO-based button displays.
conveniently, we already were holding onto the dpad inputs in the main
loop in order to handle the direct directionals, this just puts it in
the gamepad state object instead
This commit is contained in:
Brian S. Stephan
2025-06-22 14:59:32 -05:00
committed by GitHub
parent 17f4da6fec
commit e1fd4131c6
4 changed files with 22 additions and 7 deletions

View File

@@ -137,6 +137,7 @@ const uint32_t buttonMasks[] =
struct GamepadState
{
uint8_t dpad {0};
uint8_t dpadOriginal {0};
uint32_t buttons {0};
uint16_t aux {0};
uint16_t lx {GAMEPAD_JOYSTICK_MID};

View File

@@ -524,6 +524,7 @@ enum GPLever_Mode
GP_LEVER_MODE_RIGHT_ANALOG = 4;
GP_LEVER_MODE_INVERT_X = 8;
GP_LEVER_MODE_INVERT_Y = 16;
GP_LEVER_MODE_DPAD = 32;
};
enum RotaryEncoderPinMode

View File

@@ -38,16 +38,17 @@ void GPLever::draw() {
int leverRadius = (int)(((double)this->_radius * 0.75) * scaleY);
// any zero-defined levers should be forced to dpad to avoid broken functionality. to be fixed.
if (this->_inputType == GPLever_Mode::GP_LEVER_MODE_NONE) this->_inputType = GPLever_Mode::GP_LEVER_MODE_DIGITAL;
if (this->_inputType == GPLever_Mode::GP_LEVER_MODE_NONE) this->_inputType = GPLever_Mode::GP_LEVER_MODE_DPAD;
bool dpadInput = ((this->_inputType & GPLever_Mode::GP_LEVER_MODE_DIGITAL) == GPLever_Mode::GP_LEVER_MODE_DIGITAL);
bool dpadInput = ((this->_inputType & GPLever_Mode::GP_LEVER_MODE_DPAD) == GPLever_Mode::GP_LEVER_MODE_DPAD);
bool digitalOutput = ((this->_inputType & GPLever_Mode::GP_LEVER_MODE_DIGITAL) == GPLever_Mode::GP_LEVER_MODE_DIGITAL);
bool leftAnalog = ((this->_inputType & GPLever_Mode::GP_LEVER_MODE_LEFT_ANALOG) == GPLever_Mode::GP_LEVER_MODE_LEFT_ANALOG);
bool rightAnalog = ((this->_inputType & GPLever_Mode::GP_LEVER_MODE_RIGHT_ANALOG) == GPLever_Mode::GP_LEVER_MODE_RIGHT_ANALOG);
bool invertX = ((this->_inputType & GPLever_Mode::GP_LEVER_MODE_INVERT_X) == GPLever_Mode::GP_LEVER_MODE_INVERT_X);
bool invertY = ((this->_inputType & GPLever_Mode::GP_LEVER_MODE_INVERT_Y) == GPLever_Mode::GP_LEVER_MODE_INVERT_Y);
if (dpadInput) {
// dpad
if (digitalOutput) {
// digital directions regardless of how
bool upState = (this->_upMask > -1 ? getProcessedGamepad()->pressedButton((uint16_t)this->_upMask) : getProcessedGamepad()->pressedUp());
bool leftState = (this->_leftMask > -1 ? getProcessedGamepad()->pressedButton((uint16_t)this->_leftMask) : getProcessedGamepad()->pressedLeft());
bool downState = (this->_downMask > -1 ? getProcessedGamepad()->pressedButton((uint16_t)this->_downMask) : getProcessedGamepad()->pressedDown());
@@ -58,6 +59,18 @@ void GPLever::draw() {
if (leftState != rightState) {
leverX -= leftState ? (!invertX ? leverRadius : -leverRadius) : (!invertX ? -leverRadius : leverRadius);
}
} else if (dpadInput) {
// whatever the switchable dpad input is
bool upState = getGamepad()->state.dpadOriginal & GAMEPAD_MASK_UP;
bool leftState = getGamepad()->state.dpadOriginal & GAMEPAD_MASK_LEFT;
bool downState = getGamepad()->state.dpadOriginal & GAMEPAD_MASK_DOWN;
bool rightState = getGamepad()->state.dpadOriginal & GAMEPAD_MASK_RIGHT;
if (upState != downState) {
leverY -= upState ? (!invertY ? leverRadius : -leverRadius) : (!invertY ? -leverRadius : leverRadius);
}
if (leftState != rightState) {
leverX -= leftState ? (!invertX ? leverRadius : -leverRadius) : (!invertX ? -leverRadius : leverRadius);
}
} else if (leftAnalog || rightAnalog) {
// analog
uint16_t analogX = map((leftAnalog ? getProcessedGamepad()->state.lx : getProcessedGamepad()->state.rx), (!invertX ? 0 : 0xFFFF), (!invertX ? 0xFFFF : 0), 0, 100);

View File

@@ -275,13 +275,13 @@ void Gamepad::process()
}
// hold current dpad state regardless of input
uint8_t dpadOriginal = state.dpad;
state.dpadOriginal = state.dpad;
// stash digital-only dpad state for later
uint8_t dpadOnlyMask = ((dpadOriginal & 0xF0) >> 4);
uint8_t dpadOnlyMask = ((state.dpadOriginal & 0xF0) >> 4);
// and mask out the mode-specific mask
uint8_t dpadModeMask = (dpadOriginal & 0x0F);
uint8_t dpadModeMask = (state.dpadOriginal & 0x0F);
// set dpad back to dpad mode-specific state
state.dpad = dpadModeMask;