test/testjoystick.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 19 Mar 2013 22:25:02 -0700
changeset 7017 7c2eb015a6d7
parent 6771 55337ff4256f
child 7191 75360622e65f
permissions -rw-r--r--
Fixed bug 1759 - Updates to testjoystick.c

ny00

A minor patch is attached, with the following few changes to testjoystick.c:
- Unused constant definitions have been removed.
- Output for all analog axes is drawn, even when there is an odd number of axes. (I have a controller with 5 analog axes.)
- Buttons are now drawn on two rows, so there's room for more. In fact, it has been used for testing a proposed joystick patch for Android, where large button ID numbers have been involved (20 and up). For more details see http://bugzilla.libsdl.org/show_bug.cgi?id=1700.
- A few adaptations have been done for the Android platform, assuming joystick support is ever applied to it. One of them is that the very first joystick (in the enumeration of all joysticks) is opened for testing, if there is any.
- It is now possible to quit from the calibration by pressing on a mouse button, tapping on a touchscreen or pressing/tapping on the "Back" button of an Android device. Technically, a press on a key identified by key code SDLK_AC_BACK results in that.
slouken@5535
     1
/*
slouken@5535
     2
  Copyright (C) 1997-2011 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
aschiffler@6771
    21
#ifndef SDL_JOYSTICK_DISABLED
aschiffler@6771
    22
slouken@6690
    23
#ifdef __IPHONEOS__
slouken@6690
    24
#define SCREEN_WIDTH	320
slouken@6690
    25
#define SCREEN_HEIGHT	480
slouken@6690
    26
#else
slouken@6690
    27
#define SCREEN_WIDTH	640
slouken@6690
    28
#define SCREEN_HEIGHT	480
slouken@6690
    29
#endif
slouken@0
    30
aschiffler@6771
    31
icculus@6398
    32
static void
icculus@6398
    33
DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
icculus@6398
    34
{
icculus@6398
    35
    const SDL_Rect area = { x, y, w, h };
icculus@6398
    36
    SDL_RenderFillRect(r, &area);
icculus@6398
    37
}
icculus@6398
    38
icculus@6730
    39
static SDL_bool
slouken@1895
    40
WatchJoystick(SDL_Joystick * joystick)
slouken@0
    41
{
icculus@6398
    42
    SDL_Window *window = NULL;
icculus@6398
    43
    SDL_Renderer *screen = NULL;
icculus@6398
    44
    const char *name = NULL;
icculus@6730
    45
    SDL_bool retval = SDL_FALSE;
icculus@6730
    46
    SDL_bool done = SDL_FALSE;
slouken@6690
    47
    SDL_Event event;
icculus@6398
    48
    int i;
slouken@0
    49
slouken@6690
    50
    /* Create a window to display joystick axis position */
slouken@6690
    51
    window = SDL_CreateWindow("Joystick Test", SDL_WINDOWPOS_CENTERED,
slouken@6690
    52
                              SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
slouken@6690
    53
                              SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
slouken@6690
    54
    if (window == NULL) {
slouken@6690
    55
        fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
icculus@6730
    56
        return SDL_FALSE;
slouken@6690
    57
    }
slouken@6690
    58
slouken@6690
    59
    screen = SDL_CreateRenderer(window, -1, 0);
slouken@6690
    60
    if (screen == NULL) {
slouken@6690
    61
        fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
slouken@6690
    62
        SDL_DestroyWindow(window);
icculus@6730
    63
        return SDL_FALSE;
slouken@6690
    64
    }
slouken@6690
    65
slouken@6690
    66
    SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
slouken@6690
    67
    SDL_RenderClear(screen);
slouken@6690
    68
    SDL_RenderPresent(screen);
icculus@6731
    69
    SDL_RaiseWindow(window);
slouken@6690
    70
slouken@1895
    71
    /* Print info about the joystick we are watching */
slouken@6690
    72
    name = SDL_JoystickName(joystick);
slouken@6690
    73
    printf("Watching joystick %d: (%s)\n", SDL_JoystickInstanceID(joystick),
slouken@1895
    74
           name ? name : "Unknown Joystick");
slouken@1895
    75
    printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
slouken@1895
    76
           SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick),
slouken@1895
    77
           SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick));
slouken@0
    78
icculus@6398
    79
    /* Loop, getting joystick events! */
icculus@6398
    80
    while (!done) {
slouken@6690
    81
        /* blank screen, set up for drawing this frame. */
slouken@6690
    82
        SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
slouken@6690
    83
        SDL_RenderClear(screen);
slouken@6690
    84
slouken@1895
    85
        while (SDL_PollEvent(&event)) {
slouken@1895
    86
            switch (event.type) {
slouken@1895
    87
            case SDL_JOYAXISMOTION:
slouken@1895
    88
                printf("Joystick %d axis %d value: %d\n",
slouken@1895
    89
                       event.jaxis.which,
slouken@1895
    90
                       event.jaxis.axis, event.jaxis.value);
slouken@1895
    91
                break;
slouken@1895
    92
            case SDL_JOYHATMOTION:
slouken@1895
    93
                printf("Joystick %d hat %d value:",
slouken@1895
    94
                       event.jhat.which, event.jhat.hat);
slouken@1895
    95
                if (event.jhat.value == SDL_HAT_CENTERED)
slouken@1895
    96
                    printf(" centered");
slouken@1895
    97
                if (event.jhat.value & SDL_HAT_UP)
slouken@1895
    98
                    printf(" up");
slouken@1895
    99
                if (event.jhat.value & SDL_HAT_RIGHT)
slouken@1895
   100
                    printf(" right");
slouken@1895
   101
                if (event.jhat.value & SDL_HAT_DOWN)
slouken@1895
   102
                    printf(" down");
slouken@1895
   103
                if (event.jhat.value & SDL_HAT_LEFT)
slouken@1895
   104
                    printf(" left");
slouken@1895
   105
                printf("\n");
slouken@1895
   106
                break;
slouken@1895
   107
            case SDL_JOYBALLMOTION:
slouken@1895
   108
                printf("Joystick %d ball %d delta: (%d,%d)\n",
slouken@1895
   109
                       event.jball.which,
slouken@1895
   110
                       event.jball.ball, event.jball.xrel, event.jball.yrel);
slouken@1895
   111
                break;
slouken@1895
   112
            case SDL_JOYBUTTONDOWN:
slouken@1895
   113
                printf("Joystick %d button %d down\n",
slouken@1895
   114
                       event.jbutton.which, event.jbutton.button);
slouken@1895
   115
                break;
slouken@1895
   116
            case SDL_JOYBUTTONUP:
slouken@1895
   117
                printf("Joystick %d button %d up\n",
slouken@1895
   118
                       event.jbutton.which, event.jbutton.button);
slouken@1895
   119
                break;
slouken@1895
   120
            case SDL_KEYDOWN:
slouken@7017
   121
                if ((event.key.keysym.sym != SDLK_ESCAPE) &&
slouken@7017
   122
                    (event.key.keysym.sym != SDLK_AC_BACK)) {
slouken@1895
   123
                    break;
slouken@1895
   124
                }
slouken@1895
   125
                /* Fall through to signal quit */
slouken@7017
   126
            case SDL_FINGERDOWN:
slouken@7017
   127
            case SDL_MOUSEBUTTONDOWN:
slouken@1895
   128
            case SDL_QUIT:
icculus@6730
   129
                done = SDL_TRUE;
slouken@1895
   130
                break;
slouken@1895
   131
            default:
slouken@1895
   132
                break;
slouken@1895
   133
            }
slouken@1895
   134
        }
slouken@6690
   135
        /* Update visual joystick state */
slouken@6690
   136
        SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE);
slouken@6690
   137
        for (i = 0; i < SDL_JoystickNumButtons(joystick); ++i) {
slouken@6690
   138
            if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
slouken@7017
   139
                DrawRect(screen, (i%20) * 34, SCREEN_HEIGHT - 68 + (i/20) * 34, 32, 32);
slouken@6690
   140
            }
slouken@6690
   141
        }
slouken@6586
   142
slouken@6690
   143
        SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE);
slouken@7017
   144
        for (i = 0; i < SDL_JoystickNumAxes(joystick); ++i) {
slouken@6690
   145
            /* Draw the X/Y axis */
slouken@6690
   146
            int x, y;
slouken@7017
   147
            x = (((int) SDL_JoystickGetAxis(joystick, i)) + 32768);
slouken@6690
   148
            x *= SCREEN_WIDTH;
slouken@6690
   149
            x /= 65535;
slouken@6690
   150
            if (x < 0) {
slouken@6690
   151
                x = 0;
slouken@6690
   152
            } else if (x > (SCREEN_WIDTH - 16)) {
slouken@6690
   153
                x = SCREEN_WIDTH - 16;
slouken@6690
   154
            }
slouken@7017
   155
            ++i;
slouken@7017
   156
            if (i < SDL_JoystickNumAxes(joystick)) {
slouken@7017
   157
                y = (((int) SDL_JoystickGetAxis(joystick, i)) + 32768);
slouken@7017
   158
            } else {
slouken@7017
   159
                y = 32768;
slouken@7017
   160
            }
slouken@6690
   161
            y *= SCREEN_HEIGHT;
slouken@6690
   162
            y /= 65535;
slouken@6690
   163
            if (y < 0) {
slouken@6690
   164
                y = 0;
slouken@6690
   165
            } else if (y > (SCREEN_HEIGHT - 16)) {
slouken@6690
   166
                y = SCREEN_HEIGHT - 16;
slouken@1895
   167
            }
slouken@2765
   168
slouken@6690
   169
            DrawRect(screen, x, y, 16, 16);
slouken@6690
   170
        }
icculus@6397
   171
slouken@6690
   172
        SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE);
slouken@6690
   173
        for (i = 0; i < SDL_JoystickNumHats(joystick); ++i) {
slouken@6690
   174
            /* Derive the new position */
slouken@6690
   175
            int x = SCREEN_WIDTH/2;
slouken@6690
   176
            int y = SCREEN_HEIGHT/2;
slouken@6690
   177
            const Uint8 hat_pos = SDL_JoystickGetHat(joystick, i);
slouken@6690
   178
slouken@6690
   179
            if (hat_pos & SDL_HAT_UP) {
slouken@6690
   180
                y = 0;
slouken@6690
   181
            } else if (hat_pos & SDL_HAT_DOWN) {
slouken@6690
   182
                y = SCREEN_HEIGHT-8;
icculus@6397
   183
            }
icculus@6397
   184
slouken@6690
   185
            if (hat_pos & SDL_HAT_LEFT) {
slouken@6690
   186
                x = 0;
slouken@6690
   187
            } else if (hat_pos & SDL_HAT_RIGHT) {
slouken@6690
   188
                x = SCREEN_WIDTH-8;
icculus@6397
   189
            }
icculus@6397
   190
slouken@6690
   191
            DrawRect(screen, x, y, 8, 8);
slouken@1895
   192
        }
slouken@6690
   193
slouken@6690
   194
        SDL_RenderPresent(screen);
icculus@6730
   195
icculus@6730
   196
        if (SDL_JoystickGetAttached( joystick ) == 0) {
icculus@6730
   197
            done = SDL_TRUE;
icculus@6730
   198
            retval = SDL_TRUE;  /* keep going, wait for reattach. */
icculus@6730
   199
        }
slouken@1895
   200
    }
slouken@6690
   201
slouken@6690
   202
    SDL_DestroyRenderer(screen);
slouken@6690
   203
    SDL_DestroyWindow(window);
icculus@6730
   204
    return retval;
slouken@0
   205
}
slouken@0
   206
slouken@1895
   207
int
slouken@1895
   208
main(int argc, char *argv[])
slouken@0
   209
{
slouken@1895
   210
    const char *name;
slouken@6690
   211
    int i;
slouken@1895
   212
    SDL_Joystick *joystick;
slouken@0
   213
slouken@1895
   214
    /* Initialize SDL (Note: video is required to start event loop) */
slouken@6690
   215
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
slouken@1895
   216
        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
slouken@1895
   217
        exit(1);
slouken@1895
   218
    }
slouken@0
   219
slouken@1895
   220
    /* Print information about the joysticks */
slouken@1895
   221
    printf("There are %d joysticks attached\n", SDL_NumJoysticks());
slouken@1895
   222
    for (i = 0; i < SDL_NumJoysticks(); ++i) {
slouken@6690
   223
        name = SDL_JoystickNameForIndex(i);
slouken@2201
   224
        printf("Joystick %d: %s\n", i, name ? name : "Unknown Joystick");
icculus@2200
   225
        joystick = SDL_JoystickOpen(i);
icculus@2200
   226
        if (joystick == NULL) {
slouken@2201
   227
            fprintf(stderr, "SDL_JoystickOpen(%d) failed: %s\n", i,
slouken@2201
   228
                    SDL_GetError());
icculus@2200
   229
        } else {
icculus@6747
   230
            char guid[64];
icculus@6747
   231
            SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick),
icculus@6747
   232
                                      guid, sizeof (guid));
icculus@2200
   233
            printf("       axes: %d\n", SDL_JoystickNumAxes(joystick));
icculus@2200
   234
            printf("      balls: %d\n", SDL_JoystickNumBalls(joystick));
icculus@2200
   235
            printf("       hats: %d\n", SDL_JoystickNumHats(joystick));
icculus@2200
   236
            printf("    buttons: %d\n", SDL_JoystickNumButtons(joystick));
slouken@6690
   237
            printf("instance id: %d\n", SDL_JoystickInstanceID(joystick));
icculus@6747
   238
            printf("       guid: %s\n", guid);
icculus@2200
   239
            SDL_JoystickClose(joystick);
icculus@2200
   240
        }
slouken@1895
   241
    }
slouken@0
   242
slouken@7017
   243
#ifdef ANDROID
slouken@7017
   244
    if (SDL_NumJoysticks() > 0) {
slouken@7017
   245
#else
slouken@6690
   246
    if (argv[1]) {
slouken@7017
   247
#endif
icculus@6731
   248
        SDL_bool reportederror = SDL_FALSE;
icculus@6730
   249
        SDL_bool keepGoing = SDL_TRUE;
icculus@6731
   250
        SDL_Event event;
slouken@7017
   251
#ifdef ANDROID
slouken@7017
   252
        joystick = SDL_JoystickOpen(0);
slouken@7017
   253
#else
icculus@6731
   254
        joystick = SDL_JoystickOpen(atoi(argv[1]));
slouken@7017
   255
#endif
icculus@6731
   256
        while ( keepGoing ) {
icculus@6731
   257
            if (joystick == NULL) {
icculus@6731
   258
                if ( !reportederror ) {
icculus@6731
   259
                    printf("Couldn't open joystick %d: %s\n", atoi(argv[1]), SDL_GetError());
icculus@6732
   260
                    keepGoing = SDL_FALSE;
icculus@6731
   261
                    reportederror = SDL_TRUE;
icculus@6731
   262
                }
icculus@6731
   263
            } else {
icculus@6731
   264
                reportederror = SDL_FALSE;
icculus@6731
   265
                keepGoing = WatchJoystick(joystick);
icculus@6731
   266
                SDL_JoystickClose(joystick);
icculus@6731
   267
            }
icculus@6731
   268
slouken@6736
   269
            joystick = NULL;
icculus@6730
   270
            if (keepGoing) {
slouken@6736
   271
                printf("Waiting for attach\n");
slouken@6736
   272
            }
slouken@6736
   273
            while (keepGoing) {
slouken@6736
   274
                SDL_WaitEvent(&event);
slouken@7017
   275
                if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN)
slouken@7017
   276
                    || (event.type == SDL_MOUSEBUTTONDOWN)) {
slouken@6736
   277
                    keepGoing = SDL_FALSE;
slouken@6736
   278
                } else if (event.type == SDL_JOYDEVICEADDED) {
icculus@6731
   279
                    joystick = SDL_JoystickOpen(atoi(argv[1]));
slouken@6736
   280
                    break;
icculus@6731
   281
                }
icculus@6730
   282
            }
icculus@6731
   283
        }
icculus@6731
   284
    }
slouken@6690
   285
    SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
slouken@0
   286
slouken@7017
   287
#ifdef ANDROID
slouken@7017
   288
    exit(0);
slouken@7017
   289
#else
icculus@6730
   290
    return 0;
slouken@7017
   291
#endif
slouken@0
   292
}
aschiffler@6771
   293
aschiffler@6771
   294
#else
aschiffler@6771
   295
aschiffler@6771
   296
int
aschiffler@6771
   297
main(int argc, char *argv[])
aschiffler@6771
   298
{
aschiffler@6771
   299
    fprintf(stderr, "SDL compiled without Joystick support.\n");
aschiffler@6771
   300
    exit(1);
aschiffler@6771
   301
}
aschiffler@6771
   302
aschiffler@6771
   303
#endif