2 * (C) GraÅžvydas "notaz" Ignotas, 2009
4 * This work is licensed under the terms of any of these licenses
6 * - GNU GPL, version 2 or later.
7 * - GNU LGPL, version 2.1 or later.
9 * See the COPYING file in the top-level directory.
12 #define RC_INVOKED // we only need defines
18 #include "../emu.h" // array_size
21 #define IN_VK_PREFIX "vk:"
22 #define IN_VK_NKEYS 0x100
24 static const char * const in_vk_prefix = IN_VK_PREFIX;
25 static const char * const in_vk_keys[IN_VK_NKEYS] = {
26 [0 ... (IN_VK_NKEYS - 1)] = NULL,
27 [VK_LBUTTON] = "LBUTTON", [VK_RBUTTON] = "RBUTTON",
28 [VK_TAB] = "TAB", [VK_RETURN] = "RETURN",
29 [VK_SHIFT] = "SHIFT", [VK_CONTROL] = "CONTROL",
30 [VK_LEFT] = "LEFT", [VK_UP] = "UP",
31 [VK_RIGHT] = "RIGHT", [VK_DOWN] = "DOWN",
35 // additional player12 keys
38 // up to 4, keyboards rarely allow more
39 static int in_vk_keys_down[4];
46 #define VK_NUMPAD0 0x60
47 #define VK_NUMPAD1 0x61
48 #define VK_NUMPAD2 0x62
49 #define VK_NUMPAD3 0x63
50 #define VK_NUMPAD4 0x64
51 #define VK_NUMPAD5 0x65
52 #define VK_NUMPAD6 0x66
53 #define VK_NUMPAD7 0x67
54 #define VK_NUMPAD8 0x68
55 #define VK_NUMPAD9 0x69
56 #define VK_MULTIPLY 0x6A
58 #define VK_SEPARATOR 0x6C
59 #define VK_SUBTRACT 0x6D
60 #define VK_DECIMAL 0x6E
61 #define VK_DIVIDE 0x6F
76 static void in_vk_probe(void)
78 memset(in_vk_keys_down, 0, sizeof(in_vk_keys_down));
79 in_register(IN_VK_PREFIX "vk", IN_DRVID_VK, -1, (void *)1, IN_VK_NKEYS, NULL, 0);
82 static int in_vk_get_bind_count(void)
87 /* ORs result with pressed buttons */
88 int in_vk_update(void *drv_data, const int *binds, int *result)
92 for (i = 0; i < array_size(in_vk_keys_down); i++) {
93 k = in_vk_keys_down[i];
97 for (t = 0; t < IN_BINDTYPE_COUNT; t++)
98 result[t] |= binds[IN_BIND_OFFS(k, t)];
101 result[IN_BINDTYPE_PLAYER12] |= in_vk_add_pl12;
106 void in_vk_keydown(int kc)
111 for (i = 0; i < array_size(in_vk_keys_down); i++)
112 if (in_vk_keys_down[i] == kc)
116 for (i = 0; i < array_size(in_vk_keys_down); i++) {
117 if (in_vk_keys_down[i] == 0) {
118 in_vk_keys_down[i] = kc;
124 void in_vk_keyup(int kc)
127 for (i = 0; i < array_size(in_vk_keys_down); i++)
128 if (in_vk_keys_down[i] == kc)
129 in_vk_keys_down[i] = 0;
132 static int in_vk_update_keycode(void *data, int *is_down)
137 static const struct {
143 { VK_DOWN, PBTN_DOWN },
144 { VK_LEFT, PBTN_LEFT },
145 { VK_RIGHT, PBTN_RIGHT },
146 { VK_RETURN, PBTN_MOK },
148 { BTN_X, PBTN_MBACK },
153 { BTN_SELECT, PBTN_MENU },
157 #define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0]))
159 static int in_vk_menu_translate(void *drv_data, int keycode)
166 for (i = 0; i < KEY_PBTN_MAP_SIZE; i++)
167 if (key_pbtn_map[i].pbtn == keycode)
168 return key_pbtn_map[i].key;
172 for (i = 0; i < KEY_PBTN_MAP_SIZE; i++)
173 if (key_pbtn_map[i].key == keycode)
174 return key_pbtn_map[i].pbtn;
180 static int in_vk_get_key_code(const char *key_name)
184 if (key_name[1] == 0 && 'A' <= key_name[0] && key_name[0] <= 'Z')
187 for (i = 0; i < IN_VK_NKEYS; i++) {
188 const char *k = in_vk_keys[i];
189 if (k != NULL && strcasecmp(k, key_name) == 0)
196 static const char *in_vk_get_key_name(int keycode)
198 const char *name = NULL;
201 if ('A' <= keycode && keycode < 'Z') {
207 if (0 <= keycode && keycode < IN_VK_NKEYS)
208 name = in_vk_keys[keycode];
215 static const struct {
219 } in_vk_def_binds[] =
222 { VK_UP, IN_BINDTYPE_PLAYER12, 0 },
223 { VK_DOWN, IN_BINDTYPE_PLAYER12, 1 },
224 { VK_LEFT, IN_BINDTYPE_PLAYER12, 2 },
225 { VK_RIGHT, IN_BINDTYPE_PLAYER12, 3 },
226 { 'S', IN_BINDTYPE_PLAYER12, 4 }, /* B */
227 { 'D', IN_BINDTYPE_PLAYER12, 5 }, /* C */
228 { 'A', IN_BINDTYPE_PLAYER12, 6 }, /* A */
229 { VK_RETURN, IN_BINDTYPE_PLAYER12, 7 },
230 { 'E', IN_BINDTYPE_PLAYER12, 8 }, /* Z */
231 { 'W', IN_BINDTYPE_PLAYER12, 9 }, /* Y */
232 { 'Q', IN_BINDTYPE_PLAYER12,10 }, /* X */
233 { 'R', IN_BINDTYPE_PLAYER12,11 }, /* M */
235 { BTN_SELECT, IN_BINDTYPE_EMU, PEVB_MENU },
236 // { BTN_Y, IN_BINDTYPE_EMU, PEVB_SWITCH_RND },
237 { BTN_L, IN_BINDTYPE_EMU, PEVB_STATE_SAVE },
238 { BTN_R, IN_BINDTYPE_EMU, PEVB_STATE_LOAD },
239 { BTN_VOL_UP, IN_BINDTYPE_EMU, PEVB_VOL_UP },
240 { BTN_VOL_DOWN, IN_BINDTYPE_EMU, PEVB_VOL_DOWN },
244 #define DEF_BIND_COUNT (sizeof(in_vk_def_binds) / sizeof(in_vk_def_binds[0]))
246 static void in_vk_get_def_binds(int *binds)
250 for (i = 0; i < DEF_BIND_COUNT; i++)
251 binds[IN_BIND_OFFS(in_vk_def_binds[i].code, in_vk_def_binds[i].btype)] =
252 1 << in_vk_def_binds[i].bit;
255 /* remove binds of missing keys, count remaining ones */
256 static int in_vk_clean_binds(void *drv_data, int *binds, int *def_binds)
260 for (i = 0; i < IN_VK_NKEYS; i++) {
262 for (t = 0; t < IN_BINDTYPE_COUNT; t++) {
263 offs = IN_BIND_OFFS(i, t);
264 if (strcmp(in_vk_get_key_name(i), "Unkn") == 0)
265 binds[offs] = def_binds[offs] = 0;
274 void in_vk_init(void *vdrv)
276 in_drv_t *drv = vdrv;
278 drv->prefix = in_vk_prefix;
279 drv->probe = in_vk_probe;
280 drv->get_bind_count = in_vk_get_bind_count;
281 drv->get_def_binds = in_vk_get_def_binds;
282 drv->clean_binds = in_vk_clean_binds;
283 drv->menu_translate = in_vk_menu_translate;
284 drv->get_key_code = in_vk_get_key_code;
285 drv->get_key_name = in_vk_get_key_name;
286 drv->update_keycode = in_vk_update_keycode;