Commit b17fd9a180e38aefa162b4385eb6b333792c75e3

Ryan C. Gordon 2014-02-10T01:41:58

Replace testgamecontroller visualization mode with something more useful.

diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c
index 440721d..e7c1e05 100644
--- a/test/testgamecontroller.c
+++ b/test/testgamecontroller.c
@@ -24,20 +24,10 @@
 #define SCREEN_WIDTH    320
 #define SCREEN_HEIGHT    480
 #else
-#define SCREEN_WIDTH    640
-#define SCREEN_HEIGHT    480
+#define SCREEN_WIDTH    512
+#define SCREEN_HEIGHT   317
 #endif
 
-#define MAX_NUM_AXES 6
-#define MAX_NUM_HATS 2
-
-static void
-DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
-{
-    const SDL_Rect area = { x, y, w, h };
-    SDL_RenderFillRect(r, &area);
-}
-
 static const char *
 ControllerAxisName(const SDL_GameControllerAxis axis)
 {
@@ -83,13 +73,71 @@ ControllerButtonName(const SDL_GameControllerButton button)
     }
 }
 
+static SDL_Texture *
+LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
+{
+    SDL_Surface *temp = NULL;
+    SDL_Texture *texture = NULL;
+
+    temp = SDL_LoadBMP(file);
+    if (temp == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
+    } else {
+        /* Set transparent pixel as the pixel at (0,0) */
+        if (transparent) {
+            SDL_assert(!temp->format->palette);
+            SDL_assert(temp->format->BitsPerPixel == 24);
+            SDL_SetColorKey(temp, SDL_TRUE, (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
+        }
+
+        texture = SDL_CreateTextureFromSurface(renderer, temp);
+        if (!texture) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
+        }
+    }
+    if (temp) {
+        SDL_FreeSurface(temp);
+    }
+    return texture;
+}
+
 SDL_bool
 WatchGameController(SDL_GameController * gamecontroller)
 {
+    /* This is indexed by SDL_GameControllerButton. */
+    static const struct { int x; int y; } button_positions[] = {
+        {387, 167},  /* A */
+        {431, 132},  /* B */
+        {342, 132},  /* X */
+        {389, 101},  /* Y */
+        {174, 132},  /* BACK */
+        {233, 132},  /* GUIDE */
+        {289, 132},  /* START */
+        {75,  154},  /* LEFTSTICK */
+        {305, 230},  /* RIGHTSTICK */
+        {77,  40},   /* LEFTSHOULDER */
+        {396, 36},   /* RIGHTSHOULDER */
+        {154, 188},  /* DPAD_UP */
+        {154, 249},  /* DPAD_DOWN */
+        {116, 217},  /* DPAD_LEFT */
+        {186, 217},  /* DPAD_RIGHT */
+    };
+
+    /* This is indexed by SDL_GameControllerAxis. */
+    static const struct { int x; int y; double angle; } axis_positions[] = {
+        {75,  154, 0.0},  /* LEFTX */
+        {75,  154, 90.0},  /* LEFTY */
+        {305, 230, 0.0},  /* RIGHTX */
+        {305, 230, 90.0},  /* RIGHTY */
+        {91, 0, 90.0},     /* TRIGGERLEFT */
+        {375, 0, 90.0},    /* TRIGGERRIGHT */
+    };
+
     const char *name = SDL_GameControllerName(gamecontroller);
     const char *basetitle = "Game Controller Test: ";
     const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1;
     char *title = (char *)SDL_malloc(titlelen);
+    SDL_Texture *background, *button, *axis;
     SDL_Window *window = NULL;
     SDL_Renderer *screen = NULL;
     SDL_bool retval = SDL_FALSE;
@@ -101,7 +149,7 @@ WatchGameController(SDL_GameController * gamecontroller)
         SDL_snprintf(title, titlelen, "%s%s", basetitle, name);
     }
 
-    /* Create a window to display controller axis position */
+    /* Create a window to display controller state */
     window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
                               SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
                               SCREEN_HEIGHT, 0);
@@ -122,6 +170,21 @@ WatchGameController(SDL_GameController * gamecontroller)
     SDL_RenderPresent(screen);
     SDL_RaiseWindow(window);
 
+    background = LoadTexture(screen, "controllermap.bmp", SDL_FALSE);
+    button = LoadTexture(screen, "button.bmp", SDL_TRUE);
+    axis = LoadTexture(screen, "axis.bmp", SDL_TRUE);
+
+    if (!background || !button || !axis) {
+        SDL_DestroyRenderer(screen);
+        SDL_DestroyWindow(window);
+        return SDL_FALSE;
+    }
+    SDL_SetTextureColorMod(button, 10, 255, 21);
+    SDL_SetTextureColorMod(axis, 10, 255, 21);
+
+    /* !!! FIXME: */
+    /*SDL_RenderSetLogicalSize(screen, background->w, background->h);*/
+
     /* Print info about the controller we are watching */
     SDL_Log("Watching controller %s\n",  name ? name : "Unknown Controller");
 
@@ -130,26 +193,10 @@ WatchGameController(SDL_GameController * gamecontroller)
         /* blank screen, set up for drawing this frame. */
         SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
         SDL_RenderClear(screen);
+        SDL_RenderCopy(screen, background, NULL, NULL);
 
         while (SDL_PollEvent(&event)) {
             switch (event.type) {
-            case SDL_CONTROLLERAXISMOTION:
-                SDL_Log("Controller %d axis %d ('%s') value: %d\n",
-                       event.caxis.which,
-                       event.caxis.axis,
-                       ControllerAxisName((SDL_GameControllerAxis)event.caxis.axis),
-                       event.caxis.value);
-                break;
-            case SDL_CONTROLLERBUTTONDOWN:
-                SDL_Log("Controller %d button %d ('%s') down\n",
-                       event.cbutton.which, event.cbutton.button,
-                       ControllerButtonName((SDL_GameControllerButton)event.cbutton.button));
-                break;
-            case SDL_CONTROLLERBUTTONUP:
-                SDL_Log("Controller %d button %d ('%s') up\n",
-                       event.cbutton.which, event.cbutton.button,
-                       ControllerButtonName((SDL_GameControllerButton)event.cbutton.button));
-                break;
             case SDL_KEYDOWN:
                 if (event.key.keysym.sym != SDLK_ESCAPE) {
                     break;
@@ -162,40 +209,29 @@ WatchGameController(SDL_GameController * gamecontroller)
                 break;
             }
         }
+
         /* Update visual controller state */
-        SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE);
-        for (i = 0; i <SDL_CONTROLLER_BUTTON_MAX; ++i) {
+        for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) {
             if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) {
-                DrawRect(screen, i * 34, SCREEN_HEIGHT - 34, 32, 32);
+                const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 };
+                SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, 0);
             }
         }
 
-        SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE);
-        for (i = 0; i < SDL_CONTROLLER_AXIS_MAX / 2; ++i) {
-            /* Draw the X/Y axis */
-            int x, y;
-            x = (((int) SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i * 2 + 0))) + 32768);
-            x *= SCREEN_WIDTH;
-            x /= 65535;
-            if (x < 0) {
-                x = 0;
-            } else if (x > (SCREEN_WIDTH - 16)) {
-                x = SCREEN_WIDTH - 16;
+        for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) {
+            const Sint16 deadzone = 8000;  /* !!! FIXME: real deadzone */
+            const Sint16 value = SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i));
+            if (value < -deadzone) {
+                const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
+                const double angle = axis_positions[i].angle;
+                SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0);
+            } else if (value > deadzone) {
+                const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
+                const double angle = axis_positions[i].angle + 180.0;
+                SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0);
             }
-            y = (((int) SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i * 2 + 1))) + 32768);
-            y *= SCREEN_HEIGHT;
-            y /= 65535;
-            if (y < 0) {
-                y = 0;
-            } else if (y > (SCREEN_HEIGHT - 16)) {
-                y = SCREEN_HEIGHT - 16;
-            }
-
-            DrawRect(screen, x, y, 16, 16);
         }
 
-        SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE);
-
         SDL_RenderPresent(screen);
 
         if (!SDL_GameControllerGetAttached(gamecontroller)) {