update license in source code itself
[libpicofe.git] / win32 / in_vk.c
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
12 #define RC_INVOKED // we only need defines
13 #include <winuser.h>
14 #undef RC_INVOKED
15 #include <string.h>
16
17 #include "../input.h"
18 #include "../emu.h" // array_size
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));
79         in_register(IN_VK_PREFIX "vk", IN_DRVID_VK, -1, (void *)1, IN_VK_NKEYS, NULL, 0);
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
159 static int in_vk_menu_translate(void *drv_data, int keycode)
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 },
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 */
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