Annotation of uae/src/inputdevice.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.