From 3ef3789f58270a89c7a046a17654a1b022d84c13 Mon Sep 17 00:00:00 2001 From: toaster <rollerorbital@gmail.com> Date: Fri, 26 Aug 2022 19:09:46 +0100 Subject: [PATCH] Gamepad improvements for menus * For left stick up/down/left/right input, allow holding a direction down to move continuously in a direction at a rate of 7 steps per second per axis * Now supports accel axis being used for the Enter key/"accept" in menus, to mirror how an accel BUTTON bind will be used as an Enter event. --- src/m_menu.c | 91 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 28 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 2fd5bc217..29585827d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2517,8 +2517,8 @@ boolean M_Responder(event_t *ev) { INT32 ch = -1; // INT32 i; - static tic_t joywait = 0, mousewait = 0; - static INT32 pjoyx = 0, pjoyy = 0; + static tic_t joywaitx = 0, joywaity = 0, joywaitaccel = 0, mousewait = 0; + static INT32 pjoyx = 0, pjoyy = 0, pjoyaccel = 0; static INT32 pmousex = 0, pmousey = 0; static INT32 lastx = 0, lasty = 0; void (*routine)(INT32 choice); // for some casting problem @@ -2569,48 +2569,83 @@ boolean M_Responder(event_t *ev) } else if (menuactive) { - if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) + tic_t thistime = I_GetTime(); + if (ev->type == ev_joystick) { const INT32 jxdeadzone = ((JOYAXISRANGE-1) * max(cv_xdeadzone.value, FRACUNIT/2)) >> FRACBITS; const INT32 jydeadzone = ((JOYAXISRANGE-1) * max(cv_ydeadzone.value, FRACUNIT/2)) >> FRACBITS; - if (ev->data3 != INT32_MAX) + INT32 accelaxis = abs(cv_moveaxis.value); + if (ev->data1 == 0) { - if (Joystick.bGamepadStyle || abs(ev->data3) > jydeadzone) + if (ev->data3 != INT32_MAX) { - if (ev->data3 < 0 && pjoyy >= 0) + if (Joystick.bGamepadStyle || abs(ev->data3) > jydeadzone) { - ch = KEY_UPARROW; - joywait = I_GetTime() + NEWTICRATE/7; + if (joywaity < thistime) + { + ch = (ev->data3 < 0) ? KEY_UPARROW : KEY_DOWNARROW; + joywaity = thistime; + if (pjoyy == 0 // no previous input? + || ((ev->data3 < 0) == (pjoyy < 0))) // same direction as the current one? + joywaity += NEWTICRATE/7; + } + pjoyy = ev->data3; } - else if (ev->data3 > 0 && pjoyy <= 0) + else + pjoyy = 0; + } + + if (ev->data2 != INT32_MAX && joywaitx < thistime) + { + if (Joystick.bGamepadStyle || abs(ev->data2) > jxdeadzone) { - ch = KEY_DOWNARROW; - joywait = I_GetTime() + NEWTICRATE/7; + if (joywaity < thistime) + { + ch = (ev->data2 < 0) ? KEY_LEFTARROW : KEY_RIGHTARROW; + joywaity = thistime; + if (pjoyx == 0 // no previous input? + || ((ev->data2 < 0) == (pjoyx < 0))) // same direction as the current one? + joywaity += NEWTICRATE/7; + } + pjoyx = ev->data2; } - pjoyy = ev->data3; + else + pjoyx = 0; } - else - pjoyy = 0; } - - if (ev->data2 != INT32_MAX) + else if (!(accelaxis > JOYAXISSET*2 || accelaxis == 0)) { - if (Joystick.bGamepadStyle || abs(ev->data2) > jxdeadzone) + // The following borrows heavily from Joy1Axis. + const boolean xmode = (accelaxis%2); + INT32 retaxis = 0; + if (!xmode) + accelaxis--; + accelaxis /= 2; + if (ev->data1 == accelaxis) { - if (ev->data2 < 0 && pjoyx >= 0) - { - ch = KEY_LEFTARROW; - joywait = I_GetTime() + NEWTICRATE/17; - } - else if (ev->data2 > 0 && pjoyx <= 0) + const INT32 jacceldeadzone = xmode ? jxdeadzone : jydeadzone; + retaxis = xmode ? ev->data2 : ev->data3; + if (retaxis != INT32_MAX) { - ch = KEY_RIGHTARROW; - joywait = I_GetTime() + NEWTICRATE/17; + if (cv_moveaxis.value < 0) + retaxis = -retaxis; + + if (Joystick.bGamepadStyle || abs(retaxis) > jacceldeadzone) + { + if (joywaitaccel < thistime) + { + ch = KEY_ENTER; + joywaitaccel = thistime; + if (pjoyaccel == 0 // no previous input? + || ((retaxis < 0) == (pjoyaccel > 0))) // same direction as the current one? + joywaitaccel += NEWTICRATE/3; + } + pjoyaccel = retaxis; + } + else + pjoyaccel = 0; } - pjoyx = ev->data2; } - else - pjoyx = 0; } } else if (ev->type == ev_mouse && mousewait < I_GetTime()) -- GitLab