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