I have a logitech f710, where the mapping is basically a mess.
this is wrong:
dpad is seen as joystickleft (should be dpad)
lefttrigger is seen as rightx
back is seen as guide, etc.
So I made my own mapping with the help of this website you find if you google “gamepad online test”.
Here is the mapping:
char* mapping = “030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a6,lefty:a7,rightx:a3,righty:a4,dpadx:a0,dpady:a1”;
Here is the function that handles controllers:
void initControllers(){
char* mapping = "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a6,lefty:a7,rightx:a3,righty:a4,dpx:a0,dpy:a1";
SDL_GameController *ctrl;
SDL_Joystick *joy;
int i;
int mapped = SDL_GameControllerAddMapping(mapping);
if (mapped==-1){
printf( "SDL could not map! SDL Error: %s\n", SDL_GetError() );
}
printf("mapped: %d\n", mapped);
for(i = 0; i < SDL_NumJoysticks(); ++i) {
if (SDL_IsGameController(i)) {
char *mapping;
printf("Index \'%i\' is a compatible controller, named \'%s\'\n", i, SDL_GameControllerNameForIndex(i));
ctrl = SDL_GameControllerOpen(i);
joy = SDL_GameControllerGetJoystick(ctrl);
mapping = SDL_GameControllerMapping(ctrl);
printf("mapping:%s\n", mapping);
SDL_free(mapping);
char string[512] = {0};
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(i);
SDL_JoystickGetGUIDString(guid,string,512);
printf("%s\n", string);
} else {
printf("Index \'%i\' is not a compatible controller.\n", i);
}
}
}
The program prints:
mapped: 0
Index '0' is a compatible controller, named 'Logitech F710 Gamepad (XInput)'
mapping:030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a6,lefty:a7,rightx:a3,righty:a4,dpadx:a0,dpady:a1
030000006d0400001fc2000005030000
So that means it updated the mapping successfully, right?
So then why is the mapping still wrong when I actually press some buttons on the controller? For fun I tried swapping the mapping for the A and B buttons, but this did nothing, while I would have expected it to swap a and b.
So something somewhere is preventing my custom map from being applied even though sdl claims all is well.
To reiterate:
I supplied my own mapping
SDL straight up ignores it silently
Any ideas? Here is the whole code:
[spoiler]
#include <SDL2/SDL.h>
void initControllers(){
char* mapping = "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a6,lefty:a7,rightx:a3,righty:a4,dpadx:a0,dpady:a1";
SDL_GameController *ctrl;
SDL_Joystick *joy;
int i;
int mapped = SDL_GameControllerAddMapping(mapping);
if (mapped==-1){
printf( "SDL could not map! SDL Error: %s\n", SDL_GetError() );
}
printf("mapped: %d\n", mapped);
for(i = 0; i < SDL_NumJoysticks(); ++i) {
if (SDL_IsGameController(i)) {
char *mapping;
printf("Index \'%i\' is a compatible controller, named \'%s\'\n", i, SDL_GameControllerNameForIndex(i));
ctrl = SDL_GameControllerOpen(i);
joy = SDL_GameControllerGetJoystick(ctrl);
mapping = SDL_GameControllerMapping(ctrl);
printf("mapping:%s\n", mapping);
SDL_free(mapping);
char string[512] = {0};
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(i);
SDL_JoystickGetGUIDString(guid,string,512);
printf("%s\n", string);
} else {
printf("Index \'%i\' is not a compatible controller.\n", i);
}
}
}
int main(int argc, char ** argv)
{
// variables
int quit = 0;
SDL_Event event;
int x = 288;
int y = 208;
// Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0 )
{
printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
}
initControllers();
SDL_Window * window = SDL_CreateWindow("SDL2 Keyboard/Mouse events",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderPresent(renderer);
// handle events
while (!quit)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:{
quit = 1;
break;
}
case SDL_KEYDOWN:{
const char* a = SDL_GetKeyName(event.key.keysym.sym);
printf("Pressed down: %s\n", a);
break;
}
case SDL_KEYUP:{
const char* a = SDL_GetKeyName(event.key.keysym.sym);
printf("Released: %s\n", a);
break;
}
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
{
switch (event.button.button)
{
case SDL_BUTTON_LEFT:{
printf("LMB");
break;
}
case SDL_BUTTON_RIGHT:{
printf("RMB");
break;
}
case SDL_BUTTON_MIDDLE:{
printf("MMB");
break;
}
case SDL_BUTTON_X1:{
printf("X1");
break;
}
case SDL_BUTTON_X2:{
printf("X2");
break;
}
}
if (event.type == SDL_MOUSEBUTTONDOWN){
printf(" was clicked!\n");
} else {
printf(" was released!\n");
}
break;
}
case SDL_MOUSEMOTION:{
printf("Mouse moved to (%d, %d)\n", event.motion.x, event.motion.y);
break;
}
case SDL_MOUSEWHEEL:{
printf("Scrolled ");
if(event.wheel.y > 0){
printf("up\n");
}else if(event.wheel.y < 0){
printf("down\n");
}
if(event.wheel.x > 0){
printf("left\n");
}else if(event.wheel.x < 0){
printf("right\n");
}
break;
}
case SDL_JOYAXISMOTION:{
const char* axisname = SDL_GameControllerGetStringForAxis(event.jaxis.axis);
SDL_Log("Joystick axis %s value: %d\n", axisname, event.jaxis.value);
break;
}
case SDL_JOYHATMOTION:{
SDL_Log("Joystick %d hat %d value:",
event.jhat.which, event.jhat.hat);
if (event.jhat.value == SDL_HAT_CENTERED)
SDL_Log(" centered");
if (event.jhat.value & SDL_HAT_UP)
SDL_Log(" up");
if (event.jhat.value & SDL_HAT_RIGHT)
SDL_Log(" right");
if (event.jhat.value & SDL_HAT_DOWN)
SDL_Log(" down");
if (event.jhat.value & SDL_HAT_LEFT)
SDL_Log(" left");
SDL_Log("\n");
break;
}
case SDL_JOYBALLMOTION:{
SDL_Log("Joystick %d ball %d delta: (%d,%d)\n",
event.jball.which,
event.jball.ball, event.jball.xrel, event.jball.yrel);
break;
}
case SDL_JOYBUTTONDOWN:{
const char* btnname = SDL_GameControllerGetStringForButton(event.jbutton.button);
SDL_Log("Joystick button %s down\n", btnname);
break;
}
case SDL_JOYBUTTONUP:{
const char* btnname = SDL_GameControllerGetStringForButton(event.jbutton.button);
SDL_Log("Joystick button %s up\n", btnname);
break;
}
default:{
break;
printf("Unsupported input method (%d): ", event.type);
switch (event.type){
case SDL_QUIT: printf("SDL_QUIT\n");break;
case SDL_APP_TERMINATING: printf("SDL_APP_TERMINATING\n");break;
case SDL_APP_LOWMEMORY: printf("SDL_APP_LOWMEMORY\n");break;
case SDL_APP_WILLENTERBACKGROUND: printf("SDL_APP_WILLENTERBACKGROUND\n");break;
case SDL_APP_DIDENTERBACKGROUND: printf("SDL_APP_DIDENTERBACKGROUND\n");break;
case SDL_APP_WILLENTERFOREGROUND: printf("SDL_APP_WILLENTERFOREGROUND\n");break;
case SDL_APP_DIDENTERFOREGROUND: printf("SDL_APP_DIDENTERFOREGROUND\n");break;
case SDL_WINDOWEVENT: printf("SDL_WINDOWEVENT\n");break;
case SDL_SYSWMEVENT: printf("SDL_SYSWMEVENT\n");break;
case SDL_KEYDOWN: printf("SDL_KEYDOWN\n");break;
case SDL_KEYUP: printf("SDL_KEYUP\n");break;
case SDL_TEXTEDITING: printf("SDL_TEXTEDITING\n");break;
case SDL_TEXTINPUT: printf("SDL_TEXTINPUT\n");break;
case SDL_KEYMAPCHANGED: printf("SDL_KEYMAPCHANGED\n");break;
case SDL_MOUSEMOTION: printf("SDL_MOUSEMOTION\n");break;
case SDL_MOUSEBUTTONDOWN: printf("SDL_MOUSEBUTTONDOWN\n");break;
case SDL_MOUSEBUTTONUP: printf("SDL_MOUSEBUTTONUP\n");break;
case SDL_MOUSEWHEEL: printf("SDL_MOUSEWHEEL\n");break;
case SDL_JOYAXISMOTION: printf("SDL_JOYAXISMOTION\n");break;
case SDL_JOYBALLMOTION: printf("SDL_JOYBALLMOTION\n");break;
case SDL_JOYHATMOTION: printf("SDL_JOYHATMOTION\n");break;
case SDL_JOYBUTTONDOWN: printf("SDL_JOYBUTTONDOWN\n");break;
case SDL_JOYBUTTONUP: printf("SDL_JOYBUTTONUP\n");break;
case SDL_JOYDEVICEADDED: printf("SDL_JOYDEVICEADDED\n");break;
case SDL_JOYDEVICEREMOVED: printf("SDL_JOYDEVICEREMOVED\n");break;
case SDL_CONTROLLERAXISMOTION: printf("SDL_CONTROLLERAXISMOTION\n");break;
case SDL_CONTROLLERBUTTONDOWN: printf("SDL_CONTROLLERBUTTONDOWN\n");break;
case SDL_CONTROLLERBUTTONUP: printf("SDL_CONTROLLERBUTTONUP\n");break;
case SDL_CONTROLLERDEVICEADDED: printf("SDL_CONTROLLERDEVICEADDED\n");break;
case SDL_CONTROLLERDEVICEREMOVED: printf("SDL_CONTROLLERDEVICEREMOVED\n");break;
case SDL_CONTROLLERDEVICEREMAPPED: printf("SDL_CONTROLLERDEVICEREMAPPED\n");break;
case SDL_FINGERDOWN: printf("SDL_FINGERDOWN\n");break;
case SDL_FINGERUP: printf("SDL_FINGERUP\n");break;
case SDL_FINGERMOTION: printf("SDL_FINGERMOTION\n");break;
case SDL_DOLLARGESTURE: printf("SDL_DOLLARGESTURE\n");break;
case SDL_DOLLARRECORD: printf("SDL_DOLLARRECORD\n");break;
case SDL_MULTIGESTURE: printf("SDL_MULTIGESTURE\n");break;
case SDL_CLIPBOARDUPDATE: printf("SDL_CLIPBOARDUPDATE\n");break;
case SDL_DROPFILE: printf("SDL_DROPFILE\n");break;
case SDL_DROPTEXT: printf("SDL_DROPTEXT\n");break;
case SDL_DROPBEGIN: printf("SDL_DROPBEGIN\n");break;
case SDL_DROPCOMPLETE: printf("SDL_DROPCOMPLETE\n");break;
case SDL_AUDIODEVICEADDED: printf("SDL_AUDIODEVICEADDED\n");break;
case SDL_AUDIODEVICEREMOVED: printf("SDL_AUDIODEVICEREMOVED\n");break;
case SDL_RENDER_TARGETS_RESET: printf("SDL_RENDER_TARGETS_RESET\n");break;
case SDL_RENDER_DEVICE_RESET: printf("SDL_RENDER_DEVICE_RESET\n");break;
case SDL_USEREVENT: printf("SDL_USEREVENT\n");break;
case SDL_LASTEVENT: printf("SDL_LASTEVENT\n");break;
default: printf("Not a valid event\n");
}
}
}
}
// cleanup SDL
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
[/spoiler]