|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
1.1.1.2 root 4: * joystick/mouse emulation
5: *
6: * Copyright 2001, 2002 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
1.1 root 16: *
17: */
18:
1.1.1.2 root 19: //#define DONGLE_DEBUG
20:
1.1 root 21: #include "sysconfig.h"
22: #include "sysdeps.h"
23:
24: #include "options.h"
1.1.1.2 root 25: #include "keyboard.h"
26: #include "inputdevice.h"
27: #include "keybuf.h"
1.1 root 28: #include "custom.h"
29: #include "xwin.h"
1.1.1.2 root 30: #include "drawing.h"
1.1 root 31: #include "memory.h"
1.1.1.2 root 32: #include "events.h"
1.1 root 33: #include "newcpu.h"
1.1.1.2 root 34: #include "uae.h"
1.1 root 35: #include "picasso96.h"
1.1.1.2 root 36: #include "debug.h"
37: #include "gui.h"
38: #include "disk.h"
39: #include "audio.h"
40: #include "savestate.h"
41:
42: #define DIR_LEFT 1
43: #define DIR_RIGHT 2
44: #define DIR_UP 4
45: #define DIR_DOWN 8
46:
47: struct inputevent {
48: char *confname;
49: char *name;
50: int allow_mask;
51: int type;
52: int unit;
53: int data;
54: };
55:
56: #define JOYBUTTON_1 0 /* fire/left mousebutton */
57: #define JOYBUTTON_2 1 /* 2nd/right mousebutton */
58: #define JOYBUTTON_3 2 /* 3rd/middle mousebutton */
59: #define JOYBUTTON_CD32_PLAY 3
60: #define JOYBUTTON_CD32_RWD 4
61: #define JOYBUTTON_CD32_FFW 5
62: #define JOYBUTTON_CD32_GREEN 6
63: #define JOYBUTTON_CD32_YELLOW 7
64: #define JOYBUTTON_CD32_RED 8
65: #define JOYBUTTON_CD32_BLUE 9
66:
67: #define INPUTEVENT_JOY1_CD32_FIRST INPUTEVENT_JOY1_CD32_PLAY
68: #define INPUTEVENT_JOY2_CD32_FIRST INPUTEVENT_JOY2_CD32_PLAY
69: #define INPUTEVENT_JOY1_CD32_LAST INPUTEVENT_JOY1_CD32_BLUE
70: #define INPUTEVENT_JOY2_CD32_LAST INPUTEVENT_JOY2_CD32_BLUE
71:
72: /* event masks */
73: #define AM_KEY 1 /* keyboard allowed */
74: #define AM_JOY_BUT 2 /* joystick buttons allowed */
75: #define AM_JOY_AXIS 4 /* joystick axis allowed */
76: #define AM_MOUSE_BUT 8 /* mouse buttons allowed */
77: #define AM_MOUSE_AXIS 16 /* mouse direction allowed */
78: #define AM_AF 32 /* supports autofire */
79: #define AM_INFO 64 /* information data for gui */
80: #define AM_DUMMY 128 /* placeholder */
1.1.1.3 ! root 81: #define AM_AUTO 256 /* forces autofire */
1.1.1.2 root 82: #define AM_K (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT|AM_AF) /* generic button/switch */
83:
84: /* event flags */
85: #define ID_FLAG_AUTOFIRE 1
86:
87: #define DEFEVENT(A, B, C, D, E, F) {#A, B, C, D, E, F },
88: struct inputevent events[] = {
1.1.1.3 ! root 89: {0, 0, AM_K, 0, 0, 0},
1.1.1.2 root 90: #include "inputevents.def"
91: {0, 0, 0, 0, 0, 0}
92: };
93: #undef DEFEVENT
94:
95: static int sublevdir[2][MAX_INPUT_SUB_EVENT];
96:
97: struct uae_input_device2 {
98: uae_u32 buttonmask;
99: int states[MAX_INPUT_DEVICE_EVENTS / 2];
100: };
1.1 root 101:
1.1.1.2 root 102: static struct uae_input_device2 joysticks2[MAX_INPUT_DEVICES];
103: static struct uae_input_device2 mice2[MAX_INPUT_DEVICES];
1.1 root 104:
1.1.1.2 root 105: static uae_u8 mouse_settings_reset[MAX_INPUT_SETTINGS][MAX_INPUT_DEVICES];
106: static uae_u8 joystick_settings_reset[MAX_INPUT_SETTINGS][MAX_INPUT_DEVICES];
1.1 root 107:
1.1.1.3 ! root 108: static struct inputdevice_functions idev[3];
! 109:
1.1.1.2 root 110: static int isdevice (struct uae_input_device *id)
111: {
112: int i, j;
113: for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
114: for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
115: if (id->eventid[i][j] > 0)
116: return 1;
117: }
118: }
119: return 0;
120: }
1.1 root 121:
1.1.1.2 root 122: int inputdevice_uaelib (char *s, char *parm)
123: {
124: int i;
125:
126: for (i = 1; events[i].name; i++) {
127: if (!strcmp (s, events[i].confname)) {
128: handle_input_event (i, atol (parm), 1, 0);
129: return 1;
130: }
131: }
132: return 0;
133: }
134:
135: static struct uae_input_device *joysticks;
136: static struct uae_input_device *mice;
137: static struct uae_input_device *keyboards;
138: static struct uae_input_device_kbr_default *keyboard_default;
139:
140: static double mouse_axis[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
141: static double oldm_axis[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
142:
143: static int mouse_x[MAX_INPUT_DEVICES], mouse_y[MAX_INPUT_DEVICE_EVENTS];
144: static int mouse_delta[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
145: static int mouse_deltanoreset[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
146: static int joybutton[MAX_INPUT_DEVICES];
147: static unsigned int joydir[MAX_INPUT_DEVICE_EVENTS];
148: static int joydirpot[MAX_INPUT_DEVICE_EVENTS][2];
149: static int mouse_frame_x[2], mouse_frame_y[2];
150:
151: static int mouse_port[2];
152: static int cd32_shifter[2];
153: static int cd32_pad_enabled[2];
154: static int parport_joystick_enabled;
155: static int oldmx[4], oldmy[4];
156: static int oleft[4], oright[4], otop[4], obot[4];
157: static int potgo_hsync;
158:
159: static int use_joysticks[MAX_INPUT_DEVICES];
160: static int use_mice[MAX_INPUT_DEVICES];
161: static int use_keyboards[MAX_INPUT_DEVICES];
162:
163: #define INPUT_QUEUE_SIZE 16
164: struct input_queue_struct {
165: int event, storedstate, state, max, framecnt, nextframecnt;
166: };
167: static struct input_queue_struct input_queue[INPUT_QUEUE_SIZE];
168:
169: /* Sigh. */
170: #define cfgfile_write fprintf
171:
172: static void out_config (FILE *f, int id, int num, char *s1, char *s2)
173: {
174: cfgfile_write (f, "input.%d.%s%d=%s\n", id, s1, num, s2);
175: //write_log ("-input.%d.%s%d=%s\n", id, s1, num, s2);
176: }
177:
178: static void write_config2 (FILE *f, int idnum, int i, int offset, char *tmp1, struct uae_input_device *id)
179: {
180: char tmp2[200], *p;
181: int event, got, j, k;
182: char *custom;
183:
184: p = tmp2;
185: got = 0;
186: for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
187: event = id->eventid[i + offset][j];
188: custom = id->custom[i + offset][j];
189: if (custom == NULL && event <= 0) {
190: for (k = j + 1; k < MAX_INPUT_SUB_EVENT; k++) {
191: if (id->eventid[i + offset][k] > 0) break;
192: }
193: if (k == MAX_INPUT_SUB_EVENT)
194: break;
195: }
196: if (p > tmp2) {
197: *p++ = ',';
198: *p = 0;
199: }
200: if (custom)
201: sprintf (p, "'%s'.%d", custom, id->flags[i + offset][j]);
202: else if (event <= 0)
203: sprintf (p, "NULL");
204: else
205: sprintf (p, "%s.%d", events[event].confname, id->flags[i + offset][j]);
206: p += strlen (p);
207: }
208: if (p > tmp2)
209: out_config (f, idnum, i, tmp1, tmp2);
210: }
1.1 root 211:
1.1.1.2 root 212: static void write_config (FILE *f, int idnum, int devnum, char *name, struct uae_input_device *id, struct uae_input_device2 *id2)
213: {
214: char tmp1[100];
215: int i;
1.1 root 216:
1.1.1.2 root 217: if (!isdevice (id))
218: return;
219: cfgfile_write (f, "input.%d.%s.%d.disabled=%d\n", idnum, name, devnum, id->enabled ? 0 : 1);
220: sprintf (tmp1, "%s.%d.axis.", name, devnum);
221: for (i = 0; i < ID_AXIS_TOTAL; i++)
222: write_config2 (f, idnum, i, ID_AXIS_OFFSET, tmp1, id);
223: sprintf (tmp1, "%s.%d.button." ,name, devnum);
224: for (i = 0; i < ID_BUTTON_TOTAL; i++)
225: write_config2 (f, idnum, i, ID_BUTTON_OFFSET, tmp1, id);
226: }
1.1 root 227:
1.1.1.2 root 228: static void kbrlabel (char *s)
229: {
230: while (*s) {
231: *s = toupper(*s);
232: if (*s == ' ') *s = '_';
233: s++;
234: }
235: }
1.1 root 236:
1.1.1.2 root 237: static void write_kbr_config (FILE *f, int idnum, int devnum, struct uae_input_device *kbr)
1.1 root 238: {
1.1.1.2 root 239: char tmp1[200], tmp2[200], tmp3[200], *p;
240: int i, j, k, event, skip;
241:
242: if (!keyboard_default)
1.1 root 243: return;
1.1.1.2 root 244: i = 0;
245: while (i < MAX_INPUT_DEVICE_EVENTS && kbr->extra[i][0] >= 0) {
246: skip = 0;
247: k = 0;
248: while (keyboard_default[k].scancode >= 0) {
249: if (keyboard_default[k].scancode == kbr->extra[i][0]) {
250: skip = 1;
251: for (j = 1; j < MAX_INPUT_SUB_EVENT; j++) {
252: if (kbr->flags[i][j] || kbr->eventid[i][j] > 0)
253: skip = 0;
254: }
255: if (keyboard_default[k].event != kbr->eventid[i][0] || kbr->flags[i][0] != 0)
256: skip = 0;
257: break;
258: }
259: k++;
260: }
261: if (kbr->eventid[i][0] == 0 && kbr->flags[i][0] == 0 && keyboard_default[k].scancode < 0)
262: skip = 1;
263: if (skip) {
264: i++;
265: continue;
266: }
267: p = tmp2;
268: p[0] = 0;
269: for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
270: char *custom = kbr->custom[i][j];
271: event = kbr->eventid[i][j];
272: if (custom == NULL && event <= 0) {
273: for (k = j + 1; k < MAX_INPUT_SUB_EVENT; k++) {
274: if (kbr->eventid[i][k] > 0) break;
275: }
276: if (k == MAX_INPUT_SUB_EVENT)
277: break;
278: }
279: if (p > tmp2) {
280: *p++ = ',';
281: *p = 0;
282: }
283: if (custom)
284: sprintf (p, "'%s'.%d", custom, kbr->flags[i][j]);
285: else if (event > 0)
286: sprintf (p, "%s.%d", events[event].confname, kbr->flags[i][j]);
287: else
288: strcat (p, "NULL");
289: p += strlen(p);
290: }
291: sprintf (tmp3, "%d", kbr->extra[i][0]);
292: kbrlabel (tmp3);
293: sprintf (tmp1, "keyboard.%d.button.%s", devnum, tmp3);
294: cfgfile_write (f, "input.%d.%s=%s\n", idnum, tmp1, tmp2);
295: i++;
296: }
297: }
298:
299: void write_inputdevice_config (struct uae_prefs *p, FILE *f)
300: {
301: int i, id;
302:
303: cfgfile_write (f, "input.config=%d\n", p->input_selected_setting);
304: cfgfile_write (f, "input.joymouse_speed_analog=%d\n", p->input_joymouse_multiplier);
305: cfgfile_write (f, "input.joymouse_speed_digital=%d\n", p->input_joymouse_speed);
306: cfgfile_write (f, "input.joymouse_deadzone=%d\n", p->input_joymouse_deadzone);
307: cfgfile_write (f, "input.joystick_deadzone=%d\n", p->input_joystick_deadzone);
308: cfgfile_write (f, "input.mouse_speed=%d\n", p->input_mouse_speed);
309: cfgfile_write (f, "input.autofire=%d\n", p->input_autofire_framecnt);
310: for (id = 1; id <= MAX_INPUT_SETTINGS; id++) {
311: for (i = 0; i < MAX_INPUT_DEVICES; i++)
312: write_config (f, id, i, "joystick", &p->joystick_settings[id][i], &joysticks2[i]);
313: for (i = 0; i < MAX_INPUT_DEVICES; i++)
314: write_config (f, id, i, "mouse", &p->mouse_settings[id][i], &mice2[i]);
315: for (i = 0; i < MAX_INPUT_DEVICES; i++)
316: write_kbr_config (f, id, i, &p->keyboard_settings[id][i]);
317: }
318: }
319:
320: static int getnum (char **pp)
321: {
322: char *p = *pp;
323: int v = atol (p);
324:
1.1.1.3 ! root 325: while (*p != 0 && *p !='.' && *p != ',')
! 326: p++;
! 327: if (*p == '.' || *p == ',')
! 328: p++;
1.1.1.2 root 329: *pp = p;
330: return v;
331: }
332: static char *getstring (char **pp)
333: {
334: int i;
335: static char str[1000];
336: char *p = *pp;
337:
338: if (*p == 0)
339: return 0;
340: i = 0;
1.1.1.3 ! root 341: while (*p != 0 && *p !='.' && *p != ',')
! 342: str[i++] = *p++;
! 343: if (*p == '.' || *p == ',')
! 344: p++;
1.1.1.2 root 345: str[i] = 0;
346: *pp = p;
347: return str;
348: }
349:
350: void reset_inputdevice_config (struct uae_prefs *pr)
351: {
352: memset (joystick_settings_reset, 0, sizeof (joystick_settings_reset));
353: memset (mouse_settings_reset, 0, sizeof (mouse_settings_reset));
354: }
1.1 root 355:
1.1.1.2 root 356: static void clear_id (struct uae_input_device *id)
357: {
358: #ifndef _DEBUG
359: int i, j;
360: for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
361: for (j = 0; j < MAX_INPUT_SUB_EVENT; j++)
362: free (id->custom[i][j]);
363: }
364: #endif
365: memset (id, 0, sizeof (struct uae_input_device));
366: id->enabled = 1;
1.1 root 367: }
368:
1.1.1.2 root 369: void read_inputdevice_config (struct uae_prefs *pr, char *option, char *value)
1.1 root 370: {
1.1.1.2 root 371: struct uae_input_device *id = 0;
372: struct inputevent *ie;
373: int devnum, num, button, joystick, flags, i, subnum, idnum, keynum;
374: int mask;
375: char *p, *p2, *custom;
376:
377: option += 6; /* "input." */
378: p = getstring (&option);
379: if (!strcasecmp (p, "config"))
380: pr->input_selected_setting = atol (value);
381: if (!strcasecmp (p, "joymouse_speed_analog"))
382: pr->input_joymouse_multiplier = atol (value);
383: if (!strcasecmp (p, "joymouse_speed_digital"))
384: pr->input_joymouse_speed = atol (value);
385: if (!strcasecmp (p, "joystick_deadzone"))
386: pr->input_joystick_deadzone = atol (value);
387: if (!strcasecmp (p, "joymouse_deadzone"))
388: pr->input_joymouse_deadzone = atol (value);
389: if (!strcasecmp (p, "mouse_speed"))
390: pr->input_mouse_speed = atol (value);
391: if (!strcasecmp (p, "autofire"))
392: pr->input_autofire_framecnt = atol (value);
393: idnum = atol (p);
394: if (idnum <= 0 || idnum > MAX_INPUT_SETTINGS)
395: return;
396: if (memcmp (option, "mouse.", 6) == 0) {
397: p = option + 6;
398: devnum = getnum (&p);
399: if (devnum < 0 || devnum >= MAX_INPUT_DEVICES)
400: return;
401: id = &pr->mouse_settings[idnum][devnum];
402: if (!mouse_settings_reset[idnum][devnum])
403: clear_id (id);
404: mouse_settings_reset[idnum][devnum] = 1;
405: joystick = 0;
406: } else if (memcmp (option, "joystick.", 9) == 0) {
407: p = option + 9;
408: devnum = getnum (&p);
409: if (devnum < 0 || devnum >= MAX_INPUT_DEVICES)
410: return;
411: id = &pr->joystick_settings[idnum][devnum];
412: if (!joystick_settings_reset[idnum][devnum])
413: clear_id (id);
414: joystick_settings_reset[idnum][devnum] = 1;
415: joystick = 1;
416: } else if (memcmp (option, "keyboard.", 9) == 0) {
417: joystick = -1;
418: p = option + 9;
419: devnum = getnum (&p);
420: if (devnum < 0 || devnum >= MAX_INPUT_DEVICES)
421: return;
422: id = &pr->keyboard_settings[idnum][devnum];
423: }
424: if (!id)
425: return;
426: p2 = getstring (&p);
427: if (!p2)
1.1 root 428: return;
1.1.1.2 root 429: if (!strcmp (p2, "disabled")) {
430: int disabled;
431: p = value;
432: disabled = getnum (&p);
433: id->enabled = disabled == 0 ? 1 : 0;
434: return;
435: }
436:
437: if (joystick < 0) {
438: num = getnum (&p);
439: keynum = 0;
440: while (id->extra[keynum][0] >= 0) {
441: if (id->extra[keynum][0] == num)
442: break;
443: keynum++;
444: }
445: if (id->extra[keynum][0] < 0)
446: return;
447: } else {
448: button = -1;
449: if (!strcmp (p2, "axis"))
450: button = 0;
451: else if(!strcmp (p2, "button"))
452: button = 1;
453: if (button < 0)
454: return;
455: num = getnum (&p);
456: }
457: p = value;
458:
459: custom = NULL;
460: for (subnum = 0; subnum < MAX_INPUT_SUB_EVENT; subnum++) {
461: free (custom);
462: custom = NULL;
463: p2 = getstring (&p);
464: if (!p2)
465: break;
466: i = 1;
467: while (events[i].name) {
468: if (!strcmp (events[i].confname, p2))
469: break;
470: i++;
471: }
472: ie = &events[i];
473: if (!ie->name) {
474: ie = &events[0];
475: if (strlen (p2) > 2 && p2[0] == '\'' && p2[strlen (p2) - 1] == '\'') {
476: custom = my_strdup (p2 + 1);
477: custom[strlen (custom) - 1] = 0;
478: }
479: }
480: flags = getnum (&p);
481: if (custom == NULL && ie->name == NULL)
482: continue;
483: if (joystick < 0) {
484: if (!(ie->allow_mask & AM_K))
485: continue;
486: id->eventid[keynum][subnum] = ie - events;
487: id->flags[keynum][subnum] = flags;
488: free (id->custom[keynum][subnum]);
489: id->custom[keynum][subnum] = custom;
490: } else if (button) {
491: if (joystick)
492: mask = AM_JOY_BUT;
493: else
494: mask = AM_MOUSE_BUT;
495: if (!(ie->allow_mask & mask))
496: continue;
497: id->eventid[num + ID_BUTTON_OFFSET][subnum] = ie - events;
498: id->flags[num + ID_BUTTON_OFFSET][subnum] = flags;
499: free (id->custom[num + ID_BUTTON_OFFSET][subnum]);
500: id->custom[num + ID_BUTTON_OFFSET][subnum] = custom;
501: } else {
502: if (joystick)
503: mask = AM_JOY_AXIS;
504: else
505: mask = AM_MOUSE_AXIS;
506: if (!(ie->allow_mask & mask))
507: continue;
508: id->eventid[num + ID_AXIS_OFFSET][subnum] = ie - events;
509: id->flags[num + ID_AXIS_OFFSET][subnum] = flags;
510: free (id->custom[num + ID_AXIS_OFFSET][subnum]);
511: id->custom[num + ID_AXIS_OFFSET][subnum] = custom;
512: }
513: custom = NULL;
514: }
515: free (custom);
516: }
517:
518: /* Mousehack stuff */
1.1 root 519:
1.1.1.2 root 520: static int ievent_alive = 0;
521: static int lastmx, lastmy;
522:
523: int mousehack_alive (void)
524: {
525: return ievent_alive > 0;
1.1 root 526: }
527:
528: uae_u32 mousehack_helper (void)
529: {
530: int mousexpos, mouseypos;
531:
532: #ifdef PICASSO96
533: if (picasso_on) {
1.1.1.2 root 534: mousexpos = lastmx - picasso96_state.XOffset;
535: mouseypos = lastmy - picasso96_state.YOffset;
1.1 root 536: } else
537: #endif
538: {
1.1.1.2 root 539: if (mouse_y[0] >= gfxvidinfo.height)
540: mouse_y[0] = gfxvidinfo.height - 1;
1.1 root 541: mouseypos = coord_native_to_amiga_y (lastmy) << 1;
542: mousexpos = coord_native_to_amiga_x (lastmx);
543: }
544:
545: switch (m68k_dreg (regs, 0)) {
546: case 0:
547: return ievent_alive ? -1 : needmousehack ();
548: case 1:
549: ievent_alive = 10;
1.1.1.2 root 550: if (!mousehack_allowed ())
551: return 0;
1.1 root 552: return mousexpos;
553: case 2:
1.1.1.2 root 554: if (!mousehack_allowed ())
555: return 0;
1.1 root 556: return mouseypos;
557: }
558: return 0;
559: }
560:
561: STATIC_INLINE int adjust (int val)
562: {
563: if (val > 127)
564: return 127;
565: else if (val < -127)
566: return -127;
567: return val;
568: }
569:
1.1.1.2 root 570: int getbuttonstate (int joy, int button)
571: {
572: return joybutton[joy] & (1 << button);
573: }
574:
575: static void mouseupdate (int pct)
1.1 root 576: {
1.1.1.2 root 577: int v, i;
578:
579: for (i = 0; i < 2; i++) {
580:
581: v = mouse_delta[i][0] * pct / 100;
582: mouse_x[i] += v;
583: if (!mouse_deltanoreset[i][0])
584: mouse_delta[i][0] -= v;
585:
586: v = mouse_delta[i][1] * pct / 100;
587: mouse_y[i] += v;
588: if (!mouse_deltanoreset[i][1])
589: mouse_delta[i][1] -= v;
590:
591: v = mouse_delta[i][2] * pct / 100;
592: if (v > 0)
593: record_key (0x7a << 1);
594: else if (v < 0)
595: record_key (0x7b << 1);
596: if (!mouse_deltanoreset[i][2])
597: mouse_delta[i][2] = 0;
598:
599: if (mouse_frame_x[i] - mouse_x[i] > 127)
600: mouse_x[i] = mouse_frame_x[i] - 127;
601: if (mouse_frame_x[i] - mouse_x[i] < -127)
602: mouse_x[i] = mouse_frame_x[i] + 127;
603:
604: if (mouse_frame_y[i] - mouse_y[i] > 127)
605: mouse_y[i] = mouse_frame_y[i] - 127;
606: if (mouse_frame_y[i] - mouse_y[i] < -127)
607: mouse_y[i] = mouse_frame_y[i] + 127;
608:
609: if (pct == 100) {
610: if (!mouse_deltanoreset[i][0])
611: mouse_delta[i][0] = 0;
612: if (!mouse_deltanoreset[i][1])
613: mouse_delta[i][1] = 0;
614: if (!mouse_deltanoreset[i][2])
615: mouse_delta[i][2] = 0;
616: mouse_frame_x[i] = mouse_x[i];
617: mouse_frame_y[i] = mouse_y[i];
1.1 root 618: }
1.1.1.2 root 619:
620: }
621: }
622:
623: static int input_read, input_vpos;
624:
625: static void readinput (void)
626: {
627: if (!input_read && (vpos & ~31) != (input_vpos & ~31)) {
628: idev[IDTYPE_JOYSTICK].read ();
629: idev[IDTYPE_MOUSE].read ();
630: mouseupdate ((vpos - input_vpos) * 100 / maxvpos);
631: input_vpos = vpos;
632: }
633: if (input_read) {
634: input_vpos = vpos;
635: input_read = 0;
636: }
637: }
638:
639: int getjoystate (int joy)
640: {
641: int left = 0, right = 0, top = 0, bot = 0;
642: uae_u16 v = 0;
643:
644: readinput ();
645: if (joydir[joy] & DIR_LEFT)
646: left = 1;
647: if (joydir[joy] & DIR_RIGHT)
648: right = 1;
649: if (joydir[joy] & DIR_UP)
650: top = 1;
651: if (joydir[joy] & DIR_DOWN)
652: bot = 1;
653: v = (uae_u8)mouse_x[joy] | (mouse_y[joy] << 8);
654: if (left || right || top || bot || !mouse_port[joy]) {
655: if (left)
656: top = !top;
657: if (right)
658: bot = !bot;
659: v &= ~0x0303;
660: v |= bot | (right << 1) | (top << 8) | (left << 9);
661: }
662: #ifdef DONGLE_DEBUG
663: if (notinrom ())
664: write_log ("JOY%dDAT %04.4X %s\n", joy, v, debuginfo (0));
665: #endif
666: return v;
667: }
668:
669: uae_u16 JOY0DAT (void)
670: {
671: return getjoystate (0);
672: }
673: uae_u16 JOY1DAT (void)
674: {
675: return getjoystate (1);
676: }
677:
678: void JOYTEST (uae_u16 v)
679: {
680: mouse_x[0] &= 3;
681: mouse_y[0] &= 3;
682: mouse_x[1] &= 3;
683: mouse_y[1] &= 3;
684: mouse_x[0] |= v & 0xFC;
685: mouse_x[1] |= v & 0xFC;
686: mouse_y[0] |= (v >> 8) & 0xFC;
687: mouse_y[1] |= (v >> 8) & 0xFC;
688: mouse_frame_x[0] = mouse_x[0];
689: mouse_frame_y[0] = mouse_y[0];
690: mouse_frame_x[1] = mouse_x[1];
691: mouse_frame_y[1] = mouse_y[1];
692: // write_log ("%d:%04.4X %p\n",vpos,v,m68k_getpc());
693: }
694:
695: static uae_u8 parconvert (uae_u8 v, int jd, int shift)
696: {
697: if (jd & DIR_UP)
698: v &= ~(1 << shift);
699: if (jd & DIR_DOWN)
700: v &= ~(2 << shift);
701: if (jd & DIR_LEFT)
702: v &= ~(4 << shift);
703: if (jd & DIR_RIGHT)
704: v &= ~(8 << shift);
705: return v;
706: }
707:
708:
709:
710: /* io-pins floating: dir=1 -> return data, dir=0 -> always return 1 */
711: uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra)
712: {
713: uae_u8 v;
714: switch (port)
715: {
716: case 0:
717: v = (pra & dra) | (dra ^ 0xff);
718: if (parport_joystick_enabled) {
719: v = parconvert (v, joydir[2], 0);
720: v = parconvert (v, joydir[3], 4);
721: }
722: return v;
723: case 1:
724: v = ((pra & dra) | (dra ^ 0xff)) & 0x7;
725: if (parport_joystick_enabled) {
726: if (getbuttonstate (2, 0)) v &= ~1;
727: if (getbuttonstate (3, 0)) v &= ~4;
728: }
729: return v;
730: default:
1.1 root 731: abort ();
1.1.1.2 root 732: return 0;
1.1 root 733: }
734: }
735:
1.1.1.2 root 736: uae_u8 handle_joystick_buttons (uae_u8 dra)
1.1 root 737: {
1.1.1.2 root 738: uae_u8 but = 0;
739: int i;
740:
741: for (i = 0; i < 2; i++) {
742: if (cd32_pad_enabled[i]) {
743: uae_u16 p5dir = 0x0200 << (i * 4);
744: uae_u16 p5dat = 0x0100 << (i * 4);
745: but |= 0x40 << i;
746: /* Red button is connected to fire when p5 is 1 or floating */
747: if (!(potgo_value & p5dir) || ((potgo_value & p5dat) && (potgo_value & p5dir))) {
748: if (getbuttonstate (i, JOYBUTTON_CD32_RED))
749: but &= ~(0x40 << i);
750: }
751: } else if (!getbuttonstate (i, JOYBUTTON_1)) {
752: but |= 0x40 << i;
753: }
1.1 root 754: }
1.1.1.2 root 755: return but;
1.1 root 756: }
757:
1.1.1.2 root 758: /* joystick 1 button 1 is used as a output for incrementing shift register */
759: void handle_cd32_joystick_cia (uae_u8 pra, uae_u8 dra)
760: {
761: static int oldstate[2];
762: int i;
1.1 root 763:
1.1.1.2 root 764: for (i = 0; i < 2; i++) {
765: uae_u8 but = 0x40 << i;
766: uae_u16 p5dir = 0x0200 << (i * 4); /* output enable P5 */
767: uae_u16 p5dat = 0x0100 << (i * 4); /* data P5 */
768: if (!(potgo_value & p5dir) || !(potgo_value & p5dat)) {
769: if ((dra & but) && (pra & but) != oldstate[i]) {
770: if (!(pra & but)) {
771: cd32_shifter[i]--;
772: if (cd32_shifter[i] < 0)
773: cd32_shifter[i] = 0;
774: }
775: }
776: }
777: oldstate[i] = pra & but;
778: }
779: }
780:
781: /* joystick port 1 button 2 is input for button state */
782: static uae_u16 handle_joystick_potgor (uae_u16 potgor)
1.1 root 783: {
1.1.1.2 root 784: int i;
785:
786: for (i = 0; i < 2; i++) {
787: uae_u16 p9dir = 0x0800 << (i * 4); /* output enable P9 */
788: uae_u16 p9dat = 0x0400 << (i * 4); /* data P9 */
789: uae_u16 p5dir = 0x0200 << (i * 4); /* output enable P5 */
790: uae_u16 p5dat = 0x0100 << (i * 4); /* data P5 */
791:
792: if (mouse_port[i]) {
793: /* mouse has pull-up resistors in button lines */
794: if (!(potgo_value & p5dir))
795: potgor |= p5dat;
796: if (!(potgo_value & p9dir))
797: potgor |= p9dat;
798: }
799: if (potgo_hsync < 0) {
800: /* first 10 or so lines after potgo has started
801: * forces input-lines to zero
802: */
803: if (!(potgo_value & p5dir))
804: potgor &= ~p5dat;
805: if (!(potgo_value & p9dir))
806: potgor &= ~p9dat;
807: }
808:
809: if (cd32_pad_enabled[i]) {
810: /* p5 is floating in input-mode */
811: potgor &= ~p5dat;
812: potgor |= potgo_value & p5dat;
813: if (!(potgo_value & p9dir))
814: potgor |= p9dat;
815: /* P5 output and 1 -> shift register is kept reset (Blue button) */
816: if ((potgo_value & p5dir) && (potgo_value & p5dat))
817: cd32_shifter[i] = 8;
818: /* shift at 1 == return one, >1 = return button states */
819: if (cd32_shifter[i] == 0)
820: potgor &= ~p9dat; /* shift at zero == return zero */
821: if (cd32_shifter[i] >= 2 && (joybutton[i] & ((1 << JOYBUTTON_CD32_PLAY) << (cd32_shifter[i] - 2))))
822: potgor &= ~p9dat;
823: //write_log ("%d:%04.4X %08.8X\n", cd32_shifter[i], potgor, m68k_getpc());
824: } else {
825: if (getbuttonstate (i, JOYBUTTON_3))
826: potgor &= ~p5dat;
827: if (getbuttonstate (i, JOYBUTTON_2))
828: potgor &= ~p9dat;
829: }
830: }
831: return potgor;
1.1 root 832: }
833:
1.1.1.2 root 834: uae_u16 potgo_value;
835: static uae_u16 potdats[2];
836: static int inputdelay;
837:
838: void inputdevice_hsync (void)
1.1 root 839: {
1.1.1.2 root 840: int joy;
1.1 root 841:
1.1.1.2 root 842: for (joy = 0; joy < 2; joy++) {
843: if (potgo_hsync >= 0) {
844: int active;
845:
846: active = 0;
847: if ((potgo_value >> 9) & 1) /* output? */
848: active = ((potgo_value >> 8) & 1) ? 0 : 1;
849: if (potgo_hsync < joydirpot[joy][0])
850: active = 1;
851: if (getbuttonstate (joy, JOYBUTTON_3))
852: active = 1;
853: if (active)
854: potdats[joy] = ((potdats[joy] + 1) & 0xFF) | (potdats[joy] & 0xFF00);
855:
856: active = 0;
857: if ((potgo_value >> 11) & 1) /* output? */
858: active = ((potgo_value >> 10) & 1) ? 0 : 1;
859: if (potgo_hsync < joydirpot[joy][1])
860: active = 1;
861: if (getbuttonstate (joy, JOYBUTTON_2))
862: active = 1;
863: if (active)
864: potdats[joy] += 0x100;
865: }
866: }
867: potgo_hsync++;
868: if (potgo_hsync > 255)
869: potgo_hsync = 255;
1.1 root 870:
871:
1.1.1.2 root 872: #ifdef CATWEASEL
873: catweasel_hsync ();
874: #endif
875: if (inputdelay > 0) {
876: inputdelay--;
877: if (inputdelay == 0) {
878: idev[IDTYPE_JOYSTICK].read ();
879: idev[IDTYPE_KEYBOARD].read ();
880: }
1.1 root 881: }
1.1.1.2 root 882: }
883:
884: uae_u16 POT0DAT (void)
885: {
886: return potdats[0];
887: }
888: uae_u16 POT1DAT (void)
889: {
890: return potdats[1];
891: }
892:
893: /* direction=input, data pin floating, last connected logic level or previous status
894: written when direction was ouput
895: * otherwise it is currently connected logic level.
896: * direction=output, data pin is current value, forced to zero if joystick button is pressed
897: * it takes some tens of microseconds before data pin changes state
898: */
899:
900: void POTGO (uae_u16 v)
901: {
902: int i;
1.1 root 903:
1.1.1.2 root 904: //write_log ("W:%d: %04.4X %p\n", vpos, v, m68k_getpc());
905: #ifdef DONGLE_DEBUG
906: if (notinrom ())
907: write_log ("POTGO %04.4X %s\n", v, debuginfo(0));
908: #endif
909: potgo_value = potgo_value & 0x5500; /* keep state of data bits */
910: potgo_value |= v & 0xaa00; /* get new direction bits */
911: for (i = 0; i < 8; i += 2) {
912: uae_u16 dir = 0x0200 << i;
913: if (v & dir) {
914: uae_u16 data = 0x0100 << i;
915: potgo_value &= ~data;
916: potgo_value |= v & data;
917: }
918: }
919: for (i = 0; i < 2; i++) {
920: if (cd32_pad_enabled[i]) {
921: uae_u16 p5dir = 0x0200 << (i * 4); /* output enable P5 */
922: uae_u16 p5dat = 0x0100 << (i * 4); /* data P5 */
923: if ((potgo_value & p5dir) && (potgo_value & p5dat))
924: cd32_shifter[i] = 8;
925: }
926: }
927: if (v & 1) {
928: potdats[0] = potdats[1] = 0;
929: potgo_hsync = -15;
1.1 root 930: }
1.1.1.2 root 931: }
1.1 root 932:
1.1.1.2 root 933: uae_u16 POTGOR (void)
934: {
935: uae_u16 v = handle_joystick_potgor (potgo_value) & 0x5500;
936: //write_log("R:%d:%04.4X %d %p\n", vpos, v, cd32_shifter[1], m68k_getpc());
1.1 root 937: return v;
938: }
939:
1.1.1.2 root 940: static int check_input_queue (int event)
1.1 root 941: {
1.1.1.2 root 942: struct input_queue_struct *iq;
943: int i;
944: for (i = 0; i < INPUT_QUEUE_SIZE; i++) {
945: iq = &input_queue[i];
946: if (iq->event == event) return i;
1.1 root 947: }
1.1.1.2 root 948: return -1;
949: }
950:
951: static void queue_input_event (int event, int state, int max, int framecnt, int autofire)
952: {
953: struct input_queue_struct *iq;
954: int i = check_input_queue (event);
1.1 root 955:
1.1.1.2 root 956: if (event <= 0)
957: return;
958: if (state < 0 && i >= 0) {
959: iq = &input_queue[i];
960: iq->nextframecnt = -1;
961: iq->framecnt = -1;
962: iq->event = 0;
963: if (iq->state == 0)
964: handle_input_event (event, 0, 1, 0);
965: } else if (i < 0) {
966: for (i = 0; i < INPUT_QUEUE_SIZE; i++) {
967: iq = &input_queue[i];
968: if (iq->framecnt < 0) break;
969: }
970: if (i == INPUT_QUEUE_SIZE) {
971: write_log ("input queue overflow\n");
972: return;
973: }
974: iq->event = event;
975: iq->state = iq->storedstate = state;
976: iq->max = max;
977: iq->framecnt = framecnt;
978: iq->nextframecnt = autofire > 0 ? framecnt : -1;
979: }
1.1 root 980: }
1.1.1.2 root 981:
982: static uae_u8 keybuf[256];
983: static int inputcode_pending, inputcode_pending_state;
984:
985: /* Generate key up events for any keys that are 'stuck' down */
986: void inputdevice_release_all_keys (void)
1.1 root 987: {
1.1.1.2 root 988: int i;
989:
990: for (i = 0; i < 0x80; i++) {
991: if (keybuf[i] != 0) {
992: keybuf[i] = 0;
993: record_key (i << 1|1);
994: }
1.1 root 995: }
996: }
1.1.1.2 root 997:
998: void inputdevice_add_inputcode (int code, int state)
1.1 root 999: {
1.1.1.2 root 1000: inputcode_pending = code;
1001: inputcode_pending_state = state;
1002: }
1003:
1004: void inputdevice_do_keyboard (int code, int state)
1005: {
1006: if (code < 0x80) {
1007: uae_u8 key = code | (state ? 0x00 : 0x80);
1008: keybuf[key & 0x7f] = (key & 0x80) ? 0 : 1;
1009: if (((keybuf[AK_CTRL] || keybuf[AK_RCTRL]) && keybuf[AK_LAMI] && keybuf[AK_RAMI]) || key == AK_RESETWARNING) {
1010: int r = keybuf[AK_LALT] | keybuf[AK_RALT];
1011: memset (keybuf, 0, sizeof (keybuf));
1012: uae_reset (r);
1013: }
1014: record_key ((uae_u8)((key << 1) | (key >> 7)));
1015: //write_log("Amiga key %02.2X %d\n", key & 0x7f, key >> 7);
1016: return;
1.1 root 1017: }
1.1.1.2 root 1018: inputdevice_add_inputcode (code, state);
1.1 root 1019: }
1.1.1.2 root 1020:
1021: void inputdevice_handle_inputcode (void)
1.1 root 1022: {
1.1.1.2 root 1023: int code = inputcode_pending;
1024: int state = inputcode_pending_state;
1025: inputcode_pending = 0;
1026: if (code == 0)
1027: return;
1028: if (vpos != 0)
1029: write_log ("inputcode=%d but vpos = %d", code, vpos);
1030:
1031: #ifdef ARCADIA
1032: switch (code)
1033: {
1034: case AKS_ARCADIADIAGNOSTICS:
1035: arcadia_flag &= ~1;
1036: arcadia_flag |= state ? 1 : 0;
1037: break;
1038: case AKS_ARCADIAPLY1:
1039: arcadia_flag &= ~4;
1040: arcadia_flag |= state ? 4 : 0;
1041: break;
1042: case AKS_ARCADIAPLY2:
1043: arcadia_flag &= ~2;
1044: arcadia_flag |= state ? 2 : 0;
1045: break;
1046: case AKS_ARCADIACOIN1:
1047: if (state)
1048: arcadia_coin[0]++;
1049: break;
1050: case AKS_ARCADIACOIN2:
1051: if (state)
1052: arcadia_coin[1]++;
1053: break;
1054: }
1055: #endif
1056:
1057: if (!state)
1058: return;
1059: switch (code)
1060: {
1061: case AKS_ENTERGUI:
1062: gui_display (-1);
1063: break;
1064: #if 0
1065: case AKS_SCREENSHOT:
1066: screenshot(1, 1);
1067: break;
1068: #endif
1069: #ifdef ACTION_REPLAY
1070: case AKS_FREEZEBUTTON:
1071: action_replay_freeze ();
1072: break;
1073: #endif
1074: case AKS_FLOPPY0:
1075: gui_display (0);
1076: break;
1077: case AKS_FLOPPY1:
1078: gui_display (1);
1079: break;
1080: case AKS_FLOPPY2:
1081: gui_display (2);
1082: break;
1083: case AKS_FLOPPY3:
1084: gui_display (3);
1085: break;
1086: case AKS_EFLOPPY0:
1087: disk_eject (0);
1088: break;
1089: case AKS_EFLOPPY1:
1090: disk_eject (1);
1091: break;
1092: case AKS_EFLOPPY2:
1093: disk_eject (2);
1094: break;
1095: case AKS_EFLOPPY3:
1096: disk_eject (3);
1097: break;
1098: #if 0
1099: case AKS_IRQ7:
1100: Interrupt (7);
1101: break;
1102: #endif
1103: case AKS_PAUSE:
1104: pausemode (-1);
1105: break;
1106: #if 0
1107: case AKS_WARP:
1108: warpmode (-1);
1109: break;
1110: #endif
1111: case AKS_INHIBITSCREEN:
1112: toggle_inhibit_frame (IHF_SCROLLLOCK);
1113: break;
1114: #if 0
1115: case AKS_STATEREWIND:
1116: savestate_dorewind(1);
1117: break;
1118: case AKS_VOLDOWN:
1119: sound_volume (-1);
1120: break;
1121: case AKS_VOLUP:
1122: sound_volume (1);
1123: break;
1124: case AKS_VOLMUTE:
1125: sound_volume (0);
1126: break;
1127: #endif
1128: case AKS_QUIT:
1129: uae_quit ();
1130: break;
1131: case AKS_SOFTRESET:
1132: uae_reset (0);
1133: break;
1134: case AKS_HARDRESET:
1135: uae_reset (1);
1136: break;
1137: #if 0
1138: case AKS_STATESAVEQUICK:
1139: case AKS_STATESAVEQUICK1:
1140: case AKS_STATESAVEQUICK2:
1141: case AKS_STATESAVEQUICK3:
1142: case AKS_STATESAVEQUICK4:
1143: case AKS_STATESAVEQUICK5:
1144: case AKS_STATESAVEQUICK6:
1145: case AKS_STATESAVEQUICK7:
1146: case AKS_STATESAVEQUICK8:
1147: case AKS_STATESAVEQUICK9:
1148: savestate_quick ((code - AKS_STATESAVEQUICK) / 2, 1);
1149: break;
1150: case AKS_STATERESTOREQUICK:
1151: case AKS_STATERESTOREQUICK1:
1152: case AKS_STATERESTOREQUICK2:
1153: case AKS_STATERESTOREQUICK3:
1154: case AKS_STATERESTOREQUICK4:
1155: case AKS_STATERESTOREQUICK5:
1156: case AKS_STATERESTOREQUICK6:
1157: case AKS_STATERESTOREQUICK7:
1158: case AKS_STATERESTOREQUICK8:
1159: case AKS_STATERESTOREQUICK9:
1160: savestate_quick ((code - AKS_STATERESTOREQUICK) / 2, 0);
1161: break;
1162: #endif
1163: case AKS_TOGGLEFULLSCREEN:
1164: toggle_fullscreen ();
1165: break;
1166: case AKS_TOGGLEMOUSEGRAB:
1167: toggle_mousegrab ();
1168: break;
1169: case AKS_ENTERDEBUGGER:
1170: activate_debugger ();
1171: break;
1172: case AKS_STATESAVEDIALOG:
1173: gui_display (5);
1174: break;
1175: case AKS_STATERESTOREDIALOG:
1176: gui_display (4);
1177: break;
1178: #if 0
1179: case AKS_DECREASEREFRESHRATE:
1180: case AKS_INCREASEREFRESHRATE:
1181: {
1182: int dir = code == AKS_INCREASEREFRESHRATE ? 5 : -5;
1183: if (currprefs.chipset_refreshrate == 0)
1184: currprefs.chipset_refreshrate = currprefs.ntscmode ? 60 : 50;
1185: changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate + dir;
1186: if (changed_prefs.chipset_refreshrate < 10)
1187: changed_prefs.chipset_refreshrate = 10;
1188: if (changed_prefs.chipset_refreshrate > 900)
1189: changed_prefs.chipset_refreshrate = 900;
1190: }
1191: break;
1192: #endif
1.1.1.3 ! root 1193: case AKS_SWITCHINTERPOL:
! 1194: switch_audio_interpol ();
! 1195: break;
1.1 root 1196: }
1197: }
1.1.1.2 root 1198:
1199: void handle_input_event (int nr, int state, int max, int autofire)
1200: {
1201: struct inputevent *ie;
1202: int joy;
1203:
1204: if (nr <= 0)
1205: return;
1206: ie = &events[nr];
1207: //write_log("'%s' %d %d\n", ie->name, state, max);
1208: if (autofire) {
1209: if (state)
1210: queue_input_event (nr, state, max, currprefs.input_autofire_framecnt, 1);
1211: else
1212: queue_input_event (nr, -1, 0, 0, 1);
1213: }
1214: switch (ie->unit)
1215: {
1216: case 1: /* ->JOY1 */
1217: case 2: /* ->JOY2 */
1218: case 3: /* ->Parallel port joystick adapter port #1 */
1219: case 4: /* ->Parallel port joystick adapter port #2 */
1220: joy = ie->unit - 1;
1221: if (ie->type & 4) {
1222: if (state)
1223: joybutton[joy] |= 1 << ie->data;
1224: else
1225: joybutton[joy] &= ~(1 << ie->data);
1226: } else if (ie->type & 8) {
1227: /* real mouse / analog stick mouse emulation */
1228: int delta;
1229: int deadzone = currprefs.input_joymouse_deadzone * max / 100;
1230: if (max) {
1231: if (state < deadzone && state > -deadzone) {
1232: state = 0;
1233: } else if (state < 0) {
1234: state += deadzone;
1235: } else {
1236: state -= deadzone;
1237: }
1238: max -= deadzone;
1239: delta = state * currprefs.input_joymouse_multiplier / max;
1240: } else {
1241: delta = state;
1242: }
1243: mouse_delta[joy][ie->data] += delta;
1244: } else if (ie->type & 32) {
1245: int speed = currprefs.input_joymouse_speed;
1246:
1247: /* button mouse emulation */
1248: if (state && (ie->data & DIR_LEFT)) {
1249: mouse_delta[joy][0] = -speed;
1250: mouse_deltanoreset[joy][0] = 1;
1251: } else if (state && (ie->data & DIR_RIGHT)) {
1252: mouse_delta[joy][0] = speed;
1253: mouse_deltanoreset[joy][0] = 1;
1254: } else
1255: mouse_deltanoreset[joy][0] = 0;
1256:
1257: if (state && (ie->data & DIR_UP)) {
1258: mouse_delta[joy][1] = -speed;
1259: mouse_deltanoreset[joy][1] = 1;
1260: } else if (state && (ie->data & DIR_DOWN)) {
1261: mouse_delta[joy][1] = speed;
1262: mouse_deltanoreset[joy][1] = 1;
1263: } else
1264: mouse_deltanoreset[joy][1] = 0;
1265:
1266: } else if (ie->type & 64) { /* analog (paddle) */
1267: int deadzone = currprefs.input_joymouse_deadzone * max / 100;
1268: if (max) {
1269: if (state < deadzone && state > -deadzone) {
1270: state = 0;
1271: } else if (state < 0) {
1272: state += deadzone;
1273: } else {
1274: state -= deadzone;
1275: }
1276: state = state * max / (max - deadzone);
1277: }
1278: state = state / 256 + 128;
1279: joydirpot[joy][ie->data] = state;
1280: } else {
1281: int left = oleft[joy], right = oright[joy], top = otop[joy], bot = obot[joy];
1282: if (ie->type & 16) {
1283: /* button to axis mapping */
1284: if (ie->data & DIR_LEFT) left = oleft[joy] = state ? 1 : 0;
1285: if (ie->data & DIR_RIGHT) right = oright[joy] = state ? 1 : 0;
1286: if (ie->data & DIR_UP) top = otop[joy] = state ? 1 : 0;
1287: if (ie->data & DIR_DOWN) bot = obot[joy] = state ? 1 : 0;
1288: } else {
1289: /* "normal" joystick axis */
1290: int deadzone = currprefs.input_joystick_deadzone * max / 100;
1291: int neg, pos;
1292: if (state < deadzone && state > -deadzone)
1293: state = 0;
1294: neg = state < 0 ? 1 : 0;
1295: pos = state > 0 ? 1 : 0;
1296: if (ie->data & DIR_LEFT) left = oleft[joy] = neg;
1297: if (ie->data & DIR_RIGHT) right = oright[joy] = pos;
1298: if (ie->data & DIR_UP) top = otop[joy] = neg;
1299: if (ie->data & DIR_DOWN) bot = obot[joy] = pos;
1300: }
1301: joydir[joy] = 0;
1302: if (left) joydir[joy] |= DIR_LEFT;
1303: if (right) joydir[joy] |= DIR_RIGHT;
1304: if (top) joydir[joy] |= DIR_UP;
1305: if (bot) joydir[joy] |= DIR_DOWN;
1306: }
1307: break;
1308: case 0: /* ->KEY */
1309: inputdevice_do_keyboard (ie->data, state);
1310: break;
1311: }
1312: }
1313:
1314: void inputdevice_vsync (void)
1315: {
1316: struct input_queue_struct *iq;
1317: int i;
1318:
1319: for (i = 0; i < INPUT_QUEUE_SIZE; i++) {
1320: iq = &input_queue[i];
1321: if (iq->framecnt > 0) {
1322: iq->framecnt--;
1323: if (iq->framecnt == 0) {
1324: if (iq->state) iq->state = 0; else iq->state = iq->storedstate;
1325: handle_input_event (iq->event, iq->state, iq->max, 0);
1326: iq->framecnt = iq->nextframecnt;
1327: }
1328: }
1329: }
1330: mouseupdate (100);
1331: inputdelay = rand () % (maxvpos - 1);
1332: idev[IDTYPE_MOUSE].read ();
1333: input_read = 1;
1334: input_vpos = 0;
1335: inputdevice_handle_inputcode ();
1336: if (ievent_alive > 0)
1337: ievent_alive--;
1338: #ifdef ARCADIA
1339: if (arcadia_rom)
1340: arcadia_vsync ();
1341: #endif
1342: }
1343:
1344: void inputdevice_reset (void)
1345: {
1346: ievent_alive = 0;
1347: }
1348:
1349: static void setbuttonstateall (struct uae_input_device *id, struct uae_input_device2 *id2, int button, int state)
1350: {
1351: int event, autofire, i;
1352: uae_u32 mask = 1 << button;
1353: uae_u32 omask = id2->buttonmask & mask;
1354: uae_u32 nmask = (state ? 1 : 0) << button;
1355: char *custom;
1356:
1357: if (button >= ID_BUTTON_TOTAL)
1358: return;
1359: for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
1.1.1.3 ! root 1360: struct inputevent *ie;
! 1361:
1.1.1.2 root 1362: event = id->eventid[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]];
1363: custom = id->custom[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]];
1364: if (event <= 0 && custom == NULL)
1365: continue;
1366: autofire = (id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] & ID_FLAG_AUTOFIRE) ? 1 : 0;
1.1.1.3 ! root 1367: ie = events + event;
! 1368: if (ie->allow_mask & AM_AUTO)
! 1369: autofire = 1;
1.1.1.2 root 1370: if (state < 0) {
1371: handle_input_event (event, 1, 1, 0);
1372: queue_input_event (event, 0, 1, 1, 0); /* send release event next frame */
1373: } else {
1374: if ((omask ^ nmask) & mask)
1375: handle_input_event (event, state, 1, autofire);
1376: }
1377: }
1378: if ((omask ^ nmask) & mask) {
1379: if (state)
1380: id2->buttonmask |= mask;
1381: else
1382: id2->buttonmask &= ~mask;
1383: }
1384: }
1385:
1386:
1387: /* - detect required number of joysticks and mice from configuration data
1388: * - detect if CD32 pad emulation is needed
1389: * - detect device type in ports (mouse or joystick)
1390: */
1391:
1392: static int iscd32 (int ei)
1393: {
1394: if (ei >= INPUTEVENT_JOY1_CD32_FIRST && ei <= INPUTEVENT_JOY1_CD32_LAST) {
1395: cd32_pad_enabled[0] = 1;
1396: return 1;
1397: }
1398: if (ei >= INPUTEVENT_JOY2_CD32_FIRST && ei <= INPUTEVENT_JOY2_CD32_LAST) {
1399: cd32_pad_enabled[1] = 1;
1400: return 2;
1401: }
1402: return 0;
1403: }
1404:
1405: static int isparport (int ei)
1406: {
1407: if (ei > INPUTEVENT_PAR_JOY1_START && ei < INPUTEVENT_PAR_JOY_END) {
1408: parport_joystick_enabled = 1;
1409: return 1;
1410: }
1411: return 0;
1412: }
1413:
1414: static int ismouse (int ei)
1415: {
1416: if (ei >= INPUTEVENT_MOUSE1_FIRST && ei <= INPUTEVENT_MOUSE1_LAST) {
1417: mouse_port[0] = 1;
1418: return 1;
1419: }
1420: if (ei >= INPUTEVENT_MOUSE2_FIRST && ei <= INPUTEVENT_MOUSE2_LAST) {
1421: mouse_port[1] = 1;
1422: return 2;
1423: }
1424: return 0;
1425: }
1426:
1427: #ifdef CD32
1428: extern int cd32_enabled;
1429: #endif
1430:
1431: static void scanevents(struct uae_prefs *p)
1432: {
1433: int i, j, k, ei;
1434: struct inputevent *e;
1435: int n_joy = idev[IDTYPE_JOYSTICK].get_num();
1436: int n_mouse = idev[IDTYPE_MOUSE].get_num();
1437:
1438: cd32_pad_enabled[0] = cd32_pad_enabled[1] = 0;
1439: parport_joystick_enabled = 0;
1440: mouse_port[0] = mouse_port[1] = 0;
1441: for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++)
1442: joydir[i] = 0;
1443:
1444: for (i = 0; i < MAX_INPUT_DEVICES; i++) {
1445: use_joysticks[i] = 0;
1446: use_mice[i] = 0;
1447: for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
1448: for (j = 0; j < ID_BUTTON_TOTAL; j++) {
1449:
1450: if (joysticks[i].enabled && i < n_joy) {
1451: ei = joysticks[i].eventid[ID_BUTTON_OFFSET + j][k];
1452: e = &events[ei];
1453: iscd32 (ei);
1454: isparport (ei);
1455: ismouse (ei);
1456: if (joysticks[i].eventid[ID_BUTTON_OFFSET + j][k] > 0)
1457: use_joysticks[i] = 1;
1458: }
1459: if (mice[i].enabled && i < n_mouse) {
1460: ei = mice[i].eventid[ID_BUTTON_OFFSET + j][k];
1461: e = &events[ei];
1462: iscd32 (ei);
1463: isparport (ei);
1464: ismouse (ei);
1465: if (mice[i].eventid[ID_BUTTON_OFFSET + j][k] > 0)
1466: use_mice[i] = 1;
1467: }
1468:
1469: }
1470:
1471: for (j = 0; j < ID_AXIS_TOTAL; j++) {
1472:
1473: if (joysticks[i].enabled && i < n_joy) {
1474: ei = joysticks[i].eventid[ID_AXIS_OFFSET + j][k];
1475: iscd32 (ei);
1476: isparport (ei);
1477: ismouse (ei);
1478: if (ei > 0)
1479: use_joysticks[i] = 1;
1480: }
1481: if (mice[i].enabled && i < n_mouse) {
1482: ei = mice[i].eventid[ID_AXIS_OFFSET + j][k];
1483: iscd32 (ei);
1484: isparport (ei);
1485: ismouse (ei);
1486: if (ei > 0)
1487: use_mice[i] = 1;
1488: }
1489: }
1490: }
1491: }
1492: for (i = 0; i < MAX_INPUT_DEVICES; i++) {
1493: use_keyboards[i] = 0;
1494: if (keyboards[i].enabled && i < idev[IDTYPE_KEYBOARD].get_num()) {
1495: j = 0;
1496: while (keyboards[i].extra[j][0] >= 0) {
1497: use_keyboards[i] = 1;
1498: for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
1499: ei = keyboards[i].eventid[j][k];
1500: iscd32 (ei);
1501: isparport (ei);
1502: ismouse (ei);
1503: }
1504: j++;
1505: }
1506: }
1507: }
1508: }
1509:
1510: #ifdef CD32
1511: static void setcd32 (int joy, int n)
1512: {
1513: joysticks[joy].eventid[ID_BUTTON_OFFSET + 0][0] = n ? INPUTEVENT_JOY2_CD32_RED : INPUTEVENT_JOY1_CD32_RED;
1514: joysticks[joy].eventid[ID_BUTTON_OFFSET + 1][0] = n ? INPUTEVENT_JOY2_CD32_BLUE : INPUTEVENT_JOY1_CD32_BLUE;
1515: joysticks[joy].eventid[ID_BUTTON_OFFSET + 2][0] = n ? INPUTEVENT_JOY2_CD32_YELLOW : INPUTEVENT_JOY1_CD32_YELLOW;
1516: joysticks[joy].eventid[ID_BUTTON_OFFSET + 3][0] = n ? INPUTEVENT_JOY2_CD32_GREEN : INPUTEVENT_JOY1_CD32_GREEN;
1517: joysticks[joy].eventid[ID_BUTTON_OFFSET + 4][0] = n ? INPUTEVENT_JOY2_CD32_FFW : INPUTEVENT_JOY1_CD32_FFW;
1518: joysticks[joy].eventid[ID_BUTTON_OFFSET + 5][0] = n ? INPUTEVENT_JOY2_CD32_RWD : INPUTEVENT_JOY1_CD32_RWD;
1519: joysticks[joy].eventid[ID_BUTTON_OFFSET + 6][0] = n ? INPUTEVENT_JOY2_CD32_PLAY : INPUTEVENT_JOY1_CD32_PLAY;
1520: }
1521: #endif
1522:
1523: int compatibility_device[2];
1524: static void compatibility_mode (struct uae_prefs *prefs)
1525: {
1526: int joy, i;
1527: int used[4] = { 0, 0, 0, 0};
1528:
1529: compatibility_device[0] = -1;
1530: compatibility_device[1] = -1;
1531: for (i = 0; i < MAX_INPUT_DEVICES; i++) {
1532: memset (&mice[i], 0, sizeof (*mice));
1533: memset (&joysticks[i], 0, sizeof (*joysticks));
1534: }
1535:
1536: if ((joy = jsem_ismouse (0, prefs)) >= 0) {
1537: mice[joy].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_MOUSE1_HORIZ;
1538: mice[joy].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_MOUSE1_VERT;
1539: mice[joy].eventid[ID_AXIS_OFFSET + 2][0] = INPUTEVENT_MOUSE1_WHEEL;
1540: mice[joy].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY1_FIRE_BUTTON;
1541: mice[joy].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY1_2ND_BUTTON;
1542: mice[joy].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY1_3RD_BUTTON;
1543: mice[joy].eventid[ID_BUTTON_OFFSET + 3][0] = INPUTEVENT_KEY_ALT_LEFT;
1544: mice[joy].eventid[ID_BUTTON_OFFSET + 3][1] = INPUTEVENT_KEY_CURSOR_LEFT;
1545: mice[joy].eventid[ID_BUTTON_OFFSET + 4][0] = INPUTEVENT_KEY_ALT_LEFT;
1546: mice[joy].eventid[ID_BUTTON_OFFSET + 4][1] = INPUTEVENT_KEY_CURSOR_RIGHT;
1547: mice[joy].enabled = 1;
1548: }
1549: if ((joy = jsem_ismouse (1, prefs)) >= 0) {
1550: mice[joy].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_MOUSE2_HORIZ;
1551: mice[joy].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_MOUSE2_VERT;
1552: mice[joy].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY2_FIRE_BUTTON;
1553: mice[joy].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY2_2ND_BUTTON;
1554: mice[joy].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY2_3RD_BUTTON;
1555: mice[joy].enabled = 1;
1556: }
1557:
1558: joy = jsem_isjoy (1, prefs);
1559: if (joy >= 0) {
1560: joysticks[joy].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_JOY2_HORIZ;
1561: joysticks[joy].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_JOY2_VERT;
1562: used[joy] = 1;
1563: joysticks[joy].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY2_FIRE_BUTTON;
1564: joysticks[joy].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY2_2ND_BUTTON;
1.1.1.3 ! root 1565: joysticks[joy].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY2_FIRE_BUTTON_AF;
1.1.1.2 root 1566: #ifdef CD32
1567: if (cd32_enabled)
1568: setcd32 (joy, 1);
1569: #endif
1570: joysticks[joy].enabled = 1;
1571: }
1572:
1573: joy = jsem_isjoy (0, prefs);
1574: if (joy >= 0) {
1575: used[joy] = 1;
1576: joysticks[joy].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_JOY1_HORIZ;
1577: joysticks[joy].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_JOY1_VERT;
1578: joysticks[joy].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY1_FIRE_BUTTON;
1579: joysticks[joy].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY1_2ND_BUTTON;
1.1.1.3 ! root 1580: joysticks[joy].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY1_FIRE_BUTTON_AF;
1.1.1.2 root 1581: joysticks[joy].enabled = 1;
1582: }
1583:
1584: for (joy = 0; used[joy]; joy++);
1585: if (JSEM_ISANYKBD (0, prefs)) {
1586: joysticks[joy].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_JOY1_HORIZ;
1587: joysticks[joy].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_JOY1_VERT;
1588: joysticks[joy].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY1_FIRE_BUTTON;
1589: joysticks[joy].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY1_2ND_BUTTON;
1590: joysticks[joy].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY1_3RD_BUTTON;
1591: joysticks[joy].enabled = 1;
1592: used[joy] = 1;
1593: compatibility_device[0] = joy;
1594: }
1595: for (joy = 0; used[joy]; joy++);
1596: if (JSEM_ISANYKBD (1, prefs)) {
1597: joysticks[joy].eventid[ID_AXIS_OFFSET + 0][0] = INPUTEVENT_JOY2_HORIZ;
1598: joysticks[joy].eventid[ID_AXIS_OFFSET + 1][0] = INPUTEVENT_JOY2_VERT;
1599: joysticks[joy].eventid[ID_BUTTON_OFFSET + 0][0] = INPUTEVENT_JOY2_FIRE_BUTTON;
1600: joysticks[joy].eventid[ID_BUTTON_OFFSET + 1][0] = INPUTEVENT_JOY2_2ND_BUTTON;
1601: joysticks[joy].eventid[ID_BUTTON_OFFSET + 2][0] = INPUTEVENT_JOY2_3RD_BUTTON;
1602: #ifdef CD32
1603: if (cd32_enabled)
1604: setcd32 (joy, 1);
1605: #endif
1606: joysticks[joy].enabled = 1;
1607: used[joy] = 1;
1608: compatibility_device[1] = joy;
1609: }
1610: }
1611:
1612: void inputdevice_updateconfig (struct uae_prefs *prefs)
1613: {
1614: int i;
1615:
1616: if (currprefs.jport0 != changed_prefs.jport0
1617: || currprefs.jport1 != changed_prefs.jport1) {
1618: currprefs.jport0 = changed_prefs.jport0;
1619: currprefs.jport1 = changed_prefs.jport1;
1620: }
1621: joybutton[0] = joybutton[1] = 0;
1622: joydir[0] = joydir[1] = 0;
1623: oldmx[0] = oldmx[1] = -1;
1624: oldmy[0] = oldmy[1] = -1;
1625: cd32_shifter[0] = cd32_shifter[1] = 8;
1626: oleft[0] = oleft[1] = 0;
1627: oright[0] = oright[1] = 0;
1628: otop[0] = otop[1] = 0;
1629: obot[0] = obot[1] = 0;
1630: for (i = 0; i < 2; i++) {
1631: mouse_deltanoreset[i][0] = 0;
1632: mouse_delta[i][0] = 0;
1633: mouse_deltanoreset[i][1] = 0;
1634: mouse_delta[i][1] = 0;
1635: mouse_deltanoreset[i][2] = 0;
1636: mouse_delta[i][2] = 0;
1637: }
1638: memset (keybuf, 0, sizeof (keybuf));
1639:
1640: for (i = 0; i < INPUT_QUEUE_SIZE; i++)
1641: input_queue[i].framecnt = input_queue[i].nextframecnt = -1;
1642:
1643: for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
1644: sublevdir[0][i] = i;
1645: sublevdir[1][i] = MAX_INPUT_SUB_EVENT - i - 1;
1646: }
1647:
1648: joysticks = prefs->joystick_settings[prefs->input_selected_setting];
1649: mice = prefs->mouse_settings[prefs->input_selected_setting];
1650: keyboards = prefs->keyboard_settings[prefs->input_selected_setting];
1651:
1652: memset (joysticks2, 0, sizeof (joysticks2));
1653: memset (mice2, 0, sizeof (mice2));
1654: if (prefs->input_selected_setting == 0)
1655: compatibility_mode (prefs);
1656:
1657: joystick_setting_changed ();
1658:
1659: scanevents (prefs);
1660:
1661: #ifdef CD32
1662: if (currprefs.input_selected_setting == 0 && cd32_enabled)
1663: cd32_pad_enabled[1] = 1;
1664: #endif
1665: }
1666:
1667: static void set_kbr_default (struct uae_prefs *p, int index, int num)
1668: {
1669: int i, j, k, l;
1670: struct uae_input_device_kbr_default *trans = keyboard_default;
1671: struct uae_input_device *kbr;
1672: struct inputdevice_functions *id = &idev[IDTYPE_KEYBOARD];
1673: uae_u32 scancode;
1674:
1675: if (!trans)
1676: return;
1677: for (j = 0; j < MAX_INPUT_DEVICES; j++) {
1678: kbr = &p->keyboard_settings[index][j];
1679: for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
1680: memset (kbr, 0, sizeof (struct uae_input_device));
1681: kbr->extra[i][0] = -1;
1682: }
1683: if (j < id->get_num ()) {
1684: if (j == 0)
1685: kbr->enabled = 1;
1686: for (i = 0; i < id->get_widget_num (num); i++) {
1687: id->get_widget_type (num, i, 0, &scancode);
1688: kbr->extra[i][0] = scancode;
1689: l = 0;
1690: while (trans[l].scancode >= 0) {
1691: if (kbr->extra[i][0] == trans[l].scancode) {
1692: for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
1693: if (kbr->eventid[i][k] == 0) break;
1694: }
1695: if (k == MAX_INPUT_SUB_EVENT) {
1696: write_log ("corrupt default keyboard mappings\n");
1697: return;
1698: }
1699: kbr->eventid[i][k] = trans[l].event;
1700: break;
1701: }
1702: l++;
1703: }
1704: }
1705: }
1706: }
1707: }
1708:
1709: void inputdevice_default_prefs (struct uae_prefs *p)
1710: {
1711: int i;
1712:
1713: inputdevice_init ();
1714: p->input_joymouse_multiplier = 20;
1715: p->input_joymouse_deadzone = 33;
1716: p->input_joystick_deadzone = 33;
1717: p->input_joymouse_speed = 10;
1718: p->input_mouse_speed = 100;
1719: p->input_autofire_framecnt = 10;
1720: for (i = 0; i <= MAX_INPUT_SETTINGS; i++) {
1721: set_kbr_default (p, i, 0);
1722: input_get_default_mouse (p->mouse_settings[i]);
1723: input_get_default_joystick (p->joystick_settings[i]);
1724: }
1725: }
1726:
1727: void inputdevice_setkeytranslation (struct uae_input_device_kbr_default *trans)
1728: {
1729: keyboard_default = trans;
1730: }
1731:
1732: int inputdevice_translatekeycode (int keyboard, int scancode, int state)
1733: {
1734: struct uae_input_device *na = &keyboards[keyboard];
1735: int j, k;
1736:
1737: if (!keyboards || scancode < 0)
1738: return 0;
1739: j = 0;
1740: while (na->extra[j][0] >= 0) {
1741: if (na->extra[j][0] == scancode) {
1742: for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {/* send key release events in reverse order */
1743: int autofire = (na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] & ID_FLAG_AUTOFIRE) ? 1 : 0;
1744: int event = na->eventid[j][sublevdir[state == 0 ? 1 : 0][k]];
1745: char *custom = na->custom[j][sublevdir[state == 0 ? 1 : 0][k]];
1746: handle_input_event (event, state, 1, autofire);
1747: //write_log ("'%s' %d ('%s') %d\n", na->name, event, events[event].name, state);
1748: }
1749: return 1;
1750: }
1751: j++;
1752: }
1753: return 0;
1754: }
1755:
1756: void inputdevice_init (void)
1757: {
1758: idev[IDTYPE_JOYSTICK] = inputdevicefunc_joystick;
1759: idev[IDTYPE_JOYSTICK].init ();
1760: idev[IDTYPE_MOUSE] = inputdevicefunc_mouse;
1761: idev[IDTYPE_MOUSE].init ();
1762: idev[IDTYPE_KEYBOARD] = inputdevicefunc_keyboard;
1763: idev[IDTYPE_KEYBOARD].init ();
1764: }
1765:
1766: void inputdevice_close (void)
1767: {
1768: idev[IDTYPE_JOYSTICK].close ();
1769: idev[IDTYPE_MOUSE].close ();
1770: idev[IDTYPE_KEYBOARD].close ();
1771: }
1772:
1773: static struct uae_input_device *get_uid (struct inputdevice_functions *id, int devnum)
1774: {
1775: struct uae_input_device *uid = 0;
1776: if (id == &idev[IDTYPE_JOYSTICK]) {
1777: uid = &joysticks[devnum];
1778: } else if (id == &idev[IDTYPE_MOUSE]) {
1779: uid = &mice[devnum];
1780: } else if (id == &idev[IDTYPE_KEYBOARD]) {
1781: uid = &keyboards[devnum];
1782: }
1783: return uid;
1784: }
1785:
1786: static int get_event_data (struct inputdevice_functions *id, int devnum, int num, int *eventid, char **custom, int *flags, int sub)
1787: {
1788: struct uae_input_device *uid = get_uid (id, devnum);
1789: int type = id->get_widget_type (devnum, num, 0, 0);
1790: int i;
1791: if (type == IDEV_WIDGET_BUTTON) {
1792: i = num - id->get_widget_first (devnum, type) + ID_BUTTON_OFFSET;
1793: *eventid = uid->eventid[i][sub];
1794: *flags = uid->flags[i][sub];
1795: *custom = uid->custom[i][sub];
1796: return i;
1797: } else if (type == IDEV_WIDGET_AXIS) {
1798: i = num - id->get_widget_first (devnum, type) + ID_AXIS_OFFSET;
1799: *eventid = uid->eventid[i][sub];
1800: *flags = uid->flags[i][sub];
1801: *custom = uid->custom[i][sub];
1802: return i;
1803: } else if (type == IDEV_WIDGET_KEY) {
1804: i = num - id->get_widget_first (devnum, type);
1805: *eventid = uid->eventid[i][sub];
1806: *flags = uid->flags[i][sub];
1807: *custom = uid->custom[i][sub];
1808: return i;
1809: }
1810: return -1;
1811: }
1812:
1813: static int put_event_data (struct inputdevice_functions *id, int devnum, int num, int eventid, char *custom, int flags, int sub)
1814: {
1815: struct uae_input_device *uid = get_uid (id, devnum);
1816: int type = id->get_widget_type (devnum, num, 0, 0);
1817: int i;
1818: if (type == IDEV_WIDGET_BUTTON) {
1819: i = num - id->get_widget_first (devnum, type) + ID_BUTTON_OFFSET;
1820: uid->eventid[i][sub] = eventid;
1821: uid->flags[i][sub] = flags;
1822: free (uid->custom[i][sub]);
1823: uid->custom[i][sub] = custom ? my_strdup (custom) : NULL;
1824: return i;
1825: } else if (type == IDEV_WIDGET_AXIS) {
1826: i = num - id->get_widget_first (devnum, type) + ID_AXIS_OFFSET;
1827: uid->eventid[i][sub] = eventid;
1828: uid->flags[i][sub] = flags;
1829: free (uid->custom[i][sub]);
1830: uid->custom[i][sub] = custom ? my_strdup (custom) : NULL;
1831: return i;
1832: } else if (type == IDEV_WIDGET_KEY) {
1833: i = num - id->get_widget_first (devnum, type);
1834: uid->eventid[i][sub] = eventid;
1835: uid->flags[i][sub] = flags;
1836: free (uid->custom[i][sub]);
1837: uid->custom[i][sub] = custom ? my_strdup (custom) : NULL;
1838: return i;
1839: }
1840: return -1;
1841: }
1842:
1843: static int is_event_used (struct inputdevice_functions *id, int devnum, int isnum, int isevent)
1844: {
1845: struct uae_input_device *uid = get_uid (id, devnum);
1846: int num, event, flag, sub;
1847: char *custom;
1848:
1849: for (num = 0; num < id->get_widget_num (devnum); num++) {
1850: for (sub = 0; sub < MAX_INPUT_SUB_EVENT; sub++) {
1851: if (get_event_data (id, devnum, num, &event, &custom, &flag, sub) >= 0) {
1852: if (event == isevent && isnum != num)
1853: return 1;
1854: }
1855: }
1856: }
1857: return 0;
1858: }
1859:
1860: int inputdevice_get_device_index (int devnum)
1861: {
1862: if (devnum < idev[IDTYPE_JOYSTICK].get_num())
1863: return devnum;
1864: else if (devnum < idev[IDTYPE_JOYSTICK].get_num() + idev[IDTYPE_MOUSE].get_num())
1865: return devnum - idev[IDTYPE_JOYSTICK].get_num();
1866: else if (devnum < idev[IDTYPE_JOYSTICK].get_num() + idev[IDTYPE_MOUSE].get_num() + idev[IDTYPE_KEYBOARD].get_num())
1867: return devnum - idev[IDTYPE_JOYSTICK].get_num() - idev[IDTYPE_MOUSE].get_num();
1868: else
1869: return -1;
1870: }
1871:
1872: static int gettype (int devnum)
1873: {
1874: if (devnum < idev[IDTYPE_JOYSTICK].get_num())
1875: return IDTYPE_JOYSTICK;
1876: else if (devnum < idev[IDTYPE_JOYSTICK].get_num() + idev[IDTYPE_MOUSE].get_num())
1877: return IDTYPE_MOUSE;
1878: else if (devnum < idev[IDTYPE_JOYSTICK].get_num() + idev[IDTYPE_MOUSE].get_num() + idev[IDTYPE_KEYBOARD].get_num())
1879: return IDTYPE_KEYBOARD;
1880: else
1881: return -1;
1882: }
1883:
1884: static struct inputdevice_functions *getidf (int devnum)
1885: {
1886: return &idev[gettype (devnum)];
1887: }
1888:
1889:
1890: /* returns number of devices of type "type" */
1891: int inputdevice_get_device_total (int type)
1892: {
1893: return idev[type].get_num ();
1894: }
1895: /* returns the name of device */
1896: char *inputdevice_get_device_name (int type, int devnum)
1897: {
1898: return idev[type].get_name (devnum);
1899: }
1900: /* returns state (enabled/disabled) */
1901: int inputdevice_get_device_status (int devnum)
1902: {
1903: struct inputdevice_functions *idf = getidf (devnum);
1904: struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
1905: return uid->enabled;
1906: }
1907:
1908: /* set state (enabled/disabled) */
1909: void inputdevice_set_device_status (int devnum, int enabled)
1910: {
1911: struct inputdevice_functions *idf = getidf (devnum);
1912: struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
1913: uid->enabled = enabled;
1914: }
1915:
1916: /* returns number of axis/buttons and keys from selected device */
1917: int inputdevice_get_widget_num (int devnum)
1918: {
1919: struct inputdevice_functions *idf = getidf (devnum);
1920: return idf->get_widget_num (inputdevice_get_device_index (devnum));
1921: }
1922:
1923: static void get_ename (struct inputevent *ie, char *out)
1924: {
1925: if (!out)
1926: return;
1927: if (ie->allow_mask == AM_K)
1928: sprintf (out, "%s (0x%02.2X)", ie->name, ie->data);
1929: else
1930: strcpy (out, ie->name);
1931: }
1932:
1933: int inputdevice_iterate (int devnum, int num, char *name, int *af)
1934: {
1935: struct inputdevice_functions *idf = getidf (devnum);
1936: static int id_iterator;
1937: struct inputevent *ie;
1938: int mask, data, flags, type;
1939: int devindex = inputdevice_get_device_index (devnum);
1940: char *custom;
1941:
1942: *af = 0;
1943: *name = 0;
1944: for (;;) {
1945: ie = &events[++id_iterator];
1946: if (!ie->confname) {
1947: id_iterator = 0;
1948: return 0;
1949: }
1950: mask = 0;
1951: type = idf->get_widget_type (devindex, num, 0, 0);
1952: if (type == IDEV_WIDGET_BUTTON) {
1953: if (idf == &idev[IDTYPE_JOYSTICK]) {
1954: mask |= AM_JOY_BUT;
1955: } else {
1956: mask |= AM_MOUSE_BUT;
1957: }
1958: } else if (type == IDEV_WIDGET_AXIS) {
1959: if (idf == &idev[IDTYPE_JOYSTICK]) {
1960: mask |= AM_JOY_AXIS;
1961: } else {
1962: mask |= AM_MOUSE_AXIS;
1963: }
1964: } else if (type == IDEV_WIDGET_KEY) {
1965: mask |= AM_K;
1966: }
1967: if (ie->allow_mask & AM_INFO) {
1968: struct inputevent *ie2 = ie + 1;
1969: while (!(ie2->allow_mask & AM_INFO)) {
1970: if (is_event_used (idf, devindex, ie2 - ie, -1)) {
1971: ie2++;
1972: continue;
1973: }
1974: if (ie2->allow_mask & mask) break;
1975: ie2++;
1976: }
1977: if (!(ie2->allow_mask & AM_INFO))
1978: mask |= AM_INFO;
1979: }
1980: if (!(ie->allow_mask & mask))
1981: continue;
1982: get_event_data (idf, devindex, num, &data, &custom, &flags, 0);
1983: get_ename (ie, name);
1984: *af = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
1985: return 1;
1986: }
1987: }
1988:
1989: int inputdevice_get_mapped_name (int devnum, int num, int *pflags, char *name, char *custom, int sub)
1990: {
1991: struct inputdevice_functions *idf = getidf (devnum);
1992: struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
1993: int flags = 0, flag, data;
1994: int devindex = inputdevice_get_device_index (devnum);
1995: char *customp = NULL;
1996:
1997: if (name)
1998: strcpy (name, "<none>");
1999: if (custom)
2000: custom[0] = 0;
2001: if (pflags)
2002: *pflags = 0;
2003: if (uid == 0 || num < 0)
2004: return 0;
2005: if (get_event_data (idf, devindex, num, &data, &customp, &flag, sub) < 0)
2006: return 0;
2007: if (customp && custom)
2008: sprintf (custom, "\"%s\"", customp);
2009: if (flag & ID_FLAG_AUTOFIRE)
2010: flags |= IDEV_MAPPED_AUTOFIRE_SET;
2011: if (!data)
2012: return 0;
2013: if (events[data].allow_mask & AM_AF)
2014: flags |= IDEV_MAPPED_AUTOFIRE_POSSIBLE;
2015: if (pflags)
2016: *pflags = flags;
2017: get_ename (&events[data], name);
2018: return data;
2019: }
2020:
2021: int inputdevice_set_mapping (int devnum, int num, char *name, char *custom, int af, int sub)
2022: {
2023: struct inputdevice_functions *idf = getidf (devnum);
2024: struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
2025: int eid, data, flag, amask;
2026: char ename[256];
2027: int devindex = inputdevice_get_device_index (devnum);
2028:
2029: if (uid == 0 || num < 0)
2030: return 0;
2031: if (name) {
2032: eid = 1;
2033: while (events[eid].name) {
2034: get_ename (&events[eid], ename);
2035: if (!strcmp(ename, name)) break;
2036: eid++;
2037: }
2038: if (!events[eid].name)
2039: return 0;
2040: if (events[eid].allow_mask & AM_INFO)
2041: return 0;
2042: } else {
2043: eid = 0;
2044: }
2045: if (get_event_data (idf, devindex, num, &data, &custom, &flag, sub) < 0)
2046: return 0;
2047: if (data >= 0) {
2048: amask = events[eid].allow_mask;
2049: flag &= ~ID_FLAG_AUTOFIRE;
2050: if (amask & AM_AF)
2051: flag |= af ? ID_FLAG_AUTOFIRE : 0;
2052: put_event_data (idf, devindex, num, eid, custom, flag, sub);
2053: return 1;
2054: }
2055: return 0;
2056: }
2057:
2058: int inputdevice_get_widget_type (int devnum, int num, char *name)
2059: {
2060: struct inputdevice_functions *idf = getidf (devnum);
2061: return idf->get_widget_type (inputdevice_get_device_index (devnum), num, name, 0);
2062: }
2063:
2064: static int config_change;
2065:
2066: void inputdevice_config_change (void)
2067: {
2068: config_change = 1;
2069: }
2070:
2071: int inputdevice_config_change_test (void)
2072: {
2073: int v = config_change;
2074: config_change = 0;
2075: return v;
2076: }
2077:
2078: void inputdevice_copyconfig (struct uae_prefs *src, struct uae_prefs *dst)
2079: {
2080: int i, j;
2081:
2082: dst->input_selected_setting = src->input_selected_setting;
2083: dst->input_joymouse_multiplier = src->input_joymouse_multiplier;
2084: dst->input_joymouse_deadzone = src->input_joymouse_deadzone;
2085: dst->input_joystick_deadzone = src->input_joystick_deadzone;
2086: dst->input_joymouse_speed = src->input_joymouse_speed;
2087: dst->input_mouse_speed = src->input_mouse_speed;
2088: dst->input_autofire_framecnt = src->input_autofire_framecnt;
2089: dst->jport0 = src->jport0;
2090: dst->jport1 = src->jport1;
2091:
2092: for (i = 0; i < MAX_INPUT_SETTINGS + 1; i++) {
2093: for (j = 0; j < MAX_INPUT_DEVICES; j++) {
2094: memcpy (&dst->joystick_settings[i][j], &src->joystick_settings[i][j], sizeof (struct uae_input_device));
2095: memcpy (&dst->mouse_settings[i][j], &src->mouse_settings[i][j], sizeof (struct uae_input_device));
2096: memcpy (&dst->keyboard_settings[i][j], &src->keyboard_settings[i][j], sizeof (struct uae_input_device));
2097: }
2098: }
2099:
2100: inputdevice_updateconfig (dst);
2101: }
2102:
2103: void inputdevice_swap_ports (struct uae_prefs *p, int devnum)
2104: {
2105: struct inputdevice_functions *idf = getidf (devnum);
2106: struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
2107: int i, j, k, event, unit;
2108: struct inputevent *ie, *ie2;
2109:
2110: for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
2111: for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
2112: event = uid->eventid[i][j];
2113: if (event <= 0)
2114: continue;
2115: ie = &events[event];
2116: if (ie->unit <= 0)
2117: continue;
2118: unit = ie->unit;
2119: k = 1;
2120: while (events[k].confname) {
2121: ie2 = &events[k];
2122: if (ie2->type == ie->type && ie2->data == ie->data && ie2->unit - 1 == ((ie->unit - 1) ^ 1) && ie2->allow_mask == ie->allow_mask) {
2123: uid->eventid[i][j] = k;
2124: break;
2125: }
2126: k++;
2127: }
2128: }
2129: }
2130: }
2131:
2132: void inputdevice_copy_single_config (struct uae_prefs *p, int src, int dst, int devnum)
2133: {
2134: if (src == dst)
2135: return;
2136: if (devnum < 0 || gettype (devnum) == IDTYPE_JOYSTICK)
2137: memcpy (p->joystick_settings[dst], p->joystick_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
2138: if (devnum < 0 || gettype (devnum) == IDTYPE_MOUSE)
2139: memcpy (p->mouse_settings[dst], p->mouse_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
2140: if (devnum < 0 || gettype (devnum) == IDTYPE_KEYBOARD)
2141: memcpy (p->keyboard_settings[dst], p->keyboard_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
2142: }
2143:
2144: void inputdevice_acquire (void)
2145: {
2146: int i;
2147:
2148: inputdevice_unacquire ();
2149: for (i = 0; i < MAX_INPUT_DEVICES; i++) {
2150: if (use_joysticks[i])
2151: idev[IDTYPE_JOYSTICK].acquire (i, 0);
2152: }
2153: for (i = 0; i < MAX_INPUT_DEVICES; i++) {
2154: if (use_mice[i])
2155: idev[IDTYPE_MOUSE].acquire (i, 0);
2156: }
2157: for (i = 0; i < MAX_INPUT_DEVICES; i++) {
2158: if (use_keyboards[i])
2159: idev[IDTYPE_KEYBOARD].acquire (i, 0);
2160: }
2161: }
2162:
2163: void inputdevice_unacquire (void)
2164: {
2165: int i;
2166:
2167: for (i = 0; i < MAX_INPUT_DEVICES; i++)
2168: idev[IDTYPE_JOYSTICK].unacquire (i);
2169: for (i = 0; i < MAX_INPUT_DEVICES; i++)
2170: idev[IDTYPE_MOUSE].unacquire (i);
2171: for (i = 0; i < MAX_INPUT_DEVICES; i++)
2172: idev[IDTYPE_KEYBOARD].unacquire (i);
2173: }
2174:
2175: /* Call this function when host machine's joystick/joypad/etc button state changes
2176: * This function translates button events to Amiga joybutton/joyaxis/keyboard events
2177: */
2178:
2179: /* button states:
2180: * state = -1 -> mouse wheel turned or similar (button without release)
2181: * state = 1 -> button pressed
2182: * state = 0 -> button released
2183: */
2184:
2185: void setjoybuttonstate (int joy, int button, int state)
2186: {
2187: if (!joysticks[joy].enabled)
2188: return;
2189: setbuttonstateall (&joysticks[joy], &joysticks2[joy], button, state ? 1 : 0);
2190: }
2191:
2192: /* buttonmask = 1 = normal toggle button, 0 = mouse wheel turn or similar
2193: */
2194: void setjoybuttonstateall (int joy, uae_u32 buttonbits, uae_u32 buttonmask)
2195: {
2196: int i;
2197:
2198: if (!joysticks[joy].enabled)
2199: return;
2200: for (i = 0; i < ID_BUTTON_TOTAL; i++) {
2201: if (buttonmask & (1 << i))
2202: setbuttonstateall (&joysticks[joy], &joysticks2[joy], i, (buttonbits & (1 << i)) ? 1 : 0);
2203: else if (buttonbits & (1 << i))
2204: setbuttonstateall (&joysticks[joy], &joysticks2[joy], i, -1);
2205: }
2206: }
2207: /* mouse buttons (just like joystick buttons)
2208: */
2209: void setmousebuttonstateall (int mouse, uae_u32 buttonbits, uae_u32 buttonmask)
2210: {
2211: int i;
2212:
2213: if (!mice[mouse].enabled)
2214: return;
2215: for (i = 0; i < ID_BUTTON_TOTAL; i++) {
2216: if (buttonmask & (1 << i))
2217: setbuttonstateall (&mice[mouse], &mice2[mouse], i, (buttonbits & (1 << i)) ? 1 : 0);
2218: else if (buttonbits & (1 << i))
2219: setbuttonstateall (&mice[mouse], &mice2[mouse], i, -1);
2220: }
2221: }
2222:
2223: void setmousebuttonstate (int mouse, int button, int state)
2224: {
2225: if (!mice[mouse].enabled)
2226: return;
2227: setbuttonstateall (&mice[mouse], &mice2[mouse], button, state);
2228: }
2229:
2230: /* same for joystick axis (analog or digital)
2231: * (0 = center, -max = full left/top, max = full right/bottom)
2232: */
2233: void setjoystickstate (int joy, int axis, int state, int max)
2234: {
2235: struct uae_input_device *id = &joysticks[joy];
2236: struct uae_input_device2 *id2 = &joysticks2[joy];
2237: int deadzone = currprefs.input_joymouse_deadzone * max / 100;
2238: int i, v1, v2;
2239:
2240: if (!joysticks[joy].enabled)
2241: return;
2242: v1 = state;
2243: v2 = id2->states[axis];
2244: if (v1 < deadzone && v1 > -deadzone)
2245: v1 = 0;
2246: if (v2 < deadzone && v2 > -deadzone)
2247: v2 = 0;
2248: if (v1 == v2)
2249: return;
2250: for (i = 0; i < MAX_INPUT_SUB_EVENT; i++)
2251: handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max,
2252: id->flags[ID_AXIS_OFFSET + axis][i]);
2253: id2->states[axis] = state;
2254: }
2255:
2256: void setmousestate (int mouse, int axis, int data, int isabs)
2257: {
2258: int i, v;
2259: double *mouse_p, *oldm_p, d, diff;
2260: struct uae_input_device *id = &mice[mouse];
2261: static double fract1[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
2262: static double fract2[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
2263:
2264: if (!mice[mouse].enabled)
2265: return;
2266: d = 0;
2267: mouse_p = &mouse_axis[mouse][axis];
2268: oldm_p = &oldm_axis[mouse][axis];
2269: if (!isabs) {
2270: *oldm_p = *mouse_p;
2271: *mouse_p += data;
2272: d = (*mouse_p - *oldm_p) * currprefs.input_mouse_speed / 100.0;
1.1.1.3 ! root 2273: /* printf (" offs %f\n", d); */
1.1.1.2 root 2274: } else {
2275: d = data - (int)(*oldm_p);
2276: *oldm_p = data;
2277: *mouse_p += d;
2278: if (axis == 0)
2279: lastmx = data;
2280: else
2281: lastmy = data;
2282: }
2283: v = (int)(d > 0 ? d + 0.5 : d - 0.5);
2284: fract1[mouse][axis] += d;
2285: fract2[mouse][axis] += v;
2286: diff = fract2[mouse][axis] - fract1[mouse][axis];
2287: if (diff > 1 || diff < -1) {
2288: v -= (int)diff;
2289: fract2[mouse][axis] -= diff;
2290: }
2291: for (i = 0; i < MAX_INPUT_SUB_EVENT; i++)
2292: handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], v, 0, 0);
2293: }
2294:
2295: #if 0
2296: void warpmode (int mode)
2297: {
2298: if (mode < 0) {
2299: if (turbo_emulation) {
2300: changed_prefs.gfx_framerate = currprefs.gfx_framerate = turbo_emulation;
2301: turbo_emulation = 0;
2302: } else {
2303: turbo_emulation = currprefs.gfx_framerate;
2304: }
2305: } else if (mode == 0 && turbo_emulation > 0) {
2306: changed_prefs.gfx_framerate = currprefs.gfx_framerate = turbo_emulation;
2307: turbo_emulation = 0;
2308: } else if (mode > 0 && !turbo_emulation) {
2309: turbo_emulation = currprefs.gfx_framerate;
2310: }
2311: if (turbo_emulation) {
2312: #if 0
2313: if (!currprefs.cpu_cycle_exact && !currprefs.blitter_cycle_exact)
2314: changed_prefs.gfx_framerate = currprefs.gfx_framerate = 10;
2315: #endif
2316: pause_sound ();
2317: } else {
2318: resume_sound ();
2319: }
2320: compute_vsynctime ();
2321: }
2322: #endif
2323:
2324: void pausemode (int mode)
2325: {
2326: if (mode < 0)
2327: pause_emulation = pause_emulation ? 0 : 1;
2328: else
2329: pause_emulation = mode;
2330: }
2331:
2332: int jsem_isjoy (int port, struct uae_prefs *p)
2333: {
2334: int v = JSEM_DECODEVAL (port, p);
2335: if (v < JSEM_JOYS)
2336: return -1;
2337: v -= JSEM_JOYS;
2338: if (v >= inputdevice_get_device_total (IDTYPE_JOYSTICK))
2339: return -1;
2340: return v;
2341: }
2342: int jsem_ismouse (int port, struct uae_prefs *p)
2343: {
2344: int v = JSEM_DECODEVAL (port, p);
2345: if (v < JSEM_MICE)
2346: return -1;
2347: v -= JSEM_MICE;
2348: if (v >= inputdevice_get_device_total (IDTYPE_MOUSE))
2349: return -1;
2350: return v;
2351: }
2352: int jsem_iskbdjoy (int port, struct uae_prefs *p)
2353: {
2354: int v = JSEM_DECODEVAL (port, p);
2355: if (v < JSEM_KBDLAYOUT)
2356: return -1;
2357: v -= JSEM_KBDLAYOUT;
2358: if (v >= JSEM_LASTKBD)
2359: return -1;
2360: return v;
2361: }
2362:
2363: extern int jsem_ismouse (int v, struct uae_prefs*);
2364: extern int jsem_iskbd (int v, struct uae_prefs*);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.