Implement aspect ratio adjustments for inspire overlays. (#201)

* Handle texture/movie overlays for original 4:3.

* Implement aspect ratio adjustments for texture/movie overlays.

* Fix fade scale for original 4:3.
This commit is contained in:
Skyth (Asilkan) 2025-01-26 13:19:39 +03:00 committed by GitHub
parent a9573584cd
commit 76ec5f032d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 143 additions and 7 deletions

View file

@ -361,6 +361,7 @@ function(compile_pixel_shader FILE_PATH)
compile_shader(${FILE_PATH} ps_6_0)
endfunction()
compile_pixel_shader(blend_color_alpha_ps)
compile_vertex_shader(copy_vs)
compile_pixel_shader(csd_filter_ps)
compile_vertex_shader(csd_no_tex_vs)

View file

@ -0,0 +1,41 @@
#include "../../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef __spirv__
#define g_SrcAlpha_DestAlpha vk::RawBufferLoad<float4>(g_PushConstants.PixelShaderConstants + 2400, 0x10)
#define s0_Texture2DDescriptorIndex vk::RawBufferLoad<uint>(g_PushConstants.SharedConstants + 0)
#define s0_SamplerDescriptorIndex vk::RawBufferLoad<uint>(g_PushConstants.SharedConstants + 192)
#else
cbuffer PixelShaderConstants : register(b1, space4)
{
float4 g_SrcAlpha_DestAlpha : packoffset(c150);
};
cbuffer SharedConstants : register(b2, space4)
{
uint s0_Texture2DDescriptorIndex : packoffset(c0.x);
uint s0_SamplerDescriptorIndex : packoffset(c12.x);
DEFINE_SHARED_CONSTANTS();
};
#endif
float4 main(
in float4 iPos : SV_Position,
in float4 iTexCoord0 : TEXCOORD0) : SV_Target0
{
Texture2D<float4> texture = g_Texture2DDescriptorHeap[s0_Texture2DDescriptorIndex];
SamplerState samplerState = g_SamplerDescriptorHeap[s0_SamplerDescriptorIndex];
float4 color = texture.Sample(samplerState, iTexCoord0.xy);
if (any(or(iTexCoord0.xy < 0.0, iTexCoord0.xy > 1.0)))
color = float4(0.0, 0.0, 0.0, 1.0);
color.rgb *= color.a * g_SrcAlpha_DestAlpha.x;
color.a = g_SrcAlpha_DestAlpha.y + (1.0 - color.a) * g_SrcAlpha_DestAlpha.x;
return color;
}

View file

@ -38,7 +38,7 @@ cbuffer SharedConstants : register(b2, space4)
#endif
float4 main(in float4 position : SV_Position, in float2 texCoord : TEXCOORD0) : SV_Target
float4 main(in float4 position : SV_Position, in float4 texCoord : TEXCOORD0) : SV_Target
{
Texture2D<float4> sampColor = g_Texture2DDescriptorHeap[sampColor_Texture2DDescriptorIndex];
Texture2D<float4> sampVelocityMap = g_Texture2DDescriptorHeap[sampVelocityMap_Texture2DDescriptorIndex];
@ -48,19 +48,19 @@ float4 main(in float4 position : SV_Position, in float2 texCoord : TEXCOORD0) :
SamplerState sampVelocityMap_s = g_SamplerDescriptorHeap[sampVelocityMap_SamplerDescriptorIndex];
SamplerState sampZBuffer_s = g_SamplerDescriptorHeap[sampZBuffer_SamplerDescriptorIndex];
float depth = sampZBuffer.SampleLevel(sampZBuffer_s, texCoord, 0).x;
float4 velocityMap = sampVelocityMap.SampleLevel(sampVelocityMap_s, texCoord, 0);
float depth = sampZBuffer.SampleLevel(sampZBuffer_s, texCoord.xy, 0).x;
float4 velocityMap = sampVelocityMap.SampleLevel(sampVelocityMap_s, texCoord.xy, 0);
float2 velocity = (velocityMap.xz + velocityMap.yw / 255.0) * 2.0 - 1.0;
int sampleCount = min(64, round(length(velocity * g_ViewportSize.xy)));
float2 sampleOffset = velocity / (float) sampleCount;
float3 color = sampColor.SampleLevel(sampColor_s, texCoord, 0).rgb;
float3 color = sampColor.SampleLevel(sampColor_s, texCoord.xy, 0).rgb;
int count = 1;
for (int i = 1; i <= sampleCount; i++)
{
float2 sampleCoord = texCoord + sampleOffset * i;
float2 sampleCoord = texCoord.xy + sampleOffset * i;
float3 sampleColor = sampColor.SampleLevel(sampColor_s, sampleCoord, 0).rgb;
float sampleDepth = sampZBuffer.SampleLevel(sampZBuffer_s, sampleCoord, 0).x;

View file

@ -37,6 +37,7 @@
#include "../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef UNLEASHED_RECOMP_D3D12
#include "shader/blend_color_alpha_ps.hlsl.dxil.h"
#include "shader/copy_vs.hlsl.dxil.h"
#include "shader/csd_filter_ps.hlsl.dxil.h"
#include "shader/csd_no_tex_vs.hlsl.dxil.h"
@ -56,6 +57,7 @@
#include "shader/resolve_msaa_depth_8x.hlsl.dxil.h"
#endif
#include "shader/blend_color_alpha_ps.hlsl.spirv.h"
#include "shader/copy_vs.hlsl.spirv.h"
#include "shader/csd_filter_ps.hlsl.spirv.h"
#include "shader/csd_no_tex_vs.hlsl.spirv.h"
@ -4233,7 +4235,9 @@ static GuestShader* CreateShader(const be<uint32_t>* function, ResourceType reso
{
shader = g_userHeap.AllocPhysical<GuestShader>(resourceType);
if (hash == 0xB1086A4947A797DE)
if (hash == 0x85ED723035ECF535)
shader->shader = CREATE_SHADER(blend_color_alpha_ps);
else if (hash == 0xB1086A4947A797DE)
shader->shader = CREATE_SHADER(csd_no_tex_vs);
else if (hash == 0xB4CAFC034A37C8A8)
shader->shader = CREATE_SHADER(csd_vs);

View file

@ -1195,11 +1195,22 @@ void ViewRingXMidAsmHook(PPCRegister& f1, PPCVRegister& v62)
}
}
// SWA::Inspire::CLetterbox::CLetterbox
PPC_FUNC_IMPL(__imp__sub_82B8A8F8);
PPC_FUNC(sub_82B8A8F8)
{
// Permanently store the letterbox bool instead of letting the game set it to false from widescreen check.
bool letterbox = PPC_LOAD_U8(ctx.r4.u32);
__imp__sub_82B8A8F8(ctx, base);
PPC_STORE_U8(ctx.r3.u32, letterbox);
}
// SWA::Inspire::CLetterbox::Draw
PPC_FUNC_IMPL(__imp__sub_82B8AA40);
PPC_FUNC(sub_82B8AA40)
{
bool shouldDrawLetterbox = Config::CutsceneAspectRatio != ECutsceneAspectRatio::Unlocked && g_aspectRatio < WIDE_ASPECT_RATIO;
bool letterbox = PPC_LOAD_U8(ctx.r3.u32);
bool shouldDrawLetterbox = letterbox && Config::CutsceneAspectRatio != ECutsceneAspectRatio::Unlocked && g_aspectRatio < WIDE_ASPECT_RATIO;
PPC_STORE_U8(ctx.r3.u32, shouldDrawLetterbox);
if (shouldDrawLetterbox)
@ -1212,7 +1223,11 @@ PPC_FUNC(sub_82B8AA40)
PPC_STORE_U32(ctx.r3.u32 + 0x14, (720 - width * 9 / 16) / 2);
}
auto r3 = ctx.r3;
__imp__sub_82B8AA40(ctx, base);
// Restore the original letterbox value.
PPC_STORE_U8(r3.u32, letterbox);
}
void InspireLetterboxTopMidAsmHook(PPCRegister& r3)
@ -1234,3 +1249,64 @@ void InspireSubtitleMidAsmHook(PPCRegister& r3)
*reinterpret_cast<be<float>*>(g_memory.base + r3.u32 + 0x3C) = NARROW_OFFSET + (WIDE_OFFSET - NARROW_OFFSET) * g_aspectRatioNarrowScale;
}
enum class FadeTextureMode
{
Unknown,
Letterbox,
SideCrop
};
static FadeTextureMode g_fadeTextureMode;
void FxFadePreRenderQuadMidAsmHook(PPCRegister& r31)
{
g_fadeTextureMode = *(g_memory.base + r31.u32 + 0x44) ? FadeTextureMode::Letterbox : FadeTextureMode::SideCrop;
}
void FxFadePostRenderQuadMidAsmHook()
{
g_fadeTextureMode = FadeTextureMode::Unknown;
}
void YggdrasillRenderQuadMidAsmHook(PPCRegister& r3, PPCRegister& r6)
{
if (g_fadeTextureMode != FadeTextureMode::Unknown)
{
float scaleX = 1.0f;
float scaleY = 1.0f;
// Fade textures are slightly squashed in the original game at 4:3.
if (Config::AspectRatio == EAspectRatio::OriginalNarrow)
{
if (g_fadeTextureMode == FadeTextureMode::Letterbox)
scaleY = NARROW_ASPECT_RATIO;
else
scaleX = 0.8f;
}
else
{
if (g_fadeTextureMode == FadeTextureMode::Letterbox && g_aspectRatio < WIDE_ASPECT_RATIO)
scaleY = WIDE_ASPECT_RATIO / g_aspectRatio;
else
scaleX = g_aspectRatio / WIDE_ASPECT_RATIO;
}
struct Vertex
{
be<float> x;
be<float> y;
be<float> z;
be<float> u;
be<float> v;
};
auto vertex = reinterpret_cast<Vertex*>(g_memory.base + r6.u32);
for (size_t i = 0; i < 6; i++)
{
vertex[i].u = (vertex[i].u - 0.5f) * scaleX + 0.5f;
vertex[i].v = (vertex[i].v - 0.5f) * scaleY + 0.5f;
}
}
}

View file

@ -868,3 +868,17 @@ registers = ["r3", "r4"]
name = "LoadingRenderMidAsmHook"
address = 0x824DB734
jump_address_on_true = 0x824DB738
[[midasm_hook]]
name = "FxFadePreRenderQuadMidAsmHook"
address = 0x82BA7D3C
registers = ["r31"]
[[midasm_hook]]
name = "FxFadePostRenderQuadMidAsmHook"
address = 0x82BA7D40
[[midasm_hook]]
name = "YggdrasillRenderQuadMidAsmHook"
address = 0x82E9FBA0
registers = ["r3", "r6"]