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