diff options
Diffstat (limited to 'src')
60 files changed, 1528 insertions, 284 deletions
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index c30d6ecc..0f4281dc 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -2987,7 +2987,7 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) if (ped->IsPlayer()) return GetPlayerTalkSfx(sound); - switch (ped->m_modelIndex) { + switch (ped->GetModelIndex()) { case MI_COP: return GetCopTalkSfx(sound); case MI_SWAT: @@ -3035,13 +3035,13 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) case MI_SPECIAL02: case MI_SPECIAL03: case MI_SPECIAL04: - return GetSpecialCharacterTalkSfx(ped->m_modelIndex, sound); + return GetSpecialCharacterTalkSfx(ped->GetModelIndex(), sound); case MI_MALE02: return GetMaleNo2TalkSfx(sound); case MI_MALE03: case MI_P_MAN1: case MI_P_MAN2: - return GetBlackProjectMaleTalkSfx(sound, ped->m_modelIndex); + return GetBlackProjectMaleTalkSfx(sound, ped->GetModelIndex()); case MI_FATMALE01: return GetWhiteFatMaleTalkSfx(sound); case MI_FATMALE02: @@ -3094,12 +3094,12 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) return GetBlackWorkerMaleTalkSfx(sound); case MI_B_MAN1: case MI_B_MAN3: - return GetBusinessMaleYoungTalkSfx(sound, ped->m_modelIndex); + return GetBusinessMaleYoungTalkSfx(sound, ped->GetModelIndex()); case MI_B_MAN2: return GetBusinessMaleOldTalkSfx(sound); case MI_B_WOM1: case MI_B_WOM2: - return GetWhiteBusinessFemaleTalkSfx(sound, ped->m_modelIndex); + return GetWhiteBusinessFemaleTalkSfx(sound, ped->GetModelIndex()); case MI_B_WOM3: return GetBlackBusinessFemaleTalkSfx(sound); case MI_MOD_MAN: @@ -3112,7 +3112,7 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) return GetStewardFemaleTalkSfx(sound); case MI_FAN_MAN1: case MI_FAN_MAN2: - return GetFanMaleTalkSfx(sound, ped->m_modelIndex); + return GetFanMaleTalkSfx(sound, ped->GetModelIndex()); case MI_FAN_WOM: return GetFanFemaleTalkSfx(sound); case MI_HOS_MAN: @@ -3126,7 +3126,7 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound) case MI_SHOPPER1: case MI_SHOPPER2: case MI_SHOPPER3: - return GetShopperFemaleTalkSfx(sound, ped->m_modelIndex); + return GetShopperFemaleTalkSfx(sound, ped->GetModelIndex()); case MI_STUD_MAN: return GetStudentMaleTalkSfx(sound); case MI_STUD_WOM: @@ -6264,7 +6264,7 @@ cAudioManager::ProcessPed(CPhysical *ped) // params.m_bDistanceCalculated = false; params.m_pPed = (CPed *)ped; params.m_fDistance = GetDistanceSquared(&m_sQueueSample.m_vecPos); - if (ped->m_modelIndex == MI_FATMALE02) + if (ped->GetModelIndex() == MI_FATMALE02) ProcessPedHeadphones(¶ms); ProcessPedOneShots(¶ms); } @@ -7090,7 +7090,7 @@ cAudioManager::ProcessPlane(cVehicleParams *params) ProcessCesna(params); break; default: - debug("Plane Model Id is %d\n, ", params->m_pVehicle->m_modelIndex); + debug("Plane Model Id is %d\n, ", params->m_pVehicle->GetModelIndex()); break; } } @@ -7991,7 +7991,7 @@ cAudioManager::ProcessVehicle(CVehicle *veh) if (handling) params.m_pTransmission = &handling->Transmission; - params.m_nIndex = veh->m_modelIndex - 90; + params.m_nIndex = veh->GetModelIndex() - 90; if (params.m_pVehicle->GetStatus() == STATUS_SIMPLE) velChange = params.m_pVehicle->AutoPilot.m_fMaxTrafficSpeed * 0.02f; else @@ -8272,7 +8272,7 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams *params) if (params->m_fDistance < SQR(SOUND_INTENSITY)) { automobile = (CAutomobile *)params->m_pVehicle; - if ((!automobile->m_bSirenOrAlarm || !UsesSirenSwitching(params->m_nIndex)) && automobile->m_modelIndex != MI_MRWHOOP) { + if ((!automobile->m_bSirenOrAlarm || !UsesSirenSwitching(params->m_nIndex)) && automobile->GetModelIndex() != MI_MRWHOOP) { if (automobile->m_nCarHornTimer) { if (params->m_pVehicle->GetStatus() != STATUS_PLAYER) { automobile->m_nCarHornTimer = Min(44, automobile->m_nCarHornTimer); diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index 5f6dc1c3..fd02691e 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -58,7 +58,7 @@ cMusicManager::PlayerInCar() if (FindPlayerVehicle()->GetStatus() == STATUS_WRECKED) return false; - switch(FindPlayerVehicle()->m_modelIndex) { + switch (FindPlayerVehicle()->GetModelIndex()) { case MI_FIRETRUCK: case MI_AMBULAN: case MI_MRWHOOP: diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp index 31b6c7b6..5470a1af 100644 --- a/src/audio/PoliceRadio.cpp +++ b/src/audio/PoliceRadio.cpp @@ -538,7 +538,7 @@ cAudioManager::SetupSuspectLastSeenReport() main_color = gCarColourTable[color1][1]; color_pre_modifier = gCarColourTable[color1][0]; color_post_modifier = gCarColourTable[color1][2]; - switch (veh->m_modelIndex) { + switch (veh->GetModelIndex()) { #ifdef FIX_BUGS case MI_COLUMB: main_color = SFX_POLICE_RADIO_BLUE; @@ -637,7 +637,7 @@ cAudioManager::SetupSuspectLastSeenReport() break; default: - debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->m_modelIndex); + debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->GetModelIndex()); return; } m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1); diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 809e6f90..927a0070 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -696,7 +696,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle) if (pVehicle->bExtendedRange) threshold *= 1.5f; if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){ - if (pVehicle->GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(pVehicle)){ + if (pVehicle->GetIsOnScreenAndNotCulled()){ pVehicle->bFadeOut = true; }else{ CWorld::Remove(pVehicle); @@ -722,7 +722,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle) if (pVehicle->GetStatus() != STATUS_WRECKED || pVehicle->m_nTimeOfDeath == 0) return; if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nTimeOfDeath + 60000 && - (!pVehicle->GetIsOnScreen() || !CRenderer::IsEntityCullZoneVisible(pVehicle))){ + !pVehicle->GetIsOnScreenAndNotCulled()){ if ((pVehicle->GetPosition() - vecPlayerPos).MagnitudeSqr() > SQR(7.5f)){ if (!CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){ CWorld::Remove(pVehicle); diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index 86314d36..b8203821 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -661,8 +661,7 @@ CPathFind::CountFloodFillGroups(uint8 type) if(type == PATH_CAR) #ifndef MIAMI printf("Single car node: %f %f %f (%d)\n", - node->GetX(), node->GetY(), node->GetZ(), - m_mapObjects[node->objectIndex]->m_modelIndex); + node->GetX(), node->GetY(), node->GetZ(), m_mapObjects[node->objectIndex]->GetModelIndex()); #else printf("Single car node: %f %f %f\n", node->GetX(), node->GetY(), node->GetZ()); @@ -737,7 +736,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor // Calculate internal nodes, store them and connect them to defining object for(i = 0; i < m_numMapObjects; i++){ tileStart = m_numPathNodes; - start = 12*m_mapObjects[i]->m_modelIndex; + start = 12 * m_mapObjects[i]->GetModelIndex(); for(j = 0; j < 12; j++){ if(objectpathinfo[start + j].type == NodeTypeIntern){ CalcNodeCoors( @@ -826,7 +825,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor TempListLength = 0; #ifndef MIAMI for(i = 0; i < m_numMapObjects; i++){ - start = 12*m_mapObjects[i]->m_modelIndex; + start = 12 * m_mapObjects[i]->GetModelIndex(); for(j = 0; j < 12; j++){ if(objectpathinfo[start + j].type != NodeTypeExtern) continue; @@ -1056,7 +1055,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor iseg++; #ifndef MIAMI - istart = 12*m_mapObjects[m_pathNodes[i].objectIndex]->m_modelIndex; + istart = 12 * m_mapObjects[m_pathNodes[i].objectIndex]->GetModelIndex(); #endif // Add links to other internal nodes for(j = Max(oldNumPathNodes, i-12); j < Min(m_numPathNodes, i+12); j++){ @@ -1066,7 +1065,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor jseg = j-i + iseg; #ifndef MIAMI - jstart = 12*m_mapObjects[m_pathNodes[j].objectIndex]->m_modelIndex; + jstart = 12 * m_mapObjects[m_pathNodes[j].objectIndex]->GetModelIndex(); if(objectpathinfo[istart + iseg].next == jseg || objectpathinfo[jstart + jseg].next == iseg){ #else diff --git a/src/control/PathFind.h b/src/control/PathFind.h index a4bb02a2..d2799f87 100644 --- a/src/control/PathFind.h +++ b/src/control/PathFind.h @@ -138,7 +138,7 @@ struct CCarPathLink int16 pathNodeIndex; int8 numLeftLanes; int8 numRightLanes; - int8 trafficLightType; + uint8 trafficLightType; uint8 bBridgeLights : 1; // more? diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index 27bdc010..136ef7db 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -298,7 +298,7 @@ CPhoneInfo::Initialise(void) for (int i = pool->GetSize() - 1; i >= 0; i--) { CBuilding *building = pool->GetSlot(i); if (building) { - if (building->m_modelIndex == MI_PHONEBOOTH1) { + if (building->GetModelIndex() == MI_PHONEBOOTH1) { CPhone *maxPhone = &m_aPhones[m_nMax]; maxPhone->m_nState = PHONE_STATE_FREE; maxPhone->m_vecPos = building->GetPosition(); diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index bc1bbf1c..6b56cd8f 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -229,7 +229,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) if (m_eType == PICKUP_ON_STREET) { m_nTimer = CTimer::GetTimeInMilliseconds() + 30000; } else if (m_eType == PICKUP_ON_STREET_SLOW) { - if (MI_PICKUP_BRIBE == m_pObject->m_modelIndex) + if (MI_PICKUP_BRIBE == m_pObject->GetModelIndex()) m_nTimer = CTimer::GetTimeInMilliseconds() + 300000; else m_nTimer = CTimer::GetTimeInMilliseconds() + 720000; diff --git a/src/control/Record.cpp b/src/control/Record.cpp index d086543f..6ae99e2c 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -417,8 +417,10 @@ void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomo *ppCar = pCar; } +//--MIAMI: unused void RemoveUnusedCollision(void) { +#ifndef MIAMI static const char* dontDeleteArray[] = { "rd_SrRoad2A50", "rd_SrRoad2A20", "rd_CrossRda1w22", "rd_CrossRda1rw22", "road_broadway02", "road_broadway01", "com_21way5", "com_21way50", @@ -430,6 +432,7 @@ void RemoveUnusedCollision(void) CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_NONE); for (int i = 0; i < ARRAY_SIZE(dontDeleteArray); i++) CModelInfo::GetModelInfo(dontDeleteArray[i], nil)->GetColModel()->level = LEVEL_COMMERCIAL; +#endif } void CRecordDataForChase::StartChaseScene(float startTime) diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp index cf6cc4f6..c8b4242e 100644 --- a/src/control/SceneEdit.cpp +++ b/src/control/SceneEdit.cpp @@ -84,12 +84,11 @@ static int32 NextValidModelId(int32 mi, int32 step) CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)pInfo; if (!pInfo) continue; - if (pInfo->m_type == MITYPE_PED + if (pInfo->GetModelType() == MITYPE_PED #ifdef FIX_BUGS && !(i >= MI_SPECIAL01 && i <= MI_SPECIAL04) #endif - || - pInfo->m_type == MITYPE_VEHICLE && + || pInfo->GetModelType() == MITYPE_VEHICLE && #ifdef FIX_BUGS (pVehicleInfo->m_vehicleType == VEHICLE_TYPE_CAR || pVehicleInfo->m_vehicleType == VEHICLE_TYPE_BOAT)) #else // && and || priority failure it seems, also crashes on special models diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 7906b3e7..2bb945d3 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -8074,7 +8074,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command) continue; // desperatly want to believe this was inlined :| CBaseModelInfo* pInfo = CModelInfo::GetModelInfo(model); - assert(pInfo->m_type == MITYPE_VEHICLE); + assert(pInfo->GetModelType() == MITYPE_VEHICLE); CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)pInfo; if (pVehicleInfo->m_vehicleType != VEHICLE_TYPE_CAR) { switch (model) { diff --git a/src/control/Script.h b/src/control/Script.h index 01cad269..12a507c1 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -372,6 +372,9 @@ private: friend class CRunningScript; friend class CHud; friend void CMissionCleanup::Process(); +#ifdef MIAMI + friend class CColStore; +#endif }; diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index b4763627..00d39066 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -148,7 +148,7 @@ LastPedModelId(int modelId) CBaseModelInfo *model; for (int i = modelId; i >= 0; i--) { model = CModelInfo::GetModelInfo(i); - if (model->m_type == MITYPE_PED) + if (model->GetModelType() == MITYPE_PED) return i; } return modelId; @@ -160,7 +160,7 @@ LastVehicleModelId(int modelId) CBaseModelInfo* model; for (int i = modelId; i >= 0; i--) { model = CModelInfo::GetModelInfo(i); - if (model->m_type == MITYPE_VEHICLE) + if (model->GetModelType() == MITYPE_VEHICLE) return i; } return modelId; @@ -222,7 +222,7 @@ CAnimViewer::Update(void) CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelId); CEntity *newEntity = nil; - if (modelInfo->m_type == MITYPE_PED) { + if (modelInfo->GetModelType() == MITYPE_PED) { int animGroup = ((CPedModelInfo*)modelInfo)->m_animGroup; if (animId > ANIM_IDLE_STANCE) @@ -257,7 +257,7 @@ CAnimViewer::Update(void) if (!pTarget) { - if (modelInfo->m_type == MITYPE_VEHICLE) { + if (modelInfo->GetModelType() == MITYPE_VEHICLE) { CVehicleModelInfo* veh = (CVehicleModelInfo*)modelInfo; if (veh->m_vehicleType != VEHICLE_TYPE_CAR) { @@ -281,7 +281,7 @@ CAnimViewer::Update(void) newEntity->SetStatus(STATUS_ABANDONED); } newEntity->bIsStuck = true; - } else if (modelInfo->m_type == MITYPE_PED) { + } else if (modelInfo->GetModelType() == MITYPE_PED) { pTarget = newEntity = new CPed(PEDTYPE_CIVMALE); newEntity->SetModelIndex(modelId); } else { @@ -301,9 +301,9 @@ CAnimViewer::Update(void) } pTarget->GetMatrix().GetPosition().z = 0.0f; - if (modelInfo->m_type != MITYPE_PED) { + if (modelInfo->GetModelType() != MITYPE_PED) { - if (modelInfo->m_type == MITYPE_VEHICLE) { + if (modelInfo->GetModelType() == MITYPE_VEHICLE) { if (pad->NewState.LeftShoulder1 && !pad->OldState.LeftShoulder1) { nextModelId = LastPedModelId(modelId); @@ -369,10 +369,11 @@ CAnimViewer::Update(void) if (pad->NewState.Triangle) { #ifdef PED_SKIN if(IsClumpSkinned(pTarget->GetClump())) - ((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->AnimatePedColModelSkinned(pTarget->GetClump()); + ((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(pTarget->GetClump()); else #endif - CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(pTarget->m_modelIndex))->GetHitColModel(), RpClumpGetFrame(pTarget->GetClump())); + CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->GetHitColModel(), + RpClumpGetFrame(pTarget->GetClump())); AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString); CMessages::AddMessage(gUString, 100, 0); } diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index b760ae28..e33e6bb0 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -4639,7 +4639,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, uint8 camSetArrPos = 0; // We may need those later - bool isPlane = car->m_modelIndex == MI_DODO; + bool isPlane = car->GetModelIndex() == MI_DODO; bool isHeli = false; bool isBike = false; bool isCar = car->IsCar() && !isPlane && !isHeli && !isBike; @@ -4650,9 +4650,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, uint8 nextDirectionIsForward = !(pad->GetLookBehindForCar() || pad->GetLookBehindForPed() || pad->GetLookLeft() || pad->GetLookRight()) && DirectionWasLooking == LOOKING_FORWARD; - if (car->m_modelIndex == MI_FIRETRUCK) { + if (car->GetModelIndex() == MI_FIRETRUCK) { camSetArrPos = 7; - } else if (car->m_modelIndex == MI_RCBANDIT) { + } else if (car->GetModelIndex() == MI_RCBANDIT) { camSetArrPos = 5; } else if (car->IsBoat()) { camSetArrPos = 4; @@ -4851,7 +4851,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // This is also original LCS and SA bug, or some attempt to fix lag. We'll never know // if (car->m_vecMoveSpeed.MagnitudeSqr() < sq(0.2f)) - if (car->m_modelIndex != MI_FIRETRUCK) { + if (car->GetModelIndex() != MI_FIRETRUCK) { // if (!isBike || GetMysteriousWheelRelatedThingBike(car) > 3) // if (!isHeli && (!isPlane || car->GetWheelsOnGround())) { @@ -4907,7 +4907,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, bool correctAlpha = true; // if (SA checks if we aren't in work car, why?) { - if (!isCar || car->m_modelIndex != MI_YARDIE) { + if (!isCar || car->GetModelIndex() != MI_YARDIE) { correctAlpha = false; } else { @@ -5186,13 +5186,13 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // gTargetCoordsForLookingBehind = TargetCoors; // SA code from CAutomobile::TankControl/FireTruckControl. - if (car->m_modelIndex == MI_RHINO || car->m_modelIndex == MI_FIRETRUCK) { + if (car->GetModelIndex() == MI_RHINO || car->GetModelIndex() == MI_FIRETRUCK) { float &carGunLR = ((CAutomobile*)car)->m_fCarGunLR; CVector hi = Multiply3x3(Front, car->GetMatrix()); // III/VC's firetruck turret angle is reversed - float angleToFace = (car->m_modelIndex == MI_FIRETRUCK ? -hi.Heading() : hi.Heading()); + float angleToFace = (car->GetModelIndex() == MI_FIRETRUCK ? -hi.Heading() : hi.Heading()); if (angleToFace <= carGunLR + PI) { if (angleToFace < carGunLR - PI) @@ -5202,7 +5202,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, } float neededTurn = angleToFace - carGunLR; - float turnPerFrame = CTimer::GetTimeStep() * (car->m_modelIndex == MI_FIRETRUCK ? 0.05f : 0.015f); + float turnPerFrame = CTimer::GetTimeStep() * (car->GetModelIndex() == MI_FIRETRUCK ? 0.05f : 0.015f); if (neededTurn <= turnPerFrame) { if (neededTurn < -turnPerFrame) angleToFace = carGunLR - turnPerFrame; @@ -5210,7 +5210,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, angleToFace = turnPerFrame + carGunLR; } - if (car->m_modelIndex == MI_RHINO && carGunLR != angleToFace) { + if (car->GetModelIndex() == MI_RHINO && carGunLR != angleToFace) { DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_CAR_TANK_TURRET_ROTATE, Abs(angleToFace - carGunLR)); } carGunLR = angleToFace; @@ -5222,7 +5222,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, } // Because firetruk turret also has Y movement - if (car->m_modelIndex == MI_FIRETRUCK) { + if (car->GetModelIndex() == MI_FIRETRUCK) { float &carGunUD = ((CAutomobile*)car)->m_fCarGunUD; float alphaToFace = Atan2(hi.z, hi.Magnitude2D()) + DEGTORAD(15.0f); diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 3f4684e7..830a2bb2 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -934,11 +934,13 @@ CCamera::CamControl(void) if(CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer()) stairs = true; // Some hack for Mr Whoopee in a bomb shop +#ifndef MIAMI // uhh, check this if(Cams[ActiveCam].Using3rdPersonMouseCam() && CCollision::ms_collisionInMemory == LEVEL_COMMERCIAL){ if(pTargetEntity->GetPosition().x < 83.0f && pTargetEntity->GetPosition().x > 18.0f && pTargetEntity->GetPosition().y < -305.0f && pTargetEntity->GetPosition().y > -390.0f) disableGarageCam = true; } +#endif if(!disableGarageCam && (CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) || stairs)){ if(!m_bGarageFixedCamPositionSet && m_bLookingAtPlayer){ if(pToGarageWeAreIn || stairs){ diff --git a/src/core/Camera.h b/src/core/Camera.h index 6d53f417..02122dfe 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -298,11 +298,12 @@ enum enum { - // TODO: figure out - FADE_0, + // TODO: find better names + FADE_0, // faded in FADE_1, // mid fade - FADE_2, + FADE_2, // faded out + // Direction FADE_OUT = 0, FADE_IN, FADE_NONE diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp new file mode 100644 index 00000000..0c3356c5 --- /dev/null +++ b/src/core/ColStore.cpp @@ -0,0 +1,231 @@ +#include "common.h" +#ifdef MIAMI + +#include "templates.h" +#include "General.h" +#include "ModelInfo.h" +#include "Streaming.h" +#include "FileLoader.h" +#include "Script.h" +#include "Timer.h" +#include "Camera.h" +#include "Frontend.h" +#include "ColStore.h" + +CPool<ColDef,ColDef> *CColStore::ms_pColPool; + +void +CColStore::Initialise(void) +{ + if(ms_pColPool == nil) + ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles"); + AddColSlot("generic"); // slot 0. not streamed +} + +void +CColStore::Shutdown(void) +{ + int i; + for(i = 0; i < COLSTORESIZE; i++) + RemoveColSlot(i); + if(ms_pColPool) + delete ms_pColPool; + ms_pColPool = nil; +} + +int +CColStore::AddColSlot(const char *name) +{ + ColDef *def = ms_pColPool->New(); + assert(def); + def->isLoaded = false; + def->a = 0; + def->bounds.left = 1000000.0f; + def->bounds.top = 1000000.0f; + def->bounds.right = -1000000.0f; + def->bounds.bottom = -1000000.0f; + def->minIndex = INT16_MAX; + def->maxIndex = INT16_MIN; + strcpy(def->name, name); + return ms_pColPool->GetJustIndex(def); +} + +void +CColStore::RemoveColSlot(int slot) +{ + if(GetSlot(slot)){ + if(GetSlot(slot)->isLoaded) + RemoveCol(slot); + ms_pColPool->Delete(GetSlot(slot)); + } +} + +int +CColStore::FindColSlot(const char *name) +{ + ColDef *def; + int size = ms_pColPool->GetSize(); + for(int i = 0; i < size; i++){ + def = GetSlot(i); + if(def && !CGeneral::faststricmp(def->name, name)) + return i; + } + return -1; +} + +char* +CColStore::GetColName(int32 slot) +{ + return GetSlot(slot)->name; +} + +CRect& +CColStore::GetBoundingBox(int32 slot) +{ + return GetSlot(slot)->bounds; +} + +void +CColStore::IncludeModelIndex(int32 slot, int32 modelIndex) +{ + ColDef *def = GetSlot(slot); + if(modelIndex < def->minIndex) + def->minIndex = modelIndex; + if(modelIndex > def->maxIndex) + def->maxIndex = modelIndex; +} + +bool +CColStore::LoadCol(int32 slot, uint8 *buffer, int32 bufsize) +{ + bool success; + ColDef *def = GetSlot(slot); + if(def->minIndex > def->maxIndex) + success = CFileLoader::LoadCollisionFileFirstTime(buffer, bufsize, slot); + else + success = CFileLoader::LoadCollisionFile(buffer, bufsize, slot); + if(success) + def->isLoaded = true; + else + debug("Failed to load Collision\n"); + return success; +} + +void +CColStore::RemoveCol(int32 slot) +{ + int id; + GetSlot(slot)->isLoaded = false; + for(id = 0; id < MODELINFOSIZE; id++){ + CBaseModelInfo *mi = CModelInfo::GetModelInfo(id); + if(mi){ + CColModel *col = mi->GetColModel(); + if(col && col->level == slot) + col->RemoveCollisionVolumes(); + } + } +} + +void +CColStore::LoadAllCollision(void) +{ + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i)) + CStreaming::RequestCol(i, 0); + CStreaming::LoadAllRequestedModels(false); +} + +void +CColStore::RemoveAllCollision(void) +{ + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i)) + if(CStreaming::CanRemoveCol(i)) + CStreaming::RemoveCol(i); +} + +static bool bLoadAtSecondPosition; +static CVector2D secondPosition; + +void +CColStore::AddCollisionNeededAtPosn(const CVector2D &pos) +{ + bLoadAtSecondPosition = true; + secondPosition = pos; +} + +void +CColStore::LoadCollision(const CVector2D &pos) +{ + int i; + + if(CStreaming::ms_disableStreaming) + return; + + for(i = 1; i < COLSTORESIZE; i++){ + if(GetSlot(i) == nil) + continue; + + bool wantThisOne = false; + + if(GetBoundingBox(i).IsPointInside(pos) || + bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) || + CGeneral::faststrcmp(GetColName(i), "yacht") == 0){ + wantThisOne = true; + }else{ + // TODO: check mission cleanup list + } + + if(wantThisOne) + CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY); + else + CStreaming::RemoveCol(i); + } + bLoadAtSecondPosition = false; +} + +void +CColStore::RequestCollision(const CVector2D &pos) +{ + int i; + + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f)) + CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY); +} + +void +CColStore::EnsureCollisionIsInMemory(const CVector2D &pos) +{ + int i; + + if(CStreaming::ms_disableStreaming) + return; + + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) && + !CStreaming::HasColLoaded(i)){ + CStreaming::RequestCol(i, 0); + if(TheCamera.GetScreenFadeStatus() == FADE_0) + FrontEndMenuManager.MessageScreen("LOADCOL", false); + CTimer::Suspend(); + CStreaming::LoadAllRequestedModels(false); + CTimer::Resume(); + } +} + +bool +CColStore::HasCollisionLoaded(const CVector2D &pos) +{ + int i; + + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) && + !GetSlot(i)->isLoaded) + return false; + return true; +} + +#endif diff --git a/src/core/ColStore.h b/src/core/ColStore.h new file mode 100644 index 00000000..0d686ffd --- /dev/null +++ b/src/core/ColStore.h @@ -0,0 +1,43 @@ +#pragma once + +#include "templates.h" + +struct ColDef { // made up name + int32 a; + bool isLoaded; + CRect bounds; + char name[20]; + int16 minIndex; + int16 maxIndex; +}; + +class CColStore +{ + static CPool<ColDef,ColDef> *ms_pColPool; + +public: + static void Initialise(void); + static void Shutdown(void); + static int AddColSlot(const char *name); + static void RemoveColSlot(int32 slot); + static int FindColSlot(const char *name); + static char *GetColName(int32 slot); + static CRect &GetBoundingBox(int32 slot); + static void IncludeModelIndex(int32 slot, int32 modelIndex); + static bool LoadCol(int32 storeID, uint8 *buffer, int32 bufsize); + static void RemoveCol(int32 slot); + static void AddCollisionNeededAtPosn(const CVector2D &pos); + static void LoadAllCollision(void); + static void RemoveAllCollision(void); + static void LoadCollision(const CVector2D &pos); + static void RequestCollision(const CVector2D &pos); + static void EnsureCollisionIsInMemory(const CVector2D &pos); + static bool HasCollisionLoaded(const CVector2D &pos); + + static ColDef *GetSlot(int slot) { + assert(slot >= 0); + assert(ms_pColPool); + assert(slot < ms_pColPool->GetSize()); + return ms_pColPool->GetSlot(slot); + } +}; diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 7dfe3651..f20fee6d 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -20,6 +20,10 @@ #include "SurfaceTable.h" #include "Lines.h" #include "Collision.h" +#ifdef MIAMI +#include "Camera.h" +#include "ColStore.h" +#endif enum Direction { @@ -34,22 +38,32 @@ enum Direction eLevelName CCollision::ms_collisionInMemory; CLinkList<CColModel*> CCollision::ms_colModelCache; +//--MIAMI: done void CCollision::Init(void) { ms_colModelCache.Init(NUMCOLCACHELINKS); ms_collisionInMemory = LEVEL_NONE; +#ifdef MIAMI + CColStore::Initialise(); +#endif } +//--MIAMI: done void CCollision::Shutdown(void) { ms_colModelCache.Shutdown(); +#ifdef MIAMI + CColStore::Shutdown(); +#endif } +//--MIAMI: done void CCollision::Update(void) { +#ifndef MIAMI CVector playerCoors; playerCoors = FindPlayerCoors(); eLevelName level = CTheZones::m_CurrLevel; @@ -83,8 +97,10 @@ CCollision::Update(void) if(ms_collisionInMemory != CGame::currLevel) LoadCollisionWhenINeedIt(forceLevelChange); CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); +#endif } +//--MIAMI: unused eLevelName GetCollisionInSectorList(CPtrList &list) { @@ -101,6 +117,7 @@ GetCollisionInSectorList(CPtrList &list) return LEVEL_NONE; } +//--MIAMI: unused // Get a level this sector is in based on collision models eLevelName GetCollisionInSector(CSector §) @@ -121,9 +138,11 @@ GetCollisionInSector(CSector §) return (eLevelName)level; } +//--MIAMI: done void CCollision::LoadCollisionWhenINeedIt(bool forceChange) { +#ifndef MIAMI eLevelName level, l; bool multipleLevels; CVector playerCoors; @@ -184,6 +203,7 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange) CPad::StopPadsShaking(); LoadCollisionScreen(CGame::currLevel); DMAudio.Service(); + CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false); CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); @@ -204,15 +224,19 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange) CStreaming::RequestBigBuildings(CGame::currLevel); CStreaming::LoadAllRequestedModels(true); CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); + CGame::TidyUpMemory(true, true); CTimer::Update(); DMAudio.SetEffectsFadeVol(127); } +#endif } +//--MIAMI: done void CCollision::SortOutCollisionAfterLoad(void) { +#ifndef MIAMI if(ms_collisionInMemory == CGame::currLevel) return; @@ -224,6 +248,10 @@ CCollision::SortOutCollisionAfterLoad(void) } ms_collisionInMemory = CGame::currLevel; CGame::TidyUpMemory(true, false); +#else + CColStore::LoadCollision(TheCamera.GetPosition()); + CStreaming::LoadAllRequestedModels(false); +#endif } void @@ -1972,7 +2000,11 @@ CColModel::CColModel(void) vertices = nil; triangles = nil; trianglePlanes = nil; +#ifndef MIAMI level = CGame::currLevel; +#else + level = 0; // generic col slot +#endif ownsCollisionVolumes = true; } diff --git a/src/core/Collision.h b/src/core/Collision.h index bdf51eb8..fc3c1647 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -89,11 +89,15 @@ struct CColModel { CColSphere boundingSphere; CColBox boundingBox; - short numSpheres; - short numLines; - short numBoxes; - short numTriangles; - int level; + int16 numSpheres; + int16 numLines; + int16 numBoxes; + int16 numTriangles; +#ifndef MIAMI + int32 level; +#else + uint8 level; // colstore slot but probably same name +#endif bool ownsCollisionVolumes; CColSphere *spheres; CColLine *lines; diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index b7d82089..ab09d72f 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -24,6 +24,10 @@ #include "ZoneCull.h" #include "CdStream.h" #include "FileLoader.h" +#ifdef MIAMI +#include "Streaming.h" +#include "ColStore.h" +#endif char CFileLoader::ms_line[256]; @@ -53,7 +57,9 @@ CFileLoader::LoadLevel(const char *filename) savedTxd = RwTexDictionaryGetCurrent(); objectsLoaded = false; +#ifndef MIAMI savedLevel = CGame::currLevel; +#endif if(savedTxd == nil){ savedTxd = RwTexDictionaryCreate(); RwTexDictionarySetCurrent(savedTxd); @@ -77,12 +83,17 @@ CFileLoader::LoadLevel(const char *filename) AddTexDictionaries(savedTxd, txd); RwTexDictionaryDestroy(txd); }else if(strncmp(line, "COLFILE", 7) == 0){ +#ifndef MIAMI int level; sscanf(line+8, "%d", &level); CGame::currLevel = (eLevelName)level; LoadingScreenLoadingFile(line+10); LoadCollisionFile(line+10); CGame::currLevel = savedLevel; +#else + LoadingScreenLoadingFile(line+10); + LoadCollisionFile(line+10, 0); +#endif }else if(strncmp(line, "MODELFILE", 9) == 0){ LoadingScreenLoadingFile(line + 10); LoadModelFile(line + 10); @@ -94,8 +105,16 @@ CFileLoader::LoadLevel(const char *filename) LoadObjectTypes(line + 4); }else if(strncmp(line, "IPL", 3) == 0){ if(!objectsLoaded){ +#ifndef MIAMI CModelInfo::ConstructMloClumps(); CObjectData::Initialise("DATA\\OBJECT.DAT"); +#else + LoadingScreenLoadingFile("Collision"); + CObjectData::Initialise("DATA\\OBJECT.DAT"); + CStreaming::Init(); + CColStore::LoadAllCollision(); + // TODO: anim indices +#endif objectsLoaded = true; } LoadingScreenLoadingFile(line + 4); @@ -112,8 +131,18 @@ CFileLoader::LoadLevel(const char *filename) CFileMgr::CloseFile(fd); RwTexDictionarySetCurrent(savedTxd); + +#ifdef MIAMI + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(CColStore::GetSlot(i)) + CColStore::GetBoundingBox(i).Grow(120.0f); + CWorld::RepositionCertainDynamicObjects(); + CColStore::RemoveAllCollision(); +#endif } +#ifndef MIAMI void CFileLoader::LoadCollisionFromDatFile(int currlevel) { @@ -137,6 +166,7 @@ CFileLoader::LoadCollisionFromDatFile(int currlevel) CFileMgr::CloseFile(fd); } +#endif char* CFileLoader::LoadLine(int fd) @@ -172,16 +202,25 @@ CFileLoader::LoadTexDictionary(const char *filename) return txd; } +struct ColHeader +{ + char ident[4]; + uint32 size; +}; + +//--MIAMI: done +#ifndef MIAMI void CFileLoader::LoadCollisionFile(const char *filename) +#else +void +CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) +#endif { int fd; char modelname[24]; CBaseModelInfo *mi; - struct { - char ident[4]; - uint32 size; - } header; + ColHeader header; debug("Loading collision file %s\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); @@ -193,10 +232,17 @@ CFileLoader::LoadCollisionFile(const char *filename) mi = CModelInfo::GetModelInfo(modelname, nil); if(mi){ +#ifndef MIAMI if(mi->GetColModel()){ +#else + if(mi->GetColModel() && mi->DoesOwnColModel()){ +#endif LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname); }else{ CColModel *model = new CColModel; +#ifdef MIAMI + model->level = colSlot; +#endif LoadCollisionModel(work_buff+24, *model, modelname); mi->SetColModel(model, true); } @@ -208,6 +254,82 @@ CFileLoader::LoadCollisionFile(const char *filename) CFileMgr::CloseFile(fd); } +#ifdef MIAMI +bool +CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot) +{ + uint32 modelsize; + char modelname[24]; + CBaseModelInfo *mi; + ColHeader *header; + int modelIndex; + + while(size > 8){ + header = (ColHeader*)buffer; + modelsize = header->size; + if(strncmp(header->ident, "COLL", 4) != 0) + return size-8 < CDSTREAM_SECTOR_SIZE; + memcpy(modelname, buffer+8, 24); + memcpy(work_buff, buffer+32, modelsize-24); + size -= 32 + (modelsize-24); + buffer += 32 + (modelsize-24); + if(modelsize > 15*1024) + debug("colmodel %s is huge, size %d\n", modelname, modelsize); + + mi = CModelInfo::GetModelInfo(modelname, &modelIndex); + if(mi){ +if(modelIndex == 855) +modelIndex = modelIndex; + CColStore::IncludeModelIndex(colSlot, modelIndex); + CColModel *model = new CColModel; + model->level = colSlot; + LoadCollisionModel(work_buff, *model, modelname); + mi->SetColModel(model, true); + }else{ + debug("colmodel %s can't find a modelinfo\n", modelname); + } + } + return true; +} + +bool +CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot) +{ + uint32 modelsize; + char modelname[24]; + CBaseModelInfo *mi; + ColHeader *header; + + while(size > 8){ + header = (ColHeader*)buffer; + modelsize = header->size; + if(strncmp(header->ident, "COLL", 4) != 0) + return size-8 < CDSTREAM_SECTOR_SIZE; + memcpy(modelname, buffer+8, 24); + memcpy(work_buff, buffer+32, modelsize-24); + size -= 32 + (modelsize-24); + buffer += 32 + (modelsize-24); + if(modelsize > 15*1024) + debug("colmodel %s is huge, size %d\n", modelname, modelsize); + + mi = CModelInfo::GetModelInfo(modelname, CColStore::GetSlot(colSlot)->minIndex, CColStore::GetSlot(colSlot)->maxIndex); + if(mi){ + if(mi->GetColModel()){ + LoadCollisionModel(work_buff, *mi->GetColModel(), modelname); + }else{ + CColModel *model = new CColModel; + model->level = colSlot; + LoadCollisionModel(work_buff, *model, modelname); + mi->SetColModel(model, true); + } + }else{ + debug("colmodel %s can't find a modelinfo\n", modelname); + } + } + return true; +} +#endif + void CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) { @@ -384,7 +506,7 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id) return false; mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id); mi->SetClump(clump); - if(mi->m_type == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){ + if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) { // Read LOD ped clump = RpClumpStreamRead(stream); if(clump){ @@ -1060,19 +1182,36 @@ CFileLoader::LoadObjectInstance(const char *line) CSimpleModelInfo *mi; RwMatrix *xform; CEntity *entity; +#ifdef MIAMI + float area; + if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f %f", + &id, name, &area, + &trans.x, &trans.y, &trans.z, + &scale.x, &scale.y, &scale.z, + &axis.x, &axis.y, &axis.z, &angle) != 13){ +#endif if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", &id, name, &trans.x, &trans.y, &trans.z, &scale.x, &scale.y, &scale.z, &axis.x, &axis.y, &axis.z, &angle) != 12) return; +#ifdef MIAMI + area = 0; + } +#endif mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); if(mi == nil) return; assert(mi->IsSimple()); +#ifdef MIAMI + if(!CStreaming::IsObjectInCdImage(id)) + debug("Not in cdimage %s\n", mi->GetName()); +#endif + angle = -RADTODEG(2.0f * acosf(angle)); xform = RwMatrixCreate(); RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE); @@ -1087,6 +1226,9 @@ CFileLoader::LoadObjectInstance(const char *line) entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition()); +#ifdef MIAMI + entity->m_area = area; +#endif if(mi->IsSimple()){ if(mi->m_isBigBuilding) entity->SetupBigBuilding(); @@ -1096,14 +1238,28 @@ CFileLoader::LoadObjectInstance(const char *line) if(mi->GetLargestLodDistance() < 2.0f) entity->bIsVisible = false; CWorld::Add(entity); + +#ifdef MIAMI + CColModel *col = entity->GetColModel(); + if(col->numSpheres || col->numBoxes || col->numTriangles){ + if(col->level != 0) + CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect()); + }else + entity->bUsesCollision = false; + // TODO: set some flag here if col min is below 6 +#endif }else{ entity = new CDummyObject; entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); CWorld::Add(entity); +//--MIAMI: TODO if(IsGlass(entity->GetModelIndex())) entity->bIsVisible = false; entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition()); +#ifdef MIAMI + entity->m_area = area; +#endif } RwMatrixDestroy(xform); @@ -1325,7 +1481,7 @@ CFileLoader::ReloadObject(const char *line) #ifdef FIX_BUGS mi && #endif - mi->m_type == MITYPE_SIMPLE && !strcmp(mi->GetName(), model) && mi->m_numAtomics == numObjs) { + mi->GetModelType() == MITYPE_SIMPLE && !strcmp(mi->GetName(), model) && mi->m_numAtomics == numObjs) { mi->SetLodDistances(dist); SetModelInfoFlags(mi, flags); } else { diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h index 87b8fe61..aa8dcdb8 100644 --- a/src/core/FileLoader.h +++ b/src/core/FileLoader.h @@ -8,7 +8,13 @@ public: static void LoadCollisionFromDatFile(int currlevel); static char *LoadLine(int fd); static RwTexDictionary *LoadTexDictionary(const char *filename); +#ifndef MIAMI static void LoadCollisionFile(const char *filename); +#else + static void LoadCollisionFile(const char *filename, uint8 colSlot = 0); + static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot); + static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot); +#endif static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name); static void LoadModelFile(const char *filename); static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data); diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 3286f275..c27e5239 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -624,6 +624,10 @@ public: void LoadAllTextures(); void LoadSettings(); void MessageScreen(const char *); +#ifdef MIAMI + //--MIAMI: TODO: implement the second argument + void MessageScreen(const char *str, bool) { MessageScreen(str); } +#endif void PickNewPlayerColour(); void PrintBriefs(); static void PrintErrorMessage(); diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 0e618c84..d0b3f5a3 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -89,6 +89,9 @@ eLevelName CGame::currLevel; +#ifdef MIAMI +int32 CGame::currArea; +#endif bool CGame::bDemoMode = true; bool CGame::nastyGame = true; bool CGame::frenchGame; @@ -319,22 +322,7 @@ bool CGame::Initialise(const char* datFile) CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; LoadingScreen("Loading the Game", "Setup streaming", nil); -#ifdef USE_TXD_CDIMAGE - int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r"); - if (txdHandle) - CFileMgr::CloseFile(txdHandle); - if (!CheckVideoCardCaps() && txdHandle) { - CdStreamAddImage("MODELS\\TXD.IMG"); - CStreaming::Init(); - } else { - CStreaming::Init(); - if (CreateTxdImageForVideoCard()) { - CStreaming::Shutdown(); - CdStreamAddImage("MODELS\\TXD.IMG"); - CStreaming::Init(); - } - } -#else +#ifndef MIAMI CStreaming::Init(); #endif CStreaming::LoadInitialVehicles(); @@ -384,8 +372,10 @@ bool CGame::Initialise(const char* datFile) CWaterCannons::Init(); CBridge::Init(); CGarages::Init(); +#ifndef MIAMI LoadingScreen("Loading the Game", "Position dynamic objects", nil); CWorld::RepositionCertainDynamicObjects(); +#endif LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); #ifdef GTA_ZONECULL CCullZones::ResolveVisibilities(); @@ -400,7 +390,9 @@ bool CGame::Initialise(const char* datFile) CTheScripts::Process(); TheCamera.Process(); LoadingScreen("Loading the Game", "Load scene", nil); +#ifndef MIAMI CModelInfo::RemoveColModelsFromOtherLevels(currLevel); +#endif CCollision::ms_collisionInMemory = currLevel; for (int i = 0; i < MAX_PADS; i++) CPad::GetPad(i)->Clear(true); @@ -540,7 +532,9 @@ void CGame::ReloadIPLs(void) CRoadBlocks::Init(); CCranes::InitCranes(); CGarages::Init(); +#ifndef MIAMI CWorld::RepositionCertainDynamicObjects(); +#endif #ifdef GTA_ZONECULL CCullZones::ResolveVisibilities(); #endif diff --git a/src/core/Game.h b/src/core/Game.h index 48f31abc..8db5adf5 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -12,6 +12,9 @@ class CGame { public: static eLevelName currLevel; +#ifdef MIAMI + static int32 currArea; +#endif static bool bDemoMode; static bool nastyGame; static bool frenchGame; diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 0cd69119..ec6d3023 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -354,7 +354,7 @@ CPlayerInfo::Process(void) bool startTaxiTimer = true; if (m_bUnusedTaxiThing && m_pPed->bInVehicle) { CVehicle *veh = m_pPed->m_pMyVehicle; - if ((veh->m_modelIndex == MI_TAXI || veh->m_modelIndex == MI_CABBIE || veh->m_modelIndex == MI_BORGNINE) + if ((veh->GetModelIndex() == MI_TAXI || veh->GetModelIndex() == MI_CABBIE || veh->GetModelIndex() == MI_BORGNINE) && veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) { for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) { timePassed -= 1000; @@ -407,7 +407,7 @@ CPlayerInfo::Process(void) if (m_pPed->bInVehicle) { if (!m_pRemoteVehicle) { CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity; - if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->m_modelIndex)) { + if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->GetModelIndex())) { CVehicle *veh = m_pPed->m_pMyVehicle; if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) { diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 8d0a27b6..13266331 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -80,5 +80,6 @@ public: ~CPlayerInfo() { }; }; - +#ifndef MIAMI static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error"); +#endif diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index 4306cf09..bc65f6b6 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -223,21 +223,21 @@ INITSAVEBUF #ifdef COMPATIBLE_SAVES if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { WriteSaveBuf<uint32>(buf, pVehicle->m_vehType); - WriteSaveBuf<int16>(buf, pVehicle->m_modelIndex); + WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex()); WriteSaveBuf<int32>(buf, GetVehicleRef(pVehicle)); pVehicle->Save(buf); } #else if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); - WriteSaveBuf(buf, pVehicle->m_modelIndex); + WriteSaveBuf(buf, pVehicle->GetModelIndex()); WriteSaveBuf(buf, GetVehicleRef(pVehicle)); memcpy(buf, pVehicle, sizeof(CAutomobile)); SkipSaveBuf(buf, sizeof(CAutomobile)); } if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); - WriteSaveBuf(buf, pVehicle->m_modelIndex); + WriteSaveBuf(buf, pVehicle->GetModelIndex()); WriteSaveBuf(buf, GetVehicleRef(pVehicle)); memcpy(buf, pVehicle, sizeof(CBoat)); SkipSaveBuf(buf, sizeof(CBoat)); @@ -279,7 +279,7 @@ INITSAVEBUF bool bHasBeenDamaged = pObject->bHasBeenDamaged; bool bUseVehicleColours = pObject->bUseVehicleColours; CCompressedMatrixNotAligned tmp; - WriteSaveBuf(buf, pObject->m_modelIndex); + WriteSaveBuf(buf, pObject->GetModelIndex()); WriteSaveBuf(buf, GetObjectRef(pObject)); tmp.CompressFromFullMatrix(pObject->GetMatrix()); WriteSaveBuf(buf, tmp); @@ -397,7 +397,7 @@ INITSAVEBUF continue; if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) { WriteSaveBuf(buf, pPed->m_nPedType); - WriteSaveBuf(buf, pPed->m_modelIndex); + WriteSaveBuf(buf, pPed->GetModelIndex()); WriteSaveBuf(buf, GetPedRef(pPed)); #ifdef COMPATIBLE_SAVES pPed->Save(buf); diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index a76e9038..d212dd05 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -32,6 +32,10 @@ #include "Replay.h" #endif #include "main.h" +#ifdef MIAMI +#include "ColStore.h" +#include "DMAudio.h" +#endif bool CStreaming::ms_disableStreaming; bool CStreaming::ms_bLoadingBigModel; @@ -53,7 +57,9 @@ int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED]; int32 CStreaming::ms_lastVehicleDeleted; CDirectory *CStreaming::ms_pExtraObjectsDir; int32 CStreaming::ms_numPriorityRequests; +#ifndef MIAMI bool CStreaming::ms_hasLoadedLODs; +#endif int32 CStreaming::ms_currentPedGrp; int32 CStreaming::ms_currentPedLoading; int32 CStreaming::ms_lastCullZone; @@ -114,7 +120,7 @@ CStreamingInfo::RemoveFromList(void) } void -CStreaming::Init(void) +CStreaming::Init2(void) { int i; @@ -184,7 +190,9 @@ CStreaming::Init(void) ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE); ms_numPriorityRequests = 0; +#ifndef MIAMI ms_hasLoadedLODs = true; +#endif ms_currentPedGrp = -1; ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone ms_loadedGangs = 0; @@ -231,6 +239,7 @@ CStreaming::Init(void) CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd); CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom); +#ifndef MIAMI for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); if(building == nil) @@ -241,6 +250,30 @@ CStreaming::Init(void) if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building; if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building; } +#endif +} + +void +CStreaming::Init(void) +{ +#ifdef USE_TXD_CDIMAGE + int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r"); + if (txdHandle) + CFileMgr::CloseFile(txdHandle); + if (!CheckVideoCardCaps() && txdHandle) { + CdStreamAddImage("MODELS\\TXD.IMG"); + CStreaming::Init2(); + } else { + CStreaming::Init2(); + if (CreateTxdImageForVideoCard()) { + CStreaming::Shutdown(); + CdStreamAddImage("MODELS\\TXD.IMG"); + CStreaming::Init2(); + } + } +#else + CStreaming::Init(); +#endif } void @@ -269,21 +302,35 @@ CStreaming::Update(void) if(CTimer::GetIsPaused()) return; +#ifndef MIAMI train = FindPlayerTrain(); if(train && train->GetPosition().z < 0.0f){ RequestSubway(); requestedSubway = true; }else if(!ms_disableStreaming) AddModelsToRequestList(TheCamera.GetPosition()); +#else + LoadBigBuildingsWhenNeeded(); + if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f) + AddModelsToRequestList(TheCamera.GetPosition()); +#endif DeleteFarAwayRwObjects(TheCamera.GetPosition()); if(!ms_disableStreaming && +#ifndef MIAMI !CCutsceneMgr::IsRunning() && !requestedSubway && !CGame::playingIntro && +#else + !CCutsceneMgr::IsCutsceneProcessing() && +#endif ms_numModelsRequested < 5 && !CRenderer::m_loadingPriority +#ifdef MIAMI + && CGame::currArea == 0 + // replay is also MIAMI +#endif #ifdef FIX_BUGS && !CReplay::IsPlayingBack() #endif @@ -294,6 +341,17 @@ CStreaming::Update(void) LoadRequestedModels(); +#ifdef MIAMI + if(CWorld::Players[0].m_pRemoteVehicle){ + CColStore::AddCollisionNeededAtPosn(FindPlayerCoors()); + CColStore::LoadCollision(CWorld::Players[0].m_pRemoteVehicle->GetPosition()); + CColStore::EnsureCollisionIsInMemory(CWorld::Players[0].m_pRemoteVehicle->GetPosition()); + }else{ + CColStore::LoadCollision(FindPlayerCoors()); + CColStore::EnsureCollisionIsInMemory(FindPlayerCoors()); + } +#endif + for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){ prev = si->m_prev; if((si->m_flags & (STREAMFLAGS_KEEP_IN_MEMORY|STREAMFLAGS_PRIORITY)) == 0) @@ -351,6 +409,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) imgSelector = n<<24; assert(sizeof(direntry) == 32); while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){ +#ifndef MIAMI dot = strchr(direntry.name, '.'); if(dot) *dot = '\0'; if(direntry.size > (uint32)ms_streamingBufferSize) @@ -393,6 +452,64 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) } }else lastID = -1; +#else + bool bAddToStreaming = false; + + if(direntry.size > (uint32)ms_streamingBufferSize) + ms_streamingBufferSize = direntry.size; + direntry.name[23] = '\0'; + dot = strchr(direntry.name, '.'); + if(dot == nil || dot-direntry.name > 20){ + debug("%s is too long\n", direntry.name); + lastID = -1; + continue; + } + + *dot = '\0'; + + if(!CGeneral::faststricmp(dot+1, "DFF")){ + if(CModelInfo::GetModelInfo(direntry.name, &modelId)){ + bAddToStreaming = true; + }else{ +#ifdef FIX_BUGS + // remember which cdimage this came from + ms_pExtraObjectsDir->AddItem(direntry, n); +#else + ms_pExtraObjectsDir->AddItem(direntry); +#endif + lastID = -1; + } + }else if(!CGeneral::faststricmp(dot+1, "TXD")){ + modelId = CTxdStore::FindTxdSlot(direntry.name); + if(modelId == -1) + modelId = CTxdStore::AddTxdSlot(direntry.name); + modelId += STREAM_OFFSET_TXD; + bAddToStreaming = true; + }else if(!CGeneral::faststricmp(dot+1, "COL")){ + modelId = CColStore::FindColSlot(direntry.name); + if(modelId == -1) + modelId = CColStore::AddColSlot(direntry.name); + modelId += STREAM_OFFSET_COL; + bAddToStreaming = true; + // TODO: IFP + }else{ + *dot = '.'; + lastID = -1; + } + + if(bAddToStreaming){ + if(ms_aInfoForModel[modelId].GetCdSize()){ + debug("%s.%s appears more than once in %s\n", direntry.name, dot+1, dirname); + lastID = -1; + }else{ + direntry.offset |= imgSelector; + ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size); + if(lastID != -1) + ms_aInfoForModel[lastID].m_nextID = modelId; + lastID = modelId; + } + } +#endif } CFileMgr::CloseFile(fd); @@ -416,6 +533,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem); if(streamId < STREAM_OFFSET_TXD){ +//--MIAMI: also check animation // Model mi = CModelInfo::GetModelInfo(streamId); @@ -435,7 +553,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) if(mi->IsSimple()){ success = CFileLoader::LoadAtomicFile(stream, streamId); - }else if(mi->m_type == MITYPE_VEHICLE){ + } else if (mi->GetModelType() == MITYPE_VEHICLE) { // load vehicles in two parts CModelInfo::GetModelInfo(streamId)->AddRef(); success = CFileLoader::StartLoadClumpFile(stream, streamId); @@ -457,7 +575,11 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } +#ifndef MIAMI }else{ +#else + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ +#endif // Txd assert(streamId < NUMSTREAMINFO); if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 && @@ -482,10 +604,22 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } +#ifdef MIAMI + }else if(streamId >= STREAM_OFFSET_COL && streamId < NUMSTREAMINFO){ + if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){ + debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL)); + RemoveModel(streamId); + ReRequestModel(streamId); + RwStreamClose(stream, &mem); + return false; + } + // TODO: IFPs +#endif } RwStreamClose(stream, &mem); +#ifndef MIAMI // We shouldn't even end up here unless load was successful if(!success){ ReRequestModel(streamId); @@ -495,11 +629,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD)); return false; } +#endif if(streamId < STREAM_OFFSET_TXD){ // Model // Vehicles and Peds not in loaded list - if(mi->m_type != MITYPE_VEHICLE && mi->m_type != MITYPE_PED){ + if (mi->GetModelType() != MITYPE_VEHICLE && mi->GetModelType() != MITYPE_PED) { CSimpleModelInfo *smi = (CSimpleModelInfo*)mi; // Set fading for some objects @@ -510,12 +645,16 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) smi->m_alpha = 0; } - if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0) + if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); } +#ifndef MIAMI }else{ +#else + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // TODO: animations +#endif // Txd - if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0) + if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); } @@ -528,10 +667,23 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); timeDiff = endTime - startTime; if(timeDiff > 5){ +#ifndef MIAMI if(streamId < STREAM_OFFSET_TXD) debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff); else debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); +#else + // TODO: is this inlined? + static char objname[32]; + if(streamId < STREAM_OFFSET_TXD) + sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetName()); + else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL) + sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD)); + else if(streamId >= STREAM_OFFSET_COL && streamId < NUMSTREAMINFO) + sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL)); + // TODO: IFP + debug("%s took %d ms\n", objname, timeDiff); +#endif } return true; @@ -628,7 +780,7 @@ CStreaming::RequestModel(int32 id, int32 flags) // reinsert into list if(ms_aInfoForModel[id].m_next){ ms_aInfoForModel[id].RemoveFromList(); - if((ms_aInfoForModel[id].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0) + if((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) ms_aInfoForModel[id].AddToList(&ms_startLoadedList); } }else if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED || @@ -689,6 +841,12 @@ CStreaming::RequestSubway(void) } } +#ifndef MIAMI +#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY +#else +#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE +#endif + void CStreaming::RequestBigBuildings(eLevelName level) { @@ -699,27 +857,69 @@ CStreaming::RequestBigBuildings(eLevelName level) for(i = n; i >= 0; i--){ b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding && b->m_level == level) - RequestModel(b->GetModelIndex(), STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); +#ifdef MIAMI + if(!b->bStreamBIGBuilding) +#endif + RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } RequestIslands(level); +#ifndef MIAMI ms_hasLoadedLODs = false; +#endif } +#ifdef MIAMI +void +CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos) +{ + int i, n; + CBuilding *b; + + n = CPools::GetBuildingPool()->GetSize()-1; + for(i = n; i >= 0; i--){ + b = CPools::GetBuildingPool()->GetSlot(i); + if(b && b->bIsBIGBuilding && b->m_level == level) + if(b->bStreamBIGBuilding){ + if(CRenderer::ShouldModelBeStreamed(b)) + RequestModel(b->GetModelIndex(), 0); + }else + RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); + } + RequestIslands(level); +} + +void +CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos) +{ + int i, n; + CBuilding *b; + + n = CPools::GetBuildingPool()->GetSize()-1; + for(i = n; i >= 0; i--){ + b = CPools::GetBuildingPool()->GetSlot(i); + if(b && b->bIsBIGBuilding && b->m_level == level && + b->bStreamBIGBuilding && b->m_rwObject == nil) + if(CRenderer::ShouldModelBeStreamed(b)) + b->CreateRwObject(); + } +} +#endif + void CStreaming::RequestIslands(eLevelName level) { switch(level){ case LEVEL_INDUSTRIAL: - RequestModel(islandLODcomInd, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); - RequestModel(islandLODsubInd, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + RequestModel(islandLODcomInd, BIGBUILDINGFLAGS); + RequestModel(islandLODsubInd, BIGBUILDINGFLAGS); break; case LEVEL_COMMERCIAL: - RequestModel(islandLODindust, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); - RequestModel(islandLODsubCom, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + RequestModel(islandLODindust, BIGBUILDINGFLAGS); + RequestModel(islandLODsubCom, BIGBUILDINGFLAGS); break; case LEVEL_SUBURBAN: - RequestModel(islandLODindust, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); - RequestModel(islandLODcomSub, STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY); + RequestModel(islandLODindust, BIGBUILDINGFLAGS); + RequestModel(islandLODcomSub, BIGBUILDINGFLAGS); break; } } @@ -802,10 +1002,20 @@ CStreaming::RemoveModel(int32 id) return; if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ +#ifndef MIAMI if(id < STREAM_OFFSET_TXD) CModelInfo::GetModelInfo(id)->DeleteRwObject(); else CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); +#else + if(id < STREAM_OFFSET_TXD) + CModelInfo::GetModelInfo(id)->DeleteRwObject(); + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) + CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < NUMSTREAMINFO) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + // TODO: IFP +#endif ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE; } @@ -824,15 +1034,26 @@ CStreaming::RemoveModel(int32 id) } if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){ +#ifndef MIAMI if(id < STREAM_OFFSET_TXD) RpClumpGtaCancelStream(); else CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); +#else + if(id < STREAM_OFFSET_TXD) + RpClumpGtaCancelStream(); + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) + CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < NUMSTREAMINFO) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + // TODO: IFP +#endif } ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED; } +//--MIAMI: change islands void CStreaming::RemoveUnusedBuildings(eLevelName level) { @@ -844,6 +1065,7 @@ CStreaming::RemoveUnusedBuildings(eLevelName level) RemoveBuildings(LEVEL_SUBURBAN); } +//--MIAMI: done void CStreaming::RemoveBuildings(eLevelName level) { @@ -858,7 +1080,7 @@ CStreaming::RemoveBuildings(eLevelName level) mi = CModelInfo::GetModelInfo(e->GetModelIndex()); if(!e->bImBeingRendered){ e->DeleteRwObject(); - if(mi->m_refCount == 0) + if (mi->GetNumRefs() == 0) RemoveModel(e->GetModelIndex()); } } @@ -871,7 +1093,7 @@ CStreaming::RemoveBuildings(eLevelName level) mi = CModelInfo::GetModelInfo(e->GetModelIndex()); if(!e->bImBeingRendered){ e->DeleteRwObject(); - if(mi->m_refCount == 0) + if (mi->GetNumRefs() == 0) RemoveModel(e->GetModelIndex()); } } @@ -884,7 +1106,7 @@ CStreaming::RemoveBuildings(eLevelName level) mi = CModelInfo::GetModelInfo(e->GetModelIndex()); if(!e->bImBeingRendered && ((CObject*)e)->ObjectCreatedBy == GAME_OBJECT){ e->DeleteRwObject(); - if(mi->m_refCount == 0) + if (mi->GetNumRefs() == 0) RemoveModel(e->GetModelIndex()); } } @@ -897,13 +1119,14 @@ CStreaming::RemoveBuildings(eLevelName level) mi = CModelInfo::GetModelInfo(e->GetModelIndex()); if(!e->bImBeingRendered){ e->DeleteRwObject(); - if(mi->m_refCount == 0) + if (mi->GetNumRefs() == 0) RemoveModel(e->GetModelIndex()); } } } } +//--MIAMI: change islands void CStreaming::RemoveUnusedBigBuildings(eLevelName level) { @@ -932,6 +1155,21 @@ DeleteIsland(CEntity *island) void CStreaming::RemoveIslandsNotUsed(eLevelName level) { +#ifdef MIAMI + int i; + if(pIslandLODindustEntity == nil) + for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ + CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); + if(building == nil) + continue; + if(building->GetModelIndex() == islandLODindust) pIslandLODindustEntity = building; + if(building->GetModelIndex() == islandLODcomInd) pIslandLODcomIndEntity = building; + if(building->GetModelIndex() == islandLODcomSub) pIslandLODcomSubEntity = building; + if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building; + if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building; + } +#endif + switch(level){ case LEVEL_INDUSTRIAL: DeleteIsland(pIslandLODindustEntity); @@ -958,6 +1196,7 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level) } } +//--MIAMI: done void CStreaming::RemoveBigBuildings(eLevelName level) { @@ -972,7 +1211,7 @@ CStreaming::RemoveBigBuildings(eLevelName level) mi = CModelInfo::GetModelInfo(e->GetModelIndex()); if(!e->bImBeingRendered){ e->DeleteRwObject(); - if(mi->m_refCount == 0) + if (mi->GetNumRefs() == 0) RemoveModel(e->GetModelIndex()); } } @@ -990,8 +1229,7 @@ CStreaming::RemoveLoadedVehicle(void) ms_lastVehicleDeleted = 0; id = ms_vehiclesLoaded[ms_lastVehicleDeleted]; if(id != -1 && - (ms_aInfoForModel[id].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0 && - CModelInfo::GetModelInfo(id)->m_refCount == 0 && + (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 && ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED) goto found; } @@ -1012,7 +1250,7 @@ CStreaming::RemoveLeastUsedModel(void) for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){ streamId = si - ms_aInfoForModel; if(streamId < STREAM_OFFSET_TXD){ - if(CModelInfo::GetModelInfo(streamId)->m_refCount == 0){ + if (CModelInfo::GetModelInfo(streamId)->GetNumRefs() == 0) { RemoveModel(streamId); return true; } @@ -1038,7 +1276,7 @@ CStreaming::RemoveAllUnusedModels(void) for(i = NUM_DEFAULT_MODELS; i < MODELINFOSIZE; i++){ if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED && ms_aInfoForModel[i].m_flags & STREAMFLAGS_DONT_REMOVE && - CModelInfo::GetModelInfo(i)->m_refCount == 0){ + CModelInfo::GetModelInfo(i)->GetNumRefs() == 0) { RemoveModel(i); ms_aInfoForModel[i].m_loadState = STREAMSTATE_NOTLOADED; } @@ -1129,8 +1367,7 @@ CStreaming::AddToLoadedVehiclesList(int32 modelId) for(i = 0; i < MAXVEHICLESLOADED; i++){ id = ms_vehiclesLoaded[ms_lastVehicleDeleted]; if(id != -1 && - (ms_aInfoForModel[id].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0 && - CModelInfo::GetModelInfo(id)->m_refCount == 0) + (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0) goto found; ms_lastVehicleDeleted++; if(ms_lastVehicleDeleted == MAXVEHICLESLOADED) @@ -1163,6 +1400,7 @@ CStreaming::IsObjectInCdImage(int32 id) return ms_aInfoForModel[id].GetCdPosnAndSize(posn, size); } +#ifndef MIAMI void CStreaming::HaveAllBigBuildingsLoaded(eLevelName level) { @@ -1197,12 +1435,13 @@ CStreaming::HaveAllBigBuildingsLoaded(eLevelName level) RemoveUnusedBigBuildings(level); ms_hasLoadedLODs = true; } +#endif void CStreaming::SetModelIsDeletable(int32 id) { ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_DONT_REMOVE; - if((id >= STREAM_OFFSET_TXD || CModelInfo::GetModelInfo(id)->m_type != MITYPE_VEHICLE) && + if ((id >= STREAM_OFFSET_TXD || CModelInfo::GetModelInfo(id)->GetModelType() != MITYPE_VEHICLE) && (ms_aInfoForModel[id].m_flags & STREAMFLAGS_SCRIPTOWNED) == 0){ if(ms_aInfoForModel[id].m_loadState != STREAMSTATE_LOADED) RemoveModel(id); @@ -1221,7 +1460,7 @@ void CStreaming::SetMissionDoesntRequireModel(int32 id) { ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_SCRIPTOWNED; - if((id >= STREAM_OFFSET_TXD || CModelInfo::GetModelInfo(id)->m_type != MITYPE_VEHICLE) && + if ((id >= STREAM_OFFSET_TXD || CModelInfo::GetModelInfo(id)->GetModelType() != MITYPE_VEHICLE) && (ms_aInfoForModel[id].m_flags & STREAMFLAGS_DONT_REMOVE) == 0){ if(ms_aInfoForModel[id].m_loadState != STREAMSTATE_LOADED) RemoveModel(id); @@ -1430,6 +1669,43 @@ CStreaming::RemoveCurrentZonesModels(void) ms_loadedGangCars = 0; } +#ifdef MIAMI +void +CStreaming::LoadBigBuildingsWhenNeeded(void) +{ + // Very much like CCollision::Update and CCollision::LoadCollisionWhenINeedIt + if(CCutsceneMgr::IsCutsceneProcessing()) + return; + + if(CTheZones::m_CurrLevel == LEVEL_NONE || + CTheZones::m_CurrLevel == CGame::currLevel) + return; + + CTimer::Suspend(); + CGame::currLevel = CTheZones::m_CurrLevel; + DMAudio.SetEffectsFadeVol(0); + CPad::StopPadsShaking(); + CCollision::LoadCollisionScreen(CGame::currLevel); + DMAudio.Service(); + + // CPopulation::DealWithZoneChange is unused in VC + RemoveUnusedBigBuildings(CGame::currLevel); + RemoveUnusedBuildings(CGame::currLevel); + RemoveUnusedModelsInLoadedList(); + CGame::TidyUpMemory(true, true); + + CReplay::EmptyReplayBuffer(); + if(CGame::currLevel != LEVEL_NONE) + LoadSplash(GetLevelSplashScreen(CGame::currLevel)); + + CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); + CStreaming::LoadAllRequestedModels(true); + + CGame::TidyUpMemory(true, true); + CTimer::Resume(); + DMAudio.SetEffectsFadeVol(127); +} +#endif // Find starting offset of the cdimage we next want to read @@ -1599,8 +1875,8 @@ CStreaming::RequestModelStream(int32 ch) // Can't load certain combinations of files together if(streamId < STREAM_OFFSET_TXD){ - if(havePed && CModelInfo::GetModelInfo(streamId)->m_type == MITYPE_PED || - haveBigFile && CModelInfo::GetModelInfo(streamId)->m_type == MITYPE_VEHICLE || + if (havePed && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED || + haveBigFile && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE || !TxdAvailable(CModelInfo::GetModelInfo(streamId)->GetTxdSlot())) break; }else{ @@ -1619,9 +1895,9 @@ CStreaming::RequestModelStream(int32 ch) break; } if(streamId < STREAM_OFFSET_TXD){ - if(CModelInfo::GetModelInfo(streamId)->m_type == MITYPE_PED) + if (CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED) havePed = 1; - if(CModelInfo::GetModelInfo(streamId)->m_type == MITYPE_VEHICLE) + if (CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE) haveBigFile = 1; }else{ if(size > 200) @@ -1679,14 +1955,13 @@ CStreaming::ProcessLoadingChannel(int32 ch) continue; cdsize = ms_aInfoForModel[id].GetCdSize(); - if(id < STREAM_OFFSET_TXD && - CModelInfo::GetModelInfo(id)->m_type == MITYPE_VEHICLE && + if(id < STREAM_OFFSET_TXD && CModelInfo::GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && ms_numVehiclesLoaded >= desiredNumVehiclesLoaded && !RemoveLoadedVehicle() && - ((ms_aInfoForModel[id].m_flags & STREAMFLAGS_NOT_IN_LIST) == 0 || GetAvailableVehicleSlot() == -1)){ + ((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 || GetAvailableVehicleSlot() == -1)){ // can't load vehicle RemoveModel(id); - if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_NOT_IN_LIST) + if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) ReRequestModel(id); else if(CTxdStore::GetNumRefs(CModelInfo::GetModelInfo(id)->GetTxdSlot()) == 0) RemoveTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot()); @@ -1953,14 +2228,16 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float if(!e->bStreamingDontDelete && !e->bIsSubway && (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){ CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()); - if(mi->m_type != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())){ + if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) { lodDistSq = sq(mi->GetLargestLodDistance()); lodDistSq = Min(lodDistSq, sq(STREAM_DIST)); pos = CVector2D(e->GetPosition()); if(xmin < pos.x && pos.x < xmax && ymin < pos.y && pos.y < ymax && (CVector2D(x, y) - pos).MagnitudeSqr() < lodDistSq) +#ifdef GTA_ZONECULL if(CRenderer::IsEntityCullZoneVisible(e)) +#endif RequestModel(e->GetModelIndex(), 0); } } @@ -1983,8 +2260,10 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list) if(!e->bStreamingDontDelete && !e->bIsSubway && (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){ CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()); - if(mi->m_type != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) + if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) +#ifdef GTA_ZONECULL if(CRenderer::IsEntityCullZoneVisible(e)) +#endif RequestModel(e->GetModelIndex(), 0); } } @@ -2349,7 +2628,7 @@ CStreaming::DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem) if(!e->bStreamingDontDelete && !e->bImBeingRendered && e->m_rwObject && ms_aInfoForModel[e->GetModelIndex()].m_next){ e->DeleteRwObject(); - if(CModelInfo::GetModelInfo(e->GetModelIndex())->m_refCount == 0){ + if (CModelInfo::GetModelInfo(e->GetModelIndex())->GetNumRefs() == 0) { RemoveModel(e->GetModelIndex()); if(ms_memoryUsed < mem) return true; @@ -2370,7 +2649,7 @@ CStreaming::DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem) if(!e->bStreamingDontDelete && !e->bImBeingRendered && e->m_rwObject && !e->IsVisible() && ms_aInfoForModel[e->GetModelIndex()].m_next){ e->DeleteRwObject(); - if(CModelInfo::GetModelInfo(e->GetModelIndex())->m_refCount == 0){ + if (CModelInfo::GetModelInfo(e->GetModelIndex())->GetNumRefs() == 0) { RemoveModel(e->GetModelIndex()); if(ms_memoryUsed < mem) return true; @@ -2408,13 +2687,37 @@ CStreaming::LoadScene(const CVector &pos) RemoveModel(si - ms_aInfoForModel); } CRenderer::m_loadingPriority = false; +#ifdef GTA_ZONECULL CCullZones::ForceCullZoneCoors(pos); +#endif DeleteAllRwObjects(); +#ifndef MIAMI AddModelsToRequestList(pos); CRadar::StreamRadarSections(pos); RemoveUnusedBigBuildings(level); RequestBigBuildings(level); LoadAllRequestedModels(false); +#else + if(level == LEVEL_NONE) + level = CGame::currLevel; + CGame::currLevel = level; + RemoveUnusedBigBuildings(level); + RequestBigBuildings(level, pos); + RequestBigBuildings(LEVEL_NONE, pos); + RemoveIslandsNotUsed(level); + LoadAllRequestedModels(false); + InstanceBigBuildings(level, pos); + InstanceBigBuildings(LEVEL_NONE, pos); + AddModelsToRequestList(pos); + CRadar::StreamRadarSections(pos); + + // TODO: stream zone vehicles + LoadAllRequestedModels(false); + // TODO: InstanceLoadedModels + + for(int i = 0; i < NUMSTREAMINFO; i++) + ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20; +#endif debug("End load scene\n"); } diff --git a/src/core/Streaming.h b/src/core/Streaming.h index cf8790e9..d2920824 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -3,9 +3,13 @@ #include "Game.h" enum { - STREAM_OFFSET_MODEL = 0, - STREAM_OFFSET_TXD = STREAM_OFFSET_MODEL+MODELINFOSIZE, + STREAM_OFFSET_TXD = MODELINFOSIZE, +#ifndef MIAMI NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE +#else + STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE, + NUMSTREAMINFO = STREAM_OFFSET_COL+COLSTORESIZE +#endif }; enum StreamFlags @@ -15,9 +19,11 @@ enum StreamFlags STREAMFLAGS_DEPENDENCY = 0x04, // Is this right? STREAMFLAGS_PRIORITY = 0x08, STREAMFLAGS_NOFADE = 0x10, +#ifdef MIAMI + STREAMFLAGS_20 = 0x20, +#endif - // TODO: this isn't named well, maybe CANT_REMOVE? - STREAMFLAGS_NOT_IN_LIST = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED, + STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED, STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY, }; @@ -96,7 +102,9 @@ public: static int32 ms_lastVehicleDeleted; static CDirectory *ms_pExtraObjectsDir; static int32 ms_numPriorityRequests; +#ifndef MIAMI static bool ms_hasLoadedLODs; +#endif static int32 ms_currentPedGrp; static int32 ms_lastCullZone; static uint16 ms_loadedGangs; @@ -108,6 +116,7 @@ public: static uint32 ms_memoryAvailable; static void Init(void); + static void Init2(void); static void Shutdown(void); static void Update(void); static void LoadCdDirectory(void); @@ -115,12 +124,29 @@ public: static bool ConvertBufferToObject(int8 *buf, int32 streamId); static bool FinishLoadingLargeFile(int8 *buf, int32 streamId); static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; } + static bool HasTxdLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_TXD); } +#ifdef MIAMI + static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); } +#endif + static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; } + static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); } +#ifdef MIAMI + static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); } +#endif static void RequestModel(int32 model, int32 flags); static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); } static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); } static void ReRequestTxd(int32 txd) { ReRequestModel(txd + STREAM_OFFSET_TXD); } +#ifdef MIAMI + static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); } + static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); } +#endif static void RequestSubway(void); static void RequestBigBuildings(eLevelName level); +#ifdef MIAMI + static void RequestBigBuildings(eLevelName level, const CVector &pos); + static void InstanceBigBuildings(eLevelName level, const CVector &pos); +#endif static void RequestIslands(eLevelName level); static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags); static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags); @@ -129,6 +155,9 @@ public: static void DecrementRef(int32 id); static void RemoveModel(int32 id); static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); } +#ifdef MIAMI + static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); } +#endif static void RemoveUnusedBuildings(eLevelName level); static void RemoveBuildings(eLevelName level); static void RemoveUnusedBigBuildings(eLevelName level); @@ -143,7 +172,9 @@ public: static bool IsTxdUsedByRequestedModels(int32 txdId); static bool AddToLoadedVehiclesList(int32 modelId); static bool IsObjectInCdImage(int32 id); +#ifndef MIAMI static void HaveAllBigBuildingsLoaded(eLevelName level); +#endif static void SetModelIsDeletable(int32 id); static void SetModelTxdIsDeletable(int32 id); static void SetMissionDoesntRequireModel(int32 id); @@ -152,6 +183,9 @@ public: static void StreamVehiclesAndPeds(void); static void StreamZoneModels(const CVector &pos); static void RemoveCurrentZonesModels(void); +#ifdef MIAMI + static void LoadBigBuildingsWhenNeeded(void); +#endif static int32 GetCdImageOffset(int32 lastPosn); static int32 GetNextFileOnCd(int32 position, bool priority); diff --git a/src/core/World.cpp b/src/core/World.cpp index e87d23f2..09170f54 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -1,4 +1,4 @@ -#include "World.h" +#include "common.h" #include "Camera.h" #include "CarCtrl.h" #include "CopPed.h" @@ -26,7 +26,7 @@ #include "TempColModels.h" #include "Vehicle.h" #include "WaterLevel.h" -#include "common.h" +#include "World.h" #define OBJECT_REPOSITION_OFFSET_Z 2.0f @@ -758,7 +758,7 @@ CWorld::FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList &list, const CEntity *pEntity = (CEntity *)pNode->item; if(pEntity->m_scanCode != GetCurrentScanCode()) { pEntity->m_scanCode = GetCurrentScanCode(); - if(modelId == pEntity->m_modelIndex) { + if (modelId == pEntity->GetModelIndex()) { float fMagnitude = 0.0f; if(bCheck2DOnly) fMagnitude = (position - pEntity->GetPosition()).MagnitudeSqr2D(); @@ -953,14 +953,13 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad float distance = diff.Magnitude(); if(e->GetBoundRadius() + radius > distance) { - CColModel *eCol = CModelInfo::GetModelInfo(e->m_modelIndex)->GetColModel(); + CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); int collidedSpheres = CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol, gaTempSphereColPoints, nil, nil); if(collidedSpheres != 0 || - (e->IsVehicle() && ((CVehicle *)e)->m_vehType == VEHICLE_TYPE_CAR && - e->m_modelIndex != MI_DODO && + (e->IsVehicle() && ((CVehicle *)e)->m_vehType == VEHICLE_TYPE_CAR && e->GetModelIndex() != MI_DODO && radius + eCol->boundingBox.max.x > distance)) { return e; } @@ -1823,7 +1822,7 @@ CWorld::RepositionCertainDynamicObjects() void CWorld::RepositionOneObject(CEntity *pEntity) { - int16 modelId = pEntity->m_modelIndex; + int16 modelId = pEntity->GetModelIndex(); if (IsTrafficLight(modelId) || IsTreeModel(modelId) || modelId == MI_PARKINGMETER || modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || modelId == MI_BIN || modelId == MI_POSTBOX1 || modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || modelId == MI_DUMP1 || @@ -2026,8 +2025,7 @@ CWorld::Process(void) if(!movingEnt->bIsInSafePosition) { movingEnt->bIsStuck = true; if(movingEnt->GetStatus() == STATUS_PLAYER) { - printf("STUCK: Final Step: Player Entity %d Is Stuck\n", - movingEnt->m_modelIndex); + printf("STUCK: Final Step: Player Entity %d Is Stuck\n", movingEnt->GetModelIndex()); movingEnt->m_vecMoveSpeed *= 0.3f; movingEnt->ApplyMoveSpeed(); movingEnt->ApplyTurnSpeed(); @@ -2119,13 +2117,13 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa if(!pEntity->bExplosionProof && (!pEntity->IsPed() || !pPed->bInVehicle)) { if(pEntity->bIsStatic) { if(pEntity->IsObject()) { - if(fPower > pObject->m_fUprootLimit || IsFence(pObject->m_modelIndex)) { - if(IsGlass(pObject->m_modelIndex)) { + if (fPower > pObject->m_fUprootLimit || IsFence(pObject->GetModelIndex())) { + if (IsGlass(pObject->GetModelIndex())) { CGlass::WindowRespondsToExplosion(pObject, position); } else { pObject->bIsStatic = false; pObject->AddToMovingList(); - int16 modelId = pEntity->m_modelIndex; + int16 modelId = pEntity->GetModelIndex(); if(modelId != MI_FIRE_HYDRANT || pObject->bHasBeenDamaged) { if(pEntity->IsObject() && diff --git a/src/core/config.h b/src/core/config.h index f4f7205b..c3904fa9 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -7,8 +7,14 @@ enum Config { MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, +#ifndef MIAMI MODELINFOSIZE = 5500, TXDSTORESIZE = 850, +#else + MODELINFOSIZE = 6500, + TXDSTORESIZE = 1385, + COLSTORESIZE = 31, +#endif EXTRADIRSIZE = 128, CUTSCENEDIRSIZE = 512, diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 44253c14..a74b81a3 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -323,14 +323,26 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); }); DebugMenuAddCmd("Spawn", "Spawn Predator", [](){ SpawnCar(MI_PREDATOR); }); + DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil); #ifdef LIBRW DebugMenuAddVarBool8("Render", "PS2 Alpha test Emu", &gPS2alphaTest, nil); #endif DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil); DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil); DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil); + DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil); + DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil); + DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil); + DebugMenuAddVarBool8("Render", "Show Ped Road Groups", &gbShowPedRoadGroups, nil); + DebugMenuAddVarBool8("Render", "Show Car Road Groups", &gbShowCarRoadGroups, nil); + DebugMenuAddVarBool8("Render", "Show Collision Lines", &gbShowCollisionLines, nil); + DebugMenuAddVarBool8("Render", "Show Collision Polys", &gbShowCollisionPolys, nil); + DebugMenuAddVarBool8("Render", "Don't render Buildings", &gbDontRenderBuildings, nil); + DebugMenuAddVarBool8("Render", "Don't render Big Buildings", &gbDontRenderBigBuildings, nil); + DebugMenuAddVarBool8("Render", "Don't render Peds", &gbDontRenderPeds, nil); + DebugMenuAddVarBool8("Render", "Don't render Vehicles", &gbDontRenderVehicles, nil); + DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil); - DebugMenuAddVarBool8("Debug", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil); DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil); #ifdef MENU_MAP DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint); @@ -347,18 +359,6 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway); DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil); - DebugMenuAddVarBool8("Debug", "Show Ped Paths", &gbShowPedPaths, nil); - DebugMenuAddVarBool8("Debug", "Show Car Paths", &gbShowCarPaths, nil); - DebugMenuAddVarBool8("Debug", "Show Car Path Links", &gbShowCarPathsLinks, nil); - DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", &gbShowPedRoadGroups, nil); - DebugMenuAddVarBool8("Debug", "Show Car Road Groups", &gbShowCarRoadGroups, nil); - DebugMenuAddVarBool8("Debug", "Show Collision Lines", &gbShowCollisionLines, nil); - DebugMenuAddVarBool8("Debug", "Show Collision Polys", &gbShowCollisionPolys, nil); - DebugMenuAddVarBool8("Debug", "Don't render Buildings", &gbDontRenderBuildings, nil); - DebugMenuAddVarBool8("Debug", "Don't render Big Buildings", &gbDontRenderBigBuildings, nil); - DebugMenuAddVarBool8("Debug", "Don't render Peds", &gbDontRenderPeds, nil); - DebugMenuAddVarBool8("Debug", "Don't render Vehicles", &gbDontRenderVehicles, nil); - DebugMenuAddVarBool8("Debug", "Don't render Objects", &gbDontRenderObjects, nil); #ifdef TOGGLEABLE_BETA_FEATURES DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil); DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", &CPed::bMakePedsRunToPhonesToReportCrimes, nil); diff --git a/src/core/templates.h b/src/core/templates.h index 51a24e4c..74bc4713 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -35,15 +35,24 @@ class CPool public: CPool(int size){ + // TODO: use new here m_entries = (U*)malloc(sizeof(U)*size); m_flags = (Flags*)malloc(sizeof(Flags)*size); m_size = size; +#ifndef MIAMI m_allocPtr = 0; +#else + m_allocPtr = -1; +#endif for(int i = 0; i < size; i++){ m_flags[i].id = 0; m_flags[i].free = 1; } } +#ifdef MIAMI + CPool(int size, const char *name) + : CPool(size) {} +#endif ~CPool() { Flush(); } diff --git a/src/entities/Building.cpp b/src/entities/Building.cpp index aad2d402..3c096636 100644 --- a/src/entities/Building.cpp +++ b/src/entities/Building.cpp @@ -12,7 +12,7 @@ CBuilding::ReplaceWithNewModel(int32 id) { DeleteRwObject(); - if(CModelInfo::GetModelInfo(m_modelIndex)->m_refCount == 0) + if (CModelInfo::GetModelInfo(m_modelIndex)->GetNumRefs() == 0) CStreaming::RemoveModel(m_modelIndex); m_modelIndex = id; diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 2a6211d6..955f32a8 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -27,6 +27,7 @@ #include "Zones.h" #include "Bones.h" #include "Debug.h" +#include "Renderer.h" int gBuildings; @@ -51,6 +52,9 @@ CEntity::CEntity(void) bRenderScorched = false; bHasBlip = false; bIsBIGBuilding = false; +#ifdef MIAMI + bStreamBIGBuilding = false; +#endif bRenderDamaged = false; bBulletProof = false; @@ -59,8 +63,10 @@ CEntity::CEntity(void) bMeleeProof = false; bOnlyDamagedByPlayer = false; bStreamingDontDelete = false; +#ifdef GTA_ZONECULL bZoneCulled = false; bZoneCulled2 = false; +#endif bRemoveFromWorld = false; bHasHitWall = false; @@ -147,6 +153,17 @@ CEntity::GetIsOnScreenComplex(void) return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix()); } +bool +CEntity::GetIsOnScreenAndNotCulled(void) +{ +#ifdef GTA_ZONECULL + return GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(this); +#else + return GetIsOnScreen(); +#endif +} + + void CEntity::Add(void) { @@ -331,6 +348,11 @@ CEntity::SetupBigBuilding(void) bStreamingDontDelete = true; bUsesCollision = false; m_level = CTheZones::GetLevelFromPosition(GetPosition()); +#ifdef MIAMI + if(mi->m_lodDistances[0] <= 2000.0f) + bStreamBIGBuilding = true; + // TODO: the stuff down there isn't right yet +#endif if(m_level == LEVEL_NONE){ if(mi->GetTxdSlot() != CTxdStore::FindTxdSlot("generic")){ mi->SetTexDictionary("generic"); @@ -452,7 +474,7 @@ CEntity::PreRender(void) break; } - if(CModelInfo::GetModelInfo(GetModelIndex())->m_num2dEffects != 0) + if (CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects() != 0) ProcessLightsForEntity(); } @@ -611,7 +633,7 @@ CEntity::AddSteamsFromGround(CVector *unused) C2dEffect *effect; CVector pos; - n = CModelInfo::GetModelInfo(GetModelIndex())->m_num2dEffects; + n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); for(i = 0; i < n; i++){ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); if(effect->type != EFFECT_PARTICLE) @@ -654,7 +676,7 @@ CEntity::ProcessLightsForEntity(void) flashTimer2 = 0; flashTimer3 = 0; - n = CModelInfo::GetModelInfo(GetModelIndex())->m_num2dEffects; + n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects(); for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i); @@ -953,8 +975,10 @@ CEntity::SaveEntityFlags(uint8*& buf) if (bMeleeProof) tmp |= BIT(27); if (bOnlyDamagedByPlayer) tmp |= BIT(28); if (bStreamingDontDelete) tmp |= BIT(29); +#ifdef GTA_ZONECULL if (bZoneCulled) tmp |= BIT(30); if (bZoneCulled2) tmp |= BIT(31); +#endif WriteSaveBuf<uint32>(buf, tmp); @@ -1006,8 +1030,10 @@ CEntity::LoadEntityFlags(uint8*& buf) bMeleeProof = !!(tmp & BIT(27)); bOnlyDamagedByPlayer = !!(tmp & BIT(28)); bStreamingDontDelete = !!(tmp & BIT(29)); +#ifdef GTA_ZONECULL bZoneCulled = !!(tmp & BIT(30)); bZoneCulled2 = !!(tmp & BIT(31)); +#endif tmp = ReadSaveBuf<uint32>(buf); diff --git a/src/entities/Entity.h b/src/entities/Entity.h index dbe2c08b..49c6932c 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -59,7 +59,9 @@ public: uint32 bRenderScorched : 1; uint32 bHasBlip : 1; uint32 bIsBIGBuilding : 1; // Set if this entity is a big building - // VC inserts one more flag here: if drawdist <= 2000 +#ifdef MIAMI + uint32 bStreamBIGBuilding : 1; // set when draw dist <= 2000 +#endif uint32 bRenderDamaged : 1; // use damaged LOD models for objects with applicable damage // flagsC @@ -69,8 +71,10 @@ public: uint32 bMeleeProof : 1; uint32 bOnlyDamagedByPlayer : 1; uint32 bStreamingDontDelete : 1; // Dont let the streaming remove this +#ifdef GTA_ZONECULL uint32 bZoneCulled : 1; uint32 bZoneCulled2 : 1; // only treadables+10m +#endif // flagsD uint32 bRemoveFromWorld : 1; // remove this entity next time it should be processed @@ -89,7 +93,12 @@ public: uint16 m_scanCode; uint16 m_randomSeed; int16 m_modelIndex; +#ifndef MIAMI uint16 m_level; // int16 +#else + int8 m_level; + int8 m_area; +#endif CReference *m_pFirstReference; public: @@ -147,9 +156,10 @@ public: bool GetIsTouching(CVector const ¢er, float r); bool GetIsOnScreen(void); bool GetIsOnScreenComplex(void); + bool GetIsOnScreenAndNotCulled(void); bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); } bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); } - int GetModelIndex(void) { return m_modelIndex; } + int16 GetModelIndex(void) const { return m_modelIndex; } void UpdateRwFrame(void); void SetupBigBuilding(void); diff --git a/src/math/Rect.h b/src/math/Rect.h index fd1bd05e..326bb479 100644 --- a/src/math/Rect.h +++ b/src/math/Rect.h @@ -26,6 +26,25 @@ public: if(v.y < top) top = v.y; if(v.y > bottom) bottom = v.y; } + void ContainRect(const CRect &r){ + if(r.left < left) left = r.left; + if(r.right > right) right = r.right; + if(r.top < top) top = r.top; + if(r.bottom > bottom) bottom = r.bottom; + } + + bool IsPointInside(const CVector2D &p){ + return p.x >= left && + p.x <= right && + p.y >= top && + p.y <= bottom; + } + bool IsPointInside(const CVector2D &p, float extraRadius){ + return p.x >= left-extraRadius && + p.x <= right+extraRadius && + p.y >= top-extraRadius && + p.y <= bottom+extraRadius; + } void Translate(float x, float y){ left += x; diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp index e8d2601f..a2779107 100644 --- a/src/modelinfo/BaseModelInfo.cpp +++ b/src/modelinfo/BaseModelInfo.cpp @@ -6,7 +6,7 @@ #include "BaseModelInfo.h" -CBaseModelInfo::CBaseModelInfo(ModeInfoType type) +CBaseModelInfo::CBaseModelInfo(ModelInfoType type) { m_colModel = nil; m_twodEffects = nil; @@ -15,7 +15,7 @@ CBaseModelInfo::CBaseModelInfo(ModeInfoType type) m_txdSlot = -1; m_type = type; m_num2dEffects = 0; - m_freeCol = false; + m_bOwnsColModel = false; } void @@ -31,7 +31,7 @@ CBaseModelInfo::Shutdown(void) void CBaseModelInfo::DeleteCollisionModel(void) { - if(m_colModel && m_freeCol){ + if(m_colModel && m_bOwnsColModel){ if(m_colModel) delete m_colModel; m_colModel = nil; diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h index 0c4bf934..9f828e7f 100644 --- a/src/modelinfo/BaseModelInfo.h +++ b/src/modelinfo/BaseModelInfo.h @@ -4,7 +4,7 @@ #define MAX_MODEL_NAME (24) -enum ModeInfoType : uint8 +enum ModelInfoType : uint8 { MITYPE_NA = 0, MITYPE_SIMPLE = 1, @@ -15,26 +15,25 @@ enum ModeInfoType : uint8 MITYPE_PED = 6, MITYPE_XTRACOMPS = 7, }; -static_assert(sizeof(ModeInfoType) == 1, "ModeInfoType: error"); +static_assert(sizeof(ModelInfoType) == 1, "ModeInfoType: error"); class C2dEffect; class CBaseModelInfo { protected: - // TODO?: make more things protected char m_name[MAX_MODEL_NAME]; CColModel *m_colModel; C2dEffect *m_twodEffects; int16 m_objectId; -public: uint16 m_refCount; int16 m_txdSlot; - ModeInfoType m_type; + ModelInfoType m_type; uint8 m_num2dEffects; - bool m_freeCol; + bool m_bOwnsColModel; - CBaseModelInfo(ModeInfoType type); +public: + CBaseModelInfo(ModelInfoType type); virtual ~CBaseModelInfo() {} virtual void Shutdown(void); virtual void DeleteRwObject(void) = 0; @@ -42,15 +41,18 @@ public: virtual RwObject *CreateInstance(void) = 0; virtual RwObject *GetRwObject(void) = 0; + // one day it becomes virtual + ModelInfoType GetModelType() const { return m_type; } bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; } bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE || m_type == MITYPE_MLO || m_type == MITYPE_XTRACOMPS; // unused but what the heck } char *GetName(void) { return m_name; } void SetName(const char *name) { strncpy(m_name, name, 24); } - void SetColModel(CColModel *col, bool free = false){ - m_colModel = col; m_freeCol = free; } + void SetColModel(CColModel *col, bool owns = false){ + m_colModel = col; m_bOwnsColModel = owns; } CColModel *GetColModel(void) { return m_colModel; } + bool DoesOwnColModel(void) { return m_bOwnsColModel; } void DeleteCollisionModel(void); void ClearTexDictionary(void) { m_txdSlot = -1; } short GetObjectID(void) { return m_objectId; } @@ -64,6 +66,8 @@ public: void Init2dEffects(void); void Add2dEffect(C2dEffect *fx); C2dEffect *Get2dEffect(int n); + uint8 GetNum2dEffects() const { return m_num2dEffects; } + uint16 GetNumRefs() const { return m_refCount; } }; static_assert(sizeof(CBaseModelInfo) == 0x30, "CBaseModelInfo: error"); diff --git a/src/modelinfo/ClumpModelInfo.h b/src/modelinfo/ClumpModelInfo.h index 100aa30b..c37a468a 100644 --- a/src/modelinfo/ClumpModelInfo.h +++ b/src/modelinfo/ClumpModelInfo.h @@ -32,7 +32,7 @@ public: RpClump *m_clump; CClumpModelInfo(void) : CBaseModelInfo(MITYPE_CLUMP) {} - CClumpModelInfo(ModeInfoType id) : CBaseModelInfo(id) {} + CClumpModelInfo(ModelInfoType id) : CBaseModelInfo(id) {} ~CClumpModelInfo() {} void DeleteRwObject(void); RwObject *CreateInstance(void); diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp index c1ae692f..62deae2b 100644 --- a/src/modelinfo/ModelInfo.cpp +++ b/src/modelinfo/ModelInfo.cpp @@ -200,20 +200,35 @@ CModelInfo::GetModelInfo(const char *name, int *id) return nil; } +#ifdef MIAMI +CBaseModelInfo* +CModelInfo::GetModelInfo(const char *name, int minIndex, int maxIndex) +{ + CBaseModelInfo *modelinfo; + for(int i = minIndex; i <= maxIndex; i++){ + modelinfo = CModelInfo::ms_modelInfoPtrs[i]; + if(modelinfo && !CGeneral::faststricmp(modelinfo->GetName(), name)) + return modelinfo; + } + return nil; +} +#endif + bool CModelInfo::IsBoatModel(int32 id) { - return GetModelInfo(id)->m_type == MITYPE_VEHICLE && + return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_BOAT; } bool CModelInfo::IsBikeModel(int32 id) { - return GetModelInfo(id)->m_type == MITYPE_VEHICLE && + return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_BIKE; } +#ifndef MIAMI void CModelInfo::RemoveColModelsFromOtherLevels(eLevelName level) { @@ -230,6 +245,7 @@ CModelInfo::RemoveColModelsFromOtherLevels(eLevelName level) } } } +#endif void CModelInfo::ConstructMloClumps() diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h index 65cfa4e7..dadc8f8b 100644 --- a/src/modelinfo/ModelInfo.h +++ b/src/modelinfo/ModelInfo.h @@ -42,6 +42,9 @@ public: static CBaseModelInfo *GetModelInfo(int id){ return ms_modelInfoPtrs[id]; } +#ifdef MIAMI + static CBaseModelInfo *GetModelInfo(const char *name, int minIndex, int maxIndex); +#endif static bool IsBoatModel(int32 id); static bool IsBikeModel(int32 id); diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp index 2fb2adeb..63b057da 100644 --- a/src/modelinfo/SimpleModelInfo.cpp +++ b/src/modelinfo/SimpleModelInfo.cpp @@ -95,6 +95,12 @@ CSimpleModelInfo::IncreaseAlpha(void) } float +CSimpleModelInfo::GetLodDistance(int i) +{ + return m_lodDistances[i] * TheCamera.LODDistMultiplier; +} + +float CSimpleModelInfo::GetNearDistance(void) { return m_lodDistances[2] * TheCamera.LODDistMultiplier; @@ -119,11 +125,21 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist) if(m_isDamaged) i = m_firstDamaged; for(; i < m_numAtomics; i++) - if(dist < m_lodDistances[i] *TheCamera.LODDistMultiplier) + if(dist < m_lodDistances[i] * TheCamera.LODDistMultiplier) return m_atomics[i]; return nil; } +#ifdef MIAMI +RpAtomic* +CSimpleModelInfo::GetFirstAtomicFromDistance(float dist) +{ + if(dist < m_lodDistances[0] * TheCamera.LODDistMultiplier) + return m_atomics[0]; + return nil; +} +#endif + void CSimpleModelInfo::FindRelatedModel(void) { diff --git a/src/modelinfo/SimpleModelInfo.h b/src/modelinfo/SimpleModelInfo.h index 35d48669..451a9c00 100644 --- a/src/modelinfo/SimpleModelInfo.h +++ b/src/modelinfo/SimpleModelInfo.h @@ -25,7 +25,7 @@ public: uint16 m_noZwrite : 1; CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {} - CSimpleModelInfo(ModeInfoType id) : CBaseModelInfo(id) {} + CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {} ~CSimpleModelInfo() {} void DeleteRwObject(void); RwObject *CreateInstance(void); @@ -36,10 +36,13 @@ public: void IncreaseAlpha(void); void SetAtomic(int n, RpAtomic *atomic); void SetLodDistances(float *dist); - float GetLodDistance(int i) { return m_lodDistances[i]; } + float GetLodDistance(int i); float GetNearDistance(void); float GetLargestLodDistance(void); RpAtomic *GetAtomicFromDistance(float dist); +#ifdef MIAMI + RpAtomic *GetFirstAtomicFromDistance(float dist); // inline +#endif void FindRelatedModel(void); void SetupBigBuilding(void); diff --git a/src/modelinfo/TimeModelInfo.cpp b/src/modelinfo/TimeModelInfo.cpp index fec3f6e5..d4f92293 100644 --- a/src/modelinfo/TimeModelInfo.cpp +++ b/src/modelinfo/TimeModelInfo.cpp @@ -22,7 +22,7 @@ CTimeModelInfo::FindOtherTimeModel(void) for(i = 0; i < MODELINFOSIZE; i++){ CBaseModelInfo *mi = CModelInfo::GetModelInfo(i); - if(mi && mi->m_type == MITYPE_TIME && + if (mi && mi->GetModelType() == MITYPE_TIME && strncmp(name, mi->GetName(), 24) == 0){ m_otherTimeModelID = i; return (CTimeModelInfo*)mi; diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp index 3ef257d2..0938960e 100644 --- a/src/objects/CutsceneHead.cpp +++ b/src/objects/CutsceneHead.cpp @@ -131,7 +131,7 @@ CCutsceneHead::RenderLimb(int32 bone) RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(m_parentObject->GetClump()); int idx = RpHAnimIDGetIndex(hier, bone); RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); - CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + CPedModelInfo *mi = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()); switch(bone){ case BONE_Lhand: atomic = mi->getLeftHand(); diff --git a/src/objects/CutsceneObject.cpp b/src/objects/CutsceneObject.cpp index 492d5416..5c10d37d 100644 --- a/src/objects/CutsceneObject.cpp +++ b/src/objects/CutsceneObject.cpp @@ -100,7 +100,7 @@ void CCutsceneObject::RenderLimb(int32 bone) { RpAtomic *atomic; - CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + CPedModelInfo *mi = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()); switch(bone){ case BONE_head: atomic = mi->getHead(); diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 1ae5e9b0..ab1290b0 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -57,7 +57,7 @@ CObject::CObject(int32 mi, bool createRW) CObject::CObject(CDummyObject *dummy) { - SetModelIndexNoCreate(dummy->m_modelIndex); + SetModelIndexNoCreate(dummy->GetModelIndex()); if (dummy->m_rwObject) AttachToRwObject(dummy->m_rwObject); @@ -97,7 +97,7 @@ CObject::ProcessControl(void) m_vecMoveSpeed *= fTimeStep; m_vecTurnSpeed *= fTimeStep; } - if ((m_modelIndex == MI_EXPLODINGBARREL || m_modelIndex == MI_PETROLPUMP) && bHasBeenDamaged && bIsVisible + if ((GetModelIndex() == MI_EXPLODINGBARREL || GetModelIndex() == MI_PETROLPUMP) && bHasBeenDamaged && bIsVisible && (CGeneral::GetRandomNumber() & 0x1F) == 10) { bExplosionProof = true; bIsVisible = false; @@ -125,7 +125,7 @@ CObject::Render(void) if(m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours){ CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_nRefModelIndex); - assert(mi->m_type == MITYPE_VEHICLE); + assert(mi->GetModelType() == MITYPE_VEHICLE); mi->SetVehicleColour(m_colour1, m_colour2); } @@ -159,7 +159,7 @@ CObject::ObjectDamage(float amount) return; static int8 nFrameGen = 0; bool bBodyCastDamageEffect = false; - if (m_modelIndex == MI_BODYCAST){ + if (GetModelIndex() == MI_BODYCAST) { if (amount > 50.0f) nBodyCastHealth = (int16)(nBodyCastHealth - 0.5f * amount); if (nBodyCastHealth < 0) @@ -310,7 +310,7 @@ void CObject::Init(void) { m_type = ENTITY_TYPE_OBJECT; - CObjectData::SetObjectData(m_modelIndex, *this); + CObjectData::SetObjectData(GetModelIndex(), *this); m_nEndOfLifeTime = 0; ObjectCreatedBy = GAME_OBJECT; bIsStatic = true; @@ -333,9 +333,9 @@ CObject::Init(void) m_pCurSurface = outEntity; else m_pCurSurface = nil; - if (m_modelIndex == MI_BODYCAST) + if (GetModelIndex() == MI_BODYCAST) nBodyCastHealth = 1000; - else if (m_modelIndex == MI_BUOY) + else if (GetModelIndex() == MI_BUOY) bTouchingWater = true; } diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp index 2dee0397..3c25d827 100644 --- a/src/peds/CivilianPed.cpp +++ b/src/peds/CivilianPed.cpp @@ -187,8 +187,10 @@ CCivilianPed::CivilianAI(void) void CCivilianPed::ProcessControl(void) { +#ifndef MIAMI if (m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory) return; +#endif CPed::ProcessControl(); diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp index 8bfd807f..7140af76 100644 --- a/src/peds/CopPed.cpp +++ b/src/peds/CopPed.cpp @@ -565,8 +565,10 @@ CCopPed::CopAI(void) void CCopPed::ProcessControl(void) { +#ifndef MIAMI if (m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory) return; +#endif CPed::ProcessControl(); if (bWasPostponed) @@ -715,7 +717,7 @@ CCopPed::ProcessControl(void) return; bool dontShoot = false; - if (GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(this)) { + if (GetIsOnScreenAndNotCulled()) { if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) { CEntity *foundBuilding = nil; CColPoint foundCol; diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp index 7229ed3f..e85cfc8b 100644 --- a/src/peds/EmergencyPed.cpp +++ b/src/peds/EmergencyPed.cpp @@ -44,8 +44,10 @@ CEmergencyPed::InRange(CPed *victim) void CEmergencyPed::ProcessControl(void) { +#ifndef MIAMI if (m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory) return; +#endif CPed::ProcessControl(); if (bWasPostponed) diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index b1609094..04b62e46 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -1667,7 +1667,7 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP CVector vehDoorOffset; float seatOffset; - vehModel = (CVehicleModelInfo*) CModelInfo::GetModelInfo(veh->m_modelIndex); + vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex()); if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) { seatOffset = 0.0f; vehDoorOffset = vecPedVanRearDoorAnimOffset; @@ -2351,7 +2351,7 @@ CPed::SetModelIndex(uint32 mi) CEntity::SetModelIndex(mi); RpAnimBlendClumpInit(GetClump()); RpAnimBlendClumpFillFrameArray(GetClump(), m_pFrames); - CPedModelInfo *modelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + CPedModelInfo *modelInfo = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()); SetPedStats(modelInfo->m_pedStatType); m_headingRate = m_pedStats->m_headingChangeRate; m_animGroup = (AssocGroupId) modelInfo->m_animGroup; @@ -4245,9 +4245,8 @@ CPed::SetGetUp(void) CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition()); if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE || collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE - && ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8 - || CCollision::ProcessColModels(GetMatrix(), *CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(), - collidingVeh->GetMatrix(), *CModelInfo::GetModelInfo(collidingVeh->m_modelIndex)->GetColModel(), + && ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8 || + CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(), aTempPedColPts, nil, nil) > 0)) { bGetUpAnimStarted = false; @@ -4640,9 +4639,9 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType) animType = 1; } } - if (neededTurn <= DEGTORAD(90.0f) || veh->m_modelIndex == MI_RCBANDIT || vehPressedHorn || animType != 0) { + if (neededTurn <= DEGTORAD(90.0f) || veh->GetModelIndex() == MI_RCBANDIT || vehPressedHorn || animType != 0) { SetLookFlag(veh, true); - if ((CGeneral::GetRandomNumber() & 1) && veh->m_modelIndex != MI_RCBANDIT && animType == 0) { + if ((CGeneral::GetRandomNumber() & 1) && veh->GetModelIndex() != MI_RCBANDIT && animType == 0) { stepAnim = ANIM_IDLE_TAXI; } else { @@ -5149,7 +5148,7 @@ CPed::FightStrike(CVector &touchedNodePos) #ifdef PED_SKIN // Have to animate a skinned clump because the initial col model is useless if(IsClumpSkinned(GetClump())) - ourCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->AnimatePedColModelSkinned(GetClump()); + ourCol = ((CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()))->AnimatePedColModelSkinned(GetClump()); else #endif if (nearPed->m_nPedState == PED_FALL @@ -5158,7 +5157,8 @@ CPed::FightStrike(CVector &touchedNodePos) ourCol = &CTempColModels::ms_colModelPedGroundHit; } else { #ifdef ANIMATE_PED_COL_MODEL - ourCol = CPedModelInfo::AnimatePedColModel(((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->GetHitColModel(), RpClumpGetFrame(GetClump())); + ourCol = CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()))->GetHitColModel(), + RpClumpGetFrame(GetClump())); #else ourCol = ((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->GetHitColModel(); #endif @@ -5916,7 +5916,7 @@ CPed::CreateDeadPedMoney(void) if (!CGame::nastyGame) return; - int skin = m_modelIndex; + int skin = GetModelIndex(); if ((skin >= MI_COP && skin <= MI_FIREMAN) || CharCreatedBy == MISSION_CHAR || bInVehicle) return; @@ -6397,7 +6397,7 @@ uint8 CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos) { CVector enterStepOffset; - CVehicleModelInfo *trainModel = (CVehicleModelInfo*) CModelInfo::GetModelInfo(train->m_modelIndex); + CVehicleModelInfo *trainModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(train->GetModelIndex()); CMatrix trainMat = CMatrix(train->GetMatrix()); CVector leftEntryPos, rightEntryPos, midEntryPos; float distLeftEntry, distRightEntry, distMidEntry; @@ -6472,7 +6472,7 @@ void CPed::LineUpPedWithTrain(void) { CVector lineUpPos; - CVehicleModelInfo *trainModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pMyVehicle->m_modelIndex); + CVehicleModelInfo *trainModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(m_pMyVehicle->GetModelIndex()); CVector enterOffset(1.5f, 0.0f, -0.2f); m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); @@ -6535,7 +6535,7 @@ CPed::ExitCar(void) // Car is upside down if (m_pMyVehicle->GetUp().z > -0.8f) { if (exitAnim != ANIM_CAR_CLOSE_RHS && exitAnim != ANIM_CAR_CLOSE_LHS && animTime <= 0.3f) - LineUpPedWithCar((m_pMyVehicle->m_modelIndex == MI_DODO ? LINE_UP_TO_CAR_END : LINE_UP_TO_CAR_START)); + LineUpPedWithCar((m_pMyVehicle->GetModelIndex() == MI_DODO ? LINE_UP_TO_CAR_END : LINE_UP_TO_CAR_START)); else LineUpPedWithCar(LINE_UP_TO_CAR_END); } else { @@ -7043,7 +7043,7 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg) return; CVector forward(0.15f * ped->GetForward() + ped->GetPosition()); - forward.z += CModelInfo::GetModelInfo(ped->m_modelIndex)->GetColModel()->spheres->center.z + 0.25f; + forward.z += CModelInfo::GetModelInfo(ped->GetModelIndex())->GetColModel()->spheres->center.z + 0.25f; CEntity *obstacle = CWorld::TestSphereAgainstWorld(forward, 0.25f, nil, true, true, false, true, false, false); if (!obstacle) { @@ -7483,7 +7483,7 @@ CPed::Seek(void) if (!obstacle->IsVehicle() || ((CVehicle*)obstacle)->m_vehType == VEHICLE_TYPE_CAR) { distanceToCountItDone = 2.5f; } else { - CVehicleModelInfo *vehModel = (CVehicleModelInfo*) CModelInfo::GetModelInfo(obstacle->m_modelIndex); + CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(obstacle->GetModelIndex()); float yLength = vehModel->GetColModel()->boundingBox.max.y - vehModel->GetColModel()->boundingBox.min.y; distanceToCountItDone = yLength * 0.55f; @@ -7940,9 +7940,9 @@ CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen) CVector rfPos, lrPos, rrPos; bool canEnter = false; - CVehicleModelInfo *vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(veh->m_modelIndex); + CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex()); - switch (veh->m_modelIndex) { + switch (veh->GetModelIndex()) { case MI_BUS: m_vehEnterType = CAR_DOOR_RF; posToOpen = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF); @@ -8599,7 +8599,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) CVector distVec = GetPosition() - car->GetPosition(); - if ((impulse > 12.0f || car->m_modelIndex == MI_TRAIN) && !IsPlayer()) { + if ((impulse > 12.0f || car->GetModelIndex() == MI_TRAIN) && !IsPlayer()) { nodeToDamage = PED_TORSO; killMethod = WEAPONTYPE_RAMMEDBYCAR; uint8 randVal = CGeneral::GetRandomNumber() & 3; @@ -8616,11 +8616,11 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) } bIsStanding = false; damageDir = CPed::GetLocalDirection(-m_vecMoveSpeed); - vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(car->m_modelIndex); + vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(car->GetModelIndex()); vehColModel = vehModel->GetColModel(); float carRightAndDistDotProd = DotProduct(distVec, car->GetRight()); - if (car->m_modelIndex == MI_TRAIN) { + if (car->GetModelIndex() == MI_TRAIN) { killMethod = WEAPONTYPE_RUNOVERBYCAR; nodeToDamage = PED_HEAD; m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed; @@ -8780,7 +8780,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) bIsStanding = false; uint8 fallDirection = GetLocalDirection(-car->m_vecMoveSpeed); float damage; - if (IsPlayer() && car->m_modelIndex == MI_TRAIN) + if (IsPlayer() && car->GetModelIndex() == MI_TRAIN) damage = 150.0f; else damage = 30.0f; @@ -8789,14 +8789,14 @@ CPed::KillPedWithCar(CVehicle *car, float impulse) CPed::SetFall(1000, (AnimationId)(fallDirection + ANIM_KO_SKID_FRONT), true); if ((m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD) - && !m_pCollidingEntity - && (!IsPlayer() || bHasHitWall || car->m_modelIndex == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) { + && !m_pCollidingEntity && + (!IsPlayer() || bHasHitWall || car->GetModelIndex() == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) { m_pCollidingEntity = car; } bKnockedUpIntoAir = false; - if (car->m_modelIndex != MI_TRAIN && !bHasHitWall) { + if (car->GetModelIndex() != MI_TRAIN && !bHasHitWall) { m_vecMoveSpeed = car->m_vecMoveSpeed * 0.75f; } m_vecMoveSpeed.z = 0.0f; @@ -8870,8 +8870,8 @@ CPed::LookForInterestingNodes(void) for (ptrNode = sector->m_lists[ENTITYLIST_VEHICLES].first; ptrNode && !found; ptrNode = ptrNode->next) { CVehicle *veh = (CVehicle*)ptrNode->item; model = veh->GetModelInfo(); - if (model->m_num2dEffects != 0) { - for (int e = 0; e < model->m_num2dEffects; e++) { + if (model->GetNum2dEffects() != 0) { + for (int e = 0; e < model->GetNum2dEffects(); e++) { effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &veh->GetMatrix(); @@ -8887,9 +8887,9 @@ CPed::LookForInterestingNodes(void) } for (ptrNode = sector->m_lists[ENTITYLIST_OBJECTS].first; ptrNode && !found; ptrNode = ptrNode->next) { CObject *obj = (CObject*)ptrNode->item; - model = CModelInfo::GetModelInfo(obj->m_modelIndex); - if (model->m_num2dEffects != 0) { - for (int e = 0; e < model->m_num2dEffects; e++) { + model = CModelInfo::GetModelInfo(obj->GetModelIndex()); + if (model->GetNum2dEffects() != 0) { + for (int e = 0; e < model->GetNum2dEffects(); e++) { effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &obj->GetMatrix(); @@ -8905,9 +8905,9 @@ CPed::LookForInterestingNodes(void) } for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS].first; ptrNode && !found; ptrNode = ptrNode->next) { CBuilding *building = (CBuilding*)ptrNode->item; - model = CModelInfo::GetModelInfo(building->m_modelIndex); - if (model->m_num2dEffects != 0) { - for (int e = 0; e < model->m_num2dEffects; e++) { + model = CModelInfo::GetModelInfo(building->GetModelIndex()); + if (model->GetNum2dEffects() != 0) { + for (int e = 0; e < model->GetNum2dEffects(); e++) { effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &building->GetMatrix(); @@ -8923,9 +8923,9 @@ CPed::LookForInterestingNodes(void) } for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].first; ptrNode && !found; ptrNode = ptrNode->next) { CBuilding *building = (CBuilding*)ptrNode->item; - model = CModelInfo::GetModelInfo(building->m_modelIndex); - if (model->m_num2dEffects != 0) { - for (int e = 0; e < model->m_num2dEffects; e++) { + model = CModelInfo::GetModelInfo(building->GetModelIndex()); + if (model->GetNum2dEffects() != 0) { + for (int e = 0; e < model->GetNum2dEffects(); e++) { effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &building->GetMatrix(); @@ -9153,7 +9153,7 @@ CPed::MoveHeadToLook(void) if (animTime > 4.0f / 30.0f && animTime - fuckUAssoc->timeStep > 4.0f / 30.0f) { bool lookingToCop = false; - if (m_pLookTarget->m_modelIndex == MI_POLICE + if (m_pLookTarget->GetModelIndex() == MI_POLICE || m_pLookTarget->IsPed() && ((CPed*)m_pLookTarget)->m_nPedType == PEDTYPE_COP) { lookingToCop = true; @@ -9213,7 +9213,7 @@ CPed::MoveHeadToLook(void) } else { animToPlay = ANIM_FUCKU; } - } else if (m_pedStats->m_temper > 49 || m_pLookTarget->m_modelIndex == MI_POLICE) { + } else if (m_pedStats->m_temper > 49 || m_pLookTarget->GetModelIndex() == MI_POLICE) { animToPlay = ANIM_FUCKU; } } else if (notRocketLauncher && (CGeneral::GetRandomNumber() & 1)) { @@ -9397,8 +9397,10 @@ CPed::ProcessControl(void) CColPoint foundCol; CEntity *foundEnt = nil; +#ifndef MIAMI if (m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory) return; +#endif int alpha = CVisibilityPlugins::GetClumpAlpha(GetClump()); if (!bFadeOut) { @@ -9549,7 +9551,7 @@ CPed::ProcessControl(void) case ENTITY_TYPE_BUILDING: case ENTITY_TYPE_OBJECT: { - CBaseModelInfo *collidingModel = CModelInfo::GetModelInfo(collidingEnt->m_modelIndex); + CBaseModelInfo *collidingModel = CModelInfo::GetModelInfo(collidingEnt->GetModelIndex()); CColModel *collidingCol = collidingModel->GetColModel(); if (collidingEnt->IsObject() && ((CObject*)collidingEnt)->m_nSpecialCollisionResponseCases != COLLRESPONSE_CHANGE_THEN_SMASH || collidingCol->boundingBox.max.x < 3.0f @@ -9978,7 +9980,7 @@ CPed::ProcessControl(void) } else { DMAudio.PlayOneShot(collidingVeh->m_audioEntityId, SOUND_CAR_PED_COLLISION, m_fDamageImpulse); if (IsPlayer()) { - CColModel *collidingCol = CModelInfo::GetModelInfo(collidingVeh->m_modelIndex)->GetColModel(); + CColModel *collidingCol = CModelInfo::GetModelInfo(collidingVeh->GetModelIndex())->GetColModel(); CVector colMinVec = collidingCol->boundingBox.min; CVector colMaxVec = collidingCol->boundingBox.max; @@ -10040,7 +10042,7 @@ CPed::ProcessControl(void) float damage; if (driver && driver->IsPlayer()) { damage = vehRightVecAndSpeedDotProd * 1000.0f; - } else if (collidingVeh->m_modelIndex == MI_TRAIN) { + } else if (collidingVeh->GetModelIndex() == MI_TRAIN) { damage = 50.0f; } else { damage = 20.0f; @@ -11979,7 +11981,7 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker) } if (attackerPed && attackerPed->IsPlayer() && (attackerPed->m_nPedState == PED_CARJACK || attackerPed->bInVehicle)) { - if (!attackerPed->m_pMyVehicle || attackerPed->m_pMyVehicle->m_modelIndex != MI_TOYZ) { + if (!attackerPed->m_pMyVehicle || attackerPed->m_pMyVehicle->GetModelIndex() != MI_TOYZ) { int16 lastVehicle; CEntity *vehicles[8]; CWorld::FindObjectsInRange(GetPosition(), 30.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false); @@ -12706,7 +12708,7 @@ CPed::renderLimb(int node) RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump()); int idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID); RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; - CPedModelInfo *mi = (CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex); + CPedModelInfo *mi = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex()); RpAtomic *atomic; switch(node){ case PED_HEAD: @@ -14098,7 +14100,7 @@ void CPed::SetDirectionToWalkAroundObject(CEntity *obj) { float distLimitForTimer = 8.0f; - CColModel *objCol = CModelInfo::GetModelInfo(obj->m_modelIndex)->GetColModel(); + CColModel *objCol = CModelInfo::GetModelInfo(obj->GetModelIndex())->GetColModel(); CVector objColMin = objCol->boundingBox.min; CVector objColMax = objCol->boundingBox.max; CVector objColCenter = (objColMin + objColMax) / 2.0f; @@ -14117,7 +14119,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) #ifdef TOGGLEABLE_BETA_FEATURES if (!bMakePedsRunToPhonesToReportCrimes) #endif - if (CharCreatedBy != MISSION_CHAR && obj->m_modelIndex == MI_PHONEBOOTH1) { + if (CharCreatedBy != MISSION_CHAR && obj->GetModelIndex() == MI_PHONEBOOTH1) { bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT; SetFindPathAndFlee(obj, 5000, !isRunning); return; @@ -14133,7 +14135,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) if (objMat.GetUp().z < 0.0f) objUpsideDown = true; - if (obj->m_modelIndex != MI_TRAFFICLIGHTS && obj->m_modelIndex != MI_SINGLESTREETLIGHTS1 && obj->m_modelIndex != MI_SINGLESTREETLIGHTS2) { + if (obj->GetModelIndex() != MI_TRAFFICLIGHTS && obj->GetModelIndex() != MI_SINGLESTREETLIGHTS1 && obj->GetModelIndex() != MI_SINGLESTREETLIGHTS2) { objColCenter = obj->GetMatrix() * objColCenter; } else { checkIntervalInDist = 0.4f; @@ -14650,8 +14652,8 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints) CColPoint intersectionPoint; CColLine ourLine; - CColModel *ourCol = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); - CColModel *hisCol = CModelInfo::GetModelInfo(collidingEnt->m_modelIndex)->GetColModel(); + CColModel *ourCol = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel(); + CColModel *hisCol = CModelInfo::GetModelInfo(collidingEnt->GetModelIndex())->GetColModel(); if (!bUsesCollision) return false; @@ -15106,7 +15108,7 @@ CPed::SetRadioStation(void) if (IsPlayer() || !m_pMyVehicle || m_pMyVehicle->pDriver != this) return; - uint8 category = GetPedRadioCategory(m_modelIndex); + uint8 category = GetPedRadioCategory(GetModelIndex()); if (DMAudio.IsMP3RadioChannelAvailable()) { if (CGeneral::GetRandomNumber() & 15) { for (orderInCat = 0; orderInCat < 4; orderInCat++) { @@ -15196,7 +15198,7 @@ CPed::PreRender(void) if (CWeather::Rain > 0.3f && TheCamera.SoundDistUp > 15.0f) { if ((TheCamera.GetPosition() - GetPosition()).Magnitude() < 25.0f) { bool doSplashUp = true; - CColModel *ourCol = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); + CColModel *ourCol = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel(); CVector speed = FindPlayerSpeed(); if (Abs(speed.x) <= 0.05f && Abs(speed.y) <= 0.05f) { @@ -15673,7 +15675,7 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode) } else { if (veh->GetUp().z > -0.8f) { bool addDoorSmoke = false; - if (veh->m_modelIndex == MI_YARDIE) + if (veh->GetModelIndex() == MI_YARDIE) addDoorSmoke = true; switch (m_vehEnterType) { @@ -15915,7 +15917,7 @@ CPed::ScanForInterestingStuff(void) for (int i = 0; i < lastVehicle; i++) { CVehicle* veh = (CVehicle*)vehicles[i]; - if (veh->m_modelIndex == MI_MRWHOOP) { + if (veh->GetModelIndex() == MI_MRWHOOP) { if (veh->GetStatus() != STATUS_ABANDONED && veh->GetStatus() != STATUS_WRECKED) { if ((GetPosition() - veh->GetPosition()).Magnitude() < 5.0f) { SetObjective(OBJECTIVE_BUY_ICE_CREAM, veh); @@ -16132,7 +16134,7 @@ CPed::SeekCar(void) SetMoveState(PEDMOVE_STILL); return; } - if (vehToSeek->m_modelIndex == MI_COACH) { + if (vehToSeek->GetModelIndex() == MI_COACH) { GetNearestDoor(vehToSeek, dest); } else { if (vehToSeek->IsTrain()) { @@ -16270,7 +16272,7 @@ void CPed::ServiceTalking(void) { if (!bBodyPartJustCameOff || m_bodyPartBleeding != PED_HEAD) { - if (CGeneral::faststricmp(CModelInfo::GetModelInfo(m_modelIndex)->GetName(), "bomber")) { + if (CGeneral::faststricmp(CModelInfo::GetModelInfo(GetModelIndex())->GetName(), "bomber")) { if (m_nPedState == PED_ON_FIRE) m_queuedSound = SOUND_PED_BURNING; } else { @@ -16806,7 +16808,7 @@ CPed::SetPedPositionInCar(void) return; } } - CVehicleModelInfo *vehModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pMyVehicle->m_modelIndex); + CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(m_pMyVehicle->GetModelIndex()); CMatrix newMat(m_pMyVehicle->GetMatrix()); CVector seatPos; if (m_pMyVehicle->pDriver == this) { @@ -16924,7 +16926,7 @@ CPed::SpawnFlyingComponent(int pedNode, int8 direction) default: break; } - obj->RefModelInfo(m_modelIndex); + obj->RefModelInfo(GetModelIndex()); obj->AttachToRwObject((RwObject*)clump); obj->m_fMass = 15.0f; obj->m_fTurnMass = 5.0f; @@ -17602,7 +17604,7 @@ CPed::SetCarJack(CVehicle* car) pedInSeat = car->pDriver; if (m_fHealth > 0.0f && (IsPlayer() || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS || - (car->VehicleCreatedBy != MISSION_VEHICLE && car->m_modelIndex != MI_DODO))) + (car->VehicleCreatedBy != MISSION_VEHICLE && car->GetModelIndex() != MI_DODO))) if (pedInSeat && !pedInSeat->IsPedDoingDriveByShooting() && pedInSeat->m_nPedState == PED_DRIVING) if (m_nPedState != PED_CARJACK && !m_pVehicleAnim) if ((car->IsDoorReady(door) || car->IsDoorFullyOpen(door))) @@ -17658,7 +17660,7 @@ CPed::SetExitBoat(CVehicle *boat) m_nPedState = PED_IDLE; CVector firstPos = GetPosition(); CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 100.0f); - if (boat->m_modelIndex == MI_SPEEDER && boat->IsUpsideDown()) { + if (boat->GetModelIndex() == MI_SPEEDER && boat->IsUpsideDown()) { m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS, 8.0f); m_pVehicleAnim->SetFinishCallback(CPed::PedSetOutCarCB, this); m_vehEnterType = CAR_DOOR_RF; diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp index 8dd9d23d..fed607ed 100644 --- a/src/peds/Population.cpp +++ b/src/peds/Population.cpp @@ -755,7 +755,7 @@ CPopulation::AddPedInCar(CVehicle* car) int preferredModel; CTheZones::GetZoneInfoForTimeOfDay(&coors, &zoneInfo); - switch (car->m_modelIndex) { + switch (car->GetModelIndex()) { case MI_FIRETRUCK: preferredModel = 0; pedType = PEDTYPE_FIREMAN; @@ -796,14 +796,14 @@ CPopulation::AddPedInCar(CVehicle* car) int gangOfPed = 0; imSureThatModelIsLoaded = false; - while (gangOfPed < NUM_GANGS && CGangs::GetGangInfo(gangOfPed)->m_nVehicleMI != car->m_modelIndex) + while (gangOfPed < NUM_GANGS && CGangs::GetGangInfo(gangOfPed)->m_nVehicleMI != car->GetModelIndex()) gangOfPed++; if (gangOfPed < NUM_GANGS) { pedType = gangOfPed + PEDTYPE_GANG1; preferredModel = ChooseGangOccupation(gangOfPed); } else if (gangOfPed == NUM_GANGS) { - CVehicleModelInfo *carModelInfo = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(car->m_modelIndex)); + CVehicleModelInfo *carModelInfo = ((CVehicleModelInfo *)CModelInfo::GetModelInfo(car->GetModelIndex())); int i = 15; for(; i >= 0; i--) { // Should return random model each time @@ -858,6 +858,7 @@ CPopulation::AddPedInCar(CVehicle* car) void CPopulation::MoveCarsAndPedsOutOfAbandonedZones() { +#ifndef MIAMI eLevelName level; int zone; int frame = CTimer::GetFrameCounter() & 7; @@ -940,6 +941,7 @@ CPopulation::MoveCarsAndPedsOutOfAbandonedZones() } } } +#endif } void @@ -970,7 +972,7 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy) CWorld::Remove(dummy); delete dummy; CWorld::Add(obj); - int16 mi = obj->m_modelIndex; + int16 mi = obj->GetModelIndex(); if (mi == MI_GLASS1 || mi == MI_GLASS2 || mi == MI_GLASS3 || mi == MI_GLASS4 || mi == MI_GLASS5 || mi == MI_GLASS6 || mi == MI_GLASS7 || mi == MI_GLASS8) makeInvisible = true; @@ -979,7 +981,7 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy) if (makeInvisible) { obj->bIsVisible = false; - } else if (obj->m_modelIndex == MI_BUOY) { + } else if (obj->GetModelIndex() == MI_BUOY) { obj->bIsStatic = false; obj->m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f); obj->bTouchingWater = true; @@ -997,7 +999,7 @@ CPopulation::ConvertToDummyObject(CObject *obj) dummy->UpdateRwFrame(); bool makeInvisible; - int16 mi = obj->m_modelIndex; + int16 mi = obj->GetModelIndex(); if (mi == MI_GLASS1 || mi == MI_GLASS2 || mi == MI_GLASS3 || mi == MI_GLASS4 || mi == MI_GLASS5 || mi == MI_GLASS6 || mi == MI_GLASS7 || mi == MI_GLASS8) makeInvisible = true; @@ -1017,8 +1019,7 @@ bool CPopulation::TestRoomForDummyObject(CObject *obj) { int16 collidingObjs; - CWorld::FindObjectsKindaColliding(obj->m_objectMatrix.GetPosition(), - CModelInfo::GetModelInfo(obj->m_modelIndex)->GetColModel()->boundingSphere.radius, + CWorld::FindObjectsKindaColliding(obj->m_objectMatrix.GetPosition(), CModelInfo::GetModelInfo(obj->GetModelIndex())->GetColModel()->boundingSphere.radius, false, &collidingObjs, 2, nil, false, true, true, false, false); return collidingObjs == 0; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index cb2cb5b7..03bc175a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -91,9 +91,7 @@ CRenderer::RenderOneRoad(CEntity *e) if(gbDontRenderBuildings) return; if(gbShowCollisionPolys) - CCollision::DrawColModel_Coloured(e->GetMatrix(), - *CModelInfo::GetModelInfo(e->m_modelIndex)->GetColModel(), - e->m_modelIndex); + CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex()); else e->Render(); } @@ -109,9 +107,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) #ifndef MASTER if(gbShowCollisionPolys){ if(!e->IsVehicle()){ - CCollision::DrawColModel_Coloured(e->GetMatrix(), - *CModelInfo::GetModelInfo(e->m_modelIndex)->GetColModel(), - e->m_modelIndex); + CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex()); return; } }else if(e->IsBuilding()){ @@ -332,13 +328,14 @@ enum Visbility int32 CRenderer::SetupEntityVisibility(CEntity *ent) { +#ifndef MIAMI CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex); CTimeModelInfo *ti; int32 other; float dist; bool request = true; - if(mi->m_type == MITYPE_TIME){ + if (mi->GetModelType() == MITYPE_TIME) { ti = (CTimeModelInfo*)mi; other = ti->GetOtherTimeModel(); if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){ @@ -354,7 +351,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) request = false; } }else{ - if(mi->m_type != MITYPE_SIMPLE){ + if (mi->GetModelType() != MITYPE_SIMPLE) { if(FindPlayerVehicle() == ent && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){ // Player's vehicle in first person mode @@ -406,7 +403,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) RpAtomic *a = mi->GetAtomicFromDistance(dist); if(a){ - mi->m_isDamaged = 0; + mi->m_isDamaged = false; if(ent->m_rwObject == nil) ent->CreateRwObject(); assert(ent->m_rwObject); @@ -477,25 +474,178 @@ CRenderer::SetupEntityVisibility(CEntity *ent) ent->bDistanceFade = true; return VIS_OFFSCREEN; // Why this? } +#else + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex); + CTimeModelInfo *ti; + int32 other; + float dist; + + bool request = true; + if(mi->GetModelType() == MITYPE_TIME){ + ti = (CTimeModelInfo*)mi; + other = ti->GetOtherTimeModel(); + if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){ + // don't fade in, or between time objects + if(CANTIMECULL) + ti->m_alpha = 255; + }else{ + // Hide if possible + if(CANTIMECULL) + 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; + } + }else{ +// TODO(MIAMI): weapon + if(mi->GetModelType() != MITYPE_SIMPLE){ + if(FindPlayerVehicle() == ent && + TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){ + // Player's vehicle in first person mode + if(TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_FORWARD || + ent->GetModelIndex() == MI_RHINO || + ent->GetModelIndex() == MI_COACH || + TheCamera.m_bInATunnelAndABigVehicle){ + ent->bNoBrightHeadLights = true; + }else{ + m_pFirstPersonVehicle = (CVehicle*)ent; + ent->bNoBrightHeadLights = false; + } + return VIS_OFFSCREEN; + }else{ + // All sorts of Clumps + if(ent->m_rwObject == nil || !ent->bIsVisible) + return VIS_INVISIBLE; +// TODO(MIAMI): occlusion + if(!ent->GetIsOnScreen()) + return VIS_OFFSCREEN; + if(ent->bDrawLast){ + dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = false; + return VIS_INVISIBLE; + }else + return VIS_VISIBLE; + } + return VIS_INVISIBLE; + } +// TODO(MIAMI): this is different + if(ent->IsObject() && + ((CObject*)ent)->ObjectCreatedBy == TEMP_OBJECT){ + if(ent->m_rwObject == nil || !ent->bIsVisible) + return VIS_INVISIBLE; + return ent->GetIsOnScreen() ? VIS_VISIBLE : VIS_OFFSCREEN; + } + } + + // Simple ModelInfo + +// TODO(MIAMI): area + + dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); + + if(LOD_DISTANCE < dist && dist < mi->GetLargestLodDistance() + FADE_DISTANCE) + dist += mi->GetLargestLodDistance() - 300.0f; + + if(ent->IsObject() && ent->bRenderDamaged) + mi->m_isDamaged = true; + + RpAtomic *a = mi->GetAtomicFromDistance(dist); + if(a){ + mi->m_isDamaged = false; + if(ent->m_rwObject == nil) + ent->CreateRwObject(); + assert(ent->m_rwObject); + RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; + // Make sure our atomic uses the right geometry and not + // that of an atomic for another draw distance. + if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) + RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) + mi->IncreaseAlpha(); + if(ent->m_rwObject == nil || !ent->bIsVisible) + return VIS_INVISIBLE; + + if(!ent->GetIsOnScreen()){ + mi->m_alpha = 255; + return VIS_OFFSCREEN; + } + + if(mi->m_alpha != 255){ + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = true; + return VIS_INVISIBLE; + } + + if(mi->m_drawLast || ent->bDrawLast){ + if(CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist)){ + ent->bDistanceFade = false; + return VIS_INVISIBLE; + } + } + return VIS_VISIBLE; + } + + // Object is not loaded, figure out what to do + + if(mi->m_noFade){ + mi->m_isDamaged = false; + // request model + if(dist - STREAM_DISTANCE < mi->GetLargestLodDistance() && request) + return VIS_STREAMME; + return VIS_INVISIBLE; + } + + // We might be fading + + a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE); + mi->m_isDamaged = false; + if(a == nil){ + // request model + if(dist - FADE_DISTANCE - STREAM_DISTANCE < mi->GetLargestLodDistance() && request) + return VIS_STREAMME; + return VIS_INVISIBLE; + } + + if(ent->m_rwObject == nil) + ent->CreateRwObject(); + assert(ent->m_rwObject); + RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; + if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) + RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) + mi->IncreaseAlpha(); + if(ent->m_rwObject == nil || !ent->bIsVisible) + return VIS_INVISIBLE; + +// TODO(MIAMI): occlusion + if(!ent->GetIsOnScreen()){ + mi->m_alpha = 255; + return VIS_OFFSCREEN; + }else{ + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = true; + return VIS_OFFSCREEN; // Why this? + } +#endif } int32 CRenderer::SetupBigBuildingVisibility(CEntity *ent) { - CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex); +#ifndef MIAMI + CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); CTimeModelInfo *ti; int32 other; - if(mi->m_type == MITYPE_TIME){ + if (mi->GetModelType() == MITYPE_TIME) { ti = (CTimeModelInfo*)mi; other = ti->GetOtherTimeModel(); // Hide objects not in time range if possible if(CANTIMECULL) if(!CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())) - return 0; + return VIS_INVISIBLE; // Draw like normal - }else if(mi->m_type == MITYPE_VEHICLE) - return ent->IsVisible(); + } else if (mi->GetModelType() == MITYPE_VEHICLE) + return ent->IsVisible() ? VIS_VISIBLE : VIS_INVISIBLE; float dist = (ms_vecCameraPosition-ent->GetPosition()).Magnitude(); CSimpleModelInfo *nonLOD = mi->GetRelatedModel(); @@ -507,15 +657,15 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) // No non-LOD or non-LOD is completely visible. if(nonLOD == nil || nonLOD->GetRwObject() && nonLOD->m_alpha == 255) - return 0; + return VIS_INVISIBLE; // But if it is a time object, we'd rather draw the wrong // non-LOD than the right LOD. - if(nonLOD->m_type == MITYPE_TIME){ + if (nonLOD->GetModelType() == MITYPE_TIME) { ti = (CTimeModelInfo*)nonLOD; other = ti->GetOtherTimeModel(); if(other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject()) - return 0; + return VIS_INVISIBLE; } } @@ -531,18 +681,18 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) if(!ent->IsVisibleComplex()) - return 0; + return VIS_INVISIBLE; if(mi->m_drawLast){ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = 0; - return 0; + ent->bDistanceFade = false; + return VIS_INVISIBLE; } - return 1; + return VIS_VISIBLE; } if(mi->m_noFade){ ent->DeleteRwObject(); - return 0; + return VIS_INVISIBLE; } @@ -550,7 +700,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE); if(a == nil){ ent->DeleteRwObject(); - return 0; + return VIS_INVISIBLE; } // Fade... @@ -562,7 +712,122 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) if(ent->IsVisibleComplex()) CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - return 0; + return VIS_INVISIBLE; +#else + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex); + CTimeModelInfo *ti; + int32 other; + +// TODO(MIAMI): area + + bool request = true; + if(mi->GetModelType() == MITYPE_TIME){ + ti = (CTimeModelInfo*)mi; + other = ti->GetOtherTimeModel(); + if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){ + // don't fade in, or between time objects + if(CANTIMECULL) + ti->m_alpha = 255; + }else{ + // Hide if possible + 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; + } + }else if(mi->GetModelType() == MITYPE_VEHICLE) + return ent->IsVisible() ? VIS_VISIBLE : VIS_INVISIBLE; + + float dist = (ms_vecCameraPosition-ent->GetPosition()).Magnitude(); + CSimpleModelInfo *nonLOD = mi->GetRelatedModel(); + + // Find out whether to draw below near distance. + // This is only the case if there is a non-LOD which is either not + // loaded or not completely faded in yet. + if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE){ + // No non-LOD or non-LOD is completely visible. + if(nonLOD == nil || + nonLOD->GetRwObject() && nonLOD->m_alpha == 255) + return VIS_INVISIBLE; + + // But if it is a time object, we'd rather draw the wrong + // non-LOD than the right LOD. + if(nonLOD->GetModelType() == MITYPE_TIME){ + ti = (CTimeModelInfo*)nonLOD; + other = ti->GetOtherTimeModel(); + if(other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject()) + return VIS_INVISIBLE; + } + } + + RpAtomic *a = mi->GetFirstAtomicFromDistance(dist); + if(a){ + if(ent->m_rwObject == nil) + ent->CreateRwObject(); + assert(ent->m_rwObject); + RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; + + // Make sure our atomic uses the right geometry and not + // that of an atomic for another draw distance. + if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) + RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) + mi->IncreaseAlpha(); +// TODO(MIAMI): occlusion + if(!ent->IsVisibleComplex()){ + mi->m_alpha = 255; + return VIS_INVISIBLE; + } + + if(mi->m_alpha != 255){ + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = true; + return VIS_INVISIBLE; + } + + if(mi->m_drawLast){ + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = false; + return VIS_INVISIBLE; + } + return VIS_VISIBLE; + } + + if(mi->m_noFade){ + ent->DeleteRwObject(); + return VIS_INVISIBLE; + } + + + // get faded atomic + a = mi->GetFirstAtomicFromDistance(dist - FADE_DISTANCE); + if(a == nil){ + if(ent->bStreamBIGBuilding && dist-STREAM_DISTANCE < mi->GetLodDistance(0) && request){ + return ent->GetIsOnScreen() ? VIS_STREAMME : VIS_INVISIBLE; + }else{ + ent->DeleteRwObject(); + return VIS_INVISIBLE; + } + } + + // Fade... + if(ent->m_rwObject == nil) + ent->CreateRwObject(); + assert(ent->m_rwObject); + RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; + if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) + RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) + mi->IncreaseAlpha(); +// TODO(MIAMI): occlusion + if(ent->IsVisibleComplex()){ + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = true; + }else + mi->m_alpha = 255; + return VIS_INVISIBLE; +#endif } void @@ -709,7 +974,11 @@ CRenderer::ScanWorld(void) } ScanSectorPoly(poly, 3, ScanSectorList); +#ifndef MIAMI ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory)); +#else + ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel)); +#endif ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_NONE)); } } @@ -954,11 +1223,27 @@ CRenderer::ScanBigBuildingList(CPtrList &list) CPtrNode *node; CEntity *ent; +#ifndef MIAMI for(node = list.first; node; node = node->next){ ent = (CEntity*)node->item; - if(!ent->bZoneCulled && SetupBigBuildingVisibility(ent) == 1) + if(!ent->bZoneCulled && SetupBigBuildingVisibility(ent) == VIS_VISIBLE) ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; } +#else + // TODO(MIAMI): some flags and such + for(node = list.first; node; node = node->next){ + ent = (CEntity*)node->item; + switch(SetupBigBuildingVisibility(ent)){ + case VIS_VISIBLE: + ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; + break; + case VIS_STREAMME: + if(!CStreaming::ms_disableStreaming) + CStreaming::RequestModel(ent->GetModelIndex(), 0); + break; + } + } +#endif } void @@ -978,7 +1263,9 @@ CRenderer::ScanSectorList(CPtrList *lists) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); +#ifdef GTA_ZONECULL if(IsEntityCullZoneVisible(ent)) +#endif switch(SetupEntityVisibility(ent)){ case VIS_VISIBLE: ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; @@ -1001,12 +1288,14 @@ CRenderer::ScanSectorList(CPtrList *lists) CStreaming::RequestModel(ent->GetModelIndex(), 0); break; } +#ifdef GTA_ZONECULL else if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){ if(!CStreaming::ms_disableStreaming) if(SetupEntityVisibility(ent) == VIS_STREAMME) if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10) CStreaming::RequestModel(ent->GetModelIndex(), 0); } +#endif } } } @@ -1028,7 +1317,9 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); +#ifdef GTA_ZONECULL if(IsEntityCullZoneVisible(ent)) +#endif switch(SetupEntityVisibility(ent)){ case VIS_VISIBLE: ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; @@ -1053,11 +1344,13 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) } break; } +#ifdef GTA_ZONECULL else if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){ if(!CStreaming::ms_disableStreaming) if(SetupEntityVisibility(ent) == VIS_STREAMME) CStreaming::RequestModel(ent->GetModelIndex(), 0); } +#endif } } } @@ -1110,7 +1403,10 @@ CRenderer::ScanSectorList_RequestModels(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); - if(IsEntityCullZoneVisible(ent) && ShouldModelBeStreamed(ent)) +#ifdef GTA_ZONECULL + if(IsEntityCullZoneVisible(ent)) +#endif + if(ShouldModelBeStreamed(ent)) CStreaming::RequestModel(ent->GetModelIndex(), 0); } } @@ -1147,7 +1443,7 @@ CRenderer::SortBIGBuildingsForSectorList(CPtrList *list) bool CRenderer::ShouldModelBeStreamed(CEntity *ent) { - CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex); + CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); float dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); if(mi->m_noFade) return dist - STREAM_DISTANCE < mi->GetLargestLodDistance(); @@ -1155,6 +1451,7 @@ CRenderer::ShouldModelBeStreamed(CEntity *ent) return dist - FADE_DISTANCE - STREAM_DISTANCE < mi->GetLargestLodDistance(); } +#ifdef GTA_ZONECULL bool CRenderer::IsEntityCullZoneVisible(CEntity *ent) { @@ -1197,6 +1494,7 @@ CRenderer::IsVehicleCullZoneVisible(CEntity *ent) return !(v->m_pCurGroundEntity && v->m_pCurGroundEntity->bZoneCulled2); return true; } +#endif void CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset) diff --git a/src/render/Renderer.h b/src/render/Renderer.h index 362741e3..e28995c3 100644 --- a/src/render/Renderer.h +++ b/src/render/Renderer.h @@ -64,8 +64,10 @@ public: static void SortBIGBuildingsForSectorList(CPtrList *list); static bool ShouldModelBeStreamed(CEntity *ent); +#ifdef GTA_ZONECULL static bool IsEntityCullZoneVisible(CEntity *ent); static bool IsVehicleCullZoneVisible(CEntity *ent); +#endif static void RemoveVehiclePedLights(CEntity *ent, bool reset); }; diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp index 7dc27f48..b1a101e3 100644 --- a/src/rw/VisibilityPlugins.cpp +++ b/src/rw/VisibilityPlugins.cpp @@ -146,7 +146,7 @@ CVisibilityPlugins::RenderFadingEntities(void) CEntity *e = node->item.entity; if(e->m_rwObject == nil) continue; - mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(e->m_modelIndex); + mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()); if(mi->m_noZwrite) RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); @@ -718,7 +718,7 @@ CVisibilityPlugins::SetAtomicModelInfo(RpAtomic *atomic, { AtomicExt *ext = ATOMICEXT(atomic); ext->modelInfo = modelInfo; - switch(modelInfo->m_type) + switch (modelInfo->GetModelType()) case MITYPE_SIMPLE: case MITYPE_TIME: if(modelInfo->m_normalCull) @@ -828,7 +828,7 @@ CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo SetFrameHierarchyId(RpClumpGetFrame(clump), (int32)modelInfo); // Unused - switch(modelInfo->m_type){ + switch (modelInfo->GetModelType()) { // ignore MLO case MITYPE_VEHICLE: vmi = (CVehicleModelInfo*)modelInfo; diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index bb074042..c22a060c 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -543,11 +543,13 @@ RestoreForStartLoad() ReadDataFromBufferPointer(_buf, TheCamera.GetMatrix().GetPosition().z); CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); CStreaming::RemoveUnusedBuildings(CGame::currLevel); +#ifndef MIAMI CCollision::SortOutCollisionAfterLoad(); CStreaming::RequestBigBuildings(CGame::currLevel); CStreaming::LoadAllRequestedModels(false); CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); CGame::TidyUpMemory(true, false); +#endif if (CloseFile(file)) { return true; diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 9db60da0..602eb589 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -229,9 +229,11 @@ CAutomobile::ProcessControl(void) colModel = GetColModel(); bWarnedPeds = false; +#ifndef MIAMI // skip if the collision isn't for the current level if(colModel->level > LEVEL_NONE && colModel->level != CCollision::ms_collisionInMemory) return; +#endif // Improve grip of vehicles in certain cases bool strongGrip1 = false; diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 1f80c43e..ecf760e4 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -109,8 +109,10 @@ CBoat::GetComponentWorldPosition(int32 component, CVector &pos) void CBoat::ProcessControl(void) { +#ifndef MIAMI if(m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory) return; +#endif bool onLand = m_fDamageImpulse > 0.0f && m_vecDamageNormal.z > 0.1f; @@ -290,7 +292,7 @@ CBoat::ProcessControl(void) AddWakePoint(GetPosition()); float steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward()); - if(m_modelIndex == MI_GHOST) + if (GetModelIndex() == MI_GHOST) steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward())*0.3f; if(steerFactor < 0.0f) steerFactor = 0.0f; |