1 #include "libretro.h"
2 #include "libretro-core.h"
3 #include "libretro-mapper.h"
4 #include "libretro-vkbd.h"
5
6 #include "archdep.h"
7 #include "joystick.h"
8 #include "keyboard.h"
9 #include "machine.h"
10 #include "mouse.h"
11 #include "resources.h"
12 #include "autostart.h"
13 #include "datasette.h"
14 #include "kbd.h"
15 #include "mousedrv.h"
16
17 static retro_input_state_t input_state_cb;
18 static retro_input_poll_t input_poll_cb;
19
retro_set_input_state(retro_input_state_t cb)20 void retro_set_input_state(retro_input_state_t cb)
21 {
22 input_state_cb = cb;
23 }
24
retro_set_input_poll(retro_input_poll_t cb)25 void retro_set_input_poll(retro_input_poll_t cb)
26 {
27 input_poll_cb = cb;
28 }
29
30 #ifdef POINTER_DEBUG
31 int pointer_x = 0;
32 int pointer_y = 0;
33 #endif
34 int last_pointer_x = 0;
35 int last_pointer_y = 0;
36
37 /* VKBD starting point: 10x3 == f7 */
38 int vkey_pos_x = 10;
39 int vkey_pos_y = 3;
40 int vkbd_x_min = 0;
41 int vkbd_x_max = 0;
42 int vkbd_y_min = 0;
43 int vkbd_y_max = 0;
44
45 /* Mouse speed flags */
46 #define MOUSE_SPEED_SLOWER 1
47 #define MOUSE_SPEED_FASTER 2
48 /* Mouse speed multipliers */
49 #define MOUSE_SPEED_SLOW 5
50 #define MOUSE_SPEED_FAST 2
51
52 /* Core flags */
53 int mapper_keys[RETRO_MAPPER_LAST] = {0};
54 int vkflag[10] = {0};
55 int retro_capslock = false;
56 unsigned int cur_port = 2;
57 static int cur_port_prev = -1;
58 bool cur_port_locked = false;
59 unsigned int mouse_value[2 + 1] = {0};
60 unsigned int mouse_speed[2] = {0};
61
62 unsigned int retro_statusbar = 0;
63 extern unsigned char statusbar_text[64];
64 unsigned int retro_warpmode = 0;
65 extern bool retro_vkbd;
66 extern bool retro_vkbd_transparent;
67 extern unsigned int retro_devices[RETRO_DEVICES];
68
69 static unsigned retro_key_state[RETROK_LAST] = {0};
70 static int16_t joypad_bits[RETRO_DEVICES];
71 extern bool libretro_supports_bitmasks;
72
73 /* Core options */
74 extern unsigned int opt_retropad_options;
75 extern unsigned int opt_joyport_type;
76 static int opt_joyport_type_prev = -1;
77 extern unsigned int opt_dpadmouse_speed;
78 extern unsigned int opt_analogmouse;
79 extern unsigned int opt_analogmouse_deadzone;
80 extern float opt_analogmouse_speed;
81 bool datasette_hotkeys = false;
82
83 extern void emu_reset(int type);
84 extern unsigned int zoom_mode_id;
85 extern int zoom_mode_id_prev;
86 extern unsigned int opt_zoom_mode_id;
87 extern bool opt_keyrah_keypad;
88 extern bool opt_keyboard_pass_through;
89 extern unsigned int opt_aspect_ratio;
90 extern bool opt_aspect_ratio_locked;
91
92 bool retro_turbo_fire = false;
93 bool turbo_fire_locked = false;
94 unsigned int turbo_fire_button = 0;
95 unsigned int turbo_pulse = 6;
96 unsigned int turbo_state[RETRO_DEVICES] = {0};
97 unsigned int turbo_toggle[RETRO_DEVICES] = {0};
98
99 enum EMU_FUNCTIONS
100 {
101 EMU_VKBD = 0,
102 EMU_STATUSBAR,
103 EMU_JOYPORT,
104 EMU_RESET,
105 EMU_ASPECT_RATIO,
106 EMU_ZOOM_MODE,
107 EMU_TURBO_FIRE,
108 EMU_WARP_MODE,
109 EMU_DATASETTE_HOTKEYS,
110 EMU_DATASETTE_STOP,
111 EMU_DATASETTE_START,
112 EMU_DATASETTE_FORWARD,
113 EMU_DATASETTE_REWIND,
114 EMU_DATASETTE_RESET,
115 EMU_FUNCTION_COUNT
116 };
117
118 /* VKBD_MIN_HOLDING_TIME: Hold a direction longer than this and automatic movement sets in */
119 /* VKBD_MOVE_DELAY: Delay between automatic movement from button to button */
120 #define VKBD_MIN_HOLDING_TIME 200
121 #define VKBD_MOVE_DELAY 50
122 bool let_go_of_direction = true;
123 long last_move_time = 0;
124 long last_press_time = 0;
125
126 /* VKBD_STICKY_HOLDING_TIME: Button press longer than this triggers sticky key */
127 #define VKBD_STICKY_HOLDING_TIME 1000
128 int let_go_of_button = 1;
129 long last_press_time_button = 0;
130 int vkey_pressed = -1;
131 int vkey_sticky = -1;
132 int vkey_sticky1 = -1;
133 int vkey_sticky2 = -1;
134
emu_function(int function)135 void emu_function(int function)
136 {
137 switch (function)
138 {
139 case EMU_VKBD:
140 retro_vkbd = !retro_vkbd;
141 break;
142 case EMU_STATUSBAR:
143 retro_statusbar = (retro_statusbar) ? 0 : 1;
144 resources_set_int("SDLStatusbar", retro_statusbar);
145 break;
146 case EMU_JOYPORT:
147 #if defined(__XPET__) || defined(__XCBM2__) || defined(__XVIC__)
148 break;
149 #endif
150 cur_port++;
151 if (cur_port > 2) cur_port = 1;
152 /* Lock current port */
153 cur_port_locked = true;
154 /* Statusbar notification */
155 snprintf(statusbar_text, 56, "%c Port %-50d",
156 (' ' | 0x80), cur_port);
157 imagename_timer = 50;
158 break;
159 case EMU_RESET:
160 emu_reset(-1);
161 break;
162 case EMU_ASPECT_RATIO:
163 if (opt_aspect_ratio == 0)
164 opt_aspect_ratio = (retro_region == RETRO_REGION_NTSC) ? 1 : 2;
165 opt_aspect_ratio++;
166 if (opt_aspect_ratio > 3) opt_aspect_ratio = 1;
167 /* Reset zoom */
168 zoom_mode_id_prev = -1;
169 /* Lock aspect ratio */
170 opt_aspect_ratio_locked = true;
171 /* Statusbar notification */
172 snprintf(statusbar_text, 56, "%c Pixel Aspect %-50s",
173 (' ' | 0x80), (opt_aspect_ratio == 1) ? "PAL" : (opt_aspect_ratio == 2) ? "NTSC" : "1:1");
174 imagename_timer = 50;
175 break;
176 case EMU_ZOOM_MODE:
177 if (zoom_mode_id == 0 && opt_zoom_mode_id == 0)
178 break;
179 if (zoom_mode_id > 0)
180 zoom_mode_id = 0;
181 else if (zoom_mode_id == 0)
182 zoom_mode_id = opt_zoom_mode_id;
183 break;
184 case EMU_TURBO_FIRE:
185 retro_turbo_fire = !retro_turbo_fire;
186 /* Lock turbo fire */
187 turbo_fire_locked = true;
188 /* Statusbar notification */
189 snprintf(statusbar_text, 56, "%c Turbo Fire %-50s",
190 (' ' | 0x80), (retro_turbo_fire) ? "ON" : "OFF");
191 imagename_timer = 50;
192 break;
193 case EMU_WARP_MODE:
194 retro_warpmode = (retro_warpmode) ? 0 : 1;
195 resources_set_int("WarpMode", retro_warpmode);
196 break;
197 case EMU_DATASETTE_HOTKEYS:
198 datasette_hotkeys = !datasette_hotkeys;
199 break;
200
201 case EMU_DATASETTE_STOP:
202 datasette_control(DATASETTE_CONTROL_STOP);
203 break;
204 case EMU_DATASETTE_START:
205 datasette_control(DATASETTE_CONTROL_START);
206 break;
207 case EMU_DATASETTE_FORWARD:
208 datasette_control(DATASETTE_CONTROL_FORWARD);
209 break;
210 case EMU_DATASETTE_REWIND:
211 datasette_control(DATASETTE_CONTROL_REWIND);
212 break;
213 case EMU_DATASETTE_RESET:
214 datasette_control(DATASETTE_CONTROL_RESET);
215 break;
216 }
217 }
218
retro_key_up(int symkey)219 void retro_key_up(int symkey)
220 {
221 /* Prevent LShift keyup if ShiftLock is on */
222 if (symkey == RETROK_LSHIFT)
223 {
224 if (!retro_capslock)
225 kbd_handle_keyup(symkey);
226 }
227 else
228 kbd_handle_keyup(symkey);
229 }
230
retro_key_down(int symkey)231 void retro_key_down(int symkey)
232 {
233 /* CapsLock / ShiftLock */
234 if (symkey == RETROK_CAPSLOCK)
235 {
236 if (retro_capslock)
237 kbd_handle_keyup(RETROK_LSHIFT);
238 else
239 kbd_handle_keydown(RETROK_LSHIFT);
240 retro_capslock = !retro_capslock;
241 }
242 else if (!retro_vkbd)
243 kbd_handle_keydown(symkey);
244 }
245
process_key(int disable_keys)246 void process_key(int disable_keys)
247 {
248 int i = 0;
249 unsigned state = 0;
250
251 for (i = RETROK_BACKSPACE; i < RETROK_LAST; i++)
252 {
253 if (disable_keys && (i == RETROK_UP || i == RETROK_DOWN || i == RETROK_LEFT || i == RETROK_RIGHT))
254 continue;
255
256 state = input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, i);
257
258 if (state && !retro_key_state[i])
259 {
260 retro_key_state[i] = 1;
261 retro_key_down(i);
262 }
263 else if (!state && retro_key_state[i])
264 {
265 retro_key_state[i] = 0;
266 retro_key_up(i);
267 }
268 }
269 }
270
update_input(int disable_physical_cursor_keys)271 void update_input(int disable_physical_cursor_keys)
272 {
273 /* RETRO B Y SL ST UP DN LT RT A X L R L2 R2 L3 R3 LR LL LD LU RR RL RD RU
274 * INDEX 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
275 */
276
277 static long now = 0;
278 static long last_vkey_pressed_time = 0;
279 static int last_vkey_pressed = -1;
280 static int vkey_sticky1_release = 0;
281 static int vkey_sticky2_release = 0;
282
283 static int i = 0, j = 0, mk = 0;
284 static int LX = 0, LY = 0, RX = 0, RY = 0;
285 const int threshold = 20000;
286
287 static int jbt[2][24] = {0};
288 static int kbt[EMU_FUNCTION_COUNT] = {0};
289
290 now = GetTicks() / 1000;
291
292 if (vkey_sticky && last_vkey_pressed != -1 && last_vkey_pressed > 0)
293 {
294 if (vkey_sticky1 > -1 && vkey_sticky1 != last_vkey_pressed)
295 {
296 if (vkey_sticky2 > -1 && vkey_sticky2 != last_vkey_pressed)
297 kbd_handle_keyup(vkey_sticky2);
298 vkey_sticky2 = last_vkey_pressed;
299 }
300 else
301 vkey_sticky1 = last_vkey_pressed;
302 }
303
304 /* Keyup only after button is up */
305 if (last_vkey_pressed != -1 && !vkflag[RETRO_DEVICE_ID_JOYPAD_B])
306 {
307 if (vkey_pressed == -1 && last_vkey_pressed >= 0 && last_vkey_pressed != vkey_sticky1 && last_vkey_pressed != vkey_sticky2)
308 kbd_handle_keyup(last_vkey_pressed);
309
310 last_vkey_pressed = -1;
311 }
312
313 if (vkey_sticky1_release)
314 {
315 vkey_sticky1_release = 0;
316 vkey_sticky1 = -1;
317 kbd_handle_keyup(vkey_sticky1);
318 }
319 if (vkey_sticky2_release)
320 {
321 vkey_sticky2_release = 0;
322 vkey_sticky2 = -1;
323 kbd_handle_keyup(vkey_sticky2);
324 }
325
326 /* Iterate hotkeys, skip Datasette hotkeys if Datasette hotkeys are disabled or if VKBD is on */
327 int i_last = (datasette_hotkeys && !retro_vkbd) ? RETRO_MAPPER_DATASETTE_RESET : RETRO_MAPPER_DATASETTE_HOTKEYS;
328 i_last -= 24;
329
330 for (i = 0; i <= i_last; i++)
331 {
332 mk = i + 24; /* Skip RetroPad mappings from mapper_keys */
333
334 /* Key down */
335 if (input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, mapper_keys[mk]) && !kbt[i] && mapper_keys[mk])
336 {
337 kbt[i] = 1;
338 switch (mk)
339 {
340 case RETRO_MAPPER_VKBD:
341 emu_function(EMU_VKBD);
342 break;
343 case RETRO_MAPPER_STATUSBAR:
344 emu_function(EMU_STATUSBAR);
345 break;
346 case RETRO_MAPPER_JOYPORT:
347 emu_function(EMU_JOYPORT);
348 break;
349 case RETRO_MAPPER_RESET:
350 emu_function(EMU_RESET);
351 break;
352 case RETRO_MAPPER_ASPECT_RATIO:
353 emu_function(EMU_ASPECT_RATIO);
354 break;
355 case RETRO_MAPPER_ZOOM_MODE:
356 emu_function(EMU_ZOOM_MODE);
357 break;
358 case RETRO_MAPPER_WARP_MODE:
359 emu_function(EMU_WARP_MODE);
360 break;
361 case RETRO_MAPPER_DATASETTE_HOTKEYS:
362 emu_function(EMU_DATASETTE_HOTKEYS);
363 break;
364
365 case RETRO_MAPPER_DATASETTE_STOP:
366 emu_function(EMU_DATASETTE_STOP);
367 break;
368 case RETRO_MAPPER_DATASETTE_START:
369 emu_function(EMU_DATASETTE_START);
370 break;
371 case RETRO_MAPPER_DATASETTE_FORWARD:
372 emu_function(EMU_DATASETTE_FORWARD);
373 break;
374 case RETRO_MAPPER_DATASETTE_REWIND:
375 emu_function(EMU_DATASETTE_REWIND);
376 break;
377 case RETRO_MAPPER_DATASETTE_RESET:
378 emu_function(EMU_DATASETTE_RESET);
379 break;
380 }
381 }
382 /* Key up */
383 else if (!input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, mapper_keys[mk]) && kbt[i] && mapper_keys[mk])
384 {
385 kbt[i] = 0;
386 switch (mk)
387 {
388 case RETRO_MAPPER_WARP_MODE:
389 emu_function(EMU_WARP_MODE);
390 break;
391 }
392 }
393 }
394
395 /* The check for kbt[i] here prevents the hotkey from generating C64 key events */
396 /* retro_vkbd check is now in process_key() to allow certain keys while retro_vkbd */
397 int processkey = 1;
398 for (i = 0; i < (sizeof(kbt)/sizeof(kbt[0])); i++)
399 {
400 if (kbt[i])
401 {
402 processkey = 0;
403 break;
404 }
405 }
406
407 if (processkey && disable_physical_cursor_keys != 2)
408 process_key(disable_physical_cursor_keys);
409
410 /* RetroPad hotkeys for ports 1 & 2 */
411 for (j = 0; j < 2; j++)
412 {
413 if (retro_devices[j] == RETRO_DEVICE_JOYPAD)
414 {
415 LX = input_state_cb(j, RETRO_DEVICE_ANALOG, 0, 0);
416 LY = input_state_cb(j, RETRO_DEVICE_ANALOG, 0, 1);
417 RX = input_state_cb(j, RETRO_DEVICE_ANALOG, 1, 0);
418 RY = input_state_cb(j, RETRO_DEVICE_ANALOG, 1, 1);
419
420 /* No left analog remappings with non-joysticks */
421 if (opt_joyport_type > 1)
422 LX = LY = 0;
423
424 for (i = 0; i < RETRO_DEVICE_ID_JOYPAD_LAST; i++)
425 {
426 int just_pressed = 0;
427 int just_released = 0;
428 if ((i < 4 || i > 7) && i < 16) /* Remappable RetroPad buttons excluding D-Pad */
429 {
430 /* Skip the VKBD buttons if VKBD is visible and buttons are mapped to keyboard keys */
431 if (retro_vkbd)
432 {
433 switch (i)
434 {
435 case RETRO_DEVICE_ID_JOYPAD_B:
436 case RETRO_DEVICE_ID_JOYPAD_Y:
437 case RETRO_DEVICE_ID_JOYPAD_A:
438 case RETRO_DEVICE_ID_JOYPAD_START:
439 if (mapper_keys[i] >= 0)
440 continue;
441 break;
442 }
443 }
444
445 /* No mappings if button = turbo fire in joystick mode */
446 if (retro_turbo_fire && i == turbo_fire_button && opt_joyport_type == 1)
447 continue;
448
449 if ((joypad_bits[j] & (1 << i)) && !jbt[j][i])
450 just_pressed = 1;
451 else if (!(joypad_bits[j] & (1 << i)) && jbt[j][i])
452 just_released = 1;
453 }
454 else if (i >= 16) /* Remappable RetroPad analog stick directions */
455 {
456 switch (i)
457 {
458 case RETRO_DEVICE_ID_JOYPAD_LR:
459 if (LX > threshold && !jbt[j][i]) just_pressed = 1;
460 else if (LX < threshold && jbt[j][i]) just_released = 1;
461 break;
462 case RETRO_DEVICE_ID_JOYPAD_LL:
463 if (LX < -threshold && !jbt[j][i]) just_pressed = 1;
464 else if (LX > -threshold && jbt[j][i]) just_released = 1;
465 break;
466 case RETRO_DEVICE_ID_JOYPAD_LD:
467 if (LY > threshold && !jbt[j][i]) just_pressed = 1;
468 else if (LY < threshold && jbt[j][i]) just_released = 1;
469 break;
470 case RETRO_DEVICE_ID_JOYPAD_LU:
471 if (LY < -threshold && !jbt[j][i]) just_pressed = 1;
472 else if (LY > -threshold && jbt[j][i]) just_released = 1;
473 break;
474 case RETRO_DEVICE_ID_JOYPAD_RR:
475 if (RX > threshold && !jbt[j][i]) just_pressed = 1;
476 else if (RX < threshold && jbt[j][i]) just_released = 1;
477 break;
478 case RETRO_DEVICE_ID_JOYPAD_RL:
479 if (RX < -threshold && !jbt[j][i]) just_pressed = 1;
480 else if (RX > -threshold && jbt[j][i]) just_released = 1;
481 break;
482 case RETRO_DEVICE_ID_JOYPAD_RD:
483 if (RY > threshold && !jbt[j][i]) just_pressed = 1;
484 else if (RY < threshold && jbt[j][i]) just_released = 1;
485 break;
486 case RETRO_DEVICE_ID_JOYPAD_RU:
487 if (RY < -threshold && !jbt[j][i]) just_pressed = 1;
488 else if (RY > -threshold && jbt[j][i]) just_released = 1;
489 break;
490 default:
491 break;
492 }
493 }
494
495 if (just_pressed)
496 {
497 jbt[j][i] = 1;
498 if (!mapper_keys[i]) /* Unmapped, e.g. set to "---" in core options */
499 continue;
500
501 if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_VKBD])
502 emu_function(EMU_VKBD);
503 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_STATUSBAR])
504 emu_function(EMU_STATUSBAR);
505 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_JOYPORT])
506 emu_function(EMU_JOYPORT);
507 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_RESET])
508 emu_function(EMU_RESET);
509 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_ASPECT_RATIO])
510 emu_function(EMU_ASPECT_RATIO);
511 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_ZOOM_MODE])
512 emu_function(EMU_ZOOM_MODE);
513 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_WARP_MODE])
514 emu_function(EMU_WARP_MODE);
515 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_HOTKEYS])
516 emu_function(EMU_DATASETTE_HOTKEYS);
517 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_STOP])
518 emu_function(EMU_DATASETTE_STOP);
519 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_START])
520 emu_function(EMU_DATASETTE_START);
521 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_FORWARD])
522 emu_function(EMU_DATASETTE_FORWARD);
523 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_REWIND])
524 emu_function(EMU_DATASETTE_REWIND);
525 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_RESET])
526 emu_function(EMU_DATASETTE_RESET);
527 else if (mapper_keys[i] == MOUSE_SLOWER)
528 mouse_speed[j] |= MOUSE_SPEED_SLOWER;
529 else if (mapper_keys[i] == MOUSE_FASTER)
530 mouse_speed[j] |= MOUSE_SPEED_FASTER;
531 else if (mapper_keys[i] == TOGGLE_VKBD)
532 emu_function(EMU_VKBD);
533 else if (mapper_keys[i] == TOGGLE_STATUSBAR)
534 emu_function(EMU_STATUSBAR);
535 else if (mapper_keys[i] == SWITCH_JOYPORT)
536 emu_function(EMU_JOYPORT);
537 else
538 retro_key_down(mapper_keys[i]);
539 }
540 else if (just_released)
541 {
542 jbt[j][i] = 0;
543 if (!mapper_keys[i]) /* Unmapped, e.g. set to "---" in core options */
544 continue;
545
546 if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_VKBD])
547 ; /* nop */
548 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_STATUSBAR])
549 ; /* nop */
550 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_JOYPORT])
551 ; /* nop */
552 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_RESET])
553 ; /* nop */
554 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_ASPECT_RATIO])
555 ; /* nop */
556 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_ZOOM_MODE])
557 ; /* nop */
558 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_WARP_MODE])
559 emu_function(EMU_WARP_MODE);
560 else if (mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_HOTKEYS])
561 ; /* nop */
562 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_STOP])
563 ; /* nop */
564 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_START])
565 ; /* nop */
566 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_FORWARD])
567 ; /* nop */
568 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_REWIND])
569 ; /* nop */
570 else if (datasette_hotkeys && mapper_keys[i] == mapper_keys[RETRO_MAPPER_DATASETTE_RESET])
571 ; /* nop */
572 else if (mapper_keys[i] == MOUSE_SLOWER)
573 mouse_speed[j] &= ~MOUSE_SPEED_SLOWER;
574 else if (mapper_keys[i] == MOUSE_FASTER)
575 mouse_speed[j] &= ~MOUSE_SPEED_FASTER;
576 else if (mapper_keys[i] == TOGGLE_VKBD)
577 ; /* nop */
578 else if (mapper_keys[i] == TOGGLE_STATUSBAR)
579 ; /* nop */
580 else if (mapper_keys[i] == SWITCH_JOYPORT)
581 ; /* nop */
582 else
583 retro_key_up(mapper_keys[i]);
584 }
585 } /* for i */
586 } /* if retro_devices[0]==joypad */
587 } /* for j */
588
589 /* Virtual keyboard for ports 1 & 2 */
590 if (retro_vkbd)
591 {
592 if (!vkflag[RETRO_DEVICE_ID_JOYPAD_B]) /* Allow directions when key is not pressed */
593 {
594 if (!vkflag[RETRO_DEVICE_ID_JOYPAD_UP] && ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) ||
595 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) ||
596 input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_UP)))
597 vkflag[RETRO_DEVICE_ID_JOYPAD_UP] = 1;
598 else
599 if (vkflag[RETRO_DEVICE_ID_JOYPAD_UP] && (!(joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) &&
600 !(joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) &&
601 !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_UP)))
602 vkflag[RETRO_DEVICE_ID_JOYPAD_UP] = 0;
603
604 if (!vkflag[RETRO_DEVICE_ID_JOYPAD_DOWN] && ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) ||
605 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) ||
606 input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_DOWN)))
607 vkflag[RETRO_DEVICE_ID_JOYPAD_DOWN] = 1;
608 else
609 if (vkflag[RETRO_DEVICE_ID_JOYPAD_DOWN] && (!(joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) &&
610 !(joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) &&
611 !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_DOWN)))
612 vkflag[RETRO_DEVICE_ID_JOYPAD_DOWN] = 0;
613
614 if (!vkflag[RETRO_DEVICE_ID_JOYPAD_LEFT] && ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) ||
615 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) ||
616 input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_LEFT)))
617 vkflag[RETRO_DEVICE_ID_JOYPAD_LEFT] = 1;
618 else
619 if (vkflag[RETRO_DEVICE_ID_JOYPAD_LEFT] && (!(joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) &&
620 !(joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) &&
621 !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_LEFT)))
622 vkflag[RETRO_DEVICE_ID_JOYPAD_LEFT] = 0;
623
624 if (!vkflag[RETRO_DEVICE_ID_JOYPAD_RIGHT] && ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) ||
625 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) ||
626 input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RIGHT)))
627 vkflag[RETRO_DEVICE_ID_JOYPAD_RIGHT] = 1;
628 else
629 if (vkflag[RETRO_DEVICE_ID_JOYPAD_RIGHT] && (!(joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) &&
630 !(joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) &&
631 !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RIGHT)))
632 vkflag[RETRO_DEVICE_ID_JOYPAD_RIGHT] = 0;
633 }
634 else /* Release all directions when key is pressed */
635 {
636 vkflag[RETRO_DEVICE_ID_JOYPAD_UP] = 0;
637 vkflag[RETRO_DEVICE_ID_JOYPAD_DOWN] = 0;
638 vkflag[RETRO_DEVICE_ID_JOYPAD_LEFT] = 0;
639 vkflag[RETRO_DEVICE_ID_JOYPAD_RIGHT] = 0;
640 }
641
642 if (vkflag[RETRO_DEVICE_ID_JOYPAD_UP] ||
643 vkflag[RETRO_DEVICE_ID_JOYPAD_DOWN] ||
644 vkflag[RETRO_DEVICE_ID_JOYPAD_LEFT] ||
645 vkflag[RETRO_DEVICE_ID_JOYPAD_RIGHT])
646 {
647 if (let_go_of_direction)
648 /* just pressing down */
649 last_press_time = now;
650
651 if ((now - last_press_time > VKBD_MIN_HOLDING_TIME
652 && now - last_move_time > VKBD_MOVE_DELAY)
653 || let_go_of_direction)
654 {
655 last_move_time = now;
656
657 if (vkflag[RETRO_DEVICE_ID_JOYPAD_UP])
658 vkey_pos_y -= 1;
659 else if (vkflag[RETRO_DEVICE_ID_JOYPAD_DOWN])
660 vkey_pos_y += 1;
661
662 if (vkflag[RETRO_DEVICE_ID_JOYPAD_LEFT])
663 vkey_pos_x -= 1;
664 else if (vkflag[RETRO_DEVICE_ID_JOYPAD_RIGHT])
665 vkey_pos_x += 1;
666 }
667 let_go_of_direction = false;
668 }
669 else
670 let_go_of_direction = true;
671
672 if (vkey_pos_x < 0)
673 vkey_pos_x = VKBDX - 1;
674 else if (vkey_pos_x > VKBDX - 1)
675 vkey_pos_x = 0;
676 if (vkey_pos_y < 0)
677 vkey_pos_y = VKBDY - 1;
678 else if (vkey_pos_y > VKBDY - 1)
679 vkey_pos_y = 0;
680
681 /* Absolute pointer */
682 int p_x = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
683 int p_y = input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
684
685 if (p_x != 0 && p_y != 0 && (p_x != last_pointer_x || p_y != last_pointer_y))
686 {
687 int px = (int)((p_x + 0x7fff) * retrow / 0xffff);
688 int py = (int)((p_y + 0x7fff) * retroh / 0xffff);
689 last_pointer_x = p_x;
690 last_pointer_y = p_y;
691 #ifdef POINTER_DEBUG
692 pointer_x = px;
693 pointer_y = py;
694 #endif
695 if (px >= vkbd_x_min && px <= vkbd_x_max && py >= vkbd_y_min && py <= vkbd_y_max)
696 {
697 float vkey_width = (float)(vkbd_x_max - vkbd_x_min) / VKBDX;
698 vkey_pos_x = ((px - vkbd_x_min) / vkey_width);
699
700 float vkey_height = (float)(vkbd_y_max - vkbd_y_min) / VKBDY;
701 vkey_pos_y = ((py - vkbd_y_min) / vkey_height);
702
703 vkey_pos_x = (vkey_pos_x < 0) ? 0 : vkey_pos_x;
704 vkey_pos_x = (vkey_pos_x > VKBDX - 1) ? VKBDX - 1 : vkey_pos_x;
705 vkey_pos_y = (vkey_pos_y < 0) ? 0 : vkey_pos_y;
706 vkey_pos_y = (vkey_pos_y > VKBDY - 1) ? VKBDY - 1 : vkey_pos_y;
707
708 #ifdef POINTER_DEBUG
709 printf("px:%d py:%d (%d,%d) vkey:%dx%d\n", p_x, p_y, px, py, vkey_pos_x, vkey_pos_y);
710 #endif
711 }
712 }
713
714 /* Press Return, RetroPad Start */
715 i = RETRO_DEVICE_ID_JOYPAD_START;
716 if (!vkflag[i] && mapper_keys[i] >= 0 && ((joypad_bits[0] & (1 << i)) ||
717 (joypad_bits[1] & (1 << i))))
718 {
719 vkflag[i] = 1;
720 kbd_handle_keydown(RETROK_RETURN);
721 }
722 else
723 if (vkflag[i] && (!(joypad_bits[0] & (1 << i)) &&
724 !(joypad_bits[1] & (1 << i))))
725 {
726 vkflag[i] = 0;
727 kbd_handle_keyup(RETROK_RETURN);
728 }
729
730 /* ShiftLock, RetroPad Y */
731 i = RETRO_DEVICE_ID_JOYPAD_Y;
732 if (!vkflag[i] && mapper_keys[i] >= 0 && ((joypad_bits[0] & (1 << i)) ||
733 (joypad_bits[1] & (1 << i))))
734 {
735 vkflag[i] = 1;
736 retro_key_down(RETROK_CAPSLOCK);
737 retro_key_up(RETROK_CAPSLOCK);
738 }
739 else
740 if (vkflag[i] && (!(joypad_bits[0] & (1 << i)) &&
741 !(joypad_bits[1] & (1 << i))))
742 {
743 vkflag[i] = 0;
744 }
745
746 /* Transparency toggle, RetroPad A */
747 i = RETRO_DEVICE_ID_JOYPAD_A;
748 if (!vkflag[i] && mapper_keys[i] >= 0 && ((joypad_bits[0] & (1 << i)) ||
749 (joypad_bits[1] & (1 << i))))
750 {
751 vkflag[i] = 1;
752 retro_vkbd_transparent = !retro_vkbd_transparent;
753 }
754 else
755 if (vkflag[i] && (!(joypad_bits[0] & (1 << i)) &&
756 !(joypad_bits[1] & (1 << i))))
757 {
758 vkflag[i] = 0;
759 }
760
761 /* Key press, RetroPad B joyports 1+2 / Keyboard Enter / Pointer */
762 i = RETRO_DEVICE_ID_JOYPAD_B;
763 if (!vkflag[i] && ((joypad_bits[0] & (1 << i)) ||
764 (joypad_bits[1] & (1 << i)) ||
765 input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN) ||
766 input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED)))
767 {
768 vkey_pressed = check_vkey(vkey_pos_x, vkey_pos_y);
769 vkflag[i] = 1;
770
771 if (vkey_pressed != -1 && last_vkey_pressed == -1)
772 {
773 switch (vkey_pressed)
774 {
775 case -2:
776 emu_function(EMU_RESET);
777 break;
778 case -3:
779 emu_function(EMU_STATUSBAR);
780 break;
781 case -4:
782 emu_function(EMU_JOYPORT);
783 break;
784 case -5: /* sticky shift */
785 retro_key_down(RETROK_CAPSLOCK);
786 retro_key_up(RETROK_CAPSLOCK);
787 break;
788 case -20:
789 emu_function(EMU_TURBO_FIRE);
790 break;
791
792 case -11:
793 emu_function(EMU_DATASETTE_STOP);
794 break;
795 case -12:
796 emu_function(EMU_DATASETTE_START);
797 break;
798 case -13:
799 emu_function(EMU_DATASETTE_FORWARD);
800 break;
801 case -14:
802 emu_function(EMU_DATASETTE_REWIND);
803 break;
804 case -15:
805 emu_function(EMU_DATASETTE_RESET);
806 break;
807
808 default:
809 if (vkey_pressed == vkey_sticky1)
810 vkey_sticky1_release = 1;
811 if (vkey_pressed == vkey_sticky2)
812 vkey_sticky2_release = 1;
813 kbd_handle_keydown(vkey_pressed);
814 break;
815 }
816 }
817 last_vkey_pressed = vkey_pressed;
818 }
819 else
820 if (vkflag[i] && (!(joypad_bits[0] & (1 << i)) &&
821 !(joypad_bits[1] & (1 << i)) &&
822 !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN) &&
823 !input_state_cb(0, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED)))
824 {
825 vkey_pressed = -1;
826 vkflag[i] = 0;
827 }
828
829 if (vkflag[RETRO_DEVICE_ID_JOYPAD_B] && vkey_pressed > 0)
830 {
831 if (let_go_of_button)
832 last_press_time_button = now;
833 if (now - last_press_time_button > VKBD_STICKY_HOLDING_TIME)
834 vkey_sticky = 1;
835 let_go_of_button = 0;
836 }
837 else
838 {
839 let_go_of_button = 1;
840 vkey_sticky = 0;
841 }
842 }
843 #if 0
844 printf("vkey:%d sticky:%d sticky1:%d sticky2:%d, now:%d last:%d\n", vkey_pressed, vkey_sticky, vkey_sticky1, vkey_sticky2, now, last_press_time_button);
845 #endif
846 }
847
process_keyboard_pass_through()848 int process_keyboard_pass_through()
849 {
850 unsigned process = 0;
851
852 /* Defaults */
853 int fire_button = RETRO_DEVICE_ID_JOYPAD_B;
854 int jump_button = -1;
855
856 /* Fire button */
857 switch (opt_retropad_options)
858 {
859 case 1:
860 case 3:
861 fire_button = RETRO_DEVICE_ID_JOYPAD_Y;
862 break;
863 }
864
865 /* Jump button */
866 switch (opt_retropad_options)
867 {
868 case 2:
869 jump_button = RETRO_DEVICE_ID_JOYPAD_A;
870 break;
871 case 3:
872 jump_button = RETRO_DEVICE_ID_JOYPAD_B;
873 break;
874 }
875 /* Null only with RetroPad */
876 if (retro_devices[0] == RETRO_DEVICE_JOYPAD)
877 {
878 if (mapper_keys[fire_button] || (retro_turbo_fire && fire_button == turbo_fire_button))
879 fire_button = -1;
880
881 if (mapper_keys[jump_button] || (retro_turbo_fire && jump_button == turbo_fire_button))
882 jump_button = -1;
883 }
884
885 /* Prevent RetroPad from generating keyboard key presses when RetroPad is controlled with keyboard */
886 switch (retro_devices[0])
887 {
888 case RETRO_DEVICE_JOYPAD:
889 if ((fire_button > -1 && (joypad_bits[0] & (1 << fire_button))) ||
890 (jump_button > -1 && (joypad_bits[0] & (1 << jump_button))) ||
891 (retro_turbo_fire && (joypad_bits[0] & (1 << turbo_fire_button))) ||
892 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_B)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_B]) ||
893 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_Y]) ||
894 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_A)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_A]) ||
895 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_X)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_X]) ||
896 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_L)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_L]) ||
897 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_R)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_R]) ||
898 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_L2)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_L2]) ||
899 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_R2)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_R2]) ||
900 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_L3)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_L3]) ||
901 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_R3]) ||
902 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_SELECT)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_SELECT]) ||
903 ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_START)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_START]))
904 process = 2; /* Skip all keyboard input when RetroPad buttons are pressed */
905 else
906 if ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) ||
907 (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) ||
908 (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) ||
909 (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)))
910 process = 1; /* Skip cursor keys */
911 break;
912
913 case RETRO_DEVICE_VICE_JOYSTICK:
914 if ((fire_button > -1 && (joypad_bits[0] & (1 << fire_button))) ||
915 (jump_button > -1 && (joypad_bits[0] & (1 << jump_button))))
916 process = 2; /* Skip all keyboard input when RetroPad buttons are pressed */
917 else
918 if ((joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) ||
919 (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) ||
920 (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) ||
921 (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)))
922 process = 1; /* Skip cursor keys */
923 break;
924 }
925
926 /* Fire button */
927 fire_button = RETRO_DEVICE_ID_JOYPAD_B;
928 switch (opt_retropad_options)
929 {
930 case 1:
931 case 3:
932 fire_button = RETRO_DEVICE_ID_JOYPAD_Y;
933 break;
934 }
935
936 /* Jump button */
937 jump_button = -1;
938 switch (opt_retropad_options)
939 {
940 case 2:
941 jump_button = RETRO_DEVICE_ID_JOYPAD_A;
942 break;
943 case 3:
944 jump_button = RETRO_DEVICE_ID_JOYPAD_B;
945 break;
946 }
947 /* Null only with RetroPad */
948 if (retro_devices[1] == RETRO_DEVICE_JOYPAD)
949 {
950 if (mapper_keys[fire_button] || (retro_turbo_fire && fire_button == turbo_fire_button))
951 fire_button = -1;
952
953 if (mapper_keys[jump_button] || (retro_turbo_fire && jump_button == turbo_fire_button))
954 jump_button = -1;
955 }
956
957 switch (retro_devices[1])
958 {
959 case RETRO_DEVICE_JOYPAD:
960 if ((fire_button > -1 && (joypad_bits[1] & (1 << fire_button))) ||
961 (jump_button > -1 && (joypad_bits[1] & (1 << jump_button))) ||
962 (retro_turbo_fire && (joypad_bits[1] & (1 << turbo_fire_button))) ||
963 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_B)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_B]) ||
964 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_Y)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_Y]) ||
965 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_A)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_A]) ||
966 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_X)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_X]) ||
967 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_L)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_L]) ||
968 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_R)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_R]) ||
969 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_L2)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_L2]) ||
970 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_R2)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_R2]) ||
971 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_L3)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_L3]) ||
972 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_R3]) ||
973 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_SELECT)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_SELECT]) ||
974 ((joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_START)) && mapper_keys[RETRO_DEVICE_ID_JOYPAD_START]) ||
975 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) ||
976 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) ||
977 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) ||
978 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)))
979 process = 2; /* Skip all keyboard input from RetroPad 2 */
980 break;
981
982 case RETRO_DEVICE_VICE_JOYSTICK:
983 if ((fire_button > -1 && (joypad_bits[1] & (1 << fire_button))) ||
984 (jump_button > -1 && (joypad_bits[1] & (1 << jump_button))) ||
985 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) ||
986 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) ||
987 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) ||
988 (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)))
989 process = 2; /* Skip all keyboard input from RetroPad 2 */
990 break;
991 }
992
993 return process;
994 }
995
retro_poll_event()996 void retro_poll_event()
997 {
998 unsigned i, j;
999
1000 input_poll_cb();
1001
1002 for (j = 0; j < RETRO_DEVICES; j++)
1003 {
1004 if (libretro_supports_bitmasks)
1005 joypad_bits[j] = input_state_cb(j, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
1006 else
1007 {
1008 joypad_bits[j] = 0;
1009 for (i = 0; i < RETRO_DEVICE_ID_JOYPAD_LR; i++)
1010 joypad_bits[j] |= input_state_cb(j, RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0;
1011 }
1012 }
1013
1014 /* Keyboard pass-through */
1015 unsigned process_key = 0;
1016 if (!opt_keyboard_pass_through)
1017 process_key = process_keyboard_pass_through();
1018 update_input(process_key);
1019
1020 /* retro joypad take control over keyboard joy */
1021 /* override keydown, but allow keyup, to prevent key sticking during keyboard use, if held down on opening keyboard */
1022 /* keyup allowing most likely not needed on actual keyboard presses even though they get stuck also */
1023 int retro_port;
1024 for (retro_port = 0; retro_port <= 4; retro_port++)
1025 {
1026 if (retro_devices[retro_port] == RETRO_DEVICE_VICE_JOYSTICK || retro_devices[retro_port] == RETRO_DEVICE_JOYPAD)
1027 {
1028 int vice_port = cur_port;
1029 BYTE j = 0;
1030
1031 if (retro_port == 1) /* Second joypad controls other player */
1032 vice_port = (cur_port == 2) ? 1 : 2;
1033 else if (retro_port == 2)
1034 vice_port = 3;
1035 else if (retro_port == 3)
1036 vice_port = 4;
1037 else if (retro_port == 4)
1038 vice_port = 5;
1039
1040 /* No same port joystick movements with non-joysticks */
1041 if (opt_joyport_type > 1 && vice_port == cur_port)
1042 continue;
1043 /* No joystick movements with paddles */
1044 if (opt_joyport_type == 2)
1045 continue;
1046
1047 j = joystick_value[vice_port];
1048
1049 /* Up */
1050 if (((joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
1051 && !(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)))
1052 || (opt_keyrah_keypad && vice_port < 3
1053 && (
1054 (vice_port != cur_port
1055 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP9)
1056 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP3)
1057 )
1058 ||
1059 (vice_port == cur_port
1060 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP8)
1061 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP2)
1062 )
1063 )
1064 )
1065 )
1066 j |= (!retro_vkbd) ? 0x01 : j;
1067 else if (!(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)))
1068 j &= ~0x01;
1069
1070 /* Down */
1071 if (((joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))
1072 && !(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_UP)))
1073 || (opt_keyrah_keypad && vice_port < 3
1074 && (
1075 (vice_port != cur_port
1076 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP3)
1077 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP9)
1078 )
1079 ||
1080 (vice_port == cur_port
1081 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP2)
1082 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP8)
1083 )
1084 )
1085 )
1086 )
1087 j |= (!retro_vkbd) ? 0x02 : j;
1088 else if (!(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)))
1089 j &= ~0x02;
1090
1091 /* Left */
1092 if (((joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))
1093 && !(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)))
1094 || (opt_keyrah_keypad && vice_port < 3
1095 && (
1096 (vice_port != cur_port
1097 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP7)
1098 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP1)
1099 )
1100 ||
1101 (vice_port == cur_port
1102 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP4)
1103 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP6)
1104 )
1105 )
1106 )
1107 )
1108 j |= (!retro_vkbd) ? 0x04 : j;
1109 else if (!(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)))
1110 j &= ~0x04;
1111
1112 /* Right */
1113 if (((joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))
1114 && !(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)))
1115 || (opt_keyrah_keypad && vice_port < 3
1116 && (
1117 (vice_port != cur_port
1118 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP1)
1119 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP7)
1120 )
1121 ||
1122 (vice_port == cur_port
1123 && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP6)
1124 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP4)
1125 )
1126 )
1127 )
1128 )
1129 j |= (!retro_vkbd) ? 0x08 : j;
1130 else if (!(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)))
1131 j &= ~0x08;
1132
1133 /* Fire button */
1134 int fire_button = RETRO_DEVICE_ID_JOYPAD_B;
1135 switch (opt_retropad_options)
1136 {
1137 case 1:
1138 case 3:
1139 fire_button = RETRO_DEVICE_ID_JOYPAD_Y;
1140 break;
1141 }
1142 /* Null only with RetroPad */
1143 if (retro_devices[retro_port] == RETRO_DEVICE_JOYPAD)
1144 {
1145 if (mapper_keys[fire_button] || (retro_turbo_fire && fire_button == turbo_fire_button))
1146 fire_button = -1;
1147 }
1148
1149 if ((fire_button > -1 && (joypad_bits[retro_port] & (1 << fire_button)))
1150 || (opt_keyrah_keypad && vice_port < 3
1151 && (
1152 (vice_port != cur_port && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP0))
1153 ||
1154 (vice_port == cur_port && input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP5))
1155 )
1156 )
1157 )
1158 j |= (!retro_vkbd) ? 0x10 : j;
1159 else
1160 j &= ~0x10;
1161
1162 /* Jump button */
1163 int jump_button = -1;
1164 switch (opt_retropad_options)
1165 {
1166 case 2:
1167 jump_button = RETRO_DEVICE_ID_JOYPAD_A;
1168 break;
1169 case 3:
1170 jump_button = RETRO_DEVICE_ID_JOYPAD_B;
1171 break;
1172 }
1173 /* Null only with RetroPad */
1174 if (retro_devices[retro_port] == RETRO_DEVICE_JOYPAD)
1175 {
1176 if (mapper_keys[jump_button] || (retro_turbo_fire && jump_button == turbo_fire_button))
1177 jump_button = -1;
1178 }
1179
1180 if (jump_button > -1 && (joypad_bits[retro_port] & (1 << jump_button)))
1181 {
1182 j |= (!retro_vkbd) ? 0x01 : j;
1183 j &= ~0x02;
1184 }
1185 else if (!(joypad_bits[retro_port] & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
1186 && (opt_keyrah_keypad && vice_port < 3
1187 && (
1188 (vice_port != cur_port
1189 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP9)
1190 )
1191 &&
1192 (vice_port == cur_port
1193 && !input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_KP8)
1194 )
1195 )
1196 )
1197 )
1198 j &= ~0x01;
1199
1200 /* Turbo fire */
1201 if (retro_devices[retro_port] == RETRO_DEVICE_JOYPAD
1202 && retro_turbo_fire
1203 && !(joypad_bits[retro_port] & (1 << fire_button)))
1204 {
1205 if ((joypad_bits[retro_port] & (1 << turbo_fire_button)))
1206 {
1207 if (turbo_state[vice_port])
1208 {
1209 if ((turbo_toggle[vice_port]) == (turbo_pulse))
1210 turbo_toggle[vice_port] = 1;
1211 else
1212 turbo_toggle[vice_port]++;
1213
1214 if (turbo_toggle[vice_port] > (turbo_pulse / 2))
1215 j &= ~0x10;
1216 else
1217 j |= (!retro_vkbd) ? 0x10 : j;
1218 }
1219 else
1220 {
1221 turbo_state[vice_port] = 1;
1222 j |= (!retro_vkbd) ? 0x10 : j;
1223 }
1224 }
1225 else
1226 {
1227 turbo_state[vice_port] = 0;
1228 turbo_toggle[vice_port] = 0;
1229 }
1230 }
1231
1232 joystick_value[vice_port] = j;
1233
1234 #if 0
1235 if (vice_port == 2)
1236 printf("Joy %d: Button %d, %2d %d %d\n", vice_port, turbo_fire_button, j, turbo_state[vice_port], turbo_toggle[vice_port]);
1237 #endif
1238 }
1239 }
1240
1241 /* Default to joysticks, set both ports */
1242 if (opt_joyport_type == 1)
1243 {
1244 if (opt_joyport_type_prev != opt_joyport_type)
1245 {
1246 opt_joyport_type_prev = opt_joyport_type;
1247 resources_set_int("JoyPort1Device", opt_joyport_type);
1248 resources_set_int("JoyPort2Device", opt_joyport_type);
1249 }
1250 }
1251 /* Other than a joystick, set only cur_port */
1252 else if (opt_joyport_type > 1 && !retro_vkbd)
1253 {
1254 if (opt_joyport_type_prev != opt_joyport_type || cur_port_prev != cur_port)
1255 {
1256 opt_joyport_type_prev = opt_joyport_type;
1257 cur_port_prev = cur_port;
1258
1259 if (cur_port == 2)
1260 {
1261 resources_set_int("JoyPort1Device", 1);
1262 resources_set_int("JoyPort2Device", opt_joyport_type);
1263 }
1264 else
1265 {
1266 resources_set_int("JoyPort2Device", 1);
1267 resources_set_int("JoyPort1Device", opt_joyport_type);
1268 }
1269 }
1270
1271 int j = cur_port - 1;
1272 int retro_j = 0;
1273 static float mouse_multiplier[2] = {1};
1274 static int dpadmouse_speed[2] = {0};
1275 static long dpadmouse_press[2] = {0};
1276 static int dpadmouse_pressed[2] = {0};
1277 static long now = 0;
1278 now = GetTicks();
1279
1280 int retro_mouse_x[2] = {0}, retro_mouse_y[2] = {0};
1281 unsigned int retro_mouse_l[2] = {0}, retro_mouse_r[2] = {0}, retro_mouse_m[2] = {0};
1282 static unsigned int vice_mouse_l[2] = {0}, vice_mouse_r[2] = {0}, vice_mouse_m[2] = {0};
1283
1284 int analog_left[2] = {0};
1285 int analog_right[2] = {0};
1286 double analog_left_magnitude = 0;
1287 double analog_right_magnitude = 0;
1288 int analog_deadzone = 0;
1289 analog_deadzone = (opt_analogmouse_deadzone * 32768 / 100);
1290
1291 /* Paddles (opt_joyport_type = 2) share the same joyport, but are meant for 2 players.
1292 Therefore treat retroport0 vertical axis as retroport1 horizontal axis, and second fire as retroport1 fire. */
1293
1294 /* Joypad buttons */
1295 if (!retro_vkbd)
1296 {
1297 if (retro_devices[0] == RETRO_DEVICE_JOYPAD && (opt_retropad_options == 1 || opt_retropad_options == 3))
1298 {
1299 retro_mouse_l[j] = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_Y));
1300 /* Paddles-split */
1301 if (opt_joyport_type == 2)
1302 retro_mouse_r[j] = (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_Y));
1303 else
1304 retro_mouse_r[j] = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_B));
1305 }
1306 else
1307 {
1308 retro_mouse_l[j] = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_B));
1309 /* Paddles-split */
1310 if (opt_joyport_type == 2)
1311 retro_mouse_r[j] = (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_B));
1312 else
1313 retro_mouse_r[j] = (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_A));
1314 }
1315 }
1316
1317 /* Real mouse buttons */
1318 if (!retro_mouse_l[j] && !retro_mouse_r[j] && !retro_mouse_m[j])
1319 {
1320 retro_mouse_l[j] = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT);
1321 retro_mouse_r[j] = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT);
1322 retro_mouse_m[j] = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE);
1323 }
1324
1325 /* Joypad movement */
1326 if (!retro_vkbd)
1327 {
1328 for (retro_j = 0; retro_j < 2; retro_j++)
1329 {
1330 /* Digital mouse speed modifiers */
1331 if (!dpadmouse_pressed[retro_j])
1332 dpadmouse_speed[retro_j] = opt_dpadmouse_speed;
1333
1334 if (mouse_speed[retro_j] & MOUSE_SPEED_FASTER)
1335 dpadmouse_speed[retro_j] = dpadmouse_speed[retro_j] + 4;
1336 if (mouse_speed[retro_j] & MOUSE_SPEED_SLOWER)
1337 dpadmouse_speed[retro_j] = dpadmouse_speed[retro_j] - 3;
1338
1339 /* Digital mouse acceleration */
1340 if (dpadmouse_pressed[retro_j])
1341 if (now - dpadmouse_press[retro_j] > 500 * 200)
1342 {
1343 dpadmouse_speed[retro_j]++;
1344 dpadmouse_press[retro_j] = now;
1345 }
1346
1347 /* Digital mouse speed limits */
1348 if (dpadmouse_speed[retro_j] < 4) dpadmouse_speed[retro_j] = 4;
1349 if (dpadmouse_speed[retro_j] > 20) dpadmouse_speed[retro_j] = 20;
1350 }
1351
1352 if (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))
1353 retro_mouse_x[j] += dpadmouse_speed[0];
1354 else if (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))
1355 retro_mouse_x[j] -= dpadmouse_speed[0];
1356
1357 /* Paddles-split */
1358 if (opt_joyport_type == 2)
1359 {
1360 if (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))
1361 retro_mouse_y[j] += dpadmouse_speed[1];
1362 else if (joypad_bits[1] & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))
1363 retro_mouse_y[j] -= dpadmouse_speed[1];
1364 }
1365 else
1366 {
1367 if (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))
1368 retro_mouse_y[j] += dpadmouse_speed[0];
1369 else if (joypad_bits[0] & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
1370 retro_mouse_y[j] -= dpadmouse_speed[0];
1371 }
1372
1373 for (retro_j = 0; retro_j < 2; retro_j++)
1374 {
1375 /* Acceleration timestamps */
1376 if ((retro_mouse_x[j] != 0 || retro_mouse_y[j] != 0) && dpadmouse_pressed[retro_j] == 0)
1377 {
1378 dpadmouse_press[retro_j] = now;
1379 dpadmouse_pressed[retro_j] = 1;
1380 }
1381 else if ((retro_mouse_x[j] == 0 && retro_mouse_y[j] == 0) && dpadmouse_pressed[retro_j] == 1)
1382 {
1383 dpadmouse_press[retro_j] = 0;
1384 dpadmouse_pressed[retro_j] = 0;
1385 }
1386 }
1387 }
1388
1389 /* Left analog movement */
1390 analog_left[0] = input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
1391 /* Paddles split */
1392 if (opt_joyport_type == 2)
1393 analog_left[1] = -input_state_cb(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
1394 else
1395 analog_left[1] = input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
1396 analog_left_magnitude = sqrt((analog_left[0]*analog_left[0]) + (analog_left[1]*analog_left[1]));
1397 if (analog_left_magnitude <= analog_deadzone)
1398 {
1399 analog_left[0] = 0;
1400 analog_left[1] = 0;
1401 }
1402
1403 for (retro_j = 0; retro_j < 2; retro_j++)
1404 {
1405 /* Analog stick speed modifiers */
1406 mouse_multiplier[retro_j] = 1;
1407 if (mouse_speed[retro_j] & MOUSE_SPEED_FASTER)
1408 mouse_multiplier[retro_j] = mouse_multiplier[retro_j] * MOUSE_SPEED_FAST;
1409 if (mouse_speed[retro_j] & MOUSE_SPEED_SLOWER)
1410 mouse_multiplier[retro_j] = mouse_multiplier[retro_j] / MOUSE_SPEED_SLOW;
1411 }
1412
1413 if (abs(analog_left[0]) > 0)
1414 {
1415 retro_mouse_x[j] = analog_left[0] * 15 * opt_analogmouse_speed / (32768 / mouse_multiplier[0]);
1416 if (retro_mouse_x[j] == 0 && abs(analog_left[0]) > analog_deadzone)
1417 retro_mouse_x[j] = (analog_left[0] > 0) ? 1 : -1;
1418 }
1419
1420 if (abs(analog_left[1]) > 0)
1421 {
1422 retro_mouse_y[j] = analog_left[1] * 15 * opt_analogmouse_speed / (32768 / mouse_multiplier[(opt_joyport_type == 2) ? 1 : 0]);
1423 if (retro_mouse_y[j] == 0 && abs(analog_left[1]) > analog_deadzone)
1424 retro_mouse_y[j] = (analog_left[1] > 0) ? 1 : -1;
1425 }
1426
1427 /* Real mouse movement */
1428 if (!retro_mouse_x[j] && !retro_mouse_y[j])
1429 {
1430 retro_mouse_x[j] = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X);
1431 retro_mouse_y[j] = input_state_cb(0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y);
1432 }
1433
1434 /* Ports 1 & 2 to VICE */
1435 for (j = 0; j < 2; j++)
1436 {
1437 retro_j = j + 1;
1438 if (!retro_mouse_l[j] && !retro_mouse_r[j] && !retro_mouse_m[j] &&
1439 !retro_mouse_x[j] && !retro_mouse_y[j])
1440 mouse_value[retro_j] = 0;
1441
1442 /* Buttons */
1443 if (retro_mouse_l[j] && !vice_mouse_l[j])
1444 {
1445 mouse_button(0, 1);
1446 mouse_value[retro_j] |= 0x10;
1447 vice_mouse_l[j] = 1;
1448 }
1449 else if (!retro_mouse_l[j] && vice_mouse_l[j])
1450 {
1451 mouse_button(0, 0);
1452 mouse_value[retro_j] &= ~0x10;
1453 vice_mouse_l[j] = 0;
1454 }
1455
1456 if (retro_mouse_r[j] && !vice_mouse_r[j])
1457 {
1458 mouse_button(1, 1);
1459 mouse_value[retro_j] |= 0x20;
1460 vice_mouse_r[j] = 1;
1461 }
1462 else if (!retro_mouse_r[j] && vice_mouse_r[j])
1463 {
1464 mouse_button(1, 0);
1465 mouse_value[retro_j] &= ~0x20;
1466 vice_mouse_r[j] = 0;
1467 }
1468
1469 if (retro_mouse_m[j] && !vice_mouse_m[j])
1470 {
1471 mouse_button(2, 1);
1472 mouse_value[retro_j] |= 0x40;
1473 vice_mouse_m[j] = 1;
1474 }
1475 else if (!retro_mouse_m[j] && vice_mouse_m[j])
1476 {
1477 mouse_button(2, 0);
1478 mouse_value[retro_j] &= ~0x40;
1479 vice_mouse_m[j] = 0;
1480 }
1481
1482 /* Movement */
1483 if (retro_mouse_x[j] || retro_mouse_y[j])
1484 {
1485 if (retro_mouse_y[j] < 0 && !(mouse_value[retro_j] & 0x01))
1486 mouse_value[retro_j] |= 0x01;
1487 if (retro_mouse_y[j] > -1 && mouse_value[retro_j] & 0x01)
1488 mouse_value[retro_j] &= ~0x01;
1489
1490 if (retro_mouse_y[j] > 0 && !(mouse_value[retro_j] & 0x02))
1491 mouse_value[retro_j] |= 0x02;
1492 if (retro_mouse_y[j] < -1 && mouse_value[retro_j] & 0x02)
1493 mouse_value[retro_j] &= ~0x02;
1494
1495 if (retro_mouse_x[j] < 0 && !(mouse_value[retro_j] & 0x04))
1496 mouse_value[retro_j] |= 0x04;
1497 if (retro_mouse_x[j] > -1 && mouse_value[retro_j] & 0x04)
1498 mouse_value[retro_j] &= ~0x04;
1499
1500 if (retro_mouse_x[j] > 0 && !(mouse_value[retro_j] & 0x08))
1501 mouse_value[retro_j] |= 0x08;
1502 if (retro_mouse_x[j] < -1 && mouse_value[retro_j] & 0x08)
1503 mouse_value[retro_j] &= ~0x08;
1504
1505 mouse_move(retro_mouse_x[j], retro_mouse_y[j]);
1506 }
1507 }
1508 }
1509 }
1510