Home | History | Annotate | Download | only in beos
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2006 Sam Lantinga
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Lesser General Public
      7     License as published by the Free Software Foundation; either
      8     version 2.1 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Lesser General Public License for more details.
     14 
     15     You should have received a copy of the GNU Lesser General Public
     16     License along with this library; if not, write to the Free Software
     17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     18 
     19     Sam Lantinga
     20     slouken (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 #ifdef SDL_JOYSTICK_BEOS
     25 
     26 /* This is the system specific header for the SDL joystick API */
     27 
     28 #include <be/support/String.h>
     29 #include <be/device/Joystick.h>
     30 
     31 extern "C" {
     32 
     33 #include "SDL_joystick.h"
     34 #include "../SDL_sysjoystick.h"
     35 #include "../SDL_joystick_c.h"
     36 
     37 
     38 /* The maximum number of joysticks we'll detect */
     39 #define MAX_JOYSTICKS	16
     40 
     41 /* A list of available joysticks */
     42 static char *SDL_joyport[MAX_JOYSTICKS];
     43 static char *SDL_joyname[MAX_JOYSTICKS];
     44 
     45 /* The private structure used to keep track of a joystick */
     46 struct joystick_hwdata {
     47 	BJoystick *stick;
     48 	uint8 *new_hats;
     49 	int16 *new_axes;
     50 };
     51 
     52 /* Function to scan the system for joysticks.
     53  * This function should set SDL_numjoysticks to the number of available
     54  * joysticks.  Joystick 0 should be the system default joystick.
     55  * It should return 0, or -1 on an unrecoverable fatal error.
     56  */
     57 int SDL_SYS_JoystickInit(void)
     58 {
     59 	BJoystick joystick;
     60 	int numjoysticks;
     61 	int i;
     62 	int32 nports;
     63 	char name[B_OS_NAME_LENGTH];
     64 
     65 	/* Search for attached joysticks */
     66 	nports = joystick.CountDevices();
     67 	numjoysticks = 0;
     68 	SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
     69 	SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
     70 	for ( i=0; (SDL_numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i ) {
     71 		if ( joystick.GetDeviceName(i, name) == B_OK ) {
     72 			if ( joystick.Open(name) != B_ERROR ) {
     73 				BString stick_name;
     74 				joystick.GetControllerName(&stick_name);
     75 				SDL_joyport[numjoysticks] = strdup(name);
     76 				SDL_joyname[numjoysticks] =
     77 					           strdup(stick_name.String());
     78 				numjoysticks++;
     79 				joystick.Close();
     80 			}
     81 		}
     82 	}
     83 	return(numjoysticks);
     84 }
     85 
     86 /* Function to get the device-dependent name of a joystick */
     87 const char *SDL_SYS_JoystickName(int index)
     88 {
     89 	return SDL_joyname[index];
     90 }
     91 
     92 /* Function to open a joystick for use.
     93    The joystick to open is specified by the index field of the joystick.
     94    This should fill the nbuttons and naxes fields of the joystick structure.
     95    It returns 0, or -1 if there is an error.
     96  */
     97 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
     98 {
     99 	BJoystick *stick;
    100 
    101 	/* Create the joystick data structure */
    102 	joystick->hwdata = (struct joystick_hwdata *)
    103 	                   SDL_malloc(sizeof(*joystick->hwdata));
    104 	if ( joystick->hwdata == NULL ) {
    105 		SDL_OutOfMemory();
    106 		return(-1);
    107 	}
    108 	SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
    109 	stick = new BJoystick;
    110 	joystick->hwdata->stick = stick;
    111 
    112 	/* Open the requested joystick for use */
    113 	if ( stick->Open(SDL_joyport[joystick->index]) == B_ERROR ) {
    114 		SDL_SetError("Unable to open joystick");
    115 		SDL_SYS_JoystickClose(joystick);
    116 		return(-1);
    117 	}
    118 
    119 	/* Set the joystick to calibrated mode */
    120 	stick->EnableCalibration();
    121 
    122 	/* Get the number of buttons, hats, and axes on the joystick */
    123 	joystick->nbuttons = stick->CountButtons();
    124 	joystick->naxes = stick->CountAxes();
    125 	joystick->nhats = stick->CountHats();
    126 
    127 	joystick->hwdata->new_axes = (int16 *)
    128 	                  SDL_malloc(joystick->naxes*sizeof(int16));
    129 	joystick->hwdata->new_hats = (uint8 *)
    130 	                  SDL_malloc(joystick->nhats*sizeof(uint8));
    131 	if ( ! joystick->hwdata->new_hats || ! joystick->hwdata->new_axes ) {
    132 		SDL_OutOfMemory();
    133 		SDL_SYS_JoystickClose(joystick);
    134 		return(-1);
    135 	}
    136 
    137 	/* We're done! */
    138 	return(0);
    139 }
    140 
    141 /* Function to update the state of a joystick - called as a device poll.
    142  * This function shouldn't update the joystick structure directly,
    143  * but instead should call SDL_PrivateJoystick*() to deliver events
    144  * and update joystick device state.
    145  */
    146 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
    147 {
    148 	static const Uint8 hat_map[9] = {
    149              SDL_HAT_CENTERED,
    150              SDL_HAT_UP,
    151              SDL_HAT_RIGHTUP,
    152              SDL_HAT_RIGHT,
    153              SDL_HAT_RIGHTDOWN,
    154              SDL_HAT_DOWN,
    155              SDL_HAT_LEFTDOWN,
    156              SDL_HAT_LEFT,
    157              SDL_HAT_LEFTUP
    158 	};
    159 	const int JITTER = (32768/10);	/* 10% jitter threshold (ok?) */
    160 
    161 	BJoystick *stick;
    162 	int i, change;
    163 	int16 *axes;
    164 	uint8 *hats;
    165 	uint32 buttons;
    166 
    167 	/* Set up data pointers */
    168 	stick = joystick->hwdata->stick;
    169 	axes = joystick->hwdata->new_axes;
    170 	hats = joystick->hwdata->new_hats;
    171 
    172 	/* Get the new joystick state */
    173 	stick->Update();
    174 	stick->GetAxisValues(axes);
    175 	stick->GetHatValues(hats);
    176 	buttons = stick->ButtonValues();
    177 
    178 	/* Generate axis motion events */
    179 	for ( i=0; i<joystick->naxes; ++i ) {
    180 		change = ((int32)axes[i] - joystick->axes[i]);
    181 		if ( (change > JITTER) || (change < -JITTER) ) {
    182 			SDL_PrivateJoystickAxis(joystick, i, axes[i]);
    183 		}
    184 	}
    185 
    186 	/* Generate hat change events */
    187 	for ( i=0; i<joystick->nhats; ++i ) {
    188 		if ( hats[i] != joystick->hats[i] ) {
    189 			SDL_PrivateJoystickHat(joystick, i, hat_map[hats[i]]);
    190 		}
    191 	}
    192 
    193 	/* Generate button events */
    194 	for ( i=0; i<joystick->nbuttons; ++i ) {
    195 		if ( (buttons&0x01) != joystick->buttons[i] ) {
    196 			SDL_PrivateJoystickButton(joystick, i, (buttons&0x01));
    197 		}
    198 		buttons >>= 1;
    199 	}
    200 }
    201 
    202 /* Function to close a joystick after use */
    203 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
    204 {
    205 	if ( joystick->hwdata ) {
    206 		joystick->hwdata->stick->Close();
    207 		delete joystick->hwdata->stick;
    208 		if ( joystick->hwdata->new_hats ) {
    209 			SDL_free(joystick->hwdata->new_hats);
    210 		}
    211 		if ( joystick->hwdata->new_axes ) {
    212 			SDL_free(joystick->hwdata->new_axes);
    213 		}
    214 		SDL_free(joystick->hwdata);
    215 		joystick->hwdata = NULL;
    216 	}
    217 }
    218 
    219 /* Function to perform any system-specific joystick related cleanup */
    220 void SDL_SYS_JoystickQuit(void)
    221 {
    222 	int i;
    223 
    224 	for ( i=0; SDL_joyport[i]; ++i ) {
    225 		SDL_free(SDL_joyport[i]);
    226 	}
    227 	SDL_joyport[0] = NULL;
    228 
    229 	for ( i=0; SDL_joyname[i]; ++i ) {
    230 		SDL_free(SDL_joyname[i]);
    231 	}
    232 	SDL_joyname[0] = NULL;
    233 }
    234 
    235 }; // extern "C"
    236 
    237 #endif /* SDL_JOYSTICK_BEOS */
    238