| 1 | /* |
| 2 | SDL - Simple DirectMedia Layer |
| 3 | Copyright (C) 1997-2009 Sam Lantinga |
| 4 | |
| 5 | This library is free software; you can redistribute it and/or |
| 6 | modify it under the terms of the GNU Lesser General Public |
| 7 | License as published by the Free Software Foundation; either |
| 8 | version 2.1 of the License, or (at your option) any later version. |
| 9 | |
| 10 | This library is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | Lesser General Public License for more details. |
| 14 | |
| 15 | You should have received a copy of the GNU Lesser General Public |
| 16 | License along with this library; if not, write to the Free Software |
| 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | |
| 19 | Sam Lantinga |
| 20 | slouken@libsdl.org |
| 21 | */ |
| 22 | #include "SDL_config.h" |
| 23 | |
| 24 | #ifdef SDL_JOYSTICK_MINT |
| 25 | |
| 26 | /* |
| 27 | * Atari Joystick/Joypad drivers |
| 28 | * |
| 29 | * Patrice Mandin |
| 30 | */ |
| 31 | |
| 32 | #include <mint/cookie.h> |
| 33 | #include <mint/osbind.h> |
| 34 | |
| 35 | #include "SDL_events.h" |
| 36 | #include "../SDL_sysjoystick.h" |
| 37 | #include "../SDL_joystick_c.h" |
| 38 | |
| 39 | #include "../../video/ataricommon/SDL_ikbdinterrupt_s.h" |
| 40 | #include "../../video/ataricommon/SDL_xbiosevents_c.h" |
| 41 | #include "../../video/ataricommon/SDL_xbiosinterrupt_s.h" |
| 42 | |
| 43 | /*--- Const ---*/ |
| 44 | |
| 45 | /* We can have: |
| 46 | 1 joystick on IKBD port 1, read via hardware I/O |
| 47 | or same joystick on IKBD port 1, read via xbios |
| 48 | 1 joypad on port A (up to 4 with teamtap) |
| 49 | or 2 joysticks on joypad port A |
| 50 | or 1 analog paddle on joypad port A |
| 51 | or 1 lightpen on joypad port A |
| 52 | 1 joypad on port B (up to 4 with teamtap) |
| 53 | or 2 joysticks on joypad port B |
| 54 | or 1 analog paddle on joypad port B |
| 55 | 2 joysticks on parallel port |
| 56 | */ |
| 57 | |
| 58 | enum { |
| 59 | IKBD_JOY1=0, |
| 60 | XBIOS_JOY1, |
| 61 | PORTA_PAD0, |
| 62 | PORTA_PAD1, |
| 63 | PORTA_PAD2, |
| 64 | PORTA_PAD3, |
| 65 | PORTB_PAD0, |
| 66 | PORTB_PAD1, |
| 67 | PORTB_PAD2, |
| 68 | PORTB_PAD3, |
| 69 | PORTA_JOY0, |
| 70 | PORTA_JOY1, |
| 71 | PORTB_JOY0, |
| 72 | PORTB_JOY1, |
| 73 | PORTA_LP, |
| 74 | PORTA_ANPAD, |
| 75 | PORTB_ANPAD, |
| 76 | #if 0 |
| 77 | PARA_JOY0, |
| 78 | PARA_JOY1, |
| 79 | #endif |
| 80 | MAX_JOYSTICKS |
| 81 | }; |
| 82 | |
| 83 | enum { |
| 84 | MCH_ST=0, |
| 85 | MCH_STE, |
| 86 | MCH_TT, |
| 87 | MCH_F30, |
| 88 | MCH_CLONE, |
| 89 | MCH_ARANYM |
| 90 | }; |
| 91 | |
| 92 | /* Joypad buttons |
| 93 | * Procontroller note: |
| 94 | * L,R are connected to 4,6 |
| 95 | * X,Y,Z are connected to 7,8,9 |
| 96 | */ |
| 97 | |
| 98 | enum { |
| 99 | JP_UP=0, JP_DOWN, JP_LEFT, JP_RIGHT, |
| 100 | JP_KPMULT, JP_KP7, JP_KP4, JP_KP1, |
| 101 | JP_KP0, JP_KP8, JP_KP5, JP_KP2, |
| 102 | JP_KPNUM, JP_KP9, JP_KP6, JP_KP3, |
| 103 | JP_PAUSE, JP_FIRE0, JP_UNDEF0, JP_FIRE1, |
| 104 | JP_UNDEF1, JP_FIRE2, JP_UNDEF2, JP_OPTION |
| 105 | }; |
| 106 | |
| 107 | #define JP_NUM_BUTTONS 17 |
| 108 | |
| 109 | #define PORT_JS_RIGHT (1<<0) |
| 110 | #define PORT_JS_LEFT (1<<1) |
| 111 | #define PORT_JS_DOWN (1<<2) |
| 112 | #define PORT_JS_UP (1<<3) |
| 113 | #define PORT_JS_FIRE (1<<4) |
| 114 | |
| 115 | enum { |
| 116 | TEAMTAP_MAYBE=0, |
| 117 | TEAMTAP_YES, |
| 118 | TEAMTAP_NO |
| 119 | }; |
| 120 | |
| 121 | /* Teamtap detection values */ |
| 122 | static const Uint32 teamtap_ghosts[20][4]={ |
| 123 | {1<<JP_UP, /* for this event on joypad 0, port X */ |
| 124 | (1<<JP_UP)|(1<<JP_KP0), /* we get this on joypad 1 */ |
| 125 | (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KP0), /* this on joypad 2 */ |
| 126 | (1<<JP_KPMULT)|(1<<JP_KP0)}, /* this on joypad 3 */ |
| 127 | {1<<JP_DOWN, |
| 128 | (1<<JP_DOWN)|(1<<JP_KP8), |
| 129 | (1<<JP_DOWN)|(1<<JP_KP9)|(1<<JP_KP8), |
| 130 | (1<<JP_KP7)|(1<<JP_KP8)}, |
| 131 | {1<<JP_LEFT, |
| 132 | (1<<JP_LEFT)|(1<<JP_KP5), |
| 133 | (1<<JP_LEFT)|(1<<JP_KP6)|(1<<JP_KP5), |
| 134 | (1<<JP_KP4)|(1<<JP_KP5)}, |
| 135 | {1<<JP_RIGHT, |
| 136 | (1<<JP_RIGHT)|(1<<JP_KP2), |
| 137 | (1<<JP_RIGHT)|(1<<JP_KP3)|(1<<JP_KP2), |
| 138 | (1<<JP_KP1)|(1<<JP_KP2)}, |
| 139 | {1<<JP_OPTION, |
| 140 | (1<<JP_OPTION)|(1<<JP_FIRE1)|(1<<JP_FIRE2), |
| 141 | (1<<JP_FIRE0)|(1<<JP_FIRE1)|(1<<JP_FIRE2), |
| 142 | 0}, |
| 143 | {1<<JP_FIRE0, |
| 144 | (1<<JP_FIRE2)|(1<<JP_FIRE0), |
| 145 | (1<<JP_FIRE0)|(1<<JP_OPTION)|(1<<JP_FIRE2), |
| 146 | (1<<JP_FIRE1)|(1<<JP_FIRE2)}, |
| 147 | {1<<JP_FIRE1, |
| 148 | (1<<JP_FIRE0), |
| 149 | (1<<JP_OPTION)|(1<<JP_FIRE0)|(1<<JP_FIRE1), |
| 150 | (1<<JP_FIRE0)|(1<<JP_FIRE2)}, |
| 151 | {1<<JP_FIRE2, |
| 152 | (1<<JP_OPTION)|(1<<JP_FIRE0)|(1<<JP_FIRE1)|(1<<JP_FIRE2), |
| 153 | (1<<JP_OPTION), |
| 154 | (1<<JP_FIRE0)|(1<<JP_FIRE1)}, |
| 155 | {1<<JP_KP1, |
| 156 | (1<<JP_RIGHT)|(1<<JP_KP1), |
| 157 | (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP3), |
| 158 | (1<<JP_RIGHT)|(1<<JP_KP2)}, |
| 159 | {1<<JP_KP2, |
| 160 | (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2)|(1<<JP_KP3), |
| 161 | (1<<JP_KP3), |
| 162 | (1<<JP_RIGHT)|(1<<JP_KP1)}, |
| 163 | {1<<JP_KP3, |
| 164 | (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2)|(1<<JP_KP3), |
| 165 | (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2), |
| 166 | 0}, |
| 167 | {1<<JP_KP4, |
| 168 | (1<<JP_LEFT)|(1<<JP_KP4), |
| 169 | (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP6), |
| 170 | (1<<JP_LEFT)|(1<<JP_KP5)}, |
| 171 | {1<<JP_KP5, |
| 172 | (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5)|(1<<JP_KP6), |
| 173 | (1<<JP_KP6), |
| 174 | (1<<JP_LEFT)|(1<<JP_KP4)}, |
| 175 | {1<<JP_KP6, |
| 176 | (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5)|(1<<JP_KP6), |
| 177 | (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5), |
| 178 | 0}, |
| 179 | {1<<JP_KP7, |
| 180 | (1<<JP_DOWN)|(1<<JP_KP7), |
| 181 | (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP9), |
| 182 | (1<<JP_DOWN)|(1<<JP_KP8)}, |
| 183 | {1<<JP_KP8, |
| 184 | (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8)|(1<<JP_KP9), |
| 185 | (1<<JP_KP9), |
| 186 | (1<<JP_DOWN)|(1<<JP_KP7)}, |
| 187 | {1<<JP_KP9, |
| 188 | (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8)|(1<<JP_KP9), |
| 189 | (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8), |
| 190 | 0}, |
| 191 | {1<<JP_KPMULT, |
| 192 | (1<<JP_UP)|(1<<JP_KPMULT), |
| 193 | (1<<JP_UP)|(1<<JP_KPNUM), |
| 194 | (1<<JP_UP)|(1<<JP_KP0)}, |
| 195 | {1<<JP_KP0, |
| 196 | (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KPMULT)|(1<<JP_KP0), |
| 197 | 1<<JP_KPNUM, |
| 198 | (1<<JP_UP)|(1<<JP_KPMULT)}, |
| 199 | {1<<JP_KPNUM, |
| 200 | (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KPMULT)|(1<<JP_KP0), |
| 201 | (1<<JP_UP)|(1<<JP_KPMULT)|(1<<JP_KP0), |
| 202 | 0}, |
| 203 | }; |
| 204 | |
| 205 | /*--- Types ---*/ |
| 206 | |
| 207 | typedef struct { |
| 208 | SDL_bool enabled; |
| 209 | unsigned char *name; |
| 210 | Uint32 prevstate; |
| 211 | } atarijoy_t; |
| 212 | |
| 213 | /*--- Variables ---*/ |
| 214 | |
| 215 | static atarijoy_t atarijoysticks[MAX_JOYSTICKS]={ |
| 216 | {SDL_FALSE,"IKBD joystick port 1",0}, |
| 217 | {SDL_FALSE,"Xbios joystick port 1",0}, |
| 218 | {SDL_FALSE,"Joypad 0 port A",0}, |
| 219 | {SDL_FALSE,"Joypad 1 port A",0}, |
| 220 | {SDL_FALSE,"Joypad 2 port A",0}, |
| 221 | {SDL_FALSE,"Joypad 3 port A",0}, |
| 222 | {SDL_FALSE,"Joypad 0 port B",0}, |
| 223 | {SDL_FALSE,"Joypad 1 port B",0}, |
| 224 | {SDL_FALSE,"Joypad 2 port B",0}, |
| 225 | {SDL_FALSE,"Joypad 3 port B",0}, |
| 226 | {SDL_FALSE,"Joystick 0 port A",0}, |
| 227 | {SDL_FALSE,"Joystick 1 port A",0}, |
| 228 | {SDL_FALSE,"Joystick 0 port B",0}, |
| 229 | {SDL_FALSE,"Joystick 1 port B",0}, |
| 230 | {SDL_FALSE,"Lightpen port A",0}, |
| 231 | {SDL_FALSE,"Analog paddle port A",0}, |
| 232 | {SDL_FALSE,"Analog paddle port B",0} |
| 233 | #if 0 |
| 234 | ,{SDL_FALSE,"Joystick 0 parallel port",0}, |
| 235 | {SDL_FALSE,"Joystick 1 parallel port",0} |
| 236 | #endif |
| 237 | }; |
| 238 | |
| 239 | static const int jp_buttons[JP_NUM_BUTTONS]={ |
| 240 | JP_FIRE0, JP_FIRE1, JP_FIRE2, JP_PAUSE, |
| 241 | JP_OPTION, JP_KPMULT, JP_KPNUM, JP_KP0, |
| 242 | JP_KP1, JP_KP2, JP_KP3, JP_KP4, |
| 243 | JP_KP5, JP_KP6, JP_KP7, JP_KP8, |
| 244 | JP_KP9 |
| 245 | }; |
| 246 | |
| 247 | static SDL_bool joypad_ports_enabled=SDL_FALSE; |
| 248 | static int has_teamtap[2]={TEAMTAP_MAYBE,TEAMTAP_MAYBE}; |
| 249 | |
| 250 | /* Updated joypad ports */ |
| 251 | static Uint16 jp_paddles[4]; |
| 252 | static Uint16 jp_lightpens[2]; |
| 253 | static Uint16 jp_directions; |
| 254 | static Uint16 jp_fires; |
| 255 | static Uint32 jp_joypads[8]; |
| 256 | |
| 257 | /*--- Functions prototypes ---*/ |
| 258 | |
| 259 | static int GetEnabledAtariJoystick(int index); |
| 260 | static void UpdateJoypads(void); |
| 261 | |
| 262 | /*--- Functions ---*/ |
| 263 | |
| 264 | int SDL_SYS_JoystickInit(void) |
| 265 | { |
| 266 | int i; |
| 267 | unsigned long cookie_mch; |
| 268 | const char *envr=SDL_getenv("SDL_JOYSTICK_ATARI"); |
| 269 | |
| 270 | #define TEST_JOY_ENABLED(env,idstring,num) \ |
| 271 | if (SDL_strstr(env,idstring"-off")) { \ |
| 272 | atarijoysticks[num].enabled=SDL_FALSE; \ |
| 273 | } \ |
| 274 | if (SDL_strstr(env,idstring"-on")) { \ |
| 275 | atarijoysticks[num].enabled=SDL_TRUE; \ |
| 276 | } |
| 277 | |
| 278 | /* Cookie _MCH present ? if not, assume ST machine */ |
| 279 | if (Getcookie(C__MCH, &cookie_mch) != C_FOUND) { |
| 280 | cookie_mch = MCH_ST << 16; |
| 281 | } |
| 282 | |
| 283 | /* Enable some default joysticks */ |
| 284 | if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) || |
| 285 | (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16) || |
| 286 | (cookie_mch == MCH_ARANYM<<16)) |
| 287 | { |
| 288 | atarijoysticks[IKBD_JOY1].enabled=(SDL_AtariIkbd_enabled!=0); |
| 289 | } |
| 290 | if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16) || |
| 291 | (cookie_mch == MCH_ARANYM<<16)) |
| 292 | { |
| 293 | atarijoysticks[PORTA_PAD0].enabled = |
| 294 | atarijoysticks[PORTA_PAD1].enabled = |
| 295 | atarijoysticks[PORTA_PAD2].enabled = |
| 296 | atarijoysticks[PORTA_PAD3].enabled = |
| 297 | atarijoysticks[PORTB_PAD0].enabled = |
| 298 | atarijoysticks[PORTB_PAD1].enabled = |
| 299 | atarijoysticks[PORTB_PAD2].enabled = |
| 300 | atarijoysticks[PORTB_PAD3].enabled = SDL_TRUE; |
| 301 | } |
| 302 | if (!atarijoysticks[IKBD_JOY1].enabled) { |
| 303 | atarijoysticks[XBIOS_JOY1].enabled=(SDL_AtariXbios_enabled!=0); |
| 304 | } |
| 305 | |
| 306 | /* Read environment for joysticks to enable */ |
| 307 | if (envr) { |
| 308 | /* IKBD on any Atari, maybe clones */ |
| 309 | if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) || |
| 310 | (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16) || |
| 311 | (cookie_mch == MCH_ARANYM<<16)) { |
| 312 | if (SDL_AtariIkbd_enabled!=0) { |
| 313 | TEST_JOY_ENABLED(envr, "ikbd-joy1", IKBD_JOY1); |
| 314 | } |
| 315 | } |
| 316 | /* Joypads ports on STE, Falcon and maybe others */ |
| 317 | if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16) || |
| 318 | (cookie_mch == MCH_ARANYM<<16)) { |
| 319 | TEST_JOY_ENABLED(envr, "porta-pad", PORTA_PAD0); |
| 320 | if (!atarijoysticks[PORTA_PAD0].enabled) { |
| 321 | TEST_JOY_ENABLED(envr, "porta-joy0", PORTA_JOY0); |
| 322 | TEST_JOY_ENABLED(envr, "porta-joy1", PORTA_JOY1); |
| 323 | if (!(atarijoysticks[PORTA_JOY0].enabled) && !(atarijoysticks[PORTA_JOY1].enabled)) { |
| 324 | TEST_JOY_ENABLED(envr, "porta-lp", PORTA_LP); |
| 325 | if (!atarijoysticks[PORTA_LP].enabled) { |
| 326 | TEST_JOY_ENABLED(envr, "porta-anpad", PORTA_ANPAD); |
| 327 | } |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | TEST_JOY_ENABLED(envr, "portb-pad", PORTB_PAD0); |
| 332 | if (!atarijoysticks[PORTB_PAD0].enabled) { |
| 333 | TEST_JOY_ENABLED(envr, "portb-joy0", PORTB_JOY0); |
| 334 | TEST_JOY_ENABLED(envr, "portb-joy1", PORTB_JOY1); |
| 335 | if (!(atarijoysticks[PORTB_JOY0].enabled) && !(atarijoysticks[PORTB_JOY1].enabled)) { |
| 336 | TEST_JOY_ENABLED(envr, "portb-anpad", PORTB_ANPAD); |
| 337 | } |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | if (!atarijoysticks[IKBD_JOY1].enabled) { |
| 342 | if (SDL_AtariXbios_enabled!=0) { |
| 343 | TEST_JOY_ENABLED(envr, "xbios-joy1", XBIOS_JOY1); |
| 344 | } |
| 345 | } |
| 346 | #if 0 |
| 347 | /* Parallel port on any Atari, maybe clones */ |
| 348 | if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) || |
| 349 | (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16)) { |
| 350 | TEST_JOY_ENABLED(envr, "para-joy0", PARA_JOY0); |
| 351 | TEST_JOY_ENABLED(envr, "para-joy1", PARA_JOY1); |
| 352 | } |
| 353 | #endif |
| 354 | } |
| 355 | |
| 356 | /* Need to update joypad ports ? */ |
| 357 | joypad_ports_enabled=SDL_FALSE; |
| 358 | for (i=PORTA_PAD0;i<=PORTB_ANPAD;i++) { |
| 359 | if (atarijoysticks[i].enabled) { |
| 360 | joypad_ports_enabled=SDL_TRUE; |
| 361 | break; |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | SDL_numjoysticks = 0; |
| 366 | for (i=0;i<MAX_JOYSTICKS;i++) { |
| 367 | if (atarijoysticks[i].enabled) { |
| 368 | ++SDL_numjoysticks; |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | return(SDL_numjoysticks); |
| 373 | } |
| 374 | |
| 375 | static int GetEnabledAtariJoystick(int index) |
| 376 | { |
| 377 | int i,j; |
| 378 | |
| 379 | /* Return the nth'index' enabled atari joystick */ |
| 380 | j=0; |
| 381 | for (i=0;i<MAX_JOYSTICKS;i++) { |
| 382 | if (!atarijoysticks[i].enabled) { |
| 383 | continue; |
| 384 | } |
| 385 | |
| 386 | if (j==index) { |
| 387 | break; |
| 388 | } |
| 389 | |
| 390 | ++j; |
| 391 | } |
| 392 | if (i==MAX_JOYSTICKS) |
| 393 | return -1; |
| 394 | |
| 395 | return i; |
| 396 | } |
| 397 | |
| 398 | const char *SDL_SYS_JoystickName(int index) |
| 399 | { |
| 400 | int numjoystick; |
| 401 | |
| 402 | numjoystick=GetEnabledAtariJoystick(index); |
| 403 | if (numjoystick==-1) |
| 404 | return NULL; |
| 405 | |
| 406 | return(atarijoysticks[numjoystick].name); |
| 407 | } |
| 408 | |
| 409 | int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) |
| 410 | { |
| 411 | int numjoystick; |
| 412 | |
| 413 | numjoystick=GetEnabledAtariJoystick(joystick->index); |
| 414 | if (numjoystick==-1) |
| 415 | return -1; |
| 416 | |
| 417 | joystick->naxes=0; |
| 418 | joystick->nhats=0; |
| 419 | joystick->nballs=0; |
| 420 | |
| 421 | switch(numjoystick) { |
| 422 | case PORTA_PAD0: |
| 423 | case PORTA_PAD1: |
| 424 | case PORTA_PAD2: |
| 425 | case PORTA_PAD3: |
| 426 | case PORTB_PAD0: |
| 427 | case PORTB_PAD1: |
| 428 | case PORTB_PAD2: |
| 429 | case PORTB_PAD3: |
| 430 | joystick->nhats=1; |
| 431 | joystick->nbuttons=JP_NUM_BUTTONS; |
| 432 | break; |
| 433 | case PORTA_LP: |
| 434 | case PORTA_ANPAD: |
| 435 | case PORTB_ANPAD: |
| 436 | joystick->naxes=2; |
| 437 | joystick->nbuttons=2; |
| 438 | break; |
| 439 | default: |
| 440 | joystick->nhats=1; |
| 441 | joystick->nbuttons=1; |
| 442 | break; |
| 443 | } |
| 444 | |
| 445 | return(0); |
| 446 | } |
| 447 | |
| 448 | /* Detect Teamtap using ghost events */ |
| 449 | static void detect_teamtap(int num_port) |
| 450 | { |
| 451 | int i,j; |
| 452 | |
| 453 | /* Check if joypad 1,2,3 triggered but not 0 */ |
| 454 | for (i=1; i<4; i++) { |
| 455 | if (jp_joypads[num_port*4+i] && (jp_joypads[num_port*4]==0)) { |
| 456 | has_teamtap[num_port] = TEAMTAP_YES; |
| 457 | return; |
| 458 | } |
| 459 | } |
| 460 | |
| 461 | /* Check if joypad 0 on a given port triggered ghost events for |
| 462 | * other joypads |
| 463 | */ |
| 464 | for (i=0; i<20; i++) { |
| 465 | int with_teamtap=1; |
| 466 | |
| 467 | if (jp_joypads[num_port*4]!=teamtap_ghosts[i][0]) |
| 468 | continue; |
| 469 | |
| 470 | /* If any button on first joypad pressed, check other pads */ |
| 471 | for (j=1; j<4; j++) { |
| 472 | if ((jp_joypads[num_port*4+j] & teamtap_ghosts[i][j]) |
| 473 | ==teamtap_ghosts[i][j]) |
| 474 | { |
| 475 | with_teamtap = 0; |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | has_teamtap[num_port] = (with_teamtap ? TEAMTAP_YES : TEAMTAP_NO); |
| 480 | break; |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) |
| 485 | { |
| 486 | int numjoystick; |
| 487 | Uint8 hatstate; |
| 488 | Uint32 curstate,prevstate; |
| 489 | |
| 490 | numjoystick=GetEnabledAtariJoystick(joystick->index); |
| 491 | if (numjoystick==-1) |
| 492 | return; |
| 493 | |
| 494 | prevstate = atarijoysticks[numjoystick].prevstate; |
| 495 | |
| 496 | if (joypad_ports_enabled) { |
| 497 | Supexec(UpdateJoypads); |
| 498 | } |
| 499 | |
| 500 | switch (numjoystick) { |
| 501 | case IKBD_JOY1: |
| 502 | case XBIOS_JOY1: |
| 503 | { |
| 504 | curstate = 0; |
| 505 | |
| 506 | if (numjoystick==IKBD_JOY1) { |
| 507 | curstate = SDL_AtariIkbd_joystick & 0xff; |
| 508 | } |
| 509 | if (numjoystick==XBIOS_JOY1) { |
| 510 | curstate = SDL_AtariXbios_joystick & 0xff; |
| 511 | } |
| 512 | |
| 513 | if (curstate != prevstate) { |
| 514 | hatstate = SDL_HAT_CENTERED; |
| 515 | if (curstate & IKBD_JOY_LEFT) { |
| 516 | hatstate |= SDL_HAT_LEFT; |
| 517 | } |
| 518 | if (curstate & IKBD_JOY_RIGHT) { |
| 519 | hatstate |= SDL_HAT_RIGHT; |
| 520 | } |
| 521 | if (curstate & IKBD_JOY_UP) { |
| 522 | hatstate |= SDL_HAT_UP; |
| 523 | } |
| 524 | if (curstate & IKBD_JOY_DOWN) { |
| 525 | hatstate |= SDL_HAT_DOWN; |
| 526 | } |
| 527 | SDL_PrivateJoystickHat(joystick, 0, hatstate); |
| 528 | |
| 529 | /* Button */ |
| 530 | if ((curstate & IKBD_JOY_FIRE) && !(prevstate & IKBD_JOY_FIRE)) { |
| 531 | SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED); |
| 532 | } |
| 533 | if (!(curstate & IKBD_JOY_FIRE) && (prevstate & IKBD_JOY_FIRE)) { |
| 534 | SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED); |
| 535 | } |
| 536 | } |
| 537 | atarijoysticks[numjoystick].prevstate = curstate; |
| 538 | } |
| 539 | break; |
| 540 | case PORTA_PAD0: |
| 541 | case PORTA_PAD1: |
| 542 | case PORTA_PAD2: |
| 543 | case PORTA_PAD3: |
| 544 | case PORTB_PAD0: |
| 545 | case PORTB_PAD1: |
| 546 | case PORTB_PAD2: |
| 547 | case PORTB_PAD3: |
| 548 | { |
| 549 | int numjoypad,i,numport; |
| 550 | |
| 551 | numjoypad = numport = 0; |
| 552 | switch(numjoystick) { |
| 553 | case PORTA_PAD0: |
| 554 | numjoypad = 0; break; |
| 555 | case PORTA_PAD1: |
| 556 | numjoypad = 1; break; |
| 557 | case PORTA_PAD2: |
| 558 | numjoypad = 2; break; |
| 559 | case PORTA_PAD3: |
| 560 | numjoypad = 3; break; |
| 561 | case PORTB_PAD0: |
| 562 | numjoypad = 4; numport = 1; break; |
| 563 | case PORTB_PAD1: |
| 564 | numjoypad = 5; numport = 1; break; |
| 565 | case PORTB_PAD2: |
| 566 | numjoypad = 6; numport = 1; break; |
| 567 | case PORTB_PAD3: |
| 568 | numjoypad = 7; numport = 1; break; |
| 569 | } |
| 570 | |
| 571 | jp_joypads[numjoypad] &= 0xabffff; |
| 572 | |
| 573 | if (has_teamtap[numport]==TEAMTAP_MAYBE) { |
| 574 | detect_teamtap(numport); |
| 575 | } |
| 576 | /* No events for PORTX_PAD[1,2,3] if no teamtap detected */ |
| 577 | if (has_teamtap[numport] == TEAMTAP_NO) { |
| 578 | if ((numjoypad & 3)!=0) { |
| 579 | return; |
| 580 | } |
| 581 | } |
| 582 | |
| 583 | curstate=jp_joypads[numjoypad]; |
| 584 | if (curstate!=prevstate) { |
| 585 | hatstate = SDL_HAT_CENTERED; |
| 586 | if (curstate & (1<<JP_LEFT)) { |
| 587 | hatstate |= SDL_HAT_LEFT; |
| 588 | } |
| 589 | if (curstate & (1<<JP_RIGHT)) { |
| 590 | hatstate |= SDL_HAT_RIGHT; |
| 591 | } |
| 592 | if (curstate & (1<<JP_UP)) { |
| 593 | hatstate |= SDL_HAT_UP; |
| 594 | } |
| 595 | if (curstate & (1<<JP_DOWN)) { |
| 596 | hatstate |= SDL_HAT_DOWN; |
| 597 | } |
| 598 | SDL_PrivateJoystickHat(joystick, 0, hatstate); |
| 599 | |
| 600 | /* Buttons */ |
| 601 | for (i=0;i<JP_NUM_BUTTONS;i++) { |
| 602 | int button; |
| 603 | |
| 604 | button=1<<jp_buttons[i]; |
| 605 | |
| 606 | if ((curstate & button) && !(prevstate & button)) { |
| 607 | SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); |
| 608 | } |
| 609 | if (!(curstate & button) && (prevstate & button)) { |
| 610 | SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); |
| 611 | } |
| 612 | } |
| 613 | } |
| 614 | atarijoysticks[numjoystick].prevstate = curstate; |
| 615 | } |
| 616 | break; |
| 617 | case PORTA_JOY0: |
| 618 | case PORTA_JOY1: |
| 619 | case PORTB_JOY0: |
| 620 | case PORTB_JOY1: |
| 621 | { |
| 622 | int fire_shift=0,dir_shift=0; |
| 623 | |
| 624 | if (numjoystick==PORTA_JOY0) { fire_shift=0; dir_shift=0; } |
| 625 | if (numjoystick==PORTA_JOY1) { fire_shift=1; dir_shift=4; } |
| 626 | if (numjoystick==PORTB_JOY0) { fire_shift=2; dir_shift=8; } |
| 627 | if (numjoystick==PORTB_JOY1) { fire_shift=3; dir_shift=12; } |
| 628 | |
| 629 | curstate = (jp_directions>>dir_shift) & 15; |
| 630 | curstate |= ((jp_fires>>fire_shift) & 1)<<4; |
| 631 | |
| 632 | if (curstate != prevstate) { |
| 633 | hatstate = SDL_HAT_CENTERED; |
| 634 | if (curstate & PORT_JS_LEFT) { |
| 635 | hatstate |= SDL_HAT_LEFT; |
| 636 | } |
| 637 | if (curstate & PORT_JS_RIGHT) { |
| 638 | hatstate |= SDL_HAT_RIGHT; |
| 639 | } |
| 640 | if (curstate & PORT_JS_UP) { |
| 641 | hatstate |= SDL_HAT_UP; |
| 642 | } |
| 643 | if (curstate & PORT_JS_DOWN) { |
| 644 | hatstate |= SDL_HAT_DOWN; |
| 645 | } |
| 646 | SDL_PrivateJoystickHat(joystick, 0, hatstate); |
| 647 | |
| 648 | /* Button */ |
| 649 | if ((curstate & PORT_JS_FIRE) && !(prevstate & PORT_JS_FIRE)) { |
| 650 | SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED); |
| 651 | } |
| 652 | if (!(curstate & PORT_JS_FIRE) && (prevstate & PORT_JS_FIRE)) { |
| 653 | SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED); |
| 654 | } |
| 655 | } |
| 656 | atarijoysticks[numjoystick].prevstate = curstate; |
| 657 | } |
| 658 | break; |
| 659 | case PORTA_LP: |
| 660 | { |
| 661 | int i; |
| 662 | |
| 663 | curstate = jp_lightpens[0]>>1; |
| 664 | curstate |= (jp_lightpens[1]>>1)<<15; |
| 665 | curstate |= (jp_fires & 3)<<30; |
| 666 | |
| 667 | if (curstate != prevstate) { |
| 668 | /* X axis */ |
| 669 | SDL_PrivateJoystickAxis(joystick,0,jp_lightpens[0] ^ 0x8000); |
| 670 | /* Y axis */ |
| 671 | SDL_PrivateJoystickAxis(joystick,1,jp_lightpens[1] ^ 0x8000); |
| 672 | /* Buttons */ |
| 673 | for (i=0;i<2;i++) { |
| 674 | int button; |
| 675 | |
| 676 | button=1<<(30+i); |
| 677 | |
| 678 | if ((curstate & button) && !(prevstate & button)) { |
| 679 | SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); |
| 680 | } |
| 681 | if (!(curstate & button) && (prevstate & button)) { |
| 682 | SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); |
| 683 | } |
| 684 | } |
| 685 | } |
| 686 | atarijoysticks[numjoystick].prevstate = curstate; |
| 687 | } |
| 688 | break; |
| 689 | case PORTA_ANPAD: |
| 690 | case PORTB_ANPAD: |
| 691 | { |
| 692 | int numpaddle, i; |
| 693 | |
| 694 | numpaddle=0<<1; |
| 695 | if (numjoystick==PORTB_ANPAD) numpaddle=1<<1; |
| 696 | |
| 697 | curstate = jp_paddles[numpaddle]>>1; |
| 698 | curstate |= (jp_paddles[numpaddle+1]>>1)<<15; |
| 699 | curstate |= ((jp_fires>>numpaddle) & 3)<<30; |
| 700 | |
| 701 | if (curstate != prevstate) { |
| 702 | /* X axis */ |
| 703 | SDL_PrivateJoystickAxis(joystick,0,jp_paddles[numpaddle] ^ 0x8000); |
| 704 | /* Y axis */ |
| 705 | SDL_PrivateJoystickAxis(joystick,1,jp_paddles[numpaddle+1] ^ 0x8000); |
| 706 | /* Buttons */ |
| 707 | for (i=0;i<2;i++) { |
| 708 | int button; |
| 709 | |
| 710 | button=1<<(30+i); |
| 711 | |
| 712 | if ((curstate & button) && !(prevstate & button)) { |
| 713 | SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); |
| 714 | } |
| 715 | if (!(curstate & button) && (prevstate & button)) { |
| 716 | SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); |
| 717 | } |
| 718 | } |
| 719 | } |
| 720 | atarijoysticks[numjoystick].prevstate = curstate; |
| 721 | } |
| 722 | break; |
| 723 | #if 0 |
| 724 | case PARA_JOY0: |
| 725 | case PARA_JOY1: |
| 726 | break; |
| 727 | #endif |
| 728 | }; |
| 729 | |
| 730 | return; |
| 731 | } |
| 732 | |
| 733 | void SDL_SYS_JoystickClose(SDL_Joystick *joystick) |
| 734 | { |
| 735 | return; |
| 736 | } |
| 737 | |
| 738 | void SDL_SYS_JoystickQuit(void) |
| 739 | { |
| 740 | SDL_numjoysticks=0; |
| 741 | return; |
| 742 | } |
| 743 | |
| 744 | /*--- Joypad I/O read/write interface ---*/ |
| 745 | |
| 746 | #define JOYPAD_IO_BASE (0xffff9200) |
| 747 | struct JOYPAD_IO_S { |
| 748 | Uint16 fires; |
| 749 | Uint16 directions; |
| 750 | Uint16 dummy1[6]; |
| 751 | Uint16 paddles[4]; |
| 752 | Uint16 dummy2[4]; |
| 753 | Uint16 lightpens[2]; |
| 754 | }; |
| 755 | #define JOYPAD_IO ((*(volatile struct JOYPAD_IO_S *)JOYPAD_IO_BASE)) |
| 756 | |
| 757 | static const Uint16 joypad_masks[8*4]={ |
| 758 | 0xfffe, 0xfffd, 0xfffb, 0xfff7, |
| 759 | 0xfff0, 0xfff1, 0xfff2, 0xfff3, |
| 760 | 0xfff4, 0xfff5, 0xfff6, 0xfff8, |
| 761 | 0xfff9, 0xfffa, 0xfffc, 0xffff, |
| 762 | 0xffef, 0xffdf, 0xffbf, 0xff7f, |
| 763 | 0xff0f, 0xff1f, 0xff2f, 0xff3f, |
| 764 | 0xff4f, 0xff5f, 0xff6f, 0xff8f, |
| 765 | 0xff9f, 0xffaf, 0xffcf, 0xffff |
| 766 | }; |
| 767 | |
| 768 | static void UpdateJoypads(void) |
| 769 | { |
| 770 | Uint16 tmp, i, j; |
| 771 | Uint32 cur_fire, cur_dir; |
| 772 | |
| 773 | /*--- This function is called in supervisor mode ---*/ |
| 774 | |
| 775 | /* Update joysticks */ |
| 776 | jp_fires = (~(JOYPAD_IO.fires)) & 15; |
| 777 | jp_directions = (~(JOYPAD_IO.directions)); |
| 778 | |
| 779 | /* Update lightpen */ |
| 780 | tmp = JOYPAD_IO.lightpens[0] & 1023; |
| 781 | jp_lightpens[0] = (tmp<<6) | (tmp>>4); |
| 782 | tmp = JOYPAD_IO.lightpens[1] & 1023; |
| 783 | jp_lightpens[1] = (tmp<<6) | (tmp>>4); |
| 784 | |
| 785 | /* Update paddles */ |
| 786 | tmp = (JOYPAD_IO.paddles[0] & 255); |
| 787 | jp_paddles[0] = (tmp<<8) | tmp; |
| 788 | tmp = (JOYPAD_IO.paddles[1] & 255); |
| 789 | jp_paddles[1] = (tmp<<8) | tmp; |
| 790 | tmp = (JOYPAD_IO.paddles[2] & 255); |
| 791 | jp_paddles[2] = (tmp<<8) | tmp; |
| 792 | tmp = (JOYPAD_IO.paddles[3] & 255); |
| 793 | jp_paddles[3] = (tmp<<8) | tmp; |
| 794 | |
| 795 | /* Update joypads on teamtap port A */ |
| 796 | for (i=0; i<4; i++) { |
| 797 | jp_joypads[i] = 0; |
| 798 | for (j=0; j<4; j++) { |
| 799 | JOYPAD_IO.directions = joypad_masks[(i*4)+j]; |
| 800 | |
| 801 | cur_fire = (~(JOYPAD_IO.fires) & 3)<<16; |
| 802 | cur_dir = (~(JOYPAD_IO.directions)>>8) & 15; |
| 803 | |
| 804 | jp_joypads[i] |= cur_fire<<(j*2); |
| 805 | jp_joypads[i] |= cur_dir<<(j*4); |
| 806 | } |
| 807 | } |
| 808 | |
| 809 | /* Update joypads on teamtap port B */ |
| 810 | for (i=4; i<8; i++) { |
| 811 | jp_joypads[i] = 0; |
| 812 | for (j=0; j<4; j++) { |
| 813 | JOYPAD_IO.directions = joypad_masks[(i*4)+j]; |
| 814 | |
| 815 | cur_fire = (~(JOYPAD_IO.fires) & 0xc)<<14; |
| 816 | cur_dir = (~(JOYPAD_IO.directions)>>12) & 15; |
| 817 | |
| 818 | jp_joypads[i] |= cur_fire<<(j*2); |
| 819 | jp_joypads[i] |= cur_dir<<(j*4); |
| 820 | } |
| 821 | } |
| 822 | |
| 823 | JOYPAD_IO.directions=0xffff; |
| 824 | } |
| 825 | |
| 826 | #endif /* SDL_JOYSTICK_MINT */ |