Home | History | Annotate | Download | only in mint
      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 (at) 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 	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 	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 */
    827