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