bugfix
[picodrive.git] / platform / win32 / in_vk.c
CommitLineData
823b9004 1#define RC_INVOKED // we only need defines
2#include <winuser.h>
3#undef RC_INVOKED
4#include <string.h>
5
6#include "../common/input.h"
7#include "../common/emu.h" // array_size
8#include "in_vk.h"
9
10#define IN_VK_PREFIX "vk:"
11#define IN_VK_NKEYS 0x100
12
13static const char * const in_vk_prefix = IN_VK_PREFIX;
14static const char * const in_vk_keys[IN_VK_NKEYS] = {
15 [0 ... (IN_VK_NKEYS - 1)] = NULL,
16 [VK_LBUTTON] = "LBUTTON", [VK_RBUTTON] = "RBUTTON",
17 [VK_TAB] = "TAB", [VK_RETURN] = "RETURN",
18 [VK_SHIFT] = "SHIFT", [VK_CONTROL] = "CONTROL",
19 [VK_LEFT] = "LEFT", [VK_UP] = "UP",
20 [VK_RIGHT] = "RIGHT", [VK_DOWN] = "DOWN",
21 [VK_SPACE] = "SPACE",
22};
23
24// additional player12 keys
25int in_vk_add_pl12;
26
27// up to 4, keyboards rarely allow more
28static int in_vk_keys_down[4];
29
30/*
31#define VK_END 35
32#define VK_HOME 36
33#define VK_INSERT 45
34#define VK_DELETE 46
35#define VK_NUMPAD0 0x60
36#define VK_NUMPAD1 0x61
37#define VK_NUMPAD2 0x62
38#define VK_NUMPAD3 0x63
39#define VK_NUMPAD4 0x64
40#define VK_NUMPAD5 0x65
41#define VK_NUMPAD6 0x66
42#define VK_NUMPAD7 0x67
43#define VK_NUMPAD8 0x68
44#define VK_NUMPAD9 0x69
45#define VK_MULTIPLY 0x6A
46#define VK_ADD 0x6B
47#define VK_SEPARATOR 0x6C
48#define VK_SUBTRACT 0x6D
49#define VK_DECIMAL 0x6E
50#define VK_DIVIDE 0x6F
51#define VK_F1 0x70
52#define VK_F2 0x71
53#define VK_F3 0x72
54#define VK_F4 0x73
55#define VK_F5 0x74
56#define VK_F6 0x75
57#define VK_F7 0x76
58#define VK_F8 0x77
59#define VK_F9 0x78
60#define VK_F10 0x79
61#define VK_F11 0x7A
62#define VK_F12 0x7B
63*/
64
65static void in_vk_probe(void)
66{
67 memset(in_vk_keys_down, 0, sizeof(in_vk_keys_down));
68 in_register(IN_VK_PREFIX "vk", IN_DRVID_VK, -1, (void *)1, IN_VK_NKEYS, 0);
69}
70
71static int in_vk_get_bind_count(void)
72{
73 return IN_VK_NKEYS;
74}
75
76/* ORs result with pressed buttons */
77int in_vk_update(void *drv_data, const int *binds, int *result)
78{
79 int i, t, k;
80
81 for (i = 0; i < array_size(in_vk_keys_down); i++) {
82 k = in_vk_keys_down[i];
83 if (!k)
84 continue;
85
86 for (t = 0; t < IN_BINDTYPE_COUNT; t++)
87 result[t] |= binds[IN_BIND_OFFS(k, t)];
88 }
89
90 result[IN_BINDTYPE_PLAYER12] |= in_vk_add_pl12;
91
92 return 0;
93}
94
95void in_vk_keydown(int kc)
96{
97 int i;
98
99 // search
100 for (i = 0; i < array_size(in_vk_keys_down); i++)
101 if (in_vk_keys_down[i] == kc)
102 return;
103
104 // do
105 for (i = 0; i < array_size(in_vk_keys_down); i++) {
106 if (in_vk_keys_down[i] == 0) {
107 in_vk_keys_down[i] = kc;
108 return;
109 }
110 }
111}
112
113void in_vk_keyup(int kc)
114{
115 int i;
116 for (i = 0; i < array_size(in_vk_keys_down); i++)
117 if (in_vk_keys_down[i] == kc)
118 in_vk_keys_down[i] = 0;
119}
120
121static int in_vk_update_keycode(void *data, int *is_down)
122{
123 return 0;
124}
125
126static const struct {
127 short key;
128 short pbtn;
129} key_pbtn_map[] =
130{
131 { VK_UP, PBTN_UP },
132 { VK_DOWN, PBTN_DOWN },
133 { VK_LEFT, PBTN_LEFT },
134 { VK_RIGHT, PBTN_RIGHT },
135 { VK_RETURN, PBTN_MOK },
136/*
137 { BTN_X, PBTN_MBACK },
138 { BTN_A, PBTN_MA2 },
139 { BTN_Y, PBTN_MA3 },
140 { BTN_L, PBTN_L },
141 { BTN_R, PBTN_R },
142 { BTN_SELECT, PBTN_MENU },
143*/
144};
145
146#define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0]))
147
148static int in_vk_menu_translate(int keycode)
149{
150 int i;
151 if (keycode < 0)
152 {
153 /* menu -> kc */
154 keycode = -keycode;
155 for (i = 0; i < KEY_PBTN_MAP_SIZE; i++)
156 if (key_pbtn_map[i].pbtn == keycode)
157 return key_pbtn_map[i].key;
158 }
159 else
160 {
161 for (i = 0; i < KEY_PBTN_MAP_SIZE; i++)
162 if (key_pbtn_map[i].key == keycode)
163 return key_pbtn_map[i].pbtn;
164 }
165
166 return 0;
167}
168
169static int in_vk_get_key_code(const char *key_name)
170{
171 int i;
172
173 if (key_name[1] == 0 && 'A' <= key_name[0] && key_name[0] <= 'Z')
174 return key_name[0];
175
176 for (i = 0; i < IN_VK_NKEYS; i++) {
177 const char *k = in_vk_keys[i];
178 if (k != NULL && strcasecmp(k, key_name) == 0)
179 return i;
180 }
181
182 return -1;
183}
184
185static const char *in_vk_get_key_name(int keycode)
186{
187 const char *name = NULL;
188 static char buff[4];
189
190 if ('A' <= keycode && keycode < 'Z') {
191 buff[0] = keycode;
192 buff[1] = 0;
193 return buff;
194 }
195
196 if (0 <= keycode && keycode < IN_VK_NKEYS)
197 name = in_vk_keys[keycode];
198 if (name == NULL)
199 name = "Unkn";
200
201 return name;
202}
203
204static const struct {
205 short code;
206 char btype;
207 char bit;
208} in_vk_def_binds[] =
209{
210 /* MXYZ SACB RLDU */
211 { VK_UP, IN_BINDTYPE_PLAYER12, 0 },
212 { VK_DOWN, IN_BINDTYPE_PLAYER12, 1 },
213 { VK_LEFT, IN_BINDTYPE_PLAYER12, 2 },
214 { VK_RIGHT, IN_BINDTYPE_PLAYER12, 3 },
215 { 'S', IN_BINDTYPE_PLAYER12, 4 }, /* B */
216 { 'D', IN_BINDTYPE_PLAYER12, 5 }, /* C */
217 { 'A', IN_BINDTYPE_PLAYER12, 6 }, /* A */
218 { VK_RETURN, IN_BINDTYPE_PLAYER12, 7 },
ba86b61e 219 { 'E', IN_BINDTYPE_PLAYER12, 8 }, /* Z */
220 { 'W', IN_BINDTYPE_PLAYER12, 9 }, /* Y */
221 { 'Q', IN_BINDTYPE_PLAYER12,10 }, /* X */
222 { 'R', IN_BINDTYPE_PLAYER12,11 }, /* M */
823b9004 223/*
224 { BTN_SELECT, IN_BINDTYPE_EMU, PEVB_MENU },
225// { BTN_Y, IN_BINDTYPE_EMU, PEVB_SWITCH_RND },
226 { BTN_L, IN_BINDTYPE_EMU, PEVB_STATE_SAVE },
227 { BTN_R, IN_BINDTYPE_EMU, PEVB_STATE_LOAD },
228 { BTN_VOL_UP, IN_BINDTYPE_EMU, PEVB_VOL_UP },
229 { BTN_VOL_DOWN, IN_BINDTYPE_EMU, PEVB_VOL_DOWN },
230*/
231};
232
233#define DEF_BIND_COUNT (sizeof(in_vk_def_binds) / sizeof(in_vk_def_binds[0]))
234
235static void in_vk_get_def_binds(int *binds)
236{
237 int i;
238
239 for (i = 0; i < DEF_BIND_COUNT; i++)
240 binds[IN_BIND_OFFS(in_vk_def_binds[i].code, in_vk_def_binds[i].btype)] =
241 1 << in_vk_def_binds[i].bit;
242}
243
244/* remove binds of missing keys, count remaining ones */
245static int in_vk_clean_binds(void *drv_data, int *binds, int *def_binds)
246{
247 int i, count = 0;
248
249 for (i = 0; i < IN_VK_NKEYS; i++) {
250 int t, offs;
251 for (t = 0; t < IN_BINDTYPE_COUNT; t++) {
252 offs = IN_BIND_OFFS(i, t);
253 if (strcmp(in_vk_get_key_name(i), "Unkn") == 0)
254 binds[offs] = def_binds[offs] = 0;
255 if (binds[offs])
256 count++;
257 }
258 }
259
260 return count;
261}
262
263void in_vk_init(void *vdrv)
264{
265 in_drv_t *drv = vdrv;
266
267 drv->prefix = in_vk_prefix;
268 drv->probe = in_vk_probe;
269 drv->get_bind_count = in_vk_get_bind_count;
270 drv->get_def_binds = in_vk_get_def_binds;
271 drv->clean_binds = in_vk_clean_binds;
272 drv->menu_translate = in_vk_menu_translate;
273 drv->get_key_code = in_vk_get_key_code;
274 drv->get_key_name = in_vk_get_key_name;
275 drv->update_keycode = in_vk_update_keycode;
276}
277