From 3669a810c93cb945fb4794bc166e76f64f136ce8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 7 Mar 2002 20:23:11 +0000 Subject: [PATCH] Added Atari joystick support (thanks Patrice!) --- README.MiNT | 44 +- configure.in | 6 +- src/joystick/Makefile.am | 2 +- src/joystick/mint/.cvsignore | 6 + src/joystick/mint/Makefile.am | 8 + src/joystick/mint/SDL_sysjoystick.c | 625 ++++++++++++++++++++++++++++ 6 files changed, 681 insertions(+), 10 deletions(-) create mode 100644 src/joystick/mint/.cvsignore create mode 100644 src/joystick/mint/Makefile.am create mode 100644 src/joystick/mint/SDL_sysjoystick.c diff --git a/README.MiNT b/README.MiNT index 410d84110..2d97559c4 100644 --- a/README.MiNT +++ b/README.MiNT @@ -49,19 +49,19 @@ Keyboard (GEMDOS, BIOS, Ikbd) Mouse (XBIOS, GEM, Ikbd) Video (XBIOS (Fullscreen), GEM (Windowed and Fullscreen)) Timer (VBL vector) +Joystick and joypad support (Ikbd, Hardware) - What is missing: Audio support (TOS) CDROM support (Metados, /dev/cdrom) -Joystick and joypad support (Hardware) Threads support (TOS) - Driver combinations: -Video Kbd Mouse Timer -xbios ikbd ikbd vbl -xbios gemdos xbios vbl -xbios bios xbios vbl -gem gem gem vbl +Video Kbd Mouse Timer Jstick Joypads +xbios ikbd ikbd vbl ikbd hardware +xbios gemdos xbios vbl - hardware +xbios bios xbios vbl - hardware +gem gem gem vbl - hardware ============================================================================== V. Environment variables: @@ -75,6 +75,38 @@ SDL_VIDEODRIVER: Set to 'xbios' to force xbios video driver Set to 'gem' to force gem video driver +SDL_JOYSTICK_ATARI: + Use any of these strings in the environment variable to enable or + disable a joystick: + + 'ikbd-joy1-[on|off]' for IKBD joystick on port 1 + 'porta-pad-[on|off]' for joypad on port A + 'porta-joy0-[on|off]' for joystick 0 on port A + 'porta-joy1-[on|off]' for joystick 1 on port A + 'porta-lp-[on|off]' for lightpen on port A + 'porta-anpad-[on|off]' for analog paddle on port A + 'portb-pad-[on|off]' for joypad on port B + 'portb-joy0-[on|off]' for joystick 0 on port B + 'portb-joy1-[on|off]' for joystick 1 on port B + 'portb-anpad-[on|off]' for analog paddle on port B + + Default configuration is: + 'ikbd-joy1-on' (if IKBD events driver enabled) + 'porta-pad-on portb-pad-on' (if available on the machine) + + port[a|b]-[pad|joy?|lp|anpad]-* strings are mutually exclusives. + On such a port, you can only use a joypad OR 1 or 2 joysticks OR + a lightpen OR an analog paddle. You must disable joypad before + setting another controller. + + IKBD joystick only available when the IKBD events driver is enabled. + The second joystick port on IKBD is used by the mouse, so not usable. + + Joypads are multibuttons controller (Atari Jaguar console-like). + Joysticks are 1 button, 2 axis controllers. + Lightpen and analog paddle are 2 buttons, 2 axis controllers. The 2 + buttons are those affected to 1 button joysticks on the same port. + -- Patrice Mandin http://www.multimania.com/pmandin diff --git a/configure.in b/configure.in index b0332d04e..a572ae7f4 100644 --- a/configure.in +++ b/configure.in @@ -2281,10 +2281,9 @@ case "$target" in AUDIO_DRIVERS="$AUDIO_DRIVERS sun/libaudio_sun.la" fi # Set up files for the joystick library - # (No joystick support yet) if test x$enable_joystick = xyes; then - JOYSTICK_SUBDIRS="$JOYSTICK_SUBDIRS dummy" - JOYSTICK_DRIVERS="$JOYSTICK_DRIVERS dummy/libjoystick_dummy.la" + JOYSTICK_SUBDIRS="$JOYSTICK_SUBDIRS mint" + JOYSTICK_DRIVERS="$JOYSTICK_DRIVERS mint/libjoystick_mint.la" fi # Set up files for the cdrom library if test x$enable_cdrom = xyes; then @@ -2489,6 +2488,7 @@ src/joystick/darwin/Makefile src/joystick/dummy/Makefile src/joystick/linux/Makefile src/joystick/macos/Makefile +src/joystick/mint/Makefile src/joystick/win32/Makefile src/cdrom/Makefile src/cdrom/aix/Makefile diff --git a/src/joystick/Makefile.am b/src/joystick/Makefile.am index 6c5310e13..b88f107d8 100644 --- a/src/joystick/Makefile.am +++ b/src/joystick/Makefile.am @@ -5,7 +5,7 @@ noinst_LTLIBRARIES = libjoystick.la # Define which subdirectories need to be built SUBDIRS = @JOYSTICK_SUBDIRS@ -DIST_SUBDIRS = dummy amigaos beos bsd darwin linux macos win32 +DIST_SUBDIRS = dummy amigaos beos bsd darwin linux macos mint win32 DRIVERS = @JOYSTICK_DRIVERS@ diff --git a/src/joystick/mint/.cvsignore b/src/joystick/mint/.cvsignore new file mode 100644 index 000000000..899d53557 --- /dev/null +++ b/src/joystick/mint/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la diff --git a/src/joystick/mint/Makefile.am b/src/joystick/mint/Makefile.am new file mode 100644 index 000000000..9f17a7eea --- /dev/null +++ b/src/joystick/mint/Makefile.am @@ -0,0 +1,8 @@ + +## Makefile.am for the MiNT joystick driver for SDL + +noinst_LTLIBRARIES = libjoystick_mint.la +libjoystick_mint_la_SOURCES = $(SRCS) + +# The SDL joystick driver sources +SRCS = SDL_sysjoystick.c diff --git a/src/joystick/mint/SDL_sysjoystick.c b/src/joystick/mint/SDL_sysjoystick.c new file mode 100644 index 000000000..4d20f7b02 --- /dev/null +++ b/src/joystick/mint/SDL_sysjoystick.c @@ -0,0 +1,625 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* + * Atari Joystick/Joypad drivers + * + * Patrice Mandin + */ + +#include +#include + +#include +#include + +#include "SDL_types.h" +#include "SDL_error.h" +#include "SDL_joystick.h" +#include "SDL_sysjoystick.h" +#include "SDL_joystick_c.h" + +#include "../video/ataricommon/SDL_ikbdinterrupt_s.h" + +/*--- Const ---*/ + +/* We can have: + 1 joystick on IKBD port 1 (port 0 is used by mouse) + 2 joypads on ports A,B + or 4 joysticks on joypads ports A,B + or 1 lightpen on joypad port A + or 2 analog paddles on joypads ports A,B + 2 joysticks on parallel port +*/ + +enum { + IKBD_JOY1=0, + PORTA_PAD, + PORTB_PAD, + 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 +}; + +/* 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) + +/*--- Types ---*/ + +typedef struct { + SDL_bool enabled; + unsigned char *name; + Uint32 prevstate; +} atarijoy_t; + +/*--- Variables ---*/ + +static atarijoy_t atarijoysticks[MAX_JOYSTICKS]={ + {SDL_FALSE,"IKBD joystick port 1",0}, + {SDL_FALSE,"Joypad port A",0}, + {SDL_FALSE,"Joypad 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_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_FIRE1, JP_FIRE2, + JP_OPTION +}; + +static SDL_bool joypad_ports_enabled=SDL_FALSE; + +/* 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[2]; + +/*--- Functions prototypes ---*/ + +static int GetEnabledAtariJoystick(int index); +static void UpdateJoypads(void); + +/*--- Functions ---*/ + +int SDL_SYS_JoystickInit(void) +{ + int i; + unsigned long cookie_mch; + const char *envr=getenv("SDL_JOYSTICK_ATARI"); + const char *env_evt=getenv("SDL_ATARI_EVENTSDRIVER"); + SDL_bool ikbd_enabled=SDL_FALSE; + +#define TEST_JOY_ENABLED(env,idstring,num) \ + if (strstr(env,idstring"-off")) { \ + atarijoysticks[num].enabled=SDL_FALSE; \ + } \ + if (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)) { + ikbd_enabled=SDL_TRUE; + if (env_evt) { + if (!strcmp(env_evt,"ikbd")) { + ikbd_enabled=SDL_FALSE; + } + } + atarijoysticks[IKBD_JOY1].enabled=ikbd_enabled; + } + if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16)) { + atarijoysticks[PORTA_PAD].enabled=SDL_TRUE; + atarijoysticks[PORTB_PAD].enabled=SDL_TRUE; + } + + /* 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)) { + if (env_evt) { + if (strcmp(env_evt,"ikbd")) { + TEST_JOY_ENABLED(envr, "ikbd-joy1", IKBD_JOY1); + } + } + } + /* Joypads ports only on STE and Falcon */ + if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<16)) { + TEST_JOY_ENABLED(envr, "porta-pad", PORTA_PAD); + if (!atarijoysticks[PORTA_PAD].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_PAD); + if (!atarijoysticks[PORTB_PAD].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 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_PAD;i<=PORTB_ANPAD;i++) { + if (atarijoysticks[i].enabled) { + joypad_ports_enabled=SDL_TRUE; + break; + } + } + + SDL_numjoysticks = 0; + for (i=0;iindex); + if (numjoystick==-1) + return -1; + + if ((numjoystick==PORTA_PAD) || (numjoystick==PORTB_PAD)) { + joystick->nbuttons=JP_NUM_BUTTONS; + } else if ((numjoystick==PORTA_LP) || (numjoystick==PORTA_ANPAD) || + (numjoystick==PORTB_ANPAD)) { + joystick->nbuttons=2; + } else { + joystick->nbuttons=1; + } + joystick->naxes=2; + joystick->nballs=0; + joystick->nhats=0; + + return(0); +} + +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + int numjoystick; + Uint32 curstate,prevstate; + Sint16 curaxis; + + numjoystick=GetEnabledAtariJoystick(joystick->index); + if (numjoystick==-1) + return; + + prevstate = atarijoysticks[numjoystick].prevstate; + + if (joypad_ports_enabled) { + Supexec(UpdateJoypads); + } + + switch (numjoystick) { + case IKBD_JOY1: + { + curstate = SDL_AtariIkbd_joystick & 0xff; + if (curstate != prevstate) { + /* X axis */ + if ((curstate & (IKBD_JOY_LEFT|IKBD_JOY_RIGHT)) != (prevstate & (IKBD_JOY_LEFT|IKBD_JOY_RIGHT))) { + curaxis=0; + if (curstate & IKBD_JOY_LEFT) { + curaxis=-128; + } else if (curstate & IKBD_JOY_RIGHT) { + curaxis=127; + } + SDL_PrivateJoystickAxis(joystick,0,curaxis); + } + /* Y axis */ + if ((curstate & (IKBD_JOY_UP|IKBD_JOY_DOWN)) != (prevstate & (IKBD_JOY_UP|IKBD_JOY_DOWN))) { + curaxis=0; + if (curstate & IKBD_JOY_UP) { + curaxis=-128; + } else if (curstate & IKBD_JOY_DOWN) { + curaxis=127; + } + SDL_PrivateJoystickAxis(joystick,1,curaxis); + } + /* 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[IKBD_JOY1].prevstate = curstate; + } + break; + case PORTA_PAD: + case PORTB_PAD: + { + int numjoypad,i; + + numjoypad=0; +/* if (numjoystick==PORTA_PAD) numjoypad=0;*/ + if (numjoystick==PORTB_PAD) numjoypad=1; + + curstate=jp_joypads[numjoypad]; + if (curstate!=prevstate) { + /* X axis */ + if ((curstate & ((1<>dir_shift) & 15; + curstate |= ((jp_fires>>fire_shift) & 1)<<4; + + if (curstate != prevstate) { + /* X axis */ + if ((curstate & (PORT_JS_LEFT|PORT_JS_RIGHT)) != (prevstate & (PORT_JS_LEFT|PORT_JS_RIGHT))) { + curaxis=0; + if (curstate & PORT_JS_LEFT) { + curaxis=-128; + } else if (curstate & PORT_JS_RIGHT) { + curaxis=127; + } + SDL_PrivateJoystickAxis(joystick,0,curaxis); + } + /* Y axis */ + if ((curstate & (PORT_JS_UP|PORT_JS_DOWN)) != (prevstate & (PORT_JS_UP|PORT_JS_DOWN))) { + curaxis=0; + if (curstate & PORT_JS_UP) { + curaxis=-128; + } else if (curstate & PORT_JS_DOWN) { + curaxis=127; + } + SDL_PrivateJoystickAxis(joystick,1,curaxis); + } + /* 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]>>8)-128); + /* Y axis */ + SDL_PrivateJoystickAxis(joystick,1,(jp_lightpens[1]>>8)-128); + /* 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]>>8)-128); + /* Y axis */ + SDL_PrivateJoystickAxis(joystick,1,(jp_paddles[numpaddle+1]>>8)-128); + /* 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 void UpdateJoypads(void) +{ + Uint16 tmp; + + /*--- 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 joypad 0 */ + JOYPAD_IO.directions=0xfffe; + jp_joypads[0]=((~(JOYPAD_IO.fires)) & 3)<<(16); + JOYPAD_IO.directions=0xfffe; + jp_joypads[0] |= ((~(JOYPAD_IO.directions))>>8) & 15; + + JOYPAD_IO.directions=0xfffd; + jp_joypads[0] |= ((~(JOYPAD_IO.fires)) & 3)<<(16+2); + JOYPAD_IO.directions=0xfffd; + jp_joypads[0] |= (((~(JOYPAD_IO.directions))>>8) & 15)<<4; + + JOYPAD_IO.directions=0xfffb; + jp_joypads[0] |= ((~(JOYPAD_IO.fires)) & 3)<<(16+4); + JOYPAD_IO.directions=0xfffb; + jp_joypads[0] |= (((~(JOYPAD_IO.directions))>>8) & 15)<<8; + + JOYPAD_IO.directions=0xfff7; + jp_joypads[0] |= ((~(JOYPAD_IO.fires)) & 3)<<(16+6); + JOYPAD_IO.directions=0xfff7; + jp_joypads[0] |= (((~(JOYPAD_IO.directions))>>8) & 15)<<12; + + /* Update joypad 1 */ + JOYPAD_IO.directions=0xffef; + jp_joypads[1]=((~(JOYPAD_IO.fires)) & (3<<2))<<(16-2); + JOYPAD_IO.directions=0xffef; + jp_joypads[1] |= ((~(JOYPAD_IO.directions))>>12) & 15; + + JOYPAD_IO.directions=0xffdf; + jp_joypads[1] |= ((~(JOYPAD_IO.fires)) & (3<<2))<<(16); + JOYPAD_IO.directions=0xffdf; + jp_joypads[1] |= (((~(JOYPAD_IO.directions))>>12) & 15)<<4; + + JOYPAD_IO.directions=0xffbf; + jp_joypads[1] |= ((~(JOYPAD_IO.fires)) & (3<<2))<<(16+2); + JOYPAD_IO.directions=0xffbf; + jp_joypads[1] |= (((~(JOYPAD_IO.directions))>>12) & 15)<<8; + + JOYPAD_IO.directions=0xff7f; + jp_joypads[1] |= ((~(JOYPAD_IO.fires)) & (3<<2))<<(16+4); + JOYPAD_IO.directions=0xff7f; + jp_joypads[1] |= (((~(JOYPAD_IO.directions))>>12) & 15)<<12; +}