Diff for /np2/x11/joymng.c between versions 1.1 and 1.10

version 1.1, 2003/11/16 16:43:45 version 1.10, 2012/01/23 04:43:14
Line 1 Line 1
   /*-
    * Copyright (C) 2004 NONAKA Kimihiro <nonakap@gmail.com>
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    * 1. Redistributions of source code must retain the above copyright
    *    notice, this list of conditions and the following disclaimer.
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the
    *    documentation and/or other materials provided with the distribution.
    *
    * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
   
 #include "compiler.h"  #include "compiler.h"
   
   #if defined(SUPPORT_JOYSTICK)
   
 #include "np2.h"  #include "np2.h"
   
 #include "joymng.h"  #include "joymng.h"
   
   static struct {
           void *hdl;
           BOOL inited;
   
           joymng_devinfo_t **devlist;
   
           BYTE pad1btn[NELEMENTS(np2oscfg.JOY1BTN)];
           REG8 flag;
   } joyinfo = {
           NULL,
           FALSE,
   
           NULL,
   
           { 0, },
           0xff,
   };
   
   typedef struct {
           SINT16  axis[JOY_NAXIS];
           BYTE    button[JOY_NBUTTON];
   } JOYINFO_T;
   
   static joymng_devinfo_t **joydrv_initialize(void);
   static void joydrv_terminate(void);
   static void *joydrv_open(const char *dev);
   static void joydrv_close(void *hdl);
   static BOOL joydrv_getstat(void *hdl, JOYINFO_T *ji);
   
   void
   joymng_initialize(void)
   {
           int i;
   
           if (!joyinfo.inited) {
                   joyinfo.devlist = joydrv_initialize();
                   if (joyinfo.devlist == NULL) {
                           np2oscfg.JOYPAD1 |= 2;
                   }
                   joyinfo.inited = TRUE;
           }
   
           if (joyinfo.hdl) {
                   joydrv_close(joyinfo.hdl);
                   joyinfo.hdl = NULL;
           }
           if (np2oscfg.JOYPAD1 == 1) {
                   joyinfo.hdl = joydrv_open(np2oscfg.JOYDEV[0]);
                   if (joyinfo.hdl == NULL) {
                           np2oscfg.JOYPAD1 |= 2;
                   }
           }
   
           for (i = 0; i < JOY_NBUTTON; i++) {
                   joyinfo.pad1btn[i] = 0xff ^ ((np2oscfg.JOY1BTN[i] & 3) << ((np2oscfg.JOY1BTN[i] & 4) ? 4 : 6));
           }
   }
   
   void
   joymng_deinitialize(void)
   {
   
           if (joyinfo.hdl) {
                   joydrv_close(joyinfo.hdl);
                   joyinfo.hdl = NULL;
           }
           if (joyinfo.devlist) {
                   _MFREE(joyinfo.devlist);
                   joyinfo.devlist = NULL;
           }
           joydrv_terminate();
           joyinfo.inited = FALSE;
           np2oscfg.JOYPAD1 &= 1;
   }
   
   joymng_devinfo_t **
   joymng_get_devinfo_list(void)
   {
   
           return joyinfo.devlist;
   }
   
   void
   joymng_sync(void)
   {
   
           np2oscfg.JOYPAD1 &= 0x7f;
           joyinfo.flag = 0xff;
   }
   
   REG8
   joymng_getstat(void)
   {
           JOYINFO_T ji;
           int i;
   
           if ((np2oscfg.JOYPAD1 == 1) && joyinfo.hdl) {
                   if (joydrv_getstat(joyinfo.hdl, &ji) == SUCCESS) {
                           np2oscfg.JOYPAD1 |= 0x80;
                           joyinfo.flag = 0xff;
   
                           /* X */
                           if (ji.axis[0] > 0x4000) {
                                   joyinfo.flag &= ~JOY_RIGHT_BIT;
                           } else if (ji.axis[0] < -0x4000) {
                                   joyinfo.flag &= ~JOY_LEFT_BIT;
                           }
   
                           /* Y */
                           if (ji.axis[1] > 0x4000) {
                                   joyinfo.flag &= ~JOY_DOWN_BIT;
                           } else if (ji.axis[1] < -0x4000) {
                                   joyinfo.flag &= ~JOY_UP_BIT;
                           }
   
                           /* button */
                           for (i = 0; i < JOY_NBUTTON; ++i) {
                                   if (ji.button[i]) {
                                           joyinfo.flag &= joyinfo.pad1btn[i];
                                   }
                           }
                   }
           }
   
           return joyinfo.flag;
   }
   
   #if defined(USE_SDL_JOYSTICK)
   
   #include <SDL.h>
   #include <SDL_joystick.h>
   
   typedef struct {
           joymng_devinfo_t        dev;
           SDL_Joystick            *joyhdl;
   } joydrv_sdl_hdl_t;
   
   static joymng_devinfo_t **
   joydrv_initialize(void)
   {
           char str[32];
           joydrv_sdl_hdl_t *shdl;
           joymng_devinfo_t **devlist = NULL;
           size_t allocsize;
           int ndrv = 0;
           int rv;
           int i, n;
   
           rv = SDL_InitSubSystem(SDL_INIT_JOYSTICK);
           if (rv < 0) {
                   return NULL;
           }
   
           ndrv = SDL_NumJoysticks();
           if (ndrv <= 0) {
                   goto sdl_err;
           }
   
           allocsize = sizeof(joymng_devinfo_t *) * (ndrv + 1);
           devlist = _MALLOC(allocsize, "joy device list");
           if (devlist == NULL) {
                   goto sdl_err;
           }
           memset(devlist, 0, allocsize);
   
           for (n = 0, i = 0; i < ndrv; ++i) {
                   g_snprintf(str, sizeof(str), "%d", i);
                   devlist[n] = joydrv_open(str);
                   if (devlist[n] == NULL) {
                           continue;
                   }
                   shdl = (joydrv_sdl_hdl_t *)devlist[n];
                   SDL_JoystickClose(shdl->joyhdl);
                   shdl->joyhdl = NULL;
                   n++;
           }
           devlist[n] = NULL;
   
           return devlist;
   
   sdl_err:
           if (devlist) {
                   for (i = 0; i < ndrv; ++i) {
                           if (devlist[i]) {
                                   joydrv_close(devlist[i]);
                           }
                   }
                   _MFREE(devlist);
           }
   
           SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
   
           return NULL;
   }
   
   static void
   joydrv_terminate(void)
   {
   
           SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
   }
   
   static void *
   joydrv_open(const char *dvname)
   {
           joydrv_sdl_hdl_t *shdl = NULL;
           joymng_devinfo_t *dev;
           SDL_Joystick *joy = NULL;
           char *endptr;
           size_t allocsize;
           long lval;
           int drv;
           int ndrv;
           int naxis;
           int nbutton;
           int i;
   
           if (dvname == NULL) {
                   goto sdl_err;
           }
   
           errno = 0;
           lval = strtol(dvname, &endptr, 10);
           if (dvname[0] == '\0' || *endptr != '\0') {
                   goto sdl_err;
           }
           if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) {
                   goto sdl_err;
           }
           if (lval < 0 || lval > INT_MAX) {
                   goto sdl_err;
           }
           drv = (int)lval;
   
           ndrv = SDL_NumJoysticks();
           if (ndrv <= 0 || drv >= ndrv) {
                   goto sdl_err;
           }
   
           joy = SDL_JoystickOpen(drv);
           if (joy == NULL) {
                   goto sdl_err;
           }
   
           naxis = SDL_JoystickNumAxes(joy);
           if (naxis < 2 || naxis >= 255) {
                   goto sdl_err;
           }
           nbutton = SDL_JoystickNumButtons(joy);
           if (nbutton < 2 || nbutton >= 255) {
                   goto sdl_err;
           }
   
           allocsize = sizeof(joydrv_sdl_hdl_t);
           shdl = _MALLOC(allocsize, "SDL joystick handle");
           if (shdl == NULL) {
                   goto sdl_err;
           }
           memset(shdl, 0, allocsize);
   
           shdl->joyhdl = joy;
   
           dev = &shdl->dev;
           dev->devindex = drv;
           dev->devname = strdup(SDL_JoystickName(drv));
           dev->naxis = naxis;
           for (i = 0; i < JOY_NAXIS; ++i) {
                   if (np2oscfg.JOYAXISMAP[0][i] < naxis) {
                           dev->axis[i] = np2oscfg.JOYAXISMAP[0][i];
                   } else {
                           dev->axis[i] = JOY_AXIS_INVALID;
                   }
           }
           dev->nbutton = nbutton;
           for (i = 0; i < JOY_NBUTTON; ++i) {
                   if (np2oscfg.JOYBTNMAP[0][i] < nbutton) {
                           dev->button[i] = np2oscfg.JOYBTNMAP[0][i];
                   } else {
                           dev->button[i] = JOY_BUTTON_INVALID;
                   }
           }
   
           return shdl;
   
   sdl_err:
           if (shdl) {
                   if (shdl->dev.devname) {
                           free(shdl->dev.devname);
                           shdl->dev.devname = NULL;
                   }
                   _MFREE(shdl);
           }
           if (joy) {
                   SDL_JoystickClose(joy);
           }
           return NULL;
   }
   
   static void
   joydrv_close(void *hdl)
   {
           joydrv_sdl_hdl_t *shdl = (joydrv_sdl_hdl_t *)hdl;
           joymng_devinfo_t *dev = &shdl->dev;
           SDL_Joystick *joy = shdl->joyhdl;
   
           if (joy) {
                   SDL_JoystickClose(joy);
           }
           if (dev->devname) {
                   free(dev->devname);
                   dev->devname = NULL;
           }
           _MFREE(shdl);
   }
   
   static BOOL
   joydrv_getstat(void *hdl, JOYINFO_T *ji)
   {
           joydrv_sdl_hdl_t *shdl = (joydrv_sdl_hdl_t *)hdl;
           joymng_devinfo_t *dev = &shdl->dev;
           SDL_Joystick *joy = shdl->joyhdl;
           int i;
   
           SDL_JoystickUpdate();
   
           for (i = 0; i < JOY_NAXIS; ++i) {
                   ji->axis[i] = (dev->axis[i] == JOY_AXIS_INVALID) ? 0 :
                       SDL_JoystickGetAxis(joy, dev->axis[i]);
           }
           for (i = 0; i < JOY_NBUTTON; ++i) {
                   ji->button[i] = (dev->button[i] == JOY_BUTTON_INVALID) ? 0 :
                       SDL_JoystickGetButton(joy, dev->button[i]);
           }
   
           return SUCCESS;
   }
   #endif  /* USE_SDL_JOYSTICK */
   
   #endif  /* SUPPORT_JOYSTICK */

Removed from v.1.1  
changed lines
  Added in v.1.10


RetroPC.NET-CVS <cvs@retropc.net>