mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 14:50:41 -07:00
sdvx: landscape mode (#277)
## Link to GitHub Issue, if one exists n/a ## Description of change Add `SDVX Landscape Mode` option, allowing you to play SDVX in landscape monitor orientation, with black borders on left and right - similar to how EAC does it. This is meant to be an alternative to what people do today, which is launching in windowed mode. By default, with just `-sdvxlandscape` enabled, EG will launch at 1920x1080 (transposed from the original 1080x1920 resolution). It is possible to combine with `-forceres` to launch at higher resolutions. At some point though, when rendering at large resolutions past 1440p, at some point scaling may break due to #276. Disabled on 32-bit SDVX since dx9 `CreateDeviceEx` call is required; `CreateDevice` won't work. For the same reason this isn't being made a generic option for museca/rb/etc. In theory you can supply `-sdvxlandscape` to games like IIDX and play landscape games in portrait mode, although again, scaling my break due to #276. Also, add new options (bottomleft/right) for subscreen overlay position so that they don't overlap with the main screen in landscape mode. ## Compiling 🙂 ## Testing Tested a couple versions of VW and EG.
This commit is contained in:
@@ -853,9 +853,13 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDeviceEx(
|
||||
for (size_t i = 0; i < num_adapters; i++) {
|
||||
auto *params = &pPresentationParameters[i];
|
||||
|
||||
if (!GRAPHICS_WINDOWED && i == 0 && GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
||||
params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
||||
params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
||||
if (!GRAPHICS_WINDOWED && i == 0) {
|
||||
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
||||
params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
||||
params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
||||
} else if (GRAPHICS_FS_FORCE_LANDSCAPE) {
|
||||
std::swap(params->BackBufferWidth, params->BackBufferHeight);
|
||||
}
|
||||
}
|
||||
|
||||
log_info("graphics::d3d9",
|
||||
@@ -882,10 +886,15 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDeviceEx(
|
||||
for (size_t i = 0; i < num_adapters; i++) {
|
||||
auto *fullscreen_display_mode = &pFullscreenDisplayMode[i];
|
||||
|
||||
if (!GRAPHICS_WINDOWED && i == 0 && GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
||||
fullscreen_display_mode->Width = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
||||
fullscreen_display_mode->Height = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
||||
if (!GRAPHICS_WINDOWED && i == 0) {
|
||||
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
||||
fullscreen_display_mode->Width = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
||||
fullscreen_display_mode->Height = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
||||
} else if (GRAPHICS_FS_FORCE_LANDSCAPE) {
|
||||
std::swap(fullscreen_display_mode->Width, fullscreen_display_mode->Height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log_info("graphics::d3d9",
|
||||
"D3D9Ex fullscreen display mode for adapter {}: Width: {}, Height: {}, RefreshRate: {}, "
|
||||
|
||||
@@ -718,7 +718,37 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
|
||||
const int rectTop = 576;
|
||||
const int w = param.BackBufferWidth;
|
||||
const int h = param.BackBufferHeight;
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
HRESULT hr;
|
||||
topSurface->LockRect(&rect, NULL, D3DLOCK_DONOTWAIT);
|
||||
if (GRAPHICS_FS_FORCE_LANDSCAPE) {
|
||||
const int w_new = h * 9 / 16;
|
||||
const int x_new = rectLeft + ((w - w_new) / 2);
|
||||
RECT originRect {
|
||||
x_new,
|
||||
rectTop,
|
||||
(LONG)(x_new + w_new),
|
||||
(LONG)(rectTop + h),
|
||||
};
|
||||
hr = pReal->StretchRect(
|
||||
backbuffer, nullptr,
|
||||
topSurface, &originRect,
|
||||
D3DTEXF_LINEAR);
|
||||
if (hr != D3D_OK) {
|
||||
log_misc("graphics::d3d9", "StretchRect backbuffer failed (forced landscape)");
|
||||
}
|
||||
} else {
|
||||
// stretch to add top/left offset to avoid going negative
|
||||
hr = pReal->StretchRect(
|
||||
backbuffer, nullptr,
|
||||
topSurface, nullptr,
|
||||
D3DTEXF_LINEAR);
|
||||
if (hr != D3D_OK) {
|
||||
log_misc("graphics::d3d9", "StretchRect backbuffer failed");
|
||||
}
|
||||
}
|
||||
topSurface->UnlockRect();
|
||||
|
||||
RECT targetRect {
|
||||
rectLeft,
|
||||
@@ -727,44 +757,38 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
|
||||
(LONG)(rectTop + h),
|
||||
};
|
||||
|
||||
// stretch to add top/left offset to avoid going negative
|
||||
topSurface->LockRect(&rect, NULL, D3DLOCK_DONOTWAIT);
|
||||
auto hr = pReal->StretchRect(
|
||||
backbuffer, nullptr,
|
||||
topSurface, &targetRect,
|
||||
D3DTEXF_LINEAR);
|
||||
|
||||
if (hr != D3D_OK) {
|
||||
log_misc("graphics::d3d9", "StretchRect backbuffer failed");
|
||||
}
|
||||
topSurface->UnlockRect();
|
||||
|
||||
// do the actual zoom / offset math
|
||||
auto& scene = cfg::SCREENRESIZE->scene_settings[cfg::SCREENRESIZE->screen_resize_current_scene];
|
||||
if (scene.centered) {
|
||||
targetRect.right = (w + rectLeft) / scene.scale_x;
|
||||
targetRect.bottom = (h + rectTop) / scene.scale_y;
|
||||
const LONG deltaH = ((targetRect.bottom - targetRect.top) - h) / 2;
|
||||
const LONG deltaW = ((targetRect.right - targetRect.left) - w) / 2;
|
||||
targetRect.top -= deltaH;
|
||||
targetRect.bottom -= deltaH;
|
||||
targetRect.left -= deltaW;
|
||||
targetRect.right -= deltaW;
|
||||
} else {
|
||||
targetRect.left -= scene.offset_x;
|
||||
targetRect.top += scene.offset_y;
|
||||
targetRect.right = -scene.offset_x;
|
||||
targetRect.right += (w + rectLeft) / scene.scale_x;
|
||||
targetRect.bottom = scene.offset_y;
|
||||
targetRect.bottom += (h + rectTop) / scene.scale_y;
|
||||
if (cfg::SCREENRESIZE->enable_screen_resize) {
|
||||
auto& scene = cfg::SCREENRESIZE->scene_settings[cfg::SCREENRESIZE->screen_resize_current_scene];
|
||||
if (scene.centered) {
|
||||
targetRect.right = (w + rectLeft) / scene.scale_x;
|
||||
targetRect.bottom = (h + rectTop) / scene.scale_y;
|
||||
const LONG deltaH = ((targetRect.bottom - targetRect.top) - h) / 2;
|
||||
const LONG deltaW = ((targetRect.right - targetRect.left) - w) / 2;
|
||||
targetRect.top -= deltaH;
|
||||
targetRect.bottom -= deltaH;
|
||||
targetRect.left -= deltaW;
|
||||
targetRect.right -= deltaW;
|
||||
} else {
|
||||
targetRect.left -= scene.offset_x;
|
||||
targetRect.top += scene.offset_y;
|
||||
targetRect.right = -scene.offset_x;
|
||||
targetRect.right += (w + rectLeft) / scene.scale_x;
|
||||
targetRect.bottom = scene.offset_y;
|
||||
targetRect.bottom += (h + rectTop) / scene.scale_y;
|
||||
}
|
||||
}
|
||||
|
||||
// draw to back buffer
|
||||
backbuffer->LockRect(&rect, NULL, D3DLOCK_DONOTWAIT);
|
||||
bool use_linear_filter = true;
|
||||
if (cfg::SCREENRESIZE->enable_screen_resize) {
|
||||
use_linear_filter = cfg::SCREENRESIZE->enable_linear_filter;
|
||||
}
|
||||
hr = pReal->StretchRect(
|
||||
topSurface, &targetRect,
|
||||
backbuffer, nullptr,
|
||||
cfg::SCREENRESIZE->enable_linear_filter ? D3DTEXF_LINEAR : D3DTEXF_NONE);
|
||||
use_linear_filter ? D3DTEXF_LINEAR : D3DTEXF_NONE);
|
||||
backbuffer->UnlockRect();
|
||||
if (hr != D3D_OK) {
|
||||
log_misc("graphics::d3d9", "StretchRect targetRect failed");
|
||||
@@ -774,7 +798,7 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDirect3DDevice9::EndScene() {
|
||||
WRAP_DEBUG;
|
||||
|
||||
if (cfg::SCREENRESIZE->enable_screen_resize) {
|
||||
if (cfg::SCREENRESIZE->enable_screen_resize || GRAPHICS_FS_FORCE_LANDSCAPE) {
|
||||
SurfaceHook(pReal);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user