Merge commit '852f2a6343518919e5ca8d3c1bbcab9f493e3cd8'

This commit is contained in:
2024-01-17 17:02:59 +01:00
1244 changed files with 50102 additions and 28146 deletions

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -38,10 +38,10 @@ static const struct
int x;
int y;
} button_positions[] = {
{ 413, 190 }, /* SDL_GAMEPAD_BUTTON_A */
{ 456, 156 }, /* SDL_GAMEPAD_BUTTON_B */
{ 372, 159 }, /* SDL_GAMEPAD_BUTTON_X */
{ 415, 127 }, /* SDL_GAMEPAD_BUTTON_Y */
{ 413, 190 }, /* SDL_GAMEPAD_BUTTON_SOUTH */
{ 456, 156 }, /* SDL_GAMEPAD_BUTTON_EAST */
{ 372, 159 }, /* SDL_GAMEPAD_BUTTON_WEST */
{ 415, 127 }, /* SDL_GAMEPAD_BUTTON_NORTH */
{ 199, 157 }, /* SDL_GAMEPAD_BUTTON_BACK */
{ 257, 153 }, /* SDL_GAMEPAD_BUTTON_GUIDE */
{ 314, 157 }, /* SDL_GAMEPAD_BUTTON_START */
@ -120,7 +120,7 @@ struct GamepadImage
int y;
SDL_bool showing_front;
SDL_bool showing_touchpad;
GamepadImageFaceStyle face_style;
SDL_GamepadType type;
ControllerDisplayMode display_mode;
SDL_bool elements[SDL_GAMEPAD_ELEMENT_MAX];
@ -146,29 +146,6 @@ static SDL_Texture *CreateTexture(SDL_Renderer *renderer, unsigned char *data, u
return texture;
}
static SDL_GamepadButton GetRemappedButton(GamepadImageFaceStyle face_style, SDL_GamepadButton button)
{
if (face_style == GAMEPAD_IMAGE_FACE_BAYX) {
switch (button) {
case SDL_GAMEPAD_BUTTON_A:
button = SDL_GAMEPAD_BUTTON_B;
break;
case SDL_GAMEPAD_BUTTON_B:
button = SDL_GAMEPAD_BUTTON_A;
break;
case SDL_GAMEPAD_BUTTON_X:
button = SDL_GAMEPAD_BUTTON_Y;
break;
case SDL_GAMEPAD_BUTTON_Y:
button = SDL_GAMEPAD_BUTTON_X;
break;
default:
break;
}
}
return button;
}
GamepadImage *CreateGamepadImage(SDL_Renderer *renderer)
{
GamepadImage *ctx = SDL_calloc(1, sizeof(*ctx));
@ -241,22 +218,22 @@ void SetGamepadImageShowingFront(GamepadImage *ctx, SDL_bool showing_front)
ctx->showing_front = showing_front;
}
void SetGamepadImageFaceStyle(GamepadImage *ctx, GamepadImageFaceStyle face_style)
void SetGamepadImageFaceButtonType(GamepadImage *ctx, SDL_GamepadType type)
{
if (!ctx) {
return;
}
ctx->face_style = face_style;
ctx->type = type;
}
GamepadImageFaceStyle GetGamepadImageFaceStyle(GamepadImage *ctx)
SDL_GamepadType GetGamepadImageType(GamepadImage *ctx)
{
if (!ctx) {
return GAMEPAD_IMAGE_FACE_BLANK;
return SDL_GAMEPAD_TYPE_UNKNOWN;
}
return ctx->face_style;
return ctx->type;
}
void SetGamepadImageDisplayMode(GamepadImage *ctx, ControllerDisplayMode display_mode)
@ -407,7 +384,7 @@ int GetGamepadImageElementAt(GamepadImage *ctx, float x, float y)
rect.w = (float)ctx->button_width;
rect.h = (float)ctx->button_height;
if (SDL_PointInRectFloat(&point, &rect)) {
return GetRemappedButton(ctx->face_style, (SDL_GamepadButton)i);
return (SDL_GamepadButton)i;
}
}
}
@ -440,29 +417,15 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad)
return;
}
ctx->type = SDL_GetGamepadType(gamepad);
char *mapping = SDL_GetGamepadMapping(gamepad);
SDL_GamepadType gamepad_type = SDL_GetGamepadType(gamepad);
switch (gamepad_type) {
case SDL_GAMEPAD_TYPE_PS3:
case SDL_GAMEPAD_TYPE_PS4:
case SDL_GAMEPAD_TYPE_PS5:
ctx->face_style = GAMEPAD_IMAGE_FACE_SONY;
break;
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT:
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT:
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
ctx->face_style = GAMEPAD_IMAGE_FACE_BAYX;
break;
default:
if (mapping && SDL_strstr(mapping, "SDL_GAMECONTROLLER_USE_BUTTON_LABELS")) {
ctx->face_style = GAMEPAD_IMAGE_FACE_BAYX;
} else {
ctx->face_style = GAMEPAD_IMAGE_FACE_ABXY;
if (mapping) {
if (SDL_strstr(mapping, "SDL_GAMECONTROLLER_USE_BUTTON_LABELS")) {
/* Just for display purposes */
ctx->type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO;
}
break;
SDL_free(mapping);
}
SDL_free(mapping);
for (i = 0; i < SDL_GAMEPAD_BUTTON_TOUCHPAD; ++i) {
const SDL_GamepadButton button = (SDL_GamepadButton)i;
@ -557,7 +520,7 @@ void RenderGamepadImage(GamepadImage *ctx)
for (i = 0; i < SDL_arraysize(button_positions); ++i) {
if (ctx->elements[i]) {
SDL_GamepadButton button_position = GetRemappedButton(ctx->face_style, (SDL_GamepadButton)i);
SDL_GamepadButton button_position = (SDL_GamepadButton)i;
SDL_bool on_front = SDL_TRUE;
if (i >= SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 && i <= SDL_GAMEPAD_BUTTON_LEFT_PADDLE2) {
@ -579,14 +542,14 @@ void RenderGamepadImage(GamepadImage *ctx)
dst.w = (float)ctx->face_width;
dst.h = (float)ctx->face_height;
switch (ctx->face_style) {
case GAMEPAD_IMAGE_FACE_ABXY:
switch (SDL_GetGamepadButtonLabelForType(ctx->type, SDL_GAMEPAD_BUTTON_SOUTH)) {
case SDL_GAMEPAD_BUTTON_LABEL_A:
SDL_RenderTexture(ctx->renderer, ctx->face_abxy_texture, NULL, &dst);
break;
case GAMEPAD_IMAGE_FACE_BAYX:
case SDL_GAMEPAD_BUTTON_LABEL_B:
SDL_RenderTexture(ctx->renderer, ctx->face_bayx_texture, NULL, &dst);
break;
case GAMEPAD_IMAGE_FACE_SONY:
case SDL_GAMEPAD_BUTTON_LABEL_CROSS:
SDL_RenderTexture(ctx->renderer, ctx->face_sony_texture, NULL, &dst);
break;
default:
@ -665,10 +628,10 @@ void DestroyGamepadImage(GamepadImage *ctx)
static const char *gamepad_button_names[] = {
"A",
"B",
"X",
"Y",
"South",
"East",
"West",
"North",
"Back",
"Guide",
"Start",
@ -801,9 +764,49 @@ static SDL_bool GetBindingString(const char *label, char *mapping, char *text, s
static SDL_bool GetButtonBindingString(SDL_GamepadButton button, char *mapping, char *text, size_t size)
{
char label[32];
SDL_bool baxy_mapping = SDL_FALSE;
if (!mapping) {
return SDL_FALSE;
}
SDL_snprintf(label, sizeof(label), ",%s:", SDL_GetGamepadStringForButton(button));
return GetBindingString(label, mapping, text, size);
if (GetBindingString(label, mapping, text, size)) {
return SDL_TRUE;
}
/* Try the legacy button names */
if (SDL_strstr(mapping, ",hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1") != NULL) {
baxy_mapping = SDL_TRUE;
}
switch (button) {
case SDL_GAMEPAD_BUTTON_SOUTH:
if (baxy_mapping) {
return GetBindingString(",b:", mapping, text, size);
} else {
return GetBindingString(",a:", mapping, text, size);
}
case SDL_GAMEPAD_BUTTON_EAST:
if (baxy_mapping) {
return GetBindingString(",a:", mapping, text, size);
} else {
return GetBindingString(",b:", mapping, text, size);
}
case SDL_GAMEPAD_BUTTON_WEST:
if (baxy_mapping) {
return GetBindingString(",y:", mapping, text, size);
} else {
return GetBindingString(",x:", mapping, text, size);
}
case SDL_GAMEPAD_BUTTON_NORTH:
if (baxy_mapping) {
return GetBindingString(",x:", mapping, text, size);
} else {
return GetBindingString(",y:", mapping, text, size);
}
default:
return SDL_FALSE;
}
}
static SDL_bool GetAxisBindingString(SDL_GamepadAxis axis, int direction, char *mapping, char *text, size_t size)
@ -1707,7 +1710,7 @@ void RenderJoystickDisplay(JoystickDisplay *ctx, SDL_Joystick *joystick)
highlight.h = (float)ctx->button_height;
RenderJoystickButtonHighlight(ctx, i, &highlight);
SDL_snprintf(text, sizeof(text), "%2.d:", i);
SDL_snprintf(text, sizeof(text), "%2d:", i);
SDLTest_DrawString(ctx->renderer, x, y, text);
if (SDL_GetJoystickButton(joystick, (Uint8)i)) {
@ -2224,9 +2227,11 @@ static int FindMappingKey(const MappingParts *parts, const char *key)
{
int i;
for (i = 0; i < parts->num_elements; ++i) {
if (SDL_strcmp(key, parts->keys[i]) == 0) {
return i;
if (key) {
for (i = 0; i < parts->num_elements; ++i) {
if (SDL_strcmp(key, parts->keys[i]) == 0) {
return i;
}
}
}
return -1;
@ -2243,6 +2248,55 @@ static void RemoveMappingValueAt(MappingParts *parts, int index)
}
}
static void ConvertBAXYMapping(MappingParts *parts)
{
int i;
SDL_bool baxy_mapping = SDL_FALSE;
for (i = 0; i < parts->num_elements; ++i) {
const char *key = parts->keys[i];
const char *value = parts->values[i];
if (SDL_strcmp(key, "hint") == 0 &&
SDL_strcmp(value, "SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1") == 0) {
baxy_mapping = SDL_TRUE;
}
}
if (!baxy_mapping) {
return;
}
/* Swap buttons, invert hint */
for (i = 0; i < parts->num_elements; ++i) {
char *key = parts->keys[i];
char *value = parts->values[i];
if (SDL_strcmp(key, "a") == 0) {
parts->keys[i] = SDL_strdup("b");
SDL_free(key);
} else if (SDL_strcmp(key, "b") == 0) {
parts->keys[i] = SDL_strdup("a");
SDL_free(key);
} else if (SDL_strcmp(key, "x") == 0) {
parts->keys[i] = SDL_strdup("y");
SDL_free(key);
} else if (SDL_strcmp(key, "y") == 0) {
parts->keys[i] = SDL_strdup("x");
SDL_free(key);
} else if (SDL_strcmp(key, "hint") == 0 &&
SDL_strcmp(value, "SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1") == 0) {
parts->values[i] = SDL_strdup("!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1");
SDL_free(value);
}
}
}
static void UpdateLegacyElements(MappingParts *parts)
{
ConvertBAXYMapping(parts);
}
static SDL_bool CombineMappingAxes(MappingParts *parts)
{
int i, matching, axis;
@ -2337,6 +2391,7 @@ static char *JoinMapping(MappingParts *parts)
const char *name;
MappingSortEntry *sort_order;
UpdateLegacyElements(parts);
CombineMappingAxes(parts);
guid = parts->guid;
@ -2420,6 +2475,43 @@ static char *RecreateMapping(MappingParts *parts, char *mapping)
return mapping;
}
static const char *GetLegacyKey(const char *key, SDL_bool baxy)
{
if (SDL_strcmp(key, SDL_GetGamepadStringForButton(SDL_GAMEPAD_BUTTON_SOUTH)) == 0) {
if (baxy) {
return "b";
} else {
return "a";
}
}
if (SDL_strcmp(key, SDL_GetGamepadStringForButton(SDL_GAMEPAD_BUTTON_EAST)) == 0) {
if (baxy) {
return "a";
} else {
return "b";
}
}
if (SDL_strcmp(key, SDL_GetGamepadStringForButton(SDL_GAMEPAD_BUTTON_WEST)) == 0) {
if (baxy) {
return "y";
} else {
return "x";
}
}
if (SDL_strcmp(key, SDL_GetGamepadStringForButton(SDL_GAMEPAD_BUTTON_NORTH)) == 0) {
if (baxy) {
return "y";
} else {
return "x";
}
}
return key;
}
static SDL_bool MappingHasKey(const char *mapping, const char *key)
{
int i;
@ -2428,6 +2520,14 @@ static SDL_bool MappingHasKey(const char *mapping, const char *key)
SplitMapping(mapping, &parts);
i = FindMappingKey(&parts, key);
if (i < 0) {
SDL_bool baxy_mapping = SDL_FALSE;
if (mapping && SDL_strstr(mapping, ",hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1") != NULL) {
baxy_mapping = SDL_TRUE;
}
i = FindMappingKey(&parts, GetLegacyKey(key, baxy_mapping));
}
if (i >= 0) {
result = SDL_TRUE;
}
@ -2444,6 +2544,14 @@ static char *GetMappingValue(const char *mapping, const char *key)
SplitMapping(mapping, &parts);
i = FindMappingKey(&parts, key);
if (i < 0) {
SDL_bool baxy_mapping = SDL_FALSE;
if (mapping && SDL_strstr(mapping, ",hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1") != NULL) {
baxy_mapping = SDL_TRUE;
}
i = FindMappingKey(&parts, GetLegacyKey(key, baxy_mapping));
}
if (i >= 0) {
value = parts.values[i];
parts.values[i] = NULL; /* So we don't free it */
@ -2658,7 +2766,7 @@ SDL_GamepadType GetMappingType(const char *mapping)
char *SetMappingType(char *mapping, SDL_GamepadType type)
{
const char *type_string = SDL_GetGamepadStringForType(type);
if (type_string == NULL || type == SDL_GAMEPAD_TYPE_UNKNOWN) {
if (!type_string || type == SDL_GAMEPAD_TYPE_UNKNOWN) {
return RemoveMappingValue(mapping, "type");
} else {
return SetMappingValue(mapping, "type", type_string);