From 95ec90aa8a67df2e348efa53c6a97baaa71511d3 Mon Sep 17 00:00:00 2001 From: Gabriel Jacobo Date: Mon, 2 Dec 2013 19:35:04 -0300 Subject: [PATCH] Adds controllermap utility to test suite. --- src/joystick/SDL_gamecontrollerdb.h | 2 + test/Makefile.in | 7 +- test/README | 3 + test/axis.bmp | Bin 0 -> 3746 bytes test/button.bmp | Bin 0 -> 3746 bytes test/controllermap.bmp | Bin 0 -> 163450 bytes test/controllermap.c | 432 ++++++++++++++++++++++++++++ test/testgamecontroller.c | 2 + 8 files changed, 445 insertions(+), 1 deletion(-) create mode 100644 test/axis.bmp create mode 100644 test/button.bmp create mode 100644 test/controllermap.bmp create mode 100644 test/controllermap.c diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 4dd711cd02..5954ccf745 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -26,6 +26,8 @@ The easiest way to generate a new mapping is to start Steam in Big Picture mode, configure your joystick and then look in config/config.vdf in your Steam installation directory for the "SDL_GamepadBind" entry. + + Alternatively, you can use the app located in test/controllermap */ static const char *s_ControllerMappings [] = { diff --git a/test/Makefile.in b/test/Makefile.in index ac9aa372a3..a534250fd7 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -55,7 +55,8 @@ TARGETS = \ torturethread$(EXE) \ testrendercopyex$(EXE) \ testmessage$(EXE) \ - + controllermap$(EXE) \ + all: Makefile $(TARGETS) Makefile: $(srcdir)/Makefile.in @@ -238,6 +239,10 @@ testrendercopyex$(EXE): $(srcdir)/testrendercopyex.c testmessage$(EXE): $(srcdir)/testmessage.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +controllermap$(EXE): $(srcdir)/controllermap.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + + clean: rm -f $(TARGETS) diff --git a/test/README b/test/README index a2ff7942a9..b820a88d7a 100644 --- a/test/README +++ b/test/README @@ -25,3 +25,6 @@ These are test programs for the SDL library: testver Check the version and dynamic loading and endianness testwm2 Test window manager -- title, icon, events torturethread Simple test for thread creation/destruction + controllermap Useful to generate Game Controller API compatible maps + + diff --git a/test/axis.bmp b/test/axis.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c7addd3ed9372e59d11d874dace91bb64840e066 GIT binary patch literal 3746 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 L*WhAc5axzp21W)35O#78Dh5lEKrmrZ%gD&c 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 N-<N`mfU|JOD{MV(0(> literal 0 HcmV?d00001 diff --git a/test/controllermap.c b/test/controllermap.c new file mode 100644 index 0000000000..2c943cf9e3 --- /dev/null +++ b/test/controllermap.c @@ -0,0 +1,432 @@ +/* + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +/* Game controller mapping generator */ +/* Gabriel Jacobo */ + +#include +#include +#include + +#include "SDL.h" + +#ifndef SDL_JOYSTICK_DISABLED + +#ifdef __IPHONEOS__ +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 480 +#else +#define SCREEN_WIDTH 512 +#define SCREEN_HEIGHT 317 +#endif + +#define MAP_WIDTH 512 +#define MAP_HEIGHT 317 + +#define MARKER_BUTTON 1 +#define MARKER_AXIS 2 + +typedef struct MappingStep +{ + int x, y; + double angle; + int marker; + char *field; + int axis, button, hat, hat_value; + char mapping[4096]; +}MappingStep; + + +SDL_Texture * +LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) +{ + SDL_Surface *temp; + SDL_Texture *texture; + + /* Load the sprite image */ + temp = SDL_LoadBMP(file); + if (temp == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); + return NULL; + } + + /* Set transparent pixel as the pixel at (0,0) */ + if (transparent) { + if (temp->format->palette) { + SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); + } else { + switch (temp->format->BitsPerPixel) { + case 15: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint16 *) temp->pixels) & 0x00007FFF); + break; + case 16: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); + break; + case 24: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint32 *) temp->pixels) & 0x00FFFFFF); + break; + case 32: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); + break; + } + } + } + + /* Create textures from the image */ + texture = SDL_CreateTextureFromSurface(renderer, temp); + if (!texture) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); + SDL_FreeSurface(temp); + return NULL; + } + SDL_FreeSurface(temp); + + /* We're ready to roll. :) */ + return texture; +} + +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 SDL_bool +WatchJoystick(SDL_Joystick * joystick) +{ + SDL_Window *window = NULL; + SDL_Renderer *screen = NULL; + SDL_Texture *target, *background, *button, *axis, *marker; + const char *name = NULL; + SDL_bool retval = SDL_FALSE; + SDL_bool done = SDL_FALSE, next=SDL_FALSE; + SDL_Event event; + SDL_Rect dst; + int i, s, _s; + Uint8 alpha=200, alpha_step = -1; + Uint32 alpha_ticks; + char mapping[4096], temp[4096]; + MappingStep *step; + MappingStep steps[] = { + {342, 132, 0.0, MARKER_BUTTON, "x", -1, -1, -1, -1, ""}, + {387, 167, 0.0, MARKER_BUTTON, "a", -1, -1, -1, -1, ""}, + {431, 132, 0.0, MARKER_BUTTON, "b", -1, -1, -1, -1, ""}, + {389, 101, 0.0, MARKER_BUTTON, "y", -1, -1, -1, -1, ""}, + {174, 132, 0.0, MARKER_BUTTON, "back", -1, -1, -1, -1, ""}, + {233, 132, 0.0, MARKER_BUTTON, "guide", -1, -1, -1, -1, ""}, + {289, 132, 0.0, MARKER_BUTTON, "start", -1, -1, -1, -1, ""}, + {116, 217, 0.0, MARKER_BUTTON, "dpleft", -1, -1, -1, -1, ""}, + {154, 249, 0.0, MARKER_BUTTON, "dpdown", -1, -1, -1, -1, ""}, + {186, 217, 0.0, MARKER_BUTTON, "dpright", -1, -1, -1, -1, ""}, + {154, 188, 0.0, MARKER_BUTTON, "dpup", -1, -1, -1, -1, ""}, + {77, 40, 0.0, MARKER_BUTTON, "leftshoulder", -1, -1, -1, -1, ""}, + {91, 0, 0.0, MARKER_BUTTON, "lefttrigger", -1, -1, -1, -1, ""}, + {396, 36, 0.0, MARKER_BUTTON, "rightshoulder", -1, -1, -1, -1, ""}, + {375, 0, 0.0, MARKER_BUTTON, "righttrigger", -1, -1, -1, -1, ""}, + {75, 154, 0.0, MARKER_BUTTON, "leftstick", -1, -1, -1, -1, ""}, + {305, 230, 0.0, MARKER_BUTTON, "rightstick", -1, -1, -1, -1, ""}, + {75, 154, 0.0, MARKER_AXIS, "leftx", -1, -1, -1, -1, ""}, + {75, 154, 90.0, MARKER_AXIS, "lefty", -1, -1, -1, -1, ""}, + {305, 230, 0.0, MARKER_AXIS, "rightx", -1, -1, -1, -1, ""}, + {305, 230, 90.0, MARKER_AXIS, "righty", -1, -1, -1, -1, ""}, + }; + + /* Create a window to display joystick axis position */ + window = SDL_CreateWindow("Joystick Test", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, + SCREEN_HEIGHT, 0); + if (window == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); + return SDL_FALSE; + } + + screen = SDL_CreateRenderer(window, -1, 0); + if (screen == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); + SDL_DestroyWindow(window); + return SDL_FALSE; + } + + target = SDL_CreateTexture(screen, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, MAP_WIDTH, MAP_HEIGHT); + background = LoadTexture(screen, "controllermap.bmp", SDL_FALSE); + button = LoadTexture(screen, "button.bmp", SDL_TRUE); + axis = LoadTexture(screen, "axis.bmp", SDL_TRUE); + SDL_RaiseWindow(window); + + /* Print info about the joystick we are watching */ + name = SDL_JoystickName(joystick); + SDL_Log("Watching joystick %d: (%s)\n", SDL_JoystickInstanceID(joystick), + name ? name : "Unknown Joystick"); + SDL_Log("Joystick has %d axes, %d hats, %d balls, and %d buttons\n", + SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick), + SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick)); + + SDL_Log("\n\n\ + ====================================================================================\n\ + Press the buttons on your controller when indicated\n\ + (Your controller may look different than the picture)\n\ + If you want to correct a mistake, press backspace or the back button on your device\n\ + To exit, press ESC\n\ + ====================================================================================\n"); + + /* Initialize mapping with GUID and name */ + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), temp, SDL_arraysize(temp)); + SDL_snprintf(mapping, SDL_arraysize(mapping), "%s,%s,platform:%s,", + temp, name ? name : "Unknown Joystick", SDL_GetPlatform()); + + /* Loop, getting joystick events! */ + for(s=0; smapping, mapping, SDL_arraysize(step->mapping)); + step->axis = -1; + step->button = -1; + step->hat = -1; + step->hat_value = -1; + SDL_SetClipboardText("TESTING TESTING 123"); + + switch(step->marker) { + case MARKER_AXIS: + marker = axis; + break; + case MARKER_BUTTON: + marker = button; + break; + default: + break; + } + + dst.x = step->x; + dst.y = step->y; + SDL_QueryTexture(marker, NULL, NULL, &dst.w, &dst.h); + next=SDL_FALSE; + + while (!done && !next) { + if (SDL_GetTicks() - alpha_ticks > 5) { + alpha_ticks = SDL_GetTicks(); + alpha += alpha_step; + if (alpha == 255) { + alpha_step = -1; + } + if (alpha < 128) { + alpha_step = 1; + } + } + + SDL_SetRenderTarget(screen, target); + SDL_RenderCopy(screen, background, NULL, NULL); + SDL_SetTextureAlphaMod(marker, alpha); + SDL_SetTextureColorMod(marker, 10, 255, 21); + SDL_RenderCopyEx(screen, marker, NULL, &dst, step->angle, NULL, 0); + SDL_SetRenderTarget(screen, NULL); + SDL_RenderCopy(screen, target, NULL, NULL); + SDL_RenderPresent(screen); + + if (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_JOYAXISMOTION: + if (event.jaxis.value > 20000 || event.jaxis.value < -20000) { + for (_s = 0; _s < s; _s++) { + if (steps[_s].axis == event.jaxis.axis) { + break; + } + } + if (_s == s) { + step->axis = event.jaxis.axis; + SDL_strlcat(mapping, step->field, SDL_arraysize(mapping)); + SDL_snprintf(temp, SDL_arraysize(temp), ":a%u,", event.jaxis.axis); + SDL_strlcat(mapping, temp, SDL_arraysize(mapping)); + s++; + next=SDL_TRUE; + } + } + + break; + case SDL_JOYHATMOTION: + for (_s = 0; _s < s; _s++) { + if (steps[_s].hat == event.jhat.hat && steps[_s].hat_value == event.jhat.value) { + break; + } + } + if (_s == s) { + step->hat = event.jhat.hat; + step->hat_value = event.jhat.value; + SDL_strlcat(mapping, step->field, SDL_arraysize(mapping)); + SDL_snprintf(temp, SDL_arraysize(temp), ":h%u.%u,", event.jhat.hat, event.jhat.value ); + SDL_strlcat(mapping, temp, SDL_arraysize(mapping)); + s++; + next=SDL_TRUE; + } + break; + case SDL_JOYBALLMOTION: + break; + case SDL_JOYBUTTONUP: + for (_s = 0; _s < s; _s++) { + if (steps[_s].button == event.jbutton.button) { + break; + } + } + if (_s == s) { + step->button = event.jbutton.button; + SDL_strlcat(mapping, step->field, SDL_arraysize(mapping)); + SDL_snprintf(temp, SDL_arraysize(temp), ":b%u,", event.jbutton.button); + SDL_strlcat(mapping, temp, SDL_arraysize(mapping)); + s++; + next=SDL_TRUE; + } + break; + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_BACKSPACE || event.key.keysym.sym == SDLK_AC_BACK) { + /* Undo! */ + if (s > 0) { + SDL_strlcpy(mapping, step->mapping, SDL_arraysize(step->mapping)); + s--; + next = SDL_TRUE; + } + break; + } + if ((event.key.keysym.sym != SDLK_ESCAPE)) { + break; + } + /* Fall through to signal quit */ + case SDL_FINGERDOWN: + case SDL_MOUSEBUTTONDOWN: + case SDL_QUIT: + done = SDL_TRUE; + break; + default: + break; + } + } + } + + } + + if (s == SDL_arraysize(steps) ) { + SDL_Log("Mapping:\n\n%s\n\n", mapping); + /* Print to stdout as well so the user can cat the output somewhere */ + printf("%s\n", mapping); + } + + while(SDL_PollEvent(&event)) {}; + + SDL_DestroyRenderer(screen); + SDL_DestroyWindow(window); + return retval; +} + +int +main(int argc, char *argv[]) +{ + const char *name; + int i; + SDL_Joystick *joystick; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Initialize SDL (Note: video is required to start event loop) */ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + /* Print information about the joysticks */ + SDL_Log("There are %d joysticks attached\n", SDL_NumJoysticks()); + for (i = 0; i < SDL_NumJoysticks(); ++i) { + name = SDL_JoystickNameForIndex(i); + SDL_Log("Joystick %d: %s\n", i, name ? name : "Unknown Joystick"); + joystick = SDL_JoystickOpen(i); + if (joystick == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_JoystickOpen(%d) failed: %s\n", i, + SDL_GetError()); + } else { + char guid[64]; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), + guid, sizeof (guid)); + SDL_Log(" axes: %d\n", SDL_JoystickNumAxes(joystick)); + SDL_Log(" balls: %d\n", SDL_JoystickNumBalls(joystick)); + SDL_Log(" hats: %d\n", SDL_JoystickNumHats(joystick)); + SDL_Log(" buttons: %d\n", SDL_JoystickNumButtons(joystick)); + SDL_Log("instance id: %d\n", SDL_JoystickInstanceID(joystick)); + SDL_Log(" guid: %s\n", guid); + SDL_JoystickClose(joystick); + } + } + +#ifdef ANDROID + if (SDL_NumJoysticks() > 0) { +#else + if (argv[1]) { +#endif + SDL_bool reportederror = SDL_FALSE; + SDL_bool keepGoing = SDL_TRUE; + SDL_Event event; +#ifdef ANDROID + joystick = SDL_JoystickOpen(0); +#else + joystick = SDL_JoystickOpen(atoi(argv[1])); +#endif + while ( keepGoing ) { + if (joystick == NULL) { + if ( !reportederror ) { + SDL_Log("Couldn't open joystick %d: %s\n", atoi(argv[1]), SDL_GetError()); + keepGoing = SDL_FALSE; + reportederror = SDL_TRUE; + } + } else { + reportederror = SDL_FALSE; + keepGoing = WatchJoystick(joystick); + SDL_JoystickClose(joystick); + } + + joystick = NULL; + if (keepGoing) { + SDL_Log("Waiting for attach\n"); + } + while (keepGoing) { + SDL_WaitEvent(&event); + if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN) + || (event.type == SDL_MOUSEBUTTONDOWN)) { + keepGoing = SDL_FALSE; + } else if (event.type == SDL_JOYDEVICEADDED) { + joystick = SDL_JoystickOpen(atoi(argv[1])); + break; + } + } + } + } + else { + SDL_Log("\n\nUsage: ./controllermap number\nFor example: ./controllermap 0\nOr: ./controllermap 0 >> gamecontrollerdb.txt"); + } + SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK); + +#ifdef ANDROID + exit(0); +#else + return 0; +#endif +} + +#else + +int +main(int argc, char *argv[]) +{ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n"); + exit(1); +} + +#endif diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c index cbdf8c3b14..3d9101ab30 100644 --- a/test/testgamecontroller.c +++ b/test/testgamecontroller.c @@ -225,6 +225,8 @@ main(int argc, char *argv[]) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); return 1; } + + SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt"); /* Print information about the controller */ for (i = 0; i < SDL_NumJoysticks(); ++i) {