#include "StdAfxSA.h" //#include "Timer.h" #include "General.h" #include "Vehicle.h" #include "LinkList.h" #include "ModelInfoSA.h" #include "AudioHardware.h" #include "Script.h" struct RsGlobalType { const char* AppName; unsigned int unkWidth, unkHeight; unsigned int MaximumWidth; unsigned int MaximumHeight; unsigned int frameLimit; BOOL quit; void* ps; void* keyboard; void* mouse; void* pad; }; struct AlphaObjectInfo { RpAtomic* pAtomic; RpAtomic* (*callback)(RpAtomic*, float); float fCompareValue; friend bool operator < (const AlphaObjectInfo &a, const AlphaObjectInfo &b) { return a.fCompareValue < b.fCompareValue; } }; // CVisibilityPlugins clump plugin struct ClumpVisibilityPlugin { BOOL (*visibilityCallback)(RpClump*); unsigned int alpha; }; #ifndef SA_STEAM_TEST WRAPPER void RwD3D9SetRenderState(RwUInt32 state, RwUInt32 value) { WRAPARG(state); WRAPARG(value); EAXJMP(0x7FC2D0); } WRAPPER void RenderOneXLUSprite(float x, float y, float z, float width, float height, int r, int g, int b, int a, float w, char, char, char) { EAXJMP(0x70D000); } #else WRAPPER void RwD3D9SetRenderState(RwUInt32 state, RwUInt32 value) { EAXJMP(0x836290); } WRAPPER void RenderOneXLUSprite(float x, float y, float z, float width, float height, int r, int g, int b, int a, float w, char, char, char) { EAXJMP(0x7592C0); } #endif WRAPPER const char* GetFrameNodeName(RwFrame* pFrame) { WRAPARG(pFrame); EAXJMP(0x72FB30); } #if defined SILENTPATCH_VC_VER bool* bSnapShotActive; static const void* RosieAudioFix_JumpBack; #elif defined SILENTPATCH_III_VER static void (*DrawRect)(const CRect&,const CRGBA&); static void (*SetScale)(float,float); static int* InstantHitsFiredByPlayer; static signed char* pGangModelOverrides; static const void* HeadlightsFix_JumpBack; #elif defined SILENTPATCH_SA_VER bool* bSnapShotActive; #endif void (__stdcall *AudioResetTimers)(unsigned int); static void (*PrintString)(float,float,const wchar_t*); static bool* bWantsToDrawHud; static bool* bCamCheck; static RsGlobalType* RsGlobal; static const float* ResolutionWidthMult; static const float* ResolutionHeightMult; static const void* SubtitlesShadowFix_JumpBack; #if defined SILENTPATCH_III_VER void ShowRadarTrace(float fX, float fY, unsigned int nScale, BYTE r, BYTE g, BYTE b, BYTE a) { if ( *bWantsToDrawHud == true && !*bCamCheck ) { DrawRect(CRect( fX - ((nScale+1.0f) * *ResolutionWidthMult * RsGlobal->MaximumWidth), fY + ((nScale+1.0f) * *ResolutionHeightMult * RsGlobal->MaximumHeight), fX + ((nScale+1.0f) * *ResolutionWidthMult * RsGlobal->MaximumWidth), fY - ((nScale+1.0f) * *ResolutionHeightMult * RsGlobal->MaximumHeight)), CRGBA(0, 0, 0, a)); DrawRect(CRect( fX - (nScale * *ResolutionWidthMult * RsGlobal->MaximumWidth), fY + (nScale * *ResolutionHeightMult * RsGlobal->MaximumHeight), fX + (nScale * *ResolutionWidthMult * RsGlobal->MaximumWidth), fY - (nScale * *ResolutionHeightMult * RsGlobal->MaximumHeight)), CRGBA(r, g, b, a)); } } void SetScaleProperly(float fX, float fY) { SetScale(fX * *ResolutionWidthMult * RsGlobal->MaximumWidth, fY * *ResolutionHeightMult * RsGlobal->MaximumHeight); } void PurpleNinesGlitchFix() { for ( int i = 0; i < 9; ++i ) pGangModelOverrides[i * 16] = -1; } void __declspec(naked) M16StatsFix() { _asm { add eax, 34h add ebx, 34h mov ecx, [InstantHitsFiredByPlayer] inc [ecx] retn } } void __declspec(naked) HeadlightsFix() { static const float fMinusOne = -1.0f; _asm { fld [esp+708h-690h] fcomp fMinusOne fnstsw ax and ah, 5 cmp ah, 1 jnz HeadlightsFix_DontLimit fld fMinusOne fstp [esp+708h-690h] HeadlightsFix_DontLimit: fld [esp+708h-690h] fabs fld st jmp [HeadlightsFix_JumpBack] } } static float fShadowXSize, fShadowYSize; void __stdcall Recalculate(signed int nShadow) { fShadowXSize = nShadow * *ResolutionWidthMult * RsGlobal->MaximumWidth; fShadowYSize = nShadow * *ResolutionHeightMult * RsGlobal->MaximumHeight; } #elif defined SILENTPATCH_VC_VER void __declspec(naked) RosiesAudioFix() { _asm { mov byte ptr [ebx+0CCh], 0 mov byte ptr [ebx+148h], 0 jmp [RosieAudioFix_JumpBack] } } void __stdcall Recalculate(float& fX, float& fY, signed int nShadow) { fX = nShadow * *ResolutionWidthMult * RsGlobal->MaximumWidth; fY = nShadow * *ResolutionHeightMult * RsGlobal->MaximumHeight; } #elif defined SILENTPATCH_SA_VER static CLinkList& m_alphaList = **(CLinkList**)0x733A4D; static unsigned char* ZonesVisited = *(unsigned char**)0x57216A - 9; static RwInt32& clumpPluginOffset = **(RwInt32**)0x732202; static bool& CCutsceneMgr__ms_running = **(bool**)0x53F92D; #ifndef SA_STEAM_TEST #else void** rwengine = (void**)0xD22E34; #endif // Plugin members access #define CLUMPVISIBILITYLOCAL(clump, var) \ (RWPLUGINOFFSET(ClumpVisibilityPlugin, clump, clumpPluginOffset)->var) static inline void RenderOrderedList(CLinkList& list) { for ( auto i = list.m_lnListTail.m_pPrev; i != &list.m_lnListHead; i = i->m_pPrev ) i->V().callback(i->V().pAtomic, i->V().fCompareValue); } void RenderAlphaAtomics() { int nPushedAlpha = 140; RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTIONREF, &nPushedAlpha); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, 0); RenderOrderedList(m_alphaList); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(nPushedAlpha)); } RpAtomic* RenderAtomic(RpAtomic* pAtomic, float fComp) { UNREFERENCED_PARAMETER(fComp); return AtomicDefaultRenderCallBack(pAtomic); } RpMaterial* AlphaTest(RpMaterial* pMaterial, void* pData) { if ( RpMaterialGetTexture(pMaterial) ) { if ( ((BOOL(*)(RwTexture*))0x4C9EA0)(RpMaterialGetTexture(pMaterial)) ) { *static_cast(pData) = TRUE; return nullptr; } } else if ( RpMaterialGetColor(pMaterial)->alpha < 255 ) { *static_cast(pData) = TRUE; return nullptr; } return pMaterial; } RpMaterial* AlphaTestAndPush(RpMaterial* pMaterial, void* pData) { if ( RpMaterialGetTexture(pMaterial) ) { if ( !((BOOL(*)(RwTexture*))0x4C9EA0)(RpMaterialGetTexture(pMaterial)) ) { auto pStack = static_cast*,int>*>(pData); if ( pStack->second++ < 32 ) { *(pStack->first)++ = std::make_pair(&pMaterial->color, *reinterpret_cast(&pMaterial->color)); pMaterial->color.alpha = 0; } } } else if ( RpMaterialGetColor(pMaterial)->alpha == 255 ) { auto pStack = static_cast*,int>*>(pData); if ( pStack->second++ < 32 ) { *(pStack->first)++ = std::make_pair(&pMaterial->color, *reinterpret_cast(&pMaterial->color)); pMaterial->color.alpha = 0; } } return pMaterial; } RpAtomic* OnePassAlphaRender(RpAtomic* atomic) { int nAlphaBlending; RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &nAlphaBlending); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast(TRUE)); auto* pAtomic = AtomicDefaultRenderCallBack(atomic); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast(nAlphaBlending)); return pAtomic; } RpAtomic* TwoPassAlphaRender(RpAtomic* atomic) { // For cutscenes, fall back to one-pass render if ( CCutsceneMgr__ms_running && !CanSeeOutSideFromCurrArea() ) return OnePassAlphaRender(atomic); int nPushedAlpha, nAlphaFunction; int nZWrite; int nAlphaBlending; RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTIONREF, &nPushedAlpha); RwRenderStateGet(rwRENDERSTATEZWRITEENABLE, &nZWrite); RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &nAlphaBlending); RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTION, &nAlphaFunction); // 1st pass RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, FALSE); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(255)); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast(rwALPHATESTFUNCTIONEQUAL)); auto* pAtomic = AtomicDefaultRenderCallBack(atomic); // 2nd pass RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast(TRUE)); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast(rwALPHATESTFUNCTIONLESS)); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); // Push materials #if defined HIDE_MATERIALS std::pair MatsCache[32]; std::pair*,int> ParamPair = std::make_pair(MatsCache, 0); RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), AlphaTestAndPush, &ParamPair); AtomicDefaultRenderCallBack(atomic); ParamPair.first->first = 0; assert(ParamPair.second <= 32); for ( auto i = MatsCache; i->first; i++ ) *static_cast(i->first) = i->second; #else AtomicDefaultRenderCallBack(atomic); #endif RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(nPushedAlpha)); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast(nAlphaFunction)); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, reinterpret_cast(nZWrite)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast(nAlphaBlending)); return pAtomic; } RpAtomic* StaticPropellerRender(RpAtomic* pAtomic) { int nPushedAlpha; RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTIONREF, &nPushedAlpha); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, 0); auto* pReturnAtomic = AtomicDefaultRenderCallBack(pAtomic); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(nPushedAlpha)); return pReturnAtomic; } RpAtomic* RenderBigVehicleActomic(RpAtomic* pAtomic, float fComp) { UNREFERENCED_PARAMETER(fComp); const char* pNodeName = GetFrameNodeName(RpAtomicGetFrame(pAtomic)); if ( !strncmp(pNodeName, "moving_prop", 11) ) return TwoPassAlphaRender(pAtomic); if ( !strncmp(pNodeName, "static_prop", 11) ) return StaticPropellerRender(pAtomic); return AtomicDefaultRenderCallBack(pAtomic); } void RenderWeapon(CEntity* pEntity) { int nPushedAlpha, nAlphaFunction; RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTIONREF, &nPushedAlpha); RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTION, &nAlphaFunction); if ( nPushedAlpha != 255 ) RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(255)); if ( nAlphaFunction != rwALPHATESTFUNCTIONEQUAL ) RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast(rwALPHATESTFUNCTIONEQUAL)); ((void(*)(CEntity*))0x732F95)(pEntity); if ( nPushedAlpha != 255 ) RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(nPushedAlpha)); if ( nAlphaFunction != rwALPHATESTFUNCTIONEQUAL ) RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast(nAlphaFunction)); ms_weaponPedsForPC.Insert(pEntity); } void RenderWeaponsList() { int nPushedAlpha, nAlphaFunction; int nZWrite; int nAlphaBlending; RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTIONREF, &nPushedAlpha); RwRenderStateGet(rwRENDERSTATEZWRITEENABLE, &nZWrite); RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &nAlphaBlending); RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTION, &nAlphaFunction); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(255)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast(TRUE)); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast(rwALPHATESTFUNCTIONLESS)); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); for ( auto i = ms_weaponPedsForPC.m_lnListHead.m_pNext; i != &ms_weaponPedsForPC.m_lnListTail; i = i->m_pNext ) { i->V()->SetupLighting(); ((void(*)(CEntity*))0x732F95)(i->V()); i->V()->RemoveLighting(); } RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(nPushedAlpha)); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTION, reinterpret_cast(nAlphaFunction)); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, reinterpret_cast(nZWrite)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast(nAlphaBlending)); } bool GetCurrentZoneLockedOrUnlocked(float fPosX, float fPosY) { int Xindex = (fPosX+3000.0f) * (1.0f/600.0f); int Yindex = (fPosY+3000.0f) * (1.0f/600.0f); // "Territories fix" if ( (Xindex >= 0 && Xindex < 10) && (Yindex >= 0 && Yindex < 10) ) return ZonesVisited[10*Xindex - Yindex + 9] != 0; // Outside of map bounds return true; } #endif template void AlteredPrintString(float fX, float fY, const wchar_t* pText) { float fMarginX = **reinterpret_cast(pFltX); float fMarginY = **reinterpret_cast(pFltY); PrintString(fX - fMarginX + (fMarginX * *ResolutionWidthMult * RsGlobal->MaximumWidth), fY - fMarginY + (fMarginY * *ResolutionHeightMult * RsGlobal->MaximumHeight), pText); } template void AlteredPrintStringMinus(float fX, float fY, const wchar_t* pText) { float fMarginX = **reinterpret_cast(pFltX); float fMarginY = **reinterpret_cast(pFltY); PrintString(fX + fMarginX - (fMarginX * *ResolutionWidthMult * RsGlobal->MaximumWidth), fY + fMarginY - (fMarginY * *ResolutionHeightMult * RsGlobal->MaximumHeight), pText); } template void AlteredPrintStringXOnly(float fX, float fY, const wchar_t* pText) { float fMarginX = **reinterpret_cast(pFltX); PrintString(fX - fMarginX + (fMarginX * *ResolutionWidthMult * RsGlobal->MaximumWidth), fY, pText); } template void AlteredPrintStringYOnly(float fX, float fY, const wchar_t* pText) { float fMarginY = **reinterpret_cast(pFltY); PrintString(fX, fY - fMarginY + (fMarginY * *ResolutionHeightMult * RsGlobal->MaximumHeight), pText); } float FixedRefValue() { return 1.0f; } void __declspec(naked) SubtitlesShadowFix() { _asm { #if defined SILENTPATCH_III_VER push eax call Recalculate fadd [esp+50h+8] fadd [fShadowYSize] #elif defined SILENTPATCH_VC_VER mov [esp], eax fild [esp] push eax lea eax, [esp+20h-18h] push eax lea eax, [esp+24h-14h] push eax call Recalculate #endif jmp SubtitlesShadowFix_JumpBack } } #if defined SILENTPATCH_III_VER __forceinline void Patch_III_10() { using namespace MemoryVP; DrawRect = (void(*)(const CRect&,const CRGBA&))0x51F970; SetScale = (void(*)(float,float))0x501B80; AudioResetTimers = (void(__stdcall*)(unsigned int))0x57CCD0; PrintString = (void(*)(float,float,const wchar_t*))0x500F50; InstantHitsFiredByPlayer = *(int**)0x482C8F; pGangModelOverrides = *(signed char**)0x4C405E; bWantsToDrawHud = *(bool**)0x4A5877; bCamCheck = *(bool**)0x4A588C; RsGlobal = *(RsGlobalType**)0x584C42; ResolutionWidthMult = *(float**)0x57E956; ResolutionHeightMult = *(float**)0x57E940; HeadlightsFix_JumpBack = (void*)0x5382F2; SubtitlesShadowFix_JumpBack = (void*)0x500D32; CTimer::ms_fTimeScale = *(float**)0x43F73F; CTimer::ms_fTimeStep = *(float**)0x41428E; CTimer::ms_fTimeStepNotClipped = *(float**)0x404F9B; CTimer::m_UserPause = *(bool**)0x4076E9; CTimer::m_CodePause = *(bool**)0x4076F2; CTimer::m_snTimeInMilliseconds = *(int**)0x40B3B8; CTimer::m_snPreviousTimeInMilliseconds = *(int**)0x41543D; CTimer::m_snTimeInMillisecondsNonClipped = *(int**)0x4ACEA2; CTimer::m_snTimeInMillisecondsPauseMode = *(int**)0x47A780; CTimer::m_FrameCounter = *(unsigned int**)0x4AD2F3; Patch(0x490F83, 1); Patch(0x43177D, 16); Patch(0x431DBB, 16); Patch(0x432083, 16); Patch(0x432303, 16); Patch(0x479C9A, 16); Patch(0x4FAD35, 16); Patch(0x544AA4, 127); Patch(0x5382BF, 0x0EEB); InjectHook(0x5382EC, HeadlightsFix, PATCH_JUMP); InjectHook(0x4C4004, PurpleNinesGlitchFix, PATCH_JUMP); InjectHook(0x4ACE60, CTimer::Initialise, PATCH_JUMP); InjectHook(0x4AD310, CTimer::Suspend, PATCH_JUMP); InjectHook(0x4AD370, CTimer::Resume, PATCH_JUMP); InjectHook(0x4AD410, CTimer::GetCyclesPerFrame, PATCH_JUMP); InjectHook(0x4AD3F0, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); InjectHook(0x4ACF70, CTimer::Update, PATCH_JUMP); InjectHook(0x590D9F, CTimer::RecoverFromSave); InjectHook(0x4A5870, ShowRadarTrace, PATCH_JUMP); InjectHook(0x4209A7, SetScaleProperly); InjectHook(0x420A1F, SetScaleProperly); InjectHook(0x420AC1, SetScaleProperly); InjectHook(0x420D9E, SetScaleProperly); InjectHook(0x426342, SetScaleProperly); InjectHook(0x4326B8, SetScaleProperly); InjectHook(0x4F9E4D, FixedRefValue); InjectHook(0x500D27, SubtitlesShadowFix, PATCH_JUMP); Patch(0x500D4C, 0x05D8); Patch(0x500D5F, 0x05D9); Patch(0x500D6E, 0x05D9); Patch(0x500D4E, &fShadowXSize); Patch(0x500D70, &fShadowXSize); Patch(0x500D61, &fShadowYSize); Patch(0x500D53, 0x0000441F); Patch(0x500D52, 0x0F); Patch(0x500D65, 0x90); Patch(0x500D6D, 0x50); Patch(0x500D74, 0x9066); Patch(0x5623B5, 0x90); InjectHook(0x5623B6, M16StatsFix, PATCH_CALL); InjectHook(0x505F82, AlteredPrintString<0x505F7B,0x505F50>); InjectHook(0x5065DA, AlteredPrintString<0x5065D3,0x5065A8>); InjectHook(0x50669B, AlteredPrintString<0x50668E,0x506670>); InjectHook(0x50694B, AlteredPrintString<0x506944,0x506919>); InjectHook(0x506A0C, AlteredPrintString<0x5069FF,0x5069E1>); InjectHook(0x506C37, AlteredPrintString<0x506C2B,0x506C22>); InjectHook(0x5070FA, AlteredPrintString<0x5070F3,0x5070C8>); InjectHook(0x507598, AlteredPrintString<0x507591,0x507566>); InjectHook(0x507754, AlteredPrintString<0x50774D,0x507722>); InjectHook(0x507944, AlteredPrintString<0x50793D,0x507912>); InjectHook(0x507AC8, AlteredPrintStringYOnly<0x507A8B>); InjectHook(0x507CF0, AlteredPrintString<0x507CE9,0x507CBE>); InjectHook(0x507FF1, AlteredPrintStringYOnly<0x507FB4>); InjectHook(0x508C6E, AlteredPrintString<0x508C67,0x508C46>); InjectHook(0x508F09, AlteredPrintStringXOnly<0x508F02>); InjectHook(0x426446, AlteredPrintString<0x42643F,0x426418>); InjectHook(0x426584, AlteredPrintString<0x42657D,0x426556>); InjectHook(0x42665F, AlteredPrintStringMinus<0x426658,0x426637>); InjectHook(0x5098D6, AlteredPrintString<0x509A5E,0x509A3D>); InjectHook(0x509A65, AlteredPrintStringMinus<0x509A5E,0x509A3D>); InjectHook(0x50A142, AlteredPrintStringXOnly<0x50A139>); InjectHook(0x57E9F5, AlteredPrintString<0x57E9EE,0x57E9CD>); } __forceinline void Patch_III_11() { using namespace MemoryVP; DrawRect = (void(*)(const CRect&,const CRGBA&))0x51FBA0; SetScale = (void(*)(float,float))0x501C60; AudioResetTimers = (void(__stdcall*)(unsigned int))0x57CCC0; PrintString = (void(*)(float,float,const wchar_t*))0x501030; InstantHitsFiredByPlayer = *(int**)0x482D5F; pGangModelOverrides = *(signed char**)0x4C40FE; bWantsToDrawHud = *(bool**)0x4A5967; bCamCheck = *(bool**)0x4A597C; RsGlobal = *(RsGlobalType**)0x584F82; ResolutionWidthMult = *(float**)0x57ECA6; ResolutionHeightMult = *(float**)0x57EC90; HeadlightsFix_JumpBack = (void*)0x538532; SubtitlesShadowFix_JumpBack = (void*)0x500E12; CTimer::ms_fTimeScale = *(float**)0x43F73F; CTimer::ms_fTimeStep = *(float**)0x41428E; CTimer::ms_fTimeStepNotClipped = *(float**)0x404F9B; CTimer::m_UserPause = *(bool**)0x4076E9; CTimer::m_CodePause = *(bool**)0x4076F2; CTimer::m_snTimeInMilliseconds = *(int**)0x40B3B8; CTimer::m_snPreviousTimeInMilliseconds = *(int**)0x41543D; CTimer::m_snTimeInMillisecondsNonClipped = *(int**)0x4ACF92; CTimer::m_snTimeInMillisecondsPauseMode = *(int**)0x47A770; CTimer::m_FrameCounter = *(unsigned int**)0x4AD3E3; Patch(0x491043, 1); Patch(0x43177D, 16); Patch(0x431DBB, 16); Patch(0x432083, 16); Patch(0x432303, 16); Patch(0x479C9A, 16); Patch(0x4FAE15, 16); Patch(0x544CE4, 127); Patch(0x5384FF, 0x0EEB); InjectHook(0x53852C, HeadlightsFix, PATCH_JUMP); InjectHook(0x4C40A4, PurpleNinesGlitchFix, PATCH_JUMP); InjectHook(0x4ACF50, CTimer::Initialise, PATCH_JUMP); InjectHook(0x4AD400, CTimer::Suspend, PATCH_JUMP); InjectHook(0x4AD460, CTimer::Resume, PATCH_JUMP); InjectHook(0x4AD500, CTimer::GetCyclesPerFrame, PATCH_JUMP); InjectHook(0x4AD4E0, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); InjectHook(0x4AD060, CTimer::Update, PATCH_JUMP); InjectHook(0x59105F, CTimer::RecoverFromSave); InjectHook(0x4A5960, ShowRadarTrace, PATCH_JUMP); InjectHook(0x4209A7, SetScaleProperly); InjectHook(0x420A1F, SetScaleProperly); InjectHook(0x420AC1, SetScaleProperly); InjectHook(0x420D9E, SetScaleProperly); InjectHook(0x426342, SetScaleProperly); InjectHook(0x4326B8, SetScaleProperly); InjectHook(0x4F9F2D, FixedRefValue); InjectHook(0x500E07, SubtitlesShadowFix, PATCH_JUMP); Patch(0x500E2C, 0x05D8); Patch(0x500E3F, 0x05D9); Patch(0x500E4E, 0x05D9); Patch(0x500E2E, &fShadowXSize); Patch(0x500E50, &fShadowXSize); Patch(0x500E41, &fShadowYSize); Patch(0x500E33, 0x0000441F); Patch(0x500E32, 0x0F); Patch(0x500E45, 0x90); Patch(0x500E4D, 0x50); Patch(0x500E54, 0x9066); Patch(0x5624E5, 0x90); InjectHook(0x5624E6, M16StatsFix, PATCH_CALL); InjectHook(0x506062, AlteredPrintString<0x50605B,0x506030>); InjectHook(0x5066BA, AlteredPrintString<0x5066B3,0x506688>); InjectHook(0x50677B, AlteredPrintString<0x50676E,0x506750>); InjectHook(0x506A2B, AlteredPrintString<0x506A24,0x5069F9>); InjectHook(0x506AEC, AlteredPrintString<0x506ADF,0x506AC1>); InjectHook(0x506D17, AlteredPrintString<0x506D0B,0x506D02>); InjectHook(0x5071DA, AlteredPrintString<0x5071D3,0x5071A8>); InjectHook(0x507678, AlteredPrintString<0x507671,0x507646>); InjectHook(0x507834, AlteredPrintString<0x50782D,0x507802>); InjectHook(0x507A24, AlteredPrintString<0x507A1D,0x5079F2>); InjectHook(0x507BA8, AlteredPrintStringYOnly<0x507B6B>); InjectHook(0x507DD0, AlteredPrintString<0x507DC9,0x507D9E>); InjectHook(0x5080D1, AlteredPrintStringYOnly<0x508094>); InjectHook(0x508D4E, AlteredPrintString<0x508D47,0x508D26>); InjectHook(0x508FE9, AlteredPrintStringXOnly<0x508FE2>); InjectHook(0x426446, AlteredPrintString<0x42643F,0x426418>); InjectHook(0x426584, AlteredPrintString<0x42657D,0x426556>); InjectHook(0x42665F, AlteredPrintStringMinus<0x426658,0x426637>); InjectHook(0x5099B6, AlteredPrintString<0x509B3E,0x509B1D>); InjectHook(0x509B45, AlteredPrintStringMinus<0x509B3E,0x509B1D>); InjectHook(0x50A222, AlteredPrintStringXOnly<0x50A219>); InjectHook(0x57ED45, AlteredPrintString<0x57ED3E,0x57ED1D>); } __forceinline void Patch_III_Steam() { using namespace MemoryVP; DrawRect = (void(*)(const CRect&,const CRGBA&))0x51FB30; SetScale = (void(*)(float,float))0x501BF0; AudioResetTimers = (void(__stdcall*)(unsigned int))0x57CF20; PrintString = (void(*)(float,float,const wchar_t*))0x500FC0; InstantHitsFiredByPlayer = *(int**)0x482D5F; pGangModelOverrides = *(signed char**)0x4C408E; bWantsToDrawHud = *(bool**)0x4A58F7; bCamCheck = *(bool**)0x4A590C; RsGlobal = *(RsGlobalType**)0x584E72; ResolutionWidthMult = *(float**)0x57EBA6; ResolutionHeightMult = *(float**)0x57EB90; SubtitlesShadowFix_JumpBack = (void*)0x500DA2; CTimer::ms_fTimeScale = *(float**)0x43F73F; CTimer::ms_fTimeStep = *(float**)0x41428E; CTimer::ms_fTimeStepNotClipped = *(float**)0x404F9B; CTimer::m_UserPause = *(bool**)0x4076E9; CTimer::m_CodePause = *(bool**)0x4076F2; CTimer::m_snTimeInMilliseconds = *(int**)0x40B3B8; CTimer::m_snPreviousTimeInMilliseconds = *(int**)0x41543D; CTimer::m_snTimeInMillisecondsNonClipped = *(int**)0x4ACF22; CTimer::m_snTimeInMillisecondsPauseMode = *(int**)0x47A770; CTimer::m_FrameCounter = *(unsigned int**)0x4AD373; Patch(0x490FD3, 1); Patch(0x43177D, 16); Patch(0x431DBB, 16); Patch(0x432083, 16); Patch(0x432303, 16); Patch(0x479C9A, 16); Patch(0x4FADA5, 16); Patch(0x544C94, 127); InjectHook(0x4C4034, PurpleNinesGlitchFix, PATCH_JUMP); InjectHook(0x4ACEE0, CTimer::Initialise, PATCH_JUMP); InjectHook(0x4AD390, CTimer::Suspend, PATCH_JUMP); InjectHook(0x4AD3F0, CTimer::Resume, PATCH_JUMP); InjectHook(0x4AD490, CTimer::GetCyclesPerFrame, PATCH_JUMP); InjectHook(0x4AD470, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); InjectHook(0x4ACFF0, CTimer::Update, PATCH_JUMP); InjectHook(0x590F4F, CTimer::RecoverFromSave); InjectHook(0x4A58F0, ShowRadarTrace, PATCH_JUMP); InjectHook(0x4209A7, SetScaleProperly); InjectHook(0x420A1F, SetScaleProperly); InjectHook(0x420AC1, SetScaleProperly); InjectHook(0x420D9E, SetScaleProperly); InjectHook(0x426342, SetScaleProperly); InjectHook(0x4326B8, SetScaleProperly); InjectHook(0x4F9EBD, FixedRefValue); InjectHook(0x500D97, SubtitlesShadowFix, PATCH_JUMP); Patch(0x500DBC, 0x05D8); Patch(0x500DCF, 0x05D9); Patch(0x500DDE, 0x05D9); Patch(0x500DBE, &fShadowXSize); Patch(0x500DE0, &fShadowXSize); Patch(0x500DD1, &fShadowYSize); Patch(0x500DC3, 0x0000441F); Patch(0x500DC2, 0x0F); Patch(0x500DD5, 0x90); Patch(0x500DDD, 0x50); Patch(0x500DE4, 0x9066); Patch(0x562495, 0x90); InjectHook(0x562496, M16StatsFix, PATCH_CALL); InjectHook(0x505FF2, AlteredPrintString<0x505FEB,0x505FC0>); InjectHook(0x50664A, AlteredPrintString<0x506643,0x506618>); InjectHook(0x50670B, AlteredPrintString<0x5066FE,0x5066E0>); InjectHook(0x5069BB, AlteredPrintString<0x5069B4,0x506989>); InjectHook(0x506A7C, AlteredPrintString<0x506A6F,0x506A51>); InjectHook(0x506CA7, AlteredPrintString<0x506C9B,0x506C92>); InjectHook(0x50716A, AlteredPrintString<0x507163,0x507138>); InjectHook(0x507608, AlteredPrintString<0x507601,0x5075D6>); InjectHook(0x5077C4, AlteredPrintString<0x5077BD,0x507792>); InjectHook(0x5079B4, AlteredPrintString<0x5079AD,0x507982>); InjectHook(0x507B38, AlteredPrintStringYOnly<0x507AFB>); InjectHook(0x507D60, AlteredPrintString<0x507D59,0x507D2E>); InjectHook(0x508061, AlteredPrintStringYOnly<0x508024>); InjectHook(0x508CDE, AlteredPrintString<0x508CD7,0x508CB6>); InjectHook(0x508F79, AlteredPrintStringXOnly<0x508F72>); InjectHook(0x426446, AlteredPrintString<0x42643F,0x426418>); InjectHook(0x426584, AlteredPrintString<0x42657D,0x426556>); InjectHook(0x42665F, AlteredPrintStringMinus<0x426658,0x426637>); InjectHook(0x509946, AlteredPrintString<0x509ACE,0x509AAD>); InjectHook(0x509AD5, AlteredPrintStringMinus<0x509ACE,0x509AAD>); InjectHook(0x50A1B2, AlteredPrintStringXOnly<0x50A1A9>); InjectHook(0x57EC45, AlteredPrintString<0x57EC3E,0x57EC1D>); } #elif defined SILENTPATCH_VC_VER __forceinline void Patch_VC_10() { using namespace MemoryVP; AudioResetTimers = (void(__stdcall*)(unsigned int))0x5F98D0; PrintString = (void(*)(float,float,const wchar_t*))0x551040; bSnapShotActive = *(bool**)0x4D1239; RsGlobal = *(RsGlobalType**)0x602D32; ResolutionWidthMult = *(float**)0x5FA15E; ResolutionHeightMult = *(float**)0x5FA148; RosieAudioFix_JumpBack = (void*)0x42BFFE; SubtitlesShadowFix_JumpBack = (void*)0x551701; CTimer::ms_fTimeScale = *(float**)0x453D38; CTimer::ms_fTimeStep = *(float**)0x41A318; CTimer::ms_fTimeStepNotClipped = *(float**)0x40605B; CTimer::m_UserPause = *(bool**)0x4D0F91; CTimer::m_CodePause = *(bool**)0x4D0FAE; CTimer::m_snTimeInMilliseconds = *(int**)0x418CFC; CTimer::m_snPreviousTimeInMilliseconds = *(int**)0x41BB3A; CTimer::m_snTimeInMillisecondsNonClipped = *(int**)0x4D1081; CTimer::m_snTimeInMillisecondsPauseMode = *(int**)0x4D0FE2; CTimer::m_FrameCounter = *(unsigned int**)0x4D12CF; Patch(0x43E983, 16); Patch(0x43EC03, 16); Patch(0x43EECB, 16); Patch(0x43F52B, 16); Patch(0x43F842, 16); Patch(0x48EB27, 16); Patch(0x541E7E, 16); InjectHook(0x4D1300, CTimer::Initialise, PATCH_JUMP); InjectHook(0x4D0ED0, CTimer::Suspend, PATCH_JUMP); InjectHook(0x4D0E50, CTimer::Resume, PATCH_JUMP); InjectHook(0x4D0DF0, CTimer::GetCyclesPerFrame, PATCH_JUMP); InjectHook(0x4D0E30, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); InjectHook(0x4D0F30, CTimer::Update, PATCH_JUMP); InjectHook(0x61AA7D, CTimer::RecoverFromSave); InjectHook(0x5433BD, FixedRefValue); InjectHook(0x42BFF7, RosiesAudioFix, PATCH_JUMP); InjectHook(0x5516FC, SubtitlesShadowFix, PATCH_JUMP); Patch(0x5517C4, 0xD9); Patch(0x5517DF, 0xD9); Patch(0x551832, 0xD9); Patch(0x551848, 0xD9); Patch(0x5517E2, 0x34-0x14); Patch(0x55184B, 0x34-0x14); Patch(0x5517C7, 0x28-0x18); Patch(0x551835, 0x24-0x18); Patch(0x5516FB, 0x90); InjectHook(0x5FA1FD, AlteredPrintString<0x5FA1F6,0x5FA1D5>); InjectHook(0x54474D, AlteredPrintStringMinus<0x544727,0x544727>); } __forceinline void Patch_VC_11() { using namespace MemoryVP; AudioResetTimers = (void(__stdcall*)(unsigned int))0x5F98F0; PrintString = (void(*)(float,float,const wchar_t*))0x551060; bSnapShotActive = *(bool**)0x4D1259; RsGlobal = *(RsGlobalType**)0x602D12; ResolutionWidthMult = *(float**)0x5FA17E; ResolutionHeightMult = *(float**)0x5FA168; RosieAudioFix_JumpBack = (void*)0x42BFFE; SubtitlesShadowFix_JumpBack = (void*)0x551721; CTimer::ms_fTimeScale = *(float**)0x453D38; CTimer::ms_fTimeStep = *(float**)0x41A318; CTimer::ms_fTimeStepNotClipped = *(float**)0x40605B; CTimer::m_UserPause = *(bool**)0x4D0FB1; CTimer::m_CodePause = *(bool**)0x4D0FCE; CTimer::m_snTimeInMilliseconds = *(int**)0x418CFC; CTimer::m_snPreviousTimeInMilliseconds = *(int**)0x41BB3A; CTimer::m_snTimeInMillisecondsNonClipped = *(int**)0x4D10A1; CTimer::m_snTimeInMillisecondsPauseMode = *(int**)0x4D1002; CTimer::m_FrameCounter = *(unsigned int**)0x4D12EF; Patch(0x43E983, 16); Patch(0x43EC03, 16); Patch(0x43EECB, 16); Patch(0x43F52B, 16); Patch(0x43F842, 16); Patch(0x48EB37, 16); Patch(0x541E9E, 16); InjectHook(0x4D1320, CTimer::Initialise, PATCH_JUMP); InjectHook(0x4D0EF0, CTimer::Suspend, PATCH_JUMP); InjectHook(0x4D0E70, CTimer::Resume, PATCH_JUMP); InjectHook(0x4D0E10, CTimer::GetCyclesPerFrame, PATCH_JUMP); InjectHook(0x4D0E50, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); InjectHook(0x4D0F50, CTimer::Update, PATCH_JUMP); InjectHook(0x61AA5D, CTimer::RecoverFromSave); InjectHook(0x5433DD, FixedRefValue); InjectHook(0x42BFF7, RosiesAudioFix, PATCH_JUMP); InjectHook(0x55171C, SubtitlesShadowFix, PATCH_JUMP); Patch(0x5517E4, 0xD9); Patch(0x5517FF, 0xD9); Patch(0x551852, 0xD9); Patch(0x551868, 0xD9); Patch(0x551802, 0x34-0x14); Patch(0x55186B, 0x34-0x14); Patch(0x5517E7, 0x28-0x18); Patch(0x551855, 0x24-0x18); Patch(0x55171B, 0x90); InjectHook(0x5FA21D, AlteredPrintString<0x5FA216,0x5FA1F5>); InjectHook(0x54476D, AlteredPrintStringMinus<0x544747,0x544747>); } __forceinline void Patch_VC_Steam() { using namespace MemoryVP; AudioResetTimers = (void(__stdcall*)(unsigned int))0x5F9530; PrintString = (void(*)(float,float,const wchar_t*))0x550F30; bSnapShotActive = *(bool**)0x4D10F9; RsGlobal = *(RsGlobalType**)0x602952; ResolutionWidthMult = *(float**)0x5F9DBE; ResolutionHeightMult = *(float**)0x5F9DA8; RosieAudioFix_JumpBack = (void*)0x42BFCE; SubtitlesShadowFix_JumpBack = (void*)0x5515F1; CTimer::ms_fTimeScale = *(float**)0x453C18; CTimer::ms_fTimeStep = *(float**)0x41A318; CTimer::ms_fTimeStepNotClipped = *(float**)0x40605B; CTimer::m_UserPause = *(bool**)0x4D0E51; CTimer::m_CodePause = *(bool**)0x4D0E6E; CTimer::m_snTimeInMilliseconds = *(int**)0x418CFC; CTimer::m_snPreviousTimeInMilliseconds = *(int**)0x41BB3A; CTimer::m_snTimeInMillisecondsNonClipped = *(int**)0x4D0F41; CTimer::m_snTimeInMillisecondsPauseMode = *(int**)0x4D0EA2; CTimer::m_FrameCounter = *(unsigned int**)0x4D118F; Patch(0x43E8F3, 16); Patch(0x43EB73, 16); Patch(0x43EE3B, 16); Patch(0x43F49B, 16); Patch(0x43F7B2, 16); Patch(0x48EA37, 16); Patch(0x541D6E, 16); InjectHook(0x4D11C0, CTimer::Initialise, PATCH_JUMP); InjectHook(0x4D0D90, CTimer::Suspend, PATCH_JUMP); InjectHook(0x4D0D10, CTimer::Resume, PATCH_JUMP); InjectHook(0x4D0CB0, CTimer::GetCyclesPerFrame, PATCH_JUMP); InjectHook(0x4D0CF0, CTimer::GetCyclesPerMillisecond, PATCH_JUMP); InjectHook(0x4D0DF0, CTimer::Update, PATCH_JUMP); InjectHook(0x61A6A6, CTimer::RecoverFromSave); InjectHook(0x5432AD, FixedRefValue); InjectHook(0x42BFC7, RosiesAudioFix, PATCH_JUMP); InjectHook(0x5515EC, SubtitlesShadowFix, PATCH_JUMP); Patch(0x5516B4, 0xD9); Patch(0x5516CF, 0xD9); Patch(0x551722, 0xD9); Patch(0x551738, 0xD9); Patch(0x5516D2, 0x34-0x14); Patch(0x55173B, 0x34-0x14); Patch(0x5516B7, 0x28-0x18); Patch(0x551725, 0x24-0x18); Patch(0x5515EB, 0x90); InjectHook(0x5F9E5D, AlteredPrintString<0x5F9E56,0x5F9E35>); InjectHook(0x54463D, AlteredPrintStringMinus<0x544617,0x544617>); } #elif defined SILENTPATCH_SA_VER void RenderVehicleHiDetailAlphaCB_HunterDoor(RpAtomic* pAtomic) { AlphaObjectInfo NewObject; NewObject.callback = RenderAtomic; NewObject.fCompareValue = -std::numeric_limits::infinity(); NewObject.pAtomic = pAtomic; m_alphaList.InsertSorted(NewObject); } #include #include "PNGFile.h" // lunar.png static const BYTE gMoonMaskPNG[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0xAA, 0x69, 0x71, 0xDE, 0x00, 0x00, 0x03, 0xC1, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9B, 0xD7, 0x6B, 0x54, 0x51, 0x10, 0xC6, 0x27, 0x96, 0x68, 0xEC, 0xA2, 0x41, 0x09, 0x16, 0xAC, 0x60, 0x50, 0x51, 0xAC, 0xB1, 0xF7, 0x8A, 0x3E, 0xC4, 0x06, 0xBE, 0x08, 0x3E, 0xE8, 0x83, 0x82, 0xE8, 0x1F, 0xA2, 0x08, 0xFA, 0xA0, 0x0F, 0x82, 0x2F, 0x82, 0xF5, 0xC1, 0x10, 0x7B, 0x8F, 0x5D, 0x83, 0xA2, 0xA2, 0x60, 0xC5, 0x42, 0x50, 0x54, 0xEC, 0xC6, 0x12, 0xCB, 0xF7, 0x31, 0xB3, 0x70, 0x73, 0xD9, 0x9B, 0xCD, 0x66, 0xDB, 0xBD, 0x39, 0xFB, 0xC1, 0x8F, 0x90, 0x6C, 0x58, 0x76, 0xBE, 0x33, 0x67, 0x66, 0xCE, 0xDD, 0x7B, 0x0B, 0xC4, 0x71, 0x15, 0xE4, 0xFA, 0x03, 0xE4, 0x5A, 0xD9, 0x30, 0xA0, 0x15, 0xE8, 0x06, 0x3A, 0x83, 0x8E, 0xA0, 0x1D, 0x68, 0x0B, 0x0A, 0x41, 0x0B, 0xFB, 0x9F, 0xBF, 0xE0, 0x17, 0xF8, 0x01, 0xBE, 0x83, 0x2F, 0xE0, 0x13, 0x78, 0x0F, 0xEA, 0xA2, 0x68, 0x40, 0x11, 0x28, 0x01, 0x3D, 0x41, 0x77, 0xD0, 0x05, 0x74, 0x00, 0xED, 0xED, 0xB5, 0x42, 0x33, 0xA6, 0xA5, 0xFD, 0xFF, 0x1F, 0x0B, 0x94, 0x26, 0xD4, 0x82, 0x6F, 0xE0, 0x2B, 0xF8, 0x08, 0xDE, 0x81, 0xD7, 0xA0, 0xC6, 0x5E, 0x0B, 0xB5, 0x01, 0x3D, 0x40, 0x5F, 0xD0, 0x0B, 0x14, 0x8B, 0xAE, 0x7C, 0x57, 0xD0, 0xDB, 0xCC, 0x28, 0xF6, 0x98, 0x51, 0x64, 0x26, 0x88, 0x05, 0x5F, 0xEB, 0x09, 0xFA, 0xAD, 0x05, 0xFD, 0x12, 0x7C, 0x10, 0xCD, 0x04, 0xFE, 0xED, 0x15, 0x78, 0x0E, 0xDE, 0x84, 0xCD, 0x00, 0x06, 0x3E, 0xD0, 0x82, 0x2F, 0xB1, 0xDF, 0x87, 0x80, 0x41, 0xA0, 0x1F, 0x68, 0xDD, 0xC4, 0xF7, 0xFD, 0x0D, 0x9E, 0x81, 0x47, 0xE0, 0x81, 0x05, 0x5E, 0x63, 0x26, 0x3C, 0x4E, 0x87, 0x11, 0xA9, 0x1A, 0xC0, 0x55, 0x2C, 0xB5, 0x40, 0xFB, 0x58, 0xB0, 0x23, 0xC1, 0x70, 0x7B, 0x2D, 0x9D, 0x62, 0x86, 0xDC, 0x01, 0xB7, 0xCC, 0x94, 0x17, 0x66, 0xCC, 0x7D, 0x49, 0x61, 0x6B, 0xA4, 0x62, 0x00, 0x03, 0x1E, 0x06, 0xFA, 0x1B, 0x65, 0x60, 0x6C, 0x8A, 0xEF, 0xD9, 0x18, 0xFD, 0x03, 0xD7, 0xC1, 0x15, 0xF0, 0xD4, 0xB8, 0x6B, 0x86, 0x64, 0xCD, 0x00, 0xAE, 0xF0, 0x50, 0xD1, 0x95, 0x1F, 0x03, 0x26, 0x83, 0x4E, 0x19, 0x0E, 0xDC, 0xAF, 0xCF, 0xA0, 0x0A, 0xDC, 0x10, 0xCD, 0x84, 0x7B, 0xA2, 0x19, 0x92, 0x51, 0x03, 0x58, 0xB4, 0x46, 0x8B, 0xAE, 0xFC, 0x60, 0x30, 0xC7, 0xCC, 0xC8, 0xA5, 0x18, 0xF4, 0x09, 0xF0, 0x50, 0x34, 0x13, 0x6E, 0x4A, 0x12, 0xAD, 0x33, 0x19, 0x03, 0xDA, 0x88, 0xA6, 0x38, 0x03, 0x1E, 0x01, 0x16, 0x88, 0x16, 0xBC, 0x30, 0x88, 0x85, 0xF1, 0x08, 0xB8, 0x6D, 0x86, 0x70, 0x8B, 0xFC, 0x4C, 0xA7, 0x01, 0x5C, 0xF9, 0x32, 0x0B, 0x9C, 0x26, 0x2C, 0x96, 0xEC, 0xA7, 0x7C, 0x22, 0x71, 0x4B, 0x1C, 0xB6, 0xE0, 0x69, 0x04, 0x6B, 0x44, 0xC2, 0x4C, 0x68, 0xAC, 0x01, 0xE3, 0xC1, 0x28, 0xFB, 0xB9, 0x44, 0xD2, 0x5F, 0xE1, 0xD3, 0x25, 0x76, 0x83, 0x83, 0xE0, 0x2A, 0xA8, 0xB6, 0x9F, 0x29, 0x1B, 0xC0, 0x94, 0x1F, 0x27, 0xBA, 0xF2, 0xCB, 0x25, 0x7C, 0x2B, 0xEF, 0x17, 0x33, 0x61, 0x9F, 0x68, 0x26, 0x5C, 0x93, 0x04, 0x85, 0x31, 0x91, 0x01, 0x6C, 0x75, 0x93, 0x44, 0x7B, 0xFB, 0x4A, 0x09, 0xCF, 0x9E, 0x4F, 0x24, 0xD6, 0x84, 0x3D, 0xA2, 0x33, 0xC3, 0x45, 0x69, 0xA0, 0x45, 0x36, 0x64, 0x00, 0xD3, 0x7C, 0x86, 0x68, 0xD5, 0x2F, 0x97, 0xDC, 0x57, 0xFB, 0x64, 0xC5, 0x95, 0x3F, 0x24, 0xDA, 0x15, 0xCE, 0x48, 0xC0, 0xB0, 0xD4, 0x90, 0x01, 0xDC, 0xF3, 0x13, 0xC0, 0x5C, 0xB0, 0x30, 0xD7, 0xD1, 0x34, 0x51, 0x95, 0xE0, 0x38, 0xB8, 0x2C, 0x5A, 0x13, 0x1A, 0x6D, 0x00, 0x67, 0xF9, 0xE9, 0xA2, 0x7B, 0x7F, 0xB5, 0x84, 0x7F, 0xDF, 0x07, 0x89, 0xF5, 0x60, 0x97, 0x68, 0x2D, 0x38, 0x2B, 0x71, 0xCE, 0x0E, 0x41, 0x06, 0x4C, 0x34, 0xCA, 0xCD, 0x84, 0x28, 0x8B, 0xC1, 0x73, 0x2B, 0x5C, 0x32, 0x12, 0x1A, 0xC0, 0xD5, 0x9F, 0x29, 0x3A, 0xDE, 0xAE, 0x95, 0xE8, 0x5F, 0x35, 0xE2, 0xD9, 0x61, 0x87, 0xE8, 0xD8, 0x7C, 0x5A, 0x7C, 0x59, 0x10, 0x2F, 0x38, 0xB6, 0xBB, 0x29, 0x60, 0xA9, 0x44, 0x7F, 0xF5, 0x63, 0x62, 0x16, 0x1C, 0x00, 0x17, 0x44, 0xDB, 0x63, 0xA0, 0x01, 0xAC, 0xFC, 0xF3, 0x45, 0xA7, 0xBE, 0x75, 0x12, 0xDE, 0x81, 0x27, 0x59, 0xB1, 0x03, 0x6C, 0x17, 0x9D, 0x0E, 0x8F, 0x8A, 0xA7, 0x23, 0xF8, 0x0D, 0x18, 0x00, 0x66, 0x81, 0x45, 0x12, 0xDD, 0xCA, 0x1F, 0x24, 0x76, 0x84, 0x0A, 0x70, 0x0A, 0x3C, 0x09, 0x32, 0x80, 0x85, 0x6F, 0x2A, 0x58, 0x25, 0x7A, 0xDA, 0x6B, 0x4E, 0xE2, 0x69, 0x71, 0x37, 0x38, 0x2F, 0x9E, 0x62, 0xE8, 0x35, 0x80, 0x07, 0x1E, 0xAE, 0x3A, 0x27, 0xBF, 0x0D, 0xD2, 0xF4, 0xCB, 0x58, 0x61, 0x15, 0x2F, 0xAF, 0x6D, 0x15, 0x9D, 0x0C, 0x99, 0x0D, 0x75, 0x7E, 0x03, 0x58, 0xFD, 0xE7, 0x89, 0xD6, 0x80, 0x15, 0xB9, 0xFE, 0xB4, 0x19, 0xD2, 0x5E, 0xD1, 0x1A, 0x70, 0x4C, 0xAC, 0x1B, 0x78, 0x0D, 0x60, 0xCA, 0xCF, 0x06, 0xCB, 0x44, 0xB7, 0x41, 0x73, 0x14, 0xD3, 0x7F, 0x3F, 0x38, 0x29, 0xBA, 0x25, 0xEA, 0x19, 0xC0, 0xD1, 0x97, 0xFD, 0x9F, 0xFB, 0xBF, 0x34, 0xD7, 0x9F, 0x34, 0x43, 0xE2, 0x05, 0x54, 0xD6, 0x01, 0xCE, 0x03, 0xD5, 0x7E, 0x03, 0x38, 0xF8, 0xF0, 0xF0, 0xB3, 0x46, 0xA2, 0x73, 0xEA, 0x4B, 0x56, 0x3C, 0x25, 0xEE, 0x14, 0x3D, 0x1C, 0x55, 0xF9, 0x0D, 0x60, 0xFA, 0x4F, 0x03, 0xEB, 0x25, 0xBA, 0xB3, 0x7F, 0x22, 0xF1, 0x6C, 0xB0, 0x0D, 0x9C, 0x13, 0xDD, 0x06, 0xF5, 0x0C, 0x60, 0x07, 0xE0, 0x04, 0xB8, 0x51, 0x9A, 0x5F, 0x07, 0x88, 0x89, 0x9D, 0x60, 0x8B, 0xE8, 0x44, 0x58, 0xE9, 0x37, 0x80, 0xC3, 0x0F, 0x8B, 0xDF, 0x26, 0x89, 0xFE, 0xFC, 0x1F, 0x24, 0x9E, 0x0B, 0x36, 0x8B, 0x16, 0xC3, 0x8A, 0xBC, 0x01, 0x92, 0xDF, 0x02, 0xF9, 0x22, 0x98, 0x6F, 0x83, 0x9E, 0x17, 0x9D, 0x1F, 0x84, 0x9C, 0x1F, 0x85, 0x9D, 0x3F, 0x0C, 0x39, 0x7F, 0x1C, 0xA6, 0x9C, 0xBE, 0x20, 0x42, 0x39, 0x7F, 0x49, 0xCC, 0xF9, 0x8B, 0xA2, 0x94, 0xD3, 0x97, 0xC5, 0x29, 0xE7, 0xBF, 0x18, 0xA1, 0x9C, 0xFE, 0x6A, 0x8C, 0x72, 0xFE, 0xCB, 0x51, 0xCA, 0xE9, 0xAF, 0xC7, 0x29, 0xE7, 0x6F, 0x90, 0xA0, 0x9C, 0xBE, 0x45, 0x26, 0x26, 0xA7, 0x6F, 0x92, 0x8A, 0xC9, 0xE9, 0xDB, 0xE4, 0x28, 0xE7, 0x6F, 0x94, 0xA4, 0x9C, 0xBE, 0x55, 0x36, 0x26, 0xA7, 0x6F, 0x96, 0xF6, 0xCA, 0xD9, 0xDB, 0xE5, 0xBD, 0x72, 0xFA, 0x81, 0x89, 0x98, 0x9C, 0x7E, 0x64, 0xC6, 0x2B, 0x67, 0x1F, 0x9A, 0x8A, 0x67, 0x84, 0x93, 0x8F, 0xCD, 0xF9, 0xE5, 0xEC, 0x83, 0x93, 0xF1, 0xE4, 0xE4, 0xA3, 0xB3, 0x91, 0x91, 0xF3, 0x06, 0xFC, 0x07, 0x2A, 0x0D, 0x50, 0x50, 0xCC, 0xB6, 0x51, 0x67, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 }; // TODO: EXEs #ifndef SA_STEAM_TEST static float& fFarClipZ = **(float**)0x70D21F; static RwTexture** const gpCoronaTexture = *(RwTexture***)0x6FAA8C; static int& MoonSize = **(int**)0x713B0C; // TODO: Load it from an embedded PNG static RwTexture* gpMoonMask = nullptr; #else unsigned char& nGameClockDays = *(unsigned char*)0xBFCC60; static float& fFarClipZ = *(float*)0xCCE6F8; static RwTexture** const gpCoronaTexture = (RwTexture**)0xCCD768; static int& MoonSize = *(int*)0x9499F4; // TODO: Load it from an embedded PNG static RwTexture*& gpMoonMask = *(RwTexture**)0xCC9874; #endif // By NTAuthority void DrawMoonWithPhases(int moonColor, float* screenPos, float sizeX, float sizeY) { if ( !gpMoonMask ) gpMoonMask = CPNGFile::ReadFromMemory(gMoonMaskPNG, sizeof(gMoonMaskPNG)); //D3DPERF_BeginEvent(D3DCOLOR_ARGB(0,0,0,0), L"render moon"); float currentDayFraction = nGameClockDays / 31.0f; RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nullptr); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); float a10 = 1.0f / fFarClipZ; float size = (MoonSize * 2) + 4.0f; RwD3D9SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); RenderOneXLUSprite(screenPos[0], screenPos[1], fFarClipZ, sizeX * size, sizeY * size, 0, 0, 0, 0, a10, -1, 0, 0); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpMoonMask)); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDINVSRCCOLOR); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCCOLOR); float maskX = (sizeX * size) * 5.4f * (currentDayFraction - 0.5f) + screenPos[0]; float maskY = screenPos[1] + ((sizeY * size) * 0.7f); RenderOneXLUSprite(maskX, maskY, fFarClipZ, sizeX * size * 1.7f, sizeY * size * 1.7f, 0, 0, 0, 255, a10, -1, 0, 0); RwD3D9SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2])); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDDESTALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0); RenderOneXLUSprite(screenPos[0], screenPos[1], fFarClipZ, sizeX * size, sizeY * size, moonColor, moonColor, moonColor * 0.85f, 255, a10, -1, 0, 0); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); //D3DPERF_EndEvent(); } static void* HandleMoonStuffStub_JumpBack = AddressByVersion(0x713D24, 0, 0); void __declspec(naked) HandleMoonStuffStub() { __asm { mov eax, [esp + 78h - 64h] // screen x size mov ecx, [esp + 78h - 68h] // screen y size push ecx push eax lea ecx, [esp + 80h - 54h] // screen coord vector push ecx push esi call DrawMoonWithPhases add esp, 10h jmp HandleMoonStuffStub_JumpBack } } void __declspec(naked) HandleMoonStuffStub_Steam() { __asm { mov eax, [esp + 70h - 58h] // screen x size mov ecx, [esp + 70h - 5Ch] // screen y size push ecx push eax lea ecx, [esp + 78h - 48h] // screen coord vector push ecx push esi call DrawMoonWithPhases add esp, 10h push 72F17Fh retn } } static unsigned int nCachedCRC; static void* RenderVehicleHiDetailCB = AddressByVersion(0x733240, 0, 0); void __declspec(naked) HunterTest() { static const char aDoorDummy[] = "door_lf_ok"; static const char aStaticRotor[] = "static_rotor"; static const char aStaticRotor2[] = "static_rotor2"; static const char aWindscreen[] = "windscreen"; _asm { setnz al movzx di, al push 10 push offset aWindscreen push ebp call strncmp add esp, 0Ch test eax, eax jz HunterTest_RegularAlpha push 13 push offset aStaticRotor2 push ebp call strncmp add esp, 0Ch test eax, eax jz HunterTest_StaticRotor2AlphaSet push 12 push offset aStaticRotor push ebp call strncmp add esp, 0Ch test eax, eax jz HunterTest_StaticRotorAlphaSet test di, di jnz HunterTest_DoorTest push [RenderVehicleHiDetailCB] mov eax, 4C7914h jmp eax HunterTest_DoorTest: cmp nCachedCRC, 0x45D0B41C jnz HunterTest_RegularAlpha push 10 push offset aDoorDummy push ebp call strncmp add esp, 0Ch test eax, eax jnz HunterTest_RegularAlpha push RenderVehicleHiDetailAlphaCB_HunterDoor mov eax, 4C7914h jmp eax HunterTest_RegularAlpha: push 733F80h mov eax, 4C7914h jmp eax HunterTest_StaticRotorAlphaSet: push 7340B0h mov eax, 4C7914h jmp eax HunterTest_StaticRotor2AlphaSet: push 734170h mov eax, 4C7914h jmp eax } } void __declspec(naked) CacheCRC32() { _asm { mov eax, [ecx+4] mov nCachedCRC, eax mov eax, 4C7B10h jmp eax } } // 1.0 only static bool bDarkVehicleThing; static RpLight*& pDirect = **(RpLight***)0x5BA573; void __declspec(naked) DarkVehiclesFix1() { _asm { shr eax, 0Eh test al, 1 jz DarkVehiclesFix1_DontAppply mov ecx, [pDirect] mov ecx, [ecx] mov al, [ecx+2] test al, 1 jnz DarkVehiclesFix1_DontAppply mov bDarkVehicleThing, 1 jmp DarkVehiclesFix1_Return DarkVehiclesFix1_DontAppply: mov bDarkVehicleThing, 0 DarkVehiclesFix1_Return: mov eax, 756D90h jmp eax } } void __declspec(naked) DarkVehiclesFix2() { _asm { jz DarkVehiclesFix2_MakeItDark mov al, bDarkVehicleThing test al, al jnz DarkVehiclesFix2_MakeItDark mov eax, 5D9A7Ah jmp eax DarkVehiclesFix2_MakeItDark: mov eax, 5D9B09h jmp eax } } void __declspec(naked) DarkVehiclesFix3() { _asm { jz DarkVehiclesFix3_MakeItDark mov al, bDarkVehicleThing test al, al jnz DarkVehiclesFix3_MakeItDark mov eax, 5D9B4Ah jmp eax DarkVehiclesFix3_MakeItDark: mov eax, 5D9CACh jmp eax } } void __declspec(naked) DarkVehiclesFix4() { _asm { jz DarkVehiclesFix4_MakeItDark mov al, bDarkVehicleThing test al, al jnz DarkVehiclesFix4_MakeItDark mov eax, 5D9CB8h jmp eax DarkVehiclesFix4_MakeItDark: mov eax, 5D9E0Dh jmp eax } } void __declspec(naked) ResetAlphaFuncRefAfterRender() { _asm { mov edx, [rwengine] mov edx, [edx] mov ecx, [esp+7Ch-74h] push ecx push rwRENDERSTATEALPHATESTFUNCTIONREF call dword ptr [edx+20h] add esp, 8 pop edi pop esi add esp, 74h retn } } static bool bUseTwoPass; static HMODULE hDLLModule; void SetRendererForAtomic(RpAtomic* pAtomic) { BOOL bHasAlpha = FALSE; RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha); if ( bHasAlpha ) RpAtomicSetRenderCallBack(pAtomic, bUseTwoPass ? TwoPassAlphaRender : OnePassAlphaRender); } RpAtomic* RenderPedCB(RpAtomic* pAtomic) { BOOL bHasAlpha = FALSE; RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha); if ( bHasAlpha ) return TwoPassAlphaRender(pAtomic); return AtomicDefaultRenderCallBack(pAtomic); } //#define DO_MAP_DUMP #ifdef DO_MAP_DUMP #include #include #include #include class CFileObjectInstance { public: CVector position; RtQuat rotation; int modelID; int interiorID; int lod; }; typedef CFileObjectInstance tContainer; static std::string strFileName; static std::vector aEntries; #define COMPARED_AREA "vegasE" //#define DUMP_FILENAME COMPARED_AREA"_pc.dat" void DumpIPL(const CFileObjectInstance* pInst, const char* pName) { if ( strFileName.find(COMPARED_AREA) != std::string::npos ) aEntries.push_back(*pInst); } void DumpIPLName(const char* pName) { strFileName = pName; if ( !aEntries.empty() ) { #if defined DUMP_FILENAME std::sort(aEntries.begin(), aEntries.end(), [] (const tContainer& left, const tContainer& right) -> bool { if ( left.modelID < right.modelID ) return true; if ( left.modelID > right.modelID ) return false; if ( left.position.x < right.position.x ) return true; if ( left.position.x > right.position.x ) return false; if ( left.position.y < right.position.y ) return true; if ( left.position.y > right.position.y ) return false; if ( left.position.z < right.position.z ) return true; if ( left.position.z > right.position.z ) return false; if ( left.rotation.imag.x < right.rotation.imag.x ) return true; if ( left.rotation.imag.x > right.rotation.imag.x ) return false; if ( left.rotation.imag.y < right.rotation.imag.y ) return true; if ( left.rotation.imag.y > right.rotation.imag.y ) return false; if ( left.rotation.imag.z < right.rotation.imag.z ) return true; if ( left.rotation.imag.z > right.rotation.imag.z ) return false; if ( left.rotation.real < right.rotation.real ) return true; if ( left.rotation.real > right.rotation.real ) return false; if ( left.interiorID < right.interiorID ) return true; if ( left.interiorID > right.interiorID ) return false; if ( left.lod < right.lod ) return true; return false; }); if ( FILE* hFile = fopen(DUMP_FILENAME, "wb") ) { /*for ( auto it = aEntries.cbegin(); it != aEntries.cend(); it++ ) { fprintf(hFile, "%d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", it->first.modelID, it->second.c_str(), it->first.interiorID, it->first.position.x, it->first.position.y, it->first.position.z, it->first.rotation.imag.x, it->first.rotation.imag.y, it->first.rotation.imag.z, it->first.rotation.real, it->first.lod); }*/ size_t size = aEntries.size(); fwrite(&size, sizeof(size_t), 1, hFile); fwrite(aEntries.data(), size * sizeof(tContainer), 1, hFile); fclose(hFile); } #else // Instead, compare if ( FILE* hPCFile = fopen(COMPARED_AREA"_pc.dat", "rb") ) { if ( FILE* hPS2File = fopen(COMPARED_AREA"_ps2.dat", "rb") ) { size_t PCsize, PS2size; std::vector vecPC, vecPS2; fread(&PCsize, sizeof(size_t), 1, hPCFile); fread(&PS2size, sizeof(size_t), 1, hPS2File); vecPC.resize(PCsize); vecPS2.resize(PS2size); fread(vecPC.data(), PCsize * sizeof(tContainer), 1, hPCFile); fread(vecPS2.data(), PS2size * sizeof(tContainer), 1, hPS2File); // Scan for differences bool bBreak = true; while ( bBreak ) { bool bBreakThisLoop = false; for ( auto PCit = vecPC.begin(); PCit != vecPC.end(); PCit++ ) { for ( auto PS2it = vecPS2.begin(); PS2it != vecPS2.end(); PS2it++ ) { if ( PS2it->modelID == PCit->modelID && PS2it->interiorID == PCit->interiorID && PS2it->position.x == PCit->position.x && PS2it->position.y == PCit->position.y && PS2it->position.z == PCit->position.z && PS2it->rotation.imag.x == PCit->rotation.imag.x && PS2it->rotation.imag.y == PCit->rotation.imag.y && PS2it->rotation.imag.z == PCit->rotation.imag.z && PS2it->rotation.real == PCit->rotation.real ) { if ( !((PS2it->lod == -1 && PCit->lod != -1) || (PS2it->lod != -1 && PCit->lod == -1)) ) { bBreakThisLoop = true; vecPS2.erase(PS2it); vecPC.erase(PCit); break; } } } if ( bBreakThisLoop ) break; } if ( !bBreakThisLoop ) break; } fclose(hPS2File); if ( FILE* hFile = fopen(COMPARED_AREA"_pc.ipl", "w") ) { for ( auto it = vecPC.cbegin(); it != vecPC.cend(); it++ ) { fprintf(hFile, "%d, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", it->modelID, it->interiorID, it->position.x, it->position.y, it->position.z, it->rotation.imag.x, it->rotation.imag.y, it->rotation.imag.z, it->rotation.real, it->lod); } fclose(hFile); } if ( FILE* hFile = fopen(COMPARED_AREA"_ps2.ipl", "w") ) { for ( auto it = vecPS2.cbegin(); it != vecPS2.cend(); it++ ) { fprintf(hFile, "%d, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", it->modelID, it->interiorID, it->position.x, it->position.y, it->position.z, it->rotation.imag.x, it->rotation.imag.y, it->rotation.imag.z, it->rotation.real, it->lod); } fclose(hFile); } } fclose(hPCFile); } #endif aEntries.clear(); } ((void(*)(const char*))0x5B8700)(pName); } void __declspec(naked) DumpIPLStub() { _asm { push [esp+8] push [esp+4+4] call DumpIPL add esp, 8 push 0FFFFFFFFh push 83C931h push 538097h retn } } #endif #include "nvc.h" static IDirect3DVertexShader9* pNVCShader = nullptr; static bool bRenderNVC = false; 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); } WRAPPER bool IsVisionFXActive() { EAXJMP(0x7034F0); } static BOOL (*IsAlreadyRunning)(); static void (*TheScriptsLoad)(); static bool (*InitialiseRenderWare)(); void __declspec(naked) SetShader2() { _asm { mov bRenderNVC, 1 push ecx push edx push edi push ebp mov eax, 5DA6A0h call eax add esp, 10h mov bRenderNVC, 0 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 } } static CAEFLACDecoder* __stdcall DecoderCtor(CAEDataStream* pData) { return new CAEFLACDecoder(pData); } static CAEWaveDecoder* __stdcall CAEWaveDecoderInit(CAEDataStream* pStream) { return new CAEWaveDecoder(pStream); } void __declspec(naked) LoadFLAC() { _asm { jz LoadFLAC_WindowsMedia sub ebp, 2 jnz LoadFLAC_Return //push SIZE CAEStreamingDecoder //call malloc // TODO: operator new //mov [esp+20h+4], eax //test eax, eax //jz LoadFLAC_AllocFailed push esi //mov ecx, eax //call CAEFLACDecoder::CAEFLACDecoder call DecoderCtor jmp LoadFLAC_Success LoadFLAC_WindowsMedia: mov eax, 4F3743h jmp eax //LoadFLAC_AllocFailed: //xor eax, eax LoadFLAC_Success: test eax, eax mov [esp+20h+4], eax jnz LoadFLAC_Return_NoDelete LoadFLAC_Return: //push esi mov ecx, esi //call StreamDtor call CAEDataStream::~CAEDataStream push esi call GTAdelete add esp, 4 LoadFLAC_Return_NoDelete: mov eax, [esp+20h+4] mov ecx, [esp+20h-0Ch] pop esi pop ebp pop edi pop ebx mov fs:0, ecx add esp, 10h retn 4 } } void __declspec(naked) FLACInit() { _asm { mov al, 1 mov [esi+0Dh], al pop esi jnz FLACInit_DontFallBack mov UserTrackExtensions+12.Codec, DECODER_WINDOWSMEDIA FLACInit_DontFallBack: retn } } CRGBA* CRGBA::BlendGangColour(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { *this = Blend(CRGBA(r, g, b), pCurrZoneInfo->ZoneColour.a, HudColour[3], static_cast(255-pCurrZoneInfo->ZoneColour.a)); this->a = a; return this; } static const float fSteamSubtitleSizeX = 0.45f; static const float fSteamSubtitleSizeY = 0.9f; static const float fSteamRadioNamePosY = 33.0f; static const float fSteamRadioNameSizeX = 0.4f; static const float fSteamRadioNameSizeY = 0.6f; BOOL InjectDelayedPatches_10() { if ( !IsAlreadyRunning() ) { using namespace MemoryVP; // Obtain a path to the ASI wchar_t wcModulePath[MAX_PATH]; GetModuleFileNameW(hDLLModule, wcModulePath, MAX_PATH); wchar_t* pSlash = wcsrchr(wcModulePath, '\\'); if ( pSlash ) { *pSlash = '\0'; PathAppendW(wcModulePath, L"SilentPatchSA.ini"); } else { // Should never happen - if it does, something's fucking up return TRUE; } bool bHasImVehFt = GetModuleHandle("ImVehFt.asi") != nullptr; bool bSAMP = GetModuleHandle("samp") != nullptr; bUseTwoPass = GetPrivateProfileIntW(L"SilentPatch", L"TwoPassRendering", FALSE, wcModulePath) != FALSE; if ( bUseTwoPass ) { // Twopass for peds InjectHook(0x733614, RenderPedCB); } if ( GetPrivateProfileIntW(L"SilentPatch", L"EnableScriptFixes", TRUE, wcModulePath) != FALSE ) { // Gym glitch fix Patch(0x470B03, 0xCD8B); Patch(0x470B0A, 0x8B04508B); Patch(0x470B0E, 0x9000); Nop(0x470B10, 1); InjectMethodVP(0x470B05, CRunningScript::GetDay_GymGlitch, PATCH_CALL); // Basketball fix TheScriptsLoad = (void(*)())(*(int*)0x5D18F1 + 0x5D18F0 + 5); InjectHook(0x5D18F0, TheScriptsLoad_BasketballFix); InjectHook(0x464BC0, StartNewMission_BasketballFix, PATCH_JUMP); } if ( !bSAMP && GetPrivateProfileIntW(L"SilentPatch", L"NVCShader", TRUE, wcModulePath) != FALSE ) { // Shaders! // plugin-sdk compatibility InitialiseRenderWare = (bool(*)())(*(int*)0x5BF3A2 + 0x5BF3A1 + 5); InjectHook(0x5DA743, SetShader); InjectHook(0x5D66F1, SetShader2); InjectHook(0x5D6116, UsageIndex1, PATCH_JUMP); InjectHook(0x5D63B7, PassDayColoursToShader, PATCH_JUMP); InjectHook(0x5D637B, HijackEsi, PATCH_JUMP); InjectHook(0x5BF3A1, ShaderAttach); InjectHook(0x53D910, ShaderDetach); Patch(0x5D67F4, HijackAtomic); Patch(0x5D7200, 0xC3); Patch(0x5D67BB, 0x6890); Patch(0x5D67D7, 0x6890); Patch(0x5D67BD, 0x5D5FE0); Patch(0x5D67D9, 0x5D5FE0); Patch(0x5DA73F, 0x90909056); Patch(0x5D60D9, D3DDECLTYPE_D3DCOLOR); Patch(0x5D60E2, D3DDECLUSAGE_COLOR); Patch(0x5D60CF, sizeof(D3DCOLOR)); Patch(0x5D60EA, sizeof(D3DCOLOR)); Patch(0x5D60C2, 0x13); Patch(0x5D62F0, 0xEB); // PostFX fix Patch(*(float**)0x7034C0, 0.0); } if ( GetPrivateProfileIntW(L"SilentPatch", L"SkipIntroSplashes", TRUE, wcModulePath) != FALSE ) { // Skip the damn intro splash Patch(0x748AA8, 0x3DEB); } if ( GetPrivateProfileIntW(L"SilentPatch", L"SmallSteamTexts", TRUE, wcModulePath) != FALSE ) { // We're on 1.0 - make texts smaller Patch(0x58C387, &fSteamSubtitleSizeY); Patch(0x58C40F, &fSteamSubtitleSizeY); Patch(0x58C4CE, &fSteamSubtitleSizeY); Patch(0x58C39D, &fSteamSubtitleSizeX); Patch(0x58C425, &fSteamSubtitleSizeX); Patch(0x58C4E4, &fSteamSubtitleSizeX); Patch(0x4E9FD8, &fSteamRadioNamePosY); Patch(0x4E9F22, &fSteamRadioNameSizeY); Patch(0x4E9F38, &fSteamRadioNameSizeX); } if ( GetPrivateProfileIntW(L"SilentPatch", L"ColouredZoneNames", FALSE, wcModulePath) != FALSE ) { // Coloured zone names Patch(0x58ADBE, 0x0E75); Patch(0x58ADC5, 0x0775); InjectMethodVP(0x58ADE4, CRGBA::BlendGangColour, PATCH_NOTHING); } else { Patch(0x58ADAE, 0xEB); } // ImVehFt conflicts if ( !bHasImVehFt ) { // Lights InjectHook(0x4C830C, LightMaterialsFix, PATCH_CALL); // Flying components InjectMethodVP(0x59F180, CObject::Render, PATCH_JUMP); // Cars getting dirty // Only 1.0 and Steam InjectMethodVP(0x4C9648, CVehicleModelInfo::FindEditableMaterialList, PATCH_CALL); Patch(0x4C964D, 0x0FEBCE8B); Patch(0x5D5DC2, 32); // 1.0 ONLY } if ( !bHasImVehFt && !bSAMP ) { // Properly random numberplates DWORD* pVMT = *(DWORD**)0x4C75FC; void* pFunc; _asm { mov eax, offset CVehicleModelInfo::Shutdown mov [pFunc], eax } Patch(&pVMT[7], pFunc); Patch(0x6D0E43, 0xEB); InjectMethodVP(0x4C9660, CVehicleModelInfo::SetCarCustomPlate, PATCH_NOTHING); InjectMethodVP(0x6D6A58, CVehicle::CustomCarPlate_TextureCreate, PATCH_NOTHING); InjectMethodVP(0x6D651C, CVehicle::CustomCarPlate_BeforeRenderingStart, PATCH_NOTHING); InjectHook(0x6FDFE0, CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade, PATCH_JUMP); //InjectMethodVP(0x6D0E53, CVehicle::CustomCarPlate_AfterRenderingStop, PATCH_NOTHING); Nop(0x6D6517, 2); } return FALSE; } return TRUE; } __forceinline void Patch_SA_Steam() { using namespace MemoryVP; //InjectHook(0x72F058, HandleMoonStuffStub_Steam, PATCH_JUMP); } #endif BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { //UNREFERENCED_PARAMETER(hinstDLL); UNREFERENCED_PARAMETER(lpvReserved); if ( fdwReason == DLL_PROCESS_ATTACH ) { hDLLModule = hinstDLL; #if defined SILENTPATCH_III_VER if (*(DWORD*)0x5C1E70 == 0x53E58955) Patch_III_10(); else if (*(DWORD*)0x5C2130 == 0x53E58955) Patch_III_11(); else if (*(DWORD*)0x5C6FD0 == 0x53E58955) Patch_III_Steam(); #elif defined SILENTPATCH_VC_VER if(*(DWORD*)0x667BF0 == 0x53E58955) Patch_VC_10(); else if(*(DWORD*)0x667C40 == 0x53E58955) Patch_VC_11(); else if (*(DWORD*)0x666BA0 == 0x53E58955) Patch_VC_Steam(); #elif defined SILENTPATCH_SA_VER if (*(DWORD*)0x82457C == 0x94BF || *(DWORD*)0x8245BC == 0x94BF) Patch_SA_10(); //else if (*(DWORD*)0x8252FC == 0x94BF || *(DWORD*)0x82533C == 0x94BF) Patch_SA_11(); else if (*(DWORD*)0x85EC4A == 0x94BF) Patch_SA_Steam(); #endif } /*else if ( fdwReason == DLL_PROCESS_DETACH ) { if ( pNVCShader ) RwD3D9DeleteVertexShader(pNVCShader); }*/ return TRUE; }