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