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 | |
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 */ |