From 03f62ded4ce5cfdd4a0d199d5aa877fa1a1ae691 Mon Sep 17 00:00:00 2001 From: deepthaw Date: Sun, 30 Jun 2024 02:02:49 -0500 Subject: [PATCH] Change in handling overlapping button presses (fixes issue #824) (#907) * Modifications to input handling to prevent held inputs from being overridden by an alternate input mapped to the same button. i.e. R-Type holding fire to charge special shot will not be disrupted if a secondary fire button is pressed, autofire or not. * Modifications to input handling to prevent held inputs from being overridden by an alternate input mapped to the same button. i.e. R-Type holding fire to charge special shot will not be disrupted if a secondary fire button is pressed, autofire or not. * Prevent held inputs from being disrupted by alternate inputs. i.e. in R-Type, if holding the fire button to charge a special shot, tapping an alternately assigned fire button will not cause the charge to stop. --- input.cpp | 29 ++++++++++++++++------------- user_io.cpp | 16 +++++++++------- user_io.h | 2 +- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/input.cpp b/input.cpp index 2f49773..d9c7310 100644 --- a/input.cpp +++ b/input.cpp @@ -1643,8 +1643,8 @@ static int keyrah_trans(int key, int press) static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int dev); static int kbd_toggle = 0; -static uint32_t joy[NUMPLAYERS] = {}; -static uint32_t autofire[NUMPLAYERS] = {}; +static uint64_t joy[NUMPLAYERS] = {}; // 0-31 primary mappings, 32-64 alternate +static uint64_t autofire[NUMPLAYERS] = {}; // 0-31 primary mappings, 32-64 alternate static uint32_t autofirecodes[NUMPLAYERS][BTN_NUM] = {}; static int af_delay[NUMPLAYERS] = {}; @@ -1840,12 +1840,12 @@ static void joy_apply_deadzone(int* x, int* y, const devInput* dev, const int st } static uint32_t osdbtn = 0; -static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int bnum, int dont_save = 0) +static void joy_digital(int jnum, uint64_t mask, uint32_t code, char press, int bnum, int dont_save = 0) { static char str[128]; - static uint32_t lastcode[NUMPLAYERS], lastmask[NUMPLAYERS]; + static uint32_t lastcode[NUMPLAYERS]; + static uint64_t lastmask[NUMPLAYERS]; int num = jnum - 1; - if (num < NUMPLAYERS) { if (jnum) @@ -1886,6 +1886,7 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int } if (!found && zero >= 0) autofirecodes[num][zero] = lastcode[num]; + autofire[num] = !found ? autofire[num] | lastmask[num] : autofire[num] & ~lastmask[num]; if (hasAPI1_5()) @@ -2127,6 +2128,7 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int { if (press) joy[num] |= mask; else joy[num] &= ~mask; + //user_io_digital_joystick(num, joy[num]); if (code) @@ -3290,14 +3292,15 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int if (input[dev].has_map == 3) Info("This joystick is not defined"); input[dev].has_map = 1; } - + for (uint i = 0; i < BTN_NUM; i++) { - if (ev->code == (input[dev].map[i] & 0xFFFF) || ev->code == (input[dev].map[i] >> 16)) - { + uint64_t mask = 0; + if (ev->code == (input[dev].map[i] & 0xFFFF)) mask = (uint64_t)1 << i; + else if (ev->code == (input[dev].map[i] >> 16)) mask = (uint64_t)1 << (i + 32); // 1 is uint32_t. i spent hours realizing this. + if (mask) { if (i <= 3 && origcode == ev->code) origcode = 0; // prevent autofire for original dpad - if (ev->value <= 1) joy_digital(input[dev].num, 1 << i, origcode, ev->value, i, (ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 1] || ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 2])); - + if (ev->value <=1) joy_digital(input[dev].num, mask, origcode, ev->value, i, (ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 1] || ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 2])); // support 2 simultaneous functions for 1 button if defined in 2 sets. No return. } } @@ -5663,7 +5666,7 @@ int input_poll(int getchar) static int af[NUMPLAYERS] = {}; static uint32_t time[NUMPLAYERS] = {}; - static uint32_t joy_prev[NUMPLAYERS] = {}; + static uint64_t joy_prev[NUMPLAYERS] = {}; int ret = input_test(getchar); if (getchar) return ret; @@ -5705,8 +5708,8 @@ int input_poll(int getchar) if (!time[i]) time[i] = GetTimer(af_delay[i]); int send = 0; - - int newdir = ((joy[i] & 0xF) != (joy_prev[i] & 0xF)); + int newdir = ((((uint32_t)(joy[i]) | (uint32_t)(joy[i] >> 32)) & 0xF) != (((uint32_t)(joy_prev[i]) | (uint32_t)(joy_prev[i] >> 32)) & 0xF)); + if (joy[i] != joy_prev[i]) { if ((joy[i] ^ joy_prev[i]) & autofire[i]) diff --git a/user_io.cpp b/user_io.cpp index 58130ce..37ce739 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -1697,21 +1697,23 @@ void user_io_r_analog_joystick(unsigned char joystick, char valueX, char valueY) } } -void user_io_digital_joystick(unsigned char joystick, uint32_t map, int newdir) +void user_io_digital_joystick(unsigned char joystick, uint64_t map, int newdir) { uint8_t joy = (joystick>1 || !joyswap) ? joystick : joystick ^ 1; - static int use32 = 0; - use32 |= map >> 16; - + // primary button mappings are in 31:0, alternate mappings are in 64:32. + // take the logical OR to ensure a held button isn't overriden + // by other mapping being pressed + uint32_t bitmask = (uint32_t)(map) | (uint32_t)(map >> 32); + use32 |= bitmask >> 16; spi_uio_cmd_cont((joy < 2) ? (UIO_JOYSTICK0 + joy) : (UIO_JOYSTICK2 + joy - 2)); - spi_w(map); - if(use32) spi_w(map >> 16); + spi_w(bitmask); + if(use32) spi_w(bitmask >> 16); DisableIO(); if (!is_minimig() && joy_transl == 1 && newdir) { - user_io_l_analog_joystick(joystick, (map & 2) ? 128 : (map & 1) ? 127 : 0, (map & 8) ? 128 : (map & 4) ? 127 : 0); + user_io_l_analog_joystick(joystick, (bitmask & 2) ? 128 : (bitmask & 1) ? 127 : 0, (bitmask & 8) ? 128 : (bitmask & 4) ? 127 : 0); } } diff --git a/user_io.h b/user_io.h index 50ab5a9..0abddce 100644 --- a/user_io.h +++ b/user_io.h @@ -203,7 +203,7 @@ void user_io_mouse(unsigned char b, int16_t x, int16_t y, int16_t w); void user_io_kbd(uint16_t key, int press); char* user_io_create_config_name(int with_ver = 0); int user_io_get_joy_transl(); -void user_io_digital_joystick(unsigned char, uint32_t, int); +void user_io_digital_joystick(unsigned char, uint64_t, int); void user_io_l_analog_joystick(unsigned char, char, char); void user_io_r_analog_joystick(unsigned char, char, char); void user_io_set_joyswap(int swap);