slouken@6690
|
1 |
/*
|
slouken@8149
|
2 |
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
slouken@6690
|
3 |
|
slouken@6690
|
4 |
This software is provided 'as-is', without any express or implied
|
slouken@6690
|
5 |
warranty. In no event will the authors be held liable for any damages
|
slouken@6690
|
6 |
arising from the use of this software.
|
slouken@6690
|
7 |
|
slouken@6690
|
8 |
Permission is granted to anyone to use this software for any purpose,
|
slouken@6690
|
9 |
including commercial applications, and to alter it and redistribute it
|
slouken@6690
|
10 |
freely.
|
slouken@6690
|
11 |
*/
|
slouken@6690
|
12 |
|
slouken@6690
|
13 |
/* Simple program to test the SDL game controller routines */
|
slouken@6690
|
14 |
|
slouken@6690
|
15 |
#include <stdio.h>
|
slouken@6690
|
16 |
#include <stdlib.h>
|
slouken@6690
|
17 |
#include <string.h>
|
slouken@6690
|
18 |
|
slouken@6690
|
19 |
#include "SDL.h"
|
slouken@6690
|
20 |
|
aschiffler@6771
|
21 |
#ifndef SDL_JOYSTICK_DISABLED
|
aschiffler@6771
|
22 |
|
slouken@6690
|
23 |
#ifdef __IPHONEOS__
|
jorgen@7056
|
24 |
#define SCREEN_WIDTH 320
|
jorgen@7056
|
25 |
#define SCREEN_HEIGHT 480
|
slouken@6690
|
26 |
#else
|
jorgen@7056
|
27 |
#define SCREEN_WIDTH 640
|
jorgen@7056
|
28 |
#define SCREEN_HEIGHT 480
|
slouken@6690
|
29 |
#endif
|
slouken@6690
|
30 |
|
slouken@6690
|
31 |
#define MAX_NUM_AXES 6
|
slouken@6690
|
32 |
#define MAX_NUM_HATS 2
|
slouken@6690
|
33 |
|
slouken@6690
|
34 |
static void
|
slouken@6690
|
35 |
DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
|
slouken@6690
|
36 |
{
|
slouken@6690
|
37 |
const SDL_Rect area = { x, y, w, h };
|
slouken@6690
|
38 |
SDL_RenderFillRect(r, &area);
|
slouken@6690
|
39 |
}
|
slouken@6690
|
40 |
|
icculus@6914
|
41 |
static const char *
|
icculus@6917
|
42 |
ControllerAxisName(const SDL_GameControllerAxis axis)
|
icculus@6914
|
43 |
{
|
icculus@6914
|
44 |
switch (axis)
|
icculus@6914
|
45 |
{
|
icculus@6914
|
46 |
#define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax
|
icculus@6914
|
47 |
AXIS_CASE(INVALID);
|
icculus@6914
|
48 |
AXIS_CASE(LEFTX);
|
icculus@6914
|
49 |
AXIS_CASE(LEFTY);
|
icculus@6914
|
50 |
AXIS_CASE(RIGHTX);
|
icculus@6914
|
51 |
AXIS_CASE(RIGHTY);
|
icculus@6914
|
52 |
AXIS_CASE(TRIGGERLEFT);
|
icculus@6914
|
53 |
AXIS_CASE(TRIGGERRIGHT);
|
icculus@6914
|
54 |
#undef AXIS_CASE
|
icculus@6914
|
55 |
default: return "???";
|
icculus@6914
|
56 |
}
|
icculus@6914
|
57 |
}
|
icculus@6914
|
58 |
|
icculus@6914
|
59 |
static const char *
|
icculus@6917
|
60 |
ControllerButtonName(const SDL_GameControllerButton button)
|
icculus@6914
|
61 |
{
|
icculus@6914
|
62 |
switch (button)
|
icculus@6914
|
63 |
{
|
icculus@6914
|
64 |
#define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn
|
icculus@6914
|
65 |
BUTTON_CASE(INVALID);
|
icculus@6914
|
66 |
BUTTON_CASE(A);
|
icculus@6914
|
67 |
BUTTON_CASE(B);
|
icculus@6914
|
68 |
BUTTON_CASE(X);
|
icculus@6914
|
69 |
BUTTON_CASE(Y);
|
icculus@6914
|
70 |
BUTTON_CASE(BACK);
|
icculus@6914
|
71 |
BUTTON_CASE(GUIDE);
|
icculus@6914
|
72 |
BUTTON_CASE(START);
|
icculus@6914
|
73 |
BUTTON_CASE(LEFTSTICK);
|
icculus@6914
|
74 |
BUTTON_CASE(RIGHTSTICK);
|
icculus@6914
|
75 |
BUTTON_CASE(LEFTSHOULDER);
|
icculus@6914
|
76 |
BUTTON_CASE(RIGHTSHOULDER);
|
icculus@6914
|
77 |
BUTTON_CASE(DPAD_UP);
|
icculus@6914
|
78 |
BUTTON_CASE(DPAD_DOWN);
|
icculus@6914
|
79 |
BUTTON_CASE(DPAD_LEFT);
|
icculus@6914
|
80 |
BUTTON_CASE(DPAD_RIGHT);
|
icculus@6914
|
81 |
#undef BUTTON_CASE
|
icculus@6914
|
82 |
default: return "???";
|
icculus@6914
|
83 |
}
|
icculus@6914
|
84 |
}
|
icculus@6914
|
85 |
|
slouken@8068
|
86 |
SDL_bool
|
slouken@6690
|
87 |
WatchGameController(SDL_GameController * gamecontroller)
|
slouken@6690
|
88 |
{
|
icculus@6916
|
89 |
const char *name = SDL_GameControllerName(gamecontroller);
|
icculus@6914
|
90 |
const char *basetitle = "Game Controller Test: ";
|
icculus@6916
|
91 |
const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1;
|
aschiffler@7639
|
92 |
char *title = (char *)SDL_malloc(titlelen);
|
slouken@6690
|
93 |
SDL_Window *window = NULL;
|
slouken@6690
|
94 |
SDL_Renderer *screen = NULL;
|
slouken@8068
|
95 |
SDL_bool retval = SDL_FALSE;
|
slouken@8068
|
96 |
SDL_bool done = SDL_FALSE;
|
slouken@6690
|
97 |
SDL_Event event;
|
slouken@6690
|
98 |
int i;
|
slouken@6690
|
99 |
|
icculus@6914
|
100 |
if (title) {
|
icculus@6916
|
101 |
SDL_snprintf(title, titlelen, "%s%s", basetitle, name);
|
icculus@6914
|
102 |
}
|
icculus@6914
|
103 |
|
slouken@6690
|
104 |
/* Create a window to display controller axis position */
|
icculus@6914
|
105 |
window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
|
slouken@6690
|
106 |
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
|
philipp@7478
|
107 |
SCREEN_HEIGHT, 0);
|
slouken@6690
|
108 |
if (window == NULL) {
|
aschiffler@7639
|
109 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
|
slouken@8068
|
110 |
return SDL_FALSE;
|
slouken@6690
|
111 |
}
|
slouken@6690
|
112 |
|
slouken@6690
|
113 |
screen = SDL_CreateRenderer(window, -1, 0);
|
slouken@6690
|
114 |
if (screen == NULL) {
|
aschiffler@7639
|
115 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
|
slouken@6690
|
116 |
SDL_DestroyWindow(window);
|
slouken@8068
|
117 |
return SDL_FALSE;
|
slouken@6690
|
118 |
}
|
slouken@6690
|
119 |
|
slouken@6690
|
120 |
SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
|
slouken@6690
|
121 |
SDL_RenderClear(screen);
|
slouken@6690
|
122 |
SDL_RenderPresent(screen);
|
jorgen@7056
|
123 |
SDL_RaiseWindow(window);
|
slouken@6690
|
124 |
|
slouken@6690
|
125 |
/* Print info about the controller we are watching */
|
aschiffler@7639
|
126 |
SDL_Log("Watching controller %s\n", name ? name : "Unknown Controller");
|
slouken@7191
|
127 |
|
slouken@6690
|
128 |
/* Loop, getting controller events! */
|
slouken@6690
|
129 |
while (!done) {
|
slouken@6690
|
130 |
/* blank screen, set up for drawing this frame. */
|
slouken@6690
|
131 |
SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
|
slouken@6690
|
132 |
SDL_RenderClear(screen);
|
slouken@6690
|
133 |
|
slouken@6690
|
134 |
while (SDL_PollEvent(&event)) {
|
slouken@6690
|
135 |
switch (event.type) {
|
slouken@6690
|
136 |
case SDL_CONTROLLERAXISMOTION:
|
aschiffler@7639
|
137 |
SDL_Log("Controller %d axis %d ('%s') value: %d\n",
|
slouken@6690
|
138 |
event.caxis.which,
|
icculus@6914
|
139 |
event.caxis.axis,
|
aschiffler@7639
|
140 |
ControllerAxisName((SDL_GameControllerAxis)event.caxis.axis),
|
icculus@6914
|
141 |
event.caxis.value);
|
slouken@6690
|
142 |
break;
|
slouken@6690
|
143 |
case SDL_CONTROLLERBUTTONDOWN:
|
aschiffler@7639
|
144 |
SDL_Log("Controller %d button %d ('%s') down\n",
|
icculus@6914
|
145 |
event.cbutton.which, event.cbutton.button,
|
aschiffler@7639
|
146 |
ControllerButtonName((SDL_GameControllerButton)event.cbutton.button));
|
slouken@6690
|
147 |
break;
|
slouken@6690
|
148 |
case SDL_CONTROLLERBUTTONUP:
|
aschiffler@7639
|
149 |
SDL_Log("Controller %d button %d ('%s') up\n",
|
icculus@6914
|
150 |
event.cbutton.which, event.cbutton.button,
|
aschiffler@7639
|
151 |
ControllerButtonName((SDL_GameControllerButton)event.cbutton.button));
|
slouken@6690
|
152 |
break;
|
slouken@6690
|
153 |
case SDL_KEYDOWN:
|
slouken@6690
|
154 |
if (event.key.keysym.sym != SDLK_ESCAPE) {
|
slouken@6690
|
155 |
break;
|
slouken@6690
|
156 |
}
|
slouken@6690
|
157 |
/* Fall through to signal quit */
|
slouken@6690
|
158 |
case SDL_QUIT:
|
slouken@8068
|
159 |
done = SDL_TRUE;
|
slouken@6690
|
160 |
break;
|
slouken@6690
|
161 |
default:
|
slouken@6690
|
162 |
break;
|
slouken@6690
|
163 |
}
|
slouken@6690
|
164 |
}
|
slouken@6690
|
165 |
/* Update visual controller state */
|
slouken@6690
|
166 |
SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE);
|
slouken@6690
|
167 |
for (i = 0; i <SDL_CONTROLLER_BUTTON_MAX; ++i) {
|
aschiffler@7639
|
168 |
if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) {
|
slouken@6690
|
169 |
DrawRect(screen, i * 34, SCREEN_HEIGHT - 34, 32, 32);
|
slouken@6690
|
170 |
}
|
slouken@6690
|
171 |
}
|
slouken@6690
|
172 |
|
slouken@6690
|
173 |
SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE);
|
slouken@6690
|
174 |
for (i = 0; i < SDL_CONTROLLER_AXIS_MAX / 2; ++i) {
|
slouken@6690
|
175 |
/* Draw the X/Y axis */
|
slouken@6690
|
176 |
int x, y;
|
aschiffler@7639
|
177 |
x = (((int) SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i * 2 + 0))) + 32768);
|
slouken@6690
|
178 |
x *= SCREEN_WIDTH;
|
slouken@6690
|
179 |
x /= 65535;
|
slouken@6690
|
180 |
if (x < 0) {
|
slouken@6690
|
181 |
x = 0;
|
slouken@6690
|
182 |
} else if (x > (SCREEN_WIDTH - 16)) {
|
slouken@6690
|
183 |
x = SCREEN_WIDTH - 16;
|
slouken@6690
|
184 |
}
|
aschiffler@7639
|
185 |
y = (((int) SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i * 2 + 1))) + 32768);
|
slouken@6690
|
186 |
y *= SCREEN_HEIGHT;
|
slouken@6690
|
187 |
y /= 65535;
|
slouken@6690
|
188 |
if (y < 0) {
|
slouken@6690
|
189 |
y = 0;
|
slouken@6690
|
190 |
} else if (y > (SCREEN_HEIGHT - 16)) {
|
slouken@6690
|
191 |
y = SCREEN_HEIGHT - 16;
|
slouken@6690
|
192 |
}
|
slouken@6690
|
193 |
|
slouken@6690
|
194 |
DrawRect(screen, x, y, 16, 16);
|
slouken@6690
|
195 |
}
|
slouken@6690
|
196 |
|
slouken@6690
|
197 |
SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE);
|
slouken@6690
|
198 |
|
slouken@6690
|
199 |
SDL_RenderPresent(screen);
|
slouken@7191
|
200 |
|
slouken@8068
|
201 |
if (!SDL_GameControllerGetAttached(gamecontroller)) {
|
slouken@8068
|
202 |
done = SDL_TRUE;
|
slouken@8068
|
203 |
retval = SDL_TRUE; /* keep going, wait for reattach. */
|
slouken@8068
|
204 |
}
|
slouken@6690
|
205 |
}
|
slouken@6690
|
206 |
|
slouken@6690
|
207 |
SDL_DestroyRenderer(screen);
|
slouken@6690
|
208 |
SDL_DestroyWindow(window);
|
slouken@8068
|
209 |
return retval;
|
slouken@6690
|
210 |
}
|
slouken@6690
|
211 |
|
slouken@6690
|
212 |
int
|
slouken@6690
|
213 |
main(int argc, char *argv[])
|
slouken@6690
|
214 |
{
|
slouken@6690
|
215 |
int i;
|
jorgen@7056
|
216 |
int nController = 0;
|
jorgen@7056
|
217 |
int retcode = 0;
|
jorgen@7056
|
218 |
char guid[64];
|
slouken@6690
|
219 |
SDL_GameController *gamecontroller;
|
slouken@6690
|
220 |
|
aschiffler@7639
|
221 |
/* Enable standard application logging */
|
aschiffler@7639
|
222 |
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
aschiffler@7639
|
223 |
|
slouken@6690
|
224 |
/* Initialize SDL (Note: video is required to start event loop) */
|
slouken@6690
|
225 |
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER ) < 0) {
|
aschiffler@7639
|
226 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
jorgen@7056
|
227 |
return 1;
|
slouken@6690
|
228 |
}
|
gabomdq@8043
|
229 |
|
gabomdq@8043
|
230 |
SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");
|
slouken@6690
|
231 |
|
slouken@6690
|
232 |
/* Print information about the controller */
|
slouken@6690
|
233 |
for (i = 0; i < SDL_NumJoysticks(); ++i) {
|
jorgen@7056
|
234 |
const char *name;
|
icculus@7705
|
235 |
const char *description;
|
jorgen@7056
|
236 |
|
jorgen@7056
|
237 |
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i),
|
jorgen@7056
|
238 |
guid, sizeof (guid));
|
jorgen@7056
|
239 |
|
jorgen@7056
|
240 |
if ( SDL_IsGameController(i) )
|
jorgen@7056
|
241 |
{
|
jorgen@7056
|
242 |
nController++;
|
jorgen@7056
|
243 |
name = SDL_GameControllerNameForIndex(i);
|
icculus@7705
|
244 |
description = "Controller";
|
jorgen@7056
|
245 |
} else {
|
jorgen@7056
|
246 |
name = SDL_JoystickNameForIndex(i);
|
icculus@7705
|
247 |
description = "Joystick";
|
jorgen@7056
|
248 |
}
|
aschiffler@7639
|
249 |
SDL_Log("%s %d: %s (guid %s)\n", description, i, name ? name : "Unknown", guid);
|
slouken@6690
|
250 |
}
|
aschiffler@7639
|
251 |
SDL_Log("There are %d game controller(s) attached (%d joystick(s))\n", nController, SDL_NumJoysticks());
|
slouken@6690
|
252 |
|
slouken@6690
|
253 |
if (argv[1]) {
|
slouken@8068
|
254 |
SDL_bool reportederror = SDL_FALSE;
|
slouken@8068
|
255 |
SDL_bool keepGoing = SDL_TRUE;
|
slouken@8068
|
256 |
SDL_Event event;
|
jorgen@7056
|
257 |
int device = atoi(argv[1]);
|
jorgen@7056
|
258 |
if (device >= SDL_NumJoysticks()) {
|
aschiffler@7639
|
259 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%i is an invalid joystick index.\n", device);
|
jorgen@7056
|
260 |
retcode = 1;
|
jorgen@7056
|
261 |
} else {
|
jorgen@7056
|
262 |
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(device),
|
jorgen@7056
|
263 |
guid, sizeof (guid));
|
aschiffler@7639
|
264 |
SDL_Log("Attempting to open device %i, guid %s\n", device, guid);
|
jorgen@7056
|
265 |
gamecontroller = SDL_GameControllerOpen(device);
|
slouken@8068
|
266 |
while (keepGoing) {
|
slouken@8068
|
267 |
if (gamecontroller == NULL) {
|
slouken@8068
|
268 |
if (!reportederror) {
|
slouken@8068
|
269 |
if (gamecontroller == NULL) {
|
slouken@8068
|
270 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open gamecontroller %d: %s\n", device, SDL_GetError());
|
slouken@8068
|
271 |
retcode = 1;
|
slouken@8068
|
272 |
}
|
slouken@8068
|
273 |
keepGoing = SDL_FALSE;
|
slouken@8068
|
274 |
reportederror = SDL_TRUE;
|
slouken@8068
|
275 |
}
|
slouken@8068
|
276 |
} else {
|
slouken@8068
|
277 |
reportederror = SDL_FALSE;
|
slouken@8068
|
278 |
keepGoing = WatchGameController(gamecontroller);
|
slouken@8068
|
279 |
SDL_GameControllerClose(gamecontroller);
|
slouken@8068
|
280 |
}
|
slouken@8068
|
281 |
|
slouken@8068
|
282 |
gamecontroller = NULL;
|
slouken@8068
|
283 |
if (keepGoing) {
|
slouken@8068
|
284 |
SDL_Log("Waiting for attach\n");
|
slouken@8068
|
285 |
}
|
slouken@8068
|
286 |
while (keepGoing) {
|
slouken@8068
|
287 |
SDL_WaitEvent(&event);
|
slouken@8068
|
288 |
if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN)
|
slouken@8068
|
289 |
|| (event.type == SDL_MOUSEBUTTONDOWN)) {
|
slouken@8068
|
290 |
keepGoing = SDL_FALSE;
|
slouken@8068
|
291 |
} else if (event.type == SDL_CONTROLLERDEVICEADDED) {
|
slouken@8068
|
292 |
gamecontroller = SDL_GameControllerOpen(event.cdevice.which);
|
slouken@8068
|
293 |
break;
|
slouken@8068
|
294 |
}
|
slouken@8068
|
295 |
}
|
jorgen@7056
|
296 |
}
|
jorgen@7056
|
297 |
}
|
jorgen@7056
|
298 |
}
|
slouken@6690
|
299 |
|
jorgen@7056
|
300 |
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
|
jorgen@7056
|
301 |
|
jorgen@7056
|
302 |
return retcode;
|
slouken@6690
|
303 |
}
|
aschiffler@6771
|
304 |
|
aschiffler@6771
|
305 |
#else
|
aschiffler@6771
|
306 |
|
aschiffler@6771
|
307 |
int
|
aschiffler@6771
|
308 |
main(int argc, char *argv[])
|
aschiffler@6771
|
309 |
{
|
aschiffler@7639
|
310 |
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n");
|
aschiffler@6771
|
311 |
exit(1);
|
aschiffler@6771
|
312 |
}
|
aschiffler@6771
|
313 |
|
aschiffler@6771
|
314 |
#endif
|