1 /**
2 * SDL joystick test
3
4 * Copyright (C) 2007 Sylvain Beucler
5
6 * This file is part of GNU FreeDink
7
8 * GNU FreeDink is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 3 of the
11 * License, or (at your option) any later version.
12
13 * GNU FreeDink is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
21 */
22
23 /* Moves the heart surface using the joystick. Button 2 quits, button
24 4 goes full screen, button 6 triples the speed. */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include "SDL.h"
29
30 #define IMIN(a,b) ((a < b) ? a : b)
31 #define IMAX(a,b) ((a > b) ? a : b)
32
main(int argc,char * argv[])33 int main(int argc, char *argv[]) {
34 SDL_Joystick *joystick;
35 int i;
36 int quit = 0;
37 SDL_Surface *screen, *pic;
38 Uint32 video_flags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_ANYFORMAT | SDL_RESIZABLE;
39 SDL_Rect dst = {320, 240};
40
41 int default_screen_w = 640, default_screen_h = 480;
42 double
43 px = 320,
44 py = 240,
45 cur_joyx = 0,
46 cur_joyy = 0;
47 Uint32 last_update = 0;
48
49 /* pixels per second */
50 int full_speed = 200;
51
52 if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0)
53 {
54 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
55 exit(1);
56 }
57
58 screen = SDL_SetVideoMode(0, 0, 0, video_flags); /* SDL >= 1.10 */
59 if (screen == NULL)
60 {
61 printf("Trying %dx%d...\n", default_screen_w, default_screen_h);
62 screen = SDL_SetVideoMode(default_screen_w, default_screen_h, 0, video_flags);
63 if (screen == NULL)
64 {
65 fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
66 exit(1);
67 }
68 }
69 SDL_WM_SetCaption("JoyTest", NULL);
70 SDL_ShowCursor(SDL_DISABLE);
71
72 pic = SDL_LoadBMP("pic.bmp");
73 if (pic == NULL)
74 {
75 fprintf(stderr, "Failed to load pic.bmp: %s\n", SDL_GetError());
76 exit(1);
77 }
78 SDL_SetColorKey(pic, SDL_SRCCOLORKEY, SDL_MapRGB(pic->format, 255, 255, 255));
79
80 printf("%i joysticks were found.\n\n", SDL_NumJoysticks() );
81 printf("The names of the joysticks are:\n");
82
83 for (i=0; i < SDL_NumJoysticks(); i++)
84 {
85 printf(" %s\n", SDL_JoystickName(i));
86 }
87
88 SDL_JoystickEventState(SDL_ENABLE);
89 joystick = SDL_JoystickOpen(0);
90 printf("Number of axes: %d\n", SDL_JoystickNumAxes(joystick));
91 printf("Number of buttons: %d\n", SDL_JoystickNumButtons(joystick));
92 printf("Number of balls: %d\n", SDL_JoystickNumBalls(joystick));
93 printf("Number of hats: %d\n", SDL_JoystickNumHats(joystick));
94
95 /* Flush stacked joystick events */
96 {
97 SDL_Event event;
98 while (SDL_PollEvent(&event));
99 }
100
101 /* Fill screen in blue */
102 SDL_FillRect(screen, NULL,
103 SDL_MapRGB(screen->format, 0, 0, 255));
104 SDL_Flip(screen);
105
106 last_update = SDL_GetTicks();
107
108 /* Main game loop */
109 while(!quit) {
110 SDL_Event event;
111 while (SDL_PollEvent(&event))
112 {
113 switch(event.type)
114 {
115 case SDL_KEYDOWN:
116 /* handle keyboard stuff here */
117 printf("Key pressed\n");
118 if (event.key.keysym.sym == 'q' || event.key.keysym.sym == SDLK_ESCAPE)
119 quit = 1;
120 break;
121
122 case SDL_VIDEORESIZE:
123 {
124 SDL_ResizeEvent *resize = (SDL_ResizeEvent*)&event;
125 screen = SDL_SetVideoMode(resize->w, resize->h, 0, video_flags);
126 printf("Screen resized to %dx%d\n", resize->w, resize->h);
127 }
128 break;
129
130 case SDL_QUIT:
131 quit = 1;
132
133 break;
134
135 case SDL_JOYAXISMOTION: /* Joystick pad moved */
136 if (event.jaxis.axis == 0)
137 {
138 /* Ignore noise from joystick */
139 if ((event.jaxis.value < -3276 ) || (event.jaxis.value > 3276))
140 {
141 cur_joyx = event.jaxis.value;
142 }
143 else
144 cur_joyx = 0;
145 }
146
147 if (event.jaxis.axis == 1)
148 {
149 /* Ignore noise from joystick */
150 if ((event.jaxis.value < -3276 ) || (event.jaxis.value > 3276))
151 {
152 cur_joyy = event.jaxis.value;
153 }
154 else
155 cur_joyy = 0;
156 }
157
158 break;
159
160 case SDL_JOYBUTTONDOWN: /* Joystick button pressed */
161 printf("Button %d pressed\n", event.jbutton.button);
162 if (event.jbutton.button == 3)
163 {
164 SDL_WM_ToggleFullScreen(screen);
165 }
166 else if (event.jbutton.button == 1)
167 {
168 quit = 1;
169 }
170 else if (event.jbutton.button == 5)
171 {
172 full_speed *= 3;
173 }
174 break;
175
176 case SDL_JOYBUTTONUP: /* Joystick button pressed */
177 if (event.jbutton.button == 5)
178 {
179 full_speed /= 3;
180 }
181 break;
182 }
183 }
184
185 {
186 SDL_Rect erase, update;
187 int prev_x, prev_y;
188 int update_p1_x, update_p1_y;
189 int update_p2_x, update_p2_y;
190 double dx = 0, dy = 0;
191 Uint32 dt;
192
193 /* Check elapsed time since last frame */
194 dt = SDL_GetTicks() - last_update;
195 last_update = SDL_GetTicks();
196
197
198 /* Erase last position */
199 prev_x = dst.x;
200 prev_y = dst.y;
201 erase.x = prev_x;
202 erase.y = prev_y;
203 erase.w = pic->w;
204 erase.h = pic->h;
205 SDL_FillRect(screen, &erase,
206 SDL_MapRGB(screen->format, 0, 0, 255));
207
208
209 /* Update position */
210 /* dx/dy is the speed in pixels per second */
211 /* In one second, with full push (32767), I'll move full_speed (200) pixels */
212 dx = cur_joyx * (1.0 * full_speed / 32767) * dt/1000;
213 dy = cur_joyy * (1.0 * full_speed / 32767) * dt/1000;
214 px += dx;
215 py += dy;
216 dst.x = px;
217 dst.y = py;
218
219
220 /* Display new position */
221 SDL_BlitSurface(pic, NULL, screen, &dst);
222
223
224 /* What to refresh */
225 update_p1_x = IMIN(prev_x, dst.x);
226 update_p1_y = IMIN(prev_y, dst.y);
227 update_p2_x = IMAX(prev_x, dst.x) + pic->w;
228 update_p2_y = IMAX(prev_y, dst.y) + pic->h;
229
230 /* Clipping */
231 update_p1_x = IMIN(IMAX(update_p1_x, 0), screen->w);
232 update_p1_y = IMIN(IMAX(update_p1_y, 0), screen->h);
233 update_p2_x = IMIN(IMAX(update_p2_x, 0), screen->w);
234 update_p2_y = IMIN(IMAX(update_p2_y, 0), screen->h);
235
236 /* Refresh */
237 update.x = update_p1_x;
238 update.y = update_p1_y;
239 update.w = update_p2_x - update_p1_x;
240 update.h = update_p2_y - update_p1_y;
241 SDL_UpdateRects(screen, 1, &update);
242 /* printf("pos %f,%f\n", px, py); */
243 }
244 }
245 SDL_JoystickClose(joystick);
246 SDL_Quit();
247 return 0;
248 }
249