diff options
Diffstat (limited to 'distrib/sdl-1.2.12/src/joystick')
16 files changed, 6499 insertions, 0 deletions
diff --git a/distrib/sdl-1.2.12/src/joystick/SDL_joystick.c b/distrib/sdl-1.2.12/src/joystick/SDL_joystick.c new file mode 100644 index 0000000..5984a32 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/SDL_joystick.c @@ -0,0 +1,573 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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" + +/* This is the joystick API for Simple DirectMedia Layer */ + +#include "SDL_events.h" +#include "SDL_sysjoystick.h" +#include "SDL_joystick_c.h" +#if !SDL_EVENTS_DISABLED +#include "../events/SDL_events_c.h" +#endif + +/* This is used for Quake III Arena */ +#if SDL_EVENTS_DISABLED +#define SDL_Lock_EventThread() +#define SDL_Unlock_EventThread() +#endif + +Uint8 SDL_numjoysticks = 0; +SDL_Joystick **SDL_joysticks = NULL; +static SDL_Joystick *default_joystick = NULL; + +int SDL_JoystickInit(void) +{ + int arraylen; + int status; + + SDL_numjoysticks = 0; + status = SDL_SYS_JoystickInit(); + if ( status >= 0 ) { + arraylen = (status+1)*sizeof(*SDL_joysticks); + SDL_joysticks = (SDL_Joystick **)SDL_malloc(arraylen); + if ( SDL_joysticks == NULL ) { + SDL_numjoysticks = 0; + } else { + SDL_memset(SDL_joysticks, 0, arraylen); + SDL_numjoysticks = status; + } + status = 0; + } + default_joystick = NULL; + return(status); +} + +/* + * Count the number of joysticks attached to the system + */ +int SDL_NumJoysticks(void) +{ + return SDL_numjoysticks; +} + +/* + * Get the implementation dependent name of a joystick + */ +const char *SDL_JoystickName(int device_index) +{ + if ( (device_index < 0) || (device_index >= SDL_numjoysticks) ) { + SDL_SetError("There are %d joysticks available", + SDL_numjoysticks); + return(NULL); + } + return(SDL_SYS_JoystickName(device_index)); +} + +/* + * Open a joystick for use - the index passed as an argument refers to + * the N'th joystick on the system. This index is the value which will + * identify this joystick in future joystick events. + * + * This function returns a joystick identifier, or NULL if an error occurred. + */ +SDL_Joystick *SDL_JoystickOpen(int device_index) +{ + int i; + SDL_Joystick *joystick; + + if ( (device_index < 0) || (device_index >= SDL_numjoysticks) ) { + SDL_SetError("There are %d joysticks available", + SDL_numjoysticks); + return(NULL); + } + + /* If the joystick is already open, return it */ + for ( i=0; SDL_joysticks[i]; ++i ) { + if ( device_index == SDL_joysticks[i]->index ) { + joystick = SDL_joysticks[i]; + ++joystick->ref_count; + return(joystick); + } + } + + /* Create and initialize the joystick */ + joystick = (SDL_Joystick *)SDL_malloc((sizeof *joystick)); + if ( joystick != NULL ) { + SDL_memset(joystick, 0, (sizeof *joystick)); + joystick->index = device_index; + if ( SDL_SYS_JoystickOpen(joystick) < 0 ) { + SDL_free(joystick); + joystick = NULL; + } else { + if ( joystick->naxes > 0 ) { + joystick->axes = (Sint16 *)SDL_malloc + (joystick->naxes*sizeof(Sint16)); + } + if ( joystick->nhats > 0 ) { + joystick->hats = (Uint8 *)SDL_malloc + (joystick->nhats*sizeof(Uint8)); + } + if ( joystick->nballs > 0 ) { + joystick->balls = (struct balldelta *)SDL_malloc + (joystick->nballs*sizeof(*joystick->balls)); + } + if ( joystick->nbuttons > 0 ) { + joystick->buttons = (Uint8 *)SDL_malloc + (joystick->nbuttons*sizeof(Uint8)); + } + if ( ((joystick->naxes > 0) && !joystick->axes) + || ((joystick->nhats > 0) && !joystick->hats) + || ((joystick->nballs > 0) && !joystick->balls) + || ((joystick->nbuttons > 0) && !joystick->buttons)) { + SDL_OutOfMemory(); + SDL_JoystickClose(joystick); + joystick = NULL; + } + if ( joystick->axes ) { + SDL_memset(joystick->axes, 0, + joystick->naxes*sizeof(Sint16)); + } + if ( joystick->hats ) { + SDL_memset(joystick->hats, 0, + joystick->nhats*sizeof(Uint8)); + } + if ( joystick->balls ) { + SDL_memset(joystick->balls, 0, + joystick->nballs*sizeof(*joystick->balls)); + } + if ( joystick->buttons ) { + SDL_memset(joystick->buttons, 0, + joystick->nbuttons*sizeof(Uint8)); + } + } + } + if ( joystick ) { + /* Add joystick to list */ + ++joystick->ref_count; + SDL_Lock_EventThread(); + for ( i=0; SDL_joysticks[i]; ++i ) + /* Skip to next joystick */; + SDL_joysticks[i] = joystick; + SDL_Unlock_EventThread(); + } + return(joystick); +} + +/* + * Returns 1 if the joystick has been opened, or 0 if it has not. + */ +int SDL_JoystickOpened(int device_index) +{ + int i, opened; + + opened = 0; + for ( i=0; SDL_joysticks[i]; ++i ) { + if ( SDL_joysticks[i]->index == (Uint8)device_index ) { + opened = 1; + break; + } + } + return(opened); +} + +static int ValidJoystick(SDL_Joystick **joystick) +{ + int valid; + + if ( *joystick == NULL ) { + *joystick = default_joystick; + } + if ( *joystick == NULL ) { + SDL_SetError("Joystick hasn't been opened yet"); + valid = 0; + } else { + valid = 1; + } + return valid; +} + +/* + * Get the device index of an opened joystick. + */ +int SDL_JoystickIndex(SDL_Joystick *joystick) +{ + if ( ! ValidJoystick(&joystick) ) { + return(-1); + } + return(joystick->index); +} + +/* + * Get the number of multi-dimensional axis controls on a joystick + */ +int SDL_JoystickNumAxes(SDL_Joystick *joystick) +{ + if ( ! ValidJoystick(&joystick) ) { + return(-1); + } + return(joystick->naxes); +} + +/* + * Get the number of hats on a joystick + */ +int SDL_JoystickNumHats(SDL_Joystick *joystick) +{ + if ( ! ValidJoystick(&joystick) ) { + return(-1); + } + return(joystick->nhats); +} + +/* + * Get the number of trackballs on a joystick + */ +int SDL_JoystickNumBalls(SDL_Joystick *joystick) +{ + if ( ! ValidJoystick(&joystick) ) { + return(-1); + } + return(joystick->nballs); +} + +/* + * Get the number of buttons on a joystick + */ +int SDL_JoystickNumButtons(SDL_Joystick *joystick) +{ + if ( ! ValidJoystick(&joystick) ) { + return(-1); + } + return(joystick->nbuttons); +} + +/* + * Get the current state of an axis control on a joystick + */ +Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis) +{ + Sint16 state; + + if ( ! ValidJoystick(&joystick) ) { + return(0); + } + if ( axis < joystick->naxes ) { + state = joystick->axes[axis]; + } else { + SDL_SetError("Joystick only has %d axes", joystick->naxes); + state = 0; + } + return(state); +} + +/* + * Get the current state of a hat on a joystick + */ +Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat) +{ + Uint8 state; + + if ( ! ValidJoystick(&joystick) ) { + return(0); + } + if ( hat < joystick->nhats ) { + state = joystick->hats[hat]; + } else { + SDL_SetError("Joystick only has %d hats", joystick->nhats); + state = 0; + } + return(state); +} + +/* + * Get the ball axis change since the last poll + */ +int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy) +{ + int retval; + + if ( ! ValidJoystick(&joystick) ) { + return(-1); + } + + retval = 0; + if ( ball < joystick->nballs ) { + if ( dx ) { + *dx = joystick->balls[ball].dx; + } + if ( dy ) { + *dy = joystick->balls[ball].dy; + } + joystick->balls[ball].dx = 0; + joystick->balls[ball].dy = 0; + } else { + SDL_SetError("Joystick only has %d balls", joystick->nballs); + retval = -1; + } + return(retval); +} + +/* + * Get the current state of a button on a joystick + */ +Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button) +{ + Uint8 state; + + if ( ! ValidJoystick(&joystick) ) { + return(0); + } + if ( button < joystick->nbuttons ) { + state = joystick->buttons[button]; + } else { + SDL_SetError("Joystick only has %d buttons",joystick->nbuttons); + state = 0; + } + return(state); +} + +/* + * Close a joystick previously opened with SDL_JoystickOpen() + */ +void SDL_JoystickClose(SDL_Joystick *joystick) +{ + int i; + + if ( ! ValidJoystick(&joystick) ) { + return; + } + + /* First decrement ref count */ + if ( --joystick->ref_count > 0 ) { + return; + } + + /* Lock the event queue - prevent joystick polling */ + SDL_Lock_EventThread(); + + if ( joystick == default_joystick ) { + default_joystick = NULL; + } + SDL_SYS_JoystickClose(joystick); + + /* Remove joystick from list */ + for ( i=0; SDL_joysticks[i]; ++i ) { + if ( joystick == SDL_joysticks[i] ) { + SDL_memcpy(&SDL_joysticks[i], &SDL_joysticks[i+1], + (SDL_numjoysticks-i)*sizeof(joystick)); + break; + } + } + + /* Let the event thread keep running */ + SDL_Unlock_EventThread(); + + /* Free the data associated with this joystick */ + if ( joystick->axes ) { + SDL_free(joystick->axes); + } + if ( joystick->hats ) { + SDL_free(joystick->hats); + } + if ( joystick->balls ) { + SDL_free(joystick->balls); + } + if ( joystick->buttons ) { + SDL_free(joystick->buttons); + } + SDL_free(joystick); +} + +void SDL_JoystickQuit(void) +{ + /* Stop the event polling */ + SDL_Lock_EventThread(); + SDL_numjoysticks = 0; + SDL_Unlock_EventThread(); + + /* Quit the joystick setup */ + SDL_SYS_JoystickQuit(); + if ( SDL_joysticks ) { + SDL_free(SDL_joysticks); + SDL_joysticks = NULL; + } +} + + +/* These are global for SDL_sysjoystick.c and SDL_events.c */ + +int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value) +{ + int posted; + + /* Update internal joystick state */ + joystick->axes[axis] = value; + + /* Post the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if ( SDL_ProcessEvents[SDL_JOYAXISMOTION] == SDL_ENABLE ) { + SDL_Event event; + event.type = SDL_JOYAXISMOTION; + event.jaxis.which = joystick->index; + event.jaxis.axis = axis; + event.jaxis.value = value; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + return(posted); +} + +int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value) +{ + int posted; + + /* Update internal joystick state */ + joystick->hats[hat] = value; + + /* Post the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if ( SDL_ProcessEvents[SDL_JOYHATMOTION] == SDL_ENABLE ) { + SDL_Event event; + event.jhat.type = SDL_JOYHATMOTION; + event.jhat.which = joystick->index; + event.jhat.hat = hat; + event.jhat.value = value; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + return(posted); +} + +int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, + Sint16 xrel, Sint16 yrel) +{ + int posted; + + /* Update internal mouse state */ + joystick->balls[ball].dx += xrel; + joystick->balls[ball].dy += yrel; + + /* Post the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if ( SDL_ProcessEvents[SDL_JOYBALLMOTION] == SDL_ENABLE ) { + SDL_Event event; + event.jball.type = SDL_JOYBALLMOTION; + event.jball.which = joystick->index; + event.jball.ball = ball; + event.jball.xrel = xrel; + event.jball.yrel = yrel; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + return(posted); +} + +int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state) +{ + int posted; +#if !SDL_EVENTS_DISABLED + SDL_Event event; + + switch ( state ) { + case SDL_PRESSED: + event.type = SDL_JOYBUTTONDOWN; + break; + case SDL_RELEASED: + event.type = SDL_JOYBUTTONUP; + break; + default: + /* Invalid state -- bail */ + return(0); + } +#endif /* !SDL_EVENTS_DISABLED */ + + /* Update internal joystick state */ + joystick->buttons[button] = state; + + /* Post the event, if desired */ + posted = 0; +#if !SDL_EVENTS_DISABLED + if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) { + event.jbutton.which = joystick->index; + event.jbutton.button = button; + event.jbutton.state = state; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + return(posted); +} + +void SDL_JoystickUpdate(void) +{ + int i; + + for ( i=0; SDL_joysticks[i]; ++i ) { + SDL_SYS_JoystickUpdate(SDL_joysticks[i]); + } +} + +int SDL_JoystickEventState(int state) +{ +#if SDL_EVENTS_DISABLED + return SDL_IGNORE; +#else + const Uint8 event_list[] = { + SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION, + SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, + }; + unsigned int i; + + switch (state) { + case SDL_QUERY: + state = SDL_IGNORE; + for ( i=0; i<SDL_arraysize(event_list); ++i ) { + state = SDL_EventState(event_list[i],SDL_QUERY); + if ( state == SDL_ENABLE ) { + break; + } + } + break; + default: + for ( i=0; i<SDL_arraysize(event_list); ++i ) { + SDL_EventState(event_list[i], state); + } + break; + } + return(state); +#endif /* SDL_EVENTS_DISABLED */ +} diff --git a/distrib/sdl-1.2.12/src/joystick/SDL_joystick_c.h b/distrib/sdl-1.2.12/src/joystick/SDL_joystick_c.h new file mode 100644 index 0000000..2cb1e3b --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/SDL_joystick_c.h @@ -0,0 +1,38 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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" + +/* Useful functions and variables from SDL_joystick.c */ +#include "SDL_joystick.h" + +/* The number of available joysticks on the system */ +extern Uint8 SDL_numjoysticks; + +/* Internal event queueing functions */ +extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, + Uint8 axis, Sint16 value); +extern int SDL_PrivateJoystickBall(SDL_Joystick *joystick, + Uint8 ball, Sint16 xrel, Sint16 yrel); +extern int SDL_PrivateJoystickHat(SDL_Joystick *joystick, + Uint8 hat, Uint8 value); +extern int SDL_PrivateJoystickButton(SDL_Joystick *joystick, + Uint8 button, Uint8 state); diff --git a/distrib/sdl-1.2.12/src/joystick/SDL_sysjoystick.h b/distrib/sdl-1.2.12/src/joystick/SDL_sysjoystick.h new file mode 100644 index 0000000..16c534c --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/SDL_sysjoystick.h @@ -0,0 +1,82 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is SDL_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" + +/* This is the system specific header for the SDL joystick API */ + +#include "SDL_joystick.h" + +/* The SDL joystick structure */ +struct _SDL_Joystick { + Uint8 index; /* Device index */ + const char *name; /* Joystick name - system dependent */ + + int naxes; /* Number of axis controls on the joystick */ + Sint16 *axes; /* Current axis states */ + + int nhats; /* Number of hats on the joystick */ + Uint8 *hats; /* Current hat states */ + + int nballs; /* Number of trackballs on the joystick */ + struct balldelta { + int dx; + int dy; + } *balls; /* Current ball motion deltas */ + + int nbuttons; /* Number of buttons on the joystick */ + Uint8 *buttons; /* Current button states */ + + struct joystick_hwdata *hwdata; /* Driver dependent information */ + + int ref_count; /* Reference count for multiple opens */ +}; + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * This function should return the number of available joysticks, or -1 + * on an unrecoverable fatal error. + */ +extern int SDL_SYS_JoystickInit(void); + +/* Function to get the device-dependent name of a joystick */ +extern const char *SDL_SYS_JoystickName(int index); + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +extern int SDL_SYS_JoystickOpen(SDL_Joystick *joystick); + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +extern void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick); + +/* Function to close a joystick after use */ +extern void SDL_SYS_JoystickClose(SDL_Joystick *joystick); + +/* Function to perform any system-specific joystick related cleanup */ +extern void SDL_SYS_JoystickQuit(void); + diff --git a/distrib/sdl-1.2.12/src/joystick/amigaos/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/amigaos/SDL_sysjoystick.c new file mode 100644 index 0000000..35e4ebe --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/amigaos/SDL_sysjoystick.c @@ -0,0 +1,233 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_AMIGA + +/* This is the system specific header for the SDL joystick API */ + +#include <libraries/lowlevel.h> +#if defined(__SASC) || defined(STORMC4_WOS) +#include <proto/exec.h> +#include <proto/lowlevel.h> +#include <proto/graphics.h> +#else +#include <inline/exec.h> +#include <inline/lowlevel.h> +#include <inline/graphics.h> +#endif +#include "mydebug.h" + +extern struct ExecBase *SysBase; +extern struct GfxBase *GfxBase; + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ + + +/* Amiga specific datas */ +struct Library *LowLevelBase=NULL; + +ULONG joybut[]= +{ + JPF_BUTTON_RED, + JPF_BUTTON_BLUE, + JPF_BUTTON_PLAY, + JPF_BUTTON_YELLOW, + JPF_BUTTON_GREEN, + JPF_BUTTON_FORWARD, + JPF_BUTTON_REVERSE, +}; + +struct joystick_hwdata +{ + ULONG joystate; +}; + +int SDL_SYS_JoystickInit(void) +{ + if(!LowLevelBase) + { + if(LowLevelBase=OpenLibrary("lowlevel.library",37)) + return 2; + } + else + return 2; + + D(bug("%ld joysticks available.\n",SDL_numjoysticks)); + + return 0; +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + if(index<2&&LowLevelBase) + { + switch(index) + { + case 0: + return "Port 1 Amiga Joystick/Joypad"; + case 1: + return "Port 2 Amiga Joystick/Joypad"; + } + } + + SDL_SetError("No joystick available with that index"); + return(NULL); +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ + +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + ULONG temp,i; + D(bug("Opening joystick %ld\n",joystick->index)); + + if(!(joystick->hwdata=SDL_malloc(sizeof(struct joystick_hwdata)))) + return -1; + +/* This loop is to check if the controller is a joypad */ + + for(i=0;i<20;i++) + { + temp=ReadJoyPort(joystick->index^1); // fix to invert amiga joyports + WaitTOF(); + } + + if((temp&JP_TYPE_MASK)==JP_TYPE_GAMECTLR) + joystick->nbuttons=7; + else + joystick->nbuttons=3; + + joystick->nhats=0; + joystick->nballs=0; + joystick->naxes=2; + joystick->hwdata->joystate=0L; + + return 0; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + ULONG data; + int i; + + if(joystick->index<2) + { + data=ReadJoyPort(joystick->index); + + if(data&JP_DIRECTION_MASK) + { + if(data&JPF_JOY_DOWN) + { + if(!(joystick->hwdata->joystate&JPF_JOY_DOWN)) + SDL_PrivateJoystickAxis(joystick,0,127); + } + else if(data&JPF_JOY_UP) + { + if(!(joystick->hwdata->joystate&JPF_JOY_UP)) + SDL_PrivateJoystickAxis(joystick,0,-127); + } + else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN)) + SDL_PrivateJoystickAxis(joystick,0,0); + + if(data&JPF_JOY_LEFT) + { + if(!(joystick->hwdata->joystate&JPF_JOY_LEFT)) + SDL_PrivateJoystickAxis(joystick,1,-127); + } + else if(data&JPF_JOY_RIGHT) + { + if(!(joystick->hwdata->joystate&JPF_JOY_RIGHT)) + SDL_PrivateJoystickAxis(joystick,1,127); + } + else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT)) + SDL_PrivateJoystickAxis(joystick,1,0); + } + else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT)) + { + SDL_PrivateJoystickAxis(joystick,1,0); + } + else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN)) + { + SDL_PrivateJoystickAxis(joystick,0,0); + } + + for(i=0;i<joystick->nbuttons;i++) + { + if( (data&joybut[i]) ) + { + if(i==1) + data&=(~(joybut[2])); + + if(!(joystick->hwdata->joystate&joybut[i])) + SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); + } + else if(joystick->hwdata->joystate&joybut[i]) + SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); + } + + joystick->hwdata->joystate=data; + } + + return; +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + if(joystick->hwdata) + SDL_free(joystick->hwdata); + return; +} + +/* Function to perform any system-specific joystick related cleanup */ + +void SDL_SYS_JoystickQuit(void) +{ + if(LowLevelBase) + { + CloseLibrary(LowLevelBase); + LowLevelBase=NULL; + SDL_numjoysticks=0; + } + return; +} + +#endif /* SDL_JOYSTICK_AMIGA */ diff --git a/distrib/sdl-1.2.12/src/joystick/beos/SDL_bejoystick.cc b/distrib/sdl-1.2.12/src/joystick/beos/SDL_bejoystick.cc new file mode 100644 index 0000000..7c52b86 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/beos/SDL_bejoystick.cc @@ -0,0 +1,237 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_BEOS + +/* This is the system specific header for the SDL joystick API */ + +#include <be/support/String.h> +#include <be/device/Joystick.h> + +extern "C" { + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + + +/* The maximum number of joysticks we'll detect */ +#define MAX_JOYSTICKS 16 + +/* A list of available joysticks */ +static char *SDL_joyport[MAX_JOYSTICKS]; +static char *SDL_joyname[MAX_JOYSTICKS]; + +/* The private structure used to keep track of a joystick */ +struct joystick_hwdata { + BJoystick *stick; + uint8 *new_hats; + int16 *new_axes; +}; + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + BJoystick joystick; + int numjoysticks; + int i; + int32 nports; + char name[B_OS_NAME_LENGTH]; + + /* Search for attached joysticks */ + nports = joystick.CountDevices(); + numjoysticks = 0; + SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport)); + SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname)); + for ( i=0; (SDL_numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i ) { + if ( joystick.GetDeviceName(i, name) == B_OK ) { + if ( joystick.Open(name) != B_ERROR ) { + BString stick_name; + joystick.GetControllerName(&stick_name); + SDL_joyport[numjoysticks] = strdup(name); + SDL_joyname[numjoysticks] = + strdup(stick_name.String()); + numjoysticks++; + joystick.Close(); + } + } + } + return(numjoysticks); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + return SDL_joyname[index]; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + BJoystick *stick; + + /* Create the joystick data structure */ + joystick->hwdata = (struct joystick_hwdata *) + SDL_malloc(sizeof(*joystick->hwdata)); + if ( joystick->hwdata == NULL ) { + SDL_OutOfMemory(); + return(-1); + } + SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + stick = new BJoystick; + joystick->hwdata->stick = stick; + + /* Open the requested joystick for use */ + if ( stick->Open(SDL_joyport[joystick->index]) == B_ERROR ) { + SDL_SetError("Unable to open joystick"); + SDL_SYS_JoystickClose(joystick); + return(-1); + } + + /* Set the joystick to calibrated mode */ + stick->EnableCalibration(); + + /* Get the number of buttons, hats, and axes on the joystick */ + joystick->nbuttons = stick->CountButtons(); + joystick->naxes = stick->CountAxes(); + joystick->nhats = stick->CountHats(); + + joystick->hwdata->new_axes = (int16 *) + SDL_malloc(joystick->naxes*sizeof(int16)); + joystick->hwdata->new_hats = (uint8 *) + SDL_malloc(joystick->nhats*sizeof(uint8)); + if ( ! joystick->hwdata->new_hats || ! joystick->hwdata->new_axes ) { + SDL_OutOfMemory(); + SDL_SYS_JoystickClose(joystick); + return(-1); + } + + /* We're done! */ + return(0); +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + static const Uint8 hat_map[9] = { + SDL_HAT_CENTERED, + SDL_HAT_UP, + SDL_HAT_RIGHTUP, + SDL_HAT_RIGHT, + SDL_HAT_RIGHTDOWN, + SDL_HAT_DOWN, + SDL_HAT_LEFTDOWN, + SDL_HAT_LEFT, + SDL_HAT_LEFTUP + }; + const int JITTER = (32768/10); /* 10% jitter threshold (ok?) */ + + BJoystick *stick; + int i, change; + int16 *axes; + uint8 *hats; + uint32 buttons; + + /* Set up data pointers */ + stick = joystick->hwdata->stick; + axes = joystick->hwdata->new_axes; + hats = joystick->hwdata->new_hats; + + /* Get the new joystick state */ + stick->Update(); + stick->GetAxisValues(axes); + stick->GetHatValues(hats); + buttons = stick->ButtonValues(); + + /* Generate axis motion events */ + for ( i=0; i<joystick->naxes; ++i ) { + change = ((int32)axes[i] - joystick->axes[i]); + if ( (change > JITTER) || (change < -JITTER) ) { + SDL_PrivateJoystickAxis(joystick, i, axes[i]); + } + } + + /* Generate hat change events */ + for ( i=0; i<joystick->nhats; ++i ) { + if ( hats[i] != joystick->hats[i] ) { + SDL_PrivateJoystickHat(joystick, i, hat_map[hats[i]]); + } + } + + /* Generate button events */ + for ( i=0; i<joystick->nbuttons; ++i ) { + if ( (buttons&0x01) != joystick->buttons[i] ) { + SDL_PrivateJoystickButton(joystick, i, (buttons&0x01)); + } + buttons >>= 1; + } +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + if ( joystick->hwdata ) { + joystick->hwdata->stick->Close(); + delete joystick->hwdata->stick; + if ( joystick->hwdata->new_hats ) { + SDL_free(joystick->hwdata->new_hats); + } + if ( joystick->hwdata->new_axes ) { + SDL_free(joystick->hwdata->new_axes); + } + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + } +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + int i; + + for ( i=0; SDL_joyport[i]; ++i ) { + SDL_free(SDL_joyport[i]); + } + SDL_joyport[0] = NULL; + + for ( i=0; SDL_joyname[i]; ++i ) { + SDL_free(SDL_joyname[i]); + } + SDL_joyname[0] = NULL; +} + +}; // extern "C" + +#endif /* SDL_JOYSTICK_BEOS */ diff --git a/distrib/sdl-1.2.12/src/joystick/bsd/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/bsd/SDL_sysjoystick.c new file mode 100644 index 0000000..926899d --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/bsd/SDL_sysjoystick.c @@ -0,0 +1,591 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_USBHID + +/* + * Joystick driver for the uhid(4) interface found in OpenBSD, + * NetBSD and FreeBSD. + * + * Maintainer: <vedge at csoft.org> + */ + +#include <sys/param.h> + +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#if defined(HAVE_USB_H) +#include <usb.h> +#endif +#ifdef __DragonFly__ +#include <bus/usb/usb.h> +#include <bus/usb/usbhid.h> +#else +#include <dev/usb/usb.h> +#include <dev/usb/usbhid.h> +#endif + +#if defined(HAVE_USBHID_H) +#include <usbhid.h> +#elif defined(HAVE_LIBUSB_H) +#include <libusb.h> +#elif defined(HAVE_LIBUSBHID_H) +#include <libusbhid.h> +#endif + +#ifdef __FREEBSD__ +#ifndef __DragonFly__ +#include <osreldate.h> +#endif +#include <sys/joystick.h> +#endif + +#if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H +#include <machine/joystick.h> +#endif + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#define MAX_UHID_JOYS 4 +#define MAX_JOY_JOYS 2 +#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) + +struct report { + struct usb_ctl_report *buf; /* Buffer */ + size_t size; /* Buffer size */ + int rid; /* Report ID */ + enum { + SREPORT_UNINIT, + SREPORT_CLEAN, + SREPORT_DIRTY + } status; +}; + +static struct { + int uhid_report; + hid_kind_t kind; + const char *name; +} const repinfo[] = { + { UHID_INPUT_REPORT, hid_input, "input" }, + { UHID_OUTPUT_REPORT, hid_output, "output" }, + { UHID_FEATURE_REPORT, hid_feature, "feature" } +}; + +enum { + REPORT_INPUT = 0, + REPORT_OUTPUT = 1, + REPORT_FEATURE = 2 +}; + +enum { + JOYAXE_X, + JOYAXE_Y, + JOYAXE_Z, + JOYAXE_SLIDER, + JOYAXE_WHEEL, + JOYAXE_RX, + JOYAXE_RY, + JOYAXE_RZ, + JOYAXE_count +}; + +struct joystick_hwdata { + int fd; + char *path; + enum { + BSDJOY_UHID, /* uhid(4) */ + BSDJOY_JOY /* joy(4) */ + } type; + struct report_desc *repdesc; + struct report inreport; + int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,..*/ + int x; + int y; + int xmin; + int ymin; + int xmax; + int ymax; +}; + +static char *joynames[MAX_JOYS]; +static char *joydevnames[MAX_JOYS]; + +static int report_alloc(struct report *, struct report_desc *, int); +static void report_free(struct report *); + +#ifdef USBHID_UCR_DATA +#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data) +#else +#define REP_BUF_DATA(rep) ((rep)->buf->data) +#endif + +int +SDL_SYS_JoystickInit(void) +{ + char s[16]; + int i, fd; + + SDL_numjoysticks = 0; + + SDL_memset(joynames, 0, sizeof(joynames)); + SDL_memset(joydevnames, 0, sizeof(joydevnames)); + + for (i = 0; i < MAX_UHID_JOYS; i++) { + SDL_Joystick nj; + + SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); + + nj.index = SDL_numjoysticks; + joynames[nj.index] = strdup(s); + + if (SDL_SYS_JoystickOpen(&nj) == 0) { + SDL_SYS_JoystickClose(&nj); + SDL_numjoysticks++; + } else { + SDL_free(joynames[nj.index]); + joynames[nj.index] = NULL; + } + } + for (i = 0; i < MAX_JOY_JOYS; i++) { + SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); + fd = open(s, O_RDONLY); + if (fd != -1) { + joynames[SDL_numjoysticks++] = strdup(s); + close(fd); + } + } + + /* Read the default USB HID usage table. */ + hid_init(NULL); + + return (SDL_numjoysticks); +} + +const char * +SDL_SYS_JoystickName(int index) +{ + if (joydevnames[index] != NULL) { + return (joydevnames[index]); + } + return (joynames[index]); +} + +static int +usage_to_joyaxe(unsigned usage) +{ + int joyaxe; + switch (usage) { + case HUG_X: + joyaxe = JOYAXE_X; break; + case HUG_Y: + joyaxe = JOYAXE_Y; break; + case HUG_Z: + joyaxe = JOYAXE_Z; break; + case HUG_SLIDER: + joyaxe = JOYAXE_SLIDER; break; + case HUG_WHEEL: + joyaxe = JOYAXE_WHEEL; break; + case HUG_RX: + joyaxe = JOYAXE_RX; break; + case HUG_RY: + joyaxe = JOYAXE_RY; break; + case HUG_RZ: + joyaxe = JOYAXE_RZ; break; + default: + joyaxe = -1; + } + return joyaxe; +} + +static unsigned +hatval_to_sdl(Sint32 hatval) +{ + static const unsigned hat_dir_map[8] = { + SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN, + SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP + }; + unsigned result; + if ((hatval & 7) == hatval) + result = hat_dir_map[hatval]; + else + result = SDL_HAT_CENTERED; + return result; +} + + +int +SDL_SYS_JoystickOpen(SDL_Joystick *joy) +{ + char *path = joynames[joy->index]; + struct joystick_hwdata *hw; + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep; + int fd; + int i; + + fd = open(path, O_RDONLY); + if (fd == -1) { + SDL_SetError("%s: %s", path, strerror(errno)); + return (-1); + } + + hw = (struct joystick_hwdata *)SDL_malloc(sizeof(struct joystick_hwdata)); + if (hw == NULL) { + SDL_OutOfMemory(); + close(fd); + return (-1); + } + joy->hwdata = hw; + hw->fd = fd; + hw->path = strdup(path); + hw->x = 0; + hw->y = 0; + hw->xmin = 0xffff; + hw->ymin = 0xffff; + hw->xmax = 0; + hw->ymax = 0; + if (! SDL_strncmp(path, "/dev/joy", 8)) { + hw->type = BSDJOY_JOY; + joy->naxes = 2; + joy->nbuttons = 2; + joy->nhats = 0; + joy->nballs = 0; + joydevnames[joy->index] = strdup("Gameport joystick"); + goto usbend; + } else { + hw->type = BSDJOY_UHID; + } + + { + int ax; + for (ax = 0; ax < JOYAXE_count; ax++) + hw->axis_map[ax] = -1; + } + hw->repdesc = hid_get_report_desc(fd); + if (hw->repdesc == NULL) { + SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path, + strerror(errno)); + goto usberr; + } + + rep = &hw->inreport; + if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) { + rep->rid = -1; /* XXX */ + } + if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) { + goto usberr; + } + if (rep->size <= 0) { + SDL_SetError("%s: Input report descriptor has invalid length", + hw->path); + goto usberr; + } + +#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111) + hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(hw->repdesc, 1 << hid_input); +#endif + if (hdata == NULL) { + SDL_SetError("%s: Cannot start HID parser", hw->path); + goto usberr; + } + joy->naxes = 0; + joy->nbuttons = 0; + joy->nhats = 0; + joy->nballs = 0; + for (i=0; i<JOYAXE_count; i++) + hw->axis_map[i] = -1; + + while (hid_get_item(hdata, &hitem) > 0) { + char *sp; + const char *s; + + switch (hitem.kind) { + case hid_collection: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + switch (HID_USAGE(hitem.usage)) { + case HUG_JOYSTICK: + case HUG_GAME_PAD: + s = hid_usage_in_page(hitem.usage); + sp = SDL_malloc(SDL_strlen(s) + 5); + SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", s, + joy->index); + joydevnames[joy->index] = sp; + } + } + break; + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: { + unsigned usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + hw->axis_map[joyaxe] = 1; + } else if (usage == HUG_HAT_SWITCH) { + joy->nhats++; + } + break; + } + case HUP_BUTTON: + joy->nbuttons++; + break; + default: + break; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + for (i=0; i<JOYAXE_count; i++) + if (hw->axis_map[i] > 0) + hw->axis_map[i] = joy->naxes++; + +usbend: + /* The poll blocks the event thread. */ + fcntl(fd, F_SETFL, O_NONBLOCK); + + return (0); +usberr: + close(hw->fd); + SDL_free(hw->path); + SDL_free(hw); + return (-1); +} + +void +SDL_SYS_JoystickUpdate(SDL_Joystick *joy) +{ + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep; + int nbutton, naxe = -1; + Sint32 v; + +#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H + struct joystick gameport; + + if (joy->hwdata->type == BSDJOY_JOY) { + if (read(joy->hwdata->fd, &gameport, sizeof gameport) != sizeof gameport) + return; + if (abs(joy->hwdata->x - gameport.x) > 8) { + joy->hwdata->x = gameport.x; + if (joy->hwdata->x < joy->hwdata->xmin) { + joy->hwdata->xmin = joy->hwdata->x; + } + if (joy->hwdata->x > joy->hwdata->xmax) { + joy->hwdata->xmax = joy->hwdata->x; + } + if (joy->hwdata->xmin == joy->hwdata->xmax) { + joy->hwdata->xmin--; + joy->hwdata->xmax++; + } + v = (Sint32)joy->hwdata->x; + v -= (joy->hwdata->xmax + joy->hwdata->xmin + 1)/2; + v *= 32768/((joy->hwdata->xmax - joy->hwdata->xmin + 1)/2); + SDL_PrivateJoystickAxis(joy, 0, v); + } + if (abs(joy->hwdata->y - gameport.y) > 8) { + joy->hwdata->y = gameport.y; + if (joy->hwdata->y < joy->hwdata->ymin) { + joy->hwdata->ymin = joy->hwdata->y; + } + if (joy->hwdata->y > joy->hwdata->ymax) { + joy->hwdata->ymax = joy->hwdata->y; + } + if (joy->hwdata->ymin == joy->hwdata->ymax) { + joy->hwdata->ymin--; + joy->hwdata->ymax++; + } + v = (Sint32)joy->hwdata->y; + v -= (joy->hwdata->ymax + joy->hwdata->ymin + 1)/2; + v *= 32768/((joy->hwdata->ymax - joy->hwdata->ymin + 1)/2); + SDL_PrivateJoystickAxis(joy, 1, v); + } + if (gameport.b1 != joy->buttons[0]) { + SDL_PrivateJoystickButton(joy, 0, gameport.b1); + } + if (gameport.b2 != joy->buttons[1]) { + SDL_PrivateJoystickButton(joy, 1, gameport.b2); + } + return; + } +#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ + + rep = &joy->hwdata->inreport; + + if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) { + return; + } +#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111) + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); +#endif + if (hdata == NULL) { + fprintf(stderr, "%s: Cannot start HID parser\n", + joy->hwdata->path); + return; + } + + for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) { + switch (hitem.kind) { + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: { + unsigned usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + naxe = joy->hwdata->axis_map[joyaxe]; + /* scaleaxe */ + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), + &hitem); + v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2; + v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2); + if (v != joy->axes[naxe]) { + SDL_PrivateJoystickAxis(joy, naxe, v); + } + } else if (usage == HUG_HAT_SWITCH) { + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), + &hitem); + SDL_PrivateJoystickHat(joy, 0, + hatval_to_sdl(v)-hitem.logical_minimum); + } + break; + } + case HUP_BUTTON: + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), + &hitem); + if (joy->buttons[nbutton] != v) { + SDL_PrivateJoystickButton(joy, + nbutton, v); + } + nbutton++; + break; + default: + continue; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + + return; +} + +/* Function to close a joystick after use */ +void +SDL_SYS_JoystickClose(SDL_Joystick *joy) +{ + if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) { + report_free(&joy->hwdata->inreport); + hid_dispose_report_desc(joy->hwdata->repdesc); + } + close(joy->hwdata->fd); + SDL_free(joy->hwdata->path); + SDL_free(joy->hwdata); + + return; +} + +void +SDL_SYS_JoystickQuit(void) +{ + int i; + + for (i = 0; i < MAX_JOYS; i++) { + if (joynames[i] != NULL) + SDL_free(joynames[i]); + if (joydevnames[i] != NULL) + SDL_free(joydevnames[i]); + } + + return; +} + +static int +report_alloc(struct report *r, struct report_desc *rd, int repind) +{ + int len; + +#ifdef __DragonFly__ + len = hid_report_size(rd, r->rid, repinfo[repind].kind); +#elif __FREEBSD__ +# if (__FreeBSD_version >= 460000) +# if (__FreeBSD_version <= 500111) + len = hid_report_size(rd, r->rid, repinfo[repind].kind); +# else + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +# endif +# else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +# endif +#else +# ifdef USBHID_NEW + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +# else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +# endif +#endif + + if (len < 0) { + SDL_SetError("Negative HID report size"); + return (-1); + } + r->size = len; + + if (r->size > 0) { + r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) + + r->size); + if (r->buf == NULL) { + SDL_OutOfMemory(); + return (-1); + } + } else { + r->buf = NULL; + } + + r->status = SREPORT_CLEAN; + return (0); +} + +static void +report_free(struct report *r) +{ + if (r->buf != NULL) { + SDL_free(r->buf); + } + r->status = SREPORT_UNINIT; +} + +#endif /* SDL_JOYSTICK_USBHID */ diff --git a/distrib/sdl-1.2.12/src/joystick/darwin/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/darwin/SDL_sysjoystick.c new file mode 100644 index 0000000..8fd983e --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/darwin/SDL_sysjoystick.c @@ -0,0 +1,841 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 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 +*/ +#include "SDL_config.h" + +#ifdef SDL_JOYSTICK_IOKIT + +/* SDL joystick driver for Darwin / Mac OS X, based on the IOKit HID API */ +/* Written 2001 by Max Horn */ + +#include <unistd.h> +#include <ctype.h> +#include <sysexits.h> +#include <mach/mach.h> +#include <mach/mach_error.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/IOCFPlugIn.h> +#ifdef MACOS_10_0_4 +#include <IOKit/hidsystem/IOHIDUsageTables.h> +#else +/* The header was moved here in Mac OS X 10.1 */ +#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h> +#endif +#include <IOKit/hid/IOHIDLib.h> +#include <IOKit/hid/IOHIDKeys.h> +#include <CoreFoundation/CoreFoundation.h> +#include <Carbon/Carbon.h> /* for NewPtrClear, DisposePtr */ + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +struct recElement +{ + IOHIDElementCookie cookie; /* unique value which identifies element, will NOT change */ + long min; /* reported min value possible */ + long max; /* reported max value possible */ +#if 0 + /* TODO: maybe should handle the following stuff somehow? */ + + long scaledMin; /* reported scaled min value possible */ + long scaledMax; /* reported scaled max value possible */ + long size; /* size in bits of data return from element */ + Boolean relative; /* are reports relative to last report (deltas) */ + Boolean wrapping; /* does element wrap around (one value higher than max is min) */ + Boolean nonLinear; /* are the values reported non-linear relative to element movement */ + Boolean preferredState; /* does element have a preferred state (such as a button) */ + Boolean nullState; /* does element have null state */ +#endif /* 0 */ + + /* runtime variables used for auto-calibration */ + long minReport; /* min returned value */ + long maxReport; /* max returned value */ + + struct recElement * pNext; /* next element in list */ +}; +typedef struct recElement recElement; + +struct joystick_hwdata +{ + IOHIDDeviceInterface ** interface; /* interface to device, NULL = no interface */ + + char product[256]; /* name of product */ + long usage; /* usage page from IOUSBHID Parser.h which defines general usage */ + long usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */ + + long axes; /* number of axis (calculated, not reported by device) */ + long buttons; /* number of buttons (calculated, not reported by device) */ + long hats; /* number of hat switches (calculated, not reported by device) */ + long elements; /* number of total elements (shouldbe total of above) (calculated, not reported by device) */ + + recElement* firstAxis; + recElement* firstButton; + recElement* firstHat; + + int removed; + int uncentered; + + struct joystick_hwdata* pNext; /* next device */ +}; +typedef struct joystick_hwdata recDevice; + + +/* Linked list of all available devices */ +static recDevice *gpDeviceList = NULL; + + +static void HIDReportErrorNum (char * strError, long numError) +{ + SDL_SetError(strError); +} + +static void HIDGetCollectionElements (CFMutableDictionaryRef deviceProperties, recDevice *pDevice); + +/* returns current value for element, polling element + * will return 0 on error conditions which should be accounted for by application + */ + +static SInt32 HIDGetElementValue (recDevice *pDevice, recElement *pElement) +{ + IOReturn result = kIOReturnSuccess; + IOHIDEventStruct hidEvent; + hidEvent.value = 0; + + if (NULL != pDevice && NULL != pElement && NULL != pDevice->interface) + { + result = (*(pDevice->interface))->getElementValue(pDevice->interface, pElement->cookie, &hidEvent); + if (kIOReturnSuccess == result) + { + /* record min and max for auto calibration */ + if (hidEvent.value < pElement->minReport) + pElement->minReport = hidEvent.value; + if (hidEvent.value > pElement->maxReport) + pElement->maxReport = hidEvent.value; + } + } + + /* auto user scale */ + return hidEvent.value; +} + +static SInt32 HIDScaledCalibratedValue (recDevice *pDevice, recElement *pElement, long min, long max) +{ + float deviceScale = max - min; + float readScale = pElement->maxReport - pElement->minReport; + SInt32 value = HIDGetElementValue(pDevice, pElement); + if (readScale == 0) + return value; /* no scaling at all */ + else + return ((value - pElement->minReport) * deviceScale / readScale) + min; +} + + +static void HIDRemovalCallback(void * target, + IOReturn result, + void * refcon, + void * sender) +{ + recDevice *device = (recDevice *) refcon; + device->removed = 1; + device->uncentered = 1; +} + + + +/* Create and open an interface to device, required prior to extracting values or building queues. + * Note: appliction now owns the device and must close and release it prior to exiting + */ + +static IOReturn HIDCreateOpenDeviceInterface (io_object_t hidDevice, recDevice *pDevice) +{ + IOReturn result = kIOReturnSuccess; + HRESULT plugInResult = S_OK; + SInt32 score = 0; + IOCFPlugInInterface ** ppPlugInInterface = NULL; + + if (NULL == pDevice->interface) + { + result = IOCreatePlugInInterfaceForService (hidDevice, kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, &ppPlugInInterface, &score); + if (kIOReturnSuccess == result) + { + /* Call a method of the intermediate plug-in to create the device interface */ + plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface, + CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface)); + if (S_OK != plugInResult) + HIDReportErrorNum ("CouldnÕt query HID class device interface from plugInInterface", plugInResult); + (*ppPlugInInterface)->Release (ppPlugInInterface); + } + else + HIDReportErrorNum ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.", result); + } + if (NULL != pDevice->interface) + { + result = (*(pDevice->interface))->open (pDevice->interface, 0); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("Failed to open pDevice->interface via open.", result); + else + (*(pDevice->interface))->setRemovalCallback (pDevice->interface, HIDRemovalCallback, pDevice, pDevice); + + } + return result; +} + +/* Closes and releases interface to device, should be done prior to exting application + * Note: will have no affect if device or interface do not exist + * application will "own" the device if interface is not closed + * (device may have to be plug and re-plugged in different location to get it working again without a restart) + */ + +static IOReturn HIDCloseReleaseInterface (recDevice *pDevice) +{ + IOReturn result = kIOReturnSuccess; + + if ((NULL != pDevice) && (NULL != pDevice->interface)) + { + /* close the interface */ + result = (*(pDevice->interface))->close (pDevice->interface); + if (kIOReturnNotOpen == result) + { + /* do nothing as device was not opened, thus can't be closed */ + } + else if (kIOReturnSuccess != result) + HIDReportErrorNum ("Failed to close IOHIDDeviceInterface.", result); + /* release the interface */ + result = (*(pDevice->interface))->Release (pDevice->interface); + if (kIOReturnSuccess != result) + HIDReportErrorNum ("Failed to release IOHIDDeviceInterface.", result); + pDevice->interface = NULL; + } + return result; +} + +/* extracts actual specific element information from each element CF dictionary entry */ + +static void HIDGetElementInfo (CFTypeRef refElement, recElement *pElement) +{ + long number; + CFTypeRef refType; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementCookieKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->cookie = (IOHIDElementCookie) number; + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMinKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->minReport = pElement->min = number; + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMaxKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->maxReport = pElement->max = number; +/* + TODO: maybe should handle the following stuff somehow? + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMinKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->scaledMin = number; + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementScaledMaxKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->scaledMax = number; + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementSizeKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + pElement->size = number; + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsRelativeKey)); + if (refType) + pElement->relative = CFBooleanGetValue (refType); + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsWrappingKey)); + if (refType) + pElement->wrapping = CFBooleanGetValue (refType); + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementIsNonLinearKey)); + if (refType) + pElement->nonLinear = CFBooleanGetValue (refType); + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasPreferedStateKey)); + if (refType) + pElement->preferredState = CFBooleanGetValue (refType); + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementHasNullStateKey)); + if (refType) + pElement->nullState = CFBooleanGetValue (refType); +*/ +} + +/* examines CF dictionary vlaue in device element hierarchy to determine if it is element of interest or a collection of more elements + * if element of interest allocate storage, add to list and retrieve element specific info + * if collection then pass on to deconstruction collection into additional individual elements + */ + +static void HIDAddElement (CFTypeRef refElement, recDevice* pDevice) +{ + recElement* element = NULL; + recElement** headElement = NULL; + long elementType, usagePage, usage; + CFTypeRef refElementType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementTypeKey)); + CFTypeRef refUsagePage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsagePageKey)); + CFTypeRef refUsage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsageKey)); + + + if ((refElementType) && (CFNumberGetValue (refElementType, kCFNumberLongType, &elementType))) + { + /* look at types of interest */ + if ((elementType == kIOHIDElementTypeInput_Misc) || (elementType == kIOHIDElementTypeInput_Button) || + (elementType == kIOHIDElementTypeInput_Axis)) + { + if (refUsagePage && CFNumberGetValue (refUsagePage, kCFNumberLongType, &usagePage) && + refUsage && CFNumberGetValue (refUsage, kCFNumberLongType, &usage)) + { + switch (usagePage) /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */ + { + case kHIDPage_GenericDesktop: + { + switch (usage) /* look at usage to determine function */ + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + case kHIDUsage_GD_Slider: + case kHIDUsage_GD_Dial: + case kHIDUsage_GD_Wheel: + element = (recElement *) NewPtrClear (sizeof (recElement)); + if (element) + { + pDevice->axes++; + headElement = &(pDevice->firstAxis); + } + break; + case kHIDUsage_GD_Hatswitch: + element = (recElement *) NewPtrClear (sizeof (recElement)); + if (element) + { + pDevice->hats++; + headElement = &(pDevice->firstHat); + } + break; + } + } + break; + case kHIDPage_Button: + element = (recElement *) NewPtrClear (sizeof (recElement)); + if (element) + { + pDevice->buttons++; + headElement = &(pDevice->firstButton); + } + break; + default: + break; + } + } + } + else if (kIOHIDElementTypeCollection == elementType) + HIDGetCollectionElements ((CFMutableDictionaryRef) refElement, pDevice); + } + + if (element && headElement) /* add to list */ + { + pDevice->elements++; + if (NULL == *headElement) + *headElement = element; + else + { + recElement *elementPrevious, *elementCurrent; + elementCurrent = *headElement; + while (elementCurrent) + { + elementPrevious = elementCurrent; + elementCurrent = elementPrevious->pNext; + } + elementPrevious->pNext = element; + } + element->pNext = NULL; + HIDGetElementInfo (refElement, element); + } +} + +/* collects information from each array member in device element list (each array memeber = element) */ + +static void HIDGetElementsCFArrayHandler (const void * value, void * parameter) +{ + if (CFGetTypeID (value) == CFDictionaryGetTypeID ()) + HIDAddElement ((CFTypeRef) value, (recDevice *) parameter); +} + +/* handles retrieval of element information from arrays of elements in device IO registry information */ + +static void HIDGetElements (CFTypeRef refElementCurrent, recDevice *pDevice) +{ + CFTypeID type = CFGetTypeID (refElementCurrent); + if (type == CFArrayGetTypeID()) /* if element is an array */ + { + CFRange range = {0, CFArrayGetCount (refElementCurrent)}; + /* CountElementsCFArrayHandler called for each array member */ + CFArrayApplyFunction (refElementCurrent, range, HIDGetElementsCFArrayHandler, pDevice); + } +} + +/* handles extracting element information from element collection CF types + * used from top level element decoding and hierarchy deconstruction to flatten device element list + */ + +static void HIDGetCollectionElements (CFMutableDictionaryRef deviceProperties, recDevice *pDevice) +{ + CFTypeRef refElementTop = CFDictionaryGetValue (deviceProperties, CFSTR(kIOHIDElementKey)); + if (refElementTop) + HIDGetElements (refElementTop, pDevice); +} + +/* use top level element usage page and usage to discern device usage page and usage setting appropriate vlaues in device record */ + +static void HIDTopLevelElementHandler (const void * value, void * parameter) +{ + CFTypeRef refCF = 0; + if (CFGetTypeID (value) != CFDictionaryGetTypeID ()) + return; + refCF = CFDictionaryGetValue (value, CFSTR(kIOHIDElementUsagePageKey)); + if (!CFNumberGetValue (refCF, kCFNumberLongType, &((recDevice *) parameter)->usagePage)) + SDL_SetError ("CFNumberGetValue error retrieving pDevice->usagePage."); + refCF = CFDictionaryGetValue (value, CFSTR(kIOHIDElementUsageKey)); + if (!CFNumberGetValue (refCF, kCFNumberLongType, &((recDevice *) parameter)->usage)) + SDL_SetError ("CFNumberGetValue error retrieving pDevice->usage."); +} + +/* extracts device info from CF dictionary records in IO registry */ + +static void HIDGetDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef hidProperties, recDevice *pDevice) +{ + CFMutableDictionaryRef usbProperties = 0; + io_registry_entry_t parent1, parent2; + + /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also + * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties + */ + if ((KERN_SUCCESS == IORegistryEntryGetParentEntry (hidDevice, kIOServicePlane, &parent1)) && + (KERN_SUCCESS == IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2)) && + (KERN_SUCCESS == IORegistryEntryCreateCFProperties (parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) + { + if (usbProperties) + { + CFTypeRef refCF = 0; + /* get device info + * try hid dictionary first, if fail then go to usb dictionary + */ + + + /* get product name */ + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey)); + if (!refCF) + refCF = CFDictionaryGetValue (usbProperties, CFSTR("USB Product Name")); + if (refCF) + { + if (!CFStringGetCString (refCF, pDevice->product, 256, CFStringGetSystemEncoding ())) + SDL_SetError ("CFStringGetCString error retrieving pDevice->product."); + } + + /* get usage page and usage */ + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); + if (refCF) + { + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usagePage)) + SDL_SetError ("CFNumberGetValue error retrieving pDevice->usagePage."); + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); + if (refCF) + if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usage)) + SDL_SetError ("CFNumberGetValue error retrieving pDevice->usage."); + } + + if (NULL == refCF) /* get top level element HID usage page or usage */ + { + /* use top level element instead */ + CFTypeRef refCFTopElement = 0; + refCFTopElement = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey)); + { + /* refCFTopElement points to an array of element dictionaries */ + CFRange range = {0, CFArrayGetCount (refCFTopElement)}; + CFArrayApplyFunction (refCFTopElement, range, HIDTopLevelElementHandler, pDevice); + } + } + + CFRelease (usbProperties); + } + else + SDL_SetError ("IORegistryEntryCreateCFProperties failed to create usbProperties."); + + if (kIOReturnSuccess != IOObjectRelease (parent2)) + SDL_SetError ("IOObjectRelease error with parent2."); + if (kIOReturnSuccess != IOObjectRelease (parent1)) + SDL_SetError ("IOObjectRelease error with parent1."); + } +} + + +static recDevice *HIDBuildDevice (io_object_t hidDevice) +{ + recDevice *pDevice = (recDevice *) NewPtrClear (sizeof (recDevice)); + if (pDevice) + { + /* get dictionary for HID properties */ + CFMutableDictionaryRef hidProperties = 0; + kern_return_t result = IORegistryEntryCreateCFProperties (hidDevice, &hidProperties, kCFAllocatorDefault, kNilOptions); + if ((result == KERN_SUCCESS) && hidProperties) + { + /* create device interface */ + result = HIDCreateOpenDeviceInterface (hidDevice, pDevice); + if (kIOReturnSuccess == result) + { + HIDGetDeviceInfo (hidDevice, hidProperties, pDevice); /* hidDevice used to find parents in registry tree */ + HIDGetCollectionElements (hidProperties, pDevice); + } + else + { + DisposePtr((Ptr)pDevice); + pDevice = NULL; + } + CFRelease (hidProperties); + } + else + { + DisposePtr((Ptr)pDevice); + pDevice = NULL; + } + } + return pDevice; +} + +/* disposes of the element list associated with a device and the memory associated with the list + */ + +static void HIDDisposeElementList (recElement **elementList) +{ + recElement *pElement = *elementList; + while (pElement) + { + recElement *pElementNext = pElement->pNext; + DisposePtr ((Ptr) pElement); + pElement = pElementNext; + } + *elementList = NULL; +} + +/* disposes of a single device, closing and releaseing interface, freeing memory fro device and elements, setting device pointer to NULL + * all your device no longer belong to us... (i.e., you do not 'own' the device anymore) + */ + +static recDevice *HIDDisposeDevice (recDevice **ppDevice) +{ + kern_return_t result = KERN_SUCCESS; + recDevice *pDeviceNext = NULL; + if (*ppDevice) + { + /* save next device prior to disposing of this device */ + pDeviceNext = (*ppDevice)->pNext; + + /* free element lists */ + HIDDisposeElementList (&(*ppDevice)->firstAxis); + HIDDisposeElementList (&(*ppDevice)->firstButton); + HIDDisposeElementList (&(*ppDevice)->firstHat); + + result = HIDCloseReleaseInterface (*ppDevice); /* function sanity checks interface value (now application does not own device) */ + if (kIOReturnSuccess != result) + HIDReportErrorNum ("HIDCloseReleaseInterface failed when trying to dipose device.", result); + DisposePtr ((Ptr)*ppDevice); + *ppDevice = NULL; + } + return pDeviceNext; +} + + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * This function should return the number of available joysticks, or -1 + * on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + IOReturn result = kIOReturnSuccess; + mach_port_t masterPort = 0; + io_iterator_t hidObjectIterator = 0; + CFMutableDictionaryRef hidMatchDictionary = NULL; + recDevice *device, *lastDevice; + io_object_t ioHIDDeviceObject = 0; + + SDL_numjoysticks = 0; + + if (gpDeviceList) + { + SDL_SetError("Joystick: Device list already inited."); + return -1; + } + + result = IOMasterPort (bootstrap_port, &masterPort); + if (kIOReturnSuccess != result) + { + SDL_SetError("Joystick: IOMasterPort error with bootstrap_port."); + return -1; + } + + /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */ + hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey); + if (hidMatchDictionary) + { + /* Add key for device type (joystick, in this case) to refine the matching dictionary. */ + + /* NOTE: we now perform this filtering later + UInt32 usagePage = kHIDPage_GenericDesktop; + UInt32 usage = kHIDUsage_GD_Joystick; + CFNumberRef refUsage = NULL, refUsagePage = NULL; + + refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage); + CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage); + refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage); + CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage); + */ + } + else + { + SDL_SetError("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching."); + return -1; + } + + /*/ Now search I/O Registry for matching devices. */ + result = IOServiceGetMatchingServices (masterPort, hidMatchDictionary, &hidObjectIterator); + /* Check for errors */ + if (kIOReturnSuccess != result) + { + SDL_SetError("Joystick: Couldn't create a HID object iterator."); + return -1; + } + if (!hidObjectIterator) /* there are no joysticks */ + { + gpDeviceList = NULL; + SDL_numjoysticks = 0; + return 0; + } + /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */ + + /* build flat linked list of devices from device iterator */ + + gpDeviceList = lastDevice = NULL; + + while ((ioHIDDeviceObject = IOIteratorNext (hidObjectIterator))) + { + /* build a device record */ + device = HIDBuildDevice (ioHIDDeviceObject); + if (!device) + continue; + + /* dump device object, it is no longer needed */ + result = IOObjectRelease (ioHIDDeviceObject); +/* if (KERN_SUCCESS != result) + HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result); +*/ + + /* Filter device list to non-keyboard/mouse stuff */ + if ( (device->usagePage != kHIDPage_GenericDesktop) || + ((device->usage != kHIDUsage_GD_Joystick && + device->usage != kHIDUsage_GD_GamePad && + device->usage != kHIDUsage_GD_MultiAxisController)) ) { + + /* release memory for the device */ + HIDDisposeDevice (&device); + DisposePtr((Ptr)device); + continue; + } + + /* Add device to the end of the list */ + if (lastDevice) + lastDevice->pNext = device; + else + gpDeviceList = device; + lastDevice = device; + } + result = IOObjectRelease (hidObjectIterator); /* release the iterator */ + + /* Count the total number of devices we found */ + device = gpDeviceList; + while (device) + { + SDL_numjoysticks++; + device = device->pNext; + } + + return SDL_numjoysticks; +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + recDevice *device = gpDeviceList; + + for (; index > 0; index--) + device = device->pNext; + + return device->product; +} + +/* Function to open a joystick for use. + * The joystick to open is specified by the index field of the joystick. + * This should fill the nbuttons and naxes fields of the joystick structure. + * It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + recDevice *device = gpDeviceList; + int index; + + for (index = joystick->index; index > 0; index--) + device = device->pNext; + + joystick->hwdata = device; + joystick->name = device->product; + + joystick->naxes = device->axes; + joystick->nhats = device->hats; + joystick->nballs = 0; + joystick->nbuttons = device->buttons; + + return 0; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + recDevice *device = joystick->hwdata; + recElement *element; + SInt32 value; + int i; + + if (device->removed) /* device was unplugged; ignore it. */ + { + if (device->uncentered) + { + device->uncentered = 0; + + /* Tell the app that everything is centered/unpressed... */ + for (i = 0; i < device->axes; i++) + SDL_PrivateJoystickAxis(joystick, i, 0); + + for (i = 0; i < device->buttons; i++) + SDL_PrivateJoystickButton(joystick, i, 0); + + for (i = 0; i < device->hats; i++) + SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); + } + + return; + } + + element = device->firstAxis; + i = 0; + while (element) + { + value = HIDScaledCalibratedValue(device, element, -32768, 32767); + if ( value != joystick->axes[i] ) + SDL_PrivateJoystickAxis(joystick, i, value); + element = element->pNext; + ++i; + } + + element = device->firstButton; + i = 0; + while (element) + { + value = HIDGetElementValue(device, element); + if (value > 1) /* handle pressure-sensitive buttons */ + value = 1; + if ( value != joystick->buttons[i] ) + SDL_PrivateJoystickButton(joystick, i, value); + element = element->pNext; + ++i; + } + + element = device->firstHat; + i = 0; + while (element) + { + Uint8 pos = 0; + + value = HIDGetElementValue(device, element); + if (element->max == 3) /* 4 position hatswitch - scale up value */ + value *= 2; + else if (element->max != 7) /* Neither a 4 nor 8 positions - fall back to default position (centered) */ + value = -1; + switch(value) + { + case 0: + pos = SDL_HAT_UP; + break; + case 1: + pos = SDL_HAT_RIGHTUP; + break; + case 2: + pos = SDL_HAT_RIGHT; + break; + case 3: + pos = SDL_HAT_RIGHTDOWN; + break; + case 4: + pos = SDL_HAT_DOWN; + break; + case 5: + pos = SDL_HAT_LEFTDOWN; + break; + case 6: + pos = SDL_HAT_LEFT; + break; + case 7: + pos = SDL_HAT_LEFTUP; + break; + default: + /* Every other value is mapped to center. We do that because some + * joysticks use 8 and some 15 for this value, and apparently + * there are even more variants out there - so we try to be generous. + */ + pos = SDL_HAT_CENTERED; + break; + } + if ( pos != joystick->hats[i] ) + SDL_PrivateJoystickHat(joystick, i, pos); + element = element->pNext; + ++i; + } + + return; +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + /* Should we do anything here? */ + return; +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + while (NULL != gpDeviceList) + gpDeviceList = HIDDisposeDevice (&gpDeviceList); +} + +#endif /* SDL_JOYSTICK_IOKIT */ diff --git a/distrib/sdl-1.2.12/src/joystick/dc/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/dc/SDL_sysjoystick.c new file mode 100644 index 0000000..ac72473 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/dc/SDL_sysjoystick.c @@ -0,0 +1,193 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_DC + +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#include <dc/maple.h> +#include <dc/maple/controller.h> + +#define MAX_JOYSTICKS 8 /* only 2 are supported in the multimedia API */ +#define MAX_AXES 6 /* each joystick can have up to 6 axes */ +#define MAX_BUTTONS 8 /* and 8 buttons */ +#define MAX_HATS 2 + +#define JOYNAMELEN 8 + +/* array to hold joystick ID values */ +static uint8 SYS_Joystick_addr[MAX_JOYSTICKS]; + +/* The private structure used to keep track of a joystick */ +struct joystick_hwdata +{ + cont_cond_t prev_cond; + int prev_buttons; +}; + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + int numdevs; + + int p,u; + + numdevs = 0; + for(p=0;p<MAPLE_PORT_COUNT;p++) { + for(u=0;u<MAPLE_UNIT_COUNT;u++) { + if (maple_device_func(p,u)&MAPLE_FUNC_CONTROLLER) { + SYS_Joystick_addr[numdevs] = maple_addr(p,u); + numdevs++; + } + } + } + + return(numdevs); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + maple_device_t *dev; + if (maple_compat_resolve(SYS_Joystick_addr[index],&dev,MAPLE_FUNC_CONTROLLER)!=0) return NULL; + return dev->info.product_name; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + /* allocate memory for system specific hardware data */ + joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); + if (joystick->hwdata == NULL) + { + SDL_OutOfMemory(); + return(-1); + } + SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + + /* fill nbuttons, naxes, and nhats fields */ + joystick->nbuttons = MAX_BUTTONS; + joystick->naxes = MAX_AXES; + joystick->nhats = MAX_HATS; + return(0); +} + + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ + +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ +const int sdl_buttons[] = { + CONT_C, + CONT_B, + CONT_A, + CONT_START, + CONT_Z, + CONT_Y, + CONT_X, + CONT_D +}; + + uint8 addr; + cont_cond_t cond,*prev_cond; + int buttons,prev_buttons,i,changed; + + addr = SYS_Joystick_addr[joystick->index]; + if (cont_get_cond(addr,&cond)<0) return; + + buttons = cond.buttons; + prev_buttons = joystick->hwdata->prev_buttons; + changed = buttons^prev_buttons; + + if ((changed)&(CONT_DPAD_UP|CONT_DPAD_DOWN|CONT_DPAD_LEFT|CONT_DPAD_RIGHT)) { + int hat = SDL_HAT_CENTERED; + if (buttons&CONT_DPAD_UP) hat|=SDL_HAT_UP; + if (buttons&CONT_DPAD_DOWN) hat|=SDL_HAT_DOWN; + if (buttons&CONT_DPAD_LEFT) hat|=SDL_HAT_LEFT; + if (buttons&CONT_DPAD_RIGHT) hat|=SDL_HAT_RIGHT; + SDL_PrivateJoystickHat(joystick, 0, hat); + } + if ((changed)&(CONT_DPAD2_UP|CONT_DPAD2_DOWN|CONT_DPAD2_LEFT|CONT_DPAD2_RIGHT)) { + int hat = SDL_HAT_CENTERED; + if (buttons&CONT_DPAD2_UP) hat|=SDL_HAT_UP; + if (buttons&CONT_DPAD2_DOWN) hat|=SDL_HAT_DOWN; + if (buttons&CONT_DPAD2_LEFT) hat|=SDL_HAT_LEFT; + if (buttons&CONT_DPAD2_RIGHT) hat|=SDL_HAT_RIGHT; + SDL_PrivateJoystickHat(joystick, 1, hat); + } + + for(i=0;i<sizeof(sdl_buttons)/sizeof(sdl_buttons[0]);i++) { + if (changed & sdl_buttons[i]) { + SDL_PrivateJoystickButton(joystick, i, (buttons & sdl_buttons[i])?SDL_PRESSED:SDL_RELEASED); + } + } + + prev_cond = &joystick->hwdata->prev_cond; + if (cond.joyx!=prev_cond->joyx) + SDL_PrivateJoystickAxis(joystick, 0, cond.joyx-128); + if (cond.joyy!=prev_cond->joyy) + SDL_PrivateJoystickAxis(joystick, 1, cond.joyy-128); + if (cond.rtrig!=prev_cond->rtrig) + SDL_PrivateJoystickAxis(joystick, 2, cond.rtrig); + if (cond.ltrig!=prev_cond->ltrig) + SDL_PrivateJoystickAxis(joystick, 3, cond.ltrig); + if (cond.joy2x!=prev_cond->joy2x) + SDL_PrivateJoystickAxis(joystick, 4, cond.joy2x-128); + if (cond.joy2y!=prev_cond->joy2y) + SDL_PrivateJoystickAxis(joystick, 5, cond.joy2y-128); + + joystick->hwdata->prev_buttons = buttons; + joystick->hwdata->prev_cond = cond; +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + if (joystick->hwdata != NULL) { + /* free system specific hardware data */ + SDL_free(joystick->hwdata); + } +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + return; +} + +#endif /* SDL_JOYSTICK_DC */ diff --git a/distrib/sdl-1.2.12/src/joystick/dummy/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/dummy/SDL_sysjoystick.c new file mode 100644 index 0000000..f3209a2 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/dummy/SDL_sysjoystick.c @@ -0,0 +1,83 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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" + +#if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED) + +/* This is the system specific header for the SDL joystick API */ + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + SDL_numjoysticks = 0; + return(0); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + SDL_SetError("Logic error: No joysticks available"); + return(NULL); +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + SDL_SetError("Logic error: No joysticks available"); + return(-1); +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + return; +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + return; +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + return; +} + +#endif /* SDL_JOYSTICK_DUMMY || SDL_JOYSTICK_DISABLED */ diff --git a/distrib/sdl-1.2.12/src/joystick/linux/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/linux/SDL_sysjoystick.c new file mode 100644 index 0000000..d90bae6 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/linux/SDL_sysjoystick.c @@ -0,0 +1,1199 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_LINUX + +/* This is the system specific header for the SDL joystick API */ + +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <limits.h> /* For the definition of PATH_MAX */ +#include <linux/joystick.h> +#if SDL_INPUT_LINUXEV +#include <linux/input.h> +#endif + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +/* Special joystick configurations */ +static struct { + const char *name; + int naxes; + int nhats; + int nballs; +} special_joysticks[] = { + { "MadCatz Panther XL", 3, 2, 1 }, /* We don't handle rudder (axis 8) */ + { "SideWinder Precision Pro", 4, 1, 0 }, + { "SideWinder 3D Pro", 4, 1, 0 }, + { "Microsoft SideWinder 3D Pro", 4, 1, 0 }, + { "Microsoft SideWinder Precision Pro", 4, 1, 0 }, + { "Microsoft SideWinder Dual Strike USB version 1.0", 2, 1, 0 }, + { "WingMan Interceptor", 3, 3, 0 }, + { "WingMan Extreme Digital 3D", 4, 1, 0 }, + { "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0 }, + { "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0 }, + { "Saitek Saitek X45", 6, 1, 0 } +}; + +#ifndef NO_LOGICAL_JOYSTICKS + +/* + Some USB HIDs show up as a single joystick even though they actually + control 2 or more joysticks. +*/ +/* + This code handles the MP-8800 (Quad) and MP-8866 (Dual), which can + be identified by their transparent blue design. It's quite trivial + to add other joysticks with similar quirky behavior. + -id +*/ + +struct joystick_logical_mapping { + int njoy; + int nthing; +}; + +/* + {logical joy, logical axis}, + {logical joy, logical hat}, + {logical joy, logical ball}, + {logical joy, logical button} +*/ + +static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = { + {0,0},{0,1},{0,2},{0,3},{0,4},{0,5} +}; +static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = { + {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11} +}; + +static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = { + {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, + {1,2},{1,3},{0,4},{0,5},{1,4},{1,5} +}; +static struct joystick_logical_mapping mp88xx_2_logical_buttonmap[] = { + {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, + {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11} +}; + +static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = { + {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, + {1,2},{1,3},{2,0},{2,1},{2,2},{2,3}, + {0,4},{0,5},{1,4},{1,5},{2,4},{2,5} +}; +static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = { + {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, + {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}, + {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11} +}; + +static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = { + {0,0},{0,1},{0,2},{1,0},{1,1},{0,3}, + {1,2},{1,3},{2,0},{2,1},{2,2},{2,3}, + {3,0},{3,1},{3,2},{3,3},{0,4},{0,5}, + {1,4},{1,5},{2,4},{2,5},{3,4},{3,5} +}; +static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = { + {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}, + {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}, + {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11}, + {3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9},{3,10},{3,11} +}; + +struct joystick_logical_layout { + int naxes; + int nhats; + int nballs; + int nbuttons; +}; + +static struct joystick_logical_layout mp88xx_1_logical_layout[] = { + {6, 0, 0, 12} +}; +static struct joystick_logical_layout mp88xx_2_logical_layout[] = { + {6, 0, 0, 12}, + {6, 0, 0, 12} +}; +static struct joystick_logical_layout mp88xx_3_logical_layout[] = { + {6, 0, 0, 12}, + {6, 0, 0, 12}, + {6, 0, 0, 12} +}; +static struct joystick_logical_layout mp88xx_4_logical_layout[] = { + {6, 0, 0, 12}, + {6, 0, 0, 12}, + {6, 0, 0, 12}, + {6, 0, 0, 12} +}; + +/* + This array sets up a means of mapping a single physical joystick to + multiple logical joysticks. (djm) + + njoys + the number of logical joysticks + + layouts + an array of layout structures, one to describe each logical joystick + + axes, hats, balls, buttons + arrays that map a physical thingy to a logical thingy + */ +struct joystick_logicalmap { + const char *name; + int nbuttons; + int njoys; + struct joystick_logical_layout *layout; + struct joystick_logical_mapping *axismap; + struct joystick_logical_mapping *hatmap; + struct joystick_logical_mapping *ballmap; + struct joystick_logical_mapping *buttonmap; +}; + +static struct joystick_logicalmap joystick_logicalmap[] = { + { + "WiseGroup.,Ltd MP-8866 Dual USB Joypad", + 12, + 1, + mp88xx_1_logical_layout, + mp88xx_1_logical_axismap, + NULL, + NULL, + mp88xx_1_logical_buttonmap + }, + { + "WiseGroup.,Ltd MP-8866 Dual USB Joypad", + 24, + 2, + mp88xx_2_logical_layout, + mp88xx_2_logical_axismap, + NULL, + NULL, + mp88xx_2_logical_buttonmap + }, + { + "WiseGroup.,Ltd MP-8800 Quad USB Joypad", + 12, + 1, + mp88xx_1_logical_layout, + mp88xx_1_logical_axismap, + NULL, + NULL, + mp88xx_1_logical_buttonmap + }, + { + "WiseGroup.,Ltd MP-8800 Quad USB Joypad", + 24, + 2, + mp88xx_2_logical_layout, + mp88xx_2_logical_axismap, + NULL, + NULL, + mp88xx_2_logical_buttonmap + }, + { + "WiseGroup.,Ltd MP-8800 Quad USB Joypad", + 36, + 3, + mp88xx_3_logical_layout, + mp88xx_3_logical_axismap, + NULL, + NULL, + mp88xx_3_logical_buttonmap + }, + { + "WiseGroup.,Ltd MP-8800 Quad USB Joypad", + 48, + 4, + mp88xx_4_logical_layout, + mp88xx_4_logical_axismap, + NULL, + NULL, + mp88xx_4_logical_buttonmap + } +}; + +/* find the head of a linked list, given a point in it + */ +#define SDL_joylist_head(i, start)\ + for(i = start; SDL_joylist[i].fname == NULL;) i = SDL_joylist[i].prev; + +#define SDL_logical_joydecl(d) d + + +#else + +#define SDL_logical_joydecl(d) + +#endif /* USE_LOGICAL_JOYSTICKS */ + +/* The maximum number of joysticks we'll detect */ +#define MAX_JOYSTICKS 32 + +/* A list of available joysticks */ +static struct +{ + char* fname; +#ifndef NO_LOGICAL_JOYSTICKS + SDL_Joystick* joy; + struct joystick_logicalmap* map; + int prev; + int next; + int logicalno; +#endif /* USE_LOGICAL_JOYSTICKS */ +} SDL_joylist[MAX_JOYSTICKS]; + + +/* The private structure used to keep track of a joystick */ +struct joystick_hwdata { + int fd; + /* The current linux joystick driver maps hats to two axes */ + struct hwdata_hat { + int axis[2]; + } *hats; + /* The current linux joystick driver maps balls to two axes */ + struct hwdata_ball { + int axis[2]; + } *balls; + + /* Support for the Linux 2.4 unified input interface */ +#if SDL_INPUT_LINUXEV + SDL_bool is_hid; + Uint8 key_map[KEY_MAX-BTN_MISC]; + Uint8 abs_map[ABS_MAX]; + struct axis_correct { + int used; + int coef[3]; + } abs_correct[ABS_MAX]; +#endif +}; + + +#ifndef NO_LOGICAL_JOYSTICKS + +static int CountLogicalJoysticks(int max) +{ + register int i, j, k, ret, prev; + const char* name; + int nbuttons, fd; + unsigned char n; + + ret = 0; + + for(i = 0; i < max; i++) { + name = SDL_SYS_JoystickName(i); + + fd = open(SDL_joylist[i].fname, O_RDONLY, 0); + if ( fd >= 0 ) { + if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) { + nbuttons = -1; + } else { + nbuttons = n; + } + close(fd); + } + else { + nbuttons=-1; + } + + if (name) { + for(j = 0; j < SDL_arraysize(joystick_logicalmap); j++) { + if (!SDL_strcmp(name, joystick_logicalmap[j].name) && (nbuttons==-1 || nbuttons==joystick_logicalmap[j].nbuttons)) { + prev = i; + SDL_joylist[prev].map = &(joystick_logicalmap[j]); + + for(k = 1; k < joystick_logicalmap[j].njoys; k++) { + SDL_joylist[prev].next = max + ret; + SDL_joylist[max+ret].prev = prev; + + prev = max + ret; + SDL_joylist[prev].logicalno = k; + SDL_joylist[prev].map = &(joystick_logicalmap[j]); + ret++; + } + + break; + } + } + } + } + + return ret; +} + +static void LogicalSuffix(int logicalno, char* namebuf, int len) +{ + register int slen; + const static char suffixs[] = + "01020304050607080910111213141516171819" + "20212223242526272829303132"; + const char* suffix; + slen = SDL_strlen(namebuf); + suffix = NULL; + + if (logicalno*2<sizeof(suffixs)) + suffix = suffixs + (logicalno*2); + + if (slen + 4 < len && suffix) { + namebuf[slen++] = ' '; + namebuf[slen++] = '#'; + namebuf[slen++] = suffix[0]; + namebuf[slen++] = suffix[1]; + namebuf[slen++] = 0; + } +} + +#endif /* USE_LOGICAL_JOYSTICKS */ + +#if SDL_INPUT_LINUXEV +#define test_bit(nr, addr) \ + (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0) + +static int EV_IsJoystick(int fd) +{ + unsigned long evbit[40]; + unsigned long keybit[40]; + unsigned long absbit[40]; + + if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) { + return(0); + } + if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) && + test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) && + (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0; + return(1); +} + +#endif /* SDL_INPUT_LINUXEV */ + +/* Function to scan the system for joysticks */ +int SDL_SYS_JoystickInit(void) +{ + /* The base path of the joystick devices */ + const char *joydev_pattern[] = { +#if SDL_INPUT_LINUXEV + "/dev/input/event%d", +#endif + "/dev/input/js%d", + "/dev/js%d" + }; + int numjoysticks; + int i, j; + int fd; + char path[PATH_MAX]; + dev_t dev_nums[MAX_JOYSTICKS]; /* major/minor device numbers */ + struct stat sb; + int n, duplicate; + + numjoysticks = 0; + + /* First see if the user specified a joystick to use */ + if ( SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL ) { + SDL_strlcpy(path, SDL_getenv("SDL_JOYSTICK_DEVICE"), sizeof(path)); + if ( stat(path, &sb) == 0 ) { + fd = open(path, O_RDONLY, 0); + if ( fd >= 0 ) { + /* Assume the user knows what they're doing. */ + SDL_joylist[numjoysticks].fname = SDL_strdup(path); + if ( SDL_joylist[numjoysticks].fname ) { + dev_nums[numjoysticks] = sb.st_rdev; + ++numjoysticks; + } + close(fd); + } + } + } + + for ( i=0; i<SDL_arraysize(joydev_pattern); ++i ) { + for ( j=0; j < MAX_JOYSTICKS; ++j ) { + SDL_snprintf(path, SDL_arraysize(path), joydev_pattern[i], j); + + /* rcg06302000 replaced access(F_OK) call with stat(). + * stat() will fail if the file doesn't exist, so it's + * equivalent behaviour. + */ + if ( stat(path, &sb) == 0 ) { + /* Check to make sure it's not already in list. + * This happens when we see a stick via symlink. + */ + duplicate = 0; + for (n=0; (n<numjoysticks) && !duplicate; ++n) { + if ( sb.st_rdev == dev_nums[n] ) { + duplicate = 1; + } + } + if (duplicate) { + continue; + } + + fd = open(path, O_RDONLY, 0); + if ( fd < 0 ) { + continue; + } +#if SDL_INPUT_LINUXEV +#ifdef DEBUG_INPUT_EVENTS + printf("Checking %s\n", path); +#endif + if ( (i == 0) && ! EV_IsJoystick(fd) ) { + close(fd); + continue; + } +#endif + close(fd); + + /* We're fine, add this joystick */ + SDL_joylist[numjoysticks].fname = SDL_strdup(path); + if ( SDL_joylist[numjoysticks].fname ) { + dev_nums[numjoysticks] = sb.st_rdev; + ++numjoysticks; + } + } else + break; + } + +#if SDL_INPUT_LINUXEV + /* This is a special case... + If the event devices are valid then the joystick devices + will be duplicates but without extra information about their + hats or balls. Unfortunately, the event devices can't + currently be calibrated, so it's a win-lose situation. + So : /dev/input/eventX = /dev/input/jsY = /dev/jsY + */ + if ( (i == 0) && (numjoysticks > 0) ) + break; +#endif + } +#ifndef NO_LOGICAL_JOYSTICKS + numjoysticks += CountLogicalJoysticks(numjoysticks); +#endif + + return(numjoysticks); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + int fd; + static char namebuf[128]; + char *name; + SDL_logical_joydecl(int oindex = index); + +#ifndef NO_LOGICAL_JOYSTICKS + SDL_joylist_head(index, index); +#endif + name = NULL; + fd = open(SDL_joylist[index].fname, O_RDONLY, 0); + if ( fd >= 0 ) { + if ( +#if SDL_INPUT_LINUXEV + (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) && +#endif + (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) { + name = SDL_joylist[index].fname; + } else { + name = namebuf; + } + close(fd); + + +#ifndef NO_LOGICAL_JOYSTICKS + if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next || index!=oindex) + { + LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128); + } +#endif + } + return name; +} + +static int allocate_hatdata(SDL_Joystick *joystick) +{ + int i; + + joystick->hwdata->hats = (struct hwdata_hat *)SDL_malloc( + joystick->nhats * sizeof(struct hwdata_hat)); + if ( joystick->hwdata->hats == NULL ) { + return(-1); + } + for ( i=0; i<joystick->nhats; ++i ) { + joystick->hwdata->hats[i].axis[0] = 1; + joystick->hwdata->hats[i].axis[1] = 1; + } + return(0); +} + +static int allocate_balldata(SDL_Joystick *joystick) +{ + int i; + + joystick->hwdata->balls = (struct hwdata_ball *)SDL_malloc( + joystick->nballs * sizeof(struct hwdata_ball)); + if ( joystick->hwdata->balls == NULL ) { + return(-1); + } + for ( i=0; i<joystick->nballs; ++i ) { + joystick->hwdata->balls[i].axis[0] = 0; + joystick->hwdata->balls[i].axis[1] = 0; + } + return(0); +} + +static SDL_bool JS_ConfigJoystick(SDL_Joystick *joystick, int fd) +{ + SDL_bool handled; + unsigned char n; + int old_axes, tmp_naxes, tmp_nhats, tmp_nballs; + const char *name; + char *env, env_name[128]; + int i; + + handled = SDL_FALSE; + + /* Default joystick device settings */ + if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) { + joystick->naxes = 2; + } else { + joystick->naxes = n; + } + if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) { + joystick->nbuttons = 2; + } else { + joystick->nbuttons = n; + } + + name = SDL_SYS_JoystickName(joystick->index); + old_axes = joystick->naxes; + + /* Generic analog joystick support */ + if ( SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat") ) { + if ( SDL_sscanf(name,"Analog %d-axis %*d-button %d-hat", + &tmp_naxes, &tmp_nhats) == 2 ) { + + joystick->naxes = tmp_naxes; + joystick->nhats = tmp_nhats; + + handled = SDL_TRUE; + } + } + + /* Special joystick support */ + for ( i=0; i < SDL_arraysize(special_joysticks); ++i ) { + if ( SDL_strcmp(name, special_joysticks[i].name) == 0 ) { + + joystick->naxes = special_joysticks[i].naxes; + joystick->nhats = special_joysticks[i].nhats; + joystick->nballs = special_joysticks[i].nballs; + + handled = SDL_TRUE; + break; + } + } + + /* User environment joystick support */ + if ( (env = SDL_getenv("SDL_LINUX_JOYSTICK")) ) { + *env_name = '\0'; + if ( *env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1 ) + env += SDL_strlen(env_name)+2; + else if ( SDL_sscanf(env, "%s", env_name) == 1 ) + env += SDL_strlen(env_name); + + if ( SDL_strcmp(name, env_name) == 0 ) { + + if ( SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats, + &tmp_nballs) == 3 ) { + + joystick->naxes = tmp_naxes; + joystick->nhats = tmp_nhats; + joystick->nballs = tmp_nballs; + + handled = SDL_TRUE; + } + } + } + + /* Remap hats and balls */ + if (handled) { + if ( joystick->nhats > 0 ) { + if ( allocate_hatdata(joystick) < 0 ) { + joystick->nhats = 0; + } + } + if ( joystick->nballs > 0 ) { + if ( allocate_balldata(joystick) < 0 ) { + joystick->nballs = 0; + } + } + } + + return(handled); +} + +#if SDL_INPUT_LINUXEV + +static SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd) +{ + int i, t; + unsigned long keybit[40]; + unsigned long absbit[40]; + unsigned long relbit[40]; + + /* See if this device uses the new unified event API */ + if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && + (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) && + (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) { + joystick->hwdata->is_hid = SDL_TRUE; + + /* Get the number of buttons, axes, and other thingamajigs */ + for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) { + if ( test_bit(i, keybit) ) { +#ifdef DEBUG_INPUT_EVENTS + printf("Joystick has button: 0x%x\n", i); +#endif + joystick->hwdata->key_map[i-BTN_MISC] = + joystick->nbuttons; + ++joystick->nbuttons; + } + } + for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) { + if ( test_bit(i, keybit) ) { +#ifdef DEBUG_INPUT_EVENTS + printf("Joystick has button: 0x%x\n", i); +#endif + joystick->hwdata->key_map[i-BTN_MISC] = + joystick->nbuttons; + ++joystick->nbuttons; + } + } + for ( i=0; i<ABS_MAX; ++i ) { + /* Skip hats */ + if ( i == ABS_HAT0X ) { + i = ABS_HAT3Y; + continue; + } + if ( test_bit(i, absbit) ) { + int values[5]; + + if ( ioctl(fd, EVIOCGABS(i), values) < 0 ) + continue; +#ifdef DEBUG_INPUT_EVENTS + printf("Joystick has absolute axis: %x\n", i); + printf("Values = { %d, %d, %d, %d, %d }\n", + values[0], values[1], + values[2], values[3], values[4]); +#endif /* DEBUG_INPUT_EVENTS */ + joystick->hwdata->abs_map[i] = joystick->naxes; + if ( values[1] == values[2] ) { + joystick->hwdata->abs_correct[i].used = 0; + } else { + joystick->hwdata->abs_correct[i].used = 1; + joystick->hwdata->abs_correct[i].coef[0] = + (values[2] + values[1]) / 2 - values[4]; + joystick->hwdata->abs_correct[i].coef[1] = + (values[2] + values[1]) / 2 + values[4]; + t = ((values[2] - values[1]) / 2 - 2 * values[4]); + if ( t != 0 ) { + joystick->hwdata->abs_correct[i].coef[2] = (1 << 29) / t; + } else { + joystick->hwdata->abs_correct[i].coef[2] = 0; + } + } + ++joystick->naxes; + } + } + for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) { + if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) { +#ifdef DEBUG_INPUT_EVENTS + printf("Joystick has hat %d\n",(i-ABS_HAT0X)/2); +#endif + ++joystick->nhats; + } + } + if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) { + ++joystick->nballs; + } + + /* Allocate data to keep track of these thingamajigs */ + if ( joystick->nhats > 0 ) { + if ( allocate_hatdata(joystick) < 0 ) { + joystick->nhats = 0; + } + } + if ( joystick->nballs > 0 ) { + if ( allocate_balldata(joystick) < 0 ) { + joystick->nballs = 0; + } + } + } + return(joystick->hwdata->is_hid); +} + +#endif /* SDL_INPUT_LINUXEV */ + +#ifndef NO_LOGICAL_JOYSTICKS +static void ConfigLogicalJoystick(SDL_Joystick *joystick) +{ + struct joystick_logical_layout* layout; + + layout = SDL_joylist[joystick->index].map->layout + + SDL_joylist[joystick->index].logicalno; + + joystick->nbuttons = layout->nbuttons; + joystick->nhats = layout->nhats; + joystick->naxes = layout->naxes; + joystick->nballs = layout->nballs; +} +#endif + + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + int fd; + SDL_logical_joydecl(int realindex); + SDL_logical_joydecl(SDL_Joystick *realjoy = NULL); + + /* Open the joystick and set the joystick file descriptor */ +#ifndef NO_LOGICAL_JOYSTICKS + if (SDL_joylist[joystick->index].fname == NULL) { + SDL_joylist_head(realindex, joystick->index); + realjoy = SDL_JoystickOpen(realindex); + + if (realjoy == NULL) + return(-1); + + fd = realjoy->hwdata->fd; + + } else { + fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); + } + SDL_joylist[joystick->index].joy = joystick; +#else + fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0); +#endif + + if ( fd < 0 ) { + SDL_SetError("Unable to open %s\n", + SDL_joylist[joystick->index]); + return(-1); + } + joystick->hwdata = (struct joystick_hwdata *) + SDL_malloc(sizeof(*joystick->hwdata)); + if ( joystick->hwdata == NULL ) { + SDL_OutOfMemory(); + close(fd); + return(-1); + } + SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + joystick->hwdata->fd = fd; + + /* Set the joystick to non-blocking read mode */ + fcntl(fd, F_SETFL, O_NONBLOCK); + + /* Get the number of buttons and axes on the joystick */ +#ifndef NO_LOGICAL_JOYSTICKS + if (realjoy) + ConfigLogicalJoystick(joystick); + else +#endif +#if SDL_INPUT_LINUXEV + if ( ! EV_ConfigJoystick(joystick, fd) ) +#endif + JS_ConfigJoystick(joystick, fd); + + return(0); +} + +#ifndef NO_LOGICAL_JOYSTICKS + +static SDL_Joystick* FindLogicalJoystick( + SDL_Joystick *joystick, struct joystick_logical_mapping* v) +{ + SDL_Joystick *logicaljoy; + register int i; + + i = joystick->index; + logicaljoy = NULL; + + /* get the fake joystick that will receive the event + */ + for(;;) { + + if (SDL_joylist[i].logicalno == v->njoy) { + logicaljoy = SDL_joylist[i].joy; + break; + } + + if (SDL_joylist[i].next == 0) + break; + + i = SDL_joylist[i].next; + + } + + return logicaljoy; +} + +static int LogicalJoystickButton( + SDL_Joystick *joystick, Uint8 button, Uint8 state){ + struct joystick_logical_mapping* buttons; + SDL_Joystick *logicaljoy = NULL; + + /* if there's no map then this is just a regular joystick + */ + if (SDL_joylist[joystick->index].map == NULL) + return 0; + + /* get the logical joystick that will receive the event + */ + buttons = SDL_joylist[joystick->index].map->buttonmap+button; + logicaljoy = FindLogicalJoystick(joystick, buttons); + + if (logicaljoy == NULL) + return 1; + + SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state); + + return 1; +} + +static int LogicalJoystickAxis( + SDL_Joystick *joystick, Uint8 axis, Sint16 value) +{ + struct joystick_logical_mapping* axes; + SDL_Joystick *logicaljoy = NULL; + + /* if there's no map then this is just a regular joystick + */ + if (SDL_joylist[joystick->index].map == NULL) + return 0; + + /* get the logical joystick that will receive the event + */ + axes = SDL_joylist[joystick->index].map->axismap+axis; + logicaljoy = FindLogicalJoystick(joystick, axes); + + if (logicaljoy == NULL) + return 1; + + SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value); + + return 1; +} +#endif /* USE_LOGICAL_JOYSTICKS */ + +static __inline__ +void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value) +{ + struct hwdata_hat *the_hat; + const Uint8 position_map[3][3] = { + { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, + { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, + { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } + }; + SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL); + SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL); + + the_hat = &stick->hwdata->hats[hat]; + if ( value < 0 ) { + value = 0; + } else + if ( value == 0 ) { + value = 1; + } else + if ( value > 0 ) { + value = 2; + } + if ( value != the_hat->axis[axis] ) { + the_hat->axis[axis] = value; + +#ifndef NO_LOGICAL_JOYSTICKS + /* if there's no map then this is just a regular joystick + */ + if (SDL_joylist[stick->index].map != NULL) { + + /* get the fake joystick that will receive the event + */ + hats = SDL_joylist[stick->index].map->hatmap+hat; + logicaljoy = FindLogicalJoystick(stick, hats); + } + + if (logicaljoy) { + stick = logicaljoy; + hat = hats->nthing; + } +#endif /* USE_LOGICAL_JOYSTICKS */ + + SDL_PrivateJoystickHat(stick, hat, + position_map[the_hat->axis[1]][the_hat->axis[0]]); + } +} + +static __inline__ +void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value) +{ + stick->hwdata->balls[ball].axis[axis] += value; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +static __inline__ void JS_HandleEvents(SDL_Joystick *joystick) +{ + struct js_event events[32]; + int i, len; + Uint8 other_axis; + +#ifndef NO_LOGICAL_JOYSTICKS + if (SDL_joylist[joystick->index].fname == NULL) { + SDL_joylist_head(i, joystick->index); + JS_HandleEvents(SDL_joylist[i].joy); + return; + } +#endif + + while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { + len /= sizeof(events[0]); + for ( i=0; i<len; ++i ) { + switch (events[i].type & ~JS_EVENT_INIT) { + case JS_EVENT_AXIS: + if ( events[i].number < joystick->naxes ) { +#ifndef NO_LOGICAL_JOYSTICKS + if (!LogicalJoystickAxis(joystick, + events[i].number, events[i].value)) +#endif + SDL_PrivateJoystickAxis(joystick, + events[i].number, events[i].value); + break; + } + events[i].number -= joystick->naxes; + other_axis = (events[i].number / 2); + if ( other_axis < joystick->nhats ) { + HandleHat(joystick, other_axis, + events[i].number%2, + events[i].value); + break; + } + events[i].number -= joystick->nhats*2; + other_axis = (events[i].number / 2); + if ( other_axis < joystick->nballs ) { + HandleBall(joystick, other_axis, + events[i].number%2, + events[i].value); + break; + } + break; + case JS_EVENT_BUTTON: +#ifndef NO_LOGICAL_JOYSTICKS + if (!LogicalJoystickButton(joystick, + events[i].number, events[i].value)) +#endif + SDL_PrivateJoystickButton(joystick, + events[i].number, events[i].value); + break; + default: + /* ?? */ + break; + } + } + } +} +#if SDL_INPUT_LINUXEV +static __inline__ int EV_AxisCorrect(SDL_Joystick *joystick, int which, int value) +{ + struct axis_correct *correct; + + correct = &joystick->hwdata->abs_correct[which]; + if ( correct->used ) { + if ( value > correct->coef[0] ) { + if ( value < correct->coef[1] ) { + return 0; + } + value -= correct->coef[1]; + } else { + value -= correct->coef[0]; + } + value *= correct->coef[2]; + value >>= 14; + } + + /* Clamp and return */ + if ( value < -32768 ) return -32768; + if ( value > 32767 ) return 32767; + + return value; +} + +static __inline__ void EV_HandleEvents(SDL_Joystick *joystick) +{ + struct input_event events[32]; + int i, len; + int code; + +#ifndef NO_LOGICAL_JOYSTICKS + if (SDL_joylist[joystick->index].fname == NULL) { + SDL_joylist_head(i, joystick->index); + return EV_HandleEvents(SDL_joylist[i].joy); + } +#endif + + while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) { + len /= sizeof(events[0]); + for ( i=0; i<len; ++i ) { + code = events[i].code; + switch (events[i].type) { + case EV_KEY: + if ( code >= BTN_MISC ) { + code -= BTN_MISC; +#ifndef NO_LOGICAL_JOYSTICKS + if (!LogicalJoystickButton(joystick, + joystick->hwdata->key_map[code], + events[i].value)) +#endif + SDL_PrivateJoystickButton(joystick, + joystick->hwdata->key_map[code], + events[i].value); + } + break; + case EV_ABS: + switch (code) { + case ABS_HAT0X: + case ABS_HAT0Y: + case ABS_HAT1X: + case ABS_HAT1Y: + case ABS_HAT2X: + case ABS_HAT2Y: + case ABS_HAT3X: + case ABS_HAT3Y: + code -= ABS_HAT0X; + HandleHat(joystick, code/2, code%2, + events[i].value); + break; + default: + events[i].value = EV_AxisCorrect(joystick, code, events[i].value); +#ifndef NO_LOGICAL_JOYSTICKS + if (!LogicalJoystickAxis(joystick, + joystick->hwdata->abs_map[code], + events[i].value)) +#endif + SDL_PrivateJoystickAxis(joystick, + joystick->hwdata->abs_map[code], + events[i].value); + break; + } + break; + case EV_REL: + switch (code) { + case REL_X: + case REL_Y: + code -= REL_X; + HandleBall(joystick, code/2, code%2, + events[i].value); + break; + default: + break; + } + break; + default: + break; + } + } + } +} +#endif /* SDL_INPUT_LINUXEV */ + +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + int i; + +#if SDL_INPUT_LINUXEV + if ( joystick->hwdata->is_hid ) + EV_HandleEvents(joystick); + else +#endif + JS_HandleEvents(joystick); + + /* Deliver ball motion updates */ + for ( i=0; i<joystick->nballs; ++i ) { + int xrel, yrel; + + xrel = joystick->hwdata->balls[i].axis[0]; + yrel = joystick->hwdata->balls[i].axis[1]; + if ( xrel || yrel ) { + joystick->hwdata->balls[i].axis[0] = 0; + joystick->hwdata->balls[i].axis[1] = 0; + SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel); + } + } +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ +#ifndef NO_LOGICAL_JOYSTICKS + register int i; + if (SDL_joylist[joystick->index].fname == NULL) { + SDL_joylist_head(i, joystick->index); + SDL_JoystickClose(SDL_joylist[i].joy); + } +#endif + + if ( joystick->hwdata ) { +#ifndef NO_LOGICAL_JOYSTICKS + if (SDL_joylist[joystick->index].fname != NULL) +#endif + close(joystick->hwdata->fd); + if ( joystick->hwdata->hats ) { + SDL_free(joystick->hwdata->hats); + } + if ( joystick->hwdata->balls ) { + SDL_free(joystick->hwdata->balls); + } + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + } +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + int i; + + for ( i=0; SDL_joylist[i].fname; ++i ) { + SDL_free(SDL_joylist[i].fname); + } + SDL_joylist[0].fname = NULL; +} + +#endif /* SDL_JOYSTICK_LINUX */ diff --git a/distrib/sdl-1.2.12/src/joystick/macos/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/macos/SDL_sysjoystick.c new file mode 100644 index 0000000..25609b3 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/macos/SDL_sysjoystick.c @@ -0,0 +1,320 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_MACOS + +/* SDL stuff -- "SDL_sysjoystick.c" + MacOS joystick functions by Frederick Reitberger + + The code that follows is meant for SDL. Use at your own risk. +*/ + +#include <InputSprocket.h> + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + + +/* The max number of joysticks we will detect */ +#define MAX_JOYSTICKS 16 +/* Limit ourselves to 32 elements per device */ +#define kMaxReferences 32 + +#define ISpSymmetricAxisToFloat(axis) ((((float) axis) - kISpAxisMiddle) / (kISpAxisMaximum-kISpAxisMiddle)) +#define ISpAsymmetricAxisToFloat(axis) (((float) axis) / (kISpAxisMaximum)) + + +static ISpDeviceReference SYS_Joysticks[MAX_JOYSTICKS]; +static ISpElementListReference SYS_Elements[MAX_JOYSTICKS]; +static ISpDeviceDefinition SYS_DevDef[MAX_JOYSTICKS]; + +struct joystick_hwdata +{ + char name[64]; +/* Uint8 id;*/ + ISpElementReference refs[kMaxReferences]; + /* gonna need some sort of mapping info */ +}; + + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * This function should return the number of available joysticks, or -1 + * on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + static ISpDeviceClass classes[4] = { + kISpDeviceClass_Joystick, + #if kISpDeviceClass_Gamepad + kISpDeviceClass_Gamepad, + #endif + kISpDeviceClass_Wheel, + 0 + }; + OSErr err; + int i; + UInt32 count, numJoysticks; + + if ( (Ptr)0 == (Ptr)ISpStartup ) { + SDL_SetError("InputSprocket not installed"); + return -1; // InputSprocket not installed + } + + if( (Ptr)0 == (Ptr)ISpGetVersion ) { + SDL_SetError("InputSprocket not version 1.1 or newer"); + return -1; // old version of ISp (not at least 1.1) + } + + ISpStartup(); + + /* Get all the joysticks */ + numJoysticks = 0; + for ( i=0; classes[i]; ++i ) { + count = 0; + err = ISpDevices_ExtractByClass( + classes[i], + MAX_JOYSTICKS-numJoysticks, + &count, + &SYS_Joysticks[numJoysticks]); + numJoysticks += count; + } + + for(i = 0; i < numJoysticks; i++) + { + ISpDevice_GetDefinition( + SYS_Joysticks[i], sizeof(ISpDeviceDefinition), + &SYS_DevDef[i]); + + err = ISpElementList_New( + 0, NULL, + &SYS_Elements[i], 0); + + if (err) { + SDL_OutOfMemory(); + return -1; + } + + ISpDevice_GetElementList( + SYS_Joysticks[i], + &SYS_Elements[i]); + } + + ISpDevices_Deactivate(numJoysticks, SYS_Joysticks); + + return numJoysticks; +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + static char name[64]; + int len; + + /* convert pascal string to c-string */ + len = SYS_DevDef[index].deviceName[0]; + if ( len >= sizeof(name) ) { + len = (sizeof(name) - 1); + } + SDL_memcpy(name, &SYS_DevDef[index].deviceName[1], len); + name[len] = '\0'; + + return name; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + int index; + UInt32 count, gotCount, count2; + long numAxis, numButtons, numHats, numBalls; + + count = kMaxReferences; + count2 = 0; + numAxis = numButtons = numHats = numBalls = 0; + + index = joystick->index; + + /* allocate memory for system specific hardware data */ + joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); + if (joystick->hwdata == NULL) + { + SDL_OutOfMemory(); + return(-1); + } + SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + SDL_strlcpy(joystick->hwdata->name, SDL_SYS_JoystickName(index), SDL_arraysize(joystick->hwdata->name)); + joystick->name = joystick->hwdata->name; + + ISpElementList_ExtractByKind( + SYS_Elements[index], + kISpElementKind_Axis, + count, + &gotCount, + joystick->hwdata->refs); + + numAxis = gotCount; + count -= gotCount; + count2 += gotCount; + + ISpElementList_ExtractByKind( + SYS_Elements[index], + kISpElementKind_DPad, + count, + &gotCount, + &(joystick->hwdata->refs[count2])); + + numHats = gotCount; + count -= gotCount; + count2 += gotCount; + + ISpElementList_ExtractByKind( + SYS_Elements[index], + kISpElementKind_Button, + count, + &gotCount, + &(joystick->hwdata->refs[count2])); + + numButtons = gotCount; + count -= gotCount; + count2 += gotCount; + + joystick->naxes = numAxis; + joystick->nhats = numHats; + joystick->nballs = numBalls; + joystick->nbuttons = numButtons; + + ISpDevices_Activate( + 1, + &SYS_Joysticks[index]); + + return 0; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + int i, j; + ISpAxisData a; + ISpDPadData b; + //ISpDeltaData c; + ISpButtonData d; + + for(i = 0, j = 0; i < joystick->naxes; i++, j++) + { + Sint16 value; + + ISpElement_GetSimpleState( + joystick->hwdata->refs[j], + &a); + value = (ISpSymmetricAxisToFloat(a)* 32767.0); + if ( value != joystick->axes[i] ) { + SDL_PrivateJoystickAxis(joystick, i, value); + } + } + + for(i = 0; i < joystick->nhats; i++, j++) + { + Uint8 pos; + + ISpElement_GetSimpleState( + joystick->hwdata->refs[j], + &b); + switch(b) { + case kISpPadIdle: + pos = SDL_HAT_CENTERED; + break; + case kISpPadLeft: + pos = SDL_HAT_LEFT; + break; + case kISpPadUpLeft: + pos = SDL_HAT_LEFTUP; + break; + case kISpPadUp: + pos = SDL_HAT_UP; + break; + case kISpPadUpRight: + pos = SDL_HAT_RIGHTUP; + break; + case kISpPadRight: + pos = SDL_HAT_RIGHT; + break; + case kISpPadDownRight: + pos = SDL_HAT_RIGHTDOWN; + break; + case kISpPadDown: + pos = SDL_HAT_DOWN; + break; + case kISpPadDownLeft: + pos = SDL_HAT_LEFTDOWN; + break; + } + if ( pos != joystick->hats[i] ) { + SDL_PrivateJoystickHat(joystick, i, pos); + } + } + + for(i = 0; i < joystick->nballs; i++, j++) + { + /* ignore balls right now */ + } + + for(i = 0; i < joystick->nbuttons; i++, j++) + { + ISpElement_GetSimpleState( + joystick->hwdata->refs[j], + &d); + if ( d != joystick->buttons[i] ) { + SDL_PrivateJoystickButton(joystick, i, d); + } + } +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + int index; + + index = joystick->index; + + ISpDevices_Deactivate( + 1, + &SYS_Joysticks[index]); +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + ISpShutdown(); +} + +#endif /* SDL_JOYSTICK_MACOS */ diff --git a/distrib/sdl-1.2.12/src/joystick/mint/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/mint/SDL_sysjoystick.c new file mode 100644 index 0000000..364e568 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/mint/SDL_sysjoystick.c @@ -0,0 +1,683 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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) + +/*--- 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,"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; + +/* 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; + unsigned 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)) { + 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 only on STE and Falcon */ + if ((cookie_mch == MCH_STE<<16) || (cookie_mch == MCH_F30<<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); +} + +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; + + numjoypad = 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; break; + case PORTB_PAD1: + numjoypad = 5; break; + case PORTB_PAD2: + numjoypad = 6; break; + case PORTB_PAD3: + numjoypad = 7; break; + } + + 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 */ diff --git a/distrib/sdl-1.2.12/src/joystick/os2/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/os2/SDL_sysjoystick.c new file mode 100644 index 0000000..15dca4e --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/os2/SDL_sysjoystick.c @@ -0,0 +1,668 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_OS2 + +/* OS/2 Joystick driver, contributed by Daniel Caetano */ + +#include <mem.h> + +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#define INCL_DOSMEMMGR +#include <os2.h> +#include "joyos2.h" + +#include "SDL_joystick.h" +#include "SDL_events.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +HFILE hJoyPort = NULL; /* Joystick GAME$ Port Address */ +#define MAX_JOYSTICKS 2 /* Maximum of two joysticks */ +#define MAX_AXES 4 /* each joystick can have up to 4 axes */ +#define MAX_BUTTONS 8 /* 8 buttons */ +#define MAX_HATS 0 /* 0 hats - OS/2 doesn't support it */ +#define MAX_BALLS 0 /* and 0 balls - OS/2 doesn't support it */ +#define AXIS_MIN -32768 /* minimum value for axes coordinate */ +#define AXIS_MAX 32767 /* maximum value for axes coordinate */ +#define MAX_JOYNAME 128 /* Joystick name may have 128 characters */ +/* limit axes to 256 possible positions to filter out noise */ +#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256) +/* Calc Button Flag for buttons A to D */ +#define JOY_BUTTON_FLAG(n) (1<<n) + +/* Joystick data... hold information about detected devices */ +typedef struct SYS_JoyData_s +{ +Sint8 id; // Device ID +char szDeviceName[MAX_JOYNAME]; // Device Name +char axes; // Number of axes +char buttons; // Number of buttons +char hats; // Number of buttons +char balls; // Number of buttons +int axes_min[MAX_AXES]; // minimum callibration value for axes +int axes_med[MAX_AXES]; // medium callibration value for axes +int axes_max[MAX_AXES]; // maximum callibration value for axes +int buttoncalc[4]; // Used for buttons 5, 6, 7 and 8. +} SYS_JoyData_t, *SYS_JoyData_p; + +SYS_JoyData_t SYS_JoyData[MAX_JOYSTICKS]; + + +/* Structure used to convert data from OS/2 driver format to SDL format */ +struct joystick_hwdata +{ +Sint8 id; +struct _transaxes + { + int offset; /* Center Offset */ + float scale1; /* Center to left/up Scale */ + float scale2; /* Center to right/down Scale */ + } transaxes[MAX_AXES]; +}; + +/* Structure used to get values from Joystick Environment Variable */ +struct _joycfg +{ +char name[MAX_JOYNAME]; +unsigned int axes; +unsigned int buttons; +unsigned int hats; +unsigned int balls; +}; + +/* OS/2 Implementation Function Prototypes */ +APIRET joyPortOpen(HFILE * hGame); +void joyPortClose(HFILE * hGame); +int joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars); +int joyGetEnv(struct _joycfg * joydata); + + + +/************************************************************************/ +/* Function to scan the system for joysticks. */ +/* This function should set SDL_numjoysticks to the number of available */ +/* joysticks. Joystick 0 should be the system default joystick. */ +/* It should return 0, or -1 on an unrecoverable fatal error. */ +/************************************************************************/ +int SDL_SYS_JoystickInit(void) +{ +APIRET rc; /* Generic OS/2 return code */ +GAME_PORT_STRUCT stJoyStatus; /* Joystick Status Structure */ +GAME_PARM_STRUCT stGameParms; /* Joystick Parameter Structure */ +GAME_CALIB_STRUCT stGameCalib; /* Calibration Struct */ +ULONG ulDataLen; /* Size of data */ +ULONG ulLastTick; /* Tick Counter for timing operations */ +Uint8 maxdevs; /* Maximum number of devices */ +Uint8 numdevs; /* Number of present devices */ +Uint8 maxbut; /* Maximum number of buttons... */ +Uint8 i; /* Temporary Count Vars */ +Uint8 ucNewJoystickMask; /* Mask for Joystick Detection */ +struct _joycfg joycfg; /* Joy Configuration from envvar */ + + +/* Get Max Number of Devices */ +rc = joyPortOpen(&hJoyPort); /* Open GAME$ port */ +if (rc != 0) return 0; /* Cannot open... report no joystick */ +ulDataLen = sizeof(stGameParms); +rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_PARMS, + NULL, 0, NULL, &stGameParms, ulDataLen, &ulDataLen); /* Ask device info */ +if (rc != 0) + { + joyPortClose(&hJoyPort); + SDL_SetError("Could not read joystick port."); + return -1; + } +if (stGameParms.useA != 0) maxdevs++; +if (stGameParms.useB != 0) maxdevs++; +if ( maxdevs > MAX_JOYSTICKS ) maxdevs = MAX_JOYSTICKS; + +/* Defines min/max axes values (callibration) */ +ulDataLen = sizeof(stGameCalib); +rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_CALIB, + NULL, 0, NULL, &stGameCalib, ulDataLen, &ulDataLen); +if (rc != 0) + { + joyPortClose(&hJoyPort); + SDL_SetError("Could not read callibration data."); + return -1; + } + +/* Determine how many joysticks are active */ +numdevs = 0; /* Points no device */ +ucNewJoystickMask = 0x0F; /* read all 4 joystick axis */ +ulDataLen = sizeof(ucNewJoystickMask); +rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_RESET, + &ucNewJoystickMask, ulDataLen, &ulDataLen, NULL, 0, NULL); +if (rc == 0) + { + ulDataLen = sizeof(stJoyStatus); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + if (rc != 0) + { + joyPortClose(&hJoyPort); + SDL_SetError("Could not call joystick port."); + return -1; + } + ulLastTick = stJoyStatus.ulJs_Ticks; + while (stJoyStatus.ulJs_Ticks == ulLastTick) + { + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + } + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) numdevs++; + if (((stJoyStatus.ucJs_JoyStickMask >> 2) & 0x03) > 0) numdevs++; + } + +if (numdevs>maxdevs) numdevs=maxdevs; + +/* If *any* joystick was detected... Let's configure SDL for them */ +if (numdevs > 0) + { + /* Verify if it is a "user defined" joystick */ + if (joyGetEnv(&joycfg)) + { + GAME_3POS_STRUCT * axis[4]; + axis[0] = &stGameCalib.Ax; + axis[1] = &stGameCalib.Ay; + axis[2] = &stGameCalib.Bx; + axis[3] = &stGameCalib.By; + /* Say it has one device only (user defined is always one device only) */ + numdevs = 1; + /* Define Device 0 as... */ + SYS_JoyData[0].id=0; + /* Define Number of Axes... up to 4 */ + if (joycfg.axes>MAX_AXES) joycfg.axes = MAX_AXES; + SYS_JoyData[0].axes = joycfg.axes; + /* Define number of buttons... 8 if 2 axes, 6 if 3 axes and 4 if 4 axes */ + maxbut = MAX_BUTTONS; + if (joycfg.axes>2) maxbut-=((joycfg.axes-2)<<1); /* MAX_BUTTONS - 2*(axes-2) */ + if (joycfg.buttons > maxbut) joycfg.buttons = maxbut; + SYS_JoyData[0].buttons = joycfg.buttons; + /* Define number of hats */ + if (joycfg.hats > MAX_HATS) joycfg.hats = MAX_HATS; + SYS_JoyData[0].hats = joycfg.hats; + /* Define number of balls */ + if (joycfg.balls > MAX_BALLS) joycfg.balls = MAX_BALLS; + SYS_JoyData[0].balls = joycfg.balls; + /* Initialize Axes Callibration Values */ + for (i=0; i<joycfg.axes; i++) + { + SYS_JoyData[0].axes_min[i] = axis[i]->lower; + SYS_JoyData[0].axes_med[i] = axis[i]->centre; + SYS_JoyData[0].axes_max[i] = axis[i]->upper; + } + /* Initialize Buttons 5 to 8 structures */ + if (joycfg.buttons>=5) SYS_JoyData[0].buttoncalc[0]=((axis[2]->lower+axis[3]->centre)>>1); + if (joycfg.buttons>=6) SYS_JoyData[0].buttoncalc[1]=((axis[3]->lower+axis[3]->centre)>>1); + if (joycfg.buttons>=7) SYS_JoyData[0].buttoncalc[2]=((axis[2]->upper+axis[3]->centre)>>1); + if (joycfg.buttons>=8) SYS_JoyData[0].buttoncalc[3]=((axis[3]->upper+axis[3]->centre)>>1); + /* Intialize Joystick Name */ + SDL_strlcpy (SYS_JoyData[0].szDeviceName,joycfg.name, SDL_arraysize(SYS_JoyData[0].szDeviceName)); + } + /* Default Init ... autoconfig */ + else + { + /* if two devices were detected... configure as Joy1 4 axis and Joy2 2 axis */ + if (numdevs==2) + { + /* Define Device 0 as 4 axes, 4 buttons */ + SYS_JoyData[0].id=0; + SYS_JoyData[0].axes = 4; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + SYS_JoyData[0].axes_min[2] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[2] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[2] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[3] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[3] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[3] = stGameCalib.By.upper; + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[1].id=1; + SYS_JoyData[1].axes = 2; + SYS_JoyData[1].buttons = 2; + SYS_JoyData[1].hats = 0; + SYS_JoyData[1].balls = 0; + SYS_JoyData[1].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[1].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[1].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[1].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[1].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[1].axes_max[1] = stGameCalib.By.upper; + } + /* One joystick only? */ + else + { + /* If it is joystick A... */ + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) + { + /* Define Device 0 as 2 axes, 4 buttons */ + SYS_JoyData[0].id=0; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + } + /* If not, it is joystick B */ + else + { + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[0].id=1; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 2; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.By.upper; + } + } + /* Hack to define Joystick Port Names */ + if ( numdevs > maxdevs ) numdevs = maxdevs; + for (i=0; i<numdevs; i++) + SDL_snprintf (SYS_JoyData[i].szDeviceName, SDL_arraysize(SYS_JoyData[i].szDeviceName), "Default Joystick %c", 'A'+SYS_JoyData[i].id); + + } + } +/* Return the number of devices found */ +return(numdevs); +} + + +/***********************************************************/ +/* Function to get the device-dependent name of a joystick */ +/***********************************************************/ +const char *SDL_SYS_JoystickName(int index) +{ +/* No need to verify if device exists, already done in upper layer */ +return(SYS_JoyData[index].szDeviceName); +} + + + +/******************************************************************************/ +/* Function to open a joystick for use. */ +/* The joystick to open is specified by the index field of the joystick. */ +/* This should fill the nbuttons and naxes fields of the joystick structure. */ +/* It returns 0, or -1 if there is an error. */ +/******************************************************************************/ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ +int index; /* Index shortcut for index in joystick structure */ +int i; /* Generic Counter */ + +/* allocate memory for system specific hardware data */ +joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); +if (joystick->hwdata == NULL) + { + SDL_OutOfMemory(); + return(-1); + } +/* Reset Hardware Data */ +SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + +/* ShortCut Pointer */ +index = joystick->index; +/* Define offsets and scales for all axes */ +joystick->hwdata->id = SYS_JoyData[index].id; +for ( i = 0; i < MAX_AXES; ++i ) + { + if ( (i<2) || i < SYS_JoyData[index].axes ) + { + joystick->hwdata->transaxes[i].offset = ((AXIS_MAX + AXIS_MIN)>>1) - SYS_JoyData[index].axes_med[i]; + //joystick->hwdata->transaxes[i].scale = (float)((AXIS_MAX - AXIS_MIN)/(SYS_JoyData[index].axes_max[i]-SYS_JoyData[index].axes_min[i])); + joystick->hwdata->transaxes[i].scale1 = (float)abs((AXIS_MIN/SYS_JoyData[index].axes_min[i])); + joystick->hwdata->transaxes[i].scale2 = (float)abs((AXIS_MAX/SYS_JoyData[index].axes_max[i])); + } + else + { + joystick->hwdata->transaxes[i].offset = 0; + //joystick->hwdata->transaxes[i].scale = 1.0; /* Just in case */ + joystick->hwdata->transaxes[i].scale1 = 1.0; /* Just in case */ + joystick->hwdata->transaxes[i].scale2 = 1.0; /* Just in case */ + } + } + +/* fill nbuttons, naxes, and nhats fields */ +joystick->nbuttons = SYS_JoyData[index].buttons; +joystick->naxes = SYS_JoyData[index].axes; +/* joystick->nhats = SYS_JoyData[index].hats; */ +joystick->nhats = 0; /* No support for hats at this time */ +/* joystick->nballs = SYS_JoyData[index].balls; */ +joystick->nballs = 0; /* No support for balls at this time */ +return 0; +} + + + +/***************************************************************************/ +/* Function to update the state of a joystick - called as a device poll. */ +/* This function shouldn't update the joystick structure directly, */ +/* but instead should call SDL_PrivateJoystick*() to deliver events */ +/* and update joystick device state. */ +/***************************************************************************/ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ +APIRET rc; /* Generic OS/2 return code */ +int index; /* index shortcurt to joystick index */ +int i; /* Generic counter */ +int normbut; /* Number of buttons reported by joystick */ +int corr; /* Correction for button names */ +Sint16 value, change; /* Values used to update axis values */ +struct _transaxes *transaxes; /* Shortcut for Correction structure */ +Uint32 pos[MAX_AXES]; /* Vector to inform the Axis status */ +ULONG ulDataLen; /* Size of data */ +GAME_STATUS_STRUCT stGameStatus; /* Joystick Status Structure */ + +ulDataLen = sizeof(stGameStatus); +rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_STATUS, + NULL, 0, NULL, &stGameStatus, ulDataLen, &ulDataLen); +if (rc != 0) + { + SDL_SetError("Could not read joystick status."); + return; /* Could not read data */ + } + +/* Shortcut pointer */ +index = joystick->index; +/* joystick motion events */ + +if (SYS_JoyData[index].id == 0) + { + pos[0] = stGameStatus.curdata.A.x; + pos[1] = stGameStatus.curdata.A.y; + if (SYS_JoyData[index].axes >= 3) pos[2] = stGameStatus.curdata.B.x; + else pos[2]=0; + if (SYS_JoyData[index].axes >= 4) pos[3] = stGameStatus.curdata.B.y; + else pos[3]=0; + pos[4]=0; /* OS/2 basic drivers do not support more than 4 axes joysticks */ + pos[5]=0; + } +else if (SYS_JoyData[index].id == 1) + { + pos[0] = stGameStatus.curdata.B.x; + pos[1] = stGameStatus.curdata.B.y; + pos[2]=0; + pos[3]=0; + pos[4]=0; + pos[5]=0; + } + +/* Corrects the movements using the callibration */ +transaxes = joystick->hwdata->transaxes; +for (i = 0; i < joystick->naxes; i++) + { + value = pos[i] + transaxes[i].offset; + if (value<0) + { + value*=transaxes[i].scale1; + if (value>0) value = AXIS_MIN; + } + else + { + value*=transaxes[i].scale2; + if (value<0) value = AXIS_MAX; + } + change = (value - joystick->axes[i]); + if ( (change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD) ) + { + SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)value); + } + } + +/* joystick button A to D events */ +if (SYS_JoyData[index].id == 1) corr = 2; +else corr = 0; +normbut=4; /* Number of normal buttons */ +if (joystick->nbuttons<normbut) normbut = joystick->nbuttons; +for ( i = corr; (i-corr) < normbut; ++i ) + { + /* + Button A: 1110 0000 + Button B: 1101 0000 + Button C: 1011 0000 + Button D: 0111 0000 + */ + if ( (~stGameStatus.curdata.butMask)>>4 & JOY_BUTTON_FLAG(i) ) + { + if ( ! joystick->buttons[i-corr] ) + { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_PRESSED); + } + } + else + { + if ( joystick->buttons[i-corr] ) + { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_RELEASED); + } + } + } + +/* Joystick button E to H buttons */ + /* + Button E: Axis 2 X Left + Button F: Axis 2 Y Up + Button G: Axis 2 X Right + Button H: Axis 2 Y Down + */ +if (joystick->nbuttons>=5) + { + if (stGameStatus.curdata.B.x < SYS_JoyData[index].buttoncalc[0]) SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_RELEASED); + } +if (joystick->nbuttons>=6) + { + if (stGameStatus.curdata.B.y < SYS_JoyData[index].buttoncalc[1]) SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_RELEASED); + } +if (joystick->nbuttons>=7) + { + if (stGameStatus.curdata.B.x > SYS_JoyData[index].buttoncalc[2]) SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_RELEASED); + } +if (joystick->nbuttons>=8) + { + if (stGameStatus.curdata.B.y > SYS_JoyData[index].buttoncalc[3]) SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_RELEASED); + } + +/* joystick hat events */ +/* Not Supported under OS/2 */ +/* joystick ball events */ +/* Not Supported under OS/2 */ +} + + + +/******************************************/ +/* Function to close a joystick after use */ +/******************************************/ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ +if (joystick->hwdata != NULL) + { + /* free system specific hardware data */ + SDL_free(joystick->hwdata); + } +} + + + +/********************************************************************/ +/* Function to perform any system-specific joystick related cleanup */ +/********************************************************************/ +void SDL_SYS_JoystickQuit(void) +{ +joyPortClose(&hJoyPort); +} + + + +/************************/ +/************************/ +/* OS/2 Implementations */ +/************************/ +/************************/ + + +/*****************************************/ +/* Open Joystick Port, if not opened yet */ +/*****************************************/ +APIRET joyPortOpen(HFILE * hGame) +{ +APIRET rc; /* Generic Return Code */ +ULONG ulAction; /* ? */ +ULONG ulVersion; /* Version of joystick driver */ +ULONG ulDataLen; /* Size of version data */ + +/* Verifies if joyport is not already open... */ +if (*hGame != NULL) return 0; +/* Open GAME$ for read */ +rc = DosOpen((PSZ)GAMEPDDNAME, hGame, &ulAction, 0, FILE_READONLY, + FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL); +if (rc != 0) + { + SDL_SetError("Could not open Joystick Port."); + return -1; + } + +/* Get Joystick Driver Version... must be 2.0 or higher */ +ulVersion = 0; +ulDataLen = sizeof(ulVersion); +rc = DosDevIOCtl( *hGame, IOCTL_CAT_USER, GAME_GET_VERSION, + NULL, 0, NULL, &ulVersion, ulDataLen, &ulDataLen); +if (rc != 0) + { + joyPortClose(hGame); + SDL_SetError("Could not get Joystick Driver version."); + return -1; + } +if (ulVersion < GAME_VERSION) + { + joyPortClose(hGame); + SDL_SetError("Driver too old. At least IBM driver version 2.0 required."); + return -1; + } +return 0; +} + + + +/****************************/ +/* Close JoyPort, if opened */ +/****************************/ +void joyPortClose(HFILE * hGame) +{ +if (*hGame != NULL) DosClose(*hGame); +*hGame = NULL; +} + + + +/***************************/ +/* Get SDL Joystick EnvVar */ +/***************************/ +int joyGetEnv(struct _joycfg * joydata) +{ +char *joyenv; /* Pointer to tested character */ +char tempnumber[5]; /* Temporary place to put numeric texts */ + +joyenv = SDL_getenv("SDL_OS2_JOYSTICK"); +if (joyenv == NULL) return 0; +/* Joystick Environment is defined! */ +while (*joyenv==' ' && *joyenv!=0) joyenv++; /* jump spaces... */ +/* If the string name starts with '... get if fully */ +if (*joyenv=='\'') joyenv+=joyGetData(++joyenv,joydata->name,'\'',sizeof(joydata->name)); +/* If not, get it until the next space */ +else if (*joyenv=='\"') joyenv+=joyGetData(++joyenv,joydata->name,'\"',sizeof(joydata->name)); +else joyenv+=joyGetData(joyenv,joydata->name,' ',sizeof(joydata->name)); +/* Now get the number of axes */ +while (*joyenv==' ' && *joyenv!=0) joyenv++; /* jump spaces... */ +joyenv+=joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); +joydata->axes = atoi(tempnumber); +/* Now get the number of buttons */ +while (*joyenv==' ' && *joyenv!=0) joyenv++; /* jump spaces... */ +joyenv+=joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); +joydata->buttons = atoi(tempnumber); +/* Now get the number of hats */ +while (*joyenv==' ' && *joyenv!=0) joyenv++; /* jump spaces... */ +joyenv+=joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); +joydata->hats = atoi(tempnumber); +/* Now get the number of balls */ +while (*joyenv==' ' && *joyenv!=0) joyenv++; /* jump spaces... */ +joyenv+=joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); +joydata->balls = atoi(tempnumber); +return 1; +} + + + +/************************************************************************/ +/* Get a text from in the string starting in joyenv until it finds */ +/* the stopchar or maxchars is reached. The result is placed in name. */ +/************************************************************************/ +int joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars) +{ +char *nameptr; /* Pointer to the selected character */ +int chcnt=0; /* Count how many characters where copied */ + +nameptr=name; +while (*joyenv!=stopchar && *joyenv!=0) + { + if (nameptr<(name+(maxchars-1))) + { + *nameptr = *joyenv; /* Only copy if smaller than maximum */ + nameptr++; + } + chcnt++; + joyenv++; + } +if (*joyenv==stopchar) + { + joyenv++; /* Jump stopchar */ + chcnt++; + } +*nameptr = 0; /* Mark last byte */ +return chcnt; +} + +#endif /* SDL_JOYSTICK_OS2 */ diff --git a/distrib/sdl-1.2.12/src/joystick/os2/joyos2.h b/distrib/sdl-1.2.12/src/joystick/os2/joyos2.h new file mode 100644 index 0000000..2980010 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/os2/joyos2.h @@ -0,0 +1,177 @@ +/*****************************************************************************/ +/* */ +/* COPYRIGHT Copyright (C) 1995 IBM Corporation */ +/* */ +/* The following IBM OS/2 source code is provided to you solely for */ +/* the purpose of assisting you in your development of OS/2 device */ +/* drivers. You may use this code in accordance with the IBM License */ +/* Agreement provided in the IBM Device Driver Source Kit for OS/2. This */ +/* Copyright statement may not be removed. */ +/* */ +/*****************************************************************************/ +#ifndef JOYOS2_H +#define JOYOS2_H + +/****** GAMEPORT.SYS joystick definitions, start *****************************/ +#define GAME_VERSION 0x20 /* 2.0 First IBM version */ +#define GAMEPDDNAME "GAME$ " +#define IOCTL_CAT_USER 0x80 +#define GAME_PORT_GET 0x20 /* read GAMEPORT.SYS values */ +#define GAME_PORT_RESET 0x60 /* reset joystick mask with given value */ + +#pragma pack(1) /* pack structure size is 1 byte */ +typedef struct { /* GAMEPORT.SYS structure */ + USHORT usJs_AxCnt; /* Joystick_A X position */ + USHORT usJs_AyCnt; /* Joystick_A Y position */ + USHORT usJs_BxCnt; /* Joystick_B X position */ + USHORT usJs_ByCnt; /* Joystick_B Y position */ + USHORT usJs_ButtonA1Cnt; /* button A1 press count */ + USHORT usJs_ButtonA2Cnt; /* button A2 press count */ + USHORT usJs_ButtonB1Cnt; /* button B1 press count */ + USHORT usJs_ButtonB2Cnt; /* button B2 press count */ + UCHAR ucJs_JoyStickMask; /* mask of connected joystick pots */ + UCHAR ucJs_ButtonStatus; /* bits of switches down */ + ULONG ulJs_Ticks; /* joystick clock ticks */ +} GAME_PORT_STRUCT; +#pragma pack() /*reset to normal pack size */ +/****** GAMEPORT.SYS joystick definitions, end *******************************/ + + +/****************************************************************************/ +#define GAME_GET_VERSION 0x01 +#define GAME_GET_PARMS 0x02 +#define GAME_SET_PARMS 0x03 +#define GAME_GET_CALIB 0x04 +#define GAME_SET_CALIB 0x05 +#define GAME_GET_DIGSET 0x06 +#define GAME_SET_DIGSET 0x07 +#define GAME_GET_STATUS 0x10 +#define GAME_GET_STATUS_BUTWAIT 0x11 +#define GAME_GET_STATUS_SAMPWAIT 0x12 +/****************************************************************************/ + +/****************************************************************************/ +// bit masks for each axis +#define JOY_AX_BIT 0x01 +#define JOY_AY_BIT 0x02 +#define JOY_A_BITS (JOY_AX_BIT|JOY_AY_BIT) +#define JOY_BX_BIT 0x04 +#define JOY_BY_BIT 0x08 +#define JOY_B_BITS (JOY_BX_BIT|JOY_BY_BIT) +#define JOY_ALLPOS_BITS (JOY_A_BITS|JOY_B_BITS) + +// bit masks for each button +#define JOY_BUT1_BIT 0x10 +#define JOY_BUT2_BIT 0x20 +#define JOY_BUT3_BIT 0x40 +#define JOY_BUT4_BIT 0x80 +#define JOY_ALL_BUTS (JOY_BUT1_BIT|JOY_BUT2_BIT|JOY_BUT3_BIT|JOY_BUT4_BIT) +/****************************************************************************/ + +/****************************************************************************/ +// 1-D position struct used for each axis +typedef SHORT GAME_POS; /* some data formats require signed values */ + +// simple 2-D position for each joystick +typedef struct +{ + GAME_POS x; + GAME_POS y; +} +GAME_2DPOS_STRUCT; + +// struct defining the instantaneous state of both sticks and all buttons +typedef struct +{ + GAME_2DPOS_STRUCT A; + GAME_2DPOS_STRUCT B; + USHORT butMask; +} +GAME_DATA_STRUCT; + +// struct to be used for calibration and digital response on each axis +typedef struct +{ + GAME_POS lower; + GAME_POS centre; + GAME_POS upper; +} +GAME_3POS_STRUCT; +/****************************************************************************/ + +/****************************************************************************/ +// status struct returned to OS/2 applications: +// current data for all sticks as well as button counts since last read +typedef struct +{ + GAME_DATA_STRUCT curdata; + USHORT b1cnt; + USHORT b2cnt; + USHORT b3cnt; + USHORT b4cnt; +} +GAME_STATUS_STRUCT; +/****************************************************************************/ + +/****************************************************************************/ +/* in use bitmasks originating in 0.2b */ +#define GAME_USE_BOTH_OLDMASK 0x01 /* for backward compat with bool */ +#define GAME_USE_X_NEWMASK 0x02 +#define GAME_USE_Y_NEWMASK 0x04 +#define GAME_USE_X_EITHERMASK (GAME_USE_X_NEWMASK|GAME_USE_BOTH_OLDMASK) +#define GAME_USE_Y_EITHERMASK (GAME_USE_Y_NEWMASK|GAME_USE_BOTH_OLDMASK) +#define GAME_USE_BOTH_NEWMASK (GAME_USE_X_NEWMASK|GAME_USE_Y_NEWMASK) + +/* only timed sampling implemented in version 1.0 */ +#define GAME_MODE_TIMED 1 /* timed sampling */ +#define GAME_MODE_REQUEST 2 /* request driven sampling */ + +/* only raw implemented in version 1.0 */ +#define GAME_DATA_FORMAT_RAW 1 /* [l,c,r] */ +#define GAME_DATA_FORMAT_SIGNED 2 /* [-l,0,+r] */ +#define GAME_DATA_FORMAT_BINARY 3 /* {-1,0,+1} */ +#define GAME_DATA_FORMAT_SCALED 4 /* [-10,+10] */ + +// parameters defining the operation of the driver +typedef struct +{ + USHORT useA; /* new bitmasks: see above */ + USHORT useB; + USHORT mode; /* see consts above */ + USHORT format; /* see consts above */ + USHORT sampDiv; /* samp freq = 32 / n */ + USHORT scale; /* scaling factor */ + USHORT res1; /* must be 0 */ + USHORT res2; /* must be 0 */ +} +GAME_PARM_STRUCT; +/****************************************************************************/ + +/****************************************************************************/ +// calibration values for each axis: +// - upper limit on value to be considered in lower range +// - centre value +// - lower limit on value to be considered in upper range +typedef struct +{ + GAME_3POS_STRUCT Ax; + GAME_3POS_STRUCT Ay; + GAME_3POS_STRUCT Bx; + GAME_3POS_STRUCT By; +} +GAME_CALIB_STRUCT; +/****************************************************************************/ + +/****************************************************************************/ +// struct defining the digital response values for all axes +typedef struct +{ + GAME_3POS_STRUCT Ax; + GAME_3POS_STRUCT Ay; + GAME_3POS_STRUCT Bx; + GAME_3POS_STRUCT By; +} +GAME_DIGSET_STRUCT; +/****************************************************************************/ + +#endif diff --git a/distrib/sdl-1.2.12/src/joystick/riscos/SDL_sysjoystick.c b/distrib/sdl-1.2.12/src/joystick/riscos/SDL_sysjoystick.c new file mode 100644 index 0000000..ed8ac91 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/riscos/SDL_sysjoystick.c @@ -0,0 +1,176 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_RISCOS + +/* + RISC OS - Joystick support by Alan Buckley (alan_baa@hotmail.com) - 10 April 2003 + + Note: Currently assumes joystick is present if joystick module is loaded + and that there is one joystick with four buttons. +*/ + +/* This is the system specific header for the SDL joystick API */ + +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#include "kernel.h" + +#define JOYSTICK_READ 0x43F40 + +struct joystick_hwdata +{ + int joystate; +}; + + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return number of joysticks, or -1 on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + _kernel_swi_regs regs; + + /* Try to read joystick 0 */ + regs.r[0] = 0; + if (_kernel_swi(JOYSTICK_READ, ®s, ®s) == NULL) + { + /* Switch works so assume we've got a joystick */ + return 1; + } + /* Switch fails so it looks like there's no joystick here */ + + return(0); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + if (index == 0) + { + return "RISC OS Joystick 0"; + } + + SDL_SetError("No joystick available with that index"); + return(NULL); +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + _kernel_swi_regs regs; + + if(!(joystick->hwdata=SDL_malloc(sizeof(struct joystick_hwdata)))) + return -1; + + regs.r[0] = joystick->index; + + /* Don't know how to get exact count of buttons so assume max of 4 for now */ + joystick->nbuttons=4; + + joystick->nhats=0; + joystick->nballs=0; + joystick->naxes=2; + joystick->hwdata->joystate=0; + + return 0; + +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + _kernel_swi_regs regs; + regs.r[0] = joystick->index; + + if (_kernel_swi(JOYSTICK_READ, ®s, ®s) == NULL) + { + int newstate = regs.r[0]; + int oldstate = joystick->hwdata->joystate; + if (newstate != oldstate) + { + if ((newstate & 0xFF) != (oldstate & 0xFF)) + { + int y = regs.r[0] & 0xFF; + /* Convert to signed values */ + if (y >= 128) y -= 256; + SDL_PrivateJoystickAxis(joystick,1,-y * 256); /* Up and down opposite to result in SDL */ + } + if ((newstate & 0xFF00) != (oldstate & 0xFF00)) + { + int x = (regs.r[0] & 0xFF00) >> 8; + if (x >= 128) x -= 256; + SDL_PrivateJoystickAxis(joystick,0,x * 256); + } + + if ((newstate & 0xFF0000) != (oldstate & 0xFF0000)) + { + int buttons = (regs.r[0] & 0xFF0000) >> 16; + int oldbuttons = (oldstate & 0xFF0000) >> 16; + int i; + for (i = 0; i < joystick->nbuttons; i++) + { + if ((buttons & (1<<i)) != (oldbuttons & (1<<i))) + { + if (buttons & (1<<i)) SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED); + else SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED); + } + } + } + joystick->hwdata->joystate = newstate; + } + } + + return; +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + if(joystick->hwdata) + SDL_free(joystick->hwdata); + return; +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + SDL_numjoysticks=0; + + return; +} + +#endif /* SDL_JOYSTICK_RISCOS */ diff --git a/distrib/sdl-1.2.12/src/joystick/win32/SDL_mmjoystick.c b/distrib/sdl-1.2.12/src/joystick/win32/SDL_mmjoystick.c new file mode 100644 index 0000000..e71f8f8 --- /dev/null +++ b/distrib/sdl-1.2.12/src/joystick/win32/SDL_mmjoystick.c @@ -0,0 +1,405 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_WINMM + +/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <mmsystem.h> +#include <regstr.h> + +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#define MAX_JOYSTICKS 16 +#define MAX_AXES 6 /* each joystick can have up to 6 axes */ +#define MAX_BUTTONS 32 /* and 32 buttons */ +#define AXIS_MIN -32768 /* minimum value for axis coordinate */ +#define AXIS_MAX 32767 /* maximum value for axis coordinate */ +/* limit axis to 256 possible positions to filter out noise */ +#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256) +#define JOY_BUTTON_FLAG(n) (1<<n) + + +/* array to hold joystick ID values */ +static UINT SYS_JoystickID[MAX_JOYSTICKS]; +static JOYCAPS SYS_Joystick[MAX_JOYSTICKS]; +static char *SYS_JoystickName[MAX_JOYSTICKS]; + +/* The private structure used to keep track of a joystick */ +struct joystick_hwdata +{ + /* joystick ID */ + UINT id; + + /* values used to translate device-specific coordinates into + SDL-standard ranges */ + struct _transaxis { + int offset; + float scale; + } transaxis[6]; +}; + +/* Convert a win32 Multimedia API return code to a text message */ +static void SetMMerror(char *function, int code); + + +static char *GetJoystickName(int index, const char *szRegKey) +{ + /* added 7/24/2004 by Eckhard Stolberg */ + /* + see if there is a joystick for the current + index (1-16) listed in the registry + */ + char *name = NULL; + HKEY hTopKey; + HKEY hKey; + DWORD regsize; + LONG regresult; + char regkey[256]; + char regvalue[256]; + char regname[256]; + + SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s\\%s", + REGSTR_PATH_JOYCONFIG, szRegKey, REGSTR_KEY_JOYCURR); + hTopKey = HKEY_LOCAL_MACHINE; + regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey); + if (regresult != ERROR_SUCCESS) { + hTopKey = HKEY_CURRENT_USER; + regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey); + } + if (regresult != ERROR_SUCCESS) { + return NULL; + } + + /* find the registry key name for the joystick's properties */ + regsize = sizeof(regname); + SDL_snprintf(regvalue, SDL_arraysize(regvalue), "Joystick%d%s", index+1, REGSTR_VAL_JOYOEMNAME); + regresult = RegQueryValueExA(hKey, regvalue, 0, 0, (LPBYTE)regname, ®size); + RegCloseKey(hKey); + + if (regresult != ERROR_SUCCESS) { + return NULL; + } + + /* open that registry key */ + SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s", REGSTR_PATH_JOYOEM, regname); + regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey); + if (regresult != ERROR_SUCCESS) { + return NULL; + } + + /* find the size for the OEM name text */ + regsize = sizeof(regvalue); + regresult = RegQueryValueExA(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, NULL, ®size); + if (regresult == ERROR_SUCCESS) { + /* allocate enough memory for the OEM name text ... */ + name = (char *) SDL_malloc(regsize); + if ( name ) { + /* ... and read it from the registry */ + regresult = RegQueryValueExA(hKey, + REGSTR_VAL_JOYOEMNAME, 0, 0, + (LPBYTE) name, ®size); + } + } + RegCloseKey(hKey); + + return(name); +} + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int SDL_SYS_JoystickInit(void) +{ + int i; + int maxdevs; + int numdevs; + JOYINFOEX joyinfo; + JOYCAPS joycaps; + MMRESULT result; + + /* Reset the joystick ID & name mapping tables */ + for ( i = 0; i < MAX_JOYSTICKS; ++i ) { + SYS_JoystickID[i] = 0; + SYS_JoystickName[i] = NULL; + } + + /* Loop over all potential joystick devices */ + numdevs = 0; + maxdevs = joyGetNumDevs(); + for ( i = JOYSTICKID1; i < maxdevs && numdevs < MAX_JOYSTICKS; ++i ) { + + joyinfo.dwSize = sizeof(joyinfo); + joyinfo.dwFlags = JOY_RETURNALL; + result = joyGetPosEx(i, &joyinfo); + if ( result == JOYERR_NOERROR ) { + result = joyGetDevCaps(i, &joycaps, sizeof(joycaps)); + if ( result == JOYERR_NOERROR ) { + SYS_JoystickID[numdevs] = i; + SYS_Joystick[numdevs] = joycaps; + SYS_JoystickName[numdevs] = GetJoystickName(i, joycaps.szRegKey); + numdevs++; + } + } + } + return(numdevs); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + if ( SYS_JoystickName[index] != NULL ) { + return(SYS_JoystickName[index]); + } else { + return(SYS_Joystick[index].szPname); + } +} + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + int index, i; + int caps_flags[MAX_AXES-2] = + { JOYCAPS_HASZ, JOYCAPS_HASR, JOYCAPS_HASU, JOYCAPS_HASV }; + int axis_min[MAX_AXES], axis_max[MAX_AXES]; + + + /* shortcut */ + index = joystick->index; + axis_min[0] = SYS_Joystick[index].wXmin; + axis_max[0] = SYS_Joystick[index].wXmax; + axis_min[1] = SYS_Joystick[index].wYmin; + axis_max[1] = SYS_Joystick[index].wYmax; + axis_min[2] = SYS_Joystick[index].wZmin; + axis_max[2] = SYS_Joystick[index].wZmax; + axis_min[3] = SYS_Joystick[index].wRmin; + axis_max[3] = SYS_Joystick[index].wRmax; + axis_min[4] = SYS_Joystick[index].wUmin; + axis_max[4] = SYS_Joystick[index].wUmax; + axis_min[5] = SYS_Joystick[index].wVmin; + axis_max[5] = SYS_Joystick[index].wVmax; + + /* allocate memory for system specific hardware data */ + joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); + if (joystick->hwdata == NULL) + { + SDL_OutOfMemory(); + return(-1); + } + SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + + /* set hardware data */ + joystick->hwdata->id = SYS_JoystickID[index]; + for ( i = 0; i < MAX_AXES; ++i ) { + if ( (i<2) || (SYS_Joystick[index].wCaps & caps_flags[i-2]) ) { + joystick->hwdata->transaxis[i].offset = + AXIS_MIN - axis_min[i]; + joystick->hwdata->transaxis[i].scale = + (float)(AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]); + } else { + joystick->hwdata->transaxis[i].offset = 0; + joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */ + } + } + + /* fill nbuttons, naxes, and nhats fields */ + joystick->nbuttons = SYS_Joystick[index].wNumButtons; + joystick->naxes = SYS_Joystick[index].wNumAxes; + if ( SYS_Joystick[index].wCaps & JOYCAPS_HASPOV ) { + joystick->nhats = 1; + } else { + joystick->nhats = 0; + } + return(0); +} + +static Uint8 TranslatePOV(DWORD value) +{ + Uint8 pos; + + pos = SDL_HAT_CENTERED; + if ( value != JOY_POVCENTERED ) { + if ( (value > JOY_POVLEFT) || (value < JOY_POVRIGHT) ) { + pos |= SDL_HAT_UP; + } + if ( (value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD) ) { + pos |= SDL_HAT_RIGHT; + } + if ( (value > JOY_POVRIGHT) && (value < JOY_POVLEFT) ) { + pos |= SDL_HAT_DOWN; + } + if ( value > JOY_POVBACKWARD ) { + pos |= SDL_HAT_LEFT; + } + } + return(pos); +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + MMRESULT result; + int i; + DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, + JOY_RETURNR, JOY_RETURNU, JOY_RETURNV }; + DWORD pos[MAX_AXES]; + struct _transaxis *transaxis; + int value, change; + JOYINFOEX joyinfo; + + joyinfo.dwSize = sizeof(joyinfo); + joyinfo.dwFlags = JOY_RETURNALL|JOY_RETURNPOVCTS; + if ( ! joystick->hats ) { + joyinfo.dwFlags &= ~(JOY_RETURNPOV|JOY_RETURNPOVCTS); + } + result = joyGetPosEx(joystick->hwdata->id, &joyinfo); + if ( result != JOYERR_NOERROR ) { + SetMMerror("joyGetPosEx", result); + return; + } + + /* joystick motion events */ + pos[0] = joyinfo.dwXpos; + pos[1] = joyinfo.dwYpos; + pos[2] = joyinfo.dwZpos; + pos[3] = joyinfo.dwRpos; + pos[4] = joyinfo.dwUpos; + pos[5] = joyinfo.dwVpos; + + transaxis = joystick->hwdata->transaxis; + for (i = 0; i < joystick->naxes; i++) { + if (joyinfo.dwFlags & flags[i]) { + value = (int)(((float)pos[i] + transaxis[i].offset) * transaxis[i].scale); + change = (value - joystick->axes[i]); + if ( (change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD) ) { + SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)value); + } + } + } + + /* joystick button events */ + if ( joyinfo.dwFlags & JOY_RETURNBUTTONS ) { + for ( i = 0; i < joystick->nbuttons; ++i ) { + if ( joyinfo.dwButtons & JOY_BUTTON_FLAG(i) ) { + if ( ! joystick->buttons[i] ) { + SDL_PrivateJoystickButton(joystick, (Uint8)i, SDL_PRESSED); + } + } else { + if ( joystick->buttons[i] ) { + SDL_PrivateJoystickButton(joystick, (Uint8)i, SDL_RELEASED); + } + } + } + } + + /* joystick hat events */ + if ( joyinfo.dwFlags & JOY_RETURNPOV ) { + Uint8 pos; + + pos = TranslatePOV(joyinfo.dwPOV); + if ( pos != joystick->hats[0] ) { + SDL_PrivateJoystickHat(joystick, 0, pos); + } + } +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + if (joystick->hwdata != NULL) { + /* free system specific hardware data */ + SDL_free(joystick->hwdata); + } +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + int i; + for (i = 0; i < MAX_JOYSTICKS; i++) { + if ( SYS_JoystickName[i] != NULL ) { + SDL_free(SYS_JoystickName[i]); + } + } +} + + +/* implementation functions */ +void SetMMerror(char *function, int code) +{ + static char *error; + static char errbuf[1024]; + + errbuf[0] = 0; + switch (code) + { + case MMSYSERR_NODRIVER: + error = "Joystick driver not present"; + break; + + case MMSYSERR_INVALPARAM: + case JOYERR_PARMS: + error = "Invalid parameter(s)"; + break; + + case MMSYSERR_BADDEVICEID: + error = "Bad device ID"; + break; + + case JOYERR_UNPLUGGED: + error = "Joystick not attached"; + break; + + case JOYERR_NOCANDO: + error = "Can't capture joystick input"; + break; + + default: + SDL_snprintf(errbuf, SDL_arraysize(errbuf), + "%s: Unknown Multimedia system error: 0x%x", + function, code); + break; + } + + if ( ! errbuf[0] ) { + SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error); + } + SDL_SetError("%s", errbuf); +} + +#endif /* SDL_JOYSTICK_WINMM */ |