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