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
+};