/* * keyboard.c * * Basic keyboard handing functions -- allows event-handling loops * to push keyboard events onto a queue so they can be processed at * the appropriate time in the game rounds loop */ #include #include #include #include #include #include "graphics.h" #include "grv.h" #define KEYQUEUELEN 16 static SDL_KeyboardEvent keyqueue[KEYQUEUELEN]; static SDL_KeyboardEvent *kqh = keyqueue; static SDL_KeyboardEvent *kqt = keyqueue; static int queuedkeys = 0; /* * Push a keyboard event onto the queue; use this in event loops */ void push_key(SDL_KeyboardEvent *ke) { /* Hack to add some nondeterminism into the gameid's */ if ( !gp.have_id ) { gp.gameid = (gp.gameid << 5 | gp.gameid >> 59) + ((uint64_t)SDL_GetTicks() << 32) + genrand_int32(); } if ( queuedkeys >= KEYQUEUELEN ) return; /* Drop it */ queuedkeys++; *kqh++ = *ke; if ( kqh >= &keyqueue[KEYQUEUELEN] ) kqh = keyqueue; } /* * Poll the keyboard queue for a key event */ SDL_KeyboardEvent *poll_key(void) { SDL_KeyboardEvent *ke; if ( queuedkeys ) { queuedkeys--; ke = kqt++; if ( kqt >= &keyqueue[KEYQUEUELEN] ) kqt = keyqueue; return ke; } else { return NULL; } } /* * Get a key, pausing if necessary */ SDL_KeyboardEvent *get_key(void) { static SDL_Event event; SDL_KeyboardEvent *ke; if ( (ke = poll_key()) ) return ke; update_screen(); while ( SDL_WaitEvent(&event) ) { if ( event.type == SDL_KEYDOWN ) return &event.key; else if ( event.type == SDL_USEREVENT && event.user.code == event_blink ) update_blink(); } return NULL; }