SDL Input Receiver w/Joystick & gamepad support

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
rooly
Posts: 224
Joined: Tue Oct 25, 2005 4:32 pm
Location: Louisiana, USA, backwater country
Contact:

SDL Input Receiver w/Joystick & gamepad support

Post by rooly »

So, i had some spare time, i decided to make an SDL input handler. If'n you've ever seen the Mastiff Event Receiver, you'll be right at home with mine.

Currently: Keyboard and Mouse support is "there", but untested.
Joystuck axis support
Joystick button support untested
joystuck pov-hat untested

event.h

Code: Select all

// 
// File:   newfile.h
// Author: chris
//
// Created on July 6, 2008, 11:50 PM
//

#ifndef _EVENT_H
#define	_EVENT_H

#define MAX_KEY_COUNT 255
#define MAX_JOY_AXIS 4
#define MAX_JOY_BUTTON 256
#define MAX_MOUSE_BUTTON 32
#define MAX_MOUSE_AXIS 2
#define MAX_MOUSE_WHEEL 2
#define MAX_AXIS_COUNT ( MAX_JOY_AXIS + MAX_MOUSE_AXIS )

#include <SDL/SDL.h>

enum KeyEventType
{
	KeyNull,
	KeyPressed,
	KeyDown,
	KeyUp,
	KeyReleased,
	KeyEventTypeCount
};

enum MouseButtonEventType
{
	MouseButtonNull,
	MouseButtonPressed,
	MouseButtonDown,
	MouseButtonUp,
	MouseButtonReleased,
	MouseButtonTypeCount
};

enum MouseWheelEventType
{
	MouseWheelNull,
	MouseWheelRollUp,
	MouseWheelRullDown,
	MouseWheelRoll,
	MouseWheelEventTypeCount
};

enum MouseMoveAxisEventType
{
	MouseNull,
	MouseMove = 0x1,
	MouseMovePlus = 0x2,
	MouseMoveMinus = 0x4
};

enum JoyButtonEventType
{
	JoyButtonNull,
	JoyButtonPress,
	JoyButtonDown,
	JoyButtonUp,
	JoyButtonRelease,
	JoyButtonTypeCount
};

enum JoyAxisEventType
{
	JoyAxisNull,
	JoyAxisMove = 0x1,
	JoyAxisMovePlus = 0x2,
	JoyAxisMoveMinus = 0x4
};

enum JoyPovAxisEventType
{
	JoyPovNull,
	JoyPovUp		= 0x1,
	JoyPovRight		= 0x2,
	JoyPovUpRight	= 0x3,
	JoyPovDown		= 0x4,
	JoyPovRightDown = 0x6,
	JoyPovLeft		= 0x8,
	JoyPovUpLeft	= 0x9,
	JoyPovDownLeft	= 0xC
};

class SDL_InputEvent
{
	SDL_Event event;
	SDL_Joystick* joystick;
	
	KeyEventType KeyState [ MAX_KEY_COUNT ];
	JoyPovAxisEventType PovState;
	JoyAxisEventType JoyAxisState[ MAX_JOY_AXIS ];
	JoyButtonEventType JoyButtonState[ MAX_JOY_BUTTON ];
	MouseMoveAxisEventType MouseAxisState[ MAX_MOUSE_AXIS ];
	MouseWheelEventType MouseWheelState[ MAX_MOUSE_WHEEL ];
	MouseButtonEventType MouseButtonState[ MAX_MOUSE_BUTTON ];
	
	int MouseButtonCount,
		MouseAxisCount,
		MouseWheelCount,
		JoyButtonCount,
		JoyAxisCount;
	
	float JoyAxis[ MAX_JOY_AXIS ];
	unsigned int MouseAxis[ MAX_MOUSE_AXIS ];
	
	bool MousePresent,
		 KeyboardPresent,
		 JoyPresent,
		 JoyPovPresent;
	
	bool isHandled,
		 isInitialized,
		 quitMessage;

public:
	SDL_InputEvent();
	~SDL_InputEvent();
	
	KeyEventType getKeyState( unsigned char ) const;
	JoyPovAxisEventType getPovState() const;
	JoyAxisEventType getJoyAxisState( int ) const;
	JoyButtonEventType getJoyButtonState( int ) const;
	MouseMoveAxisEventType getMouseAxisState( int ) const;
	MouseButtonEventType getMouseButtonState( int ) const;
	MouseWheelEventType getMouseWheelState( int ) const;
	
	bool isMouesPresent() const;
	bool isKeyboardPresent() const;
	bool isJoyPresent() const;
	bool isJoyPovPresent() const;
	bool initialized() const;
	bool quitMessageReceived() const;
	
	int getMouseButtonCount() const;
	int getMouseAxisCount() const;
	int getMouseWheelCount() const;
	int getJoyButtonCount() const;
	int getJoyAxisCount() const;
	
	float getJoyAxis( int Axis ) const;
	unsigned int getMouseAxis( int Axis ) const;
	
	void beginEventHandle();
};

#endif	/* _EVENT_H */
event.cc

Code: Select all

#include <stdlib.h>
#include "event.h"

#include <iostream>
using std::cout;
using std::endl;

/* Input handling init/destroy
 *
 *	Init's the input handler using SDL
 *	Destroys the input handler
 */
SDL_InputEvent::SDL_InputEvent()
{
	int error = SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK );
	
	if( error != 0 )
	{
		SDL_Quit();
		isInitialized = false;
		cout<<"SDL failed to initialize"<<endl;
		return;
	}

	SDL_JoystickEventState(SDL_ENABLE);
	joystick = SDL_JoystickOpen(0);
	
	for( int i=0; i<MAX_KEY_COUNT; i++ )
		KeyState[i] = KeyNull;
	
	PovState = JoyPovNull;
	
	for( int i=0; i<MAX_JOY_AXIS; i++)
		JoyAxisState[i] = JoyAxisNull;
	
	for( int i=0; i<MAX_JOY_BUTTON; i++ )
		JoyButtonState[i] = JoyButtonNull;
	
	for( int i=0; i<MAX_MOUSE_AXIS; i++ )
		MouseAxisState[i] = MouseNull;

	for( int i=0; i<MAX_MOUSE_WHEEL; i++ )
		MouseWheelState[i] = MouseWheelNull;

	for( int i=0; i<MAX_MOUSE_BUTTON; i++ )
		MouseButtonState[i] = MouseButtonNull;
	
	MouseButtonCount = 2;
	MouseAxisCount = 2;
	MouseWheelCount = 1;
	JoyButtonCount = SDL_JoystickNumButtons( joystick );
	JoyAxisCount = SDL_JoystickNumAxes( joystick );

	for( int i=0; i<MAX_JOY_AXIS; i++ )
		JoyAxis[i] = 0.0f;
	for( int i=0; i<MAX_MOUSE_AXIS; i++ )
		MouseAxis[i] = 0;
	
	MousePresent = true;
	KeyboardPresent = true;
	JoyPresent = (SDL_NumJoysticks()>0)?true:false;
	if( joystick != NULL )
		JoyPovPresent = (SDL_JoystickNumHats(joystick)>0)?true:false;
	else
		JoyPovPresent = false;
	quitMessage = false;
	
	cout<<"JoyPresent: "<< (char*)((JoyPresent)?"true":"false") <<endl;
	cout<<"JoyPovPresent: "<< (char*)((JoyPovPresent)?"true":"false") <<endl;
	
	isHandled = false;
	isInitialized = true;
	
	cout<<"SDL Initialized"<<endl;
}
SDL_InputEvent::~SDL_InputEvent()
{
	cout<<"SDL De-Initialized"<<endl;
	SDL_Quit();
}

/* Key input handleing
 *
 *	Handles key input
 */
KeyEventType SDL_InputEvent::getKeyState( unsigned char a ) const
{
	if( a < MAX_KEY_COUNT )
		return KeyState[a];
	else
		return KeyNull;
}

/* Joystick input handleing
 *
 *	Handles all Joystick input
 */
JoyPovAxisEventType SDL_InputEvent::getPovState() const
{
	if( JoyPovPresent )
		return PovState;
	else
		return JoyPovNull;
}
JoyAxisEventType SDL_InputEvent::getJoyAxisState( int a ) const
{
	if( JoyPresent && a < JoyAxisCount && a < MAX_JOY_AXIS )
		return JoyAxisState[a];
	else
		return JoyAxisNull;
}
JoyButtonEventType SDL_InputEvent::getJoyButtonState( int a ) const
{
	if( JoyPresent && a < JoyButtonCount && a < MAX_JOY_BUTTON )
		return JoyButtonState[a];
	else
		return JoyButtonNull;
}

/* Mouse input handling
 *
 *	Handles all Mouse input
 */
MouseMoveAxisEventType SDL_InputEvent::getMouseAxisState( int a ) const
{
	if( a < MouseAxisCount && a < MAX_MOUSE_AXIS )
		return MouseAxisState[a];
	else
		return MouseNull;
}
MouseButtonEventType SDL_InputEvent::getMouseButtonState( int a ) const
{
	if( a < MouseButtonCount && a < MAX_MOUSE_BUTTON )
		return MouseButtonState[a];
	else
		return MouseButtonNull;
}
MouseWheelEventType SDL_InputEvent::getMouseWheelState( int a ) const
{
	if( a < MouseWheelCount && a < MAX_MOUSE_WHEEL )
		return MouseWheelState[a];
	else
		return MouseWheelNull;
}

/* Input hardware verifier
 *
 *	Verifies existence of connected hardware
 */
bool SDL_InputEvent::isMouesPresent() const
{
	return MousePresent;
}
bool SDL_InputEvent::isKeyboardPresent() const
{
	return KeyboardPresent;
}
bool SDL_InputEvent::isJoyPresent() const
{
	return JoyPresent;
}
bool SDL_InputEvent::isJoyPovPresent() const
{
	return JoyPovPresent;
}
bool SDL_InputEvent::initialized() const
{
	return isInitialized;
}
bool SDL_InputEvent::quitMessageReceived() const
{
	return quitMessage;
}

/* Button/Axis Verifiers
 *
 *	Verifies existence of button and axis amounts
 */
int SDL_InputEvent::getMouseButtonCount() const
{
	return MouseButtonCount;
}
int SDL_InputEvent::getMouseAxisCount() const
{
	return MouseAxisCount;
}
int SDL_InputEvent::getMouseWheelCount() const
{
	return MouseWheelCount;
}
int SDL_InputEvent::getJoyButtonCount() const
{
	return JoyButtonCount;
}
int SDL_InputEvent::getJoyAxisCount() const
{
	return JoyAxisCount;
}

/* getAxis
 *
 *	returns axis values between -1.0f and 1.0f
 */
float SDL_InputEvent::getJoyAxis( int Axis ) const
{
	if( Axis < JoyAxisCount && Axis < MAX_JOY_AXIS )
		return JoyAxis[Axis];
	else
		return 0.0f;
}
unsigned int SDL_InputEvent::getMouseAxis( int Axis ) const
{
	if( Axis < MouseAxisCount && Axis < MAX_MOUSE_AXIS )
		return MouseAxis[Axis];
	else
		return 0;
}

/* beginEventHandle
 *
 *	Begins input capture sequence
 */
void SDL_InputEvent::beginEventHandle()
{
	for( int i=0; i<MAX_KEY_COUNT; i++ )
		if( KeyState[i] == KeyPressed )
			KeyState[i] = KeyUp;
	for( int i=0; i<MAX_JOY_BUTTON; i++ )
		if( JoyButtonState[i] == JoyButtonPress )
			JoyButtonState[i] = JoyButtonUp;
	
	while( SDL_PollEvent( &event) )
	{
		switch( event.type )
		{
			case SDL_QUIT:
				quitMessage = true;
				continue;
			case SDL_KEYDOWN:
				if( KeyState[ event.key.keysym.sym ] == KeyUp )
					KeyState[ event.key.keysym.sym ] = KeyPressed;
				else 
					KeyState[ event.key.keysym.sym ] = KeyDown;
				continue;
			case SDL_KEYUP:
				if( KeyState[ event.key.keysym.sym ] == KeyDown )
					KeyState[ event.key.keysym.sym ] = KeyReleased;
				else
					KeyState[ event.key.keysym.sym ] = KeyUp;
				continue;
			case SDL_JOYBUTTONDOWN:
				if( JoyButtonState[ event.jbutton.button ] == JoyButtonUp )
					JoyButtonState[ event.jbutton.button ] = JoyButtonPress;
				else
					JoyButtonState[ event.jbutton.button ] = JoyButtonDown;
				continue;
			case SDL_JOYBUTTONUP:
				if( JoyButtonState[ event.jbutton.button ] == JoyButtonDown )
					JoyButtonState[ event.jbutton.button ] = JoyButtonRelease;
				else
					JoyButtonState[ event.jbutton.button ] = JoyButtonDown;
				continue;
			case SDL_JOYAXISMOTION:
				/* TODO:
				 *	make the cushion value dynamic
				 */
				if( event.jaxis.value > 3200 || event.jaxis.value < -3200 )
				{
					if( event.jaxis.value > 3200 )
						JoyAxisState[ event.jaxis.axis ] = (JoyAxisEventType)(JoyAxisMove | JoyAxisMovePlus);
					if( event.jaxis.value < -3200 )
						JoyAxisState[ event.jaxis.axis ] = (JoyAxisEventType)(JoyAxisMove | JoyAxisMoveMinus);
					JoyAxis[ event.jaxis.axis ] = (float)event.jaxis.value/(float)32768;
				}
				else
				{
					JoyAxisState[ event.jaxis.axis ] = JoyAxisNull;
					JoyAxis[ event.jaxis.axis ] = 0.0f;
				}
				continue;
			case SDL_JOYHATMOTION:
				PovState = JoyPovNull;
				if( event.jhat.type == SDL_HAT_UP )
					PovState = (JoyPovAxisEventType) (PovState | JoyPovUp);
				if( event.jhat.type == SDL_HAT_RIGHT )
					PovState = (JoyPovAxisEventType) (PovState | JoyPovRight);
				if( event.jhat.type == SDL_HAT_DOWN )
					PovState = (JoyPovAxisEventType) (PovState | JoyPovDown);
				if( event.jhat.type == SDL_HAT_LEFT )
					PovState = (JoyPovAxisEventType) (PovState | JoyPovLeft);
		}
	}
}
i'd appreciate any errors that you find.
to compile, just link to SDL
initialize the receiver once, and in your main loop, use "beginEventHandle()"

REMEMBER, most of this code is untested.
When banks compete, you win.
When ISPs compete, you win.
When electronics retailers compete, you win.
When governments compete...you get drafted.
gbox
Posts: 37
Joined: Mon May 01, 2006 3:41 am
Location: jeonju, korea
Contact:

Post by gbox »

:D
i try to find joystick module

thanks
http://cafe.naver.com/jcga

professor of Jelabukdo Game Engine Academy
3DModelerMan
Posts: 1691
Joined: Sun May 18, 2008 9:42 pm

sorry

Post by 3DModelerMan »

Sorry to pull up an old thread, but does this have support for multiple joysticks?.
That would be illogical captain...

My first full game:
http://www.kongregate.com/games/3DModel ... tor#tipjar
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

No, since it only calls SDL_JoystickOpen() for the 1st joystick.

It also doesn't validate joystick before using it in SDL_JoystickNumButtons() and SDL_JoystickNumAxes().

Both of these are fixable, if you want to put some work in.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply