Annotation of hatari/src/joy.c, revision 1.1.1.18

1.1       root        1: /*
1.1.1.4   root        2:   Hatari - joy.c
1.1       root        3: 
1.1.1.14  root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1.1.4   root        6: 
                      7:   Joystick routines.
1.1       root        8: 
1.1.1.6   root        9:   NOTE: The ST uses the joystick port 1 as the default controller.
1.1       root       10: */
1.1.1.10  root       11: const char Joy_fileid[] = "Hatari joy.c : " __DATE__ " " __TIME__;
1.1       root       12: 
                     13: #include <SDL.h>
                     14: 
                     15: #include "main.h"
                     16: #include "configuration.h"
1.1.1.6   root       17: #include "ioMem.h"
1.1       root       18: #include "joy.h"
1.1.1.5   root       19: #include "log.h"
1.1.1.18! root       20: #include "m68000.h"
1.1.1.12  root       21: #include "screen.h"
1.1.1.2   root       22: #include "video.h"
1.1.1.15  root       23: #include "statusbar.h"
1.1       root       24: 
1.1.1.16  root       25: #define JOY_DEBUG 0
                     26: #if JOY_DEBUG
                     27: #define Dprintf(a) printf a
                     28: #else
                     29: #define Dprintf(a)
                     30: #endif
                     31: 
1.1.1.17  root       32: #define JOYREADING_BUTTON1  1          /* bit 0 */
                     33: #define JOYREADING_BUTTON2  2          /* bit 1 */
1.1       root       34: 
1.1.1.14  root       35: typedef struct
                     36: {
                     37:        int XPos,YPos;                /* the actually read axis values in range of -32768...0...32767 */
                     38:        int XAxisID,YAxisID;          /* the IDs of the physical PC joystick's axis to be used to gain ST joystick axis input */
1.1.1.17  root       39:        int Buttons;                  /* JOYREADING_BUTTON1 */
1.1.1.14  root       40: } JOYREADING;
                     41: 
                     42: typedef struct
                     43: {
                     44:     const char *SDLJoystickName;
                     45:     int XAxisID,YAxisID;           /* the IDs associated with a certain SDL joystick */
                     46: } JOYAXISMAPPING;
1.1.1.2   root       47: 
1.1.1.13  root       48: static SDL_Joystick *sdlJoystick[ JOYSTICK_COUNT ] =           /* SDL's joystick structures */
1.1.1.6   root       49: {
                     50:        NULL, NULL, NULL, NULL, NULL, NULL
                     51: };
1.1.1.7   root       52: 
1.1.1.13  root       53: /* Further explanation see JoyInit() */
1.1.1.14  root       54: static JOYAXISMAPPING const *sdlJoystickMapping[ JOYSTICK_COUNT ] =    /* references which axis are actually in use by the selected SDL joystick */
1.1.1.13  root       55: {
                     56:        NULL, NULL, NULL, NULL, NULL, NULL
                     57: };
                     58: 
                     59: static bool bJoystickWorking[ JOYSTICK_COUNT ] =               /* Is joystick plugged in and working? */
1.1.1.6   root       60: {
1.1.1.11  root       61:        false, false, false, false, false, false
1.1.1.13  root       62: };
1.1.1.6   root       63: 
1.1.1.11  root       64: int JoystickSpaceBar = false;           /* State of space-bar on joystick button 2 */
1.1.1.13  root       65: static Uint8 nJoyKeyEmu[ JOYSTICK_COUNT ];
1.1.1.7   root       66: static Uint16 nSteJoySelect;
1.1       root       67: 
                     68: 
1.1.1.16  root       69: /**
                     70:  * Get joystick name
                     71:  */
                     72: const char *Joy_GetName(int id)
                     73: {
                     74: #if WITH_SDL2
                     75:        return SDL_JoystickName(sdlJoystick[id]);
                     76: #else
                     77:        return SDL_JoystickName(id);
                     78: #endif
                     79: }
                     80: 
                     81: /**
                     82:  * Return maximum available real joystick ID
                     83:  */
                     84: int Joy_GetMaxId(void)
                     85: {
                     86:        int count = SDL_NumJoysticks();
                     87:        if (count > JOYSTICK_COUNT)
                     88:                count = JOYSTICK_COUNT;
                     89:        return count - 1;
                     90: }
                     91: 
                     92: /**
                     93:  * Make sure real Joystick ID is valid, and if not, disable it & return false
                     94:  */
                     95: bool Joy_ValidateJoyId(int i)
                     96: {
                     97:        /* Unavailable joystick ID -> disable it if necessary */
                     98:        if (ConfigureParams.Joysticks.Joy[i].nJoystickMode == JOYSTICK_REALSTICK &&
                     99:            !bJoystickWorking[ConfigureParams.Joysticks.Joy[i].nJoyId])
                    100:        {
                    101:                Log_Printf(LOG_WARN, "Selected real Joystick %d unavailable, disabling ST joystick %d\n", ConfigureParams.Joysticks.Joy[i].nJoyId, i);
                    102:                ConfigureParams.Joysticks.Joy[i].nJoystickMode = JOYSTICK_DISABLED;
                    103:                ConfigureParams.Joysticks.Joy[i].nJoyId = 0;
                    104:                return false;
                    105:        }
                    106:        return true;
                    107: }
                    108: 
1.1       root      109: /*-----------------------------------------------------------------------*/
1.1.1.8   root      110: /**
                    111:  * This function initialises the (real) joysticks.
                    112:  */
1.1       root      113: void Joy_Init(void)
                    114: {
1.1.1.13  root      115:        /* Joystick axis mapping table                          */
                    116:        /* Matthias Arndt <[email protected]>               */
                    117:        /* Somehow, not all SDL joysticks are created equal.    */
                    118:        /* Not all pads or sticks use axis 0 for x and axis 1   */
                    119:        /* for y information.                                   */
                    120:        /* This table allows to remap the axis to used.         */
                    121:        /* A joystick is identified by its SDL name and         */
                    122:        /* followed by the X axis to use and the Y axis.        */
                    123:        /* Find out the axis number with the tool jstest.       */
                    124: 
                    125:        /* FIXME: Read those settings from a configuration file and make them tunable from the GUI. */
1.1.1.14  root      126:        static const JOYAXISMAPPING AxisMappingTable [] =
1.1.1.13  root      127:        {
1.1.1.15  root      128:                /* Example entry for mapping joystick axis for a certain device: */
                    129:                /* USB game pad with ID ID 0079:0011, sold by Speedlink with axis 3 and 4 used */
                    130:                /*{"USB Gamepad" , 3, 4}, */
1.1.1.14  root      131:                /* Default entry used if no other SDL joystick name does match (should be last of this list) */
1.1.1.13  root      132:                {"*DEFAULT*" , 0, 1},
                    133:        };
                    134: 
1.1.1.14  root      135:        int i, j, nPadsConnected;
1.1.1.13  root      136: 
1.1.1.6   root      137:        /* Initialise SDL's joystick subsystem: */
                    138:        if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
                    139:        {
                    140:                Log_Printf(LOG_ERROR, "Could not init joysticks: %s\n", SDL_GetError());
                    141:                return;
                    142:        }
                    143: 
                    144:        /* Scan joystick connection array for working joysticks */
                    145:        nPadsConnected = SDL_NumJoysticks();
1.1.1.13  root      146:        for (i = 0; i < nPadsConnected && i < JOYSTICK_COUNT ; i++)
1.1.1.6   root      147:        {
                    148:                /* Open the joystick for use */
                    149:                sdlJoystick[i] = SDL_JoystickOpen(i);
                    150:                /* Is joystick ok? */
                    151:                if (sdlJoystick[i] != NULL)
                    152:                {
                    153:                        /* Set as working */
1.1.1.11  root      154:                        bJoystickWorking[i] = true;
1.1.1.16  root      155:                        Log_Printf(LOG_DEBUG, "Joystick %i: %s\n", i, Joy_GetName(i));
1.1.1.14  root      156:                        /* determine joystick axis mapping for given SDL joystick name, last is default: */
1.1.1.17  root      157:                        for (j = 0; j < ARRAY_SIZE(AxisMappingTable)-1; j++) {
1.1.1.13  root      158:                                /* check if ID string matches the one reported by SDL: */
1.1.1.16  root      159:                                if(strncmp(AxisMappingTable[j].SDLJoystickName, Joy_GetName(i), strlen(AxisMappingTable[j].SDLJoystickName)) == 0)
1.1.1.13  root      160:                                        break;
                    161:                        }
                    162: 
1.1.1.14  root      163:                        sdlJoystickMapping[i] = &(AxisMappingTable[j]);
                    164:                        Log_Printf(LOG_DEBUG, "Joystick %i maps axis %d and %d (%s)\n", i, sdlJoystickMapping[i]->XAxisID, sdlJoystickMapping[i]->YAxisID,
                    165:                                        sdlJoystickMapping[i]->SDLJoystickName );
1.1.1.6   root      166:                }
                    167:        }
                    168: 
1.1.1.16  root      169:        for (i = 0; i < JOYSTICK_COUNT ; i++)
                    170:                Joy_ValidateJoyId(i);
                    171: 
1.1.1.11  root      172:        JoystickSpaceBar = false;
1.1       root      173: }
                    174: 
                    175: 
1.1.1.2   root      176: /*-----------------------------------------------------------------------*/
1.1.1.8   root      177: /**
                    178:  * Close the (real) joysticks.
                    179:  */
1.1.1.7   root      180: void Joy_UnInit(void)
                    181: {
                    182:        int i, nPadsConnected;
                    183: 
                    184:        nPadsConnected = SDL_NumJoysticks();
                    185: 
1.1.1.13  root      186:        for (i = 0; i < nPadsConnected && i < JOYSTICK_COUNT ; i++)
1.1.1.7   root      187:        {
1.1.1.11  root      188:                if (bJoystickWorking[i] == true)
1.1.1.7   root      189:                {
                    190:                        SDL_JoystickClose(sdlJoystick[i]);
                    191:                }
                    192:        }
                    193: }
                    194: 
                    195: 
                    196: /*-----------------------------------------------------------------------*/
1.1.1.8   root      197: /**
                    198:  * Read details from joystick using SDL calls
                    199:  * NOTE ID is that of SDL
                    200:  */
1.1.1.9   root      201: static bool Joy_ReadJoystick(int nSdlJoyID, JOYREADING *pJoyReading)
1.1.1.6   root      202: {
1.1.1.12  root      203:        /* Joystick is OK, read position from the configured joystick axis */
                    204:        pJoyReading->XPos = SDL_JoystickGetAxis(sdlJoystick[nSdlJoyID], pJoyReading->XAxisID);
                    205:        pJoyReading->YPos = SDL_JoystickGetAxis(sdlJoystick[nSdlJoyID], pJoyReading->YAxisID);
1.1.1.6   root      206:        /* Sets bit #0 if button #1 is pressed: */
                    207:        pJoyReading->Buttons = SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], 0);
                    208:        /* Sets bit #1 if button #2 is pressed: */
                    209:        if (SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], 1))
1.1.1.17  root      210:                pJoyReading->Buttons |= JOYREADING_BUTTON2;
1.1.1.6   root      211: 
1.1.1.11  root      212:        return true;
1.1       root      213: }
                    214: 
1.1.1.2   root      215: 
                    216: /*-----------------------------------------------------------------------*/
1.1.1.8   root      217: /**
                    218:  * Read PC joystick and return ST format byte, i.e. lower 4 bits direction
                    219:  * and top bit fire.
                    220:  * NOTE : ID 0 is Joystick 0/Mouse and ID 1 is Joystick 1 (default),
                    221:  *        ID 2 and 3 are STE joypads and ID 4 and 5 are parport joysticks.
                    222:  */
1.1.1.6   root      223: Uint8 Joy_GetStickData(int nStJoyId)
1.1       root      224: {
1.1.1.6   root      225:        Uint8 nData = 0;
                    226:        JOYREADING JoyReading;
                    227: 
                    228:        /* Are we emulating the joystick via the keyboard? */
                    229:        if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_KEYBOARD)
                    230:        {
                    231:                /* If holding 'SHIFT' we actually want cursor key movement, so ignore any of this */
                    232:                if ( !(SDL_GetModState()&(KMOD_LSHIFT|KMOD_RSHIFT)) )
                    233:                {
                    234:                        nData = nJoyKeyEmu[nStJoyId];
                    235:                }
                    236:        }
1.1.1.17  root      237:        else if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_REALSTICK)
1.1.1.6   root      238:        {
1.1.1.17  root      239:                int nSdlJoyId;
                    240:                int nAxes;      /* How many axes are there on the corresponding SDL joystick? */
                    241: 
                    242:                nSdlJoyId = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyId;
                    243:                if (nSdlJoyId < 0 || !bJoystickWorking[nSdlJoyId])
                    244:                        return 0;
                    245:                nAxes = SDL_JoystickNumAxes(sdlJoystick[nSdlJoyId]);
                    246: 
1.1.1.12  root      247:                /* get joystick axis from configuration settings and make them plausible */
1.1.1.13  root      248:                JoyReading.XAxisID = sdlJoystickMapping[nSdlJoyId]->XAxisID;
                    249:                JoyReading.YAxisID = sdlJoystickMapping[nSdlJoyId]->YAxisID;
                    250: 
1.1.1.12  root      251:                /* make selected axis IDs plausible */
                    252:                if(  (JoyReading.XAxisID == JoyReading.YAxisID) /* same joystick axis for two directions? */
                    253:                   ||(JoyReading.XAxisID > nAxes)               /* ID for x axis beyond nr of existing axes? */
                    254:                   ||(JoyReading.YAxisID > nAxes)               /* ID for y axis beyond nr of existing axes? */
                    255:                  )
                    256:                {
                    257:                        /* define sane SDL joystick axis defaults and prepare them for saving back to the config file: */
                    258:                        JoyReading.XAxisID = 0;
                    259:                        JoyReading.YAxisID = 1;
                    260:                }
1.1.1.13  root      261: 
1.1.1.12  root      262:                /* Read real joystick and map to emulated ST joystick for emulation */
1.1.1.6   root      263:                if (!Joy_ReadJoystick(nSdlJoyId, &JoyReading))
                    264:                {
1.1.1.12  root      265:                        /* Something is wrong, we cannot read the joystick from SDL */
1.1.1.11  root      266:                        bJoystickWorking[nSdlJoyId] = false;
1.1.1.6   root      267:                        return 0;
                    268:                }
                    269: 
                    270:                /* Directions */
                    271:                if (JoyReading.YPos <= JOYRANGE_UP_VALUE)
1.1.1.11  root      272:                        nData |= ATARIJOY_BITMASK_UP;
1.1.1.6   root      273:                else if (JoyReading.YPos >= JOYRANGE_DOWN_VALUE)
1.1.1.11  root      274:                        nData |= ATARIJOY_BITMASK_DOWN;
1.1.1.6   root      275:                if (JoyReading.XPos <= JOYRANGE_LEFT_VALUE)
1.1.1.11  root      276:                        nData |= ATARIJOY_BITMASK_LEFT;
1.1.1.6   root      277:                else if (JoyReading.XPos >= JOYRANGE_RIGHT_VALUE)
1.1.1.11  root      278:                        nData |= ATARIJOY_BITMASK_RIGHT;
1.1.1.6   root      279: 
                    280:                /* PC Joystick button 1 is set as ST joystick button */
1.1.1.17  root      281:                if (JoyReading.Buttons & JOYREADING_BUTTON1)
1.1.1.11  root      282:                        nData |= ATARIJOY_BITMASK_FIRE;
1.1.1.6   root      283: 
                    284:                /* Enable PC Joystick button 2 to mimick space bar (For XenonII, Flying Shark etc...) */
1.1.1.17  root      285:                if (nStJoyId == JOYID_JOYSTICK1 && (JoyReading.Buttons & JOYREADING_BUTTON2))
1.1.1.6   root      286:                {
1.1.1.11  root      287:                        if (ConfigureParams.Joysticks.Joy[nStJoyId].bEnableJumpOnFire2)
1.1.1.6   root      288:                        {
1.1.1.11  root      289:                                /* If "Jump on Button 2" is enabled, PC Joystick button 2 acts as "ST Joystick up" */
                    290:                                nData |= ATARIJOY_BITMASK_UP;
                    291:                        } else {
                    292:                                /* If "Jump on Button 2" is not enabled, PC Joystick button 2 acts as pressing SPACE on the ST keyboard */
                    293:                                /* Only press 'space bar' if not in NULL state */
                    294:                                if (!JoystickSpaceBar)
                    295:                                {
                    296:                                        /* Press, ikbd will send packets and de-press */
                    297:                                        JoystickSpaceBar = JOYSTICK_SPACE_DOWN;
                    298:                                }
1.1.1.6   root      299:                        }
                    300:                }
                    301:        }
                    302: 
                    303:        /* Ignore fire button every 8 frames if enabled autofire (for both cursor emulation and joystick) */
                    304:        if (ConfigureParams.Joysticks.Joy[nStJoyId].bEnableAutoFire)
                    305:        {
                    306:                if ((nVBLs&0x7)<4)
1.1.1.11  root      307:                        nData &= ~ATARIJOY_BITMASK_FIRE;          /* Remove top bit! */
1.1.1.6   root      308:        }
                    309: 
                    310:        return nData;
1.1       root      311: }
                    312: 
1.1.1.2   root      313: 
                    314: /*-----------------------------------------------------------------------*/
1.1.1.8   root      315: /**
                    316:  * Get the fire button states.
                    317:  * Note: More than one fire buttons are only supported for real joystick,
                    318:  * not for keyboard emulation!
                    319:  */
1.1.1.6   root      320: static int Joy_GetFireButtons(int nStJoyId)
                    321: {
                    322:        int nButtons = 0;
                    323:        int nSdlJoyId;
                    324:        int i, nMaxButtons;
                    325: 
                    326:        nSdlJoyId = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyId;
                    327: 
                    328:        /* Are we emulating the joystick via the keyboard? */
                    329:        if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_KEYBOARD)
                    330:        {
                    331:                if (nJoyKeyEmu[nStJoyId] & 0x80)
                    332:                {
                    333:                        nButtons |= 1;
                    334:                }
                    335:        }
                    336:        else if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_REALSTICK
                    337:                 && bJoystickWorking[nSdlJoyId])
                    338:        {
                    339:                nMaxButtons = SDL_JoystickNumButtons(sdlJoystick[nSdlJoyId]);
                    340:                if (nMaxButtons > 17)
                    341:                        nMaxButtons = 17;
                    342:                /* Now read all fire buttons and set a bit for each pressed button: */
                    343:                for (i = 0; i < nMaxButtons; i++)
                    344:                {
                    345:                        if (SDL_JoystickGetButton(sdlJoystick[nSdlJoyId], i))
                    346:                        {
                    347:                                nButtons |= (1 << i);
                    348:                        }
                    349:                }
                    350:        }
1.1.1.2   root      351: 
1.1.1.6   root      352:        return nButtons;
1.1       root      353: }
                    354: 
1.1.1.2   root      355: 
                    356: /*-----------------------------------------------------------------------*/
1.1.1.8   root      357: /**
                    358:  * Set joystick cursor emulation for given port.  This assumes that
                    359:  * if the same keys have been defined for "cursor key emulation" in
                    360:  * other ports, the emulation for them has been switched off. Returns
                    361:  * 1 if the port number was OK, zero for error.
                    362:  */
1.1.1.9   root      363: bool Joy_SetCursorEmulation(int port)
1.1.1.7   root      364: {
                    365:        if (port < 0 || port >= JOYSTICK_COUNT) {
1.1.1.16  root      366:                return false;
1.1.1.7   root      367:        }
                    368:        ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_KEYBOARD;
1.1.1.16  root      369:        return true;
1.1.1.7   root      370: }
                    371: 
                    372: 
                    373: /*-----------------------------------------------------------------------*/
1.1.1.8   root      374: /**
                    375:  * Toggle joystick cursor emulation between port 0, port 1 and being off
                    376:  * from them. When it's turned off from them, the port's previous state
                    377:  * is restored
                    378:  */
1.1       root      379: void Joy_ToggleCursorEmulation(void)
                    380: {
1.1.1.11  root      381:        static JOYSTICKMODE saved[2] = { JOYSTICK_DISABLED, JOYSTICK_DISABLED };
                    382:        JOYSTICKMODE state;
                    383:        int i, port = 2;
1.1.1.7   root      384:        for (i = 0; i < 2; i++) {
                    385:                state = ConfigureParams.Joysticks.Joy[i].nJoystickMode;
                    386:                if (state == JOYSTICK_KEYBOARD) {
                    387:                        port = i;
                    388:                } else {
                    389:                        saved[i] = state;
                    390:                }
                    391:        }
                    392:        switch (port) {
                    393:        case 0:  /* (only) in port 0, disable cursor emu */
                    394:                ConfigureParams.Joysticks.Joy[0].nJoystickMode = saved[0];
                    395:                break;
                    396:        case 1:  /* (at least) in port 1, switch cursor emu to port 0 */
                    397:                ConfigureParams.Joysticks.Joy[1].nJoystickMode = saved[1];
                    398:                ConfigureParams.Joysticks.Joy[0].nJoystickMode = JOYSTICK_KEYBOARD;
                    399:                break;
                    400:        default:  /* neither in port 0 or 1, enable cursor emu to port 1 */
                    401:                ConfigureParams.Joysticks.Joy[1].nJoystickMode = JOYSTICK_KEYBOARD;
1.1.1.6   root      402:        }
1.1.1.15  root      403:        Statusbar_UpdateInfo();
1.1.1.6   root      404: }
                    405: 
                    406: 
                    407: /*-----------------------------------------------------------------------*/
1.1.1.8   root      408: /**
1.1.1.16  root      409:  * Switch between joystick types in given joyport
                    410:  */
                    411: bool Joy_SwitchMode(int port)
                    412: {
                    413:        int mode;
                    414:        if (port < 0 || port >= JOYSTICK_COUNT) {
                    415:                return false;
                    416:        }
                    417:        mode = (ConfigureParams.Joysticks.Joy[port].nJoystickMode + 1) % JOYSTICK_MODES;
                    418:        ConfigureParams.Joysticks.Joy[port].nJoystickMode = mode;
                    419:        Statusbar_UpdateInfo();
                    420:        return true;
                    421: }
                    422: 
                    423: 
                    424: /*-----------------------------------------------------------------------*/
                    425: /**
1.1.1.8   root      426:  * A key has been pressed down, check if we use it for joystick emulation
                    427:  * via keyboard.
                    428:  */
1.1.1.9   root      429: bool Joy_KeyDown(int symkey, int modkey)
1.1.1.6   root      430: {
                    431:        int i;
                    432: 
1.1.1.7   root      433:        for (i = 0; i < JOYSTICK_COUNT; i++)
1.1.1.6   root      434:        {
                    435:                if (ConfigureParams.Joysticks.Joy[i].nJoystickMode == JOYSTICK_KEYBOARD
                    436:                    && !(modkey & KMOD_SHIFT))
                    437:                {
                    438:                        if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeUp)
                    439:                        {
1.1.1.11  root      440:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_DOWN;   /* Disable down */
                    441:                                nJoyKeyEmu[i] |= ATARIJOY_BITMASK_UP;    /* Enable up */
                    442:                                return true;
1.1.1.6   root      443:                        }
                    444:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeDown)
                    445:                        {
1.1.1.11  root      446:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_UP;   /* Disable up */
                    447:                                nJoyKeyEmu[i] |= ATARIJOY_BITMASK_DOWN;    /* Enable down */
                    448:                                return true;
1.1.1.6   root      449:                        }
                    450:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeLeft)
                    451:                        {
1.1.1.11  root      452:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_RIGHT;   /* Disable right */
                    453:                                nJoyKeyEmu[i] |= ATARIJOY_BITMASK_LEFT;    /* Enable left */
                    454:                                return true;
1.1.1.6   root      455:                        }
                    456:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeRight)
                    457:                        {
1.1.1.11  root      458:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_LEFT;   /* Disable left */
                    459:                                nJoyKeyEmu[i] |= ATARIJOY_BITMASK_RIGHT;    /* Enable right */
                    460:                                return true;
1.1.1.6   root      461:                        }
                    462:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeFire)
                    463:                        {
1.1.1.11  root      464:                                nJoyKeyEmu[i] |= ATARIJOY_BITMASK_FIRE;
                    465:                                return true;
1.1.1.6   root      466:                        }
                    467:                }
                    468:        }
                    469: 
1.1.1.11  root      470:        return false;
1.1.1.6   root      471: }
                    472: 
                    473: 
                    474: /*-----------------------------------------------------------------------*/
1.1.1.8   root      475: /**
                    476:  * A key has been released, check if we use it for joystick emulation
                    477:  * via keyboard.
                    478:  */
1.1.1.9   root      479: bool Joy_KeyUp(int symkey, int modkey)
1.1.1.6   root      480: {
                    481:        int i;
                    482: 
1.1.1.7   root      483:        for (i = 0; i < JOYSTICK_COUNT; i++)
1.1.1.6   root      484:        {
                    485:                if (ConfigureParams.Joysticks.Joy[i].nJoystickMode == JOYSTICK_KEYBOARD
                    486:                    && !(modkey & KMOD_SHIFT))
                    487:                {
                    488:                        if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeUp)
                    489:                        {
1.1.1.11  root      490:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_UP;
                    491:                                return true;
1.1.1.6   root      492:                        }
                    493:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeDown)
                    494:                        {
1.1.1.11  root      495:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_DOWN;
                    496:                                return true;
1.1.1.6   root      497:                        }
                    498:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeLeft)
                    499:                        {
1.1.1.11  root      500:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_LEFT;
                    501:                                return true;
1.1.1.6   root      502:                        }
                    503:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeRight)
                    504:                        {
1.1.1.11  root      505:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_RIGHT;
                    506:                                return true;
1.1.1.6   root      507:                        }
                    508:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeFire)
                    509:                        {
1.1.1.11  root      510:                                nJoyKeyEmu[i] &= ~ATARIJOY_BITMASK_FIRE;
                    511:                                return true;
1.1.1.6   root      512:                        }
                    513:                }
                    514:        }
                    515: 
1.1.1.11  root      516:        return false;
1.1.1.6   root      517: }
                    518: 
                    519: 
                    520: /*-----------------------------------------------------------------------*/
1.1.1.8   root      521: /**
1.1.1.17  root      522:  * Read from STE joypad buttons register (0xff9201)
1.1.1.8   root      523:  */
1.1.1.17  root      524: void Joy_StePadButtons_ReadByte(void)
1.1.1.6   root      525: {
1.1.1.17  root      526:        Uint8 nData = 0xff;
1.1.1.6   root      527: 
                    528:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADA].nJoystickMode != JOYSTICK_DISABLED
                    529:            && (nSteJoySelect & 0x0f) != 0x0f)
                    530:        {
                    531:                int nButtons = Joy_GetFireButtons(JOYID_STEPADA);
                    532:                if (!(nSteJoySelect & 0x1))
                    533:                {
                    534:                        if (nButtons & 0x01)  /* Fire button A pressed? */
                    535:                                nData &= ~2;
                    536:                        if (nButtons & 0x10)  /* Fire button PAUSE pressed? */
                    537:                                nData &= ~1;
                    538:                }
                    539:                else if (!(nSteJoySelect & 0x2))
                    540:                {
                    541:                        if (nButtons & 0x02)  /* Fire button B pressed? */
                    542:                                nData &= ~2;
                    543:                }
                    544:                else if (!(nSteJoySelect & 0x4))
                    545:                {
                    546:                        if (nButtons & 0x04)  /* Fire button C pressed? */
                    547:                                nData &= ~2;
                    548:                }
                    549:                else if (!(nSteJoySelect & 0x8))
                    550:                {
1.1.1.16  root      551:                        if (nButtons & 0x08)  /* Fire button OPTION pressed? */
1.1.1.6   root      552:                                nData &= ~2;
                    553:                }
                    554:        }
                    555: 
                    556:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADB].nJoystickMode != JOYSTICK_DISABLED
                    557:            && (nSteJoySelect & 0xf0) != 0xf0)
                    558:        {
                    559:                int nButtons = Joy_GetFireButtons(JOYID_STEPADB);
                    560:                if (!(nSteJoySelect & 0x10))
                    561:                {
                    562:                        if (nButtons & 0x01)  /* Fire button A pressed? */
                    563:                                nData &= ~8;
                    564:                        if (nButtons & 0x10)  /* Fire button PAUSE pressed? */
                    565:                                nData &= ~4;
                    566:                }
                    567:                else if (!(nSteJoySelect & 0x20))
                    568:                {
                    569:                        if (nButtons & 0x02)  /* Fire button B pressed? */
                    570:                                nData &= ~8;
                    571:                }
                    572:                else if (!(nSteJoySelect & 0x40))
                    573:                {
                    574:                        if (nButtons & 0x04)  /* Fire button C pressed? */
                    575:                                nData &= ~8;
                    576:                }
                    577:                else if (!(nSteJoySelect & 0x80))
                    578:                {
                    579:                        if (nButtons & 0x08)  /* Fire button OPTION pressed? */
                    580:                                nData &= ~8;
                    581:                }
                    582:        }
                    583: 
1.1.1.17  root      584:        Dprintf(("0xff9201 -> 0x%04x\n", nData));
                    585:        IoMem_WriteByte(0xff9201, nData);
1.1       root      586: }
1.1.1.2   root      587: 
1.1.1.6   root      588: 
                    589: /*-----------------------------------------------------------------------*/
1.1.1.8   root      590: /**
                    591:  * Read from STE joypad direction/buttons register (0xff9202)
1.1.1.16  root      592:  *
                    593:  * This is used e.g. by Reservoir Gods' Tautology II
1.1.1.8   root      594:  */
1.1.1.6   root      595: void Joy_StePadMulti_ReadWord(void)
                    596: {
1.1.1.16  root      597:        Uint16 nData = 0xff;
1.1.1.6   root      598: 
                    599:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADA].nJoystickMode != JOYSTICK_DISABLED
                    600:            && (nSteJoySelect & 0x0f) != 0x0f)
                    601:        {
                    602:                nData &= 0xf0;
                    603:                if (!(nSteJoySelect & 0x1))
                    604:                {
                    605:                        nData |= ~Joy_GetStickData(JOYID_STEPADA) & 0x0f;
                    606:                }
                    607:                else if (!(nSteJoySelect & 0x2))
                    608:                {
                    609:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADA) >> 13) & 0x0f;
                    610:                }
                    611:                else if (!(nSteJoySelect & 0x4))
                    612:                {
                    613:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADA) >> 9) & 0x0f;
                    614:                }
                    615:                else if (!(nSteJoySelect & 0x8))
                    616:                {
                    617:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADA) >> 5) & 0x0f;
                    618:                }
                    619:        }
                    620: 
                    621:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADB].nJoystickMode != JOYSTICK_DISABLED
                    622:            && (nSteJoySelect & 0xf0) != 0xf0)
                    623:        {
                    624:                nData &= 0x0f;
                    625:                if (!(nSteJoySelect & 0x10))
                    626:                {
                    627:                        nData |= ~Joy_GetStickData(JOYID_STEPADB) << 4;
                    628:                }
                    629:                else if (!(nSteJoySelect & 0x20))
                    630:                {
1.1.1.16  root      631:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADB) >> (13-4)) & 0xf0;
1.1.1.6   root      632:                }
                    633:                else if (!(nSteJoySelect & 0x40))
                    634:                {
1.1.1.16  root      635:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADB) >> (9-4)) & 0xf0;
1.1.1.6   root      636:                }
                    637:                else if (!(nSteJoySelect & 0x80))
                    638:                {
1.1.1.16  root      639:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADB) >> (5-4)) & 0xf0;
1.1.1.6   root      640:                }
                    641:        }
                    642: 
1.1.1.16  root      643:        nData = (nData << 8) | 0x0ff;
                    644:        Dprintf(("0xff9202 -> 0x%04x\n", nData));
                    645:        IoMem_WriteWord(0xff9202, nData);
1.1.1.6   root      646: }
                    647: 
                    648: 
                    649: /*-----------------------------------------------------------------------*/
1.1.1.8   root      650: /**
                    651:  * Write to STE joypad selection register (0xff9202)
                    652:  */
1.1.1.6   root      653: void Joy_StePadMulti_WriteWord(void)
                    654: {
                    655:        nSteJoySelect = IoMem_ReadWord(0xff9202);
1.1.1.16  root      656:        Dprintf(("0xff9202 <- 0x%04x\n", nSteJoySelect));
1.1.1.6   root      657: }
1.1.1.18! root      658: 
        !           659: 
        !           660: /*-----------------------------------------------------------------------*/
        !           661: /**
        !           662:  * Read STE lightpen X register (0xff9220)
        !           663:  */
        !           664: void Joy_SteLightpenX_ReadWord(void)
        !           665: {
        !           666:        Uint16 nData = 0;       /* Lightpen is not supported yet */
        !           667: 
        !           668:        Dprintf(("0xff9220 -> 0x%04x\n", nData));
        !           669: 
        !           670:        if (nIoMemAccessSize == SIZE_BYTE)
        !           671:        {
        !           672:                /* This register does not like to be accessed in byte mode */
        !           673:                M68000_BusError(IoAccessFullAddress, BUS_ERROR_READ,
        !           674:                                BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
        !           675:                return;
        !           676:        }
        !           677: 
        !           678:        IoMem_WriteWord(0xff9220, nData);
        !           679: }
        !           680: 
        !           681: /**
        !           682:  * Read STE lightpen Y register (0xff9222)
        !           683:  */
        !           684: void Joy_SteLightpenY_ReadWord(void)
        !           685: {
        !           686:        Uint16 nData = 0;       /* Lightpen is not supported yet */
        !           687: 
        !           688:        Dprintf(("0xff9222 -> 0x%04x\n", nData));
        !           689: 
        !           690:        if (nIoMemAccessSize == SIZE_BYTE)
        !           691:        {
        !           692:                /* This register does not like to be accessed in byte mode */
        !           693:                M68000_BusError(IoAccessFullAddress, BUS_ERROR_READ,
        !           694:                                BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
        !           695:                return;
        !           696:        }
        !           697: 
        !           698:        IoMem_WriteWord(0xff9222, nData);
        !           699: }

unix.superglobalmegacorp.com

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