# SDL input problems...

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

## Recommended Posts

[source lang=C++]
if (SDL_Init( SDL_INIT_EVERYTHING) < 0)
return cWUtility::ErrorLog.Write("cWInput::Init()");

SDL_EVENT   m_Event;
Uint8       *m_KeyState;
Uint8       m_MouseState;
long        m_AbsX, m_AbsY, m_RelX, m_RelY;

SDL_PollEvent( &m_Event );
SDL_EnableUNICODE( 1 );

m_KeyState = SDL_GetKeyState(NULL);

while (loop)
{
SDL_PollEvent( &m_Event );
SDL_PumpEvents();
m_MouseState = SDL_GetMouseState((int*)m_AbsX, (int*)m_AbsY);
SDL_GetRelativeMouseState((int*)m_RelX, (int*)m_RelY);

if ( MYGetKeyState(SDL_ESCAPE))
exit();
}

bool MYGetKeyState(long Key)
{
if (m_KeyState[Key] == 1 )
return true;
return false;
}


for some reason none of my keyboard and mouse events are working.. it's not seeing that anything is being pressed (of course this is a very simplified version of what i really have coded) is there anything wrong with that?

##### Share on other sites
The problem with your keyboard inputs can be explained because the
m_KeyState = SDL_GetKeyState(NULL) should be within your main loop.

Also, I think you're calling SDL_GetMouseState incorrectly. It should look something like:
m_MouseState = SDL_GetMouseState( &m_AbsX, &m_AbsY );

Cheers,
--Brian

##### Share on other sites
ohhh, ok. what about pollevent() and pumpevents()? should i have those in my main loop?

##### Share on other sites
If you're not using that SDL_Event object, you don't need SDL_PollEvent at all. You will need SDL_PumpEvents, however.

##### Share on other sites
Alright. How's the order go in the loop? should i pump events THEN getkeystate? for vice-versa?

Also, what's the purpose of using the SDL_EVENT, and polling the event?

##### Share on other sites
Quote:
 Original post by EvilKnuckles666Alright. How's the order go in the loop? should i pump events THEN getkeystate? for vice-versa?Also, what's the purpose of using the SDL_EVENT, and polling the event?

the event queue is central to SDL's event handling. if you do not empty the queue( by polling over every element and dealing with those you want ) your application will become unresponsive. you need to do that regularly.

the "snapshot" input functions can then be used, but they are not a complete replacement for polling

##### Share on other sites
alright, i get the part about pollevent().. kinda, but what if there are 2 buttons being pressed at the same time?

can someone post some examples using pollevent() AND pumpevents() and event getkeystate()?

##### Share on other sites
Quote:
 Original post by EvilKnuckles666alright, i get the part about pollevent().. kinda, but what if there are 2 buttons being pressed at the same time? can someone post some examples using pollevent() AND pumpevents() and event getkeystate()?

I've tried SDL_Event with double key presses. It _WONT_ work. However, SDL_GetKeyState(...) will: (from my code) (not really, from my _previous_ code)
bool Run() {    static SDL_Event s_Event;    while (SDL_PollEvent(&s_Event)) {        if (s_Event.type == SDL_KEYDOWN) {            switch (s_Event.key.keysym.sym) {                case SDLK_ESCAPE: return false; break;                default: // whatever            }        }    }    static unsigned char *s_Keys = SDL_GetKeyState(NULL);    // Just for my sake ;)    static unsigned int SDLK_ALT = (SDLK_LALT | SDLK_RALT);    if (s_Keys[SDLK_ALT] && s_Keys[SDLK_F4])        return false;    SDL_PumpEvents();    return true;}

As you can see, the polling will NOT take two or more keys. However, the snapshot version of the keys will, as you can see.

If you have any more questions, say so.

C++

##### Share on other sites
hmm... would i be able to just have something that looks like this?

[source lang=C++]bool Run() {    static SDL_Event s_Event;        // main loop    while (1)    {      SDL_PollEvent(&s_Event);      static unsigned char *s_Keys = SDL_GetKeyState(NULL);      static unsigned int SDLK_ALT = (SDLK_LALT | SDLK_RALT);      if (s_Keys[SDLK_ALT] && s_Keys[SDLK_F4])          break;      SDL_PumpEvents();    }    return true;}

also:
so the pollevent() needs to be at the top with the getkeystate() and the pumpevents() needs to be at the bottom once i'm done checking the states and whatnot?

edit:
since the SDL_EVENT only checks one key, and i'm going to use the getkeystate() anyway? could i just avoid using pollevent() completely? or would i have to do just what i'm doing in that code i posted and just ahve a call to it?

##### Share on other sites
Quote:
 Original post by EvilKnuckles666hmm... would i be able to just have something that looks like this?*** Source Snippet Removed ***also:so the pollevent() needs to be at the top with the getkeystate() and the pumpevents() needs to be at the bottom once i'm done checking the states and whatnot?edit:since the SDL_EVENT only checks one key, and i'm going to use the getkeystate() anyway? could i just avoid using pollevent() completely? or would i have to do just what i'm doing in that code i posted and just ahve a call to it?

Basicly, yes, you can have code like that. Take this as a note though, it DOESN'T have to look like that, it's just how I wrote some code. What you should do is:
while (gameRunning) // or whatever your main loop is{    while (SDL_PollEvent(&yourEvent))    {        // event stuff    }    // other stuff}

My previous code was just an example.

No, it doesn't have to be in that order. It's just the order that I and many others prefer because of it's readability.

SDL_Event will hold events. Each key press, and any other message is an event. However, when you press 'w' and key holding it and press 'd' you will get a message for 'd', and not for 'w'. This is not what you wan't in games because your character then won't be able to move diagnoally. However, this is good for menus. This is where SDL_GetKeyState is nice. It get's a snapshot of the keys. So it can capture many keys at once. This way, you can have diagnol movement.

C++

##### Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
 Original post by EvilKnuckles666hmm... would i be able to just have something that looks like this?*** Source Snippet Removed ***also:so the pollevent() needs to be at the top with the getkeystate() and the pumpevents() needs to be at the bottom once i'm done checking the states and whatnot?edit:since the SDL_EVENT only checks one key, and i'm going to use the getkeystate() anyway? could i just avoid using pollevent() completely? or would i have to do just what i'm doing in that code i posted and just ahve a call to it?

Basicly, yes, you can have code like that. Take this as a note though, it DOESN'T have to look like that, it's just how I wrote some code. What you should do is:
*** Source Snippet Removed ***
My previous code was just an example.

No, it doesn't have to be in that order. It's just the order that I and many others prefer because of it's readability.

SDL_Event will hold events. Each key press, and any other message is an event. However, when you press 'w' and key holding it and press 'd' you will get a message for 'd', and not for 'w'. This is not what you wan't in games because your character then won't be able to move diagnoally. However, this is good for menus. This is where SDL_GetKeyState is nice. It get's a snapshot of the keys. So it can capture many keys at once. This way, you can have diagnol movement.

C++

I thought you said not 'avoid' but 'only use'. Anyways, not really.

SDL will send many messages. For example, the 'X' on top of your window is a message. When you click it, you get SDL_QUIT. Knowing that, you would quit. However, you would not get SDL_QUIT without SDL_PollEvent.

Do you see what I mean? I don't know how to explain, really... Ask if you have any more questions.

C++

##### Share on other sites
I may be mistaken, but won't the line:

static unsigned char *s_Keys = SDL_GetKeyState(NULL);

Only call SDL_GetKeyState(NULL); once when that variable is first initialized first time around? Each subsequent call will not update the keystate since it's declared as static?

Of course, I go about all this input stuff a lot different from the ideas presented here, so rather than just post that, you can take a look at what I do if you want (lots of comments): Input Demo

##### Share on other sites
Quote:
 Original post by Drew_BentonI may be mistaken, but won't the line:static unsigned char *s_Keys = SDL_GetKeyState(NULL);Only call SDL_GetKeyState(NULL); once when that variable is first initialized first time around? Each subsequent call will not update the keystate since it's declared as static?Of course, I go about all this input stuff a lot different from the ideas presented here, so rather than just post that, you can take a look at what I do if you want (lots of comments): Input Demo

Oh... Yeah, I didn't think about that (rofl)!

It's just that I had keys in my functions, but not static, and since in the example I made a Run() function that ran the keys I decided to make it static, off-my-head. Atleast it's only an example... Since I got... anonymous I can't edit things so I'll just say it here:
// if in a function// notstatic unsigned char s_Keys = SDL_GetKeyState(NULL);//butstatuc unsigned char s_Keys;s_Keys = SDL_GetKeyState(NULL);

Good luck!

C++

##### Share on other sites
Quote:
 Original post by Anonymous PosterIt's just that I had keys in my functions, but not static, and since in the example I made a Run() function that ran the keys I decided to make it static, off-my-head. Atleast it's only an example... Since I got... anonymous I can't edit things so I'll just say it here:*** Source Snippet Removed ***Good luck!C++

your use of statics is unnessecary and adds nothing but possible confusion and bugs.

only consider statics when you need to retain data across function calls, which for c++ means making an object usually.

the lowdown on SDL events:

you _must_ call SDL_PollEvent(...) to clear the event queue. your application will not run correctly on some systems without periodically running pollevent.

calls to GetKeyState and GetMouseState are just handy ways of accessing an input device. you can get exactly the same information from polling events.

problems can occur when detecting mulitiple keypresses. basically, sometimes if you hold down 2 or 3 keys, no program can detect them, (on windows) you can try this out in notepad. try pressing p, then y then t then r without releasing any of them.

on my system, you cant simultaneously detect all of them. your application will get the same data then using Poll()ing or Get*State()ing...

##### Share on other sites
Quote:
Original post by rip-off
Quote:
 Original post by Anonymous PosterIt's just that I had keys in my functions, but not static, and since in the example I made a Run() function that ran the keys I decided to make it static, off-my-head. Atleast it's only an example... Since I got... anonymous I can't edit things so I'll just say it here:*** Source Snippet Removed ***Good luck!C++

your use of statics is unnessecary and adds nothing but possible confusion and bugs.

only consider statics when you need to retain data across function calls, which for c++ means making an object usually.

the lowdown on SDL events:

you _must_ call SDL_PollEvent(...) to clear the event queue. your application will not run correctly on some systems without periodically running pollevent.

calls to GetKeyState and GetMouseState are just handy ways of accessing an input device. you can get exactly the same information from polling events.

problems can occur when detecting mulitiple keypresses. basically, sometimes if you hold down 2 or 3 keys, no program can detect them, (on windows) you can try this out in notepad. try pressing p, then y then t then r without releasing any of them.

on my system, you cant simultaneously detect all of them. your application will get the same data then using Poll()ing or Get*State()ing...

I like your words. They are... 'wise'.

Anyways, 'Poll()ing' cannot give me all my keys. However, 'Get*State()ing' can. 'Get*State()ing' gives a snapshot... All the keys pressed. 'Poll()ing' gives you the event, so that's why when you press 'p' you get a 'p' and even if you still hold it and press something else you would get something else.

C++

##### Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Original post by rip-off
Quote:
 Original post by Anonymous PosterIt's just that I had keys in my functions, but not static, and since in the example I made a Run() function that ran the keys I decided to make it static, off-my-head. Atleast it's only an example... Since I got... anonymous I can't edit things so I'll just say it here:*** Source Snippet Removed ***Good luck!C++

your use of statics is unnessecary and adds nothing but possible confusion and bugs.

only consider statics when you need to retain data across function calls, which for c++ means making an object usually.

the lowdown on SDL events:

you _must_ call SDL_PollEvent(...) to clear the event queue. your application will not run correctly on some systems without periodically running pollevent.

calls to GetKeyState and GetMouseState are just handy ways of accessing an input device. you can get exactly the same information from polling events.

problems can occur when detecting mulitiple keypresses. basically, sometimes if you hold down 2 or 3 keys, no program can detect them, (on windows) you can try this out in notepad. try pressing p, then y then t then r without releasing any of them.

on my system, you cant simultaneously detect all of them. your application will get the same data then using Poll()ing or Get*State()ing...

I like your words. They are... 'wise'.

Anyways, 'Poll()ing' cannot give me all my keys. However, 'Get*State()ing' can. 'Get*State()ing' gives a snapshot... All the keys pressed. 'Poll()ing' gives you the event, so that's why when you press 'p' you get a 'p' and even if you still hold it and press something else you would get something else.

C++

depends on what you are doing.

some people prefer

if( leftkey ) movePlayerLeft();

i prefer

if( leftkeydown ) setPlayerVelocity( ... );
if( leftkeyup ) setPlayerVelocity( 0 );

its a bit more than that but you get the point...

##### Share on other sites
Seems to be a bit of confusion here... as I said earlier, if you use PumpEvents, you don't need PollEvent. (Unless there's a bug in SDL that I am not aware of.)

Also, you can track multiple keypresses using SDL_EVENT/PollEvent, but you have to watch for it yourself. When a keydown event comes in, you mark the key as down, and when a keyup comes in, you mark it as up. That way you can see when multiple keys are pressed. If you don't need the event handling for other purposes though, you may as well stick with GetKeyState.