test/testgamecontroller.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 24 Feb 2013 22:57:25 -0500
changeset 6914 8a9915ab24f0
parent 6771 55337ff4256f
child 6916 92e978d6dafa
permissions -rw-r--r--
Made testgamecontroller minimally more useful.
     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 game controller 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 #define MAX_NUM_AXES 6
    32 #define MAX_NUM_HATS 2
    33 
    34 static SDL_bool s_ForceQuit = SDL_FALSE;
    35 
    36 static void
    37 DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
    38 {
    39     const SDL_Rect area = { x, y, w, h };
    40     SDL_RenderFillRect(r, &area);
    41 }
    42 
    43 static const char *
    44 ControllerAxisName(const SDL_CONTROLLER_AXIS axis)
    45 {
    46     switch (axis)
    47     {
    48         #define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax
    49         AXIS_CASE(INVALID);
    50         AXIS_CASE(LEFTX);
    51         AXIS_CASE(LEFTY);
    52         AXIS_CASE(RIGHTX);
    53         AXIS_CASE(RIGHTY);
    54         AXIS_CASE(TRIGGERLEFT);
    55         AXIS_CASE(TRIGGERRIGHT);
    56         #undef AXIS_CASE
    57         default: return "???";
    58     }
    59 }
    60 
    61 static const char *
    62 ControllerButtonName(const SDL_CONTROLLER_BUTTON button)
    63 {
    64     switch (button)
    65     {
    66         #define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn
    67         BUTTON_CASE(INVALID);
    68         BUTTON_CASE(A);
    69         BUTTON_CASE(B);
    70         BUTTON_CASE(X);
    71         BUTTON_CASE(Y);
    72         BUTTON_CASE(BACK);
    73         BUTTON_CASE(GUIDE);
    74         BUTTON_CASE(START);
    75         BUTTON_CASE(LEFTSTICK);
    76         BUTTON_CASE(RIGHTSTICK);
    77         BUTTON_CASE(LEFTSHOULDER);
    78         BUTTON_CASE(RIGHTSHOULDER);
    79         BUTTON_CASE(DPAD_UP);
    80         BUTTON_CASE(DPAD_DOWN);
    81         BUTTON_CASE(DPAD_LEFT);
    82         BUTTON_CASE(DPAD_RIGHT);
    83         #undef BUTTON_CASE
    84         default: return "???";
    85     }
    86 }
    87 
    88 void
    89 WatchGameController(SDL_GameController * gamecontroller)
    90 {
    91     const char *controllername = gamecontroller ? SDL_GameControllerName(gamecontroller) : "???";
    92     const char *basetitle = "Game Controller Test: ";
    93     const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(controllername) + 1;
    94     char *title = SDL_malloc(titlelen);
    95     SDL_Window *window = NULL;
    96     SDL_Renderer *screen = NULL;
    97     const char *name = NULL;
    98     int done = 0;
    99     SDL_Event event;
   100     int i;
   101 
   102     if (title) {
   103         SDL_snprintf(title, titlelen, "%s%s", basetitle, controllername);
   104     }
   105 
   106     /* Create a window to display controller axis position */
   107     window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
   108                               SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
   109                               SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
   110     if (window == NULL) {
   111         fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
   112         return;
   113     }
   114 
   115     screen = SDL_CreateRenderer(window, -1, 0);
   116     if (screen == NULL) {
   117         fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
   118         SDL_DestroyWindow(window);
   119         return;
   120     }
   121 
   122     SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
   123     SDL_RenderClear(screen);
   124     SDL_RenderPresent(screen);
   125 	SDL_RaiseWindow(window);
   126 
   127     /* Print info about the controller we are watching */
   128     name = SDL_GameControllerName(gamecontroller);
   129     printf("Watching controller %s\n",  name ? name : "Unknown Controller");
   130     
   131     /* Loop, getting controller events! */
   132     while (!done) {
   133         /* blank screen, set up for drawing this frame. */
   134         SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
   135         SDL_RenderClear(screen);
   136 
   137         while (SDL_PollEvent(&event)) {
   138             switch (event.type) {
   139             case SDL_CONTROLLERAXISMOTION:
   140                 printf("Controller %d axis %d ('%s') value: %d\n",
   141                        event.caxis.which,
   142                        event.caxis.axis,
   143                        ControllerAxisName(event.caxis.axis),
   144                        event.caxis.value);
   145                 break;
   146             case SDL_CONTROLLERBUTTONDOWN:
   147                 printf("Controller %d button %d ('%s') down\n",
   148                        event.cbutton.which, event.cbutton.button,
   149                        ControllerButtonName(event.cbutton.button));
   150                 break;
   151             case SDL_CONTROLLERBUTTONUP:
   152                 printf("Controller %d button %d ('%s') up\n",
   153                        event.cbutton.which, event.cbutton.button,
   154                        ControllerButtonName(event.cbutton.button));
   155                 break;
   156             case SDL_KEYDOWN:
   157                 if (event.key.keysym.sym != SDLK_ESCAPE) {
   158                     break;
   159                 }
   160                 /* Fall through to signal quit */
   161             case SDL_QUIT:
   162                 done = 1;
   163                 s_ForceQuit = SDL_TRUE;
   164                 break;
   165             default:
   166                 break;
   167             }
   168         }
   169         /* Update visual controller state */
   170         SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE);
   171         for (i = 0; i <SDL_CONTROLLER_BUTTON_MAX; ++i) {
   172             if (SDL_GameControllerGetButton(gamecontroller, i) == SDL_PRESSED) {
   173                 DrawRect(screen, i * 34, SCREEN_HEIGHT - 34, 32, 32);
   174             }
   175         }
   176 
   177         SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE);
   178         for (i = 0; i < SDL_CONTROLLER_AXIS_MAX / 2; ++i) {
   179             /* Draw the X/Y axis */
   180             int x, y;
   181             x = (((int) SDL_GameControllerGetAxis(gamecontroller, i * 2 + 0)) + 32768);
   182             x *= SCREEN_WIDTH;
   183             x /= 65535;
   184             if (x < 0) {
   185                 x = 0;
   186             } else if (x > (SCREEN_WIDTH - 16)) {
   187                 x = SCREEN_WIDTH - 16;
   188             }
   189             y = (((int) SDL_GameControllerGetAxis(gamecontroller, i * 2 + 1)) + 32768);
   190             y *= SCREEN_HEIGHT;
   191             y /= 65535;
   192             if (y < 0) {
   193                 y = 0;
   194             } else if (y > (SCREEN_HEIGHT - 16)) {
   195                 y = SCREEN_HEIGHT - 16;
   196             }
   197 
   198             DrawRect(screen, x, y, 16, 16);
   199         }
   200 
   201         SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE);
   202 
   203         SDL_RenderPresent(screen);
   204 		
   205 		if ( !done )
   206 			done = SDL_GameControllerGetAttached( gamecontroller ) == 0;
   207     }
   208 
   209     SDL_DestroyRenderer(screen);
   210     SDL_DestroyWindow(window);
   211 }
   212 
   213 int
   214 main(int argc, char *argv[])
   215 {
   216     const char *name;
   217     int i;
   218 	int nController = 0;
   219     SDL_GameController *gamecontroller;
   220 
   221 	SDL_SetHint( SDL_HINT_GAMECONTROLLERCONFIG, "341a3608000000000000504944564944,Aferglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7" );
   222     /* Initialize SDL (Note: video is required to start event loop) */
   223     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER ) < 0) {
   224         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   225         exit(1);
   226     }
   227 
   228     /* Print information about the controller */
   229     for (i = 0; i < SDL_NumJoysticks(); ++i) {
   230 		if ( SDL_IsGameController(i) )
   231 		{
   232 			nController++;
   233 			name = SDL_GameControllerNameForIndex(i);
   234 			printf("Game Controller %d: %s\n", i, name ? name : "Unknown Controller");
   235 		}
   236     }
   237 	printf("There are %d game controllers attached\n", nController);
   238 
   239     if (argv[1]) {
   240 		int nreportederror = 0;
   241 		SDL_Event event;
   242 		gamecontroller = SDL_GameControllerOpen(atoi(argv[1]));
   243 		while ( s_ForceQuit == SDL_FALSE ) {
   244 			if (gamecontroller == NULL) {
   245 				if ( nreportederror == 0 ) {
   246 					printf("Couldn't open joystick %d: %s\n", atoi(argv[1]), SDL_GetError());
   247 					nreportederror = 1;
   248 				}
   249 			} else {
   250 				nreportederror = 0;
   251 				WatchGameController(gamecontroller);
   252 				SDL_GameControllerClose(gamecontroller);
   253 			}
   254 			
   255 			gamecontroller = NULL;
   256 			SDL_WaitEvent( &event );
   257 			if ( event.type == SDL_JOYDEVICEADDED )
   258 				gamecontroller = SDL_GameControllerOpen(atoi(argv[1]));
   259 		}
   260 	}
   261     SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER );
   262 
   263     return (0);
   264 }
   265 
   266 #else
   267 
   268 int
   269 main(int argc, char *argv[])
   270 {
   271     fprintf(stderr, "SDL compiled without Joystick support.\n");
   272     exit(1);
   273 }
   274 
   275 #endif