SDL-1.2.14
[sdl_omap.git] / src / joystick / mint / SDL_sysjoystick.c
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 */