src/joystick/SDL_joystick.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 21 Sep 2003 18:32:04 +0000
changeset 720 f90d80d68071
parent 716 f25e3334d583
child 769 b8d311d90021
permissions -rw-r--r--
N Sep 17 8791 Sam Lantinga Re: tks source released
Date: Sun, 07 Sep 2003 02:51:58 +0200
From: Stephane Marchesin
Subject: [SDL] Two little patches

Compiling SDL with a recent gcc (gcc 3.3.1, 3.3 doesn't have this
behaviour) gives some nasty warnings :

SDL_blit_A.c: In function `BlitRGBtoRGBSurfaceAlpha128MMX':
SDL_blit_A.c:223: warning: integer constant is too large for "long" type
SDL_blit_A.c:225: warning: integer constant is too large for "long" type
SDL_blit_A.c:227: warning: integer constant is too large for "long" type
[...]

The first attached patch (longlongfix.patch) tells gcc to really treat
those constants as unsigned long long and not long.

The second patch (nasinclude.patch) fixes an include problem I had while
compiling nas audio : when the <audio/audiolib.h> file lies in
/usr/X11R6/include, a -I/usr/X11R6/include option is needed or the file
isn't found.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 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     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 /* This is the joystick API for Simple DirectMedia Layer */
    29 
    30 #include <stdio.h>
    31 #include <stdlib.h>
    32 #include <string.h>
    33 
    34 #include "SDL_error.h"
    35 #include "SDL_events.h"
    36 #ifndef DISABLE_EVENTS
    37 #include "SDL_events_c.h"
    38 #endif
    39 #include "SDL_joystick_c.h"
    40 #include "SDL_sysjoystick.h"
    41 
    42 /* This is used for Quake III Arena */
    43 #ifdef DISABLE_EVENTS
    44 #define SDL_Lock_EventThread()
    45 #define SDL_Unlock_EventThread()
    46 #endif
    47 
    48 Uint8 SDL_numjoysticks = 0;
    49 SDL_Joystick **SDL_joysticks = NULL;
    50 static SDL_Joystick *default_joystick = NULL;
    51 
    52 int SDL_JoystickInit(void)
    53 {
    54 	int arraylen;
    55 	int status;
    56 
    57 	SDL_numjoysticks = 0;
    58 	status = SDL_SYS_JoystickInit();
    59 	if ( status >= 0 ) {
    60 		arraylen = (status+1)*sizeof(*SDL_joysticks);
    61 		SDL_joysticks = (SDL_Joystick **)malloc(arraylen);
    62 		if ( SDL_joysticks == NULL ) {
    63 			SDL_numjoysticks = 0;
    64 		} else {
    65 			memset(SDL_joysticks, 0, arraylen);
    66 			SDL_numjoysticks = status;
    67 		}
    68 		status = 0;
    69 	}
    70 	default_joystick = NULL;
    71 	return(status);
    72 }
    73 
    74 /*
    75  * Count the number of joysticks attached to the system
    76  */
    77 int SDL_NumJoysticks(void)
    78 {
    79 	return SDL_numjoysticks;
    80 }
    81 
    82 /*
    83  * Get the implementation dependent name of a joystick
    84  */
    85 const char *SDL_JoystickName(int device_index)
    86 {
    87 	if ( (device_index < 0) || (device_index >= SDL_numjoysticks) ) {
    88 		SDL_SetError("There are %d joysticks available",
    89 		             SDL_numjoysticks);
    90 		return(NULL);
    91 	}
    92 	return(SDL_SYS_JoystickName(device_index));
    93 }
    94 
    95 /*
    96  * Open a joystick for use - the index passed as an argument refers to
    97  * the N'th joystick on the system.  This index is the value which will
    98  * identify this joystick in future joystick events.
    99  *
   100  * This function returns a joystick identifier, or NULL if an error occurred.
   101  */
   102 SDL_Joystick *SDL_JoystickOpen(int device_index)
   103 {
   104 	int i;
   105 	SDL_Joystick *joystick;
   106 
   107 	if ( (device_index < 0) || (device_index >= SDL_numjoysticks) ) {
   108 		SDL_SetError("There are %d joysticks available",
   109 		             SDL_numjoysticks);
   110 		return(NULL);
   111 	}
   112 
   113 	/* If the joystick is already open, return it */
   114 	for ( i=0; SDL_joysticks[i]; ++i ) {
   115 		if ( device_index == SDL_joysticks[i]->index ) {
   116 			joystick = SDL_joysticks[i];
   117 			++joystick->ref_count;
   118 			return(joystick);
   119 		}
   120 	}
   121 
   122 	/* Create and initialize the joystick */
   123 	joystick = (SDL_Joystick *)malloc((sizeof *joystick));
   124 	if ( joystick != NULL ) {
   125 		memset(joystick, 0, (sizeof *joystick));
   126 		joystick->index = device_index;
   127 		if ( SDL_SYS_JoystickOpen(joystick) < 0 ) {
   128 			free(joystick);
   129 			joystick = NULL;
   130 		} else {
   131 			if ( joystick->naxes > 0 ) {
   132 				joystick->axes = (Sint16 *)malloc
   133 					(joystick->naxes*sizeof(Sint16));
   134 			}
   135 			if ( joystick->nhats > 0 ) {
   136 				joystick->hats = (Uint8 *)malloc
   137 					(joystick->nhats*sizeof(Uint8));
   138 			}
   139 			if ( joystick->nballs > 0 ) {
   140 				joystick->balls = (struct balldelta *)malloc
   141 				  (joystick->nballs*sizeof(*joystick->balls));
   142 			}
   143 			if ( joystick->nbuttons > 0 ) {
   144 				joystick->buttons = (Uint8 *)malloc
   145 					(joystick->nbuttons*sizeof(Uint8));
   146 			}
   147 			if ( ((joystick->naxes > 0) && !joystick->axes)
   148 			  || ((joystick->nhats > 0) && !joystick->hats)
   149 			  || ((joystick->nballs > 0) && !joystick->balls)
   150 			  || ((joystick->nbuttons > 0) && !joystick->buttons)) {
   151 				SDL_OutOfMemory();
   152 				SDL_JoystickClose(joystick);
   153 				joystick = NULL;
   154 			}
   155 			if ( joystick->axes ) {
   156 				memset(joystick->axes, 0,
   157 					joystick->naxes*sizeof(Sint16));
   158 			}
   159 			if ( joystick->hats ) {
   160 				memset(joystick->hats, 0,
   161 					joystick->nhats*sizeof(Uint8));
   162 			}
   163 			if ( joystick->balls ) {
   164 				memset(joystick->balls, 0,
   165 				  joystick->nballs*sizeof(*joystick->balls));
   166 			}
   167 			if ( joystick->buttons ) {
   168 				memset(joystick->buttons, 0,
   169 					joystick->nbuttons*sizeof(Uint8));
   170 			}
   171 		}
   172 	}
   173 	if ( joystick ) {
   174 		/* Add joystick to list */
   175 		++joystick->ref_count;
   176 		SDL_Lock_EventThread();
   177 		for ( i=0; SDL_joysticks[i]; ++i )
   178 			/* Skip to next joystick */;
   179 		SDL_joysticks[i] = joystick;
   180 		SDL_Unlock_EventThread();
   181 	}
   182 	return(joystick);
   183 }
   184 
   185 /*
   186  * Returns 1 if the joystick has been opened, or 0 if it has not.
   187  */
   188 int SDL_JoystickOpened(int device_index)
   189 {
   190 	int i, opened;
   191 
   192 	opened = 0;
   193 	for ( i=0; SDL_joysticks[i]; ++i ) {
   194 		if ( SDL_joysticks[i]->index == (Uint8)device_index ) {
   195 			opened = 1;
   196 			break;
   197 		}
   198 	}
   199 	return(opened);
   200 }
   201 
   202 static int ValidJoystick(SDL_Joystick **joystick)
   203 {
   204 	int valid;
   205 
   206 	if ( *joystick == NULL ) {
   207 		*joystick = default_joystick;
   208 	}
   209 	if ( *joystick == NULL ) {
   210 		SDL_SetError("Joystick hasn't been opened yet");
   211 		valid = 0;
   212 	} else {
   213 		valid = 1;
   214 	}
   215 	return valid;
   216 }
   217 
   218 /*
   219  * Get the device index of an opened joystick.
   220  */
   221 int SDL_JoystickIndex(SDL_Joystick *joystick)
   222 {
   223 	if ( ! ValidJoystick(&joystick) ) {
   224 		return(-1);
   225 	}
   226 	return(joystick->index);
   227 }
   228 
   229 /*
   230  * Get the number of multi-dimensional axis controls on a joystick
   231  */
   232 int SDL_JoystickNumAxes(SDL_Joystick *joystick)
   233 {
   234 	if ( ! ValidJoystick(&joystick) ) {
   235 		return(-1);
   236 	}
   237 	return(joystick->naxes);
   238 }
   239 
   240 /*
   241  * Get the number of hats on a joystick
   242  */
   243 int SDL_JoystickNumHats(SDL_Joystick *joystick)
   244 {
   245 	if ( ! ValidJoystick(&joystick) ) {
   246 		return(-1);
   247 	}
   248 	return(joystick->nhats);
   249 }
   250 
   251 /*
   252  * Get the number of trackballs on a joystick
   253  */
   254 int SDL_JoystickNumBalls(SDL_Joystick *joystick)
   255 {
   256 	if ( ! ValidJoystick(&joystick) ) {
   257 		return(-1);
   258 	}
   259 	return(joystick->nballs);
   260 }
   261 
   262 /*
   263  * Get the number of buttons on a joystick
   264  */
   265 int SDL_JoystickNumButtons(SDL_Joystick *joystick)
   266 {
   267 	if ( ! ValidJoystick(&joystick) ) {
   268 		return(-1);
   269 	}
   270 	return(joystick->nbuttons);
   271 }
   272 
   273 /*
   274  * Get the current state of an axis control on a joystick
   275  */
   276 Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis)
   277 {
   278 	Sint16 state;
   279 
   280 	if ( ! ValidJoystick(&joystick) ) {
   281 		return(0);
   282 	}
   283 	if ( axis < joystick->naxes ) {
   284 		state = joystick->axes[axis];
   285 	} else {
   286 		SDL_SetError("Joystick only has %d axes", joystick->naxes);
   287 		state = 0;
   288 	}
   289 	return(state);
   290 }
   291 
   292 /*
   293  * Get the current state of a hat on a joystick
   294  */
   295 Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat)
   296 {
   297 	Uint8 state;
   298 
   299 	if ( ! ValidJoystick(&joystick) ) {
   300 		return(0);
   301 	}
   302 	if ( hat < joystick->nhats ) {
   303 		state = joystick->hats[hat];
   304 	} else {
   305 		SDL_SetError("Joystick only has %d hats", joystick->nhats);
   306 		state = 0;
   307 	}
   308 	return(state);
   309 }
   310 
   311 /*
   312  * Get the ball axis change since the last poll
   313  */
   314 int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy)
   315 {
   316 	int retval;
   317 
   318 	if ( ! ValidJoystick(&joystick) ) {
   319 		return(-1);
   320 	}
   321 
   322 	retval = 0;
   323 	if ( ball < joystick->nballs ) {
   324 		if ( dx ) {
   325 			*dx = joystick->balls[ball].dx;
   326 		}
   327 		if ( dy ) {
   328 			*dy = joystick->balls[ball].dy;
   329 		}
   330 		joystick->balls[ball].dx = 0;
   331 		joystick->balls[ball].dy = 0;
   332 	} else {
   333 		SDL_SetError("Joystick only has %d balls", joystick->nballs);
   334 		retval = -1;
   335 	}
   336 	return(retval);
   337 }
   338 
   339 /*
   340  * Get the current state of a button on a joystick
   341  */
   342 Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button)
   343 {
   344 	Uint8 state;
   345 
   346 	if ( ! ValidJoystick(&joystick) ) {
   347 		return(0);
   348 	}
   349 	if ( button < joystick->nbuttons ) {
   350 		state = joystick->buttons[button];
   351 	} else {
   352 		SDL_SetError("Joystick only has %d buttons",joystick->nbuttons);
   353 		state = 0;
   354 	}
   355 	return(state);
   356 }
   357 
   358 /*
   359  * Close a joystick previously opened with SDL_JoystickOpen()
   360  */
   361 void SDL_JoystickClose(SDL_Joystick *joystick)
   362 {
   363 	int i;
   364 
   365 	if ( ! ValidJoystick(&joystick) ) {
   366 		return;
   367 	}
   368 
   369 	/* First decrement ref count */
   370 	if ( --joystick->ref_count > 0 ) {
   371 		return;
   372 	}
   373 
   374 	/* Lock the event queue - prevent joystick polling */
   375 	SDL_Lock_EventThread();
   376 
   377 	if ( joystick == default_joystick ) {
   378 		default_joystick = NULL;
   379 	}
   380 	SDL_SYS_JoystickClose(joystick);
   381 
   382 	/* Remove joystick from list */
   383 	for ( i=0; SDL_joysticks[i]; ++i ) {
   384 		if ( joystick == SDL_joysticks[i] ) {
   385 			memcpy(&SDL_joysticks[i], &SDL_joysticks[i+1],
   386 			       (SDL_numjoysticks-i)*sizeof(joystick));
   387 			break;
   388 		}
   389 	}
   390 
   391 	/* Let the event thread keep running */
   392 	SDL_Unlock_EventThread();
   393 
   394 	/* Free the data associated with this joystick */
   395 	if ( joystick->axes ) {
   396 		free(joystick->axes);
   397 	}
   398 	if ( joystick->hats ) {
   399 		free(joystick->hats);
   400 	}
   401 	if ( joystick->balls ) {
   402 		free(joystick->balls);
   403 	}
   404 	if ( joystick->buttons ) {
   405 		free(joystick->buttons);
   406 	}
   407 	free(joystick);
   408 }
   409 
   410 void SDL_JoystickQuit(void)
   411 {
   412 	/* Stop the event polling */
   413 	SDL_Lock_EventThread();
   414 	SDL_numjoysticks = 0;
   415 	SDL_Unlock_EventThread();
   416 
   417 	/* Quit the joystick setup */
   418 	SDL_SYS_JoystickQuit();
   419 	if ( SDL_joysticks ) {
   420 		free(SDL_joysticks);
   421 		SDL_joysticks = NULL;
   422 	}
   423 }
   424 
   425 
   426 /* These are global for SDL_sysjoystick.c and SDL_events.c */
   427 
   428 int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
   429 {
   430 	int posted;
   431 
   432 	/* Update internal joystick state */
   433 	joystick->axes[axis] = value;
   434 
   435 	/* Post the event, if desired */
   436 	posted = 0;
   437 #ifndef DISABLE_EVENTS
   438 	if ( SDL_ProcessEvents[SDL_JOYAXISMOTION] == SDL_ENABLE ) {
   439 		SDL_Event event;
   440 		event.type = SDL_JOYAXISMOTION;
   441 		event.jaxis.which = joystick->index;
   442 		event.jaxis.axis = axis;
   443 		event.jaxis.value = value;
   444 		if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
   445 			posted = 1;
   446 			SDL_PushEvent(&event);
   447 		}
   448 	}
   449 #endif /* !DISABLE_EVENTS */
   450 	return(posted);
   451 }
   452 
   453 int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
   454 {
   455 	int posted;
   456 
   457 	/* Update internal joystick state */
   458 	joystick->hats[hat] = value;
   459 
   460 	/* Post the event, if desired */
   461 	posted = 0;
   462 #ifndef DISABLE_EVENTS
   463 	if ( SDL_ProcessEvents[SDL_JOYHATMOTION] == SDL_ENABLE ) {
   464 		SDL_Event event;
   465 		event.jhat.type = SDL_JOYHATMOTION;
   466 		event.jhat.which = joystick->index;
   467 		event.jhat.hat = hat;
   468 		event.jhat.value = value;
   469 		if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
   470 			posted = 1;
   471 			SDL_PushEvent(&event);
   472 		}
   473 	}
   474 #endif /* !DISABLE_EVENTS */
   475 	return(posted);
   476 }
   477 
   478 int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball,
   479 					Sint16 xrel, Sint16 yrel)
   480 {
   481 	int posted;
   482 
   483 	/* Update internal mouse state */
   484 	joystick->balls[ball].dx += xrel;
   485 	joystick->balls[ball].dy += yrel;
   486 
   487 	/* Post the event, if desired */
   488 	posted = 0;
   489 #ifndef DISABLE_EVENTS
   490 	if ( SDL_ProcessEvents[SDL_JOYBALLMOTION] == SDL_ENABLE ) {
   491 		SDL_Event event;
   492 		event.jball.type = SDL_JOYBALLMOTION;
   493 		event.jball.which = joystick->index;
   494 		event.jball.ball = ball;
   495 		event.jball.xrel = xrel;
   496 		event.jball.yrel = yrel;
   497 		if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
   498 			posted = 1;
   499 			SDL_PushEvent(&event);
   500 		}
   501 	}
   502 #endif /* !DISABLE_EVENTS */
   503 	return(posted);
   504 }
   505 
   506 int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
   507 {
   508 	int posted;
   509 #ifndef DISABLE_EVENTS
   510 	SDL_Event event;
   511 
   512 	switch ( state ) {
   513 		case SDL_PRESSED:
   514 			event.type = SDL_JOYBUTTONDOWN;
   515 			break;
   516 		case SDL_RELEASED:
   517 			event.type = SDL_JOYBUTTONUP;
   518 			break;
   519 		default:
   520 			/* Invalid state -- bail */
   521 			return(0);
   522 	}
   523 #endif /* !DISABLE_EVENTS */
   524 
   525 	/* Update internal joystick state */
   526 	joystick->buttons[button] = state;
   527 
   528 	/* Post the event, if desired */
   529 	posted = 0;
   530 #ifndef DISABLE_EVENTS
   531 	if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) {
   532 		event.jbutton.which = joystick->index;
   533 		event.jbutton.button = button;
   534 		event.jbutton.state = state;
   535 		if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
   536 			posted = 1;
   537 			SDL_PushEvent(&event);
   538 		}
   539 	}
   540 #endif /* !DISABLE_EVENTS */
   541 	return(posted);
   542 }
   543 
   544 void SDL_JoystickUpdate(void)
   545 {
   546 	int i;
   547 
   548 	for ( i=0; SDL_joysticks[i]; ++i ) {
   549 		SDL_SYS_JoystickUpdate(SDL_joysticks[i]);
   550 	}
   551 }
   552 
   553 int SDL_JoystickEventState(int state)
   554 {
   555 #ifdef DISABLE_EVENTS
   556 	return SDL_IGNORE;
   557 #else
   558 	const Uint8 event_list[] = {
   559 		SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION,
   560 		SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP,
   561 	};
   562 	int i;
   563 
   564 	switch (state) {
   565 		case SDL_QUERY:
   566 			state = SDL_IGNORE;
   567 			for ( i=0; i<SDL_TABLESIZE(event_list); ++i ) {
   568 				state = SDL_EventState(event_list[i],SDL_QUERY);
   569 				if ( state == SDL_ENABLE ) {
   570 					break;
   571 				}
   572 			}
   573 			break;
   574 		default:
   575 			for ( i=0; i<SDL_TABLESIZE(event_list); ++i ) {
   576 				SDL_EventState(event_list[i], state);
   577 			}
   578 			break;
   579 	}
   580 	return(state);
   581 #endif /* DISABLE_EVENTS */
   582 }