diff --git a/src/spice2x/cfg/screen_resize.cpp b/src/spice2x/cfg/screen_resize.cpp index 10956e8..d31040c 100644 --- a/src/spice2x/cfg/screen_resize.cpp +++ b/src/spice2x/cfg/screen_resize.cpp @@ -81,16 +81,12 @@ namespace cfg { load_bool_value(doc, root + "enable_linear_filter", this->enable_linear_filter); for (size_t i = 0; i < std::size(this->scene_settings); i++) { auto& scene = this->scene_settings[i]; - std::string prefix = ""; - if (0 < i) { - prefix += fmt::format("scenes/{}/", i-1); - } + const std::string prefix = fmt::format("scenes/{}/", i); load_int_value(doc, root + prefix + "offset_x", scene.offset_x); load_int_value(doc, root + prefix + "offset_y", scene.offset_y); load_float_value(doc, root + prefix + "scale_x", scene.scale_x); load_float_value(doc, root + prefix + "scale_y", scene.scale_y); load_bool_value(doc, root + prefix + "keep_aspect_ratio", scene.keep_aspect_ratio); - load_bool_value(doc, root + prefix + "centered", scene.centered); } // windowed settings are always under game settings @@ -201,16 +197,12 @@ namespace cfg { rapidjson::Pointer(root + "enable_linear_filter").Set(doc, this->enable_linear_filter); for (size_t i = 0; i < std::size(this->scene_settings); i++) { auto& scene = this->scene_settings[i]; - std::string prefix = ""; - if (0 < i) { - prefix += fmt::format("scenes/{}/", i-1); - } + const std::string prefix = fmt::format("scenes/{}/", i); rapidjson::Pointer(root + prefix + "offset_x").Set(doc, scene.offset_x); rapidjson::Pointer(root + prefix + "offset_y").Set(doc, scene.offset_y); rapidjson::Pointer(root + prefix + "scale_x").Set(doc, scene.scale_x); rapidjson::Pointer(root + prefix + "scale_y").Set(doc, scene.scale_y); rapidjson::Pointer(root + prefix + "keep_aspect_ratio").Set(doc, scene.keep_aspect_ratio); - rapidjson::Pointer(root + prefix + "centered").Set(doc, scene.centered); } // windowed mode settings diff --git a/src/spice2x/cfg/screen_resize.h b/src/spice2x/cfg/screen_resize.h index 103ae77..dd60cc6 100644 --- a/src/spice2x/cfg/screen_resize.h +++ b/src/spice2x/cfg/screen_resize.h @@ -20,7 +20,6 @@ namespace cfg { float scale_x = 1.0; float scale_y = 1.0; bool keep_aspect_ratio = true; - bool centered = true; }; extern std::optional SCREEN_RESIZE_CFG_PATH_OVERRIDE; diff --git a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp index 9ce8916..bf88b88 100644 --- a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp +++ b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_backend.cpp @@ -681,10 +681,27 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDevice( // dump presentation parameters 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) { + GRAPHICS_FS_ORIGINAL_WIDTH = params->BackBufferWidth; + GRAPHICS_FS_ORIGINAL_HEIGHT = params->BackBufferHeight; + log_misc("graphics::d3d9", "original resolution: {}x{}", GRAPHICS_FS_ORIGINAL_WIDTH, GRAPHICS_FS_ORIGINAL_HEIGHT); + if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) { + log_misc( + "graphics::d3d9", + "use custom resolution {}x{} => {}x{}", + params->BackBufferWidth, params->BackBufferHeight, + GRAPHICS_FS_CUSTOM_RESOLUTION.value().first, + GRAPHICS_FS_CUSTOM_RESOLUTION.value().second); + params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first; + params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second; + } else if (GRAPHICS_FS_ORIENTATION_SWAP) { + log_misc( + "graphics::d3d9", + "swap full orientation {}x{} => {}x{}", + params->BackBufferWidth, params->BackBufferHeight, + params->BackBufferHeight, params->BackBufferWidth); + std::swap(params->BackBufferWidth, params->BackBufferHeight); + } } log_info("graphics::d3d9", @@ -852,12 +869,25 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDeviceEx( for (size_t i = 0; i < num_adapters; i++) { auto *params = &pPresentationParameters[i]; - if (!GRAPHICS_WINDOWED && i == 0) { + GRAPHICS_FS_ORIGINAL_WIDTH = params->BackBufferWidth; + GRAPHICS_FS_ORIGINAL_HEIGHT = params->BackBufferHeight; + log_misc("graphics::d3d9", "original resolution: {}x{}", GRAPHICS_FS_ORIGINAL_WIDTH, GRAPHICS_FS_ORIGINAL_HEIGHT); if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) { + log_misc( + "graphics::d3d9", + "use custom resolution {}x{} => {}x{}", + params->BackBufferWidth, params->BackBufferHeight, + GRAPHICS_FS_CUSTOM_RESOLUTION.value().first, + GRAPHICS_FS_CUSTOM_RESOLUTION.value().second); params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first; params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second; - } else if (GRAPHICS_FS_FORCE_LANDSCAPE) { + } else if (GRAPHICS_FS_ORIENTATION_SWAP) { + log_misc( + "graphics::d3d9", + "swap full orientation {}x{} => {}x{}", + params->BackBufferWidth, params->BackBufferHeight, + params->BackBufferHeight, params->BackBufferWidth); std::swap(params->BackBufferWidth, params->BackBufferHeight); } } @@ -890,11 +920,10 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDeviceEx( 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) { + } else if (GRAPHICS_FS_ORIENTATION_SWAP) { std::swap(fullscreen_display_mode->Width, fullscreen_display_mode->Height); } } - log_info("graphics::d3d9", "D3D9Ex fullscreen display mode for adapter {}: Width: {}, Height: {}, RefreshRate: {}, " diff --git a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp index 7dbdf0d..bb50c16 100644 --- a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp +++ b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp @@ -7,6 +7,7 @@ #include "hooks/graphics/graphics.h" #include "overlay/overlay.h" #include "util/flags_helper.h" +#include "util/utils.h" #include "cfg/screen_resize.h" #include "d3d9_backend.h" @@ -692,94 +693,159 @@ static IDirect3DSurface9 *backbuffer = nullptr; static LPDIRECT3DSWAPCHAIN9 mSwapChain = nullptr; static IDirect3DTexture9* tex; +static UINT topSurface_width = 0; +static UINT topSurface_height = 0; +static float topSurface_aspect_ratio = 1.f; + void SurfaceHook(IDirect3DDevice9 *pReal) { - // log_misc("graphics::d3d9", "SurfaceHook called"); D3DPRESENT_PARAMETERS param {}; pReal->GetSwapChain(0, &mSwapChain); mSwapChain->GetPresentParameters(¶m); + + // phase 0 - create a surface that has the same aspect ratio as the original back buffer + // but larger in size. this is needed to ensure that when the user zooms out, we have + // sufficient buffer space (black border) around the original image + // + // (only done once) if (!topSurface) { - if (pReal->CreateTexture(4096, 4096, 1, + topSurface_width = param.BackBufferWidth * 3; + topSurface_height = param.BackBufferHeight * 3; + topSurface_aspect_ratio = (float)topSurface_width / (float)topSurface_height; + if (pReal->CreateTexture(topSurface_width, topSurface_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL) != D3D_OK) { - log_misc("graphics::d3d9", "create texture failed"); - + log_warning("graphics::d3d9", "SurfaceHook - create texture failed"); } - log_misc("graphics::d3d9", "Backbuffer: {} {} {}", - param.BackBufferWidth, param.BackBufferHeight, param.BackBufferCount); - tex->GetSurfaceLevel(0, &topSurface); + log_misc( + "graphics::d3d9", "SurfaceHook - Backbuffer: {} {} {}", + param.BackBufferWidth, param.BackBufferHeight, param.BackBufferCount); + + tex->GetSurfaceLevel(0, &topSurface); if (mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backbuffer) != D3D_OK) { - log_misc("graphics::d3d9", "GetBackBuffer failed"); + log_warning("graphics::d3d9", "SurfaceHook - GetBackBuffer failed"); } } - const int rectLeft = 1024; - const int rectTop = 576; + // pre-calculate dimensions used for phase 1 + const int rectLeft = param.BackBufferWidth; + const int rectTop = param.BackBufferHeight; 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( + + // phase 1 - copy the original back buffer onto the new surface. + // we draw it 1:1 in the center of the surface. + // if orientation is swapped, fix up the rect and draw it in the center. + // + // for this phase we always render with the same rect so that it's always overwritten + // by a new frame on the same spot. + RECT originRect { + rectLeft, + rectTop, + (LONG)(rectLeft + w), + (LONG)(rectTop + h), + }; + if (GRAPHICS_FS_ORIENTATION_SWAP) { + originRect.left = (topSurface_width / 2) - (GRAPHICS_FS_ORIGINAL_WIDTH / 2); + originRect.top = (topSurface_height / 2) - (GRAPHICS_FS_ORIGINAL_HEIGHT / 2); + originRect.right = originRect.left + GRAPHICS_FS_ORIGINAL_WIDTH; + originRect.bottom = originRect.top + GRAPHICS_FS_ORIGINAL_HEIGHT; + } + + // log_misc( + // "graphics::d3d9", "originRect: {} {} {} {}", + // originRect.left, originRect.top, originRect.right, originRect.bottom); + + 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"); - } + if (hr != D3D_OK) { + log_warning( + "graphics::d3d9", + "SurfaceHook - StretchRect backbuffer failed, rect: {} {} {} {}", + originRect.left, originRect.top, originRect.right, originRect.bottom); } topSurface->UnlockRect(); + // phase 2 - viewport calculation - do the actual zoom / offset math + // figure out what region of the surface to copy back to the back buffer. RECT targetRect { rectLeft, rectTop, (LONG)(rectLeft + w), (LONG)(rectTop + h), }; - - // do the actual zoom / offset math 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; + auto w_new = w / scene.scale_x; + auto h_new = h / scene.scale_y; + + // make sure the scaling is within bounds + if (cfg::SCREENRESIZE->client_keep_aspect_ratio) { + if (w_new > topSurface_width || h_new > topSurface_height) { + w_new = topSurface_width; + h_new = topSurface_height; + } } 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; + w_new = MIN(w_new, topSurface_width); + h_new = MIN(h_new, topSurface_height); + } + + targetRect.left = (topSurface_width / 2) - (w_new / 2) - scene.offset_x; + targetRect.top = (topSurface_height / 2) - (h_new / 2) - scene.offset_y; + targetRect.right = targetRect.left + w_new; + targetRect.bottom = targetRect.top + h_new; + + // boundary check to prevent StretchRect failures + if (targetRect.left < 0) { + targetRect.left = 0; + targetRect.right = w_new; + } else if (targetRect.right > (LONG)topSurface_width) { + targetRect.left = topSurface_width - w_new; + targetRect.right = topSurface_width; + } + if (targetRect.top < 0) { + targetRect.top = 0; + targetRect.bottom = h_new; + } else if (targetRect.bottom > (LONG)topSurface_height) { + targetRect.top = topSurface_height - h_new; + targetRect.bottom = topSurface_height; + } + + } else if (GRAPHICS_FS_ORIENTATION_SWAP) { + // increase the viewport to fit the image on screen (effectively, zoom out a little) + if (GRAPHICS_FS_ORIGINAL_WIDTH < GRAPHICS_FS_ORIGINAL_HEIGHT) { + // portrait game on landscape display + // height should match the original image + targetRect.top = originRect.top; + targetRect.bottom = originRect.bottom; + + // width of viewport should be wider, effectively shrinking the image on x-axis when rendered + const auto w_new = GRAPHICS_FS_ORIGINAL_HEIGHT * topSurface_aspect_ratio; + targetRect.left = (topSurface_width / 2) - (w_new / 2); + targetRect.right = targetRect.left + w_new; + } else { + // landscape game on portrait display + targetRect.left = originRect.left; + targetRect.right = originRect.right; + + // height of viewport should be taller, effectively shrinking the image on y-axis when rendered + const auto h_new = GRAPHICS_FS_ORIGINAL_WIDTH / topSurface_aspect_ratio; + targetRect.top = (topSurface_height / 2) - (h_new / 2); + targetRect.bottom = targetRect.top + h_new; } } - // draw to back buffer + // log_misc("graphics::d3d9", "targetRect: {} {} {} {}", + // targetRect.left, targetRect.top, targetRect.right, targetRect.bottom); + + // phase 3 - draw the surface to back buffer backbuffer->LockRect(&rect, NULL, D3DLOCK_DONOTWAIT); bool use_linear_filter = true; if (cfg::SCREENRESIZE->enable_screen_resize) { @@ -791,14 +857,17 @@ void SurfaceHook(IDirect3DDevice9 *pReal) { use_linear_filter ? D3DTEXF_LINEAR : D3DTEXF_NONE); backbuffer->UnlockRect(); if (hr != D3D_OK) { - log_misc("graphics::d3d9", "StretchRect targetRect failed"); + log_warning( + "graphics::d3d9", + "SurfaceHook - StretchRect targetRect failed, you must reset image scaling to default values! rect: {} {} {} {}", + targetRect.left, targetRect.top, targetRect.right, targetRect.bottom); } } HRESULT STDMETHODCALLTYPE WrappedIDirect3DDevice9::EndScene() { WRAP_DEBUG; - if (cfg::SCREENRESIZE->enable_screen_resize || GRAPHICS_FS_FORCE_LANDSCAPE) { + if (cfg::SCREENRESIZE->enable_screen_resize || GRAPHICS_FS_ORIENTATION_SWAP) { SurfaceHook(pReal); } diff --git a/src/spice2x/hooks/graphics/graphics.cpp b/src/spice2x/hooks/graphics/graphics.cpp index 128855d..9aa0521 100644 --- a/src/spice2x/hooks/graphics/graphics.cpp +++ b/src/spice2x/hooks/graphics/graphics.cpp @@ -68,7 +68,9 @@ bool GRAPHICS_9_ON_12_REQUESTED_BY_GAME = false; bool SUBSCREEN_FORCE_REDRAW = false; bool D3D9_DEVICE_HOOK_DISABLE = false; std::optional> GRAPHICS_FS_CUSTOM_RESOLUTION; -bool GRAPHICS_FS_FORCE_LANDSCAPE = false; +bool GRAPHICS_FS_ORIENTATION_SWAP = false; +uint32_t GRAPHICS_FS_ORIGINAL_WIDTH = 0; +uint32_t GRAPHICS_FS_ORIGINAL_HEIGHT = 0; // settings std::string GRAPHICS_DEVICEID = "PCI\\VEN_1002&DEV_7146"; diff --git a/src/spice2x/hooks/graphics/graphics.h b/src/spice2x/hooks/graphics/graphics.h index 907c9e0..8c80159 100644 --- a/src/spice2x/hooks/graphics/graphics.h +++ b/src/spice2x/hooks/graphics/graphics.h @@ -36,7 +36,9 @@ extern std::optional GRAPHICS_FORCE_VSYNC_BUFFER; extern bool GRAPHICS_FORCE_SINGLE_ADAPTER; extern bool GRAPHICS_PREVENT_SECONDARY_WINDOW; extern std::optional> GRAPHICS_FS_CUSTOM_RESOLUTION; -extern bool GRAPHICS_FS_FORCE_LANDSCAPE; +extern bool GRAPHICS_FS_ORIENTATION_SWAP; +extern uint32_t GRAPHICS_FS_ORIGINAL_WIDTH; +extern uint32_t GRAPHICS_FS_ORIGINAL_HEIGHT; extern graphics_dx9on12_state GRAPHICS_9_ON_12_STATE; extern bool GRAPHICS_9_ON_12_REQUESTED_BY_GAME; diff --git a/src/spice2x/launcher/launcher.cpp b/src/spice2x/launcher/launcher.cpp index 5d4c21b..52dd72e 100644 --- a/src/spice2x/launcher/launcher.cpp +++ b/src/spice2x/launcher/launcher.cpp @@ -1167,11 +1167,14 @@ int main_implementation(int argc, char *argv[]) { if (options[launcher::Options::SDVXFullscreenLandscape].value_bool() && !GRAPHICS_WINDOWED) { #if SPICE64 - GRAPHICS_FS_FORCE_LANDSCAPE = true; + GRAPHICS_FS_ORIENTATION_SWAP = true; #else log_warning("launcher", "-sdvxlandscape is not supported in 32-bit SDVX, ignoring..."); #endif } + if (options[launcher::Options::FullscreenOrientationFlip].value_bool() && !GRAPHICS_WINDOWED) { + GRAPHICS_FS_ORIENTATION_SWAP = true; + } // deleted options if (options[launcher::Options::OpenKFControl].value_bool()) { diff --git a/src/spice2x/launcher/options.cpp b/src/spice2x/launcher/options.cpp index edc8421..93d3fe0 100644 --- a/src/spice2x/launcher/options.cpp +++ b/src/spice2x/launcher/options.cpp @@ -218,6 +218,17 @@ static const std::vector OPTION_DEFINITIONS = { .setting_name = "1280,720", .category = "Graphics (Full Screen)" }, + { + // FullscreenOrientationFlip + .title = "Full Screen Orientation Swap", + .name = "forceresswap", + .desc = + "Allows you to play portrait games in in landscape (and vice versa) by transposing resolution and applying image scaling.\n\n" + "Works great for some games, but can COMPLETELY BREAK other games - YMMV!\n\n" + "Strongly consider combining this with -forceres option to render at monitor native resolution", + .type = OptionType::Bool, + .category = "Graphics (Full Screen)" + }, { // Graphics9On12 .title = "DirectX 9 on 12 (DEPRECATED - use -dx9on12 instead)", @@ -2039,9 +2050,8 @@ static const std::vector OPTION_DEFINITIONS = { .name = "sdvxlandscape", .desc = "Allows you to play in landscape by transposing resolution and applying image scaling.\n\n" - "Only for SDVX5 and above!\n\n" - "Can also be combined with -forceres option to render at larger or smaller resolution, " - "and with image resize option to zoom into certain areas of the screen", + "Works only for SDVX5 and above! This is identical to -forceorientation.\n\n" + "Will launch at 1080p by default; strongly consider combining this with -forceres option to render at monitor native resolution", .type = OptionType::Bool, .game_name = "Sound Voltex", .category = "Game Options" diff --git a/src/spice2x/launcher/options.h b/src/spice2x/launcher/options.h index e148d79..3f6ae1d 100644 --- a/src/spice2x/launcher/options.h +++ b/src/spice2x/launcher/options.h @@ -30,6 +30,7 @@ namespace launcher { GraphicsForceSingleAdapter, GraphicsForceRefresh, FullscreenResolution, + FullscreenOrientationFlip, Graphics9On12, spice2x_Dx9On12, NoLegacy, diff --git a/src/spice2x/overlay/windows/screen_resize.cpp b/src/spice2x/overlay/windows/screen_resize.cpp index 03143ef..ed242aa 100644 --- a/src/spice2x/overlay/windows/screen_resize.cpp +++ b/src/spice2x/overlay/windows/screen_resize.cpp @@ -51,7 +51,6 @@ namespace overlay::windows { for (size_t i = 0; i < std::size(cfg::SCREENRESIZE->scene_settings); i++) { auto& scene = cfg::SCREENRESIZE->scene_settings[i]; scene.keep_aspect_ratio = true; - scene.centered = true; scene.offset_x = 0; scene.offset_y = 0; scene.scale_x = 1.f; @@ -126,21 +125,28 @@ namespace overlay::windows { auto& scene = cfg::SCREENRESIZE->scene_settings[cfg::SCREENRESIZE->screen_resize_current_scene]; // general settings - ImGui::Checkbox("Centered", &scene.centered); - if (!scene.centered) { - ImGui::InputInt("X Offset", &scene.offset_x); - ImGui::InputInt("Y Offset", &scene.offset_y); - } + ImGui::InputInt("X Offset", &scene.offset_x); + ImGui::SameLine(); + ImGui::HelpMarker("Hint: ctrl + click on +/- buttons to move quickly."); + ImGui::InputInt("Y Offset", &scene.offset_y); + ImGui::SameLine(); + ImGui::HelpMarker("Hint: ctrl + click on +/- buttons to move quickly."); // aspect ratio ImGui::Checkbox("Keep Aspect Ratio", &scene.keep_aspect_ratio); if (scene.keep_aspect_ratio) { - if (ImGui::SliderFloat("Scale", &scene.scale_x, 0.65f, 2.0f)) { + if (ImGui::SliderFloat("Scale", &scene.scale_x, 0.5f, 2.5f)) { scene.scale_y = scene.scale_x; } + ImGui::SameLine(); + ImGui::HelpMarker("Hint: ctrl + click on the slider to type in a numeric value."); } else { - ImGui::SliderFloat("Width Scale", &scene.scale_x, 0.65f, 2.0f); - ImGui::SliderFloat("Height Scale", &scene.scale_y, 0.65f, 2.0f); + ImGui::SliderFloat("Width Scale", &scene.scale_x, 0.5f, 2.5f); + ImGui::SameLine(); + ImGui::HelpMarker("Hint: ctrl + click on the slider to type in a numeric value."); + ImGui::SliderFloat("Height Scale", &scene.scale_y, 0.5f, 2.5f); + ImGui::SameLine(); + ImGui::HelpMarker("Hint: ctrl + click on the slider to type in a numeric value."); } ImGui::EndDisabled(); diff --git a/src/spice2x/overlay/windows/sdvx_sub.cpp b/src/spice2x/overlay/windows/sdvx_sub.cpp index 3d2d6a1..9e128bc 100644 --- a/src/spice2x/overlay/windows/sdvx_sub.cpp +++ b/src/spice2x/overlay/windows/sdvx_sub.cpp @@ -35,7 +35,7 @@ namespace overlay::windows { default: this->init_size = ImVec2(ImGui::GetIO().DisplaySize.x - (padding * 2), 0.f); this->init_size.y = (this->init_size.x * 9 / 16) + ImGui::GetFrameHeight(); - if (GRAPHICS_FS_FORCE_LANDSCAPE) { + if (GRAPHICS_FS_ORIENTATION_SWAP) { this->init_size.x /= 2; this->init_size.y /= 2; }