diff options
author | aap <aap@papnet.eu> | 2019-05-15 16:52:37 +0200 |
---|---|---|
committer | aap <aap@papnet.eu> | 2019-05-15 16:52:37 +0200 |
commit | 600bf0351476a5a21aabb5429132ddf7f52ac0b9 (patch) | |
tree | d8e48b3a581679e33830fb7c98ed69e1e242e2c2 /src/CullZones.cpp | |
download | re3-600bf0351476a5a21aabb5429132ddf7f52ac0b9.tar re3-600bf0351476a5a21aabb5429132ddf7f52ac0b9.tar.gz re3-600bf0351476a5a21aabb5429132ddf7f52ac0b9.tar.bz2 re3-600bf0351476a5a21aabb5429132ddf7f52ac0b9.tar.lz re3-600bf0351476a5a21aabb5429132ddf7f52ac0b9.tar.xz re3-600bf0351476a5a21aabb5429132ddf7f52ac0b9.tar.zst re3-600bf0351476a5a21aabb5429132ddf7f52ac0b9.zip |
Diffstat (limited to 'src/CullZones.cpp')
-rw-r--r-- | src/CullZones.cpp | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/src/CullZones.cpp b/src/CullZones.cpp new file mode 100644 index 00000000..dc30790b --- /dev/null +++ b/src/CullZones.cpp @@ -0,0 +1,323 @@ +#include "common.h" +#include "patcher.h" +#include "Building.h" +#include "Treadable.h" +#include "Pools.h" +#include "Timer.h" +#include "Camera.h" +#include "World.h" +#include "CullZones.h" + +int32 &CCullZones::NumCullZones = *(int*)0x8F2564; +CCullZone *CCullZones::aZones = (CCullZone*)0x864750; // [NUMCULLZONES]; +int32 &CCullZones::NumAttributeZones = *(int*)0x8E29D0; +CAttributeZone *CCullZones::aAttributeZones = (CAttributeZone*)0x709C60; // [NUMATTRIBZONES]; +uint16 *CCullZones::aIndices = (uint16*)0x847330; // [NUMZONEINDICES]; +int16 *CCullZones::aPointersToBigBuildingsForBuildings = (int16*)0x86C9D0; // [NUMBUILDINGS]; +int16 *CCullZones::aPointersToBigBuildingsForTreadables = (int16*)0x8F1B8C; // [NUMTREADABLES]; + +int32 &CCullZones::CurrentWantedLevelDrop_Player = *(int32*)0x880DA8; +int32 &CCullZones::CurrentFlags_Camera = *(int32*)0x940718; +int32 &CCullZones::CurrentFlags_Player = *(int32*)0x9415F0; +int32 &CCullZones::OldCullZone = *(int32*)0x8E2C90; +int32 &CCullZones::EntityIndicesUsed = *(int32*)0x8F2508; +bool &CCullZones::bCurrentSubwayIsInvisible = *(bool*)0x95CDA5; +bool &CCullZones::bCullZonesDisabled = *(bool*)0x95CD4A; + + +void +CCullZones::Init(void) +{ + int i; + + NumAttributeZones = 0; + NumCullZones = 0; + CurrentWantedLevelDrop_Player = 0; + CurrentFlags_Camera = 0; + CurrentFlags_Player = 0; + OldCullZone = -1; + EntityIndicesUsed = 0; + bCurrentSubwayIsInvisible = false; + + for(i = 0; i < NUMBUILDINGS; i++) + aPointersToBigBuildingsForBuildings[i] = -1; + for(i = 0; i < NUMTREADABLES; i++) + aPointersToBigBuildingsForTreadables[i] = -1; +} + +void +CCullZones::Update(void) +{ + bool invisible; + CVector v; + + if(bCullZonesDisabled) + return; + + switch(CTimer::GetFrameCounter() & 7){ + case 0: + case 4: + /* Update Cull zone */ + ForceCullZoneCoors(TheCamera.GetGameCamPosition()); + break; + + case 2: + /* Update camera attributes */ + CurrentFlags_Camera = FindAttributesForCoors(TheCamera.GetGameCamPosition(), nil); + invisible = (CurrentFlags_Camera & ATTRZONE_SUBWAYVISIBLE) == 0; + if(invisible != bCurrentSubwayIsInvisible){ + MarkSubwayAsInvisible(!invisible); + bCurrentSubwayIsInvisible = invisible; + } + break; + + case 6: + /* Update player attributes */ + CurrentFlags_Player = FindAttributesForCoors(FindPlayerCoors(v), + &CurrentWantedLevelDrop_Player); + break; + } +} + +void +CCullZones::ForceCullZoneCoors(CVector coors) +{ + int32 z; + z = FindCullZoneForCoors(coors); + if(z != OldCullZone){ + if(OldCullZone >= 0) + aZones[OldCullZone].DoStuffLeavingZone(); + if(z >= 0) + aZones[z].DoStuffEnteringZone(); + OldCullZone = z; + } +} + +int32 +CCullZones::FindCullZoneForCoors(CVector coors) +{ + int i; + + for(i = 0; i < NumCullZones; i++) + if(coors.x >= aZones[i].minx && coors.x <= aZones[i].maxx && + coors.y >= aZones[i].miny && coors.y <= aZones[i].maxy && + coors.z >= aZones[i].minz && coors.z <= aZones[i].maxz) + return i; + return -1; +} + +int32 +CCullZones::FindAttributesForCoors(CVector coors, int32 *wantedLevel) +{ + int i; + int32 attribs; + + attribs = 0; + for(i = 0; i < NumAttributeZones; i++) + if(coors.x >= aAttributeZones[i].minx && coors.x <= aAttributeZones[i].maxx && + coors.y >= aAttributeZones[i].miny && coors.y <= aAttributeZones[i].maxy && + coors.z >= aAttributeZones[i].minz && coors.z <= aAttributeZones[i].maxz){ + attribs |= aAttributeZones[i].attributes; + if(wantedLevel && *wantedLevel <= aAttributeZones[i].wantedLevel) + *wantedLevel = aAttributeZones[i].wantedLevel; + } + return attribs; +} + +CAttributeZone* +CCullZones::FindZoneWithStairsAttributeForPlayer(void) +{ + int i; + CVector coors; + + FindPlayerCoors(coors); + for(i = 0; i < NumAttributeZones; i++) + if(aAttributeZones[i].attributes & ATTRZONE_STAIRS && + coors.x >= aAttributeZones[i].minx && coors.x <= aAttributeZones[i].maxx && + coors.y >= aAttributeZones[i].miny && coors.y <= aAttributeZones[i].maxy && + coors.z >= aAttributeZones[i].minz && coors.z <= aAttributeZones[i].maxz) + return &aAttributeZones[i]; + return nil; +} + +WRAPPER void +CCullZones::MarkSubwayAsInvisible(bool visible) +{ EAXJMP(0x525AF0); +} + +void +CCullZones::AddCullZone(CVector const &position, + float minx, float maxx, + float miny, float maxy, + float minz, float maxz, + uint16 flag, int16 wantedLevel) +{ + CCullZone *cull; + CAttributeZone *attrib; + + CVector v; + if((flag & ATTRZONE_NOTCULLZONE) == 0){ + cull = &aZones[NumCullZones++]; + v = position; + // WTF is this? + if((v-CVector(1032.14f, -624.255f, 24.93f)).Magnitude() < 1.0f) + v = CVector(1061.7f, -613.0f, 19.0f); + if((v-CVector(1029.48f, -495.757f, 21.98f)).Magnitude() < 1.0f) + v = CVector(1061.4f, -506.0f, 18.5f); + cull->position.x = clamp(v.x, minx, maxx); + cull->position.y = clamp(v.y, miny, maxy); + cull->position.z = clamp(v.z, minz, maxz); + cull->minx = minx; + cull->maxx = maxx; + cull->miny = miny; + cull->maxy = maxy; + cull->minz = minz; + cull->maxz = maxz; + cull->unk2 = 0; + cull->unk3 = 0; + cull->unk4 = 0; + cull->m_indexStart = 0; + } + if(flag & ~ATTRZONE_NOTCULLZONE){ + attrib = &aAttributeZones[NumAttributeZones++]; + attrib->minx = minx; + attrib->maxx = maxx; + attrib->miny = miny; + attrib->maxy = maxy; + attrib->minz = minz; + attrib->maxz = maxz; + attrib->attributes = flag; + attrib->wantedLevel = wantedLevel; + } +} + + + +void +CCullZone::DoStuffLeavingZone(void) +{ + int i; + + for(i = 0; i < m_numBuildings; i++) + DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]); + for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables ; i++) + DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[m_indexStart + i]); +} + +void +CCullZone::DoStuffLeavingZone_OneBuilding(uint16 i) +{ + int16 bb; + int j; + + if(i < 6000){ + CPools::GetBuildingPool()->GetSlot(i)->m_bZoneCulled = false; + bb = CCullZones::aPointersToBigBuildingsForBuildings[i]; + if(bb != -1) + CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = false; + }else{ + i -= 6000; + for(j = 0; j < 3; j++) + DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]); + } +} + +void +CCullZone::DoStuffLeavingZone_OneTreadableBoth(uint16 i) +{ + int16 bb; + int j; + + if(i < 6000){ + CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled = false; + CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled2 = false; + bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; + if(bb != -1) + CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = false; + }else{ + i -= 6000; + for(j = 0; j < 3; j++) + DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[i+j]); + } +} + +void +CCullZone::DoStuffEnteringZone(void) +{ + int i; + + for(i = 0; i < m_numBuildings; i++) + DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]); + for(; i < m_numBuildings + m_numTreadablesPlus10m; i++) + DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[m_indexStart + i]); + for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables; i++) + DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[m_indexStart + i]); +} + +void +CCullZone::DoStuffEnteringZone_OneBuilding(uint16 i) +{ + int16 bb; + int j; + + if(i < 6000){ + CPools::GetBuildingPool()->GetSlot(i)->m_bZoneCulled = true; + bb = CCullZones::aPointersToBigBuildingsForBuildings[i]; + if(bb != -1) + CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = true; + }else{ + i -= 6000; + for(j = 0; j < 3; j++) + DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]); + } +} + +void +CCullZone::DoStuffEnteringZone_OneTreadablePlus10m(uint16 i) +{ + int16 bb; + int j; + + if(i < 6000){ + CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled = true;; + CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled2 = true;; + bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; + if(bb != -1) + CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = true; + }else{ + i -= 6000; + for(j = 0; j < 3; j++) + DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]); + } +} + +void +CCullZone::DoStuffEnteringZone_OneTreadable(uint16 i) +{ + int16 bb; + int j; + + if(i < 6000){ + CPools::GetTreadablePool()->GetSlot(i)->m_bZoneCulled = true;; + bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; + if(bb != -1) + CPools::GetBuildingPool()->GetSlot(bb)->m_bZoneCulled = true; + }else{ + i -= 6000; + for(j = 0; j < 3; j++) + DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]); + } +} + +STARTPATCHES + InjectHook(0x524BC0, &CCullZones::Init, PATCH_JUMP); + InjectHook(0x524F80, &CCullZones::Update, PATCH_JUMP); + InjectHook(0x525370, &CCullZones::AddCullZone, PATCH_JUMP); + InjectHook(0x5250D0, &CCullZones::ForceCullZoneCoors, PATCH_JUMP); + InjectHook(0x525130, &CCullZones::FindCullZoneForCoors, PATCH_JUMP); + InjectHook(0x5251C0, &CCullZones::FindAttributesForCoors, PATCH_JUMP); + InjectHook(0x525290, &CCullZones::FindZoneWithStairsAttributeForPlayer, PATCH_JUMP); + + InjectHook(0x525610, &CCullZone::DoStuffLeavingZone, PATCH_JUMP); + InjectHook(0x525810, &CCullZone::DoStuffEnteringZone, PATCH_JUMP); +ENDPATCHES |