From ee34805053bd845976ea000a3c98c0ac8fdf2fe3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 11 Jul 2023 18:56:29 -0700 Subject: [PATCH] Added ABXY button labels to the gamepad image --- test/gamepadutils.c | 103 +++++++++++++++++++++++++++++++++++++++++--- test/gamepadutils.h | 1 + 2 files changed, 97 insertions(+), 7 deletions(-) diff --git a/test/gamepadutils.c b/test/gamepadutils.c index f399cbbc5a..bd3f88d513 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -34,10 +34,10 @@ static const struct int x; int y; } button_positions[] = { - { 412, 192 }, /* SDL_GAMEPAD_BUTTON_A */ - { 456, 157 }, /* SDL_GAMEPAD_BUTTON_B */ - { 367, 157 }, /* SDL_GAMEPAD_BUTTON_X */ - { 414, 126 }, /* SDL_GAMEPAD_BUTTON_Y */ + { 413, 193 }, /* SDL_GAMEPAD_BUTTON_A */ + { 456, 156 }, /* SDL_GAMEPAD_BUTTON_B */ + { 372, 159 }, /* SDL_GAMEPAD_BUTTON_X */ + { 416, 125 }, /* SDL_GAMEPAD_BUTTON_Y */ { 199, 157 }, /* SDL_GAMEPAD_BUTTON_BACK */ { 257, 153 }, /* SDL_GAMEPAD_BUTTON_GUIDE */ { 314, 157 }, /* SDL_GAMEPAD_BUTTON_START */ @@ -106,6 +106,7 @@ struct GamepadImage int x; int y; SDL_bool showing_front; + SDL_bool reverse_diamond; SDL_bool showing_battery; SDL_bool showing_touchpad; @@ -133,6 +134,29 @@ static SDL_Texture *CreateTexture(SDL_Renderer *renderer, unsigned char *data, u return texture; } +static SDL_GamepadButton GetRemappedButton(SDL_bool reverse_diamond, SDL_GamepadButton button) +{ + if (reverse_diamond) { + 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)); @@ -185,6 +209,15 @@ void SetGamepadImageShowingFront(GamepadImage *ctx, SDL_bool showing_front) ctx->showing_front = showing_front; } +void SetGamepadImageReverseDiamond(GamepadImage *ctx, SDL_bool reverse_diamond) +{ + if (!ctx) { + return; + } + + ctx->reverse_diamond = reverse_diamond; +} + void SetGamepadImageShowingBattery(GamepadImage *ctx, SDL_bool showing_battery) { if (!ctx) { @@ -298,7 +331,7 @@ SDL_GamepadButton GetGamepadImageButtonAt(GamepadImage *ctx, float x, float y) rect.w = (float)ctx->button_width; rect.h = (float)ctx->button_height; if (SDL_PointInRectFloat(&point, &rect)) { - return (SDL_GamepadButton)i; + return GetRemappedButton(ctx->reverse_diamond, (SDL_GamepadButton)i); } } } @@ -367,6 +400,23 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) return; } + if (gamepad) { + char *mapping = SDL_GetGamepadMapping(gamepad); + if (mapping) { + SDL_GamepadType gamepad_type = SDL_GetGamepadType(gamepad); + if (gamepad_type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO || + gamepad_type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT || + gamepad_type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT || + gamepad_type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR || + SDL_strstr(mapping, "SDL_GAMECONTROLLER_USE_BUTTON_LABELS")) { + ctx->reverse_diamond = SDL_TRUE; + } else { + ctx->reverse_diamond = SDL_FALSE; + } + SDL_free(mapping); + } + } + for (i = 0; i < SDL_GAMEPAD_BUTTON_TOUCHPAD; ++i) { const SDL_GamepadButton button = (SDL_GamepadButton)i; @@ -421,11 +471,16 @@ void RenderGamepadImage(GamepadImage *ctx) { SDL_FRect dst; int i; + Uint8 r, g, b, a; + char label[32]; + SDL_bool invert_color = SDL_FALSE; if (!ctx) { return; } + SDL_GetRenderDrawColor(ctx->renderer, &r, &g, &b, &a); + dst.x = (float)ctx->x; dst.y = (float)ctx->y; dst.w = (float)ctx->gamepad_width; @@ -438,6 +493,40 @@ void RenderGamepadImage(GamepadImage *ctx) } for (i = 0; i < SDL_arraysize(button_positions); ++i) { + SDL_GamepadButton button_position = GetRemappedButton(ctx->reverse_diamond, (SDL_GamepadButton)i); + + switch (i) { + case SDL_GAMEPAD_BUTTON_A: + SDL_strlcpy(label, "A", sizeof(label)); + break; + case SDL_GAMEPAD_BUTTON_B: + SDL_strlcpy(label, "B", sizeof(label)); + break; + case SDL_GAMEPAD_BUTTON_X: + SDL_strlcpy(label, "X", sizeof(label)); + break; + case SDL_GAMEPAD_BUTTON_Y: + SDL_strlcpy(label, "Y", sizeof(label)); + break; + default: + *label = '\0'; + break; + } + if (*label != '\0') { + dst.x = (float)ctx->x + button_positions[button_position].x - (float)(FONT_CHARACTER_SIZE * SDL_strlen(label)) / 2; + dst.y = (float)ctx->y + button_positions[button_position].y - (float)FONT_CHARACTER_SIZE / 2; + dst.w = (float)FONT_CHARACTER_SIZE; + dst.h = (float)FONT_CHARACTER_SIZE; + + if (button_position == SDL_GAMEPAD_BUTTON_B || button_position == SDL_GAMEPAD_BUTTON_X) { + SDL_SetRenderDrawColor(ctx->renderer, ~r, ~g, ~b, a); + SDLTest_DrawString(ctx->renderer, dst.x, dst.y, label); + SDL_SetRenderDrawColor(ctx->renderer, r, g, b, a); + } else { + SDLTest_DrawString(ctx->renderer, dst.x, dst.y, label); + } + } + if (ctx->buttons[i]) { SDL_bool on_front = SDL_TRUE; @@ -445,8 +534,8 @@ void RenderGamepadImage(GamepadImage *ctx) on_front = SDL_FALSE; } if (on_front == ctx->showing_front) { - dst.x = (float)ctx->x + button_positions[i].x - ctx->button_width / 2; - dst.y = (float)ctx->y + button_positions[i].y - ctx->button_height / 2; + dst.x = (float)ctx->x + button_positions[button_position].x - ctx->button_width / 2; + dst.y = (float)ctx->y + button_positions[button_position].y - ctx->button_height / 2; dst.w = (float)ctx->button_width; dst.h = (float)ctx->button_height; SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); diff --git a/test/gamepadutils.h b/test/gamepadutils.h index fbfc77cbf8..6a9c7f480c 100644 --- a/test/gamepadutils.h +++ b/test/gamepadutils.h @@ -17,6 +17,7 @@ typedef struct GamepadImage GamepadImage; extern GamepadImage *CreateGamepadImage(SDL_Renderer *renderer); extern void SetGamepadImagePosition(GamepadImage *ctx, int x, int y); extern void SetGamepadImageShowingFront(GamepadImage *ctx, SDL_bool showing_front); +extern void SetGamepadImageReverseDiamond(GamepadImage *ctx, SDL_bool reverse_diamond); extern void SetGamepadImageShowingBattery(GamepadImage *ctx, SDL_bool showing_battery); extern void SetGamepadImageShowingTouchpad(GamepadImage *ctx, SDL_bool showing_touchpad); extern void GetGamepadImageArea(GamepadImage *ctx, int *x, int *y, int *width, int *height);