Joystick troubles

I’m attempting to use a joystick under LInux using libSDL. The
problem that I’m having is that all my axis readings for the stick
return 0, no matter what position the actual sticks are in (using an
xbox gamepad, which registers as an 8-axis joystick). The standard
linux jstest program works perfectly, and SDL reports that there is
one joystick with 8 axes as expected, but all calls to
SDL_JoystickGetAxis return 0. Can anybody tell me if there’s anything
painfully obviously wrong about the program below?

#include <stdio.h>
#include <SDL/SDL.h>

int main()
{
SDL_Init(SDL_INIT_JOYSTICK);
SDL_JoystickEventState(SDL_DISABLE);

int i, j;
int numsticks = SDL_NumJoysticks();

SDL_Joystick *sticks = malloc(numstickssizeof(SDL_Joystick));
int
axes = malloc(numsticks*sizeof(int));

printf("%d Stick(s)\n", numsticks);
for(i = 0; i < numsticks; i++) {
sticks[i] = SDL_JoystickOpen(i);
if(!sticks[i]) {
printf(“No stick!\n”);
return 1;
}
axes[i] = SDL_JoystickNumAxes(sticks[i]);
}

for(;:wink: {
for(i = 0; i < numsticks; i++) {
for(j = 0; j < axes[i]; j++) {
printf(“Stick %d, axis %d, position is %d\n”, i, j,
SDL_JoystickGetAxis(sticks[i], j));
}
}
}
return 0;
}

Can anybody tell me if there’s anything
painfully obviously wrong about the program below?

Yes, even though you’ve disabled joystick events you still need to poll
for events if you want to update the joystick state.

See ya,
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

As Sam alluded, you have to “pump” the event subsystem in order to get
the values from those sort of functions to be updated. It is a little
counter-intuitive, but even the functions to pull input state
require you to pump the system that seems to be for pushing the
input state ;)On Mon, Feb 16, 2009 at 2:48 PM, tsuraan wrote:

for(;:wink: {
for(i = 0; i < numsticks; i++) {
for(j = 0; j < axes[i]; j++) {
printf(“Stick %d, axis %d, position is %d\n”, i, j,
SDL_JoystickGetAxis(sticks[i], j));
}
}
}


http://codebad.com/

Err, forgot the conclusion: use SDL_PumpEvents()On Mon, Feb 16, 2009 at 3:10 PM, Donny Viszneki <@Donny_Viszneki> wrote:

On Mon, Feb 16, 2009 at 2:48 PM, tsuraan wrote:

for(;:wink: {
for(i = 0; i < numsticks; i++) {
for(j = 0; j < axes[i]; j++) {
printf(“Stick %d, axis %d, position is %d\n”, i, j,
SDL_JoystickGetAxis(sticks[i], j));
}
}
}

As Sam alluded, you have to “pump” the event subsystem in order to get
the values from those sort of functions to be updated. It is a little
counter-intuitive, but even the functions to pull input state
require you to pump the system that seems to be for pushing the
input state :wink:


http://codebad.com/


http://codebad.com/

Yes, even though you’ve disabled joystick events you still need to poll
for events if you want to update the joystick state.

So putting the line

while(SDL_PollEvents(0));

inside the forever loop should work? I’ve also tried using events,
with this program:

#include <stdio.h>
#include <SDL/SDL.h>

int main()
{
SDL_Init(SDL_INIT_JOYSTICK);
SDL_JoystickEventState(SDL_ENABLE);

int i, j;
int numsticks = SDL_NumJoysticks();

SDL_Joystick *stick;
SDL_Event *evt;
SDL_JoyAxisEvent *axis;

printf("%d Stick(s)\n", numsticks);
for(i = 0; i < numsticks; i++) {
stick = SDL_JoystickOpen(i);
if(!stick) {
printf(“No stick!\n”);
return 1;
}
}

for(;:wink: {
if(SDL_WaitEvent(evt)) {
if(evt->type == SDL_JOYAXISMOTION) {
axis = (SDL_JoyAxisEvent*)evt;
printf(“Stick %d, axis %d, position is %d\n”,
axis->which, axis->axis, axis->value);
}
}
else {
printf(“SDL_Error says %s\n”, SDL_GetError());
return 1;
}
}
return 0;
}

That one exits immedately, with no useful error. Its exact output is:

1 Stick(s)
SDL_Error says

So really, there isn’t any error message at all. I’m running SDL
1.2.13 compiled with joystick support (obviously, since it does see
the stick), if that helps.

Err, forgot the conclusion: use SDL_PumpEvents()

Reading the man page for SDL_PumpEvents, it says that function can
only be called from the thread that set the video mode. Is it a
problem that I don’t have a video mode set, since I haven’t gotten to
that yet? Does SDL only work when there is some video present?

if(SDL_WaitEvent(evt)) {

}
else {
printf(“SDL_Error says %s\n”, SDL_GetError());
return 1;
}

That one exits immedately, with no useful error. Its exact output is:

1 Stick(s)
SDL_Error says

You need to examine the meaning of SDL_WaitEvent()'s return value a
little more carefully.On Mon, Feb 16, 2009 at 3:17 PM, tsuraan wrote:

On Mon, Feb 16, 2009 at 3:21 PM, tsuraan wrote:

Err, forgot the conclusion: use SDL_PumpEvents()

Reading the man page for SDL_PumpEvents, it says that function can
only be called from the thread that set the video mode. Is it a
problem that I don’t have a video mode set, since I haven’t gotten to
that yet? Does SDL only work when there is some video present?

I’m sure some others know better than I, but I believe on some systems
certain functionality is only available if you have a window (for
instance keyboard input on MS Windows I am quite sure only works if
you create a window.) I think joysticks generally work without a
window, but I could be wrong. Just create a window to be safe, I say.


http://codebad.com/

Gadzooks!

That won’t work either.

I hate to be the one to say this, especially since I tend to ask a lot
of questions when I’m new to something to, but why don’t you start by
reading the SDL documentation thoroughly? It seems like you’ve found a
lot of ways to do things wrong with very little code.On Mon, Feb 16, 2009 at 3:17 PM, tsuraan wrote:

SDL_Event *evt;
for(;:wink: {
if(SDL_WaitEvent(evt)) {


http://codebad.com/

As Sam alluded, you have to “pump” the event subsystem in order to get
the values from those sort of functions to be updated. It is a little
counter-intuitive, but even the functions to pull input state
require you to pump the system that seems to be for pushing the
input state :wink:

Thus, polling is an illusion. ;-)On Mon, Feb 16, 2009 at 3:10 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://pphaneuf.livejournal.com/

You need to examine the meaning of SDL_WaitEvent()'s return value a
little more carefully.

[…and…]

That won’t work either.

I hate to be the one to say this, especially since I tend to ask a lot
of questions when I’m new to something to, but why don’t you start by
reading the SDL documentation thoroughly? It seems like you’ve found a
lot of ways to do things wrong with very little code.

Well, I’m not guessing these function names off the top of my head :slight_smile:
The man page for SDL_WaitEvent says “Waits indefinitely for the next
available event, returning 1, or 0 if there was an error while waiting
for events.” So if it returns true (1), then it’s happy, and if it
returns false(0) then there was an error that should be retrievable
with SDL_GetError, right?

Is there a tutorial or tiny demo for joysticks anywhere? I’ve used
SDL with OpenGL and keyboard input for years, but joystick input is
just killing me. I’ve read
http://www.libsdl.org/docs/html/joystick.html of course, but I don’t
see anything there that would tell me what I’m doing wrong.

Especially in Florida :(On Mon, Feb 16, 2009 at 3:41 PM, Pierre Phaneuf wrote:

Thus, polling is an illusion. :wink:


http://codebad.com/

You need to examine the meaning of SDL_WaitEvent()'s return value a
little more carefully.

Augh, somehow I was thinking of SDL_PollEvent()!

At any rate perhaps the error is related to the other problem in your
code. Maybe it SIGSEGV’d when it tried to fill in the SDL_Event struct
you’re supposed to give it a pointer to (or NULL, but not an
uninitialized pointer!)

So if it returns true (1), then it’s happy, and if it
returns false(0) then there was an error that should be retrievable
with SDL_GetError, right?

I guess there is no error message set up for whatever went wrong. (I’d
reason on some systems your code would cause a crash.)On Mon, Feb 16, 2009 at 3:47 PM, tsuraan wrote:


http://codebad.com/

I guess there is no error message set up for whatever went wrong. (I’d
reason on some systems your code would cause a crash.)

Yeah, that definitely shouldn’t have run at all; replacing the event
pointer with an actual event did make the program a bit more valid,
but it didn’t make it work. Creating a window did the trick though.
I was planning on having a window anyhow, so that works well enough
for me. Is there some tips/pitfalls section of the libsdl site where
things like that can be recorded so people don’t run into them in the
future?

Err, forgot the conclusion: use SDL_PumpEvents()

Reading the man page for SDL_PumpEvents, it says that function can
only be called from the thread that set the video mode. Is it a
problem that I don’t have a video mode set, since I haven’t gotten to
that yet? Does SDL only work when there is some video present?

No, it just means that if you have set a video mode, that’s the thread
that should do all the graphics calls and event handling.

See ya,
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

tsuraan wrote:

I guess there is no error message set up for whatever went wrong. (I’d
reason on some systems your code would cause a crash.)

Yeah, that definitely shouldn’t have run at all; replacing the event
pointer with an actual event did make the program a bit more valid,
but it didn’t make it work. Creating a window did the trick though.
I was planning on having a window anyhow, so that works well enough
for me. Is there some tips/pitfalls section of the libsdl site where
things like that can be recorded so people don’t run into them in the
future?

What OS? I think all OS in 1.3 shouldn’t need windows for joystick
events. I believe I hacked it in for Windows, but Mac OS X and Linux I
don’t believe ever needed it (Linux for sure). Can’t speak for the
other ports. Some OS just don’t believe in sending input events if you
don’t have a window to catch them.

Edgar
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkmZ5ksACgkQolm4VNX3QTxuMQCg6rPI9R2ZORJAK3gHGjg4fPKX
l6EAoImG/d4dmd5bnFlsdUe/4Nzeif1L
=tH7j
-----END PGP SIGNATURE-----

What OS? I think all OS in 1.3 shouldn’t need windows for joystick
events. I believe I hacked it in for Windows, but Mac OS X and Linux I
don’t believe ever needed it (Linux for sure). Can’t speak for the
other ports. Some OS just don’t believe in sending input events if you
don’t have a window to catch them.

I’m using gentoo linux and SDL 1.2.13. Creating the window did make
the event-based code work, but not the GetAxis code, even with the
PumpEvents in place.