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