How to read multiple inputs at the same time?

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
? switch(event.type) {
? ? case SDL_KEYDOWN:
? ? ? if (event.key.keysym.sym == SDLK_LEFT) ?key = “left”;
? ? ? if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
? ? ? if (event.key.keysym.sym == SDLK_UP) ? ?key = “up”;
? ? ? if (event.key.keysym.sym == SDLK_DOWN) ?key = “down”;
? ? ? printf(“Key down: %s\n”, key);
? ? ? break;
? }
}

I’m finding that when I press and hold down two arrow keys (so I can go diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew

if (SDL_PollEvent(&event)) {

Should be while :)?

----- Reply message -----Von: “Andrew Havens”
An:
Betreff: [SDL] How to read multiple inputs at the same time?
Datum: Di., Nov 12, 2013 21:59

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew

IIRC you should use key states, basically you fetch an array containing the
state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in
SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens > Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go
diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL2 uses SDL_GetKeyboardState(). It’s mostly the same as how SDL1.2 did
it, though. The biggest difference is that instead of using keycodes (e.g.
SDLK_LEFT), you have to use scancodes (e.g. SDL_SCANCODE_LEFT or
SDL_GetScancodeFromKey(SDLK_LEFT)) or else expect crashing.

Jonny DOn Tue, Nov 12, 2013 at 4:06 PM, Hern?n Gurmendi wrote:

IIRC you should use key states, basically you fetch an array containing
the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in
SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go
diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I just properly read your code and found some things that are worth
mentioning:

  • You should define your “key” string like “char key[LEN]” instead of just
    a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code, in
    case you want to fetch the key events you should use something like
    while(SDL_PollEvent(&event)) because in your code you’re actually grabbing
    the first event in the event queue and nothing else. Furthermore, after
    using SDL_PollEvent, the event structure only holds information regarding a
    SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check
this :P.

2013/11/12 Hern?n Gurmendi <@Hernan_Gurmendi>> IIRC you should use key states, basically you fetch an array containing

the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in
SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go
diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

BTW, nevermind my first comment, the one about the memory leaks. I’m just
plain stupid, there’s nothing wrong with yours. LOL.

2013/11/12 Hern?n Gurmendi <@Hernan_Gurmendi>> I just properly read your code and found some things that are worth

mentioning:

  • You should define your “key” string like “char key[LEN]” instead of just
    a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code, in
    case you want to fetch the key events you should use something like
    while(SDL_PollEvent(&event)) because in your code you’re actually grabbing
    the first event in the event queue and nothing else. Furthermore, after
    using SDL_PollEvent, the event structure only holds information regarding a
    SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check
this :P.

2013/11/12 Hern?n Gurmendi <@Hernan_Gurmendi>

IIRC you should use key states, basically you fetch an array containing
the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in
SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go
diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

If you’re only ever assigning constant memory such as string literals, a
pointer is fine. I would make it const, though. Using an array and then
assigning anything to it would be bad (use strncpy() if you go that route).

You don’t need to put SDL_GetKeyState() (or SDL2’s SDL_GetKeyboardState())
in the loop. The state array is owned and updated by SDL.

Jonny DOn Tue, Nov 12, 2013 at 4:26 PM, Hern?n Gurmendi wrote:

I just properly read your code and found some things that are worth
mentioning:

  • You should define your “key” string like “char key[LEN]” instead of just
    a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code, in
    case you want to fetch the key events you should use something like
    while(SDL_PollEvent(&event)) because in your code you’re actually grabbing
    the first event in the event queue and nothing else. Furthermore, after
    using SDL_PollEvent, the event structure only holds information regarding a
    SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check
this :P.

2013/11/12 Hern?n Gurmendi

IIRC you should use key states, basically you fetch an array containing
the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in
SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go
diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Do you mean perhaps that the array ‘updates itself’, so that we get a pointer to the actual data that SDL2 keeps, and not a copy of it?

Cause that’s something awesome I didn’t know about :slight_smile:

– Aggelos KolaitisOn 12 ??? 2013, at 11:39 ?.?., Jonathan Dearborn wrote:

If you’re only ever assigning constant memory such as string literals, a pointer is fine. I would make it const, though. Using an array and then assigning anything to it would be bad (use strncpy() if you go that route).

You don’t need to put SDL_GetKeyState() (or SDL2’s SDL_GetKeyboardState()) in the loop. The state array is owned and updated by SDL.

Jonny D

On Tue, Nov 12, 2013 at 4:26 PM, Hern?n Gurmendi wrote:
I just properly read your code and found some things that are worth mentioning:

  • You should define your “key” string like “char key[LEN]” instead of just a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code, in case you want to fetch the key events you should use something like while(SDL_PollEvent(&event)) because in your code you’re actually grabbing the first event in the event queue and nothing else. Furthermore, after using SDL_PollEvent, the event structure only holds information regarding a SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check this :P.

2013/11/12 Hern?n Gurmendi
IIRC you should use key states, basically you fetch an array containing the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens
Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Thanks! First of all, I’m using SDL 2.0. I didn’t realize that SDL_PollEvent only returned the first in a stack. That makes sense now why I would want to use a while. Also, I did not know about?SDL_GetKeyboardState. That will simplify my code a lot. The code I came up with was based on me navigating through the API documentation on the wiki. I never came across any examples of using?SDL_GetKeyboardState. So does?SDL_GetKeyboardState read all current key presses? Does that mean that it does not go in the SDL_PollEvent loop because that would duplicate the key presses? If I’m only concerned with the keyboard presses, does that mean I can skip using SDL_PollEvent?

Regarding this note: "If you’re only ever assigning constant memory such as string literals, a pointer is fine. ?I would make it const, though. ?Using an array and then assigning anything to it would be bad (use strncpy() if you go that route)."
Can you elaborate with a code sample? That would help me understand.

–AndrewOn November 12, 2013 at 1:26:28 PM, Hern?n Gurmendi (hgurmen at gmail.com) wrote:

I just properly read your code and found some things that are worth mentioning:

  • You should define your “key” string like “char key[LEN]” instead of just a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code, in case you want to fetch the key events you should use something like while(SDL_PollEvent(&event)) because in your code you’re actually grabbing the first event in the event queue and nothing else. Furthermore, after using SDL_PollEvent, the event structure only holds information regarding a SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check this :P.

2013/11/12 Hern?n Gurmendi
IIRC you should use key states, basically you fetch an array containing the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens <@Andrew_Havens>
Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
? switch(event.type) {
? ? case SDL_KEYDOWN:
? ? ? if (event.key.keysym.sym == SDLK_LEFT) ?key = “left”;
? ? ? if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
? ? ? if (event.key.keysym.sym == SDLK_UP) ? ?key = “up”;
? ? ? if (event.key.keysym.sym == SDLK_DOWN) ?key = “down”;
? ? ? printf(“Key down: %s\n”, key);
? ? ? break;
? }
}

I’m finding that when I press and hold down two arrow keys (so I can go diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL_GetKeyboardState() only gives you access to the instantaneous "state"
of the keyboard. The events are completely separate. Some events might
even be missed altogether if you’re only checking the state. In my games,
it is important to check both. Sometimes you might want to respond to a
key press or release (events) by firing a weapon. Sometimes you want to
respond to whether or not a key is down (states) by moving your character.

The difference between char pointers and char arrays is really a language
thing, not that on-topic for SDL:
char* ptr; // A pointer
const char* cptr; // A pointer that can’t be used to alter the pointed
memory
char arr[256]; // A block of memory (technically also a pointer)
ptr = &arr[5];
cptr = “string literal”;
strncpy(arr, cptr, 256);
// Now try some bad things (hopefully your compiler will yell at you)
ptr = cptr; // Should we be able to modify that string??
arr = “another string”; // Where’d that memory go?

Jonny DOn Tue, Nov 12, 2013 at 5:19 PM, Andrew Havens wrote:

Thanks! First of all, I’m using SDL 2.0. I didn’t realize that
SDL_PollEvent only returned the first in a stack. That makes sense now why
I would want to use a while. Also, I did not know
about SDL_GetKeyboardState. That will simplify my code a lot. The code I
came up with was based on me navigating through the API documentation on
the wiki. I never came across any examples of using SDL_GetKeyboardState.
So does SDL_GetKeyboardState read all current key presses? Does that mean
that it does not go in the SDL_PollEvent loop because that would duplicate
the key presses? If I’m only concerned with the keyboard presses, does that
mean I can skip using SDL_PollEvent?

Regarding this note: "If you’re only ever assigning constant memory such
as string literals, a pointer is fine. I would make it const, though.
Using an array and then assigning anything to it would be bad (use
strncpy() if you go that route)."
Can you elaborate with a code sample? That would help me understand.

–Andrew

On November 12, 2013 at 1:26:28 PM, Hern?n Gurmendi (hgurmen at gmail.com<//hgurmen at gmail.com>) wrote:

I just properly read your code and found some things that are worth
mentioning:

  • You should define your “key” string like “char key[LEN]” instead of just
    a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code, in
    case you want to fetch the key events you should use something like
    while(SDL_PollEvent(&event)) because in your code you’re actually grabbing
    the first event in the event queue and nothing else. Furthermore, after
    using SDL_PollEvent, the event structure only holds information regarding a
    SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check
this :P.

2013/11/12 Hern?n Gurmendi

IIRC you should use key states, basically you fetch an array containing
the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in
SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go
diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Oh I see. So if I understand correctly, Events are mostly used for “one-time” events since each event provides additional details such as whether the event is a button press or a button release, while the KeyboardState is used when those details aren’t necessary and all you care about is whether or not a button is currently pressed. The reason I asked this question in the first place is because I am programming a character’s directional controls. So when two arrow keys are pressed, I want the character to move in a diagonal direction by incrementing/decrementing the x and y positions. I’m curious which approach would be best suited for this because I could see either one being used. If you want to move the character and you use Events, each event will be handled and the x/y will be updated. However, it sounds like, if you used KeyboardState, you might miss a key press and even though you pressed that key to move the character one step, it was not captured because SDL_GetKeyboardState() was not called at the right time. But if you were in an Event, you could use the KeyboardState to check if any “modifier keys” were being pressed at the time that you are processing the Event.

Did I summarize this correctly?On November 12, 2013 at 3:06:22 PM, Jonathan Dearborn (grimfang4 at gmail.com) wrote:

SDL_GetKeyboardState() only gives you access to the instantaneous “state” of the keyboard. ?The events are completely separate. ?Some events might even be missed altogether if you’re only checking the state. ?In my games, it is important to check both. ?Sometimes you might want to respond to a key press or release (events) by firing a weapon. ?Sometimes you want to respond to whether or not a key is down (states) by moving your character.

The difference between char pointers and char arrays is really a language thing, not that on-topic for SDL:
char* ptr; ?// A pointer
const char* cptr; ?// A pointer that can’t be used to alter the pointed memory
char arr[256]; ?// A block of memory (technically also a pointer)
ptr = &arr[5];
cptr = “string literal”;
strncpy(arr, cptr, 256);
// Now try some bad things (hopefully your compiler will yell at you)
ptr = cptr; ?// Should we be able to modify that string??
arr = “another string”; ?// Where’d that memory go?

Jonny D

On Tue, Nov 12, 2013 at 5:19 PM, Andrew Havens <@Andrew_Havens> wrote:
Thanks! First of all, I’m using SDL 2.0. I didn’t realize that SDL_PollEvent only returned the first in a stack. That makes sense now why I would want to use a while. Also, I did not know about?SDL_GetKeyboardState. That will simplify my code a lot. The code I came up with was based on me navigating through the API documentation on the wiki. I never came across any examples of using?SDL_GetKeyboardState. So does?SDL_GetKeyboardState read all current key presses? Does that mean that it does not go in the SDL_PollEvent loop because that would duplicate the key presses? If I’m only concerned with the keyboard presses, does that mean I can skip using SDL_PollEvent?

Regarding this note: "If you’re only ever assigning constant memory such as string literals, a pointer is fine. ?I would make it const, though. ?Using an array and then assigning anything to it would be bad (use strncpy() if you go that route)."
Can you elaborate with a code sample? That would help me understand.

–Andrew

On November 12, 2013 at 1:26:28 PM, Hern?n Gurmendi (hgurmen at gmail.com) wrote:

I just properly read your code and found some things that are worth mentioning:

  • You should define your “key” string like “char key[LEN]” instead of just a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code, in case you want to fetch the key events you should use something like while(SDL_PollEvent(&event)) because in your code you’re actually grabbing the first event in the event queue and nothing else. Furthermore, after using SDL_PollEvent, the event structure only holds information regarding a SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check this :P.

2013/11/12 Hern?n Gurmendi
IIRC you should use key states, basically you fetch an array containing the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens <@Andrew_Havens>
Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
? switch(event.type) {
? ? case SDL_KEYDOWN:
? ? ? if (event.key.keysym.sym == SDLK_LEFT) ?key = “left”;
? ? ? if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
? ? ? if (event.key.keysym.sym == SDLK_UP) ? ?key = “up”;
? ? ? if (event.key.keysym.sym == SDLK_DOWN) ?key = “down”;
? ? ? printf(“Key down: %s\n”, key);
? ? ? break;
? }
}

I’m finding that when I press and hold down two arrow keys (so I can go diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Yeah, that’s pretty much it, but it’s not about when you call
SDL_GetKeyboardState(). It’s about when you check the state, like with
if(keystates[SDL_SCANCODE_SPACE]). The spacebar could have been pressed
and released in a single frame, so you get a press event and a release
event before even getting to the state check.

As for modifiers, the events capture that info too. You can do this (it’s
a bit field): if(event.key.keysym.mod & KMOD_CTRL). There is also
SDL_GetModState() for checking the state of modifier keys, analogous to
SDL_GetKeyboardState().

One note about combining events and states… Proper movement in a
real-time simulation must use an integration strategy. The simplest and
most common is forward Euler integration: x += velx*dt; Your key states
and events would set the velocity and then the integration each frame (or
loop) takes care of the movement. If you want key press events to nudge
your character one step, then you should have a variable that skips the key
state check when a movement event has been processed this frame (so no
extra movement).

Jonny DOn Tue, Nov 12, 2013 at 9:32 PM, Andrew Havens wrote:

Oh I see. So if I understand correctly, Events are mostly used for
"one-time" events since each event provides additional details such as
whether the event is a button press or a button release, while the
KeyboardState is used when those details aren’t necessary and all you care
about is whether or not a button is currently pressed. The reason I asked
this question in the first place is because I am programming a character’s
directional controls. So when two arrow keys are pressed, I want the
character to move in a diagonal direction by incrementing/decrementing the
x and y positions. I’m curious which approach would be best suited for this
because I could see either one being used. If you want to move the
character and you use Events, each event will be handled and the x/y will
be updated. However, it sounds like, if you used KeyboardState, you might
miss a key press and even though you pressed that key to move the character
one step, it was not captured because SDL_GetKeyboardState() was not called
at the right time. But if you were in an Event, you could use the
KeyboardState to check if any “modifier keys” were being pressed at the
time that you are processing the Event.

Did I summarize this correctly?

On November 12, 2013 at 3:06:22 PM, Jonathan Dearborn (@Jonathan_Dearborn<//@Jonathan_Dearborn>) wrote:

SDL_GetKeyboardState() only gives you access to the instantaneous "state"
of the keyboard. The events are completely separate. Some events might
even be missed altogether if you’re only checking the state. In my games,
it is important to check both. Sometimes you might want to respond to a
key press or release (events) by firing a weapon. Sometimes you want to
respond to whether or not a key is down (states) by moving your character.

The difference between char pointers and char arrays is really a language
thing, not that on-topic for SDL:
char* ptr; // A pointer
const char* cptr; // A pointer that can’t be used to alter the pointed
memory
char arr[256]; // A block of memory (technically also a pointer)
ptr = &arr[5];
cptr = “string literal”;
strncpy(arr, cptr, 256);
// Now try some bad things (hopefully your compiler will yell at you)
ptr = cptr; // Should we be able to modify that string??
arr = “another string”; // Where’d that memory go?

Jonny D

On Tue, Nov 12, 2013 at 5:19 PM, Andrew Havens wrote:

Thanks! First of all, I’m using SDL 2.0. I didn’t realize that
SDL_PollEvent only returned the first in a stack. That makes sense now why
I would want to use a while. Also, I did not know
about SDL_GetKeyboardState. That will simplify my code a lot. The code I
came up with was based on me navigating through the API documentation on
the wiki. I never came across any examples of using SDL_GetKeyboardState.
So does SDL_GetKeyboardState read all current key presses? Does that mean
that it does not go in the SDL_PollEvent loop because that would duplicate
the key presses? If I’m only concerned with the keyboard presses, does that
mean I can skip using SDL_PollEvent?

Regarding this note: "If you’re only ever assigning constant memory such
as string literals, a pointer is fine. I would make it const, though.
Using an array and then assigning anything to it would be bad (use
strncpy() if you go that route)."
Can you elaborate with a code sample? That would help me understand.

–Andrew

On November 12, 2013 at 1:26:28 PM, Hern?n Gurmendi (hgurmen at gmail.com<//hgurmen at gmail.com>) wrote:

I just properly read your code and found some things that are worth
mentioning:

  • You should define your “key” string like “char key[LEN]” instead of
    just a pointer; you might get some memory leaks.
  • Just like Daniel pointed out, and from what I’ve read from your code,
    in case you want to fetch the key events you should use something like
    while(SDL_PollEvent(&event)) because in your code you’re actually grabbing
    the first event in the event queue and nothing else. Furthermore, after
    using SDL_PollEvent, the event structure only holds information regarding a
    SINGLE event therefore it only holds information for a single key press.
  • If you want to check the states of keys you could do something like
    this:

while (running) {
/* Handle events, standard way. /
while (SDL_PollEvent(&event)) {
/
… */
}

/* Check the keyboard state every tick of the loop. */
Uint8 *keystates = SDL_GetKeyState(NULL);

up_pressed = keystates[SDLK_UP];
down_pressed = keystates[SDLK_DOWN];
left_pressed = keystates[SDLK_LEFT];
right_pressed = keystates[SDLK_RIGHT];

/* Key logic goes here. /
if (up_pressed && left_pressed) {
/
upper-left diagonal. */
}

/* … */
}

Still, it would be nice to have an expert or something like that to check
this :P.

2013/11/12 Hern?n Gurmendi

IIRC you should use key states, basically you fetch an array containing
the state of all the keys at the moment. Check the following page:

http://lazyfoo.net/SDL_tutorials/lesson10/index.php

I assumed you use SDL 1.2. Hope this helps, though I’m kind of a noob in
SDL, so maybe you should wait for someone else’s response.

2013/11/12 Andrew Havens

Given I have the following code:

char *key = NULL;
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) key = “left”;
if (event.key.keysym.sym == SDLK_RIGHT) key = “right”;
if (event.key.keysym.sym == SDLK_UP) key = “up”;
if (event.key.keysym.sym == SDLK_DOWN) key = “down”;
printf(“Key down: %s\n”, key);
break;
}
}

I’m finding that when I press and hold down two arrow keys (so I can go
diagonal) only one of those keys is registered. What am I doing wrong?

–Andrew


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org