| /* |
| SDL - Simple DirectMedia Layer |
| Copyright (C) 1997-2012 Sam Lantinga |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| |
| Sam Lantinga |
| slouken@libsdl.org |
| */ |
| #include "SDL_config.h" |
| |
| #ifdef SDL_JOYSTICK_MINT |
| |
| /* |
| * Atari Joystick/Joypad drivers |
| * |
| * Patrice Mandin |
| */ |
| |
| #include <mint/cookie.h> |
| #include <mint/osbind.h> |
| |
| #include "SDL_events.h" |
| #include "../SDL_sysjoystick.h" |
| #include "../SDL_joystick_c.h" |
| |
| #include "../../video/ataricommon/SDL_ikbdinterrupt_s.h" |
| #include "../../video/ataricommon/SDL_xbiosevents_c.h" |
| #include "../../video/ataricommon/SDL_xbiosinterrupt_s.h" |
| |
| /*--- Const ---*/ |
| |
| /* We can have: |
| 1 joystick on IKBD port 1, read via hardware I/O |
| or same joystick on IKBD port 1, read via xbios |
| 1 joypad on port A (up to 4 with teamtap) |
| or 2 joysticks on joypad port A |
| or 1 analog paddle on joypad port A |
| or 1 lightpen on joypad port A |
| 1 joypad on port B (up to 4 with teamtap) |
| or 2 joysticks on joypad port B |
| or 1 analog paddle on joypad port B |
| 2 joysticks on parallel port |
| */ |
| |
| enum { |
| IKBD_JOY1=0, |
| XBIOS_JOY1, |
| PORTA_PAD0, |
| PORTA_PAD1, |
| PORTA_PAD2, |
| PORTA_PAD3, |
| PORTB_PAD0, |
| PORTB_PAD1, |
| PORTB_PAD2, |
| PORTB_PAD3, |
| PORTA_JOY0, |
| PORTA_JOY1, |
| PORTB_JOY0, |
| PORTB_JOY1, |
| PORTA_LP, |
| PORTA_ANPAD, |
| PORTB_ANPAD, |
| #if 0 |
| PARA_JOY0, |
| PARA_JOY1, |
| #endif |
| MAX_JOYSTICKS |
| }; |
| |
| enum { |
| MCH_ST=0, |
| MCH_STE, |
| MCH_TT, |
| MCH_F30, |
| MCH_CLONE, |
| MCH_ARANYM |
| }; |
| |
| /* Joypad buttons |
| * Procontroller note: |
| * L,R are connected to 4,6 |
| * X,Y,Z are connected to 7,8,9 |
| */ |
| |
| enum { |
| JP_UP=0, JP_DOWN, JP_LEFT, JP_RIGHT, |
| JP_KPMULT, JP_KP7, JP_KP4, JP_KP1, |
| JP_KP0, JP_KP8, JP_KP5, JP_KP2, |
| JP_KPNUM, JP_KP9, JP_KP6, JP_KP3, |
| JP_PAUSE, JP_FIRE0, JP_UNDEF0, JP_FIRE1, |
| JP_UNDEF1, JP_FIRE2, JP_UNDEF2, JP_OPTION |
| }; |
| |
| #define JP_NUM_BUTTONS 17 |
| |
| #define PORT_JS_RIGHT (1<<0) |
| #define PORT_JS_LEFT (1<<1) |
| #define PORT_JS_DOWN (1<<2) |
| #define PORT_JS_UP (1<<3) |
| #define PORT_JS_FIRE (1<<4) |
| |
| enum { |
| TEAMTAP_MAYBE=0, |
| TEAMTAP_YES, |
| TEAMTAP_NO |
| }; |
| |
| /* Teamtap detection values */ |
| static const Uint32 teamtap_ghosts[20][4]={ |
| {1<<JP_UP, /* for this event on joypad 0, port X */ |
| (1<<JP_UP)|(1<<JP_KP0), /* we get this on joypad 1 */ |
| (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KP0), /* this on joypad 2 */ |
| (1<<JP_KPMULT)|(1<<JP_KP0)}, /* this on joypad 3 */ |
| {1<<JP_DOWN, |
| (1<<JP_DOWN)|(1<<JP_KP8), |
| (1<<JP_DOWN)|(1<<JP_KP9)|(1<<JP_KP8), |
| (1<<JP_KP7)|(1<<JP_KP8)}, |
| {1<<JP_LEFT, |
| (1<<JP_LEFT)|(1<<JP_KP5), |
| (1<<JP_LEFT)|(1<<JP_KP6)|(1<<JP_KP5), |
| (1<<JP_KP4)|(1<<JP_KP5)}, |
| {1<<JP_RIGHT, |
| (1<<JP_RIGHT)|(1<<JP_KP2), |
| (1<<JP_RIGHT)|(1<<JP_KP3)|(1<<JP_KP2), |
| (1<<JP_KP1)|(1<<JP_KP2)}, |
| {1<<JP_OPTION, |
| (1<<JP_OPTION)|(1<<JP_FIRE1)|(1<<JP_FIRE2), |
| (1<<JP_FIRE0)|(1<<JP_FIRE1)|(1<<JP_FIRE2), |
| 0}, |
| {1<<JP_FIRE0, |
| (1<<JP_FIRE2)|(1<<JP_FIRE0), |
| (1<<JP_FIRE0)|(1<<JP_OPTION)|(1<<JP_FIRE2), |
| (1<<JP_FIRE1)|(1<<JP_FIRE2)}, |
| {1<<JP_FIRE1, |
| (1<<JP_FIRE0), |
| (1<<JP_OPTION)|(1<<JP_FIRE0)|(1<<JP_FIRE1), |
| (1<<JP_FIRE0)|(1<<JP_FIRE2)}, |
| {1<<JP_FIRE2, |
| (1<<JP_OPTION)|(1<<JP_FIRE0)|(1<<JP_FIRE1)|(1<<JP_FIRE2), |
| (1<<JP_OPTION), |
| (1<<JP_FIRE0)|(1<<JP_FIRE1)}, |
| {1<<JP_KP1, |
| (1<<JP_RIGHT)|(1<<JP_KP1), |
| (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP3), |
| (1<<JP_RIGHT)|(1<<JP_KP2)}, |
| {1<<JP_KP2, |
| (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2)|(1<<JP_KP3), |
| (1<<JP_KP3), |
| (1<<JP_RIGHT)|(1<<JP_KP1)}, |
| {1<<JP_KP3, |
| (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2)|(1<<JP_KP3), |
| (1<<JP_RIGHT)|(1<<JP_KP1)|(1<<JP_KP2), |
| 0}, |
| {1<<JP_KP4, |
| (1<<JP_LEFT)|(1<<JP_KP4), |
| (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP6), |
| (1<<JP_LEFT)|(1<<JP_KP5)}, |
| {1<<JP_KP5, |
| (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5)|(1<<JP_KP6), |
| (1<<JP_KP6), |
| (1<<JP_LEFT)|(1<<JP_KP4)}, |
| {1<<JP_KP6, |
| (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5)|(1<<JP_KP6), |
| (1<<JP_LEFT)|(1<<JP_KP4)|(1<<JP_KP5), |
| 0}, |
| {1<<JP_KP7, |
| (1<<JP_DOWN)|(1<<JP_KP7), |
| (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP9), |
| (1<<JP_DOWN)|(1<<JP_KP8)}, |
| {1<<JP_KP8, |
| (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8)|(1<<JP_KP9), |
| (1<<JP_KP9), |
| (1<<JP_DOWN)|(1<<JP_KP7)}, |
| {1<<JP_KP9, |
| (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8)|(1<<JP_KP9), |
| (1<<JP_DOWN)|(1<<JP_KP7)|(1<<JP_KP8), |
| 0}, |
| {1<<JP_KPMULT, |
| (1<<JP_UP)|(1<<JP_KPMULT), |
| (1<<JP_UP)|(1<<JP_KPNUM), |
| (1<<JP_UP)|(1<<JP_KP0)}, |
| {1<<JP_KP0, |
| (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KPMULT)|(1<<JP_KP0), |
| 1<<JP_KPNUM, |
| (1<<JP_UP)|(1<<JP_KPMULT)}, |
| {1<<JP_KPNUM, |
| (1<<JP_UP)|(1<<JP_KPNUM)|(1<<JP_KPMULT)|(1<<JP_KP0), |
| (1<<JP_UP)|(1<<JP_KPMULT)|(1<<JP_KP0), |
| 0}, |
| }; |
| |
| /*--- Types ---*/ |
| |
| typedef struct { |
| SDL_bool enabled; |
| char *name; |
| Uint32 prevstate; |
| } atarijoy_t; |
| |
| /*--- Variables ---*/ |
| |
| static atarijoy_t atarijoysticks[MAX_JOYSTICKS]={ |
| {SDL_FALSE,"IKBD joystick port 1",0}, |
| {SDL_FALSE,"Xbios joystick port 1",0}, |
| {SDL_FALSE,"Joypad 0 port A",0}, |
| {SDL_FALSE,"Joypad 1 port A",0}, |
| {SDL_FALSE,"Joypad 2 port A",0}, |
| {SDL_FALSE,"Joypad 3 port A",0}, |
| {SDL_FALSE,"Joypad 0 port B",0}, |
| {SDL_FALSE,"Joypad 1 port B",0}, |
| {SDL_FALSE,"Joypad 2 port B",0}, |
| {SDL_FALSE,"Joypad 3 port B",0}, |
| {SDL_FALSE,"Joystick 0 port A",0}, |
| {SDL_FALSE,"Joystick 1 port A",0}, |
| {SDL_FALSE,"Joystick 0 port B",0}, |
| {SDL_FALSE,"Joystick 1 port B",0}, |
| {SDL_FALSE,"Lightpen port A",0}, |
| {SDL_FALSE,"Analog paddle port A",0}, |
| {SDL_FALSE,"Analog paddle port B",0} |
| #if 0 |
| ,{SDL_FALSE,"Joystick 0 parallel port",0}, |
| {SDL_FALSE,"Joystick 1 parallel port",0} |
| #endif |
| }; |
| |
| static const int jp_buttons[JP_NUM_BUTTONS]={ |
| JP_FIRE0, JP_FIRE1, JP_FIRE2, JP_PAUSE, |
| JP_OPTION, JP_KPMULT, JP_KPNUM, JP_KP0, |
| JP_KP1, JP_KP2, JP_KP3, JP_KP4, |
| JP_KP5, JP_KP6, JP_KP7, JP_KP8, |
| JP_KP9 |
| }; |
| |
| static SDL_bool joypad_ports_enabled=SDL_FALSE; |
| static int has_teamtap[2]={TEAMTAP_MAYBE,TEAMTAP_MAYBE}; |
| |
| /* Updated joypad ports */ |
| static Uint16 jp_paddles[4]; |
| static Uint16 jp_lightpens[2]; |
| static Uint16 jp_directions; |
| static Uint16 jp_fires; |
| static Uint32 jp_joypads[8]; |
| |
| /*--- Functions prototypes ---*/ |
| |
| static int GetEnabledAtariJoystick(int index); |
| static void UpdateJoypads(void); |
| |
| /*--- Functions ---*/ |
| |
| int SDL_SYS_JoystickInit(void) |
| { |
| int i; |
| long cookie_mch; |
| const char *envr=SDL_getenv("SDL_JOYSTICK_ATARI"); |
| |
| #define TEST_JOY_ENABLED(env,idstring,num) \ |
| if (SDL_strstr(env,idstring"-off")) { \ |
| atarijoysticks[num].enabled=SDL_FALSE; \ |
| } \ |
| if (SDL_strstr(env,idstring"-on")) { \ |
| atarijoysticks[num].enabled=SDL_TRUE; \ |
| } |
| |
| /* Cookie _MCH present ? if not, assume ST machine */ |
| if (Getcookie(C__MCH, &cookie_mch) != C_FOUND) { |
| cookie_mch = MCH_ST << 16; |
| } |
| |
| /* Enable some default joysticks */ |
| if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) || |
| (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16) || |
| (cookie_mch == MCH_ARANYM<<16)) |
| { |
| atarijoysticks[IKBD_JOY1].enabled=(SDL_AtariIkbd_enabled!=0); |
| } |
| if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16) || |
| (cookie_mch == MCH_ARANYM<<16)) |
| { |
| atarijoysticks[PORTA_PAD0].enabled = |
| atarijoysticks[PORTA_PAD1].enabled = |
| atarijoysticks[PORTA_PAD2].enabled = |
| atarijoysticks[PORTA_PAD3].enabled = |
| atarijoysticks[PORTB_PAD0].enabled = |
| atarijoysticks[PORTB_PAD1].enabled = |
| atarijoysticks[PORTB_PAD2].enabled = |
| atarijoysticks[PORTB_PAD3].enabled = SDL_TRUE; |
| } |
| if (!atarijoysticks[IKBD_JOY1].enabled) { |
| atarijoysticks[XBIOS_JOY1].enabled=(SDL_AtariXbios_enabled!=0); |
| } |
| |
| /* Read environment for joysticks to enable */ |
| if (envr) { |
| /* IKBD on any Atari, maybe clones */ |
| if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) || |
| (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16) || |
| (cookie_mch == MCH_ARANYM<<16)) { |
| if (SDL_AtariIkbd_enabled!=0) { |
| TEST_JOY_ENABLED(envr, "ikbd-joy1", IKBD_JOY1); |
| } |
| } |
| /* Joypads ports on STE, Falcon and maybe others */ |
| if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16) || |
| (cookie_mch == MCH_ARANYM<<16)) { |
| TEST_JOY_ENABLED(envr, "porta-pad", PORTA_PAD0); |
| if (!atarijoysticks[PORTA_PAD0].enabled) { |
| TEST_JOY_ENABLED(envr, "porta-joy0", PORTA_JOY0); |
| TEST_JOY_ENABLED(envr, "porta-joy1", PORTA_JOY1); |
| if (!(atarijoysticks[PORTA_JOY0].enabled) && !(atarijoysticks[PORTA_JOY1].enabled)) { |
| TEST_JOY_ENABLED(envr, "porta-lp", PORTA_LP); |
| if (!atarijoysticks[PORTA_LP].enabled) { |
| TEST_JOY_ENABLED(envr, "porta-anpad", PORTA_ANPAD); |
| } |
| } |
| } |
| |
| TEST_JOY_ENABLED(envr, "portb-pad", PORTB_PAD0); |
| if (!atarijoysticks[PORTB_PAD0].enabled) { |
| TEST_JOY_ENABLED(envr, "portb-joy0", PORTB_JOY0); |
| TEST_JOY_ENABLED(envr, "portb-joy1", PORTB_JOY1); |
| if (!(atarijoysticks[PORTB_JOY0].enabled) && !(atarijoysticks[PORTB_JOY1].enabled)) { |
| TEST_JOY_ENABLED(envr, "portb-anpad", PORTB_ANPAD); |
| } |
| } |
| } |
| |
| if (!atarijoysticks[IKBD_JOY1].enabled) { |
| if (SDL_AtariXbios_enabled!=0) { |
| TEST_JOY_ENABLED(envr, "xbios-joy1", XBIOS_JOY1); |
| } |
| } |
| #if 0 |
| /* Parallel port on any Atari, maybe clones */ |
| if ((cookie_mch == MCH_ST<<16) || ((cookie_mch>>16) == MCH_STE) || |
| (cookie_mch == MCH_TT<<16) || (cookie_mch == MCH_F30<<16)) { |
| TEST_JOY_ENABLED(envr, "para-joy0", PARA_JOY0); |
| TEST_JOY_ENABLED(envr, "para-joy1", PARA_JOY1); |
| } |
| #endif |
| } |
| |
| /* Need to update joypad ports ? */ |
| joypad_ports_enabled=SDL_FALSE; |
| for (i=PORTA_PAD0;i<=PORTB_ANPAD;i++) { |
| if (atarijoysticks[i].enabled) { |
| joypad_ports_enabled=SDL_TRUE; |
| break; |
| } |
| } |
| |
| SDL_numjoysticks = 0; |
| for (i=0;i<MAX_JOYSTICKS;i++) { |
| if (atarijoysticks[i].enabled) { |
| ++SDL_numjoysticks; |
| } |
| } |
| |
| return(SDL_numjoysticks); |
| } |
| |
| static int GetEnabledAtariJoystick(int index) |
| { |
| int i,j; |
| |
| /* Return the nth'index' enabled atari joystick */ |
| j=0; |
| for (i=0;i<MAX_JOYSTICKS;i++) { |
| if (!atarijoysticks[i].enabled) { |
| continue; |
| } |
| |
| if (j==index) { |
| break; |
| } |
| |
| ++j; |
| } |
| if (i==MAX_JOYSTICKS) |
| return -1; |
| |
| return i; |
| } |
| |
| const char *SDL_SYS_JoystickName(int index) |
| { |
| int numjoystick; |
| |
| numjoystick=GetEnabledAtariJoystick(index); |
| if (numjoystick==-1) |
| return NULL; |
| |
| return(atarijoysticks[numjoystick].name); |
| } |
| |
| int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) |
| { |
| int numjoystick; |
| |
| numjoystick=GetEnabledAtariJoystick(joystick->index); |
| if (numjoystick==-1) |
| return -1; |
| |
| joystick->naxes=0; |
| joystick->nhats=0; |
| joystick->nballs=0; |
| |
| switch(numjoystick) { |
| case PORTA_PAD0: |
| case PORTA_PAD1: |
| case PORTA_PAD2: |
| case PORTA_PAD3: |
| case PORTB_PAD0: |
| case PORTB_PAD1: |
| case PORTB_PAD2: |
| case PORTB_PAD3: |
| joystick->nhats=1; |
| joystick->nbuttons=JP_NUM_BUTTONS; |
| break; |
| case PORTA_LP: |
| case PORTA_ANPAD: |
| case PORTB_ANPAD: |
| joystick->naxes=2; |
| joystick->nbuttons=2; |
| break; |
| default: |
| joystick->nhats=1; |
| joystick->nbuttons=1; |
| break; |
| } |
| |
| return(0); |
| } |
| |
| /* Detect Teamtap using ghost events */ |
| static void detect_teamtap(int num_port) |
| { |
| int i,j; |
| |
| /* Check if joypad 1,2,3 triggered but not 0 */ |
| for (i=1; i<4; i++) { |
| if (jp_joypads[num_port*4+i] && (jp_joypads[num_port*4]==0)) { |
| has_teamtap[num_port] = TEAMTAP_YES; |
| return; |
| } |
| } |
| |
| /* Check if joypad 0 on a given port triggered ghost events for |
| * other joypads |
| */ |
| for (i=0; i<20; i++) { |
| int with_teamtap=1; |
| |
| if (jp_joypads[num_port*4]!=teamtap_ghosts[i][0]) |
| continue; |
| |
| /* If any button on first joypad pressed, check other pads */ |
| for (j=1; j<4; j++) { |
| if ((jp_joypads[num_port*4+j] & teamtap_ghosts[i][j]) |
| ==teamtap_ghosts[i][j]) |
| { |
| with_teamtap = 0; |
| } |
| } |
| |
| has_teamtap[num_port] = (with_teamtap ? TEAMTAP_YES : TEAMTAP_NO); |
| break; |
| } |
| } |
| |
| void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) |
| { |
| int numjoystick; |
| Uint8 hatstate; |
| Uint32 curstate,prevstate; |
| |
| numjoystick=GetEnabledAtariJoystick(joystick->index); |
| if (numjoystick==-1) |
| return; |
| |
| prevstate = atarijoysticks[numjoystick].prevstate; |
| |
| if (joypad_ports_enabled) { |
| Supexec(UpdateJoypads); |
| } |
| |
| switch (numjoystick) { |
| case IKBD_JOY1: |
| case XBIOS_JOY1: |
| { |
| curstate = 0; |
| |
| if (numjoystick==IKBD_JOY1) { |
| curstate = SDL_AtariIkbd_joystick & 0xff; |
| } |
| if (numjoystick==XBIOS_JOY1) { |
| curstate = SDL_AtariXbios_joystick & 0xff; |
| } |
| |
| if (curstate != prevstate) { |
| hatstate = SDL_HAT_CENTERED; |
| if (curstate & IKBD_JOY_LEFT) { |
| hatstate |= SDL_HAT_LEFT; |
| } |
| if (curstate & IKBD_JOY_RIGHT) { |
| hatstate |= SDL_HAT_RIGHT; |
| } |
| if (curstate & IKBD_JOY_UP) { |
| hatstate |= SDL_HAT_UP; |
| } |
| if (curstate & IKBD_JOY_DOWN) { |
| hatstate |= SDL_HAT_DOWN; |
| } |
| SDL_PrivateJoystickHat(joystick, 0, hatstate); |
| |
| /* Button */ |
| if ((curstate & IKBD_JOY_FIRE) && !(prevstate & IKBD_JOY_FIRE)) { |
| SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED); |
| } |
| if (!(curstate & IKBD_JOY_FIRE) && (prevstate & IKBD_JOY_FIRE)) { |
| SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED); |
| } |
| } |
| atarijoysticks[numjoystick].prevstate = curstate; |
| } |
| break; |
| case PORTA_PAD0: |
| case PORTA_PAD1: |
| case PORTA_PAD2: |
| case PORTA_PAD3: |
| case PORTB_PAD0: |
| case PORTB_PAD1: |
| case PORTB_PAD2: |
| case PORTB_PAD3: |
| { |
| int numjoypad,i,numport; |
| |
| numjoypad = numport = 0; |
| switch(numjoystick) { |
| case PORTA_PAD0: |
| numjoypad = 0; break; |
| case PORTA_PAD1: |
| numjoypad = 1; break; |
| case PORTA_PAD2: |
| numjoypad = 2; break; |
| case PORTA_PAD3: |
| numjoypad = 3; break; |
| case PORTB_PAD0: |
| numjoypad = 4; numport = 1; break; |
| case PORTB_PAD1: |
| numjoypad = 5; numport = 1; break; |
| case PORTB_PAD2: |
| numjoypad = 6; numport = 1; break; |
| case PORTB_PAD3: |
| numjoypad = 7; numport = 1; break; |
| } |
| |
| jp_joypads[numjoypad] &= 0xabffff; |
| |
| if (has_teamtap[numport]==TEAMTAP_MAYBE) { |
| detect_teamtap(numport); |
| } |
| /* No events for PORTX_PAD[1,2,3] if no teamtap detected */ |
| if (has_teamtap[numport] == TEAMTAP_NO) { |
| if ((numjoypad & 3)!=0) { |
| return; |
| } |
| } |
| |
| curstate=jp_joypads[numjoypad]; |
| if (curstate!=prevstate) { |
| hatstate = SDL_HAT_CENTERED; |
| if (curstate & (1<<JP_LEFT)) { |
| hatstate |= SDL_HAT_LEFT; |
| } |
| if (curstate & (1<<JP_RIGHT)) { |
| hatstate |= SDL_HAT_RIGHT; |
| } |
| if (curstate & (1<<JP_UP)) { |
| hatstate |= SDL_HAT_UP; |
| } |
| if (curstate & (1<<JP_DOWN)) { |
| hatstate |= SDL_HAT_DOWN; |
| } |
| SDL_PrivateJoystickHat(joystick, 0, hatstate); |
| |
| /* Buttons */ |
| for (i=0;i<JP_NUM_BUTTONS;i++) { |
| int button; |
| |
| button=1<<jp_buttons[i]; |
| |
| if ((curstate & button) && !(prevstate & button)) { |
| SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); |
| } |
| if (!(curstate & button) && (prevstate & button)) { |
| SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); |
| } |
| } |
| } |
| atarijoysticks[numjoystick].prevstate = curstate; |
| } |
| break; |
| case PORTA_JOY0: |
| case PORTA_JOY1: |
| case PORTB_JOY0: |
| case PORTB_JOY1: |
| { |
| int fire_shift=0,dir_shift=0; |
| |
| if (numjoystick==PORTA_JOY0) { fire_shift=0; dir_shift=0; } |
| if (numjoystick==PORTA_JOY1) { fire_shift=1; dir_shift=4; } |
| if (numjoystick==PORTB_JOY0) { fire_shift=2; dir_shift=8; } |
| if (numjoystick==PORTB_JOY1) { fire_shift=3; dir_shift=12; } |
| |
| curstate = (jp_directions>>dir_shift) & 15; |
| curstate |= ((jp_fires>>fire_shift) & 1)<<4; |
| |
| if (curstate != prevstate) { |
| hatstate = SDL_HAT_CENTERED; |
| if (curstate & PORT_JS_LEFT) { |
| hatstate |= SDL_HAT_LEFT; |
| } |
| if (curstate & PORT_JS_RIGHT) { |
| hatstate |= SDL_HAT_RIGHT; |
| } |
| if (curstate & PORT_JS_UP) { |
| hatstate |= SDL_HAT_UP; |
| } |
| if (curstate & PORT_JS_DOWN) { |
| hatstate |= SDL_HAT_DOWN; |
| } |
| SDL_PrivateJoystickHat(joystick, 0, hatstate); |
| |
| /* Button */ |
| if ((curstate & PORT_JS_FIRE) && !(prevstate & PORT_JS_FIRE)) { |
| SDL_PrivateJoystickButton(joystick,0,SDL_PRESSED); |
| } |
| if (!(curstate & PORT_JS_FIRE) && (prevstate & PORT_JS_FIRE)) { |
| SDL_PrivateJoystickButton(joystick,0,SDL_RELEASED); |
| } |
| } |
| atarijoysticks[numjoystick].prevstate = curstate; |
| } |
| break; |
| case PORTA_LP: |
| { |
| int i; |
| |
| curstate = jp_lightpens[0]>>1; |
| curstate |= (jp_lightpens[1]>>1)<<15; |
| curstate |= (jp_fires & 3)<<30; |
| |
| if (curstate != prevstate) { |
| /* X axis */ |
| SDL_PrivateJoystickAxis(joystick,0,jp_lightpens[0] ^ 0x8000); |
| /* Y axis */ |
| SDL_PrivateJoystickAxis(joystick,1,jp_lightpens[1] ^ 0x8000); |
| /* Buttons */ |
| for (i=0;i<2;i++) { |
| int button; |
| |
| button=1<<(30+i); |
| |
| if ((curstate & button) && !(prevstate & button)) { |
| SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); |
| } |
| if (!(curstate & button) && (prevstate & button)) { |
| SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); |
| } |
| } |
| } |
| atarijoysticks[numjoystick].prevstate = curstate; |
| } |
| break; |
| case PORTA_ANPAD: |
| case PORTB_ANPAD: |
| { |
| int numpaddle, i; |
| |
| numpaddle=0<<1; |
| if (numjoystick==PORTB_ANPAD) numpaddle=1<<1; |
| |
| curstate = jp_paddles[numpaddle]>>1; |
| curstate |= (jp_paddles[numpaddle+1]>>1)<<15; |
| curstate |= ((jp_fires>>numpaddle) & 3)<<30; |
| |
| if (curstate != prevstate) { |
| /* X axis */ |
| SDL_PrivateJoystickAxis(joystick,0,jp_paddles[numpaddle] ^ 0x8000); |
| /* Y axis */ |
| SDL_PrivateJoystickAxis(joystick,1,jp_paddles[numpaddle+1] ^ 0x8000); |
| /* Buttons */ |
| for (i=0;i<2;i++) { |
| int button; |
| |
| button=1<<(30+i); |
| |
| if ((curstate & button) && !(prevstate & button)) { |
| SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); |
| } |
| if (!(curstate & button) && (prevstate & button)) { |
| SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); |
| } |
| } |
| } |
| atarijoysticks[numjoystick].prevstate = curstate; |
| } |
| break; |
| #if 0 |
| case PARA_JOY0: |
| case PARA_JOY1: |
| break; |
| #endif |
| }; |
| |
| return; |
| } |
| |
| void SDL_SYS_JoystickClose(SDL_Joystick *joystick) |
| { |
| return; |
| } |
| |
| void SDL_SYS_JoystickQuit(void) |
| { |
| SDL_numjoysticks=0; |
| return; |
| } |
| |
| /*--- Joypad I/O read/write interface ---*/ |
| |
| #define JOYPAD_IO_BASE (0xffff9200) |
| struct JOYPAD_IO_S { |
| Uint16 fires; |
| Uint16 directions; |
| Uint16 dummy1[6]; |
| Uint16 paddles[4]; |
| Uint16 dummy2[4]; |
| Uint16 lightpens[2]; |
| }; |
| #define JOYPAD_IO ((*(volatile struct JOYPAD_IO_S *)JOYPAD_IO_BASE)) |
| |
| static const Uint16 joypad_masks[8*4]={ |
| 0xfffe, 0xfffd, 0xfffb, 0xfff7, |
| 0xfff0, 0xfff1, 0xfff2, 0xfff3, |
| 0xfff4, 0xfff5, 0xfff6, 0xfff8, |
| 0xfff9, 0xfffa, 0xfffc, 0xffff, |
| 0xffef, 0xffdf, 0xffbf, 0xff7f, |
| 0xff0f, 0xff1f, 0xff2f, 0xff3f, |
| 0xff4f, 0xff5f, 0xff6f, 0xff8f, |
| 0xff9f, 0xffaf, 0xffcf, 0xffff |
| }; |
| |
| static void UpdateJoypads(void) |
| { |
| Uint16 tmp, i, j; |
| Uint32 cur_fire, cur_dir; |
| |
| /*--- This function is called in supervisor mode ---*/ |
| |
| /* Update joysticks */ |
| jp_fires = (~(JOYPAD_IO.fires)) & 15; |
| jp_directions = (~(JOYPAD_IO.directions)); |
| |
| /* Update lightpen */ |
| tmp = JOYPAD_IO.lightpens[0] & 1023; |
| jp_lightpens[0] = (tmp<<6) | (tmp>>4); |
| tmp = JOYPAD_IO.lightpens[1] & 1023; |
| jp_lightpens[1] = (tmp<<6) | (tmp>>4); |
| |
| /* Update paddles */ |
| tmp = (JOYPAD_IO.paddles[0] & 255); |
| jp_paddles[0] = (tmp<<8) | tmp; |
| tmp = (JOYPAD_IO.paddles[1] & 255); |
| jp_paddles[1] = (tmp<<8) | tmp; |
| tmp = (JOYPAD_IO.paddles[2] & 255); |
| jp_paddles[2] = (tmp<<8) | tmp; |
| tmp = (JOYPAD_IO.paddles[3] & 255); |
| jp_paddles[3] = (tmp<<8) | tmp; |
| |
| /* Update joypads on teamtap port A */ |
| for (i=0; i<4; i++) { |
| jp_joypads[i] = 0; |
| for (j=0; j<4; j++) { |
| JOYPAD_IO.directions = joypad_masks[(i*4)+j]; |
| |
| cur_fire = (~(JOYPAD_IO.fires) & 3)<<16; |
| cur_dir = (~(JOYPAD_IO.directions)>>8) & 15; |
| |
| jp_joypads[i] |= cur_fire<<(j*2); |
| jp_joypads[i] |= cur_dir<<(j*4); |
| } |
| } |
| |
| /* Update joypads on teamtap port B */ |
| for (i=4; i<8; i++) { |
| jp_joypads[i] = 0; |
| for (j=0; j<4; j++) { |
| JOYPAD_IO.directions = joypad_masks[(i*4)+j]; |
| |
| cur_fire = (~(JOYPAD_IO.fires) & 0xc)<<14; |
| cur_dir = (~(JOYPAD_IO.directions)>>12) & 15; |
| |
| jp_joypads[i] |= cur_fire<<(j*2); |
| jp_joypads[i] |= cur_dir<<(j*4); |
| } |
| } |
| |
| JOYPAD_IO.directions=0xffff; |
| } |
| |
| #endif /* SDL_JOYSTICK_MINT */ |