Button Sticking Bug / What controller do you use?

I thought it might beneficial to get a list of what controller(s) people use and whether they experience the button sticking bug with them. I was inspired by massiverican to create this after he mentioned that some people have never had an issue. My hope is that maybe we can build a consensus on which controllers are affected and which ones seem to be unaffected (if any).

Note: This is not a thread to bitch about the bug itself. Been there, done that. We all want Retroarch Wii to be the best it can be. Maybe this won’t help, but at least we can try.

So to start it off, I use the Classic Controller Pro, default mapping, and experience the bug 0-2 times per hour on average.

P.S. I suggest we stick to a similar formatting to make for easier consumption.

I use the Wiimote, CC pro and the older CC, wavebird GC controller Experiencing the bug at variable intervals.

Mostly after loading a different core. Could the core switching be related?

The Wavebird is the only controller for me that acts without a problem.

I get some playtime in tomorrow, I’ll test my CC, Wiimote, and wavebird. So just hitting buttons frantically in RGUI should do it right? lol. I really can’t remember it happening in-game though.

That’s how I’ve gotten it to trigger. I’ve been able to trigger it in RGUI and in game too.

Wii devs don’t want to help out, and we don’t know what is causing the issue.

Not much you can do in such a scene.No real way of knowing what is at fault either - unlike with a real SDK where you can at least assume it works out of the box.

This is somewhat obvious, but given that it appears to happen with different controllers regardless of which core is used, is it safe to assume that it’s a bug somewhere in the RetroArch code branch for the GUI itself? Which files on GitHub deal with input, specifically?

I posted here about the possibility of using HID compliant USB gamepads the same way nintendon’t does, and squarepusher said:

So if there is a problem, it might be there.

here’s lines 201-222 of gx_input.c:


static int16_t gx_input_state(void *data, const struct retro_keybind **binds,
      unsigned port, unsigned device,
      unsigned index, unsigned id)
{
   gx_input_t *gx = (gx_input_t*)data;

   if (port >= MAX_PADS)
      return 0;

   switch (device)
   {
      case RETRO_DEVICE_JOYPAD:
         if (binds[port][id].joykey >= CONSOLE_MENU_FIRST && binds[port][id].joykey <= CONSOLE_MENU_LAST)
            return gx_menu_input_state(binds[port][id].joykey, gx->pad_state[port]) ? 1 : 0;
         else
            return input_joypad_pressed(&gx_joypad, port, binds[port], id);;
      case RETRO_DEVICE_ANALOG:
         return input_joypad_analog(&gx_joypad, port, index, id, binds[port]);
      default:
         return 0;
   }
}

it looks like input_joypad_pressed and input_joypad_analog wind back to input_common.c:


bool input_joypad_pressed(const rarch_joypad_driver_t *driver,
      unsigned port, const struct retro_keybind *binds, unsigned key)
{
   if (!driver)
      return false;

   int joy_index = g_settings.input.joypad_map[port];
   if (joy_index < 0 || joy_index >= MAX_PLAYERS)
      return false;

   // Auto-binds are per joypad, not per player.
   const struct retro_keybind *auto_binds = g_settings.input.autoconf_binds[joy_index];

   if (!binds[key].valid)
      return false;

   uint64_t joykey = binds[key].joykey;
   if (joykey == NO_BTN)
      joykey = auto_binds[key].joykey;

   if (driver->button(joy_index, (uint16_t)joykey))
      return true;

   uint32_t joyaxis = binds[key].joyaxis;
   if (joyaxis == AXIS_NONE)
      joyaxis = auto_binds[key].joyaxis;

   int16_t axis = driver->axis(joy_index, joyaxis);
   float scaled_axis = (float)abs(axis) / 0x8000;
   return scaled_axis > g_settings.input.axis_threshold;
}


int16_t input_joypad_analog(const rarch_joypad_driver_t *driver,
      unsigned port, unsigned index, unsigned id, const struct retro_keybind *binds)
{
   if (!driver)
      return 0;

   int joy_index = g_settings.input.joypad_map[port];
   if (joy_index < 0 || joy_index >= MAX_PLAYERS)
      return 0;

   // Auto-binds are per joypad, not per player.
   const struct retro_keybind *auto_binds = g_settings.input.autoconf_binds[joy_index];

   unsigned id_minus = 0;
   unsigned id_plus = 0;
   input_conv_analog_id_to_bind_id(index, id, &id_minus, &id_plus);

   const struct retro_keybind *bind_minus = &binds[id_minus];
   const struct retro_keybind *bind_plus = &binds[id_plus];
   if (!bind_minus->valid || !bind_plus->valid)
      return 0;

   uint32_t axis_minus = bind_minus->joyaxis;
   uint32_t axis_plus = bind_plus->joyaxis;
   if (axis_minus == AXIS_NONE)
      axis_minus = auto_binds[id_minus].joyaxis;
   if (axis_plus == AXIS_NONE)
      axis_plus = auto_binds[id_plus].joyaxis;

   int16_t pressed_minus = abs(driver->axis(joy_index, axis_minus));
   int16_t pressed_plus = abs(driver->axis(joy_index, axis_plus));

   int16_t res = pressed_plus - pressed_minus;

   if (res != 0)
      return res;

   uint64_t key_minus = bind_minus->joykey;
   uint64_t key_plus = bind_plus->joykey;
   if (key_minus == NO_BTN)
      key_minus = auto_binds[id_minus].joykey;
   if (key_plus == NO_BTN)
      key_plus = auto_binds[id_plus].joykey;

   int16_t digital_left = driver->button(joy_index, (uint16_t)key_minus) ? -0x7fff : 0;
   int16_t digital_right = driver->button(joy_index, (uint16_t)key_plus) ? 0x7fff : 0;
   return digital_right + digital_left;
}

Is there some sort of clear state callback in the button press event that isn’t firing?

Bumping the post above. Hoping to help find some answers for those who are having issues during gameplay.