1 #include <allegro5/allegro.h>
2 #include <stdio.h>
3 #include "global.h"
4 #include "keyboard.h"
5 
6 #define KEYBUF_SIZE 16
7 
8 /*
9  * bit 0: key is down
10  * bit 1: key was pressed
11  * bit 2: key was released
12  */
13 static int key_array[ALLEGRO_KEY_MAX];
14 static int unicode_array[KEYBUF_SIZE];
15 static int unicode_count;
16 
key_down(int k)17 bool key_down(int k)
18 {
19    return key_array[k] & 1;
20 }
21 
key_pressed(int k)22 bool key_pressed(int k)
23 {
24    return key_array[k] & 2;
25 }
26 
unicode_char(bool remove)27 int unicode_char(bool remove)
28 {
29    int u;
30    if (unicode_count == 0) return 0;
31    u = unicode_array[0];
32    if (remove) {
33       memmove(unicode_array, unicode_array + 1,
34          (KEYBUF_SIZE - 1) * sizeof(int));
35    }
36    return u;
37 }
38 
keyboard_event(ALLEGRO_EVENT * event)39 void keyboard_event(ALLEGRO_EVENT *event)
40 {
41    switch (event->type) {
42       case ALLEGRO_EVENT_KEY_DOWN:
43          key_array[event->keyboard.keycode] |= (1 << 0);
44          key_array[event->keyboard.keycode] |= (1 << 1);
45          break;
46 
47       case ALLEGRO_EVENT_KEY_CHAR:
48          if (event->keyboard.unichar && unicode_count < KEYBUF_SIZE) {
49             unicode_array[unicode_count++] = event->keyboard.unichar;
50          }
51          break;
52 
53       case ALLEGRO_EVENT_KEY_UP:
54          key_array[event->keyboard.keycode] &= ~(1 << 0);
55          key_array[event->keyboard.keycode] |= (1 << 2);
56          break;
57    }
58 }
59 
keyboard_tick(void)60 void keyboard_tick(void)
61 {
62    /* clear pressed/released bits */
63    int i;
64    for (i = 0; i < ALLEGRO_KEY_MAX; i++) {
65       key_array[i] &= ~(1 << 1);
66       key_array[i] &= ~(1 << 2);
67    }
68 
69    unicode_count = 0;
70 }
71 
read_config(VCONTROLLER * this,const char * config_path)72 static void read_config(VCONTROLLER * this, const char *config_path)
73 {
74    int i;
75    char tmp[64];
76    int def[] = {
77       ALLEGRO_KEY_LEFT,
78       ALLEGRO_KEY_RIGHT,
79       ALLEGRO_KEY_SPACE
80    };
81 
82    ALLEGRO_CONFIG *c = al_load_config_file(config_path);
83    if (!c) c = al_create_config();
84 
85    for (i = 0; i < 3; i++) {
86       snprintf(tmp, sizeof(tmp), "button%d", i);
87       ((int *)(this->private_data))[i] =
88          get_config_int(c, "KEYBOARD", tmp, def[i]);
89    }
90 
91    al_destroy_config(c);
92 }
93 
94 
95 
write_config(VCONTROLLER * this,const char * config_path)96 static void write_config(VCONTROLLER * this, const char *config_path)
97 {
98    int i;
99    char tmp[64];
100 
101    ALLEGRO_CONFIG *c = al_load_config_file(config_path);
102    if (!c) c = al_create_config();
103 
104    for (i = 0; i < 3; i++) {
105       snprintf(tmp, sizeof(tmp), "button%d", i);
106       set_config_int(c, "KEYBOARD", tmp, ((int *)(this->private_data))[i]);
107    }
108 
109    al_save_config_file(config_path, c);
110    al_destroy_config(c);
111 }
112 
113 
114 
poll(VCONTROLLER * this)115 static void poll(VCONTROLLER * this)
116 {
117    int i;
118 
119    int *private_data = (int *)(this->private_data);
120 
121    for (i = 0; i < 3; i++) {
122       if (key_down(private_data[i])) {
123          this->button[i] = 1;
124       } else {
125          this->button[i] = 0;
126       }
127    }
128 }
129 
130 
131 
calibrate_button(VCONTROLLER * this,int i)132 static int calibrate_button(VCONTROLLER * this, int i)
133 {
134    int c;
135 
136    if (key_down(ALLEGRO_KEY_ESCAPE)) {
137       return 0;
138    }
139 
140    for (c = 1; c < ALLEGRO_KEY_MAX; c++) {
141       if (key_pressed(c)) {
142          ((int *)(this->private_data))[i] = c;
143          return 1;
144       }
145    }
146 
147    return 0;
148 }
149 
150 
151 
get_button_description(VCONTROLLER * this,int i)152 static const char *get_button_description(VCONTROLLER * this, int i)
153 {
154    int *private_data = (int *)(this->private_data);
155 
156    return al_keycode_to_name(private_data[i]);
157 }
158 
159 
160 
create_keyboard_controller(const char * config_path)161 VCONTROLLER *create_keyboard_controller(const char *config_path)
162 {
163    int i;
164    VCONTROLLER *ret = malloc(sizeof(VCONTROLLER));
165 
166    ret->private_data = malloc(3 * sizeof(int));
167    for (i = 0; i < 3; i++) {
168       ret->button[i] = 0;
169       ((int *)(ret->private_data))[i] = 0;
170    }
171    ret->poll = poll;
172    ret->calibrate_button = calibrate_button;
173    ret->get_button_description = get_button_description;
174    ret->read_config = read_config;
175    ret->write_config = write_config;
176 
177    read_config(ret, config_path);
178 
179    return ret;
180 }
181