
What's working already?
- I changed the gamepad input on all platforms to use the SDL gamecontroller API. This API abstracts the usual numbered buttons to provide a single controller layout which looks like an Xbox controller. This allows us to create more advanced mappings which can use all of the available buttons, sticks and triggers on the controller. This also makes XInput controllers such as the Xbox and Steam controllers available on Windows. (I didn't try building the code on Windows yet.)
- I made analog input from the gamepad sticks and triggers available to the script. There already was a
strength
parameter, but it was only updated once when moving the stick. With my changes, the PlayerControl() function continuously receives stick movement events. Additionally, the sticks and triggers still send regular "key down" and "key up" events for cases where analog input isn't needed (for example menus).- Make
GetPlayerControlState()
query the current position of analog sticks and not the emulated button state. (optional via third parameter)- Improve main menu controls with the gamepad. Previously, these controls used a simple mapping heuristic with odd/even buttons etc. This isn't necessary anymore because we know exactly what the controller looks like. The main menu can now be controlled with the left stick or the dpad and the A/B buttons.
- Implement controller rumbling / force feedback (the simple rumbling provided by SDL is probably enough for now): StartRumble(int plr, int strength, int length) and StopRumble(int plr)
- Documentation. The
strength
parameter to PlayerControl() now receives the full range 0-32767/32768 exposed by SDL. The release
flag has been replaced with a status parameter with the possible values CONS_Down, CONS_Up, CONS_Moved
. Third parameter of GetPlayerControlState()
makes the function query the current strength of an analog stick or trigger. StartRumble/StopRumble.- Automatic controller selection and hot plugging. The available controllers are automatically distributed among all players with gamepad controls. It is possible to start a game without a gamepad, controls work as soon as a controller is plugged in. When removing a controller while playing, the game is paused and controls continue to work after plugging the controller back in.
- Controlling multiple players with gamepads. There are a few issues with split screen play (broken HUD, music), but the gamepad controls work fine.
Todo list
- Implement analog movement and aiming in script. Create a good controller mapping which is competitive with keyboard/mouse controls. (Would be cool if someone who's familiar with the existing gamepad controls could help here.)
- Improve control device selection. The current method where the device number of the gamepad is baked into the control scheme doesn't make a lot of sense. There probably should be a separate player selection screen when starting a game both locally and over the network. On this screen, each player would select their player file with the controller or keyboard/mouse they want to play with. (I will probably need some help here as well.)
- Re-enable split-screen playing. Currently, it isn't possible to select more than one player at once.
- Code review: I'm new to engine modifications so I don't really know whether my changes actually make sense :)
- Improve main menu UX with keyboard and controller. For example, when leaving a scenario folder, the selection bar should already be on the folder we just left. There are also some things which are possible with the keyboard, but lack proper gamepad bindings (e.g. crew selection).

>There already was a strength parameter, but it was only updated once when moving the stick. With my changes, the PlayerControl() function continuously receives stick movement events.
Why? IIRC if the mouse does also not spawn a new mouse event every frame even if it is not moved, right?
> This isn't necessary anymore because we know exactly what the controller looks like.
Does this mean the game will only work with XBOX like controllers? What about PS-like controllers?

>Why? IIRC if the mouse does also not spawn a new mouse event every frame even if it is not moved, right?
I'm not sure what you're trying to say there, but I can explain a bit more: Previously, the analog sticks were translated to button presses. Think of a mouse that would only send a single event "left" if you're moving it to the left and "up" when moving it back. That's not enough to do get the precise location of the mouse cursor, or the position of the analog stick. (It may be enough for mouse input as the cursor location usually only matters when clicking, but that's an optimization we cannot do for analog sticks.)
Now, every time the controller sends an updated stick position, the new position is sent to the script. If you don't move any sticks or triggers, no calls are made. However, the sensors are so sensitive that the position will even change slightly if you're just holding the controller in the hand without touching any of the sticks. If it turns out that we have too may events, we could introduce a "minimum movement" threshold.
>What about PS-like controllers?
This is mainly about the presence of buttons and sticks, not about the exact layout. For our purposes, a PS controller is the same thing. The only disadvantage you'll have with a PS controller is that the X/Y/A/B button labeling does not match. That's still better than the previous button numbering which matched neither the PS controller nor the Xbox controller.

XBox, PS, Steam?


I didn't know that XBox and Steam controller buttons are labeled the same.


But I realized that this layout which I thought of as "PS alike" is as much PS alike as Xbox or Steam controllers.


But I guess as long as I have two analog sticks, one arrow pad and four buttons (and possibly additional four on the rear), I should be fine?

It would be interesting to hear whether this actually works - I only have XInput controllers which don't need any mapping (because they only support the Xbox controller layout).

I have already used the Big Picture mode with that gamepad and I can't remember having to explicitely configure it beforehand


Probably something in the PUA. Alternatively if we want to use standard geometric shapes without specially marking them as "gamepad buttons" in the font, U+25A1 WHITE SQUARE "□", U+25B3 WHITE UP-POINTING TRIANGLE "△", U+25CB WHITE CIRCLE "○", U+274C CROSS MARK "❌"?

Yeah but I feel we should mark them differently so we can render them in the proper color.


Since when does Icon:Name work? I still wanted to use some icons for the tutorial messages.



I think my changes are still beneficial as they allow script authors to treat gamepad sticks and triggers as buttons if that's all they need, while still having access to the raw controller state.

I think this is done as far as the most important engine changes go. The remaining todos there (improved main menu controls, gamepad selection when multiple players use gamepad controls) would be nice to have, but aren't very important (players can use a mouse for things not accessible with the controllers, and can plug out controllers they don't want to use).
To make all of this actually useful, a lot of work on the script is necessary. Merging the engine changes will make snapshots available, making the script part easier.
For some reason, when I compile it, the game tells me there is no gamepad for my player and I should plug it in. (Linux, Controller)

It should definitely work on Linux with this controller, as that's exactly my test setup.
>Do you have SDL2 installed and did cmake report that it found SDL2?
Yes. I hope its normal that cmake colors all lines red and when pressing Configure a second time, all lines become white. I wait for snapshots, it is likely I'm doing something wrong anyway.

You could try to compile this tool, it uses the same SDL2 API to talk to the controller. It should print something like this (the GUID will obviously be different):
% sdl2-jstest -l
Found 1 joystick(s)
Joystick Name: 'Microsoft X-Box 360 pad'
Joystick GUID: 030000005e0400008e02000014010000
Joystick Number: 0
Number of Axes: 6
Number of Buttons: 11
Number of Hats: 1
Number of Balls: 0
GameController:
Name: 'XInput Controller'
Mapping: '(null)'
Additionally,
sdl2-jstest -g 0
should work and sdl2-jstest -r 0
should make your controller rumble (hint: pick it up before running).
[19:03 root .../sdl-jstest/build (master)]# ./sdl2-jstest -l
Found 1 joystick(s)
Joystick Name: 'Microsoft X-Box 360 pad'
Joystick GUID: 030000005e0400008e02000014010000
Joystick Number: 0
Number of Axes: 6
Number of Buttons: 11
Number of Hats: 1
Number of Balls: 0
GameController:
Name: 'X360 Controller'
Mapping: '030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,'
The other two commands worked fine, too. Nice rumble.
Yes it works everywhere I use it (Steam games & dolphin emulator). I also already tried a bunch of stuff like installing all packages that contain "sdl", using different USB slots and I've redone cmake&compile after installing that libcurse.
Found 1 joystick(s)
Joystick Name: 'Microsoft X-Box 360 pad'
Joystick GUID: 030000005e0400008e02000014010000
Joystick Number: 0
Number of Axes: 6
Number of Buttons: 11
Number of Hats: 1
Number of Balls: 0
GameController:
Name: 'X360 Controller'
Mapping: '030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,'
The other two commands worked fine, too. Nice rumble.
>Does the gamepad work correctly in other applications?
Yes it works everywhere I use it (Steam games & dolphin emulator). I also already tried a bunch of stuff like installing all packages that contain "sdl", using different USB slots and I've redone cmake&compile after installing that libcurse.
Working now! I noted that every time I start a scenario, I can't do anything and the log tells me that there is no controller. But when I end the scenario and start the same or another scenario, it works. When I close and restart OpenClonk after that, I have to do this again - the first try does never work here. I think it's been like that since you told me that OC can compile without SDL lol. I always closed OC when I noted that it does not work on the first try because I thought the success chance would be higher when restarting Clonk after changing something like switching usb slot e.g.

[17:01:24] OpenClonk
[17:01:24] Version: 8.0-alpha unix linux-x86_64 (876c31fc2e6f)
[...]
[17:01:24] Gamepad #0 connected: Microsoft X-Box 360 pad
[...]
[17:01:30] Game started.
[17:01:30] Player join: Test
[17:01:30] Test: Using gamepad #0.
[17:01:41] Gamepad #0 disconnected.
[17:01:41] Test: No gamepad available.
[17:01:45] Gamepad #1 connected: Microsoft X-Box 360 pad
[17:01:48] Test: Using gamepad #1.
Here are the logs:
#1 Start a scen, restart a scen.
#2 Remove and reconnect controller, then do the same as in #1. I repeated this because "Gamepad #1 connected" came twice -> Same result.
#1 Start a scen, restart a scen.
#2 Remove and reconnect controller, then do the same as in #1. I repeated this because "Gamepad #1 connected" came twice -> Same result.
Attachment: StartClonk_StartScenario_StartScenario.log (4k)
Attachment: StartClonk_ReplugController_StartScenari.log (4k)

(It should also work if you unpause the game after starting. It pauses the game automatically to give players a chance to plug their controller in. There's currently no way to unpause the game with the controller, but that will hopefully be possible in the future.)
Edit: I pushed a fix now. This also makes gamepad controls available in the main menu, provided that
GamepadGuiControl
is set in the configuration.



bool release
parameter is now an int with three possible values. However, this isn't used yet (only "key down" and "key up" events are passed through). This way, even the gamepad controlls work just (as badly) as before.
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill