From c02f8e91b6e8a2e3bc2fcb05bcbab0f7cca4024e Mon Sep 17 00:00:00 2001 From: Dragomir Ivanov Date: Mon, 31 Jan 2022 00:00:26 +0200 Subject: [PATCH] fshack: Add faking current resolution ability --- .../65-proton-fake_current_res_patches.patch | 106 ++++++++++++++++++ patches/protonprep.sh | 4 + 2 files changed, 110 insertions(+) create mode 100644 patches/proton/65-proton-fake_current_res_patches.patch diff --git a/patches/proton/65-proton-fake_current_res_patches.patch b/patches/proton/65-proton-fake_current_res_patches.patch new file mode 100644 index 0000000000..0f836fca11 --- /dev/null +++ b/patches/proton/65-proton-fake_current_res_patches.patch @@ -0,0 +1,106 @@ +From c6d0490250dbc6783618326429b0e4e819bc3cc2 Mon Sep 17 00:00:00 2001 +From: Dragomir Ivanov +Date: Sun, 30 Jan 2022 23:47:56 +0200 +Subject: [PATCH] FSR: Add fshack faking current resolution ability + +--- + dlls/winex11.drv/fs.c | 55 +++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 50 insertions(+), 5 deletions(-) + +diff --git a/dlls/winex11.drv/fs.c b/dlls/winex11.drv/fs.c +index 9b781a729e5..0c8db02f06c 100644 +--- a/dlls/winex11.drv/fs.c ++++ b/dlls/winex11.drv/fs.c +@@ -95,6 +95,8 @@ static struct fs_monitor_size fs_monitor_sizes[] = + {1280, 1024}, /* 5:4 */ + }; + ++static struct fs_monitor_size fake_current_resolution; ++ + /* A fake monitor for the fullscreen hack */ + struct fs_monitor + { +@@ -249,13 +251,30 @@ static BOOL fs_monitor_add_modes(struct fs_monitor *fs_monitor) + return TRUE; + } + ++BOOL fs_hack_is_fake_current_res(struct fs_monitor_size* fixed_size) ++{ ++ fixed_size->width = 0; ++ fixed_size->height = 0; ++ const char *e = getenv("WINE_FULLSCREEN_FAKE_CURRENT_RES"); ++ if (e) ++ { ++ const int n = sscanf(e,"%dx%d",&(fixed_size->width),&(fixed_size->height)); ++ if (n==2) ++ { ++ return TRUE; ++ } ++ } ++ return FALSE; ++} ++ + /* Add a fake monitor to fs_monitors list. + * Call this function with fs_section entered */ + static BOOL fs_add_monitor(const WCHAR *device_name) + { + struct fs_monitor *fs_monitor; +- DEVMODEW real_mode; ++ DEVMODEW real_mode, user_mode; + ULONG_PTR real_id; ++ double scale; + + if (!real_settings_handler.get_id(device_name, &real_id)) + return FALSE; +@@ -266,11 +285,33 @@ static BOOL fs_add_monitor(const WCHAR *device_name) + if (!(fs_monitor = malloc(sizeof(*fs_monitor)))) + return FALSE; + +- fs_monitor->user_mode = real_mode; ++ user_mode = real_mode; ++ ++ if (fs_hack_is_fake_current_res(&fake_current_resolution)) { ++ user_mode.dmPelsWidth = fake_current_resolution.width; ++ user_mode.dmPelsHeight = fake_current_resolution.height; ++ TRACE("is_fake_current_res: %dx%d", fake_current_resolution.width, fake_current_resolution.height); ++ } ++ ++ fs_monitor->user_mode = user_mode; + fs_monitor->real_mode = real_mode; +- fs_monitor->user_to_real_scale = 1.0; +- fs_monitor->top_left.x = real_mode.u1.s2.dmPosition.x; +- fs_monitor->top_left.y = real_mode.u1.s2.dmPosition.y; ++ /* If real mode is narrower than fake mode, scale to fit width */ ++ if ((double)real_mode.dmPelsWidth / (double)real_mode.dmPelsHeight ++ < (double)user_mode.dmPelsWidth / (double)user_mode.dmPelsHeight) ++ { ++ scale = (double)real_mode.dmPelsWidth / (double)user_mode.dmPelsWidth; ++ fs_monitor->user_to_real_scale = scale; ++ fs_monitor->top_left.x = real_mode.u1.s2.dmPosition.x; ++ fs_monitor->top_left.y = real_mode.u1.s2.dmPosition.y + (real_mode.dmPelsHeight - user_mode.dmPelsHeight * scale) / 2; ++ } ++ /* Else scale to fit height */ ++ else ++ { ++ scale = (double)real_mode.dmPelsHeight / (double)user_mode.dmPelsHeight; ++ fs_monitor->user_to_real_scale = scale; ++ fs_monitor->top_left.x = real_mode.u1.s2.dmPosition.x + (real_mode.dmPelsWidth - user_mode.dmPelsWidth * scale) / 2; ++ fs_monitor->top_left.y = real_mode.u1.s2.dmPosition.y; ++ } + lstrcpyW(fs_monitor->user_mode.dmDeviceName, device_name); + if (!fs_monitor_add_modes(fs_monitor)) + { +@@ -373,6 +414,10 @@ static BOOL fs_get_current_mode(ULONG_PTR id, DEVMODEW *mode) + if (fs_monitor) + { + *mode = fs_monitor->user_mode; ++ if (fake_current_resolution.width != 0 && fake_current_resolution.height != 0) { ++ mode->dmPelsWidth=fake_current_resolution.width; ++ mode->dmPelsHeight=fake_current_resolution.height; ++ } + LeaveCriticalSection(&fs_section); + return TRUE; + } +-- +2.30.2 + diff --git a/patches/protonprep.sh b/patches/protonprep.sh index 87d0661294..4eb2d32413 100755 --- a/patches/protonprep.sh +++ b/patches/protonprep.sh @@ -337,6 +337,10 @@ echo "proton battleye patches" patch -Np1 < ../patches/proton/59-proton-battleye_patches.patch + echo "proton fake current res patches" + patch -Np1 < ../patches/proton/65-proton-fake_current_res_patches.patch + + # disabled for now, needs rebase. only used for vr anyway # echo "proton openxr patches" # patch -Np1 < ../patches/proton/37-proton-OpenXR-patches.patch