Skip to content

Commit ca94f16

Browse files
committed
SC:PT - Port everything to retail
1 parent d719147 commit ca94f16

5 files changed

Lines changed: 197 additions & 71 deletions

File tree

source/SplinterCellPandoraTomorrow.WidescreenFix/D3DDrv.ixx

Lines changed: 151 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,49 @@ namespace RainSplashFix
1717
float* pMaxSizeC75z = nullptr;
1818
float* pMaxSizeC75w = nullptr;
1919
float fOrigC73z = 0.0f, fOrigC75y = 0.0f, fOrigC75z = 0.0f, fOrigC75w = 0.0f;
20+
uint32_t* pDoneFlag = nullptr; // retail only
21+
22+
// Retail builds c73 on the stack and lazily stores c74/c75 as immediates
23+
void InitRetail()
24+
{
25+
auto pat = hook::module_pattern(GetModuleHandle(L"D3DDrv"), "F6 05 ? ? ? ? 02 75 ? 83 0D ? ? ? ? 02 C7 05 ? ? ? ? 00 00 00 41 C7 05 ? ? ? ? 00 40 9C 45 C7 05 ? ? ? ? 00 00 C0 41 C7 05 ? ? ? ? 00 00 F0 41");
26+
auto pat2 = hook::module_pattern(GetModuleHandle(L"D3DDrv"), "8B 0D ? ? ? ? DC 08 D9 05");
27+
if (pat.empty() || pat2.empty())
28+
return;
29+
30+
uint32_t* doneFlag = *pat.get_first<uint32_t*>(2);
31+
float* c73z = *pat2.get_first<float*>(2);
32+
if (!doneFlag || !c73z || *reinterpret_cast<uint32_t*>(c73z) != 0x46EA6000u)
33+
return;
34+
35+
pDoneFlag = doneFlag;
36+
pSizeScaleC73z = c73z;
37+
pSizeScaleC75y = pat.get_first<float>(32);
38+
pMaxSizeC75z = pat.get_first<float>(42);
39+
pMaxSizeC75w = pat.get_first<float>(52);
40+
41+
if (*reinterpret_cast<uint32_t*>(pSizeScaleC75y) != 0x459C4000u ||
42+
*reinterpret_cast<uint32_t*>(pMaxSizeC75z) != 0x41C00000u ||
43+
*reinterpret_cast<uint32_t*>(pMaxSizeC75w) != 0x41F00000u)
44+
return;
45+
46+
fOrigC73z = *pSizeScaleC73z;
47+
fOrigC75y = *pSizeScaleC75y;
48+
fOrigC75z = *pMaxSizeC75z;
49+
fOrigC75w = *pMaxSizeC75w;
50+
51+
bInitialized = true;
52+
}
2053

2154
void Init()
2255
{
2356
// Rain splash constant block (c73–c75)
2457
auto pattern = hook::module_pattern(GetModuleHandle(L"D3DDrv"), "6A 01 68 ? ? ? ? 6A 4B 8B 80 94 46 00 00");
2558
if (pattern.empty())
59+
{
60+
InitRetail();
2661
return;
62+
}
2763

2864
float* c75 = *pattern.get_first<float*>(3);
2965
if (!c75)
@@ -71,6 +107,9 @@ namespace RainSplashFix
71107
injector::WriteMemory<float>(pSizeScaleC75y, fOrigC75y * scale, true);
72108
injector::WriteMemory<float>(pMaxSizeC75z, fOrigC75z * scale, true);
73109
injector::WriteMemory<float>(pMaxSizeC75w, fOrigC75w * scale, true);
110+
111+
if (pDoneFlag) // retail: re-run the patched lazy initialiser
112+
injector::WriteMemory<uint32_t>(pDoneFlag, *pDoneFlag & ~2u, true);
74113
}
75114
}
76115

@@ -324,15 +363,13 @@ export void InitD3DDrv()
324363
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "55 8B EC 6A ? 68 ? ? ? ? 64 A1 ? ? ? ? 50 64 89 25 ? ? ? ? 81 EC ? ? ? ? 53 56 57 8B 7D ? 8B F1", "55 8B EC 6A ? 68 ? ? ? ? 64 A1 ? ? ? ? 50 81 EC ? ? ? ? A1 ? ? ? ? 33 C5 89 45 ? 56 57 50 8D 45 ? 64 A3 ? ? ? ? 8B F1 89 75");
325364
shUD3DRenderDeviceSetRes = safetyhook::create_inline(pattern.get_first(), UD3DRenderDeviceSetRes);
326365

327-
bool bRetailVersion = false;
366+
bool bRetailVersion = GetProcAddress(GetModuleHandle(L"D3DDrv"), "?Exec@UD3DRenderDevice@@UAEHPBGAAVFOutputDevice@@@Z") != nullptr;
328367

329368
// Water Blend Fix
330369
static DWORD OriginalAlphaBlendEnable = 0;
331370
static DWORD OriginalSrcBlend = 0;
332371
static DWORD OriginalDestBlend = 0;
333372

334-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "FF B5 ? ? ? ? 8B 07 6A ? FF B5");
335-
if (!pattern.empty())
336373
{
337374
static DWORD WaterBlendPS = 0;
338375
static thread_local bool bWaterFixApplied = false;
@@ -451,46 +488,86 @@ export void InitD3DDrv()
451488
}
452489
};
453490

454-
static auto WaterPreDrawPrimitiveHook1 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
491+
if (!bRetailVersion)
455492
{
456-
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.edi);
457-
WaterPreDraw(regs, pDevice);
458-
});
493+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "FF B5 ? ? ? ? 8B 07 6A ? FF B5");
494+
static auto WaterPreDrawPrimitiveHook1 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
495+
{
496+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.edi);
497+
WaterPreDraw(regs, pDevice);
498+
});
459499

460-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "F3 0F 10 9D ? ? ? ? 8B 95 ? ? ? ? F3 0F 10 25");
461-
static auto WaterPostDrawPrimitiveHook1 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
462-
{
463-
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.edi);
464-
WaterPostDraw(regs, pDevice);
465-
});
500+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "F3 0F 10 9D ? ? ? ? 8B 95 ? ? ? ? F3 0F 10 25");
501+
static auto WaterPostDrawPrimitiveHook1 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
502+
{
503+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.edi);
504+
WaterPostDraw(regs, pDevice);
505+
});
466506

467-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "FF B5 ? ? ? ? 8B 06 6A ? FF B5 ? ? ? ? 6A ? 6A ? 56 FF 90 ? ? ? ? F3 0F 10 9D");
468-
static auto WaterPreDrawPrimitiveHook2 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
469-
{
470-
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.esi);
471-
WaterPreDraw(regs, pDevice);
472-
});
507+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "FF B5 ? ? ? ? 8B 06 6A ? FF B5 ? ? ? ? 6A ? 6A ? 56 FF 90 ? ? ? ? F3 0F 10 9D");
508+
static auto WaterPreDrawPrimitiveHook2 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
509+
{
510+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.esi);
511+
WaterPreDraw(regs, pDevice);
512+
});
473513

474-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "F3 0F 10 9D ? ? ? ? 8B 95 ? ? ? ? 8B 8F");
475-
static auto WaterPostDrawPrimitiveHook2 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
514+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "F3 0F 10 9D ? ? ? ? 8B 95 ? ? ? ? 8B 8F");
515+
static auto WaterPostDrawPrimitiveHook2 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
516+
{
517+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.esi);
518+
WaterPostDraw(regs, pDevice);
519+
});
520+
}
521+
else
476522
{
477-
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.esi);
478-
WaterPostDraw(regs, pDevice);
479-
});
523+
// retail: device is in EBP at all four sites
524+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "8B 4C 24 ? 8B 45 00 51 6A 00 57 6A 00 6A 05 55 FF 90 1C 01 00 00 8B 83 EC 03 00 00");
525+
if (!pattern.empty())
526+
{
527+
static auto WaterPreDrawPrimitiveHook1Retail = safetyhook::create_mid(pattern.get_first(7), [](SafetyHookContext& regs)
528+
{
529+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.ebp);
530+
WaterPreDraw(regs, pDevice);
531+
});
480532

481-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "68 ? ? ? ? 50 8B 08 FF 51 ? 8B 07");
482-
static auto DeviceResetHook = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
483-
{
484-
IDirect3DDevice8* pDevice = *(IDirect3DDevice8**)(regs.edi);
485-
if (WaterBlendPS)
533+
static auto WaterPostDrawPrimitiveHook1Retail = safetyhook::create_mid(pattern.get_first(22), [](SafetyHookContext& regs)
534+
{
535+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.ebp);
536+
WaterPostDraw(regs, pDevice);
537+
});
538+
}
539+
540+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "8B 44 24 ? 8B 4C 24 ? 8B 55 00 50 6A 00 51 6A 00 6A 05 55 FF 92 1C 01 00 00 8B 8B EC 03 00 00");
541+
if (!pattern.empty())
486542
{
487-
pDevice->DeletePixelShader(WaterBlendPS);
488-
WaterBlendPS = 0;
543+
static auto WaterPreDrawPrimitiveHook2Retail = safetyhook::create_mid(pattern.get_first(11), [](SafetyHookContext& regs)
544+
{
545+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.ebp);
546+
WaterPreDraw(regs, pDevice);
547+
});
548+
549+
static auto WaterPostDrawPrimitiveHook2Retail = safetyhook::create_mid(pattern.get_first(26), [](SafetyHookContext& regs)
550+
{
551+
IDirect3DDevice8* pDevice = (IDirect3DDevice8*)(regs.ebp);
552+
WaterPostDraw(regs, pDevice);
553+
});
489554
}
490-
});
555+
}
556+
557+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "68 ? ? ? ? 50 8B 08 FF 51 ? 8B 07", "68 ? ? ? ? 50 FF 51 38 33 C9 3B C1");
558+
if (!pattern.empty())
559+
{
560+
static auto DeviceResetHook = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
561+
{
562+
IDirect3DDevice8* pDevice = *(IDirect3DDevice8**)(regs.edi);
563+
if (WaterBlendPS)
564+
{
565+
pDevice->DeletePixelShader(WaterBlendPS);
566+
WaterBlendPS = 0;
567+
}
568+
});
569+
}
491570
}
492-
else
493-
bRetailVersion = true;
494571

495572
//FMV
496573
UD3DRenderDevice::shDisplayVideo = safetyhook::create_inline(GetProcAddress(GetModuleHandle(L"D3DDrv"), "?DisplayVideo@UD3DRenderDevice@@UAEXPAVUCanvas@@PAX@Z"), UD3DRenderDevice::DisplayVideo);
@@ -594,12 +671,18 @@ export void InitD3DDrv()
594671
}
595672

596673
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "68 ? ? ? ? 68 ? ? ? ? 6A ? 6A ? 8B CF", "68 ? ? ? ? 68 ? ? ? ? 6A ? 6A ? FF 50 ? 8B 07");
597-
injector::WriteMemory(pattern.get_first(1), Screen.nReflectionsResolution, true);
598-
injector::WriteMemory(pattern.get_first(6), Screen.nReflectionsResolution, true);
674+
if (!pattern.empty())
675+
{
676+
injector::WriteMemory(pattern.get_first(1), Screen.nReflectionsResolution, true);
677+
injector::WriteMemory(pattern.get_first(6), Screen.nReflectionsResolution, true);
678+
}
599679

600-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "68 ? ? ? ? 68 ? ? ? ? 6A ? 6A ? 8B CB");
601-
injector::WriteMemory(pattern.get_first(1), Screen.nReflectionsResolution, true);
602-
injector::WriteMemory(pattern.get_first(6), Screen.nReflectionsResolution, true);
680+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "68 ? ? ? ? 68 ? ? ? ? 6A ? 6A ? 8B CB FF 50", "68 ? ? ? ? 68 ? ? ? ? 6A ? 6A ? 8B CB FF 52 ? 68 ? ? ? ? 68 ? ? ? ? 53 8D 4C 24 ? FF 15 ? ? ? ? 8B 45 ? 85 C0");
681+
if (!pattern.empty())
682+
{
683+
injector::WriteMemory(pattern.get_first(1), Screen.nReflectionsResolution, true);
684+
injector::WriteMemory(pattern.get_first(6), Screen.nReflectionsResolution, true);
685+
}
603686
}
604687

605688
if (Screen.nBloomResolutionMultiplier > 0)
@@ -614,24 +697,25 @@ export void InitD3DDrv()
614697
injector::WriteMemory(rpattern.get(4).get<uint32_t>(1), *rpattern.get(3).get<uint32_t>(1) * Screen.nBloomResolutionMultiplier, true);
615698
injector::WriteMemory(rpattern.get(4).get<uint32_t>(6), *rpattern.get(3).get<uint32_t>(6) * Screen.nBloomResolutionMultiplier, true);
616699

617-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "50 FF 51 ? 8B 45 ? 81 C6 ? ? ? ? 56 6A ? 6A");
700+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "50 FF 51 ? 8B 45 ? 81 C6 ? ? ? ? 56 6A ? 6A", "50 FF 52 ? 8B 07 8B 10 8D 8B ? ? ? ? 51 6A ? 6A ? 6A ? 6A ? 6A 20 6A 20 50");
618701
static auto ResHook1 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
619702
{
620703
*(uint32_t*)(regs.esp + 0x0) *= Screen.nBloomResolutionMultiplier;
621704
*(uint32_t*)(regs.esp + 0x4) *= Screen.nBloomResolutionMultiplier;
622705
});
623706

624-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "50 FF 51 ? 8B 4D ? 6A");
707+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "50 FF 51 ? 8B 4D ? 6A", "50 FF 52 50 6A ? 6A ? 8B CE FF 15 ? ? ? ? 8B 16 8D 8B E4 58");
625708
static auto ResHook2 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
626709
{
627710
*(uint32_t*)(regs.esp + 0x0) *= Screen.nBloomResolutionMultiplier;
628711
*(uint32_t*)(regs.esp + 0x4) *= Screen.nBloomResolutionMultiplier;
629712
});
630713

631-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "55 8B EC 6A ? 68 ? ? ? ? 64 A1 ? ? ? ? 50 81 EC ? ? ? ? A1 ? ? ? ? 33 C5 89 45 ? 53 56 57 50 8D 45 ? 64 A3 ? ? ? ? 8B D9 89 9D ? ? ? ? F3 0F 10 45");
632-
shsub_1009D270 = safetyhook::create_inline(pattern.get_first(), sub_1009D270);
714+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "55 8B EC 6A ? 68 ? ? ? ? 64 A1 ? ? ? ? 50 81 EC ? ? ? ? A1 ? ? ? ? 33 C5 89 45 ? 53 56 57 50 8D 45 ? 64 A3 ? ? ? ? 8B D9 89 9D ? ? ? ? F3 0F 10 45", "6A FF 68 ? ? ? ? 64 A1 ? ? ? ? 50 64 89 25 ? ? ? ? 81 EC ? ? ? ? 53 55 56 8B B4 24 ? ? ? ? 33 DB 3B F3 8B E9 57");
715+
if (!pattern.empty())
716+
shsub_1009D270 = safetyhook::create_inline(pattern.get_first(), sub_1009D270);
633717

634-
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "55 8B EC 83 EC ? A1 ? ? ? ? 33 C5 89 45 ? 8B 45 ? 8D 55");
718+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "55 8B EC 83 EC ? A1 ? ? ? ? 33 C5 89 45 ? 8B 45 ? 8D 55", "55 8B EC 6A FF 68 ? ? ? ? 64 A1 ? ? ? ? 50 64 89 25 ? ? ? ? 83 EC 24 8B 45 10 53 8B 5D 0C 56 57 8B 7D 08 8B F1");
635719
shsub_100A7850 = safetyhook::create_inline(pattern.get_first(), sub_100A7850);
636720
}
637721

@@ -704,7 +788,7 @@ export void InitD3DDrv()
704788
});
705789

706790
// EOceanInfo "Ocean2" culling fix
707-
pattern = hook::module_pattern(GetModuleHandle(L"D3DDrv"), "3D 2C 01 00 00 77 43 85 C0 0F 84 ? ? ? ? 6A 08 6A 01");
791+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "3D 2C 01 00 00 77 43 85 C0 0F 84 ? ? ? ? 6A 08 6A 01", "F9 2C 01 00 00 77 ? 85 C9 0F 86");
708792
if (!pattern.empty())
709793
injector::WriteMemory<uint8_t>(pattern.get_first(5), 0xEB, true); // ja -> jmp
710794

@@ -731,6 +815,28 @@ export void InitD3DDrv()
731815
}
732816
});
733817
}
818+
else
819+
{
820+
pattern = find_module_pattern(GetModuleHandle(L"D3DDrv"), "DB 45 08 8B 4C 24 1C 8B 11 D9 5C 24 14 FF 52 68 89 44 24 18 DB 44 24 18 8B 4C 24 1C 8B 01 D8 7C 24 14 D9 5C 24 18 DB 45 0C D9 5C 24 20 FF 50 6C 89 44 24 1C DB 44 24 1C D8 7C 24 20 D9 5C 24 1C");
821+
if (!pattern.empty())
822+
{
823+
static auto NightVisionGrainHookRetail = safetyhook::create_mid(pattern.get_first(0x40), [](SafetyHookContext& regs)
824+
{
825+
if (Screen.fGrainScale == 0.0f)
826+
return;
827+
828+
float* pGrainScaleU = reinterpret_cast<float*>(regs.esp + 0x18);
829+
float* pGrainScaleV = reinterpret_cast<float*>(regs.esp + 0x1C);
830+
float renderWidth = static_cast<float>(*reinterpret_cast<int32_t*>(regs.ebp + 0x8));
831+
float renderHeight = static_cast<float>(*reinterpret_cast<int32_t*>(regs.ebp + 0xC));
832+
if (renderWidth > 0.0f && renderHeight > 0.0f)
833+
{
834+
*pGrainScaleU *= 1.0f + (640.0f / renderWidth - 1.0f) * Screen.fGrainScale;
835+
*pGrainScaleV *= 1.0f + (480.0f / renderHeight - 1.0f) * Screen.fGrainScale;
836+
}
837+
});
838+
}
839+
}
734840

735841
InitShaders();
736842
}

source/SplinterCellPandoraTomorrow.WidescreenFix/Echelon.ixx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ namespace AEPlayerControllerCheckpoint
505505

506506
void Init()
507507
{
508-
FName_ctor = decltype(FName_ctor)(GetProcAddress(GetModuleHandle(L"Core"), "??0FName@@QAE@PB_WW4EFindName@@@Z"));
508+
FName_ctor = decltype(FName_ctor)(FindProcAddress(GetModuleHandle(L"Core"), "??0FName@@QAE@PB_WW4EFindName@@@Z", "??0FName@@QAE@PBGW4EFindName@@@Z"));
509509
FindFunction = decltype(FindFunction)(GetProcAddress(GetModuleHandle(L"Core"), "?FindFunction@UObject@@QAEPAVUFunction@@VFName@@H@Z"));
510510
ProcessEvent = decltype(ProcessEvent)(GetProcAddress(GetModuleHandle(L"Core"), "?ProcessEvent@UObject@@UAEXPAVUFunction@@PAX1@Z"));
511511
gNullSlot = (void**)GetProcAddress(GetModuleHandle(L"Core"), "?GNull@@3PAVFOutputDevice@@A");
@@ -519,10 +519,10 @@ namespace AEPlayerControllerCheckpoint
519519
if (auto pProcessInternal = GetProcAddress(GetModuleHandle(L"Core"), "?ProcessInternal@UObject@@QAEXAAUFFrame@@QAX@Z"))
520520
shProcessInternal = safetyhook::create_inline(pProcessInternal, ProcessInternalHook);
521521

522-
if (auto pLocalize = GetProcAddress(GetModuleHandle(L"Core"), "?Localize@@YAPB_WPB_W000H@Z"))
522+
if (auto pLocalize = FindProcAddress(GetModuleHandle(L"Core"), "?Localize@@YAPB_WPB_W000H@Z", "?Localize@@YAPBGPBG000H@Z"))
523523
shLocalize = safetyhook::create_inline(pLocalize, LocalizeHook);
524524

525-
if (auto pExec = GetProcAddress(GetModuleHandle(L"Engine"), "?Exec@UGameEngine@@UAEHPB_WAAVFOutputDevice@@@Z"))
525+
if (auto pExec = FindProcAddress(GetModuleHandle(L"Engine"), "?Exec@UGameEngine@@UAEHPB_WAAVFOutputDevice@@@Z", "?Exec@UGameEngine@@UAEHPBGAAVFOutputDevice@@@Z"))
526526
shUGameEngineExec = safetyhook::create_inline(pExec, UGameEngineExecHook);
527527
}
528528
}

0 commit comments

Comments
 (0)