Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[joystick] Wii: introduce split-joysticks option #30

Open
wants to merge 1 commit into
base: ogc-sdl-1.2
Choose a base branch
from

Conversation

mardy
Copy link
Collaborator

@mardy mardy commented Oct 9, 2023

Add an option to present the Wii controller expansions as independent controllers.

Introduce the SDL_WII_JOYSTICK_SPLIT environment variable, which, if set to "1" before initializing the joystick subsystem, changes the number of reported joysticks from 8 to 12:

  • Joysticks 0-3: the 4 wiimotes
  • Joysticks 4-7: the 4 expansions
  • Joysticks 8-11: the 4 GameCube controllers

This is for the benefits of those applications which need to alter their behaviour depending on the controller that generated the event, or even to increase the number of possible players in a game, assuming that it needs just the directional keys and a couple of buttons.

Due to the refactoring, some changes were made to the default non-split view of the controllers, a couple of which are actually bugfixes:

  • When a classic controller is being used, the arrow keys (hat) on the wiimote also work, delivering the same events as the arrow keys on the classic controller (previously, pressing them would produce no effect whatsoever, which looks like a bug).

  • When an expansion is detached, its axes are reset to 0; previously, they would continue to be reported as moving, therefore rendering the controller unusable.

  • Naming of the Wii controllers has been extended and now looks as following (assuming that we are operating on the second wiimote), depending on the expansion attached:

    • Wiimote 1 (if no expansion is attached)
    • Wiimote 1 + Nunchuck
    • Wiimote 1 + Classic
    • Wiimote 1 + Guitar Hero 3
    • Wiimote 1 + Balance board

    This can help applications to map buttons and axes to their proper function.

All these changes can be easily tested with this application; both modes of operation can be tested, just by commenting out the

setenv("SDL_WII_JOYSTICK_SPLIT", "1", 1);

line in the init() function, if you want to check the non-split functionality. The application can also be built against the devkitPro version of the SDL, for a comparison. Please let me know if you'd like the binary DOL file for quicker testing.

WinterMute pushed a commit that referenced this pull request Oct 27, 2023
…pened

This was the callstack:
    frame #3: 0x00000001004e1930 libSDL3.1.0.0.dylib`IOS_AddJoystickDevice(controller=0x0000600003b0c000, accelerometer=SDL_FALSE) at SDL_mfijoystick.m:528:14
    frame #4: 0x00000001004e1a54 libSDL3.1.0.0.dylib`__IOS_JoystickInit_block_invoke(.block_descriptor=0x0000000100547760, note=@"GCControllerDidConnectNotification") at SDL_mfijoystick.m:673:45
    frame #5: 0x000000018601e578 CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 128
    frame #6: 0x00000001860bc074 CoreFoundation`___CFXRegistrationPost_block_invoke + 88
    frame #7: 0x00000001860bbfbc CoreFoundation`_CFXRegistrationPost + 440
    frame #8: 0x0000000185fefbac CoreFoundation`_CFXNotificationPost + 708
    frame #9: 0x0000000186edc72c Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 88
    frame #10: 0x000000019b054a18 GameController`__60-[_GCControllerManagerAppClient _onqueue_publishController:]_block_invoke + 156
    frame #11: 0x0000000185dc19dc libdispatch.dylib`_dispatch_call_block_and_release + 32
    frame #12: 0x0000000185dc3504 libdispatch.dylib`_dispatch_client_callout + 20
    frame #13: 0x0000000185dd1d1c libdispatch.dylib`_dispatch_main_queue_drain + 928
    frame #14: 0x0000000185dd196c libdispatch.dylib`_dispatch_main_queue_callback_4CF + 44
    frame #15: 0x000000018606ad6c CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
    frame #16: 0x00000001860287ec CoreFoundation`__CFRunLoopRun + 2036
    frame #17: 0x00000001860278a4 CoreFoundation`CFRunLoopRunSpecific + 612
    frame #18: 0x00000001003b1194 libSDL3.1.0.0.dylib`process_pending_events at hid.c:509:9
    frame #19: 0x00000001003aebe8 libSDL3.1.0.0.dylib`PLATFORM_hid_open_path(path="USB_054c_05c4_0x11a104290", bExclusive=0) at hid.c:823:2
    frame #20: 0x00000001003b051c libSDL3.1.0.0.dylib`SDL_hid_open_path_REAL(path="USB_054c_05c4_0x11a104290", bExclusive=0) at SDL_hidapi.c:1419:19
    frame #21: 0x00000001004dabdc libSDL3.1.0.0.dylib`HIDAPI_SetupDeviceDriver(device=0x0000600003518000, removed=0x000000016fdfee3c) at SDL_hidapijoystick.c:399:19
    frame #22: 0x00000001004da890 libSDL3.1.0.0.dylib`HIDAPI_AddDevice(info=0x000060000212c2d0, num_children=0, children=0x0000000000000000) at SDL_hidapijoystick.c:843:5
    frame #23: 0x00000001004d9148 libSDL3.1.0.0.dylib`HIDAPI_UpdateDeviceList at SDL_hidapijoystick.c:1000:21
    frame #24: 0x00000001004d9940 libSDL3.1.0.0.dylib`HIDAPI_JoystickDetect at SDL_hidapijoystick.c:1205:13
    frame #25: 0x00000001003bc6d8 libSDL3.1.0.0.dylib`SDL_UpdateJoysticks_REAL at SDL_joystick.c:1703:9
    frame #26: 0x00000001003a13a8 libSDL3.1.0.0.dylib`SDL_PumpEventsInternal(push_sentinel=SDL_FALSE) at SDL_events.c:855:9
    frame #27: 0x00000001003a1340 libSDL3.1.0.0.dylib`SDL_PumpEvents_REAL at SDL_events.c:879:5
    frame #28: 0x000000010038b380 libSDL3.1.0.0.dylib`SDL_PumpEvents at SDL_dynapi_procs.h:572:1
    frame #29: 0x0000000100004524 testgamepad`loop + 40
    frame #30: 0x00000001000063d8 testgamepad`main + 2140

(cherry picked from commit a9650d4)
@WinterMute
Copy link
Member

It seems kind of odd to me to treat wiimote expansions as separate joysticks. What's the reasoning for this?

For behaviour of wiimotes with expansions it's probably worth looking at what official games typically do. We should probably look into figuring out some kind of guidelines for controller usage (as Nintendo do although clearly we don't need to be as proscriptive) It also seems slightly odd to have wiimote buttons produce the same events as attached classic controllers. Have you looked at how official games use expansions?

I think there are too many changes here for a single commit. The axis reset seems like an obvious fix that can & should be a single commit.

@mardy
Copy link
Collaborator Author

mardy commented Jan 1, 2024

It seems kind of odd to me to treat wiimote expansions as separate joysticks. What's the reasoning for this?

It is odd indeed, and as far as I know no official game uses this: my guess is that for safety reasons Nintendo prohibited (or at least discouraged) this usage of controllers, because if players get too excited they could make some movements that would pull the cord a bit too much and damage it (or the connector).

There are, anyway, a few requests for this feature (a quick search led me to this and this. In my case, I'm developing a simple top-down car game (https://gitlab.com/mardy/wicked-sliders) which can be played with just the directional arrows and two buttons, so this feature would allow local multiplayer even for people that have just a wiimote + expansion.

I understand that it's not a common use case, but that's why I'm hiding it behind an environment variable.

I think there are too many changes here for a single commit. The axis reset seems like an obvious fix that can & should be a single commit.

I agree. I'll file a separate PR for that. As for the split-joystick functionality, it's already part of the SDL2 port that I'm working on :-)

@halotroop2288
Copy link

This sometimes makes sense for Classic Controllers but not for the Nunchuck.

It would be very nice to be able to play multiplayer on simple d-pad + 2 button games using just a Wiimote and Wii Classic (Pro) Controller or (S)NES Classic controller.

But it would also make backwards compatibility quite awkward for games that would otherwise fit fine into the standard Wiimote and Nunchuck configuration.
Consider that some engines which might implement SDL might not have the ability to treat multiple gamepads as one input device, or might abstract that information away from the engine user and make it confusing to develop for.

@mardy
Copy link
Collaborator Author

mardy commented Jan 19, 2024

It would be very nice to be able to play multiplayer on simple d-pad + 2 button games using just a Wiimote and Wii Classic (Pro) Controller or (S)NES Classic controller.

Indeed. For the nunchuck this is much less useful, as you rightfully pointed out, but there are still games that can be played with just a directional control and two buttons (I'm working on one at the moment, and that's what inspired this PR).

But it would also make backwards compatibility quite awkward for games that would otherwise fit fine into the standard Wiimote and Nunchuck configuration. Consider that some engines which might implement SDL might not have the ability to treat multiple gamepads as one input device, or might abstract that information away from the engine user and make it confusing to develop for.

I'm fully away of this, and that's why this split behaviour is only activated if the game sets an environment variable; otherwise, you'll get the normal behaviour.

Add an option to present the Wii controller expansions as independent
controllers.

Introduce the SDL_WII_JOYSTICK_SPLIT environment variable, which, if set
to "1" before initializing the joystick subsystem, changes the number of
reported joysticks from 8 to 12:

- Joysticks 0-3: the 4 wiimotes
- Joysticks 4-7: the 4 expansions
- Joysticks 8-11: the 4 GameCube controllers

This is for the benefits of those applications which need to alter their
behaviour depending on the controller that generated the event, or even
to increase the number of possible players in a game, assuming that it
needs just the directional keys and a couple of buttons.

Due to the refactoring, some changes were made to the default non-split
view of the controllers, a couple of which are actually bugfixes:

- When a classic controller is being used, the arrow keys (hat) on the
  wiimote also work, delivering the same events as the arrow keys on the
  classic controller (previously, pressing them would produce no effect
  whatsoever, which looks like a bug).

- When an expansion is detached, its axes are reset to 0; previously,
  they would continue to be reported as moving, therefore rendering the
  controller unusable.

- Naming of the Wii controllers has been extended and now looks as
  following (assuming that we are operating on the second wiimote),
  depending on the expansion attached:
  * `Wiimote 1` (if no expansion is attached)
  * `Wiimote 1 + Nunchuck`
  * `Wiimote 1 + Classic`
  * `Wiimote 1 + Guitar Hero 3`
  * `Wiimote 1 + Balance board`
  This can help applications to map buttons and axes to their proper
  function.
@mardy
Copy link
Collaborator Author

mardy commented May 28, 2024

I updated the branch to work with the consolidated joystick code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants