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.
     1 /*
     2   Copyright (C) 1997-2011 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 #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, SDL_WINDOW_SHOWN);
    54     if (window == NULL) {
    55         fprintf(stderr, "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         fprintf(stderr, "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     printf("Watching joystick %d: (%s)\n", SDL_JoystickInstanceID(joystick),
    74            name ? name : "Unknown Joystick");
    75     printf("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                 printf("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                 printf("Joystick %d hat %d value:",
    94                        event.jhat.which, event.jhat.hat);
    95                 if (event.jhat.value == SDL_HAT_CENTERED)
    96                     printf(" centered");
    97                 if (event.jhat.value & SDL_HAT_UP)
    98                     printf(" up");
    99                 if (event.jhat.value & SDL_HAT_RIGHT)
   100                     printf(" right");
   101                 if (event.jhat.value & SDL_HAT_DOWN)
   102                     printf(" down");
   103                 if (event.jhat.value & SDL_HAT_LEFT)
   104                     printf(" left");
   105                 printf("\n");
   106                 break;
   107             case SDL_JOYBALLMOTION:
   108                 printf("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                 printf("Joystick %d button %d down\n",
   114                        event.jbutton.which, event.jbutton.button);
   115                 break;
   116             case SDL_JOYBUTTONUP:
   117                 printf("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     /* Initialize SDL (Note: video is required to start event loop) */
   215     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
   216         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   217         exit(1);
   218     }
   219 
   220     /* Print information about the joysticks */
   221     printf("There are %d joysticks attached\n", SDL_NumJoysticks());
   222     for (i = 0; i < SDL_NumJoysticks(); ++i) {
   223         name = SDL_JoystickNameForIndex(i);
   224         printf("Joystick %d: %s\n", i, name ? name : "Unknown Joystick");
   225         joystick = SDL_JoystickOpen(i);
   226         if (joystick == NULL) {
   227             fprintf(stderr, "SDL_JoystickOpen(%d) failed: %s\n", i,
   228                     SDL_GetError());
   229         } else {
   230             char guid[64];
   231             SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick),
   232                                       guid, sizeof (guid));
   233             printf("       axes: %d\n", SDL_JoystickNumAxes(joystick));
   234             printf("      balls: %d\n", SDL_JoystickNumBalls(joystick));
   235             printf("       hats: %d\n", SDL_JoystickNumHats(joystick));
   236             printf("    buttons: %d\n", SDL_JoystickNumButtons(joystick));
   237             printf("instance id: %d\n", SDL_JoystickInstanceID(joystick));
   238             printf("       guid: %s\n", guid);
   239             SDL_JoystickClose(joystick);
   240         }
   241     }
   242 
   243 #ifdef ANDROID
   244     if (SDL_NumJoysticks() > 0) {
   245 #else
   246     if (argv[1]) {
   247 #endif
   248         SDL_bool reportederror = SDL_FALSE;
   249         SDL_bool keepGoing = SDL_TRUE;
   250         SDL_Event event;
   251 #ifdef ANDROID
   252         joystick = SDL_JoystickOpen(0);
   253 #else
   254         joystick = SDL_JoystickOpen(atoi(argv[1]));
   255 #endif
   256         while ( keepGoing ) {
   257             if (joystick == NULL) {
   258                 if ( !reportederror ) {
   259                     printf("Couldn't open joystick %d: %s\n", atoi(argv[1]), SDL_GetError());
   260                     keepGoing = SDL_FALSE;
   261                     reportederror = SDL_TRUE;
   262                 }
   263             } else {
   264                 reportederror = SDL_FALSE;
   265                 keepGoing = WatchJoystick(joystick);
   266                 SDL_JoystickClose(joystick);
   267             }
   268 
   269             joystick = NULL;
   270             if (keepGoing) {
   271                 printf("Waiting for attach\n");
   272             }
   273             while (keepGoing) {
   274                 SDL_WaitEvent(&event);
   275                 if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN)
   276                     || (event.type == SDL_MOUSEBUTTONDOWN)) {
   277                     keepGoing = SDL_FALSE;
   278                 } else if (event.type == SDL_JOYDEVICEADDED) {
   279                     joystick = SDL_JoystickOpen(atoi(argv[1]));
   280                     break;
   281                 }
   282             }
   283         }
   284     }
   285     SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
   286 
   287 #ifdef ANDROID
   288     exit(0);
   289 #else
   290     return 0;
   291 #endif
   292 }
   293 
   294 #else
   295 
   296 int
   297 main(int argc, char *argv[])
   298 {
   299     fprintf(stderr, "SDL compiled without Joystick support.\n");
   300     exit(1);
   301 }
   302 
   303 #endif