summaryrefslogtreecommitdiffstats
path: root/keyboard.c
blob: 5d586c848d7de589f66e2feb54b11bf116a9ae24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#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;
}