1/* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 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 58enum { 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 83enum { 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 98enum { 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 115enum { 116 TEAMTAP_MAYBE=0, 117 TEAMTAP_YES, 118 TEAMTAP_NO 119}; 120 121/* Teamtap detection values */ 122static 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 207typedef struct { 208 SDL_bool enabled; 209 char *name; 210 Uint32 prevstate; 211} atarijoy_t; 212 213/*--- Variables ---*/ 214 215static 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 239static 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 247static SDL_bool joypad_ports_enabled=SDL_FALSE; 248static int has_teamtap[2]={TEAMTAP_MAYBE,TEAMTAP_MAYBE}; 249 250/* Updated joypad ports */ 251static Uint16 jp_paddles[4]; 252static Uint16 jp_lightpens[2]; 253static Uint16 jp_directions; 254static Uint16 jp_fires; 255static Uint32 jp_joypads[8]; 256 257/*--- Functions prototypes ---*/ 258 259static int GetEnabledAtariJoystick(int index); 260static void UpdateJoypads(void); 261 262/*--- Functions ---*/ 263 264int SDL_SYS_JoystickInit(void) 265{ 266 int i; 267 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 375static 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 398const 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 409int 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 */ 449static 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 484void 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 733void SDL_SYS_JoystickClose(SDL_Joystick *joystick) 734{ 735 return; 736} 737 738void 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) 747struct 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 757static 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 768static 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 */ 827