sdvx: fix touchscreen and API touch in landscape mode (#859)

## Link to GitHub Issue or related Pull Request, if one exists
Fixes #858 

## Description of change
Landscape mode needs another adjustment applied to touch coordinates.

This fixex both native touch and wintouchemu paths.

## Testing
Tested landscape, also with full screen resolution changes.
This commit is contained in:
bicarus
2026-08-08 16:22:29 -07:00
committed by GitHub
parent baa550037a
commit 2386047c2f
2 changed files with 33 additions and 5 deletions
+6 -5
View File
@@ -55,9 +55,10 @@ namespace api::modules {
native_canvas_w = 0; native_canvas_w = 0;
native_canvas_h = 0; native_canvas_h = 0;
if (is_sdvx) { if (is_sdvx) {
// exceed gear subscreen, portrait after the rotation applied in apply_touch_errata // landscape API coordinates already match the primary screen orientation;
native_canvas_w = 1080; // portrait coordinates are rotated by apply_touch_errata
native_canvas_h = 1920; native_canvas_w = GRAPHICS_FS_ORIENTATION_SWAP ? 1920 : 1080;
native_canvas_h = GRAPHICS_FS_ORIENTATION_SWAP ? 1080 : 1920;
} else if (avs::game::is_model("LDJ")) { } else if (avs::game::is_model("LDJ")) {
// TDJ subscreen; FHD models are upscaled to 1080p by apply_touch_errata // TDJ subscreen; FHD models are upscaled to 1080p by apply_touch_errata
native_canvas_w = is_tdj_fhd ? 1920 : 1280; native_canvas_w = is_tdj_fhd ? 1920 : 1280;
@@ -218,8 +219,8 @@ namespace api::modules {
// the target of the touch events so just assume it's the sub screen // the target of the touch events so just assume it's the sub screen
x = x_raw * 1920 / 1280; x = x_raw * 1920 / 1280;
y = y_raw * 1080 / 720; y = y_raw * 1080 / 720;
} else if (is_sdvx) { } else if (is_sdvx && !GRAPHICS_FS_ORIENTATION_SWAP) {
// for exceed gear, they are both 1080p screens, but need to apply transformation // rotate API coordinates into SDVX's portrait touch space
x = 1080 - y_raw; x = 1080 - y_raw;
y = x_raw; y = x_raw;
} }
+27
View File
@@ -1,5 +1,6 @@
#include "transform.h" #include "transform.h"
#include "avs/game.h"
#include "hooks/graphics/graphics.h" #include "hooks/graphics/graphics.h"
#include "overlay/overlay.h" #include "overlay/overlay.h"
#include "settings.h" #include "settings.h"
@@ -82,6 +83,25 @@ namespace nativetouch::transform {
return overlay::OVERLAY->transform_touch_point(&position->x, &position->y); return overlay::OVERLAY->transform_touch_point(&position->x, &position->y);
} }
// the digitizer is mapped to the zero-based primary display, while SDVX
// still expects portrait coordinates when its image is rendered in landscape:
// (x, y) -> (width * (1 - y / height), height * x / width).
static bool transform_sdvx_landscape_touch_position(POINT *position) {
const auto landscape_width = static_cast<LONG>(GRAPHICS_FS_CUSTOM_RESOLUTION.has_value() ?
GRAPHICS_FS_CUSTOM_RESOLUTION.value().first : GRAPHICS_FS_ORIGINAL_HEIGHT);
const auto landscape_height = static_cast<LONG>(GRAPHICS_FS_CUSTOM_RESOLUTION.has_value() ?
GRAPHICS_FS_CUSTOM_RESOLUTION.value().second : GRAPHICS_FS_ORIGINAL_WIDTH);
if (landscape_width <= 0 || landscape_height <= 0) {
return false;
}
const auto input_x = position->x;
position->x = landscape_width -
MulDiv(position->y, landscape_width, landscape_height);
position->y = MulDiv(input_x, landscape_height, landscape_width);
return true;
}
// convert physical screen coordinates to game touch coordinates for a known target // convert physical screen coordinates to game touch coordinates for a known target
bool screen_to_game(HWND window, POINT *position) { bool screen_to_game(HWND window, POINT *position) {
if (settings::SYNTHETIC_TOUCH_USES_CLIENT_COORDINATES) { if (settings::SYNTHETIC_TOUCH_USES_CLIENT_COORDINATES) {
@@ -144,6 +164,13 @@ namespace nativetouch::transform {
const auto dedicated_subscreen = is_tdj_dedicated_subscreen(TDJ_SUBSCREEN_WINDOW); const auto dedicated_subscreen = is_tdj_dedicated_subscreen(TDJ_SUBSCREEN_WINDOW);
const auto active_overlay = has_active_overlay_transform(); const auto active_overlay = has_active_overlay_transform();
// special case for SDVX landscape mode
if (!dedicated_subscreen && !active_overlay &&
GRAPHICS_FS_ORIENTATION_SWAP && avs::game::is_model("KFC")) {
return transform_sdvx_landscape_touch_position(position) ?
Result::Transformed : Result::Rejected;
}
// no dedicated subscreen or active overlay mapping; pass the point through unchanged // no dedicated subscreen or active overlay mapping; pass the point through unchanged
if (!dedicated_subscreen && !active_overlay) { if (!dedicated_subscreen && !active_overlay) {
return Result::Unchanged; return Result::Unchanged;