1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * joystick/mouse emulation
5 *
6 * Copyright 2001-2012 Toni Wilen
7 *
8 * new fetures:
9 * - very configurable (and very complex to configure :)
10 * - supports multiple native input devices (joysticks and mice)
11 * - supports mapping joystick/mouse buttons to keys and vice versa
12 * - joystick mouse emulation (supports both ports)
13 * - supports parallel port joystick adapter
14 * - full cd32 pad support (supports both ports)
15 * - fully backward compatible with old joystick/mouse configuration
16 *
17 */
18
19 //#define DONGLE_DEBUG
20
21 #include "sysconfig.h"
22 #include "sysdeps.h"
23
24 #include <ctype.h>
25
26 #include "cfgfile.h"
27 #include "keyboard.h"
28 #include "inputdevice.h"
29 #include "inputrecord.h"
30 #include "keybuf.h"
31 #include "custom.h"
32 #include "xwin.h"
33 #include "drawing.h"
34 #include "memory_uae.h"
35 #include "events.h"
36 #include "newcpu.h"
37 #include "uae.h"
38 #include "picasso96.h"
39 #include "catweasel.h"
40 #include "debug.h"
41 #include "ar.h"
42 #include "gui.h"
43 #include "disk.h"
44 #include "audio.h"
45 #include "savestate.h"
46 #include "arcadia.h"
47 #include "zfile.h"
48 #include "cia.h"
49 #include "autoconf.h"
50 #include "filesys.h"
51 #ifdef RETROPLATFORM
52 #include "rp.h"
53 #endif
54 #include "dongle.h"
55 #include "cdtv.h"
56 #include "misc.h"
57
58 /* external members */
59 extern int bootrom_header, bootrom_items;
60
61 /* external functions */
62 extern void master_sound_volume (int);
63 extern void sound_mute (int);
64 extern void sound_volume (int dir);
65 extern uae_u32 uaerand (void);
66 extern TCHAR *my_strdup_trim (const TCHAR *s);
67
68 // 01 = host events
69 // 02 = joystick
70 // 04 = cia buttons
71 // 16 = potgo
72 // 32 = vsync
73
74 int inputdevice_logging = 0;
75
76 #define COMPA_RESERVED_FLAGS ID_FLAG_INVERT
77
78 #define ID_FLAG_CANRELEASE 0x1000
79 #define ID_FLAG_TOGGLED 0x2000
80 #define ID_FLAG_CUSTOMEVENT_TOGGLED1 0x4000
81 #define ID_FLAG_CUSTOMEVENT_TOGGLED2 0x8000
82
83 #define ID_FLAG_SAVE_MASK_CONFIG 0x000000ff
84 #define ID_FLAG_SAVE_MASK_QUALIFIERS ID_FLAG_QUALIFIER_MASK
85 #define ID_FLAG_SAVE_MASK_FULL (ID_FLAG_SAVE_MASK_CONFIG | ID_FLAG_SAVE_MASK_QUALIFIERS)
86
87 #define IE_INVERT 0x80
88 #define IE_CDTV 0x100
89
90 #define INPUTEVENT_JOY1_CD32_FIRST INPUTEVENT_JOY1_CD32_PLAY
91 #define INPUTEVENT_JOY2_CD32_FIRST INPUTEVENT_JOY2_CD32_PLAY
92 #define INPUTEVENT_JOY1_CD32_LAST INPUTEVENT_JOY1_CD32_BLUE
93 #define INPUTEVENT_JOY2_CD32_LAST INPUTEVENT_JOY2_CD32_BLUE
94
95 /* event masks */
96 #define AM_KEY 1 /* keyboard allowed */
97 #define AM_JOY_BUT 2 /* joystick buttons allowed */
98 #define AM_JOY_AXIS 4 /* joystick axis allowed */
99 #define AM_MOUSE_BUT 8 /* mouse buttons allowed */
100 #define AM_MOUSE_AXIS 16 /* mouse direction allowed */
101 #define AM_AF 32 /* supports autofire */
102 #define AM_INFO 64 /* information data for gui */
103 #define AM_DUMMY 128 /* placeholder */
104 #define AM_CUSTOM 256 /* custom event */
105 #define AM_K (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT|AM_AF) /* generic button/switch */
106 #define AM_KK (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT)
107
108 #define JOYMOUSE_CDTV 8
109
110 #define DEFEVENT(A, B, C, D, E, F) {_T(#A), B, C, D, E, F },
111 static struct inputevent events[] = {
112 {0, 0, AM_K,0,0,0},
113 #include "inputevents.def"
114 {0, 0, 0, 0, 0, 0}
115 };
116 #undef DEFEVENT
117
118 static int sublevdir[2][MAX_INPUT_SUB_EVENT];
119
120 static const int slotorder1[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
121 static const int slotorder2[] = { 8, 1, 2, 3, 4, 5, 6, 7 };
122
123 struct uae_input_device2 {
124 uae_u32 buttonmask;
125 int states[MAX_INPUT_DEVICE_EVENTS / 2][MAX_INPUT_SUB_EVENT + 1];
126 };
127
128 static struct uae_input_device2 joysticks2[MAX_INPUT_DEVICES];
129 static struct uae_input_device2 mice2[MAX_INPUT_DEVICES];
130 static uae_u8 scancodeused[MAX_INPUT_DEVICES][256];
131 static uae_u64 qualifiers, qualifiers_r;
132 static uae_s16 *qualifiers_evt[MAX_INPUT_QUALIFIERS];
133
134 // fire/left mouse button pullup resistors enabled?
135 static bool mouse_pullup = true;
136
137 static int joymodes[MAX_JPORTS];
138 static int *joyinputs[MAX_JPORTS];
139
140 static int input_acquired;
141 static int testmode;
142 struct teststore
143 {
144 int testmode_type;
145 int testmode_num;
146 int testmode_wtype;
147 int testmode_wnum;
148 int testmode_state;
149 int testmode_max;
150 };
151 #define TESTMODE_MAX 2
152 static int testmode_count;
153 static struct teststore testmode_data[TESTMODE_MAX];
154 static struct teststore testmode_wait[TESTMODE_MAX];
155
156 static int bouncy;
157 static unsigned long bouncy_cycles;
158
159 int handle_input_event (int nr, int state, int max, int autofire, bool canstoprecord, bool playbackevent);
160
161 static struct inputdevice_functions idev[IDTYPE_MAX];
162
isdevice(struct uae_input_device * id)163 static int isdevice (struct uae_input_device *id)
164 {
165 int i, j;
166 for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
167 for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
168 if (id->eventid[i][j] > 0)
169 return 1;
170 }
171 }
172 return 0;
173 }
174
inputdevice_uaelib(const TCHAR * s,const TCHAR * parm)175 int inputdevice_uaelib (const TCHAR *s, const TCHAR *parm)
176 {
177 int i;
178
179 for (i = 1; events[i].name; i++) {
180 if (!_tcscmp (s, events[i].confname)) {
181 handle_input_event (i, _tstol (parm), 1, 0, false, false);
182 return 1;
183 }
184 }
185 return 0;
186 }
187
188 static struct uae_input_device *joysticks;
189 static struct uae_input_device *mice;
190 static struct uae_input_device *keyboards;
191 static struct uae_input_device *internalevents;
192 static struct uae_input_device_kbr_default *keyboard_default, **keyboard_default_table;
193 static int default_keyboard_layout[MAX_JPORTS];
194
195 #define KBR_DEFAULT_MAP_FIRST 0
196 #define KBR_DEFAULT_MAP_LAST 5
197 #define KBR_DEFAULT_MAP_CD32_FIRST 6
198 #define KBR_DEFAULT_MAP_CD32_LAST 8
199
200 #define KBR_DEFAULT_MAP_NP 0
201 #define KBR_DEFAULT_MAP_CK 1
202 #define KBR_DEFAULT_MAP_SE 2
203 #define KBR_DEFAULT_MAP_NP3 3
204 #define KBR_DEFAULT_MAP_CK3 4
205 #define KBR_DEFAULT_MAP_SE3 5
206 #define KBR_DEFAULT_MAP_CD32_NP 6
207 #define KBR_DEFAULT_MAP_CD32_CK 7
208 #define KBR_DEFAULT_MAP_CD32_SE 8
209 #define KBR_DEFAULT_MAP_XA1 9
210 #define KBR_DEFAULT_MAP_XA2 10
211 #define KBR_DEFAULT_MAP_ARCADIA 11
212 #define KBR_DEFAULT_MAP_ARCADIA_XA 12
213 #define KBR_DEFAULT_MAP_CDTV 13
214 static int **keyboard_default_kbmaps;
215
216 static int mouse_axis[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
217 static int oldm_axis[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
218
219 #define MOUSE_AXIS_TOTAL 4
220
221 static uae_s16 mouse_x[MAX_JPORTS], mouse_y[MAX_JPORTS];
222 static uae_s16 mouse_delta[MAX_JPORTS][MOUSE_AXIS_TOTAL];
223 static uae_s16 mouse_deltanoreset[MAX_JPORTS][MOUSE_AXIS_TOTAL];
224 static int joybutton[MAX_JPORTS];
225 static int joydir[MAX_JPORTS];
226 static int joydirpot[MAX_JPORTS][2];
227 static uae_s16 mouse_frame_x[MAX_JPORTS], mouse_frame_y[MAX_JPORTS];
228
229 #ifdef __LIBRETRO__
230 int mouse_port[NORMAL_JPORTS];
231 #else
232 static int mouse_port[NORMAL_JPORTS];
233 #endif
234 static int cd32_shifter[NORMAL_JPORTS];
235 #ifdef __LIBRETRO__
236 int cd32_pad_enabled[NORMAL_JPORTS];
237 #else
238 static int cd32_pad_enabled[NORMAL_JPORTS];
239 #endif
240 static int parport_joystick_enabled;
241 static int oldmx[MAX_JPORTS], oldmy[MAX_JPORTS];
242 static int oleft[MAX_JPORTS], oright[MAX_JPORTS], otop[MAX_JPORTS], obot[MAX_JPORTS];
243 static int horizclear[MAX_JPORTS], vertclear[MAX_JPORTS];
244
245 uae_u16 potgo_value;
246 static int pot_cap[NORMAL_JPORTS][2];
247 static uae_u8 pot_dat[NORMAL_JPORTS][2];
248 static int pot_dat_act[NORMAL_JPORTS][2];
249 static int analog_port[NORMAL_JPORTS][2];
250 static int digital_port[NORMAL_JPORTS][2];
251 static int lightpen;
252 #define POTDAT_DELAY_PAL 8
253 #define POTDAT_DELAY_NTSC 7
254
255 static int use_joysticks[MAX_INPUT_DEVICES];
256 static int use_mice[MAX_INPUT_DEVICES];
257 static int use_keyboards[MAX_INPUT_DEVICES];
258
259 #define INPUT_QUEUE_SIZE 16
260 struct input_queue_struct {
261 int evt, storedstate, state, max, linecnt, nextlinecnt;
262 TCHAR *custom;
263 };
264 static struct input_queue_struct input_queue[INPUT_QUEUE_SIZE];
265
restore_input(uae_u8 * src)266 uae_u8 *restore_input (uae_u8 *src)
267 {
268 restore_u32 ();
269 for (int i = 0; i < 2; i++) {
270 for (int j = 0; j < 2; j++) {
271 pot_cap[i][j] = restore_u16 ();
272 }
273 }
274 return src;
275 }
save_input(int * len,uae_u8 * dstptr)276 uae_u8 *save_input (int *len, uae_u8 *dstptr)
277 {
278 uae_u8 *dstbak, *dst;
279
280 if (dstptr)
281 dstbak = dst = dstptr;
282 else
283 dstbak = dst = xmalloc (uae_u8, 1000);
284 save_u32 (0);
285 for (int i = 0; i < 2; i++) {
286 for (int j = 0; j < 2; j++) {
287 save_u16 (pot_cap[i][j]);
288 }
289 }
290 *len = dst - dstbak;
291 return dstbak;
292 }
293
freejport(struct uae_prefs * dst,int num)294 static void freejport (struct uae_prefs *dst, int num)
295 {
296 memset (&dst->jports[num], 0, sizeof (struct jport));
297 dst->jports[num].id = -1;
298 }
copyjport(const struct uae_prefs * src,struct uae_prefs * dst,int num)299 static void copyjport (const struct uae_prefs *src, struct uae_prefs *dst, int num)
300 {
301 if (!src)
302 return;
303 freejport (dst, num);
304 _tcscpy (dst->jports[num].configname, src->jports[num].configname);
305 _tcscpy (dst->jports[num].name, src->jports[num].name);
306 dst->jports[num].id = src->jports[num].id;
307 dst->jports[num].mode = src->jports[num].mode;
308 dst->jports[num].autofire = src->jports[num].autofire;
309 }
310
311 /* REMOVEME:
312 * nowhere used
313 */
314 #if 0
315 static void out_config (struct zfile *f, int id, int num, TCHAR *s1, TCHAR *s2)
316 {
317 TCHAR tmp[MAX_DPATH];
318 _stprintf (tmp, _T("input.%d.%s%d"), id, s1, num);
319 cfgfile_write_str (f, tmp, s2);
320 }
321 #endif
322
write_config_head(struct zfile * f,int idnum,int devnum,TCHAR * name,struct uae_input_device * id,struct inputdevice_functions * idf)323 static bool write_config_head (struct zfile *f, int idnum, int devnum, TCHAR *name, struct uae_input_device *id, struct inputdevice_functions *idf)
324 {
325 TCHAR tmp2[CONFIG_BLEN];
326
327 if (idnum == GAMEPORT_INPUT_SETTINGS) {
328 if (!isdevice (id))
329 return false;
330 if (!id->enabled)
331 return false;
332 }
333
334 TCHAR *s = NULL;
335 if (id->name)
336 s = id->name;
337 else if (devnum < idf->get_num ())
338 s = idf->get_friendlyname (devnum);
339 if (s) {
340 _stprintf (tmp2, _T("input.%d.%s.%d.friendlyname"), idnum + 1, name, devnum);
341 cfgfile_write_str (f, tmp2, s);
342 }
343
344 s = NULL;
345 if (id->configname)
346 s = id->configname;
347 else if (devnum < idf->get_num ())
348 s = idf->get_uniquename (devnum);
349 if (s) {
350 _stprintf (tmp2, _T("input.%d.%s.%d.name"), idnum + 1, name, devnum);
351 cfgfile_write_str (f, tmp2, s);
352 }
353
354 if (!isdevice (id)) {
355 _stprintf (tmp2, _T("input.%d.%s.%d.empty"), idnum + 1, name, devnum);
356 cfgfile_write_bool (f, tmp2, true);
357 if (id->enabled) {
358 _stprintf (tmp2, _T("input.%d.%s.%d.disabled"), idnum + 1, name, devnum);
359 cfgfile_write (f, tmp2, _T("%d"), id->enabled ? 0 : 1);
360 }
361 return false;
362 }
363
364 if (idnum == GAMEPORT_INPUT_SETTINGS) {
365 _stprintf (tmp2, _T("input.%d.%s.%d.custom"), idnum + 1, name, devnum);
366 cfgfile_write_bool (f, tmp2, true);
367 } else {
368 _stprintf (tmp2, _T("input.%d.%s.%d.empty"), idnum + 1, name, devnum);
369 cfgfile_write_bool (f, tmp2, false);
370 _stprintf (tmp2, _T("input.%d.%s.%d.disabled"), idnum + 1, name, devnum);
371 cfgfile_write_bool (f, tmp2, id->enabled ? false : true);
372 }
373 return true;
374 }
375
write_slot(TCHAR * p,struct uae_input_device * uid,int i,int j)376 static bool write_slot (TCHAR *p, struct uae_input_device *uid, int i, int j)
377 {
378 bool ok = false;
379 if (i < 0 || j < 0) {
380 _tcscpy (p, _T("NULL"));
381 return false;
382 }
383 uae_u64 flags = uid->flags[i][j];
384 if (uid->custom[i][j] && _tcslen (uid->custom[i][j]) > 0) {
385 _stprintf (p, _T("'%s'.%d"), uid->custom[i][j], flags & ID_FLAG_SAVE_MASK_CONFIG);
386 ok = true;
387 } else if (uid->eventid[i][j] > 0) {
388 _stprintf (p, _T("%s.%d"), events[uid->eventid[i][j]].confname, flags & ID_FLAG_SAVE_MASK_CONFIG);
389 ok = true;
390 } else {
391 _tcscpy (p, _T("NULL"));
392 }
393 if (ok && (flags & ID_FLAG_SAVE_MASK_QUALIFIERS)) {
394 TCHAR *p2 = p + _tcslen (p);
395 *p2++ = '.';
396 for (int i = 0; i < MAX_INPUT_QUALIFIERS * 2; i++) {
397 if ((ID_FLAG_QUALIFIER1 << i) & flags) {
398 if (i & 1)
399 _stprintf (p2, _T("%c"), 'a' + i / 2);
400 else
401 _stprintf (p2, _T("%c"), 'A' + i / 2);
402 p2++;
403 }
404 }
405 }
406 return ok;
407 }
408
409 static struct inputdevice_functions *getidf (int devnum);
410
kbrlabel(TCHAR * s)411 static void kbrlabel (TCHAR *s)
412 {
413 while (*s) {
414 *s = _totupper (*s);
415 if (*s == ' ')
416 *s = '_';
417 s++;
418 }
419 }
420
write_config2(struct zfile * f,int idnum,int i,int offset,const TCHAR * extra,struct uae_input_device * id)421 static void write_config2 (struct zfile *f, int idnum, int i, int offset, const TCHAR *extra, struct uae_input_device *id)
422 {
423 TCHAR tmp2[CONFIG_BLEN], tmp3[CONFIG_BLEN], *p;
424 /* REMOVEME:
425 * nowhere used
426 */
427 #if 0
428 int got;
429 #endif
430 int evt, j, k;
431 TCHAR *custom;
432 const int *slotorder;
433 int io = i + offset;
434
435 tmp2[0] = 0;
436 p = tmp2;
437
438 /* REMOVEME:
439 * nowhere used
440 */
441 #if 0
442 got = 0;
443 #endif
444
445 slotorder = slotorder1;
446 // if gameports non-custom mapping in slot0 -> save slot8 as slot0
447 if (id->port[io][0] && !(id->flags[io][0] & ID_FLAG_GAMEPORTSCUSTOM_MASK))
448 slotorder = slotorder2;
449
450 for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
451
452 evt = id->eventid[io][slotorder[j]];
453 custom = id->custom[io][slotorder[j]];
454 if (custom == NULL && evt <= 0) {
455 for (k = j + 1; k < MAX_INPUT_SUB_EVENT; k++) {
456 if ((id->port[io][k] == 0 || id->port[io][k] == MAX_JPORTS + 1) && (id->eventid[io][slotorder[k]] > 0 || id->custom[io][slotorder[k]] != NULL))
457 break;
458 }
459 if (k == MAX_INPUT_SUB_EVENT)
460 break;
461 }
462
463 if (p > tmp2) {
464 *p++ = ',';
465 *p = 0;
466 }
467 bool ok = write_slot (p, id, io, slotorder[j]);
468 p += _tcslen (p);
469 if (ok) {
470 if (id->port[io][slotorder[j]] > 0 && id->port[io][slotorder[j]] < MAX_JPORTS + 1) {
471 int pnum = id->port[io][slotorder[j]] - 1;
472 _stprintf (p, _T(".%d"), pnum);
473 p += _tcslen (p);
474 if (idnum != GAMEPORT_INPUT_SETTINGS && j == 0 && id->port[io][SPARE_SUB_EVENT] && slotorder == slotorder1) {
475 *p++ = '.';
476 write_slot (p, id, io, SPARE_SUB_EVENT);
477 p += _tcslen (p);
478 }
479 }
480 }
481 }
482 if (p > tmp2) {
483 _stprintf (tmp3, _T("input.%d.%s%d"), idnum + 1, extra, i);
484 cfgfile_write_str (f, tmp3, tmp2);
485 }
486 }
487
write_kbr_config(struct zfile * f,int idnum,int devnum,struct uae_input_device * kbr,struct inputdevice_functions * idf)488 static void write_kbr_config (struct zfile *f, int idnum, int devnum, struct uae_input_device *kbr, struct inputdevice_functions *idf)
489 {
490 TCHAR tmp1[CONFIG_BLEN], tmp2[CONFIG_BLEN], tmp3[CONFIG_BLEN], tmp4[CONFIG_BLEN], tmp5[CONFIG_BLEN], *p;
491 int i, j, k, evt, skip;
492 const int *slotorder;
493
494 if (!keyboard_default)
495 return;
496
497 if (!write_config_head (f, idnum, devnum, _T("keyboard"), kbr, idf))
498 return;
499
500 i = 0;
501 while (i < MAX_INPUT_DEVICE_EVENTS && kbr->extra[i] >= 0) {
502
503 slotorder = slotorder1;
504 // if gameports non-custom mapping in slot0 -> save slot4 as slot0
505 if (kbr->port[i][0] && !(kbr->flags[i][0] & ID_FLAG_GAMEPORTSCUSTOM_MASK))
506 slotorder = slotorder2;
507
508 skip = 0;
509 k = 0;
510 while (keyboard_default[k].scancode >= 0) {
511 if (keyboard_default[k].scancode == kbr->extra[i]) {
512 skip = 1;
513 for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
514 if (keyboard_default[k].node[j].evt != 0) {
515 if (keyboard_default[k].node[j].evt != kbr->eventid[i][slotorder[j]] || keyboard_default[k].node[j].flags != (kbr->flags[i][slotorder[j]] & ID_FLAG_SAVE_MASK_FULL))
516 skip = 0;
517 } else if ((kbr->flags[i][slotorder[j]] & ID_FLAG_SAVE_MASK_FULL) != 0 || kbr->eventid[i][slotorder[j]] > 0) {
518 skip = 0;
519 }
520 }
521 break;
522 }
523 k++;
524 }
525 bool isdefaultspare =
526 kbr->port[i][SPARE_SUB_EVENT] &&
527 keyboard_default[k].node[0].evt == kbr->eventid[i][SPARE_SUB_EVENT] && keyboard_default[k].node[0].flags == (kbr->flags[i][SPARE_SUB_EVENT] & ID_FLAG_SAVE_MASK_FULL);
528
529 if (kbr->port[i][0] > 0 && !(kbr->flags[i][0] & ID_FLAG_GAMEPORTSCUSTOM_MASK) &&
530 (kbr->eventid[i][1] <= 0 && kbr->eventid[i][2] <= 0 && kbr->eventid[i][3] <= 0) &&
531 (kbr->port[i][SPARE_SUB_EVENT] == 0 || isdefaultspare))
532 skip = 1;
533 if (kbr->eventid[i][0] == 0 && (kbr->flags[i][0] & ID_FLAG_SAVE_MASK_FULL) == 0 && keyboard_default[k].scancode < 0)
534 skip = 1;
535 if (skip) {
536 i++;
537 continue;
538 }
539 tmp2[0] = 0;
540 p = tmp2;
541 for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
542 TCHAR *custom = kbr->custom[i][slotorder[j]];
543 evt = kbr->eventid[i][slotorder[j]];
544 if (custom == NULL && evt <= 0) {
545 for (k = j + 1; k < MAX_INPUT_SUB_EVENT; k++) {
546 if (kbr->eventid[i][slotorder[k]] > 0 || kbr->custom[i][slotorder[k]] != NULL)
547 break;
548 }
549 if (k == MAX_INPUT_SUB_EVENT)
550 break;
551 }
552 if (p > tmp2) {
553 *p++ = ',';
554 *p = 0;
555 }
556 bool ok = write_slot (p, kbr, i, slotorder[j]);
557 p += _tcslen (p);
558 if (ok) {
559 // save port number + SPARE SLOT if needed
560 if (kbr->port[i][slotorder[j]] > 0 && (kbr->flags[i][slotorder[j]] & ID_FLAG_GAMEPORTSCUSTOM_MASK)) {
561 _stprintf (p, _T(".%d"), kbr->port[i][slotorder[j]] - 1);
562 p += _tcslen (p);
563 if (idnum != GAMEPORT_INPUT_SETTINGS && j == 0 && kbr->port[i][SPARE_SUB_EVENT] && !isdefaultspare && slotorder == slotorder1) {
564 *p++ = '.';
565 write_slot (p, kbr, i, SPARE_SUB_EVENT);
566 p += _tcslen (p);
567 }
568 }
569 }
570 }
571 idf->get_widget_type (devnum, i, tmp5, NULL);
572 _stprintf (tmp3, _T("%d%s%s"), kbr->extra[i], tmp5[0] ? _T(".") : _T(""), tmp5[0] ? tmp5 : _T(""));
573 kbrlabel (tmp3);
574 _stprintf (tmp1, _T("keyboard.%d.button.%s"), devnum, tmp3);
575 _stprintf (tmp4, _T("input.%d.%s"), idnum + 1, tmp1);
576 cfgfile_write_str (f, tmp4, tmp2[0] ? tmp2 : _T("NULL"));
577 i++;
578 }
579 }
580
write_config(struct zfile * f,int idnum,int devnum,TCHAR * name,struct uae_input_device * id,struct inputdevice_functions * idf)581 static void write_config (struct zfile *f, int idnum, int devnum, TCHAR *name, struct uae_input_device *id, struct inputdevice_functions *idf)
582 {
583 TCHAR tmp1[MAX_DPATH];
584 int i;
585
586 if (!write_config_head (f, idnum, devnum, name, id, idf))
587 return;
588
589 _stprintf (tmp1, _T("%s.%d.axis."), name, devnum);
590 for (i = 0; i < ID_AXIS_TOTAL; i++)
591 write_config2 (f, idnum, i, ID_AXIS_OFFSET, tmp1, id);
592 _stprintf (tmp1, _T("%s.%d.button.") ,name, devnum);
593 for (i = 0; i < ID_BUTTON_TOTAL; i++)
594 write_config2 (f, idnum, i, ID_BUTTON_OFFSET, tmp1, id);
595 }
596
597 static const TCHAR *kbtypes[] = { _T("amiga"), _T("pc"), NULL };
598
write_inputdevice_config(struct uae_prefs * p,struct zfile * f)599 void write_inputdevice_config (struct uae_prefs *p, struct zfile *f)
600 {
601 int i, id;
602
603 cfgfile_write (f, _T("input.config"), _T("%d"), p->input_selected_setting == GAMEPORT_INPUT_SETTINGS ? 0 : p->input_selected_setting + 1);
604 cfgfile_write (f, _T("input.joymouse_speed_analog"), _T("%d"), p->input_joymouse_multiplier);
605 cfgfile_write (f, _T("input.joymouse_speed_digital"), _T("%d"), p->input_joymouse_speed);
606 cfgfile_write (f, _T("input.joymouse_deadzone"), _T("%d"), p->input_joymouse_deadzone);
607 cfgfile_write (f, _T("input.joystick_deadzone"), _T("%d"), p->input_joystick_deadzone);
608 cfgfile_write (f, _T("input.analog_joystick_multiplier"), _T("%d"), p->input_analog_joystick_mult);
609 cfgfile_write (f, _T("input.analog_joystick_offset"), _T("%d"), p->input_analog_joystick_offset);
610 cfgfile_write (f, _T("input.mouse_speed"), _T("%d"), p->input_mouse_speed);
611 cfgfile_write (f, _T("input.autofire_speed"), _T("%d"), p->input_autofire_linecnt);
612 cfgfile_dwrite_str (f, _T("input.keyboard_type"), kbtypes[p->input_keyboard_type]);
613 cfgfile_dwrite (f, _T("input.contact_bounce"), _T("%d"), p->input_contact_bounce);
614 for (id = 0; id < MAX_INPUT_SETTINGS; id++) {
615 TCHAR tmp[MAX_DPATH];
616 if (id < GAMEPORT_INPUT_SETTINGS) {
617 _stprintf (tmp, _T("input.%d.name"), id + 1);
618 cfgfile_dwrite_str (f, tmp, p->input_config_name[id]);
619 }
620 for (i = 0; i < MAX_INPUT_DEVICES; i++)
621 write_config (f, id, i, _T("joystick"), &p->joystick_settings[id][i], &idev[IDTYPE_JOYSTICK]);
622 for (i = 0; i < MAX_INPUT_DEVICES; i++)
623 write_config (f, id, i, _T("mouse"), &p->mouse_settings[id][i], &idev[IDTYPE_MOUSE]);
624 for (i = 0; i < MAX_INPUT_DEVICES; i++)
625 write_kbr_config (f, id, i, &p->keyboard_settings[id][i], &idev[IDTYPE_KEYBOARD]);
626 write_config (f, id, 0, _T("internal"), &p->internalevent_settings[id][0], &idev[IDTYPE_INTERNALEVENT]);
627 }
628 }
629
getqual(const TCHAR ** pp)630 static uae_u64 getqual (const TCHAR **pp)
631 {
632 const TCHAR *p = *pp;
633 uae_u64 mask = 0;
634
635 while ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')) {
636 bool press = (*p >= 'A' && *p <= 'Z');
637 int shift, inc;
638
639 if (press) {
640 shift = *p - 'A';
641 inc = 0;
642 } else {
643 shift = *p - 'a';
644 inc = 1;
645 }
646 mask |= ID_FLAG_QUALIFIER1 << (shift * 2 + inc);
647 p++;
648 }
649 while (*p != 0 && *p !='.' && *p != ',')
650 p++;
651 if (*p == '.' || *p == ',')
652 p++;
653 *pp = p;
654 return mask;
655 }
656
getnum(const TCHAR ** pp)657 static int getnum (const TCHAR **pp)
658 {
659 const TCHAR *p = *pp;
660 int v;
661
662 if (!_tcsnicmp (p, _T("false"), 5))
663 v = 0;
664 if (!_tcsnicmp (p, _T("true"), 4))
665 v = 1;
666 else
667 v = _tstol (p);
668
669 while (*p != 0 && *p !='.' && *p != ',')
670 p++;
671 if (*p == '.' || *p == ',')
672 p++;
673 *pp = p;
674 return v;
675 }
getstring(const TCHAR ** pp)676 static TCHAR *getstring (const TCHAR **pp)
677 {
678 int i;
679 static TCHAR str[CONFIG_BLEN];
680 const TCHAR *p = *pp;
681 bool quoteds = false;
682 bool quotedd = false;
683
684 if (*p == 0)
685 return 0;
686 i = 0;
687 while (*p != 0 && i < 1000 - 1) {
688 if (*p == '\"')
689 quotedd = quotedd ? false : true;
690 if (*p == '\'')
691 quoteds = quoteds ? false : true;
692 if (!quotedd && !quoteds) {
693 if (*p == '.' || *p == ',')
694 break;
695 }
696 str[i++] = *p++;
697 }
698 if (*p == '.' || *p == ',')
699 p++;
700 str[i] = 0;
701 *pp = p;
702 return str;
703 }
704
reset_inputdevice_settings(struct uae_input_device * uid)705 static void reset_inputdevice_settings (struct uae_input_device *uid)
706 {
707 for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
708 for (int i = 0; i < MAX_INPUT_SUB_EVENT_ALL; i++) {
709 uid->eventid[l][i] = 0;
710 uid->flags[l][i] = 0;
711 xfree (uid->custom[l][i]);
712 uid->custom[l][i] = NULL;
713 }
714 }
715 }
reset_inputdevice_slot(struct uae_prefs * prefs,int slot)716 static void reset_inputdevice_slot (struct uae_prefs *prefs, int slot)
717 {
718 for (int m = 0; m < MAX_INPUT_DEVICES; m++) {
719 reset_inputdevice_settings (&prefs->joystick_settings[slot][m]);
720 reset_inputdevice_settings (&prefs->mouse_settings[slot][m]);
721 reset_inputdevice_settings (&prefs->keyboard_settings[slot][m]);
722 }
723 }
reset_inputdevice_config(struct uae_prefs * prefs)724 void reset_inputdevice_config (struct uae_prefs *prefs)
725 {
726 for (int i = 0; i< MAX_INPUT_SETTINGS; i++)
727 reset_inputdevice_slot (prefs, i);
728 }
729
730
set_kbr_default_event(struct uae_input_device * kbr,struct uae_input_device_kbr_default * trans,int num)731 static void set_kbr_default_event (struct uae_input_device *kbr, struct uae_input_device_kbr_default *trans, int num)
732 {
733 for (int i = 0; trans[i].scancode >= 0; i++) {
734 if (kbr->extra[num] == trans[i].scancode) {
735 int k;
736 for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
737 if (kbr->eventid[num][k] == 0)
738 break;
739 }
740 if (k == MAX_INPUT_SUB_EVENT) {
741 write_log (_T("corrupt default keyboard mappings\n"));
742 return;
743 }
744 int l = 0;
745 while (k < MAX_INPUT_SUB_EVENT && trans[i].node[l].evt) {
746 int evt = trans[i].node[l].evt;
747 if (evt < 0 || evt >= INPUTEVENT_SPC_LAST)
748 gui_message(_T("invalid event in default keyboard table!"));
749 kbr->eventid[num][k] = evt;
750 kbr->flags[num][k] = trans[i].node[l].flags;
751 l++;
752 k++;
753 }
754 break;
755 }
756 }
757 }
758
clear_id(struct uae_input_device * id)759 static void clear_id (struct uae_input_device *id)
760 {
761 #ifndef _DEBUG
762 int i, j;
763 for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
764 for (j = 0; j < MAX_INPUT_SUB_EVENT_ALL; j++)
765 xfree (id->custom[i][j]);
766 }
767 #endif
768 TCHAR *cn = id->configname;
769 TCHAR *n = id->name;
770 memset (id, 0, sizeof (struct uae_input_device));
771 id->configname = cn;
772 id->name = n;
773 }
774
set_kbr_default(struct uae_prefs * p,int index,int devnum,struct uae_input_device_kbr_default * trans)775 static void set_kbr_default (struct uae_prefs *p, int index, int devnum, struct uae_input_device_kbr_default *trans)
776 {
777 int i, j;
778 struct uae_input_device *kbr;
779 struct inputdevice_functions *id = &idev[IDTYPE_KEYBOARD];
780 uae_u32 scancode;
781
782 if (!trans)
783 return;
784 for (j = 0; j < MAX_INPUT_DEVICES; j++) {
785 if (devnum >= 0 && devnum != j)
786 continue;
787 kbr = &p->keyboard_settings[index][j];
788 for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
789 clear_id (kbr);
790 kbr->extra[i] = -1;
791 }
792 if (j < id->get_num ()) {
793 if (input_get_default_keyboard (j))
794 kbr->enabled = 1;
795 for (i = 0; i < id->get_widget_num (j); i++) {
796 id->get_widget_type (j, i, 0, &scancode);
797 kbr->extra[i] = scancode;
798 set_kbr_default_event (kbr, trans, i);
799 }
800 }
801 }
802 }
803
inputdevice_default_kb(struct uae_prefs * p,int num)804 static void inputdevice_default_kb (struct uae_prefs *p, int num)
805 {
806 if (num == GAMEPORT_INPUT_SETTINGS) {
807 if (p->jports[0].id != JPORT_CUSTOM || p->jports[1].id != JPORT_CUSTOM)
808 reset_inputdevice_slot (p, num);
809 }
810 set_kbr_default (p, num, -1, keyboard_default);
811 }
inputdevice_default_kb_all(struct uae_prefs * p)812 static void inputdevice_default_kb_all (struct uae_prefs *p)
813 {
814 for (int i = 0; i < MAX_INPUT_SETTINGS; i++)
815 inputdevice_default_kb (p, i);
816 }
817
read_slot(const TCHAR * parm,int num,int joystick,int button,struct uae_input_device * id,int keynum,int subnum,struct inputevent * ie,uae_u64 flags,int port,TCHAR * custom)818 static bool read_slot (const TCHAR *parm, int num, int joystick, int button, struct uae_input_device *id, int keynum, int subnum, struct inputevent *ie, uae_u64 flags, int port, TCHAR *custom)
819 {
820 int mask;
821
822 if (custom == NULL && ie->name == NULL) {
823 if (!_tcscmp (parm, _T("NULL"))) {
824 if (joystick < 0) {
825 id->eventid[keynum][subnum] = 0;
826 id->flags[keynum][subnum] = 0;
827 } else if (button) {
828 id->eventid[num + ID_BUTTON_OFFSET][subnum] = 0;
829 id->flags[num + ID_BUTTON_OFFSET][subnum] = 0;
830 } else {
831 id->eventid[num + ID_AXIS_OFFSET][subnum] = 0;
832 id->flags[num + ID_AXIS_OFFSET][subnum] = 0;
833 }
834 }
835 return false;
836 }
837 if (custom)
838 ie = &events[INPUTEVENT_SPC_CUSTOM_EVENT];
839
840 if (joystick < 0) {
841 if (!(ie->allow_mask & AM_K))
842 return false;
843 id->eventid[keynum][subnum] = ie - events;
844 id->flags[keynum][subnum] = flags;
845 id->port[keynum][subnum] = port;
846 xfree (id->custom[keynum][subnum]);
847 id->custom[keynum][subnum] = custom;
848 } else if (button) {
849 if (joystick)
850 mask = AM_JOY_BUT;
851 else
852 mask = AM_MOUSE_BUT;
853 if (!(ie->allow_mask & mask))
854 return false;
855 id->eventid[num + ID_BUTTON_OFFSET][subnum] = ie - events;
856 id->flags[num + ID_BUTTON_OFFSET][subnum] = flags;
857 id->port[num + ID_BUTTON_OFFSET][subnum] = port;
858 xfree (id->custom[num + ID_BUTTON_OFFSET][subnum]);
859 id->custom[num + ID_BUTTON_OFFSET][subnum] = custom;
860 } else {
861 if (joystick)
862 mask = AM_JOY_AXIS;
863 else
864 mask = AM_MOUSE_AXIS;
865 if (!(ie->allow_mask & mask))
866 return false;
867 id->eventid[num + ID_AXIS_OFFSET][subnum] = ie - events;
868 id->flags[num + ID_AXIS_OFFSET][subnum] = flags;
869 id->port[num + ID_AXIS_OFFSET][subnum] = port;
870 xfree (id->custom[num + ID_AXIS_OFFSET][subnum]);
871 id->custom[num + ID_AXIS_OFFSET][subnum] = custom;
872 }
873 return true;
874 }
875
readevent(const TCHAR * name,TCHAR ** customp)876 static struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
877 {
878 int i = 1;
879 while (events[i].name) {
880 if (!_tcscmp (events[i].confname, name))
881 return &events[i];
882 i++;
883 }
884 if (_tcslen (name) > 2 && name[0] == '\'' && name[_tcslen (name) - 1] == '\'') {
885 TCHAR *custom = my_strdup (name + 1);
886 custom[_tcslen (custom) - 1] = 0;
887 *customp = custom;
888 }
889 return &events[0];
890 }
891
read_inputdevice_config(struct uae_prefs * pr,const TCHAR * option,TCHAR * value)892 void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *value)
893 {
894 struct uae_input_device *id = 0;
895 struct inputevent *ie;
896 int devnum, num, button, joystick, subnum, idnum, keynum;
897 const TCHAR *p;
898 TCHAR *p2, *custom;
899
900 option += 6; /* "input." */
901 p = getstring (&option);
902 if (!strcasecmp (p, _T("config"))) {
903 pr->input_selected_setting = _tstol (value) - 1;
904 if (pr->input_selected_setting == -1)
905 pr->input_selected_setting = GAMEPORT_INPUT_SETTINGS;
906 if (pr->input_selected_setting < 0 || pr->input_selected_setting > MAX_INPUT_SETTINGS)
907 pr->input_selected_setting = 0;
908 }
909 if (!strcasecmp (p, _T("joymouse_speed_analog")))
910 pr->input_joymouse_multiplier = _tstol (value);
911 if (!strcasecmp (p, _T("joymouse_speed_digital")))
912 pr->input_joymouse_speed = _tstol (value);
913 if (!strcasecmp (p, _T("joystick_deadzone")))
914 pr->input_joystick_deadzone = _tstol (value);
915 if (!strcasecmp (p, _T("joymouse_deadzone")))
916 pr->input_joymouse_deadzone = _tstol (value);
917 if (!strcasecmp (p, _T("mouse_speed")))
918 pr->input_mouse_speed = _tstol (value);
919 if (!strcasecmp (p, _T("autofire_speed")))
920 pr->input_autofire_linecnt = _tstol (value);
921 if (!strcasecmp (p, _T("analog_joystick_multiplier")))
922 pr->input_analog_joystick_mult = _tstol (value);
923 if (!strcasecmp (p, _T("analog_joystick_offset")))
924 pr->input_analog_joystick_offset = _tstol (value);
925 if (!strcasecmp (p, _T("keyboard_type"))) {
926 cfgfile_strval (option, value, NULL, &pr->input_analog_joystick_offset, kbtypes, 0);
927 keyboard_default = keyboard_default_table[pr->input_keyboard_type];
928 inputdevice_default_kb_all (pr);
929 }
930
931 if (!strcasecmp (p, _T("contact_bounce")))
932 pr->input_contact_bounce = _tstol (value);
933
934 idnum = _tstol (p);
935 if (idnum <= 0 || idnum > MAX_INPUT_SETTINGS)
936 return;
937 idnum--;
938
939 if (!_tcscmp (option, _T("name"))) {
940 if (idnum < GAMEPORT_INPUT_SETTINGS)
941 _tcscpy (pr->input_config_name[idnum], value);
942 return;
943 }
944
945 if (_tcsncmp (option, _T("mouse."), 6) == 0) {
946 p = option + 6;
947 } else if (_tcsncmp (option, _T("joystick."), 9) == 0) {
948 p = option + 9;
949 } else if (_tcsncmp (option, _T("keyboard."), 9) == 0) {
950 p = option + 9;
951 } else if (_tcsncmp (option, _T("internal."), 9) == 0) {
952 p = option + 9;
953 } else
954 return;
955
956 devnum = getnum (&p);
957 if (devnum < 0 || devnum >= MAX_INPUT_DEVICES)
958 return;
959
960 p2 = getstring (&p);
961 if (!p2)
962 return;
963
964 if (_tcsncmp (option, _T("mouse."), 6) == 0) {
965 id = &pr->mouse_settings[idnum][devnum];
966 joystick = 0;
967 } else if (_tcsncmp (option, _T("joystick."), 9) == 0) {
968 id = &pr->joystick_settings[idnum][devnum];
969 joystick = 1;
970 } else if (_tcsncmp (option, _T("keyboard."), 9) == 0) {
971 id = &pr->keyboard_settings[idnum][devnum];
972 joystick = -1;
973 } else if (_tcsncmp (option, _T("internal."), 9) == 0) {
974 if (devnum > 0)
975 return;
976 id = &pr->internalevent_settings[idnum][devnum];
977 joystick = 1;
978 }
979 if (!id)
980 return;
981
982 if (!_tcscmp (p2, _T("name"))) {
983 xfree (id->configname);
984 id->configname = my_strdup (value);
985 return;
986 }
987 if (!_tcscmp (p2, _T("friendlyname"))) {
988 xfree (id->name);
989 id->name = my_strdup (value);
990 return;
991 }
992
993 if (!_tcscmp (p2, _T("custom"))) {
994 int iscustom;
995 p = value;
996 iscustom = getnum (&p);
997 if (idnum == GAMEPORT_INPUT_SETTINGS) {
998 clear_id (id);
999 if (joystick < 0)
1000 set_kbr_default (pr, idnum, devnum, keyboard_default);
1001 id->enabled = iscustom;
1002 } else {
1003 id->enabled = false;
1004 }
1005 return;
1006 }
1007
1008 if (!_tcscmp (p2, _T("empty"))) {
1009 int empty;
1010 p = value;
1011 empty = getnum (&p);
1012 clear_id (id);
1013 if (!empty) {
1014 if (joystick < 0)
1015 set_kbr_default (pr, idnum, devnum, keyboard_default);
1016 }
1017 id->enabled = 1;
1018 if (idnum == GAMEPORT_INPUT_SETTINGS)
1019 id->enabled = 0;
1020 return;
1021 }
1022
1023 if (!_tcscmp (p2, _T("disabled"))) {
1024 int disabled;
1025 p = value;
1026 disabled = getnum (&p);
1027 id->enabled = disabled == 0 ? 1 : 0;
1028 if (idnum == GAMEPORT_INPUT_SETTINGS)
1029 id->enabled = 0;
1030 return;
1031 }
1032
1033 if (idnum == GAMEPORT_INPUT_SETTINGS && id->enabled == 0)
1034 return;
1035
1036 button = 0;
1037 keynum = 0;
1038 if (joystick < 0) {
1039 num = getnum (&p);
1040 for (keynum = 0; keynum < MAX_INPUT_DEVICE_EVENTS; keynum++) {
1041 if (id->extra[keynum] == num)
1042 break;
1043 }
1044 if (keynum >= MAX_INPUT_DEVICE_EVENTS)
1045 return;
1046 } else {
1047 button = -1;
1048 if (!_tcscmp (p2, _T("axis")))
1049 button = 0;
1050 else if(!_tcscmp (p2, _T("button")))
1051 button = 1;
1052 if (button < 0)
1053 return;
1054 num = getnum (&p);
1055 }
1056 p = value;
1057
1058 custom = NULL;
1059 for (subnum = 0; subnum < MAX_INPUT_SUB_EVENT; subnum++) {
1060 uae_u64 flags;
1061 int port;
1062 xfree (custom);
1063 custom = NULL;
1064 p2 = getstring (&p);
1065 if (!p2)
1066 break;
1067 ie = readevent (p2, &custom);
1068 flags = 0;
1069 port = 0;
1070 if (p[-1] == '.')
1071 flags = getnum (&p) & ID_FLAG_SAVE_MASK_CONFIG;
1072 if (p[-1] == '.') {
1073 if ((p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z'))
1074 flags |= getqual (&p);
1075 if (p[-1] == '.')
1076 port = getnum (&p) + 1;
1077 }
1078 if (idnum == GAMEPORT_INPUT_SETTINGS && port == 0)
1079 continue;
1080 if (p[-1] == '.' && idnum != GAMEPORT_INPUT_SETTINGS) {
1081 p2 = getstring (&p);
1082 if (p2) {
1083 int flags2 = 0;
1084 if (p[-1] == '.')
1085 flags2 = getnum (&p) & ID_FLAG_SAVE_MASK_CONFIG;
1086 if (p[-1] == '.' && ( (p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z') ) )
1087 flags |= getqual (&p);
1088 TCHAR *custom2 = NULL;
1089 struct inputevent *ie2 = readevent (p2, &custom2);
1090 read_slot (p2, num, joystick, button, id, keynum, SPARE_SUB_EVENT, ie2, flags2, MAX_JPORTS + 1, custom2);
1091 }
1092 }
1093
1094 while (*p != 0) {
1095 if (p[-1] == ',')
1096 break;
1097 p++;
1098 }
1099 if (!read_slot (p2, num, joystick, button, id, keynum, subnum, ie, flags, port, custom))
1100 continue;
1101 custom = NULL;
1102 }
1103 xfree (custom);
1104 }
1105
1106 static int mouseedge_alive, mousehack_alive_cnt;
1107 static int lastmx, lastmy;
1108 static uaecptr magicmouse_ibase, magicmouse_gfxbase;
1109 static int dimensioninfo_width, dimensioninfo_height, dimensioninfo_dbl;
1110 static int vp_xoffset, vp_yoffset, mouseoffset_x, mouseoffset_y;
1111 static int tablet_maxx, tablet_maxy, tablet_data;
1112
mousehack_alive(void)1113 int mousehack_alive (void)
1114 {
1115 return mousehack_alive_cnt > 0 ? mousehack_alive_cnt : 0;
1116 }
1117
get_base(const uae_char * name)1118 static uaecptr get_base (const uae_char *name)
1119 {
1120 uaecptr v = get_long (4);
1121 addrbank *b = &get_mem_bank(v);
1122
1123 if (!b || !b->check (v, 400) || b->flags != ABFLAG_RAM)
1124 return 0;
1125 v += 378; // liblist
1126 while ( (v = get_long (v)) ) {
1127 uae_u32 v2;
1128 uae_u8 *p;
1129 b = &get_mem_bank (v);
1130 if (!b || !b->check (v, 32) || b->flags != ABFLAG_RAM)
1131 goto fail;
1132 v2 = get_long (v + 10); // name
1133 b = &get_mem_bank (v2);
1134 if (!b || !b->check (v2, 20))
1135 goto fail;
1136 if (b->flags != ABFLAG_ROM && b->flags != ABFLAG_RAM)
1137 return 0;
1138 p = b->xlateaddr (v2);
1139 if (!memcmp (p, name, strlen (name) + 1)) {
1140 TCHAR *s = au (name);
1141 write_log (_T("get_base('%s')=%08x\n"), s, v);
1142 xfree (s);
1143 return v;
1144 }
1145 }
1146 return 0;
1147 fail:
1148 {
1149 TCHAR *s = au (name);
1150 write_log (_T("get_base('%s') failed, invalid library list\n"), s);
1151 xfree (s);
1152 }
1153 return 0xffffffff;
1154 }
1155
get_intuitionbase(void)1156 static uaecptr get_intuitionbase (void)
1157 {
1158 if (magicmouse_ibase == 0xffffffff)
1159 return 0;
1160 if (magicmouse_ibase)
1161 return magicmouse_ibase;
1162 magicmouse_ibase = get_base ("intuition.library");
1163 return magicmouse_ibase;
1164 }
1165
1166 /// REMOVEME: only use in inputdevice_mh_abs_v36() which is marked "#if 0"
1167 #if 0
1168 static uaecptr get_gfxbase (void)
1169 {
1170 if (magicmouse_gfxbase == 0xffffffff)
1171 return 0;
1172 if (magicmouse_gfxbase)
1173 return magicmouse_gfxbase;
1174 magicmouse_gfxbase = get_base ("graphics.library");
1175 return magicmouse_gfxbase;
1176 }
1177 #endif // 0
1178
1179 #define MH_E 0
1180 #define MH_CNT 2
1181 #define MH_MAXX 4
1182 #define MH_MAXY 6
1183 #define MH_MAXZ 8
1184 #define MH_X 10
1185 #define MH_Y 12
1186 #define MH_Z 14
1187 #define MH_RESX 16
1188 #define MH_RESY 18
1189 #define MH_MAXAX 20
1190 #define MH_MAXAY 22
1191 #define MH_MAXAZ 24
1192 #define MH_AX 26
1193 #define MH_AY 28
1194 #define MH_AZ 30
1195 #define MH_PRESSURE 32
1196 #define MH_BUTTONBITS 34
1197 #define MH_INPROXIMITY 38
1198 #define MH_ABSX 40
1199 #define MH_ABSY 42
1200
1201 #define MH_END 44
1202 #define MH_START 4
1203
inputdevice_is_tablet(void)1204 int inputdevice_is_tablet (void)
1205 {
1206 /* REMOVEME:
1207 * nowhere used
1208 */
1209 #if 0
1210 int v;
1211 #endif
1212 if (!uae_boot_rom)
1213 return 0;
1214 if (currprefs.input_tablet == TABLET_OFF)
1215 return 0;
1216 if (currprefs.input_tablet == TABLET_MOUSEHACK)
1217 return -1;
1218 return 0;
1219 }
1220
1221 static uaecptr mousehack_address;
1222 static bool mousehack_enabled;
1223
mousehack_reset(void)1224 static void mousehack_reset (void)
1225 {
1226 dimensioninfo_width = dimensioninfo_height = 0;
1227 mouseoffset_x = mouseoffset_y = 0;
1228 dimensioninfo_dbl = 0;
1229 mousehack_alive_cnt = 0;
1230 vp_xoffset = vp_yoffset = 0;
1231 tablet_data = 0;
1232 if (mousehack_address)
1233 put_byte (mousehack_address + MH_E, 0);
1234 mousehack_address = 0;
1235 mousehack_enabled = false;
1236 }
1237
mousehack_enable(void)1238 static bool mousehack_enable (void)
1239 {
1240 #ifdef FILESYS /* Internal mousehack depends on filesys boot-rom */
1241 int mode;
1242
1243 if (!uae_boot_rom || currprefs.input_tablet == TABLET_OFF)
1244 return false;
1245 if (mousehack_address && mousehack_enabled)
1246 return true;
1247 mode = 0x80;
1248 if (currprefs.input_tablet == TABLET_MOUSEHACK)
1249 mode |= 1;
1250 if (inputdevice_is_tablet () > 0)
1251 mode |= 2;
1252 if (mousehack_address) {
1253 write_log (_T("Mouse driver enabled (%s)\n"), ((mode & 3) == 3 ? _T("tablet+mousehack") : ((mode & 3) == 2) ? _T("tablet") : _T("mousehack")));
1254 put_byte (mousehack_address + MH_E, mode);
1255 mousehack_enabled = true;
1256 }
1257 return true;
1258 #endif
1259 }
1260
input_mousehack_mouseoffset(uaecptr pointerprefs)1261 void input_mousehack_mouseoffset (uaecptr pointerprefs)
1262 {
1263 mouseoffset_x = (uae_s16)get_word (pointerprefs + 28);
1264 mouseoffset_y = (uae_s16)get_word (pointerprefs + 30);
1265 }
1266
input_mousehack_status(int mode,uaecptr diminfo,uaecptr dispinfo,uaecptr vp,uae_u32 moffset)1267 int input_mousehack_status (int mode, uaecptr diminfo, uaecptr dispinfo, uaecptr vp, uae_u32 moffset)
1268 {
1269 if (mode == 4) {
1270 return mousehack_enable () ? 1 : 0;
1271 } else if (mode == 5) {
1272 mousehack_address = m68k_dreg (regs, 0);
1273 mousehack_enable ();
1274 } else if (mode == 0) {
1275 if (mousehack_address) {
1276 uae_u8 v = get_byte (mousehack_address + MH_E);
1277 v |= 0x40;
1278 put_byte (mousehack_address + MH_E, v);
1279 write_log (_T("Tablet driver running (%08x,%02x)\n"), mousehack_address, v);
1280 }
1281 } else if (mode == 1) {
1282 int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
1283 uae_u32 props = 0;
1284 dimensioninfo_width = -1;
1285 dimensioninfo_height = -1;
1286 vp_xoffset = 0;
1287 vp_yoffset = 0;
1288 if (diminfo) {
1289 x1 = get_word (diminfo + 50);
1290 y1 = get_word (diminfo + 52);
1291 x2 = get_word (diminfo + 54);
1292 y2 = get_word (diminfo + 56);
1293 dimensioninfo_width = x2 - x1 + 1;
1294 dimensioninfo_height = y2 - y1 + 1;
1295 }
1296 if (vp) {
1297 vp_xoffset = get_word (vp + 28);
1298 vp_yoffset = get_word (vp + 30);
1299 }
1300 if (dispinfo)
1301 props = get_long (dispinfo + 18);
1302 dimensioninfo_dbl = (props & 0x00020000) ? 1 : 0;
1303 write_log (_T("%08x %08x %08x (%dx%d)-(%dx%d) d=%dx%d %s\n"),
1304 diminfo, props, vp, x1, y1, x2, y2, vp_xoffset, vp_yoffset,
1305 (props & 0x00020000) ? _T("dbl") : _T(""));
1306 } else if (mode == 2) {
1307 if (mousehack_alive_cnt == 0)
1308 mousehack_alive_cnt = -100;
1309 else if (mousehack_alive_cnt > 0)
1310 mousehack_alive_cnt = 100;
1311 }
1312 return 1;
1313 }
1314
1315 void get_custom_mouse_limits (int *w, int *h, int *dx, int *dy, int dbl);
1316
inputdevice_tablet_strobe(void)1317 void inputdevice_tablet_strobe (void)
1318 {
1319 mousehack_enable ();
1320 if (!uae_boot_rom)
1321 return;
1322 if (!tablet_data)
1323 return;
1324 if (mousehack_address)
1325 put_byte (mousehack_address + MH_CNT, get_byte (mousehack_address + MH_CNT) + 1);
1326 }
1327
inputdevice_tablet(int x,int y,int z,int pressure,uae_u32 buttonbits,int inproximity,int ax,int ay,int az)1328 void inputdevice_tablet (int x, int y, int z, int pressure, uae_u32 buttonbits, int inproximity, int ax, int ay, int az)
1329 {
1330 uae_u8 *p;
1331 uae_u8 tmp[MH_END];
1332
1333 mousehack_enable ();
1334 if (inputdevice_is_tablet () <= 0 || !mousehack_address)
1335 return;
1336 //write_log (_T("%d %d %d %d %08X %d %d %d %d\n"), x, y, z, pressure, buttonbits, inproximity, ax, ay, az);
1337 p = get_real_address (mousehack_address);
1338
1339 memcpy (tmp, p + MH_START, MH_END - MH_START);
1340 #if 0
1341 if (currprefs.input_magic_mouse) {
1342 int maxx, maxy, diffx, diffy;
1343 int dw, dh, ax, ay, aw, ah;
1344 float xmult, ymult;
1345 float fx, fy;
1346
1347 fx = (float)x;
1348 fy = (float)y;
1349 desktop_coords (&dw, &dh, &ax, &ay, &aw, &ah);
1350 xmult = (float)tablet_maxx / dw;
1351 ymult = (float)tablet_maxy / dh;
1352
1353 diffx = 0;
1354 diffy = 0;
1355 if (picasso_on) {
1356 maxx = gfxvidinfo.width;
1357 maxy = gfxvidinfo.height;
1358 } else {
1359 get_custom_mouse_limits (&maxx, &maxy, &diffx, &diffy);
1360 }
1361 diffx += ax;
1362 diffy += ah;
1363
1364 fx -= diffx * xmult;
1365 if (fx < 0)
1366 fx = 0;
1367 if (fx >= aw * xmult)
1368 fx = aw * xmult - 1;
1369 fy -= diffy * ymult;
1370 if (fy < 0)
1371 fy = 0;
1372 if (fy >= ah * ymult)
1373 fy = ah * ymult - 1;
1374
1375 x = (int)(fx * (aw * xmult) / tablet_maxx + 0.5);
1376 y = (int)(fy * (ah * ymult) / tablet_maxy + 0.5);
1377
1378 }
1379 #endif
1380 p[MH_X] = x >> 8;
1381 p[MH_X + 1] = x;
1382 p[MH_Y] = y >> 8;
1383 p[MH_Y + 1] = y;
1384 p[MH_Z] = z >> 8;
1385 p[MH_Z + 1] = z;
1386
1387 p[MH_AX] = ax >> 8;
1388 p[MH_AX + 1] = ax;
1389 p[MH_AY] = ay >> 8;
1390 p[MH_AY + 1] = ay;
1391 p[MH_AZ] = az >> 8;
1392 p[MH_AZ + 1] = az;
1393
1394 p[MH_MAXX] = tablet_maxx >> 8;
1395 p[MH_MAXX + 1] = tablet_maxx;
1396 p[MH_MAXY] = tablet_maxy >> 8;
1397 p[MH_MAXY + 1] = tablet_maxy;
1398
1399 p[MH_PRESSURE] = pressure >> 8;
1400 p[MH_PRESSURE + 1] = pressure;
1401
1402 p[MH_BUTTONBITS + 0] = buttonbits >> 24;
1403 p[MH_BUTTONBITS + 1] = buttonbits >> 16;
1404 p[MH_BUTTONBITS + 2] = buttonbits >> 8;
1405 p[MH_BUTTONBITS + 3] = buttonbits >> 0;
1406
1407 if (inproximity < 0) {
1408 p[MH_INPROXIMITY] = p[MH_INPROXIMITY + 1] = 0xff;
1409 } else {
1410 p[MH_INPROXIMITY] = 0;
1411 p[MH_INPROXIMITY + 1] = inproximity ? 1 : 0;
1412 }
1413
1414 if (!memcmp (tmp, p + MH_START, MH_END - MH_START))
1415 return;
1416
1417 p[MH_E] = 0xc0 | 2;
1418 p[MH_CNT]++;
1419 }
1420
inputdevice_tablet_info(int maxx,int maxy,int maxz,int maxax,int maxay,int maxaz,int xres,int yres)1421 void inputdevice_tablet_info (int maxx, int maxy, int maxz, int maxax, int maxay, int maxaz, int xres, int yres)
1422 {
1423 uae_u8 *p;
1424
1425 if (!uae_boot_rom || !mousehack_address)
1426 return;
1427 p = get_real_address (mousehack_address);
1428
1429 tablet_maxx = maxx;
1430 tablet_maxy = maxy;
1431 p[MH_MAXX] = maxx >> 8;
1432 p[MH_MAXX + 1] = maxx;
1433 p[MH_MAXY] = maxy >> 8;
1434 p[MH_MAXY + 1] = maxy;
1435 p[MH_MAXZ] = maxz >> 8;
1436 p[MH_MAXZ + 1] = maxz;
1437
1438 p[MH_RESX] = xres >> 8;
1439 p[MH_RESX + 1] = xres;
1440 p[MH_RESY] = yres >> 8;
1441 p[MH_RESY + 1] = yres;
1442
1443 p[MH_MAXAX] = maxax >> 8;
1444 p[MH_MAXAX + 1] = maxax;
1445 p[MH_MAXAY] = maxay >> 8;
1446 p[MH_MAXAY + 1] = maxay;
1447 p[MH_MAXAZ] = maxaz >> 8;
1448 p[MH_MAXAZ + 1] = maxaz;
1449 }
1450
1451
inputdevice_mh_abs(int x,int y,uae_u32 buttonbits)1452 static void inputdevice_mh_abs (int x, int y, uae_u32 buttonbits)
1453 {
1454 uae_u8 *p;
1455 uae_u8 tmp1[4], tmp2[4];
1456
1457 mousehack_enable ();
1458 if (!mousehack_address)
1459 return;
1460 p = get_real_address (mousehack_address);
1461
1462 memcpy (tmp1, p + MH_ABSX, sizeof tmp1);
1463 memcpy (tmp2, p + MH_BUTTONBITS, sizeof tmp2);
1464
1465 x -= mouseoffset_x + 1;
1466 y -= mouseoffset_y + 2;
1467
1468 //write_log (_T("%dx%d %08x\n"), x, y, buttonbits);
1469
1470 p[MH_ABSX] = x >> 8;
1471 p[MH_ABSX + 1] = x;
1472 p[MH_ABSY] = y >> 8;
1473 p[MH_ABSY + 1] = y;
1474
1475 p[MH_BUTTONBITS + 0] = buttonbits >> 24;
1476 p[MH_BUTTONBITS + 1] = buttonbits >> 16;
1477 p[MH_BUTTONBITS + 2] = buttonbits >> 8;
1478 p[MH_BUTTONBITS + 3] = buttonbits >> 0;
1479
1480 if (!memcmp (tmp1, p + MH_ABSX, sizeof tmp1) && !memcmp (tmp2, p + MH_BUTTONBITS, sizeof tmp2))
1481 return;
1482 p[MH_E] = 0xc0 | 1;
1483 p[MH_CNT]++;
1484 tablet_data = 1;
1485 }
1486
1487 #ifdef FILESYS
1488 /* FIXME
1489 * Was "if 0" already, also in moushack_helper(). Why?
1490 */
1491 #if 0
1492 static void inputdevice_mh_abs_v36 (int x, int y)
1493 {
1494 uae_u8 *p;
1495 uae_u8 tmp[MH_END];
1496 uae_u32 off;
1497 int maxx, maxy, diffx, diffy;
1498 int fdy, fdx, fmx, fmy;
1499
1500 mousehack_enable ();
1501 off = getmhoffset ();
1502 p = rtarea + off;
1503
1504 memcpy (tmp, p + MH_START, MH_END - MH_START);
1505
1506 getgfxoffset (&fdx, &fdy, &fmx, &fmy);
1507 x -= fdx;
1508 y -= fdy;
1509 x += vp_xoffset;
1510 y += vp_yoffset;
1511
1512 diffx = diffy = 0;
1513 maxx = maxy = 0;
1514
1515 if (picasso_on) {
1516 maxx = picasso96_state.Width;
1517 maxy = picasso96_state.Height;
1518 } else if (dimensioninfo_width > 0 && dimensioninfo_height > 0) {
1519 maxx = dimensioninfo_width;
1520 maxy = dimensioninfo_height;
1521 get_custom_mouse_limits (&maxx, &maxy, &diffx, &diffy, dimensioninfo_dbl);
1522 } else {
1523 uaecptr gb = get_gfxbase ();
1524 maxx = 0; maxy = 0;
1525 if (gb) {
1526 maxy = get_word (gb + 216);
1527 maxx = get_word (gb + 218);
1528 }
1529 get_custom_mouse_limits (&maxx, &maxy, &diffx, &diffy, 0);
1530 }
1531 #if 0
1532 {
1533 uaecptr gb = get_intuitionbase ();
1534 maxy = get_word (gb + 1344 + 2);
1535 maxx = get_word (gb + 1348 + 2);
1536 write_log (_T("%d %d\n"), maxx, maxy);
1537 }
1538 #endif
1539 #if 1
1540 {
1541 uaecptr gb = get_gfxbase ();
1542 uaecptr view = get_long (gb + 34);
1543 if (view) {
1544 uaecptr vp = get_long (view);
1545 if (vp) {
1546 int w, h, dw, dh;
1547 w = get_word (vp + 24);
1548 h = get_word (vp + 26) * 2;
1549 dw = get_word (vp + 28);
1550 dh = get_word (vp + 30);
1551 //write_log (_T("%d %d %d %d\n"), w, h, dw, dh);
1552 if (w < maxx)
1553 maxx = w;
1554 if (h < maxy)
1555 maxy = h;
1556 x -= dw;
1557 y -= dh;
1558 }
1559 }
1560 //write_log (_T("* %d %d\n"), get_word (gb + 218), get_word (gb + 216));
1561 }
1562 //write_log (_T("%d %d\n"), maxx, maxy);
1563 #endif
1564
1565 maxx = maxx * 1000 / fmx;
1566 maxy = maxy * 1000 / fmy;
1567
1568 if (maxx <= 0)
1569 maxx = 1;
1570 if (maxy <= 0)
1571 maxy = 1;
1572
1573 x -= diffx;
1574 if (x < 0)
1575 x = 0;
1576 if (x >= maxx)
1577 x = maxx - 1;
1578
1579 y -= diffy;
1580 if (y < 0)
1581 y = 0;
1582 if (y >= maxy)
1583 y = maxy - 1;
1584
1585 //write_log (_T("%d %d %d %d\n"), x, y, maxx, maxy);
1586
1587 p[MH_X] = x >> 8;
1588 p[MH_X + 1] = x;
1589 p[MH_Y] = y >> 8;
1590 p[MH_Y + 1] = y;
1591 p[MH_MAXX] = maxx >> 8;
1592 p[MH_MAXX + 1] = maxx;
1593 p[MH_MAXY] = maxy >> 8;
1594 p[MH_MAXY + 1] = maxy;
1595
1596 p[MH_Z] = p[MH_Z + 1] = 0;
1597 p[MH_MAXZ] = p[MH_MAXZ + 1] = 0;
1598 p[MH_AX] = p[MH_AX + 1] = 0;
1599 p[MH_AY] = p[MH_AY + 1] = 0;
1600 p[MH_AZ] = p[MH_AZ + 1] = 0;
1601 p[MH_PRESSURE] = p[MH_PRESSURE + 1] = 0;
1602 p[MH_INPROXIMITY] = p[MH_INPROXIMITY + 1] = 0xff;
1603
1604 if (!memcmp (tmp, p + MH_START, MH_END - MH_START))
1605 return;
1606 p[MH_CNT]++;
1607 tablet_data = 1;
1608 }
1609 #endif // 0
1610 #endif // FILESYS
1611
mousehack_helper(uae_u32 buttonmask)1612 static void mousehack_helper (uae_u32 buttonmask)
1613 {
1614 #ifdef FILESYS /* Internal mousehack depends on filesys boot-rom */
1615 int x, y;
1616 int fdy, fdx, fmx, fmy;
1617
1618 if (currprefs.input_magic_mouse == 0 && currprefs.input_tablet < TABLET_MOUSEHACK)
1619 return;
1620 #if 0
1621 if (kickstart_version >= 36) {
1622 inputdevice_mh_abs_v36 (lastmx, lastmy);
1623 return;
1624 }
1625 #endif
1626 x = lastmx;
1627 y = lastmy;
1628 getgfxoffset (&fdx, &fdy, &fmx, &fmy);
1629
1630 #ifdef PICASSO96
1631 if (picasso_on) {
1632 x -= picasso96_state.XOffset;
1633 y -= picasso96_state.YOffset;
1634 x = (int)(x * fmx);
1635 y = (int)(y * fmy);
1636 x -= (int)(fdx * fmx);
1637 y -= (int)(fdy * fmy);
1638 } else
1639 #endif
1640 {
1641 x = (int)(x * fmx);
1642 y = (int)(y * fmy);
1643 x -= (int)(fdx * fmx) - 1;
1644 y -= (int)(fdy * fmy) - 2;
1645 if (x < 0)
1646 x = 0;
1647 if (x >= gfxvidinfo.outwidth)
1648 x = gfxvidinfo.outwidth - 1;
1649 if (y < 0)
1650 y = 0;
1651 if (y >= gfxvidinfo.outheight)
1652 y = gfxvidinfo.outheight - 1;
1653 x = coord_native_to_amiga_x (x);
1654 y = coord_native_to_amiga_y (y) << 1;
1655 }
1656 inputdevice_mh_abs (x, y, buttonmask);
1657 #endif
1658 }
1659
1660 static int mouseedge_x, mouseedge_y, mouseedge_time;
1661 #define MOUSEEDGE_RANGE 100
1662 #define MOUSEEDGE_TIME 2
1663
1664 extern void setmouseactivexy (int,int,int);
1665
mouseedge(void)1666 static int mouseedge (void)
1667 {
1668 int x, y, dir;
1669 uaecptr ib;
1670 static int melast_x, melast_y;
1671 static int isnonzero;
1672
1673 if (currprefs.input_magic_mouse == 0 || currprefs.input_tablet > 0)
1674 return 0;
1675 if (magicmouse_ibase == 0xffffffff)
1676 return 0;
1677 dir = 0;
1678 if (!mouseedge_time) {
1679 isnonzero = 0;
1680 goto end;
1681 }
1682 ib = get_intuitionbase ();
1683 if (!ib || get_word (ib + 20) < 31) // version < 31
1684 return 0;
1685 x = get_word (ib + 70);
1686 y = get_word (ib + 68);
1687 if (x || y)
1688 isnonzero = 1;
1689 if (!isnonzero)
1690 return 0;
1691 if (melast_x == x) {
1692 if (mouseedge_x < -MOUSEEDGE_RANGE) {
1693 mouseedge_x = 0;
1694 dir |= 1;
1695 goto end;
1696 }
1697 if (mouseedge_x > MOUSEEDGE_RANGE) {
1698 mouseedge_x = 0;
1699 dir |= 2;
1700 goto end;
1701 }
1702 } else {
1703 mouseedge_x = 0;
1704 melast_x = x;
1705 }
1706 if (melast_y == y) {
1707 if (mouseedge_y < -MOUSEEDGE_RANGE) {
1708 mouseedge_y = 0;
1709 dir |= 4;
1710 goto end;
1711 }
1712 if (mouseedge_y > MOUSEEDGE_RANGE) {
1713 mouseedge_y = 0;
1714 dir |= 8;
1715 goto end;
1716 }
1717 } else {
1718 mouseedge_y = 0;
1719 melast_y = y;
1720 }
1721 return 1;
1722
1723 end:
1724 mouseedge_time = 0;
1725 if (dir) {
1726 if (!picasso_on) {
1727 int aw = 0, ah = 0, dx, dy;
1728 get_custom_mouse_limits (&aw, &ah, &dx, &dy, dimensioninfo_dbl);
1729 x += dx;
1730 y += dy;
1731 }
1732 if (!dmaen (DMA_SPRITE))
1733 setmouseactivexy (x, y, 0);
1734 else
1735 setmouseactivexy (x, y, dir);
1736 }
1737 return 1;
1738 }
1739
magicmouse_alive(void)1740 int magicmouse_alive (void)
1741 {
1742 return mouseedge_alive > 0;
1743 }
1744
adjust(int val)1745 STATIC_INLINE int adjust (int val)
1746 {
1747 if (val > 127)
1748 return 127;
1749 else if (val < -127)
1750 return -127;
1751 return val;
1752 }
1753
getbuttonstate(int joy,int button)1754 static int getbuttonstate (int joy, int button)
1755 {
1756 return (joybutton[joy] & (1 << button)) ? 1 : 0;
1757 }
1758
getvelocity(int num,int subnum,int pct)1759 static int getvelocity (int num, int subnum, int pct)
1760 {
1761 int val;
1762 int v;
1763
1764 if (pct > 1000)
1765 pct = 1000;
1766 val = mouse_delta[num][subnum];
1767 v = val * pct / 1000;
1768 if (!v) {
1769 if (val < -maxvpos / 2)
1770 v = -2;
1771 else if (val < 0)
1772 v = -1;
1773 else if (val > maxvpos / 2)
1774 v = 2;
1775 else if (val > 0)
1776 v = 1;
1777 }
1778 if (!mouse_deltanoreset[num][subnum]) {
1779 mouse_delta[num][subnum] -= v;
1780 gui_gameport_axis_change (num, subnum * 2 + 0, 0, -1);
1781 gui_gameport_axis_change (num, subnum * 2 + 1, 0, -1);
1782 }
1783 return v;
1784 }
1785
1786 #define MOUSEXY_MAX 16384
1787
mouseupdate(int pct,bool vsync)1788 static void mouseupdate (int pct, bool vsync)
1789 {
1790 int v, i;
1791 int max = 120;
1792 static int mxd, myd;
1793
1794 if (vsync) {
1795 if (mxd < 0) {
1796 if (mouseedge_x > 0)
1797 mouseedge_x = 0;
1798 else
1799 mouseedge_x += mxd;
1800 mouseedge_time = MOUSEEDGE_TIME;
1801 }
1802 if (mxd > 0) {
1803 if (mouseedge_x < 0)
1804 mouseedge_x = 0;
1805 else
1806 mouseedge_x += mxd;
1807 mouseedge_time = MOUSEEDGE_TIME;
1808 }
1809 if (myd < 0) {
1810 if (mouseedge_y > 0)
1811 mouseedge_y = 0;
1812 else
1813 mouseedge_y += myd;
1814 mouseedge_time = MOUSEEDGE_TIME;
1815 }
1816 if (myd > 0) {
1817 if (mouseedge_y < 0)
1818 mouseedge_y = 0;
1819 else
1820 mouseedge_y += myd;
1821 mouseedge_time = MOUSEEDGE_TIME;
1822 }
1823 if (mouseedge_time > 0) {
1824 mouseedge_time--;
1825 if (mouseedge_time == 0) {
1826 mouseedge_x = 0;
1827 mouseedge_y = 0;
1828 }
1829 }
1830 mxd = 0;
1831 myd = 0;
1832 }
1833
1834 for (i = 0; i < 2; i++) {
1835
1836 if (mouse_port[i]) {
1837
1838 v = getvelocity (i, 0, pct);
1839 mxd += v;
1840 mouse_x[i] += v;
1841 if (mouse_x[i] < 0) {
1842 mouse_x[i] += MOUSEXY_MAX;
1843 mouse_frame_x[i] = mouse_x[i] - v;
1844 }
1845 if (mouse_x[i] >= MOUSEXY_MAX) {
1846 mouse_x[i] -= MOUSEXY_MAX;
1847 mouse_frame_x[i] = mouse_x[i] - v;
1848 }
1849
1850 v = getvelocity (i, 1, pct);
1851 myd += v;
1852 mouse_y[i] += v;
1853 if (mouse_y[i] < 0) {
1854 mouse_y[i] += MOUSEXY_MAX;
1855 mouse_frame_y[i] = mouse_y[i] - v;
1856 }
1857 if (mouse_y[i] >= MOUSEXY_MAX) {
1858 mouse_y[i] -= MOUSEXY_MAX;
1859 mouse_frame_y[i] = mouse_y[i] - v;
1860 }
1861
1862 v = getvelocity (i, 2, pct);
1863 if (v > 0)
1864 record_key (0x7a << 1);
1865 else if (v < 0)
1866 record_key (0x7b << 1);
1867 if (!mouse_deltanoreset[i][2])
1868 mouse_delta[i][2] = 0;
1869
1870 if (mouse_frame_x[i] - mouse_x[i] > max) {
1871 mouse_x[i] = mouse_frame_x[i] - max;
1872 mouse_x[i] &= MOUSEXY_MAX - 1;
1873 }
1874 if (mouse_frame_x[i] - mouse_x[i] < -max) {
1875 mouse_x[i] = mouse_frame_x[i] + max;
1876 mouse_x[i] &= MOUSEXY_MAX - 1;
1877 }
1878
1879 if (mouse_frame_y[i] - mouse_y[i] > max)
1880 mouse_y[i] = mouse_frame_y[i] - max;
1881 if (mouse_frame_y[i] - mouse_y[i] < -max)
1882 mouse_y[i] = mouse_frame_y[i] + max;
1883 }
1884
1885 if (!vsync) {
1886 mouse_frame_x[i] = mouse_x[i];
1887 mouse_frame_y[i] = mouse_y[i];
1888 }
1889
1890 }
1891 }
1892
1893 static int input_vpos, input_frame;
1894 extern int vpos;
readinput(void)1895 static void readinput (void)
1896 {
1897 uae_u32 totalvpos;
1898 int diff;
1899
1900 totalvpos = input_frame * current_maxvpos () + vpos;
1901 diff = totalvpos - input_vpos;
1902 if (diff > 0) {
1903 if (diff < 10) {
1904 mouseupdate (0, false);
1905 } else {
1906 mouseupdate (diff * 1000 / current_maxvpos (), false);
1907 }
1908 }
1909 input_vpos = totalvpos;
1910
1911 }
1912
joymousecounter(int joy)1913 static void joymousecounter (int joy)
1914 {
1915 int left = 1, right = 1, top = 1, bot = 1;
1916 int b9, b8, b1, b0;
1917 int cntx, cnty, ocntx, ocnty;
1918
1919 if (joydir[joy] & DIR_LEFT)
1920 left = 0;
1921 if (joydir[joy] & DIR_RIGHT)
1922 right = 0;
1923 if (joydir[joy] & DIR_UP)
1924 top = 0;
1925 if (joydir[joy] & DIR_DOWN)
1926 bot = 0;
1927
1928 b0 = (bot ^ right) ? 1 : 0;
1929 b1 = (right ^ 1) ? 2 : 0;
1930 b8 = (top ^ left) ? 1 : 0;
1931 b9 = (left ^ 1) ? 2 : 0;
1932
1933 cntx = b0 | b1;
1934 cnty = b8 | b9;
1935 ocntx = mouse_x[joy] & 3;
1936 ocnty = mouse_y[joy] & 3;
1937
1938 if (cntx == 3 && ocntx == 0)
1939 mouse_x[joy] -= 4;
1940 else if (cntx == 0 && ocntx == 3)
1941 mouse_x[joy] += 4;
1942 mouse_x[joy] = (mouse_x[joy] & 0xfc) | cntx;
1943
1944 if (cnty == 3 && ocnty == 0)
1945 mouse_y[joy] -= 4;
1946 else if (cnty == 0 && ocnty == 3)
1947 mouse_y[joy] += 4;
1948 mouse_y[joy] = (mouse_y[joy] & 0xfc) | cnty;
1949
1950 if (!left || !right || !top || !bot) {
1951 mouse_frame_x[joy] = mouse_x[joy];
1952 mouse_frame_y[joy] = mouse_y[joy];
1953 }
1954 }
1955
getjoystate(int joy)1956 static uae_u16 getjoystate (int joy)
1957 {
1958 uae_u16 v;
1959
1960 v = (uae_u8)mouse_x[joy] | (mouse_y[joy] << 8);
1961 #ifdef DONGLE_DEBUG
1962 if (notinrom ())
1963 write_log (_T("JOY%dDAT %04X %s\n"), joy, v, debuginfo (0));
1964 #endif
1965 if (inputdevice_logging & 2)
1966 write_log (_T("JOY%dDAT=%04x %08x\n"), joy, v, M68K_GETPC);
1967 return v;
1968 }
1969
JOY0DAT(void)1970 uae_u16 JOY0DAT (void)
1971 {
1972 uae_u16 v;
1973 readinput ();
1974 v = getjoystate (0);
1975 v = dongle_joydat (0, v);
1976 return v;
1977 }
1978
JOY1DAT(void)1979 uae_u16 JOY1DAT (void)
1980 {
1981 uae_u16 v;
1982 readinput ();
1983 v = getjoystate (1);
1984 v = dongle_joydat (1, v);
1985
1986 if (inputrecord_debug & 2) {
1987 if (input_record > 0)
1988 inprec_recorddebug_cia (v, -1, m68k_getpc ());
1989 else if (input_play > 0)
1990 inprec_playdebug_cia (v, -1, m68k_getpc ());
1991 }
1992
1993 return v;
1994 }
1995
JOYGET(int num)1996 uae_u16 JOYGET (int num)
1997 {
1998 uae_u16 v;
1999 v = getjoystate (num);
2000 v = dongle_joydat (num, v);
2001 return v;
2002 }
2003
JOYSET(int num,uae_u16 dat)2004 void JOYSET (int num, uae_u16 dat)
2005 {
2006 mouse_x[num] = dat & 0xff;
2007 mouse_y[num] = (dat >> 8) & 0xff;
2008 mouse_frame_x[num] = mouse_x[num];
2009 mouse_frame_y[num] = mouse_y[num];
2010 }
2011
JOYTEST(uae_u16 v)2012 void JOYTEST (uae_u16 v)
2013 {
2014 mouse_x[0] &= 3;
2015 mouse_y[0] &= 3;
2016 mouse_x[1] &= 3;
2017 mouse_y[1] &= 3;
2018 mouse_x[0] |= v & 0xFC;
2019 mouse_x[1] |= v & 0xFC;
2020 mouse_y[0] |= (v >> 8) & 0xFC;
2021 mouse_y[1] |= (v >> 8) & 0xFC;
2022 mouse_frame_x[0] = mouse_x[0];
2023 mouse_frame_y[0] = mouse_y[0];
2024 mouse_frame_x[1] = mouse_x[1];
2025 mouse_frame_y[1] = mouse_y[1];
2026 dongle_joytest (v);
2027 if (inputdevice_logging & 2)
2028 write_log (_T("JOYTEST: %04X PC=%x\n"), v , M68K_GETPC);
2029 }
2030
parconvert(uae_u8 v,int jd,int shift)2031 static uae_u8 parconvert (uae_u8 v, int jd, int shift)
2032 {
2033 if (jd & DIR_UP)
2034 v &= ~(1 << shift);
2035 if (jd & DIR_DOWN)
2036 v &= ~(2 << shift);
2037 if (jd & DIR_LEFT)
2038 v &= ~(4 << shift);
2039 if (jd & DIR_RIGHT)
2040 v &= ~(8 << shift);
2041 return v;
2042 }
2043
2044 /* io-pins floating: dir=1 -> return data, dir=0 -> always return 1 */
handle_parport_joystick(int port,uae_u8 pra,uae_u8 dra)2045 uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra)
2046 {
2047 uae_u8 v;
2048 switch (port)
2049 {
2050 case 0:
2051 v = (pra & dra) | (dra ^ 0xff);
2052 if (parport_joystick_enabled) {
2053 v = parconvert (v, joydir[2], 0);
2054 v = parconvert (v, joydir[3], 4);
2055 }
2056 return v;
2057 case 1:
2058 v = ((pra & dra) | (dra ^ 0xff)) & 0x7;
2059 if (parport_joystick_enabled) {
2060 if (getbuttonstate (2, 0))
2061 v &= ~4;
2062 if (getbuttonstate (3, 0))
2063 v &= ~1;
2064 if (getbuttonstate (2, 1) || getbuttonstate (3, 1))
2065 v &= ~2; /* spare */
2066 }
2067 return v;
2068 default:
2069 abort ();
2070 return 0;
2071 }
2072 }
2073
2074 /* p5 is 1 or floating = cd32 2-button mode */
cd32padmode(uae_u16 p5dir,uae_u16 p5dat)2075 static bool cd32padmode (uae_u16 p5dir, uae_u16 p5dat)
2076 {
2077 if (!(potgo_value & p5dir) || ((potgo_value & p5dat) && (potgo_value & p5dir)))
2078 return false;
2079 return true;
2080 }
2081
is_joystick_pullup(int joy)2082 static bool is_joystick_pullup (int joy)
2083 {
2084 return joymodes[joy] == JSEM_MODE_GAMEPAD;
2085 }
is_mouse_pullup(int joy)2086 static bool is_mouse_pullup (int joy)
2087 {
2088 return mouse_pullup;
2089 }
2090
charge_cap(int joy,int idx,int charge)2091 static void charge_cap (int joy, int idx, int charge)
2092 {
2093 if (charge < -1 || charge > 1)
2094 charge = charge * 80;
2095 pot_cap[joy][idx] += charge;
2096 if (pot_cap[joy][idx] < 0)
2097 pot_cap[joy][idx] = 0;
2098 if (pot_cap[joy][idx] > 511)
2099 pot_cap[joy][idx] = 511;
2100 }
2101
cap_check(void)2102 static void cap_check (void)
2103 {
2104 int joy, i;
2105
2106 for (joy = 0; joy < 2; joy++) {
2107 for (i = 0; i < 2; i++) {
2108 int charge = 0, dong, joypot;
2109 uae_u16 pdir = 0x0200 << (joy * 4 + i * 2); /* output enable */
2110 uae_u16 pdat = 0x0100 << (joy * 4 + i * 2); /* data */
2111 uae_u16 p5dir = 0x0200 << (joy * 4);
2112 uae_u16 p5dat = 0x0100 << (joy * 4);
2113 int isbutton = getbuttonstate (joy, i == 0 ? JOYBUTTON_3 : JOYBUTTON_2);
2114
2115 if (cd32_pad_enabled[joy]) {
2116 // only red and blue can be read if CD32 pad and only if it is in normal pad mode
2117 isbutton |= getbuttonstate (joy, JOYBUTTON_CD32_BLUE);
2118 // CD32 pad 3rd button line (P5) is always floating
2119 if (i == 0)
2120 isbutton = 0;
2121 if (cd32padmode (p5dir, p5dat))
2122 continue;
2123 }
2124
2125 dong = dongle_analogjoy (joy, i);
2126 if (dong >= 0) {
2127 isbutton = 0;
2128 joypot = dong;
2129 if (pot_cap[joy][i] < joypot)
2130 charge = 1; // slow charge via dongle resistor
2131 } else {
2132 joypot = joydirpot[joy][i];
2133 if (analog_port[joy][i] && pot_cap[joy][i] < joypot)
2134 charge = 1; // slow charge via pot variable resistor
2135 if ((is_joystick_pullup (joy) && digital_port[joy][i]) || (is_mouse_pullup (joy) && mouse_port[joy]))
2136 charge = 1; // slow charge via pull-up resistor
2137 }
2138 if (!(potgo_value & pdir)) { // input?
2139 if (pot_dat_act[joy][i])
2140 pot_dat[joy][i]++;
2141 /* first 7 or 8 lines after potgo has been started = discharge cap */
2142 if (pot_dat_act[joy][i] == 1) {
2143 if (pot_dat[joy][i] < (currprefs.ntscmode ? POTDAT_DELAY_NTSC : POTDAT_DELAY_PAL)) {
2144 charge = -2; /* fast discharge delay */
2145 } else {
2146 pot_dat_act[joy][i] = 2;
2147 pot_dat[joy][i] = 0;
2148 }
2149 }
2150 if (dong >= 0) {
2151 if (pot_dat_act[joy][i] == 2 && pot_cap[joy][i] >= joypot)
2152 pot_dat_act[joy][i] = 0;
2153 } else {
2154 if (analog_port[joy][i] && pot_dat_act[joy][i] == 2 && pot_cap[joy][i] >= joypot)
2155 pot_dat_act[joy][i] = 0;
2156 if ((digital_port[joy][i] || mouse_port[joy]) && pot_dat_act[joy][i] == 2) {
2157 if (pot_cap[joy][i] >= 10 && !isbutton)
2158 pot_dat_act[joy][i] = 0;
2159 }
2160 }
2161 } else { // output?
2162 charge = (potgo_value & pdat) ? 2 : -2; /* fast (dis)charge if output */
2163 if (potgo_value & pdat)
2164 pot_dat_act[joy][i] = 0; // instant stop if output+high
2165 if (isbutton)
2166 pot_dat[joy][i]++; // "free running" if output+low
2167 }
2168
2169 if (isbutton)
2170 charge = -2; // button press overrides everything
2171
2172 if (currprefs.cs_cdtvcd) {
2173 /* CDTV P9 is not floating */
2174 if (!(potgo_value & pdir) && i == 1 && charge == 0)
2175 charge = 2;
2176 }
2177 // CD32 pad in 2-button mode: blue button is not floating
2178 #ifdef __LIBRETRO__
2179 if (i == 1 && charge == 0)
2180 #else
2181 if (cd32_pad_enabled[joy] && i == 1 && charge == 0)
2182 #endif
2183 charge = 2;
2184
2185 /* official Commodore mouse has pull-up resistors in button lines
2186 * NOTE: 3rd party mice may not have pullups! */
2187 if (dong < 0 && (is_mouse_pullup (joy) && mouse_port[joy] && digital_port[joy][i]) && charge == 0)
2188 charge = 2;
2189 /* emulate pullup resistor if button mapped because there too many broken
2190 * programs that read second button in input-mode (and most 2+ button pads have
2191 * pullups)
2192 */
2193 if (dong < 0 && (is_joystick_pullup (joy) && digital_port[joy][i]) && charge == 0)
2194 charge = 2;
2195
2196 charge_cap (joy, i, charge);
2197 }
2198 }
2199 }
2200
2201
handle_joystick_buttons(uae_u8 pra,uae_u8 dra)2202 uae_u8 handle_joystick_buttons (uae_u8 pra, uae_u8 dra)
2203 {
2204 uae_u8 but = 0;
2205 int i;
2206
2207 cap_check ();
2208 for (i = 0; i < 2; i++) {
2209 int mask = 0x40 << i;
2210 if (cd32_pad_enabled[i]) {
2211 uae_u16 p5dir = 0x0200 << (i * 4);
2212 uae_u16 p5dat = 0x0100 << (i * 4);
2213 but |= mask;
2214 if (!cd32padmode (p5dir, p5dat)) {
2215 if (getbuttonstate (i, JOYBUTTON_CD32_RED) || getbuttonstate (i, JOYBUTTON_1))
2216 but &= ~mask;
2217 }
2218 } else {
2219 if (!getbuttonstate (i, JOYBUTTON_1))
2220 but |= mask;
2221 if (bouncy && cycles_in_range (bouncy_cycles)) {
2222 but &= ~mask;
2223 if (uaerand () & 1)
2224 but |= mask;
2225 }
2226 if (dra & mask)
2227 but = (but & ~mask) | (pra & mask);
2228 }
2229 }
2230
2231 if (inputdevice_logging & 4) {
2232 static uae_u8 old;
2233 if (but != old)
2234 write_log (_T("BFE001 R: %02X:%02X %x\n"), dra, but, M68K_GETPC);
2235 old = but;
2236 }
2237 return but;
2238 }
2239
2240 /* joystick 1 button 1 is used as a output for incrementing shift register */
handle_cd32_joystick_cia(uae_u8 pra,uae_u8 dra)2241 void handle_cd32_joystick_cia (uae_u8 pra, uae_u8 dra)
2242 {
2243 static int oldstate[2];
2244 int i;
2245
2246 if (inputdevice_logging & 4) {
2247 write_log (_T("BFE001 W: %02X:%02X %x\n"), dra, pra, M68K_GETPC);
2248 }
2249 cap_check ();
2250 for (i = 0; i < 2; i++) {
2251 uae_u8 but = 0x40 << i;
2252 uae_u16 p5dir = 0x0200 << (i * 4); /* output enable P5 */
2253 uae_u16 p5dat = 0x0100 << (i * 4); /* data P5 */
2254 if (cd32padmode (p5dir, p5dat)) {
2255 if ((dra & but) && (pra & but) != oldstate[i]) {
2256 if (!(pra & but)) {
2257 cd32_shifter[i]--;
2258 if (cd32_shifter[i] < 0)
2259 cd32_shifter[i] = 0;
2260 if (inputdevice_logging & 4)
2261 write_log (_T("CD32 %d shift: %d %08x\n"), i, cd32_shifter[i], M68K_GETPC);
2262 }
2263 }
2264 }
2265 oldstate[i] = dra & pra & but;
2266 }
2267 }
2268
2269 /* joystick port 1 button 2 is input for button state */
handle_joystick_potgor(uae_u16 potgor)2270 static uae_u16 handle_joystick_potgor (uae_u16 potgor)
2271 {
2272 int i;
2273
2274 cap_check ();
2275 for (i = 0; i < 2; i++) {
2276 uae_u16 p9dir = 0x0800 << (i * 4); /* output enable P9 */
2277 uae_u16 p9dat = 0x0400 << (i * 4); /* data P9 */
2278 uae_u16 p5dir = 0x0200 << (i * 4); /* output enable P5 */
2279 uae_u16 p5dat = 0x0100 << (i * 4); /* data P5 */
2280
2281 if (cd32_pad_enabled[i] && cd32padmode (p5dir, p5dat)) {
2282
2283 /* p5 is floating in input-mode */
2284 potgor &= ~p5dat;
2285 potgor |= potgo_value & p5dat;
2286 if (!(potgo_value & p9dir))
2287 potgor |= p9dat;
2288 /* (P5 output and 1) or floating -> shift register is kept reset (Blue button) */
2289 if (!(potgo_value & p5dir) || ((potgo_value & p5dat) && (potgo_value & p5dir)))
2290 cd32_shifter[i] = 8;
2291 /* shift at 1 == return one, >1 = return button states */
2292 if (cd32_shifter[i] == 0)
2293 potgor &= ~p9dat; /* shift at zero == return zero */
2294 if (cd32_shifter[i] >= 2 && (joybutton[i] & ((1 << JOYBUTTON_CD32_PLAY) << (cd32_shifter[i] - 2))))
2295 potgor &= ~p9dat;
2296
2297 } else {
2298
2299 potgor &= ~p5dat;
2300 if (pot_cap[i][0] > 100)
2301 potgor |= p5dat;
2302
2303
2304 if (!cd32_pad_enabled[i] || !cd32padmode (p5dir, p5dat)) {
2305 potgor &= ~p9dat;
2306 if (pot_cap[i][1] > 100)
2307 potgor |= p9dat;
2308 }
2309
2310 }
2311 }
2312 return potgor;
2313 }
2314
2315
2316 static int inputdelay;
2317
inputdevice_read(void)2318 static void inputdevice_read (void)
2319 {
2320 //do {
2321 // handle_msgpump ();
2322 idev[IDTYPE_MOUSE].read ();
2323 idev[IDTYPE_JOYSTICK].read ();
2324 idev[IDTYPE_KEYBOARD].read ();
2325 //} while (handle_msgpump ());
2326 }
2327
inject_events(const TCHAR * str)2328 static void inject_events (const TCHAR *str)
2329 {
2330 bool quot = false;
2331 bool first = true;
2332 uae_u8 keys[300];
2333 int keycnt = 0;
2334
2335 for (;;) {
2336 TCHAR ch = *str++;
2337 if (!ch)
2338 break;
2339
2340 if (ch == '\'') {
2341 first = false;
2342 quot = !quot;
2343 continue;
2344 }
2345
2346 if (!quot && (ch == ' ' || first)) {
2347 const TCHAR *s = str;
2348 if (first)
2349 s--;
2350 while (*s == ' ')
2351 s++;
2352 const TCHAR *s2 = s;
2353 while (*s && *s != ' ')
2354 s++;
2355 int s2len = s - s2;
2356 if (!s2len)
2357 break;
2358 for (int i = 1; events[i].name; i++) {
2359 const TCHAR *cf = events[i].confname;
2360 if (!_tcsnicmp (cf, _T("KEY_"), 4))
2361 cf += 4;
2362 if (events[i].allow_mask == AM_K && !_tcsnicmp (cf, s2, _tcslen (cf)) && s2len == _tcslen (cf)) {
2363 int j;
2364 uae_u8 kc = events[i].data << 1;
2365 TCHAR tch = _totupper (s2[0]);
2366 if (tch != s2[0]) {
2367 // release
2368 for (j = 0; j < keycnt; j++) {
2369 if (keys[j] == kc)
2370 keys[j] = 0xff;
2371 }
2372 kc |= 0x01;
2373 } else {
2374 for (j = 0; j < keycnt; j++) {
2375 if (keys[j] == kc) {
2376 kc = 0xff;
2377 }
2378 }
2379 if (kc != 0xff) {
2380 for (j = 0; j < keycnt; j++) {
2381 if (keys[j] == 0xff) {
2382 keys[j] = kc;
2383 break;
2384 }
2385 }
2386 if (j == keycnt) {
2387 if (keycnt < sizeof keys)
2388 keys[keycnt++] = kc;
2389 }
2390 }
2391 }
2392 if (kc != 0xff) {
2393 //write_log (_T("%s\n"), cf);
2394 record_key (kc);
2395 }
2396 }
2397 }
2398 } else if (quot) {
2399 ch = _totupper (ch);
2400 if ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) {
2401 for (int i = 1; events[i].name; i++) {
2402 if (events[i].allow_mask == AM_K && events[i].name[1] == 0 && events[i].name[0] == ch) {
2403 record_key (events[i].data << 1);
2404 record_key ((events[i].data << 1) | 0x01);
2405 //write_log (_T("%c\n"), ch);
2406 }
2407 }
2408 }
2409 }
2410 first = false;
2411 }
2412 while (--keycnt >= 0) {
2413 uae_u8 kc = keys[keycnt];
2414 if (kc != 0xff)
2415 record_key (kc | 0x01);
2416 }
2417 }
2418
handle_custom_event(const TCHAR * custom)2419 static int handle_custom_event (const TCHAR *custom)
2420 {
2421 TCHAR *p = NULL, *buf = NULL, *nextp = NULL;
2422 bool noquot = false;
2423
2424 if (custom == NULL)
2425 return 0;
2426 config_changed = 1;
2427 write_log (_T("%s\n"), custom);
2428 p = buf = my_strdup_trim (custom);
2429 if (p[0] != '\"')
2430 noquot = true;
2431 while (p && *p) {
2432 TCHAR *p2;
2433 if (!noquot) {
2434 if (*p != '\"')
2435 break;
2436 p++;
2437 p2 = p;
2438 while (*p2 != '\"' && *p2 != 0)
2439 p2++;
2440 if (*p2 == '\"') {
2441 *p2++ = 0;
2442 nextp = p2 + 1;
2443 while (*nextp == ' ')
2444 nextp++;
2445 }
2446 }
2447 //write_log (L"-> '%s'\n", p);
2448 if (!_tcsicmp (p, _T("no_config_check"))) {
2449 config_changed = 0;
2450 } else if (!_tcsicmp (p, _T("do_config_check"))) {
2451 config_changed = 1;
2452 } else if (!_tcsnicmp (p, _T("dbg "), 4)) {
2453 debug_parser (p + 4, NULL, -1);
2454 } else if (!_tcsnicmp (p, _T("kbr "), 4)) {
2455 inject_events (p + 4);
2456 } else {
2457 cfgfile_parse_line (&changed_prefs, p, 0);
2458 }
2459 if (noquot)
2460 break;
2461 p = nextp;
2462 }
2463 xfree (buf);
2464 return 0;
2465 }
2466
inputdevice_hsync(void)2467 void inputdevice_hsync (void)
2468 {
2469 static int cnt;
2470 cap_check ();
2471
2472 #ifdef CATWEASEL
2473 catweasel_hsync ();
2474 #endif
2475
2476 for (int i = 0; i < INPUT_QUEUE_SIZE; i++) {
2477 struct input_queue_struct *iq = &input_queue[i];
2478 if (iq->linecnt > 0) {
2479 iq->linecnt--;
2480 if (iq->linecnt == 0) {
2481 if (iq->state)
2482 iq->state = 0;
2483 else
2484 iq->state = iq->storedstate;
2485 if (iq->custom)
2486 handle_custom_event (iq->custom);
2487 if (iq->evt)
2488 handle_input_event (iq->evt, iq->state, iq->max, 0, false, true);
2489 iq->linecnt = iq->nextlinecnt;
2490 }
2491 }
2492 }
2493
2494 if (bouncy && get_cycles () > bouncy_cycles)
2495 bouncy = 0;
2496
2497 if (input_record && input_record != INPREC_RECORD_PLAYING) {
2498 if (vpos == 0)
2499 inputdevice_read ();
2500 inputdelay = 0;
2501 }
2502 if (input_play) {
2503 inprec_playdiskchange ();
2504 int nr, state, max, autofire;
2505 while (inprec_playevent (&nr, &state, &max, &autofire))
2506 handle_input_event (nr, state, max, autofire, false, true);
2507 //if (vpos == 0)
2508 //handle_msgpump ();
2509 }
2510 if (!input_record && !input_play) {
2511 if ((++cnt & 63) == 63 ) {
2512 inputdevice_read ();
2513 } else if (inputdelay > 0) {
2514 inputdelay--;
2515 if (inputdelay == 0)
2516 inputdevice_read ();
2517 }
2518 }
2519 }
2520
POTDAT(int joy)2521 static uae_u16 POTDAT (int joy)
2522 {
2523 uae_u16 v = (pot_dat[joy][1] << 8) | pot_dat[joy][0];
2524 if (inputdevice_logging & 16)
2525 write_log (_T("POTDAT%d: %04X %08X\n"), joy, v, M68K_GETPC);
2526 return v;
2527 }
2528
POT0DAT(void)2529 uae_u16 POT0DAT (void)
2530 {
2531 return POTDAT (0);
2532 }
POT1DAT(void)2533 uae_u16 POT1DAT (void)
2534 {
2535 return POTDAT (1);
2536 }
2537
2538 /* direction=input, data pin floating, last connected logic level or previous status
2539 * written when direction was ouput
2540 * otherwise it is currently connected logic level.
2541 * direction=output, data pin is current value, forced to zero if joystick button is pressed
2542 * it takes some tens of microseconds before data pin changes state
2543 */
2544
POTGO(uae_u16 v)2545 void POTGO (uae_u16 v)
2546 {
2547 int i, j;
2548
2549 if (inputdevice_logging & 16)
2550 write_log (_T("POTGO_W: %04X %08X\n"), v, M68K_GETPC);
2551 #ifdef DONGLE_DEBUG
2552 if (notinrom ())
2553 write_log (_T("POTGO %04X %s\n"), v, debuginfo(0));
2554 #endif
2555 dongle_potgo (v);
2556 potgo_value = potgo_value & 0x5500; /* keep state of data bits */
2557 potgo_value |= v & 0xaa00; /* get new direction bits */
2558 for (i = 0; i < 8; i += 2) {
2559 uae_u16 dir = 0x0200 << i;
2560 if (v & dir) {
2561 uae_u16 data = 0x0100 << i;
2562 potgo_value &= ~data;
2563 potgo_value |= v & data;
2564 }
2565 }
2566 for (i = 0; i < 2; i++) {
2567 if (cd32_pad_enabled[i]) {
2568 uae_u16 p5dir = 0x0200 << (i * 4); /* output enable P5 */
2569 uae_u16 p5dat = 0x0100 << (i * 4); /* data P5 */
2570 if (!(potgo_value & p5dir) || ((potgo_value & p5dat) && (potgo_value & p5dir)))
2571 cd32_shifter[i] = 8;
2572 }
2573 }
2574 if (v & 1) {
2575 for (i = 0; i < 2; i++) {
2576 for (j = 0; j < 2; j++) {
2577 pot_dat_act[i][j] = 1;
2578 pot_dat[i][j] = 0;
2579 }
2580 }
2581 }
2582 }
2583
POTGOR(void)2584 uae_u16 POTGOR (void)
2585 {
2586 uae_u16 v;
2587
2588 v = handle_joystick_potgor (potgo_value) & 0x5500;
2589 v = dongle_potgor (v);
2590 #ifdef DONGLE_DEBUG
2591 if (notinrom ())
2592 write_log (_T("POTGOR %04X %s\n"), v, debuginfo(0));
2593 #endif
2594 if (inputdevice_logging & 16)
2595 write_log (_T("POTGO_R: %04X %08X %d %d\n"), v, M68K_GETPC, cd32_shifter[0], cd32_shifter[1]);
2596 return v;
2597 }
2598
check_input_queue(int evt)2599 static int check_input_queue (int evt)
2600 {
2601 struct input_queue_struct *iq;
2602 int i;
2603 for (i = 0; i < INPUT_QUEUE_SIZE; i++) {
2604 iq = &input_queue[i];
2605 if (iq->evt == evt && iq->linecnt >= 0)
2606 return i;
2607 }
2608 return -1;
2609 }
2610
queue_input_event(int evt,const TCHAR * custom,int state,int max,int linecnt,int autofire)2611 static void queue_input_event (int evt, const TCHAR *custom, int state, int max, int linecnt, int autofire)
2612 {
2613 struct input_queue_struct *iq;
2614 int idx;
2615
2616 if (!evt)
2617 return;
2618 idx = check_input_queue (evt);
2619 if (state < 0 && idx >= 0) {
2620 iq = &input_queue[idx];
2621 iq->nextlinecnt = -1;
2622 iq->linecnt = -1;
2623 iq->evt = 0;
2624 if (iq->state == 0 && evt > 0)
2625 handle_input_event (evt, 0, 1, 0, false, false);
2626 } else if (state >= 0 && idx < 0) {
2627 if (evt == 0 && custom == NULL)
2628 return;
2629 for (idx = 0; idx < INPUT_QUEUE_SIZE; idx++) {
2630 iq = &input_queue[idx];
2631 if (iq->linecnt < 0)
2632 break;
2633 }
2634 if (idx == INPUT_QUEUE_SIZE) {
2635 write_log (_T("input queue overflow\n"));
2636 return;
2637 }
2638 xfree (iq->custom);
2639 iq->custom = NULL;
2640 if (custom)
2641 iq->custom = my_strdup (custom);
2642 iq->evt = evt;
2643 iq->state = iq->storedstate = state;
2644 iq->max = max;
2645 iq->linecnt = linecnt < 0 ? maxvpos + maxvpos / 2 : linecnt;
2646 iq->nextlinecnt = autofire > 0 ? linecnt : -1;
2647 }
2648 }
2649
2650 static uae_u8 keybuf[256];
2651 static int inputcode_pending, inputcode_pending_state;
2652
inputdevice_release_all_keys(void)2653 void inputdevice_release_all_keys (void)
2654 {
2655 int i;
2656
2657 for (i = 0; i < 0x80; i++) {
2658 if (keybuf[i] != 0) {
2659 keybuf[i] = 0;
2660 record_key (i << 1|1);
2661 }
2662 }
2663 }
2664
2665
inputdevice_add_inputcode(int code,int state)2666 void inputdevice_add_inputcode (int code, int state)
2667 {
2668 inputcode_pending = code;
2669 inputcode_pending_state = state;
2670 }
2671
inputdevice_do_keyboard(int code,int state)2672 void inputdevice_do_keyboard (int code, int state)
2673 {
2674 #ifdef CDTV
2675 if (code >= 0x72 && code <= 0x77) { // CDTV keys
2676 if (cdtv_front_panel (-1)) {
2677 // front panel active
2678 if (!state)
2679 return;
2680 cdtv_front_panel (code - 0x72);
2681 return;
2682 }
2683 }
2684 #endif
2685 if (code < 0x80) {
2686 uae_u8 key = code | (state ? 0x00 : 0x80);
2687 keybuf[key & 0x7f] = (key & 0x80) ? 0 : 1;
2688 if (key == AK_RESETWARNING) {
2689 resetwarning_do (0);
2690 return;
2691 } else if ((keybuf[AK_CTRL] || keybuf[AK_RCTRL]) && keybuf[AK_LAMI] && keybuf[AK_RAMI]) {
2692 int r = keybuf[AK_LALT] | keybuf[AK_RALT];
2693 if (!r && currprefs.cs_resetwarning && resetwarning_do (1))
2694 return;
2695 memset (keybuf, 0, sizeof (keybuf));
2696 send_internalevent (INTERNALEVENT_KBRESET);
2697 uae_reset (r, 1);
2698 }
2699 if (record_key ((uae_u8)((key << 1) | (key >> 7)))) {
2700 if (inputdevice_logging & 1)
2701 write_log (_T("Amiga key %02X %d\n"), key & 0x7f, key >> 7);
2702 }
2703 return;
2704 }
2705 inputdevice_add_inputcode (code, state);
2706 }
2707
2708 // these need cpu trace data
needcputrace(int code)2709 static bool needcputrace (int code)
2710 {
2711 switch (code)
2712 {
2713 case AKS_ENTERGUI:
2714 case AKS_STATECAPTURE:
2715 case AKS_STATESAVEQUICK:
2716 case AKS_STATESAVEQUICK1:
2717 case AKS_STATESAVEQUICK2:
2718 case AKS_STATESAVEQUICK3:
2719 case AKS_STATESAVEQUICK4:
2720 case AKS_STATESAVEQUICK5:
2721 case AKS_STATESAVEQUICK6:
2722 case AKS_STATESAVEQUICK7:
2723 case AKS_STATESAVEQUICK8:
2724 case AKS_STATESAVEQUICK9:
2725 case AKS_STATESAVEDIALOG:
2726 return true;
2727 }
2728 return false;
2729 }
2730
inputdevice_handle_inputcode(void)2731 void inputdevice_handle_inputcode (void)
2732 {
2733 static int swapperslot;
2734 int code = inputcode_pending;
2735 int state = inputcode_pending_state;
2736 static int tracer_enable;
2737
2738 if (code == 0)
2739 goto end;
2740 if (needcputrace (code) && can_cpu_tracer () == true && is_cpu_tracer () == false && !input_play && !input_record && !debugging) {
2741 if (set_cpu_tracer (true)) {
2742 tracer_enable = 1;
2743 return; // wait for next frame
2744 }
2745 }
2746
2747 inputcode_pending = 0;
2748
2749 if (vpos != 0)
2750 write_log (_T("inputcode=%d but vpos = %d"), code, vpos);
2751
2752 #ifdef ARCADIA
2753 switch (code)
2754 {
2755 case AKS_ARCADIADIAGNOSTICS:
2756 arcadia_flag &= ~1;
2757 arcadia_flag |= state ? 1 : 0;
2758 break;
2759 case AKS_ARCADIAPLY1:
2760 arcadia_flag &= ~4;
2761 arcadia_flag |= state ? 4 : 0;
2762 break;
2763 case AKS_ARCADIAPLY2:
2764 arcadia_flag &= ~2;
2765 arcadia_flag |= state ? 2 : 0;
2766 break;
2767 case AKS_ARCADIACOIN1:
2768 if (state)
2769 arcadia_coin[0]++;
2770 break;
2771 case AKS_ARCADIACOIN2:
2772 if (state)
2773 arcadia_coin[1]++;
2774 break;
2775 }
2776 #endif
2777
2778 if (!state)
2779 return;
2780 switch (code)
2781 {
2782 case AKS_ENTERGUI:
2783 gui_display (-1);
2784 setsystime ();
2785 break;
2786 case AKS_SCREENSHOT_FILE:
2787 screenshot (1, 1);
2788 break;
2789 case AKS_SCREENSHOT_CLIPBOARD:
2790 screenshot (0, 1);
2791 break;
2792 #ifdef ACTION_REPLAY
2793 case AKS_FREEZEBUTTON:
2794 action_replay_freeze ();
2795 break;
2796 #endif
2797 case AKS_FLOPPY0:
2798 gui_display (0);
2799 setsystime ();
2800 break;
2801 case AKS_FLOPPY1:
2802 gui_display (1);
2803 setsystime ();
2804 break;
2805 case AKS_FLOPPY2:
2806 gui_display (2);
2807 setsystime ();
2808 break;
2809 case AKS_FLOPPY3:
2810 gui_display (3);
2811 setsystime ();
2812 break;
2813 case AKS_EFLOPPY0:
2814 disk_eject (0);
2815 break;
2816 case AKS_EFLOPPY1:
2817 disk_eject (1);
2818 break;
2819 case AKS_EFLOPPY2:
2820 disk_eject (2);
2821 break;
2822 case AKS_EFLOPPY3:
2823 disk_eject (3);
2824 break;
2825 case AKS_IRQ7:
2826 NMI_delayed ();
2827 break;
2828 case AKS_PAUSE:
2829 pausemode (-1);
2830 break;
2831 case AKS_WARP:
2832 warpmode (-1);
2833 break;
2834 case AKS_INHIBITSCREEN:
2835 toggle_inhibit_frame (IHF_SCROLLLOCK);
2836 break;
2837 #ifdef SAVESTATE
2838 case AKS_STATEREWIND:
2839 savestate_dorewind (-2);
2840 break;
2841 case AKS_STATECURRENT:
2842 savestate_dorewind (-1);
2843 break;
2844 case AKS_STATECAPTURE:
2845 savestate_capture (1);
2846 break;
2847 #endif
2848 case AKS_VOLDOWN:
2849 sound_volume (-1);
2850 break;
2851 case AKS_VOLUP:
2852 sound_volume (1);
2853 break;
2854 case AKS_VOLMUTE:
2855 sound_mute (-1);
2856 break;
2857 case AKS_MVOLDOWN:
2858 master_sound_volume (-1);
2859 break;
2860 case AKS_MVOLUP:
2861 master_sound_volume (1);
2862 break;
2863 case AKS_MVOLMUTE:
2864 master_sound_volume (0);
2865 break;
2866 case AKS_QUIT:
2867 uae_quit ();
2868 break;
2869 case AKS_SOFTRESET:
2870 uae_reset (0, 0);
2871 break;
2872 case AKS_HARDRESET:
2873 uae_reset (1, 1);
2874 break;
2875 #ifdef SAVESTATE
2876 case AKS_STATESAVEQUICK:
2877 case AKS_STATESAVEQUICK1:
2878 case AKS_STATESAVEQUICK2:
2879 case AKS_STATESAVEQUICK3:
2880 case AKS_STATESAVEQUICK4:
2881 case AKS_STATESAVEQUICK5:
2882 case AKS_STATESAVEQUICK6:
2883 case AKS_STATESAVEQUICK7:
2884 case AKS_STATESAVEQUICK8:
2885 case AKS_STATESAVEQUICK9:
2886 savestate_quick ((code - AKS_STATESAVEQUICK) / 2, 1);
2887 break;
2888 case AKS_STATERESTOREQUICK:
2889 case AKS_STATERESTOREQUICK1:
2890 case AKS_STATERESTOREQUICK2:
2891 case AKS_STATERESTOREQUICK3:
2892 case AKS_STATERESTOREQUICK4:
2893 case AKS_STATERESTOREQUICK5:
2894 case AKS_STATERESTOREQUICK6:
2895 case AKS_STATERESTOREQUICK7:
2896 case AKS_STATERESTOREQUICK8:
2897 case AKS_STATERESTOREQUICK9:
2898 savestate_quick ((code - AKS_STATERESTOREQUICK) / 2, 0);
2899 break;
2900 #endif
2901 case AKS_TOGGLEDEFAULTSCREEN:
2902 toggle_fullscreen (-1);
2903 break;
2904 case AKS_TOGGLEWINDOWEDFULLSCREEN:
2905 toggle_fullscreen (0);
2906 break;
2907 case AKS_TOGGLEFULLWINDOWFULLSCREEN:
2908 toggle_fullscreen (1);
2909 break;
2910 case AKS_TOGGLEWINDOWFULLWINDOW:
2911 toggle_fullscreen (2);
2912 break;
2913 case AKS_TOGGLEMOUSEGRAB:
2914 toggle_mousegrab ();
2915 break;
2916 #ifdef DEBUGGER
2917 case AKS_ENTERDEBUGGER:
2918 activate_debugger ();
2919 break;
2920 #endif
2921 case AKS_STATESAVEDIALOG:
2922 gui_display (5);
2923 break;
2924 case AKS_STATERESTOREDIALOG:
2925 gui_display (4);
2926 break;
2927 case AKS_DECREASEREFRESHRATE:
2928 case AKS_INCREASEREFRESHRATE:
2929 {
2930 int dir = code == AKS_INCREASEREFRESHRATE ? 5 : -5;
2931 if (currprefs.chipset_refreshrate == 0)
2932 currprefs.chipset_refreshrate = currprefs.ntscmode ? 60 : 50;
2933 changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate + dir;
2934 if (changed_prefs.chipset_refreshrate < 10.0)
2935 changed_prefs.chipset_refreshrate = 10.0;
2936 if (changed_prefs.chipset_refreshrate > 900.0)
2937 changed_prefs.chipset_refreshrate = 900.0;
2938 config_changed = 1;
2939 }
2940 break;
2941 case AKS_DISKSWAPPER_NEXT:
2942 swapperslot++;
2943 if (swapperslot >= MAX_SPARE_DRIVES || currprefs.dfxlist[swapperslot][0] == 0)
2944 swapperslot = 0;
2945 break;
2946 case AKS_DISKSWAPPER_PREV:
2947 swapperslot--;
2948 if (swapperslot < 0)
2949 swapperslot = MAX_SPARE_DRIVES - 1;
2950 while (swapperslot > 0) {
2951 if (currprefs.dfxlist[swapperslot][0])
2952 break;
2953 swapperslot--;
2954 }
2955 break;
2956 case AKS_DISKSWAPPER_INSERT0:
2957 case AKS_DISKSWAPPER_INSERT1:
2958 case AKS_DISKSWAPPER_INSERT2:
2959 case AKS_DISKSWAPPER_INSERT3:
2960 _tcscpy (changed_prefs.floppyslots[code - AKS_DISKSWAPPER_INSERT0].df, currprefs.dfxlist[swapperslot]);
2961 config_changed = 1;
2962 break;
2963
2964 break;
2965 case AKS_INPUT_CONFIG_1:
2966 case AKS_INPUT_CONFIG_2:
2967 case AKS_INPUT_CONFIG_3:
2968 case AKS_INPUT_CONFIG_4:
2969 changed_prefs.input_selected_setting = currprefs.input_selected_setting = code - AKS_INPUT_CONFIG_1;
2970 inputdevice_updateconfig (&changed_prefs, &currprefs);
2971 break;
2972 case AKS_DISK_PREV0:
2973 case AKS_DISK_PREV1:
2974 case AKS_DISK_PREV2:
2975 case AKS_DISK_PREV3:
2976 disk_prevnext (code - AKS_DISK_PREV0, -1);
2977 break;
2978 case AKS_DISK_NEXT0:
2979 case AKS_DISK_NEXT1:
2980 case AKS_DISK_NEXT2:
2981 case AKS_DISK_NEXT3:
2982 disk_prevnext (code - AKS_DISK_NEXT0, 1);
2983 break;
2984 #ifdef CDTV
2985 case AKS_CDTV_FRONT_PANEL_STOP:
2986 case AKS_CDTV_FRONT_PANEL_PLAYPAUSE:
2987 case AKS_CDTV_FRONT_PANEL_PREV:
2988 case AKS_CDTV_FRONT_PANEL_NEXT:
2989 case AKS_CDTV_FRONT_PANEL_REW:
2990 case AKS_CDTV_FRONT_PANEL_FF:
2991 cdtv_front_panel (code - AKS_CDTV_FRONT_PANEL_STOP);
2992 break;
2993 #endif
2994 }
2995 end:
2996 if (tracer_enable) {
2997 set_cpu_tracer (false);
2998 tracer_enable = 0;
2999 }
3000 }
3001
getqualid(int evt)3002 static int getqualid (int evt)
3003 {
3004 if (evt > INPUTEVENT_SPC_QUALIFIER_START && evt < INPUTEVENT_SPC_QUALIFIER_END)
3005 return evt - INPUTEVENT_SPC_QUALIFIER1;
3006 return -1;
3007 }
3008
isqual(int evt)3009 static uae_u64 isqual (int evt)
3010 {
3011 int num = getqualid (evt);
3012 if (num < 0)
3013 return 0;
3014 return ID_FLAG_QUALIFIER1 << (num * 2);
3015 }
3016
handle_input_event(int nr,int state,int max,int autofire,bool canstopplayback,bool playbackevent)3017 int handle_input_event (int nr, int state, int max, int autofire, bool canstopplayback, bool playbackevent)
3018 {
3019 struct inputevent *ie;
3020 int joy;
3021 bool isaks = false;
3022
3023 if (nr <= 0 || nr == INPUTEVENT_SPC_CUSTOM_EVENT)
3024 return 0;
3025 ie = &events[nr];
3026 if (isqual (nr))
3027 return 0; // qualifiers do nothing
3028 if (ie->unit == 0 && ie->data >= AKS_FIRST) {
3029 isaks = true;
3030 if (!state) // release AKS_ does nothing
3031 return 0;
3032 }
3033
3034 if (!isaks) {
3035 if (input_record && input_record != INPREC_RECORD_PLAYING)
3036 inprec_recordevent (nr, state, max, autofire);
3037 if (input_play && state && canstopplayback) {
3038 if (inprec_realtimev ()) {
3039 if (input_record && input_record != INPREC_RECORD_PLAYING)
3040 inprec_recordevent (nr, state, max, autofire);
3041 }
3042 }
3043 if (!playbackevent && input_play)
3044 return 0;
3045 }
3046
3047 if ((inputdevice_logging & 1) || input_record || input_play)
3048 write_log (_T("STATE=%05d MAX=%05d AF=%d QUAL=%06x '%s' \n"), state, max, autofire, (uae_u32)(qualifiers >> 32), ie->name);
3049 if (autofire) {
3050 if (state)
3051 queue_input_event (nr, NULL, state, max, currprefs.input_autofire_linecnt, 1);
3052 else
3053 queue_input_event (nr, NULL, -1, 0, 0, 1);
3054 }
3055 switch (ie->unit)
3056 {
3057 case 5: /* lightpen/gun */
3058 {
3059 if (!lightpen_active) {
3060 lightpen_x = gfxvidinfo.outwidth / 2;
3061 lightpen_y = gfxvidinfo.outheight / 2;
3062 }
3063 lightpen_active = true;
3064 if (ie->type == 0) {
3065 int delta = 0;
3066 if (max == 0)
3067 delta = state * currprefs.input_mouse_speed / 100;
3068 else if (state > 0)
3069 delta = currprefs.input_joymouse_speed;
3070 else if (state < 0)
3071 delta = -currprefs.input_joymouse_speed;
3072 if (ie->data)
3073 lightpen_y += delta;
3074 else
3075 lightpen_x += delta;
3076 } else {
3077 int delta = currprefs.input_joymouse_speed;
3078 if (ie->data & DIR_LEFT)
3079 lightpen_x -= delta;
3080 if (ie->data & DIR_RIGHT)
3081 lightpen_x += delta;
3082 if (ie->data & DIR_UP)
3083 lightpen_y -= delta;
3084 if (ie->data & DIR_DOWN)
3085 lightpen_y += delta;
3086 }
3087 }
3088 break;
3089 case 1: /* ->JOY1 */
3090 case 2: /* ->JOY2 */
3091 case 3: /* ->Parallel port joystick adapter port #1 */
3092 case 4: /* ->Parallel port joystick adapter port #2 */
3093 joy = ie->unit - 1;
3094 if (ie->type & 4) {
3095 int old = joybutton[joy] & (1 << ie->data);
3096
3097 if (state) {
3098 joybutton[joy] |= 1 << ie->data;
3099 gui_gameport_button_change (joy, ie->data, 1);
3100 } else {
3101 joybutton[joy] &= ~(1 << ie->data);
3102 gui_gameport_button_change (joy, ie->data, 0);
3103 }
3104
3105 if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) {
3106 if (!input_record && !input_play && currprefs.input_contact_bounce) {
3107 // emulate contact bounce, 1st button only, others have capacitors
3108 bouncy = 1;
3109 bouncy_cycles = get_cycles () + CYCLE_UNIT * currprefs.input_contact_bounce;
3110 }
3111 }
3112
3113
3114 } else if (ie->type & 8) {
3115
3116 /* real mouse / analog stick mouse emulation */
3117 int delta;
3118 int deadzone = currprefs.input_joymouse_deadzone * max / 100;
3119 int unit = ie->data & 0x7f;
3120
3121 if (max) {
3122 if (state <= deadzone && state >= -deadzone) {
3123 state = 0;
3124 mouse_deltanoreset[joy][unit] = 0;
3125 } else if (state < 0) {
3126 state += deadzone;
3127 mouse_deltanoreset[joy][unit] = 1;
3128 } else {
3129 state -= deadzone;
3130 mouse_deltanoreset[joy][unit] = 1;
3131 }
3132 max -= deadzone;
3133 delta = state * currprefs.input_joymouse_multiplier / max;
3134 } else {
3135 delta = state;
3136 mouse_deltanoreset[joy][unit] = 0;
3137 }
3138 if (ie->data & IE_CDTV) {
3139 delta = 0;
3140 if (state > 0)
3141 delta = JOYMOUSE_CDTV;
3142 else if (state < 0)
3143 delta = -JOYMOUSE_CDTV;
3144 }
3145
3146 if (ie->data & IE_INVERT)
3147 delta = -delta;
3148
3149 if (max)
3150 mouse_delta[joy][unit] = delta;
3151 else
3152 mouse_delta[joy][unit] += delta;
3153
3154 max = 32;
3155 if (unit) {
3156 if (delta < 0) {
3157 gui_gameport_axis_change (joy, DIR_UP_BIT, abs (delta), max);
3158 gui_gameport_axis_change (joy, DIR_DOWN_BIT, 0, max);
3159 }
3160 if (delta > 0) {
3161 gui_gameport_axis_change (joy, DIR_DOWN_BIT, abs (delta), max);
3162 gui_gameport_axis_change (joy, DIR_UP_BIT, 0, max);
3163 }
3164 } else {
3165 if (delta < 0) {
3166 gui_gameport_axis_change (joy, DIR_LEFT_BIT, abs (delta), max);
3167 gui_gameport_axis_change (joy, DIR_RIGHT_BIT, 0, max);
3168 }
3169 if (delta > 0) {
3170 gui_gameport_axis_change (joy, DIR_RIGHT_BIT, abs (delta), max);
3171 gui_gameport_axis_change (joy, DIR_LEFT_BIT, 0, max);
3172 }
3173 }
3174
3175 } else if (ie->type & 32) { /* button mouse emulation vertical */
3176
3177 int speed = (ie->data & IE_CDTV) ? JOYMOUSE_CDTV : currprefs.input_joymouse_speed;
3178
3179 if (state && (ie->data & DIR_UP)) {
3180 mouse_delta[joy][1] = -speed;
3181 mouse_deltanoreset[joy][1] = 1;
3182 } else if (state && (ie->data & DIR_DOWN)) {
3183 mouse_delta[joy][1] = speed;
3184 mouse_deltanoreset[joy][1] = 1;
3185 } else
3186 mouse_deltanoreset[joy][1] = 0;
3187
3188 } else if (ie->type & 64) { /* button mouse emulation horizontal */
3189
3190 int speed = (ie->data & IE_CDTV) ? JOYMOUSE_CDTV : currprefs.input_joymouse_speed;
3191
3192 if (state && (ie->data & DIR_LEFT)) {
3193 mouse_delta[joy][0] = -speed;
3194 mouse_deltanoreset[joy][0] = 1;
3195 } else if (state && (ie->data & DIR_RIGHT)) {
3196 mouse_delta[joy][0] = speed;
3197 mouse_deltanoreset[joy][0] = 1;
3198 } else
3199 mouse_deltanoreset[joy][0] = 0;
3200
3201 } else if (ie->type & 128) { /* analog joystick / paddle */
3202
3203 int deadzone = currprefs.input_joymouse_deadzone * max / 100;
3204 int unit = ie->data & 0x7f;
3205 if (max) {
3206 if (state <= deadzone && state >= -deadzone) {
3207 state = 0;
3208 } else if (state < 0) {
3209 state += deadzone;
3210 } else {
3211 state -= deadzone;
3212 }
3213 state = state * max / (max - deadzone);
3214 }
3215 if (ie->data & IE_INVERT)
3216 state = -state;
3217
3218 if (!unit) {
3219 if (state <= 0)
3220 gui_gameport_axis_change (joy, DIR_UP_BIT, abs (state), max);
3221 if (state >= 0)
3222 gui_gameport_axis_change (joy, DIR_DOWN_BIT, abs (state), max);
3223 } else {
3224 if (state <= 0)
3225 gui_gameport_axis_change (joy, DIR_LEFT_BIT, abs (state), max);
3226 if (state >= 0)
3227 gui_gameport_axis_change (joy, DIR_RIGHT_BIT, abs (state), max);
3228 }
3229
3230 state = state * currprefs.input_analog_joystick_mult / max;
3231 state += (128 * currprefs.input_analog_joystick_mult / 100) + currprefs.input_analog_joystick_offset;
3232 if (state < 0)
3233 state = 0;
3234 if (state > 255)
3235 state = 255;
3236 joydirpot[joy][unit] = state;
3237 mouse_deltanoreset[joy][0] = 1;
3238 mouse_deltanoreset[joy][1] = 1;
3239
3240 } else {
3241
3242 int left = oleft[joy], right = oright[joy], top = otop[joy], bot = obot[joy];
3243 if (ie->type & 16) {
3244 /* button to axis mapping */
3245 if (ie->data & DIR_LEFT) {
3246 left = oleft[joy] = state ? 1 : 0;
3247 if (horizclear[joy] && left) {
3248 horizclear[joy] = 0;
3249 right = oright[joy] = 0;
3250 }
3251 }
3252 if (ie->data & DIR_RIGHT) {
3253 right = oright[joy] = state ? 1 : 0;
3254 if (horizclear[joy] && right) {
3255 horizclear[joy] = 0;
3256 left = oleft[joy] = 0;
3257 }
3258 }
3259 if (ie->data & DIR_UP) {
3260 top = otop[joy] = state ? 1 : 0;
3261 if (vertclear[joy] && top) {
3262 vertclear[joy] = 0;
3263 bot = obot[joy] = 0;
3264 }
3265 }
3266 if (ie->data & DIR_DOWN) {
3267 bot = obot[joy] = state ? 1 : 0;
3268 if (vertclear[joy] && bot) {
3269 vertclear[joy] = 0;
3270 top = otop[joy] = 0;
3271 }
3272 }
3273 } else {
3274 /* "normal" joystick axis */
3275 int deadzone = currprefs.input_joystick_deadzone * max / 100;
3276 int neg, pos;
3277 if (state < deadzone && state > -deadzone)
3278 state = 0;
3279 neg = state < 0 ? 1 : 0;
3280 pos = state > 0 ? 1 : 0;
3281 if (ie->data & DIR_LEFT) {
3282 left = oleft[joy] = neg;
3283 if (horizclear[joy] && left) {
3284 horizclear[joy] = 0;
3285 right = oright[joy] = 0;
3286 }
3287 }
3288 if (ie->data & DIR_RIGHT) {
3289 right = oright[joy] = pos;
3290 if (horizclear[joy] && right) {
3291 horizclear[joy] = 0;
3292 left = oleft[joy] = 0;
3293 }
3294 }
3295 if (ie->data & DIR_UP) {
3296 top = otop[joy] = neg;
3297 if (vertclear[joy] && top) {
3298 vertclear[joy] = 0;
3299 bot = obot[joy] = 0;
3300 }
3301 }
3302 if (ie->data & DIR_DOWN) {
3303 bot = obot[joy] = pos;
3304 if (vertclear[joy] && bot) {
3305 vertclear[joy] = 0;
3306 top = otop[joy] = 0;
3307 }
3308 }
3309 }
3310 mouse_deltanoreset[joy][0] = 1;
3311 mouse_deltanoreset[joy][1] = 1;
3312 joydir[joy] = 0;
3313 if (left)
3314 joydir[joy] |= DIR_LEFT;
3315 if (right)
3316 joydir[joy] |= DIR_RIGHT;
3317 if (top)
3318 joydir[joy] |= DIR_UP;
3319 if (bot)
3320 joydir[joy] |= DIR_DOWN;
3321 if (joy == 0 || joy == 1)
3322 joymousecounter (joy);
3323
3324 gui_gameport_axis_change (joy, DIR_LEFT_BIT, left, 0);
3325 gui_gameport_axis_change (joy, DIR_RIGHT_BIT, right, 0);
3326 gui_gameport_axis_change (joy, DIR_UP_BIT, top, 0);
3327 gui_gameport_axis_change (joy, DIR_DOWN_BIT, bot, 0);
3328 }
3329 break;
3330 case 0: /* ->KEY */
3331 inputdevice_do_keyboard (ie->data, state);
3332 break;
3333 }
3334 return 1;
3335 }
3336
inputdevice_checkconfig(void)3337 static void inputdevice_checkconfig (void)
3338 {
3339 if (
3340 currprefs.jports[0].id != changed_prefs.jports[0].id ||
3341 currprefs.jports[1].id != changed_prefs.jports[1].id ||
3342 currprefs.jports[2].id != changed_prefs.jports[2].id ||
3343 currprefs.jports[3].id != changed_prefs.jports[3].id ||
3344 currprefs.jports[0].mode != changed_prefs.jports[0].mode ||
3345 currprefs.jports[1].mode != changed_prefs.jports[1].mode ||
3346 currprefs.jports[2].mode != changed_prefs.jports[2].mode ||
3347 currprefs.jports[3].mode != changed_prefs.jports[3].mode ||
3348 currprefs.input_selected_setting != changed_prefs.input_selected_setting ||
3349 currprefs.input_joymouse_multiplier != changed_prefs.input_joymouse_multiplier ||
3350 currprefs.input_joymouse_deadzone != changed_prefs.input_joymouse_deadzone ||
3351 currprefs.input_joystick_deadzone != changed_prefs.input_joystick_deadzone ||
3352 currprefs.input_joymouse_speed != changed_prefs.input_joymouse_speed ||
3353 currprefs.input_autofire_linecnt != changed_prefs.input_autofire_linecnt ||
3354 currprefs.input_mouse_speed != changed_prefs.input_mouse_speed) {
3355
3356 currprefs.input_selected_setting = changed_prefs.input_selected_setting;
3357 currprefs.input_joymouse_multiplier = changed_prefs.input_joymouse_multiplier;
3358 currprefs.input_joymouse_deadzone = changed_prefs.input_joymouse_deadzone;
3359 currprefs.input_joystick_deadzone = changed_prefs.input_joystick_deadzone;
3360 currprefs.input_joymouse_speed = changed_prefs.input_joymouse_speed;
3361 currprefs.input_autofire_linecnt = changed_prefs.input_autofire_linecnt;
3362 currprefs.input_mouse_speed = changed_prefs.input_mouse_speed;
3363
3364 inputdevice_updateconfig (&changed_prefs, &currprefs);
3365 }
3366 if (currprefs.dongle != changed_prefs.dongle) {
3367 currprefs.dongle = changed_prefs.dongle;
3368 dongle_reset ();
3369 }
3370 }
3371
inputdevice_vsync(void)3372 void inputdevice_vsync (void)
3373 {
3374 if (inputdevice_logging & 32)
3375 write_log (_T("*\n"));
3376
3377 input_frame++;
3378 mouseupdate (0, true);
3379
3380 if (!input_record) {
3381 inputdevice_read ();
3382 if (!input_play)
3383 inputdelay = uaerand () % (maxvpos <= 1 ? 1 : maxvpos - 1);
3384 }
3385
3386 inputdevice_handle_inputcode ();
3387 if (mouseedge_alive > 0)
3388 mouseedge_alive--;
3389 #ifdef ARCADIA
3390 if (arcadia_bios)
3391 arcadia_vsync ();
3392 #endif
3393 if (mouseedge ())
3394 mouseedge_alive = 10;
3395 if (mousehack_alive_cnt > 0) {
3396 mousehack_alive_cnt--;
3397 if (mousehack_alive_cnt == 0)
3398 setmouseactive (-1);
3399 } else if (mousehack_alive_cnt < 0) {
3400 mousehack_alive_cnt++;
3401 if (mousehack_alive_cnt == 0) {
3402 mousehack_alive_cnt = 100;
3403 setmouseactive (0);
3404 setmouseactive (1);
3405 }
3406 }
3407 inputdevice_checkconfig ();
3408 }
3409
inputdevice_reset(void)3410 void inputdevice_reset (void)
3411 {
3412 magicmouse_ibase = 0;
3413 magicmouse_gfxbase = 0;
3414 mousehack_reset ();
3415 if (inputdevice_is_tablet ())
3416 mousehack_enable ();
3417 bouncy = 0;
3418 }
3419
getoldport(struct uae_input_device * id)3420 static int getoldport (struct uae_input_device *id)
3421 {
3422 int i, j;
3423
3424 for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
3425 for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
3426 int evt = id->eventid[i][j];
3427 if (evt > 0) {
3428 int unit = events[evt].unit;
3429 if (unit >= 1 && unit <= 4)
3430 return unit;
3431 }
3432 }
3433 }
3434 return -1;
3435 }
3436
switchdevice(struct uae_input_device * id,int num,bool buttonmode)3437 static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
3438 {
3439 int i, j;
3440 int ismouse = 0;
3441 int newport = 0;
3442 int flags = 0;
3443 TCHAR *name = NULL;
3444 int otherbuttonpressed = 0;
3445
3446 if (num >= 4)
3447 return 0;
3448 #ifdef RETROPLATFORM
3449 if (rp_isactive ())
3450 return 0;
3451 #endif
3452 for (i = 0; i < MAX_INPUT_DEVICES; i++) {
3453 if (id == &joysticks[i]) {
3454 name = idev[IDTYPE_JOYSTICK].get_uniquename (i);
3455 newport = num == 0 ? 1 : 0;
3456 flags = idev[IDTYPE_JOYSTICK].get_flags (i);
3457 for (j = 0; j < MAX_INPUT_DEVICES; j++) {
3458 if (j != i) {
3459 struct uae_input_device2 *id2 = &joysticks2[j];
3460 if (id2->buttonmask)
3461 otherbuttonpressed = 1;
3462 }
3463 }
3464 }
3465 if (id == &mice[i]) {
3466 ismouse = 1;
3467 name = idev[IDTYPE_MOUSE].get_uniquename (i);
3468 newport = num == 0 ? 0 : 1;
3469 flags = idev[IDTYPE_MOUSE].get_flags (i);
3470 }
3471 }
3472 if (!name)
3473 return 0;
3474 if (buttonmode) {
3475 if (num == 0 && otherbuttonpressed)
3476 newport = newport ? 0 : 1;
3477 } else {
3478 newport = num ? 1 : 0;
3479 }
3480 /* "GamePorts" switch if in GamePorts mode or Input mode and GamePorts port was not NONE */
3481 if (currprefs.input_selected_setting == GAMEPORT_INPUT_SETTINGS || currprefs.jports[newport].id != JPORT_NONE) {
3482 if ((num == 0 || num == 1) && currprefs.jports[newport].id != JPORT_CUSTOM) {
3483 /* REMOVEME:
3484 * nowhere used
3485 */
3486 #if 0
3487 int om = jsem_ismouse (num, &currprefs);
3488 #endif
3489 int om1 = jsem_ismouse (0, &currprefs);
3490 int om2 = jsem_ismouse (1, &currprefs);
3491 if ((om1 >= 0 || om2 >= 0) && ismouse)
3492 return 0;
3493 if (flags)
3494 return 0;
3495 if (name) {
3496 write_log (_T("inputdevice change '%s':%d->%d\n"), name, num, newport);
3497 inputdevice_joyport_config (&changed_prefs, name, newport, -1, 2);
3498 inputdevice_copyconfig (&changed_prefs, &currprefs);
3499 return 1;
3500 }
3501 }
3502 return 0;
3503 } else {
3504 int oldport = getoldport (id);
3505 int k, evt;
3506 struct inputevent *ie, *ie2;
3507
3508 if (flags)
3509 return 0;
3510 if (oldport <= 0)
3511 return 0;
3512 newport++;
3513 /* do not switch if switching mouse and any "supermouse" mouse enabled */
3514 if (ismouse) {
3515 for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
3516 if (mice[i].enabled && idev[IDTYPE_MOUSE].get_flags (i))
3517 return 0;
3518 }
3519 }
3520 for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
3521 if (getoldport (&joysticks[i]) == newport)
3522 joysticks[i].enabled = 0;
3523 if (getoldport (&mice[i]) == newport)
3524 mice[i].enabled = 0;
3525 }
3526 id->enabled = 1;
3527 for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
3528 for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
3529 evt = id->eventid[i][j];
3530 if (evt <= 0)
3531 continue;
3532 ie = &events[evt];
3533 if (ie->unit == oldport) {
3534 k = 1;
3535 while (events[k].confname) {
3536 ie2 = &events[k];
3537 if (ie2->type == ie->type && ie2->data == ie->data && ie2->allow_mask == ie->allow_mask && ie2->unit == newport) {
3538 id->eventid[i][j] = k;
3539 break;
3540 }
3541 k++;
3542 }
3543 } else if (ie->unit == newport) {
3544 k = 1;
3545 while (events[k].confname) {
3546 ie2 = &events[k];
3547 if (ie2->type == ie->type && ie2->data == ie->data && ie2->allow_mask == ie->allow_mask && ie2->unit == oldport) {
3548 id->eventid[i][j] = k;
3549 break;
3550 }
3551 k++;
3552 }
3553 }
3554 }
3555 }
3556 write_log (_T("inputdevice change '%s':%d->%d\n"), name, num, newport);
3557 inputdevice_copyconfig (&currprefs, &changed_prefs);
3558 inputdevice_copyconfig (&changed_prefs, &currprefs);
3559 return 1;
3560 }
3561 return 0;
3562 }
3563
input_getqualifiers(void)3564 uae_u64 input_getqualifiers (void)
3565 {
3566 return qualifiers;
3567 }
3568
checkqualifiers(int evt,uae_u64 flags,uae_u64 * qualmask,uae_s16 events[MAX_INPUT_SUB_EVENT_ALL])3569 static bool checkqualifiers (int evt, uae_u64 flags, uae_u64 *qualmask, uae_s16 events[MAX_INPUT_SUB_EVENT_ALL])
3570 {
3571 int i, j;
3572 int qualid = getqualid (evt);
3573 int nomatch = 0;
3574 bool isspecial = (qualifiers & (ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SPECIAL_R)) != 0;
3575
3576 flags &= ID_FLAG_QUALIFIER_MASK;
3577 if (qualid >= 0 && events)
3578 qualifiers_evt[qualid] = events;
3579 /* special set and new qualifier pressed? do not sent it to Amiga-side */
3580 if ((qualifiers & (ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SPECIAL_R)) && qualid >= 0)
3581 return false;
3582
3583 for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
3584 if (qualmask[i])
3585 break;
3586 }
3587 if (i == MAX_INPUT_SUB_EVENT) {
3588 // no qualifiers in any slot and no special = always match
3589 return isspecial == false;
3590 }
3591
3592 for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
3593 for (j = 0; j < MAX_INPUT_QUALIFIERS; j++) {
3594 uae_u64 mask = (ID_FLAG_QUALIFIER1 | ID_FLAG_QUALIFIER1_R) << (j * 2);
3595 bool isqualmask = (qualmask[i] & mask) != 0;
3596 bool isqual = (qualifiers & mask) != 0;
3597 if (isqualmask != isqual) {
3598 nomatch++;
3599 break;
3600 }
3601 }
3602 }
3603 if (nomatch == MAX_INPUT_SUB_EVENT) {
3604 // no matched qualifiers in any slot
3605 // allow all slots without qualifiers
3606 // special = never accept
3607 if (isspecial)
3608 return false;
3609 return flags ? false : true;
3610 }
3611
3612 for (i = 0; i < MAX_INPUT_QUALIFIERS; i++) {
3613 uae_u64 mask = (ID_FLAG_QUALIFIER1 | ID_FLAG_QUALIFIER1_R) << (i * 2);
3614 bool isflags = (flags & mask) != 0;
3615 bool isqual = (qualifiers & mask) != 0;
3616 if (isflags != isqual)
3617 return false;
3618 }
3619 return true;
3620 }
3621
setqualifiers(int evt,int state)3622 static void setqualifiers (int evt, int state)
3623 {
3624 uae_u64 mask = isqual (evt);
3625 if (!mask)
3626 return;
3627 if (state)
3628 qualifiers |= mask;
3629 else
3630 qualifiers &= ~mask;
3631 }
3632
getqualmask(uae_u64 * qualmask,struct uae_input_device * id,int num,bool * qualonly)3633 static uae_u64 getqualmask (uae_u64 *qualmask, struct uae_input_device *id, int num, bool *qualonly)
3634 {
3635 uae_u64 mask = 0, mask2 = 0;
3636 for (int i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
3637 int evt = id->eventid[num][i];
3638 mask |= id->flags[num][i];
3639 qualmask[i] = id->flags[num][i] & ID_FLAG_QUALIFIER_MASK;
3640 mask2 |= isqual (evt);
3641 }
3642 mask &= ID_FLAG_QUALIFIER_MASK;
3643 *qualonly = false;
3644 if (qualifiers & ID_FLAG_QUALIFIER_SPECIAL) {
3645 // ID_FLAG_QUALIFIER_SPECIAL already active and this event has one or more qualifiers configured
3646 *qualonly = mask2 != 0;
3647 }
3648 return mask;
3649 }
3650
3651
process_custom_event(struct uae_input_device * id,int offset,int state,uae_u64 * qualmask,int autofire,int sub)3652 static bool process_custom_event (struct uae_input_device *id, int offset, int state, uae_u64 *qualmask, int autofire, int sub)
3653 {
3654 int idx, slotoffset, custompos;
3655 TCHAR *custom;
3656 uae_u64 flags, qual;
3657
3658 if (!id)
3659 return false;
3660
3661 slotoffset = sub & ~3;
3662 sub &= 3;
3663 flags = id->flags[offset][slotoffset];
3664 qual = flags & ID_FLAG_QUALIFIER_MASK;
3665 custom = id->custom[offset][slotoffset];
3666 /* REMOVEME:
3667 * nowhere used
3668 */
3669 #if 0
3670 int af = flags & ID_FLAG_AUTOFIRE_MASK;
3671 #endif
3672
3673 for (idx = 1; idx < 4; idx++) {
3674 uae_u64 flags2 = id->flags[offset][slotoffset + idx];
3675 /* REMOVEME:
3676 * nowhere used
3677 */
3678 #if 0
3679 TCHAR *custom2 = id->custom[offset][slotoffset + idx];
3680 #endif
3681
3682 // all slots must have same qualifier
3683 if ((flags2 & ID_FLAG_QUALIFIER_MASK) != qual)
3684 break;
3685 // no slot must have autofire
3686 if ((flags2 & ID_FLAG_AUTOFIRE_MASK) || (flags & ID_FLAG_AUTOFIRE_MASK))
3687 break;
3688 }
3689 // at least slot 0 and 2 must have custom
3690 if (custom == NULL || id->custom[offset][slotoffset + 2] == NULL)
3691 idx = -1;
3692
3693 if (idx < 4) {
3694 id->flags[offset][slotoffset] &= ~(ID_FLAG_CUSTOMEVENT_TOGGLED1 | ID_FLAG_CUSTOMEVENT_TOGGLED2);
3695 int evt2 = id->eventid[offset][slotoffset + sub];
3696 uae_u64 flags2 = id->flags[offset][slotoffset + sub];
3697 if (checkqualifiers (evt2, flags2, qualmask, NULL)) {
3698 custom = id->custom[offset][slotoffset + sub];
3699 if (state && custom) {
3700 if (autofire)
3701 queue_input_event (-1, custom, 1, 1, currprefs.input_autofire_linecnt, 1);
3702 handle_custom_event (custom);
3703 return true;
3704 }
3705 }
3706 return false;
3707 }
3708
3709 if (sub != 0)
3710 return false;
3711
3712 slotoffset = 0;
3713 if (!checkqualifiers (id->eventid[offset][slotoffset], id->flags[offset][slotoffset], qualmask, NULL)) {
3714 slotoffset = 4;
3715 if (!checkqualifiers (id->eventid[offset][slotoffset], id->flags[offset][slotoffset], qualmask, NULL))
3716 return false;
3717 }
3718
3719 flags = id->flags[offset][slotoffset];
3720 custompos = (flags & ID_FLAG_CUSTOMEVENT_TOGGLED1) ? 1 : 0;
3721 custompos |= (flags & ID_FLAG_CUSTOMEVENT_TOGGLED2) ? 2 : 0;
3722
3723 if (state < 0) {
3724 idx = 0;
3725 custompos = 0;
3726 } else {
3727 if (state > 0) {
3728 if (custompos & 1)
3729 return false; // waiting for release
3730 } else {
3731 if (!(custompos & 1))
3732 return false; // waiting for press
3733 }
3734 idx = custompos;
3735 custompos++;
3736 }
3737
3738 queue_input_event (-1, NULL, -1, 0, 0, 1);
3739
3740 if ((id->flags[offset][slotoffset + idx] & ID_FLAG_QUALIFIER_MASK) == qual) {
3741 custom = id->custom[offset][slotoffset + idx];
3742 if (autofire)
3743 queue_input_event (-1, custom, 1, 1, currprefs.input_autofire_linecnt, 1);
3744 if (custom)
3745 handle_custom_event (custom);
3746 }
3747
3748 id->flags[offset][slotoffset] &= ~(ID_FLAG_CUSTOMEVENT_TOGGLED1 | ID_FLAG_CUSTOMEVENT_TOGGLED2);
3749 id->flags[offset][slotoffset] |= (custompos & 1) ? ID_FLAG_CUSTOMEVENT_TOGGLED1 : 0;
3750 id->flags[offset][slotoffset] |= (custompos & 2) ? ID_FLAG_CUSTOMEVENT_TOGGLED2 : 0;
3751
3752 return true;
3753 }
3754
setbuttonstateall(struct uae_input_device * id,struct uae_input_device2 * id2,int button,int buttonstate)3755 static void setbuttonstateall (struct uae_input_device *id, struct uae_input_device2 *id2, int button, int buttonstate)
3756 {
3757 static frame_time_t switchdevice_timeout;
3758 int i;
3759 uae_u32 mask = 1 << button;
3760 uae_u32 omask = id2 ? id2->buttonmask & mask : 0;
3761 uae_u32 nmask = (buttonstate ? 1 : 0) << button;
3762 uae_u64 qualmask[MAX_INPUT_SUB_EVENT];
3763 bool qualonly;
3764
3765 if (input_play && buttonstate)
3766 inprec_realtimev ();
3767 if (input_play)
3768 return;
3769 if (!id->enabled) {
3770 frame_time_t t = read_processor_time ();
3771 if (buttonstate) {
3772 switchdevice_timeout = t;
3773 } else {
3774 int port = button;
3775 if (t - switchdevice_timeout >= syncbase) // 1s
3776 port ^= 1;
3777 switchdevice (id, port, true);
3778 }
3779 return;
3780 }
3781 if (button >= ID_BUTTON_TOTAL)
3782 return;
3783
3784 getqualmask (qualmask, id, ID_BUTTON_OFFSET + button, &qualonly);
3785
3786 bool didcustom = false;
3787
3788 for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
3789 int sub = sublevdir[buttonstate == 0 ? 1 : 0][i];
3790 uae_u64 *flagsp = &id->flags[ID_BUTTON_OFFSET + button][sub];
3791 int evt = id->eventid[ID_BUTTON_OFFSET + button][sub];
3792 /* REMOVEME:
3793 * nowhere used
3794 */
3795 #if 0
3796 TCHAR *custom = id->custom[ID_BUTTON_OFFSET + button][sub];
3797 #endif
3798 uae_u64 flags = flagsp[0];
3799 int autofire = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
3800 int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0;
3801 int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
3802 int invert = (flags & ID_FLAG_INVERT) ? 1 : 0;
3803 int state;
3804
3805 if (buttonstate < 0) {
3806 state = buttonstate;
3807 } else if (invert) {
3808 state = buttonstate ? 0 : 1;
3809 } else {
3810 state = buttonstate;
3811 }
3812
3813 if (!state) {
3814 didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
3815 }
3816
3817 setqualifiers (evt, state > 0);
3818
3819 if (qualonly)
3820 continue;
3821
3822 if (state < 0) {
3823 if (!checkqualifiers (evt, flags, qualmask, NULL))
3824 continue;
3825 handle_input_event (evt, 1, 1, 0, true, false);
3826 didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, 0, i);
3827 } else if (inverttoggle) {
3828 /* pressed = firebutton, not pressed = autofire */
3829 if (state) {
3830 queue_input_event (evt, NULL, -1, 0, 0, 1);
3831 handle_input_event (evt, 1, 1, 0, true, false);
3832 } else {
3833 handle_input_event (evt, 1, 1, autofire, true, false);
3834 }
3835 didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
3836 } else if (toggle) {
3837 if (!state)
3838 continue;
3839 if (omask & mask)
3840 continue;
3841 if (!checkqualifiers (evt, flags, qualmask, NULL))
3842 continue;
3843 *flagsp ^= ID_FLAG_TOGGLED;
3844 int toggled = (*flagsp & ID_FLAG_TOGGLED) ? 1 : 0;
3845 handle_input_event (evt, toggled, 1, autofire, true, false);
3846 didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, toggled, qualmask, autofire, i);
3847 } else {
3848 if (!checkqualifiers (evt, flags, qualmask, NULL)) {
3849 if (!state && !(flags & ID_FLAG_CANRELEASE)) {
3850 if (!invert)
3851 continue;
3852 } else if (state) {
3853 continue;
3854 }
3855 }
3856 if (!state)
3857 *flagsp &= ~ID_FLAG_CANRELEASE;
3858 else
3859 *flagsp |= ID_FLAG_CANRELEASE;
3860 if ((omask ^ nmask) & mask) {
3861 handle_input_event (evt, state, 1, autofire, true, false);
3862 if (state)
3863 didcustom |= process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask, autofire, i);
3864 }
3865 }
3866 }
3867
3868 if (!didcustom)
3869 queue_input_event (-1, NULL, -1, 0, 0, 1);
3870
3871 if (id2 && ((omask ^ nmask) & mask)) {
3872 if (buttonstate)
3873 id2->buttonmask |= mask;
3874 else
3875 id2->buttonmask &= ~mask;
3876 }
3877 }
3878
3879
3880 /* - detect required number of joysticks and mice from configuration data
3881 * - detect if CD32 pad emulation is needed
3882 * - detect device type in ports (mouse or joystick)
3883 */
3884
iscd32(int ei)3885 static int iscd32 (int ei)
3886 {
3887 if (ei >= INPUTEVENT_JOY1_CD32_FIRST && ei <= INPUTEVENT_JOY1_CD32_LAST) {
3888 cd32_pad_enabled[0] = 1;
3889 return 1;
3890 }
3891 if (ei >= INPUTEVENT_JOY2_CD32_FIRST && ei <= INPUTEVENT_JOY2_CD32_LAST) {
3892 cd32_pad_enabled[1] = 1;
3893 return 2;
3894 }
3895 return 0;
3896 }
3897
isparport(int ei)3898 static int isparport (int ei)
3899 {
3900 if (ei > INPUTEVENT_PAR_JOY1_START && ei < INPUTEVENT_PAR_JOY_END) {
3901 parport_joystick_enabled = 1;
3902 return 1;
3903 }
3904 return 0;
3905 }
3906
ismouse(int ei)3907 static int ismouse (int ei)
3908 {
3909 if (ei >= INPUTEVENT_MOUSE1_FIRST && ei <= INPUTEVENT_MOUSE1_LAST) {
3910 mouse_port[0] = 1;
3911 return 1;
3912 }
3913 if (ei >= INPUTEVENT_MOUSE2_FIRST && ei <= INPUTEVENT_MOUSE2_LAST) {
3914 mouse_port[1] = 1;
3915 return 2;
3916 }
3917 return 0;
3918 }
3919
isanalog(int ei)3920 static int isanalog (int ei)
3921 {
3922 if (ei == INPUTEVENT_JOY1_HORIZ_POT || ei == INPUTEVENT_JOY1_HORIZ_POT_INV) {
3923 analog_port[0][0] = 1;
3924 return 1;
3925 }
3926 if (ei == INPUTEVENT_JOY1_VERT_POT || ei == INPUTEVENT_JOY1_VERT_POT_INV) {
3927 analog_port[0][1] = 1;
3928 return 1;
3929 }
3930 if (ei == INPUTEVENT_JOY2_HORIZ_POT || ei == INPUTEVENT_JOY2_HORIZ_POT_INV) {
3931 analog_port[1][0] = 1;
3932 return 1;
3933 }
3934 if (ei == INPUTEVENT_JOY2_VERT_POT || ei == INPUTEVENT_JOY2_VERT_POT_INV) {
3935 analog_port[1][1] = 1;
3936 return 1;
3937 }
3938 return 0;
3939 }
3940
isdigitalbutton(int ei)3941 static int isdigitalbutton (int ei)
3942 {
3943 if (ei == INPUTEVENT_JOY1_2ND_BUTTON) {
3944 digital_port[0][1] = 1;
3945 return 1;
3946 }
3947 if (ei == INPUTEVENT_JOY1_3RD_BUTTON) {
3948 digital_port[0][0] = 1;
3949 return 1;
3950 }
3951 if (ei == INPUTEVENT_JOY2_2ND_BUTTON) {
3952 digital_port[1][1] = 1;
3953 return 1;
3954 }
3955 if (ei == INPUTEVENT_JOY2_3RD_BUTTON) {
3956 digital_port[1][0] = 1;
3957 return 1;
3958 }
3959 return 0;
3960 }
3961
islightpen(int ei)3962 static int islightpen (int ei)
3963 {
3964 if (ei >= INPUTEVENT_LIGHTPEN_FIRST && ei < INPUTEVENT_LIGHTPEN_LAST) {
3965 lightpen = 1;
3966 return 1;
3967 }
3968 return 0;
3969 }
3970
isqualifier(int ei)3971 static void isqualifier (int ei)
3972 {
3973 }
3974
scanevents(struct uae_prefs * p)3975 static void scanevents (struct uae_prefs *p)
3976 {
3977 int i, j, k, ei;
3978 /* REMOVEME:
3979 * nowhere used
3980 */
3981 #if 0
3982 const struct inputevent *e;
3983 #endif
3984 int n_joy = idev[IDTYPE_JOYSTICK].get_num();
3985 int n_mouse = idev[IDTYPE_MOUSE].get_num();
3986
3987 cd32_pad_enabled[0] = cd32_pad_enabled[1] = 0;
3988 parport_joystick_enabled = 0;
3989 mouse_port[0] = mouse_port[1] = 0;
3990 qualifiers = 0;
3991
3992 for (i = 0; i < NORMAL_JPORTS; i++) {
3993 for (j = 0; j < 2; j++) {
3994 digital_port[i][j] = 0;
3995 analog_port[i][j] = 0;
3996 joydirpot[i][j] = 128 / (312 * 100 / currprefs.input_analog_joystick_mult) + (128 * currprefs.input_analog_joystick_mult / 100) + currprefs.input_analog_joystick_offset;
3997 }
3998 }
3999 lightpen = 0;
4000 if (lightpen_active > 0)
4001 lightpen_active = -1;
4002
4003 for (i = 0; i < MAX_INPUT_DEVICES; i++) {
4004 use_joysticks[i] = 0;
4005 use_mice[i] = 0;
4006 for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
4007 for (j = 0; j < ID_BUTTON_TOTAL; j++) {
4008
4009 if ((joysticks[i].enabled && i < n_joy) || joysticks[i].enabled < 0) {
4010 ei = joysticks[i].eventid[ID_BUTTON_OFFSET + j][k];
4011 /* REMOVEME:
4012 * nowhere used
4013 */
4014 #if 0
4015 e = &events[ei];
4016 #endif
4017 iscd32 (ei);
4018 isparport (ei);
4019 ismouse (ei);
4020 isdigitalbutton (ei);
4021 isqualifier (ei);
4022 islightpen (ei);
4023 if (joysticks[i].eventid[ID_BUTTON_OFFSET + j][k] > 0)
4024 use_joysticks[i] = 1;
4025 }
4026 if ((mice[i].enabled && i < n_mouse) || mice[i].enabled < 0) {
4027 ei = mice[i].eventid[ID_BUTTON_OFFSET + j][k];
4028 /* REMOVEME:
4029 * nowhere used
4030 */
4031 #if 0
4032 e = &events[ei];
4033 #endif
4034 iscd32 (ei);
4035 isparport (ei);
4036 ismouse (ei);
4037 isdigitalbutton (ei);
4038 isqualifier (ei);
4039 islightpen (ei);
4040 if (mice[i].eventid[ID_BUTTON_OFFSET + j][k] > 0)
4041 use_mice[i] = 1;
4042 }
4043
4044 }
4045
4046 for (j = 0; j < ID_AXIS_TOTAL; j++) {
4047
4048 if ((joysticks[i].enabled && i < n_joy) || joysticks[i].enabled < 0) {
4049 ei = joysticks[i].eventid[ID_AXIS_OFFSET + j][k];
4050 iscd32 (ei);
4051 isparport (ei);
4052 ismouse (ei);
4053 isanalog (ei);
4054 isdigitalbutton (ei);
4055 isqualifier (ei);
4056 islightpen (ei);
4057 if (ei > 0)
4058 use_joysticks[i] = 1;
4059 }
4060 if ((mice[i].enabled && i < n_mouse) || mice[i].enabled < 0) {
4061 ei = mice[i].eventid[ID_AXIS_OFFSET + j][k];
4062 iscd32 (ei);
4063 isparport (ei);
4064 ismouse (ei);
4065 isanalog (ei);
4066 isdigitalbutton (ei);
4067 isqualifier (ei);
4068 islightpen (ei);
4069 if (ei > 0)
4070 use_mice[i] = 1;
4071 }
4072 }
4073 }
4074 }
4075 memset (scancodeused, 0, sizeof scancodeused);
4076 for (i = 0; i < MAX_INPUT_DEVICES; i++) {
4077 use_keyboards[i] = 0;
4078 if (keyboards[i].enabled && i < idev[IDTYPE_KEYBOARD].get_num()) {
4079 j = 0;
4080 while (j < MAX_INPUT_DEVICE_EVENTS && keyboards[i].extra[j] >= 0) {
4081 use_keyboards[i] = 1;
4082 for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
4083 ei = keyboards[i].eventid[j][k];
4084 iscd32 (ei);
4085 isparport (ei);
4086 ismouse (ei);
4087 isdigitalbutton (ei);
4088 isqualifier (ei);
4089 islightpen (ei);
4090 if (ei > 0)
4091 scancodeused[i][keyboards[i].extra[j]] = ei;
4092 }
4093 j++;
4094 }
4095 }
4096 }
4097 }
4098
4099 static const int axistable[] = {
4100 INPUTEVENT_MOUSE1_HORIZ, INPUTEVENT_MOUSE1_LEFT, INPUTEVENT_MOUSE1_RIGHT,
4101 INPUTEVENT_MOUSE1_VERT, INPUTEVENT_MOUSE1_UP, INPUTEVENT_MOUSE1_DOWN,
4102 INPUTEVENT_MOUSE2_HORIZ, INPUTEVENT_MOUSE2_LEFT, INPUTEVENT_MOUSE2_RIGHT,
4103 INPUTEVENT_MOUSE2_VERT, INPUTEVENT_MOUSE2_UP, INPUTEVENT_MOUSE2_DOWN,
4104 INPUTEVENT_JOY1_HORIZ, INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT,
4105 INPUTEVENT_JOY1_VERT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
4106 INPUTEVENT_JOY2_HORIZ, INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT,
4107 INPUTEVENT_JOY2_VERT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
4108 INPUTEVENT_LIGHTPEN_HORIZ, INPUTEVENT_LIGHTPEN_LEFT, INPUTEVENT_LIGHTPEN_RIGHT,
4109 INPUTEVENT_LIGHTPEN_VERT, INPUTEVENT_LIGHTPEN_UP, INPUTEVENT_LIGHTPEN_DOWN,
4110 INPUTEVENT_PAR_JOY1_HORIZ, INPUTEVENT_PAR_JOY1_LEFT, INPUTEVENT_PAR_JOY1_RIGHT,
4111 INPUTEVENT_PAR_JOY1_VERT, INPUTEVENT_PAR_JOY1_UP, INPUTEVENT_PAR_JOY1_DOWN,
4112 INPUTEVENT_PAR_JOY2_HORIZ, INPUTEVENT_PAR_JOY2_LEFT, INPUTEVENT_PAR_JOY2_RIGHT,
4113 INPUTEVENT_PAR_JOY2_VERT, INPUTEVENT_PAR_JOY2_UP, INPUTEVENT_PAR_JOY2_DOWN,
4114 INPUTEVENT_MOUSE_CDTV_HORIZ, INPUTEVENT_MOUSE_CDTV_LEFT, INPUTEVENT_MOUSE_CDTV_RIGHT,
4115 INPUTEVENT_MOUSE_CDTV_VERT, INPUTEVENT_MOUSE_CDTV_UP, INPUTEVENT_MOUSE_CDTV_DOWN,
4116 -1
4117 };
4118
intputdevice_compa_get_eventtype(int evt,const int ** axistablep)4119 int intputdevice_compa_get_eventtype (int evt, const int **axistablep)
4120 {
4121 for (int i = 0; axistable[i] >= 0; i += 3) {
4122 *axistablep = &axistable[i];
4123 if (axistable[i] == evt)
4124 return IDEV_WIDGET_AXIS;
4125 if (axistable[i + 1] == evt)
4126 return IDEV_WIDGET_BUTTONAXIS;
4127 if (axistable[i + 2] == evt)
4128 return IDEV_WIDGET_BUTTONAXIS;
4129 }
4130 *axistablep = NULL;
4131 return IDEV_WIDGET_BUTTON;
4132 }
4133
4134 static int rem_port1[] = {
4135 INPUTEVENT_MOUSE1_HORIZ, INPUTEVENT_MOUSE1_VERT,
4136 INPUTEVENT_JOY1_HORIZ, INPUTEVENT_JOY1_VERT,
4137 INPUTEVENT_JOY1_HORIZ_POT, INPUTEVENT_JOY1_VERT_POT,
4138 INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON, INPUTEVENT_JOY1_3RD_BUTTON,
4139 INPUTEVENT_JOY1_CD32_RED, INPUTEVENT_JOY1_CD32_BLUE, INPUTEVENT_JOY1_CD32_GREEN, INPUTEVENT_JOY1_CD32_YELLOW,
4140 INPUTEVENT_JOY1_CD32_RWD, INPUTEVENT_JOY1_CD32_FFW, INPUTEVENT_JOY1_CD32_PLAY,
4141 INPUTEVENT_MOUSE_CDTV_HORIZ, INPUTEVENT_MOUSE_CDTV_VERT,
4142 INPUTEVENT_LIGHTPEN_HORIZ, INPUTEVENT_LIGHTPEN_VERT,
4143 -1
4144 };
4145 static int rem_port2[] = {
4146 INPUTEVENT_MOUSE2_HORIZ, INPUTEVENT_MOUSE2_VERT,
4147 INPUTEVENT_JOY2_HORIZ, INPUTEVENT_JOY2_VERT,
4148 INPUTEVENT_JOY2_HORIZ_POT, INPUTEVENT_JOY2_VERT_POT,
4149 INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON, INPUTEVENT_JOY2_3RD_BUTTON,
4150 INPUTEVENT_JOY2_CD32_RED, INPUTEVENT_JOY2_CD32_BLUE, INPUTEVENT_JOY2_CD32_GREEN, INPUTEVENT_JOY2_CD32_YELLOW,
4151 INPUTEVENT_JOY2_CD32_RWD, INPUTEVENT_JOY2_CD32_FFW, INPUTEVENT_JOY2_CD32_PLAY,
4152 -1, -1,
4153 -1, -1,
4154 -1
4155 };
4156 static int rem_port3[] = {
4157 INPUTEVENT_PAR_JOY1_LEFT, INPUTEVENT_PAR_JOY1_RIGHT, INPUTEVENT_PAR_JOY1_UP, INPUTEVENT_PAR_JOY1_DOWN,
4158 INPUTEVENT_PAR_JOY1_FIRE_BUTTON, INPUTEVENT_PAR_JOY1_2ND_BUTTON,
4159 -1
4160 };
4161 static int rem_port4[] = {
4162 INPUTEVENT_PAR_JOY2_LEFT, INPUTEVENT_PAR_JOY2_RIGHT, INPUTEVENT_PAR_JOY2_UP, INPUTEVENT_PAR_JOY2_DOWN,
4163 INPUTEVENT_PAR_JOY2_FIRE_BUTTON, INPUTEVENT_PAR_JOY2_2ND_BUTTON,
4164 -1
4165 };
4166
4167 static int *rem_ports[] = { rem_port1, rem_port2, rem_port3, rem_port4 };
4168 static int af_port1[] = {
4169 INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_CD32_RED,
4170 -1
4171 };
4172 static int af_port2[] = {
4173 INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_CD32_RED,
4174 -1
4175 };
4176 static int af_port3[] = {
4177 INPUTEVENT_PAR_JOY1_FIRE_BUTTON, INPUTEVENT_PAR_JOY1_2ND_BUTTON,
4178 -1
4179 };
4180 static int af_port4[] = {
4181 INPUTEVENT_PAR_JOY2_FIRE_BUTTON, INPUTEVENT_PAR_JOY2_2ND_BUTTON,
4182 -1
4183 };
4184 static int *af_ports[] = { af_port1, af_port2, af_port3, af_port4 };
4185 static int ip_joy1[] = {
4186 INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
4187 INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON,
4188 -1
4189 };
4190 static int ip_joy2[] = {
4191 INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
4192 INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON,
4193 -1
4194 };
4195 static int ip_joypad1[] = {
4196 INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
4197 INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON, INPUTEVENT_JOY1_3RD_BUTTON,
4198 -1
4199 };
4200 static int ip_joypad2[] = {
4201 INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
4202 INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON, INPUTEVENT_JOY2_3RD_BUTTON,
4203 -1
4204 };
4205 static int ip_joycd321[] = {
4206 INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
4207 INPUTEVENT_JOY1_CD32_RED, INPUTEVENT_JOY1_CD32_BLUE, INPUTEVENT_JOY1_CD32_GREEN, INPUTEVENT_JOY1_CD32_YELLOW,
4208 INPUTEVENT_JOY1_CD32_RWD, INPUTEVENT_JOY1_CD32_FFW, INPUTEVENT_JOY1_CD32_PLAY,
4209 -1
4210 };
4211 static int ip_joycd322[] = {
4212 INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
4213 INPUTEVENT_JOY2_CD32_RED, INPUTEVENT_JOY2_CD32_BLUE, INPUTEVENT_JOY2_CD32_GREEN, INPUTEVENT_JOY2_CD32_YELLOW,
4214 INPUTEVENT_JOY2_CD32_RWD, INPUTEVENT_JOY2_CD32_FFW, INPUTEVENT_JOY2_CD32_PLAY,
4215 -1
4216 };
4217 static int ip_parjoy1[] = {
4218 INPUTEVENT_PAR_JOY1_LEFT, INPUTEVENT_PAR_JOY1_RIGHT, INPUTEVENT_PAR_JOY1_UP, INPUTEVENT_PAR_JOY1_DOWN,
4219 INPUTEVENT_PAR_JOY1_FIRE_BUTTON, INPUTEVENT_PAR_JOY1_2ND_BUTTON,
4220 -1
4221 };
4222 static int ip_parjoy2[] = {
4223 INPUTEVENT_PAR_JOY2_LEFT, INPUTEVENT_PAR_JOY2_RIGHT, INPUTEVENT_PAR_JOY2_UP, INPUTEVENT_PAR_JOY2_DOWN,
4224 INPUTEVENT_PAR_JOY2_FIRE_BUTTON, INPUTEVENT_PAR_JOY2_2ND_BUTTON,
4225 -1
4226 };
4227 static int ip_parjoy1default[] = {
4228 INPUTEVENT_PAR_JOY1_LEFT, INPUTEVENT_PAR_JOY1_RIGHT, INPUTEVENT_PAR_JOY1_UP, INPUTEVENT_PAR_JOY1_DOWN,
4229 INPUTEVENT_PAR_JOY1_FIRE_BUTTON,
4230 -1
4231 };
4232 static int ip_parjoy2default[] = {
4233 INPUTEVENT_PAR_JOY2_LEFT, INPUTEVENT_PAR_JOY2_RIGHT, INPUTEVENT_PAR_JOY2_UP, INPUTEVENT_PAR_JOY2_DOWN,
4234 INPUTEVENT_PAR_JOY2_FIRE_BUTTON,
4235 -1
4236 };
4237 static int ip_mouse1[] = {
4238 INPUTEVENT_MOUSE1_LEFT, INPUTEVENT_MOUSE1_RIGHT, INPUTEVENT_MOUSE1_UP, INPUTEVENT_MOUSE1_DOWN,
4239 INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON,
4240 -1
4241 };
4242 static int ip_mouse2[] = {
4243 INPUTEVENT_MOUSE2_LEFT, INPUTEVENT_MOUSE2_RIGHT, INPUTEVENT_MOUSE2_UP, INPUTEVENT_MOUSE2_DOWN,
4244 INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON,
4245 -1
4246 };
4247 static int ip_mousecdtv[] =
4248 {
4249 INPUTEVENT_MOUSE_CDTV_LEFT, INPUTEVENT_MOUSE_CDTV_RIGHT, INPUTEVENT_MOUSE_CDTV_UP, INPUTEVENT_MOUSE_CDTV_DOWN,
4250 INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON,
4251 -1
4252 };
4253
4254 #ifdef CDTV
4255 static int ip_mediacdtv[] =
4256 {
4257 INPUTEVENT_KEY_CDTV_PLAYPAUSE, INPUTEVENT_KEY_CDTV_STOP, INPUTEVENT_KEY_CDTV_PREV, INPUTEVENT_KEY_CDTV_NEXT,
4258 -1
4259 };
4260 #endif
4261
4262 #ifdef ARCADIA
4263 static int ip_arcadia[] = {
4264 INPUTEVENT_SPC_ARCADIA_DIAGNOSTICS, INPUTEVENT_SPC_ARCADIA_PLAYER1, INPUTEVENT_SPC_ARCADIA_PLAYER2,
4265 INPUTEVENT_SPC_ARCADIA_COIN1, INPUTEVENT_SPC_ARCADIA_COIN2,
4266 -1
4267 };
4268 #endif
4269
4270 static int ip_lightpen1[] = {
4271 INPUTEVENT_LIGHTPEN_HORIZ, INPUTEVENT_LIGHTPEN_VERT, INPUTEVENT_JOY1_3RD_BUTTON,
4272 -1
4273 };
4274 static int ip_lightpen2[] = {
4275 INPUTEVENT_LIGHTPEN_HORIZ, INPUTEVENT_LIGHTPEN_VERT, INPUTEVENT_JOY2_3RD_BUTTON,
4276 -1
4277 };
4278 static int ip_analog1[] = {
4279 INPUTEVENT_JOY1_HORIZ_POT, INPUTEVENT_JOY1_VERT_POT, INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT,
4280 -1
4281 };
4282 static int ip_analog2[] = {
4283 INPUTEVENT_JOY2_HORIZ_POT, INPUTEVENT_JOY2_VERT_POT, INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT,
4284 -1
4285 };
4286
4287 #ifdef ARCADIA
4288 static int ip_arcadiaxa[] = {
4289 -1
4290 };
4291 #endif
4292
checkcompakb(int * kb,int * srcmap)4293 static void checkcompakb (int *kb, int *srcmap)
4294 {
4295 int found = 0, avail = 0;
4296 int j, k;
4297
4298 k = j = 0;
4299 while (kb[j] >= 0) {
4300 struct uae_input_device *uid = &keyboards[0];
4301 while (kb[j] >= 0 && srcmap[k] >= 0) {
4302 int id = kb[j];
4303 for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
4304 if (uid->extra[l] == id) {
4305 avail++;
4306 if (uid->eventid[l][0] == srcmap[k])
4307 found++;
4308 break;
4309 }
4310 }
4311 j++;
4312 }
4313 if (srcmap[k] < 0)
4314 break;
4315 j++;
4316 k++;
4317 }
4318 if (avail != found || avail == 0)
4319 return;
4320 k = j = 0;
4321 while (kb[j] >= 0) {
4322 struct uae_input_device *uid = &keyboards[0];
4323 while (kb[j] >= 0) {
4324 int id = kb[j];
4325 /* REMOVEME:
4326 * nowhere used
4327 */
4328 #if 0
4329 int evt0 = 0, evt1 = 0;
4330 #endif
4331 k = 0;
4332 while (keyboard_default[k].scancode >= 0) {
4333 if (keyboard_default[k].scancode == kb[j]) {
4334 for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
4335 if (uid->extra[l] == id && uid->port[l][0] == 0) {
4336 for (int m = 0; m < MAX_INPUT_SUB_EVENT && keyboard_default[k].node[m].evt; m++) {
4337 uid->eventid[l][m] = keyboard_default[k].node[m].evt;
4338 uid->port[l][m] = 0;
4339 uid->flags[l][m] = 0;
4340 }
4341 break;
4342 }
4343 }
4344 break;
4345 }
4346 k++;
4347 }
4348 j++;
4349 }
4350 j++;
4351 }
4352 }
4353
setautofireevent(struct uae_input_device * uid,int num,int sub,int af,int index)4354 static void setautofireevent (struct uae_input_device *uid, int num, int sub, int af, int index)
4355 {
4356 if (!af)
4357 return;
4358 #ifdef RETROPLATFORM
4359 // don't override custom AF autofire mappings
4360 if (rp_isactive ())
4361 return;
4362 #endif
4363 int *afp = af_ports[index];
4364 for (int k = 0; afp[k] >= 0; k++) {
4365 if (afp[k] == uid->eventid[num][sub]) {
4366 uid->flags[num][sub] &= ~ID_FLAG_AUTOFIRE_MASK;
4367 if (af >= JPORT_AF_NORMAL)
4368 uid->flags[num][sub] |= ID_FLAG_AUTOFIRE;
4369 if (af == JPORT_AF_TOGGLE)
4370 uid->flags[num][sub] |= ID_FLAG_TOGGLE;
4371 if (af == JPORT_AF_ALWAYS)
4372 uid->flags[num][sub] |= ID_FLAG_INVERTTOGGLE;
4373 return;
4374 }
4375 }
4376 }
4377
inputdevice_sparerestore(struct uae_input_device * uid,int num,int sub)4378 static void inputdevice_sparerestore (struct uae_input_device *uid, int num, int sub)
4379 {
4380 if (uid->port[num][SPARE_SUB_EVENT]) {
4381 uid->eventid[num][sub] = uid->eventid[num][SPARE_SUB_EVENT];
4382 uid->flags[num][sub] = uid->flags[num][SPARE_SUB_EVENT];
4383 uid->custom[num][sub] = uid->custom[num][SPARE_SUB_EVENT];
4384 } else {
4385 uid->eventid[num][sub] = 0;
4386 uid->flags[num][sub] = 0;
4387 xfree (uid->custom[num][sub]);
4388 uid->custom[num][sub] = 0;
4389 }
4390 uid->eventid[num][SPARE_SUB_EVENT] = 0;
4391 uid->flags[num][SPARE_SUB_EVENT] = 0;
4392 uid->port[num][SPARE_SUB_EVENT] = 0;
4393 uid->custom[num][SPARE_SUB_EVENT] = 0;
4394 }
4395
inputdevice_sparecopy(struct uae_input_device * uid,int num,int sub)4396 void inputdevice_sparecopy (struct uae_input_device *uid, int num, int sub)
4397 {
4398 if (uid->port[num][SPARE_SUB_EVENT] != 0)
4399 return;
4400 if (uid->eventid[num][sub] <= 0 && uid->custom[num][sub] == NULL) {
4401 uid->eventid[num][SPARE_SUB_EVENT] = 0;
4402 uid->flags[num][SPARE_SUB_EVENT] = 0;
4403 uid->port[num][SPARE_SUB_EVENT] = 0;
4404 xfree (uid->custom[num][SPARE_SUB_EVENT]);
4405 uid->custom[num][SPARE_SUB_EVENT] = NULL;
4406 } else {
4407 uid->eventid[num][SPARE_SUB_EVENT] = uid->eventid[num][sub];
4408 uid->flags[num][SPARE_SUB_EVENT] = uid->flags[num][sub];
4409 uid->port[num][SPARE_SUB_EVENT] = MAX_JPORTS + 1;
4410 xfree (uid->custom[num][SPARE_SUB_EVENT]);
4411 uid->custom[num][SPARE_SUB_EVENT] = uid->custom[num][sub];
4412 uid->custom[num][sub] = NULL;
4413 }
4414 }
4415
setcompakb(int * kb,int * srcmap,int index,int af)4416 static void setcompakb (int *kb, int *srcmap, int index, int af)
4417 {
4418 int j, k;
4419 k = j = 0;
4420 while (kb[j] >= 0 && srcmap[k] >= 0) {
4421 while (kb[j] >= 0) {
4422 int id = kb[j];
4423 for (int m = 0; m < MAX_INPUT_DEVICES; m++) {
4424 struct uae_input_device *uid = &keyboards[m];
4425 for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
4426 if (uid->extra[l] == id) {
4427 inputdevice_sparecopy (uid, l, 0);
4428 uid->eventid[l][0] = srcmap[k];
4429 uid->flags[l][0] &= COMPA_RESERVED_FLAGS;
4430 uid->port[l][0] = index + 1;
4431 xfree (uid->custom[l][0]);
4432 uid->custom[l][0] = NULL;
4433 setautofireevent (uid, l, 0, af, index);
4434 break;
4435 }
4436 }
4437 }
4438 j++;
4439 }
4440 j++;
4441 k++;
4442 }
4443 }
4444
inputdevice_get_compatibility_input(struct uae_prefs * prefs,int index,int * typelist,int * inputlist,const int ** at)4445 int inputdevice_get_compatibility_input (struct uae_prefs *prefs, int index, int *typelist, int *inputlist, const int **at)
4446 {
4447 if (index >= MAX_JPORTS || joymodes[index] < 0)
4448 return -1;
4449 if (typelist != NULL)
4450 *typelist = joymodes[index];
4451 if (at != NULL)
4452 *at = axistable;
4453 if (inputlist == NULL)
4454 return -1;
4455
4456 //write_log (_T("%d %p %p\n"), *typelist, *inputlist, *at);
4457 int cnt;
4458 for (cnt = 0; joyinputs[index] && joyinputs[index][cnt] >= 0; cnt++) {
4459 inputlist[cnt] = joyinputs[index][cnt];
4460 }
4461 inputlist[cnt] = -1;
4462
4463 // find custom events (custom event = event that is mapped to same port but not included in joyinputs[]
4464 int devnum = 0;
4465 while (inputdevice_get_device_status (devnum) >= 0) {
4466 for (int j = 0; j < inputdevice_get_widget_num (devnum); j++) {
4467 for (int sub = 0; sub < MAX_INPUT_SUB_EVENT; sub++) {
4468 int port, k, l;
4469 uae_u64 flags;
4470 bool ignore = false;
4471 int evtnum2 = inputdevice_get_mapping (devnum, j, &flags, &port, NULL, NULL, sub);
4472 if (port - 1 != index)
4473 continue;
4474 for (k = 0; axistable[k] >= 0; k += 3) {
4475 if (evtnum2 == axistable[k] || evtnum2 == axistable[k + 1] || evtnum2 == axistable[k + 2]) {
4476 for (l = 0; inputlist[l] >= 0; l++) {
4477 if (inputlist[l] == axistable[k] || inputlist[l] == axistable[k + 1] || inputlist[l] == axistable[k + 1]) {
4478 ignore = true;
4479 }
4480 }
4481 }
4482 }
4483 if (!ignore) {
4484 for (k = 0; inputlist[k] >= 0; k++) {
4485 if (evtnum2 == inputlist[k])
4486 break;
4487 }
4488 if (inputlist[k] < 0) {
4489 inputlist[k] = evtnum2;
4490 inputlist[k + 1] = -1;
4491 cnt++;
4492 }
4493 }
4494 }
4495 }
4496 devnum++;
4497 }
4498
4499 //write_log (_T("%d\n"), cnt);
4500 return cnt;
4501 }
4502
clearevent(struct uae_input_device * uid,int evt)4503 static void clearevent (struct uae_input_device *uid, int evt)
4504 {
4505 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
4506 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
4507 if (uid->eventid[i][j] == evt) {
4508 uid->eventid[i][j] = 0;
4509 uid->flags[i][j] &= COMPA_RESERVED_FLAGS;
4510 xfree (uid->custom[i][j]);
4511 uid->custom[i][j] = NULL;
4512 }
4513 }
4514 }
4515 }
clearkbrevent(struct uae_input_device * uid,int evt)4516 static void clearkbrevent (struct uae_input_device *uid, int evt)
4517 {
4518 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
4519 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
4520 if (uid->eventid[i][j] == evt) {
4521 uid->eventid[i][j] = 0;
4522 uid->flags[i][j] &= COMPA_RESERVED_FLAGS;
4523 xfree (uid->custom[i][j]);
4524 uid->custom[i][j] = NULL;
4525 if (j == 0)
4526 set_kbr_default_event (uid, keyboard_default, i);
4527 }
4528 }
4529 }
4530 }
4531
resetjport(struct uae_prefs * prefs,int index)4532 static void resetjport (struct uae_prefs *prefs, int index)
4533 {
4534 int *p = rem_ports[index];
4535 while (*p >= 0) {
4536 int evtnum = *p++;
4537 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
4538 clearevent (&prefs->joystick_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum);
4539 clearevent (&prefs->mouse_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum);
4540 clearkbrevent (&prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum);
4541 }
4542 for (int i = 0; axistable[i] >= 0; i += 3) {
4543 if (evtnum == axistable[i] || evtnum == axistable[i + 1] || evtnum == axistable[i + 2]) {
4544 for (int j = 0; j < 3; j++) {
4545 int evtnum2 = axistable[i + j];
4546 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
4547 clearevent (&prefs->joystick_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum2);
4548 clearevent (&prefs->mouse_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum2);
4549 clearkbrevent (&prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum2);
4550 }
4551 }
4552 break;
4553 }
4554 }
4555 }
4556 }
4557
remove_compa_config(struct uae_prefs * prefs,int index)4558 static void remove_compa_config (struct uae_prefs *prefs, int index)
4559 {
4560 int typelist;
4561 const int *atp;
4562 int inputlist[MAX_COMPA_INPUTLIST];
4563
4564 if (inputdevice_get_compatibility_input (prefs, index, &typelist, inputlist, &atp) <= 0)
4565 return;
4566 for (int i = 0; inputlist[i] >= 0; i++) {
4567 int evtnum = inputlist[i];
4568
4569 int atpidx = 0;
4570 while (*atp >= 0) {
4571 if (*atp == evtnum) {
4572 atp++;
4573 atpidx = 2;
4574 break;
4575 }
4576 if (atp[1] == evtnum || atp[2] == evtnum) {
4577 atpidx = 1;
4578 break;
4579 }
4580 atp += 3;
4581 }
4582 while (atpidx >= 0) {
4583 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
4584 clearevent (&prefs->joystick_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum);
4585 clearevent (&prefs->mouse_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum);
4586 clearkbrevent (&prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS][l], evtnum);
4587 }
4588 evtnum = *atp++;
4589 atpidx--;
4590 }
4591 }
4592 }
4593
cleardevgp(struct uae_input_device * uid,int num,bool nocustom,int index)4594 static void cleardevgp (struct uae_input_device *uid, int num, bool nocustom, int index)
4595 {
4596 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
4597 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
4598 if (uid[num].port[i][j] == index + 1) {
4599 if (nocustom && (uid[num].flags[i][j] & ID_FLAG_GAMEPORTSCUSTOM_MASK))
4600 continue;
4601 uid[num].eventid[i][j] = 0;
4602 uid[num].flags[i][j] &= COMPA_RESERVED_FLAGS;
4603 xfree (uid[num].custom[i][j]);
4604 uid[num].custom[i][j] = NULL;
4605 uid[num].port[i][j] = 0;
4606 if (uid[num].port[i][SPARE_SUB_EVENT])
4607 inputdevice_sparerestore (&uid[num], i, j);
4608 }
4609 }
4610 }
4611 }
cleardevkbrgp(struct uae_input_device * uid,int num,bool nocustom,int index)4612 static void cleardevkbrgp (struct uae_input_device *uid, int num, bool nocustom, int index)
4613 {
4614 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
4615 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
4616 if (uid[num].port[i][j] == index + 1) {
4617 if (nocustom && (uid[num].flags[i][j] & ID_FLAG_GAMEPORTSCUSTOM_MASK))
4618 continue;
4619 uid[num].eventid[i][j] = 0;
4620 uid[num].flags[i][j] &= COMPA_RESERVED_FLAGS;
4621 xfree (uid[num].custom[i][j]);
4622 uid[num].custom[i][j] = NULL;
4623 uid[num].port[i][j] = 0;
4624 if (uid[num].port[i][SPARE_SUB_EVENT]) {
4625 inputdevice_sparerestore (&uid[num], i, j);
4626 } else if (j == 0) {
4627 set_kbr_default_event (&uid[num], keyboard_default, i);
4628 }
4629 }
4630 }
4631 }
4632 }
4633
4634 // remove all gameports mappings mapped to port 'index'
remove_custom_config(struct uae_prefs * prefs,bool nocustom,int index)4635 static void remove_custom_config (struct uae_prefs *prefs, bool nocustom, int index)
4636 {
4637 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
4638 cleardevgp (joysticks, l, nocustom, index);
4639 cleardevgp (mice, l, nocustom, index);
4640 cleardevkbrgp (keyboards, l, nocustom, index);
4641 }
4642 }
4643
4644 // prepare port for custom mapping, remove all current Amiga side device mappings
inputdevice_compa_prepare_custom(struct uae_prefs * prefs,int index,int newmode,bool removeold)4645 void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int newmode, bool removeold)
4646 {
4647 int mode = prefs->jports[index].mode;
4648 freejport (prefs, index);
4649 resetjport (prefs, index);
4650 if (newmode >= 0) {
4651 mode = newmode;
4652 } else if (mode == 0) {
4653 mode = index == 0 ? JSEM_MODE_WHEELMOUSE : (prefs->cs_cd32cd ? JSEM_MODE_JOYSTICK_CD32 : JSEM_MODE_JOYSTICK);
4654 }
4655 prefs->jports[index].mode = mode;
4656 prefs->jports[index].id = JPORT_CUSTOM;
4657
4658 if (removeold) {
4659 remove_compa_config (prefs, index);
4660 remove_custom_config (prefs, false, index);
4661 }
4662 }
4663 // clear device before switching to new one
inputdevice_compa_clear(struct uae_prefs * prefs,int index)4664 void inputdevice_compa_clear (struct uae_prefs *prefs, int index)
4665 {
4666 freejport (prefs, index);
4667 resetjport (prefs, index);
4668 remove_compa_config (prefs, index);
4669 }
4670
cleardev(struct uae_input_device * uid,int num)4671 static void cleardev (struct uae_input_device *uid, int num)
4672 {
4673 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
4674 inputdevice_sparecopy (&uid[num], i, 0);
4675 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
4676 uid[num].eventid[i][j] = 0;
4677 uid[num].flags[i][j] = 0;
4678 xfree (uid[num].custom[i][j]);
4679 uid[num].custom[i][j] = NULL;
4680 }
4681 }
4682 }
4683
enablejoydevice(struct uae_input_device * uid,bool gameportsmode,int evtnum)4684 static void enablejoydevice (struct uae_input_device *uid, bool gameportsmode, int evtnum)
4685 {
4686 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
4687 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
4688 if ((gameportsmode && uid->eventid[i][j] == evtnum) || uid->port[i][j] > 0) {
4689 uid->enabled = 1;
4690 }
4691 }
4692 }
4693 }
4694
setjoydevices(struct uae_prefs * prefs,bool gameportsmode,int port)4695 static void setjoydevices (struct uae_prefs *prefs, bool gameportsmode, int port)
4696 {
4697 for (int i = 0; joyinputs[port] && joyinputs[port][i] >= 0; i++) {
4698 int evtnum = joyinputs[port][i];
4699 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
4700 enablejoydevice (&joysticks[l], gameportsmode, evtnum);
4701 enablejoydevice (&mice[l], gameportsmode, evtnum);
4702 enablejoydevice (&keyboards[l], gameportsmode, evtnum);
4703 }
4704 for (int k = 0; axistable[k] >= 0; k += 3) {
4705 if (evtnum == axistable[k] || evtnum == axistable[k + 1] || evtnum == axistable[k + 2]) {
4706 for (int j = 0; j < 3; j++) {
4707 int evtnum2 = axistable[k + j];
4708 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
4709 enablejoydevice (&joysticks[l], gameportsmode, evtnum2);
4710 enablejoydevice (&mice[l], gameportsmode, evtnum2);
4711 enablejoydevice (&keyboards[l], gameportsmode, evtnum2);
4712 }
4713 }
4714 break;
4715 }
4716 }
4717
4718 }
4719 }
4720
setjoyinputs(struct uae_prefs * prefs,int port)4721 static void setjoyinputs (struct uae_prefs *prefs, int port)
4722 {
4723 joyinputs[port] = NULL;
4724 switch (joymodes[port])
4725 {
4726 case JSEM_MODE_JOYSTICK:
4727 if (port >= 2)
4728 joyinputs[port] = port == 3 ? ip_parjoy2 : ip_parjoy1;
4729 else
4730 joyinputs[port] = port == 1 ? ip_joy2 : ip_joy1;
4731 break;
4732 case JSEM_MODE_GAMEPAD:
4733 joyinputs[port] = port ? ip_joypad2 : ip_joypad1;
4734 break;
4735 case JSEM_MODE_JOYSTICK_CD32:
4736 joyinputs[port] = port ? ip_joycd322 : ip_joycd321;
4737 break;
4738 case JSEM_MODE_JOYSTICK_ANALOG:
4739 joyinputs[port] = port ? ip_analog2 : ip_analog1;
4740 break;
4741 case JSEM_MODE_WHEELMOUSE:
4742 case JSEM_MODE_MOUSE:
4743 joyinputs[port] = port ? ip_mouse2 : ip_mouse1;
4744 break;
4745 case JSEM_MODE_LIGHTPEN:
4746 joyinputs[port] = port ? ip_lightpen2 : ip_lightpen1;
4747 break;
4748 case JSEM_MODE_MOUSE_CDTV:
4749 joyinputs[port] = ip_mousecdtv;
4750 break;
4751 }
4752 }
4753
setautofire(struct uae_input_device * uid,int port,int af)4754 static void setautofire (struct uae_input_device *uid, int port, int af)
4755 {
4756 int *afp = af_ports[port];
4757 for (int k = 0; afp[k] >= 0; k++) {
4758 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
4759 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
4760 if (uid->eventid[i][j] == afp[k]) {
4761 uid->flags[i][j] &= ~ID_FLAG_AUTOFIRE_MASK;
4762 if (af >= JPORT_AF_NORMAL)
4763 uid->flags[i][j] |= ID_FLAG_AUTOFIRE;
4764 if (af == JPORT_AF_TOGGLE)
4765 uid->flags[i][j] |= ID_FLAG_TOGGLE;
4766 if (af == JPORT_AF_ALWAYS)
4767 uid->flags[i][j] |= ID_FLAG_INVERTTOGGLE;
4768 }
4769 }
4770 }
4771 }
4772 }
4773
setautofires(struct uae_prefs * prefs,int port,int af)4774 static void setautofires (struct uae_prefs *prefs, int port, int af)
4775 {
4776 #ifdef RETROPLATFORM
4777 // don't override custom AF autofire mappings
4778 if (rp_isactive ())
4779 return;
4780 #endif
4781 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
4782 setautofire (&joysticks[l], port, af);
4783 setautofire (&mice[l], port, af);
4784 setautofire (&keyboards[l], port, af);
4785 }
4786 }
4787
4788 // merge gameport settings with current input configuration
compatibility_copy(struct uae_prefs * prefs,bool gameports)4789 static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
4790 {
4791 int used[MAX_INPUT_DEVICES] = { 0 };
4792 int i, joy;
4793
4794 for (i = 0; i < MAX_JPORTS; i++) {
4795 joymodes[i] = prefs->jports[i].mode;
4796 joyinputs[i]= NULL;
4797 // remove all mappings from this port, except if custom
4798 if (prefs->jports[i].id != JPORT_CUSTOM) {
4799 if (gameports)
4800 remove_compa_config (prefs, i);
4801 }
4802 remove_custom_config (prefs, prefs->jports[i].id == JPORT_CUSTOM, i);
4803 setjoyinputs (prefs, i);
4804 }
4805
4806 for (i = 0; i < 2; i++) {
4807 /* REMOVEME:
4808 * nowhere used
4809 */
4810 #if 0
4811 int af = prefs->jports[i].autofire;
4812 #endif
4813 if (prefs->jports[i].id >= 0 && joymodes[i] <= 0) {
4814 int mode = prefs->jports[i].mode;
4815 if (jsem_ismouse (i, prefs) >= 0) {
4816 switch (mode)
4817 {
4818 case JSEM_MODE_DEFAULT:
4819 case JSEM_MODE_MOUSE:
4820 case JSEM_MODE_WHEELMOUSE:
4821 default:
4822 joymodes[i] = JSEM_MODE_WHEELMOUSE;
4823 joyinputs[i] = i ? ip_mouse2 : ip_mouse1;
4824 break;
4825 case JSEM_MODE_LIGHTPEN:
4826 joymodes[i] = JSEM_MODE_LIGHTPEN;
4827 joyinputs[i] = i ? ip_lightpen2 : ip_lightpen1;
4828 break;
4829 case JSEM_MODE_MOUSE_CDTV:
4830 joymodes[i] = JSEM_MODE_MOUSE_CDTV;
4831 joyinputs[i] = ip_mousecdtv;
4832 break;
4833 }
4834 } else if (jsem_isjoy (i, prefs) >= 0) {
4835 switch (mode)
4836 {
4837 case JSEM_MODE_DEFAULT:
4838 case JSEM_MODE_JOYSTICK:
4839 case JSEM_MODE_GAMEPAD:
4840 case JSEM_MODE_JOYSTICK_CD32:
4841 default:
4842 {
4843 bool iscd32 = mode == JSEM_MODE_JOYSTICK_CD32 || (mode == JSEM_MODE_DEFAULT && prefs->cs_cd32cd);
4844 if (iscd32) {
4845 joymodes[i] = JSEM_MODE_JOYSTICK_CD32;
4846 joyinputs[i] = i ? ip_joycd322 : ip_joycd321;
4847 } else if (mode == JSEM_MODE_GAMEPAD) {
4848 joymodes[i] = JSEM_MODE_GAMEPAD;
4849 joyinputs[i] = i ? ip_joypad2 : ip_joypad1;
4850 } else {
4851 joymodes[i] = JSEM_MODE_JOYSTICK;
4852 joyinputs[i] = i ? ip_joy2 : ip_joy1;
4853 }
4854 break;
4855 }
4856 case JSEM_MODE_JOYSTICK_ANALOG:
4857 joymodes[i] = JSEM_MODE_JOYSTICK_ANALOG;
4858 joyinputs[i] = i ? ip_analog2 : ip_analog1;
4859 break;
4860 case JSEM_MODE_MOUSE:
4861 case JSEM_MODE_WHEELMOUSE:
4862 joymodes[i] = JSEM_MODE_WHEELMOUSE;
4863 joyinputs[i] = i ? ip_mouse2 : ip_mouse1;
4864 break;
4865 case JSEM_MODE_LIGHTPEN:
4866 joymodes[i] = JSEM_MODE_LIGHTPEN;
4867 joyinputs[i] = i ? ip_lightpen2 : ip_lightpen1;
4868 break;
4869 case JSEM_MODE_MOUSE_CDTV:
4870 joymodes[i] = JSEM_MODE_MOUSE_CDTV;
4871 joyinputs[i] = ip_mousecdtv;
4872 break;
4873 }
4874 } else if (prefs->jports[i].id >= 0) {
4875 joymodes[i] = i ? JSEM_MODE_JOYSTICK : JSEM_MODE_WHEELMOUSE;
4876 joyinputs[i] = i ? ip_joy2 : ip_mouse1;
4877 }
4878 }
4879 }
4880
4881 for (i = 2; i < MAX_JPORTS; i++) {
4882 if (prefs->jports[i].id >= 0 && joymodes[i] <= 0) {
4883 /* REMOVEME:
4884 * nowhere used
4885 */
4886 #if 0
4887 int mode = prefs->jports[i].mode;
4888 #endif
4889 if (jsem_isjoy (i, prefs) >= 0) {
4890 joymodes[i] = JSEM_MODE_JOYSTICK;
4891 joyinputs[i] = i == 3 ? ip_parjoy2 : ip_parjoy1;
4892 } else if (prefs->jports[i].id >= 0) {
4893 prefs->jports[i].mode = joymodes[i] = JSEM_MODE_JOYSTICK;
4894 joyinputs[i] = i == 3 ? ip_parjoy2 : ip_parjoy1;
4895 }
4896 }
4897 }
4898
4899 for (i = 0; i < 2; i++) {
4900 int af = prefs->jports[i].autofire;
4901 if (prefs->jports[i].id >= 0) {
4902 int mode = prefs->jports[i].mode;
4903 if ((joy = jsem_ismouse (i, prefs)) >= 0) {
4904 if (gameports)
4905 cleardev (mice, joy);
4906 switch (mode)
4907 {
4908 case JSEM_MODE_DEFAULT:
4909 case JSEM_MODE_MOUSE:
4910 case JSEM_MODE_WHEELMOUSE:
4911 default:
4912 input_get_default_mouse (mice, joy, i, af, !gameports, mode != JSEM_MODE_MOUSE);
4913 joymodes[i] = JSEM_MODE_WHEELMOUSE;
4914 break;
4915 case JSEM_MODE_LIGHTPEN:
4916 input_get_default_lightpen (mice, joy, i, af, !gameports);
4917 joymodes[i] = JSEM_MODE_LIGHTPEN;
4918 break;
4919 }
4920 _tcsncpy (prefs->jports[i].name, idev[IDTYPE_MOUSE].get_friendlyname (joy), MAX_JPORTNAME - 1);
4921 _tcsncpy (prefs->jports[i].configname, idev[IDTYPE_MOUSE].get_uniquename (joy), MAX_JPORTNAME - 1);
4922 }
4923 }
4924 }
4925
4926 for (i = 1; i >= 0; i--) {
4927 int af = prefs->jports[i].autofire;
4928 if (prefs->jports[i].id >= 0) {
4929 int mode = prefs->jports[i].mode;
4930 joy = jsem_isjoy (i, prefs);
4931 if (joy >= 0) {
4932 if (gameports)
4933 cleardev (joysticks, joy);
4934 switch (mode)
4935 {
4936 case JSEM_MODE_DEFAULT:
4937 case JSEM_MODE_JOYSTICK:
4938 case JSEM_MODE_GAMEPAD:
4939 case JSEM_MODE_JOYSTICK_CD32:
4940 default:
4941 {
4942 bool iscd32 = mode == JSEM_MODE_JOYSTICK_CD32 || (mode == JSEM_MODE_DEFAULT && prefs->cs_cd32cd);
4943 input_get_default_joystick (joysticks, joy, i, af, mode, !gameports);
4944 if (iscd32)
4945 joymodes[i] = JSEM_MODE_JOYSTICK_CD32;
4946 else if (mode == JSEM_MODE_GAMEPAD)
4947 joymodes[i] = JSEM_MODE_GAMEPAD;
4948 else
4949 joymodes[i] = JSEM_MODE_JOYSTICK;
4950 break;
4951 }
4952 case JSEM_MODE_JOYSTICK_ANALOG:
4953 input_get_default_joystick_analog (joysticks, joy, i, af, !gameports);
4954 joymodes[i] = JSEM_MODE_JOYSTICK_ANALOG;
4955 break;
4956 case JSEM_MODE_MOUSE:
4957 case JSEM_MODE_WHEELMOUSE:
4958 input_get_default_mouse (joysticks, joy, i, af, !gameports, mode == JSEM_MODE_WHEELMOUSE);
4959 joymodes[i] = JSEM_MODE_WHEELMOUSE;
4960 break;
4961 case JSEM_MODE_LIGHTPEN:
4962 input_get_default_lightpen (joysticks, joy, i, af, !gameports);
4963 joymodes[i] = JSEM_MODE_LIGHTPEN;
4964 break;
4965 case JSEM_MODE_MOUSE_CDTV:
4966 joymodes[i] = JSEM_MODE_MOUSE_CDTV;
4967 input_get_default_joystick (joysticks, joy, i, af, mode, !gameports);
4968 break;
4969
4970 }
4971 _tcsncpy (prefs->jports[i].name, idev[IDTYPE_JOYSTICK].get_friendlyname (joy), MAX_JPORTNAME - 1);
4972 _tcsncpy (prefs->jports[i].configname, idev[IDTYPE_JOYSTICK].get_uniquename (joy), MAX_JPORTNAME - 1);
4973 used[joy] = 1;
4974 }
4975 }
4976 }
4977
4978 if (gameports) {
4979 // replace possible old mappings with default keyboard mapping
4980 for (i = KBR_DEFAULT_MAP_FIRST; i <= KBR_DEFAULT_MAP_LAST; i++) {
4981 checkcompakb (keyboard_default_kbmaps[i], ip_joy2);
4982 checkcompakb (keyboard_default_kbmaps[i], ip_joy1);
4983 checkcompakb (keyboard_default_kbmaps[i], ip_joypad2);
4984 checkcompakb (keyboard_default_kbmaps[i], ip_joypad1);
4985 checkcompakb (keyboard_default_kbmaps[i], ip_parjoy2);
4986 checkcompakb (keyboard_default_kbmaps[i], ip_parjoy1);
4987 checkcompakb (keyboard_default_kbmaps[i], ip_mouse2);
4988 checkcompakb (keyboard_default_kbmaps[i], ip_mouse1);
4989 }
4990 for (i = KBR_DEFAULT_MAP_CD32_FIRST; i <= KBR_DEFAULT_MAP_CD32_LAST; i++) {
4991 checkcompakb (keyboard_default_kbmaps[i], ip_joycd321);
4992 checkcompakb (keyboard_default_kbmaps[i], ip_joycd322);
4993 }
4994 }
4995
4996 for (i = 0; i < 2; i++) {
4997 if (prefs->jports[i].id >= 0) {
4998 int *kb = NULL;
4999 int mode = prefs->jports[i].mode;
5000 int af = prefs->jports[i].autofire;
5001 for (joy = 0; used[joy]; joy++);
5002 if (JSEM_ISANYKBD (i, prefs)) {
5003 bool cd32 = mode == JSEM_MODE_JOYSTICK_CD32 || (mode == JSEM_MODE_DEFAULT && prefs->cs_cd32cd);
5004 if (JSEM_ISNUMPAD (i, prefs)) {
5005 if (cd32)
5006 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CD32_NP];
5007 else if (mode == JSEM_MODE_GAMEPAD)
5008 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_NP3];
5009 else
5010 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_NP];
5011 } else if (JSEM_ISCURSOR (i, prefs)) {
5012 if (cd32)
5013 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CD32_CK];
5014 else if (mode == JSEM_MODE_GAMEPAD)
5015 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CK3];
5016 else
5017 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CK];
5018 } else if (JSEM_ISSOMEWHEREELSE (i, prefs)) {
5019 if (cd32)
5020 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CD32_SE];
5021 else if (mode == JSEM_MODE_GAMEPAD)
5022 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE3];
5023 else
5024 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE];
5025 } else if (JSEM_ISXARCADE1 (i, prefs)) {
5026 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA1];
5027 } else if (JSEM_ISXARCADE2 (i, prefs)) {
5028 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA2];
5029 }
5030 if (kb) {
5031 switch (mode)
5032 {
5033 case JSEM_MODE_JOYSTICK:
5034 case JSEM_MODE_GAMEPAD:
5035 case JSEM_MODE_JOYSTICK_CD32:
5036 case JSEM_MODE_DEFAULT:
5037 if (cd32) {
5038 setcompakb (kb, i ? ip_joycd322 : ip_joycd321, i, af);
5039 joymodes[i] = JSEM_MODE_JOYSTICK_CD32;
5040 } else if (mode == JSEM_MODE_GAMEPAD) {
5041 setcompakb (kb, i ? ip_joypad2 : ip_joypad1, i, af);
5042 joymodes[i] = JSEM_MODE_GAMEPAD;
5043 } else {
5044 setcompakb (kb, i ? ip_joy2 : ip_joy1, i, af);
5045 joymodes[i] = JSEM_MODE_JOYSTICK;
5046 }
5047 break;
5048 case JSEM_MODE_MOUSE:
5049 case JSEM_MODE_WHEELMOUSE:
5050 setcompakb (kb, i ? ip_mouse2 : ip_mouse1, i, af);
5051 joymodes[i] = JSEM_MODE_WHEELMOUSE;
5052 break;
5053 }
5054 used[joy] = 1;
5055 }
5056 }
5057 }
5058 }
5059 #ifdef ARCADIA
5060 if (arcadia_bios) {
5061 setcompakb (keyboard_default_kbmaps[KBR_DEFAULT_MAP_ARCADIA], ip_arcadia, 0, 0);
5062 if (JSEM_ISXARCADE1 (i, prefs) || JSEM_ISXARCADE2 (i, prefs))
5063 setcompakb (keyboard_default_kbmaps[KBR_DEFAULT_MAP_ARCADIA_XA], ip_arcadiaxa, JSEM_ISXARCADE2 (i, prefs) ? 1 : 0, prefs->jports[i].autofire);
5064 }
5065 #endif
5066 #ifdef CDTV
5067 if (0 && currprefs.cs_cdtvcd) {
5068 setcompakb (keyboard_default_kbmaps[KBR_DEFAULT_MAP_CDTV], ip_mediacdtv, 0, 0);
5069 }
5070 #endif
5071 // parport
5072 for (i = 2; i < MAX_JPORTS; i++) {
5073 int af = prefs->jports[i].autofire;
5074 if (prefs->jports[i].id >= 0) {
5075 /* REMOVEME:
5076 * nowhere used
5077 */
5078 #if 0
5079 int *kb = NULL;
5080 #endif
5081 joy = jsem_isjoy (i, prefs);
5082 if (joy >= 0) {
5083 if (gameports)
5084 cleardev (joysticks, joy);
5085 input_get_default_joystick (joysticks, joy, i, af, 0, !gameports);
5086 _tcsncpy (prefs->jports[i].name, idev[IDTYPE_JOYSTICK].get_friendlyname (joy), MAX_JPORTNAME - 1);
5087 _tcsncpy (prefs->jports[i].configname, idev[IDTYPE_JOYSTICK].get_uniquename (joy), MAX_JPORTNAME - 1);
5088 used[joy] = 1;
5089 joymodes[i] = JSEM_MODE_JOYSTICK;
5090 }
5091 }
5092 }
5093 for (i = 2; i < MAX_JPORTS; i++) {
5094 if (prefs->jports[i].id >= 0) {
5095 int *kb = NULL;
5096 for (joy = 0; used[joy]; joy++);
5097 if (JSEM_ISANYKBD (i, prefs)) {
5098 if (JSEM_ISNUMPAD (i, prefs))
5099 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_NP];
5100 else if (JSEM_ISCURSOR (i, prefs))
5101 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CK];
5102 else if (JSEM_ISSOMEWHEREELSE (i, prefs))
5103 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE];
5104 else if (JSEM_ISXARCADE1 (i, prefs))
5105 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA1];
5106 else if (JSEM_ISXARCADE2 (i, prefs))
5107 kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA2];
5108 if (kb) {
5109 setcompakb (kb, i == 3 ? ip_parjoy2default : ip_parjoy1default, i, prefs->jports[i].autofire);
5110 used[joy] = 1;
5111 joymodes[i] = JSEM_MODE_JOYSTICK;
5112 }
5113 }
5114 }
5115 }
5116
5117 for (i = 0; i < MAX_JPORTS; i++) {
5118 if (gameports)
5119 setautofires (prefs, i, prefs->jports[i].autofire);
5120 }
5121
5122 for (i = 0; i < MAX_JPORTS; i++) {
5123 setjoyinputs (prefs, i);
5124 setjoydevices (prefs, gameports, i);
5125 }
5126 }
5127
disableifempty2(struct uae_input_device * uid)5128 static void disableifempty2 (struct uae_input_device *uid)
5129 {
5130 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
5131 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
5132 if (uid->eventid[i][j] > 0 || uid->custom[i][j] != NULL)
5133 return;
5134 }
5135 }
5136 uid->enabled = false;
5137 }
disableifempty(struct uae_prefs * prefs)5138 static void disableifempty (struct uae_prefs *prefs)
5139 {
5140 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
5141 disableifempty2 (&joysticks[l]);
5142 disableifempty2 (&mice[l]);
5143 disableifempty2 (&keyboards[l]);
5144 }
5145 prefs->internalevent_settings[0]->enabled = true;
5146 }
5147
matchdevices(struct inputdevice_functions * inf,struct uae_input_device * uid)5148 static void matchdevices (struct inputdevice_functions *inf, struct uae_input_device *uid)
5149 {
5150 int i, j;
5151
5152 for (i = 0; i < inf->get_num (); i++) {
5153 TCHAR *aname1 = inf->get_friendlyname (i);
5154 TCHAR *aname2 = inf->get_uniquename (i);
5155 int match = -1;
5156 for (j = 0; j < MAX_INPUT_DEVICES; j++) {
5157 if (aname2 && uid[j].configname) {
5158 bool matched = false;
5159 TCHAR bname[MAX_DPATH];
5160 TCHAR bname2[MAX_DPATH];
5161 TCHAR *p1 ,*p2;
5162 _tcscpy (bname, uid[j].configname);
5163 _tcscpy (bname2, aname2);
5164 // strip possible local guid part
5165 p1 = _tcschr (bname, '{');
5166 p2 = _tcschr (bname2, '{');
5167 if (!p1 && !p2) {
5168 // check possible directinput names too
5169 p1 = _tcschr (bname, ' ');
5170 p2 = _tcschr (bname2, ' ');
5171 }
5172 if (!_tcscmp (bname, bname2)) {
5173 matched = true;
5174 } else if (p1 && p2 && p1 - bname == p2 - bname2) {
5175 *p1 = 0;
5176 *p2 = 0;
5177 if (bname && !_tcscmp (bname2, bname))
5178 matched = true;
5179 }
5180 if (matched) {
5181 if (match >= 0)
5182 match = -2;
5183 else
5184 match = j;
5185 }
5186 if (match == -2)
5187 break;
5188 }
5189 }
5190 // multiple matches -> use complete local-only id string for comparisons
5191 if (match == -2) {
5192 for (j = 0; j < MAX_INPUT_DEVICES; j++) {
5193 TCHAR *bname2 = uid[j].configname;
5194 if (aname2 && bname2 && !_tcscmp (aname2, bname2)) {
5195 match = j;
5196 break;
5197 }
5198 }
5199 }
5200 if (match < 0) {
5201 // no match, try friend names
5202 for (j = 0; j < MAX_INPUT_DEVICES; j++) {
5203 TCHAR *bname1 = uid[j].name;
5204 if (aname1 && bname1 && !_tcscmp (aname1, bname1)) {
5205 match = j;
5206 break;
5207 }
5208 }
5209 }
5210 if (match >= 0) {
5211 j = match;
5212 if (j != i) {
5213 struct uae_input_device *tmp = xmalloc (struct uae_input_device, 1);
5214 memcpy (tmp, &uid[j], sizeof (struct uae_input_device));
5215 memcpy (&uid[j], &uid[i], sizeof (struct uae_input_device));
5216 memcpy (&uid[i], tmp, sizeof (struct uae_input_device));
5217 xfree (tmp);
5218 }
5219 }
5220 }
5221 for (i = 0; i < inf->get_num (); i++) {
5222 if (uid[i].name == NULL)
5223 uid[i].name = my_strdup (inf->get_friendlyname (i));
5224 if (uid[i].configname == NULL)
5225 uid[i].configname = my_strdup (inf->get_uniquename (i));
5226 }
5227 }
5228
matchdevices_all(struct uae_prefs * prefs)5229 static void matchdevices_all (struct uae_prefs *prefs)
5230 {
5231 int i;
5232 for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
5233 matchdevices (&idev[IDTYPE_MOUSE], prefs->mouse_settings[i]);
5234 matchdevices (&idev[IDTYPE_JOYSTICK], prefs->joystick_settings[i]);
5235 matchdevices (&idev[IDTYPE_KEYBOARD], prefs->keyboard_settings[i]);
5236 }
5237 }
5238
inputdevice_set_gameports_mapping(struct uae_prefs * prefs,int devnum,int num,int evtnum,uae_u64 flags,int port)5239 bool inputdevice_set_gameports_mapping (struct uae_prefs *prefs, int devnum, int num, int evtnum, uae_u64 flags, int port)
5240 {
5241 TCHAR name[256];
5242 struct inputevent *ie;
5243 int sub;
5244
5245 if (evtnum < 0) {
5246 joysticks = prefs->joystick_settings[GAMEPORT_INPUT_SETTINGS];
5247 mice = prefs->mouse_settings[GAMEPORT_INPUT_SETTINGS];
5248 keyboards = prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS];
5249 for (sub = 0; sub < MAX_INPUT_SUB_EVENT; sub++) {
5250 int port2 = 0;
5251 inputdevice_get_mapping (devnum, num, NULL, &port2, NULL, NULL, sub);
5252 if (port2 == port + 1) {
5253 inputdevice_set_mapping (devnum, num, NULL, NULL, 0, 0, sub);
5254 }
5255 }
5256 return true;
5257 }
5258 ie = inputdevice_get_eventinfo (evtnum);
5259 if (!inputdevice_get_eventname (ie, name))
5260 return false;
5261 joysticks = prefs->joystick_settings[GAMEPORT_INPUT_SETTINGS];
5262 mice = prefs->mouse_settings[GAMEPORT_INPUT_SETTINGS];
5263 keyboards = prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS];
5264
5265 sub = 0;
5266 if (inputdevice_get_widget_type (devnum, num, NULL) != IDEV_WIDGET_KEY) {
5267 for (sub = 0; sub < MAX_INPUT_SUB_EVENT; sub++) {
5268 int port2 = 0;
5269 int evt = inputdevice_get_mapping (devnum, num, NULL, &port2, NULL, NULL, sub);
5270 if (port2 == port + 1 && evt == evtnum)
5271 break;
5272 if (!inputdevice_get_mapping (devnum, num, NULL, NULL, NULL, NULL, sub))
5273 break;
5274 }
5275 }
5276 if (sub >= MAX_INPUT_SUB_EVENT)
5277 sub = MAX_INPUT_SUB_EVENT - 1;
5278 inputdevice_set_mapping (devnum, num, name, NULL, IDEV_MAPPED_GAMEPORTSCUSTOM1 | flags, port + 1, sub);
5279
5280 joysticks = prefs->joystick_settings[prefs->input_selected_setting];
5281 mice = prefs->mouse_settings[prefs->input_selected_setting];
5282 keyboards = prefs->keyboard_settings[prefs->input_selected_setting];
5283
5284 if (prefs->input_selected_setting != GAMEPORT_INPUT_SETTINGS) {
5285 int xport;
5286 uae_u64 xflags;
5287 TCHAR xname[MAX_DPATH], xcustom[MAX_DPATH];
5288 inputdevice_get_mapping (devnum, num, &xflags, &xport, xname, xcustom, 0);
5289 if (xport == 0)
5290 inputdevice_set_mapping (devnum, num, xname, xcustom, xflags, MAX_JPORTS + 1, SPARE_SUB_EVENT);
5291 inputdevice_set_mapping (devnum, num, name, NULL, IDEV_MAPPED_GAMEPORTSCUSTOM1 | flags, port + 1, 0);
5292 }
5293 return true;
5294 }
5295
resetinput(void)5296 static void resetinput (void)
5297 {
5298 if ((input_play || input_record) && hsync_counter > 0)
5299 return;
5300 cd32_shifter[0] = cd32_shifter[1] = 8;
5301 for (int i = 0; i < MAX_JPORTS; i++) {
5302 oleft[i] = 0;
5303 oright[i] = 0;
5304 otop[i] = 0;
5305 obot[i] = 0;
5306 oldmx[i] = -1;
5307 oldmy[i] = -1;
5308 joybutton[i] = 0;
5309 joydir[i] = 0;
5310 mouse_deltanoreset[i][0] = 0;
5311 mouse_delta[i][0] = 0;
5312 mouse_deltanoreset[i][1] = 0;
5313 mouse_delta[i][1] = 0;
5314 mouse_deltanoreset[i][2] = 0;
5315 mouse_delta[i][2] = 0;
5316 }
5317 memset (keybuf, 0, sizeof keybuf);
5318 for (int i = 0; i < INPUT_QUEUE_SIZE; i++)
5319 input_queue[i].linecnt = input_queue[i].nextlinecnt = -1;
5320
5321 for (int i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
5322 sublevdir[0][i] = i;
5323 sublevdir[1][i] = MAX_INPUT_SUB_EVENT - i - 1;
5324 }
5325 }
5326
5327
inputdevice_updateconfig_internal(const struct uae_prefs * srcprrefs,struct uae_prefs * dstprefs)5328 void inputdevice_updateconfig_internal (const struct uae_prefs *srcprrefs, struct uae_prefs *dstprefs)
5329 {
5330 int i;
5331
5332 keyboard_default = keyboard_default_table[currprefs.input_keyboard_type];
5333
5334 copyjport (srcprrefs, dstprefs, 0);
5335 copyjport (srcprrefs, dstprefs, 1);
5336 copyjport (srcprrefs, dstprefs, 2);
5337 copyjport (srcprrefs, dstprefs, 3);
5338
5339 resetinput ();
5340
5341 joysticks = dstprefs->joystick_settings[dstprefs->input_selected_setting];
5342 mice = dstprefs->mouse_settings[dstprefs->input_selected_setting];
5343 keyboards = dstprefs->keyboard_settings[dstprefs->input_selected_setting];
5344 internalevents = dstprefs->internalevent_settings[dstprefs->input_selected_setting];
5345
5346 matchdevices_all (dstprefs);
5347
5348 memset (joysticks2, 0, sizeof joysticks2);
5349 memset (mice2, 0, sizeof mice2);
5350
5351 joysticks = dstprefs->joystick_settings[GAMEPORT_INPUT_SETTINGS];
5352 mice = dstprefs->mouse_settings[GAMEPORT_INPUT_SETTINGS];
5353 keyboards = dstprefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS];
5354 internalevents = dstprefs->internalevent_settings[GAMEPORT_INPUT_SETTINGS];
5355
5356 for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
5357 joysticks[i].enabled = 0;
5358 mice[i].enabled = 0;
5359 }
5360
5361 compatibility_copy (dstprefs, true);
5362 joysticks = dstprefs->joystick_settings[dstprefs->input_selected_setting];
5363 mice = dstprefs->mouse_settings[dstprefs->input_selected_setting];
5364 keyboards = dstprefs->keyboard_settings[dstprefs->input_selected_setting];
5365 internalevents = dstprefs->internalevent_settings[dstprefs->input_selected_setting];
5366
5367 if (dstprefs->input_selected_setting != GAMEPORT_INPUT_SETTINGS) {
5368 compatibility_copy (dstprefs, false);
5369 }
5370
5371 disableifempty (dstprefs);
5372 scanevents (dstprefs);
5373 }
5374
inputdevice_updateconfig(const struct uae_prefs * srcprefs,struct uae_prefs * dstprefs)5375 void inputdevice_updateconfig (const struct uae_prefs *srcprefs, struct uae_prefs *dstprefs)
5376 {
5377 inputdevice_updateconfig_internal (srcprefs, dstprefs);
5378
5379 config_changed = 1;
5380
5381 #ifdef RETROPLATFORM
5382 rp_input_change (0);
5383 rp_input_change (1);
5384 rp_input_change (2);
5385 rp_input_change (3);
5386 for (int i = 0; i < MAX_JPORTS; i++)
5387 rp_update_gameport (i, -1, 0);
5388 #endif
5389 }
5390
5391 /* called when devices get inserted or removed
5392 * store old devices temporarily, enumerate all devices
5393 * restore old devices back (order may have changed)
5394 */
inputdevice_devicechange(struct uae_prefs * prefs)5395 void inputdevice_devicechange (struct uae_prefs *prefs)
5396 {
5397 int acc = input_acquired;
5398 int i, idx;
5399 TCHAR *jports[MAX_JPORTS];
5400 int jportskb[MAX_JPORTS], jportsmode[MAX_JPORTS];
5401 int jportid[MAX_JPORTS], jportaf[MAX_JPORTS];
5402
5403 for (i = 0; i < MAX_JPORTS; i++) {
5404 jports[i] = NULL;
5405 jportskb[i] = -1;
5406 jportid[i] = prefs->jports[i].id;
5407 jportaf[i] = prefs->jports[i].autofire;
5408 idx = inputdevice_getjoyportdevice (i, prefs->jports[i].id);
5409 if (idx >= JSEM_LASTKBD) {
5410 struct inputdevice_functions *idf;
5411 int devidx;
5412 idx -= JSEM_LASTKBD;
5413 idf = getidf (idx);
5414 devidx = inputdevice_get_device_index (idx);
5415 jports[i] = my_strdup (idf->get_uniquename (devidx));
5416 } else {
5417 jportskb[i] = idx;
5418 }
5419 jportsmode[i] = prefs->jports[i].mode;
5420 }
5421
5422 inputdevice_unacquire ();
5423 idev[IDTYPE_JOYSTICK].close ();
5424 idev[IDTYPE_MOUSE].close ();
5425 idev[IDTYPE_KEYBOARD].close ();
5426 idev[IDTYPE_JOYSTICK].init ();
5427 idev[IDTYPE_MOUSE].init ();
5428 idev[IDTYPE_KEYBOARD].init ();
5429 matchdevices (&idev[IDTYPE_MOUSE], mice);
5430 matchdevices (&idev[IDTYPE_JOYSTICK], joysticks);
5431 matchdevices (&idev[IDTYPE_KEYBOARD], keyboards);
5432
5433 for (i = 0; i < MAX_JPORTS; i++) {
5434 freejport (prefs, i);
5435 if (jportid[i] == JPORT_CUSTOM) {
5436 inputdevice_joyport_config (prefs, _T("custom"), i, jportsmode[i], 0);
5437 } else if (jports[i]) {
5438 inputdevice_joyport_config (prefs, jports[i], i, jportsmode[i], 2);
5439 } else if (jportskb[i] >= 0) {
5440 TCHAR tmp[10];
5441 _stprintf (tmp, _T("kbd%d"), jportskb[i]);
5442 inputdevice_joyport_config (prefs, tmp, i, jportsmode[i], 0);
5443 }
5444 prefs->jports[i].autofire = jportaf[i];
5445 xfree (jports[i]);
5446 }
5447
5448 if (prefs == &changed_prefs)
5449 inputdevice_copyconfig (&changed_prefs, &currprefs);
5450 if (acc)
5451 inputdevice_acquire (true);
5452 #ifdef RETROPLATFORM
5453 rp_enumdevices ();
5454 #endif
5455 config_changed = 1;
5456 }
5457
5458
5459 // set default prefs to all input configuration settings
inputdevice_default_prefs(struct uae_prefs * p)5460 void inputdevice_default_prefs (struct uae_prefs *p)
5461 {
5462 inputdevice_init ();
5463
5464 p->input_selected_setting = GAMEPORT_INPUT_SETTINGS;
5465 p->input_joymouse_multiplier = 100;
5466 p->input_joymouse_deadzone = 33;
5467 p->input_joystick_deadzone = 33;
5468 p->input_joymouse_speed = 10;
5469 p->input_analog_joystick_mult = 15;
5470 p->input_analog_joystick_offset = -1;
5471 p->input_mouse_speed = 100;
5472 p->input_autofire_linecnt = 600;
5473 p->input_keyboard_type = 0;
5474 keyboard_default = keyboard_default_table[p->input_keyboard_type];
5475 inputdevice_default_kb_all (p);
5476 }
5477
5478 // set default keyboard and keyboard>joystick layouts
inputdevice_setkeytranslation(struct uae_input_device_kbr_default ** trans,int ** kbmaps)5479 void inputdevice_setkeytranslation (struct uae_input_device_kbr_default **trans, int **kbmaps)
5480 {
5481 keyboard_default_table = trans;
5482 keyboard_default_kbmaps = kbmaps;
5483 }
5484
5485 // return true if keyboard/scancode pair is mapped
inputdevice_iskeymapped(int keyboard,int scancode)5486 int inputdevice_iskeymapped (int keyboard, int scancode)
5487 {
5488 /* REMOVEME:
5489 * nowhere used
5490 */
5491 #if 0
5492 struct uae_input_device *na = &keyboards[keyboard];
5493 #endif
5494 if (!keyboards || scancode < 0)
5495 return 0;
5496 return scancodeused[keyboard][scancode];
5497 }
5498
inputdevice_synccapslock(int oldcaps,int * capstable)5499 int inputdevice_synccapslock (int oldcaps, int *capstable)
5500 {
5501 struct uae_input_device *na = &keyboards[0];
5502 int j, i;
5503
5504 if (!keyboards)
5505 return -1;
5506 for (j = 0; na->extra[j]; j++) {
5507 if (na->extra[j] == INPUTEVENT_KEY_CAPS_LOCK) {
5508 for (i = 0; capstable[i]; i += 2) {
5509 if (na->extra[j] == capstable[i]) {
5510 if (oldcaps != capstable[i + 1]) {
5511 oldcaps = capstable[i + 1];
5512 inputdevice_translatekeycode (0, capstable[i], oldcaps ? -1 : 0);
5513 }
5514 return i;
5515 }
5516 }
5517 }
5518 }
5519 return -1;
5520 }
5521
rqualifiers(uae_u64 flags,bool release)5522 static void rqualifiers (uae_u64 flags, bool release)
5523 {
5524 uae_u64 mask = ID_FLAG_QUALIFIER1 << 1;
5525 for (int i = 0; i < MAX_INPUT_QUALIFIERS; i++) {
5526 if ((flags & mask) && (mask & (qualifiers << 1))) {
5527 if (release) {
5528 if (!(mask & qualifiers_r)) {
5529 qualifiers_r |= mask;
5530 for (int ii = 0; ii < MAX_INPUT_SUB_EVENT; ii++) {
5531 int qevt = qualifiers_evt[i][ii];
5532 if (qevt > 0) {
5533 write_log (_T("Released %d '%s'\n"), qevt, events[qevt].name);
5534 inputdevice_do_keyboard (events[qevt].data, 0);
5535 }
5536 }
5537 }
5538 } else {
5539 if ((mask & qualifiers_r)) {
5540 qualifiers_r &= ~mask;
5541 for (int ii = 0; ii < MAX_INPUT_SUB_EVENT; ii++) {
5542 int qevt = qualifiers_evt[i][ii];
5543 if (qevt > 0) {
5544 write_log (_T("Pressed %d '%s'\n"), qevt, events[qevt].name);
5545 inputdevice_do_keyboard (events[qevt].data, 1);
5546 }
5547 }
5548 }
5549 }
5550 }
5551 mask <<= 2;
5552 }
5553 }
5554
inputdevice_translatekeycode_2(int keyboard,int scancode,int keystate,bool qualifiercheckonly)5555 static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int keystate, bool qualifiercheckonly)
5556 {
5557 struct uae_input_device *na = &keyboards[keyboard];
5558 int j, k;
5559 int handled = 0;
5560 bool didcustom = false;
5561
5562 if (!keyboards || scancode < 0)
5563 return handled;
5564
5565 j = 0;
5566 while (j < MAX_INPUT_DEVICE_EVENTS && na->extra[j] >= 0) {
5567 if (na->extra[j] == scancode) {
5568 bool qualonly;
5569 uae_u64 qualmask[MAX_INPUT_SUB_EVENT];
5570 getqualmask (qualmask, na, j, &qualonly);
5571
5572 if (qualonly)
5573 qualifiercheckonly = true;
5574 for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {/* send key release events in reverse order */
5575 uae_u64 *flagsp = &na->flags[j][sublevdir[keystate == 0 ? 1 : 0][k]];
5576 int evt = na->eventid[j][sublevdir[keystate == 0 ? 1 : 0][k]];
5577 uae_u64 flags = *flagsp;
5578 int autofire = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
5579 int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0;
5580 int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
5581 int invert = (flags & ID_FLAG_INVERT) ? 1 : 0;
5582 int toggled;
5583 int state;
5584
5585 if (keystate < 0) {
5586 state = keystate;
5587 } else if (invert) {
5588 state = keystate ? 0 : 1;
5589 } else {
5590 state = keystate;
5591 }
5592
5593 setqualifiers (evt, state > 0);
5594
5595 if (qualifiercheckonly) {
5596 if (!state && (flags & ID_FLAG_CANRELEASE)) {
5597 *flagsp &= ~ID_FLAG_CANRELEASE;
5598 handle_input_event (evt, state, 1, autofire, true, false);
5599 if (k == 0) {
5600 process_custom_event (na, j, state, qualmask, autofire, k);
5601 }
5602 }
5603 continue;
5604 }
5605
5606 if (!state) {
5607 didcustom |= process_custom_event (na, j, state, qualmask, autofire, k);
5608 }
5609
5610 // if evt == caps and scan == caps: sync with native caps led
5611 if (evt == INPUTEVENT_KEY_CAPS_LOCK) {
5612 int v;
5613 if (state < 0)
5614 state = 1;
5615 v = target_checkcapslock (scancode, &state);
5616 if (v < 0)
5617 continue;
5618 if (v > 0)
5619 toggle = 0;
5620 } else if (state < 0) {
5621 // it was caps lock resync, ignore, not mapped to caps
5622 continue;
5623 }
5624
5625 if (inverttoggle) {
5626 na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] &= ~ID_FLAG_TOGGLED;
5627 if (state) {
5628 queue_input_event (evt, NULL, -1, 0, 0, 1);
5629 handled |= handle_input_event (evt, 1, 1, 0, true, false);
5630 } else {
5631 handled |= handle_input_event (evt, 1, 1, autofire, true, false);
5632 }
5633 didcustom |= process_custom_event (na, j, state, qualmask, autofire, k);
5634 } else if (toggle) {
5635 if (!state)
5636 continue;
5637 if (!checkqualifiers (evt, flags, qualmask, na->eventid[j]))
5638 continue;
5639 *flagsp ^= ID_FLAG_TOGGLED;
5640 toggled = (*flagsp & ID_FLAG_TOGGLED) ? 1 : 0;
5641 handled |= handle_input_event (evt, toggled, 1, autofire, true, false);
5642 if (k == 0)
5643 didcustom |= process_custom_event (na, j, state, qualmask, autofire, k);
5644 } else {
5645 rqualifiers (flags, state ? true : false);
5646 if (!checkqualifiers (evt, flags, qualmask, na->eventid[j])) {
5647 if (!state && !(flags & ID_FLAG_CANRELEASE)) {
5648 if (!invert)
5649 continue;
5650 } else if (state) {
5651 continue;
5652 }
5653 }
5654
5655 if (state) {
5656 if (!invert)
5657 *flagsp |= ID_FLAG_CANRELEASE;
5658 } else {
5659 if (!(flags & ID_FLAG_CANRELEASE) && !invert)
5660 continue;
5661 *flagsp &= ~ID_FLAG_CANRELEASE;
5662 }
5663 handled |= handle_input_event (evt, state, 1, autofire, true, false);
5664 didcustom |= process_custom_event (na, j, state, qualmask, autofire, k);
5665 }
5666 }
5667 if (!didcustom)
5668 queue_input_event (-1, NULL, -1, 0, 0, 1);
5669 return handled;
5670 }
5671 j++;
5672 }
5673 return handled;
5674 }
5675
5676 #define IECODE_UP_PREFIX 0x80
5677 #define RAW_STEALTH 0x68
5678 #define STEALTHF_E0KEY 0x08
5679 #define STEALTHF_UPSTROKE 0x04
5680 #define STEALTHF_SPECIAL 0x02
5681 #define STEALTHF_E1KEY 0x01
5682
sendmmcodes(int code,int newstate)5683 static void sendmmcodes (int code, int newstate)
5684 {
5685 uae_u8 b;
5686
5687 b = RAW_STEALTH | IECODE_UP_PREFIX;
5688 record_key(((b << 1) | (b >> 7)) & 0xff);
5689 b = IECODE_UP_PREFIX;
5690 if ((code >> 8) == 0x01)
5691 b |= STEALTHF_E0KEY;
5692 if ((code >> 8) == 0x02)
5693 b |= STEALTHF_E1KEY;
5694 if (!newstate)
5695 b |= STEALTHF_UPSTROKE;
5696 record_key(((b << 1) | (b >> 7)) & 0xff);
5697 b = ((code >> 4) & 0x0f) | IECODE_UP_PREFIX;
5698 record_key(((b << 1) | (b >> 7)) & 0xff);
5699 b = (code & 0x0f) | IECODE_UP_PREFIX;
5700 record_key(((b << 1) | (b >> 7)) & 0xff);
5701 }
5702
5703 // main keyboard press/release entry point
inputdevice_translatekeycode(int keyboard,int scancode,int state)5704 int inputdevice_translatekeycode (int keyboard, int scancode, int state)
5705 {
5706 if (inputdevice_translatekeycode_2 (keyboard, scancode, state, false))
5707 return 1;
5708 if (currprefs.mmkeyboard && scancode > 0)
5709 sendmmcodes (scancode, state);
5710 return 0;
5711 }
inputdevice_checkqualifierkeycode(int keyboard,int scancode,int state)5712 void inputdevice_checkqualifierkeycode (int keyboard, int scancode, int state)
5713 {
5714 inputdevice_translatekeycode_2 (keyboard, scancode, state, true);
5715 }
5716
5717 static const TCHAR *internaleventlabels[] = {
5718 _T("CPU reset"),
5719 _T("Keyboard reset"),
5720 NULL
5721 };
init_int(void)5722 static int init_int (void)
5723 {
5724 return 1;
5725 }
close_int(void)5726 static void close_int (void)
5727 {
5728 }
acquire_int(int num,int flags)5729 static int acquire_int (int num, int flags)
5730 {
5731 return 1;
5732 }
unacquire_int(int num)5733 static void unacquire_int (int num)
5734 {
5735 }
read_int(void)5736 static void read_int (void)
5737 {
5738 }
get_int_num(void)5739 static int get_int_num (void)
5740 {
5741 return 1;
5742 }
get_int_friendlyname(int num)5743 static TCHAR *get_int_friendlyname (int num)
5744 {
5745 return _T("Internal events");
5746 }
get_int_uniquename(int num)5747 static TCHAR *get_int_uniquename (int num)
5748 {
5749 return _T("INTERNALEVENTS1");
5750 }
get_int_widget_num(int num)5751 static int get_int_widget_num (int num)
5752 {
5753 int i;
5754 for (i = 0; internaleventlabels[i]; i++);
5755 return i;
5756 }
get_int_widget_type(int kb,int num,TCHAR * name,uae_u32 * code)5757 static int get_int_widget_type (int kb, int num, TCHAR *name, uae_u32 *code)
5758 {
5759 if (code)
5760 *code = num;
5761 if (name)
5762 _tcscpy (name, internaleventlabels[num]);
5763 return IDEV_WIDGET_BUTTON;
5764 }
get_int_widget_first(int kb,int type)5765 static int get_int_widget_first (int kb, int type)
5766 {
5767 return 0;
5768 }
get_int_flags(int num)5769 static int get_int_flags (int num)
5770 {
5771 return 0;
5772 }
5773
5774 struct inputdevice_functions inputdevicefunc_internalevent = {
5775 init_int, close_int, acquire_int, unacquire_int, read_int,
5776 get_int_num, get_int_friendlyname, get_int_uniquename,
5777 get_int_widget_num, get_int_widget_type,
5778 get_int_widget_first,
5779 get_int_flags
5780 };
5781
send_internalevent(int eventid)5782 void send_internalevent (int eventid)
5783 {
5784 setbuttonstateall (&internalevents[0], NULL, eventid, -1);
5785 }
5786
5787
inputdevice_init(void)5788 void inputdevice_init (void)
5789 {
5790 idev[IDTYPE_JOYSTICK] = inputdevicefunc_joystick;
5791 idev[IDTYPE_JOYSTICK].init ();
5792 idev[IDTYPE_MOUSE] = inputdevicefunc_mouse;
5793 idev[IDTYPE_MOUSE].init ();
5794 idev[IDTYPE_KEYBOARD] = inputdevicefunc_keyboard;
5795 idev[IDTYPE_KEYBOARD].init ();
5796 idev[IDTYPE_INTERNALEVENT] = inputdevicefunc_internalevent;
5797 idev[IDTYPE_INTERNALEVENT].init ();
5798 }
5799
inputdevice_close(void)5800 void inputdevice_close (void)
5801 {
5802 idev[IDTYPE_JOYSTICK].close ();
5803 idev[IDTYPE_MOUSE].close ();
5804 idev[IDTYPE_KEYBOARD].close ();
5805 idev[IDTYPE_INTERNALEVENT].close ();
5806 inprec_close (true);
5807 }
5808
get_uid(const struct inputdevice_functions * id,int devnum)5809 static struct uae_input_device *get_uid (const struct inputdevice_functions *id, int devnum)
5810 {
5811 struct uae_input_device *uid = 0;
5812 if (id == &idev[IDTYPE_JOYSTICK]) {
5813 uid = &joysticks[devnum];
5814 } else if (id == &idev[IDTYPE_MOUSE]) {
5815 uid = &mice[devnum];
5816 } else if (id == &idev[IDTYPE_KEYBOARD]) {
5817 uid = &keyboards[devnum];
5818 } else if (id == &idev[IDTYPE_INTERNALEVENT]) {
5819 uid = &internalevents[devnum];
5820 }
5821 return uid;
5822 }
5823
get_event_data(const struct inputdevice_functions * id,int devnum,int num,int * eventid,TCHAR ** custom,uae_u64 * flags,int * port,int sub)5824 static int get_event_data (const struct inputdevice_functions *id, int devnum, int num, int *eventid, TCHAR **custom, uae_u64 *flags, int *port, int sub)
5825 {
5826 const struct uae_input_device *uid = get_uid (id, devnum);
5827 int type = id->get_widget_type (devnum, num, 0, 0);
5828 int i;
5829 if (type == IDEV_WIDGET_BUTTON || type == IDEV_WIDGET_BUTTONAXIS) {
5830 i = num - id->get_widget_first (devnum, IDEV_WIDGET_BUTTON) + ID_BUTTON_OFFSET;
5831 *eventid = uid->eventid[i][sub];
5832 if (flags)
5833 *flags = uid->flags[i][sub];
5834 if (port)
5835 *port = uid->port[i][sub];
5836 if (custom)
5837 *custom = uid->custom[i][sub];
5838 return i;
5839 } else if (type == IDEV_WIDGET_AXIS) {
5840 i = num - id->get_widget_first (devnum, type) + ID_AXIS_OFFSET;
5841 *eventid = uid->eventid[i][sub];
5842 if (flags)
5843 *flags = uid->flags[i][sub];
5844 if (port)
5845 *port = uid->port[i][sub];
5846 if (custom)
5847 *custom = uid->custom[i][sub];
5848 return i;
5849 } else if (type == IDEV_WIDGET_KEY) {
5850 i = num - id->get_widget_first (devnum, type);
5851 *eventid = uid->eventid[i][sub];
5852 if (flags)
5853 *flags = uid->flags[i][sub];
5854 if (port)
5855 *port = uid->port[i][sub];
5856 if (custom)
5857 *custom = uid->custom[i][sub];
5858 return i;
5859 }
5860 return -1;
5861 }
5862
stripstrdup(const TCHAR * s)5863 static TCHAR *stripstrdup (const TCHAR *s)
5864 {
5865 TCHAR *out = my_strdup (s);
5866 if (!out)
5867 return NULL;
5868 for (int i = 0; out[i]; i++) {
5869 if (out[i] < ' ')
5870 out[i] = ' ';
5871 }
5872 return out;
5873 }
5874
put_event_data(const struct inputdevice_functions * id,int devnum,int num,int eventid,TCHAR * custom,uae_u64 flags,int port,int sub)5875 static int put_event_data (const struct inputdevice_functions *id, int devnum, int num, int eventid, TCHAR *custom, uae_u64 flags, int port, int sub)
5876 {
5877 struct uae_input_device *uid = get_uid (id, devnum);
5878 int type = id->get_widget_type (devnum, num, 0, 0);
5879 int i, ret;
5880
5881 for (i = 0; i < MAX_INPUT_QUALIFIERS; i++) {
5882 uae_u64 mask1 = ID_FLAG_QUALIFIER1 << (i * 2);
5883 uae_u64 mask2 = mask1 << 1;
5884 if ((flags & (mask1 | mask2)) == (mask1 | mask2))
5885 flags &= ~mask2;
5886 }
5887 if (custom && custom[0] == 0)
5888 custom = NULL;
5889 if (custom)
5890 eventid = 0;
5891 if (eventid <= 0 && !custom)
5892 flags = 0;
5893
5894 ret = -1;
5895 if (type == IDEV_WIDGET_BUTTON || type == IDEV_WIDGET_BUTTONAXIS) {
5896 i = num - id->get_widget_first (devnum, IDEV_WIDGET_BUTTON) + ID_BUTTON_OFFSET;
5897 uid->eventid[i][sub] = eventid;
5898 uid->flags[i][sub] = flags;
5899 uid->port[i][sub] = port;
5900 xfree (uid->custom[i][sub]);
5901 uid->custom[i][sub] = custom && _tcslen (custom) > 0 ? stripstrdup (custom) : NULL;
5902 ret = i;
5903 } else if (type == IDEV_WIDGET_AXIS) {
5904 i = num - id->get_widget_first (devnum, type) + ID_AXIS_OFFSET;
5905 uid->eventid[i][sub] = eventid;
5906 uid->flags[i][sub] = flags;
5907 uid->port[i][sub] = port;
5908 xfree (uid->custom[i][sub]);
5909 uid->custom[i][sub] = custom && _tcslen (custom) > 0 ? stripstrdup (custom) : NULL;
5910 ret = i;
5911 } else if (type == IDEV_WIDGET_KEY) {
5912 i = num - id->get_widget_first (devnum, type);
5913 uid->eventid[i][sub] = eventid;
5914 uid->flags[i][sub] = flags;
5915 uid->port[i][sub] = port;
5916 xfree (uid->custom[i][sub]);
5917 uid->custom[i][sub] = custom && _tcslen (custom) > 0 ? stripstrdup (custom) : NULL;
5918 ret = i;
5919 }
5920 if (ret < 0)
5921 return -1;
5922 if (uid->custom[i][sub])
5923 uid->eventid[i][sub] = INPUTEVENT_SPC_CUSTOM_EVENT;
5924 return ret;
5925 }
5926
is_event_used(const struct inputdevice_functions * id,int devnum,int isnum,int isevent)5927 static int is_event_used (const struct inputdevice_functions *id, int devnum, int isnum, int isevent)
5928 {
5929 /* REMOVEME:
5930 * nowhere used
5931 */
5932 #if 0
5933 struct uae_input_device *uid = get_uid (id, devnum);
5934 #endif
5935 int num, evt, sub;
5936
5937 for (num = 0; num < id->get_widget_num (devnum); num++) {
5938 for (sub = 0; sub < MAX_INPUT_SUB_EVENT; sub++) {
5939 if (get_event_data (id, devnum, num, &evt, NULL, NULL, NULL, sub) >= 0) {
5940 if (evt == isevent && isnum != num)
5941 return 1;
5942 }
5943 }
5944 }
5945 return 0;
5946 }
5947
5948 // device based index from global device index
inputdevice_get_device_index(int devnum)5949 int inputdevice_get_device_index (int devnum)
5950 {
5951 int jcnt = idev[IDTYPE_JOYSTICK].get_num ();
5952 int mcnt = idev[IDTYPE_MOUSE].get_num ();
5953 int kcnt = idev[IDTYPE_KEYBOARD].get_num ();
5954
5955 if (devnum < jcnt)
5956 return devnum;
5957 else if (devnum < jcnt + mcnt)
5958 return devnum - jcnt;
5959 else if (devnum < jcnt + mcnt + kcnt)
5960 return devnum - (jcnt + mcnt);
5961 else if (devnum < jcnt + mcnt + kcnt + INTERNALEVENT_COUNT)
5962 return devnum - (jcnt + mcnt + kcnt);
5963 return -1;
5964 }
5965
getdevnum(int type,int devnum)5966 static int getdevnum (int type, int devnum)
5967 {
5968 int jcnt = idev[IDTYPE_JOYSTICK].get_num ();
5969 int mcnt = idev[IDTYPE_MOUSE].get_num ();
5970 int kcnt = idev[IDTYPE_KEYBOARD].get_num ();
5971
5972 if (type == IDTYPE_JOYSTICK)
5973 return devnum;
5974 else if (type == IDTYPE_MOUSE)
5975 return jcnt + devnum;
5976 else if (type == IDTYPE_KEYBOARD)
5977 return jcnt + mcnt + devnum;
5978 else if (type == IDTYPE_INTERNALEVENT)
5979 return jcnt + mcnt + kcnt + devnum;
5980 return -1;
5981 }
5982
gettype(int devnum)5983 static int gettype (int devnum)
5984 {
5985 int jcnt = idev[IDTYPE_JOYSTICK].get_num ();
5986 int mcnt = idev[IDTYPE_MOUSE].get_num ();
5987 int kcnt = idev[IDTYPE_KEYBOARD].get_num ();
5988
5989 if (devnum < jcnt)
5990 return IDTYPE_JOYSTICK;
5991 else if (devnum < jcnt + mcnt)
5992 return IDTYPE_MOUSE;
5993 else if (devnum < jcnt + mcnt + kcnt)
5994 return IDTYPE_KEYBOARD;
5995 else if (devnum < jcnt + mcnt + kcnt + INTERNALEVENT_COUNT)
5996 return IDTYPE_INTERNALEVENT;
5997 return -1;
5998 }
5999
getidf(int devnum)6000 static struct inputdevice_functions *getidf (int devnum)
6001 {
6002 int type = gettype (devnum);
6003 if (type < 0)
6004 return NULL;
6005 return &idev[type];
6006 }
6007
inputdevice_get_eventinfo(int evt)6008 struct inputevent *inputdevice_get_eventinfo (int evt)
6009 {
6010 if (evt > 0 && !events[evt].name)
6011 return NULL;
6012 return &events[evt];
6013 }
6014
6015
6016 /* returns number of devices of type "type" */
inputdevice_get_device_total(int type)6017 int inputdevice_get_device_total (int type)
6018 {
6019 return idev[type].get_num ();
6020 }
6021 /* returns the name of device */
inputdevice_get_device_name(int type,int devnum)6022 TCHAR *inputdevice_get_device_name (int type, int devnum)
6023 {
6024 return idev[type].get_friendlyname (devnum);
6025 }
6026 /* returns the name of device */
inputdevice_get_device_name2(int devnum)6027 TCHAR *inputdevice_get_device_name2 (int devnum)
6028 {
6029 return getidf (devnum)->get_friendlyname (inputdevice_get_device_index (devnum));
6030 }
6031 /* returns machine readable name of device */
inputdevice_get_device_unique_name(int type,int devnum)6032 TCHAR *inputdevice_get_device_unique_name (int type, int devnum)
6033 {
6034 return idev[type].get_uniquename (devnum);
6035 }
6036 /* returns state (enabled/disabled) */
inputdevice_get_device_status(int devnum)6037 int inputdevice_get_device_status (int devnum)
6038 {
6039 const struct inputdevice_functions *idf = getidf (devnum);
6040 if (idf == NULL)
6041 return -1;
6042 struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
6043 return uid->enabled;
6044 }
6045
6046 /* set state (enabled/disabled) */
inputdevice_set_device_status(int devnum,int enabled)6047 void inputdevice_set_device_status (int devnum, int enabled)
6048 {
6049 const struct inputdevice_functions *idf = getidf (devnum);
6050 int num = inputdevice_get_device_index (devnum);
6051 struct uae_input_device *uid = get_uid (idf, num);
6052 if (enabled) { // disable incompatible devices ("super device" vs "raw device")
6053 for (int i = 0; i < idf->get_num (); i++) {
6054 if (idf->get_flags (i) != idf->get_flags (num)) {
6055 struct uae_input_device *uid2 = get_uid (idf, i);
6056 uid2->enabled = 0;
6057 }
6058 }
6059 }
6060 uid->enabled = enabled;
6061 }
6062
6063 /* returns number of axis/buttons and keys from selected device */
inputdevice_get_widget_num(int devnum)6064 int inputdevice_get_widget_num (int devnum)
6065 {
6066 const struct inputdevice_functions *idf = getidf (devnum);
6067 return idf->get_widget_num (inputdevice_get_device_index (devnum));
6068 }
6069
6070 // return name of event, do not use ie->name directly
inputdevice_get_eventname(const struct inputevent * ie,TCHAR * out)6071 bool inputdevice_get_eventname (const struct inputevent *ie, TCHAR *out)
6072 {
6073 if (!out)
6074 return false;
6075 _tcscpy (out, ie->name);
6076 return true;
6077 }
6078
inputdevice_iterate(int devnum,int num,TCHAR * name,int * af)6079 int inputdevice_iterate (int devnum, int num, TCHAR *name, int *af)
6080 {
6081 const struct inputdevice_functions *idf = getidf (devnum);
6082 static int id_iterator;
6083 struct inputevent *ie;
6084 int mask, data, type;
6085 uae_u64 flags;
6086 int devindex = inputdevice_get_device_index (devnum);
6087
6088 *af = 0;
6089 *name = 0;
6090 for (;;) {
6091 ie = &events[++id_iterator];
6092 if (!ie->confname) {
6093 id_iterator = 0;
6094 return 0;
6095 }
6096 mask = 0;
6097 type = idf->get_widget_type (devindex, num, NULL, NULL);
6098 if (type == IDEV_WIDGET_BUTTON || type == IDEV_WIDGET_BUTTONAXIS) {
6099 if (idf == &idev[IDTYPE_JOYSTICK]) {
6100 mask |= AM_JOY_BUT;
6101 } else {
6102 mask |= AM_MOUSE_BUT;
6103 }
6104 } else if (type == IDEV_WIDGET_AXIS) {
6105 if (idf == &idev[IDTYPE_JOYSTICK]) {
6106 mask |= AM_JOY_AXIS;
6107 } else {
6108 mask |= AM_MOUSE_AXIS;
6109 }
6110 } else if (type == IDEV_WIDGET_KEY) {
6111 mask |= AM_K;
6112 }
6113 if (ie->allow_mask & AM_INFO) {
6114 struct inputevent *ie2 = ie + 1;
6115 while (!(ie2->allow_mask & AM_INFO)) {
6116 if (is_event_used (idf, devindex, ie2 - ie, -1)) {
6117 ie2++;
6118 continue;
6119 }
6120 if (ie2->allow_mask & mask)
6121 break;
6122 ie2++;
6123 }
6124 if (!(ie2->allow_mask & AM_INFO))
6125 mask |= AM_INFO;
6126 }
6127 if (!(ie->allow_mask & mask))
6128 continue;
6129 get_event_data (idf, devindex, num, &data, NULL, &flags, NULL, 0);
6130 inputdevice_get_eventname (ie, name);
6131 *af = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
6132 return 1;
6133 }
6134 }
6135
6136 // return mapped event from devnum/num/sub
inputdevice_get_mapping(int devnum,int num,uae_u64 * pflags,int * pport,TCHAR * name,TCHAR * custom,int sub)6137 int inputdevice_get_mapping (int devnum, int num, uae_u64 *pflags, int *pport, TCHAR *name, TCHAR *custom, int sub)
6138 {
6139 const struct inputdevice_functions *idf = getidf (devnum);
6140 const struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
6141 int port, data;
6142 uae_u64 flags = 0, flag;
6143 int devindex = inputdevice_get_device_index (devnum);
6144 TCHAR *customp = NULL;
6145
6146 if (name)
6147 _tcscpy (name, _T("<none>"));
6148 if (custom)
6149 custom[0] = 0;
6150 if (pflags)
6151 *pflags = 0;
6152 if (pport)
6153 *pport = 0;
6154 if (uid == 0 || num < 0)
6155 return 0;
6156 if (get_event_data (idf, devindex, num, &data, &customp, &flag, &port, sub) < 0)
6157 return 0;
6158 if (customp && custom)
6159 _tcscpy (custom, customp);
6160 if (flag & ID_FLAG_AUTOFIRE)
6161 flags |= IDEV_MAPPED_AUTOFIRE_SET;
6162 if (flag & ID_FLAG_TOGGLE)
6163 flags |= IDEV_MAPPED_TOGGLE;
6164 if (flag & ID_FLAG_INVERTTOGGLE)
6165 flags |= IDEV_MAPPED_INVERTTOGGLE;
6166 if (flag & ID_FLAG_INVERT)
6167 flags |= IDEV_MAPPED_INVERT;
6168 if (flag & ID_FLAG_GAMEPORTSCUSTOM1)
6169 flags |= IDEV_MAPPED_GAMEPORTSCUSTOM1;
6170 if (flag & ID_FLAG_GAMEPORTSCUSTOM2)
6171 flags |= IDEV_MAPPED_GAMEPORTSCUSTOM2;
6172 if (flag & ID_FLAG_QUALIFIER_MASK)
6173 flags |= flag & ID_FLAG_QUALIFIER_MASK;
6174 if (pflags)
6175 *pflags = flags;
6176 if (pport)
6177 *pport = port;
6178 if (!data)
6179 return 0;
6180 if (events[data].allow_mask & AM_AF)
6181 flags |= IDEV_MAPPED_AUTOFIRE_POSSIBLE;
6182 if (pflags)
6183 *pflags = flags;
6184 inputdevice_get_eventname (&events[data], name);
6185 return data;
6186 }
6187
6188 // set event name/custom/flags to devnum/num/sub
inputdevice_set_mapping(int devnum,int num,const TCHAR * name,TCHAR * custom,uae_u64 flags,int port,int sub)6189 int inputdevice_set_mapping (int devnum, int num, const TCHAR *name, TCHAR *custom, uae_u64 flags, int port, int sub)
6190 {
6191 const struct inputdevice_functions *idf = getidf (devnum);
6192 const struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
6193 int eid, data, portp, amask;
6194 uae_u64 flag;
6195 TCHAR ename[256];
6196 int devindex = inputdevice_get_device_index (devnum);
6197 TCHAR *customp = NULL;
6198
6199 if (uid == 0 || num < 0)
6200 return 0;
6201 if (name) {
6202 eid = 1;
6203 while (events[eid].name) {
6204 inputdevice_get_eventname (&events[eid], ename);
6205 if (!_tcscmp(ename, name))
6206 break;
6207 eid++;
6208 }
6209 if (!events[eid].name)
6210 return 0;
6211 if (events[eid].allow_mask & AM_INFO)
6212 return 0;
6213 } else {
6214 eid = 0;
6215 }
6216 if (get_event_data (idf, devindex, num, &data, &customp, &flag, &portp, sub) < 0)
6217 return 0;
6218 if (data >= 0) {
6219 amask = events[eid].allow_mask;
6220 flag &= ~(ID_FLAG_AUTOFIRE_MASK | ID_FLAG_GAMEPORTSCUSTOM_MASK | IDEV_MAPPED_QUALIFIER_MASK | ID_FLAG_INVERT);
6221 if (amask & AM_AF) {
6222 flag |= (flags & IDEV_MAPPED_AUTOFIRE_SET) ? ID_FLAG_AUTOFIRE : 0;
6223 flag |= (flags & IDEV_MAPPED_TOGGLE) ? ID_FLAG_TOGGLE : 0;
6224 flag |= (flags & IDEV_MAPPED_INVERTTOGGLE) ? ID_FLAG_INVERTTOGGLE : 0;
6225 }
6226 flag |= (flags & IDEV_MAPPED_INVERT) ? ID_FLAG_INVERT : 0;
6227 flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM1) ? ID_FLAG_GAMEPORTSCUSTOM1 : 0;
6228 flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM2) ? ID_FLAG_GAMEPORTSCUSTOM2 : 0;
6229 flag |= flags & IDEV_MAPPED_QUALIFIER_MASK;
6230 if (port >= 0)
6231 portp = port;
6232 put_event_data (idf, devindex, num, eid, custom, flag, portp, sub);
6233 return 1;
6234 }
6235 return 0;
6236 }
6237
inputdevice_get_widget_type(int devnum,int num,TCHAR * name)6238 int inputdevice_get_widget_type (int devnum, int num, TCHAR *name)
6239 {
6240 const struct inputdevice_functions *idf = getidf (devnum);
6241 return idf->get_widget_type (inputdevice_get_device_index (devnum), num, name, 0);
6242 }
6243
6244 static int config_change;
6245
inputdevice_config_change(void)6246 void inputdevice_config_change (void)
6247 {
6248 config_change = 1;
6249 }
6250
inputdevice_config_change_test(void)6251 int inputdevice_config_change_test (void)
6252 {
6253 int v = config_change;
6254 config_change = 0;
6255 return v;
6256 }
6257
6258 // copy configuration #src to configuration #dst
inputdevice_copyconfig(const struct uae_prefs * src,struct uae_prefs * dst)6259 void inputdevice_copyconfig (const struct uae_prefs *src, struct uae_prefs *dst)
6260 {
6261 int i, j;
6262
6263 dst->input_selected_setting = src->input_selected_setting;
6264 dst->input_joymouse_multiplier = src->input_joymouse_multiplier;
6265 dst->input_joymouse_deadzone = src->input_joymouse_deadzone;
6266 dst->input_joystick_deadzone = src->input_joystick_deadzone;
6267 dst->input_joymouse_speed = src->input_joymouse_speed;
6268 dst->input_mouse_speed = src->input_mouse_speed;
6269 dst->input_autofire_linecnt = src->input_autofire_linecnt;
6270 copyjport (src, dst, 0);
6271 copyjport (src, dst, 1);
6272 copyjport (src, dst, 2);
6273 copyjport (src, dst, 3);
6274
6275 for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
6276 for (j = 0; j < MAX_INPUT_DEVICES; j++) {
6277 memcpy (&dst->joystick_settings[i][j], &src->joystick_settings[i][j], sizeof (struct uae_input_device));
6278 memcpy (&dst->mouse_settings[i][j], &src->mouse_settings[i][j], sizeof (struct uae_input_device));
6279 memcpy (&dst->keyboard_settings[i][j], &src->keyboard_settings[i][j], sizeof (struct uae_input_device));
6280 }
6281 }
6282
6283 inputdevice_updateconfig (src, dst);
6284 }
6285
swapevent(struct uae_input_device * uid,int i,int j,int evt)6286 static void swapevent (struct uae_input_device *uid, int i, int j, int evt)
6287 {
6288 uid->eventid[i][j] = evt;
6289 int port = uid->port[i][j];
6290 if (port == 1)
6291 port = 2;
6292 else if (port == 2)
6293 port = 1;
6294 else if (port == 3)
6295 port = 4;
6296 else if (port == 4)
6297 port = 3;
6298 uid->port[i][j] = port;
6299 }
6300
swapjoydevice(struct uae_input_device * uid,int ** swaps)6301 static void swapjoydevice (struct uae_input_device *uid, int **swaps)
6302 {
6303 for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
6304 for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
6305 bool found = false;
6306 for (int k = 0; k < 2 && !found; k++) {
6307 int evtnum;
6308 for (int kk = 0; (evtnum = swaps[k][kk]) >= 0 && !found; kk++) {
6309 if (uid->eventid[i][j] == evtnum) {
6310 swapevent (uid, i, j, swaps[1 - k][kk]);
6311 found = true;
6312 } else {
6313 for (int jj = 0; axistable[jj] >= 0; jj += 3) {
6314 if (evtnum == axistable[jj] || evtnum == axistable[jj + 1] || evtnum == axistable[jj + 2]) {
6315 for (int ii = 0; ii < 3; ii++) {
6316 if (uid->eventid[i][j] == axistable[jj + ii]) {
6317 int evtnum2 = swaps[1 - k][kk];
6318 for (int m = 0; axistable[m] >= 0; m += 3) {
6319 if (evtnum2 == axistable[m] || evtnum2 == axistable[m + 1] || evtnum2 == axistable[m + 2]) {
6320 swapevent (uid, i, j, axistable[m + ii]);
6321 found = true;
6322 }
6323 }
6324 }
6325 }
6326 }
6327 }
6328 }
6329 }
6330 }
6331 }
6332 }
6333 }
6334
6335 // swap gameports ports, remember to handle customized ports too
inputdevice_swap_compa_ports(struct uae_prefs * prefs,int portswap)6336 void inputdevice_swap_compa_ports (struct uae_prefs *prefs, int portswap)
6337 {
6338 struct jport tmp;
6339 if ((prefs->jports[portswap].id == JPORT_CUSTOM || prefs->jports[portswap + 1].id == JPORT_CUSTOM)) {
6340 int *swaps[2];
6341 swaps[0] = rem_ports[portswap];
6342 swaps[1] = rem_ports[portswap + 1];
6343 for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
6344 swapjoydevice (&prefs->joystick_settings[GAMEPORT_INPUT_SETTINGS][l], swaps);
6345 swapjoydevice (&prefs->mouse_settings[GAMEPORT_INPUT_SETTINGS][l], swaps);
6346 swapjoydevice (&prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS][l], swaps);
6347 }
6348 }
6349 memcpy (&tmp, &prefs->jports[portswap], sizeof (struct jport));
6350 memcpy (&prefs->jports[portswap], &prefs->jports[portswap + 1], sizeof (struct jport));
6351 memcpy (&prefs->jports[portswap + 1], &tmp, sizeof (struct jport));
6352 inputdevice_updateconfig (NULL, prefs);
6353 }
6354
6355 // swap device "devnum" ports 0<>1 and 2<>3
inputdevice_swap_ports(struct uae_prefs * p,int devnum)6356 void inputdevice_swap_ports (struct uae_prefs *p, int devnum)
6357 {
6358 const struct inputdevice_functions *idf = getidf (devnum);
6359 struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
6360 int i, j, k, event;
6361 /* REMOVEME:
6362 * nowhere used
6363 */
6364 #if 0
6365 int unit;
6366 #endif
6367 const struct inputevent *ie, *ie2;
6368
6369 for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
6370 for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
6371 event = uid->eventid[i][j];
6372 if (event <= 0)
6373 continue;
6374 ie = &events[event];
6375 if (ie->unit <= 0)
6376 continue;
6377 /* REMOVEME:
6378 * nowhere used
6379 */
6380 #if 0
6381 unit = ie->unit;
6382 #endif
6383 k = 1;
6384 while (events[k].confname) {
6385 ie2 = &events[k];
6386 if (ie2->type == ie->type && ie2->data == ie->data && ie2->unit - 1 == ((ie->unit - 1) ^ 1) &&
6387 ie2->allow_mask == ie->allow_mask && uid->port[i][j] == 0) {
6388 uid->eventid[i][j] = k;
6389 break;
6390 }
6391 k++;
6392 }
6393 }
6394 }
6395 }
6396
6397 //memcpy (p->joystick_settings[dst], p->joystick_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
copydev(struct uae_input_device * dst,struct uae_input_device * src,int selectedwidget)6398 static void copydev (struct uae_input_device *dst, struct uae_input_device *src, int selectedwidget)
6399 {
6400 for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
6401 for (int j = 0; j < MAX_INPUT_DEVICE_EVENTS; j++) {
6402 if (j == selectedwidget || selectedwidget < 0) {
6403 for (int k = 0; k < MAX_INPUT_SUB_EVENT_ALL; k++) {
6404 xfree (dst[i].custom[j][k]);
6405 }
6406 }
6407 }
6408 if (selectedwidget < 0) {
6409 xfree (dst[i].configname);
6410 xfree (dst[i].name);
6411 }
6412 }
6413 if (selectedwidget < 0) {
6414 memcpy (dst, src, sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
6415 } else {
6416 int j = selectedwidget;
6417 for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
6418 for (int k = 0; k < MAX_INPUT_SUB_EVENT_ALL; k++) {
6419 dst[i].eventid[j][k] = src[i].eventid[j][k];
6420 dst[i].custom[j][k] = src[i].custom[j][k];
6421 dst[i].flags[j][k] = src[i].flags[j][k];
6422 dst[i].port[j][k] = src[i].port[j][k];
6423 }
6424 dst[i].extra[j] = src[i].extra[j];
6425 }
6426 }
6427 for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
6428 for (int j = 0; j < MAX_INPUT_DEVICE_EVENTS; j++) {
6429 if (j == selectedwidget || selectedwidget < 0) {
6430 for (int k = 0; k < MAX_INPUT_SUB_EVENT_ALL; k++) {
6431 if (dst[i].custom)
6432 dst[i].custom[j][k] = my_strdup (dst[i].custom[j][k]);
6433 }
6434 }
6435 }
6436 if (selectedwidget < 0) {
6437 dst[i].configname = my_strdup (dst[i].configname);
6438 dst[i].name = my_strdup (dst[i].name);
6439 }
6440 }
6441 }
6442
6443 // copy whole configuration #x-slot to another
6444 // +1 = default
6445 // +2 = default (pc keyboard)
inputdevice_copy_single_config(struct uae_prefs * p,int src,int dst,int devnum,int selectedwidget)6446 void inputdevice_copy_single_config (struct uae_prefs *p, int src, int dst, int devnum, int selectedwidget)
6447 {
6448 if (selectedwidget >= 0) {
6449 if (devnum < 0)
6450 return;
6451 if (gettype (devnum) != IDTYPE_KEYBOARD)
6452 return;
6453 }
6454 if (src >= MAX_INPUT_SETTINGS) {
6455 if (gettype (devnum) == IDTYPE_KEYBOARD) {
6456 p->input_keyboard_type = src > MAX_INPUT_SETTINGS ? 1 : 0;
6457 keyboard_default = keyboard_default_table[p->input_keyboard_type];
6458 inputdevice_default_kb (p, dst);
6459 }
6460 }
6461 if (src == dst)
6462 return;
6463 if (src < MAX_INPUT_SETTINGS) {
6464 if (devnum < 0 || gettype (devnum) == IDTYPE_JOYSTICK)
6465 copydev (p->joystick_settings[dst], p->joystick_settings[src], selectedwidget);
6466 if (devnum < 0 || gettype (devnum) == IDTYPE_MOUSE)
6467 copydev (p->mouse_settings[dst], p->mouse_settings[src], selectedwidget);
6468 if (devnum < 0 || gettype (devnum) == IDTYPE_KEYBOARD)
6469 copydev (p->keyboard_settings[dst], p->keyboard_settings[src], selectedwidget);
6470 }
6471 }
6472
inputdevice_acquire(int allmode)6473 void inputdevice_acquire (int allmode)
6474 {
6475 int i;
6476
6477 for (i = 0; i < MAX_INPUT_DEVICES; i++)
6478 idev[IDTYPE_JOYSTICK].unacquire (i);
6479 for (i = 0; i < MAX_INPUT_DEVICES; i++)
6480 idev[IDTYPE_MOUSE].unacquire (i);
6481 for (i = 0; i < MAX_INPUT_DEVICES; i++)
6482 idev[IDTYPE_KEYBOARD].unacquire (i);
6483
6484 for (i = 0; i < MAX_INPUT_DEVICES; i++) {
6485 if ((use_joysticks[i] && allmode >= 0) || (allmode && !idev[IDTYPE_JOYSTICK].get_flags (i)))
6486 idev[IDTYPE_JOYSTICK].acquire (i, 0);
6487 }
6488 for (i = 0; i < MAX_INPUT_DEVICES; i++) {
6489 if ((use_mice[i] && allmode >= 0) || (allmode && !idev[IDTYPE_MOUSE].get_flags (i)))
6490 idev[IDTYPE_MOUSE].acquire (i, allmode < 0);
6491 }
6492 for (i = 0; i < MAX_INPUT_DEVICES; i++) {
6493 if ((use_keyboards[i] && allmode >= 0) || (allmode < 0 && !idev[IDTYPE_KEYBOARD].get_flags (i)))
6494 idev[IDTYPE_KEYBOARD].acquire (i, allmode < 0);
6495 }
6496
6497 if (input_acquired)
6498 return;
6499
6500 idev[IDTYPE_JOYSTICK].acquire (-1, 0);
6501 idev[IDTYPE_MOUSE].acquire (-1, 0);
6502 idev[IDTYPE_KEYBOARD].acquire (-1, 0);
6503 // if (!input_acquired)
6504 // write_log (_T("input devices acquired (%s)\n"), allmode ? "all" : "selected only");
6505 input_acquired = 1;
6506 }
6507
inputdevice_unacquire(void)6508 void inputdevice_unacquire (void)
6509 {
6510 int i;
6511
6512 for (i = 0; i < MAX_INPUT_DEVICES; i++)
6513 idev[IDTYPE_JOYSTICK].unacquire (i);
6514 for (i = 0; i < MAX_INPUT_DEVICES; i++)
6515 idev[IDTYPE_MOUSE].unacquire (i);
6516 for (i = 0; i < MAX_INPUT_DEVICES; i++)
6517 idev[IDTYPE_KEYBOARD].unacquire (i);
6518
6519 if (!input_acquired)
6520 return;
6521
6522 input_acquired = 0;
6523 idev[IDTYPE_JOYSTICK].unacquire (-1);
6524 idev[IDTYPE_MOUSE].unacquire (-1);
6525 idev[IDTYPE_KEYBOARD].unacquire (-1);
6526 }
6527
inputdevice_testrecord(int type,int num,int wtype,int wnum,int state,int max)6528 void inputdevice_testrecord (int type, int num, int wtype, int wnum, int state, int max)
6529 {
6530 if (wnum < 0) {
6531 testmode = -1;
6532 return;
6533 }
6534 if (testmode_count >= TESTMODE_MAX)
6535 return;
6536 if (type == IDTYPE_KEYBOARD) {
6537 if (wnum >= 0x100) {
6538 wnum = 0x100 - wnum;
6539 } else {
6540 struct uae_input_device *na = &keyboards[num];
6541 int j = 0;
6542 while (j < MAX_INPUT_DEVICE_EVENTS && na->extra[j] >= 0) {
6543 if (na->extra[j] == wnum) {
6544 wnum = j;
6545 break;
6546 }
6547 j++;
6548 }
6549 if (j >= MAX_INPUT_DEVICE_EVENTS || na->extra[j] < 0)
6550 return;
6551 }
6552 }
6553 // wait until previous event is released before accepting new ones
6554 for (int i = 0; i < TESTMODE_MAX; i++) {
6555 struct teststore *ts2 = &testmode_wait[i];
6556 if (ts2->testmode_num < 0)
6557 continue;
6558 if (ts2->testmode_num != num || ts2->testmode_type != type || ts2->testmode_wtype != wtype || ts2->testmode_wnum != wnum)
6559 continue;
6560 if (max <= 0) {
6561 if (state)
6562 continue;
6563 } else {
6564 if (state < -(max / 2) || state > (max / 2))
6565 continue;
6566 }
6567 ts2->testmode_num = -1;
6568 }
6569 if (max <= 0) {
6570 if (!state)
6571 return;
6572 } else {
6573 if (state >= -(max / 2) && state <= (max / 2))
6574 return;
6575 }
6576
6577 //write_log (_T("%d %d %d %d %d/%d\n"), type, num, wtype, wnum, state, max);
6578 struct teststore *ts = &testmode_data[testmode_count];
6579 ts->testmode_type = type;
6580 ts->testmode_num = num;
6581 ts->testmode_wtype = wtype;
6582 ts->testmode_wnum = wnum;
6583 ts->testmode_state = state;
6584 ts->testmode_max = max;
6585 testmode_count++;
6586 }
6587
inputdevice_istest(void)6588 int inputdevice_istest (void)
6589 {
6590 return testmode;
6591 }
inputdevice_settest(int set)6592 void inputdevice_settest (int set)
6593 {
6594 testmode = set;
6595 testmode_count = 0;
6596 testmode_wait[0].testmode_num = -1;
6597 testmode_wait[1].testmode_num = -1;
6598 }
6599
inputdevice_testread_count(void)6600 int inputdevice_testread_count (void)
6601 {
6602 inputdevice_read ();
6603 if (testmode != 1) {
6604 testmode = 0;
6605 return -1;
6606 }
6607 return testmode_count;
6608 }
6609
inputdevice_testread(int * devnum,int * wtype,int * state,bool doread)6610 int inputdevice_testread (int *devnum, int *wtype, int *state, bool doread)
6611 {
6612 if (doread) {
6613 inputdevice_read ();
6614 if (testmode != 1) {
6615 testmode = 0;
6616 return -1;
6617 }
6618 }
6619 if (testmode_count > 0) {
6620 testmode_count--;
6621 struct teststore *ts = &testmode_data[testmode_count];
6622 *devnum = getdevnum (ts->testmode_type, ts->testmode_num);
6623 if (ts->testmode_wnum >= 0 && ts->testmode_wnum < MAX_INPUT_DEVICE_EVENTS)
6624 *wtype = idev[ts->testmode_type].get_widget_first (ts->testmode_num, ts->testmode_wtype) + ts->testmode_wnum;
6625 else
6626 *wtype = ts->testmode_wnum;
6627 *state = ts->testmode_state;
6628 if (ts->testmode_state)
6629 memcpy (&testmode_wait[testmode_count], ts, sizeof (struct teststore));
6630 return 1;
6631 }
6632 return 0;
6633 }
6634
6635 /* Call this function when host machine's joystick/joypad/etc button state changes
6636 * This function translates button events to Amiga joybutton/joyaxis/keyboard events
6637 */
6638
6639 /* button states:
6640 * state = -1 -> mouse wheel turned or similar (button without release)
6641 * state = 1 -> button pressed
6642 * state = 0 -> button released
6643 */
6644
setjoybuttonstate(int joy,int button,int state)6645 void setjoybuttonstate (int joy, int button, int state)
6646 {
6647 if (testmode) {
6648 inputdevice_testrecord (IDTYPE_JOYSTICK, joy, IDEV_WIDGET_BUTTON, button, state, -1);
6649 if (state < 0)
6650 inputdevice_testrecord (IDTYPE_JOYSTICK, joy, IDEV_WIDGET_BUTTON, button, 0, -1);
6651 return;
6652 }
6653 #if 0
6654 if (ignoreoldinput (joy)) {
6655 if (state)
6656 switchdevice (&joysticks[joy], button, 1);
6657 return;
6658 }
6659 #endif
6660 setbuttonstateall (&joysticks[joy], &joysticks2[joy], button, state ? 1 : 0);
6661 }
6662
6663 /* buttonmask = 1 = normal toggle button, 0 = mouse wheel turn or similar
6664 */
setjoybuttonstateall(int joy,uae_u32 buttonbits,uae_u32 buttonmask)6665 void setjoybuttonstateall (int joy, uae_u32 buttonbits, uae_u32 buttonmask)
6666 {
6667 int i;
6668
6669 #if 0
6670 if (ignoreoldinput (joy))
6671 return;
6672 #endif
6673 for (i = 0; i < ID_BUTTON_TOTAL; i++) {
6674 if (buttonmask & (1 << i))
6675 setbuttonstateall (&joysticks[joy], &joysticks2[joy], i, (buttonbits & (1 << i)) ? 1 : 0);
6676 else if (buttonbits & (1 << i))
6677 setbuttonstateall (&joysticks[joy], &joysticks2[joy], i, -1);
6678 }
6679 }
6680 /* mouse buttons (just like joystick buttons)
6681 */
setmousebuttonstateall(int mouse,uae_u32 buttonbits,uae_u32 buttonmask)6682 void setmousebuttonstateall (int mouse, uae_u32 buttonbits, uae_u32 buttonmask)
6683 {
6684 int i;
6685 uae_u32 obuttonmask = mice2[mouse].buttonmask;
6686
6687 for (i = 0; i < ID_BUTTON_TOTAL; i++) {
6688 if (buttonmask & (1 << i))
6689 setbuttonstateall (&mice[mouse], &mice2[mouse], i, (buttonbits & (1 << i)) ? 1 : 0);
6690 else if (buttonbits & (1 << i))
6691 setbuttonstateall (&mice[mouse], &mice2[mouse], i, -1);
6692 }
6693 if (obuttonmask != mice2[mouse].buttonmask)
6694 mousehack_helper (mice2[mouse].buttonmask);
6695 }
6696
setmousebuttonstate(int mouse,int button,int state)6697 void setmousebuttonstate (int mouse, int button, int state)
6698 {
6699 uae_u32 obuttonmask = mice2[mouse].buttonmask;
6700 if (testmode) {
6701 inputdevice_testrecord (IDTYPE_MOUSE, mouse, IDEV_WIDGET_BUTTON, button, state, -1);
6702 return;
6703 }
6704 setbuttonstateall (&mice[mouse], &mice2[mouse], button, state);
6705 if (obuttonmask != mice2[mouse].buttonmask)
6706 mousehack_helper (mice2[mouse].buttonmask);
6707 }
6708
6709 /* same for joystick axis (analog or digital)
6710 * (0 = center, -max = full left/top, max = full right/bottom)
6711 */
setjoystickstate(int joy,int axis,int state,int max)6712 void setjoystickstate (int joy, int axis, int state, int max)
6713 {
6714 struct uae_input_device *id = &joysticks[joy];
6715 struct uae_input_device2 *id2 = &joysticks2[joy];
6716 int deadzone = currprefs.input_joymouse_deadzone * max / 100;
6717 int i, v1, v2;
6718
6719 if (testmode) {
6720 inputdevice_testrecord (IDTYPE_JOYSTICK, joy, IDEV_WIDGET_AXIS, axis, state, max);
6721 return;
6722 }
6723 v1 = state;
6724 v2 = id2->states[axis][MAX_INPUT_SUB_EVENT];
6725
6726 //write_log (_T("new=%d old=%d axis=%d state=%d max=%d\n"), v1, v2, axis, state, max);
6727
6728 if (v1 < deadzone && v1 > -deadzone)
6729 v1 = 0;
6730 if (v2 < deadzone && v2 > -deadzone)
6731 v2 = 0;
6732 if (input_play && state) {
6733 if (v1 != v2)
6734 inprec_realtimev ();
6735 }
6736 if (input_play)
6737 return;
6738 if (!joysticks[joy].enabled) {
6739 if (v1 && v1 != v2)
6740 switchdevice (&joysticks[joy], axis * 2 + (v1 < 0 ? 0 : 1), false);
6741 return;
6742 }
6743 for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
6744 uae_u64 flags = id->flags[ID_AXIS_OFFSET + axis][i];
6745 if (flags & ID_FLAG_INVERT)
6746 state = -state;
6747 if (state != id2->states[axis][i]) {
6748 //write_log(_T("-> %d %d\n"), i, state);
6749 handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, flags & ID_FLAG_AUTOFIRE, true, false);
6750 id2->states[axis][i] = state;
6751 }
6752 }
6753 id2->states[axis][MAX_INPUT_SUB_EVENT] = v1;
6754 }
getjoystickstate(int joy)6755 int getjoystickstate (int joy)
6756 {
6757 if (testmode)
6758 return 1;
6759 return joysticks[joy].enabled;
6760 }
6761
setmousestate(int mouse,int axis,int data,int isabs)6762 void setmousestate (int mouse, int axis, int data, int isabs)
6763 {
6764 int i, v, diff;
6765 int *mouse_p, *oldm_p;
6766 float d;
6767 struct uae_input_device *id = &mice[mouse];
6768 static float fract[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
6769
6770 if (testmode) {
6771 inputdevice_testrecord (IDTYPE_MOUSE, mouse, IDEV_WIDGET_AXIS, axis, data, -1);
6772 // fake "release" event
6773 inputdevice_testrecord (IDTYPE_MOUSE, mouse, IDEV_WIDGET_AXIS, axis, 0, -1);
6774 return;
6775 }
6776 if (input_play)
6777 return;
6778 if (!mice[mouse].enabled) {
6779 if (isabs && currprefs.input_tablet > 0) {
6780 if (axis == 0)
6781 lastmx = data;
6782 else
6783 lastmy = data;
6784 if (axis)
6785 mousehack_helper (mice2[mouse].buttonmask);
6786 }
6787 return;
6788 }
6789 d = 0;
6790 mouse_p = &mouse_axis[mouse][axis];
6791 oldm_p = &oldm_axis[mouse][axis];
6792 if (!isabs) {
6793 // eat relative movements while in mousehack mode
6794 /* if (currprefs.input_tablet == TABLET_MOUSEHACK && mousehack_alive ())
6795 return;*/
6796 *oldm_p = *mouse_p;
6797 *mouse_p += data;
6798 d = (*mouse_p - *oldm_p) * currprefs.input_mouse_speed / 100.0f;
6799 } else {
6800 d = data - *oldm_p;
6801 *oldm_p = data;
6802 *mouse_p += d;
6803 if (axis == 0)
6804 lastmx = data;
6805 else
6806 lastmy = data;
6807 if (axis)
6808 mousehack_helper (mice2[mouse].buttonmask);
6809 if (currprefs.input_tablet == TABLET_MOUSEHACK && mousehack_alive ())
6810 return;
6811 }
6812 v = (int)d;
6813 fract[mouse][axis] += d - v;
6814 diff = (int)fract[mouse][axis];
6815 v += diff;
6816 fract[mouse][axis] -= diff;
6817 for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
6818 uae_u64 flags = id->flags[ID_AXIS_OFFSET + axis][i];
6819 if (!isabs && (flags & ID_FLAG_INVERT))
6820 v = -v;
6821 handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], v, 0, 0, true, false);
6822 }
6823 }
6824
getmousestate(int joy)6825 int getmousestate (int joy)
6826 {
6827 if (testmode)
6828 return 1;
6829 return mice[joy].enabled;
6830 }
6831
warpmode(int mode)6832 void warpmode (int mode)
6833 {
6834 int fr, fr2;
6835
6836 fr = currprefs.gfx_framerate;
6837 if (fr == 0)
6838 fr = -1;
6839 fr2 = currprefs.turbo_emulation;
6840 if (fr2 == -1)
6841 fr2 = 0;
6842
6843 if (mode < 0) {
6844 if (currprefs.turbo_emulation) {
6845 changed_prefs.gfx_framerate = currprefs.gfx_framerate = fr2;
6846 currprefs.turbo_emulation = 0;
6847 } else {
6848 currprefs.turbo_emulation = fr;
6849 }
6850 } else if (mode == 0 && currprefs.turbo_emulation) {
6851 if (currprefs.turbo_emulation > 0)
6852 changed_prefs.gfx_framerate = currprefs.gfx_framerate = fr2;
6853 currprefs.turbo_emulation = 0;
6854 } else if (mode > 0 && !currprefs.turbo_emulation) {
6855 currprefs.turbo_emulation = fr;
6856 }
6857 if (currprefs.turbo_emulation) {
6858 if (!currprefs.cpu_cycle_exact && !currprefs.blitter_cycle_exact)
6859 changed_prefs.gfx_framerate = currprefs.gfx_framerate = 10;
6860 pause_sound ();
6861 } else {
6862 resume_sound ();
6863 }
6864 compute_vsynctime ();
6865 #ifdef RETROPLATFORM
6866 rp_turbo_cpu (currprefs.turbo_emulation);
6867 #endif
6868 changed_prefs.turbo_emulation = currprefs.turbo_emulation;
6869 config_changed = 1;
6870 setsystime ();
6871 }
6872
pausemode(int mode)6873 void pausemode (int mode)
6874 {
6875 if (mode < 0)
6876 pause_emulation = pause_emulation ? 0 : 9;
6877 else
6878 pause_emulation = mode;
6879 config_changed = 1;
6880 setsystime ();
6881 }
6882
jsem_isjoy(int port,const struct uae_prefs * p)6883 int jsem_isjoy (int port, const struct uae_prefs *p)
6884 {
6885 int v = JSEM_DECODEVAL (port, p);
6886 if (v < JSEM_JOYS)
6887 return -1;
6888 v -= JSEM_JOYS;
6889 if (v >= inputdevice_get_device_total (IDTYPE_JOYSTICK))
6890 return -1;
6891 return v;
6892 }
6893
jsem_ismouse(int port,const struct uae_prefs * p)6894 int jsem_ismouse (int port, const struct uae_prefs *p)
6895 {
6896 int v = JSEM_DECODEVAL (port, p);
6897 if (v < JSEM_MICE)
6898 return -1;
6899 v -= JSEM_MICE;
6900 if (v >= inputdevice_get_device_total (IDTYPE_MOUSE))
6901 return -1;
6902 return v;
6903 }
6904
jsem_iskbdjoy(int port,const struct uae_prefs * p)6905 int jsem_iskbdjoy (int port, const struct uae_prefs *p)
6906 {
6907 int v = JSEM_DECODEVAL (port, p);
6908 if (v < JSEM_KBDLAYOUT)
6909 return -1;
6910 v -= JSEM_KBDLAYOUT;
6911 if (v >= JSEM_LASTKBD)
6912 return -1;
6913 return v;
6914 }
6915
inputdevice_joyport_config(struct uae_prefs * p,const TCHAR * value,int portnum,int mode,int type)6916 int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type)
6917 {
6918 switch (type)
6919 {
6920 case 1:
6921 case 2:
6922 {
6923 int i, j;
6924 for (j = 0; j < MAX_JPORTS; j++) {
6925 struct inputdevice_functions *idf;
6926 int type = IDTYPE_MOUSE;
6927 int idnum = JSEM_MICE;
6928 if (j > 0) {
6929 type = IDTYPE_JOYSTICK;
6930 idnum = JSEM_JOYS;
6931 }
6932 idf = &idev[type];
6933 for (i = 0; i < idf->get_num (); i++) {
6934 TCHAR *name1 = idf->get_friendlyname (i);
6935 TCHAR *name2 = idf->get_uniquename (i);
6936 if ((name1 && !_tcscmp (name1, value)) || (name2 && !_tcscmp (name2, value))) {
6937 p->jports[portnum].id = idnum + i;
6938 if (mode >= 0)
6939 p->jports[portnum].mode = mode;
6940 config_changed = 1;
6941 return 1;
6942 }
6943 }
6944 }
6945 }
6946 break;
6947 case 0:
6948 {
6949 int start = JPORT_NONE, got = 0, max = -1;
6950 const TCHAR *pp = 0;
6951 if (_tcsncmp (value, _T("kbd"), 3) == 0) {
6952 start = JSEM_KBDLAYOUT;
6953 pp = value + 3;
6954 got = 1;
6955 max = JSEM_LASTKBD;
6956 } else if (_tcsncmp (value, _T("joy"), 3) == 0) {
6957 start = JSEM_JOYS;
6958 pp = value + 3;
6959 got = 1;
6960 max = idev[IDTYPE_JOYSTICK].get_num ();
6961 } else if (_tcsncmp (value, _T("mouse"), 5) == 0) {
6962 start = JSEM_MICE;
6963 pp = value + 5;
6964 got = 1;
6965 max = idev[IDTYPE_MOUSE].get_num ();
6966 } else if (_tcscmp (value, _T("none")) == 0) {
6967 got = 2;
6968 } else if (_tcscmp (value, _T("custom")) == 0) {
6969 got = 2;
6970 start = JPORT_CUSTOM;
6971 }
6972 if (got) {
6973 if (pp && max != 0) {
6974 int v = _tstol (pp);
6975 if (start >= 0) {
6976 if (start == JSEM_KBDLAYOUT && v > 0)
6977 v--;
6978 if (v >= 0) {
6979 if (v >= max)
6980 v = 0;
6981 start += v;
6982 got = 2;
6983 }
6984 }
6985 }
6986 if (got == 2) {
6987 p->jports[portnum].id = start;
6988 if (mode >= 0)
6989 p->jports[portnum].mode = mode;
6990 if (start < JSEM_JOYS)
6991 default_keyboard_layout[portnum] = start;
6992 config_changed = 1;
6993 return 1;
6994 }
6995 // joystick not found, select default
6996 if (start == JSEM_JOYS && p->jports[portnum].id < JSEM_JOYS) {
6997 p->jports[portnum].id = default_keyboard_layout[portnum];
6998 config_changed = 1;
6999 return 1;
7000 }
7001 }
7002 }
7003 break;
7004 }
7005 return 0;
7006 }
7007
inputdevice_getjoyportdevice(int port,int val)7008 int inputdevice_getjoyportdevice (int port, int val)
7009 {
7010 int idx;
7011 if (val == JPORT_CUSTOM) {
7012 idx = inputdevice_get_device_total (IDTYPE_JOYSTICK) + JSEM_LASTKBD;
7013 if (port < 2)
7014 idx += inputdevice_get_device_total (IDTYPE_MOUSE);
7015 } else if (val < 0) {
7016 idx = -1;
7017 } else if (val >= JSEM_MICE) {
7018 idx = val - JSEM_MICE;
7019 if (idx >= inputdevice_get_device_total (IDTYPE_MOUSE))
7020 idx = 0;
7021 else
7022 idx += inputdevice_get_device_total (IDTYPE_JOYSTICK);
7023 idx += JSEM_LASTKBD;
7024 } else if (val >= JSEM_JOYS) {
7025 idx = val - JSEM_JOYS;
7026 if (idx >= inputdevice_get_device_total (IDTYPE_JOYSTICK))
7027 idx = 0;
7028 idx += JSEM_LASTKBD;
7029 } else {
7030 idx = val - JSEM_KBDLAYOUT;
7031 }
7032 return idx;
7033 }
7034
7035 #ifdef SAVESTATE
7036 // for state recorder use only!
7037
save_inputstate(int * len,uae_u8 * dstptr)7038 uae_u8 *save_inputstate (int *len, uae_u8 *dstptr)
7039 {
7040 uae_u8 *dstbak, *dst;
7041
7042 if (dstptr)
7043 dstbak = dst = dstptr;
7044 else
7045 dstbak = dst = xmalloc (uae_u8, 1000);
7046 for (int i = 0; i < MAX_JPORTS; i++) {
7047 save_u16 (joydir[i]);
7048 save_u16 (joybutton[i]);
7049 save_u16 (otop[i]);
7050 save_u16 (obot[i]);
7051 save_u16 (oleft[i]);
7052 save_u16 (oright[i]);
7053 }
7054 for (int i = 0; i < NORMAL_JPORTS; i++) {
7055 save_u16 (cd32_shifter[i]);
7056 for (int j = 0; j < 2; j++) {
7057 save_u16 (pot_cap[i][j]);
7058 save_u16 (joydirpot[i][j]);
7059 }
7060 }
7061 for (int i = 0; i < NORMAL_JPORTS; i++) {
7062 for (int j = 0; j < MOUSE_AXIS_TOTAL; j++) {
7063 save_u16 (mouse_delta[i][j]);
7064 save_u16 (mouse_deltanoreset[i][j]);
7065 }
7066 save_u16 (mouse_frame_x[i]);
7067 save_u16 (mouse_frame_y[i]);
7068 }
7069 *len = dst - dstbak;
7070 return dstbak;
7071 }
7072
restore_inputstate(uae_u8 * src)7073 uae_u8 *restore_inputstate (uae_u8 *src)
7074 {
7075 for (int i = 0; i < MAX_JPORTS; i++) {
7076 joydir[i] = restore_u16 ();
7077 joybutton[i] = restore_u16 ();
7078 otop[i] = restore_u16 ();
7079 obot[i] = restore_u16 ();
7080 oleft[i] = restore_u16 ();
7081 oright[i] = restore_u16 ();
7082 }
7083 for (int i = 0; i < NORMAL_JPORTS; i++) {
7084 cd32_shifter[i] = restore_u16 ();
7085 for (int j = 0; j < 2; j++) {
7086 pot_cap[i][j] = restore_u16 ();
7087 joydirpot[i][j] = restore_u16 ();
7088 }
7089 }
7090 for (int i = 0; i < NORMAL_JPORTS; i++) {
7091 for (int j = 0; j < MOUSE_AXIS_TOTAL; j++) {
7092 mouse_delta[i][j] = restore_u16 ();
7093 mouse_deltanoreset[i][j] = restore_u16 ();
7094 }
7095 mouse_frame_x[i] = restore_u16 ();
7096 mouse_frame_y[i] = restore_u16 ();
7097 }
7098 return src;
7099 }
7100
clear_inputstate(void)7101 void clear_inputstate (void)
7102 {
7103 return;
7104 for (int i = 0; i < MAX_JPORTS; i++) {
7105 horizclear[i] = 1;
7106 vertclear[i] = 1;
7107 }
7108 }
7109 #endif
7110