Skip to main content
GameDev.net gamedev.net
🔒 Locked

[SDL] Joystick axis problem and crash.

Started by Yezu Jun 23, 2010 at 5:34 AM 3 replies 3.3k views
Original Post
Yezu
Yezu
Hello!
I've been trying to add joystick/joypad support to my app. However I have ran into some problems.

I test this with a "dualshock" type of gamepad. All of the buttons work correctly. The analogues and the d-pad are recognized as axes.

The problem is:
When I use any of the analogue sticks the axis is always returned as 0.
When I use the D-pad the app exits.


GDB says that the crash appears somewhere deep within SDL.
I call SDL_PollEvent(),
which in turn calls SDL_PumpEvents(),
which in turn calls SDL_JoystickUpdate()
and then the app. exits with a Segmentation fault.

I initialize SDL with:
        if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) != 0 )    {		std::cout << "Unable to initialize SDL: " << SDL_GetError() << std::endl;		return false;    }


Here's how I setup joystick support:
        bool joyok = true;	if(SDL_JoystickEventState(SDL_ENABLE) != SDL_ENABLE)	{		Console::print("Cannot enable Joystick event polling!");		joyok = false;	}	if( SDL_NumJoysticks() < 1 )	{		Console::print("No Joysticks!");		joyok = false;	}	else		joystick = SDL_JoystickOpen(0);	if(joystick == 0x0 && joyok)		Console::print("Joystick failed!");	if(joyok)		Console::print("Joystick enabled.");	else		Console::print("Joystick enabling failed.");


Here's how I handle events:
	SDL_Event Event;	while(SDL_PollEvent(&Event))	{		switch(Event.type)		{			case SDL_JOYAXISMOTION:				{					JoystickInput::getAxisAction(Event.jaxis);					std::string o = "Axis: " + Utilities::intToStr(Event.jaxis.axis);					Console::print(o);				}				break;			case SDL_JOYBUTTONDOWN:				{					JoystickInput::getMenuAction(Event.jbutton.button);					std::string o = "Button: " + Utilities::intToStr(Event.jbutton.button);					Console::print(o);				}				break;		}	}


I couldn't find anywhere anything useful. Does anyone have any idea what I am doing wrong?
I'm running Fedora 13 i386.

thanks a lot :)
_______All your base are belong to us.
Amrazek
Amrazek
I tested out all of the SDL joystick functions and they seem to work fine on windows XP (using a logitech joystick and a digital and analog gamepad). Can we see more code? I'm interested in JoystickInput::getAxisAction() and JoyStickInput::getMenuAction() in particular.

Quote:
The analogues and the d-pad are recognized as axes.

Uh oh, are you sure? The D-pad should be recognized as a joyhat and not an axis. Pressing it should do nothing at all with the given code. Is there more to your message pump?

When you open your joystick, what does it report for number of buttons, axes, trackballs, hats?
printf("Number of Axes: %d\n", SDL_JoystickNumAxes(joystick));printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joystick));printf("Number of Balls: %d\n", SDL_JoystickNumBalls(joystick));printf("Number of Hats: %d\n", SDL_JoystickNumHats(joystick));
If I put my 2 cents in and get a penny for my thoughts, where does my other penny go?
Yezu
Yezu
I also thought that's peculiar. I was sure that the d-pad should be recognized as a hat. I've also tried with an arcade style controller (digital 8 direction joystick and 10 buttons).

The output is
for the "dual shock" controller:
Quote:

Joystick name: GreenAsia Inc. USB Joystick
Number of Axes: 2
Number of Buttons: 12
Number of Balls: 0
Number of Hats: 0


for the arcade controller:
Quote:

Joystick name: WiseGroup.,Ltd Mayflash Arcade Stick
Number of Axes: 1
Number of Buttons: 16
Number of Balls: 0
Number of Hats: 0


When I use the joystick of the arcade controller the app also crashes.

JoystickInput::getAxisAction() and JoyStickInput::getMenuAction() don't do anything spectacular:

Input::Action JoystickInput::getMenuAction(Uint8 sym){	for(register int i = CONSOLE ; i < NUMBER_OF_ACTIONS ; i++)		if(actionMap == sym)			return (Action)i;	return INVALID_ACTION;}//----------------------------------------------------------------------JoystickInput::AxisAction JoystickInput::getAxisAction(SDL_JoyAxisEvent ev){	AxisAction ret;	switch(ev.axis)	{		case 0:			ret.a = AxisAction::X_0_AXIS;			break;		case 1:			ret.a = AxisAction::Y_0_AXIS;			break;		case 2:			ret.a = AxisAction::X_1_AXIS;			break;		case 3:			ret.a = AxisAction::Y_1_AXIS;			break;		case 4:			ret.a = AxisAction::X_2_AXIS;			break;		case 5:			ret.a = AxisAction::X_2_AXIS;			break;		default:			Console::print("Wrong axis!");			break;	}	if(ev.value > zeroAnalog)		ret.value = ((float)(ev.value - zeroAnalog))/((float)(maxAnalog - zeroAnalog));	else if(ev.value < zeroAnalog)		ret.value = ((float)(ev.value - zeroAnalog))/((float)(minAnalog - zeroAnalog));	else		ret.value = 0.0f;	return ret;}



BTW. Is there any other multiplatform input library that I could use instead? Preferably that would work with SDL?
_______All your base are belong to us.
Amrazek
Amrazek
Google turns up some mention of certain PS3->USB hardware not mapping the D-pad correctly, which sounds very similar to what you've got. I assume you installed whatever driver the controllers might have come with?

Try holding UP, START and SELECT for 3 seconds after plugging them in and re-testing. Do you get the same results? Does the documentation on either disc mention any special codes (the above is a common one) as a workaround?
If I put my 2 cents in and get a penny for my thoughts, where does my other penny go?
Yezu
Yezu
The gamepad doesn't have select and start. Buttons 9 and 10 instead. However pushing that combination doesn't do anything.
_______All your base are belong to us.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.