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

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

unix.superglobalmegacorp.com

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