Hello all, I was just wondering if people would be kind enough to test some
joystick code for me.
I only have access to on joystick and one machine.
I’d also like some suggestions on things that I can do to improve my joystick
handling.
i used png image files with alpha channels
background.png was 640x480
aim.png : 100x100
light-on & light-off : 50x50
I made mine w/ gimp.
right now I don’t have a home online to put this project of mine.
I hope to soon be able to do so.
(sourceforge won’t take it)
if anyone want’s a copy of the package they can email me and request on for
now. (330K tar.bz2)
Hope this helps some people w/ joystick questions too.
here is the code
/******************************************************************************
- joytest.c : this code is for testing joysticks using sdl.
- Copyright © 2002 Samuel E. Bray
- You may contact me at:
- aristoidaneel at yahoo.com
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program 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 General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to
- the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
*****************************************************************************/
/* ** ** ToDo: Install RCS ** ** */
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#define TRUE 1
#define FALSE 0
#define NUM_LIGHTS 24
/* Other constants */
const int JS_MAX = 65535;
/* global variables */
int screenWidth = 640;
int screenHeight = 480;
int screenBPP = 32;
int screenUnitX;
int screenUnitY;
int joyYCenter;
int joyXCenter;
int videoFlags = SDL_HWSURFACE | SDL_DOUBLEBUF;
int pad = 5; /* pad our edges */
SDL_Surface *screen;
SDL_Surface *onLight;
SDL_Surface *offLight;
SDL_Surface *background;
SDL_Surface *aim;
int isActive = FALSE;
typedef struct light_struct {
SDL_Surface *image;
int toggle;
int x_offset;
int y_offset;
} light;
light lights[NUM_LIGHTS];
typedef struct aimer_struct {
int x, y;
} aimer_t;
aimer_t aimer;
/*** End variables & constants ***/
/* use this to clean up and quit gracefully,
- depending on the particular situation /
void Quit(int returnCode)
{
SDL_Quit();
if(returnCode != 42)
exit(returnCode);
fprintf(stdout,"\nQuiting…\n");
}
/** End Quit ***/
/** ** ToDo ** ** : add logging
*
-
do so by
-
*creating a LogEntry function
-
which would
-
*take an error message,
-
*perhaps a pointer to some data,
-
*and a logLevel number
-
which would
-
*be used to rate the error and allow the user
-
to filter out unwanted or over zelous
-
warnings and errors.
-
LogEntry then puts the data in an array (or 2)
-
A parse function would then select the messages
-
to print and
-
Then the buffer array is written to the
-
external logfile and emptied at the end
-
of each event loop.
*/
/* use this function for error printing
- to stderr /
void Kaboom(char endString)
{
fprintf(stderr, “Error %s: %s\n”,endString, SDL_GetError());
Quit(1);
}
/* End Kaboom ***/
void VideoInit()
{
/* I should probably remove this function and merge the code elsewhere /
/ like main or QueryJoystick */
/* Init Video and setup drawing surface /
if(SDL_Init(SDL_INIT_VIDEO) == -1)
Kaboom(“Unable to initialize video hardware”);
}
/** End VideoInit ***/
/* Load the Images, exit w/ message on failure */
void Load_Images(void)
{
if((onLight = IMG_Load(“light-on.png”)) == NULL)
Kaboom(“Unable to load image”);
if((offLight = IMG_Load(“light-off.png”)) == NULL)
Kaboom(“Unable to load image”);
if((background = IMG_Load(“background.png”)) == NULL)
Kaboom(“Unable to load image”);
if((aim = IMG_Load(“aim.png”)) == NULL)
Kaboom(“Unable to load image”);
}
/*** End Load_Images ***/
/* ** ** ToDo: Add on screen text ** ** */
void Init()
{
int i = 0;
screenUnitX = JS_MAX / screenWidth;
screenUnitY = JS_MAX / screenHeight;
joyYCenter = screenHeight / 2;
joyXCenter = screenWidth / 2;
if((screen = SDL_SetVideoMode(screenWidth, screenHeight, screenBPP,
videoFlags)) == NULL)
Kaboom(“Unable to set video mode”);
/* umm, i dunno */
Load_Images();
for(i=0;i<NUM_LIGHTS;i++)
{
lights[i].x_offset = onLight->w;
lights[i].y_offset = (onLight->h * i) + 10;
lights[i].toggle = FALSE;
lights[i].image = offLight;
}
aimer.x = joyXCenter;
aimer.y = joyYCenter;
}
/*** End Init() ***/
/* check the system and list all available joysticks
- then test each one and display the results
- then ask the to pick a joystick to test */
SDL_Joystick *QueryJoyStick()
{
int numJoyStick = 0;
int i = 0;
int die = 0;
SDL_Joystick *joystick;
int choice = 0;
/* attempt joystick init, explode on error */
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
Kaboom(NULL);
/* This should never happen, but it doesn’t hurt to be robust /
/ Check to make sure there is at least one joystick available /
if((numJoyStick = SDL_NumJoysticks()) == 0)
Kaboom(“No joysticks available.”);
fprintf(stdout,“Found %i joystick(s) on this system.\n”,numJoyStick);
die = numJoyStick;
/ loop through each joystick and print the info for each /
for(i = 0; i < numJoyStick; i++)
{
if((joystick = SDL_JoystickOpen(i)) == NULL)
{
fprintf(stderr,“Unable to open joystick %i: %s\n”,i,SDL_GetError());
die–; / see below */
}
else
{
fprintf(stdout,“Joystick %i\n”,i);
fprintf(stdout,"\tName:…%s\n",SDL_JoystickName(i));
fprintf(stdout,"\tAxes: %i\n",SDL_JoystickNumAxes(joystick));
fprintf(stdout,"\tTrackBalls:…%i\n",SDL_JoystickNumBalls(joystick));
fprintf(stdout,"\tButtons: %i\n",SDL_JoystickNumButtons(joystick));
SDL_JoystickClose(joystick);
}
}
/* This should never happen, again, trying to be robust, like *
- above, checked for each joystick as it is looped through *
- if none can be opened at this point, then explode, and something is
- seriously wrong, with the system */
/* I have read recently, that the above robustness is an error in coding; /
/ I’m not sure how, perhaps a little extra bloat, this is a testing program
/
/ after all. */
/* **Note: Kaboom not used here, because Kaboom() checks with
SDL_GetError(),
- which would not be correct to do here. */
if(die == 0)
{
fprintf(stderr,“Unable to open any of the listed joysticks.\n”);
Quit(1);
}
/* ask for a joystick to work with */
fprintf(stdout,“Which Joystick do you want to use(0 - %i): “,(numJoyStick -
1));
scanf(”%i”,&choice);
/* attempt to open the requested joystick, explode on error. */
if((joystick = SDL_JoystickOpen(choice)) == NULL)
Kaboom(NULL);
fprintf(stdout,“Joystick %i:%s selected.\n”,choice,
SDL_JoystickName(choice));
return joystick;
}
/*** End QueryJoyStick() ***/
void DrawScreen(int numLights)
{
int i;
SDL_Rect source;
SDL_Rect dest;
/* first draw the background */
source.x = 0;
source.y = 0;
source.w = background->w;
source.h = background->h;
dest.x = 0;
dest.y = 0;
dest.w = background->w;
dest.h = background->h;
SDL_BlitSurface(background, &source, screen, &dest);
/* next draw the lights */
for(i=0;i<numLights;i++)
{
if(lights[i].toggle)
lights[i].image = onLight;
else
lights[i].image = offLight;
source.x = 0;
source.y = 0;
source.w = lights[i].image->w;
source.h = lights[i].image->h;
dest.x = lights[i].x_offset;
dest.y = lights[i].y_offset;
dest.w = source.w;
dest.h = source.h;
SDL_BlitSurface(lights[i].image, &source, screen, &dest);
}
/* now draw the aim recticle */
source.x = 0;
source.y = 0;
source.w = aim->w;
source.h = aim->h;
dest.x = aimer.x - (aim->w / 2);
dest.y = aimer.y - (aim->h / 2);
dest.w = aim->w;
dest.h = aim->h;
SDL_BlitSurface(aim, &source, screen, &dest);
SDL_Flip(screen);
}
/*** End DrawScreen() ***/
void HandleKeyPress (SDL_keysym keysym)
{
switch (keysym->sym)
{
case SDLK_q:
case SDLK_ESCAPE:
Quit (0);
break;
case SDLK_F1:
SDL_WM_ToggleFullScreen(screen);
break;
default:
break;
}
}
/** End HandleKeyPress() ***/
int ProcessEvent (SDL_Event event)
{
int done = FALSE;
while (SDL_PollEvent (event))
{
switch (event->type)
{
case SDL_ACTIVEEVENT:
if (event->active.gain == 0)
isActive = FALSE;
else
isActive = TRUE;
break;
case SDL_VIDEORESIZE:
if (!(screen = SDL_SetVideoMode (event->resize.w,
event->resize.h,
screenBPP,
videoFlags)
)
) / close of ‘if’ above */
{
Kaboom("Unable to set video mode after resize event.");
}
break;
case SDL_KEYDOWN:
HandleKeyPress (&event->key.keysym);
break;
case SDL_KEYUP:
/* HandleKeyUp (&event->key.keysym); */
break;
case SDL_JOYAXISMOTION:
/* use these 'if' statements to filter out
* joystick noise (a 0.1% deadzone) */
if((event->jaxis.value > (-32)) && (event->jaxis.value < 32))
{
if(event->jaxis.axis == 0)
aimer.x = joyXCenter;
if(event->jaxis.axis == 1)
aimer.y = joyYCenter;
}
if((event->jaxis.value < (-32)) || (event->jaxis.value > 32))
{
switch (event->jaxis.axis)
{
case 0:
aimer.x = (event->jaxis.value / screenUnitX) + joyXCenter;
if(aimer.x > screenWidth+pad)
aimer.x = 0;
if(aimer.x < 0-pad)
aimer.x = screenWidth;
break;
case 1:
aimer.y = (event->jaxis.value / screenUnitY) + joyYCenter;
if(aimer.y > screenHeight+pad)
aimer.y = 0;
if(aimer.y < 0-pad)
aimer.y = screenHeight;
break;
case 2:
/* ** ** ToDo: Add an animated slider to represent! ** ** */
break;
case 3:
/* ** ** ToDo: Same as above ** ** */
break;
default:
break;
}
}
break;
case SDL_JOYBUTTONDOWN:
lights[event->jbutton.button].toggle =
!lights[event->jbutton.button].toggle;
//fprintf(stdout,“Button %d pressed.\n”,event->jbutton.button);
break;
case SDL_JOYBUTTONUP:
/* comment out the below line to make the buttons toggle off with each
press /
lights[event->jbutton.button].toggle = FALSE;
break;
case SDL_QUIT:
fprintf(stdout,“Recived quit event\n”);
done = TRUE;
break;
default:
break;
}
}
return done;
}
/** End ProcessEvent() ***/
/* ** ** ToDo: Add command line options
-
Such as the ability to blindly choose a joystick
*/
int main()
{
SDL_Event event;
SDL_Joystick *joystick;
int numLights;
/* init video system */
VideoInit();
/* init JoyStick */
joystick = QueryJoyStick();
/* Determin how many lights needed to represent the buttons */
numLights=SDL_JoystickNumButtons(joystick);
/* init other thingies */
Init(numLights);
while(!ProcessEvent(&event))
{
if(isActive)
{
DrawScreen(numLights);
}
}
/* releasing surfaces and joystick */
fprintf(stdout,"\nReleasing surfaces and joysticks…\n");
fprintf(stdout,"\tReleasing background image…");
SDL_FreeSurface(background);
fprintf(stdout,“done\n”);
fprintf(stdout,"\tReleasing onLight image…");
SDL_FreeSurface(onLight);
fprintf(stdout,“done\n”);
fprintf(stdout,"\tReleasing offLight image…");
SDL_FreeSurface(offLight);
fprintf(stdout,“done\n”);
fprintf(stdout,"\tReleasing aim image…");
SDL_FreeSurface(aim);
fprintf(stdout,“done\n”);
fprintf(stdout,"\tReleasing joystick device…");
SDL_JoystickClose(joystick);
fprintf(stdout,“done\n”);
fprintf(stdout,“Calling Quit() to finalize close…”);
Quit(42);
fprintf(stdout,“done\nReturning to OS\n”);
return 0;
}