|
|
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:
9: NOTE Also the ST uses the joystick port 1 as the default controller
10: - so we allocate our joysticks with index 1 and then 0 so these match.
11: */
1.1.1.5 ! root 12: char Joy_rcsid[] = "Hatari $Id: joy.c,v 1.5 2005/04/05 14:41:27 thothy Exp $";
1.1 root 13:
14: #include <SDL.h>
15:
16: #include "main.h"
17: #include "configuration.h"
18: #include "dialog.h"
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:
27: SDL_Joystick *sdlJoystick[2] = { NULL,NULL }; /* SDL's joystick structures */
1.1 root 28: BOOL bJoystickWorking[2] = { FALSE,FALSE }; /* Is joystick plugged in and working? */
29: int JoystickSpaceBar = FALSE; /* State of space-bar on joystick button 2 */
30: int cursorJoyEmu; /* set in view.c */
31:
32:
33: /*-----------------------------------------------------------------------*/
34: /*
1.1.1.3 root 35: This function initialises the (real) joysticks.
1.1 root 36: */
37: void Joy_Init(void)
38: {
1.1.1.2 root 39: int i, nPadsConnected, JoyID=1; /* Store in ST joystick slot 1 then 0 */
40:
1.1.1.3 root 41: /* Initialise SDL's joystick subsystem: */
42: if( SDL_InitSubSystem(SDL_INIT_JOYSTICK)<0 )
43: {
44: fprintf(stderr, "Could not init joysticks: %s\n", SDL_GetError() );
45: return;
46: }
47:
1.1.1.2 root 48: /* Scan joystick connection array for first two working joysticks */
49: nPadsConnected = SDL_NumJoysticks();
1.1.1.3 root 50: for(i=0; (i<nPadsConnected) && (JoyID>=0); i++)
51: {
1.1.1.2 root 52: /* Open the joystick for use */
53: sdlJoystick[JoyID] = SDL_JoystickOpen(i);
54: /* Is pad ok? */
1.1.1.3 root 55: if(sdlJoystick[JoyID]!=NULL)
56: {
1.1.1.2 root 57: /* Set as working (NOTE we assign ST joysticks 1 first), and store ID */
1.1.1.5 ! root 58: Log_Printf(LOG_DEBUG, "Joystick: %d found\n", JoyID);
1.1.1.2 root 59: bJoystickWorking[JoyID] = TRUE;
60: JoyID--;
61: }
62: }
63:
1.1 root 64:
65: /* OK, do we have any working joysticks? */
66: if (!bJoystickWorking[1]) {
67: /* No, so if first time install need to set cursor emulation */
1.1.1.2 root 68: if (bFirstTimeInstall)
69: ConfigureParams.Joysticks.Joy[1].bCursorEmulation = TRUE;
1.1 root 70: }
71: /* Make sure we only have one in cursor emulation mode */
72: Joy_PreventBothUsingCursorEmulation();
73:
74: JoystickSpaceBar = FALSE;
75: }
76:
77:
1.1.1.2 root 78: /*-----------------------------------------------------------------------*/
1.1 root 79: /*
80: Make sure only one joystick is assigned as cursor emulation mode
81: */
82: void Joy_PreventBothUsingCursorEmulation(void)
83: {
84: /* Make sure we cannot have both joysticks assigned as cursor emulation */
85: if (ConfigureParams.Joysticks.Joy[0].bCursorEmulation && ConfigureParams.Joysticks.Joy[0].bCursorEmulation) {
86: ConfigureParams.Joysticks.Joy[0].bCursorEmulation = FALSE;
87: ConfigureParams.Joysticks.Joy[1].bCursorEmulation = TRUE;
88: }
89: }
90:
1.1.1.2 root 91:
92: /*-----------------------------------------------------------------------*/
1.1 root 93: /*
1.1.1.2 root 94: Read details from joystick using SDL calls
95: NOTE ID is that of ST (ie 1 is default)
1.1 root 96: */
1.1.1.4 root 97: static BOOL Joy_ReadJoystick(int JoystickID, JOYREADING *pJoyReading)
1.1 root 98: {
1.1.1.2 root 99: /* Joystick is OK, read position */
100: pJoyReading->XPos = SDL_JoystickGetAxis(sdlJoystick[JoystickID], 0);
101: pJoyReading->YPos = SDL_JoystickGetAxis(sdlJoystick[JoystickID], 1);
102: /* Sets bit #0 if button #1 is pressed: */
103: pJoyReading->Buttons = SDL_JoystickGetButton(sdlJoystick[JoystickID], 0);
104: /* Sets bit #1 if button #2 is pressed: */
105: if( SDL_JoystickGetButton(sdlJoystick[JoystickID], 1) )
106: pJoyReading->Buttons |= JOY_BUTTON2;
1.1 root 107:
1.1.1.2 root 108: return(TRUE);
1.1 root 109: }
110:
1.1.1.2 root 111:
112: /*-----------------------------------------------------------------------*/
1.1 root 113: /*
114: Read PC joystick and return ST format byte, ie lower 4 bits direction and top bit fire
1.1.1.2 root 115: NOTE : ID 0 is Joystick 0/Mouse and ID 1 is Joystick 1 (default)
1.1 root 116: */
117: unsigned char Joy_GetStickData(unsigned int JoystickID)
118: {
119: unsigned char Data = 0;
120:
1.1.1.2 root 121: JOYREADING JoyReading;
1.1 root 122:
123: /* Are we emulating the joystick via the cursor key? */
124: if (ConfigureParams.Joysticks.Joy[JoystickID].bCursorEmulation) {
125: /* If holding 'SHIFT' we actually want cursor key movement, so ignore any of this */
1.1.1.2 root 126: if ( !(SDL_GetModState()&(KMOD_LSHIFT|KMOD_RSHIFT)) ) {
127: Data = cursorJoyEmu; /* cursorJoyEmu is set in keymap.c */
128: }
1.1 root 129: }
130: else if (bJoystickWorking[JoystickID]) {
1.1.1.2 root 131: if (!Joy_ReadJoystick(JoystickID,&JoyReading)) {
132: /* Something is wrong, we cannot read the joystick */
133: bJoystickWorking[JoystickID] = FALSE;
1.1 root 134: }
135:
1.1.1.2 root 136: /* So, did read joysyick OK? */
1.1 root 137: if (bJoystickWorking[JoystickID]) {
1.1.1.2 root 138: /* Directions */
1.1 root 139: if (JoyReading.YPos<=JOYRANGE_UP_VALUE)
140: Data |= 0x01;
141: if (JoyReading.YPos>=JOYRANGE_DOWN_VALUE)
142: Data |= 0x02;
143: if (JoyReading.XPos<=JOYRANGE_LEFT_VALUE)
144: Data |= 0x04;
145: if (JoyReading.XPos>=JOYRANGE_RIGHT_VALUE)
146: Data |= 0x08;
147:
1.1.1.2 root 148: /* Buttons - I've made fire button 2 to simulate the pressing of the space bar (for Xenon II etc...) */
1.1 root 149: #ifdef USE_FIREBUTTON_2_AS_SPACE
1.1.1.2 root 150: /* PC Joystick button 1 is set as ST joystick button and PC button 2 is the space bar */
1.1 root 151: if (JoyReading.Buttons&JOY_BUTTON1)
152: Data |= 0x80;
153: if (JoyReading.Buttons&JOY_BUTTON2) {
1.1.1.2 root 154: /* Only press 'space bar' if not in NULL state */
1.1 root 155: if (!JoystickSpaceBar) {
1.1.1.2 root 156: /* Press, ikbd will send packets and de-press */
1.1 root 157: JoystickSpaceBar = JOYSTICK_SPACE_DOWN;
158: }
159: }
1.1.1.2 root 160: #else /*USE_FIREBUTTON_2_AS_SPACE*/
161: /* PC Joystick buttons 1+2 are set as ST joystick button */
1.1 root 162: if ( (JoyReading.Buttons&JOY_BUTTON1) || (JoyReading.Buttons&JOY_BUTTON2) )
163: Data |= 0x80;
1.1.1.2 root 164: #endif /*USE_FIREBUTTON_2_AS_SPACE*/
1.1 root 165: }
166: }
167:
1.1.1.2 root 168: /* Ignore fire button every 8 frames if enabled autofire (for both cursor emulation and joystick) */
1.1 root 169: if (ConfigureParams.Joysticks.Joy[JoystickID].bEnableAutoFire) {
170: if ((VBLCounter&0x7)<4)
1.1.1.2 root 171: Data &= 0x7f; /* Remove top bit! */
1.1 root 172: }
1.1.1.2 root 173:
1.1 root 174: return(Data);
175: }
176:
1.1.1.2 root 177:
178: /*-----------------------------------------------------------------------*/
1.1 root 179: /*
180: Toggle cursor emulation
181: */
182: void Joy_ToggleCursorEmulation(void)
183: {
1.1.1.2 root 184: /* Toggle joystick 1 cursor emulation */
1.1 root 185: ConfigureParams.Joysticks.Joy[1].bCursorEmulation ^= TRUE;
1.1.1.2 root 186: /* Prevent both having emulation */
1.1 root 187: Joy_PreventBothUsingCursorEmulation();
188: }
1.1.1.2 root 189:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.