Sign in to follow this  
nullsquared

Huh? SDL - Weird (I mean it, WEIRD) stuff happens with keys...???

Recommended Posts

Ok...... This is freaky... Anyways, SDL is kinda messing up or something... Look:
if (mainApp.GetKey(SDLK_RIGHT))
    player1.Setx(player1.Getx() + player1.GetSpeed());
CApp_Input::GetKey(Uint8 aKey) is this:
Uint8 CApp_Input::GetKey(Uint8 aKey)
{
    return (m_pKeysHeld[aKey]);
}

//^^^^  That is updated by:
void CApp_Input::UpdateKeys()
{
    m_pKeysHeld = SDL_GetKeyState(NULL);
}

I believe that should work... Guess what? It doesnt. HOWEVER - IF I change SDLK_LEFT to SDLK_f or whatever it works. HOWEVER - The above code works fine, if I just do SDL_GetKeyState(NULL)[SDLK_LEFT]... What can be wrong here? I had a problem with LALT and RALT before, too. It wasnt fixed either. I've also tried making GetKey(Uint8 ...) {...} to return SDL_GetKeyState(...)[aKey], but it doesnt work either... Any ideas? Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
Well... Uhh... Anyone have any ideas?


how often does UpdateKeys get called. are you positive it gets called (its not accidentally in some if clause )?

other than that we'll need some code...

EDIT: do you use SDL_PumpEvents for reasons described here

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Quote:
Original post by agi_shi
Well... Uhh... Anyone have any ideas?


how often does UpdateKeys get called. are you positive it gets called (its not accidentally in some if clause )?

other than that we'll need some code...


Every frame. Ok, here:

bool Run()
{
while (mainApp.UpdateEvent())
{
switch (mainApp.GetEvent().type)
{
case SDL_QUIT:
return false;
break;

case SDL_KEYDOWN:
{
switch(mainApp.GetEvent().key.keysym.sym)
{
case SDLK_ESCAPE:
return false;
break;
}
}
break;
}
}

mainApp.UpdateKeys();

if (mainApp.GetKey(SDLK_LEFT))
player1.Setx(player1.Getx() - player1.GetSpeed());

if (mainApp.GetKey(SDLK_RIGHT))
player1.Setx(player1.Getx() + player1.GetSpeed());

return true;
}


This is the 'so-called' core part of the problem. It's called every frame in this:

while (Run())
/*Draw my stuff...*/;


Here is the simple CApp_Input class (implementation, the declaration is simply the names of the funcs and the names of the variables...):

#include <SDL/SDL.h>

#include "CApp_Input.h"

CApp_Input::CApp_Input()
{
}

CApp_Input::~CApp_Input()
{
}

Uint8 CApp_Input::GetKey(Uint8 aKey)
{
return (m_pKeysHeld[aKey]);
}

void CApp_Input::UpdateKeys()
{
m_pKeysHeld = SDL_GetKeyState(NULL);
}



mainApp is a CApp. CApp inherits from CApp_Event and CApp_Input.

Like I said, returning the Uint8 doesnt work with SDLK_LEFT(or RIGHT). However, if I do it on the fly (SDL_GetKeyState(NULL)[SDLK_LEFT]) it works. And again, LEFT and RIGHT dont work and also F<whatever> and LALT and RALT. Before I never had these probs, maybe it's just me?

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Quote:
Original post by agi_shi
Well... Uhh... Anyone have any ideas?


how often does UpdateKeys get called. are you positive it gets called (its not accidentally in some if clause )?

other than that we'll need some code...

EDIT: do you use SDL_PumpEvents for reasons described here


Nope, I dont. IIRC, SDL_PollEvent(...) calls it.

Anyways, I remember seeing that so I tried it, but it didnt work. Any ideas?

EDIT: Yup, I tried it again. Doesn't work.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
what can i say. should work. the only thing i can think of is to make the smallest example you can think of that demonstrates this behaviour, and post it so we can try it out.


Ok.. Sure.

I'll make an example right now, when I finish I'll post the source.

(It'll be one file though, I'm not going with perfect code right now...)

Share this post


Link to post
Share on other sites
There we go:

#include <SDL/SDL.h>

class input // no specific nice names right now, just code...
{
public:
input();
~input();

Uint8 GetKey(Uint8 aKey);
void UpdateKeys();

private:
Uint8 *m_pKeysHeld;
};

input::input()
{
}

input::~input()
{
}

Uint8 input::GetKey(Uint8 aKey)
{
return (m_pKeysHeld[aKey]);
}

void input::UpdateKeys()
{
m_pKeysHeld = SDL_GetKeyState(NULL);
}

int main(int, char**)
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
return 1;

if (SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF) == NULL)
return 1;

input myIn;

SDL_Event theEvent;

short done = 0;

while (!done)
{
while (SDL_PollEvent(&theEvent))
{
switch (theEvent.type)
{
case SDL_QUIT:
done = 1;
break;
}
}

myIn.UpdateKeys();

if (myIn.GetKey(SDLK_LEFT)) // Nope... Ain't working
done = 1;

if (myIn.GetKey(SDLK_SPACE)) // Guess what happens? It works
done = 1;

//Uncomment this and it works.... but comment that so it doesnt mess
//with it
//if (SDL_GetKeyState(NULL)[SDLK_LEFT])
//done = 1;
}

SDL_Quit();

return 0;
}


Like I said inside, uncomment the direct one and see... Uncomment the other one and comment the direct one and see again...

Any ideas?

Share this post


Link to post
Share on other sites
hmm. thats really strange. i'm going to take another look, because this works...

and as far as i can tell its doing the same thing


/*
you may need to change the header...
*/

#include "SDL.h"

int main( int argc, char **argv )
{
Uint8 *keys;
SDL_Event event;
SDL_Surface *screen;
int done = 0;
SDL_Init(0);
screen = SDL_SetVideoMode( 400, 400, 32, 0 );

while(!done)
{

while( SDL_PollEvent( &event ) )
{
if( event.type == SDL_QUIT )
done = 1;
}
keys = SDL_GetKeyState(NULL);
if( keys[SDLK_RIGHT] )
{
SDL_WM_SetCaption( "right",NULL );
}
else
{
if( keys[SDLK_LEFT] )
SDL_WM_SetCaption( "Left",NULL );
else
SDL_WM_SetCaption( "NONE!",NULL );
}
}
SDL_Quit();
return 0;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
hmm. thats really strange. i'm going to take another look, because this works...

and as far as i can tell its doing the same thing

*** Source Snippet Removed ***


Well... Rip-off, that works for me. Using a variable... And SDL_GetKeyState(...). I actually thought of doing something like this so in my example I tried SDL_GetKeyState(NULL)[SDLK_LEFT] and it worked. But when I put it into a class (the example) it doesn't work. It's interesting no one else actually replied here lol.

*The problem continues...*

Share this post


Link to post
Share on other sites
okay i solved it.

the "aKey" argument of GetKey needs to be an int.

how i missed this...

i noticed it eventually.

SDLK_LEFT is a high value ( bigger than a Uint8) it gets truncated in assignment. so you were getting the value of some other key.

enjoy!

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
okay i solved it.

the "aKey" argument of GetKey needs to be an int.

how i missed this...

i noticed it eventually.

SDLK_LEFT is a high value ( bigger than a Uint8) it gets truncated in assignment. so you were getting the value of some other key.

enjoy!


WOW - THANKS A LOT. A LOT.

Really, thanks. I was using Uint8 because.. well, since the array is delclared as a Uint8 I thought that all the keys might be Uint8's. Now that I think about it, it's not that way. The result of x[j] might be a Uint8, but j might not be.


rip_off->rating->setByInt(rip_off->rating->get() + 1);


Hmmm.. I think (yup, 'another user with the same ip') I rated you up already before. Aww well lol.

Share this post


Link to post
Share on other sites
Calling SDL_GetKeyState every tick is quite a lot of work. A polling system will help you out a lot.

It would end up being something like this:
SDL_Event event;
while( SDL_PollEvent( &event ) ) {
switch( event.type )
{
case SDL_KEYDOWN:
KeyDown(&event.key.keysym); // Call the KeyDown event.
break;
case SDL_KEYUP:
KeyUp(&event.key.keysym); // Call the KeyUp event.
break;
case SDL_QUIT:
QuitApp(); // quit the app
break;
}
}

Forgive me if that's wrong, I haven't writen C++ in a while (turned to C#). In your KeyUp and KeyDown methods, you could update an array depending on which key was pressed or "un-pressed". Good luck!

Share this post


Link to post
Share on other sites
Quote:
Original post by Rob Loach
Calling SDL_GetKeyState every tick is quite a lot of work. A polling system will help you out a lot.

It would end up being something like this:
SDL_Event event;
while( SDL_PollEvent( &event ) ) {
switch( event.type )
{
case SDL_KEYDOWN:
KeyDown(&event.key.keysym); // Call the KeyDown event.
break;
case SDL_KEYUP:
KeyUp(&event.key.keysym); // Call the KeyUp event.
break;
case SDL_QUIT:
QuitApp(); // quit the app
break;
}
}

Forgive me if that's wrong, I haven't writen C++ in a while (turned to C#). In your KeyUp and KeyDown methods, you could update an array depending on which key was pressed or "un-pressed". Good luck!


Good idea. Maybe a bool array would be nice. Does anyone know how many keys there are on a keyboard? I don't want to count them...

Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
Quote:
Original post by Rob Loach
Calling SDL_GetKeyState every tick is quite a lot of work. A polling system will help you out a lot.

It would end up being something like this:
SDL_Event event;
while( SDL_PollEvent( &event ) ) {
switch( event.type )
{
case SDL_KEYDOWN:
KeyDown(&event.key.keysym); // Call the KeyDown event.
break;
case SDL_KEYUP:
KeyUp(&event.key.keysym); // Call the KeyUp event.
break;
case SDL_QUIT:
QuitApp(); // quit the app
break;
}
}

Forgive me if that's wrong, I haven't writen C++ in a while (turned to C#). In your KeyUp and KeyDown methods, you could update an array depending on which key was pressed or "un-pressed". Good luck!


Good idea. Maybe a bool array would be nice. Does anyone know how many keys there are on a keyboard? I don't want to count them...


okay. if you do it that way you are just duplicating SDL_GetKeyState.

the way i chose to do is to wrap input into a class.

the only keys you store are the ones relavent ( breakout might have 3, left, right and quit ).

in an update() oer equivelant function you just check wether those keys have been pressed or released, and update your bool array. then provide you won enum like so

enum Keys{
KEY_LEFT,
KEY_RIGHT,
KEY_QUIT,
};

the actual keys these are mapped to can get stored in a file, allowing you to make your program independant of the keys you use while programming

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this