From 30061396e8fb5afb003cb686e3b2d8665145c76f Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 29 Jul 2021 19:43:06 +0200 Subject: [PATCH 1/3] CVisibilityPlugins and CRenderer fixes; pulled MLO back in --- src/modelinfo/MloModelInfo.cpp | 41 ++++++++++++++++++++++++++ src/modelinfo/MloModelInfo.h | 14 +++++++++ src/modelinfo/ModelInfo.h | 1 + src/renderer/Renderer.cpp | 26 +++++++++++----- src/rw/VisibilityPlugins.cpp | 54 +++++++++++++++++++++++++++------- src/rw/VisibilityPlugins.h | 4 +++ 6 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 src/modelinfo/MloModelInfo.cpp create mode 100644 src/modelinfo/MloModelInfo.h diff --git a/src/modelinfo/MloModelInfo.cpp b/src/modelinfo/MloModelInfo.cpp new file mode 100644 index 00000000..fa12b900 --- /dev/null +++ b/src/modelinfo/MloModelInfo.cpp @@ -0,0 +1,41 @@ +#include "common.h" + +#include "VisibilityPlugins.h" +#include "ModelInfo.h" + +/* +void +CMloModelInfo::ConstructClump() +{ + m_clump = RpClumpCreate(); + RwFrame *mainFrame = RwFrameCreate(); + RwFrameSetIdentity(mainFrame); + RpClumpSetFrame(m_clump, mainFrame); + + for (int i = firstInstance; i < lastInstance; i++) { + int modelId = CModelInfo::GetMloInstanceStore().store[i].m_modelIndex; + RwMatrix *attMat = CModelInfo::GetMloInstanceStore().store[i].GetMatrix().m_attachment; + CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(modelId); + + if (minfo->m_atomics[0] != nil) { + RpAtomic *newAtomic = RpAtomicClone(minfo->m_atomics[0]); + RwFrame *newFrame = RwFrameCreate(); + if (newAtomic != nil && newFrame != nil) { + *RwFrameGetMatrix(newFrame) = *attMat; + RpAtomicSetFrame(newAtomic, newFrame); + RwFrameAddChild(mainFrame, newFrame); + RpClumpAddAtomic(m_clump, newAtomic); + } else { + debug("Failed to allocate memory while creating template MLO.\n"); + } + } + } + + if (RpClumpGetNumAtomics(m_clump) != 0) { + CVisibilityPlugins::SetClumpModelInfo(m_clump, this); + } else { + RpClumpDestroy(m_clump); + m_clump = nil; + } +} +*/ \ No newline at end of file diff --git a/src/modelinfo/MloModelInfo.h b/src/modelinfo/MloModelInfo.h new file mode 100644 index 00000000..b1ae3298 --- /dev/null +++ b/src/modelinfo/MloModelInfo.h @@ -0,0 +1,14 @@ +#pragma once + +#include "ClumpModelInfo.h" + +class CMloModelInfo : public CClumpModelInfo +{ +public: + float drawDist; + int firstInstance; + int lastInstance; +public: + CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {} + void ConstructClump(); +}; \ No newline at end of file diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h index f92a73ad..a0ee0015 100644 --- a/src/modelinfo/ModelInfo.h +++ b/src/modelinfo/ModelInfo.h @@ -2,6 +2,7 @@ #include "2dEffect.h" #include "SimpleModelInfo.h" +#include "MloModelInfo.h" #include "TimeModelInfo.h" #include "WeaponModelInfo.h" #include "ClumpModelInfo.h" diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 6b306b6c..49e8e611 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -29,6 +29,8 @@ bool gbShowPedRoadGroups; bool gbShowCarRoadGroups; bool gbShowCollisionPolys; +bool gbShowCollisionPolysReflections; +bool gbShowCollisionPolysNoShadows; bool gbShowCollisionLines; bool gbBigWhiteDebugLightSwitchedOn; @@ -126,11 +128,16 @@ CRenderer::PreRender(void) void CRenderer::RenderOneRoad(CEntity *e) { +#ifndef FINAL if(gbDontRenderBuildings) return; - if(gbShowCollisionPolys) +#endif +#ifndef MASTER + if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows) CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex()); - else{ + else +#endif + { PUSH_RENDERGROUP(CModelInfo::GetModelInfo(e->GetModelIndex())->GetModelName()); e->Render(); @@ -148,12 +155,15 @@ CRenderer::RenderOneNonRoad(CEntity *e) bool resetLights; #ifndef MASTER - if(gbShowCollisionPolys){ + if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows){ if(!e->IsVehicle()){ CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex()); return; } - }else if(e->IsBuilding()){ + }else +#endif +#ifndef FINAL + if(e->IsBuilding()){ if(e->bIsBIGBuilding){ if(gbDontRenderBigBuildings) return; @@ -164,7 +174,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) }else #endif if(e->IsPed()){ -#ifndef MASTER +#ifndef FINAL if(gbDontRenderPeds) return; #endif @@ -172,7 +182,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) if(ped->m_nPedState == PED_DRIVING) return; } -#ifndef MASTER +#ifndef FINAL else if(e->IsObject() || e->IsDummy()){ if(gbDontRenderObjects) return; @@ -665,8 +675,10 @@ CRenderer::SetupEntityVisibility(CEntity *ent) ti->m_alpha = 255; }else{ // Hide if possible - if(CANTIMECULL) + if(CANTIMECULL){ + ent->DeleteRwObject(); return VIS_INVISIBLE; + } // can't cull, so we'll try to draw this one, but don't request // it since what we really want is the other one. request = false; diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp index 01db546c..01f2c8e7 100644 --- a/src/rw/VisibilityPlugins.cpp +++ b/src/rw/VisibilityPlugins.cpp @@ -51,7 +51,7 @@ CVisibilityPlugins::Initialise(void) m_alphaBoatAtomicList.tail.item.sort = 100000000.0f; #ifdef ASPECT_RATIO_SCALE - // default 150 if not enough for bigger FOVs + // default 150 is not enough for bigger FOVs m_alphaEntityList.Init(NUMALPHAENTITYLIST * 3); #else m_alphaEntityList.Init(NUMALPHAENTITYLIST); @@ -604,8 +604,7 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic) return atomic; if(flags & ATOMIC_FLAG_DRAWLAST){ - // sort before clump - if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f)) + if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq)) RENDERCALLBACK(atomic); }else{ if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot)) @@ -662,12 +661,14 @@ CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic) RpAtomic* CVisibilityPlugins::RenderPedCB(RpAtomic *atomic) { + RpClump *clump; + float dist; int32 alpha; - RwV3d cam2atm; - RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn); - if(RwV3dDotProduct(&cam2atm, &cam2atm) < ms_pedLod1Dist){ - alpha = GetClumpAlpha(RpAtomicGetClump(atomic)); + clump = RpAtomicGetClump(atomic); + dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)); + if(dist < ms_pedLod1Dist){ + alpha = GetClumpAlpha(clump); if(alpha == 255) RENDERCALLBACK(atomic); else @@ -755,12 +756,23 @@ CVisibilityPlugins::FrustumSphereCB(RpClump *clump) return RwCameraFrustumTestSphere(ms_pCamera, &sphere) != rwSPHEREOUTSIDE; } +bool +CVisibilityPlugins::MloVisibilityCB(RpClump *clump) +{ + RwFrame *frame = RpClumpGetFrame(clump); + CMloModelInfo *modelInfo = (CMloModelInfo*)GetFrameHierarchyId(frame); + if (SQR(modelInfo->drawDist) < GetDistanceSquaredFromCamera(frame)) + return false; + return CVisibilityPlugins::FrustumSphereCB(clump); +} + bool CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump) { - if (GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)) <= ms_vehicleLod1Dist) - return FrustumSphereCB(clump); - return false; + RwFrame *frame = RpClumpGetFrame(clump); + if (ms_vehicleLod1Dist < GetDistanceSquaredFromCamera(frame)) + return false; + return FrustumSphereCB(clump); } bool @@ -854,6 +866,12 @@ CVisibilityPlugins::ClearAtomicFlag(RpAtomic *atomic, int f) ATOMICEXT(atomic)->flags &= ~f; } +void +CVisibilityPlugins::SetAtomicId(RpAtomic *atomic, int id) +{ + ATOMICEXT(atomic)->flags = id; +} + int CVisibilityPlugins::GetAtomicId(RpAtomic *atomic) { @@ -939,7 +957,9 @@ CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo // Unused switch (modelInfo->GetModelType()) { - // ignore MLO + case MITYPE_MLO: + CLUMPEXT(clump)->visibilityCB = MloVisibilityCB; + break; case MITYPE_VEHICLE: vmi = (CVehicleModelInfo*)modelInfo; if(vmi->m_vehicleType == VEHICLE_TYPE_TRAIN || @@ -953,6 +973,12 @@ CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo } } +CClumpModelInfo* +CVisibilityPlugins::GetClumpModelInfo(RpClump *clump) +{ + return (CClumpModelInfo*)GetFrameHierarchyId(RpClumpGetFrame(clump)); +} + void CVisibilityPlugins::SetClumpAlpha(RpClump *clump, int alpha) { @@ -964,3 +990,9 @@ CVisibilityPlugins::GetClumpAlpha(RpClump *clump) { return CLUMPEXT(clump)->alpha; } + +bool +CVisibilityPlugins::IsClumpVisible(RpClump *clump) +{ + return CLUMPEXT(clump)->visibilityCB(clump); +} diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h index d375044b..90afc0f5 100644 --- a/src/rw/VisibilityPlugins.h +++ b/src/rw/VisibilityPlugins.h @@ -84,6 +84,7 @@ public: // All actually unused static bool DefaultVisibilityCB(RpClump *clump); static bool FrustumSphereCB(RpClump *clump); + static bool MloVisibilityCB(RpClump *clump); static bool VehicleVisibilityCB(RpClump *clump); static bool VehicleVisibilityCB_BigVehicle(RpClump *clump); @@ -104,6 +105,7 @@ public: static CSimpleModelInfo *GetAtomicModelInfo(RpAtomic *atomic); static void SetAtomicFlag(RpAtomic*, int); static void ClearAtomicFlag(RpAtomic*, int); + static void SetAtomicId(RpAtomic *atomic, int); static int GetAtomicId(RpAtomic *atomic); static void SetAtomicRenderCallback(RpAtomic*, RpAtomicCallBackRender); @@ -133,8 +135,10 @@ public: int alpha; }; static void SetClumpModelInfo(RpClump*, CClumpModelInfo*); + static CClumpModelInfo *GetClumpModelInfo(RpClump*); static void SetClumpAlpha(RpClump*, int); static int GetClumpAlpha(RpClump*); + static bool IsClumpVisible(RpClump*); static void *ClumpConstructor(void *object, int32 offset, int32 len); static void *ClumpDestructor(void *object, int32 offset, int32 len); From 835fa4e74b1014ca1ccef83979f039cafb75e3a4 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Fri, 23 Jul 2021 21:07:44 +0300 Subject: [PATCH 2/3] Make cars and peds to not despawn when you look away # Conflicts: # src/control/CarCtrl.cpp # src/core/config.h # src/peds/Population.cpp --- src/audio/DMAudio.cpp | 2 +- src/control/CarCtrl.cpp | 7 ++++++- src/core/config.h | 4 ++++ src/peds/Population.cpp | 9 ++++++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp index f5b08c71..3843007d 100644 --- a/src/audio/DMAudio.cpp +++ b/src/audio/DMAudio.cpp @@ -65,7 +65,7 @@ cDMAudio::DestroyAllGameCreatedEntities(void) void cDMAudio::SetOutputMode(bool8 surround) { - return AudioManager.SetOutputMode(surround); + AudioManager.SetOutputMode(surround); } void diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 5e4e62ee..870669e8 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -964,6 +964,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle) } float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D(); float threshold = OFFSCREEN_DESPAWN_RANGE; +#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE if (pVehicle->GetIsOnScreen() || TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight || @@ -975,11 +976,15 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle) pVehicle->bIsLawEnforcer || pVehicle->bIsCarParkVehicle || CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime - ){ + ) +#endif + { threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier; } +#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE if (TheCamera.GetForward().z < -0.9f) threshold = 70.0f; +#endif if (pVehicle->bExtendedRange) threshold *= EXTENDED_RANGE_DESPAWN_MULTIPLIER; if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){ diff --git a/src/core/config.h b/src/core/config.h index 307f55d3..9a1b9846 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -274,6 +274,9 @@ enum Config { #define NO_MOVIES // add option to disable intro videos +#define EXTENDED_OFFSCREEN_DESPAWN_RANGE // Use onscreen despawn range for offscreen peds and vehicles to avoid them despawning in the distance when you look + // away + #if defined(__LP64__) || defined(_WIN64) #define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build #endif @@ -449,6 +452,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually #undef PS2_ALPHA_TEST #undef NO_ISLAND_LOADING #undef PS2_AUDIO_CHANNELS + #undef EXTENDED_OFFSCREEN_DESPAWN_RANGE #endif // if these defines are enabled saves are not vanilla compatible without COMPATIBLE_SAVES diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 384cef99..b9347256 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -1105,8 +1105,9 @@ CPopulation::ManagePopulation(void) if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist || (!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)) { pedIsFarAway = true; - - } else if (PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT < dist) { + } +#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE + else if (PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE) * OFFSCREEN_CREATION_MULT < dist) { if (CTimer::GetTimeInMilliseconds() > ped->m_nExtendedRangeTimer && !ped->GetIsOnScreen()) { if (TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_SNIPER_RUNABOUT @@ -1118,7 +1119,9 @@ CPopulation::ManagePopulation(void) } } - } else { + } +#endif + else { ped->m_nExtendedRangeTimer = ped->m_nPedType == PEDTYPE_COP ? CTimer::GetTimeInMilliseconds() + 10000 : CTimer::GetTimeInMilliseconds() + 4000; } From d923cd2f240d29a062c91a2b00c110f74986f281 Mon Sep 17 00:00:00 2001 From: Magnus Larsen Date: Mon, 26 Jul 2021 19:23:37 -0700 Subject: [PATCH 3/3] Allow sector ped count to exceed gap-list size This solves the gnNumTempPedList assertion. To prove this works, change gapTempPedList's length to 12, and visit the Triad's basketball court. # Conflicts: # src/peds/Ped.cpp --- src/peds/Ped.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index eadd9d64..7194d824 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -511,8 +511,20 @@ CPed::BuildPedLists(void) continue; deadsRegistered++; } +#ifdef FIX_BUGS + // If the gap ped list is full, sort it and truncate it + // before pushing more unsorted peds + if( gnNumTempPedList == ARRAY_SIZE(gapTempPedList) - 1 ) + { + gapTempPedList[gnNumTempPedList] = nil; + SortPeds(gapTempPedList, 0, gnNumTempPedList - 1); + gnNumTempPedList = ARRAY_SIZE(m_nearPeds); + } +#endif + gapTempPedList[gnNumTempPedList] = ped; gnNumTempPedList++; + // NOTE: We cannot absolutely fill the gap list, as the list is null-terminated before being passed to SortPeds assert(gnNumTempPedList < ARRAY_SIZE(gapTempPedList)); } }