c-buttons cancel each other
Closed this issue · 7 comments
Hi.
Don't know if this is how the NSO N64 controller also behaves on pc or not, i don't own a switch to test there, but only one c-button can be active at any given time, even if you press two c-buttons of different axes (c-down and c-left for example).
I'm using the usb version on a regular raspberry pico with an original n64 controller.
Since the project currently mimics a Switch Pro Controller, and that uses an analog stick for c button inputs, I have to translate c buttons to an analog stick output. I could've handle adjacent c-buttons, but what would I send if opposite buttons or 3+ c buttons are pressed?
i understand that c-buttons are working as the right analog, but X and Y axis button combinations should be able to be pressed together.
as for same axis c-buttons, there are 3 ways to handle that kind of situation:
- cancel out: if you press c-up and c-down, both would be ignored.
- second button is cancelled: if you press c-up and then c-down, c-up would register and c-down would be ignored.
- second button wins: if you press c-up and then c-down, c-up is ignored while c-down is pressed and only c-down is registered, when c-down is released, c-up is registered again.
i think the most accepted way is the second one, but to maintain current behavior the first option is best.
another solution would be to map c-left and c-down to Y and X respectively and leave c-up and c-right on the stick, this matches NSO mappings.
i managed to add the diagonals and found a solution for opposite directions by configuring c-up+down to be c-up and X and c-left+right to be c-right and Y.
first added the missing defines for the c-buttons in N64Controller.h:
#define N64_MASK_C_UP 0x8
#define N64_MASK_C_UPRIGHT 0x9
#define N64_MASK_C_RIGHT 0x1
#define N64_MASK_C_DOWNRIGHT 0x5
#define N64_MASK_C_DOWN 0x4
#define N64_MASK_C_DOWNLEFT 0x6
#define N64_MASK_C_LEFT 0x2
#define N64_MASK_C_UPLEFT 0xA
#define N64_MASK_C_UPDOWN 0xC
#define N64_MASK_C_LEFTRIGHT 0x3
then added the extra switches in N64Controller.cpp:
switch (N64_MASK_C & _controllerState[1]) {
case N64_MASK_C_UP:
ry = SWITCH_JOYSTICK_MAX;
break;
case N64_MASK_C_DOWN:
ry = SWITCH_JOYSTICK_MIN;
break;
case N64_MASK_C_LEFT:
rx = SWITCH_JOYSTICK_MIN;
break;
case N64_MASK_C_RIGHT:
rx = SWITCH_JOYSTICK_MAX;
break;
case N64_MASK_C_UPLEFT:
rx = SWITCH_JOYSTICK_MIN;
ry = SWITCH_JOYSTICK_MAX;
break;
case N64_MASK_C_DOWNLEFT:
rx = SWITCH_JOYSTICK_MIN;
ry = SWITCH_JOYSTICK_MIN;
break;
case N64_MASK_C_UPRIGHT:
rx = SWITCH_JOYSTICK_MAX;
ry = SWITCH_JOYSTICK_MAX;
break;
case N64_MASK_C_DOWNRIGHT:
rx = SWITCH_JOYSTICK_MAX;
ry = SWITCH_JOYSTICK_MIN;
break;
case N64_MASK_C_UPDOWN:
ry = SWITCH_JOYSTICK_MAX;
switchReport->buttons[0] = SWITCH_MASK_X;
break;
case N64_MASK_C_LEFTRIGHT:
rx = SWITCH_JOYSTICK_MAX;
switchReport->buttons[0] = SWITCH_MASK_Y;
break;
like that, you have no conflicts and additionally you get access to the X and Y buttons.
i can send you a pull request with the changes if you like.
@DavidPagels, @Sakitoshi
I'm having issues with the C-Buttons and this fix isn't included in the latest release. Would it be possible to provide a compiled build with this fix in it? Thanks in advance!
@BSeraph i have it compiled on my repo https://github.com/Sakitoshi/retro-pico-switch/releases
i have been experimenting adding mario 64 all-stars compatibility and an analog stick curve better suited for gamecube style analog replacements. those hopefully will come soon™.
Thank you so much! I'm testing this on MiSTer FPGA, for N64 Controllers. The C-buttons are unuseable on it on the standard Right Stick mode, (for some reason they don't register at all) but they work perfectly via the Button Mode. Is there a way to make the Button mode the default mode, or does it have to reset everytime on boot?
i don't know how to make it persistent yet, but the default mode can be easily changed by modifying https://github.com/Sakitoshi/retro-pico-switch/blob/70d720f1ee5af70bfdc9371a5e0e856761d2b68c/include/N64Controller.h#L25 to 1 and compiling.