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 4dd711cd02f72..5954ccf745ee2 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 ac9aa372a39ea..a534250fd7e5c 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 a2ff7942a9442..b820a88d7a92d 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 zcmd6pWmH>R6NcZqP^GT4rL>d?1PK8Ov`ABTcc*U9LX?Dr1d9>^Az1N3-GI7KcXxMp zZ*T4nRG^oBUwePuv(`ClubKUvnb~L0d$v!%^m-_{xK)8UWaRkuu7sK;cH7!OBa6}- zm57PlKJ3APCC)#1RIXrdrAn1hxpHMxsZs@1t5!v|YSmD^dUe#OQ3Ew=)eZ`<`t|FhL4yWp*sviiEiKWgQ6n^N+!#%oG(pp*P0_4bGc<4B z94%V3K+Bdb(W+G|v~JxRZQ8U!+qP|CWo3nS?b@Mz`}XM2p#!X~t(&k3yLX3=j}Lr(ec|Wl2Y-Km z^ytw8Y&IJ`d-g=HUcJz}cW?CR(+7R~_C>#b{m{REe+(Ef00RdO#GpZgFnI7_3>h*6 zLx&E7PM~=j(QKK+=^k|G3GX`VFj>Wif<1l{wcubfu0TU-q#H2}+ zFnRK1OqntTQ>RYFv}w~Yefo3+1O#Blj2W0Yb0%iZnuXc3XJgKsIhZ?lF6Pafhxzm8 zW5I$2Sh#Q@7A;zYz`#HR1qEU8;>B39WC? z&`^j(B8bIegoTAcB9TBUl_ESm95R^C&Z0PftfiMg}r7Gm({*h3xEX-R23sF>5giV_^Ve{tA*s^5{ zwr<^uZQHhC`}XbFv112z?%au8yLMss?%gOZF2J9Z4mj~~a06DM%;^pFhWo7ccPg7beTY%gei4Hy>{%&HDdgRH{9L;mCAjF`b>5?w;OWzI{EZZT=@k zr_$*T&JOJx*RDqNvt~mp2X}X$p00LXeo4`&Br%6BmbIGDM{qT9k#l`o*KJ_q?C$UF zLi+_ol+WJ5rhX$fH*;;SL8XYxSXY!d&EBHDv$wAYwL*v>4)n%#*-AyYfHXf}AmH-_ z5r*vOHuY#-{a6*PAVKJqI?boZXD;URh-h#)Tn?8f4CQKec~`Y%vE3;Dh(x7Q=+yew z<7NhMc|3tgEDj@rA` zgX-9J^kY z6^BW~WimO@HG+x7LQyDJ#M$Fq-^I_hZP`Gi7+MQEml<4sXjr&R9uXNuWG^aGE|Z!w z6p-KrjXS!r%T`38P#HGXCQ}GcD3;12qhl0Gl}f2p#6-%&%@E(j(FN6EdV7?q$c{>5 zT9F3i2*lEe=opnoqb1U*)u!!;xU$Q9SqjC;o|sL%P&1;|#OmXTyvFNw z8YO|mBC**yz|zgr`FlZRq0L5lD&P!vLeHYhZDT=3zUmP1VVD86AA@9 zPGEq4%Qj=DbSKD9VMwGct1~uf4}VeH2{sn!g&`cG@=F32PVZ}D>8=X*v!|9{fUjBZ zT(hiDx90iTiR|go>A7h}jU;HaTkGcCRQr{lEc}JB!34ggJ%0Hpu~P~Tb^;%*23%rRb*J;^igbAdsk=LcOm>0 sdT7V`oUF{Wc%^v8aJH|H2jibhToHP@xFE-<6wRMFnC(=N|37W}8=w12r~m)} literal 0 HcmV?d00001 diff --git a/test/button.bmp b/test/button.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1593ccea49037934f387f73ea40c96ea32c18d41 GIT binary patch literal 3746 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 z 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 G;r|0kJ7VYn literal 0 HcmV?d00001 diff --git a/test/controllermap.c b/test/controllermap.c new file mode 100644 index 0000000000000..2c943cf9e3aa5 --- /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 cbdf8c3b146ea..3d9101ab30ed7 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) {