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