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