The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Joystick behaviour seriously flawed?
rainwarrior


Joined: 16 Oct 2013
Posts: 19
Location: Toronto, Canada
I tried 3 different gamepads with the SDL2 joystick system under Windows 7, and I'm getting some rather bizarre results. In SDL these same controllers worked exactly as I expected, but in SDL2 they are very broken. What has happened to this system? Is it currently under heavy revision?


Gamestop brand USB XBox 360 controller: "Controller (TSZ360 Pad)"
- Incorrectly has 6 axes (control panel has 5)
- Incorrectly has 15 buttons (control panel has 10)
- no hat (control panel shows d-pad as hat)
- Additionally, the d-pad is mapped to buttons 0-3, which is very unfortunate. (On every controller I've ever seen, at least button 0 is mapped to a sensible button. If you need a default button for the user to get through a menu, d-pad up is not an intuitive choice!)
- I tried using it as an SDL_GameController instead of an SDL_Joystick but the result was the same.
- In the past I've found this controller behaves identically to an XBox360 controller, though I do not currently have a microsoft branded 360 controller to compare against.


Retrolink SNES style gamepad: "USB Gamepad"
- Not an SDL_IsGameController, so unusable by the new Game Controller system.
- Axis 1 returns the axis 0 value, so I can only get "diagonal" input from this controller in SDL2.


RetroUSB SNES USB adapter with SNES control pad: "SNES"
- Not an SDL_IsGameController, so unusable by the new Game Controller system.
- This one actually worked as I expected. It does not have a hat, the d-pad is 2 axes, and all the buttons are coming through correctly.
rainwarrior


Joined: 16 Oct 2013
Posts: 19
Location: Toronto, Canada
Is there a flag or anything I could easily do to get the SDL joystick behaviour back in SDL2?
rainwarrior


Joined: 16 Oct 2013
Posts: 19
Location: Toronto, Canada
In SDL_SYS_JoystickOpen, I added:
Code:
joystickdevice->bXInputDevice = SDL_FALSE;

Doing this before that value is tested seems to get my 360 style gamepad working as expected again. I am not sure what's going on in the XInputDevice code path there, but it's a disaster for this controller in particular.

Still not sure why the retrolink pad is getting a duplicated X axis instead of X and Y.
rainwarrior


Joined: 16 Oct 2013
Posts: 19
Location: Toronto, Canada
I discovered the older MM implementation and enabled it by doing the following in SDL_windows_config.h:

1. Remove: #define SDL_JOYSTICK_DINPUT 1
2. Add: #define SDL_JOYSTICK_WINMM 1
3. Remove: #define SDL_HAPTIC_DINPUT 1
4. Add: #define SDL_HAPTIC_DISABLED 1

With this done, all of my problems using these gamepads are gone. They all operate as I expect.
Joystick behaviour seriously flawed?
Sik


Joined: 26 Nov 2011
Posts: 905
Except... that driver has just been removed in newer versions
(especially because many new controllers don't work properly with it -
their drivers simply refuse to report all buttons or axes).

2013/10/19, rainwarrior:
Quote:
I discovered the older MM implementation and enabled it by doing the
following in SDL_windows_config.h:

1. Remove: #define SDL_JOYSTICK_DINPUT 1
2. Add: #define SDL_JOYSTICK_WINMM 1
3. Remove: #define SDL_HAPTIC_DINPUT 1
4. Add: #define SDL_HAPTIC_DISABLED 1

With this done, all of my problems using these gamepads are gone. They all
operate as I expect.





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Mason Wheeler
Guest

...such as an XBox controller clone, which is what was originally mentioned.

It has 6 axes (2 for left stick, 2 for right stick, 1 for each trigger) and so if it
was trying to represent it as a system with 5 axes, that's a bug.


Mason



From: Sik the hedgehog
To:
Sent: Saturday, October 19, 2013 5:32 PM
Subject: Re: [SDL] Joystick behaviour seriously flawed?


Except... that driver has just been removed in newer versions(especially because many new controllers don't work properly with it -their drivers simply refuse to report all buttons or axes).2013/10/19, rainwarrior:> I discovered the older MM implementation and enabled it by doing the> following in SDL_windows_config.h:>> 1. Remove: #define SDL_JOYSTICK_DINPUT 1> 2. Add: #define SDL_JOYSTICK_WINMM 1> 3. Remove: #define SDL_HAPTIC_DINPUT 1> 4. Add: #define SDL_HAPTIC_DISABLED 1>> With this done, all of my problems using these gamepads are gone. They all> operate as I expect.>>>>>_______________________________________________SDL mailinghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
rainwarrior


Joined: 16 Oct 2013
Posts: 19
Location: Toronto, Canada
No, that's normal for MM and the 360 controller. The Microsoft 360 controller works exactly the same way. LT and RT are combined as a single axis (one add 0 to negative to the axis, one adds 0 to positive). The clone operates like the original in this respect.
Joystick behaviour seriously flawed?
Joseph Carter


Joined: 20 Sep 2013
Posts: 279
On Sat, Oct 19, 2013 at 10:28:06PM +0000, rainwarrior wrote:
Quote:
In SDL_SYS_JoystickOpen, I added:

Code:
joystickdevice->bXInputDevice = SDL_FALSE;


Doing this before that value is tested seems to get my 360 style gamepad working as expected again. I am not sure what's going on in the XInputDevice code path there, but it's a disaster for this controller in particular.

Still not sure why the retrolink pad is getting a duplicated X axis instead of X and Y.

Regarding the joystick mapping differently under XInput versus
DirectInput: Blame Microsoft. If you want to know what I mean by
that, read here:

http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx

And then curse them for ever and ever for deliberately making
triggers STUPID. Despite this idiocy, you'll find SDL does the
intelligent thing in its GameController API.

Which RetroLink pad have you got? I don't have one here to test, but
I might be willing to get one—they tend to be like $10 on Amazon. As
I have kind of made the joystick subsystem a hobby of mine lately…


Now, regarding SDL: If you want to use an XBox 360 controller (or
anything that is basically close enough), SDL 2.x has a great option
for you: GameController. Any XInput-compatible device will just work
for you using that API and be automatically and correctly mapped.

The API's a little verbose in its naming and enums, and the functions
all use Microsoftian lolomgwtfbbqVAR naming (which Sam won't let me
change into reasonable and descriptive names that make sense to the
rest of the world), but that's a documentation issue and I really
ought to get back to writing it at some point soon. :)

For some idea how to use it, have a look at test/testgamecontroller.c
(which I am completely rewriting—within the next week or so, it will
hopefully become IMO a much better example!)

The major thing testgamecontroller does NOT do yet, even in my code,
is handle device added/removed events. Short form: Device added
event.which contains the device index to open the thing. You'll want
to keep the SDL_GameController pointer around so you can close it if
you get a device removed, whose event.which contains an instance ID
that isn't the same as a device index.

At the moment, when I open a device, I immediately get its instance
ID and save both. If I get a device removed event, I go through my
list of open devices and close it if it's opened. I proposed an
alternative solution, but Sam pointed out it wouldn't work. Since I
haven't got a more brilliant suggestion, existing behavior stands.


Any joystick can be mapped to a SDL_GameController. Steam will do it
for you, though getting the data out of Steam and its database for
use with SDL is currently not the most user-friendly process in the
world. (This will be addressed too!)

Programmatically speaking, SDL_GameControllers are 14 buttons (A, B,
X, Y, Back, Guide, Start, LSB, RSB, LB, RB, and four DPad buttons)
plus 6 axes (left stick, right stick, left trigger, and right
trigger), consequently in that order actually. Smile (But that's an
implementation detail…) Your triggers range 0 to 32767 instead of
the usual -32768 to 32767, and they may be digital buttons. Guide
often doesn't exist, and retro controllers can be expected to map to
the DPad rather than the analog stick.

On the whole it's a good API. I'd like to see the Windows 7+ XInput
controller type hints used in SDL, but other targets may provide
different (and sometimes more) information than XInput does.

Joseph

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Alex Szpakowski
Guest

That was the old (awful, IMO) behaviour for Microsoft's MM and DirectInput APIs. XInput fixes this to behave like one might expect intuitively. The triggers are in separate physical locations, it does not make sense to me that they were both treated as one axis.


Some drivers report controller d-pads as buttons, some report them as a hat. The only xbox 360 controller driver for OS X always reports them as buttons.


Just because you are used to old code behaving a certain way, doesn't mean it becomes flawed or broken when it's changed, especially if that change is in an intuitive direction. Smile

On 2013-10-19, at 9:51 PM, "rainwarrior" wrote:
Quote:
No, that's normal for MM and the 360 controller. The Microsoft 360 controller works exactly the same way. LT and RT are combined as a single axis (one add 0 to negative to the axis, one adds 0 to positive). The clone operates like the original in this respect.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Joseph Carter


Joined: 20 Sep 2013
Posts: 279
For what it's worth, there's like 10 years of bug reports against SDL
for the mmjoystick driver failing to see buttons on many controllers,
reporting wrong axes, and generally being awful. Also, Microsoft has
said "Don't use this API anymore" since literally 1997.

Joseph


On Sat, Oct 19, 2013 at 11:45:01PM +0000, rainwarrior wrote:
Quote:
I discovered the older MM implementation and enabled it by doing the following in SDL_windows_config.h:

1. Remove: #define SDL_JOYSTICK_DINPUT 1
2. Add: #define SDL_JOYSTICK_WINMM 1
3. Remove: #define SDL_HAPTIC_DINPUT 1
4. Add: #define SDL_HAPTIC_DISABLED 1

With this done, all of my problems using these gamepads are gone. They all operate as I expect.





Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Joseph Carter


Joined: 20 Sep 2013
Posts: 279
On Sat, Oct 19, 2013 at 05:41:35PM -0700, Mason Wheeler wrote:
Quote:
...such as an XBox controller clone, which is what was originally mentioned.

It has 6 axes (2 for left stick, 2 for right stick, 1 for each trigger) and so if it
was trying to represent it as a system with 5 axes, that's a bug.

Actually, Windows XP lacks XInput entirely. That means the
XInput/DirectInput driver uses DirectInput mode for the XBox 360
controller on Windows XP.

And on DirectInput, the XBox 360 controller reports having 5 axes.
Microsoft insists that this is "correct" behavior:

http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx

Basically, under DirectInput (but not XInput), the XBox 360
controller reports both triggers as the 5th axis. You cannot
determine their values independently since the left trigger is a
negative offset from center and the right is a positive offset.

The only two realistic explanations for this behavior I can think of
are:

1. Microsoft wanted to intentionally cripple the very common XBox 360
controller for DirectInput in order to force everyone to migrate to
XInput, an API for which Microsoft makes makes a royalty fee for
controller makers to support.

2. Whoever made the decision is actually a moron. The explanation
that it had to be done this way so that sticks always appear to be
centerd when not being manipulated by the user is complete horse
crap, as evidenced by SDL's simple and obvious solution to the
problem. Moreover, the XBox 360 controller's centering is so
pathetically dismal as-is that I found it necessary to specify a dead
zone of ±4096 in order _usually_ have the joystick report as centered
when it wasn't being moved. And I say usually, because even that
value fails. The triggers require no dead zone at all.


I have strong views on this subject. :)

Joseph

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Joseph Carter


Joined: 20 Sep 2013
Posts: 279
On Sat, Oct 19, 2013 at 09:56:55PM -0300, Alex Szpakowski wrote:
Quote:
That was the old (awful, IMO) behaviour for Microsoft's MM and DirectInput APIs. XInput fixes this to behave like one might expect intuitively. The triggers are in separate physical locations, it does not make sense to me that they were both treated as one axis.

Some drivers report controller d-pads as buttons, some report them as a hat. The only xbox 360 controller driver for OS X always reports them as buttons.

The tattieboggle OS X driver reports the DPad as a hat. I dunno what
you're using.

Joseph

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
rainwarrior


Joined: 16 Oct 2013
Posts: 19
Location: Toronto, Canada
I would be willing to use the SDL_GameController API if it didn't just reject 2/3 of the controllers I had at hand.

Yes I would agree that the 360 implementing LT/RT as a combined axis was a stupid thing to do, I was just responding to the idea that this is a "clone" behaviour. When I bought it, I also had access to 360 controllers at the time, and I put it through a lot of tests. Everything it did in my tests was identical to the 360 controller except it has more noise on the axes, and instead of the analog stick output being a shaped circle like the 360's controller, it's a square. Otherwise it's the same (works fine plugged into an XBox 360 too).

The retrolink appears to have 5 axes in the SDL2-DX implementation, the first 4 of which are the X axis duplicated. I am not sure why this is occuring. Yes it is likely something wrong on the DX end, but that doesn't make it any more usable.


I think the MM implementation is worth keeping around. I'm sure SDL_GameController is working well in a lot of cases, but it seems to categorically reject a lot of older controllers, which for my purposes makes it useless. My current project does not need LT/RT, it needs a direction and some sensibly mapped buttons, which MM provides just fine for every controller I've ever tested against it. Microsoft may advice using XInput instead of MM, but Windows 7's Control Panels' "Game Controller Settings" still appear to use MM, so they certainly aren't practising what they preach if that's the case. Here's what the situation looks like to me:

DX
Pros:
- works well with new controllers
- can take advantage of external programs to provide mappings
Cons:
- works poorly or not at all with old controllers

MM
Pros:
- works well with old controllers
- works OK with new controllers
Cons:
- some newer controllers missing features


If the set of features you need is narrower, I think MM has more compatibility.
Joystick behaviour seriously flawed?
Alex Szpakowski
Guest

No it doesn't.


Check out SDL's GameController mappings for it. It's all buttons and axes, no hat: http://hg.libsdl.org/SDL/file/tip/src/joystick/SDL_gamecontrollerdb.h#l48

On 2013-10-19, at 10:22 PM, "T. Joseph Carter" wrote:
Quote:
On Sat, Oct 19, 2013 at 09:56:55PM -0300, Alex Szpakowski wrote:
Quote:
That was the old (awful, IMO) behaviour for Microsoft's MM and DirectInput APIs. XInput fixes this to behave like one might expect intuitively. The triggers are in separate physical locations, it does not make sense to me that they were both treated as one axis.

Some drivers report controller d-pads as buttons, some report them as a hat. The only xbox 360 controller driver for OS X always reports them as buttons.

The tattieboggle OS X driver reports the DPad as a hat. I dunno what you're using.

Joseph

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Joseph Carter


Joined: 20 Sep 2013
Posts: 279
Whoa, not only are you right, but the axis mapping is bat guano
crazy! Turns out that I missed that I was looking at my Logitech,
not my Microsoft before. That axis mapping:

Axis 0 and 1 are left stick.
Axis 2 is left trigger and does report full -32768 to 32767.
Axis 3 and 4 are right stick.
Axis 5 is right trigger.

I'd check to see if Linux does the same thing but … I kind of
clobbered my Linux install trying to do something clever and so I'm
waiting for packages to download so I can un-clobber it. :)

Joseph


On Sat, Oct 19, 2013 at 10:27:45PM -0300, Alex Szpakowski wrote:
Quote:
No it doesn't.

Check out SDL's GameController mappings for it. It's all buttons and axes, no hat: http://hg.libsdl.org/SDL/file/tip/src/joystick/SDL_gamecontrollerdb.h#l48

On 2013-10-19, at 10:22 PM, "T. Joseph Carter" wrote:

Quote:
On Sat, Oct 19, 2013 at 09:56:55PM -0300, Alex Szpakowski wrote:
Quote:
That was the old (awful, IMO) behaviour for Microsoft's MM and DirectInput APIs. XInput fixes this to behave like one might expect intuitively. The triggers are in separate physical locations, it does not make sense to me that they were both treated as one axis.

Some drivers report controller d-pads as buttons, some report them as a hat. The only xbox 360 controller driver for OS X always reports them as buttons.

The tattieboggle OS X driver reports the DPad as a hat. I dunno what you're using.

Joseph

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Quote:
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Sik


Joined: 26 Nov 2011
Posts: 905
2013/10/19, T. Joseph Carter:
Quote:
I'd check to see if Linux does the same thing but … I kind of
clobbered my Linux install trying to do something clever and so I'm
waiting for packages to download so I can un-clobber it. Smile

Don't even attempt, because Linux *doesn't have hats at all*, period.
Any stuff that used to be mapped to hats will get remapped to axes in
Linux. SDL seems to work around this in order to remap the usual case
(the D-pad in most modern controllers) back to the hat, but that's a
hack really.

In other words, Linux is pretty much guaranteed to show different
mappings as soon as hats are involved.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Ryan C. Gordon
Guest

Quote:
Actually, Windows XP lacks XInput entirely.

Nope, it works, as of Service Pack 1.

--ryan.





_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Ryan C. Gordon
Guest

Quote:
DX
Pros:
- works well with new controllers
- can take advantage of external programs to provide mappings
Cons:
- works poorly or not at all with old controllers

Using DirectInput will disqualify you from the Microsoft Store,
according to MSDN.

(Although I wonder what happens if you use a joystick through RAWINPUT.)

--ryan.



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Joystick behaviour seriously flawed?
Sik


Joined: 26 Nov 2011
Posts: 905
I think you get disqualified if you use anything but XInput.

That said... Anybody ever considered supporting joysticks through raw
input on SDL? That should work even on Windows XP. It could be
considered a fallback to replace the multimedia joystick API, though I
guess it's too much work for the effort Razz (maybe somebody could work
on it separately then merge into SDL when it's complete?)

2013/10/20, Ryan C. Gordon:
Quote:

Quote:
DX
Pros:
- works well with new controllers
- can take advantage of external programs to provide mappings
Cons:
- works poorly or not at all with old controllers

Using DirectInput will disqualify you from the Microsoft Store,
according to MSDN.

(Although I wonder what happens if you use a joystick through RAWINPUT.)

--ryan.



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Ressurrection
martinis_shaken


Joined: 03 Jun 2014
Posts: 3
I'm resurrecting this topic because I am having this issue as well.

I am using SDL soley for opening a window and event handling cross-platform. The rest of my code is all direct openGL calls, so it's pretty imperative I get this working as it's a large part of why I am even using SDL in the first place.

I have the XBOX360 Afterglow controller and am trying to use it in windows.

When I run the testjoystick.c program
http://www.libsdl.org/tmp/SDL/test/testjoystick.c

I get different results in linux (ubuntu 13) vs Windows 7.
It works perfectly in Linux, showing hats as they are supposed to be as well as giving a unique GUID for the controller.
However in Windows I run the exact same program, compiled against mingw libraries, and I get a GUID of all 0's and instead the controller is mapped to buttons 1-15 and my hat is read as buttons (same as OP).

Is there a fix for this yet? Has anybody come up with a workaround that doesn't make me have to have different controller mappings for the same controller?

If you need more detail, please just ask.

Thank You
Update
martinis_shaken


Joined: 03 Jun 2014
Posts: 3
http://www.libsdl.org/tmp/SDL/test/testgamecontroller.c

this works with the 360 controller! However it doesn't give me events because it's gamecontroller instead of joystick.

This poses an annoyance... I built my system using a switch statement for cases like button pushes - so when an event comes in I can handle it. This forces me to pull an event each loop and see if something is there with
SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED)

or similar. I don't want to do this... it's an event. Treat it like one.

SO back to "how to get 360 controller working in windows". I have dug through the gamecontrollerdb.txt to find the guid strings associated with my controller -

"xinput,X360 Controller,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,platform:Windows"

mapping seems good enough, but even manually adding that and then opening joystick it still isn't recognized. There's no way for me to force a mapping of the current stick to something else, either.

Ironically, this mapping shows that "button 0" is the hat or dpad "up". so it knows what's going on. How do I either fix this at its core, or as an interim, make this mapping valid for the current controller?