0

In my SDL 1.2 program I have a function KeyPressed which needs to check if a key has been pressed. If the mouse pointer has not been moved in front of the window the program halts as intended when a key is pressed. On the other hand, if the mouse pointer is moved in front of the window the event queue seems to fill up and after that the program does not respond to key presses. Is there a way to empty the event queue when there are no keyboard events in it?

#include <SDL/SDL.h>
#include <stdio.h>

static void Init(int *error)
{
    SDL_Surface *display;

    *error = SDL_Init(SDL_INIT_VIDEO);
    if (! *error) {
        display = SDL_SetVideoMode(640, 480, 8, 0);
        if (display != NULL) {
            *error = 0;
        } else {
            fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
            *error = 1;
        }
    } else {
        fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
        *error = 1;
    }   
}


static int KeyPressed(void)
{
    SDL_Event event;
    int count, result;

    result = 0;
    SDL_PumpEvents();
    count = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_EVENTMASK(SDL_KEYDOWN));
    switch (count) {
        case -1:
            fprintf(stderr, "SDL_PeepEvents: %s\n", SDL_GetError());
            break;
        case 0:
            break;
        case 1:
            result = 1;
            break;
    }
    return result;
}


int main(void)
{
    int error;

    Init(&error);
    if (! error) {
        do {
            /*nothing*/
        } while (! KeyPressed());
    }
    return error;
}
Martin G
  • 17,357
  • 9
  • 82
  • 98
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60
  • You'll have to remove the events from the event queue somewhere, have you tried with SDL_GETEVENT instead of SDL_PEEKEVENT ? – nos Nov 25 '14 at 14:35
  • @nos OK, but how many events should I remove? As far as I know there is no way to get the length of the event queue. – August Karlstrom Nov 25 '14 at 15:20
  • 1
    You'd do a loop where you first perform a SDL_PEEKEVENT, if that returns non-zero, you perform a SDL_GETEVENT. If it did return zero, you've emptied the event queue. Though, it's unclear if this code is just part of a real application - where the control flow and checking for key events would normally be very different -and often handled as shown here http://stackoverflow.com/questions/3741055/inputs-in-sdl-on-key-pressed – nos Nov 25 '14 at 15:29
  • @nos I reason that since I filter the events the mouse events will not be removed with *SDL_GETEVENT*. (In the real code that I'm working on the function *KeyPressed* is part of an API that cannot be changed.) – August Karlstrom Nov 25 '14 at 15:46

2 Answers2

2

You should be checking event's in a while loop using polling which will pop the events from the queue as they are handled. Use either multiple if/then statements or a swicth block for handling the event. I recommend this method as you can easily miss important events such as SDL_QUIT when using SDL_PeepEvent

Basic example:

SDL_Event e;
while (SDL_PollEvent(&e))
{
    if (e.type == SDL_QUIT)
    {
        // do something here
    }
}
TPS
  • 2,067
  • 3
  • 23
  • 32
  • Thanks for the input. However, in the real code that I'm working on the function *KeyPressed* is a part of an API that cannot be changed. Otherwise I would follow your advice. – August Karlstrom Nov 25 '14 at 17:57
  • 2
    In which case you should check the event queue with the event mask as you have in your code to see if there are no key press events. if there are none, also check that there is no important events to handle ie SDL_QUIT in the same way. Then you use `SDL_PeepEvent` to remove all the events with SDL_GETEVENT. See here - https://wiki.libsdl.org/SDL_PeepEvents – TPS Nov 25 '14 at 19:33
0

The following solution, inspired by Zammalad's comment seems to work. When no key down event is found we remove one event (typically a mouse event) from the queue to make room for new events. To make the code more robust I have also replaced the scalar event with the array events.

#define LEN(a) ((int) (sizeof (a) / sizeof (a)[0]))

static int KeyPressed(void)
{
    SDL_Event events[1];
    int count, result;

    result = 0;
    SDL_PumpEvents();
    /*search the event queue for key down events*/
    count = SDL_PeepEvents(events, LEN(events), SDL_PEEKEVENT, SDL_EVENTMASK(SDL_KEYDOWN));
    switch (count) {
        case -1:
            fprintf(stderr, "SDL_PeepEvents: %s\n", SDL_GetError());
            break;
        case 0:
            /*make room for new events by removing (non-key down) event from the queue*/
            count = SDL_PeepEvents(events, LEN(events), SDL_GETEVENT, -1);
            if ((count > 0) && (events[0].type == SDL_QUIT)) {
                exit(EXIT_SUCCESS);
            }
            break;
        case 1:
            result = 1;
            break;
    }
    return result;
}
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60