f89d8471 |
1 | /* |
2 | * (C) GraÅžvydas "notaz" Ignotas, 2009 |
3 | * |
4 | * This work is licensed under the terms of any of these licenses |
5 | * (at your option): |
6 | * - GNU GPL, version 2 or later. |
7 | * - GNU LGPL, version 2.1 or later. |
8 | * - MAME license. |
9 | * See the COPYING file in the top-level directory. |
10 | */ |
11 | |
8ced8d2b |
12 | #define RC_INVOKED // we only need defines |
13 | #include <winuser.h> |
14 | #undef RC_INVOKED |
15 | #include <string.h> |
16 | |
a86e9a3e |
17 | #include "../input.h" |
18 | #include "../emu.h" // array_size |
8ced8d2b |
19 | #include "in_vk.h" |
20 | |
21 | #define IN_VK_PREFIX "vk:" |
22 | #define IN_VK_NKEYS 0x100 |
23 | |
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", |
32 | [VK_SPACE] = "SPACE", |
33 | }; |
34 | |
35 | // additional player12 keys |
36 | int in_vk_add_pl12; |
37 | |
38 | // up to 4, keyboards rarely allow more |
39 | static int in_vk_keys_down[4]; |
40 | |
41 | /* |
42 | #define VK_END 35 |
43 | #define VK_HOME 36 |
44 | #define VK_INSERT 45 |
45 | #define VK_DELETE 46 |
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 |
57 | #define VK_ADD 0x6B |
58 | #define VK_SEPARATOR 0x6C |
59 | #define VK_SUBTRACT 0x6D |
60 | #define VK_DECIMAL 0x6E |
61 | #define VK_DIVIDE 0x6F |
62 | #define VK_F1 0x70 |
63 | #define VK_F2 0x71 |
64 | #define VK_F3 0x72 |
65 | #define VK_F4 0x73 |
66 | #define VK_F5 0x74 |
67 | #define VK_F6 0x75 |
68 | #define VK_F7 0x76 |
69 | #define VK_F8 0x77 |
70 | #define VK_F9 0x78 |
71 | #define VK_F10 0x79 |
72 | #define VK_F11 0x7A |
73 | #define VK_F12 0x7B |
74 | */ |
75 | |
76 | static void in_vk_probe(void) |
77 | { |
78 | memset(in_vk_keys_down, 0, sizeof(in_vk_keys_down)); |
e9b29264 |
79 | in_register(IN_VK_PREFIX "vk", IN_DRVID_VK, -1, (void *)1, IN_VK_NKEYS, NULL, 0); |
8ced8d2b |
80 | } |
81 | |
82 | static int in_vk_get_bind_count(void) |
83 | { |
84 | return IN_VK_NKEYS; |
85 | } |
86 | |
87 | /* ORs result with pressed buttons */ |
88 | int in_vk_update(void *drv_data, const int *binds, int *result) |
89 | { |
90 | int i, t, k; |
91 | |
92 | for (i = 0; i < array_size(in_vk_keys_down); i++) { |
93 | k = in_vk_keys_down[i]; |
94 | if (!k) |
95 | continue; |
96 | |
97 | for (t = 0; t < IN_BINDTYPE_COUNT; t++) |
98 | result[t] |= binds[IN_BIND_OFFS(k, t)]; |
99 | } |
100 | |
101 | result[IN_BINDTYPE_PLAYER12] |= in_vk_add_pl12; |
102 | |
103 | return 0; |
104 | } |
105 | |
106 | void in_vk_keydown(int kc) |
107 | { |
108 | int i; |
109 | |
110 | // search |
111 | for (i = 0; i < array_size(in_vk_keys_down); i++) |
112 | if (in_vk_keys_down[i] == kc) |
113 | return; |
114 | |
115 | // do |
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; |
119 | return; |
120 | } |
121 | } |
122 | } |
123 | |
124 | void in_vk_keyup(int kc) |
125 | { |
126 | int i; |
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; |
130 | } |
131 | |
132 | static int in_vk_update_keycode(void *data, int *is_down) |
133 | { |
134 | return 0; |
135 | } |
136 | |
137 | static const struct { |
138 | short key; |
139 | short pbtn; |
140 | } key_pbtn_map[] = |
141 | { |
142 | { VK_UP, PBTN_UP }, |
143 | { VK_DOWN, PBTN_DOWN }, |
144 | { VK_LEFT, PBTN_LEFT }, |
145 | { VK_RIGHT, PBTN_RIGHT }, |
146 | { VK_RETURN, PBTN_MOK }, |
147 | /* |
148 | { BTN_X, PBTN_MBACK }, |
149 | { BTN_A, PBTN_MA2 }, |
150 | { BTN_Y, PBTN_MA3 }, |
151 | { BTN_L, PBTN_L }, |
152 | { BTN_R, PBTN_R }, |
153 | { BTN_SELECT, PBTN_MENU }, |
154 | */ |
155 | }; |
156 | |
157 | #define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0])) |
158 | |
e9b29264 |
159 | static int in_vk_menu_translate(void *drv_data, int keycode) |
8ced8d2b |
160 | { |
161 | int i; |
162 | if (keycode < 0) |
163 | { |
164 | /* menu -> kc */ |
165 | keycode = -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; |
169 | } |
170 | else |
171 | { |
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; |
175 | } |
176 | |
177 | return 0; |
178 | } |
179 | |
180 | static int in_vk_get_key_code(const char *key_name) |
181 | { |
182 | int i; |
183 | |
184 | if (key_name[1] == 0 && 'A' <= key_name[0] && key_name[0] <= 'Z') |
185 | return key_name[0]; |
186 | |
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) |
190 | return i; |
191 | } |
192 | |
193 | return -1; |
194 | } |
195 | |
196 | static const char *in_vk_get_key_name(int keycode) |
197 | { |
198 | const char *name = NULL; |
199 | static char buff[4]; |
200 | |
201 | if ('A' <= keycode && keycode < 'Z') { |
202 | buff[0] = keycode; |
203 | buff[1] = 0; |
204 | return buff; |
205 | } |
206 | |
207 | if (0 <= keycode && keycode < IN_VK_NKEYS) |
208 | name = in_vk_keys[keycode]; |
209 | if (name == NULL) |
210 | name = "Unkn"; |
211 | |
212 | return name; |
213 | } |
214 | |
215 | static const struct { |
216 | short code; |
217 | char btype; |
218 | char bit; |
219 | } in_vk_def_binds[] = |
220 | { |
221 | /* MXYZ SACB RLDU */ |
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 }, |
7ee5c389 |
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 */ |
8ced8d2b |
234 | /* |
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 }, |
241 | */ |
242 | }; |
243 | |
244 | #define DEF_BIND_COUNT (sizeof(in_vk_def_binds) / sizeof(in_vk_def_binds[0])) |
245 | |
246 | static void in_vk_get_def_binds(int *binds) |
247 | { |
248 | int i; |
249 | |
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; |
253 | } |
254 | |
255 | /* remove binds of missing keys, count remaining ones */ |
256 | static int in_vk_clean_binds(void *drv_data, int *binds, int *def_binds) |
257 | { |
258 | int i, count = 0; |
259 | |
260 | for (i = 0; i < IN_VK_NKEYS; i++) { |
261 | int t, offs; |
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; |
266 | if (binds[offs]) |
267 | count++; |
268 | } |
269 | } |
270 | |
271 | return count; |
272 | } |
273 | |
274 | void in_vk_init(void *vdrv) |
275 | { |
276 | in_drv_t *drv = vdrv; |
277 | |
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; |
287 | } |
288 | |