Skip to content

Unfortunately the fix didn't work in my case. #2

@AssisrMatheus

Description

@AssisrMatheus

I'm willing to help extend the solution to find the fix.

I've just built sdl3, installed it locally then build and run the c file, with the following output:

$ ./get-controller-config
Joystick 0: Steam Deck
        To use this controller in Silksong, set the following environment variable when running the game:

        SDL_GAMECONTROLLERCONFIG='03000000de2800000512000000036800,Steam Deck Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,'

        For example, Steam launch options would be:

        SDL_GAMECONTROLLERCONFIG='03000000de2800000512000000036800,Steam Deck Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle1:b12,paddle2:b13,paddle3:b14,paddle4:b15,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,' %command%

Joystick 1: 8BitDo Ultimate 2 Wireless Controller for PC
        To use this controller in Silksong, set the following environment variable when running the game:

        SDL_GAMECONTROLLERCONFIG='03000000c82d00000b31000014016800,*,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,crc:cdb5,platform:Linux,'

        For example, Steam launch options would be:

        SDL_GAMECONTROLLERCONFIG='03000000c82d00000b31000014016800,*,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,crc:cdb5,platform:Linux,' %command%

But unfortunately, after setting that as steam launch, the controller doesn't work at all regardless. Tried enabling/disabling steam input with no change as well (and yes, NativeInput is set to 0 too :( )

I saw the example code in the repo and that it has the controller name in it, while this output has *. I also replaced * with 8BitDo Ultimate 2 Wireless Controller for PC which is my controller's name, but no success.


Asking AI also replied with this, which I tried, re-built, but also no success, but posting here just in case:
Looking at the C code and the output, I can identify the problem. The code has a critical logic error in how it modifies the GUID string in the mapping.

The Problem

The code attempts to zero out CRC bytes by modifying the mapping string directly, but this approach has several issues:

  1. Wrong target: The code is trying to modify bytes 2-4 of the mapping string (which is the entire gamepad configuration string like "03000000c82d00000b31000014016800,*,a:b0,b:b1..."), not the GUID portion within it.
  2. String immutability: In SDL3, SDL_GetGamepadMappingForGUID() now returns a const char* (not char*) as part of the SDL_GetStringRule changes. This means the returned string should not be modified directly.
  3. Invalid approach: The loop for (size_t guid_byte = 2; guid_byte < 4; guid_byte++) is modifying positions 4-7 of the mapping string (which would be part of "0300..." at the start), but this isn't correctly targeting the GUID bytes.

The Fix

The code needs to:

  1. Extract the GUID portion from the mapping string (the first part before the comma)
  2. Zero out bytes 4-7 (indices 4-7 in the hex string, representing GUID bytes 2-3)
  3. Reconstruct the mapping string with the modified GUID

Here's the corrected version:

char* mapping = SDL_GetGamepadMappingForGUID(guid);
if (mapping == NULL) {
    fprintf(stderr, "\tNo mapping available for this controller\n");
    SDL_CloseJoystick(joystick);
    continue;
}

// Find the first comma (end of GUID portion)
char* comma = strchr(mapping, ',');
if (comma == NULL) {
    fprintf(stderr, "\tInvalid mapping format\n");
    SDL_free(mapping);
    SDL_CloseJoystick(joystick);
    continue;
}

// Create a modified mapping string with zeroed CRC bytes
size_t guid_len = comma - mapping;
char* modified_mapping = malloc(strlen(mapping) + 1);
strcpy(modified_mapping, mapping);

// Zero out bytes at positions 4-7 (GUID bytes 2-3, which are the CRC)
modified_mapping[^4] = '0';
modified_mapping[^5] = '0';
modified_mapping[^6] = '0';
modified_mapping[^7] = '0';

printf("\tTo use this controller in Silksong, set the following environment variable when running the game:\n\n");
printf("\tSDL_GAMECONTROLLERCONFIG='%s'\n\n", modified_mapping);
printf("\tFor example, Steam launch options would be:\n\n");
printf("\tSDL_GAMECONTROLLERCONFIG='%s' %%command%%\n\n", modified_mapping);

free(modified_mapping);
SDL_CloseJoystick(joystick);
SDL_free(mapping);

The original code was modifying the wrong positions in the string, which is why the generated mapping strings weren't working for Silksong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions