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