diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b6e7b724bf..895f885b13 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -89,7 +89,7 @@ if(NOT CMAKE_VERSION VERSION_LESS 3.20) endif() if(DOS) - set(NAME83_LONG "unifont-15.1.05.hex;unifont-15.1.05-license.txt;physaudiodev.png;logaudiodev.png;audiofile.png;soundboard.png;soundboard_levels.png;trashcan.png;msdf_font.png;msdf_font.csv;gamepad_front.png;gamepad_back.png;gamepad_face_abxy.png;gamepad_face_axby.png;gamepad_face_bayx.png;gamepad_face_sony.png;gamepad_battery.png;gamepad_battery_unknown.png;gamepad_battery_wired.png;gamepad_touchpad.png;gamepad_button.png;gamepad_button_small.png;gamepad_button_background.png;gamepad_axis.png;gamepad_axis_arrow.png;gamepad_wired.png;gamepad_wireless.png;sdl-test_round.png") + set(NAME83_LONG "unifont-15.1.05.hex;unifont-15.1.05-license.txt;physaudiodev.png;logaudiodev.png;audiofile.png;soundboard.png;soundboard_levels.png;trashcan.png;msdf_font.png;msdf_font.csv;gamepad_front.png;gamepad_back.png;gamepad_face_abxy.png;gamepad_face_axby.png;gamepad_face_bayx.png;gamepad_face_sony.png;gamepad_battery.png;gamepad_battery_unknown.png;gamepad_battery_wired.png;gamepad_touchpad.png;gamepad_dual_touchpad.png;gamepad_button.png;gamepad_button_small.png;gamepad_button_background.png;gamepad_axis.png;gamepad_axis_arrow.png;gamepad_wired.png;gamepad_wireless.png;sdl-test_round.png") set(DOS83_SHORT "UNIFONT.HEX;UNIFONTL.TXT;PHYSADEV.PNG;LOGADEV.PNG;AUDIOFIL.PNG;SNDBRD.PNG;SNDLVL.PNG;TRASHCAN.PNG;MSDFFONT.PNG;MSDFFONT.CSV;GP_FRONT.PNG;GP_BACK.PNG;GP_FABXY.PNG;GP_FAXBY.PNG;GP_FBAYX.PNG;GP_FSONY.PNG;GP_BATT.PNG;GP_BATTX.PNG;GP_BATTW.PNG;GP_TOUCH.PNG;GP_BTN.PNG;GP_BTNSM.PNG;GP_BTNBG.PNG;GP_AXIS.PNG;GP_AXARW.PNG;GP_WIRED.PNG;GP_WLESS.PNG;SDLROUND.PNG") endif() @@ -296,6 +296,7 @@ files2headers(gamepad_image_headers gamepad_button_background.png gamepad_button.png gamepad_button_small.png + gamepad_dual_touchpad.png gamepad_face_abxy.png gamepad_face_axby.png gamepad_face_bayx.png diff --git a/test/gamepad_dual_touchpad.h b/test/gamepad_dual_touchpad.h new file mode 100644 index 0000000000..39909cc373 --- /dev/null +++ b/test/gamepad_dual_touchpad.h @@ -0,0 +1,57 @@ +unsigned char gamepad_dual_touchpad_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x9f, + 0x08, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x09, 0x91, 0x77, 0x00, 0x00, 0x00, + 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, + 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9, 0x65, 0x3c, 0x00, 0x00, + 0x00, 0x1e, 0x50, 0x4c, 0x54, 0x45, 0x00, 0x00, 0x00, 0x17, 0x17, 0x17, + 0x25, 0x25, 0x25, 0x76, 0x76, 0x76, 0x86, 0x86, 0x86, 0xc3, 0xc3, 0xc3, + 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xff, 0xff, 0xff, + 0x6b, 0xf3, 0x50, 0x72, 0x00, 0x00, 0x01, 0xfb, 0x49, 0x44, 0x41, 0x54, + 0x78, 0xda, 0xec, 0xd5, 0x81, 0x71, 0x03, 0x21, 0x0c, 0x45, 0x41, 0x0e, + 0x01, 0x39, 0xf7, 0xdf, 0x70, 0xe2, 0x16, 0x32, 0x89, 0x2c, 0x5b, 0xfb, + 0x2a, 0xf8, 0xa3, 0x59, 0x86, 0xf1, 0x50, 0xeb, 0x86, 0x13, 0x00, 0x20, + 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, 0x02, 0x40, 0x00, 0x08, 0x00, 0x01, + 0x20, 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, 0x02, 0x40, 0x00, 0x08, 0x00, + 0x01, 0x20, 0x00, 0x04, 0xc0, 0x6f, 0xba, 0x63, 0x24, 0x16, 0x77, 0xe7, + 0xd5, 0x15, 0x01, 0xc4, 0x1c, 0xfb, 0xdc, 0x49, 0x9d, 0x3d, 0x66, 0xf4, + 0x5d, 0x5d, 0x11, 0x40, 0xcc, 0xfd, 0x95, 0xda, 0xfe, 0x8b, 0x5b, 0xbe, + 0xe7, 0xea, 0x8a, 0x00, 0x76, 0xf6, 0x25, 0x9f, 0xb7, 0xdc, 0x3d, 0x57, + 0x97, 0x04, 0x10, 0xeb, 0x64, 0x9f, 0xf2, 0xac, 0xe8, 0xb9, 0xba, 0x24, + 0x80, 0xfc, 0xa7, 0xf4, 0x7c, 0x4c, 0x3d, 0x57, 0x97, 0x04, 0x30, 0x5e, + 0x71, 0xca, 0xd1, 0x73, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xd9, 0x7c, 0xc5, 0x29, 0x67, 0xcf, 0xd5, 0x25, 0x01, + 0xc4, 0xca, 0x3f, 0xe5, 0x8a, 0x9e, 0xab, 0x4b, 0x02, 0x58, 0x91, 0xfe, + 0x98, 0x76, 0xac, 0x9e, 0xab, 0x4b, 0x02, 0x78, 0xcc, 0x75, 0x72, 0x2f, + 0x79, 0xd6, 0xec, 0xba, 0xba, 0x24, 0x80, 0x7d, 0xc5, 0xbe, 0xf3, 0x0e, + 0x79, 0xef, 0xb8, 0x76, 0xd7, 0xd5, 0x25, 0x01, 0xfc, 0x7c, 0xa8, 0xd7, + 0x48, 0xec, 0x8a, 0xce, 0xab, 0x4b, 0x02, 0x50, 0xb9, 0x00, 0x00, 0x40, + 0x00, 0x08, 0x00, 0x01, 0x20, 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, 0x02, + 0x40, 0x00, 0x08, 0x00, 0x01, 0x20, 0x00, 0x04, 0x80, 0x00, 0x10, 0x00, + 0x02, 0x40, 0x00, 0x08, 0x00, 0x7d, 0x46, 0xdf, 0x02, 0x0c, 0x00, 0xeb, + 0x17, 0x39, 0xb7, 0x96, 0x32, 0x99, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; +unsigned int gamepad_dual_touchpad_png_len = 643; diff --git a/test/gamepad_dual_touchpad.png b/test/gamepad_dual_touchpad.png new file mode 100644 index 0000000000..66cbc9da82 Binary files /dev/null and b/test/gamepad_dual_touchpad.png differ diff --git a/test/gamepadutils.c b/test/gamepadutils.c index 2f0fcc55eb..4da9522d16 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -22,6 +22,7 @@ #include "gamepad_battery.h" #include "gamepad_battery_wired.h" #include "gamepad_touchpad.h" +#include "gamepad_dual_touchpad.h" #include "gamepad_button.h" #include "gamepad_button_small.h" #include "gamepad_axis.h" @@ -323,10 +324,18 @@ static const struct { 400, 5, 180.0 }, /* SDL_GAMEPAD_ELEMENT_AXIS_RIGHT_TRIGGER */ }; -static SDL_FRect touchpad_area = { +#define MAX_TOUCHPADS 2 +#define MAX_FINGERS 2 + +static const SDL_FRect touchpad_area = { 148.0f, 20.0f, 216.0f, 118.0f }; +static const SDL_FRect dual_touchpad_area[MAX_TOUCHPADS] = { + {106.0f, 20.0f, 118.0f, 118.0f}, + {288.0f, 20.0f, 118.0f, 118.0f}, +}; + typedef struct { bool down; @@ -335,6 +344,13 @@ typedef struct float pressure; } GamepadTouchpadFinger; +typedef struct +{ + SDL_FRect area; + int num_fingers; + GamepadTouchpadFinger *fingers; +} GamepadTouchpad; + struct GamepadImage { SDL_Renderer *renderer; @@ -347,6 +363,7 @@ struct GamepadImage SDL_Texture *connection_texture[2]; SDL_Texture *battery_texture[2]; SDL_Texture *touchpad_texture; + SDL_Texture *dual_touchpad_texture; SDL_Texture *button_texture; SDL_Texture *axis_texture; float gamepad_width; @@ -359,6 +376,8 @@ struct GamepadImage float battery_height; float touchpad_width; float touchpad_height; + float dual_touchpad_width; + float dual_touchpad_height; float button_width; float button_height; float axis_width; @@ -378,8 +397,8 @@ struct GamepadImage SDL_PowerState battery_state; int battery_percent; - int num_fingers; - GamepadTouchpadFinger *fingers; + int num_touchpads; + GamepadTouchpad *touchpads; }; static SDL_Texture *CreateTexture(SDL_Renderer *renderer, unsigned char *data, unsigned int len) @@ -423,6 +442,9 @@ GamepadImage *CreateGamepadImage(SDL_Renderer *renderer) ctx->touchpad_texture = CreateTexture(renderer, gamepad_touchpad_png, gamepad_touchpad_png_len); SDL_GetTextureSize(ctx->touchpad_texture, &ctx->touchpad_width, &ctx->touchpad_height); + ctx->dual_touchpad_texture = CreateTexture(renderer, gamepad_dual_touchpad_png, gamepad_dual_touchpad_png_len); + SDL_GetTextureSize(ctx->dual_touchpad_texture, &ctx->dual_touchpad_width, &ctx->dual_touchpad_height); + ctx->button_texture = CreateTexture(renderer, gamepad_button_png, gamepad_button_png_len); SDL_GetTextureSize(ctx->button_texture, &ctx->button_width, &ctx->button_height); SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21); @@ -462,17 +484,20 @@ void GetGamepadImageArea(GamepadImage *ctx, SDL_FRect *area) } } -void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area) +void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area, int touchpad) { + int i; + if (!ctx) { SDL_zerop(area); return; } - area->x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2 + touchpad_area.x; - area->y = ctx->y + ctx->gamepad_height + touchpad_area.y; - area->w = touchpad_area.w; - area->h = touchpad_area.h; + i = SDL_clamp(touchpad, 0, MAX_TOUCHPADS - 1); + area->x = ctx->x + (ctx->gamepad_width - ctx->dual_touchpad_width) / 2 + dual_touchpad_area[i].x; + area->y = ctx->y + ctx->gamepad_height + dual_touchpad_area[i].y; + area->w = dual_touchpad_area[i].w; + area->h = dual_touchpad_area[i].h; } void SetGamepadImageShowingFront(GamepadImage *ctx, bool showing_front) @@ -666,6 +691,18 @@ void SetGamepadImageElement(GamepadImage *ctx, int element, bool active) ctx->elements[element] = active; } +static void FreeTouchpads(GamepadImage *ctx) +{ + if (ctx->touchpads) { + for (int i = 0; i < ctx->num_touchpads; ++i) { + SDL_free(ctx->touchpads[i].fingers); + } + SDL_free(ctx->touchpads); + ctx->touchpads = NULL; + ctx->num_touchpads = 0; + } +} + void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) { int i; @@ -726,31 +763,39 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) ctx->connection_state = SDL_GetGamepadConnectionState(gamepad); ctx->battery_state = SDL_GetGamepadPowerInfo(gamepad, &ctx->battery_percent); - if (SDL_GetNumGamepadTouchpads(gamepad) > 0) { - int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, 0); - if (num_fingers != ctx->num_fingers) { - GamepadTouchpadFinger *fingers = (GamepadTouchpadFinger *)SDL_realloc(ctx->fingers, num_fingers * sizeof(*fingers)); - if (fingers) { - ctx->fingers = fingers; - ctx->num_fingers = num_fingers; - } else { - num_fingers = SDL_min(ctx->num_fingers, num_fingers); + FreeTouchpads(ctx); + ctx->num_touchpads = SDL_GetNumGamepadTouchpads(gamepad); + ctx->num_touchpads = SDL_min(ctx->num_touchpads, MAX_TOUCHPADS); + if (ctx->num_touchpads > 0) { + ctx->touchpads = (GamepadTouchpad *)SDL_malloc(sizeof(*ctx->touchpads) * ctx->num_touchpads); + if (ctx->touchpads) { + for (i = 0; i < ctx->num_touchpads; ++i) { + GamepadTouchpad *touchpad = &ctx->touchpads[i]; + touchpad->num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, i); + touchpad->num_fingers = SDL_min(touchpad->num_fingers, MAX_FINGERS); + if (touchpad->num_fingers > 0) { + touchpad->fingers = (GamepadTouchpadFinger *)SDL_malloc(sizeof(*touchpad->fingers) * touchpad->num_fingers); + if (touchpad->fingers) { + for (int j = 0; j < touchpad->num_fingers; ++j) { + GamepadTouchpadFinger *finger = &touchpad->fingers[j]; + SDL_GetGamepadTouchpadFinger(gamepad, i, j, &finger->down, &finger->x, &finger->y, &finger->pressure); + } + } else { + touchpad->num_fingers = 0; + } + } } + if (ctx->num_touchpads == 1) { + SDL_memcpy(&ctx->touchpads[0].area, &touchpad_area, sizeof(SDL_FRect)); + } else { + SDL_memcpy(&ctx->touchpads[0].area, &dual_touchpad_area[0], sizeof(SDL_FRect)); + SDL_memcpy(&ctx->touchpads[1].area, &dual_touchpad_area[1], sizeof(SDL_FRect)); + } + } else { + ctx->num_touchpads = 0; } - for (i = 0; i < num_fingers; ++i) { - GamepadTouchpadFinger *finger = &ctx->fingers[i]; - - SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &finger->down, &finger->x, &finger->y, &finger->pressure); - } - ctx->showing_touchpad = true; - } else { - if (ctx->fingers) { - SDL_free(ctx->fingers); - ctx->fingers = NULL; - ctx->num_fingers = 0; - } - ctx->showing_touchpad = false; } + ctx->showing_touchpad = (ctx->num_touchpads > 0); } void RenderGamepadImage(GamepadImage *ctx) @@ -883,27 +928,39 @@ void RenderGamepadImage(GamepadImage *ctx) } if (ctx->display_mode == CONTROLLER_MODE_TESTING && ctx->showing_touchpad) { - dst.x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2; - dst.y = ctx->y + ctx->gamepad_height; - dst.w = ctx->touchpad_width; - dst.h = ctx->touchpad_height; - SDL_RenderTexture(ctx->renderer, ctx->touchpad_texture, NULL, &dst); + float initial_dst_x; + if (ctx->num_touchpads == 1) { + dst.x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2; + dst.y = ctx->y + ctx->gamepad_height; + dst.w = ctx->touchpad_width; + dst.h = ctx->touchpad_height; + SDL_RenderTexture(ctx->renderer, ctx->touchpad_texture, NULL, &dst); + } else { + dst.x = ctx->x + (ctx->gamepad_width - ctx->dual_touchpad_width) / 2; + dst.y = ctx->y + ctx->gamepad_height; + dst.w = ctx->dual_touchpad_width; + dst.h = ctx->dual_touchpad_height; + SDL_RenderTexture(ctx->renderer, ctx->dual_touchpad_texture, NULL, &dst); + } + initial_dst_x = dst.x; - for (i = 0; i < ctx->num_fingers; ++i) { - GamepadTouchpadFinger *finger = &ctx->fingers[i]; - - if (finger->down) { - dst.x = ctx->x + (ctx->gamepad_width - ctx->touchpad_width) / 2; - dst.x += touchpad_area.x + finger->x * touchpad_area.w; - dst.x -= ctx->button_width / 2; - dst.y = ctx->y + ctx->gamepad_height; - dst.y += touchpad_area.y + finger->y * touchpad_area.h; - dst.y -= ctx->button_height / 2; - dst.w = ctx->button_width; - dst.h = ctx->button_height; - SDL_SetTextureAlphaMod(ctx->button_texture, (Uint8)(finger->pressure * SDL_ALPHA_OPAQUE)); - SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); - SDL_SetTextureAlphaMod(ctx->button_texture, SDL_ALPHA_OPAQUE); + for (i = 0; i < ctx->num_touchpads; ++i) { + GamepadTouchpad *touchpad = &ctx->touchpads[i]; + for (int j = 0; j < touchpad->num_fingers; ++j) { + GamepadTouchpadFinger *finger = &touchpad->fingers[j]; + if (finger->down) { + dst.x = initial_dst_x; + dst.x += touchpad->area.x + finger->x * touchpad->area.w; + dst.x -= ctx->button_width / 2; + dst.y = ctx->y + ctx->gamepad_height; + dst.y += touchpad->area.y + finger->y * touchpad->area.h; + dst.y -= ctx->button_height / 2; + dst.w = ctx->button_width; + dst.h = ctx->button_height; + SDL_SetTextureAlphaMod(ctx->button_texture, (Uint8)(finger->pressure * SDL_ALPHA_OPAQUE)); + SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); + SDL_SetTextureAlphaMod(ctx->button_texture, SDL_ALPHA_OPAQUE); + } } } } @@ -924,9 +981,10 @@ void DestroyGamepadImage(GamepadImage *ctx) SDL_DestroyTexture(ctx->battery_texture[i]); } SDL_DestroyTexture(ctx->touchpad_texture); + SDL_DestroyTexture(ctx->dual_touchpad_texture); SDL_DestroyTexture(ctx->button_texture); SDL_DestroyTexture(ctx->axis_texture); - SDL_free(ctx->fingers); + FreeTouchpads(ctx); SDL_free(ctx); } } @@ -1615,37 +1673,40 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad) } if (ctx->display_mode == CONTROLLER_MODE_TESTING) { - if (SDL_GetNumGamepadTouchpads(gamepad) > 0) { - int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, 0); - for (i = 0; i < num_fingers; ++i) { - bool down; - float finger_x, finger_y, finger_pressure; + int num_touchpads = SDL_GetNumGamepadTouchpads(gamepad); + if (num_touchpads > 0) { + for (i = 0; i < num_touchpads; ++i) { + int num_fingers = SDL_GetNumGamepadTouchpadFingers(gamepad, i); + for (int j = 0; j < num_fingers; ++j) { + bool down; + float finger_x, finger_y, finger_pressure; - if (!SDL_GetGamepadTouchpadFinger(gamepad, 0, i, &down, &finger_x, &finger_y, &finger_pressure)) { - continue; + if (!SDL_GetGamepadTouchpadFinger(gamepad, i, j, &down, &finger_x, &finger_y, &finger_pressure)) { + continue; + } + + SDL_snprintf(text, sizeof(text), "Pad %d Finger %d:", i, j); + SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text); + + if (down) { + SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21); + } else { + SDL_SetTextureColorMod(ctx->button_texture, 255, 255, 255); + } + + dst.x = x + center + 2.0f; + dst.y = y + FONT_CHARACTER_SIZE / 2 - ctx->button_height / 2; + dst.w = ctx->button_width; + dst.h = ctx->button_height; + SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); + + if (down) { + SDL_snprintf(text, sizeof(text), "(%.2f,%.2f)", finger_x, finger_y); + SDLTest_DrawString(ctx->renderer, x + center + ctx->button_width + 4.0f, y, text); + } + + y += ctx->button_height + 2.0f; } - - SDL_snprintf(text, sizeof(text), "Touch finger %d:", i); - SDLTest_DrawString(ctx->renderer, x + center - SDL_strlen(text) * FONT_CHARACTER_SIZE, y, text); - - if (down) { - SDL_SetTextureColorMod(ctx->button_texture, 10, 255, 21); - } else { - SDL_SetTextureColorMod(ctx->button_texture, 255, 255, 255); - } - - dst.x = x + center + 2.0f; - dst.y = y + FONT_CHARACTER_SIZE / 2 - ctx->button_height / 2; - dst.w = ctx->button_width; - dst.h = ctx->button_height; - SDL_RenderTexture(ctx->renderer, ctx->button_texture, NULL, &dst); - - if (down) { - SDL_snprintf(text, sizeof(text), "(%.2f,%.2f)", finger_x, finger_y); - SDLTest_DrawString(ctx->renderer, x + center + ctx->button_width + 4.0f, y, text); - } - - y += ctx->button_height + 2.0f; } } diff --git a/test/gamepadutils.h b/test/gamepadutils.h index d2ee1a7758..503238afe1 100644 --- a/test/gamepadutils.h +++ b/test/gamepadutils.h @@ -69,7 +69,7 @@ enum extern GamepadImage *CreateGamepadImage(SDL_Renderer *renderer); extern void SetGamepadImagePosition(GamepadImage *ctx, float x, float y); extern void GetGamepadImageArea(GamepadImage *ctx, SDL_FRect *area); -extern void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area); +extern void GetGamepadTouchpadArea(GamepadImage *ctx, SDL_FRect *area, int touchpad); extern void SetGamepadImageShowingFront(GamepadImage *ctx, bool showing_front); extern SDL_GamepadType GetGamepadImageType(GamepadImage *ctx); extern void SetGamepadImageDisplayMode(GamepadImage *ctx, ControllerDisplayMode display_mode); diff --git a/test/testcontroller.c b/test/testcontroller.c index a0fee1c811..d6276d97e7 100644 --- a/test/testcontroller.c +++ b/test/testcontroller.c @@ -33,7 +33,7 @@ #define PANEL_SPACING 25.0f #define PANEL_WIDTH 250.0f #define GAMEPAD_WIDTH 512.0f -#define GAMEPAD_HEIGHT 560.0f +#define GAMEPAD_HEIGHT 596.0f #define BUTTON_MARGIN 16.0f #define SCREEN_WIDTH (PANEL_WIDTH + PANEL_SPACING + GAMEPAD_WIDTH + PANEL_SPACING + PANEL_WIDTH) #define SCREEN_HEIGHT (TITLE_HEIGHT + GAMEPAD_HEIGHT) @@ -378,9 +378,16 @@ static SDL_GamepadAxis virtual_axis_active = SDL_GAMEPAD_AXIS_INVALID; static float virtual_axis_start_x; static float virtual_axis_start_y; static SDL_GamepadButton virtual_button_active = SDL_GAMEPAD_BUTTON_INVALID; -static bool virtual_touchpad_active = false; -static float virtual_touchpad_x; -static float virtual_touchpad_y; + +typedef struct +{ + bool active; + float x; + float y; +} VirtualTouchpad; + +#define MAX_VIRTUAL_TOUCHPADS 2 +static VirtualTouchpad virtual_touchpad[MAX_VIRTUAL_TOUCHPADS]; static int s_arrBindingOrder[] = { /* Standard sequence */ @@ -1585,7 +1592,10 @@ static bool SDLCALL VirtualGamepadSetLED(void *userdata, Uint8 red, Uint8 green, static void OpenVirtualGamepad(void) { - SDL_VirtualJoystickTouchpadDesc virtual_touchpad = { 1, { 0, 0, 0 } }; + SDL_VirtualJoystickTouchpadDesc virtual_touchpad_desc[MAX_VIRTUAL_TOUCHPADS] = { + { 1, { 0, 0, 0 } }, + { 1, { 0, 0, 0 } } + }; SDL_VirtualJoystickSensorDesc virtual_sensors[] = { { SDL_SENSOR_ACCEL, 0.0f }, { SDL_SENSOR_GYRO, 0.0f } @@ -1601,8 +1611,8 @@ static void OpenVirtualGamepad(void) desc.type = SDL_JOYSTICK_TYPE_GAMEPAD; desc.naxes = SDL_GAMEPAD_AXIS_COUNT; desc.nbuttons = SDL_GAMEPAD_BUTTON_COUNT; - desc.ntouchpads = 1; - desc.touchpads = &virtual_touchpad; + desc.ntouchpads = MAX_VIRTUAL_TOUCHPADS; + desc.touchpads = virtual_touchpad_desc; desc.nsensors = SDL_arraysize(virtual_sensors); desc.sensors = virtual_sensors; desc.SetPlayerIndex = VirtualGamepadSetPlayerIndex; @@ -1681,12 +1691,14 @@ static void VirtualGamepadMouseMotion(float x, float y) } } - if (virtual_touchpad_active) { - SDL_FRect touchpad; - GetGamepadTouchpadArea(image, &touchpad); - virtual_touchpad_x = (x - touchpad.x) / touchpad.w; - virtual_touchpad_y = (y - touchpad.y) / touchpad.h; - SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, true, virtual_touchpad_x, virtual_touchpad_y, 1.0f); + for (int i = 0; i < MAX_VIRTUAL_TOUCHPADS; ++i) { + if (virtual_touchpad[i].active) { + SDL_FRect touchpad; + GetGamepadTouchpadArea(image, &touchpad, i); + virtual_touchpad[i].x = (x - touchpad.x) / touchpad.w; + virtual_touchpad[i].y = (y - touchpad.y) / touchpad.h; + SDL_SetJoystickVirtualTouchpad(virtual_joystick, i, 0, true, virtual_touchpad[i].x, virtual_touchpad[i].y, 1.0f); + } } } @@ -1695,16 +1707,18 @@ static void VirtualGamepadMouseDown(float x, float y) int element = GetGamepadImageElementAt(image, x, y); if (element == SDL_GAMEPAD_ELEMENT_INVALID) { - SDL_FPoint point; - point.x = x; - point.y = y; - SDL_FRect touchpad; - GetGamepadTouchpadArea(image, &touchpad); - if (SDL_PointInRectFloat(&point, &touchpad)) { - virtual_touchpad_active = true; - virtual_touchpad_x = (x - touchpad.x) / touchpad.w; - virtual_touchpad_y = (y - touchpad.y) / touchpad.h; - SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, true, virtual_touchpad_x, virtual_touchpad_y, 1.0f); + for (int i = 0; i < MAX_VIRTUAL_TOUCHPADS; ++i) { + SDL_FPoint point; + point.x = x; + point.y = y; + SDL_FRect touchpad; + GetGamepadTouchpadArea(image, &touchpad, i); + if (SDL_PointInRectFloat(&point, &touchpad)) { + virtual_touchpad[i].active = true; + virtual_touchpad[i].x = (x - touchpad.x) / touchpad.w; + virtual_touchpad[i].y = (y - touchpad.y) / touchpad.h; + SDL_SetJoystickVirtualTouchpad(virtual_joystick, i, 0, true, virtual_touchpad[i].x, virtual_touchpad[i].y, 1.0f); + } } return; } @@ -1756,9 +1770,11 @@ static void VirtualGamepadMouseUp(float x, float y) virtual_axis_active = SDL_GAMEPAD_AXIS_INVALID; } - if (virtual_touchpad_active) { - SDL_SetJoystickVirtualTouchpad(virtual_joystick, 0, 0, false, virtual_touchpad_x, virtual_touchpad_y, 0.0f); - virtual_touchpad_active = false; + for (int i = 0; i < MAX_VIRTUAL_TOUCHPADS; ++i) { + if (virtual_touchpad[i].active) { + SDL_SetJoystickVirtualTouchpad(virtual_joystick, i, 0, false, virtual_touchpad[i].x, virtual_touchpad[i].y, 0.0f); + virtual_touchpad[i].active = false; + } } } diff --git a/test/testutils.c b/test/testutils.c index d828bb49a5..99f18831e9 100644 --- a/test/testutils.c +++ b/test/testutils.c @@ -39,6 +39,7 @@ static const struct { "gamepad_battery_unknown.png", "GP_BATTX.PNG" }, { "gamepad_battery_wired.png", "GP_BATTW.PNG" }, { "gamepad_touchpad.png", "GP_TOUCH.PNG" }, + { "gamepad_dual_touchpad.png", "GP_DUALT.PNG" }, { "gamepad_button.png", "GP_BTN.PNG" }, { "gamepad_button_small.png", "GP_BTNSM.PNG" }, { "gamepad_button_background.png", "GP_BTNBG.PNG" },