update license in source code itself
[libpicofe.git] / win32 / in_vk.c
CommitLineData
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
24static const char * const in_vk_prefix = IN_VK_PREFIX;
25static 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
36int in_vk_add_pl12;
37
38// up to 4, keyboards rarely allow more
39static 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
76static 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
82static int in_vk_get_bind_count(void)
83{
84 return IN_VK_NKEYS;
85}
86
87/* ORs result with pressed buttons */
88int 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
106void 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
124void 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
132static int in_vk_update_keycode(void *data, int *is_down)
133{
134 return 0;
135}
136
137static 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 159static 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
180static 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
196static 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
215static 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
246static 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 */
256static 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
274void 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