diff --git a/SAFix/SAFix.vcxproj b/SAFix/SAFix.vcxproj index e96da57..8184504 100644 --- a/SAFix/SAFix.vcxproj +++ b/SAFix/SAFix.vcxproj @@ -19,6 +19,7 @@ DynamicLibrary true MultiByte + v100 DynamicLibrary @@ -48,7 +49,7 @@ Disabled MultiThreadedDebug SILENTPATCH_SA_VER;%(PreprocessorDefinitions) - D:\RWSDK\Graphics\rwsdk\include\d3d9 + D:\RWSDK\Graphics\rwsdk\include\d3d9;C:\Program Files\Microsoft DirectX SDK (June 2010)\Include Use @@ -100,6 +101,15 @@ + + Document + "C:\Program Files\Microsoft DirectX SDK (June 2010)\Utilities\bin\x86\fxc.exe" /T vs_2_0 /E NVC_vertex_shader /Fh ..\SilentPatch\nvc.h ..\SilentPatch\nvc.fx + ..\SilentPatch\nvc.h + Compiling shaders... + "C:\Program Files\Microsoft DirectX SDK (June 2010)\Utilities\bin\x86\fxc.exe" /T vs_2_0 /E NVC_vertex_shader /Fh ..\SilentPatch\nvc.h ..\SilentPatch\nvc.fx + Compiling shaders... + ..\SilentPatch\nvc.h + diff --git a/SAFix/SAFix.vcxproj.filters b/SAFix/SAFix.vcxproj.filters index f76985f..1300fd1 100644 --- a/SAFix/SAFix.vcxproj.filters +++ b/SAFix/SAFix.vcxproj.filters @@ -65,4 +65,7 @@ Header Files + + + \ No newline at end of file diff --git a/SilentPatch/Vehicle.cpp b/SilentPatch/Vehicle.cpp index 1b8e333..dfdaacf 100644 --- a/SilentPatch/Vehicle.cpp +++ b/SilentPatch/Vehicle.cpp @@ -74,6 +74,8 @@ void CHeli::Render() void CPlane::Render() { double dRotorsSpeed, dMovingRotorSpeed; + bool bHasMovingProp = m_pCarNode[12] != nullptr; + bool bHasMovingProp2 = m_pCarNode[14] != nullptr; m_nTimeTillWeNeedThisCar = *CTimer::m_snTimeInMilliseconds + 3000; @@ -94,7 +96,7 @@ void CPlane::Render() RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[11], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) - SetComponentAtomicAlpha(pOutAtomic, nStaticRotorAlpha); + SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nStaticRotorAlpha : 255); } if ( m_pCarNode[13] ) @@ -102,10 +104,10 @@ void CPlane::Render() RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) - SetComponentAtomicAlpha(pOutAtomic, nStaticRotorAlpha); + SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nStaticRotorAlpha : 255); } - if ( m_pCarNode[12] ) + if ( bHasMovingProp ) { RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic); @@ -113,7 +115,7 @@ void CPlane::Render() SetComponentAtomicAlpha(pOutAtomic, nMovingRotorAlpha); } - if ( m_pCarNode[14] ) + if ( bHasMovingProp2 ) { RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic); diff --git a/SilentPatch/dllmain.cpp b/SilentPatch/dllmain.cpp index 6e068bc..273dae4 100644 --- a/SilentPatch/dllmain.cpp +++ b/SilentPatch/dllmain.cpp @@ -1290,7 +1290,7 @@ void __declspec(naked) ResetAlphaFuncRefAfterRender() } } -bool bUseTwoPass = false; +static bool bUseTwoPass = false; void SetRendererForAtomic(RpAtomic* pAtomic) { @@ -1523,10 +1523,206 @@ void __declspec(naked) DumpIPLStub() #endif +#include + +#include "nvc.h" + +static IDirect3DVertexShader9* pNVCShader = nullptr; +static bool bRenderNVC; +static RpAtomic* pRenderedAtomic; + +WRAPPER void _rwD3D9SetVertexShader(void *shader) { EAXJMP(0x7F9FB0); } +WRAPPER RwBool RwD3D9CreateVertexShader(const RwUInt32 *function, void **shader) { EAXJMP(0x7FAC60); } +WRAPPER void RwD3D9DeleteVertexShader(void *shader) { EAXJMP(0x7FAC90); } +WRAPPER void _rwD3D9VSGetComposedTransformMatrix(void *transformMatrix) { EAXJMP(0x7646E0); } +WRAPPER void _rwD3D9VSSetActiveWorldMatrix(const RwMatrix *worldMatrix) { EAXJMP(0x764650); } +WRAPPER RwMatrix* RwFrameGetLTM(RwFrame* frame) { EAXJMP(0x7F0990); } +WRAPPER void _rwD3D9SetVertexShaderConstant(RwUInt32 registerAddress, + const void *constantData, + RwUInt32 constantCount) { EAXJMP(0x7FACA0); } + +WRAPPER RwBool _rpD3D9VertexDeclarationInstColor(RwUInt8 *mem, + const RwRGBA *color, + RwInt32 numVerts, + RwUInt32 stride) { EAXJMP(0x754AE0); } + +void CompileShader() +{ + static bool bCompiledYet = false; + + if ( !bCompiledYet ) + { + bCompiledYet = true; + RwD3D9CreateVertexShader(reinterpret_cast(g_vs20_NVC_vertex_shader), reinterpret_cast(&pNVCShader)); + } +} + +void SetShader(void* shader) +{ + if ( bRenderNVC ) + { + // TODO: Daynight balance var + D3DMATRIX outMat; + float fDayNightBalance = *(float*)0x8D12C0; + + RwD3D9SetVertexShader(pNVCShader); + + _rwD3D9VSSetActiveWorldMatrix(RwFrameGetLTM(RpAtomicGetFrame(pRenderedAtomic))); + _rwD3D9VSGetComposedTransformMatrix(&outMat); + + RwD3D9SetVertexShaderConstant(0, &outMat, 4); + RwD3D9SetVertexShaderConstant(4, &fDayNightBalance, 1); + } + else + RwD3D9SetVertexShader(shader); +} + +void __declspec(naked) SetShader2() +{ + _asm + { + mov bRenderNVC, 1 + push ecx + push edx + push edi + push ebp + call CompileShader + mov eax, 5DA6A0h + call eax + add esp, 10h + mov bRenderNVC, 0 + retn + } +} + +void __declspec(naked) HijackAtomic() +{ + _asm + { + mov eax, [esp+8] + mov pRenderedAtomic, eax + mov eax, 5D6480h + jmp eax + } +} + +void __declspec(naked) UsageIndex1() +{ + _asm + { + mov byte ptr [esp+eax*8+27h], 1 + inc eax + + push 5D611Bh + retn + } +} + +static void* pJackedEsi; + +void __declspec(naked) HijackEsi() +{ + _asm + { + mov [esp+48h-2Ch], eax + mov pJackedEsi, esi + lea esi, [ebp+44h] + + mov eax, 5D6382h + jmp eax + } +} + +void __declspec(naked) PassDayColoursToShader() +{ + _asm + { + mov [esp+54h],eax + jz PassDayColoursToShader_FindDayColours + mov eax, 5D6382h + jmp eax + +PassDayColoursToShader_FindDayColours: + xor eax, eax + +PassDayColoursToShader_FindDayColours_Loop: + cmp byte ptr [esp+eax*8+48h-28h+6], D3DDECLUSAGE_COLOR + jnz PassDayColoursToShader_FindDayColours_Next + cmp byte ptr [esp+eax*8+48h-28h+7], 1 + jz PassDayColoursToShader_DoDayColours + +PassDayColoursToShader_FindDayColours_Next: + inc eax + jmp PassDayColoursToShader_FindDayColours_Loop + +PassDayColoursToShader_DoDayColours: + mov esi, pJackedEsi + mov edx, 8D12BCh + mov edx, dword ptr [edx] + mov edx, dword ptr [edx+esi+4] + mov edi, dword ptr [ebp+18h] + mov [esp+48h+4], edx + mov edx, dword ptr [ebp+4] + lea eax, [esp+eax*8+48h-26h] + mov [esp+48h+0Ch], edx + mov [esp+48h-2Ch], eax + lea esi, [ebp+44h] + +PassDayColoursToShader_Iterate: + mov edx, dword ptr [esi+14h] + mov eax, dword ptr [esi] + push edi + push edx + mov edx, dword ptr [esp+50h+4] + lea edx, [edx+eax*4] + imul eax, edi + push edx + mov edx, dword ptr [esp+54h-2Ch] + movzx edx, word ptr [edx] + add ecx, eax + add edx, ecx + push edx + call _rpD3D9VertexDeclarationInstColor + mov ecx, dword ptr [esp+58h-34h] + mov [esi+8], eax + mov eax, dword ptr [esp+58h+0Ch] + add esp, 10h + add esi, 24h + dec eax + mov [esp+48h+0Ch], eax + jnz PassDayColoursToShader_Iterate + + mov eax, 5D63BDh + jmp eax + } +} + __forceinline void Patch_SA_10() { using namespace MemoryVP; + // TEMP - shaders! + /*InjectHook(0x5DA743, SetShader); + InjectHook(0x5D66F1, SetShader2); + InjectHook(0x5D6116, UsageIndex1, PATCH_JUMP); + InjectHook(0x5D63B7, PassDayColoursToShader, PATCH_JUMP); + InjectHook(0x5D637B, HijackEsi, PATCH_JUMP); + Patch(0x5D67F4, HijackAtomic); + Patch(0x5D7200, 0xC3); + Patch(0x5D67BB, 0x6890); + Patch(0x5D67D7, 0x6890); + Patch(0x5D67BD, 0x5D5FE0); + Patch(0x5D67D9, 0x5D5FE0); + + Patch(0x5D60D9, D3DDECLTYPE_D3DCOLOR); + Patch(0x5D60E2, D3DDECLUSAGE_COLOR); + Patch(0x5D60CF, sizeof(D3DCOLOR)); + Patch(0x5D60EA, sizeof(D3DCOLOR)); + Patch(0x5D60C2, 0x13); + Patch(0x5D62F0, 0xEB);*/ + + //Patch(0x5D7265, 0xEB); + // Temp CTimer::m_snTimeInMilliseconds = *(int**)0x4242D1; @@ -1591,7 +1787,7 @@ __forceinline void Patch_SA_10() // Cars getting dirty // Only 1.0 and Steam - InjectMethod(0x4C9648, CVehicleModelInfo::FindEditableMaterialList, PATCH_CALL); + InjectMethodVP(0x4C9648, CVehicleModelInfo::FindEditableMaterialList, PATCH_CALL); Patch(0x4C964D, 0x0FEBCE8B); Patch(0x5D5DC2, 32); // 1.0 ONLY @@ -1693,5 +1889,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) else if (*(DWORD*)0x85EC4A == 0x94BF) Patch_SA_Steam(); #endif } + /*else if ( fdwReason == DLL_PROCESS_DETACH ) + { + if ( pNVCShader ) + RwD3D9DeleteVertexShader(pNVCShader); + }*/ return TRUE; } \ No newline at end of file diff --git a/SilentPatch/nvc.fx b/SilentPatch/nvc.fx new file mode 100644 index 0000000..f6136d4 --- /dev/null +++ b/SilentPatch/nvc.fx @@ -0,0 +1,28 @@ +struct VS_INPUT +{ + float4 Position : POSITION; + float2 Texture : TEXCOORD0; + float4 NightColor : COLOR0; + float4 DayColor : COLOR1; +}; + +struct VS_OUTPUT +{ + float4 Position : POSITION; + float2 Texture : TEXCOORD0; + float4 Color : COLOR0; +}; + +float4x4 viewProjMatrix : register(c0); +float fDayNightBalance : register(c4); + +VS_OUTPUT NVC_vertex_shader( in VS_INPUT In ) +{ + VS_OUTPUT Out; + + Out.Position = mul(In.Position, viewProjMatrix); + Out.Texture = In.Texture; + Out.Color = In.DayColor * (1.0-fDayNightBalance) + In.NightColor * fDayNightBalance; + + return Out; +} \ No newline at end of file diff --git a/SilentPatch/nvc.h b/SilentPatch/nvc.h new file mode 100644 index 0000000..42fda30 --- /dev/null +++ b/SilentPatch/nvc.h @@ -0,0 +1,114 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 +// +// fxc /T vs_2_0 /E NVC_vertex_shader /Fh ..\SilentPatch\nvc.h +// ..\SilentPatch\nvc.fx +// +// +// Parameters: +// +// float fDayNightBalance; +// float4x4 viewProjMatrix; +// +// +// Registers: +// +// Name Reg Size +// ---------------- ----- ---- +// viewProjMatrix c0 4 +// fDayNightBalance c4 1 +// + + vs_2_0 + def c5, 1, 0, 0, 0 + dcl_position v0 + dcl_texcoord v1 + dcl_color v2 + dcl_color1 v3 + dp4 oPos.x, v0, c0 + dp4 oPos.y, v0, c1 + dp4 oPos.z, v0, c2 + dp4 oPos.w, v0, c3 + mov r0.x, c4.x + add r0.x, -r0.x, c5.x + mul r1, v2, c4.x + mad oD0, v3, r0.x, r1 + mov oT0.xy, v1 + +// approximately 9 instruction slots used +#endif + +const BYTE g_vs20_NVC_vertex_shader[] = +{ + 0, 2, 254, 255, 254, 255, + 49, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 143, 0, + 0, 0, 0, 2, 254, 255, + 2, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 136, 0, 0, 0, 68, 0, + 0, 0, 2, 0, 4, 0, + 1, 0, 18, 0, 88, 0, + 0, 0, 0, 0, 0, 0, + 104, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 2, 0, + 120, 0, 0, 0, 0, 0, + 0, 0, 102, 68, 97, 121, + 78, 105, 103, 104, 116, 66, + 97, 108, 97, 110, 99, 101, + 0, 171, 171, 171, 0, 0, + 3, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 118, 105, 101, 119, + 80, 114, 111, 106, 77, 97, + 116, 114, 105, 120, 0, 171, + 3, 0, 3, 0, 4, 0, + 4, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 118, 115, + 95, 50, 95, 48, 0, 77, + 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, + 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, + 32, 67, 111, 109, 112, 105, + 108, 101, 114, 32, 57, 46, + 50, 57, 46, 57, 53, 50, + 46, 51, 49, 49, 49, 0, + 81, 0, 0, 5, 5, 0, + 15, 160, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 0, 128, 1, 0, 15, 144, + 31, 0, 0, 2, 10, 0, + 0, 128, 2, 0, 15, 144, + 31, 0, 0, 2, 10, 0, + 1, 128, 3, 0, 15, 144, + 9, 0, 0, 3, 0, 0, + 1, 192, 0, 0, 228, 144, + 0, 0, 228, 160, 9, 0, + 0, 3, 0, 0, 2, 192, + 0, 0, 228, 144, 1, 0, + 228, 160, 9, 0, 0, 3, + 0, 0, 4, 192, 0, 0, + 228, 144, 2, 0, 228, 160, + 9, 0, 0, 3, 0, 0, + 8, 192, 0, 0, 228, 144, + 3, 0, 228, 160, 1, 0, + 0, 2, 0, 0, 1, 128, + 4, 0, 0, 160, 2, 0, + 0, 3, 0, 0, 1, 128, + 0, 0, 0, 129, 5, 0, + 0, 160, 5, 0, 0, 3, + 1, 0, 15, 128, 2, 0, + 228, 144, 4, 0, 0, 160, + 4, 0, 0, 4, 0, 0, + 15, 208, 3, 0, 228, 144, + 0, 0, 0, 128, 1, 0, + 228, 128, 1, 0, 0, 2, + 0, 0, 3, 224, 1, 0, + 228, 144, 255, 255, 0, 0 +};