test/testjoystick.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Thu, 12 Feb 2015 21:40:53 +0100
changeset 9340 af5be9462bb4
parent 9338 86bc1c9a090f
child 9433 bd062398b648
permissions -rw-r--r--
Fixed test programs for joystick not exiting on events after first disconnect.

Exit was broken since the main loop extraction needed for Emscripten support
because the former local but now global variables were not reset correctly.
slouken@5535
     1
/*
slouken@8149
     2
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@0
    12
slouken@0
    13
/* Simple program to test the SDL joystick routines */
slouken@0
    14
slouken@0
    15
#include <stdio.h>
slouken@0
    16
#include <stdlib.h>
slouken@0
    17
#include <string.h>
slouken@0
    18
slouken@0
    19
#include "SDL.h"
slouken@0
    20
icculus@9278
    21
#ifdef __EMSCRIPTEN__
icculus@9278
    22
#include <emscripten/emscripten.h>
icculus@9278
    23
#endif
icculus@9278
    24
aschiffler@6771
    25
#ifndef SDL_JOYSTICK_DISABLED
aschiffler@6771
    26
slouken@6690
    27
#ifdef __IPHONEOS__
slouken@7191
    28
#define SCREEN_WIDTH    320
slouken@7191
    29
#define SCREEN_HEIGHT   480
slouken@6690
    30
#else
slouken@7191
    31
#define SCREEN_WIDTH    640
slouken@7191
    32
#define SCREEN_HEIGHT   480
slouken@6690
    33
#endif
slouken@0
    34
icculus@9278
    35
SDL_Renderer *screen = NULL;
icculus@9278
    36
SDL_bool retval = SDL_FALSE;
icculus@9278
    37
SDL_bool done = SDL_FALSE;
aschiffler@6771
    38
icculus@6398
    39
static void
icculus@6398
    40
DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
icculus@6398
    41
{
icculus@6398
    42
    const SDL_Rect area = { x, y, w, h };
icculus@6398
    43
    SDL_RenderFillRect(r, &area);
icculus@6398
    44
}
icculus@6398
    45
icculus@9278
    46
void
icculus@9278
    47
loop(void *arg)
slouken@0
    48
{
slouken@6690
    49
    SDL_Event event;
icculus@6398
    50
    int i;
icculus@9278
    51
    SDL_Joystick *joystick = (SDL_Joystick *)arg;
slouken@0
    52
slouken@6690
    53
        /* blank screen, set up for drawing this frame. */
icculus@9278
    54
    SDL_SetRenderDrawColor(screen, 0x0, 0x0, 0x0, SDL_ALPHA_OPAQUE);
slouken@6690
    55
        SDL_RenderClear(screen);
slouken@6690
    56
slouken@1895
    57
        while (SDL_PollEvent(&event)) {
slouken@1895
    58
            switch (event.type) {
slouken@1895
    59
            case SDL_JOYAXISMOTION:
aschiffler@7639
    60
                SDL_Log("Joystick %d axis %d value: %d\n",
slouken@1895
    61
                       event.jaxis.which,
slouken@1895
    62
                       event.jaxis.axis, event.jaxis.value);
slouken@1895
    63
                break;
slouken@1895
    64
            case SDL_JOYHATMOTION:
aschiffler@7639
    65
                SDL_Log("Joystick %d hat %d value:",
slouken@1895
    66
                       event.jhat.which, event.jhat.hat);
slouken@1895
    67
                if (event.jhat.value == SDL_HAT_CENTERED)
aschiffler@7639
    68
                    SDL_Log(" centered");
slouken@1895
    69
                if (event.jhat.value & SDL_HAT_UP)
aschiffler@7639
    70
                    SDL_Log(" up");
slouken@1895
    71
                if (event.jhat.value & SDL_HAT_RIGHT)
aschiffler@7639
    72
                    SDL_Log(" right");
slouken@1895
    73
                if (event.jhat.value & SDL_HAT_DOWN)
aschiffler@7639
    74
                    SDL_Log(" down");
slouken@1895
    75
                if (event.jhat.value & SDL_HAT_LEFT)
aschiffler@7639
    76
                    SDL_Log(" left");
aschiffler@7639
    77
                SDL_Log("\n");
slouken@1895
    78
                break;
slouken@1895
    79
            case SDL_JOYBALLMOTION:
aschiffler@7639
    80
                SDL_Log("Joystick %d ball %d delta: (%d,%d)\n",
slouken@1895
    81
                       event.jball.which,
slouken@1895
    82
                       event.jball.ball, event.jball.xrel, event.jball.yrel);
slouken@1895
    83
                break;
slouken@1895
    84
            case SDL_JOYBUTTONDOWN:
aschiffler@7639
    85
                SDL_Log("Joystick %d button %d down\n",
slouken@1895
    86
                       event.jbutton.which, event.jbutton.button);
slouken@1895
    87
                break;
slouken@1895
    88
            case SDL_JOYBUTTONUP:
aschiffler@7639
    89
                SDL_Log("Joystick %d button %d up\n",
slouken@1895
    90
                       event.jbutton.which, event.jbutton.button);
slouken@1895
    91
                break;
slouken@1895
    92
            case SDL_KEYDOWN:
slouken@7017
    93
                if ((event.key.keysym.sym != SDLK_ESCAPE) &&
slouken@7017
    94
                    (event.key.keysym.sym != SDLK_AC_BACK)) {
slouken@1895
    95
                    break;
slouken@1895
    96
                }
slouken@1895
    97
                /* Fall through to signal quit */
slouken@7017
    98
            case SDL_FINGERDOWN:
slouken@7017
    99
            case SDL_MOUSEBUTTONDOWN:
slouken@1895
   100
            case SDL_QUIT:
icculus@6730
   101
                done = SDL_TRUE;
slouken@1895
   102
                break;
slouken@1895
   103
            default:
slouken@1895
   104
                break;
slouken@1895
   105
            }
slouken@1895
   106
        }
slouken@6690
   107
        /* Update visual joystick state */
slouken@6690
   108
        SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE);
slouken@6690
   109
        for (i = 0; i < SDL_JoystickNumButtons(joystick); ++i) {
slouken@6690
   110
            if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
slouken@7017
   111
                DrawRect(screen, (i%20) * 34, SCREEN_HEIGHT - 68 + (i/20) * 34, 32, 32);
slouken@6690
   112
            }
slouken@6690
   113
        }
slouken@6586
   114
slouken@6690
   115
        SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE);
slouken@7017
   116
        for (i = 0; i < SDL_JoystickNumAxes(joystick); ++i) {
slouken@6690
   117
            /* Draw the X/Y axis */
slouken@6690
   118
            int x, y;
slouken@7017
   119
            x = (((int) SDL_JoystickGetAxis(joystick, i)) + 32768);
slouken@6690
   120
            x *= SCREEN_WIDTH;
slouken@6690
   121
            x /= 65535;
slouken@6690
   122
            if (x < 0) {
slouken@6690
   123
                x = 0;
slouken@6690
   124
            } else if (x > (SCREEN_WIDTH - 16)) {
slouken@6690
   125
                x = SCREEN_WIDTH - 16;
slouken@6690
   126
            }
slouken@7017
   127
            ++i;
slouken@7017
   128
            if (i < SDL_JoystickNumAxes(joystick)) {
slouken@7017
   129
                y = (((int) SDL_JoystickGetAxis(joystick, i)) + 32768);
slouken@7017
   130
            } else {
slouken@7017
   131
                y = 32768;
slouken@7017
   132
            }
slouken@6690
   133
            y *= SCREEN_HEIGHT;
slouken@6690
   134
            y /= 65535;
slouken@6690
   135
            if (y < 0) {
slouken@6690
   136
                y = 0;
slouken@6690
   137
            } else if (y > (SCREEN_HEIGHT - 16)) {
slouken@6690
   138
                y = SCREEN_HEIGHT - 16;
slouken@1895
   139
            }
slouken@2765
   140
slouken@6690
   141
            DrawRect(screen, x, y, 16, 16);
slouken@6690
   142
        }
icculus@6397
   143
slouken@6690
   144
        SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE);
slouken@6690
   145
        for (i = 0; i < SDL_JoystickNumHats(joystick); ++i) {
slouken@6690
   146
            /* Derive the new position */
slouken@6690
   147
            int x = SCREEN_WIDTH/2;
slouken@6690
   148
            int y = SCREEN_HEIGHT/2;
slouken@6690
   149
            const Uint8 hat_pos = SDL_JoystickGetHat(joystick, i);
slouken@6690
   150
slouken@6690
   151
            if (hat_pos & SDL_HAT_UP) {
slouken@6690
   152
                y = 0;
slouken@6690
   153
            } else if (hat_pos & SDL_HAT_DOWN) {
slouken@6690
   154
                y = SCREEN_HEIGHT-8;
icculus@6397
   155
            }
icculus@6397
   156
slouken@6690
   157
            if (hat_pos & SDL_HAT_LEFT) {
slouken@6690
   158
                x = 0;
slouken@6690
   159
            } else if (hat_pos & SDL_HAT_RIGHT) {
slouken@6690
   160
                x = SCREEN_WIDTH-8;
icculus@6397
   161
            }
icculus@6397
   162
slouken@6690
   163
            DrawRect(screen, x, y, 8, 8);
slouken@1895
   164
        }
slouken@6690
   165
slouken@6690
   166
        SDL_RenderPresent(screen);
icculus@6730
   167
icculus@6730
   168
        if (SDL_JoystickGetAttached( joystick ) == 0) {
icculus@6730
   169
            done = SDL_TRUE;
icculus@6730
   170
            retval = SDL_TRUE;  /* keep going, wait for reattach. */
icculus@6730
   171
        }
icculus@9278
   172
}
icculus@9278
   173
icculus@9278
   174
static SDL_bool
icculus@9278
   175
WatchJoystick(SDL_Joystick * joystick)
icculus@9278
   176
{
icculus@9278
   177
    SDL_Window *window = NULL;
icculus@9278
   178
    const char *name = NULL;
philipp@9340
   179
philipp@9340
   180
    retval = SDL_FALSE;
philipp@9338
   181
    done = SDL_FALSE;
icculus@9278
   182
icculus@9278
   183
    /* Create a window to display joystick axis position */
icculus@9278
   184
    window = SDL_CreateWindow("Joystick Test", SDL_WINDOWPOS_CENTERED,
icculus@9278
   185
                              SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
icculus@9278
   186
                              SCREEN_HEIGHT, 0);
icculus@9278
   187
    if (window == NULL) {
icculus@9278
   188
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
icculus@9278
   189
        return SDL_FALSE;
slouken@1895
   190
    }
slouken@6690
   191
icculus@9278
   192
    screen = SDL_CreateRenderer(window, -1, 0);
icculus@9278
   193
    if (screen == NULL) {
icculus@9278
   194
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
icculus@9278
   195
        SDL_DestroyWindow(window);
icculus@9278
   196
        return SDL_FALSE;
icculus@9278
   197
    }
icculus@9278
   198
icculus@9278
   199
    SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
icculus@9278
   200
    SDL_RenderClear(screen);
icculus@9278
   201
    SDL_RenderPresent(screen);
icculus@9278
   202
    SDL_RaiseWindow(window);
icculus@9278
   203
icculus@9278
   204
    /* Print info about the joystick we are watching */
icculus@9278
   205
    name = SDL_JoystickName(joystick);
icculus@9278
   206
    SDL_Log("Watching joystick %d: (%s)\n", SDL_JoystickInstanceID(joystick),
icculus@9278
   207
           name ? name : "Unknown Joystick");
icculus@9278
   208
    SDL_Log("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
icculus@9278
   209
           SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick),
icculus@9278
   210
           SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick));
icculus@9278
   211
icculus@9278
   212
    /* Loop, getting joystick events! */
icculus@9278
   213
#ifdef __EMSCRIPTEN__
icculus@9278
   214
    emscripten_set_main_loop_arg(loop, joystick, 0, 1);
icculus@9278
   215
#else
icculus@9278
   216
    while (!done) {
icculus@9278
   217
        loop(joystick);
icculus@9278
   218
    }
icculus@9278
   219
#endif
icculus@9278
   220
slouken@6690
   221
    SDL_DestroyRenderer(screen);
philipp@9340
   222
    screen = NULL;
slouken@6690
   223
    SDL_DestroyWindow(window);
icculus@6730
   224
    return retval;
slouken@0
   225
}
slouken@0
   226
slouken@1895
   227
int
slouken@1895
   228
main(int argc, char *argv[])
slouken@0
   229
{
slouken@1895
   230
    const char *name;
slouken@6690
   231
    int i;
slouken@1895
   232
    SDL_Joystick *joystick;
slouken@0
   233
aschiffler@7639
   234
    /* Enable standard application logging */
aschiffler@7639
   235
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);	
aschiffler@7639
   236
slouken@1895
   237
    /* Initialize SDL (Note: video is required to start event loop) */
slouken@6690
   238
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
aschiffler@7639
   239
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
slouken@1895
   240
        exit(1);
slouken@1895
   241
    }
slouken@0
   242
slouken@1895
   243
    /* Print information about the joysticks */
aschiffler@7639
   244
    SDL_Log("There are %d joysticks attached\n", SDL_NumJoysticks());
slouken@1895
   245
    for (i = 0; i < SDL_NumJoysticks(); ++i) {
slouken@6690
   246
        name = SDL_JoystickNameForIndex(i);
aschiffler@7639
   247
        SDL_Log("Joystick %d: %s\n", i, name ? name : "Unknown Joystick");
icculus@2200
   248
        joystick = SDL_JoystickOpen(i);
icculus@2200
   249
        if (joystick == NULL) {
aschiffler@7639
   250
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_JoystickOpen(%d) failed: %s\n", i,
slouken@2201
   251
                    SDL_GetError());
icculus@2200
   252
        } else {
icculus@6747
   253
            char guid[64];
icculus@6747
   254
            SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick),
icculus@6747
   255
                                      guid, sizeof (guid));
aschiffler@7639
   256
            SDL_Log("       axes: %d\n", SDL_JoystickNumAxes(joystick));
aschiffler@7639
   257
            SDL_Log("      balls: %d\n", SDL_JoystickNumBalls(joystick));
aschiffler@7639
   258
            SDL_Log("       hats: %d\n", SDL_JoystickNumHats(joystick));
aschiffler@7639
   259
            SDL_Log("    buttons: %d\n", SDL_JoystickNumButtons(joystick));
aschiffler@7639
   260
            SDL_Log("instance id: %d\n", SDL_JoystickInstanceID(joystick));
aschiffler@7639
   261
            SDL_Log("       guid: %s\n", guid);
icculus@2200
   262
            SDL_JoystickClose(joystick);
icculus@2200
   263
        }
slouken@1895
   264
    }
slouken@0
   265
gabomdq@8762
   266
#ifdef __ANDROID__
slouken@7017
   267
    if (SDL_NumJoysticks() > 0) {
slouken@7017
   268
#else
slouken@6690
   269
    if (argv[1]) {
slouken@7017
   270
#endif
icculus@6731
   271
        SDL_bool reportederror = SDL_FALSE;
icculus@6730
   272
        SDL_bool keepGoing = SDL_TRUE;
icculus@6731
   273
        SDL_Event event;
philipp@8078
   274
        int device;
gabomdq@8762
   275
#ifdef __ANDROID__
philipp@8078
   276
        device = 0;
slouken@7017
   277
#else
philipp@8078
   278
        device = atoi(argv[1]);
slouken@7017
   279
#endif
philipp@8078
   280
        joystick = SDL_JoystickOpen(device);
philipp@8078
   281
icculus@6731
   282
        while ( keepGoing ) {
icculus@6731
   283
            if (joystick == NULL) {
icculus@6731
   284
                if ( !reportederror ) {
philipp@8078
   285
                    SDL_Log("Couldn't open joystick %d: %s\n", device, SDL_GetError());
icculus@6732
   286
                    keepGoing = SDL_FALSE;
icculus@6731
   287
                    reportederror = SDL_TRUE;
icculus@6731
   288
                }
icculus@6731
   289
            } else {
icculus@6731
   290
                reportederror = SDL_FALSE;
icculus@6731
   291
                keepGoing = WatchJoystick(joystick);
icculus@6731
   292
                SDL_JoystickClose(joystick);
icculus@6731
   293
            }
icculus@6731
   294
slouken@6736
   295
            joystick = NULL;
icculus@6730
   296
            if (keepGoing) {
aschiffler@7639
   297
                SDL_Log("Waiting for attach\n");
slouken@6736
   298
            }
slouken@6736
   299
            while (keepGoing) {
slouken@6736
   300
                SDL_WaitEvent(&event);
slouken@7017
   301
                if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN)
slouken@7017
   302
                    || (event.type == SDL_MOUSEBUTTONDOWN)) {
slouken@6736
   303
                    keepGoing = SDL_FALSE;
slouken@6736
   304
                } else if (event.type == SDL_JOYDEVICEADDED) {
philipp@8078
   305
                    joystick = SDL_JoystickOpen(device);
slouken@6736
   306
                    break;
icculus@6731
   307
                }
icculus@6730
   308
            }
icculus@6731
   309
        }
icculus@6731
   310
    }
slouken@6690
   311
    SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
slouken@0
   312
philipp@8073
   313
    return 0;
slouken@0
   314
}
aschiffler@6771
   315
aschiffler@6771
   316
#else
aschiffler@6771
   317
aschiffler@6771
   318
int
aschiffler@6771
   319
main(int argc, char *argv[])
aschiffler@6771
   320
{
aschiffler@7639
   321
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n");
aschiffler@6771
   322
    exit(1);
aschiffler@6771
   323
}
aschiffler@6771
   324
aschiffler@6771
   325
#endif