|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.