Skip to content

Latest commit

 

History

History
785 lines (696 loc) · 30.4 KB

controllermap.c

File metadata and controls

785 lines (696 loc) · 30.4 KB
 
Jan 5, 2019
Jan 5, 2019
2
Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
/* Game controller mapping generator */
/* Gabriel Jacobo <gabomdq@gmail.com> */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#ifndef SDL_JOYSTICK_DISABLED
Nov 21, 2019
Nov 21, 2019
24
25
26
/* Define this for verbose output while mapping controllers */
#define DEBUG_CONTROLLERMAP
27
28
29
30
31
#ifdef __IPHONEOS__
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
#else
#define SCREEN_WIDTH 512
Oct 13, 2016
Oct 13, 2016
32
#define SCREEN_HEIGHT 320
33
34
35
36
37
#endif
#define MARKER_BUTTON 1
#define MARKER_AXIS 2
Dec 27, 2016
Dec 27, 2016
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
enum
{
SDL_CONTROLLER_BINDING_AXIS_LEFTX_NEGATIVE,
SDL_CONTROLLER_BINDING_AXIS_LEFTX_POSITIVE,
SDL_CONTROLLER_BINDING_AXIS_LEFTY_NEGATIVE,
SDL_CONTROLLER_BINDING_AXIS_LEFTY_POSITIVE,
SDL_CONTROLLER_BINDING_AXIS_RIGHTX_NEGATIVE,
SDL_CONTROLLER_BINDING_AXIS_RIGHTX_POSITIVE,
SDL_CONTROLLER_BINDING_AXIS_RIGHTY_NEGATIVE,
SDL_CONTROLLER_BINDING_AXIS_RIGHTY_POSITIVE,
SDL_CONTROLLER_BINDING_AXIS_TRIGGERLEFT,
SDL_CONTROLLER_BINDING_AXIS_TRIGGERRIGHT,
SDL_CONTROLLER_BINDING_AXIS_MAX,
};
#define BINDING_COUNT (SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_MAX)
Dec 15, 2016
Dec 15, 2016
54
55
static struct
56
57
58
59
60
{
int x, y;
double angle;
int marker;
Dec 15, 2016
Dec 15, 2016
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
} s_arrBindingDisplay[BINDING_COUNT] = {
{ 387, 167, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_A */
{ 431, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_B */
{ 342, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_X */
{ 389, 101, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_Y */
{ 174, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_BACK */
{ 233, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_GUIDE */
{ 289, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_START */
{ 75, 154, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_LEFTSTICK */
{ 305, 230, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_RIGHTSTICK */
{ 77, 40, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_LEFTSHOULDER */
{ 396, 36, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_RIGHTSHOULDER */
{ 154, 188, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_UP */
{ 154, 249, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_DOWN */
{ 116, 217, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_LEFT */
{ 186, 217, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_RIGHT */
Dec 27, 2016
Dec 27, 2016
77
78
79
80
81
82
83
84
85
86
{ 74, 153, 270.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_LEFTX_NEGATIVE */
{ 74, 153, 90.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_LEFTX_POSITIVE */
{ 74, 153, 0.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_LEFTY_NEGATIVE */
{ 74, 153, 180.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_LEFTY_POSITIVE */
{ 306, 231, 270.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_RIGHTX_NEGATIVE */
{ 306, 231, 90.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_RIGHTX_POSITIVE */
{ 306, 231, 0.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_RIGHTY_NEGATIVE */
{ 306, 231, 180.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_RIGHTY_POSITIVE */
{ 91, -20, 180.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_TRIGGERLEFT */
{ 375, -20, 180.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_TRIGGERRIGHT */
Dec 15, 2016
Dec 15, 2016
87
88
89
90
91
92
93
};
static int s_arrBindingOrder[BINDING_COUNT] = {
SDL_CONTROLLER_BUTTON_A,
SDL_CONTROLLER_BUTTON_B,
SDL_CONTROLLER_BUTTON_Y,
SDL_CONTROLLER_BUTTON_X,
Dec 27, 2016
Dec 27, 2016
94
95
96
97
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_LEFTX_NEGATIVE,
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_LEFTX_POSITIVE,
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_LEFTY_NEGATIVE,
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_LEFTY_POSITIVE,
Dec 15, 2016
Dec 15, 2016
98
SDL_CONTROLLER_BUTTON_LEFTSTICK,
Dec 27, 2016
Dec 27, 2016
99
100
101
102
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_RIGHTX_NEGATIVE,
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_RIGHTX_POSITIVE,
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_RIGHTY_NEGATIVE,
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_RIGHTY_POSITIVE,
Dec 15, 2016
Dec 15, 2016
103
104
SDL_CONTROLLER_BUTTON_RIGHTSTICK,
SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
Dec 27, 2016
Dec 27, 2016
105
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_TRIGGERLEFT,
Dec 15, 2016
Dec 15, 2016
106
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
Dec 27, 2016
Dec 27, 2016
107
SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_TRIGGERRIGHT,
Dec 15, 2016
Dec 15, 2016
108
109
110
111
112
113
114
115
116
SDL_CONTROLLER_BUTTON_DPAD_UP,
SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
SDL_CONTROLLER_BUTTON_BACK,
SDL_CONTROLLER_BUTTON_GUIDE,
SDL_CONTROLLER_BUTTON_START,
};
Dec 27, 2016
Dec 27, 2016
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
typedef struct
{
SDL_GameControllerBindType bindType;
union
{
int button;
struct {
int axis;
int axis_min;
int axis_max;
} axis;
struct {
int hat;
int hat_mask;
} hat;
} value;
Jan 21, 2017
Jan 21, 2017
137
138
SDL_bool committed;
Dec 27, 2016
Dec 27, 2016
139
140
141
142
143
144
145
} SDL_GameControllerExtendedBind;
static SDL_GameControllerExtendedBind s_arrBindings[BINDING_COUNT];
typedef struct
{
SDL_bool m_bMoving;
Dec 5, 2019
Dec 5, 2019
146
int m_nLastValue;
Dec 27, 2016
Dec 27, 2016
147
148
149
150
151
152
153
int m_nStartingValue;
int m_nFarthestValue;
} AxisState;
static int s_nNumAxes;
static AxisState *s_arrAxisState;
Dec 15, 2016
Dec 15, 2016
154
155
156
static int s_iCurrentBinding;
static Uint32 s_unPendingAdvanceTime;
static SDL_bool s_bBindingComplete;
Sep 21, 2016
Sep 21, 2016
159
LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
{
SDL_Surface *temp;
SDL_Texture *texture;
/* Load the sprite image */
temp = SDL_LoadBMP(file);
if (temp == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
return NULL;
}
/* Set transparent pixel as the pixel at (0,0) */
if (transparent) {
if (temp->format->palette) {
SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
}
}
/* Create textures from the image */
texture = SDL_CreateTextureFromSurface(renderer, temp);
if (!texture) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
SDL_FreeSurface(temp);
return NULL;
}
SDL_FreeSurface(temp);
/* We're ready to roll. :) */
return texture;
}
Dec 27, 2016
Dec 27, 2016
191
192
static int
StandardizeAxisValue(int nValue)
Dec 15, 2016
Dec 15, 2016
193
{
Dec 27, 2016
Dec 27, 2016
194
195
196
197
198
199
200
201
202
203
204
205
if (nValue > SDL_JOYSTICK_AXIS_MAX/2) {
return SDL_JOYSTICK_AXIS_MAX;
} else if (nValue < SDL_JOYSTICK_AXIS_MIN/2) {
return SDL_JOYSTICK_AXIS_MIN;
} else {
return 0;
}
}
static void
SetCurrentBinding(int iBinding)
{
Jan 4, 2017
Jan 4, 2017
206
int iIndex;
Dec 27, 2016
Dec 27, 2016
207
SDL_GameControllerExtendedBind *pBinding;
Dec 15, 2016
Dec 15, 2016
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
if (iBinding < 0) {
return;
}
if (iBinding == BINDING_COUNT) {
s_bBindingComplete = SDL_TRUE;
return;
}
s_iCurrentBinding = iBinding;
pBinding = &s_arrBindings[s_arrBindingOrder[s_iCurrentBinding]];
SDL_zerop(pBinding);
Jan 4, 2017
Jan 4, 2017
223
224
225
for (iIndex = 0; iIndex < s_nNumAxes; ++iIndex) {
s_arrAxisState[iIndex].m_nFarthestValue = s_arrAxisState[iIndex].m_nStartingValue;
}
Dec 27, 2016
Dec 27, 2016
226
Dec 15, 2016
Dec 15, 2016
227
228
229
s_unPendingAdvanceTime = 0;
}
Jan 4, 2017
Jan 4, 2017
230
231
232
233
234
235
236
237
238
239
240
241
242
static SDL_bool
BBindingContainsBinding(const SDL_GameControllerExtendedBind *pBindingA, const SDL_GameControllerExtendedBind *pBindingB)
{
if (pBindingA->bindType != pBindingB->bindType)
{
return SDL_FALSE;
}
switch (pBindingA->bindType)
{
case SDL_CONTROLLER_BINDTYPE_AXIS:
if (pBindingA->value.axis.axis != pBindingB->value.axis.axis) {
return SDL_FALSE;
}
Jan 21, 2017
Jan 21, 2017
243
244
245
if (!pBindingA->committed) {
return SDL_FALSE;
}
Jan 4, 2017
Jan 4, 2017
246
247
248
249
250
251
252
253
254
255
256
257
258
{
int minA = SDL_min(pBindingA->value.axis.axis_min, pBindingA->value.axis.axis_max);
int maxA = SDL_max(pBindingA->value.axis.axis_min, pBindingA->value.axis.axis_max);
int minB = SDL_min(pBindingB->value.axis.axis_min, pBindingB->value.axis.axis_max);
int maxB = SDL_max(pBindingB->value.axis.axis_min, pBindingB->value.axis.axis_max);
return (minA <= minB && maxA >= maxB);
}
/* Not reached */
default:
return SDL_memcmp(pBindingA, pBindingB, sizeof(*pBindingA)) == 0;
}
}
Dec 15, 2016
Dec 15, 2016
259
static void
Dec 27, 2016
Dec 27, 2016
260
ConfigureBinding(const SDL_GameControllerExtendedBind *pBinding)
Dec 15, 2016
Dec 15, 2016
261
{
Dec 27, 2016
Dec 27, 2016
262
SDL_GameControllerExtendedBind *pCurrent;
Dec 15, 2016
Dec 15, 2016
263
264
265
266
267
int iIndex;
int iCurrentElement = s_arrBindingOrder[s_iCurrentBinding];
/* Do we already have this binding? */
for (iIndex = 0; iIndex < SDL_arraysize(s_arrBindings); ++iIndex) {
Jan 4, 2017
Jan 4, 2017
268
269
pCurrent = &s_arrBindings[iIndex];
if (BBindingContainsBinding(pCurrent, pBinding)) {
Dec 15, 2016
Dec 15, 2016
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
if (iIndex == SDL_CONTROLLER_BUTTON_A && iCurrentElement != SDL_CONTROLLER_BUTTON_B) {
/* Skip to the next binding */
SetCurrentBinding(s_iCurrentBinding + 1);
return;
}
if (iIndex == SDL_CONTROLLER_BUTTON_B) {
/* Go back to the previous binding */
SetCurrentBinding(s_iCurrentBinding - 1);
return;
}
/* Already have this binding, ignore it */
return;
}
}
Jan 21, 2017
Jan 21, 2017
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#ifdef DEBUG_CONTROLLERMAP
switch ( pBinding->bindType )
{
case SDL_CONTROLLER_BINDTYPE_NONE:
break;
case SDL_CONTROLLER_BINDTYPE_BUTTON:
SDL_Log("Configuring button binding for button %d\n", pBinding->value.button);
break;
case SDL_CONTROLLER_BINDTYPE_AXIS:
SDL_Log("Configuring axis binding for axis %d %d/%d committed = %s\n", pBinding->value.axis.axis, pBinding->value.axis.axis_min, pBinding->value.axis.axis_max, pBinding->committed ? "true" : "false");
break;
case SDL_CONTROLLER_BINDTYPE_HAT:
SDL_Log("Configuring hat binding for hat %d %d\n", pBinding->value.hat.hat, pBinding->value.hat.hat_mask);
break;
}
#endif /* DEBUG_CONTROLLERMAP */
Dec 15, 2016
Dec 15, 2016
304
305
306
307
308
309
310
311
312
313
314
/* Should the new binding override the existing one? */
pCurrent = &s_arrBindings[iCurrentElement];
if (pCurrent->bindType != SDL_CONTROLLER_BINDTYPE_NONE) {
SDL_bool bNativeDPad, bCurrentDPad;
SDL_bool bNativeAxis, bCurrentAxis;
bNativeDPad = (iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_UP ||
iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_DOWN ||
iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_LEFT ||
iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
bCurrentDPad = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_HAT);
Jan 21, 2017
Jan 21, 2017
315
if (bNativeDPad && bCurrentDPad) {
Dec 15, 2016
Dec 15, 2016
316
317
318
319
320
321
/* We already have a binding of the type we want, ignore the new one */
return;
}
bNativeAxis = (iCurrentElement >= SDL_CONTROLLER_BUTTON_MAX);
bCurrentAxis = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_AXIS);
Jan 4, 2017
Jan 4, 2017
322
323
324
if (bNativeAxis == bCurrentAxis &&
(pBinding->bindType != SDL_CONTROLLER_BINDTYPE_AXIS ||
pBinding->value.axis.axis != pCurrent->value.axis.axis)) {
Dec 15, 2016
Dec 15, 2016
325
326
327
328
329
330
331
/* We already have a binding of the type we want, ignore the new one */
return;
}
}
*pCurrent = *pBinding;
Jan 21, 2017
Jan 21, 2017
332
333
334
335
336
if (pBinding->committed) {
s_unPendingAdvanceTime = SDL_GetTicks();
} else {
s_unPendingAdvanceTime = 0;
}
Dec 15, 2016
Dec 15, 2016
337
338
}
Dec 27, 2016
Dec 27, 2016
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
static SDL_bool
BMergeAxisBindings(int iIndex)
{
SDL_GameControllerExtendedBind *pBindingA = &s_arrBindings[iIndex];
SDL_GameControllerExtendedBind *pBindingB = &s_arrBindings[iIndex+1];
if (pBindingA->bindType == SDL_CONTROLLER_BINDTYPE_AXIS &&
pBindingB->bindType == SDL_CONTROLLER_BINDTYPE_AXIS &&
pBindingA->value.axis.axis == pBindingB->value.axis.axis) {
if (pBindingA->value.axis.axis_min == pBindingB->value.axis.axis_min) {
pBindingA->value.axis.axis_min = pBindingA->value.axis.axis_max;
pBindingA->value.axis.axis_max = pBindingB->value.axis.axis_max;
pBindingB->bindType = SDL_CONTROLLER_BINDTYPE_NONE;
return SDL_TRUE;
}
}
return SDL_FALSE;
}
Dec 15, 2016
Dec 15, 2016
357
static void
358
359
360
361
362
363
WatchJoystick(SDL_Joystick * joystick)
{
SDL_Window *window = NULL;
SDL_Renderer *screen = NULL;
SDL_Texture *background, *button, *axis, *marker;
const char *name = NULL;
Dec 15, 2016
Dec 15, 2016
364
SDL_bool done = SDL_FALSE;
365
366
367
368
SDL_Event event;
SDL_Rect dst;
Uint8 alpha=200, alpha_step = -1;
Uint32 alpha_ticks = 0;
Dec 15, 2016
Dec 15, 2016
369
SDL_JoystickID nJoystickID;
Jan 4, 2017
Jan 4, 2017
370
int iIndex;
371
372
373
374
375
376
377
/* Create a window to display joystick axis position */
window = SDL_CreateWindow("Game Controller Map", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
SCREEN_HEIGHT, 0);
if (window == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
Dec 15, 2016
Dec 15, 2016
378
return;
379
380
381
382
383
384
}
screen = SDL_CreateRenderer(window, -1, 0);
if (screen == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
Dec 15, 2016
Dec 15, 2016
385
return;
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
}
background = LoadTexture(screen, "controllermap.bmp", SDL_FALSE);
button = LoadTexture(screen, "button.bmp", SDL_TRUE);
axis = LoadTexture(screen, "axis.bmp", SDL_TRUE);
SDL_RaiseWindow(window);
/* scale for platforms that don't give you the window size you asked for. */
SDL_RenderSetLogicalSize(screen, SCREEN_WIDTH, SCREEN_HEIGHT);
/* Print info about the joystick we are watching */
name = SDL_JoystickName(joystick);
SDL_Log("Watching joystick %d: (%s)\n", SDL_JoystickInstanceID(joystick),
name ? name : "Unknown Joystick");
SDL_Log("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick),
SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick));
SDL_Log("\n\n\
====================================================================================\n\
Press the buttons on your controller when indicated\n\
(Your controller may look different than the picture)\n\
If you want to correct a mistake, press backspace or the back button on your device\n\
To skip a button, press SPACE or click/touch the screen\n\
To exit, press ESC\n\
====================================================================================\n");
Dec 15, 2016
Dec 15, 2016
412
413
nJoystickID = SDL_JoystickInstanceID(joystick);
Dec 27, 2016
Dec 27, 2016
415
s_nNumAxes = SDL_JoystickNumAxes(joystick);
Mar 4, 2017
Mar 4, 2017
416
s_arrAxisState = (AxisState *)SDL_calloc(s_nNumAxes, sizeof(*s_arrAxisState));
Dec 27, 2016
Dec 27, 2016
417
418
/* Loop, getting joystick events! */
Dec 15, 2016
Dec 15, 2016
419
420
421
422
while (!done && !s_bBindingComplete) {
int iElement = s_arrBindingOrder[s_iCurrentBinding];
switch (s_arrBindingDisplay[iElement].marker) {
423
424
425
426
427
428
429
430
431
432
case MARKER_AXIS:
marker = axis;
break;
case MARKER_BUTTON:
marker = button;
break;
default:
break;
}
Dec 15, 2016
Dec 15, 2016
433
434
dst.x = s_arrBindingDisplay[iElement].x;
dst.y = s_arrBindingDisplay[iElement].y;
435
436
SDL_QueryTexture(marker, NULL, NULL, &dst.w, &dst.h);
Dec 15, 2016
Dec 15, 2016
437
438
439
440
441
if (SDL_GetTicks() - alpha_ticks > 5) {
alpha_ticks = SDL_GetTicks();
alpha += alpha_step;
if (alpha == 255) {
alpha_step = -1;
Dec 15, 2016
Dec 15, 2016
443
444
445
446
447
448
449
450
451
452
453
454
if (alpha < 128) {
alpha_step = 1;
}
}
SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE);
SDL_RenderClear(screen);
SDL_RenderCopy(screen, background, NULL, NULL);
SDL_SetTextureAlphaMod(marker, alpha);
SDL_SetTextureColorMod(marker, 10, 255, 21);
SDL_RenderCopyEx(screen, marker, NULL, &dst, s_arrBindingDisplay[iElement].angle, NULL, SDL_FLIP_NONE);
SDL_RenderPresent(screen);
Dec 15, 2016
Dec 15, 2016
456
457
458
459
460
461
462
463
464
while (SDL_PollEvent(&event) > 0) {
switch (event.type) {
case SDL_JOYDEVICEREMOVED:
if (event.jaxis.which == nJoystickID) {
done = SDL_TRUE;
}
break;
case SDL_JOYAXISMOTION:
if (event.jaxis.which == nJoystickID) {
Dec 5, 2019
Dec 5, 2019
465
const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 controller needed 96 */
Dec 27, 2016
Dec 27, 2016
466
467
468
469
AxisState *pAxisState = &s_arrAxisState[event.jaxis.axis];
int nValue = event.jaxis.value;
int nCurrentDistance, nFarthestDistance;
if (!pAxisState->m_bMoving) {
Nov 28, 2019
Nov 28, 2019
470
471
Sint16 nInitialValue;
pAxisState->m_bMoving = SDL_JoystickGetAxisInitialState(joystick, event.jaxis.axis, &nInitialValue);
Dec 5, 2019
Dec 5, 2019
472
pAxisState->m_nLastValue = nInitialValue;
Nov 28, 2019
Nov 28, 2019
473
474
pAxisState->m_nStartingValue = nInitialValue;
pAxisState->m_nFarthestValue = nInitialValue;
Dec 5, 2019
Dec 5, 2019
475
476
477
478
} else if (SDL_abs(nValue - pAxisState->m_nLastValue) <= MAX_ALLOWED_JITTER) {
break;
} else {
pAxisState->m_nLastValue = nValue;
Dec 27, 2016
Dec 27, 2016
479
480
481
482
483
}
nCurrentDistance = SDL_abs(nValue - pAxisState->m_nStartingValue);
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
if (nCurrentDistance > nFarthestDistance) {
pAxisState->m_nFarthestValue = nValue;
Jan 21, 2017
Jan 21, 2017
484
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
Dec 27, 2016
Dec 27, 2016
485
}
Jan 21, 2017
Jan 21, 2017
486
487
488
489
490
491
492
#ifdef DEBUG_CONTROLLERMAP
SDL_Log("AXIS %d nValue %d nCurrentDistance %d nFarthestDistance %d\n", event.jaxis.axis, nValue, nCurrentDistance, nFarthestDistance);
#endif
if (nFarthestDistance >= 16000) {
/* If we've gone out far enough and started to come back, let's bind this axis */
SDL_bool bCommitBinding = (nCurrentDistance <= 10000) ? SDL_TRUE : SDL_FALSE;
Dec 27, 2016
Dec 27, 2016
493
SDL_GameControllerExtendedBind binding;
Dec 15, 2016
Dec 15, 2016
494
495
SDL_zero(binding);
binding.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
Dec 27, 2016
Dec 27, 2016
496
497
498
binding.value.axis.axis = event.jaxis.axis;
binding.value.axis.axis_min = StandardizeAxisValue(pAxisState->m_nStartingValue);
binding.value.axis.axis_max = StandardizeAxisValue(pAxisState->m_nFarthestValue);
Jan 21, 2017
Jan 21, 2017
499
binding.committed = bCommitBinding;
Dec 15, 2016
Dec 15, 2016
500
ConfigureBinding(&binding);
Dec 15, 2016
Dec 15, 2016
502
503
504
505
506
}
break;
case SDL_JOYHATMOTION:
if (event.jhat.which == nJoystickID) {
if (event.jhat.value != SDL_HAT_CENTERED) {
Dec 27, 2016
Dec 27, 2016
507
SDL_GameControllerExtendedBind binding;
Jan 21, 2017
Jan 21, 2017
508
509
510
511
#ifdef DEBUG_CONTROLLERMAP
SDL_Log("HAT %d %d\n", event.jhat.hat, event.jhat.value);
#endif
Dec 15, 2016
Dec 15, 2016
512
513
514
515
SDL_zero(binding);
binding.bindType = SDL_CONTROLLER_BINDTYPE_HAT;
binding.value.hat.hat = event.jhat.hat;
binding.value.hat.hat_mask = event.jhat.value;
Jan 21, 2017
Jan 21, 2017
516
binding.committed = SDL_TRUE;
Dec 15, 2016
Dec 15, 2016
517
ConfigureBinding(&binding);
Dec 15, 2016
Dec 15, 2016
519
520
521
522
523
524
}
break;
case SDL_JOYBALLMOTION:
break;
case SDL_JOYBUTTONDOWN:
if (event.jbutton.which == nJoystickID) {
Dec 27, 2016
Dec 27, 2016
525
SDL_GameControllerExtendedBind binding;
Jan 21, 2017
Jan 21, 2017
526
527
528
529
#ifdef DEBUG_CONTROLLERMAP
SDL_Log("BUTTON %d\n", event.jbutton.button);
#endif
Dec 15, 2016
Dec 15, 2016
530
531
532
SDL_zero(binding);
binding.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
binding.value.button = event.jbutton.button;
Jan 21, 2017
Jan 21, 2017
533
binding.committed = SDL_TRUE;
Dec 15, 2016
Dec 15, 2016
534
535
536
537
538
539
540
541
542
543
544
ConfigureBinding(&binding);
}
break;
case SDL_FINGERDOWN:
case SDL_MOUSEBUTTONDOWN:
/* Skip this step */
SetCurrentBinding(s_iCurrentBinding + 1);
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_BACKSPACE || event.key.keysym.sym == SDLK_AC_BACK) {
SetCurrentBinding(s_iCurrentBinding - 1);
Dec 15, 2016
Dec 15, 2016
546
547
548
}
if (event.key.keysym.sym == SDLK_SPACE) {
SetCurrentBinding(s_iCurrentBinding + 1);
Dec 15, 2016
Dec 15, 2016
550
551
552
}
if ((event.key.keysym.sym != SDLK_ESCAPE)) {
Dec 15, 2016
Dec 15, 2016
555
556
557
558
559
560
/* Fall through to signal quit */
case SDL_QUIT:
done = SDL_TRUE;
break;
default:
break;
Dec 15, 2016
Dec 15, 2016
564
565
566
567
568
569
570
571
SDL_Delay(15);
/* Wait 100 ms for joystick events to stop coming in,
in case a controller sends multiple events for a single control (e.g. axis and button for trigger)
*/
if (s_unPendingAdvanceTime && SDL_GetTicks() - s_unPendingAdvanceTime >= 100) {
SetCurrentBinding(s_iCurrentBinding + 1);
}
Dec 15, 2016
Dec 15, 2016
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
if (s_bBindingComplete) {
char mapping[1024];
char trimmed_name[128];
char *spot;
int iIndex;
char pszElement[12];
SDL_strlcpy(trimmed_name, name, SDL_arraysize(trimmed_name));
while (SDL_isspace(trimmed_name[0])) {
SDL_memmove(&trimmed_name[0], &trimmed_name[1], SDL_strlen(trimmed_name));
}
while (trimmed_name[0] && SDL_isspace(trimmed_name[SDL_strlen(trimmed_name) - 1])) {
trimmed_name[SDL_strlen(trimmed_name) - 1] = '\0';
}
while ((spot = SDL_strchr(trimmed_name, ',')) != NULL) {
SDL_memmove(spot, spot + 1, SDL_strlen(spot));
}
/* Initialize mapping with GUID and name */
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), mapping, SDL_arraysize(mapping));
SDL_strlcat(mapping, ",", SDL_arraysize(mapping));
SDL_strlcat(mapping, trimmed_name, SDL_arraysize(mapping));
SDL_strlcat(mapping, ",", SDL_arraysize(mapping));
SDL_strlcat(mapping, "platform:", SDL_arraysize(mapping));
SDL_strlcat(mapping, SDL_GetPlatform(), SDL_arraysize(mapping));
SDL_strlcat(mapping, ",", SDL_arraysize(mapping));
for (iIndex = 0; iIndex < SDL_arraysize(s_arrBindings); ++iIndex) {
Dec 27, 2016
Dec 27, 2016
602
SDL_GameControllerExtendedBind *pBinding = &s_arrBindings[iIndex];
Dec 15, 2016
Dec 15, 2016
603
604
605
606
607
608
609
610
if (pBinding->bindType == SDL_CONTROLLER_BINDTYPE_NONE) {
continue;
}
if (iIndex < SDL_CONTROLLER_BUTTON_MAX) {
SDL_GameControllerButton eButton = (SDL_GameControllerButton)iIndex;
SDL_strlcat(mapping, SDL_GameControllerGetStringForButton(eButton), SDL_arraysize(mapping));
} else {
Dec 27, 2016
Dec 27, 2016
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
const char *pszAxisName;
switch (iIndex - SDL_CONTROLLER_BUTTON_MAX) {
case SDL_CONTROLLER_BINDING_AXIS_LEFTX_NEGATIVE:
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTX);
break;
case SDL_CONTROLLER_BINDING_AXIS_LEFTX_POSITIVE:
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTX);
break;
case SDL_CONTROLLER_BINDING_AXIS_LEFTY_NEGATIVE:
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTY);
break;
case SDL_CONTROLLER_BINDING_AXIS_LEFTY_POSITIVE:
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_LEFTY);
break;
case SDL_CONTROLLER_BINDING_AXIS_RIGHTX_NEGATIVE:
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTX);
break;
case SDL_CONTROLLER_BINDING_AXIS_RIGHTX_POSITIVE:
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTX);
break;
case SDL_CONTROLLER_BINDING_AXIS_RIGHTY_NEGATIVE:
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTY);
break;
case SDL_CONTROLLER_BINDING_AXIS_RIGHTY_POSITIVE:
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_RIGHTY);
break;
case SDL_CONTROLLER_BINDING_AXIS_TRIGGERLEFT:
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_TRIGGERLEFT);
break;
case SDL_CONTROLLER_BINDING_AXIS_TRIGGERRIGHT:
pszAxisName = SDL_GameControllerGetStringForAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
break;
}
SDL_strlcat(mapping, pszAxisName, SDL_arraysize(mapping));
Dec 15, 2016
Dec 15, 2016
661
662
663
664
665
666
667
668
669
}
SDL_strlcat(mapping, ":", SDL_arraysize(mapping));
pszElement[0] = '\0';
switch (pBinding->bindType) {
case SDL_CONTROLLER_BINDTYPE_BUTTON:
SDL_snprintf(pszElement, sizeof(pszElement), "b%d", pBinding->value.button);
break;
case SDL_CONTROLLER_BINDTYPE_AXIS:
Dec 27, 2016
Dec 27, 2016
670
671
672
673
674
675
676
677
678
679
680
681
682
if (pBinding->value.axis.axis_min == 0 && pBinding->value.axis.axis_max == SDL_JOYSTICK_AXIS_MIN) {
/* The negative half axis */
SDL_snprintf(pszElement, sizeof(pszElement), "-a%d", pBinding->value.axis.axis);
} else if (pBinding->value.axis.axis_min == 0 && pBinding->value.axis.axis_max == SDL_JOYSTICK_AXIS_MAX) {
/* The positive half axis */
SDL_snprintf(pszElement, sizeof(pszElement), "+a%d", pBinding->value.axis.axis);
} else {
SDL_snprintf(pszElement, sizeof(pszElement), "a%d", pBinding->value.axis.axis);
if (pBinding->value.axis.axis_min > pBinding->value.axis.axis_max) {
/* Invert the axis */
SDL_strlcat(pszElement, "~", SDL_arraysize(pszElement));
}
}
Dec 15, 2016
Dec 15, 2016
683
684
685
686
687
688
689
690
691
692
693
694
break;
case SDL_CONTROLLER_BINDTYPE_HAT:
SDL_snprintf(pszElement, sizeof(pszElement), "h%d.%d", pBinding->value.hat.hat, pBinding->value.hat.hat_mask);
break;
default:
SDL_assert(!"Unknown bind type");
break;
}
SDL_strlcat(mapping, pszElement, SDL_arraysize(mapping));
SDL_strlcat(mapping, ",", SDL_arraysize(mapping));
}
695
696
697
698
SDL_Log("Mapping:\n\n%s\n\n", mapping);
/* Print to stdout as well so the user can cat the output somewhere */
printf("%s\n", mapping);
}
Dec 27, 2016
Dec 27, 2016
699
700
701
SDL_free(s_arrAxisState);
s_arrAxisState = NULL;
702
703
704
705
706
707
708
709
710
711
712
713
714
SDL_DestroyRenderer(screen);
SDL_DestroyWindow(window);
}
int
main(int argc, char *argv[])
{
const char *name;
int i;
SDL_Joystick *joystick;
/* Enable standard application logging */
Nov 25, 2015
Nov 25, 2015
715
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
/* Initialize SDL (Note: video is required to start event loop) */
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
/* Print information about the joysticks */
SDL_Log("There are %d joysticks attached\n", SDL_NumJoysticks());
for (i = 0; i < SDL_NumJoysticks(); ++i) {
name = SDL_JoystickNameForIndex(i);
SDL_Log("Joystick %d: %s\n", i, name ? name : "Unknown Joystick");
joystick = SDL_JoystickOpen(i);
if (joystick == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_JoystickOpen(%d) failed: %s\n", i,
SDL_GetError());
} else {
char guid[64];
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick),
guid, sizeof (guid));
SDL_Log(" axes: %d\n", SDL_JoystickNumAxes(joystick));
SDL_Log(" balls: %d\n", SDL_JoystickNumBalls(joystick));
SDL_Log(" hats: %d\n", SDL_JoystickNumHats(joystick));
SDL_Log(" buttons: %d\n", SDL_JoystickNumButtons(joystick));
SDL_Log("instance id: %d\n", SDL_JoystickInstanceID(joystick));
SDL_Log(" guid: %s\n", guid);
Nov 11, 2016
Nov 11, 2016
742
SDL_Log(" VID/PID: 0x%.4x/0x%.4x\n", SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick));
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
SDL_JoystickClose(joystick);
}
}
#ifdef __ANDROID__
if (SDL_NumJoysticks() > 0) {
#else
if (argv[1]) {
#endif
int device;
#ifdef __ANDROID__
device = 0;
#else
device = atoi(argv[1]);
#endif
joystick = SDL_JoystickOpen(device);
Dec 15, 2016
Dec 15, 2016
759
760
761
762
763
if (joystick == NULL) {
SDL_Log("Couldn't open joystick %d: %s\n", device, SDL_GetError());
} else {
WatchJoystick(joystick);
SDL_JoystickClose(joystick);
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
}
}
else {
SDL_Log("\n\nUsage: ./controllermap number\nFor example: ./controllermap 0\nOr: ./controllermap 0 >> gamecontrollerdb.txt");
}
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
return 0;
}
#else
int
main(int argc, char *argv[])
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n");
Sep 10, 2019
Sep 10, 2019
780
return 1;
Nov 11, 2016
Nov 11, 2016
784
785
/* vi: set ts=4 sw=4 expandtab: */