Patch D3D_CommonSetRenderTarget

This commit is contained in:
Silent 2020-10-28 18:03:42 +01:00
parent 62af56b67a
commit cbe534cb54
No known key found for this signature in database
GPG Key ID: AE53149BB0C45AF1
3 changed files with 64 additions and 2 deletions

View File

@ -315,6 +315,7 @@ g_EmuCDPD = {0};
XB_MACRO(xbox::hresult_xt, WINAPI, Direct3D_CreateDevice_4, (xbox::X_D3DPRESENT_PARAMETERS*) ); \ XB_MACRO(xbox::hresult_xt, WINAPI, Direct3D_CreateDevice_4, (xbox::X_D3DPRESENT_PARAMETERS*) ); \
XB_MACRO(xbox::void_xt, WINAPI, Lock2DSurface, (xbox::X_D3DPixelContainer*, D3DCUBEMAP_FACES, xbox::uint_xt, D3DLOCKED_RECT*, RECT*, xbox::dword_xt) ); \ XB_MACRO(xbox::void_xt, WINAPI, Lock2DSurface, (xbox::X_D3DPixelContainer*, D3DCUBEMAP_FACES, xbox::uint_xt, D3DLOCKED_RECT*, RECT*, xbox::dword_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, Lock3DSurface, (xbox::X_D3DPixelContainer*, xbox::uint_xt, D3DLOCKED_BOX*, D3DBOX*, xbox::dword_xt) ); \ XB_MACRO(xbox::void_xt, WINAPI, Lock3DSurface, (xbox::X_D3DPixelContainer*, xbox::uint_xt, D3DLOCKED_BOX*, D3DBOX*, xbox::dword_xt) ); \
XB_MACRO(xbox::void_xt, WINAPI, D3D_CommonSetRenderTarget, (xbox::X_D3DSurface*, xbox::X_D3DSurface*, void*) ); \
XB_TRAMPOLINES(XB_trampoline_declare); XB_TRAMPOLINES(XB_trampoline_declare);
@ -7790,6 +7791,10 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(D3DDevice_LightEnable)
return hRet; return hRet;
} }
// SetRenderTarget can call CommonSetRenderTarget, nested call detection is required
// Test case: Midtown Madness 3
static thread_local uint32_t setRenderTargetCount = 0;
static void CxbxImpl_SetRenderTarget static void CxbxImpl_SetRenderTarget
( (
xbox::X_D3DSurface *pRenderTarget, xbox::X_D3DSurface *pRenderTarget,
@ -7878,6 +7883,8 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget)
LOG_FUNC_ARG(pNewZStencil) LOG_FUNC_ARG(pNewZStencil)
LOG_FUNC_END; LOG_FUNC_END;
NestedPatchCounter call(setRenderTargetCount);
XB_TRMP(D3DDevice_SetRenderTarget)(pRenderTarget, pNewZStencil); XB_TRMP(D3DDevice_SetRenderTarget)(pRenderTarget, pNewZStencil);
CxbxImpl_SetRenderTarget(pRenderTarget, pNewZStencil); CxbxImpl_SetRenderTarget(pRenderTarget, pNewZStencil);
@ -7885,11 +7892,28 @@ xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget)
// LTCG specific D3DDevice_SetRenderTarget function... // LTCG specific D3DDevice_SetRenderTarget function...
// Passes pRenderTarget in ecx and pNewZStencil in eax // Passes pRenderTarget in ecx and pNewZStencil in eax
static void D3DDevice_SetRenderTarget_0
(
xbox::X_D3DSurface *pRenderTarget,
xbox::X_D3DSurface *pNewZStencil
)
{
LOG_FUNC_BEGIN LOG_FUNC_BEGIN
LOG_FUNC_ARG(pRenderTarget) LOG_FUNC_ARG(pRenderTarget)
LOG_FUNC_ARG(pNewZStencil) LOG_FUNC_ARG(pNewZStencil)
LOG_FUNC_END; LOG_FUNC_END;
NestedPatchCounter call(setTransformCount);
__asm {
mov ecx, pRenderTarget
mov eax, pNewZStencil
call XB_TRMP(D3DDevice_SetRenderTarget_0)
}
CxbxImpl_SetRenderTarget(pRenderTarget, pNewZStencil);
}
__declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget_0) __declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget_0)
( (
) )
@ -7904,10 +7928,10 @@ __declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget_
sub esp, __LOCAL_SIZE sub esp, __LOCAL_SIZE
mov pRenderTarget, ecx mov pRenderTarget, ecx
mov pNewZStencil, eax mov pNewZStencil, eax
call XB_TRMP(D3DDevice_SetRenderTarget_0)
} }
CxbxImpl_SetRenderTarget(pRenderTarget, pNewZStencil); // Actual function body
D3DDevice_SetRenderTarget_0(pRenderTarget, pNewZStencil);
// epilogue // epilogue
__asm { __asm {
@ -7917,6 +7941,33 @@ __declspec(naked) xbox::void_xt WINAPI xbox::EMUPATCH(D3DDevice_SetRenderTarget_
} }
} }
// ******************************************************************
// * patch: D3D_CommonSetRenderTarget
// ******************************************************************
// This is an internal function, but some LTCG games inline SetRenderTarget and call it directly
// Test-case: Midtown Madness 3
xbox::void_xt WINAPI xbox::EMUPATCH(D3D_CommonSetRenderTarget)
(
X_D3DSurface *pRenderTarget,
X_D3DSurface *pNewZStencil,
void *unknown
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pRenderTarget)
LOG_FUNC_ARG(pNewZStencil)
LOG_FUNC_ARG(unknown)
LOG_FUNC_END;
NestedPatchCounter call(setRenderTargetCount);
XB_TRMP(D3D_CommonSetRenderTarget)(pRenderTarget, pNewZStencil, unknown);
if (call.GetLevel() == 0) {
CxbxImpl_SetRenderTarget(pRenderTarget, pNewZStencil);
}
}
// LTCG specific D3DDevice_SetPalette function... // LTCG specific D3DDevice_SetPalette function...
// This uses a custom calling convention where parameter is passed in EAX // This uses a custom calling convention where parameter is passed in EAX

View File

@ -1517,6 +1517,16 @@ xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetRenderTarget)
// ****************************************************************** // ******************************************************************
xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetRenderTarget_0)(); xbox::void_xt WINAPI EMUPATCH(D3DDevice_SetRenderTarget_0)();
// ******************************************************************
// * patch: D3D_CommonSetRenderTarget
// ******************************************************************
xbox::void_xt WINAPI EMUPATCH(D3D_CommonSetRenderTarget)
(
X_D3DSurface *pRenderTarget,
X_D3DSurface *pNewZStencil,
void *unknown
);
// ****************************************************************** // ******************************************************************
// * patch: D3DDevice_SetPalette // * patch: D3DDevice_SetPalette
// ****************************************************************** // ******************************************************************

View File

@ -183,6 +183,7 @@ std::map<const std::string, const xbox_patch_t> g_PatchTable = {
PATCH_ENTRY("D3DResource_BlockUntilNotBusy", xbox::EMUPATCH(D3DResource_BlockUntilNotBusy), PATCH_HLE_D3D), PATCH_ENTRY("D3DResource_BlockUntilNotBusy", xbox::EMUPATCH(D3DResource_BlockUntilNotBusy), PATCH_HLE_D3D),
PATCH_ENTRY("D3D_BlockOnTime", xbox::EMUPATCH(D3D_BlockOnTime), PATCH_HLE_D3D), PATCH_ENTRY("D3D_BlockOnTime", xbox::EMUPATCH(D3D_BlockOnTime), PATCH_HLE_D3D),
PATCH_ENTRY("D3D_BlockOnTime_4", xbox::EMUPATCH(D3D_BlockOnTime_4), PATCH_HLE_D3D), PATCH_ENTRY("D3D_BlockOnTime_4", xbox::EMUPATCH(D3D_BlockOnTime_4), PATCH_HLE_D3D),
PATCH_ENTRY("D3D_CommonSetRenderTarget", xbox::EMUPATCH(D3D_CommonSetRenderTarget), PATCH_HLE_D3D),
PATCH_ENTRY("D3D_DestroyResource", xbox::EMUPATCH(D3D_DestroyResource), PATCH_HLE_D3D), PATCH_ENTRY("D3D_DestroyResource", xbox::EMUPATCH(D3D_DestroyResource), PATCH_HLE_D3D),
PATCH_ENTRY("D3D_DestroyResource__LTCG", xbox::EMUPATCH(D3D_DestroyResource__LTCG), PATCH_HLE_D3D), PATCH_ENTRY("D3D_DestroyResource__LTCG", xbox::EMUPATCH(D3D_DestroyResource__LTCG), PATCH_HLE_D3D),
PATCH_ENTRY("D3D_LazySetPointParams", xbox::EMUPATCH(D3D_LazySetPointParams), PATCH_HLE_D3D), PATCH_ENTRY("D3D_LazySetPointParams", xbox::EMUPATCH(D3D_LazySetPointParams), PATCH_HLE_D3D),