/** * SDL joystick test * Copyright (C) 2007 Sylvain Beucler * This file is part of GNU FreeDink * GNU FreeDink 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 3 of the * License, or (at your option) any later version. * GNU FreeDink 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. If not, see * . */ /* Moves the heart surface using the joystick. Button 2 quits, button 4 goes full screen, button 6 triples the speed. */ #include #include #include "SDL.h" #define IMIN(a,b) ((a < b) ? a : b) #define IMAX(a,b) ((a > b) ? a : b) int main(int argc, char *argv[]) { SDL_Joystick *joystick; int i; int quit = 0; SDL_Surface *screen, *pic; Uint32 video_flags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_ANYFORMAT | SDL_RESIZABLE; SDL_Rect dst = {320, 240}; int default_screen_w = 640, default_screen_h = 480; double px = 320, py = 240, cur_joyx = 0, cur_joyy = 0; Uint32 last_update = 0; /* pixels per second */ int full_speed = 200; if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } screen = SDL_SetVideoMode(0, 0, 0, video_flags); /* SDL >= 1.10 */ if (screen == NULL) { printf("Trying %dx%d...\n", default_screen_w, default_screen_h); screen = SDL_SetVideoMode(default_screen_w, default_screen_h, 0, video_flags); if (screen == NULL) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } } SDL_WM_SetCaption("JoyTest", NULL); SDL_ShowCursor(SDL_DISABLE); pic = SDL_LoadBMP("pic.bmp"); if (pic == NULL) { fprintf(stderr, "Failed to load pic.bmp: %s\n", SDL_GetError()); exit(1); } SDL_SetColorKey(pic, SDL_SRCCOLORKEY, SDL_MapRGB(pic->format, 255, 255, 255)); printf("%i joysticks were found.\n\n", SDL_NumJoysticks() ); printf("The names of the joysticks are:\n"); for (i=0; i < SDL_NumJoysticks(); i++) { printf(" %s\n", SDL_JoystickName(i)); } SDL_JoystickEventState(SDL_ENABLE); joystick = SDL_JoystickOpen(0); printf("Number of axes: %d\n", SDL_JoystickNumAxes(joystick)); printf("Number of buttons: %d\n", SDL_JoystickNumButtons(joystick)); printf("Number of balls: %d\n", SDL_JoystickNumBalls(joystick)); printf("Number of hats: %d\n", SDL_JoystickNumHats(joystick)); /* Flush stacked joystick events */ { SDL_Event event; while (SDL_PollEvent(&event)); } /* Fill screen in blue */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 255)); SDL_Flip(screen); last_update = SDL_GetTicks(); /* Main game loop */ while(!quit) { SDL_Event event; while (SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: /* handle keyboard stuff here */ printf("Key pressed\n"); if (event.key.keysym.sym == 'q' || event.key.keysym.sym == SDLK_ESCAPE) quit = 1; break; case SDL_VIDEORESIZE: { SDL_ResizeEvent *resize = (SDL_ResizeEvent*)&event; screen = SDL_SetVideoMode(resize->w, resize->h, 0, video_flags); printf("Screen resized to %dx%d\n", resize->w, resize->h); } break; case SDL_QUIT: quit = 1; break; case SDL_JOYAXISMOTION: /* Joystick pad moved */ if (event.jaxis.axis == 0) { /* Ignore noise from joystick */ if ((event.jaxis.value < -3276 ) || (event.jaxis.value > 3276)) { cur_joyx = event.jaxis.value; } else cur_joyx = 0; } if (event.jaxis.axis == 1) { /* Ignore noise from joystick */ if ((event.jaxis.value < -3276 ) || (event.jaxis.value > 3276)) { cur_joyy = event.jaxis.value; } else cur_joyy = 0; } break; case SDL_JOYBUTTONDOWN: /* Joystick button pressed */ printf("Button %d pressed\n", event.jbutton.button); if (event.jbutton.button == 3) { SDL_WM_ToggleFullScreen(screen); } else if (event.jbutton.button == 1) { quit = 1; } else if (event.jbutton.button == 5) { full_speed *= 3; } break; case SDL_JOYBUTTONUP: /* Joystick button pressed */ if (event.jbutton.button == 5) { full_speed /= 3; } break; } } { SDL_Rect erase, update; int prev_x, prev_y; int update_p1_x, update_p1_y; int update_p2_x, update_p2_y; double dx = 0, dy = 0; Uint32 dt; /* Check elapsed time since last frame */ dt = SDL_GetTicks() - last_update; last_update = SDL_GetTicks(); /* Erase last position */ prev_x = dst.x; prev_y = dst.y; erase.x = prev_x; erase.y = prev_y; erase.w = pic->w; erase.h = pic->h; SDL_FillRect(screen, &erase, SDL_MapRGB(screen->format, 0, 0, 255)); /* Update position */ /* dx/dy is the speed in pixels per second */ /* In one second, with full push (32767), I'll move full_speed (200) pixels */ dx = cur_joyx * (1.0 * full_speed / 32767) * dt/1000; dy = cur_joyy * (1.0 * full_speed / 32767) * dt/1000; px += dx; py += dy; dst.x = px; dst.y = py; /* Display new position */ SDL_BlitSurface(pic, NULL, screen, &dst); /* What to refresh */ update_p1_x = IMIN(prev_x, dst.x); update_p1_y = IMIN(prev_y, dst.y); update_p2_x = IMAX(prev_x, dst.x) + pic->w; update_p2_y = IMAX(prev_y, dst.y) + pic->h; /* Clipping */ update_p1_x = IMIN(IMAX(update_p1_x, 0), screen->w); update_p1_y = IMIN(IMAX(update_p1_y, 0), screen->h); update_p2_x = IMIN(IMAX(update_p2_x, 0), screen->w); update_p2_y = IMIN(IMAX(update_p2_y, 0), screen->h); /* Refresh */ update.x = update_p1_x; update.y = update_p1_y; update.w = update_p2_x - update_p1_x; update.h = update_p2_y - update_p1_y; SDL_UpdateRects(screen, 1, &update); /* printf("pos %f,%f\n", px, py); */ } } SDL_JoystickClose(joystick); SDL_Quit(); return 0; }