mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-28 05:11:37 +00:00
Implement the aspect ratio option.
This commit is contained in:
parent
3647261f2b
commit
a39b3ec855
8 changed files with 123 additions and 44 deletions
|
|
@ -152,9 +152,9 @@ set(SWA_PATCHES_CXX_SOURCES
|
|||
"patches/ui/CTitleStateIntro_patches.cpp"
|
||||
"patches/ui/CTitleStateMenu_patches.cpp"
|
||||
"patches/ui/frontend_listener.cpp"
|
||||
"patches/aspect_ratio_patches.cpp"
|
||||
"patches/audio_patches.cpp"
|
||||
"patches/camera_patches.cpp"
|
||||
"patches/csd_patches.cpp"
|
||||
"patches/fps_patches.cpp"
|
||||
"patches/inspire_patches.cpp"
|
||||
"patches/misc_patches.cpp"
|
||||
|
|
|
|||
|
|
@ -5,12 +5,17 @@
|
|||
#define g_Gamma vk::RawBufferLoad<float3>(g_PushConstants.SharedConstants + 0)
|
||||
#define g_TextureDescriptorIndex vk::RawBufferLoad<uint>(g_PushConstants.SharedConstants + 12)
|
||||
|
||||
#define g_ViewportOffset vk::RawBufferLoad<int2>(g_PushConstants.SharedConstants + 16)
|
||||
#define g_ViewportSize vk::RawBufferLoad<int2>(g_PushConstants.SharedConstants + 24)
|
||||
|
||||
#else
|
||||
|
||||
cbuffer SharedConstants : register(b2, space4)
|
||||
{
|
||||
float3 g_Gamma : packoffset(c0.x);
|
||||
uint g_TextureDescriptorIndex : packoffset(c0.w);
|
||||
float3 g_Gamma;
|
||||
uint g_TextureDescriptorIndex;
|
||||
int2 g_ViewportOffset;
|
||||
int2 g_ViewportSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -18,7 +23,12 @@ cbuffer SharedConstants : register(b2, space4)
|
|||
float4 main(in float4 position : SV_Position) : SV_Target
|
||||
{
|
||||
Texture2D<float4> texture = g_Texture2DDescriptorHeap[g_TextureDescriptorIndex];
|
||||
float4 color = texture.Load(int3(position.xy, 0));
|
||||
|
||||
int2 movedPosition = int2(position.xy) - g_ViewportOffset;
|
||||
bool boxed = any(movedPosition < 0) || any(movedPosition >= g_ViewportSize);
|
||||
if (boxed) movedPosition = 0;
|
||||
|
||||
float4 color = boxed ? 0.0 : texture.Load(int3(movedPosition, 0));
|
||||
color.rgb = pow(color.rgb, g_Gamma);
|
||||
return color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <ui/options_menu.h>
|
||||
#include <ui/sdl_listener.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <patches/aspect_ratio_patches.h>
|
||||
#include <user/config.h>
|
||||
#include <xxHashMap.h>
|
||||
|
||||
|
|
@ -1352,16 +1353,19 @@ static void CheckSwapChain()
|
|||
if (g_swapChainValid)
|
||||
g_swapChainValid = g_swapChain->acquireTexture(g_acquireSemaphores[g_frame].get(), &g_backBufferIndex);
|
||||
|
||||
float aspectRatio = float(GameWindow::s_width) / GameWindow::s_height;
|
||||
if (g_needsResize)
|
||||
Video::ComputeViewportDimensions();
|
||||
|
||||
float aspectRatio = float(Video::s_viewportWidth) / Video::s_viewportHeight;
|
||||
if (aspectRatio >= ORIGINAL_ASPECT_RATIO)
|
||||
{
|
||||
g_backBuffer->width = GameWindow::s_width * 720 / GameWindow::s_height;
|
||||
g_backBuffer->width = Video::s_viewportWidth * 720 / Video::s_viewportHeight;
|
||||
g_backBuffer->height = 720;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_backBuffer->width = 960;
|
||||
g_backBuffer->height = GameWindow::s_height * 960 / GameWindow::s_width;
|
||||
g_backBuffer->height = Video::s_viewportHeight * 960 / Video::s_viewportWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1376,13 +1380,14 @@ static void BeginCommandList()
|
|||
|
||||
if (g_swapChainValid)
|
||||
{
|
||||
bool applyingGammaCorrection = Config::XboxColorCorrection || abs(Config::Brightness - 0.5f) > 0.001f;
|
||||
uint32_t width = Video::s_viewportWidth;
|
||||
uint32_t height = Video::s_viewportHeight;
|
||||
|
||||
if (applyingGammaCorrection)
|
||||
bool usingIntermediaryTexture = (width != g_swapChain->getWidth()) || (height != g_swapChain->getHeight()) ||
|
||||
Config::XboxColorCorrection || (abs(Config::Brightness - 0.5f) > 0.001f);
|
||||
|
||||
if (usingIntermediaryTexture)
|
||||
{
|
||||
uint32_t width = g_swapChain->getWidth();
|
||||
uint32_t height = g_swapChain->getHeight();
|
||||
|
||||
if (g_intermediaryBackBufferTextureWidth != width ||
|
||||
g_intermediaryBackBufferTextureHeight != height)
|
||||
{
|
||||
|
|
@ -1665,6 +1670,7 @@ void Video::CreateHostDevice(const char *sdlVideoDriver)
|
|||
g_backBuffer->format = BACKBUFFER_FORMAT;
|
||||
g_backBuffer->textureHolder = g_device->createTexture(RenderTextureDesc::Texture2D(1, 1, 1, BACKBUFFER_FORMAT, RenderTextureFlag::RENDER_TARGET));
|
||||
|
||||
Video::ComputeViewportDimensions();
|
||||
CheckSwapChain();
|
||||
BeginCommandList();
|
||||
|
||||
|
|
@ -2062,6 +2068,8 @@ static void DrawImGui()
|
|||
ImGui::End();
|
||||
#endif
|
||||
|
||||
ImGui::GetIO().DisplaySize = { float(Video::s_viewportWidth), float(Video::s_viewportHeight) };
|
||||
|
||||
AchievementMenu::Draw();
|
||||
OptionsMenu::Draw();
|
||||
AchievementOverlay::Draw();
|
||||
|
|
@ -2343,6 +2351,11 @@ static void ProcExecuteCommandList(const RenderCommand& cmd)
|
|||
float gammaG;
|
||||
float gammaB;
|
||||
uint32_t textureDescriptorIndex;
|
||||
|
||||
int32_t viewportOffsetX;
|
||||
int32_t viewportOffsetY;
|
||||
int32_t viewportWidth;
|
||||
int32_t viewportHeight;
|
||||
} constants;
|
||||
|
||||
if (Config::XboxColorCorrection)
|
||||
|
|
@ -2365,6 +2378,11 @@ static void ProcExecuteCommandList(const RenderCommand& cmd)
|
|||
constants.gammaB = 1.0f / std::clamp(constants.gammaB + offset, 0.1f, 4.0f);
|
||||
constants.textureDescriptorIndex = g_intermediaryBackBufferTextureDescriptorIndex;
|
||||
|
||||
constants.viewportOffsetX = (int32_t(g_swapChain->getWidth()) - int32_t(Video::s_viewportWidth)) / 2;
|
||||
constants.viewportOffsetY = (int32_t(g_swapChain->getHeight()) - int32_t(Video::s_viewportHeight)) / 2;
|
||||
constants.viewportWidth = Video::s_viewportWidth;
|
||||
constants.viewportHeight = Video::s_viewportHeight;
|
||||
|
||||
auto &framebuffer = g_backBuffer->framebuffers[swapChainTexture];
|
||||
if (!framebuffer)
|
||||
{
|
||||
|
|
@ -2387,8 +2405,8 @@ static void ProcExecuteCommandList(const RenderCommand& cmd)
|
|||
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
|
||||
SetRootDescriptor(g_uploadAllocators[g_frame].allocate<false>(&constants, sizeof(constants), 0x100), 2);
|
||||
commandList->setFramebuffer(framebuffer.get());
|
||||
commandList->setViewports(RenderViewport(0.0f, 0.0f, g_intermediaryBackBufferTextureWidth, g_intermediaryBackBufferTextureHeight));
|
||||
commandList->setScissors(RenderRect(0, 0, g_intermediaryBackBufferTextureWidth, g_intermediaryBackBufferTextureHeight));
|
||||
commandList->setViewports(RenderViewport(0.0f, 0.0f, g_swapChain->getWidth(), g_swapChain->getHeight()));
|
||||
commandList->setScissors(RenderRect(0, 0, g_swapChain->getWidth(), g_swapChain->getHeight()));
|
||||
commandList->drawInstanced(6, 1, 0, 0);
|
||||
commandList->barriers(RenderBarrierStage::GRAPHICS, RenderTextureBarrier(swapChainTexture, RenderTextureLayout::PRESENT));
|
||||
}
|
||||
|
|
@ -2442,6 +2460,56 @@ GuestSurface* Video::GetBackBuffer()
|
|||
return g_backBuffer;
|
||||
}
|
||||
|
||||
void Video::ComputeViewportDimensions()
|
||||
{
|
||||
uint32_t width = g_swapChain->getWidth();
|
||||
uint32_t height = g_swapChain->getHeight();
|
||||
float aspectRatio = float(width) / float(height);
|
||||
|
||||
switch (Config::AspectRatio)
|
||||
{
|
||||
case EAspectRatio::Wide:
|
||||
{
|
||||
if (aspectRatio > (16.0f / 9.0f))
|
||||
{
|
||||
s_viewportWidth = height * 16 / 9;
|
||||
s_viewportHeight = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_viewportWidth = width;
|
||||
s_viewportHeight = width * 9 / 16;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EAspectRatio::Narrow:
|
||||
case EAspectRatio::OriginalNarrow:
|
||||
{
|
||||
if (aspectRatio > (4.0f / 3.0f))
|
||||
{
|
||||
s_viewportWidth = height * 4 / 3;
|
||||
s_viewportHeight = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_viewportWidth = width;
|
||||
s_viewportHeight = width * 3 / 4;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
s_viewportWidth = width;
|
||||
s_viewportHeight = height;
|
||||
break;
|
||||
}
|
||||
|
||||
AspectRatioPatches::ComputeOffsets();
|
||||
}
|
||||
|
||||
static RenderFormat ConvertFormat(uint32_t format)
|
||||
{
|
||||
switch (format)
|
||||
|
|
@ -2610,8 +2678,8 @@ static void FlushViewport()
|
|||
|
||||
if (renderingToBackBuffer)
|
||||
{
|
||||
float width = g_swapChain->getWidth();
|
||||
float height = g_swapChain->getHeight();
|
||||
float width = Video::s_viewportWidth;
|
||||
float height = Video::s_viewportHeight;
|
||||
|
||||
viewport.x *= width / g_backBuffer->width;
|
||||
viewport.y *= height / g_backBuffer->height;
|
||||
|
|
@ -2637,8 +2705,8 @@ static void FlushViewport()
|
|||
|
||||
if (renderingToBackBuffer)
|
||||
{
|
||||
uint32_t width = g_swapChain->getWidth();
|
||||
uint32_t height = g_swapChain->getHeight();
|
||||
uint32_t width = Video::s_viewportWidth;
|
||||
uint32_t height = Video::s_viewportHeight;
|
||||
|
||||
scissorRect.left = scissorRect.left * width / g_backBuffer->width;
|
||||
scissorRect.top = scissorRect.top * height / g_backBuffer->height;
|
||||
|
|
@ -4958,8 +5026,10 @@ void SetShadowResolutionMidAsmHook(PPCRegister& r11)
|
|||
|
||||
static void SetResolution(be<uint32_t>* device)
|
||||
{
|
||||
uint32_t width = uint32_t(round(g_swapChain->getWidth() * Config::ResolutionScale));
|
||||
uint32_t height = uint32_t(round(g_swapChain->getHeight() * Config::ResolutionScale));
|
||||
Video::ComputeViewportDimensions();
|
||||
|
||||
uint32_t width = uint32_t(round(Video::s_viewportWidth * Config::ResolutionScale));
|
||||
uint32_t height = uint32_t(round(Video::s_viewportHeight * Config::ResolutionScale));
|
||||
device[46] = width == 0 ? 880 : width;
|
||||
device[47] = height == 0 ? 720 : height;
|
||||
}
|
||||
|
|
@ -6438,10 +6508,14 @@ void VideoConfigValueChangedCallback(IConfigDef* config)
|
|||
{
|
||||
// Config options that require internal resolution resize
|
||||
g_needsResize |=
|
||||
config == &Config::AspectRatio ||
|
||||
config == &Config::ResolutionScale ||
|
||||
config == &Config::AntiAliasing ||
|
||||
config == &Config::ShadowResolution;
|
||||
|
||||
if (g_needsResize)
|
||||
Video::ComputeViewportDimensions();
|
||||
|
||||
// Config options that require pipeline recompilation
|
||||
bool shouldRecompile =
|
||||
config == &Config::AntiAliasing ||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,16 @@ using namespace plume;
|
|||
|
||||
struct Video
|
||||
{
|
||||
static inline uint32_t s_viewportWidth;
|
||||
static inline uint32_t s_viewportHeight;
|
||||
|
||||
static void CreateHostDevice(const char *sdlVideoDriver);
|
||||
static void WaitOnSwapChain();
|
||||
static void Present();
|
||||
static void StartPipelinePrecompilation();
|
||||
static void WaitForGPU();
|
||||
static struct GuestSurface* GetBackBuffer();
|
||||
static void ComputeViewportDimensions();
|
||||
};
|
||||
|
||||
struct GuestSamplerState
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
#include <api/SWA.h>
|
||||
#include <app.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <ui/sdl_listener.h>
|
||||
#include <gpu/video.h>
|
||||
|
||||
#include "aspect_ratio_patches.h"
|
||||
#include "camera_patches.h"
|
||||
|
||||
// These are here for now to not recompile basically all of the project.
|
||||
|
|
@ -191,8 +191,11 @@ static float ComputeScale(float aspectRatio)
|
|||
return ((aspectRatio * 720.0f) / 1280.0f) / sqrt((aspectRatio * 720.0f) / 1280.0f);
|
||||
}
|
||||
|
||||
static void ComputeOffsets(float width, float height)
|
||||
void AspectRatioPatches::ComputeOffsets()
|
||||
{
|
||||
float width = Video::s_viewportWidth;
|
||||
float height = Video::s_viewportHeight;
|
||||
|
||||
g_aspectRatio = width / height;
|
||||
g_scale = 1.0f;
|
||||
|
||||
|
|
@ -224,25 +227,6 @@ static void ComputeOffsets(float width, float height)
|
|||
g_worldMapOffset = std::clamp((g_aspectRatio - NARROW_ASPECT_RATIO) / (WIDE_ASPECT_RATIO - NARROW_ASPECT_RATIO), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
static class SDLEventListenerForCSD : public SDLEventListener
|
||||
{
|
||||
public:
|
||||
void OnSDLEvent(SDL_Event* event) override
|
||||
{
|
||||
if (event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_RESIZED)
|
||||
ComputeOffsets(event->window.data1, event->window.data2);
|
||||
}
|
||||
} g_sdlEventListenerForCSD;
|
||||
|
||||
// Chao::CSD::SetOffsets
|
||||
PPC_FUNC_IMPL(__imp__sub_830C0A78);
|
||||
PPC_FUNC(sub_830C0A78)
|
||||
{
|
||||
__imp__sub_830C0A78(ctx, base);
|
||||
|
||||
ComputeOffsets(GameWindow::s_width, GameWindow::s_height);
|
||||
}
|
||||
|
||||
// SWA::CGameDocument::ComputeScreenPosition
|
||||
PPC_FUNC_IMPL(__imp__sub_8250FC70);
|
||||
PPC_FUNC(sub_8250FC70)
|
||||
6
UnleashedRecomp/patches/aspect_ratio_patches.h
Normal file
6
UnleashedRecomp/patches/aspect_ratio_patches.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
struct AspectRatioPatches
|
||||
{
|
||||
static void ComputeOffsets();
|
||||
};
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#include <api/SWA.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <user/config.h>
|
||||
#include <gpu/video.h>
|
||||
#include "camera_patches.h"
|
||||
|
||||
static constexpr float ORIGINAL_ASPECT_RATIO = 4.0f / 3.0f;
|
||||
|
|
@ -13,7 +14,7 @@ void CameraAspectRatioMidAsmHook(PPCRegister& r30, PPCRegister& r31)
|
|||
auto camera = (SWA::CCamera*)g_memory.Translate(r31.u32);
|
||||
|
||||
// Dynamically adjust horizontal aspect ratio to window dimensions.
|
||||
camera->m_HorzAspectRatio = float(GameWindow::s_width) / float(GameWindow::s_height);
|
||||
camera->m_HorzAspectRatio = float(Video::s_viewportWidth) / float(Video::s_viewportHeight);
|
||||
}
|
||||
|
||||
float AdjustFieldOfView(float fieldOfView, float aspectRatio)
|
||||
|
|
|
|||
|
|
@ -1057,8 +1057,8 @@ static void DrawInfoPanel()
|
|||
auto resScale = round(*(float*)g_selectedItem->GetValue() * 1000) / 1000;
|
||||
|
||||
std::snprintf(buf, sizeof(buf), desc.c_str(),
|
||||
(int)((float)GameWindow::s_width * resScale),
|
||||
(int)((float)GameWindow::s_height * resScale));
|
||||
(int)((float)Video::s_viewportWidth * resScale),
|
||||
(int)((float)Video::s_viewportHeight * resScale));
|
||||
|
||||
desc = buf;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue