From 16fe421c76175cfcdd56d1c97e0db26446edde00 Mon Sep 17 00:00:00 2001 From: Silent Date: Tue, 3 Jun 2014 02:10:03 +0200 Subject: [PATCH] Improved moving rotors PS2 sun Onepass/twopass rendering switch Some IPL debugging code --- SilentPatch/StdAfx.h | 7 +- SilentPatch/Vehicle.cpp | 13 +- SilentPatch/dllmain.cpp | 513 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 504 insertions(+), 29 deletions(-) diff --git a/SilentPatch/StdAfx.h b/SilentPatch/StdAfx.h index 5ea5cc3..6c81a6e 100644 --- a/SilentPatch/StdAfx.h +++ b/SilentPatch/StdAfx.h @@ -22,4 +22,9 @@ #include #include "MemoryMgr.h" -#include "Maths.h" \ No newline at end of file +#include "Maths.h" + +//#define HIDE_MATERIAL +//#define EXPAND_ALPHA_ENTITY_LISTS 800 + +//#define SA_STEAM_TEST \ No newline at end of file diff --git a/SilentPatch/Vehicle.cpp b/SilentPatch/Vehicle.cpp index 3994bce..1b8e333 100644 --- a/SilentPatch/Vehicle.cpp +++ b/SilentPatch/Vehicle.cpp @@ -9,13 +9,18 @@ WRAPPER void CVehicle::Render() { EAXJMP(0x6D0E60); } static RwObject* GetCurrentAtomicObjectCB(RwObject* pObject, void* data) { if ( RpAtomicGetFlags(pObject) & rpATOMICRENDER ) + { *static_cast(data) = pObject; + return nullptr; + } return pObject; } void CHeli::Render() { double dRotorsSpeed, dMovingRotorSpeed; + bool bHasMovingRotor = m_pCarNode[12] != nullptr; + bool bHasMovingRotor2 = m_pCarNode[14] != nullptr; m_nTimeTillWeNeedThisCar = *CTimer::m_snTimeInMilliseconds + 3000; @@ -36,7 +41,7 @@ void CHeli::Render() RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[11], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) - SetComponentAtomicAlpha(pOutAtomic, nStaticRotorAlpha); + SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nStaticRotorAlpha : 255); } if ( m_pCarNode[13] ) @@ -44,10 +49,10 @@ void CHeli::Render() RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic); if ( pOutAtomic ) - SetComponentAtomicAlpha(pOutAtomic, nStaticRotorAlpha); + SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nStaticRotorAlpha : 255); } - if ( m_pCarNode[12] ) + if ( bHasMovingRotor ) { RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic); @@ -55,7 +60,7 @@ void CHeli::Render() SetComponentAtomicAlpha(pOutAtomic, nMovingRotorAlpha); } - if ( m_pCarNode[14] ) + if ( bHasMovingRotor2 ) { RpAtomic* pOutAtomic = nullptr; RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic); diff --git a/SilentPatch/dllmain.cpp b/SilentPatch/dllmain.cpp index 6e7cd61..6e068bc 100644 --- a/SilentPatch/dllmain.cpp +++ b/SilentPatch/dllmain.cpp @@ -36,10 +36,22 @@ WRAPPER RwFrame* RwFrameForAllObjects(RwFrame* frame, RwObjectCallBack callBack, WRAPPER RpClump* RpClumpForAllAtomics(RpClump* clump, RpAtomicCallBack callback, void* pData) { WRAPARG(clump); WRAPARG(callback); WRAPARG(pData); EAXJMP(0x749B70); } WRAPPER RpGeometry* RpGeometryForAllMaterials(RpGeometry* geometry, RpMaterialCallBack fpCallBack, void* pData) { WRAPARG(geometry); WRAPARG(fpCallBack); WRAPARG(pData); EAXJMP(0x74C790); } WRAPPER RpAtomic* AtomicDefaultRenderCallBack(RpAtomic* atomic) { WRAPARG(atomic); EAXJMP(0x7491C0); } -WRAPPER void RwD3D9SetRenderState(RwUInt32 state, RwUInt32 value) { WRAPARG(state); WRAPARG(value); EAXJMP(0x7FC2D0); } +#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; @@ -165,8 +177,11 @@ void __stdcall Recalculate(float& fX, float& fY, signed int nShadow) static CLinkList& m_alphaList = **(CLinkList**)0x733A4D; static CLinkList& ms_weaponPedsForPC = **(CLinkList**)0x53EACA; - +#ifndef SA_STEAM_TEST void** rwengine = *(void***)0x58FFC0; +#else +void** rwengine = (void**)0xD22E34; +#endif static inline void RenderOrderedList(CLinkList& list) { @@ -176,14 +191,14 @@ static inline void RenderOrderedList(CLinkList& list) void RenderAlphaAtomics() { - int nPushedAlpha; + int nPushedAlpha = 140; RwRenderStateGet(rwRENDERSTATEALPHATESTFUNCTIONREF, &nPushedAlpha); RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, 0); - //RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); + RenderOrderedList(m_alphaList); + RwRenderStateSet(rwRENDERSTATEALPHATESTFUNCTIONREF, reinterpret_cast(nPushedAlpha)); - //RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, reinterpret_cast(TRUE)); } RpAtomic* RenderAtomic(RpAtomic* pAtomic, float fComp) @@ -211,27 +226,49 @@ RpMaterial* AlphaTest(RpMaterial* pMaterial, void* pData) return pMaterial; } +#include + RpMaterial* AlphaTestAndPush(RpMaterial* pMaterial, void* pData) { if ( RpMaterialGetTexture(pMaterial) ) { if ( !((BOOL(*)(RwTexture*))0x4C9EA0)(RpMaterialGetTexture(pMaterial)) ) { - auto pStack = static_cast**>(pData); - *((*pStack)++) = std::make_pair(&pMaterial->color, *reinterpret_cast(&pMaterial->color)); - pMaterial->color.alpha = 0; + 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**>(pData); - *((*pStack)++) = std::make_pair(&pMaterial->color, *reinterpret_cast(&pMaterial->color)); - pMaterial->color.alpha = 0; + 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) { int nPushedAlpha, nAlphaFunction; @@ -256,15 +293,21 @@ RpAtomic* TwoPassAlphaRender(RpAtomic* atomic) RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); // Push materials - std::pair MatsCache[16]; - auto* pMats = MatsCache; +#if defined HIDE_MATERIALS + std::pair MatsCache[32]; + std::pair*,int> ParamPair = std::make_pair(MatsCache, 0); - RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), AlphaTestAndPush, &pMats); + RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), AlphaTestAndPush, &ParamPair); AtomicDefaultRenderCallBack(atomic); - pMats->first = nullptr; + 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)); @@ -272,6 +315,35 @@ RpAtomic* TwoPassAlphaRender(RpAtomic* atomic) RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast(nAlphaBlending)); return pAtomic; + //return nullptr; +} + +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) @@ -889,6 +961,8 @@ void RenderVehicleHiDetailAlphaCB_HunterDoor(RpAtomic* pAtomic) #include // TODO: EXEs +#ifndef SA_STEAM_TEST + static unsigned char& nGameClockDays = **(unsigned char**)0x4E841D; static float& fFarClipZ = **(float**)0x70D21F; static RwTexture** const gpCoronaTexture = *(RwTexture***)0x6FAA8C; @@ -897,6 +971,18 @@ static int& MoonSize = **(int**)0x713B0C; // TODO: Load it from an embedded PNG static RwTexture*& gpMoonMask = *(RwTexture**)0xC6AA74; +#else + +static 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) { @@ -908,7 +994,7 @@ void DrawMoonWithPhases(int moonColor, float* screenPos, float sizeX, float size RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - float a10 = 1.0 / fFarClipZ; + float a10 = 1.0f / fFarClipZ; float size = (MoonSize * 2) + 4.0f; RwD3D9SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); @@ -919,10 +1005,10 @@ void DrawMoonWithPhases(int moonColor, float* screenPos, float sizeX, float size RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDINVSRCCOLOR); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCCOLOR); - float maskX = (sizeX * size) * 5.40 * (currentDayFraction - 0.5) + screenPos[0]; - float maskY = screenPos[1] + ((sizeY * size) * 0.7); + 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.7, sizeY * size * 1.7, 0, 0, 0, 255, a10, -1, 0, 0); + 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); @@ -994,8 +1080,51 @@ static unsigned int nCachedCRC; 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 aWidescreen[] = "widescreen"; + //static bool bToPleaseFuckingCargobob; _asm { + //setnz di + setnz al + movzx di, al + //mov bToPleaseFuckingCargobob, al + + push 10 + push offset aWidescreen + 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 + //mov al, bToPleaseFuckingCargobob + //test al, al + jnz HunterTest_DoorTest + + push 733240h + mov eax, 4C7914h + jmp eax + +HunterTest_DoorTest: cmp nCachedCRC, 0x45D0B41C jnz HunterTest_RegularAlpha push 10 @@ -1007,12 +1136,22 @@ void __declspec(naked) HunterTest() jnz HunterTest_RegularAlpha push RenderVehicleHiDetailAlphaCB_HunterDoor mov eax, 4C7914h - jmp eax + 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 } } @@ -1027,6 +1166,33 @@ void __declspec(naked) CacheCRC32() } } +void __declspec(naked) PlaneAtomicRendererSetup() +{ + static const char aStaticProp[] = "static_prop"; + _asm + { + mov eax, [esi+4] + push eax + call GetFrameNodeName + push 11 + push offset aStaticProp + push eax + call strncmp + add esp, 10h + test eax, eax + jnz PlaneAtomicRendererSetup_NoAlpha + push 734370h + jmp PlaneAtomicRendererSetup_Return + +PlaneAtomicRendererSetup_NoAlpha: + push 733420h + +PlaneAtomicRendererSetup_Return: + mov eax, 4C7986h + jmp eax + } +} + // 1.0 only static bool bDarkVehicleThing; static RpLight*& pDirect = **(RpLight***)0x5BA573; @@ -1106,15 +1272,257 @@ DarkVehiclesFix4_MakeItDark: } } +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 + } +} + +bool bUseTwoPass = false; + void SetRendererForAtomic(RpAtomic* pAtomic) { BOOL bHasAlpha = FALSE; RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha); if ( bHasAlpha ) - RpAtomicSetRenderCallBack(pAtomic, TwoPassAlphaRender); + RpAtomicSetRenderCallBack(pAtomic, bUseTwoPass ? TwoPassAlphaRender : OnePassAlphaRender); } +//#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 + __forceinline void Patch_SA_10() { using namespace MemoryVP; @@ -1128,8 +1536,12 @@ __forceinline void Patch_SA_10() //InjectHook(0x553318, RenderAlphaAtomics); Patch(0x7341D9, TwoPassAlphaRender); Patch(0x734127, TwoPassAlphaRender); + Patch(0x73445E, RenderBigVehicleActomic); //Patch(0x73406E, TwoPassAlphaRender); + // Plane rotors + InjectHook(0x4C7981, PlaneAtomicRendererSetup, PATCH_JUMP); + // DOUBLE_RWHEELS Patch(0x4C9290, 0xE281); Patch(0x4C9292, ~(rwMATRIXTYPEMASK|rwMATRIXINTERNALIDENTITY)); @@ -1166,8 +1578,8 @@ __forceinline void Patch_SA_10() Nop(0x732FA6, 6); //Nop(0x5E46DA, 2); - // Hunter interior - InjectHook(0x4C7908, HunterTest, PATCH_JUMP); + // Hunter interior & static_rotor for helis + InjectHook(0x4C78F2, HunterTest, PATCH_JUMP); InjectHook(0x4C9618, CacheCRC32); // Fixed blown up car rendering @@ -1205,6 +1617,57 @@ __forceinline void Patch_SA_10() InjectHook(0x4C441F, SetRendererForAtomic, PATCH_CALL); Patch(0x4C4424, 0x5F04C483); Patch(0x4C4428, 0x0004C25E); + + // Lightbeam fix + Patch(0x6A2E88, 0x0EEB); + Nop(0x6A2E9C, 3); + Patch(0x6E0F63, 0x0AEB); + Patch(0x6E0F7C, 0x0BEB); + Patch(0x6E0F95, 0x0BEB); + Patch(0x6E0FAF, 0x1AEB); + + Patch(0x6E13D5, 0x09EB); + Patch(0x6E13ED, 0x17EB); + Patch(0x6E141F, 0x0AEB); + + Patch(0x6E0FE0, 0x28); + Patch(0x6E142D, 0x18); + Patch(0x6E0FDB, 0xC8-0x7C); + //InjectHook(0x6A2EDA, CullTest); + + InjectHook(0x6A2EF7, ResetAlphaFuncRefAfterRender, PATCH_JUMP); + + // PS2 SUN!!!!!!!!!!!!!!!!! + static const float fSunMult = (1050.0f * 0.95f) / 1500.0f; + + Nop(0x6FB17C, 3); + Patch(0x6FC5B0, &fSunMult); + //Patch(0x6FB172, 0x0BEB); + //Patch(0x6FB1A7, 8); + +#if defined EXPAND_ALPHA_ENTITY_LISTS + // Bigger alpha entity lists + Patch(0x733B05, EXPAND_ALPHA_ENTITY_LISTS * 20); + Patch(0x733B55, EXPAND_ALPHA_ENTITY_LISTS * 20); +#endif + + // Fixed police scanner names + char* pScannerNames = *(char**)0x4E72D4; + strncpy(pScannerNames + (8*113), "WESTP", 8); + strncpy(pScannerNames + (8*134), "????", 8); + + // TEMP - dumping IPL data +#ifdef DO_MAP_DUMP + InjectHook(0x538090, DumpIPLStub, PATCH_JUMP); + InjectHook(0x5B92C7, DumpIPLName); +#endif +} + +__forceinline void Patch_SA_Steam() +{ + using namespace MemoryVP; + + InjectHook(0x72F058, HandleMoonStuffStub_Steam, PATCH_JUMP); } #endif @@ -1225,7 +1688,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) else if(*(DWORD*)0x667C40 == 0x53E58955) Patch_VC_11(); else if (*(DWORD*)0x666BA0 == 0x53E58955) Patch_VC_Steam(); #elif defined SILENTPATCH_SA_VER - Patch_SA_10(); + 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 } return TRUE;