diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 81a71f11..a3b23ac3 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -2023,12 +2023,37 @@ static void ProcStretchRect(const RenderCommand& cmd) AddBarrier(args.texture, RenderTextureLayout::SHADER_READ); } +static void SetDefaultViewport(GuestDevice* device, GuestSurface* surface) +{ + if (surface != nullptr) + { + RenderCommand cmd; + cmd.type = RenderCommandType::SetViewport; + cmd.setViewport.x = 0.0f; + cmd.setViewport.y = 0.0f; + cmd.setViewport.width = float(surface->width); + cmd.setViewport.height = float(surface->height); + cmd.setViewport.minDepth = 0.0f; + cmd.setViewport.maxDepth = 1.0f; + g_renderQueue.enqueue(cmd); + + device->viewport.x = 0.0f; + device->viewport.y = 0.0f; + device->viewport.width = float(surface->width); + device->viewport.height = float(surface->height); + device->viewport.minZ = 0.0f; + device->viewport.maxZ = 1.0f; + } +} + static void SetRenderTarget(GuestDevice* device, uint32_t index, GuestSurface* renderTarget) { RenderCommand cmd; cmd.type = RenderCommandType::SetRenderTarget; cmd.setRenderTarget.renderTarget = renderTarget; g_renderQueue.enqueue(cmd); + + SetDefaultViewport(device, renderTarget); } static void ProcSetRenderTarget(const RenderCommand& cmd) @@ -2049,6 +2074,8 @@ static void SetDepthStencilSurface(GuestDevice* device, GuestSurface* depthStenc cmd.type = RenderCommandType::SetDepthStencilSurface; cmd.setDepthStencilSurface.depthStencil = depthStencil; g_renderQueue.enqueue(cmd); + + SetDefaultViewport(device, depthStencil); } static void ProcSetDepthStencilSurface(const RenderCommand& cmd) @@ -2996,6 +3023,8 @@ static void SetVertexDeclaration(GuestDevice* device, GuestVertexDeclaration* ve cmd.type = RenderCommandType::SetVertexDeclaration; cmd.setVertexDeclaration.vertexDeclaration = vertexDeclaration; g_renderQueue.enqueue(cmd); + + device->vertexDeclaration = g_memory.MapVirtual(vertexDeclaration); } static void ProcSetVertexDeclaration(const RenderCommand& cmd) @@ -3693,9 +3722,13 @@ static void SetResolution(be* device) device[47] = height == 0 ? 720 : height; } -static uint32_t StubFunction() +// The game does some weird stuff to render targets if they are above +// 1024x1024 resolution, setting this bool at address 20 seems to avoid all that. +PPC_FUNC(sub_82E9F048) { - return 0; + PPC_STORE_U8(ctx.r4.u32 + 20, 1); + PPC_STORE_U32(ctx.r4.u32 + 44, PPC_LOAD_U32(ctx.r4.u32 + 8)); // Width + PPC_STORE_U32(ctx.r4.u32 + 48, PPC_LOAD_U32(ctx.r4.u32 + 12)); // Height } static GuestShader* g_movieVertexShader; @@ -3890,7 +3923,6 @@ GUEST_FUNCTION_HOOK(sub_82C00910, D3DXFillVolumeTexture); GUEST_FUNCTION_HOOK(sub_82E43FC8, MakePictureData); GUEST_FUNCTION_HOOK(sub_82E9EE38, SetResolution); -GUEST_FUNCTION_HOOK(sub_82BE77B0, StubFunction); GUEST_FUNCTION_HOOK(sub_82AE2BF8, ScreenShaderInit); diff --git a/UnleashedRecomp/kernel/imports.cpp b/UnleashedRecomp/kernel/imports.cpp index 6821b7b8..c5b05f9f 100644 --- a/UnleashedRecomp/kernel/imports.cpp +++ b/UnleashedRecomp/kernel/imports.cpp @@ -664,7 +664,7 @@ void RtlRaiseException_x() void KfReleaseSpinLock(uint32_t* spinLock) { //printf("!!! STUB !!! KfReleaseSpinLock\n"); - *spinLock = 0; + InterlockedExchange((volatile long*)spinLock, 0); } void KfAcquireSpinLock(uint32_t* spinLock) @@ -711,7 +711,7 @@ void VdGetSystemCommandBuffer() void KeReleaseSpinLockFromRaisedIrql(uint32_t* spinLock) { //printf("!!! STUB !!! KeReleaseSpinLockFromRaisedIrql\n"); - *spinLock = 0; + InterlockedExchange((volatile long*)spinLock, 0); } void KeAcquireSpinLockAtRaisedIrql(uint32_t* spinLock) diff --git a/UnleashedRecomp/patches/fps_patches.cpp b/UnleashedRecomp/patches/fps_patches.cpp index 5de2f40c..0542c204 100644 --- a/UnleashedRecomp/patches/fps_patches.cpp +++ b/UnleashedRecomp/patches/fps_patches.cpp @@ -3,6 +3,9 @@ #include "ui/window.h" #include "config.h" +float m_lastLoadingFrameDelta = 0.0f; +std::chrono::steady_clock::time_point m_lastLoadingFrameTime; + void HighFrameRateDeltaTimeFixMidAsmHook(PPCRegister& f1) { // Having 60 FPS threshold ensures we still retain @@ -58,3 +61,15 @@ void Camera2DSlopeLerpFixMidAsmHook(PPCRegister& t, PPCRegister& deltaTime) { t.f64 = ComputeLerpFactor(t.f64, deltaTime.f64 / 60.0); } + +void LoadingScreenSpeedFixMidAsmHook(PPCRegister& r4) +{ + auto now = std::chrono::high_resolution_clock::now(); + + m_lastLoadingFrameDelta = std::min(std::chrono::duration(now - m_lastLoadingFrameTime).count(), 1.0f / 15.0f); + m_lastLoadingFrameTime = now; + + auto pDeltaTime = (be*)g_memory.Translate(r4.u32); + + *pDeltaTime = m_lastLoadingFrameDelta; +} diff --git a/UnleashedRecomp/stdafx.h b/UnleashedRecomp/stdafx.h index b0075c44..96152f7b 100644 --- a/UnleashedRecomp/stdafx.h +++ b/UnleashedRecomp/stdafx.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index 2d44cb33..8d2fe1a3 100644 --- a/UnleashedRecompLib/config/SWA.toml +++ b/UnleashedRecompLib/config/SWA.toml @@ -417,3 +417,8 @@ jump_address_on_true = 0x827D20EC name = "ParticleTestDrawIndexedPrimitiveMidAsmHook" address = 0x827D25AC registers = ["r7"] + +[[midasm_hook]] +name = "LoadingScreenSpeedFixMidAsmHook" +address = 0x824DAB60 +registers = ["r4"] diff --git a/thirdparty/ShaderRecomp b/thirdparty/ShaderRecomp index b7c03722..30f59860 160000 --- a/thirdparty/ShaderRecomp +++ b/thirdparty/ShaderRecomp @@ -1 +1 @@ -Subproject commit b7c037224665ac826490c142b800b11dfc4acf49 +Subproject commit 30f598604767602e3afce56b947e99dba2b51211