Joystick API behavior

Gonna split this into its own thread because the other one derailed a
lot already.

First of all, I’m gonna insist: are we sure that the joystick added
events on initialization are needed? I decided to just give it a try
by letting the events open the joystick instead of the init code…
turns out it doesn’t detect my controller! In fact, I didn’t get any
joystick detected events (verified by logging the events, that one
never happens).

Decided to take a look at the code. On Windows it indeed calls the
function used to detect which joysticks are connected, which is
probably why the added events happen. However, it seems that on Linux
this function call doesn’t happen, so Linux never gets the events in
the first place. Questioning whether it was undefined behavior or not
doesn’t seem so stupid now, I guess.

On that note: is one supposed to keep track of the instance IDs for
every joystick? Because SDL_JOYDEVICEREMOVED will give the instance ID
but SDL_JoystickClose wants the pointer to the joystick structure, and
there’s no way to retrieve it from the instance ID. Also I’m not even
sure if it needs to be closed if that event happens.

2013/10/9 Sik the hedgehog <sik.the.hedgehog at gmail.com>

Gonna split this into its own thread because the other one derailed a
lot already.

First of all, I’m gonna insist: are we sure that the joystick added
events on initialization are needed? I decided to just give it a try
by letting the events open the joystick instead of the init code…
turns out it doesn’t detect my controller! In fact, I didn’t get any
joystick detected events (verified by logging the events, that one
never happens).

I think it’s a great way to simplify user code, because instead of writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.

Yeah, I wrote the wrong verb but since I’m writing on the mailing list
I can’t edit x_X I meant to ask if the joystick added events are
always generated (on Linux SDL seems to disagree).

2013/10/9, Jonas Kulla :> 2013/10/9 Sik the hedgehog <@Sik_the_hedgehog>

Gonna split this into its own thread because the other one derailed a
lot already.

First of all, I’m gonna insist: are we sure that the joystick added
events on initialization are needed? I decided to just give it a try
by letting the events open the joystick instead of the init code…
turns out it doesn’t detect my controller! In fact, I didn’t get any
joystick detected events (verified by logging the events, that one
never happens).

I think it’s a great way to simplify user code, because instead of writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.

2013/10/9 Sik the hedgehog <sik.the.hedgehog at gmail.com>

Gonna split this into its own thread because the other one derailed a
lot already.

First of all, I’m gonna insist: are we sure that the joystick added
events on initialization are needed? I decided to just give it a try
by letting the events open the joystick instead of the init code…
turns out it doesn’t detect my controller! In fact, I didn’t get any
joystick detected events (verified by logging the events, that one
never happens).

Decided to take a look at the code. On Windows it indeed calls the
function used to detect which joysticks are connected, which is
probably why the added events happen. However, it seems that on Linux
this function call doesn’t happen, so Linux never gets the events in
the first place. Questioning whether it was undefined behavior or not
doesn’t seem so stupid now, I guess.

On that note: is one supposed to keep track of the instance IDs for
every joystick? Because SDL_JOYDEVICEREMOVED will give the instance ID
but SDL_JoystickClose wants the pointer to the joystick structure, and
there’s no way to retrieve it from the instance ID. Also I’m not even
sure if it needs to be closed if that event happens.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Do you have libudev installed? (on Ubuntu sudo apt-get install libudev-dev
and then recompile)

If you don’t, hotplugging support on Linux doesn’t work, it just crudely
scans a bunch of devices trying to guess which ones are joysticks.

What should happen (if udev is present and there’s no bugs :stuck_out_tongue: ) is that
upon initialization of the joystick system, a SDL_JOYDEVICEADDED event
should fire for each joystick detected.–
Gabriel.

How would you know which ones were there at startup and which ones
weren’t?

JosephOn Wed, Oct 09, 2013 at 03:42:23PM +0200, Jonas Kulla wrote:

I think it’s a great way to simplify user code, because instead of writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.

2013/10/9 T. Joseph Carter > On Wed, Oct 09, 2013 at 03:42:23PM +0200, Jonas Kulla wrote:

I think it’s a great way to simplify user code, because instead of writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.

How would you know which ones were there at startup and which ones weren’t?

Why would this matter? You shouldn’t treat them differently based upon that
IMO.

And if you want to, it’s just a matter of setting a flag in your game that
tells you when initialization is over.

Jonny DOn Wed, Oct 9, 2013 at 11:22 AM, Jonas Kulla wrote:

2013/10/9 T. Joseph Carter

On Wed, Oct 09, 2013 at 03:42:23PM +0200, Jonas Kulla wrote:

I think it’s a great way to simplify user code, because instead of
writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.

How would you know which ones were there at startup and which ones
weren’t?

Why would this matter? You shouldn’t treat them differently based upon
that IMO.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2013/10/9, Gabriel Jacobo :

Do you have libudev installed? (on Ubuntu sudo apt-get install libudev-dev
and then recompile)

If you don’t, hotplugging support on Linux doesn’t work, it just crudely
scans a bunch of devices trying to guess which ones are joysticks.

Well, that explains a lot (many programs refuse to recognize the
joystick again until I restart them).

What should happen (if udev is present and there’s no bugs :stuck_out_tongue: ) is that
upon initialization of the joystick system, a SDL_JOYDEVICEADDED event
should fire for each joystick detected.

The point is, it’s perfectly possible for that to not happen (if this
wasn’t acceptable for SDL, then it wouldn’t be able to build without
udev in the first place). Either this is fixed so that an event is
generated for each joystick connected (even if faked) or this becomes
considered undefined behavior.

Sik says you should treat them differently and only report the NEW
ones.

Q: How do you know which ones are “new”?

Q: What if a joystick is added after InitSubSystem, but before the
program loops over the NumJoysticks? Do you emit an add event or
not?

Q: If you DON’T emit the event because the caller hasn’t yet iterated
over the initial joysticks, how do you know the caller ever will?
And why should SDL be keeping track?

Q: If you DO emit the event, then why would you not emit all
joysticks added, regardless of whether they are added during
InitSubSystem or after? They’re still added regardless.

It doesn’t make sense any other way than it works now.

JosephOn Wed, Oct 09, 2013 at 05:22:04PM +0200, Jonas Kulla wrote:

I think it’s a great way to simplify user code, because instead of writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.

How would you know which ones were there at startup and which ones weren’t?

Why would this matter? You shouldn’t treat them differently based upon that
IMO.

2013/10/9, T. Joseph Carter :

Sik says you should treat them differently and only report the NEW
ones.

No, I’m saying that we can’t rely on SDL doing this because there
isn’t any guarantee it’s doing that.

It doesn’t make sense any other way than it works now.

Issue joystick added events in some builds but not in others? That
sounds about as inconsistent as it can get.

What should happen (if udev is present and there’s no bugs :stuck_out_tongue: ) is that
upon initialization of the joystick system, a SDL_JOYDEVICEADDED event
should fire for each joystick detected.

Our crude fallback should probably fire events, too, to keep this
consistent.

–ryan.

2013/10/9, Gabriel Jacobo :

Do you have libudev installed? (on Ubuntu sudo apt-get install libudev-dev
and then recompile)

If you don’t, hotplugging support on Linux doesn’t work, it just crudely
scans a bunch of devices trying to guess which ones are joysticks.

Well, that explains a lot (many programs refuse to recognize the
joystick again until I restart them).

I’d suggest installing udev then. The point of SDL_JOYDEVICEADDED
events is that when you do hotplug a joystick, any SDL 2.0 using app
should get notified. That’s not going to happen on Linux without
udev. But now that you point it out (and now that I have a Linux VM
to develop in), I’m going to fix it.

I’m willing to do the same for the mmjoystick API in Windows if
someone wouldn’t mind just a little handholding for setting up a
build environment using MingW-w64 later on.

The unsupported platforms will take more work since I haven’t got a
PSP or other such things. I might be able to do something with Haiku
since I could download it and set it up in VMWare. Just found some
instructions!

What should happen (if udev is present and there’s no bugs :stuck_out_tongue: ) is that
upon initialization of the joystick system, a SDL_JOYDEVICEADDED event
should fire for each joystick detected.

The point is, it’s perfectly possible for that to not happen (if this
wasn’t acceptable for SDL, then it wouldn’t be able to build without
udev in the first place). Either this is fixed so that an event is
generated for each joystick connected (even if faked) or this becomes
considered undefined behavior.

That’s a bug. And now that I know it’s there, I’ll see to it that it
becomes squished forthwith. Well, after I meet the GF for lunch.
Because if I don’t, I won’t live long enough to to actually submit
the fix. :slight_smile:

JosephOn Wed, Oct 09, 2013 at 12:52:53PM -0300, Sik the hedgehog wrote:

Hey Ryan, LTNT,

In complete agreement here. That all but two supported targets do
the right thing and only the crude fallbacks which weren’t updated
fail to do it suggests that those events are the established 2.0 API.
The two targets that don’t do it (Windows MMJoystick being the other)
should be patched. :slight_smile:

If we’re still arguing about this tonight and there’s not already a
patch in hg, I’ll fix it for Linux. For Windows will take more doing
because I don’t have a development environment at present.

JosephOn Wed, Oct 09, 2013 at 02:22:45PM -0400, Ryan C. Gordon wrote:

What should happen (if udev is present and there’s no bugs :stuck_out_tongue: ) is that
upon initialization of the joystick system, a SDL_JOYDEVICEADDED event
should fire for each joystick detected.

Our crude fallback should probably fire events, too, to keep this
consistent.

2013/10/9, T. Joseph Carter :

I’m willing to do the same for the mmjoystick API in Windows if
someone wouldn’t mind just a little handholding for setting up a
build environment using MingW-w64 later on.

The biggest problem here would be Code::Blocks I think, which comes
with the original MinGW and without MSYS (unless that changed
recently). Convince the Code::Blocks maintainers to switch to
MinGW-w64 and that’ll probably cover most of those who care (since
then it’ll be just a matter of installing as usual).

Also since we’re talking about working on the API: does anybody know
what the program is supposed to do with SDL_JOYDEVICEREMOVED? Because
SDL_JoystickClose() wants a joystick structure, but the event data
gives an instance ID instead (and there’s no way to get a joystick
structure out of an instance ID, so one would need to do bookkeeping
of every joystick). I guess you’ll say “keep track of every
joystick!”, but since my game is single player I opted to just handle
all joysticks the same without paying attention which is which :stuck_out_tongue:

You are correct, and this is a problem. You should close the
joystick, since it is no longer useful to keep around. This is the
problem with new APIs? It’s almost too bad I didn’t start my little
project a few months ago or I could’ve caught this before the 2.0
release. :slight_smile:

This patch was made a couple of days ago, but should apply cleanly.

Joseph

-------------- next part --------------
diff -r d9f0067a5421 include/SDL_joystick.h
— a/include/SDL_joystick.h Sun Oct 06 20:39:23 2013 -0700
+++ b/include/SDL_joystick.h Mon Oct 07 12:40:53 2013 -0700
@@ -133,6 +133,11 @@
extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick * joystick);

/**

    • Get the opened joystick or NULL if the instance id is invalid.
  • */
    +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickForInstanceID(SDL_JoystickID instance_id);On Wed, Oct 09, 2013 at 04:20:44PM -0300, Sik the hedgehog wrote:

I’m willing to do the same for the mmjoystick API in Windows if
someone wouldn’t mind just a little handholding for setting up a
build environment using MingW-w64 later on.

The biggest problem here would be Code::Blocks I think, which comes
with the original MinGW and without MSYS (unless that changed
recently). Convince the Code::Blocks maintainers to switch to
MinGW-w64 and that’ll probably cover most of those who care (since
then it’ll be just a matter of installing as usual).

Also since we’re talking about working on the API: does anybody know
what the program is supposed to do with SDL_JOYDEVICEREMOVED? Because
SDL_JoystickClose() wants a joystick structure, but the event data
gives an instance ID instead (and there’s no way to get a joystick
structure out of an instance ID, so one would need to do bookkeeping
of every joystick). I guess you’ll say “keep track of every
joystick!”, but since my game is single player I opted to just handle
all joysticks the same without paying attention which is which :stuck_out_tongue:

+/**

  • Get the number of general axis controls on a joystick.
    */
    extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick * joystick);
    diff -r d9f0067a5421 src/joystick/SDL_joystick.c
    — a/src/joystick/SDL_joystick.c Sun Oct 06 20:39:23 2013 -0700
    +++ b/src/joystick/SDL_joystick.c Mon Oct 07 12:40:53 2013 -0700
    @@ -379,6 +379,29 @@
    }

/*

    • Get the opened joystick for this instance id
  • */
    +SDL_Joystick *
    +SDL_JoystickForInstanceID(SDL_JoystickID instance_id)
    +{
  • SDL_Joystick * joystick;
  • joystick = SDL_joysticks;
  • while ( joystick )
  • {
  •    if ( instance_id == joystick->instance_id ) {
    
  •            /* Found it */
    
  •            return (joystick);
    
  •    }
    
  •    joystick = joystick->next;
    
  • }
  • SDL_SetError(“Instance id %d is not valid”, instance_id);
  • return NULL;
    +}

+/*

  • Get the friendly name of this joystick
    */
    const char *

As discussed (possibly to death), the Linux joystick driver does not
actually report events for added or removed joysticks when you
haven’t got udev support.

We simply cannot know about removed joysticks without udev. But we
can (and we should) report adding them. This brings the legacy case
in line with pretty much the rest of SDL’s joystick drivers.

The included patch corrects this.

It doesn’t fix the FIXMEs because I’ve been asked not to refactor
code that doesn’t absolutely need it. I agree that it should be done
that way if desired, but patches are best isolated.

JosephOn Wed, Oct 09, 2013 at 03:42:23PM +0200, Jonas Kulla wrote:

2013/10/9 Sik the hedgehog <sik.the.hedgehog at gmail.com>

Gonna split this into its own thread because the other one derailed a
lot already.

First of all, I’m gonna insist: are we sure that the joystick added
events on initialization are needed? I decided to just give it a try
by letting the events open the joystick instead of the init code…
turns out it doesn’t detect my controller! In fact, I didn’t get any
joystick detected events (verified by logging the events, that one
never happens).

I think it’s a great way to simplify user code, because instead of writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

-------------- next part --------------
diff -r 7995e0920bf9 src/joystick/linux/SDL_sysjoystick.c
— a/src/joystick/linux/SDL_sysjoystick.c Wed Oct 09 11:30:01 2013 -0300
+++ b/src/joystick/linux/SDL_sysjoystick.c Thu Oct 10 06:10:04 2013 -0700
@@ -138,8 +138,6 @@
#if SDL_USE_LIBUDEV
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
{

  • int instance;
  • if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
    return;
    }
    @@ -147,41 +145,11 @@
    switch( udev_type )
    {
    case SDL_UDEV_DEVICEADDED:
  •        instance = MaybeAddDevice(devpath);
    
  •        if (instance != -1) {
    
  •            /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */
    
  •            #if !SDL_EVENTS_DISABLED
    
  •            SDL_Event event;
    
  •            event.type = SDL_JOYDEVICEADDED;
    
  •            if (SDL_GetEventState(event.type) == SDL_ENABLE) {
    
  •                event.jdevice.which = instance;
    
  •                if ( (SDL_EventOK == NULL) ||
    
  •                     (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
    
  •                    SDL_PushEvent(&event);
    
  •                }
    
  •            }
    
  •            #endif /* !SDL_EVENTS_DISABLED */
    
  •        }
    
  •        MaybeAddDevice(devpath);
           break;
           
       case SDL_UDEV_DEVICEREMOVED:
    
  •        instance = MaybeRemoveDevice(devpath);
    
  •        if (instance != -1) {
    
  •            /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */
    
  •            #if !SDL_EVENTS_DISABLED
    
  •            SDL_Event event;
    
  •            event.type = SDL_JOYDEVICEREMOVED;
    
  •            if (SDL_GetEventState(event.type) == SDL_ENABLE) {
    
  •                event.jdevice.which = instance;
    
  •                if ( (SDL_EventOK == NULL) ||
    
  •                     (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
    
  •                    SDL_PushEvent(&event);
    
  •                }
    
  •            }
    
  •            #endif /* !SDL_EVENTS_DISABLED */
    
  •        }
    
  •        MaybeRemoveDevice(devpath);
           break;
           
       default:
    

@@ -202,6 +170,9 @@
char namebuf[128];
SDL_JoystickGUID guid;
SDL_joylist_item *item;
+#if !SDL_EVENTS_DISABLED

  • SDL_Event event;
    +#endif

    if (path == NULL) {
    return -1;
    @@ -259,6 +230,19 @@
    SDL_joylist_tail = item;
    }

  • /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */
    +#if !SDL_EVENTS_DISABLED

  • event.type = SDL_JOYDEVICEADDED;

  • if (SDL_GetEventState(event.type) == SDL_ENABLE) {

  •    event.jdevice.which = numjoysticks;
    
  •    if ( (SDL_EventOK == NULL) ||
    
  •         (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
    
  •        SDL_PushEvent(&event);
    
  •    }
    
  • }
    +#endif /* !SDL_EVENTS_DISABLED */

  • return numjoysticks++;
    }

@@ -269,6 +253,9 @@
{
SDL_joylist_item *item;
SDL_joylist_item *prev = NULL;
+#if !SDL_EVENTS_DISABLED

  • SDL_Event event;
    +#endif

    if (path == NULL) {
    return -1;
    @@ -290,6 +277,20 @@
    if (item == SDL_joylist_tail) {
    SDL_joylist_tail = prev;
    }

  •        /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */
    

+#if !SDL_EVENTS_DISABLED

  •        event.type = SDL_JOYDEVICEREMOVED;
    
  •        if (SDL_GetEventState(event.type) == SDL_ENABLE) {
    
  •            event.jdevice.which = item->device_instance;
    
  •            if ( (SDL_EventOK == NULL) ||
    
  •                 (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
    
  •                SDL_PushEvent(&event);
    
  •            }
    
  •        }
    

+#endif /* !SDL_EVENTS_DISABLED */
+
SDL_free(item->path);
SDL_free(item->name);
SDL_free(item);

Added, thanks!On Thu, Oct 10, 2013 at 6:30 AM, T. Joseph Carter < tjcarter at spiritsubstance.com> wrote:

As discussed (possibly to death), the Linux joystick driver does not
actually report events for added or removed joysticks when you haven’t got
udev support.

We simply cannot know about removed joysticks without udev. But we can
(and we should) report adding them. This brings the legacy case in line
with pretty much the rest of SDL’s joystick drivers.

The included patch corrects this.

It doesn’t fix the FIXMEs because I’ve been asked not to refactor code
that doesn’t absolutely need it. I agree that it should be done that way
if desired, but patches are best isolated.

Joseph

On Wed, Oct 09, 2013 at 03:42:23PM +0200, Jonas Kulla wrote:

2013/10/9 Sik the hedgehog <sik.the.hedgehog at gmail.com>

Gonna split this into its own thread because the other one derailed a

lot already.

First of all, I’m gonna insist: are we sure that the joystick added
events on initialization are needed? I decided to just give it a try
by letting the events open the joystick instead of the init code…
turns out it doesn’t detect my controller! In fact, I didn’t get any
joystick detected events (verified by logging the events, that one
never happens).

I think it’s a great way to simplify user code, because instead of writing
code to initialize all plugged in joysticks at startup and deal with
hotplugged
ones at runtime, you can just completely skip the former code path.

_____________**

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Sik’s got a point here:On Wed, Oct 09, 2013 at 04:20:44PM -0300, Sik the hedgehog wrote:

Also since we’re talking about working on the API: does anybody know
what the program is supposed to do with SDL_JOYDEVICEREMOVED? Because
SDL_JoystickClose() wants a joystick structure, but the event data
gives an instance ID instead (and there’s no way to get a joystick
structure out of an instance ID, so one would need to do bookkeeping
of every joystick). I guess you’ll say “keep track of every
joystick!”, but since my game is single player I opted to just handle
all joysticks the same without paying attention which is which :stuck_out_tongue:

Using the event interface, you should be able to handle an arbitrary
number of joysticks as they are added to and removed from the system.
And you can, but at the moment you must create a structure in your
program to store pointers to SDL_Joysticks in a linked list. Which
is stupid because SDL_Joystick is already a linked list?but one you
don’t have access to outside of SDL.

So to support an arbitrary number of joysticks, you wait for SDL to
give you SDL_JOYDEVICEADDED, which it now does for every supported
target except Windows mmjoystick which is happily getting nuked! :smiley:
You query the index, open it, etc. And now you’ve got this pointer
to some SDL_Joystick node. If you are going to keep track of it, you
need to create a linked list structure to store the nodes of the
joysticks you open, because you don’t have access to the head of the
list.

So when you get SDL_JOYDEVICEREMOVED, you have to check your
program’s linked list to find the one that matches event.which, the
instance id of the removed joystick, and then you have to remove that
node from your program’s list and call SDL_JoyStickClose. The reason
SDL_JOYDEVICEREMOVED doesn’t close the joystick, Sam confirmed, is
that it can’t?the program may have a pointer to the SDL_Joystick and
SDL cannot know that the program isn’t going to dereference that
pointer at any moment.

After all, you might not be watching for joystick device events. You
may not even have events compiled into SDL,though I can’t imagine
why that is still even an option. They’re pretty much expected in
every SDL program I’ve ever seen, even (or should I say especially?)
on portable devices like iOS and Android. But still, if you’re using
the old API and polling stuff the hard way, you’re probably using
that pointer SDL_JoystickOpen gave you.

Of course, if you’re using the event API the way it ought to be used,
you get that pointer from SDL_JoystickOpen, save off the instance id
from the SDL_Joystick if you need to know it later on, and you ought
to be able to promptly forget about it. After all, it’s a pointer to
a structure internal to (and managed by) SDL.

The only issue is that you cannot close a joystick by instance id.
You have to send SDL the pointer, which you had no reason to save,
other than being able to close a joystick without shutting down the
whole joystick subsystem, basically upon SDL_JOYDEVICEREMOVED.

It’d be much easier if you could just ask SDL for the SDL_Joystick
pointer corresponding to the instance id. And so I’ve got a patch to
that effect, attached.

Thoughts?

Joseph

-------------- next part --------------
diff -r d9f0067a5421 include/SDL_joystick.h
— a/include/SDL_joystick.h Sun Oct 06 20:39:23 2013 -0700
+++ b/include/SDL_joystick.h Mon Oct 07 12:40:53 2013 -0700
@@ -133,6 +133,11 @@
extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick * joystick);

/**

    • Get the opened joystick or NULL if the instance id is invalid.
  • */
    +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickForInstanceID(SDL_JoystickID instance_id);

+/**

  • Get the number of general axis controls on a joystick.
    */
    extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick * joystick);
    diff -r d9f0067a5421 src/joystick/SDL_joystick.c
    — a/src/joystick/SDL_joystick.c Sun Oct 06 20:39:23 2013 -0700
    +++ b/src/joystick/SDL_joystick.c Mon Oct 07 12:40:53 2013 -0700
    @@ -379,6 +379,29 @@
    }

/*

    • Get the opened joystick for this instance id
  • */
    +SDL_Joystick *
    +SDL_JoystickForInstanceID(SDL_JoystickID instance_id)
    +{
  • SDL_Joystick * joystick;
  • joystick = SDL_joysticks;
  • while ( joystick )
  • {
  •    if ( instance_id == joystick->instance_id ) {
    
  •            /* Found it */
    
  •            return (joystick);
    
  •    }
    
  •    joystick = joystick->next;
    
  • }
  • SDL_SetError(“Instance id %d is not an open joystick”, instance_id);
  • return NULL;
    +}

+/*

  • Get the friendly name of this joystick
    */
    const char *

2013/10/11, T. Joseph Carter :

After all, you might not be watching for joystick device events. You
may not even have events compiled into SDL,though I can’t imagine
why that is still even an option.

By using polling you can make SDL do the bookkeeping for you (instead
of having to keep track of what happens when each event triggers).
That can help make code simpler. This would be the main appeal for not
using events.

I didn’t think you could disable them from a SDL build though…

Of course, if you’re using the event API the way it ought to be used,
you get that pointer from SDL_JoystickOpen, save off the instance id
from the SDL_Joystick if you need to know it later on, and you ought
to be able to promptly forget about it. After all, it’s a pointer to
a structure internal to (and managed by) SDL.

Actually, this is related to the above. Polling functions make use of
SDL_Joystick, but events make use of the instance IDs instead. Yeah,
API inconsistency, but sadly the ABI is frozen by now which means this
can’t be changed.

This patch is probably the best workaround for this :stuck_out_tongue:

Part of the reason why the polling functions work on structures is
that if you hand SDL a structure, it doesn’t have to look up which
stick you’re polling. That simplifies the code quite a lot, and it
also would be very slow to test for all the various buttons and
controls. It’s not two axes and two buttons anymore. :slight_smile:

Hopefully my improvements to testgamecontroller and eventually also
testjoystick will serve as good models for how to do both. I would
like to see this patch (perhaps with a renamed function if someone
has a better name) make it into 2.0.1, basically before too many
people find themselves inventing workarounds they don’t need to.

JosephOn Fri, Oct 11, 2013 at 05:08:06PM -0300, Sik the hedgehog wrote:

Of course, if you’re using the event API the way it ought to be used,
you get that pointer from SDL_JoystickOpen, save off the instance id
from the SDL_Joystick if you need to know it later on, and you ought
to be able to promptly forget about it. After all, it’s a pointer to
a structure internal to (and managed by) SDL.

Actually, this is related to the above. Polling functions make use of
SDL_Joystick, but events make use of the instance IDs instead. Yeah,
API inconsistency, but sadly the ABI is frozen by now which means this
can’t be changed.

This patch is probably the best workaround for this :stuck_out_tongue: