SDL  2.0
controllermap.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
+ Include dependency graph for controllermap.c:

Go to the source code of this file.

Data Structures

struct  SDL_GameControllerExtendedBind
struct  AxisState

Macros

#define SCREEN_WIDTH   512
#define SCREEN_HEIGHT   320
#define MARKER_BUTTON   1
#define MARKER_AXIS   2
#define BINDING_COUNT   (SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_BINDING_AXIS_MAX)

Enumerations

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
}

Functions

SDL_TextureLoadTexture (SDL_Renderer *renderer, const char *file, SDL_bool transparent)
static int StandardizeAxisValue (int nValue)
static void SetCurrentBinding (int iBinding)
static SDL_bool BBindingContainsBinding (const SDL_GameControllerExtendedBind *pBindingA, const SDL_GameControllerExtendedBind *pBindingB)
static void ConfigureBinding (const SDL_GameControllerExtendedBind *pBinding)
static SDL_bool BMergeAxisBindings (int iIndex)
static void WatchJoystick (SDL_Joystick *joystick)
int main (int argc, char *argv[])

Variables

struct {
   int   x
   int   y
   double   angle
   int   marker
s_arrBindingDisplay [BINDING_COUNT]
static int s_arrBindingOrder [BINDING_COUNT]
static
SDL_GameControllerExtendedBind 
s_arrBindings [BINDING_COUNT]
static int s_nNumAxes
static AxisStates_arrAxisState
static int s_iCurrentBinding
static Uint32 s_unPendingAdvanceTime
static SDL_bool s_bBindingComplete

Macro Definition Documentation

Definition at line 50 of file controllermap.c.

Referenced by SetCurrentBinding().

#define MARKER_AXIS   2

Definition at line 33 of file controllermap.c.

Referenced by WatchJoystick().

#define MARKER_BUTTON   1

Definition at line 32 of file controllermap.c.

Referenced by WatchJoystick().

#define SCREEN_HEIGHT   320

Definition at line 29 of file controllermap.c.

Referenced by WatchJoystick().

#define SCREEN_WIDTH   512

Definition at line 28 of file controllermap.c.

Referenced by WatchJoystick().

Enumeration Type Documentation

anonymous enum
Enumerator:
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 

Definition at line 35 of file controllermap.c.

Function Documentation

static SDL_bool BBindingContainsBinding ( const SDL_GameControllerExtendedBind pBindingA,
const SDL_GameControllerExtendedBind pBindingB 
)
static

Definition at line 227 of file controllermap.c.

References SDL_GameControllerExtendedBind::axis, SDL_GameControllerExtendedBind::bindType, SDL_GameControllerExtendedBind::committed, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_FALSE, SDL_max, SDL_memcmp, SDL_min, and SDL_GameControllerExtendedBind::value.

Referenced by ConfigureBinding().

{
if (pBindingA->bindType != pBindingB->bindType)
{
return SDL_FALSE;
}
switch (pBindingA->bindType)
{
if (pBindingA->value.axis.axis != pBindingB->value.axis.axis) {
return SDL_FALSE;
}
if (!pBindingA->committed) {
return SDL_FALSE;
}
{
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;
}
}
static SDL_bool BMergeAxisBindings ( int  iIndex)
static

Definition at line 336 of file controllermap.c.

References SDL_GameControllerExtendedBind::axis, SDL_GameControllerExtendedBind::bindType, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_NONE, SDL_FALSE, SDL_TRUE, and SDL_GameControllerExtendedBind::value.

Referenced by WatchJoystick().

{
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;
return SDL_TRUE;
}
}
return SDL_FALSE;
}
static void ConfigureBinding ( const SDL_GameControllerExtendedBind pBinding)
static

Definition at line 256 of file controllermap.c.

References SDL_GameControllerExtendedBind::axis, BBindingContainsBinding(), SDL_GameControllerExtendedBind::bindType, SDL_GameControllerExtendedBind::button, SDL_GameControllerExtendedBind::committed, SDL_GameControllerExtendedBind::hat, s_arrBindingOrder, s_iCurrentBinding, s_unPendingAdvanceTime, SDL_arraysize, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_HAT, SDL_CONTROLLER_BINDTYPE_NONE, SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_BUTTON_DPAD_DOWN, SDL_CONTROLLER_BUTTON_DPAD_LEFT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_UP, SDL_CONTROLLER_BUTTON_MAX, SDL_GetTicks(), SDL_Log, SetCurrentBinding(), and SDL_GameControllerExtendedBind::value.

Referenced by WatchJoystick().

{
int iIndex;
int iCurrentElement = s_arrBindingOrder[s_iCurrentBinding];
/* Do we already have this binding? */
for (iIndex = 0; iIndex < SDL_arraysize(s_arrBindings); ++iIndex) {
pCurrent = &s_arrBindings[iIndex];
if (BBindingContainsBinding(pCurrent, pBinding)) {
if (iIndex == SDL_CONTROLLER_BUTTON_A && iCurrentElement != SDL_CONTROLLER_BUTTON_B) {
/* Skip to the next binding */
return;
}
if (iIndex == SDL_CONTROLLER_BUTTON_B) {
/* Go back to the previous binding */
return;
}
/* Already have this binding, ignore it */
return;
}
}
#ifdef DEBUG_CONTROLLERMAP
switch ( pBinding->bindType )
{
break;
SDL_Log("Configuring button binding for button %d\n", pBinding->value.button);
break;
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;
SDL_Log("Configuring hat binding for hat %d %d\n", pBinding->value.hat.hat, pBinding->value.hat.hat_mask);
break;
}
#endif /* DEBUG_CONTROLLERMAP */
/* Should the new binding override the existing one? */
pCurrent = &s_arrBindings[iCurrentElement];
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);
if (bNativeDPad && bCurrentDPad) {
/* 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);
if (bNativeAxis == bCurrentAxis &&
pBinding->value.axis.axis != pCurrent->value.axis.axis)) {
/* We already have a binding of the type we want, ignore the new one */
return;
}
}
*pCurrent = *pBinding;
if (pBinding->committed) {
} else {
}
}
SDL_Texture* LoadTexture ( SDL_Renderer renderer,
const char *  file,
SDL_bool  transparent 
)

Definition at line 155 of file controllermap.c.

References SDL_Surface::format, NULL, SDL_PixelFormat::palette, SDL_Surface::pixels, SDL_CreateTextureFromSurface, SDL_FreeSurface, SDL_GetError, SDL_LoadBMP, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_SetColorKey, and SDL_TRUE.

Referenced by main(), WatchGameController(), and WatchJoystick().

{
SDL_Surface *temp;
/* 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());
return NULL;
}
/* We're ready to roll. :) */
return texture;
}
int main ( int  argc,
char *  argv[] 
)

Definition at line 704 of file controllermap.c.

References device, i, main, NULL, SDL_GetError, SDL_Init, SDL_INIT_JOYSTICK, SDL_INIT_VIDEO, SDL_JoystickClose, SDL_JoystickGetGUID, SDL_JoystickGetGUIDString, SDL_JoystickGetProduct, SDL_JoystickGetVendor, SDL_JoystickInstanceID, SDL_JoystickNameForIndex, SDL_JoystickNumAxes, SDL_JoystickNumBalls, SDL_JoystickNumButtons, SDL_JoystickNumHats, SDL_JoystickOpen, SDL_Log, SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, SDL_LogError, SDL_LogSetPriority, SDL_NumJoysticks, SDL_QuitSubSystem, and WatchJoystick().

{
const char *name;
int i;
SDL_Joystick *joystick;
/* Enable standard application logging */
/* Initialize SDL (Note: video is required to start event loop) */
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) {
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,
} else {
char guid[64];
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);
SDL_Log(" VID/PID: 0x%.4x/0x%.4x\n", SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick));
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);
if (joystick == NULL) {
SDL_Log("Couldn't open joystick %d: %s\n", device, SDL_GetError());
} else {
WatchJoystick(joystick);
SDL_JoystickClose(joystick);
}
}
else {
SDL_Log("\n\nUsage: ./controllermap number\nFor example: ./controllermap 0\nOr: ./controllermap 0 >> gamecontrollerdb.txt");
}
return 0;
}
static void SetCurrentBinding ( int  iBinding)
static
static int StandardizeAxisValue ( int  nValue)
static

Definition at line 188 of file controllermap.c.

References SDL_JOYSTICK_AXIS_MAX, and SDL_JOYSTICK_AXIS_MIN.

Referenced by WatchJoystick().

{
if (nValue > SDL_JOYSTICK_AXIS_MAX/2) {
} else if (nValue < SDL_JOYSTICK_AXIS_MIN/2) {
} else {
return 0;
}
}
static void WatchJoystick ( SDL_Joystick *  joystick)
static

Definition at line 354 of file controllermap.c.

References axis, SDL_GameControllerExtendedBind::axis, SDL_JoyAxisEvent::axis, background, SDL_GameControllerExtendedBind::bindType, BMergeAxisBindings(), button, SDL_GameControllerExtendedBind::button, SDL_JoyButtonEvent::button, SDL_GameControllerExtendedBind::committed, ConfigureBinding(), done, SDL_Rect::h, SDL_GameControllerExtendedBind::hat, SDL_JoyHatEvent::hat, SDL_Event::jaxis, SDL_Event::jbutton, SDL_Event::jhat, SDL_Event::key, SDL_KeyboardEvent::keysym, LoadTexture(), AxisState::m_bMoving, AxisState::m_nFarthestValue, AxisState::m_nStartingValue, MARKER_AXIS, MARKER_BUTTON, NULL, s_arrBindingDisplay, s_arrBindingOrder, s_bBindingComplete, s_iCurrentBinding, s_nNumAxes, s_unPendingAdvanceTime, screen, SCREEN_HEIGHT, SCREEN_WIDTH, SDL_abs, SDL_ALPHA_OPAQUE, SDL_arraysize, SDL_assert, SDL_calloc, SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTY, SDL_CONTROLLER_AXIS_RIGHTX, SDL_CONTROLLER_AXIS_RIGHTY, SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 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_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_HAT, SDL_CONTROLLER_BINDTYPE_NONE, SDL_CONTROLLER_BUTTON_MAX, SDL_CreateRenderer, SDL_CreateWindow, SDL_Delay, SDL_DestroyRenderer, SDL_DestroyWindow, SDL_FALSE, SDL_FINGERDOWN, SDL_FLIP_NONE, SDL_free, SDL_GameControllerGetStringForAxis, SDL_GameControllerGetStringForButton, SDL_GetError, SDL_GetPlatform, SDL_GetTicks(), SDL_HAT_CENTERED, SDL_isspace, SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYBUTTONDOWN, SDL_JOYDEVICEREMOVED, SDL_JOYHATMOTION, SDL_JOYSTICK_AXIS_MAX, SDL_JOYSTICK_AXIS_MIN, SDL_JoystickGetAxisInitialState, SDL_JoystickGetGUID, SDL_JoystickGetGUIDString, SDL_JoystickInstanceID, SDL_JoystickName, SDL_JoystickNumAxes, SDL_JoystickNumBalls, SDL_JoystickNumButtons, SDL_JoystickNumHats, SDL_KEYDOWN, SDL_Log, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_memmove, SDL_MOUSEBUTTONDOWN, SDL_PollEvent, SDL_QueryTexture, SDL_QUIT, SDL_RaiseWindow, SDL_RenderClear, SDL_RenderCopy, SDL_RenderCopyEx, SDL_RenderPresent, SDL_RenderSetLogicalSize, SDL_SetRenderDrawColor, SDL_SetTextureAlphaMod, SDL_SetTextureColorMod, SDL_snprintf, SDL_strchr, SDL_strlcat, SDL_strlcpy, SDL_strlen, SDL_TRUE, SDL_WINDOWPOS_CENTERED, SDL_zero, SDLK_AC_BACK, SDLK_BACKSPACE, SDLK_ESCAPE, SDLK_SPACE, SetCurrentBinding(), StandardizeAxisValue(), SDL_Keysym::sym, SDL_Event::type, SDL_GameControllerExtendedBind::value, SDL_JoyHatEvent::value, SDL_Rect::w, SDL_JoyAxisEvent::which, SDL_JoyHatEvent::which, SDL_JoyButtonEvent::which, SDL_Rect::x, and SDL_Rect::y.

Referenced by main().

{
const char *name = NULL;
Uint8 alpha=200, alpha_step = -1;
Uint32 alpha_ticks = 0;
SDL_JoystickID nJoystickID;
int iIndex;
/* Create a window to display joystick axis position */
window = SDL_CreateWindow("Game Controller Map", SDL_WINDOWPOS_CENTERED,
if (window == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
return;
}
screen = SDL_CreateRenderer(window, -1, 0);
if (screen == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
return;
}
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. */
/* 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_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");
nJoystickID = SDL_JoystickInstanceID(joystick);
for (iIndex = 0; iIndex < s_nNumAxes; ++iIndex) {
AxisState *pAxisState = &s_arrAxisState[iIndex];
Sint16 nInitialValue;
pAxisState->m_bMoving = SDL_JoystickGetAxisInitialState(joystick, iIndex, &nInitialValue);
pAxisState->m_nStartingValue = nInitialValue;
pAxisState->m_nFarthestValue = nInitialValue;
}
/* Loop, getting joystick events! */
while (!done && !s_bBindingComplete) {
switch (s_arrBindingDisplay[iElement].marker) {
marker = axis;
break;
marker = button;
break;
default:
break;
}
dst.x = s_arrBindingDisplay[iElement].x;
dst.y = s_arrBindingDisplay[iElement].y;
SDL_QueryTexture(marker, NULL, NULL, &dst.w, &dst.h);
if (SDL_GetTicks() - alpha_ticks > 5) {
alpha_ticks = SDL_GetTicks();
alpha += alpha_step;
if (alpha == 255) {
alpha_step = -1;
}
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);
while (SDL_PollEvent(&event) > 0) {
switch (event.type) {
if (event.jaxis.which == nJoystickID) {
done = SDL_TRUE;
}
break;
if (event.jaxis.which == nJoystickID) {
AxisState *pAxisState = &s_arrAxisState[event.jaxis.axis];
int nValue = event.jaxis.value;
int nCurrentDistance, nFarthestDistance;
if (!pAxisState->m_bMoving) {
pAxisState->m_bMoving = SDL_TRUE;
pAxisState->m_nStartingValue = nValue;
pAxisState->m_nFarthestValue = nValue;
}
nCurrentDistance = SDL_abs(nValue - pAxisState->m_nStartingValue);
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
if (nCurrentDistance > nFarthestDistance) {
pAxisState->m_nFarthestValue = nValue;
nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);
}
#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;
SDL_zero(binding);
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);
binding.committed = bCommitBinding;
ConfigureBinding(&binding);
}
}
break;
if (event.jhat.which == nJoystickID) {
if (event.jhat.value != SDL_HAT_CENTERED) {
#ifdef DEBUG_CONTROLLERMAP
SDL_Log("HAT %d %d\n", event.jhat.hat, event.jhat.value);
#endif
SDL_zero(binding);
binding.value.hat.hat = event.jhat.hat;
binding.value.hat.hat_mask = event.jhat.value;
binding.committed = SDL_TRUE;
ConfigureBinding(&binding);
}
}
break;
break;
if (event.jbutton.which == nJoystickID) {
#ifdef DEBUG_CONTROLLERMAP
SDL_Log("BUTTON %d\n", event.jbutton.button);
#endif
SDL_zero(binding);
binding.value.button = event.jbutton.button;
binding.committed = SDL_TRUE;
ConfigureBinding(&binding);
}
break;
/* Skip this step */
break;
if (event.key.keysym.sym == SDLK_BACKSPACE || event.key.keysym.sym == SDLK_AC_BACK) {
break;
}
if (event.key.keysym.sym == SDLK_SPACE) {
break;
}
if ((event.key.keysym.sym != SDLK_ESCAPE)) {
break;
}
/* Fall through to signal quit */
case SDL_QUIT:
done = SDL_TRUE;
break;
default:
break;
}
}
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)
*/
}
}
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_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) {
continue;
}
if (iIndex < SDL_CONTROLLER_BUTTON_MAX) {
} else {
const char *pszAxisName;
switch (iIndex - SDL_CONTROLLER_BUTTON_MAX) {
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
break;
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
break;
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
break;
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
break;
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
break;
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
break;
if (!BMergeAxisBindings(iIndex)) {
SDL_strlcat(mapping, "-", SDL_arraysize(mapping));
}
break;
SDL_strlcat(mapping, "+", SDL_arraysize(mapping));
break;
break;
break;
}
SDL_strlcat(mapping, pszAxisName, SDL_arraysize(mapping));
}
SDL_strlcat(mapping, ":", SDL_arraysize(mapping));
pszElement[0] = '\0';
switch (pBinding->bindType) {
SDL_snprintf(pszElement, sizeof(pszElement), "b%d", pBinding->value.button);
break;
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));
}
}
break;
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));
}
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);
}
}

Variable Documentation

double angle

Definition at line 55 of file controllermap.c.

int marker

Definition at line 56 of file controllermap.c.

AxisState* s_arrAxisState
static

Definition at line 148 of file controllermap.c.

struct { ... } s_arrBindingDisplay[BINDING_COUNT]

Referenced by WatchJoystick().

Definition at line 138 of file controllermap.c.

SDL_bool s_bBindingComplete
static

Definition at line 152 of file controllermap.c.

Referenced by SetCurrentBinding(), and WatchJoystick().

int s_iCurrentBinding
static

Definition at line 150 of file controllermap.c.

Referenced by ConfigureBinding(), SetCurrentBinding(), and WatchJoystick().

int s_nNumAxes
static

Definition at line 147 of file controllermap.c.

Referenced by SetCurrentBinding(), and WatchJoystick().

Uint32 s_unPendingAdvanceTime
static

Definition at line 151 of file controllermap.c.

Referenced by ConfigureBinding(), SetCurrentBinding(), and WatchJoystick().

int x

Definition at line 54 of file controllermap.c.

int y

Definition at line 54 of file controllermap.c.