Public Group

# Keyboard Input Handling

This topic is 2946 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have been using...
if(SDL_PollEvent(&ev))//in main loop{do_event(&ev);}//....void do_event(SDL_Event* Event);//members of a classvoid ev_exit();//functionsvoid ev_keydown(SDLKey sym, SDLMod mod, Uint16 unicode);//...........void c_app::ev_keydown(SDLKey sym, SDLMod mod, Uint16 unicode){	switch (sym)	{		case SDLK_ESCAPE: ev_exit();break;		case SDLK_LEFT: /*do stuff*/break;                //.................        }}//.........

...to handle all events and keyboard/mouse input, but this method limits me to one keypress(or mouse click I suppose) at a time. That is one unique key not holding down the same key(which is handled with whatever the relevant SDL function is).

So I was thinking that maybe I could use a vector to capture every event each frame and then repeat the event checking code until the list was cleared, but I'm thinking that this might cause a significant slowdown, so what would be a better method to handle key presses? or events in general?

##### Share on other sites
I'm not sure what you mean by only one event at a time, but the first thing you'll want to do is to replace your 'if' statement with a 'while' loop, so as to process all pending events each update. (This may fix whatever problem you're describing, but since I'm not clear on the nature of the problem, I can't really say for sure.)

##### Share on other sites
Ah that seems silly for me to have overlooked that...but my problem was having multiple actions basedon different events. For example if pressing left rotates a square clockwise and pressing left rotates the square counter-clockwise, pressing both should initiate both actions and they should cancel out each other.

Granted, that specific example is completely useless, but that is the best way for me to convey what I'm thinking. I noticed that I ommitted a large part of the code...

do_event(...)
void c_events::do_event(SDL_Event* Event){	switch(Event->type)	{		case SDL_ACTIVEEVENT:		{			switch(Event->active.state)			{				case SDL_APPMOUSEFOCUS:				{					if ( Event->active.gain )					{						ev_mouse_focus();					}					else					{						ev_mouse_blur();					}					break;				}				case SDL_APPINPUTFOCUS:				{					if ( Event->active.gain )					{						ev_input_focus();					}					else					{						ev_input_blur();					}					break;				}				case SDL_APPACTIVE:				{					if ( Event->active.gain )					{						ev_restore();					}					else					{						ev_minimize();					}					break;				}			}			break;		}		case SDL_KEYDOWN:		{			ev_keydown(Event->key.keysym.sym,Event->key.keysym.mod,			 Event->key.keysym.unicode);			break;		}		case SDL_KEYUP:		{			ev_keyup(Event->key.keysym.sym,Event->key.keysym.mod,			 Event->key.keysym.unicode);			break;		}		case SDL_MOUSEMOTION:		{			ev_mouse_move(Event->motion.x,Event->motion.y,			 Event->motion.xrel,Event->motion.yrel,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_LEFT))!=0,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_RIGHT))!=0,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_MIDDLE))!=0);			break;		}		case SDL_MOUSEBUTTONDOWN:		{			switch(Event->button.button)			{				case SDL_BUTTON_LEFT:				{					ev_mouse_ldown(Event->button.x,Event->button.y);					break;				}				case SDL_BUTTON_RIGHT:				{					ev_mouse_rdown(Event->button.x,Event->button.y);					break;				}				case SDL_BUTTON_MIDDLE:				{					ev_mouse_mdown(Event->button.x,Event->button.y);					break;				}			}			break;		}		case SDL_MOUSEBUTTONUP:		{			switch(Event->button.button)			{				case SDL_BUTTON_LEFT:				{					ev_mouse_lup(Event->button.x,Event->button.y);					break;				}				case SDL_BUTTON_RIGHT:				{					ev_mouse_rup(Event->button.x,Event->button.y);					break;				}				case SDL_BUTTON_MIDDLE:				{					ev_mouse_mup(Event->button.x,Event->button.y);					break;				}			}			break;		}		case SDL_JOYAXISMOTION:		{			ev_joy_axis(Event->jaxis.which,Event->jaxis.axis,Event->jaxis.value);			break;		}		case SDL_JOYBALLMOTION:		{			ev_joy_ball(Event->jball.which,Event->jball.ball,			 Event->jball.xrel,Event->jball.yrel);			break;		}		case SDL_JOYHATMOTION:		{			ev_joy_hat(Event->jhat.which,Event->jhat.hat,Event->jhat.value);			break;		}		case SDL_JOYBUTTONDOWN:		{			ev_joy_bdown(Event->jbutton.which,Event->jbutton.button);			break;		}		case SDL_JOYBUTTONUP:		{			ev_joy_bup(Event->jbutton.which,Event->jbutton.button);			break;		}		case SDL_QUIT:		{			ev_exit();			break;		}		case SDL_SYSWMEVENT:		{			//Ignore			break;		}		case SDL_VIDEORESIZE:		{			ev_resize(Event->resize.w,Event->resize.h);			break;		}		case SDL_VIDEOEXPOSE:		{			ev_expose();			break;		}		default:		{			ev_user(Event->user.type,Event->user.code,			 Event->user.data1,Event->user.data2);			break;		}	}}

##### Share on other sites
Quote:
 For example if pressing left rotates a square clockwise and pressing left rotates the square counter-clockwise
Did you mean pressing 'right' rotates the square counter-clockwise?

If so, it's not clear to me from what you've posted why you wouldn't get the desired behavior.

Or are you asking how to tell if a key is currently held down, as opposed to determining when it's pressed and released? If so, you can use the SDL 'get keys' function and poll directly, or you can set a flag (e.g. a 'rotating clockwise' flag) when the corresponding key is pressed, and then clear the flag when it's released.

##### Share on other sites
I was just making up something random for an example regarding the clockwise/couter statement.

Right now everything works as expected for keypresses.

However, I want to add the possibility to have multiple *different* key presses per frame. For example if holding up moves forward, and moving left moves toward the left, holding both up and left simultaneously should cause you to move diagonally left of true up.

Right now, if I press left while I was already pressing up, it will stop moving up, and only move left. So whatever the most recent event is is overriding any other event.

I also have 'SDL_EnableKeyRepeat(1, SDL_DEFAULT_REPEAT_INTERVAL);' during initialization to allow holding keys. I don't know exactly what this function affects, though.

##### Share on other sites
Make an array of all the keys pressed like:
C#:
bool[] Keysdown = new bool[323];... in key pressed:Keysdown[get key number that is down] = true;... in key released:Keysdown[get key number that was released] = false;

Sorry if anything is wrong, trying to work off the top of my head and am very tired atm :S

##### Share on other sites
I think you need to preserve the state of each key, button, etc.
I'm not used to SDL myself but there seems to be a couple of functions SDL_GetKeyState SDL_GetMouseState that does most of the job for you.

edit:
And the joystick SDL Joystick API ...

##### Share on other sites
Well I hope that the functions that you mentioned will help clean up my code. I managed to get it working suing flags like so...
void c_app::ev_keydown(SDLKey sym, SDLMod mod, Uint16 unicode){	switch (sym)	{		case SDLK_ESCAPE: ev_exit();break;		//		case SDLK_w: key_check1|=DOWN_W;break;		case SDLK_s: key_check1|=DOWN_S;break;                //....       }}void c_app::ev_keyup(SDLKey sym, SDLMod mod, Uint16 unicode){	switch (sym)	{		case SDLK_w: key_check1&=~DOWN_W;break;		case SDLK_s: key_check1&=~DOWN_S;break;		case SDLK_a: key_check1&=~DOWN_A;break;                //..........        }}//this runs afetr all event checksvoid c_app::check_flags(){	int ii=1;	if (key_check1 & DOWN_UP){o_camera.inc_coords(0,0,0, -ii,0,0);}	if (key_check1 & DOWN_DOWN){o_camera.inc_coords(0,0,0, +ii,0,0);}}

...and it works as I was hoping, but requires a lot of extra typing.
I know that you said that you don't have much experience with SDL, but would you have any idea on the performance of 'SDL_GetKeyState' versus bitwise checking? It would be fantastic if the SDL function is slower so that I will have a reason to not go back and erase all of what I'd added.

##### Share on other sites
I couldn't say for sure but I'm pretty sure both will be a leap year from becoming a bottleneck. The few times I have profiled my code the rendering is always the big CPU hog. Stuff like input branching doesn't even show up on the charts.

If I were to guess, I guess that your method is at least as fast, assuming the system needs to dispatch input events either way

##### Share on other sites
Damn...well at least I learned a bit about flags and such, thank you for the suggestions.

1. 1
2. 2
frob
16
3. 3
4. 4
5. 5

• 17
• 13
• 14
• 76
• 22
• ### Forum Statistics

• Total Topics
632148
• Total Posts
3004359

×