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

SDL Custom Input

Started by wanderinghobo Sep 6, 2009 at 2:36 AM 2 replies 3.2k views
Original Post
wanderinghobo
wanderinghobo
Hi everyone, I've been slowly building a 2d fighting engine and its getting to the point where I need to worry about how I want the players to store which keyboard keys or joystick keys will be the ones they will use when playing the game. So at the moment its currently using just some default keys, but I've got it so you can change which keys will be used within the code. But before I go to far down this road I was wondering if there any examples of saving in and out custom input for both keyboard and gamepad devices? How would you go about this? etc. Anything would be helpful. I know a lot of the sdl emulators have some sort of custom key binding system, but I'm not sure where to start. Thanks for everyone's time
fastcall22
fastcall22
I whipped this up in about 20 minutes, hopefully it can give you some ideas:

#include <string>#include <map>#include <exception>#include <sstream>#include <boost/shared_ptr.hpp>class InputBind {protected:	InputManager&	mInput;public:	InputBind( InputManager& input ) : mInput( input ) {	}		virtual ~InputBind() {	}		virtual float GetTriggerState() const = 0;	// For buttons, keys, and etc	virtual bool GetAxisState() const = 0; // For axes, returns range from, 0.f to 1.f};class KeyBind : public InputBind {public:	unsigned	mWhichKeyPos;	// If used in place of a joy axis, this is the key for +axis	unsigned	mWhichKeyNeg;	// and for -axis.  If this is a regular key press, then this is ignored	public:	KeyBind( InputManager& i, unsigned keypos, unsigned keyneg = 0 ) 		: InputBind( i )		, mWhichKeyPos( keypos )		, mWhichKeyNeg( keyneg ) {	}		bool GetTriggerState() const {		// Returns either of the buttons state state		return mInput.IsKeyDown( mWhichKeyPos ) || mInput.IsKeyDown( mWhichKeyNeg );	}		float GetAxisState() const {		// Returns -1 when mWhichKeyNeg is pressed, 1 when mWhichKeyPos is pressed		// or 0 when none or both are pressed.		return 			(mInput.IsKeyDown( mWhichKeyPos ) ? 1.f : 0.f) + 			(mInput.IsKeyDown( mWhichKeyNeg ) ? -1.f : 0.f );	}};class AxisBind : public InputBind {public:	unsigned	mWhichJoy;	unsigned	mWhichAxis;		// If an axis is used in place of a key press, this is the minimum value the 	// axis state must be in order for the press to be registered.	float		mThreshold;	public:	AxisBind( InputManager& i, unsigned joy, unsigned axis, float thres = 0.f ) 		: mWhichJoy( joy )		, mWhichAxis( axis )		, mThreshold( thres ) {	}	private:	float GetAxisState() const { 		// Returns the state of the axis		return mInput.GetJoystick( mWhichJoy ).GetAxis( mWhichAxis );	}public:		bool GetTriggerState() const {		return std::abs( GetAxisState() ) < mThreshold ? true : false;	}		bool GetAxisState() const {		return GetAxisState();	}};class BindMap {public:	typedef boost::shared_ptr<InputBind> 		SharedBind;	typedef std::map<std::string, SharedBind>	BindMap;	private:	BindMap		mBinds;public:		const InputBind* operator[] ( const std::string& name ) {		// Probably add some checks here, throw an exception		// on an attempt to access a bind that doesn't exists		// or log the message then return a dummy bind.		return mBinds[ name ].get();	}		// Assumes ownership of "bind":	void RegisterBind( const std::string& name, InputBind* bind ) {		mBinds[ name ] = SharedBind( bind );	}};// Usage:void Player::RegisterTestBinds( BindMap& binds, InputManager& i ) {	binds.RegisterBind( "PLAYER_MOVE_XAXIS", new AxisBind( i, 0, 0 ) );	binds.RegisterBind( "PLAYER_MOVE_YAXIS", new KeyBind( i, SDLK_UP, SDLK_DOWN ) );	binds.RegisterBind( "PLAYER_JUMP", new KeyBind( i, SDLK_SPACE ) );}bool Player::Update( BindMap& binds, float dt ) {	Vector2 drive = Vector2( 		// Either a button/key or an axis, GetAxisState will return anything between -1 and 1:		binds[ "PLAYER_MOVE_XAXIS" ]->GetAxisState(),			binds[ "PLAYER_MOVE_YAXIS" ]->GetAxisState() );	float jump = 0.f;	if ( this->IsOnGround() && binds[ "PLAYER_JUMP" ].get()->GetTriggerState() ) 		jump = 1.f;			return false;}


I haven't tested, but I *think* this will compile. There's probably some typos somewhere ...
grimfang4
grimfang4
Similar, but better tested and more complete than _fastcall's implementation (which looks good), is StickyInput (http://code.bluedinosaurs.com/SDL.html). If you need any help with it, just ask.

Jonny D

Topic Locked

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

Sign in to reply to this topic.