@@ -203,11 +203,13 @@ class ReflexInputPsx : public RZInputModule {
203203 state[outputIndex].dpad = (state[outputIndex].dpad | specialDpadMask) & 0xF ;
204204 }
205205
206- bool loopDualShock () {
207- static byte lastLX[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
208- static byte lastLY[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
209- static byte lastRX[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
210- static byte lastRY[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
206+ bool loopDualShock () {
207+ static byte lastLX[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
208+ static byte lastLY[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
209+ static byte lastRX[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
210+ static byte lastRY[] = { ANALOG_IDLE_VALUE, ANALOG_IDLE_VALUE };
211+ static uint8_t lastStableDpad[] = { 0 , 0 };
212+ static uint16_t lastStableButtons[] = { 0 , 0 };
211213
212214 #ifdef ENABLE_REFLEX_PAD
213215 static PsxControllerProtocol lastPadType[] = { PSPROTO_UNKNOWN, PSPROTO_UNKNOWN };
@@ -219,8 +221,8 @@ class ReflexInputPsx : public RZInputModule {
219221 byte analogY = ANALOG_IDLE_VALUE;
220222 // word convertedX, convertedY;
221223
222- const bool digitalStateChanged = psx-> buttonsChanged (); // check if any digital value changed (dpad and buttons)
223- bool stateChanged = digitalStateChanged ;
224+ bool digitalStateChanged = false ;
225+ bool stateChanged = false ;
224226
225227 const PsxControllerProtocol proto = psx->getProtocol ();
226228
@@ -244,10 +246,10 @@ class ReflexInputPsx : public RZInputModule {
244246
245247// uint16_t buttonData = 0;
246248 // controller buttons
247- state[outputIndex].buttons = 0
248- | (psx->buttonPressed (PSB_CROSS) ? GAMEPAD_MASK_B1 : 0 ) // Generic: K1, Switch: B, Xbox: A
249- | (psx->buttonPressed (PSB_CIRCLE) ? GAMEPAD_MASK_B2 : 0 ) // Generic: K2, Switch: A, Xbox: B
250- | (psx->buttonPressed (PSB_SQUARE) ? GAMEPAD_MASK_B3 : 0 ) // Generic: P1, Switch: Y, Xbox: X
249+ state[outputIndex].buttons = 0
250+ | (psx->buttonPressed (PSB_CROSS) ? GAMEPAD_MASK_B1 : 0 ) // Generic: K1, Switch: B, Xbox: A
251+ | (psx->buttonPressed (PSB_CIRCLE) ? GAMEPAD_MASK_B2 : 0 ) // Generic: K2, Switch: A, Xbox: B
252+ | (psx->buttonPressed (PSB_SQUARE) ? GAMEPAD_MASK_B3 : 0 ) // Generic: P1, Switch: Y, Xbox: X
251253 | (psx->buttonPressed (PSB_TRIANGLE) ? GAMEPAD_MASK_B4 : 0 ) // Generic: P2, Switch: X, Xbox: Y
252254 | (psx->buttonPressed (PSB_L1) ? GAMEPAD_MASK_L1 : 0 ) // Generic: P4, Switch: L, Xbox: LB
253255 | (psx->buttonPressed (PSB_R1) ? GAMEPAD_MASK_R1 : 0 ) // Generic: P3, Switch: R, Xbox: RB
@@ -256,8 +258,17 @@ class ReflexInputPsx : public RZInputModule {
256258 | (psx->buttonPressed (PSB_SELECT) ? GAMEPAD_MASK_S1 : 0 ) // Generic: Select, Switch: -, Xbox: View
257259 | (psx->buttonPressed (PSB_START) ? GAMEPAD_MASK_S2 : 0 ) // Generic: Start, Switch: +, Xbox: Menu
258260 | (psx->buttonPressed (PSB_L3) ? GAMEPAD_MASK_L3 : 0 ) // All: Left Stick Click
259- | (psx->buttonPressed (PSB_R3) ? GAMEPAD_MASK_R3 : 0 ) // All: Right Stick Click
260- ;
261+ | (psx->buttonPressed (PSB_R3) ? GAMEPAD_MASK_R3 : 0 ) // All: Right Stick Click
262+ ;
263+
264+ // Ignore obvious one-frame D-pad corruption without changing normal input latency.
265+ if (specialDpadMask == 0x0
266+ && state[outputIndex].dpad == (GAMEPAD_MASK_UP | GAMEPAD_MASK_DOWN | GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT)) {
267+ state[outputIndex].dpad = lastStableDpad[outputIndex];
268+ }
269+ digitalStateChanged = state[outputIndex].dpad != lastStableDpad[outputIndex]
270+ || state[outputIndex].buttons != lastStableButtons[outputIndex];
271+ stateChanged = digitalStateChanged;
261272
262273
263274 // if(proto != PSPROTO_DIGITAL)
@@ -294,8 +305,10 @@ class ReflexInputPsx : public RZInputModule {
294305 if (lastRX[outputIndex] != analogX || lastRY[outputIndex] != analogY)
295306 stateChanged = true ;
296307
297- lastRX[outputIndex] = analogX;
298- lastRY[outputIndex] = analogY;
308+ lastRX[outputIndex] = analogX;
309+ lastRY[outputIndex] = analogY;
310+ lastStableDpad[outputIndex] = state[outputIndex].dpad ;
311+ lastStableButtons[outputIndex] = state[outputIndex].buttons ;
299312
300313 if (stateChanged) {
301314 #ifdef ENABLE_REFLEX_PAD
@@ -497,10 +510,11 @@ class ReflexInputPsx : public RZInputModule {
497510 }
498511 }
499512
500- bool read () override {
501- static bool isReadSuccess[] = {false ,false };
502- static bool isEnabled[] = {false ,false };
503- bool stateChanged = false ;
513+ bool read () override {
514+ static bool isReadSuccess[] = {false ,false };
515+ static bool isEnabled[] = {false ,false };
516+ static uint8_t readFailCount[] = {0 ,0 };
517+ bool stateChanged = false ;
504518
505519 outputIndex = 0 ;
506520
@@ -603,28 +617,32 @@ class ReflexInputPsx : public RZInputModule {
603617 if (!isEnabled[i])
604618 continue ;
605619
606- if (!haveController[i]) {
607- if (psx->begin ()) {
608- haveController[i] = true ;
609- tryEnableRumble ();
610- ShowDefaultPadPsx (i, psx->getProtocol ());
611- }
612- } else {
620+ if (!haveController[i]) {
621+ if (psx->begin ()) {
622+ haveController[i] = true ;
623+ readFailCount[i] = 0 ;
624+ tryEnableRumble ();
625+ ShowDefaultPadPsx (i, psx->getProtocol ());
626+ }
627+ } else {
613628 const PsxControllerProtocol proto = psx->getProtocol ();
614629 if (lastProto[i] != proto)
615630 tryEnableRumble ();
616631 lastProto[i] = proto;
617632 #ifdef PSX_COMBINE_RUMBLE
618633 psx->setRumble ((rumble[i].left_power | rumble[i].right_power ) != 0x0 , (rumble[i].left_power | rumble[i].right_power ));
619- #else
620- psx->setRumble (rumble[i].right_power != 0x0 , rumble[i].left_power );
621- #endif
622- isReadSuccess[i] = psx->read ();
623- if (!isReadSuccess[i]){ // debug (F("Controller lost.")); debug (F(" last values: x = ")); debug (lastX); debug (F(", y = ")); debugln (lastY);
624- haveController[i] = false ;
625- ShowDefaultPadPsx (i, PSPROTO_UNKNOWN);
626- }
627- }
634+ #else
635+ psx->setRumble (rumble[i].right_power != 0x0 , rumble[i].left_power );
636+ #endif
637+ isReadSuccess[i] = psx->read ();
638+ if (isReadSuccess[i]) {
639+ readFailCount[i] = 0 ;
640+ } else if (++readFailCount[i] >= 2 ){ // debug (F("Controller lost.")); debug (F(" last values: x = ")); debug (lastX); debug (F(", y = ")); debugln (lastY);
641+ haveController[i] = false ;
642+ readFailCount[i] = 0 ;
643+ ShowDefaultPadPsx (i, PSPROTO_UNKNOWN);
644+ }
645+ }
628646 if (isGuncon)// only use first port for guncon
629647 break ;
630648 }
0 commit comments