diff --git a/SAFix/SAFix.vcxproj b/SAFix/SAFix.vcxproj index e58e8a1..b0e45fa 100644 --- a/SAFix/SAFix.vcxproj +++ b/SAFix/SAFix.vcxproj @@ -78,7 +78,7 @@ Use - false + true true true Windows diff --git a/SilentPatch/General.cpp b/SilentPatch/General.cpp index 06c52a0..47647ef 100644 --- a/SilentPatch/General.cpp +++ b/SilentPatch/General.cpp @@ -9,3 +9,51 @@ WRAPPER void CEntity::UpdateRW() { EAXJMP(0x446F90); } WRAPPER void CEntity::RegisterReference(CEntity** pAddress) { WRAPARG(pAddress); EAXJMP(0x571B70); } WRAPPER void CEntity::CleanUpOldReference(CEntity** pAddress) { WRAPARG(pAddress); EAXJMP(0x571A00); } WRAPPER void CEntity::Render() { EAXJMP(0x534310); } + +static RwTexture*& ms_pRemapTexture = *(RwTexture**)0xB4E47C; +static unsigned char* ms_currentCol = *(unsigned char**)0x4C84C8; + +WRAPPER RpAtomic* SetEditableMaterialsCB(RpAtomic* pMaterial, void* pData) { WRAPARG(pMaterial); WRAPARG(pData); EAXJMP(0x4C83E0); } + +static void SetVehicleColour(unsigned char primaryColour, unsigned char secondaryColour, unsigned char tertiaryColour, unsigned char quaternaryColour) +{ + ms_currentCol[0] = primaryColour; + ms_currentCol[1] = secondaryColour; + ms_currentCol[2] = tertiaryColour; + ms_currentCol[3] = quaternaryColour; +} + +static void ResetEditableMaterials(std::pair* pData) +{ + for ( auto* i = pData; i->first; i++ ) + *static_cast(i->first) = i->second; +} + +void CObject::Render() +{ + if ( m_bDoNotRender ) + return; + + bool bCallRestore; + std::pair materialRestoreData[16]; + + if ( m_wCarPartModelIndex != -1 && m_nObjectType == 3 && bObjectFlag7 && RwObjectGetType(m_pRwObject) == rpATOMIC ) + { + auto* pData = materialRestoreData; + + ms_pRemapTexture = m_pPaintjobTex; + SetVehicleColour(m_nCarColor[0], m_nCarColor[1], m_nCarColor[2], m_nCarColor[3]); + + SetEditableMaterialsCB(reinterpret_cast(m_pRwObject), &pData); + pData->first = nullptr; + + bCallRestore = true; + } + else + bCallRestore = false; + + CEntity::Render(); + + if ( bCallRestore ) + ResetEditableMaterials(materialRestoreData); +} \ No newline at end of file diff --git a/SilentPatch/General.h b/SilentPatch/General.h index 47e462e..f9a0b91 100644 --- a/SilentPatch/General.h +++ b/SilentPatch/General.h @@ -44,7 +44,8 @@ public: ((One.b * OneStrength) + (Two.b * TwoStrength) + (Three.b * ThreeStrength))/TotalStrength, ((One.a * OneStrength) + (Two.a * TwoStrength) + (Three.a * ThreeStrength))/TotalStrength); } - void BaseColors__Constructor(); + // SilentPatch + CRGBA* BlendGangColour(unsigned char r, unsigned char g, unsigned char b, unsigned char a); }; class CRect @@ -277,7 +278,95 @@ public: : CEntity(0) {} }; +class NOVMT CObject : public CPhysical +{ +public: + void* m_pObjectList; + unsigned char m_nObjectType; + __int8 field_13D; + __int16 field_13E; + bool bObjectFlag0 : 1; + bool bObjectFlag1 : 1; + bool bObjectFlag2 : 1; + bool bObjectFlag3 : 1; + bool bObjectFlag4 : 1; + bool bObjectFlag5 : 1; + bool m_bIsExploded : 1; + bool bObjectFlag7 : 1; + bool m_bIsLampPost : 1; + bool m_bIsTargetable : 1; + bool m_bIsBroken : 1; + bool m_bTrainCrossEnabled : 1; + bool m_bIsPhotographed : 1; + bool m_bIsLiftable : 1; + bool bObjectFlag14 : 1; + bool m_bIsDoor : 1; + bool m_bHasNoModel : 1; + bool m_bIsScaled : 1; + bool m_bCanBeAttachedToMagnet : 1; + bool bObjectFlag19 : 1; + bool bObjectFlag20 : 1; + bool bObjectFlag21 : 1; + bool m_bFadingIn : 1; + bool m_bAffectedByColBrightness : 1; + bool bObjectFlag24 : 1; + bool m_bDoNotRender : 1; + bool m_bFadingIn2 : 1; + bool bObjectFlag27 : 1; + bool bObjectFlag28 : 1; + bool bObjectFlag29 : 1; + bool bObjectFlag30 : 1; + bool bObjectFlag31 : 1; + unsigned char m_nColDamageEffect; + __int8 field_145; + __int8 field_146; + __int8 field_147; + unsigned char m_nLastWeaponDamage; + unsigned char m_nColBrightness; + __int16 m_wCarPartModelIndex; + // this is used for detached car parts + unsigned __int8 m_nCarColor[4]; + // time when this object must be deleted + unsigned __int32 m_dwRemovalTime; + float m_fHealth; + // this is used for door objects + float m_fDoorStartAngle; + float m_fScale; + void* m_pObjectInfo; + void* m_pFire; // CFire * + short field_168; + // this is used for detached car parts + short m_wPaintjobTxd; + // this is used for detached car parts + RwTexture* m_pPaintjobTex; + void* m_pDummyObject; + // time when particles must be stopped + signed int m_dwTimeToStopParticles; + float m_fParticlesIntensity; + +public: + virtual void Render() override; +}; + +class CZoneInfo +{ +public: + unsigned char GangDensity[10]; + unsigned char DrugDealerCounter; + CRGBA ZoneColour; + bool unk1 : 1; + bool unk2 : 1; + bool unk3 : 1; + bool unk4 : 1; + bool unk5 : 1; + bool bUseColour : 1; + bool bInGangWar : 1; + bool bNoCops : 1; + unsigned char flags; +}; + static_assert(sizeof(CEntity) == 0x38, "Wrong size: CEntity"); static_assert(sizeof(CPhysical) == 0x138, "Wrong size: CPhysical"); +static_assert(sizeof(CObject) == 0x17C, "Wrong size: CObject"); #endif \ No newline at end of file diff --git a/SilentPatch/dllmain.cpp b/SilentPatch/dllmain.cpp index ba9750c..c7f0f67 100644 --- a/SilentPatch/dllmain.cpp +++ b/SilentPatch/dllmain.cpp @@ -1872,12 +1872,35 @@ FLACInit_DontFallBack: } } +void __declspec(naked) LightMaterialsFix() +{ + _asm + { + mov [esi], edi + mov ebx, [ecx] + lea esi, [edx+4] + mov [ebx+4], esi + mov edi, [esi] + mov [ebx+8], edi + add esi, 4 + mov [ebx+12], esi + mov edi, [esi] + mov [ebx+16], edi + add ebx, 20 + mov [ecx], ebx + retn + } +} + static BOOL (*IsAlreadyRunning)(); static void (*TheScriptsLoad)(); static unsigned char* ScriptSpace = *(unsigned char**)0x5D5380; static int* ScriptParams = *(int**)0x48995B; +static CZoneInfo*& pCurrZoneInfo = **(CZoneInfo***)0x58ADB1; +static CRGBA* HudColour = *(CRGBA**)0x58ADF6; + static void BasketballFix(unsigned char* pBuf, int nSize) { for ( int i = 0, hits = 0; i < nSize && hits < 7; i++, pBuf++ ) @@ -1934,6 +1957,14 @@ void StartNewMission_BasketballFix() BasketballFix(ScriptSpace+200000, 69000); } +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; @@ -2014,6 +2045,26 @@ BOOL InjectDelayedPatches_10() Patch(0x4E9F38, &fSteamRadioNameSizeX); } + if ( GetPrivateProfileInt("SilentPatch", "ColouredZoneNames", FALSE, ".\\SilentPatchSA.ini") != FALSE ) + { + // Coloured zone names + Patch(0x58ADBE, 0x0E75); + Patch(0x58ADC5, 0x0775); + + InjectMethodVP(0x58ADE4, CRGBA::BlendGangColour, PATCH_NOTHING); + } + else + { + Patch(0x58ADAE, 0xEB); + } + + // ImVehFt conflicts + if ( GetModuleHandle("ImVehFt.asi") == nullptr ) + { + InjectHook(0x4C830C, LightMaterialsFix, PATCH_CALL); + InjectMethodVP(0x59F180, CObject::Render, PATCH_JUMP); + } + return FALSE; } return TRUE; @@ -2061,10 +2112,6 @@ __forceinline void Patch_SA_10() // No framedelay Patch(0x53E923, 0x42EB56); - // Coloured zone names - Patch(0x58ADBE, 0x0E75); - Patch(0x58ADC5, 0x0775); - // Disable re-initialization of DirectInput mouse device by the game Patch(0x576CCC, 0xEB); Patch(0x576EBA, 0xEB); @@ -2209,7 +2256,7 @@ __forceinline void Patch_SA_Steam() { using namespace MemoryVP; - InjectHook(0x72F058, HandleMoonStuffStub_Steam, PATCH_JUMP); + //InjectHook(0x72F058, HandleMoonStuffStub_Steam, PATCH_JUMP); } #endif