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

1.1       root        1: /*
1.1.1.4   root        2:   Hatari - joy.c
1.1       root        3: 
1.1.1.4   root        4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      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.6 ! root       11: char Joy_rcsid[] = "Hatari $Id: joy.c,v 1.8 2005/10/05 14:14:35 thothy Exp $";
1.1       root       12: 
                     13: #include <SDL.h>
                     14: 
                     15: #include "main.h"
                     16: #include "configuration.h"
                     17: #include "dialog.h"
1.1.1.6 ! root       18: #include "ioMem.h"
1.1       root       19: #include "joy.h"
1.1.1.5   root       20: #include "log.h"
1.1.1.2   root       21: #include "video.h"
1.1       root       22: 
1.1.1.2   root       23: #define JOY_BUTTON1  1
                     24: #define JOY_BUTTON2  2
1.1       root       25: 
1.1.1.2   root       26: 
1.1.1.6 ! root       27: SDL_Joystick *sdlJoystick[6] =          /* SDL's joystick structures */
        !            28: {
        !            29:        NULL, NULL, NULL, NULL, NULL, NULL
        !            30: };
        !            31: BOOL bJoystickWorking[6] =              /* Is joystick plugged in and working? */
        !            32: {
        !            33:        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
        !            34: }; 
        !            35: 
        !            36: int JoystickSpaceBar = FALSE;           /* State of space-bar on joystick button 2 */
        !            37: static Uint8 nJoyKeyEmu[6];
        !            38: Uint16 nSteJoySelect;
1.1       root       39: 
                     40: 
                     41: /*-----------------------------------------------------------------------*/
                     42: /*
1.1.1.3   root       43:   This function initialises the (real) joysticks.
1.1       root       44: */
                     45: void Joy_Init(void)
                     46: {
1.1.1.6 ! root       47:        int i, nPadsConnected;
        !            48: 
        !            49:        /* Initialise SDL's joystick subsystem: */
        !            50:        if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
        !            51:        {
        !            52:                Log_Printf(LOG_ERROR, "Could not init joysticks: %s\n", SDL_GetError());
        !            53:                return;
        !            54:        }
        !            55: 
        !            56:        /* Scan joystick connection array for working joysticks */
        !            57:        nPadsConnected = SDL_NumJoysticks();
        !            58:        for (i = 0; i < nPadsConnected && i < 6; i++)
        !            59:        {
        !            60:                /* Open the joystick for use */
        !            61:                sdlJoystick[i] = SDL_JoystickOpen(i);
        !            62:                /* Is joystick ok? */
        !            63:                if (sdlJoystick[i] != NULL)
        !            64:                {
        !            65:                        /* Set as working */
        !            66:                        bJoystickWorking[i] = TRUE;
        !            67:                        Log_Printf(LOG_DEBUG, "Joystick %i: %s\n", i, SDL_JoystickName(i));
        !            68:                }
        !            69:        }
        !            70: 
        !            71:        /* OK, do we have any working joysticks? */
        !            72:        if (!bJoystickWorking[0])
        !            73:        {
        !            74:                /* No, so if first time install need to set cursor emulation */
        !            75:                if (bFirstTimeInstall)
        !            76:                        ConfigureParams.Joysticks.Joy[1].nJoystickMode = JOYSTICK_KEYBOARD;
        !            77:        }
1.1.1.2   root       78: 
1.1.1.6 ! root       79:        JoystickSpaceBar = FALSE;
1.1       root       80: }
                     81: 
                     82: 
1.1.1.2   root       83: /*-----------------------------------------------------------------------*/
1.1       root       84: /*
1.1.1.6 ! root       85:   Read details from joystick using SDL calls
        !            86:   NOTE ID is that of SDL
        !            87: */
        !            88: static BOOL Joy_ReadJoystick(int nSdlJoyID, JOYREADING *pJoyReading)
        !            89: {
        !            90:        /* Joystick is OK, read position */
        !            91:        pJoyReading->XPos = SDL_JoystickGetAxis(sdlJoystick[nSdlJoyID], 0);
        !            92:        pJoyReading->YPos = SDL_JoystickGetAxis(sdlJoystick[nSdlJoyID], 1);
        !            93:        /* Sets bit #0 if button #1 is pressed: */
        !            94:        pJoyReading->Buttons = SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], 0);
        !            95:        /* Sets bit #1 if button #2 is pressed: */
        !            96:        if (SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], 1))
        !            97:                pJoyReading->Buttons |= JOY_BUTTON2;
        !            98: 
        !            99:        return TRUE;
1.1       root      100: }
                    101: 
1.1.1.2   root      102: 
                    103: /*-----------------------------------------------------------------------*/
1.1       root      104: /*
1.1.1.6 ! root      105:   Read PC joystick and return ST format byte, i.e. lower 4 bits direction
        !           106:   and top bit fire.
        !           107:   NOTE : ID 0 is Joystick 0/Mouse and ID 1 is Joystick 1 (default),
        !           108:          ID 2 and 3 are STE joypads and ID 4 and 5 are parport joysticks.
1.1       root      109: */
1.1.1.6 ! root      110: Uint8 Joy_GetStickData(int nStJoyId)
1.1       root      111: {
1.1.1.6 ! root      112:        Uint8 nData = 0;
        !           113:        JOYREADING JoyReading;
        !           114:        int nSdlJoyId;
        !           115: 
        !           116:        nSdlJoyId = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyId;
        !           117: 
        !           118:        /* Are we emulating the joystick via the keyboard? */
        !           119:        if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_KEYBOARD)
        !           120:        {
        !           121:                /* If holding 'SHIFT' we actually want cursor key movement, so ignore any of this */
        !           122:                if ( !(SDL_GetModState()&(KMOD_LSHIFT|KMOD_RSHIFT)) )
        !           123:                {
        !           124:                        nData = nJoyKeyEmu[nStJoyId];
        !           125:                }
        !           126:        }
        !           127:        else if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_REALSTICK
        !           128:                 && bJoystickWorking[nSdlJoyId])
        !           129:        {
        !           130:                /* Use real joystick for emulation */
        !           131:                if (!Joy_ReadJoystick(nSdlJoyId, &JoyReading))
        !           132:                {
        !           133:                        /* Something is wrong, we cannot read the joystick */
        !           134:                        bJoystickWorking[nSdlJoyId] = FALSE;
        !           135:                        return 0;
        !           136:                }
        !           137: 
        !           138:                /* Directions */
        !           139:                if (JoyReading.YPos <= JOYRANGE_UP_VALUE)
        !           140:                        nData |= 0x01;
        !           141:                else if (JoyReading.YPos >= JOYRANGE_DOWN_VALUE)
        !           142:                        nData |= 0x02;
        !           143:                if (JoyReading.XPos <= JOYRANGE_LEFT_VALUE)
        !           144:                        nData |= 0x04;
        !           145:                else if (JoyReading.XPos >= JOYRANGE_RIGHT_VALUE)
        !           146:                        nData |= 0x08;
        !           147: 
        !           148:                /* PC Joystick button 1 is set as ST joystick button */
        !           149:                if (JoyReading.Buttons & JOY_BUTTON1)
        !           150:                        nData |= 0x80;
        !           151: 
        !           152:                /* Enable PC Joystick button 2 to mimick space bar (For XenonII, Flying Shark etc...) */
        !           153:                if (nStJoyId == JOYID_JOYSTICK1 && (JoyReading.Buttons & JOY_BUTTON2))
        !           154:                {
        !           155:                        /* Only press 'space bar' if not in NULL state */
        !           156:                        if (!JoystickSpaceBar)
        !           157:                        {
        !           158:                                /* Press, ikbd will send packets and de-press */
        !           159:                                JoystickSpaceBar = JOYSTICK_SPACE_DOWN;
        !           160:                        }
        !           161:                }
        !           162:        }
        !           163: 
        !           164:        /* Ignore fire button every 8 frames if enabled autofire (for both cursor emulation and joystick) */
        !           165:        if (ConfigureParams.Joysticks.Joy[nStJoyId].bEnableAutoFire)
        !           166:        {
        !           167:                if ((nVBLs&0x7)<4)
        !           168:                        nData &= ~0x80;          /* Remove top bit! */
        !           169:        }
        !           170: 
        !           171:        return nData;
1.1       root      172: }
                    173: 
1.1.1.2   root      174: 
                    175: /*-----------------------------------------------------------------------*/
1.1       root      176: /*
1.1.1.6 ! root      177:   Get the fire button states.
        !           178:   Note: More than one fire buttons are only supported for real joystick,
        !           179:   not for keyboard emulation!
        !           180: */
        !           181: static int Joy_GetFireButtons(int nStJoyId)
        !           182: {
        !           183:        int nButtons = 0;
        !           184:        int nSdlJoyId;
        !           185:        int i, nMaxButtons;
        !           186: 
        !           187:        nSdlJoyId = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyId;
        !           188: 
        !           189:        /* Are we emulating the joystick via the keyboard? */
        !           190:        if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_KEYBOARD)
        !           191:        {
        !           192:                if (nJoyKeyEmu[nStJoyId] & 0x80)
        !           193:                {
        !           194:                        nButtons |= 1;
        !           195:                }
        !           196:        }
        !           197:        else if (ConfigureParams.Joysticks.Joy[nStJoyId].nJoystickMode == JOYSTICK_REALSTICK
        !           198:                 && bJoystickWorking[nSdlJoyId])
        !           199:        {
        !           200:                nMaxButtons = SDL_JoystickNumButtons(sdlJoystick[nSdlJoyId]);
        !           201:                if (nMaxButtons > 17)
        !           202:                        nMaxButtons = 17;
        !           203:                /* Now read all fire buttons and set a bit for each pressed button: */
        !           204:                for (i = 0; i < nMaxButtons; i++)
        !           205:                {
        !           206:                        if (SDL_JoystickGetButton(sdlJoystick[nSdlJoyId], i))
        !           207:                        {
        !           208:                                nButtons |= (1 << i);
        !           209:                        }
        !           210:                }
        !           211:        }
1.1.1.2   root      212: 
1.1.1.6 ! root      213:        return nButtons;
1.1       root      214: }
                    215: 
1.1.1.2   root      216: 
                    217: /*-----------------------------------------------------------------------*/
1.1       root      218: /*
                    219:   Toggle cursor emulation
                    220: */
                    221: void Joy_ToggleCursorEmulation(void)
                    222: {
1.1.1.6 ! root      223:        /* Toggle joystick 1 keyboard emulation */
        !           224:        if (ConfigureParams.Joysticks.Joy[1].nJoystickMode != JOYSTICK_DISABLED)
        !           225:        {
        !           226:                if (ConfigureParams.Joysticks.Joy[1].nJoystickMode == JOYSTICK_REALSTICK)
        !           227:                        ConfigureParams.Joysticks.Joy[1].nJoystickMode = JOYSTICK_KEYBOARD;
        !           228:                else
        !           229:                        ConfigureParams.Joysticks.Joy[1].nJoystickMode = JOYSTICK_REALSTICK;
        !           230:        }
        !           231: }
        !           232: 
        !           233: 
        !           234: /*-----------------------------------------------------------------------*/
        !           235: /*
        !           236:   A key has been pressed down, check if we use it for joystick emulation
        !           237:   via keyboard.
        !           238: */
        !           239: BOOL Joy_KeyDown(int symkey, int modkey)
        !           240: {
        !           241:        int i;
        !           242: 
        !           243:        for (i = 0; i < 6; i++)
        !           244:        {
        !           245:                if (ConfigureParams.Joysticks.Joy[i].nJoystickMode == JOYSTICK_KEYBOARD
        !           246:                    && !(modkey & KMOD_SHIFT))
        !           247:                {
        !           248:                        if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeUp)
        !           249:                        {
        !           250:                                nJoyKeyEmu[i] |= 1;
        !           251:                                return TRUE;
        !           252:                        }
        !           253:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeDown)
        !           254:                        {
        !           255:                                nJoyKeyEmu[i] |= 2; 
        !           256:                                return TRUE;
        !           257:                        }
        !           258:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeLeft)
        !           259:                        {
        !           260:                                nJoyKeyEmu[i] |= 4;
        !           261:                                return TRUE;
        !           262:                        }
        !           263:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeRight)
        !           264:                        {
        !           265:                                nJoyKeyEmu[i] |= 8;
        !           266:                                return TRUE;
        !           267:                        }
        !           268:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeFire)
        !           269:                        {
        !           270:                                nJoyKeyEmu[i] |= 0x80;
        !           271:                                return TRUE;
        !           272:                        }
        !           273:                }
        !           274:        }
        !           275: 
        !           276:        return FALSE;
        !           277: }
        !           278: 
        !           279: 
        !           280: /*-----------------------------------------------------------------------*/
        !           281: /*
        !           282:   A key has been released, check if we use it for joystick emulation
        !           283:   via keyboard.
        !           284: */
        !           285: BOOL Joy_KeyUp(int symkey, int modkey)
        !           286: {
        !           287:        int i;
        !           288: 
        !           289:        for (i = 0; i < 6; i++)
        !           290:        {
        !           291:                if (ConfigureParams.Joysticks.Joy[i].nJoystickMode == JOYSTICK_KEYBOARD
        !           292:                    && !(modkey & KMOD_SHIFT))
        !           293:                {
        !           294:                        if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeUp)
        !           295:                        {
        !           296:                                nJoyKeyEmu[i] &= ~1;
        !           297:                                return TRUE;
        !           298:                        }
        !           299:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeDown)
        !           300:                        {
        !           301:                                nJoyKeyEmu[i] &= ~2;
        !           302:                                return TRUE;
        !           303:                        }
        !           304:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeLeft)
        !           305:                        {
        !           306:                                nJoyKeyEmu[i] &= ~4;
        !           307:                                return TRUE;
        !           308:                        }
        !           309:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeRight)
        !           310:                        {
        !           311:                                nJoyKeyEmu[i] &= ~8;
        !           312:                                return TRUE;
        !           313:                        }
        !           314:                        else if (symkey == ConfigureParams.Joysticks.Joy[i].nKeyCodeFire)
        !           315:                        {
        !           316:                                nJoyKeyEmu[i] &= ~0x80;
        !           317:                                return TRUE;
        !           318:                        }
        !           319:                }
        !           320:        }
        !           321: 
        !           322:        return FALSE;
        !           323: }
        !           324: 
        !           325: 
        !           326: /*-----------------------------------------------------------------------*/
        !           327: /*
        !           328:   Read from STE joypad buttons register (0xff9200)
        !           329: */
        !           330: void Joy_StePadButtons_ReadWord(void)
        !           331: {
        !           332:        Uint16 nData = 0xffff;
        !           333: 
        !           334:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADA].nJoystickMode != JOYSTICK_DISABLED
        !           335:            && (nSteJoySelect & 0x0f) != 0x0f)
        !           336:        {
        !           337:                int nButtons = Joy_GetFireButtons(JOYID_STEPADA);
        !           338:                if (!(nSteJoySelect & 0x1))
        !           339:                {
        !           340:                        if (nButtons & 0x01)  /* Fire button A pressed? */
        !           341:                                nData &= ~2;
        !           342:                        if (nButtons & 0x10)  /* Fire button PAUSE pressed? */
        !           343:                                nData &= ~1;
        !           344:                }
        !           345:                else if (!(nSteJoySelect & 0x2))
        !           346:                {
        !           347:                        if (nButtons & 0x02)  /* Fire button B pressed? */
        !           348:                                nData &= ~2;
        !           349:                }
        !           350:                else if (!(nSteJoySelect & 0x4))
        !           351:                {
        !           352:                        if (nButtons & 0x04)  /* Fire button C pressed? */
        !           353:                                nData &= ~2;
        !           354:                }
        !           355:                else if (!(nSteJoySelect & 0x8))
        !           356:                {
        !           357:                        if (nButtons & 0x01)  /* Fire button OPTION pressed? */
        !           358:                                nData &= ~2;
        !           359:                }
        !           360:        }
        !           361: 
        !           362:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADB].nJoystickMode != JOYSTICK_DISABLED
        !           363:            && (nSteJoySelect & 0xf0) != 0xf0)
        !           364:        {
        !           365:                int nButtons = Joy_GetFireButtons(JOYID_STEPADB);
        !           366:                if (!(nSteJoySelect & 0x10))
        !           367:                {
        !           368:                        if (nButtons & 0x01)  /* Fire button A pressed? */
        !           369:                                nData &= ~8;
        !           370:                        if (nButtons & 0x10)  /* Fire button PAUSE pressed? */
        !           371:                                nData &= ~4;
        !           372:                }
        !           373:                else if (!(nSteJoySelect & 0x20))
        !           374:                {
        !           375:                        if (nButtons & 0x02)  /* Fire button B pressed? */
        !           376:                                nData &= ~8;
        !           377:                }
        !           378:                else if (!(nSteJoySelect & 0x40))
        !           379:                {
        !           380:                        if (nButtons & 0x04)  /* Fire button C pressed? */
        !           381:                                nData &= ~8;
        !           382:                }
        !           383:                else if (!(nSteJoySelect & 0x80))
        !           384:                {
        !           385:                        if (nButtons & 0x08)  /* Fire button OPTION pressed? */
        !           386:                                nData &= ~8;
        !           387:                }
        !           388:        }
        !           389: 
        !           390:        IoMem_WriteWord(0xff9200, nData);
1.1       root      391: }
1.1.1.2   root      392: 
1.1.1.6 ! root      393: 
        !           394: /*-----------------------------------------------------------------------*/
        !           395: /*
        !           396:   Read from STE joypad direction/buttons register (0xff9202)
        !           397: */
        !           398: void Joy_StePadMulti_ReadWord(void)
        !           399: {
        !           400:        Uint8 nData = 0xff;
        !           401: 
        !           402:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADA].nJoystickMode != JOYSTICK_DISABLED
        !           403:            && (nSteJoySelect & 0x0f) != 0x0f)
        !           404:        {
        !           405:                nData &= 0xf0;
        !           406:                if (!(nSteJoySelect & 0x1))
        !           407:                {
        !           408:                        nData |= ~Joy_GetStickData(JOYID_STEPADA) & 0x0f;
        !           409:                }
        !           410:                else if (!(nSteJoySelect & 0x2))
        !           411:                {
        !           412:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADA) >> 13) & 0x0f;
        !           413:                }
        !           414:                else if (!(nSteJoySelect & 0x4))
        !           415:                {
        !           416:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADA) >> 9) & 0x0f;
        !           417:                }
        !           418:                else if (!(nSteJoySelect & 0x8))
        !           419:                {
        !           420:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADA) >> 5) & 0x0f;
        !           421:                }
        !           422:        }
        !           423: 
        !           424:        if (ConfigureParams.Joysticks.Joy[JOYID_STEPADB].nJoystickMode != JOYSTICK_DISABLED
        !           425:            && (nSteJoySelect & 0xf0) != 0xf0)
        !           426:        {
        !           427:                nData &= 0x0f;
        !           428:                if (!(nSteJoySelect & 0x10))
        !           429:                {
        !           430:                        nData |= ~Joy_GetStickData(JOYID_STEPADB) << 4;
        !           431:                }
        !           432:                else if (!(nSteJoySelect & 0x20))
        !           433:                {
        !           434:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADB) >> 13) & 0x0f;
        !           435:                }
        !           436:                else if (!(nSteJoySelect & 0x40))
        !           437:                {
        !           438:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADB) >> 9) & 0x0f;
        !           439:                }
        !           440:                else if (!(nSteJoySelect & 0x80))
        !           441:                {
        !           442:                        nData |= ~(Joy_GetFireButtons(JOYID_STEPADB) >> 5) & 0x0f;
        !           443:                }
        !           444:        }
        !           445: 
        !           446:        IoMem_WriteWord(0xff9202, (nData << 8) | 0x0ff);
        !           447: }
        !           448: 
        !           449: 
        !           450: /*-----------------------------------------------------------------------*/
        !           451: /*
        !           452:   Write to STE joypad selection register (0xff9202)
        !           453: */
        !           454: void Joy_StePadMulti_WriteWord(void)
        !           455: {
        !           456:        nSteJoySelect = IoMem_ReadWord(0xff9202);
        !           457: }

unix.superglobalmegacorp.com

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