diff options
Diffstat (limited to '')
46 files changed, 2569 insertions, 2250 deletions
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index f49f811f..35106a6b 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -368,13 +368,7 @@ CAnimViewer::Update(void) } else { // Originally it was GetPad(1)->LeftShoulder2 if (pad->NewState.Triangle) { -#ifdef PED_SKIN - if(IsClumpSkinned(pTarget->GetClump())) - ((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(pTarget->GetClump()); - else -#endif - CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->GetHitColModel(), - RpClumpGetFrame(pTarget->GetClump())); + ((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(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 6c79604c..afa153f9 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -280,12 +280,12 @@ CCam::Process(void) if(DirectionWasLooking != LOOKING_BEHIND) TheCamera.m_bJust_Switched = true; DirectionWasLooking = LOOKING_BEHIND; - }else if(CPad::GetPad(0)->GetLookLeft()){ + }else if(!((CVehicle*)CamTargetEntity)->IsRealHeli() && CPad::GetPad(0)->GetLookLeft()){ LookLeft(); if(DirectionWasLooking != LOOKING_LEFT) TheCamera.m_bJust_Switched = true; DirectionWasLooking = LOOKING_LEFT; - }else if(CPad::GetPad(0)->GetLookRight()){ + }else if(!((CVehicle*)CamTargetEntity)->IsRealHeli() && CPad::GetPad(0)->GetLookRight()){ LookRight(); if(DirectionWasLooking != LOOKING_RIGHT) TheCamera.m_bJust_Switched = true; @@ -1627,20 +1627,6 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient entity = nil; } - if(CamTargetEntity->m_rwObject){ - // what's going on here? - if(RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_PUMP) || - RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROW) || - RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROWU) || - RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_START_THROW)){ - CPed *player = FindPlayerPed(); - float PlayerDist = (Source - player->GetPosition()).Magnitude(); - if(PlayerDist < 2.75f) - Near = PlayerDist/2.75f * DEFAULT_NEAR - 0.3f; - RwCameraSetNearClipPlane(Scene.camera, Max(Near, 0.1f)); - } - } - TheCamera.m_bCamDirectlyInFront = false; TheCamera.m_bCamDirectlyBehind = false; @@ -4539,6 +4525,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient Rotating = false; } + if(TheCamera.m_bUseTransitionBeta) + Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta)); if(TheCamera.m_bUseTransitionBeta) Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta)); @@ -4908,7 +4896,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->GetModelIndex() != MI_YARDIE) { + if (!isCar || car->GetModelIndex() != MI_VOODOO) { correctAlpha = false; } else { diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 35d230dc..fa5e44bb 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -61,6 +61,8 @@ enum CCamera TheCamera; bool CCamera::m_bUseMouse3rdPerson = true; bool bDidWeProcessAnyCinemaCam; +float CCamera::m_f3rdPersonCHairMultX; +float CCamera::m_f3rdPersonCHairMultY; #ifdef IMPROVED_CAMERA #define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k) @@ -80,10 +82,6 @@ CCamera::CCamera(void) Init(); } -CCamera::CCamera(float) -{ -} - void CCamera::Init(void) { @@ -91,12 +89,7 @@ CCamera::Init(void) float fMouseAccelHorzntl = m_fMouseAccelHorzntl; float fMouseAccelVertical = m_fMouseAccelVertical; #endif -#ifdef FIX_BUGS - static const CCamera DummyCamera = CCamera(0.f); - *this = DummyCamera; -#else - memset(this, 0, sizeof(CCamera)); // getting rid of vtable, eh? -#endif + memset(this, 0, sizeof(CCamera)); // this is fine, no vtable #ifdef GTA3_1_1_PATCH m_fMouseAccelHorzntl = fMouseAccelHorzntl; m_fMouseAccelVertical = fMouseAccelVertical; @@ -642,7 +635,11 @@ CCamera::CamControl(void) m_bInitialNodeFound = false; m_bInitialNoNodeStaticsSet = false; } +#ifdef GTA_TRAIN Process_Train_Camera_Control(); +#else + assert(0 && "this can't happen"); +#endif }else{ if(((CVehicle*)pTargetEntity)->IsBoat()) boatTarget = true; @@ -701,8 +698,8 @@ CCamera::CamControl(void) garageDoorPos2.z = 0.0f; #endif } - garageCenter.x = (pToGarageWeAreIn->m_fX1 + pToGarageWeAreIn->m_fX2)/2.0f; - garageCenter.y = (pToGarageWeAreIn->m_fY1 + pToGarageWeAreIn->m_fY2)/2.0f; + garageCenter.x = pToGarageWeAreIn->GetGarageCenterX(); + garageCenter.y = pToGarageWeAreIn->GetGarageCenterY(); garageCenter.z = 0.0f; if(whichDoor == 1) garageCenterToDoor = garageDoorPos1 - garageCenter; @@ -940,11 +937,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){ @@ -983,8 +982,8 @@ CCamera::CamControl(void) } if(pToGarageWeAreIn){ - garageCenter.x = (pToGarageWeAreIn->m_fX1 + pToGarageWeAreIn->m_fX2)/2.0f; - garageCenter.y = (pToGarageWeAreIn->m_fY1 + pToGarageWeAreIn->m_fY2)/2.0f; + garageCenter.x = pToGarageWeAreIn->GetGarageCenterX(); + garageCenter.y = pToGarageWeAreIn->GetGarageCenterY(); garageCenter.z = 0.0f; }else{ garageDoorPos1.z = 0.0f; @@ -1017,8 +1016,8 @@ CCamera::CamControl(void) if(PedZoomIndicator == CAM_ZOOM_TOPDOWN && !stairs){ garageCamPos = garageCenter; garageCamPos.z += FindPlayerPed()->GetPosition().z + 2.1f; - if(pToGarageWeAreIn && garageCamPos.z > pToGarageWeAreIn->m_fX2) // What? - garageCamPos.z = pToGarageWeAreIn->m_fX2; + if(pToGarageWeAreIn && garageCamPos.z > pToGarageWeAreIn->m_fSupX) // What? + garageCamPos.z = pToGarageWeAreIn->m_fSupX; }else garageCamPos.z = ground + 3.1f; SetCamPositionForFixedMode(garageCamPos, CVector(0.0f, 0.0f, 0.0f)); @@ -1533,7 +1532,6 @@ CCamera::UpdateTargetEntity(void) pTargetEntity = FindPlayerVehicle(); else{ pTargetEntity = FindPlayerPed(); -#ifndef GTA_PS2_STUFF // this keeps the camera on the player while entering cars if(PLAYER->GetPedState() == PED_ENTER_CAR || PLAYER->GetPedState() == PED_CARJACK || @@ -1543,7 +1541,6 @@ CCamera::UpdateTargetEntity(void) if(!enteringCar) if(Cams[ActiveCam].CamTargetEntity != pTargetEntity) Cams[ActiveCam].CamTargetEntity = pTargetEntity; -#endif } bool cantOpen = true; @@ -1562,16 +1559,9 @@ CCamera::UpdateTargetEntity(void) if((PLAYER->GetPedState() == PED_CARJACK || PLAYER->GetPedState() == PED_OPEN_DOOR) && !cantOpen){ if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS) -#ifdef GTA_PS2_STUFF -// dunno if this has any amazing effects - { -#endif pTargetEntity = PLAYER->m_pMyVehicle; if(PLAYER->m_pMyVehicle == nil) pTargetEntity = PLAYER; -#ifdef GTA_PS2_STUFF - } -#endif } if(PLAYER->GetPedState() == PED_EXIT_CAR) @@ -2717,6 +2707,7 @@ CCamera::DontProcessObbeCinemaCamera(void) bDidWeProcessAnyCinemaCam = false; } +#ifdef GTA_TRAIN void CCamera::LoadTrainCamNodes(char const *name) { @@ -2894,6 +2885,7 @@ CCamera::Process_Train_Camera_Control(void) } } } +#endif void @@ -3189,7 +3181,7 @@ CCamera::RenderMotionBlur(void) CMBlur::MotionBlurRender(m_pRwCamera, m_BlurRed, m_BlurGreen, m_BlurBlue, - m_motionBlur, m_BlurType, m_imotionBlurAddAlpha); + m_motionBlur, m_BlurType); } void diff --git a/src/core/Camera.h b/src/core/Camera.h index 80fc878e..135f9d8f 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -472,8 +472,8 @@ public: // not static yet float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls - float m_f3rdPersonCHairMultX; - float m_f3rdPersonCHairMultY; + static float m_f3rdPersonCHairMultX; + static float m_f3rdPersonCHairMultY; CCam Cams[3]; @@ -549,7 +549,6 @@ public: // High level and misc CCamera(void); - CCamera(float); void Init(void); void Process(void); void CamControl(void); diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp new file mode 100644 index 00000000..80bbdc77 --- /dev/null +++ b/src/core/ColStore.cpp @@ -0,0 +1,237 @@ +#include "common.h" + +#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 "Physical.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->unused = 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{ + for (int j = 0; j < MAX_CLEANUP; j++) { + CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j); + if (pEntity /* !pEntity->bDontLoadCollision && !pEntity->bIsFrozen */) { + if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f)) + wantThisOne = true; + } + } + } + + 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(); + } +} + +//--MIAMI: done +bool +CColStore::HasCollisionLoaded(const CVector2D &pos) +{ + int i; + + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f) && + !GetSlot(i)->isLoaded) + return false; + return true; +} diff --git a/src/core/ColStore.h b/src/core/ColStore.h new file mode 100644 index 00000000..8e2a3a70 --- /dev/null +++ b/src/core/ColStore.h @@ -0,0 +1,43 @@ +#pragma once + +#include "templates.h" + +struct ColDef { // made up name + int32 unused; + 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 01cc323a..c29c1d28 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -20,6 +20,8 @@ #include "SurfaceTable.h" #include "Lines.h" #include "Collision.h" +#include "Camera.h" +#include "ColStore.h" enum Direction { @@ -34,57 +36,30 @@ 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; + CColStore::Initialise(); } +//--MIAMI: done void CCollision::Shutdown(void) { ms_colModelCache.Shutdown(); + CColStore::Shutdown(); } +//--MIAMI: done void CCollision::Update(void) { - CVector playerCoors; - playerCoors = FindPlayerCoors(); - eLevelName level = CTheZones::m_CurrLevel; - bool forceLevelChange = false; - - if(CTimer::GetTimeInMilliseconds() < 2000 || CCutsceneMgr::IsCutsceneProcessing()) - return; - - // hardcode a level if there are no zones - if(level == LEVEL_NONE){ - if(CGame::currLevel == LEVEL_INDUSTRIAL && - playerCoors.x < 400.0f){ - level = LEVEL_COMMERCIAL; - forceLevelChange = true; - }else if(CGame::currLevel == LEVEL_SUBURBAN && - playerCoors.x > -450.0f && playerCoors.y < -1400.0f){ - level = LEVEL_COMMERCIAL; - forceLevelChange = true; - }else{ - if(playerCoors.x > 800.0f){ - level = LEVEL_INDUSTRIAL; - forceLevelChange = true; - }else if(playerCoors.x < -800.0f){ - level = LEVEL_SUBURBAN; - forceLevelChange = true; - } - } - } - if(level != LEVEL_NONE && level != CGame::currLevel) - CGame::currLevel = level; - if(ms_collisionInMemory != CGame::currLevel) - LoadCollisionWhenINeedIt(forceLevelChange); - CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); } +//--MIAMI: unused eLevelName GetCollisionInSectorList(CPtrList &list) { @@ -101,6 +76,7 @@ GetCollisionInSectorList(CPtrList &list) return LEVEL_NONE; } +//--MIAMI: unused // Get a level this sector is in based on collision models eLevelName GetCollisionInSector(CSector §) @@ -121,111 +97,16 @@ GetCollisionInSector(CSector §) return (eLevelName)level; } +//--MIAMI: done void CCollision::LoadCollisionWhenINeedIt(bool forceChange) { - eLevelName level, l; - bool multipleLevels; - CVector playerCoors; - CVehicle *veh; - CEntryInfoNode *ei; - int sx, sy; - int xmin, xmax, ymin, ymax; - int x, y; - - level = LEVEL_NONE; - - playerCoors = FindPlayerCoors(); - sx = CWorld::GetSectorIndexX(playerCoors.x); - sy = CWorld::GetSectorIndexY(playerCoors.y); - multipleLevels = false; - - veh = FindPlayerVehicle(); - if(veh && veh->IsTrain()){ - if(((CTrain*)veh)->m_nDoorState != TRAIN_DOOR_OPEN) - return; - }else if(playerCoors.z < -4.0f && !CCullZones::DoINeedToLoadCollision()) - return; - - // Figure out whose level's collisions we're most likely to be interested in - if(!forceChange){ - if(veh && veh->IsBoat()){ - // on water we expect to be between levels - multipleLevels = true; - }else{ - xmin = Max(sx - 1, 0); - xmax = Min(sx + 1, NUMSECTORS_X-1); - ymin = Max(sy - 1, 0); - ymax = Min(sy + 1, NUMSECTORS_Y-1); - - for(x = xmin; x <= xmax; x++) - for(y = ymin; y <= ymax; y++){ - l = GetCollisionInSector(*CWorld::GetSector(x, y)); - if(l != LEVEL_NONE){ - if(level == LEVEL_NONE) - level = l; - if(level != l) - multipleLevels = true; - } - } - } - - if(multipleLevels && veh && veh->IsBoat()) - for(ei = veh->m_entryInfoList.first; ei; ei = ei->next){ - level = GetCollisionInSector(*ei->sector); - if(level != LEVEL_NONE) - break; - } - } - - if(level == CGame::currLevel || forceChange){ - CTimer::Stop(); - DMAudio.SetEffectsFadeVol(0); - CPad::StopPadsShaking(); - LoadCollisionScreen(CGame::currLevel); - DMAudio.Service(); - - CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false); - CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); - CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); - CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); - CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); - CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); - CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); - CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); - CStreaming::RemoveUnusedModelsInLoadedList(); - CGame::TidyUpMemory(true, true); - CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); - ms_collisionInMemory = CGame::currLevel; - CReplay::EmptyReplayBuffer(); - if(CGame::currLevel != LEVEL_NONE) - LoadSplash(GetLevelSplashScreen(CGame::currLevel)); - CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); - CStreaming::RemoveUnusedBuildings(CGame::currLevel); - CStreaming::RequestBigBuildings(CGame::currLevel); - CStreaming::LoadAllRequestedModels(true); - CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); - - CGame::TidyUpMemory(true, true); - CTimer::Update(); - DMAudio.SetEffectsFadeVol(127); - } } +//--MIAMI: done void CCollision::SortOutCollisionAfterLoad(void) { - if(ms_collisionInMemory == CGame::currLevel) - return; - - CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); - if(CGame::currLevel != LEVEL_NONE){ - CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); - if(!CGame::playingIntro) - LoadSplash(GetLevelSplashScreen(CGame::currLevel)); - } - ms_collisionInMemory = CGame::currLevel; - CGame::TidyUpMemory(true, false); } void @@ -249,14 +130,14 @@ CCollision::LoadCollisionScreen(eLevelName level) bool -CCollision::TestSphereSphere(const CColSphere &s1, const CColSphere &s2) +CCollision::TestSphereSphere(const CSphere &s1, const CSphere &s2) { float d = s1.radius + s2.radius; return (s1.center - s2.center).MagnitudeSqr() < d*d; } bool -CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box) +CCollision::TestSphereBox(const CSphere &sph, const CBox &box) { if(sph.center.x + sph.radius < box.min.x) return false; if(sph.center.x - sph.radius > box.max.x) return false; @@ -268,7 +149,7 @@ CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box) } bool -CCollision::TestLineBox(const CColLine &line, const CColBox &box) +CCollision::TestLineBox(const CColLine &line, const CBox &box) { float t, x, y, z; // If either line point is in the box, we have a collision @@ -353,7 +234,7 @@ CCollision::TestLineBox(const CColLine &line, const CColBox &box) } bool -CCollision::TestVerticalLineBox(const CColLine &line, const CColBox &box) +CCollision::TestVerticalLineBox(const CColLine &line, const CBox &box) { if(line.p0.x <= box.min.x) return false; if(line.p0.y <= box.min.y) return false; @@ -1974,7 +1855,7 @@ CColModel::CColModel(void) vertices = nil; triangles = nil; trianglePlanes = nil; - level = CGame::currLevel; + level = 0; // generic col slot ownsCollisionVolumes = true; } diff --git a/src/core/Collision.h b/src/core/Collision.h index 895f012a..4b0c2fb9 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -10,26 +10,37 @@ #define MAX_COLLISION_POINTS 32 #endif -struct CColSphere +struct CSphere { CVector center; float radius; + void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; } +}; + +struct CBox +{ + CVector min; + CVector max; + CVector GetSize(void) { return max - min; } + void Set(const CVector &min, const CVector &max) { this->min = min; this->max = max; } +}; + +struct CColSphere : public CSphere +{ uint8 surface; uint8 piece; void Set(float radius, const CVector ¢er, uint8 surf, uint8 piece); - void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; } + using CSphere::Set; }; -struct CColBox +struct CColBox : public CBox { - CVector min; - CVector max; uint8 surface; uint8 piece; void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece); - CVector GetSize(void) { return max - min; } + using CBox::Set; }; struct CColLine @@ -85,15 +96,16 @@ struct CStoredCollPoly bool valid; }; +//--MIAMI: done struct struct CColModel { - CColSphere boundingSphere; - CColBox boundingBox; + CSphere boundingSphere; + CBox boundingBox; int16 numSpheres; - int16 numLines; int16 numBoxes; int16 numTriangles; - int32 level; + int8 numLines; + uint8 level; // colstore slot but probably still named level bool ownsCollisionVolumes; CColSphere *spheres; CColLine *lines; @@ -132,10 +144,10 @@ public: static void CalculateTrianglePlanes(CColModel *model); // all these return true if there's a collision - static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2); - static bool TestSphereBox(const CColSphere &sph, const CColBox &box); - static bool TestLineBox(const CColLine &line, const CColBox &box); - static bool TestVerticalLineBox(const CColLine &line, const CColBox &box); + static bool TestSphereSphere(const CSphere &s1, const CSphere &s2); + static bool TestSphereBox(const CSphere &sph, const CBox &box); + static bool TestLineBox(const CColLine &line, const CBox &box); + static bool TestVerticalLineBox(const CColLine &line, const CBox &box); static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); static bool TestLineSphere(const CColLine &line, const CColSphere &sph); static bool TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp index 675040ea..c3508a51 100644 --- a/src/core/EventList.cpp +++ b/src/core/EventList.cpp @@ -67,8 +67,6 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent switch(entityType){ case EVENT_ENTITY_PED: ref = CPools::GetPedRef((CPed*)ent); - if(ent->GetModelIndex() >= MI_GANG01 && ent->GetModelIndex() <= MI_CRIMINAL02) - copsDontCare = true; break; case EVENT_ENTITY_VEHICLE: ref = CPools::GetVehicleRef((CVehicle*)ent); diff --git a/src/core/EventList.h b/src/core/EventList.h index 8840afc4..f2c3d7a8 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -22,10 +22,12 @@ enum eEventType EVENT_PED_SET_ON_FIRE, EVENT_COP_SET_ON_FIRE, EVENT_CAR_SET_ON_FIRE, - EVENT_ASSAULT_NASTYWEAPON, // not sure + EVENT_ASSAULT_NASTYWEAPON, + EVENT_ASSAULT_NASTYWEAPON_POLICE, EVENT_ICECREAM, EVENT_ATM, - EVENT_SHOPSTALL, // used on graffitis + EVENT_SHOPSTALL, + EVENT_SHOPWINDOW, EVENT_LAST_EVENT }; diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 6e7188c5..1463b4a5 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -1,4 +1,5 @@ #include "common.h" +#include <ctype.h> #include "main.h" #include "Quaternion.h" @@ -24,6 +25,11 @@ #include "ZoneCull.h" #include "CdStream.h" #include "FileLoader.h" +#include "Streaming.h" +#include "ColStore.h" +#include "Occlusion.h" + +//--MIAMI: file done char CFileLoader::ms_line[256]; @@ -46,14 +52,12 @@ CFileLoader::LoadLevel(const char *filename) { int fd; RwTexDictionary *savedTxd; - eLevelName savedLevel; bool objectsLoaded; char *line; char txdname[64]; savedTxd = RwTexDictionaryGetCurrent(); objectsLoaded = false; - savedLevel = CGame::currLevel; if(savedTxd == nil){ savedTxd = RwTexDictionaryCreate(); RwTexDictionarySetCurrent(savedTxd); @@ -77,12 +81,8 @@ CFileLoader::LoadLevel(const char *filename) AddTexDictionaries(savedTxd, txd); RwTexDictionaryDestroy(txd); }else if(strncmp(line, "COLFILE", 7) == 0){ - int level; - sscanf(line+8, "%d", &level); - CGame::currLevel = (eLevelName)level; LoadingScreenLoadingFile(line+10); - LoadCollisionFile(line+10); - CGame::currLevel = savedLevel; + LoadCollisionFile(line+10, 0); }else if(strncmp(line, "MODELFILE", 9) == 0){ LoadingScreenLoadingFile(line + 10); LoadModelFile(line + 10); @@ -94,15 +94,17 @@ CFileLoader::LoadLevel(const char *filename) LoadObjectTypes(line + 4); }else if(strncmp(line, "IPL", 3) == 0){ if(!objectsLoaded){ - CModelInfo::ConstructMloClumps(); + LoadingScreenLoadingFile("Collision"); CObjectData::Initialise("DATA\\OBJECT.DAT"); + CStreaming::Init(); + CColStore::LoadAllCollision(); + for(int i = 0; i < MODELINFOSIZE; i++) + if(CModelInfo::GetModelInfo(i)) + CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex(); objectsLoaded = true; } LoadingScreenLoadingFile(line + 4); LoadScene(line + 4); - }else if(strncmp(line, "MAPZONE", 7) == 0){ - LoadingScreenLoadingFile(line + 8); - LoadMapZones(line + 8); }else if(strncmp(line, "SPLASH", 6) == 0){ LoadSplash(GetRandomSplashScreen()); }else if(strncmp(line, "CDIMAGE", 7) == 0){ @@ -112,30 +114,13 @@ CFileLoader::LoadLevel(const char *filename) CFileMgr::CloseFile(fd); RwTexDictionarySetCurrent(savedTxd); -} - -void -CFileLoader::LoadCollisionFromDatFile(int currlevel) -{ - int fd; - char *line; - - fd = CFileMgr::OpenFile(CGame::aDatFile, "r"); - assert(fd > 0); - - for(line = LoadLine(fd); line; line = LoadLine(fd)){ - if(*line == '#') - continue; - - if(strncmp(line, "COLFILE", 7) == 0){ - int level; - sscanf(line+8, "%d", &level); - if(currlevel == level) - LoadCollisionFile(line+10); - } - } - CFileMgr::CloseFile(fd); + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(CColStore::GetSlot(i)) + CColStore::GetBoundingBox(i).Grow(120.0f); + CWorld::RepositionCertainDynamicObjects(); + CColStore::RemoveAllCollision(); } char* @@ -179,7 +164,7 @@ struct ColHeader }; void -CFileLoader::LoadCollisionFile(const char *filename) +CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) { int fd; char modelname[24]; @@ -188,6 +173,7 @@ CFileLoader::LoadCollisionFile(const char *filename) debug("Loading collision file %s\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); + assert(fd > 0); while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){ assert(strncmp(header.ident, "COLL", 4) == 0); @@ -196,10 +182,11 @@ CFileLoader::LoadCollisionFile(const char *filename) mi = CModelInfo::GetModelInfo(modelname, nil); if(mi){ - if(mi->GetColModel()){ + if(mi->GetColModel() && mi->DoesOwnColModel()){ LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname); }else{ CColModel *model = new CColModel; + model->level = colSlot; LoadCollisionModel(work_buff+24, *model, modelname); mi->SetColModel(model, true); } @@ -211,6 +198,79 @@ CFileLoader::LoadCollisionFile(const char *filename) CFileMgr::CloseFile(fd); } + +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){ + 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; +} + void CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) { @@ -240,13 +300,15 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) model.numLines = *(int16*)buf; buf += 4; if(model.numLines > 0){ - model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); + //model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); for(i = 0; i < model.numLines; i++){ - model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); + //model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); buf += 24; } }else model.lines = nil; + model.numLines = 0; + model.lines = nil; model.numBoxes = *(int16*)buf; buf += 4; @@ -265,10 +327,12 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector)); for(i = 0; i < numVertices; i++){ model.vertices[i] = *(CVector*)buf; +#if 0 if(Abs(model.vertices[i].x) >= 256.0f || Abs(model.vertices[i].y) >= 256.0f || Abs(model.vertices[i].z) >= 256.0f) printf("%s:Collision volume too big\n", modelname); +#endif buf += 12; } }else @@ -291,7 +355,7 @@ GetNameAndLOD(char *nodename, char *name, int *n) { char *underscore = nil; for(char *s = nodename; *s != '\0'; s++){ - if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L')) + if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L') && isdigit(s[2])) underscore = s; } if(underscore){ @@ -317,11 +381,11 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data) mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil); if(mi){ assert(mi->IsSimple()); + CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); mi->SetAtomic(n, atomic); RpClumpRemoveAtomic(clump, atomic); RpAtomicSetFrame(atomic, RwFrameCreate()); CVisibilityPlugins::SetAtomicModelInfo(atomic, mi); - CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); }else{ debug("Can't find Atomic %s\n", name); } @@ -387,14 +451,6 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id) return false; mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id); mi->SetClump(clump); - if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) { - // Read LOD ped - clump = RpClumpStreamRead(stream); - if(clump){ - ((CPedModelInfo*)mi)->SetLowDetailClump(clump); - RpClumpDestroy(clump); - } - } return true; } @@ -456,11 +512,11 @@ CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, void *data) nodename = GetFrameNodeName(RpAtomicGetFrame(atomic)); GetNameAndLOD(nodename, name, &n); + CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); gpRelatedModelInfo->SetAtomic(n, atomic); RpClumpRemoveAtomic(clump, atomic); RpAtomicSetFrame(atomic, RwFrameCreate()); CVisibilityPlugins::SetAtomicModelInfo(atomic, gpRelatedModelInfo); - CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); return atomic; } @@ -498,8 +554,9 @@ CFileLoader::LoadObjectTypes(const char *filename) enum { NONE, OBJS, - MLO, + MLO, // unused but enum still has it TOBJ, + WEAP, HIER, CARS, PEDS, @@ -510,16 +567,17 @@ CFileLoader::LoadObjectTypes(const char *filename) int fd; int section; int pathIndex; - char pathTypeStr[20]; int id, pathType; - int mlo; + int minID, maxID; section = NONE; + minID = INT32_MAX; + maxID = -1; pathIndex = -1; - mlo = 0; debug("Loading object types from %s...\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); + assert(fd > 0); for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ if(*line == '\0' || *line == '#') continue; @@ -527,25 +585,27 @@ CFileLoader::LoadObjectTypes(const char *filename) if(section == NONE){ if(strncmp(line, "objs", 4) == 0) section = OBJS; else if(strncmp(line, "tobj", 4) == 0) section = TOBJ; + else if(strncmp(line, "weap", 4) == 0) section = WEAP; else if(strncmp(line, "hier", 4) == 0) section = HIER; else if(strncmp(line, "cars", 4) == 0) section = CARS; else if(strncmp(line, "peds", 4) == 0) section = PEDS; else if(strncmp(line, "path", 4) == 0) section = PATH; else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX; }else if(strncmp(line, "end", 3) == 0){ - section = section == MLO ? OBJS : NONE; + section = NONE; }else switch(section){ case OBJS: - if(strncmp(line, "sta", 3) == 0) - mlo = LoadMLO(line); - else - LoadObject(line); - break; - case MLO: - LoadMLOInstance(mlo, line); + id = LoadObject(line); + if(id > maxID) maxID = id; + if(id < minID) minID = id; break; case TOBJ: - LoadTimeObject(line); + id = LoadTimeObject(line); + if(id > maxID) maxID = id; + if(id < minID) minID = id; + break; + case WEAP: + LoadWeaponObject(line); break; case HIER: LoadClumpObject(line); @@ -558,17 +618,15 @@ CFileLoader::LoadObjectTypes(const char *filename) break; case PATH: if(pathIndex == -1){ - id = LoadPathHeader(line, pathTypeStr); - if(strncmp(pathTypeStr, "ped", 4) == 0) - pathType = 1; - else if(strncmp(pathTypeStr, "car", 4) == 0) - pathType = 0; + id = LoadPathHeader(line, pathType); pathIndex = 0; }else{ - if(pathType == 1) + if(pathType == 0) LoadPedPathNode(line, id, pathIndex); - else if(pathType == 0) - LoadCarPathNode(line, id, pathIndex); + else if (pathType == 1) + LoadCarPathNode(line, id, pathIndex, false); + else if (pathType == 2) + LoadCarPathNode(line, id, pathIndex, true); pathIndex++; if(pathIndex == 12) pathIndex = -1; @@ -581,26 +639,30 @@ CFileLoader::LoadObjectTypes(const char *filename) } CFileMgr::CloseFile(fd); - for(id = 0; id < MODELINFOSIZE; id++){ + for(id = minID; id <= maxID; id++){ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); - if(mi && mi->IsSimple()) - mi->SetupBigBuilding(); + if(mi && mi->IsBuilding()) + mi->SetupBigBuilding(minID, maxID); } } void SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags) { - mi->m_normalCull = !!(flags & 1); + mi->m_wetRoadReflection = !!(flags & 1); mi->m_noFade = !!(flags & 2); mi->m_drawLast = !!(flags & (4|8)); mi->m_additive = !!(flags & 8); mi->m_isSubway = !!(flags & 0x10); mi->m_ignoreLight = !!(flags & 0x20); mi->m_noZwrite = !!(flags & 0x40); + mi->m_noShadows = !!(flags & 0x80); + mi->m_ignoreDrawDist = !!(flags & 0x100); + mi->m_isCodeGlass = !!(flags & 0x200); + mi->m_isArtistGlass = !!(flags & 0x400); } -void +int CFileLoader::LoadObject(const char *line) { int id, numObjs; @@ -611,7 +673,7 @@ CFileLoader::LoadObject(const char *line) CSimpleModelInfo *mi; if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) - return; + return 0; // game returns return value switch(numObjs){ case 1: @@ -643,60 +705,11 @@ CFileLoader::LoadObject(const char *line) mi->m_firstDamaged = damaged; mi->SetTexDictionary(txd); MatchModelString(model, id); -} -int -CFileLoader::LoadMLO(const char *line) -{ - char smth[8]; - char name[24]; - int modelIndex; - float someFloat; - - sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat); - CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex); - minfo->SetName(name); - minfo->field_34 = someFloat; - int instId = CModelInfo::GetMloInstanceStore().allocPtr; - minfo->firstInstance = instId; - minfo->lastInstance = instId; - minfo->SetTexDictionary("generic"); - return modelIndex; -} - -void -CFileLoader::LoadMLOInstance(int id, const char *line) -{ - char name[24]; - RwV3d pos, scale, rot; - float angle; - int modelIndex; - - CMloModelInfo *minfo = (CMloModelInfo*)CModelInfo::GetModelInfo(id); - sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", - &modelIndex, - name, - &pos.x, &pos.y, &pos.z, - &scale.x, &scale.y, &scale.z, - &rot.x, &rot.y, &rot.z, - &angle); - float rad = Acos(angle) * 2.0f; - CInstance *inst = CModelInfo::GetMloInstanceStore().alloc(); - minfo->lastInstance++; - - RwMatrix *matrix = RwMatrixCreate(); - RwMatrixScale(matrix, &scale, rwCOMBINEREPLACE); - RwMatrixRotate(matrix, &rot, -RADTODEG(rad), rwCOMBINEPOSTCONCAT); - RwMatrixTranslate(matrix, &pos, rwCOMBINEPOSTCONCAT); - - inst->GetMatrix() = CMatrix(matrix); - inst->GetMatrix().UpdateRW(); - - inst->m_modelIndex = modelIndex; - RwMatrixDestroy(matrix); + return id; } -void +int CFileLoader::LoadTimeObject(const char *line) { int id, numObjs; @@ -708,7 +721,7 @@ CFileLoader::LoadTimeObject(const char *line) CTimeModelInfo *mi, *other; if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) - return; + return 0; // game returns return value switch(numObjs){ case 1: @@ -744,6 +757,29 @@ CFileLoader::LoadTimeObject(const char *line) if(other) other->SetOtherTimeModel(id); MatchModelString(model, id); + + return id; +} + +int +CFileLoader::LoadWeaponObject(const char *line) +{ + int id, numObjs; + char model[24], txd[24], animFile[16]; + float dist; + CWeaponModelInfo *mi; + + sscanf(line, "%d %s %s %s %d %f", &id, model, txd, animFile, &numObjs, &dist); + + mi = CModelInfo::AddWeaponModel(id); + mi->SetName(model); + mi->SetNumAtomics(1); + mi->m_lodDistances[0] = dist; + mi->SetTexDictionary(txd); + mi->SetAnimFile(animFile); + mi->SetColModel(&CTempColModels::ms_colModelWeapon); + MatchModelString(model, id); + return id; } void @@ -766,21 +802,22 @@ CFileLoader::LoadVehicleObject(const char *line) { int id; char model[24], txd[24]; - char type[8], handlingId[16], gamename[32], vehclass[12]; + char type[8], handlingId[16], gamename[32], animFile[16], vehclass[12]; uint32 frequency, comprules; int32 level, misc; float wheelScale; CVehicleModelInfo *mi; char *p; - sscanf(line, "%d %s %s %s %s %s %s %d %d %x %d %f", + sscanf(line, "%d %s %s %s %s %s %s %s %d %d %x %d %f", &id, model, txd, - type, handlingId, gamename, vehclass, + type, handlingId, gamename, animFile, vehclass, &frequency, &level, &comprules, &misc, &wheelScale); mi = CModelInfo::AddVehicleModel(id); mi->SetName(model); mi->SetTexDictionary(txd); + mi->SetAnimFile(animFile); for(p = gamename; *p; p++) if(*p == '_') *p = ' '; strcpy(mi->m_gameName, gamename); @@ -810,36 +847,34 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId); - // Well this is kinda dumb.... - if(strncmp(vehclass, "poorfamily", 11) == 0){ + if(strncmp(vehclass, "normal", 7) == 0) + mi->m_vehicleClass = CCarCtrl::NORMAL; + else if(strncmp(vehclass, "poorfamily", 11) == 0) mi->m_vehicleClass = CCarCtrl::POOR; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::POOR); - }else if(strncmp(vehclass, "richfamily", 11) == 0){ + else if(strncmp(vehclass, "richfamily", 11) == 0) mi->m_vehicleClass = CCarCtrl::RICH; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::RICH); - }else if(strncmp(vehclass, "executive", 10) == 0){ + else if(strncmp(vehclass, "executive", 10) == 0) mi->m_vehicleClass = CCarCtrl::EXEC; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::EXEC); - }else if(strncmp(vehclass, "worker", 7) == 0){ + else if(strncmp(vehclass, "worker", 7) == 0) mi->m_vehicleClass = CCarCtrl::WORKER; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::WORKER); - }else if(strncmp(vehclass, "special", 8) == 0){ - mi->m_vehicleClass = CCarCtrl::SPECIAL; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::SPECIAL); - }else if(strncmp(vehclass, "big", 4) == 0){ + else if(strncmp(vehclass, "big", 4) == 0) mi->m_vehicleClass = CCarCtrl::BIG; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::BIG); - }else if(strncmp(vehclass, "taxi", 5) == 0){ + else if(strncmp(vehclass, "taxi", 5) == 0) mi->m_vehicleClass = CCarCtrl::TAXI; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::TAXI); + else if(strncmp(vehclass, "moped", 6) == 0) + mi->m_vehicleClass = CCarCtrl::MOPED; + else if(strncmp(vehclass, "motorbike", 10) == 0) + mi->m_vehicleClass = CCarCtrl::MOTORBIKE; + else if(strncmp(vehclass, "leisureboat", 12) == 0) + mi->m_vehicleClass = CCarCtrl::LEISUREBOAT; + else if(strncmp(vehclass, "workerboat", 11) == 0) + mi->m_vehicleClass = CCarCtrl::WORKERBOAT; + else if(strncmp(vehclass, "ignore", 11) == 0){ + mi->m_vehicleClass = -1; + return; } + CCarCtrl::AddToCarArray(id, mi->m_vehicleClass); + mi->m_frequency = frequency; } void @@ -847,67 +882,87 @@ CFileLoader::LoadPedObject(const char *line) { int id; char model[24], txd[24]; - char pedType[24], pedStats[24], animGroup[24]; + char pedType[24], pedStats[24], animGroup[24], animFile[16]; int carsCanDrive; CPedModelInfo *mi; int animGroupId; + int radio1, radio2; - if(sscanf(line, "%d %s %s %s %s %s %x", + sscanf(line, "%d %s %s %s %s %s %x %s %d %d", &id, model, txd, - pedType, pedStats, animGroup, &carsCanDrive) != 7) - return; + pedType, pedStats, animGroup, &carsCanDrive, + animFile, &radio1, &radio2); mi = CModelInfo::AddPedModel(id); mi->SetName(model); mi->SetTexDictionary(txd); + mi->SetAnimFile(animFile); mi->SetColModel(&CTempColModels::ms_colModelPed1); mi->m_pedType = CPedType::FindPedType(pedType); mi->m_pedStatType = CPedStats::GetPedStatType(pedStats); for(animGroupId = 0; animGroupId < NUM_ANIM_ASSOC_GROUPS; animGroupId++) if(strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)animGroupId)) == 0) break; + assert(animGroupId < NUM_ANIM_ASSOC_GROUPS); mi->m_animGroup = animGroupId; mi->m_carsCanDrive = carsCanDrive; - - // ??? - CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1); + mi->radio1 = radio1; + mi->radio2 = radio2; } int -CFileLoader::LoadPathHeader(const char *line, char *type) +CFileLoader::LoadPathHeader(const char *line, int &type) { int id; char modelname[32]; - sscanf(line, "%s %d %s", type, &id, modelname); + sscanf(line, "%d %d %s", &type, &id, modelname); return id; } void CFileLoader::LoadPedPathNode(const char *line, int id, int node) { - int type, next, cross; - float x, y, z, width; - - sscanf(line, "%d %d %d %f %f %f %f", &type, &next, &cross, &x, &y, &z, &width); - ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, 0, !!cross); + int type, next, cross, numLeft, numRight, speed, flags; + float x, y, z, width, spawnRate; + + if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f", + &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight, + &speed, &flags, &spawnRate) != 12) + spawnRate = 1.0f; + + if(id == -1) + ThePaths.StoreDetachedNodeInfoPed(node, type, next, x, y, z, + width, !!cross, !!(flags&1), !!(flags&4), spawnRate*15.0f); + else + ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, + width, !!cross, spawnRate*15.0f); } void -CFileLoader::LoadCarPathNode(const char *line, int id, int node) +CFileLoader::LoadCarPathNode(const char *line, int id, int node, bool waterPath) { - int type, next, cross, numLeft, numRight; - float x, y, z, width; - - sscanf(line, "%d %d %d %f %f %f %f %d %d", &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight); - ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight); + int type, next, cross, numLeft, numRight, speed, flags; + float x, y, z, width, spawnRate; + + if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f", + &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight, + &speed, &flags, &spawnRate) != 12) + spawnRate = 1.0f; + + if(id == -1) + ThePaths.StoreDetachedNodeInfoCar(node, type, next, x, y, z, width, numLeft, numRight, + !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15, false); + else + ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight, + !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15); } void CFileLoader::Load2dEffect(const char *line) { - int id, r, g, b, a, type; + int id, r, g, b, a, type, ptype; float x, y, z; char corona[32], shadow[32]; int shadowIntens, lightType, roadReflection, flare, flags, probability; @@ -980,6 +1035,18 @@ CFileLoader::Load2dEffect(const char *line) effect->attractor.flags = flags; effect->attractor.probability = probability; break; + case EFFECT_PED_ATTRACTOR: + sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %f %f %f", + &id, &x, &y, &z, &r, &g, &b, &a, &type, + &ptype, + &effect->pedattr.queueDir.x, + &effect->pedattr.queueDir.y, + &effect->pedattr.queueDir.z, + &effect->pedattr.useDir.x, + &effect->pedattr.useDir.y, + &effect->pedattr.useDir.z); + effect->pedattr.type = ptype; + break; } CTxdStore::PopCurrentTxd(); @@ -993,20 +1060,21 @@ CFileLoader::LoadScene(const char *filename) INST, ZONE, CULL, + OCCL, PICK, PATH, }; char *line; int fd; int section; - int pathIndex; - char pathTypeStr[20]; + int pathType, pathIndex; section = NONE; pathIndex = -1; debug("Creating objects from %s...\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); + assert(fd > 0); for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ if(*line == '\0' || *line == '#') continue; @@ -1017,6 +1085,7 @@ CFileLoader::LoadScene(const char *filename) else if(strncmp(line, "cull", 4) == 0) section = CULL; else if(strncmp(line, "pick", 4) == 0) section = PICK; else if(strncmp(line, "path", 4) == 0) section = PATH; + else if(strncmp(line, "occl", 4) == 0) section = OCCL; }else if(strncmp(line, "end", 3) == 0){ section = NONE; }else switch(section){ @@ -1029,18 +1098,24 @@ CFileLoader::LoadScene(const char *filename) case CULL: LoadCullZone(line); break; + case OCCL: + LoadOcclusionVolume(line); + break; case PICK: // unused LoadPickup(line); break; case PATH: - // unfinished in the game if(pathIndex == -1){ - LoadPathHeader(line, pathTypeStr); - // type not set + LoadPathHeader(line, pathType); pathIndex = 0; }else{ - // nodes not loaded + if(pathType == 0) + LoadPedPathNode(line, -1, pathIndex); + else if (pathType == 1) + LoadCarPathNode(line, -1, pathIndex, false); + else if (pathType == 2) + LoadCarPathNode(line, -1, pathIndex, true); pathIndex++; if(pathIndex == 12) pathIndex = -1; @@ -1063,18 +1138,30 @@ CFileLoader::LoadObjectInstance(const char *line) CSimpleModelInfo *mi; RwMatrix *xform; CEntity *entity; - if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", - &id, name, + 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) != 12) - return; + &axis.x, &axis.y, &axis.z, &angle) != 13){ + 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; + area = 0; + } mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); if(mi == nil) return; assert(mi->IsSimple()); + if(!CStreaming::IsObjectInCdImage(id)) + debug("Not in cdimage %s\n", mi->GetName()); + angle = -RADTODEG(2.0f * acosf(angle)); xform = RwMatrixCreate(); RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE); @@ -1089,7 +1176,8 @@ CFileLoader::LoadObjectInstance(const char *line) entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition()); - if(mi->IsSimple()){ + entity->m_area = area; + if(mi->IsBuilding()){ if(mi->m_isBigBuilding) entity->SetupBigBuilding(); if(mi->m_isSubway) @@ -1098,14 +1186,25 @@ CFileLoader::LoadObjectInstance(const char *line) if(mi->GetLargestLodDistance() < 2.0f) entity->bIsVisible = false; CWorld::Add(entity); + + 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; + + if(entity->GetPosition().z + col->boundingBox.min.z < 6.0f) + entity->bUnderwater = true; }else{ entity = new CDummyObject; entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); CWorld::Add(entity); - if(IsGlass(entity->GetModelIndex())) + if(IsGlass(entity->GetModelIndex()) && !mi->m_isArtistGlass) entity->bIsVisible = false; entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition()); + entity->m_area = area; } RwMatrixDestroy(xform); @@ -1151,53 +1250,21 @@ CFileLoader::LoadPickup(const char *line) } void -CFileLoader::LoadMapZones(const char *filename) +CFileLoader::LoadOcclusionVolume(const char *line) { - enum { - NONE, - INST, - ZONE, - CULL, - PICK, - PATH, - }; - char *line; - int fd; - int section; - - section = NONE; - debug("Creating zones from %s...\n", filename); - - fd = CFileMgr::OpenFile(filename, "rb"); - for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ - if(*line == '\0' || *line == '#') - continue; - - if(section == NONE){ - if(strncmp(line, "zone", 4) == 0) section = ZONE; - }else if(strncmp(line, "end", 3) == 0){ - section = NONE; - }else switch(section){ - case ZONE: { - char name[24]; - int type, level; - float minx, miny, minz; - float maxx, maxy, maxz; - if(sscanf(line, "%s %d %f %f %f %f %f %f %d", - name, &type, - &minx, &miny, &minz, - &maxx, &maxy, &maxz, - &level) == 9) - CTheZones::CreateMapZone(name, (eZoneType)type, minx, miny, minz, maxx, maxy, maxz, (eLevelName)level); - } - break; - } - } - CFileMgr::CloseFile(fd); + float x, y, z; + float width, length, height; + float angle; - debug("Finished loading IPL\n"); + sscanf(line, "%f %f %f %f %f %f %f", + &x, &y, &z, + &width, &length, &height, + &angle); + COcclusion::AddOne(x, y, z, width, length, z + height/2.0f, angle); } + +//--MIAMI: unused void CFileLoader::ReloadPaths(const char *filename) { @@ -1208,10 +1275,10 @@ CFileLoader::ReloadPaths(const char *filename) char *line; int section = NONE; int id, pathType, pathIndex = -1; - char pathTypeStr[20]; debug("Reloading paths from %s...\n", filename); int fd = CFileMgr::OpenFile(filename, "r"); + assert(fd > 0); for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { if (*line == '\0' || *line == '#') continue; @@ -1227,17 +1294,15 @@ CFileLoader::ReloadPaths(const char *filename) switch (section) { case PATH: if (pathIndex == -1) { - id = LoadPathHeader(line, pathTypeStr); - if (strncmp(pathTypeStr, "ped", 4) == 0) - pathType = 1; - else if (strncmp(pathTypeStr, "car", 4) == 0) - pathType = 0; + id = LoadPathHeader(line, pathType); pathIndex = 0; } else { - if (pathType == 1) + if(pathType == 0) LoadPedPathNode(line, id, pathIndex); - else if (pathType == 0) - LoadCarPathNode(line, id, pathIndex); + else if (pathType == 1) + LoadCarPathNode(line, id, pathIndex, false); + else if (pathType == 2) + LoadCarPathNode(line, id, pathIndex, true); pathIndex++; if (pathIndex == 12) pathIndex = -1; @@ -1267,6 +1332,7 @@ CFileLoader::ReloadObjectTypes(const char *filename) CFileMgr::ChangeDir("\\DATA\\MAPS\\"); int fd = CFileMgr::OpenFile(filename, "r"); + assert(fd > 0); CFileMgr::ChangeDir("\\"); for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { if (*line == '\0' || *line == '#') @@ -1342,6 +1408,7 @@ CFileLoader::ReLoadScene(const char *filename) char *line; CFileMgr::ChangeDir("\\DATA\\"); int fd = CFileMgr::OpenFile(filename, "r"); + assert(fd > 0); CFileMgr::ChangeDir("\\"); for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h index 87b8fe61..077e7bdd 100644 --- a/src/core/FileLoader.h +++ b/src/core/FileLoader.h @@ -5,10 +5,11 @@ class CFileLoader static char ms_line[256]; public: static void LoadLevel(const char *filename); - static void LoadCollisionFromDatFile(int currlevel); static char *LoadLine(int fd); static RwTexDictionary *LoadTexDictionary(const char *filename); - static void LoadCollisionFile(const char *filename); + static void LoadCollisionFile(const char *filename, uint8 colSlot); + static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot); + static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot); static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name); static void LoadModelFile(const char *filename); static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data); @@ -22,16 +23,15 @@ public: static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src); static void LoadObjectTypes(const char *filename); - static void LoadObject(const char *line); - static int LoadMLO(const char *line); - static void LoadMLOInstance(int id, const char *line); - static void LoadTimeObject(const char *line); + static int LoadObject(const char *line); + static int LoadTimeObject(const char *line); + static int LoadWeaponObject(const char *line); static void LoadClumpObject(const char *line); static void LoadVehicleObject(const char *line); static void LoadPedObject(const char *line); - static int LoadPathHeader(const char *line, char *type); + static int LoadPathHeader(const char *line, int &type); static void LoadPedPathNode(const char *line, int id, int node); - static void LoadCarPathNode(const char *line, int id, int node); + static void LoadCarPathNode(const char *line, int id, int node, bool waterPath); static void Load2dEffect(const char *line); static void LoadScene(const char *filename); @@ -39,8 +39,7 @@ public: static void LoadZone(const char *line); static void LoadCullZone(const char *line); static void LoadPickup(const char *line); - - static void LoadMapZones(const char *filename); + static void LoadOcclusionVolume(const char *line); static void ReloadPaths(const char *filename); static void ReloadObjectTypes(const char *filename); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index d58d0576..dd840bdc 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -37,6 +37,18 @@ #include "Messages.h" #include "FileLoader.h" +// Similar story to Hud.cpp: +// Game has colors inlined in code. +// For easier modification we collect them here: +CRGBA LABEL_COLOR(255, 150, 225, 255); +CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255); +CRGBA MENUOPTION_COLOR(255, 150, 225, 255); +CRGBA SELECTEDMENUOPTION_COLOR(255, 150, 225, 255); +CRGBA HEADER_COLOR(255, 150, 255, 255); +CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); +CRGBA SLIDERON_COLOR(97, 194, 247, 255); +CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); + #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result @@ -149,53 +161,7 @@ bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x5F311C -const char* FrontendFilenames[][2] = { - {"fe2_mainpanel_ul", "" }, - {"fe2_mainpanel_ur", "" }, - {"fe2_mainpanel_dl", "" }, - {"fe2_mainpanel_dr", "" }, - {"fe2_mainpanel_dr2", "" }, - {"fe2_tabactive", "" }, - {"fe_iconbrief", "" }, - {"fe_iconstats", "" }, - {"fe_iconcontrols", "" }, - {"fe_iconsave", "" }, - {"fe_iconaudio", "" }, - {"fe_icondisplay", "" }, - {"fe_iconlanguage", "" }, - {"fe_controller", "" }, - {"fe_controllersh", "" }, - {"fe_arrows1", "" }, - {"fe_arrows2", "" }, - {"fe_arrows3", "" }, - {"fe_arrows4", "" }, - {"fe_radio1", "" }, - {"fe_radio2", "" }, - {"fe_radio3", "" }, - {"fe_radio4", "" }, - {"fe_radio5", "" }, - {"fe_radio6", "" }, - {"fe_radio7", "" }, - {"fe_radio8", "" }, - {"fe_radio9", "" }, -}; - -#ifdef MENU_MAP -const char* MapFilenames[][2] = { - {"mapMid01", "mapMid01A"}, - {"mapMid02", "mapMid02A"}, - {"mapMid03", "mapMid03A"}, - {"mapBot01", "mapBot01A"}, - {"mapBot02", "mapBot02A"}, - {"mapBot03", "mapBot03A"}, - {"mapTop01", "mapTop01A"}, - {"mapTop02", "mapTop02A"}, - {"mapTop03", "mapTop03A"}, -}; -CSprite2d CMenuManager::m_aMapSprites[NUM_MAP_SPRITES]; -#endif - +/* // 0x5F3344 const char* MenuFilenames[][2] = { {"connection24", ""}, @@ -219,6 +185,37 @@ const char* MenuFilenames[][2] = { {"gta3logo256", "gta3logo256m"}, { nil, nil } }; +*/ + +// 0x68C144 +const char* FrontendFilenames[][2] = { + {"background", ""}, + {"vc_logo", "vc_logom"}, + {"mouse", "mousea"}, + {"mapTop01", "mapTop01A"}, + {"mapTop02", "mapTop02A"}, + {"mapTop03", "mapTop03A"}, + {"mapMid01", "mapMid01A"}, + {"mapMid02", "mapMid02A"}, + {"mapMid03", "mapMid03A"}, + {"mapBot01", "mapBot01A"}, + {"mapBot02", "mapBot02A"}, + {"mapBot03", "mapBot03A"}, + {"wildstyle", "wildstyleA"}, + {"flash", "flashA"}, + {"kchat", "kchatA"}, + {"fever", "feverA"}, + {"vrock", "vrockA"}, + {"vcpr", "vcprA"}, + {"espantoso", "espantosoA"}, + {"emotion", "emotionA"}, + {"wave103", "wave103A"}, + {"mp3", "mp3A"}, + {"downOff", "buttonA"}, + {"downOn", "buttonA"}, + {"upOff", "buttonA"}, + {"upOn", "buttonA"} +}; #ifdef ASPECT_RATIO_SCALE // All of the defines below replace the StretchX function. Otherwise use SCREEN_SCALE_X. @@ -284,7 +281,7 @@ ScaleAndCenterX(float x) #endif #define PREPARE_MENU_HEADER \ - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \ + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); \ CFont::SetRightJustifyOn(); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); @@ -306,9 +303,10 @@ ScaleAndCenterX(float x) m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ } while(0) +// TODO: this is COMPLETELY different in VC #define ProcessRadioIcon(sprite, x, y, radioId, hoverOpt) \ do { \ - sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170)); \ + sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(255, 255, 255, 100)); \ if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \ m_nHoverOption = hoverOpt; \ } while (0) @@ -651,15 +649,15 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR int lastActiveBarX = 0; float curBarX = 0.0f; - float spacing = SCREEN_SCALE_X(10.0f); + float spacing = SCREEN_SCALE_X(4.0f); // TODO: find actual numbers used in the game for (int i = 0; i < 16; i++) { - curBarX = i * rectSize/16.0f + x; + curBarX = i * rectSize/32.0f + x; if (i / 16.0f + 1 / 32.0f < progress) { - color = CRGBA(255, 217, 106, FadeIn(255)); + color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255)); lastActiveBarX = curBarX; } else - color = CRGBA(185, 120, 0, FadeIn(255)); + color = CRGBA(SLIDEROFF_COLOR.r, SLIDEROFF_COLOR.g, SLIDEROFF_COLOR.b, FadeIn(255)); maxBarHeight = Max(mostLeftBarSize, mostRightBarSize); @@ -700,8 +698,10 @@ CMenuManager::Draw() CFont::SetCentreOff(); CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOn(); -#ifdef GTA3_1_1_PATCH - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + + // no V1.1 text in vc obv +#if 0 //def GTA3_1_1_PATCH + CFont::SetColor(CRGBA(255, 150, 225, FadeIn(255))); CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f)); @@ -711,6 +711,7 @@ CMenuManager::Draw() AsciiToUnicode(gString, gUString); CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString); #endif + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); @@ -736,9 +737,13 @@ CMenuManager::Draw() if(!m_bRenderGameInMenu) #endif if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') { - + PREPARE_MENU_HEADER - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); // Weird place to put that. nextYToUse += 24.0f + 10.0f; @@ -747,7 +752,7 @@ CMenuManager::Draw() CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_X), MENU_Y(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_Y)); CFont::SetRightJustifyOff(); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); // Label wchar *str; @@ -845,7 +850,7 @@ CMenuManager::Draw() break; case MENUPAGE_START_MENU: columnWidth = 320; - headerHeight = 140; + headerHeight = 110; lineHeight = 24; CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); @@ -898,7 +903,7 @@ CMenuManager::Draw() } float usableLineHeight = lineHeight * 0.9f; // also height of biggest bar in slider - float smallestSliderBar = lineHeight * 0.1f; + float smallestSliderBar = lineHeight * 0.25f; // TODO: find actual number bool foundTheHoveringItem = false; wchar unicodeTemp[64]; char asciiTemp[32]; @@ -1084,16 +1089,16 @@ CMenuManager::Draw() rightText = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF"); break; case MENUACTION_PEDROADGROUPS: - rightText = TheText.Get(gbShowPedRoadGroups ? "FEM_ON" : "FEM_OFF"); + // REMOVED(MIAMI) break; case MENUACTION_CARROADGROUPS: - rightText = TheText.Get(gbShowCarRoadGroups ? "FEM_ON" : "FEM_OFF"); + // REMOVED(MIAMI) break; case MENUACTION_COLLISIONPOLYS: rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF"); break; case MENUACTION_SHOWCULL: - rightText = TheText.Get(gbShowCullZoneDebugStuff ? "FEM_ON" : "FEM_OFF"); + // REMOVED(MIAMI) break; case MENUACTION_SHOWHEADBOB: rightText = TheText.Get(TheCamera.m_bHeadBob ? "FEM_ON" : "FEM_OFF"); @@ -1226,7 +1231,7 @@ CMenuManager::Draw() // We keep stretching, because we also stretch background image and we want that bar to be aligned with borders of background CSprite2d::DrawRect(CRect(StretchX(10.0f), MENU_Y(bitAboveNextItemY), SCREEN_STRETCH_FROM_RIGHT(11.0f), MENU_Y(usableLineHeight + nextItemY)), - CRGBA(100, 200, 50, FadeIn(50))); + CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); } CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90))); @@ -1245,14 +1250,14 @@ CMenuManager::Draw() if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") && !m_bGameNotLoaded && textLayer == 1) { - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); } if (i == m_nCurrOption && itemsAreSelectable){ - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } } @@ -1321,18 +1326,18 @@ CMenuManager::Draw() // Radio icons if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) { - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO1], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO2], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO5], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO7], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO8], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO3], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO4], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO6], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO9], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WILDSTYLE], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FLASH], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_KCHAT], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FEVER], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VROCK], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VCPR], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_ESPANTOSO], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_EMOTION], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WAVE], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8); if (DMAudio.IsMP3RadioChannelAvailable()) - ProcessRadioIcon(m_aMenuSprites[MENUSPRITE_MP3LOGO], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9); + ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_MP3], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9); nextYToUse += 70.0f; } @@ -1813,11 +1818,21 @@ CMenuManager::DrawControllerSetupScreen() switch (m_ControlMethod) { case CONTROL_STANDARD: - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); break; case CONTROL_CLASSIC: - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + TheText.Get("FET_CTI")); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_CTI")); break; default: @@ -2079,13 +2094,13 @@ CMenuManager::DrawFrontEndSaveZone() mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); } } } @@ -2273,13 +2288,13 @@ CMenuManager::DrawFrontEndNormal() mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); } } } @@ -2293,65 +2308,24 @@ CMenuManager::DrawFrontEndNormal() LoadSplash(nil); - eMenuSprites previousSprite; + eMenuSprites previousSprite = MENUSPRITE_BACKGROUND; + if (m_nMenuFadeAlpha < 255) { - switch (m_nPrevScreen) { - case MENUPAGE_STATS: - case MENUPAGE_START_MENU: - case MENUPAGE_PAUSE_MENU: - previousSprite = MENUSPRITE_MAINMENU; - break; - case MENUPAGE_NEW_GAME: - case MENUPAGE_CHOOSE_LOAD_SLOT: - case MENUPAGE_CHOOSE_DELETE_SLOT: - case MENUPAGE_NEW_GAME_RELOAD: - case MENUPAGE_LOAD_SLOT_CONFIRM: - case MENUPAGE_DELETE_SLOT_CONFIRM: - case MENUPAGE_EXIT: - previousSprite = MENUSPRITE_SINGLEPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAIN: - previousSprite = MENUSPRITE_MULTIPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAP: - case MENUPAGE_MULTIPLAYER_FIND_GAME: - case MENUPAGE_SKIN_SELECT: - case MENUPAGE_KEYBOARD_CONTROLS: - case MENUPAGE_MOUSE_CONTROLS: - previousSprite = MENUSPRITE_FINDGAME; - break; - case MENUPAGE_MULTIPLAYER_CONNECTION: - case MENUPAGE_MULTIPLAYER_MODE: - previousSprite = MENUSPRITE_CONNECTION; - break; - case MENUPAGE_MULTIPLAYER_CREATE: - previousSprite = MENUSPRITE_HOSTGAME; - break; - case MENUPAGE_SKIN_SELECT_OLD: - case MENUPAGE_OPTIONS: - previousSprite = MENUSPRITE_PLAYERSET; - break; - default: - previousSprite = MENUSPRITE_MAINMENU; - break; - } - if (m_nPrevScreen == m_nCurrScreen) CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255 - m_nMenuFadeAlpha)); else - m_aMenuSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255 - m_nMenuFadeAlpha)); + m_aFrontEndSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255 - m_nMenuFadeAlpha)); } RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); - eMenuSprites currentSprite = MENUSPRITE_MAINMENU; // actually uninitialized + eMenuSprites currentSprite = MENUSPRITE_BACKGROUND; // actually uninitialized + switch (m_nCurrScreen) { case MENUPAGE_STATS: case MENUPAGE_START_MENU: case MENUPAGE_PAUSE_MENU: - currentSprite = MENUSPRITE_MAINMENU; - break; case MENUPAGE_NEW_GAME: case MENUPAGE_CHOOSE_LOAD_SLOT: case MENUPAGE_CHOOSE_DELETE_SLOT: @@ -2359,28 +2333,18 @@ CMenuManager::DrawFrontEndNormal() case MENUPAGE_LOAD_SLOT_CONFIRM: case MENUPAGE_DELETE_SLOT_CONFIRM: case MENUPAGE_EXIT: - currentSprite = MENUSPRITE_SINGLEPLAYER; - break; case MENUPAGE_MULTIPLAYER_MAIN: - currentSprite = MENUSPRITE_MULTIPLAYER; - break; case MENUPAGE_MULTIPLAYER_MAP: case MENUPAGE_MULTIPLAYER_FIND_GAME: case MENUPAGE_SKIN_SELECT: case MENUPAGE_KEYBOARD_CONTROLS: case MENUPAGE_MOUSE_CONTROLS: - currentSprite = MENUSPRITE_FINDGAME; - break; case MENUPAGE_MULTIPLAYER_CONNECTION: case MENUPAGE_MULTIPLAYER_MODE: - currentSprite = MENUSPRITE_CONNECTION; - break; case MENUPAGE_MULTIPLAYER_CREATE: - currentSprite = MENUSPRITE_HOSTGAME; - break; case MENUPAGE_SKIN_SELECT_OLD: case MENUPAGE_OPTIONS: - currentSprite = MENUSPRITE_PLAYERSET; + currentSprite = MENUSPRITE_BACKGROUND; break; } @@ -2404,13 +2368,13 @@ CMenuManager::DrawFrontEndNormal() #endif if (m_nMenuFadeAlpha > 255){ - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); } else { RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha)); + m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha)); } } else { - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); // TODO: what is this? waiting mouse? if(field_518 == 4){ if(m_nHoverOption == HOVEROPTION_3 || m_nHoverOption == HOVEROPTION_4 || @@ -2422,15 +2386,20 @@ CMenuManager::DrawFrontEndNormal() } } + m_aFrontEndSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); + // GTA LOGO RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + /* if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_PAUSE_MENU) { if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - m_aMenuSprites[MENUSPRITE_GTA3LOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), MENU_Y(70.0f), MENU_X_LEFT_ALIGNED(435.0f), MENU_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255))); + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), MENU_Y(70.0f), MENU_X_LEFT_ALIGNED(435.0f), MENU_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255))); else - m_aMenuSprites[MENUSPRITE_GTALOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), MENU_Y(40.0f), MENU_X_LEFT_ALIGNED(415.0f), MENU_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255))); + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), MENU_Y(40.0f), MENU_X_LEFT_ALIGNED(415.0f), MENU_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255))); } + */ + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_SCALE_X(27.0f), MENU_Y(8.0f), SCREEN_SCALE_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255))); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); @@ -2457,19 +2426,19 @@ CMenuManager::DrawFrontEndNormal() RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f)); - CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f)); + CRect mouse(0.0f, 0.0f, MENU_X(40.0f), MENU_Y(40.0f)); + CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(55.0f), MENU_Y(43.0f)); mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); } } } @@ -2711,21 +2680,21 @@ CMenuManager::DrawPlayerSetupScreen() // 2 - leaves gap between button and scrollbar if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP) { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(-20.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)), CRGBA(255, 255, 255, FadeIn(255))); #endif } else { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(-21.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)), CRGBA(255, 255, 255, FadeIn(255))); #endif @@ -2733,21 +2702,21 @@ CMenuManager::DrawPlayerSetupScreen() if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN) { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), + m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f), + m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f), MENU_X_RIGHT_ALIGNED(-20.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)), CRGBA(255, 255, 255, FadeIn(255))); #endif } else { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), + m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f), + m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f), MENU_X_RIGHT_ALIGNED(-21.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)), CRGBA(255, 255, 255, FadeIn(255))); #endif @@ -3021,51 +2990,59 @@ CMenuManager::LoadAllTextures() CStreaming::ImGonnaUseStreamingMemory(); CGame::TidyUpMemory(false, true); CTxdStore::PushCurrentTxd(); - int frontendTxdSlot = CTxdStore::FindTxdSlot("frontend"); + int frontendTxdSlot1 = CTxdStore::FindTxdSlot("frontend1"); - if(frontendTxdSlot == -1) - frontendTxdSlot = CTxdStore::AddTxdSlot("frontend"); + if(frontendTxdSlot1 == -1) + frontendTxdSlot1 = CTxdStore::AddTxdSlot("frontend1"); - printf("LOAD frontend\n"); - CTxdStore::LoadTxd(frontendTxdSlot, "MODELS/FRONTEND.TXD"); - CTxdStore::AddRef(frontendTxdSlot); - CTxdStore::SetCurrentTxd(frontendTxdSlot); -#ifndef GTA3_1_1_PATCH - CStreaming::IHaveUsedStreamingMemory(); - CTimer::Update(); -#endif + printf("LOAD frontend1\n"); + CTxdStore::LoadTxd(frontendTxdSlot1, "MODELS/FRONTEN1.TXD"); + CTxdStore::AddRef(frontendTxdSlot1); + CTxdStore::SetCurrentTxd(frontendTxdSlot1); - for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) { + for (int i = 0; i < 3; i++) { m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]); m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } - int menuTxdSlot = CTxdStore::FindTxdSlot("menu"); + CTxdStore::PopCurrentTxd(); + CStreaming::IHaveUsedStreamingMemory(); + + + // if ( !*(_BYTE *)(v1 + 124) ) - if (menuTxdSlot == -1) - menuTxdSlot = CTxdStore::AddTxdSlot("menu"); + CStreaming::MakeSpaceFor(350 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile + CStreaming::ImGonnaUseStreamingMemory(); + CTxdStore::PushCurrentTxd(); + + int frontendTxdSlot2 = CTxdStore::FindTxdSlot("frontend2"); - printf("LOAD sprite\n"); - CTxdStore::LoadTxd(menuTxdSlot, "MODELS/MENU.TXD"); - CTxdStore::AddRef(menuTxdSlot); - CTxdStore::SetCurrentTxd(menuTxdSlot); + if (frontendTxdSlot2 == -1) + frontendTxdSlot2 = CTxdStore::AddTxdSlot("frontend2"); - for (int i = 0; i < ARRAY_SIZE(MenuFilenames); i++) { - m_aMenuSprites[i].SetTexture(MenuFilenames[i][0], MenuFilenames[i][1]); - m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); + printf("LOAD frontend2\n"); + CTxdStore::LoadTxd(frontendTxdSlot2, "MODELS/FRONTEN2.TXD"); + CTxdStore::AddRef(frontendTxdSlot2); + CTxdStore::SetCurrentTxd(frontendTxdSlot2); + + for (int i = 3; i < NUM_MENU_SPRITES; i++) { + m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]); + m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } -#ifdef MENU_MAP + + CTxdStore::PopCurrentTxd(); + CStreaming::IHaveUsedStreamingMemory(); + + +#if 0 //MENU_MAP for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) { m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]); m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } #endif -#ifdef GTA3_1_1_PATCH - CStreaming::IHaveUsedStreamingMemory(); - CTimer::Update(); -#endif + m_bSpritesLoaded = true; - CTxdStore::PopCurrentTxd(); + CTimer::Update(); } void @@ -4468,7 +4445,7 @@ CMenuManager::ProcessButtonPresses(void) CGame::ReloadIPLs(); break; case MENUACTION_SHOWCULL: - gbShowCullZoneDebugStuff = !gbShowCullZoneDebugStuff; + // REMOVED(MIAMI) break; case MENUACTION_MEMCARDSAVECONFIRM: return; @@ -4938,11 +4915,11 @@ CMenuManager::ProcessOnOffMenuOptions() DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); break; case MENUACTION_PEDROADGROUPS: - gbShowPedRoadGroups = !gbShowPedRoadGroups; + // REMOVED(MIAMI) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); break; case MENUACTION_CARROADGROUPS: - gbShowCarRoadGroups = !gbShowCarRoadGroups; + // REMOVED(MIAMI) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); break; case MENUACTION_COLLISIONPOLYS: @@ -5147,18 +5124,16 @@ CMenuManager::UnloadTextures() for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); ++i) m_aFrontEndSprites[i].Delete(); - int frontend = CTxdStore::FindTxdSlot("frontend"); + int frontend = CTxdStore::FindTxdSlot("frontend1"); CTxdStore::RemoveTxd(frontend); - printf("REMOVE menu textures\n"); - for (int i = 0; i < ARRAY_SIZE(MenuFilenames); ++i) - m_aMenuSprites[i].Delete(); -#ifdef MENU_MAP + int frontend2 = CTxdStore::FindTxdSlot("frontend2"); + CTxdStore::RemoveTxd(frontend2); + +#ifdef false //MENU_MAP for (int i = 0; i < ARRAY_SIZE(MapFilenames); ++i) m_aMapSprites[i].Delete(); #endif - int menu = CTxdStore::FindTxdSlot("menu"); - CTxdStore::RemoveTxd(menu); m_bSpritesLoaded = false; } @@ -5197,6 +5172,9 @@ CMenuManager::PrintController(void) // FIX: Originally this function doesn't have StretchX/Y, everything had constant pixel size (due to screen was abandoned early?) // Also texts and their alignment were very bad, so I tried to make them readable (commented out the original code, and marked the ones I added with X) + // sorry! + + /* m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(240.0f), MENU_Y(180.0f), CRGBA(0, 0, 0, 255)); m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); if (m_DisplayControllerOnFoot) { @@ -5210,6 +5188,7 @@ CMenuManager::PrintController(void) else m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); } + */ CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); // X @@ -5468,47 +5447,47 @@ CMenuManager::PrintMap(void) RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize, + m_aFrontEndSprites[MENUSPRITE_MAPTOP01].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize, fMapCenterX - halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize, + m_aFrontEndSprites[MENUSPRITE_MAPTOP02].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize, fMapCenterX + halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize, + m_aFrontEndSprites[MENUSPRITE_MAPTOP03].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize, fMapCenterX + fMapSize, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile, + m_aFrontEndSprites[MENUSPRITE_MAPMID01].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile, fMapCenterX - halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile, + m_aFrontEndSprites[MENUSPRITE_MAPMID02].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile, fMapCenterX + halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile, + m_aFrontEndSprites[MENUSPRITE_MAPMID03].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile, fMapCenterX + fMapSize, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile, + m_aFrontEndSprites[MENUSPRITE_MAPBOT01].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile, fMapCenterX - halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile, + m_aFrontEndSprites[MENUSPRITE_MAPBOT02].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile, fMapCenterX + halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile, + m_aFrontEndSprites[MENUSPRITE_MAPBOT03].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile, fMapCenterX + fMapSize, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } @@ -5536,9 +5515,10 @@ CMenuManager::PrintMap(void) if (mapPoint.y > fMapCenterY - fMapSize && mapPoint.y < fMapCenterY + fMapSize && mapPoint.x > fMapCenterX - fMapSize && mapPoint.x < fMapCenterX + fMapSize) { + // Don't ask me the meanings, I don't know. Found them by trying float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize; - float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f; - float y = 2000.0f - ((mapPoint.y - diffY) / (fMapSize * 2)) * 4000.0f; + float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * (WORLD_SIZE_X / MENU_MAP_WIDTH_SCALE) - (WORLD_SIZE_X / 2 + MENU_MAP_LEFT_OFFSET * MENU_MAP_LENGTH_UNIT); + float y = (WORLD_SIZE_Y / 2 - MENU_MAP_TOP_OFFSET * MENU_MAP_LENGTH_UNIT) - ((mapPoint.y - diffY) / (fMapSize * 2)) * (WORLD_SIZE_Y / MENU_MAP_HEIGHT_SCALE); CRadar::ToggleTargetMarker(x, y); DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0); } @@ -5584,7 +5564,8 @@ CMenuManager::PrintMap(void) if (fMapCenterY + fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f)) fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - fMapSize; - fMapCenterY = Min(fMapCenterY, fMapSize); // To not show beyond north border + if (fMapCenterY - fMapSize > SCREEN_HEIGHT / 2) + fMapCenterY = SCREEN_HEIGHT / 2 + fMapSize; bMenuMapActive = false; @@ -5654,9 +5635,7 @@ CMenuManager::ConstructStatLine(int rowIdx) STAT_LINE("PL_STAT", nil, false, nil); - int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : - CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1)); - percentCompleted = Min(percentCompleted, 100); + int percentCompleted = CStats::GetPercentageProgress(); STAT_LINE("PER_COM", &percentCompleted, false, nil); STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 89517528..114ea6ba 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -7,8 +7,8 @@ #define MENUHEADER_POS_Y 75.0f #define MENUHEADER_HEIGHT 1.3f #else -#define MENUHEADER_POS_X 35.0f -#define MENUHEADER_POS_Y 93.0f +#define MENUHEADER_POS_X 10.0f +#define MENUHEADER_POS_Y 10.0f #define MENUHEADER_HEIGHT 1.6f #endif #define MENUHEADER_WIDTH 0.84f @@ -20,7 +20,7 @@ #define MENURADIO_ICON_SCALE 60.0f -#define MENUSLIDER_X 256.0f +#define MENUSLIDER_X 128.0f #define MENUSLIDER_UNK 256.0f #define BIGTEXT_X_SCALE 0.75f @@ -95,6 +95,7 @@ enum eLanguages #endif }; +/* enum eFrontendSprites { FE2_MAINPANEL_UL, @@ -128,29 +129,36 @@ enum eFrontendSprites NUM_FE_SPRITES }; +*/ enum eMenuSprites { - MENUSPRITE_CONNECTION, - MENUSPRITE_FINDGAME, - MENUSPRITE_HOSTGAME, - MENUSPRITE_MAINMENU, - MENUSPRITE_PLAYERSET, - MENUSPRITE_SINGLEPLAYER, - MENUSPRITE_MULTIPLAYER, - MENUSPRITE_DMALOGO, - MENUSPRITE_GTALOGO, - MENUSPRITE_RSTARLOGO, - MENUSPRITE_GAMESPY, + MENUSPRITE_BACKGROUND, + MENUSPRITE_VCLOGO, MENUSPRITE_MOUSE, - MENUSPRITE_MOUSET, - MENUSPRITE_MP3LOGO, + MENUSPRITE_MAPTOP01, + MENUSPRITE_MAPTOP02, + MENUSPRITE_MAPTOP03, + MENUSPRITE_MAPMID01, + MENUSPRITE_MAPMID02, + MENUSPRITE_MAPMID03, + MENUSPRITE_MAPBOT01, + MENUSPRITE_MAPBOT02, + MENUSPRITE_MAPBOT03, + MENUSPRITE_WILDSTYLE, + MENUSPRITE_FLASH, + MENUSPRITE_KCHAT, + MENUSPRITE_FEVER, + MENUSPRITE_VROCK, + MENUSPRITE_VCPR, + MENUSPRITE_ESPANTOSO, + MENUSPRITE_EMOTION, + MENUSPRITE_WAVE, + MENUSPRITE_MP3, MENUSPRITE_DOWNOFF, MENUSPRITE_DOWNON, MENUSPRITE_UPOFF, MENUSPRITE_UPON, - MENUSPRITE_GTA3LOGO, - MENUSPRITE_UNUSED, NUM_MENU_SPRITES }; @@ -509,8 +517,9 @@ public: char field_455; bool m_bStartWaitingForKeyBind; bool m_bSpritesLoaded; - CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES]; - CSprite2d m_aMenuSprites[NUM_MENU_SPRITES]; + //CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES]; + //CSprite2d m_aMenuSprites[NUM_MENU_SPRITES]; + CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES]; int32 field_518; int32 m_nMenuFadeAlpha; bool m_bPressedPgUpOnList; @@ -624,6 +633,8 @@ public: void LoadAllTextures(); void LoadSettings(); void MessageScreen(const char *); + // TODO(MIAMI): implement the second argument + void MessageScreen(const char *str, bool) { MessageScreen(str); } void PickNewPlayerColour(); void PrintBriefs(); static void PrintErrorMessage(); diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 33afc956..3f4a3217 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -84,11 +84,13 @@ #include "World.h" #include "ZoneCull.h" #include "Zones.h" +#include "Occlusion.h" #include "debugmenu.h" eLevelName CGame::currLevel; +int32 CGame::currArea; bool CGame::bDemoMode = true; bool CGame::nastyGame = true; bool CGame::frenchGame; @@ -251,7 +253,7 @@ bool CGame::Initialise(const char* datFile) strcpy(aDatFile, datFile); CPools::Initialise(); CIniFile::LoadIniFile(); - currLevel = LEVEL_INDUSTRIAL; + currLevel = LEVEL_BEACH; LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen()); gameTxdSlot = CTxdStore::AddTxdSlot("generic"); CTxdStore::Create(gameTxdSlot); @@ -271,6 +273,7 @@ bool CGame::Initialise(const char* datFile) ThePaths.AllocatePathFindInfoMem(4500); CWeather::Init(); CCullZones::Init(); + COcclusion::Init(); CCollision::Init(); CTheZones::Init(); CUserDisplay::Init(); @@ -306,7 +309,6 @@ bool CGame::Initialise(const char* datFile) CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; LoadingScreen("Loading the Game", "Setup streaming", nil); - CStreaming::Init(); CStreaming::LoadInitialVehicles(); CStreaming::LoadInitialPeds(); CStreaming::RequestBigBuildings(LEVEL_NONE); @@ -314,6 +316,7 @@ bool CGame::Initialise(const char* datFile) printf("Streaming uses %dK of its memory", CStreaming::ms_memoryUsed / 1024); LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen()); CAnimManager::LoadAnimFiles(); + CStreaming::LoadInitialWeapons(); CPed::Initialise(); CRouteNode::Initialise(); CEventList::Initialise(); @@ -354,10 +357,7 @@ bool CGame::Initialise(const char* datFile) CWaterCannons::Init(); CBridge::Init(); CGarages::Init(); - LoadingScreen("Loading the Game", "Position dynamic objects", nil); - CWorld::RepositionCertainDynamicObjects(); LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); - CCullZones::ResolveVisibilities(); CTrain::InitTrains(); CPlane::InitPlanes(); CCredits::Init(); @@ -368,7 +368,6 @@ bool CGame::Initialise(const char* datFile) CTheScripts::Process(); TheCamera.Process(); LoadingScreen("Loading the Game", "Load scene", nil); - CModelInfo::RemoveColModelsFromOtherLevels(currLevel); CCollision::ms_collisionInMemory = currLevel; for (int i = 0; i < MAX_PADS; i++) CPad::GetPad(i)->Clear(true); @@ -474,7 +473,6 @@ void CGame::ReInitGameObjectVariables(void) CSpecialFX::Init(); CWaterCannons::Init(); CParticle::ReloadConfig(); - CCullZones::ResolveVisibilities(); if ( !FrontEndMenuManager.m_bWantToLoad ) { @@ -506,8 +504,6 @@ void CGame::ReloadIPLs(void) CRoadBlocks::Init(); CCranes::InitCranes(); CGarages::Init(); - CWorld::RepositionCertainDynamicObjects(); - CCullZones::ResolveVisibilities(); CRenderer::SortBIGBuildings(); CTimer::Update(); } @@ -579,7 +575,7 @@ void CGame::InitialiseWhenRestarting(void) CTimer::Initialise(); FrontEndMenuManager.m_bWantToLoad = false; ReInitGameObjectVariables(); - currLevel = LEVEL_INDUSTRIAL; + currLevel = LEVEL_NONE; CCollision::SortOutCollisionAfterLoad(); } } @@ -668,6 +664,13 @@ void CGame::Process(void) } } +bool +CGame::CanSeeOutSideFromCurrArea(void) +{ + return currArea == AREA_MAIN_MAP || currArea == AREA_MALL || + currArea == AREA_MANSION || currArea == AREA_HOTEL; +} + void CGame::DrasticTidyUpMemory(bool) { #ifdef PS2 diff --git a/src/core/Game.h b/src/core/Game.h index 48f31abc..6efacf8d 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -3,15 +3,37 @@ enum eLevelName { LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel LEVEL_NONE = 0, - LEVEL_INDUSTRIAL, - LEVEL_COMMERCIAL, - LEVEL_SUBURBAN + LEVEL_BEACH, + LEVEL_MAINLAND +}; + +enum eAreaName { + AREA_MAIN_MAP, + AREA_HOTEL, + AREA_MANSION, + AREA_BANK, + AREA_MALL, + AREA_STRIP_CLUB, + AREA_LAWYERS, + AREA_COFFEE_SHOP, + AREA_CONCERT_HALL, + AREA_STUDIO, + AREA_RIFLE_RANGE, + AREA_BIKER_BAR, + AREA_POLICE_STATION, + AREA_EVERYWHERE, + AREA_DIRT, + AREA_BLOOD, + AREA_OVALRING, + AREA_MALIBU_CLUB, + AREA_PRINT_WORKS }; class CGame { public: static eLevelName currLevel; + static int32 currArea; static bool bDemoMode; static bool nastyGame; static bool frenchGame; @@ -36,9 +58,14 @@ public: static void ShutDownForRestart(void); static void InitialiseWhenRestarting(void); static void Process(void); + + static bool IsInInterior(void) { return currArea != AREA_MAIN_MAP; } + static bool CanSeeOutSideFromCurrArea(void); // NB: these do something on PS2 static void TidyUpMemory(bool, bool); static void DrasticTidyUpMemory(bool); static void ProcessTidyUpMemory(void); }; + +inline bool IsAreaVisible(int area) { return area == CGame::currArea || area == AREA_EVERYWHERE; } diff --git a/src/core/General.h b/src/core/General.h index 7ffa99de..3188d82b 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -145,4 +145,6 @@ public: static int32 GetRandomNumberInRange(int32 low, int32 high) { return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); } + static void SetRandomSeed(int32 seed) + { mysrand(seed); } }; diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 924d4724..ae7fcdb4 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -65,23 +65,42 @@ extern bool gbFastTime; void WeaponCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT2"), true); + + CStreaming::RequestModel(MI_GRENADE, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_BOMB, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_AK47, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_BASEBALL_BAT, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_COLT, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_ROCKETLAUNCHER, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SHOTGUN, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SNIPER, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_MP5, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0); FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_MP5, 100); FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20); FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200); FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5); FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR_GRENADE, 5); + + CStreaming::SetModelIsDeletable(MI_GRENADE); + CStreaming::SetModelIsDeletable(MI_BOMB); + CStreaming::SetModelIsDeletable(MI_AK47); + CStreaming::SetModelIsDeletable(MI_BASEBALL_BAT); + CStreaming::SetModelIsDeletable(MI_COLT); + CStreaming::SetModelIsDeletable(MI_ROCKETLAUNCHER); + CStreaming::SetModelIsDeletable(MI_SHOTGUN); + CStreaming::SetModelIsDeletable(MI_SNIPER); + CStreaming::SetModelIsDeletable(MI_MP5); } void HealthCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT3"), true); - FindPlayerPed()->m_fHealth = 100.0f; + FindPlayerPed()->m_fHealth = CWorld::Players[0].m_nMaxHealth; if (FindPlayerVehicle()) { FindPlayerVehicle()->m_fHealth = 1000.0f; if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR) @@ -140,9 +159,9 @@ void ChangePlayerCheat() do { do - modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1); + modelId = CGeneral::GetRandomNumberInRange(0, MI_WFYG2+1); while (!CModelInfo::GetModelInfo(modelId)); - } while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D); + } while (modelId == MI_TAXI_D); uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags; ped->DeleteRwObject(); @@ -205,7 +224,7 @@ void MoneyCheat() void ArmourCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT4"), true); - FindPlayerPed()->m_fArmour = 100.0f; + FindPlayerPed()->m_fArmour = CWorld::Players[0].m_nMaxArmour; } void WantedLevelUpCheat() @@ -273,6 +292,20 @@ void NastyLimbsCheat() { CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat; } + +void BlackCarsCheat() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + gbBlackCars = true; + gbPinkCars = false; +} + +void PinkCarsCheat() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + gbBlackCars = false; + gbPinkCars = true; +} ////////////////////////////////////////////////////////////////////////// #ifdef KANGAROO_CHEAT @@ -951,6 +984,14 @@ void CPad::AddToPCCheatString(char c) if ( !_CHEATCMP("TAEHCSBMILYTSAN") ) NastyLimbsCheat(); + // "IWANTITPAINTEDBLACK" + if ( !_CHEATCMP("KCALBDETNIAPTITNAWI") ) + BlackCarsCheat(); + + // "AHAIRDRESSERSCAR" + if ( !_CHEATCMP("RACSRESSERDRIAHA") ) + PinkCarsCheat(); + #ifdef KANGAROO_CHEAT // "KANGAROO" if (!_CHEATCMP("OORAGNAK")) @@ -2336,6 +2377,8 @@ void CPad::ResetCheats(void) CVehicle::bCheat3 = false; CVehicle::bCheat4 = false; CVehicle::bCheat5 = false; + gbBlackCars = false; + gbPinkCars = false; gbFastTime = false; CTimer::SetTimeScale(1.0f); diff --git a/src/core/Placeable.cpp b/src/core/Placeable.cpp index 69b3d3ea..6efc1540 100644 --- a/src/core/Placeable.cpp +++ b/src/core/Placeable.cpp @@ -7,8 +7,6 @@ CPlaceable::CPlaceable(void) m_matrix.SetScale(1.0f); } -CPlaceable::~CPlaceable(void) = default; - void CPlaceable::SetHeading(float angle) { diff --git a/src/core/Placeable.h b/src/core/Placeable.h index 970c0d48..22f7583c 100644 --- a/src/core/Placeable.h +++ b/src/core/Placeable.h @@ -9,7 +9,6 @@ public: CMatrix m_matrix; CPlaceable(void); - virtual ~CPlaceable(void); const CVector &GetPosition(void) { return m_matrix.GetPosition(); } void SetPosition(float x, float y, float z) { m_matrix.GetPosition().x = x; diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 487f536f..37a62adf 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -140,8 +140,10 @@ CPlayerInfo::Clear(void) m_nUpsideDownCounter = 0; m_bInfiniteSprint = false; m_bFastReload = false; + m_nMaxHealth = m_nMaxArmour = 100; m_bGetOutOfJailFree = false; m_bGetOutOfHospitalFree = false; + m_bDriveByAllowed = true; m_nPreviousTimeRewardedForExplosion = 0; m_nExplosionsSinceLastReward = 0; } @@ -171,7 +173,6 @@ void CPlayerInfo::MakePlayerSafe(bool toggle) { if (toggle) { - CTheScripts::ResetCountdownToMakePlayerUnsafe(); m_pPed->m_pWanted->m_bIgnoredByEveryone = true; CWorld::StopAllLawEnforcersInTheirTracks(); CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20; @@ -192,7 +193,8 @@ CPlayerInfo::MakePlayerSafe(bool toggle) CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); CReplay::DisableReplays(); - } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) { + } + else { m_pPed->m_pWanted->m_bIgnoredByEveryone = false; CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20; m_pPed->bBulletProof = false; @@ -348,7 +350,7 @@ CPlayerInfo::Process(void) bool startTaxiTimer = true; if (m_bUnusedTaxiThing && m_pPed->bInVehicle) { CVehicle *veh = m_pPed->m_pMyVehicle; - if ((veh->GetModelIndex() == MI_TAXI || veh->GetModelIndex() == MI_CABBIE || veh->GetModelIndex() == MI_BORGNINE) + if (veh->IsTaxi() && veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) { for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) { timePassed -= 1000; diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 94410753..ea9d563a 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -52,8 +52,12 @@ public: int32 field_272; bool m_bInfiniteSprint; bool m_bFastReload; + bool m_bFireproof; + uint8 m_nMaxHealth; + uint8 m_nMaxArmour; bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; + bool m_bDriveByAllowed; char m_aSkinName[32]; RwTexture *m_pSkinTexture; @@ -80,5 +84,3 @@ public: ~CPlayerInfo() { }; }; - -VALIDATE_SIZE(CPlayerInfo, 0x13C); diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index 17b9e08d..6838ef8e 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -499,8 +499,20 @@ INITSAVEBUF pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy; pPed->m_currentWeapon = 0; pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed; - for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) - pPed->m_weapons[i] = pBufferPlayer->m_weapons[i]; + for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { + if (pBufferPlayer->HasWeaponSlot(i)) { + int modelId = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModelId; + if (modelId != -1) { + CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY); + int modelId2 = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModel2Id; + if (modelId2 != -1) + CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY); + + CStreaming::LoadAllRequestedModels(false); + } + pPed->GiveWeapon(pBufferPlayer->GetWeapon(i).m_eWeaponType, pBufferPlayer->GetWeapon(i).m_nAmmoTotal); + } + } if (pedtype == PEDTYPE_PLAYER1) { pPed->m_wepAccuracy = 100; diff --git a/src/core/Pools.h b/src/core/Pools.h index b0ba6598..2f0537ff 100644 --- a/src/core/Pools.h +++ b/src/core/Pools.h @@ -4,7 +4,7 @@ #include "Lists.h" #include "Treadable.h" #include "Object.h" -#include "CutsceneHead.h" +#include "CutsceneObject.h" #include "PlayerPed.h" #include "Automobile.h" #include "DummyPed.h" @@ -16,7 +16,7 @@ typedef CPool<CPed,CPlayerPed> CPedPool; typedef CPool<CVehicle,CAutomobile> CVehiclePool; typedef CPool<CBuilding> CBuildingPool; typedef CPool<CTreadable> CTreadablePool; -typedef CPool<CObject, CCutsceneHead> CObjectPool; +typedef CPool<CObject, CCutsceneObject> CObjectPool; typedef CPool<CDummy, CDummyPed> CDummyPool; typedef CPool<cAudioScriptObject> CAudioScriptObjectPool; diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 9406f1bd..1267896a 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -21,49 +21,87 @@ sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS]; CVector2D vec2DRadarOrigin; int32 gRadarTxdIds[64]; -CSprite2d CRadar::AsukaSprite; -CSprite2d CRadar::BombSprite; -CSprite2d CRadar::CatSprite; CSprite2d CRadar::CentreSprite; -CSprite2d CRadar::CopcarSprite; -CSprite2d CRadar::DonSprite; -CSprite2d CRadar::EightSprite; -CSprite2d CRadar::ElSprite; -CSprite2d CRadar::IceSprite; -CSprite2d CRadar::JoeySprite; -CSprite2d CRadar::KenjiSprite; -CSprite2d CRadar::LizSprite; -CSprite2d CRadar::LuigiSprite; +CSprite2d CRadar::MapHereSprite; CSprite2d CRadar::NorthSprite; -CSprite2d CRadar::RaySprite; -CSprite2d CRadar::SalSprite; -CSprite2d CRadar::SaveSprite; +CSprite2d CRadar::AverySprite; +CSprite2d CRadar::BikerSprite; +CSprite2d CRadar::CortezSprite; +CSprite2d CRadar::DiazSprite; +CSprite2d CRadar::KentSprite; +CSprite2d CRadar::LawyerSprite; +CSprite2d CRadar::PhilSprite; +CSprite2d CRadar::BikersSprite; +CSprite2d CRadar::BoatyardSprite; +CSprite2d CRadar::MalibuClubSprite; +CSprite2d CRadar::CubansSprite; +CSprite2d CRadar::FilmSprite; +CSprite2d CRadar::GunSprite; +CSprite2d CRadar::HaitiansSprite; +CSprite2d CRadar::HardwareSprite; +CSprite2d CRadar::SaveHouseSprite; +CSprite2d CRadar::StripSprite; +CSprite2d CRadar::IceSprite; +CSprite2d CRadar::KCabsSprite; +CSprite2d CRadar::LovefistSprite; +CSprite2d CRadar::PrintworksSprite; +CSprite2d CRadar::PropertySprite; +CSprite2d CRadar::SunYardSprite; CSprite2d CRadar::SpraySprite; -CSprite2d CRadar::TonySprite; -CSprite2d CRadar::WeaponSprite; +CSprite2d CRadar::TShirtSprite; +CSprite2d CRadar::TommySprite; +CSprite2d CRadar::PhoneSprite; +CSprite2d CRadar::RadioWildstyleSprite; +CSprite2d CRadar::RadioFlashSprite; +CSprite2d CRadar::RadioKChatSprite; +CSprite2d CRadar::RadioFeverSprite; +CSprite2d CRadar::RadioVRockSprite; +CSprite2d CRadar::RadioVCPRSprite; +CSprite2d CRadar::RadioEspantosoSprite; +CSprite2d CRadar::RadioEmotionSprite; +CSprite2d CRadar::RadioWaveSprite; CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = { nil, - &AsukaSprite, - &BombSprite, - &CatSprite, &CentreSprite, - &CopcarSprite, - &DonSprite, - &EightSprite, - &ElSprite, - &IceSprite, - &JoeySprite, - &KenjiSprite, - &LizSprite, - &LuigiSprite, + &MapHereSprite, &NorthSprite, - &RaySprite, - &SalSprite, - &SaveSprite, + &AverySprite, + &BikerSprite, + &CortezSprite, + &DiazSprite, + &KentSprite, + &LawyerSprite, + &PhilSprite, + &BikersSprite, + &BoatyardSprite, + &MalibuClubSprite, + &CubansSprite, + &FilmSprite, + &GunSprite, + &HaitiansSprite, + &HardwareSprite, + &SaveHouseSprite, + &StripSprite, + &IceSprite, + &KCabsSprite, + &LovefistSprite, + &PrintworksSprite, + &PropertySprite, + &SunYardSprite, &SpraySprite, - &TonySprite, - &WeaponSprite + &TShirtSprite, + &TommySprite, + &PhoneSprite, + &RadioWildstyleSprite, + &RadioFlashSprite, + &RadioKChatSprite, + &RadioFeverSprite, + &RadioVRockSprite, + &RadioVCPRSprite, + &RadioEspantosoSprite, + &RadioEmotionSprite, + &RadioWaveSprite }; // Why this doesn't coincide with world coordinates i don't know @@ -87,12 +125,11 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not CRGBA CRadar::ArrowBlipColour1; CRGBA CRadar::ArrowBlipColour2; uint16 CRadar::MapLegendCounter; -uint16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; +int16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; int CRadar::TargetMarkerId = -1; CVector CRadar::TargetMarkerPos; #endif -// taken from VC float CRadar::cachedCos; float CRadar::cachedSin; @@ -273,12 +310,9 @@ void CRadar::ClearBlip(int32 i) if (index != -1) { SetRadarMarkerState(index, false); ms_RadarTrace[index].m_bInUse = false; -#ifndef MENU_MAP - // Ssshhh ms_RadarTrace[index].m_eBlipType = BLIP_NONE; ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER; ms_RadarTrace[index].m_eRadarSprite = RADAR_SPRITE_NONE; -#endif } } @@ -378,9 +412,8 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect) bool CRadar::DisplayThisBlip(int32 counter) { switch (ms_RadarTrace[counter].m_eRadarSprite) { - case RADAR_SPRITE_BOMB: case RADAR_SPRITE_SPRAY: - case RADAR_SPRITE_WEAPON: + case RADAR_SPRITE_GUN: return true; default: return false; @@ -481,11 +514,6 @@ void CRadar::DrawBlips() CEntity *blipEntity = nil; for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { -#ifdef MENU_MAP - // A little hack to reuse cleared blips in menu map. hehe - if (!CMenuManager::bMenuMapActive || ms_RadarTrace[blipId].m_eBlipType == BLIP_CAR || - ms_RadarTrace[blipId].m_eBlipType == BLIP_CHAR || ms_RadarTrace[blipId].m_eBlipType == BLIP_OBJECT) -#endif if (!ms_RadarTrace[blipId].m_bInUse) continue; @@ -493,8 +521,8 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON) { + if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE + || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) { switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: @@ -527,21 +555,24 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } else { -#ifdef TRIANGULAR_BLIPS - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + else { +#ifdef TRIANGULAR_BLIPS + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = blipEntity->GetPosition(); + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } } @@ -549,8 +580,8 @@ void CRadar::DrawBlips() break; case BLIP_COORD: case BLIP_CONTACT_POINT: - if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON) + if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE + || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); @@ -566,21 +597,24 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } else { -#ifdef TRIANGULAR_BLIPS - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + else { +#ifdef TRIANGULAR_BLIPS + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } } @@ -597,8 +631,8 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN) { switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: @@ -632,23 +666,25 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + else #ifdef TRIANGULAR_BLIPS - { - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = blipEntity->GetPosition(); + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } } @@ -664,8 +700,8 @@ void CRadar::DrawBlips() switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_COORD: case BLIP_CONTACT_POINT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); @@ -681,23 +717,25 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || CMenuManager::bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + else #ifdef TRIANGULAR_BLIPS - { - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } break; @@ -992,6 +1030,7 @@ CRadar::Initialise() ms_RadarTrace[i].m_BlipIndex = 1; SetRadarMarkerState(i, false); ms_RadarTrace[i].m_bInUse = false; + ms_RadarTrace[i].m_bShortRange = false; ms_RadarTrace[i].m_eBlipType = BLIP_NONE; ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER; ms_RadarTrace[i].m_eRadarSprite = RADAR_SPRITE_NONE; @@ -1036,26 +1075,45 @@ CRadar::LoadTextures() { CTxdStore::PushCurrentTxd(); CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("hud")); - AsukaSprite.SetTexture("radar_asuka"); - BombSprite.SetTexture("radar_bomb"); - CatSprite.SetTexture("radar_cat"); CentreSprite.SetTexture("radar_centre"); - CopcarSprite.SetTexture("radar_copcar"); - DonSprite.SetTexture("radar_don"); - EightSprite.SetTexture("radar_eight"); - ElSprite.SetTexture("radar_el"); - IceSprite.SetTexture("radar_ice"); - JoeySprite.SetTexture("radar_joey"); - KenjiSprite.SetTexture("radar_kenji"); - LizSprite.SetTexture("radar_liz"); - LuigiSprite.SetTexture("radar_luigi"); + MapHereSprite.SetTexture("arrow"); NorthSprite.SetTexture("radar_north"); - RaySprite.SetTexture("radar_ray"); - SalSprite.SetTexture("radar_sal"); - SaveSprite.SetTexture("radar_save"); - SpraySprite.SetTexture("radar_spray"); - TonySprite.SetTexture("radar_tony"); - WeaponSprite.SetTexture("radar_weapon"); + AverySprite.SetTexture("radar_avery"); + BikerSprite.SetTexture("radar_biker"); + CortezSprite.SetTexture("radar_cortez"); + DiazSprite.SetTexture("radar_diaz"); + KentSprite.SetTexture("radar_kent"); + LawyerSprite.SetTexture("radar_lawyer"); + PhilSprite.SetTexture("radar_phil"); + BikersSprite.SetTexture("bikers"); + BoatyardSprite.SetTexture("boatyard"); + MalibuClubSprite.SetTexture("club"); + CubansSprite.SetTexture("cubans"); + FilmSprite.SetTexture("filmstudio"); + GunSprite.SetTexture("gun"); + HaitiansSprite.SetTexture("haitians"); + HardwareSprite.SetTexture("hardware"); + SaveHouseSprite.SetTexture("radar_save"); + StripSprite.SetTexture("radar_strip"); + IceSprite.SetTexture("icecream"); + KCabsSprite.SetTexture("kcabs"); + LovefistSprite.SetTexture("lovefist"); + PrintworksSprite.SetTexture("printworks"); + PropertySprite.SetTexture("property"); + SunYardSprite.SetTexture("SunYard"); + SpraySprite.SetTexture("spray"); + TShirtSprite.SetTexture("tshirt"); + TommySprite.SetTexture("tommy"); + PhoneSprite.SetTexture("phone"); + RadioWildstyleSprite.SetTexture("RWildstyle"); + RadioFlashSprite.SetTexture("RFlash"); + RadioKChatSprite.SetTexture("RKchat"); + RadioFeverSprite.SetTexture("RFever"); + RadioVRockSprite.SetTexture("RVRock"); + RadioVCPRSprite.SetTexture("RVCPR"); + RadioEspantosoSprite.SetTexture("REspantoso"); + RadioEmotionSprite.SetTexture("REmotion"); + RadioWaveSprite.SetTexture("RWave"); CTxdStore::PopCurrentTxd(); } @@ -1102,8 +1160,9 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay } ms_RadarTrace[nextBlip].m_eBlipType = type; ms_RadarTrace[nextBlip].m_nColor = color; - ms_RadarTrace[nextBlip].m_bDim = 1; - ms_RadarTrace[nextBlip].m_bInUse = 1; + ms_RadarTrace[nextBlip].m_bDim = true; + ms_RadarTrace[nextBlip].m_bInUse = true; + ms_RadarTrace[nextBlip].m_bShortRange = false; ms_RadarTrace[nextBlip].m_Radius = 1.0f; ms_RadarTrace[nextBlip].m_vec2DPos = pos; ms_RadarTrace[nextBlip].m_vecPos = pos; @@ -1114,6 +1173,15 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay return CRadar::GetNewUniqueBlipIndex(nextBlip); } +int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display) +{ + int index = SetCoordBlip(type, pos, color, display); + if (index == -1) + return -1; + ms_RadarTrace[GetActualBlipArrayIndex(index)].m_bShortRange = true; + return index; +} + int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display) { int nextBlip; @@ -1123,8 +1191,9 @@ int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDispla } ms_RadarTrace[nextBlip].m_eBlipType = type; ms_RadarTrace[nextBlip].m_nColor = color; - ms_RadarTrace[nextBlip].m_bDim = 1; - ms_RadarTrace[nextBlip].m_bInUse = 1; + ms_RadarTrace[nextBlip].m_bDim = true; + ms_RadarTrace[nextBlip].m_bInUse = true; + ms_RadarTrace[nextBlip].m_bShortRange = false; ms_RadarTrace[nextBlip].m_Radius = 1.0f; ms_RadarTrace[nextBlip].m_nEntityHandle = handle; ms_RadarTrace[nextBlip].m_wScale = 1; @@ -1226,26 +1295,45 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, void CRadar::Shutdown() { - AsukaSprite.Delete(); - BombSprite.Delete(); - CatSprite.Delete(); CentreSprite.Delete(); - CopcarSprite.Delete(); - DonSprite.Delete(); - EightSprite.Delete(); - ElSprite.Delete(); - IceSprite.Delete(); - JoeySprite.Delete(); - KenjiSprite.Delete(); - LizSprite.Delete(); - LuigiSprite.Delete(); + MapHereSprite.Delete(); NorthSprite.Delete(); - RaySprite.Delete(); - SalSprite.Delete(); - SaveSprite.Delete(); + AverySprite.Delete(); + BikerSprite.Delete(); + CortezSprite.Delete(); + DiazSprite.Delete(); + KentSprite.Delete(); + LawyerSprite.Delete(); + PhilSprite.Delete(); + BikersSprite.Delete(); + BoatyardSprite.Delete(); + MalibuClubSprite.Delete(); + CubansSprite.Delete(); + FilmSprite.Delete(); + GunSprite.Delete(); + HaitiansSprite.Delete(); + HardwareSprite.Delete(); + SaveHouseSprite.Delete(); + StripSprite.Delete(); + IceSprite.Delete(); + KCabsSprite.Delete(); + LovefistSprite.Delete(); + PrintworksSprite.Delete(); + PropertySprite.Delete(); + SunYardSprite.Delete(); SpraySprite.Delete(); - TonySprite.Delete(); - WeaponSprite.Delete(); + TShirtSprite.Delete(); + TommySprite.Delete(); + PhoneSprite.Delete(); + RadioWildstyleSprite.Delete(); + RadioFlashSprite.Delete(); + RadioKChatSprite.Delete(); + RadioFeverSprite.Delete(); + RadioVRockSprite.Delete(); + RadioVCPRSprite.Delete(); + RadioEspantosoSprite.Delete(); + RadioEmotionSprite.Delete(); + RadioWaveSprite.Delete(); RemoveRadarSections(); } @@ -1316,9 +1404,8 @@ void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &i { #ifdef MENU_MAP if (CMenuManager::bMenuMapActive) { - // fMapSize is actually half map size. Radar range is 1000, so if x is -2000, in.x + 2.0f is 0. - out.x = (CMenuManager::fMapCenterX - CMenuManager::fMapSize) + (in.x + 2.0f) * CMenuManager::fMapSize * 2.0f / 4.0f; - out.y = (CMenuManager::fMapCenterY - CMenuManager::fMapSize) + (2.0f - in.y) * CMenuManager::fMapSize * 2.0f / 4.0f; + out.x = (CMenuManager::fMapCenterX - CMenuManager::fMapSize) + (MENU_MAP_LENGTH / 2 + MENU_MAP_LEFT_OFFSET + in.x) * CMenuManager::fMapSize * MENU_MAP_WIDTH_SCALE * 2.0f / MENU_MAP_LENGTH; + out.y = (CMenuManager::fMapCenterY - CMenuManager::fMapSize) + (MENU_MAP_LENGTH / 2 - MENU_MAP_TOP_OFFSET - in.y) * CMenuManager::fMapSize * MENU_MAP_HEIGHT_SCALE * 2.0f / MENU_MAP_LENGTH; } else #endif { @@ -1406,7 +1493,7 @@ CRadar::InitFrontEndMap() CalculateCachedSinCos(); vec2DRadarOrigin.x = 0.0f; vec2DRadarOrigin.y = 0.0f; - m_radarRange = 1000.0f; // doesn't mean anything, just affects the calculation in TransformRadarPointToScreenSpace + m_radarRange = MENU_MAP_LENGTH_UNIT; // just affects the multiplier in TransformRadarPointToScreenSpace for (int i = 0; i < NUM_MAP_LEGENDS; i++) { MapLegendList[i] = RADAR_SPRITE_NONE; } diff --git a/src/core/Radar.h b/src/core/Radar.h index ec2bacd0..f68d290c 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -1,6 +1,13 @@ #pragma once #include "Sprite2d.h" +#define MENU_MAP_LENGTH_UNIT 1190.0f // in game unit +#define MENU_MAP_WIDTH_SCALE 1.112f // in game unit (originally 1.112494151260504f) +#define MENU_MAP_HEIGHT_SCALE 1.119f // in game unit (originally 1.118714268907563f) +#define MENU_MAP_TOP_OFFSET 0.28f // in length unit defined above - ~333 game unit +#define MENU_MAP_LEFT_OFFSET 0.185f // in length unit defined above - ~220 game unit +#define MENU_MAP_LENGTH (4000.f / MENU_MAP_LENGTH_UNIT) + enum eBlipType { BLIP_NONE, @@ -26,26 +33,46 @@ enum eRadarSprite RADAR_SPRITE_COORD_BLIP = -1, #endif RADAR_SPRITE_NONE = 0, - RADAR_SPRITE_ASUKA, - RADAR_SPRITE_BOMB, - RADAR_SPRITE_CAT, RADAR_SPRITE_CENTRE, - RADAR_SPRITE_COPCAR, - RADAR_SPRITE_DON, - RADAR_SPRITE_EIGHT, - RADAR_SPRITE_EL, - RADAR_SPRITE_ICE, - RADAR_SPRITE_JOEY, - RADAR_SPRITE_KENJI, - RADAR_SPRITE_LIZ, - RADAR_SPRITE_LUIGI, + RADAR_SPRITE_MAP_HERE, RADAR_SPRITE_NORTH, - RADAR_SPRITE_RAY, - RADAR_SPRITE_SAL, + RADAR_SPRITE_AVERY, + RADAR_SPRITE_BIKER, + RADAR_SPRITE_CORTEZ, + RADAR_SPRITE_DIAZ, + RADAR_SPRITE_KENT, + RADAR_SPRITE_LAWYER, + RADAR_SPRITE_PHIL, + RADAR_SPRITE_BIKERS, + RADAR_SPRITE_BOATYARD, + RADAR_SPRITE_MALIBU_CLUB, + RADAR_SPRITE_CUBANS, + RADAR_SPRITE_FILM, + RADAR_SPRITE_GUN, + RADAR_SPRITE_HAITIANS, + RADAR_SPRITE_HARDWARE, RADAR_SPRITE_SAVE, + RADAR_SPRITE_STRIP, + RADAR_SPRITE_ICE, + RADAR_SPRITE_KCABS, + RADAR_SPRITE_LOVEFIST, + RADAR_SPRITE_PRINTWORKS, + RADAR_SPRITE_PROPERTY, + RADAR_SPRITE_SUNYARD, RADAR_SPRITE_SPRAY, - RADAR_SPRITE_TONY, - RADAR_SPRITE_WEAPON, + RADAR_SPRITE_TSHIRT, + RADAR_SPRITE_TOMMY, + RADAR_SPRITE_PHONE, + RADAR_SPRITE_RADIO_WILDSTYLE, + RADAR_SPRITE_RADIO_FLASH, + RADAR_SPRITE_RADIO_KCHAT, + RADAR_SPRITE_RADIO_FEVER, + RADAR_SPRITE_RADIO_VROCK, + RADAR_SPRITE_RADIO_VCPR, + RADAR_SPRITE_RADIO_ESPANTOSO, + RADAR_SPRITE_RADIO_EMOTION, + RADAR_SPRITE_RADIO_WAVE, + RADAR_SPRITE_COUNT }; @@ -66,12 +93,12 @@ struct sRadarTrace uint16 m_BlipIndex; bool m_bDim; bool m_bInUse; + bool m_bShortRange; float m_Radius; int16 m_wScale; uint16 m_eBlipDisplay; // eBlipDisplay uint16 m_eRadarSprite; // eRadarSprite }; -VALIDATE_SIZE(sRadarTrace, 0x30); // Values for screen space #define RADAR_LEFT (40.0f) @@ -84,26 +111,45 @@ class CRadar public: static float m_radarRange; static sRadarTrace ms_RadarTrace[NUMRADARBLIPS]; - static CSprite2d AsukaSprite; - static CSprite2d BombSprite; - static CSprite2d CatSprite; static CSprite2d CentreSprite; - static CSprite2d CopcarSprite; - static CSprite2d DonSprite; - static CSprite2d EightSprite; - static CSprite2d ElSprite; - static CSprite2d IceSprite; - static CSprite2d JoeySprite; - static CSprite2d KenjiSprite; - static CSprite2d LizSprite; - static CSprite2d LuigiSprite; + static CSprite2d MapHereSprite; static CSprite2d NorthSprite; - static CSprite2d RaySprite; - static CSprite2d SalSprite; - static CSprite2d SaveSprite; + static CSprite2d AverySprite; + static CSprite2d BikerSprite; + static CSprite2d CortezSprite; + static CSprite2d DiazSprite; + static CSprite2d KentSprite; + static CSprite2d LawyerSprite; + static CSprite2d PhilSprite; + static CSprite2d BikersSprite; + static CSprite2d BoatyardSprite; + static CSprite2d MalibuClubSprite; + static CSprite2d CubansSprite; + static CSprite2d FilmSprite; + static CSprite2d GunSprite; + static CSprite2d HaitiansSprite; + static CSprite2d HardwareSprite; + static CSprite2d SaveHouseSprite; + static CSprite2d StripSprite; + static CSprite2d IceSprite; + static CSprite2d KCabsSprite; + static CSprite2d LovefistSprite; + static CSprite2d PrintworksSprite; + static CSprite2d PropertySprite; + static CSprite2d SunYardSprite; static CSprite2d SpraySprite; - static CSprite2d TonySprite; - static CSprite2d WeaponSprite; + static CSprite2d TShirtSprite; + static CSprite2d TommySprite; + static CSprite2d PhoneSprite; + static CSprite2d RadioWildstyleSprite; + static CSprite2d RadioFlashSprite; + static CSprite2d RadioKChatSprite; + static CSprite2d RadioFeverSprite; + static CSprite2d RadioVRockSprite; + static CSprite2d RadioVCPRSprite; + static CSprite2d RadioEspantosoSprite; + static CSprite2d RadioEmotionSprite; + static CSprite2d RadioWaveSprite; static CSprite2d *RadarSprites[RADAR_SPRITE_COUNT]; static float cachedCos; static float cachedSin; @@ -111,7 +157,7 @@ public: #define NUM_MAP_LEGENDS 75 static CRGBA ArrowBlipColour1; static CRGBA ArrowBlipColour2; - static uint16 MapLegendList[NUM_MAP_LEGENDS]; + static int16 MapLegendList[NUM_MAP_LEGENDS]; static uint16 MapLegendCounter; static int TargetMarkerId; static CVector TargetMarkerPos; @@ -149,6 +195,7 @@ public: static void SetBlipSprite(int32 i, int32 icon); static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay); + static int32 SetShortRangeCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); static void SetRadarMarkerState(int32 i, bool flag); static void ShowRadarMarker(CVector pos, uint32 color, float radius); static void ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha); diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index 99274e04..32148476 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -58,6 +58,11 @@ int32 CStats::CarsCrushed; int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES]; int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES]; +int32 CStats::Sprayings; +float CStats::AutoPaintingBudget; +int32 CStats::NoMoreHurricanes; +float CStats::FashionBudget; + void CStats::Init() { PeopleKilledByOthers = 0; @@ -113,6 +118,10 @@ void CStats::Init() IndustrialPassed = 0; CommercialPassed = 0; SuburbanPassed = 0; + + Sprayings = 0; + AutoPaintingBudget = 0.0f; + NoMoreHurricanes = 0; } void CStats::RegisterFastestTime(int32 index, int32 time) @@ -241,6 +250,19 @@ int32 CStats::FindCriminalRatingNumber() return rating; } +float CStats::GetPercentageProgress() +{ + float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : + CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f)); + + return Min(percentCompleted, 100.0f); +} + +void CStats::MoneySpentOnFashion(int32 money) +{ + FashionBudget += money; +} + void CStats::SaveStats(uint8 *buf, uint32 *size) { CheckPointReachedSuccessfully(); diff --git a/src/core/Stats.h b/src/core/Stats.h index 4445ecf4..67ee86f7 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -62,6 +62,10 @@ public: static int32 CarsCrushed; static int32 FastestTimes[TOTAL_FASTEST_TIMES]; static int32 HighestScores[TOTAL_HIGHEST_SCORES]; + static int32 Sprayings; + static float AutoPaintingBudget; + static int32 NoMoreHurricanes; + static float FashionBudget; public: static void Init(void); @@ -87,4 +91,7 @@ public: static int32 FindCriminalRatingNumber(); static void SaveStats(uint8 *buf, uint32 *size); static void LoadStats(uint8 *buf, uint32 size); + static float GetPercentageProgress(); + + static void MoneySpentOnFashion(int32); }; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index c961f53d..0ce8b50e 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -18,7 +18,6 @@ #include "FileMgr.h" #include "FileLoader.h" #include "Zones.h" -#include "ZoneCull.h" #include "Radar.h" #include "Camera.h" #include "Record.h" @@ -28,10 +27,10 @@ #include "CutsceneMgr.h" #include "CdStream.h" #include "Streaming.h" -#ifdef FIX_BUGS #include "Replay.h" -#endif #include "main.h" +#include "ColStore.h" +#include "DMAudio.h" bool CStreaming::ms_disableStreaming; bool CStreaming::ms_bLoadingBigModel; @@ -51,9 +50,9 @@ int32 CStreaming::ms_channelError; int32 CStreaming::ms_numVehiclesLoaded; int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED]; int32 CStreaming::ms_lastVehicleDeleted; +bool CStreaming::ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP]; CDirectory *CStreaming::ms_pExtraObjectsDir; int32 CStreaming::ms_numPriorityRequests; -bool CStreaming::ms_hasLoadedLODs; int32 CStreaming::ms_currentPedGrp; int32 CStreaming::ms_currentPedLoading; int32 CStreaming::ms_lastCullZone; @@ -66,17 +65,12 @@ uint32 CStreaming::ms_memoryAvailable; int32 desiredNumVehiclesLoaded = 12; -CEntity *pIslandLODindustEntity; -CEntity *pIslandLODcomIndEntity; -CEntity *pIslandLODcomSubEntity; -CEntity *pIslandLODsubIndEntity; -CEntity *pIslandLODsubComEntity; -int32 islandLODindust; -int32 islandLODcomInd; -int32 islandLODcomSub; -int32 islandLODsubInd; -int32 islandLODsubCom; +CEntity *pIslandLODmainlandEntity; +CEntity *pIslandLODbeachEntity; +int32 islandLODmainland; +int32 islandLODbeach; +//--MIAMI: done bool CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size) { @@ -87,6 +81,7 @@ CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size) return true; } +//--MIAMI: done void CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size) { @@ -94,6 +89,7 @@ CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size) m_size = size; } +//--MIAMI: done void CStreamingInfo::AddToList(CStreamingInfo *link) { @@ -104,6 +100,7 @@ CStreamingInfo::AddToList(CStreamingInfo *link) m_next->m_prev = this; } +//--MIAMI: done void CStreamingInfo::RemoveFromList(void) { @@ -113,6 +110,7 @@ CStreamingInfo::RemoveFromList(void) m_prev = nil; } +//--MIAMI: done void CStreaming::Init2(void) { @@ -182,13 +180,15 @@ CStreaming::Init2(void) ms_vehiclesLoaded[i] = -1; ms_numVehiclesLoaded = 0; + for(i = 0; i < ARRAY_SIZE(ms_bIsPedFromPedGroupLoaded); i++) + ms_bIsPedFromPedGroupLoaded[i] = false; + ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE); ms_numPriorityRequests = 0; - ms_hasLoadedLODs = true; ms_currentPedGrp = -1; ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone ms_loadedGangs = 0; - ms_currentPedLoading = 8; // unused, whatever it is + ms_currentPedLoading = NUMMODELSPERPEDGROUP; // unused, whatever it is LoadCdDirectory(); @@ -199,48 +199,20 @@ CStreaming::Init2(void) ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; debug("Streaming buffer size is %d sectors", ms_streamingBufferSize); - // PC only, figure out how much memory we got -#ifdef GTA_PC #define MB (1024*1024) - extern unsigned long _dwMemAvailPhys; - ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2; - if(ms_memoryAvailable < 50*MB) - ms_memoryAvailable = 50*MB; - desiredNumVehiclesLoaded = (ms_memoryAvailable/MB - 50)/3 + 12; - if(desiredNumVehiclesLoaded > MAXVEHICLESLOADED) - desiredNumVehiclesLoaded = MAXVEHICLESLOADED; + ms_memoryAvailable = 65*MB; + desiredNumVehiclesLoaded = 25; debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable/MB); #undef MB -#endif // find island LODs - pIslandLODindustEntity = nil; - pIslandLODcomIndEntity = nil; - pIslandLODcomSubEntity = nil; - pIslandLODsubIndEntity = nil; - pIslandLODsubComEntity = nil; - islandLODindust = -1; - islandLODcomInd = -1; - islandLODcomSub = -1; - islandLODsubInd = -1; - islandLODsubCom = -1; - CModelInfo::GetModelInfo("IslandLODInd", &islandLODindust); - CModelInfo::GetModelInfo("IslandLODcomIND", &islandLODcomInd); - CModelInfo::GetModelInfo("IslandLODcomSUB", &islandLODcomSub); - CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd); - CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom); - - 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; - } + pIslandLODmainlandEntity = nil; + pIslandLODbeachEntity = nil; + islandLODmainland = -1; + islandLODbeach = -1; + CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland); + CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach); } void @@ -266,6 +238,7 @@ CStreaming::Init(void) #endif } +//--MIAMI: done void CStreaming::Shutdown(void) { @@ -275,10 +248,10 @@ CStreaming::Shutdown(void) delete ms_pExtraObjectsDir; } +//--MIAMI: done void CStreaming::Update(void) { - CEntity *train; CStreamingInfo *si, *prev; bool requestedSubway = false; @@ -292,31 +265,32 @@ CStreaming::Update(void) if(CTimer::GetIsPaused()) return; - train = FindPlayerTrain(); - if(train && train->GetPosition().z < 0.0f){ - RequestSubway(); - requestedSubway = true; - }else if(!ms_disableStreaming) + LoadBigBuildingsWhenNeeded(); + if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f) AddModelsToRequestList(TheCamera.GetPosition()); DeleteFarAwayRwObjects(TheCamera.GetPosition()); if(!ms_disableStreaming && - !CCutsceneMgr::IsRunning() && - !requestedSubway && - !CGame::playingIntro && + !CCutsceneMgr::IsCutsceneProcessing() && ms_numModelsRequested < 5 && - !CRenderer::m_loadingPriority -#ifdef FIX_BUGS - && !CReplay::IsPlayingBack() -#endif - ){ + !CRenderer::m_loadingPriority && + CGame::currArea == AREA_MAIN_MAP && + !CReplay::IsPlayingBack()){ StreamVehiclesAndPeds(); StreamZoneModels(FindPlayerCoors()); } LoadRequestedModels(); + 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()); + } for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){ prev = si->m_prev; @@ -325,6 +299,7 @@ CStreaming::Update(void) } } +//--MIAMI: done void CStreaming::LoadCdDirectory(void) { @@ -338,12 +313,6 @@ CStreaming::LoadCdDirectory(void) ms_imageOffsets[3] = -1; ms_imageOffsets[4] = -1; ms_imageOffsets[5] = -1; - ms_imageOffsets[6] = -1; - ms_imageOffsets[7] = -1; - ms_imageOffsets[8] = -1; - ms_imageOffsets[9] = -1; - ms_imageOffsets[10] = -1; - ms_imageOffsets[11] = -1; ms_imageSize = GetGTA3ImgSize(); // PS2 uses CFileMgr::GetCdFile on all IMG files to fill the array #endif @@ -359,12 +328,12 @@ CStreaming::LoadCdDirectory(void) ms_imageSize /= CDSTREAM_SECTOR_SIZE; } +//--MIAMI: done void CStreaming::LoadCdDirectory(const char *dirname, int n) { int fd, lastID, imgSelector; - int modelId, txdId; - uint32 posn, size; + int modelId; CDirectory::DirectoryInfo direntry; char *dot; @@ -375,23 +344,23 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) imgSelector = n<<24; assert(sizeof(direntry) == 32); while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){ - dot = strchr(direntry.name, '.'); - if(dot) *dot = '\0'; + 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::faststrcmp(dot+1, "DFF") || !CGeneral::faststrcmp(dot+1, "dff")){ + if(strncasecmp(dot+1, "DFF", 3) == 0){ if(CModelInfo::GetModelInfo(direntry.name, &modelId)){ - if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){ - debug("%s appears more than once in %s\n", direntry.name, 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; - } + bAddToStreaming = true; }else{ #ifdef FIX_BUGS // remember which cdimage this came from @@ -401,27 +370,63 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) #endif lastID = -1; } - }else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){ - txdId = CTxdStore::FindTxdSlot(direntry.name); - if(txdId == -1) - txdId = CTxdStore::AddTxdSlot(direntry.name); - if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){ - debug("%s appears more than once in %s\n", direntry.name, dirname); + }else if(strncasecmp(dot+1, "TXD", 3) == 0){ + modelId = CTxdStore::FindTxdSlot(direntry.name); + if(modelId == -1) + modelId = CTxdStore::AddTxdSlot(direntry.name); + modelId += STREAM_OFFSET_TXD; + bAddToStreaming = true; + }else if(strncasecmp(dot+1, "COL", 3) == 0){ + modelId = CColStore::FindColSlot(direntry.name); + if(modelId == -1) + modelId = CColStore::AddColSlot(direntry.name); + modelId += STREAM_OFFSET_COL; + bAddToStreaming = true; + }else if(strncasecmp(dot+1, "IFP", 3) == 0){ + modelId = CAnimManager::RegisterAnimBlock(direntry.name); + modelId += STREAM_OFFSET_ANIM; + bAddToStreaming = true; + }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[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size); + ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size); if(lastID != -1) - ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD; - lastID = txdId + STREAM_OFFSET_TXD; + ms_aInfoForModel[lastID].m_nextID = modelId; + lastID = modelId; } - }else - lastID = -1; + } } CFileMgr::CloseFile(fd); } +static char* +GetObjectName(int streamId) +{ + 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 < STREAM_OFFSET_ANIM) + sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL)); + else{ + assert(streamId < NUMSTREAMINFO); + sprintf(objname, "%s.ifp", CAnimManager::GetAnimationBlock(streamId-STREAM_OFFSET_ANIM)->name); + } + return objname; +} + + +//--MIAMI: done bool CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) { @@ -443,22 +448,25 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) // Model mi = CModelInfo::GetModelInfo(streamId); - // Txd has to be loaded - if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil){ - debug("failed to load %s because TXD %s is not in memory\n", mi->GetName(), CTxdStore::GetTxdName(mi->GetTxdSlot())); + // Txd and anim have to be loaded + int animId = mi->GetAnimFileIndex(); + if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil || + animId != -1 && !CAnimManager::GetAnimationBlock(animId)->isLoaded){ RemoveModel(streamId); - RemoveTxd(mi->GetTxdSlot()); ReRequestModel(streamId); RwStreamClose(stream, &mem); return false; } - // Set Txd to use + // Set Txd and anims to use CTxdStore::AddRef(mi->GetTxdSlot()); + if(animId != -1) + CAnimManager::AddAnimBlockRef(animId); CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); if(mi->IsSimple()){ success = CFileLoader::LoadAtomicFile(stream, streamId); + // TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that } else if (mi->GetModelType() == MITYPE_VEHICLE) { // load vehicles in two parts CModelInfo::GetModelInfo(streamId)->AddRef(); @@ -470,9 +478,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) } UpdateMemoryUsed(); - // Txd no longer needed unless we only read part of the file - if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED) + // Txd and anims no longer needed unless we only read part of the file + if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){ CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); + if(animId != -1) + CAnimManager::RemoveAnimBlockRefWithoutDelete(animId); + } if(!success){ debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName()); @@ -481,9 +492,8 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } - }else{ + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // Txd - assert(streamId < NUMSTREAMINFO); if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 && !IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){ RemoveModel(streamId); @@ -506,20 +516,28 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } + }else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){ + 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; + } + }else if(streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 && + !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){ + RemoveModel(streamId); + RwStreamClose(stream, &mem); + return false; + } + CAnimManager::LoadAnimFile(stream, true, nil); + CAnimManager::CreateAnimAssocGroups(); } RwStreamClose(stream, &mem); - // We shouldn't even end up here unless load was successful - if(!success){ - ReRequestModel(streamId); - if(streamId < STREAM_OFFSET_TXD) - debug("Failed to load %s.dff\n", mi->GetName()); - else - debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD)); - return false; - } - if(streamId < STREAM_OFFSET_TXD){ // Model // Vehicles and Peds not in loaded list @@ -534,12 +552,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) smi->m_alpha = 0; } - if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) + if(CanRemoveModel(streamId)) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); } - }else{ - // Txd - if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL || + streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + // Txd and anims + if(CanRemoveModel(streamId)) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); } @@ -551,17 +571,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); timeDiff = endTime - startTime; - if(timeDiff > 5){ - 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); - } + if(timeDiff > 5) + debug("%s took %d ms\n", GetObjectName(streamId), timeDiff); return true; } - +//--MIAMI: done bool CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) { @@ -592,11 +608,15 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) success = AddToLoadedVehiclesList(streamId); mi->RemoveRef(); CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); - }else{ + if(mi->GetAnimFileIndex() != -1) + CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex()); + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // Txd CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD); success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream); CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD); + }else{ + assert(0 && "invalid streamId"); } RwStreamClose(stream, &mem); @@ -614,16 +634,13 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); timeDiff = endTime - startTime; - if(timeDiff > 5){ - if(streamId < STREAM_OFFSET_TXD) - debug("finish model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff); - else - debug("finish txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); - } + if(timeDiff > 5) + debug("%s took %d ms\n", GetObjectName(streamId), timeDiff); return true; } +//--MIAMI: done void CStreaming::RequestModel(int32 id, int32 flags) { @@ -652,15 +669,20 @@ 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_CANT_REMOVE) == 0) + if(CanRemoveModel(id)) ms_aInfoForModel[id].AddToList(&ms_startLoadedList); } }else if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED || ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ // how can this be true again? if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED){ - if(id < STREAM_OFFSET_TXD) - RequestTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot(), flags); + if(id < STREAM_OFFSET_TXD){ + mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); + RequestTxd(mi->GetTxdSlot(), flags); + int anim = mi->GetAnimFileIndex(); + if(anim != -1) + RequestAnim(anim, STREAMFLAGS_DEPENDENCY); + } ms_aInfoForModel[id].AddToList(&ms_startRequestedList); ms_numModelsRequested++; if(flags & STREAMFLAGS_PRIORITY) @@ -672,52 +694,28 @@ CStreaming::RequestModel(int32 id, int32 flags) } } +#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE + +//--MIAMI: done void -CStreaming::RequestSubway(void) -{ - RequestModel(MI_SUBWAY1, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY2, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY3, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY4, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY5, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY6, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY7, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY8, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY9, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY10, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY11, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY12, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY13, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY14, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY15, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY16, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY17, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY18, STREAMFLAGS_NOFADE); - - switch(CGame::currLevel){ - case LEVEL_INDUSTRIAL: - RequestModel(MI_SUBPLATFORM_IND, STREAMFLAGS_NOFADE); - break; - case LEVEL_COMMERCIAL: - if(FindPlayerTrain()->GetPosition().y < -700.0f){ - RequestModel(MI_SUBPLATFORM_COMS, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBPLATFORM_COMS2, STREAMFLAGS_NOFADE); - }else{ - RequestModel(MI_SUBPLATFORM_COMN, STREAMFLAGS_NOFADE); - } - break; - case LEVEL_SUBURBAN: - RequestModel(MI_SUBPLATFORM_SUB, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBPLATFORM_SUB2, STREAMFLAGS_NOFADE); - break; - default: break; +CStreaming::RequestBigBuildings(eLevelName level) +{ + 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) + RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } + RequestIslands(level); } -#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY - +//--MIAMI: done void -CStreaming::RequestBigBuildings(eLevelName level) +CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos) { int i, n; CBuilding *b; @@ -726,32 +724,91 @@ 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(), BIGBUILDINGFLAGS); + if(b->bStreamBIGBuilding){ + if(CRenderer::ShouldModelBeStreamed(b, pos)) + RequestModel(b->GetModelIndex(), 0); + }else + RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } RequestIslands(level); - ms_hasLoadedLODs = false; } +//--MIAMI: done +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, pos)) + b->CreateRwObject(); + } +} + +//--MIAMI: done +void +CStreaming::InstanceLoadedModelsInSectorList(CPtrList &list) +{ + CPtrNode *node; + CEntity *e; + for(node = list.first; node; node = node->next) { + e = (CEntity *)node->item; + if(IsAreaVisible(e->m_area) && e->m_rwObject == nil) + e->CreateRwObject(); + } +} + +//--MIAMI: done +void +CStreaming::InstanceLoadedModels(const CVector &pos) +{ + int minX = CWorld::GetSectorIndexX(pos.x - 80.0f); + if(minX <= 0) minX = 0; + + int minY = CWorld::GetSectorIndexY(pos.y - 80.0f); + if(minY <= 0) minY = 0; + + int maxX = CWorld::GetSectorIndexX(pos.x + 80.0f); + if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1; + + int maxY = CWorld::GetSectorIndexY(pos.y + 80.0f); + if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1; + + int x, y; + for(y = minY; y <= maxY; y++){ + for(x = minX; x <= maxX; x++){ + CSector *sector = CWorld::GetSector(x, y); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS]); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_OBJECTS]); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_DUMMIES]); + } + } +} + +//--MIAMI: done void CStreaming::RequestIslands(eLevelName level) { switch(level){ - case LEVEL_INDUSTRIAL: - RequestModel(islandLODcomInd, BIGBUILDINGFLAGS); - RequestModel(islandLODsubInd, BIGBUILDINGFLAGS); - break; - case LEVEL_COMMERCIAL: - RequestModel(islandLODindust, BIGBUILDINGFLAGS); - RequestModel(islandLODsubCom, BIGBUILDINGFLAGS); + case LEVEL_MAINLAND: + if(islandLODbeach != -1) + RequestModel(islandLODbeach, BIGBUILDINGFLAGS); break; - case LEVEL_SUBURBAN: - RequestModel(islandLODindust, BIGBUILDINGFLAGS); - RequestModel(islandLODcomSub, BIGBUILDINGFLAGS); + case LEVEL_BEACH: + if(islandLODmainland != -1) + RequestModel(islandLODmainland, BIGBUILDINGFLAGS); break; default: break; } } +//--MIAMI: TODO void CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flags) { @@ -793,24 +850,28 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag RequestModel(modelId, flags); } +//--MIAMI: done void CStreaming::RequestSpecialChar(int32 charId, const char *modelName, int32 flags) { RequestSpecialModel(charId + MI_SPECIAL01, modelName, flags); } +//--MIAMI: done bool CStreaming::HasSpecialCharLoaded(int32 id) { return HasModelLoaded(id + MI_SPECIAL01); } +//--MIAMI: done void CStreaming::SetMissionDoesntRequireSpecialChar(int32 id) { return SetMissionDoesntRequireModel(id + MI_SPECIAL01); } +//--MIAMI: done void CStreaming::DecrementRef(int32 id) { @@ -821,6 +882,7 @@ CStreaming::DecrementRef(int32 id) } } +//--MIAMI: done void CStreaming::RemoveModel(int32 id) { @@ -832,8 +894,14 @@ CStreaming::RemoveModel(int32 id) if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ if(id < STREAM_OFFSET_TXD) CModelInfo::GetModelInfo(id)->DeleteRwObject(); - else + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + else if(id >= STREAM_OFFSET_ANIM){ + assert(id < NUMSTREAMINFO); + CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM); + } ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE; } @@ -854,24 +922,30 @@ CStreaming::RemoveModel(int32 id) if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){ if(id < STREAM_OFFSET_TXD) RpClumpGtaCancelStream(); - else + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + else if(id >= STREAM_OFFSET_ANIM){ + assert(id < NUMSTREAMINFO); + CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM); + } } ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED; } +//--MIAMI: done void CStreaming::RemoveUnusedBuildings(eLevelName level) { - if(level != LEVEL_INDUSTRIAL) - RemoveBuildings(LEVEL_INDUSTRIAL); - if(level != LEVEL_COMMERCIAL) - RemoveBuildings(LEVEL_COMMERCIAL); - if(level != LEVEL_SUBURBAN) - RemoveBuildings(LEVEL_SUBURBAN); + if(level != LEVEL_BEACH) + RemoveBuildings(LEVEL_BEACH); + if(level != LEVEL_MAINLAND) + RemoveBuildings(LEVEL_MAINLAND); } +//--MIAMI: done void CStreaming::RemoveBuildings(eLevelName level) { @@ -932,18 +1006,18 @@ CStreaming::RemoveBuildings(eLevelName level) } } +//--MIAMI: done void CStreaming::RemoveUnusedBigBuildings(eLevelName level) { - if(level != LEVEL_INDUSTRIAL) - RemoveBigBuildings(LEVEL_INDUSTRIAL); - if(level != LEVEL_COMMERCIAL) - RemoveBigBuildings(LEVEL_COMMERCIAL); - if(level != LEVEL_SUBURBAN) - RemoveBigBuildings(LEVEL_SUBURBAN); + if(level != LEVEL_BEACH) + RemoveBigBuildings(LEVEL_BEACH); + if(level != LEVEL_MAINLAND) + RemoveBigBuildings(LEVEL_MAINLAND); RemoveIslandsNotUsed(level); } +//--MIAMI: done void DeleteIsland(CEntity *island) { @@ -957,35 +1031,33 @@ DeleteIsland(CEntity *island) } } +//--MIAMI: done void CStreaming::RemoveIslandsNotUsed(eLevelName level) { + int i; + if(pIslandLODmainlandEntity == nil) + for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ + CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); + if(building == nil) + continue; + if(building->GetModelIndex() == islandLODmainland) + pIslandLODmainlandEntity = building; + if(building->GetModelIndex() == islandLODbeach) + pIslandLODbeachEntity = building; + } + switch(level){ - case LEVEL_INDUSTRIAL: - DeleteIsland(pIslandLODindustEntity); - DeleteIsland(pIslandLODcomSubEntity); - DeleteIsland(pIslandLODsubComEntity); - break; - case LEVEL_COMMERCIAL: - DeleteIsland(pIslandLODcomIndEntity); - DeleteIsland(pIslandLODcomSubEntity); - DeleteIsland(pIslandLODsubIndEntity); - break; - case LEVEL_SUBURBAN: - DeleteIsland(pIslandLODsubIndEntity); - DeleteIsland(pIslandLODsubComEntity); - DeleteIsland(pIslandLODcomIndEntity); + case LEVEL_MAINLAND: + DeleteIsland(pIslandLODmainlandEntity); break; - default: - DeleteIsland(pIslandLODindustEntity); - DeleteIsland(pIslandLODcomIndEntity); - DeleteIsland(pIslandLODcomSubEntity); - DeleteIsland(pIslandLODsubIndEntity); - DeleteIsland(pIslandLODsubComEntity); + case LEVEL_BEACH: + DeleteIsland(pIslandLODbeachEntity); break; } } +//--MIAMI: done void CStreaming::RemoveBigBuildings(eLevelName level) { @@ -1017,8 +1089,7 @@ CStreaming::RemoveLoadedVehicle(void) if(ms_lastVehicleDeleted == MAXVEHICLESLOADED) ms_lastVehicleDeleted = 0; id = ms_vehiclesLoaded[ms_lastVehicleDeleted]; - if(id != -1 && - (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 && + if(id != -1 && CanRemoveModel(id) && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 && ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED) goto found; } @@ -1027,33 +1098,47 @@ found: RemoveModel(ms_vehiclesLoaded[ms_lastVehicleDeleted]); ms_numVehiclesLoaded--; ms_vehiclesLoaded[ms_lastVehicleDeleted] = -1; + CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); + if (pVehicleInfo->m_vehicleClass != -1) + CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass); return true; } +//--MIAMI: done bool -CStreaming::RemoveLeastUsedModel(void) +CStreaming::RemoveLeastUsedModel(uint32 excludeMask) { CStreamingInfo *si; int streamId; for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){ + if(si->m_flags & excludeMask) + continue; streamId = si - ms_aInfoForModel; if(streamId < STREAM_OFFSET_TXD){ if (CModelInfo::GetModelInfo(streamId)->GetNumRefs() == 0) { RemoveModel(streamId); return true; } - }else{ + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ if(CTxdStore::GetNumRefs(streamId - STREAM_OFFSET_TXD) == 0 && !IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){ RemoveModel(streamId); return true; } + }else if(streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + if(CAnimManager::GetNumRefsToAnimBlock(streamId - STREAM_OFFSET_ANIM) == 0 && + !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){ + RemoveModel(streamId); + return true; + } } } - return ms_numVehiclesLoaded > 7 && RemoveLoadedVehicle(); + return (ms_numVehiclesLoaded > 7 || CGame::currArea != AREA_MAIN_MAP && ms_numVehiclesLoaded > 4) && RemoveLoadedVehicle(); } +//--MIAMI: done void CStreaming::RemoveAllUnusedModels(void) { @@ -1064,7 +1149,6 @@ 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)->GetNumRefs() == 0) { RemoveModel(i); ms_aInfoForModel[i].m_loadState = STREAMSTATE_NOTLOADED; @@ -1072,30 +1156,14 @@ CStreaming::RemoveAllUnusedModels(void) } } -bool -CStreaming::RemoveReferencedTxds(int32 mem) -{ - CStreamingInfo *si; - int streamId; - - for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){ - streamId = si - ms_aInfoForModel; - if(streamId >= STREAM_OFFSET_TXD && - CTxdStore::GetNumRefs(streamId-STREAM_OFFSET_TXD) == 0){ - RemoveModel(streamId); - if(ms_memoryUsed < mem) - return true; - } - } - return false; -} - +//--MIAMI: done void CStreaming::RemoveUnusedModelsInLoadedList(void) { // empty } +//--MIAMI: done bool CStreaming::IsTxdUsedByRequestedModels(int32 txdId) { @@ -1124,6 +1192,34 @@ CStreaming::IsTxdUsedByRequestedModels(int32 txdId) return false; } +bool +CStreaming::AreAnimsUsedByRequestedModels(int32 animId) +{ + CStreamingInfo *si; + int streamId; + int i; + + for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = si->m_next){ + streamId = si - ms_aInfoForModel; + if(streamId < STREAM_OFFSET_TXD && + CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId) + return true; + } + + for(i = 0; i < 4; i++){ + streamId = ms_channel[0].streamIds[i]; + if(streamId != -1 && streamId < STREAM_OFFSET_TXD && + CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId) + return true; + streamId = ms_channel[1].streamIds[i]; + if(streamId != -1 && streamId < STREAM_OFFSET_TXD && + CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId) + return true; + } + + return false; +} + int32 CStreaming::GetAvailableVehicleSlot(void) { @@ -1155,8 +1251,8 @@ CStreaming::AddToLoadedVehiclesList(int32 modelId) // find vehicle we can remove for(i = 0; i < MAXVEHICLESLOADED; i++){ id = ms_vehiclesLoaded[ms_lastVehicleDeleted]; - if(id != -1 && - (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0) + if(id != -1 && CanRemoveModel(id) && + CModelInfo::GetModelInfo(id)->GetNumRefs() == 0) goto found; ms_lastVehicleDeleted++; if(ms_lastVehicleDeleted == MAXVEHICLESLOADED) @@ -1172,13 +1268,21 @@ found: ms_lastVehicleDeleted = id; // this is more that we wanted actually ms_numVehiclesLoaded++; - }else + } + else{ RemoveModel(id); + CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); + if (pVehicleInfo->m_vehicleClass != -1) + CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass); + } } ms_vehiclesLoaded[ms_lastVehicleDeleted++] = modelId; if(ms_lastVehicleDeleted == MAXVEHICLESLOADED) ms_lastVehicleDeleted = 0; + CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(modelId); + if (pVehicleInfo->m_vehicleClass != -1) + CCarCtrl::AddToLoadedVehicleArray(modelId, pVehicleInfo->m_vehicleClass, pVehicleInfo->m_frequency); return true; } @@ -1190,41 +1294,6 @@ CStreaming::IsObjectInCdImage(int32 id) } void -CStreaming::HaveAllBigBuildingsLoaded(eLevelName level) -{ - int i, n; - CEntity *e; - - if(ms_hasLoadedLODs) - return; - - if(level == LEVEL_INDUSTRIAL){ - if(ms_aInfoForModel[islandLODcomInd].m_loadState != STREAMSTATE_LOADED || - ms_aInfoForModel[islandLODsubInd].m_loadState != STREAMSTATE_LOADED) - return; - }else if(level == LEVEL_COMMERCIAL){ - if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED || - ms_aInfoForModel[islandLODsubCom].m_loadState != STREAMSTATE_LOADED) - return; - }else if(level == LEVEL_SUBURBAN){ - if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED || - ms_aInfoForModel[islandLODcomSub].m_loadState != STREAMSTATE_LOADED) - return; - } - - n = CPools::GetBuildingPool()->GetSize()-1; - for(i = n; i >= 0; i--){ - e = CPools::GetBuildingPool()->GetSlot(i); - if(e && e->bIsBIGBuilding && e->m_level == level && - ms_aInfoForModel[e->GetModelIndex()].m_loadState != STREAMSTATE_LOADED) - return; - } - - RemoveUnusedBigBuildings(level); - ms_hasLoadedLODs = true; -} - -void CStreaming::SetModelIsDeletable(int32 id) { ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_DONT_REMOVE; @@ -1243,6 +1312,7 @@ CStreaming::SetModelTxdIsDeletable(int32 id) SetModelIsDeletable(CModelInfo::GetModelInfo(id)->GetTxdSlot() + STREAM_OFFSET_TXD); } +//--MIAMI: done void CStreaming::SetMissionDoesntRequireModel(int32 id) { @@ -1265,6 +1335,13 @@ CStreaming::LoadInitialPeds(void) } void +CStreaming::LoadInitialWeapons(void) +{ + CStreaming::RequestModel(MI_NIGHTSTICK, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_MISSILE, STREAMFLAGS_DONT_REMOVE); +} + +void CStreaming::LoadInitialVehicles(void) { int id; @@ -1327,28 +1404,72 @@ CStreaming::StreamVehiclesAndPeds(void) else SetModelIsDeletable(MI_CHOPPER); + if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired()) { + SetModelIsDeletable(MI_VICE1); + SetModelIsDeletable(MI_VICE2); + SetModelIsDeletable(MI_VICE3); + SetModelIsDeletable(MI_VICE4); + SetModelIsDeletable(MI_VICE5); + SetModelIsDeletable(MI_VICE6); + SetModelIsDeletable(MI_VICE7); + SetModelIsDeletable(MI_VICE8); + switch (CCarCtrl::MiamiViceCycle) { + case 0: + RequestModel(MI_VICE1, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE2, STREAMFLAGS_DONT_REMOVE); + break; + case 1: + RequestModel(MI_VICE3, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE4, STREAMFLAGS_DONT_REMOVE); + break; + case 2: + RequestModel(MI_VICE5, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE6, STREAMFLAGS_DONT_REMOVE); + break; + case 3: + RequestModel(MI_VICE7, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE8, STREAMFLAGS_DONT_REMOVE); + break; + } + RequestModel(MI_VICECHEE, STREAMFLAGS_DONT_REMOVE); + } + else { + SetModelIsDeletable(MI_VICECHEE); + SetModelIsDeletable(MI_VICE1); + SetModelIsDeletable(MI_VICE2); + SetModelIsDeletable(MI_VICE3); + SetModelIsDeletable(MI_VICE4); + SetModelIsDeletable(MI_VICE5); + SetModelIsDeletable(MI_VICE6); + SetModelIsDeletable(MI_VICE7); + SetModelIsDeletable(MI_VICE8); + } + if(timeBeforeNextLoad >= 0) timeBeforeNextLoad--; else if(ms_numVehiclesLoaded <= desiredNumVehiclesLoaded){ - for(i = 1; i <= 10; i++){ - model = CCarCtrl::ChooseCarModel(modelQualityClass); - modelQualityClass++; - if(modelQualityClass >= CCarCtrl::TOTAL_CUSTOM_CLASSES) - modelQualityClass = 0; - - // check if we want to load this model - if(ms_aInfoForModel[model].m_loadState == STREAMSTATE_NOTLOADED && - ((CVehicleModelInfo*)CModelInfo::GetModelInfo(model))->m_level & (1 << (CGame::currLevel-1))) - break; + CZoneInfo zone; + CTheZones::GetZoneInfoForTimeOfDay(&FindPlayerCoors(), &zone); + int32 maxReq = -1; + int32 mostRequestedRating = 0; + for(i = 0; i < CCarCtrl::TOTAL_CUSTOM_CLASSES; i++){ + if(CCarCtrl::NumRequestsOfCarRating[i] > maxReq && + ((i == 0 && zone.carThreshold[0] != 0) || + (i != 0 && zone.carThreshold[i] != zone.carThreshold[i-1]))) { + maxReq = CCarCtrl::NumRequestsOfCarRating[i]; + mostRequestedRating = i; + } } - - if(i <= 10){ + model = CCarCtrl::ChooseCarModelToLoad(mostRequestedRating); + if(!HasModelLoaded(model)){ RequestModel(model, STREAMFLAGS_DEPENDENCY); - timeBeforeNextLoad = 500; + timeBeforeNextLoad = 350; } + CCarCtrl::NumRequestsOfCarRating[mostRequestedRating] = 0; } } +//--MIAMI: TODO void CStreaming::StreamZoneModels(const CVector &pos) { @@ -1374,58 +1495,54 @@ CStreaming::StreamZoneModels(const CVector &pos) for(i = 0; i < NUMMODELSPERPEDGROUP; i++){ if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1) break; - RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DONT_REMOVE); + RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DEPENDENCY); } } RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE); + //RequestModel(MI_HMOCA, STREAMFLAGS_DONT_REMOVE); gangsToLoad = 0; gangCarsToLoad = 0; - if(info.gangDensity[0] != 0) gangsToLoad |= 1<<0; - if(info.gangDensity[1] != 0) gangsToLoad |= 1<<1; - if(info.gangDensity[2] != 0) gangsToLoad |= 1<<2; - if(info.gangDensity[3] != 0) gangsToLoad |= 1<<3; - if(info.gangDensity[4] != 0) gangsToLoad |= 1<<4; - if(info.gangDensity[5] != 0) gangsToLoad |= 1<<5; - if(info.gangDensity[6] != 0) gangsToLoad |= 1<<6; - if(info.gangDensity[7] != 0) gangsToLoad |= 1<<7; - if(info.gangDensity[8] != 0) gangsToLoad |= 1<<8; - if(info.gangThreshold[0] != info.copDensity) gangCarsToLoad |= 1<<0; - if(info.gangThreshold[1] != info.gangThreshold[0]) gangCarsToLoad |= 1<<1; - if(info.gangThreshold[2] != info.gangThreshold[1]) gangCarsToLoad |= 1<<2; - if(info.gangThreshold[3] != info.gangThreshold[2]) gangCarsToLoad |= 1<<3; - if(info.gangThreshold[4] != info.gangThreshold[3]) gangCarsToLoad |= 1<<4; - if(info.gangThreshold[5] != info.gangThreshold[4]) gangCarsToLoad |= 1<<5; - if(info.gangThreshold[6] != info.gangThreshold[5]) gangCarsToLoad |= 1<<6; - if(info.gangThreshold[7] != info.gangThreshold[6]) gangCarsToLoad |= 1<<7; - if(info.gangThreshold[8] != info.gangThreshold[7]) gangCarsToLoad |= 1<<8; + if(info.gangPedThreshold[0] != info.copPedThreshold) + gangsToLoad = 1; + for(i = 1; i < NUM_GANGS; i++) + if(info.gangPedThreshold[i] != info.gangPedThreshold[i-1]) + gangsToLoad |= 1<<i; + if(info.gangThreshold[0] != info.copThreshold) + gangCarsToLoad = 1; + for(i = 1; i < NUM_GANGS; i++) + if(info.gangThreshold[i] != info.gangThreshold[i-1]) + gangCarsToLoad |= 1<<i; if(gangsToLoad == ms_loadedGangs && gangCarsToLoad == ms_loadedGangCars) return; - // This makes things simpler than the game does it gangsToLoad |= gangCarsToLoad; for(i = 0; i < NUM_GANGS; i++){ bit = 1<<i; if(gangsToLoad & bit && (ms_loadedGangs & bit) == 0){ - RequestModel(MI_GANG01 + i*2, STREAMFLAGS_DONT_REMOVE); - RequestModel(MI_GANG01 + i*2 + 1, STREAMFLAGS_DONT_REMOVE); + RequestModel(CGangs::GetGangPedModel1(i), STREAMFLAGS_DEPENDENCY); + RequestModel(CGangs::GetGangPedModel2(i), STREAMFLAGS_DEPENDENCY); ms_loadedGangs |= bit; }else if((gangsToLoad & bit) == 0 && ms_loadedGangs & bit){ - SetModelIsDeletable(MI_GANG01 + i*2); - SetModelIsDeletable(MI_GANG01 + i*2 + 1); - SetModelTxdIsDeletable(MI_GANG01 + i*2); - SetModelTxdIsDeletable(MI_GANG01 + i*2 + 1); + SetModelIsDeletable(CGangs::GetGangPedModel1(i)); + SetModelIsDeletable(CGangs::GetGangPedModel2(i)); + SetModelTxdIsDeletable(CGangs::GetGangPedModel1(i)); + SetModelTxdIsDeletable(CGangs::GetGangPedModel2(i)); ms_loadedGangs &= ~bit; } - if(gangCarsToLoad & bit && (ms_loadedGangCars & bit) == 0){ - RequestModel(CGangs::GetGangInfo(i)->m_nVehicleMI, STREAMFLAGS_DONT_REMOVE); + // TODO(MIAMI): check this + if(CGangs::GetGangVehicleModel(i) < 0) + continue; + + if((gangCarsToLoad & bit) && (ms_loadedGangCars & bit) == 0){ + RequestModel(CGangs::GetGangVehicleModel(i), STREAMFLAGS_DEPENDENCY); }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){ - SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); - SetModelTxdIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + SetModelIsDeletable(CGangs::GetGangVehicleModel(i)); + SetModelTxdIsDeletable(CGangs::GetGangVehicleModel(i)); } } ms_loadedGangCars = gangCarsToLoad; @@ -1437,7 +1554,7 @@ CStreaming::RemoveCurrentZonesModels(void) int i; if(ms_currentPedGrp != -1) - for(i = 0; i < 8; i++){ + for(i = 0; i < NUMMODELSPERPEDGROUP; i++){ if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1) break; if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) @@ -1445,10 +1562,10 @@ CStreaming::RemoveCurrentZonesModels(void) } for(i = 0; i < NUM_GANGS; i++){ - SetModelIsDeletable(MI_GANG01 + i*2); - SetModelIsDeletable(MI_GANG01 + i*2 + 1); - if(CGangs::GetGangInfo(i)->m_nVehicleMI != -1) - SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + SetModelIsDeletable(CGangs::GetGangPedModel1(i)); + SetModelIsDeletable(CGangs::GetGangPedModel2(i)); + if(CGangs::GetGangVehicleModel(i) != -1) + SetModelIsDeletable(CGangs::GetGangVehicleModel(i)); } ms_currentPedGrp = -1; @@ -1456,6 +1573,42 @@ CStreaming::RemoveCurrentZonesModels(void) ms_loadedGangCars = 0; } +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); +} + // Find starting offset of the cdimage we next want to read // Not useful at all on PC... @@ -1502,6 +1655,7 @@ ModelNotLoaded(int32 modelId) } inline bool TxdNotLoaded(int32 txdId) { return ModelNotLoaded(txdId + STREAM_OFFSET_TXD); } +inline bool AnimNotLoaded(int32 animId) { return animId != -1 && ModelNotLoaded(animId + STREAM_OFFSET_ANIM); } // Find stream id of next requested file in cdimage int32 @@ -1526,14 +1680,20 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority) if(priority && ms_numPriorityRequests != 0 && !si->IsPriority()) continue; - // request Txd if necessary + // request Txds or anims if necessary if(streamId < STREAM_OFFSET_TXD){ int txdId = CModelInfo::GetModelInfo(streamId)->GetTxdSlot(); if(TxdNotLoaded(txdId)){ ReRequestTxd(txdId); continue; } - } + int animId = CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex(); + if(AnimNotLoaded(animId)){ + ReRequestAnim(animId); + continue; + } + }else if(streamId >= STREAM_OFFSET_ANIM && CCutsceneMgr::IsCutsceneProcessing()) + continue; if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){ if(posn < posnFirst){ @@ -1576,6 +1736,7 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority) * TODO: two-part files */ +//--MIAMI: done // Make channel read from disc void CStreaming::RequestModelStream(int32 ch) @@ -1590,13 +1751,18 @@ CStreaming::RequestModelStream(int32 ch) imgOffset = GetCdImageOffset(lastPosn); streamId = GetNextFileOnCd(lastPosn - imgOffset, true); - if(streamId == -1) - return; - - // remove Txds that aren't requested anymore - while(streamId >= STREAM_OFFSET_TXD){ - if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY || - IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)) + // remove Txds and Anims that aren't requested anymore + while(streamId != -1){ + if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) + break; + if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ + if(IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)) + break; + }else if(streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + if(AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)) + break; + }else break; RemoveModel(streamId); // so try next file @@ -1633,7 +1799,8 @@ CStreaming::RequestModelStream(int32 ch) if(streamId < STREAM_OFFSET_TXD){ if (havePed && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED || haveBigFile && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE || - TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot())) + TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()) || + AnimNotLoaded(CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex())) break; }else{ if(haveBigFile && size > 200) @@ -1680,6 +1847,7 @@ CStreaming::RequestModelStream(int32 ch) ms_channel[ch].numTries = 0; } +//--MIAMI: done // Load data previously read from disc bool CStreaming::ProcessLoadingChannel(int32 ch) @@ -1714,10 +1882,10 @@ CStreaming::ProcessLoadingChannel(int32 ch) if(id < STREAM_OFFSET_TXD && CModelInfo::GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && ms_numVehiclesLoaded >= desiredNumVehiclesLoaded && !RemoveLoadedVehicle() && - ((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 || GetAvailableVehicleSlot() == -1)){ + (CanRemoveModel(id) || GetAvailableVehicleSlot() == -1)){ // can't load vehicle RemoveModel(id); - if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) + if(!CanRemoveModel(id)) ReRequestModel(id); else if(CTxdStore::GetNumRefs(CModelInfo::GetModelInfo(id)->GetTxdSlot()) == 0) RemoveTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot()); @@ -1749,6 +1917,7 @@ CStreaming::ProcessLoadingChannel(int32 ch) return true; } +//--MIAMI: done void CStreaming::RetryLoadFile(int32 ch) { @@ -1785,6 +1954,7 @@ CStreaming::RetryLoadFile(int32 ch) } } +//--MIAMI: done void CStreaming::LoadRequestedModels(void) { @@ -1809,6 +1979,7 @@ CStreaming::LoadRequestedModels(void) } } +//--MIAMI: done void CStreaming::LoadAllRequestedModels(bool priority) { @@ -1862,6 +2033,7 @@ CStreaming::LoadAllRequestedModels(bool priority) bInsideLoadAll = false; } +//--MIAMI: done void CStreaming::FlushChannels(void) { @@ -1883,6 +2055,7 @@ CStreaming::FlushChannels(void) ProcessLoadingChannel(1); } +//--MIAMI: done void CStreaming::FlushRequestList(void) { @@ -1991,8 +2164,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float if(xmin < pos.x && pos.x < xmax && ymin < pos.y && pos.y < ymax && (CVector2D(x, y) - pos).MagnitudeSqr() < lodDistSq) - if(CRenderer::IsEntityCullZoneVisible(e)) - RequestModel(e->GetModelIndex(), 0); + RequestModel(e->GetModelIndex(), 0); } } } @@ -2015,8 +2187,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list) (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){ CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()); if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) - if(CRenderer::IsEntityCullZoneVisible(e)) - RequestModel(e->GetModelIndex(), 0); + RequestModel(e->GetModelIndex(), 0); } } } @@ -2254,9 +2425,6 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem) } } - if(RemoveReferencedTxds(mem)) - return; - // As last resort, delete objects from the last step more aggressively for(y = ymin; y <= ymax; y++){ for(x = xmax; x != xmin; x -= inc){ @@ -2318,9 +2486,6 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem) } } - if(RemoveReferencedTxds(mem)) - return; - // As last resort, delete objects from the last step more aggressively for(x = xmin; x <= xmax; x++){ for(y = ymax; y != ymin; y -= inc){ @@ -2419,12 +2584,13 @@ CStreaming::MakeSpaceFor(int32 size) // but it's not nice.... while((uint32)ms_memoryUsed >= ms_memoryAvailable - size) - if(!RemoveLeastUsedModel()){ + if(!RemoveLeastUsedModel(STREAMFLAGS_20)){ DeleteRwObjectsBehindCamera(ms_memoryAvailable - size); return; } } +//--MIAMI: done void CStreaming::LoadScene(const CVector &pos) { @@ -2439,16 +2605,44 @@ CStreaming::LoadScene(const CVector &pos) RemoveModel(si - ms_aInfoForModel); } CRenderer::m_loadingPriority = false; - CCullZones::ForceCullZoneCoors(pos); DeleteAllRwObjects(); + 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); - RemoveUnusedBigBuildings(level); - RequestBigBuildings(level); + + if (!CGame::IsInInterior()) { + for (int i = 0; i < 5; i++) { + CZoneInfo zone; + CTheZones::GetZoneInfoForTimeOfDay(&pos, &zone); + int32 model = CCarCtrl::ChooseCarModelToLoad(CCarCtrl::ChooseCarRating(&zone)); + CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY); + } + } LoadAllRequestedModels(false); + InstanceLoadedModels(pos); + + for(int i = 0; i < NUMSTREAMINFO; i++) + ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20; debug("End load scene\n"); } +//--MIAMI: done +void +CStreaming::LoadSceneCollision(const CVector &pos) +{ + CColStore::LoadCollision(pos); + CStreaming::LoadAllRequestedModels(false); +} + void CStreaming::MemoryCardSave(uint8 *buf, uint32 *size) { diff --git a/src/core/Streaming.h b/src/core/Streaming.h index 84434769..8a92266f 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -4,7 +4,9 @@ enum { STREAM_OFFSET_TXD = MODELINFOSIZE, - NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE + STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE, + STREAM_OFFSET_ANIM = STREAM_OFFSET_COL+COLSTORESIZE, + NUMSTREAMINFO = STREAM_OFFSET_ANIM+NUMANIMBLOCKS }; enum StreamFlags @@ -14,6 +16,7 @@ enum StreamFlags STREAMFLAGS_DEPENDENCY = 0x04, // Is this right? STREAMFLAGS_PRIORITY = 0x08, STREAMFLAGS_NOFADE = 0x10, + STREAMFLAGS_20 = 0x20, // TODO(MIAMI): what's this STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED, STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY, @@ -92,9 +95,9 @@ public: static int32 ms_numVehiclesLoaded; static int32 ms_vehiclesLoaded[MAXVEHICLESLOADED]; static int32 ms_lastVehicleDeleted; + static bool ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP]; static CDirectory *ms_pExtraObjectsDir; static int32 ms_numPriorityRequests; - static bool ms_hasLoadedLODs; static int32 ms_currentPedGrp; static int32 ms_lastCullZone; static uint16 ms_loadedGangs; @@ -115,14 +118,25 @@ public: 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); } + static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); } + static bool HasAnimLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_ANIM); } 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); } + static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); } + static bool CanRemoveAnim(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_ANIM); } 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); } - static void RequestSubway(void); + static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); } + static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); } + static void RequestAnim(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_ANIM, flags); } + static void ReRequestAnim(int32 col) { ReRequestModel(col + STREAM_OFFSET_ANIM); } static void RequestBigBuildings(eLevelName level); + static void RequestBigBuildings(eLevelName level, const CVector &pos); + static void InstanceBigBuildings(eLevelName level, const CVector &pos); + static void InstanceLoadedModelsInSectorList(CPtrList &list); + static void InstanceLoadedModels(const CVector &pos); 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); @@ -131,29 +145,32 @@ public: static void DecrementRef(int32 id); static void RemoveModel(int32 id); static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); } + static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); } + static void RemoveAnim(int32 id) { RemoveModel(id + STREAM_OFFSET_ANIM); } static void RemoveUnusedBuildings(eLevelName level); static void RemoveBuildings(eLevelName level); static void RemoveUnusedBigBuildings(eLevelName level); static void RemoveIslandsNotUsed(eLevelName level); static void RemoveBigBuildings(eLevelName level); static bool RemoveLoadedVehicle(void); - static bool RemoveLeastUsedModel(void); + static bool RemoveLeastUsedModel(uint32 excludeMask); static void RemoveAllUnusedModels(void); static void RemoveUnusedModelsInLoadedList(void); - static bool RemoveReferencedTxds(int32 mem); static int32 GetAvailableVehicleSlot(void); static bool IsTxdUsedByRequestedModels(int32 txdId); + static bool AreAnimsUsedByRequestedModels(int32 animId); static bool AddToLoadedVehiclesList(int32 modelId); static bool IsObjectInCdImage(int32 id); - static void HaveAllBigBuildingsLoaded(eLevelName level); static void SetModelIsDeletable(int32 id); static void SetModelTxdIsDeletable(int32 id); static void SetMissionDoesntRequireModel(int32 id); static void LoadInitialPeds(void); + static void LoadInitialWeapons(void); static void LoadInitialVehicles(void); static void StreamVehiclesAndPeds(void); static void StreamZoneModels(const CVector &pos); static void RemoveCurrentZonesModels(void); + static void LoadBigBuildingsWhenNeeded(void); static int32 GetCdImageOffset(int32 lastPosn); static int32 GetNextFileOnCd(int32 position, bool priority); @@ -183,6 +200,7 @@ public: static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem); static void LoadScene(const CVector &pos); + static void LoadSceneCollision(const CVector &pos); static void MemoryCardSave(uint8 *buffer, uint32 *length); static void MemoryCardLoad(uint8 *buffer, uint32 length); diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp index 79d6252b..f20923f2 100644 --- a/src/core/TempColModels.cpp +++ b/src/core/TempColModels.cpp @@ -16,6 +16,7 @@ CColModel CTempColModels::ms_colModelPedGroundHit; CColModel CTempColModels::ms_colModelBoot1; CColModel CTempColModels::ms_colModelDoor1; CColModel CTempColModels::ms_colModelBonnet1; +CColModel CTempColModels::ms_colModelWeapon; CColSphere s_aPedSpheres[3]; @@ -41,13 +42,13 @@ CTempColModels::Initialise(void) int i; - ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0); + ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f)); ms_colModelBBox.level = LEVEL_NONE; for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) { - ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0); + ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f)); ms_colModelCutObj[i].level = LEVEL_NONE; } @@ -69,8 +70,8 @@ CTempColModels::Initialise(void) s_aPedSpheres[i].piece = 0; } - ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0); + ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f)); SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres); // Ped 2 Spheres @@ -88,8 +89,8 @@ CTempColModels::Initialise(void) s_aPed2Spheres[i].piece = 0; } - ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0); + ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f)); SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres); @@ -114,8 +115,8 @@ CTempColModels::Initialise(void) s_aPedGSpheres[2].piece = 0; s_aPedGSpheres[3].piece = 6; - ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0); + ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f)); SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres); @@ -134,8 +135,8 @@ CTempColModels::Initialise(void) s_aDoorSpheres[i].piece = 0; } - ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0); + ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f)); + ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f)); SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres); @@ -154,8 +155,8 @@ CTempColModels::Initialise(void) s_aBumperSpheres[i].piece = 0; } - ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, -0.2f), SURFACE_DEFAULT, 0); + ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f)); + ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, -0.2f)); SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres); @@ -174,8 +175,8 @@ CTempColModels::Initialise(void) s_aPanelSpheres[i].piece = 0; } - ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0); + ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f)); SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres); @@ -194,8 +195,8 @@ CTempColModels::Initialise(void) s_aBonnetSpheres[i].piece = 0; } - ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f)); + ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres); @@ -214,8 +215,8 @@ CTempColModels::Initialise(void) s_aBootSpheres[i].piece = 0; } - ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f)); + ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres); @@ -236,8 +237,8 @@ CTempColModels::Initialise(void) s_aWheelSpheres[i].piece = 0; } - ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0); + ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f)); SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres); @@ -258,8 +259,8 @@ CTempColModels::Initialise(void) s_aBodyPartSpheres1[i].piece = 0; } - ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f)); + ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1); @@ -280,10 +281,14 @@ CTempColModels::Initialise(void) s_aBodyPartSpheres2[i].piece = 0; } - ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0); + ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f)); + ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f)); SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2); + + ms_colModelWeapon.boundingSphere.Set(0.25f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelWeapon.boundingBox.Set(CVector(-0.25f, -0.25, -0.25f), CVector(0.25f, 0.25, 0.25f)); + #undef SET_COLMODEL_SPHERES } diff --git a/src/core/TempColModels.h b/src/core/TempColModels.h index 3e1dd5e1..0c936d6f 100644 --- a/src/core/TempColModels.h +++ b/src/core/TempColModels.h @@ -18,6 +18,7 @@ public: static CColModel ms_colModelBoot1; static CColModel ms_colModelDoor1; static CColModel ms_colModelBonnet1; + static CColModel ms_colModelWeapon; static void Initialise(void); }; diff --git a/src/core/User.cpp b/src/core/User.cpp index f906ae44..716d6393 100644 --- a/src/core/User.cpp +++ b/src/core/User.cpp @@ -32,8 +32,8 @@ void CPlaceName::Process() { CVector pos = CWorld::Players[CWorld::PlayerInFocus].GetPos(); - CZone *navigZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_NAVIG); - CZone *defaultZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_DEFAULT); + CZone *navigZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, false, true); + CZone *defaultZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, true, false); if (navigZone == nil) m_pZone = nil; if (defaultZone == nil) m_pZone2 = nil; diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp index 7508c9f4..d2623431 100644 --- a/src/core/Wanted.cpp +++ b/src/core/Wanted.cpp @@ -40,6 +40,12 @@ CWanted::Initialise() } bool +CWanted::AreMiamiViceRequired() +{ + return m_nWantedLevel >= 3; +} + +bool CWanted::AreSwatRequired() { return m_nWantedLevel == 4 || m_bSwatRequired; @@ -456,3 +462,10 @@ CWanted::UpdateCrimesQ(void) } } } + +void +CWanted::Suspend(void) +{ + // TODO(MIAMI)! + Reset(); // <- temporary +} diff --git a/src/core/Wanted.h b/src/core/Wanted.h index de36c442..ee72aa47 100644 --- a/src/core/Wanted.h +++ b/src/core/Wanted.h @@ -31,6 +31,7 @@ public: public: void Initialise(); + bool AreMiamiViceRequired(); bool AreSwatRequired(); bool AreFbiRequired(); bool AreArmyRequired(); @@ -48,6 +49,8 @@ public: void UpdateCrimesQ(); void Update(); + void Suspend(); + bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; } static int32 WorkOutPolicePresence(CVector posn, float radius); diff --git a/src/core/World.cpp b/src/core/World.cpp index edcfd865..16e5e80d 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -339,26 +339,10 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP if(e->IsPed()) { if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) { -#ifdef PED_SKIN - if(IsClumpSkinned(e->GetClump())) - colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump()); - else -#endif - if(((CPed *)e)->UseGroundColModel()) - colmodel = &CTempColModels::ms_colModelPedGroundHit; - else -#ifdef ANIMATE_PED_COL_MODEL - colmodel = CPedModelInfo::AnimatePedColModel( - ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex())) - ->GetHitColModel(), - RpClumpGetFrame(e->GetClump())); -#else - colmodel = - ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex())) - ->GetHitColModel(); -#endif + colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump()); } else colmodel = nil; + } else if(e->bUsesCollision) colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); @@ -382,7 +366,11 @@ CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, C { AdvanceCurrentScanCode(); CVector point2(point1.x, point1.y, z2); - return ProcessVerticalLineSector(*GetSector(GetSectorIndexX(point1.x), GetSectorIndexY(point1.y)), + int secX = GetSectorIndexX(point1.x); + int secY = GetSectorIndexY(point1.y); + secX = clamp(secX, 0, NUMSECTORS_X-1); + secY = clamp(secY, 0, NUMSECTORS_Y-1); + return ProcessVerticalLineSector(*GetSector(secX, secY), CColLine(point1, point2), point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly); } @@ -920,6 +908,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad bool ignoreSomeObjects) { static CColModel sphereCol; + CColSphere sphere; sphereCol.boundingSphere.center.x = 0.0f; sphereCol.boundingSphere.center.y = 0.0f; @@ -932,7 +921,8 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad sphereCol.boundingBox.max.y = radius; sphereCol.boundingBox.max.z = radius; sphereCol.numSpheres = 1; - sphereCol.spheres = &sphereCol.boundingSphere; + sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f)); + sphereCol.spheres = &sphere; sphereCol.numLines = 0; sphereCol.numBoxes = 0; sphereCol.numTriangles = 0; @@ -1201,7 +1191,7 @@ CWorld::FindObjectsIntersectingCubeSectorList(CPtrList &list, const CVector &vec } void -CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, const CMatrix &matrix, +CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const CMatrix &matrix, const CVector &position, float fStartX, float fStartY, float fEndX, float fEndY, int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, @@ -1261,7 +1251,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co } void -CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CColBox &boundingBox, +CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CBox &boundingBox, const CMatrix &matrix, const CVector &position, int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities) @@ -1823,18 +1813,22 @@ void CWorld::RepositionOneObject(CEntity *pEntity) { int16 modelId = pEntity->GetModelIndex(); - if (IsStreetLight(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 || - modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 || - modelId == MI_PHONESIGN || modelId == MI_TAXISIGN || modelId == MI_FISHSTALL01 || - modelId == MI_FISHSTALL02 || modelId == MI_FISHSTALL03 || modelId == MI_FISHSTALL04 || - modelId == MI_BAGELSTAND2 || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT || - modelId == MI_PARKTABLE) { + if (modelId == MI_PARKINGMETER || modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || + modelId == MI_BIN || modelId == MI_POSTBOX1 || modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || + modelId == MI_DUMP1 || modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 || + modelId == MI_PHONESIGN || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT || + modelId == MI_PARKTABLE || modelId == MI_PARKINGMETER2 || modelId == MI_TELPOLE02 || + modelId == MI_PARKBENCH || modelId == MI_BARRIER1 || IsTreeModel(modelId) +// TODO(MIAMI): this is actually a different case +|| IsStreetLight(modelId) + ) { CVector &position = pEntity->GetMatrix().GetPosition(); - float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z; + CColModel *pColModel = pEntity->GetColModel(); + float fBoundingBoxMinZ = pColModel->boundingBox.min.z; + float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z; + if(fHeight < OBJECT_REPOSITION_OFFSET_Z) fHeight = OBJECT_REPOSITION_OFFSET_Z; position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y, - position.z + OBJECT_REPOSITION_OFFSET_Z, nil) - + position.z + fHeight, nil) - fBoundingBoxMinZ; pEntity->m_matrix.UpdateRW(); pEntity->UpdateRwFrame(); @@ -1921,6 +1915,7 @@ CWorld::Process(void) if(csObj && csObj->m_entryInfoList.first) { if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) { +// TODO(MIAMI): doRender argument RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * (csObj->IsObject() ? CTimer::GetTimeStepNonClipped() @@ -1939,6 +1934,7 @@ CWorld::Process(void) CEntity *movingEnt = (CEntity *)node->item; if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) { +// TODO(MIAMI): doRender argument RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * (movingEnt->IsObject() ? CTimer::GetTimeStepNonClipped() @@ -2041,9 +2037,12 @@ CWorld::Process(void) movingPed->EnteringCar()) { CVehicle *movingCar = movingPed->m_pMyVehicle; if(movingCar) { +#ifdef GTA_TRAIN if(movingCar->IsTrain()) { movingPed->SetPedPositionInTrain(); - } else { + } else +#endif + { switch(movingPed->m_nPedState) { case PED_ENTER_CAR: case PED_CARJACK: movingPed->EnterCar(); break; @@ -2228,4 +2227,60 @@ CWorld::UseDetonator(CEntity *pEntity) pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity); } } + CProjectileInfo::RemoveDetonatorProjectiles(); +} + +bool +CWorld::IsWanderPathClear(CVector const& point1, CVector const& point2, float distance, int maxSteps) +{ + if (Abs(point1.z - point2.z) > distance) + return false; + if (!GetIsLineOfSightClear(point1, point2, true, false, false, false, false, false, false)) + return false; + CVector vecBetween = point2 - point1; + uint32 nSteps = Max(vecBetween.Magnitude(), maxSteps); + if (nSteps == 0) + return true; + vecBetween.Normalise(); + uint32 step = 1; + for (step = 1; step < nSteps; step++) { + CVector posThisStep = point1 + vecBetween * step; + float level; + if (!CWaterLevel::GetWaterLevel(posThisStep, &level, false)) + continue; + posThisStep.z = level; + AdvanceCurrentScanCode(); + + CVector vecCheckedPos(posThisStep.x, posThisStep.y, Max(point1.z, point2.z)); + CColPoint colpoint; + CEntity* entity; + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + } + + CVector posThisStep = point1; + AdvanceCurrentScanCode(); + CVector vecCheckedPos(posThisStep.x, posThisStep.y, point1.z - 5.0f); + + CColPoint colpoint; + CEntity* entity; + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + + float heightNextStep = colpoint.point.z + 0.5f; + for (step = 1; step < nSteps; step++) { + CVector posThisStep = point1 + vecBetween * step; + posThisStep.z = heightNextStep; + AdvanceCurrentScanCode(); + CVector vecCheckedPos(posThisStep.x, posThisStep.y, heightNextStep - 2.0f); + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + if (Abs(colpoint.point.z - heightNextStep) > 1.0f) + return false; + heightNextStep = colpoint.point.z + 0.5f; + } + return true; } diff --git a/src/core/World.h b/src/core/World.h index 2bcc4e43..89f05cfd 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -4,19 +4,19 @@ #include "Lists.h" #include "PlayerInfo.h" -/* Sectors span from -2000 to 2000 in x and y. - * With 100x100 sectors, each is 40x40 units. */ +/* Sectors span from -2400 to 1600 in x and -2000 to 2000 y. + * With 80x80 sectors, each is 50x50 units. */ -#define SECTOR_SIZE_X (40.0f) -#define SECTOR_SIZE_Y (40.0f) +#define SECTOR_SIZE_X (50.0f) +#define SECTOR_SIZE_Y (50.0f) -#define NUMSECTORS_X (100) -#define NUMSECTORS_Y (100) +#define NUMSECTORS_X (80) +#define NUMSECTORS_Y (80) #define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X) #define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y) -#define WORLD_MIN_X (-2000.0f) +#define WORLD_MIN_X (-2400.0f) #define WORLD_MIN_Y (-2000.0f) #define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X) @@ -114,8 +114,8 @@ public: static void FindObjectsKindaCollidingSectorList(CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities); static void FindObjectsIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies); static void FindObjectsIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities); - static void FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool); - static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities); + static void FindObjectsIntersectingAngledCollisionBox(const CBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool); + static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities); static void FindMissionEntitiesIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bVehicles, bool bPeds, bool bObjects); static void FindMissionEntitiesIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bIsVehicleList, bool bIsPedList); @@ -125,6 +125,8 @@ public: static void CallOffChaseForAreaSectorListVehicles(CPtrList& list, float x1, float y1, float x2, float y2, float fStartX, float fStartY, float fEndX, float fEndY); static void CallOffChaseForAreaSectorListPeds(CPtrList& list, float x1, float y1, float x2, float y2); + static bool IsWanderPathClear(CVector const&, CVector const&, float, int); + static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); } static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); } static int GetSectorIndexX(float f) { return (int)GetSectorX(f); } diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp index c376e11f..729cc35d 100644 --- a/src/core/ZoneCull.cpp +++ b/src/core/ZoneCull.cpp @@ -11,207 +11,22 @@ #include "ZoneCull.h" #include "Zones.h" -int32 CCullZones::NumCullZones; -CCullZone CCullZones::aZones[NUMCULLZONES]; int32 CCullZones::NumAttributeZones; CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES]; -uint16 CCullZones::aIndices[NUMZONEINDICES]; -int16 CCullZones::aPointersToBigBuildingsForBuildings[NUMBUILDINGS]; -int16 CCullZones::aPointersToBigBuildingsForTreadables[NUMTREADABLES]; int32 CCullZones::CurrentWantedLevelDrop_Player; int32 CCullZones::CurrentFlags_Camera; int32 CCullZones::CurrentFlags_Player; -int32 CCullZones::OldCullZone; -int32 CCullZones::EntityIndicesUsed; bool CCullZones::bCurrentSubwayIsInvisible; -bool CCullZones::bCullZonesDisabled; - void CCullZones::Init(void) { - int i; - NumAttributeZones = 0; CurrentWantedLevelDrop_Player = 0; CurrentFlags_Camera = 0; CurrentFlags_Player = 0; bCurrentSubwayIsInvisible = false; - NumCullZones = 0; - OldCullZone = -1; - EntityIndicesUsed = 0; - - for(i = 0; i < NUMBUILDINGS; i++) - aPointersToBigBuildingsForBuildings[i] = -1; - for(i = 0; i < NUMTREADABLES; i++) - aPointersToBigBuildingsForTreadables[i] = -1; -} - -bool CCullZone::TestLine(CVector vec1, CVector vec2) -{ - CColPoint colPoint; - CEntity *entity; - - if (CWorld::ProcessLineOfSight(vec1, vec2, colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x + 0.05f, vec1.y, vec1.z), CVector(vec2.x + 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x - 0.05f, vec1.y, vec1.z), CVector(vec2.x - 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y + 0.05f, vec1.z), CVector(vec2.x, vec2.y + 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y - 0.05f, vec1.z), CVector(vec2.x, vec2.y - 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z + 0.05f), CVector(vec2.x, vec2.y, vec2.z + 0.05f), colPoint, entity, true, false, false, false, false, true, false)) - return true; - return CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z - 0.05f), CVector(vec2.x, vec2.y, vec2.z - 0.05f), colPoint, entity, true, false, false, false, false, true, false); -} - - -uint16* pTempArrayIndices; -int TempEntityIndicesUsed; - -void -CCullZones::ResolveVisibilities(void) -{ - int fd; - - CFileMgr::SetDir(""); - fd = CFileMgr::OpenFile("DATA\\cullzone.dat", "rb"); - if(fd > 0){ - CFileMgr::Read(fd, (char*)&NumCullZones, sizeof(NumCullZones)); - CFileMgr::Read(fd, (char*)aZones, sizeof(aZones)); - CFileMgr::Read(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones)); - CFileMgr::Read(fd, (char*)aAttributeZones, sizeof(aAttributeZones)); - CFileMgr::Read(fd, (char*)aIndices, sizeof(aIndices)); - CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings)); - CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables)); - CFileMgr::CloseFile(fd); - }else{ -#if 0 - // TODO: implement code from mobile to generate data here - EntityIndicesUsed = 0; - BuildListForBigBuildings(); - pTempArrayIndices = new uint16[140000]; - TempEntityIndicesUsed = 0; - - for (int i = 0; i < NumCullZones; i++) { - DoVisibilityTestCullZone(i, true); - } - - CompressIndicesArray(); - delete[] pTempArrayIndices; - - fd = CFileMgr::OpenFileForWriting("data\\cullzone.dat"); - if (fd != 0) { - CFileMgr::Write(fd, (char*)&NumCullZones, sizeof(NumCullZones)); - CFileMgr::Write(fd, (char*)aZones, sizeof(aZones)); - CFileMgr::Write(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones)); - CFileMgr::Write(fd, (char*)&aAttributeZones, sizeof(aAttributeZones)); - CFileMgr::Write(fd, (char*)&aIndices, sizeof(aIndices)); - CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings)); - CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables)); - CFileMgr::CloseFile(fd); - } -#endif - } -} - -void -CCullZones::BuildListForBigBuildings() -{ - for (int i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--) { - CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); - if (building == nil || !building->bIsBIGBuilding) continue; - CSimpleModelInfo *nonlod = (CSimpleModelInfo*)((CSimpleModelInfo *)CModelInfo::GetModelInfo(building->GetModelIndex()))->m_atomics[2]; - if (nonlod == nil) continue; - - for (int j = i; j >= 0; j--) { - CBuilding *building2 = CPools::GetBuildingPool()->GetSlot(j); - if (building2 == nil || building2->bIsBIGBuilding) continue; - if (CModelInfo::GetModelInfo(building2->GetModelIndex()) == nonlod) { - if ((building2->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) { - aPointersToBigBuildingsForBuildings[j] = i; - } - } - } - - for (int j = CPools::GetTreadablePool()->GetSize()-1; j >= 0; j--) { - CTreadable *treadable = CPools::GetTreadablePool()->GetSlot(j); - if (treadable == nil || treadable->bIsBIGBuilding) continue; - if (CModelInfo::GetModelInfo(treadable->GetModelIndex()) == nonlod) { - if ((treadable->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) { - aPointersToBigBuildingsForTreadables[j] = i; - } - } - } - } -} - -void -CCullZones::DoVisibilityTestCullZone(int zoneId, bool doIt) -{ - aZones[zoneId].m_groupIndexCount[0] = 0; - aZones[zoneId].m_groupIndexCount[1] = 0; - aZones[zoneId].m_groupIndexCount[2] = 0; - aZones[zoneId].m_indexStart = TempEntityIndicesUsed; - aZones[zoneId].FindTestPoints(); - - if (!doIt) return; - - for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) { - CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); - if (building != nil && !building->bIsBIGBuilding && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForBuildings[i] != -1)) { - CBuilding *building2 = nil; - if (aPointersToBigBuildingsForBuildings[i] != -1) - building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForBuildings[i]); - - if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) { - pTempArrayIndices[TempEntityIndicesUsed++] = i; - aZones[zoneId].m_groupIndexCount[0]++; - } - } - } - - for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) { - CTreadable* building = CPools::GetTreadablePool()->GetSlot(i); - if (building != nil && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForTreadables[i] != -1)) { - CTreadable* building2 = nil; - if (aPointersToBigBuildingsForTreadables[i] != -1) - building2 = CPools::GetTreadablePool()->GetSlot(aPointersToBigBuildingsForTreadables[i]); - - if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 10.0f, building2)) { - pTempArrayIndices[TempEntityIndicesUsed++] = i; - aZones[zoneId].m_groupIndexCount[1]++; - } - } - } - - for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) { - CTreadable *building = CPools::GetTreadablePool()->GetSlot(i); - if (building != nil && aZones[zoneId].CalcDistToCullZoneSquared(building->GetPosition().x, building->GetPosition().y) < 40000.0f) { - int start = aZones[zoneId].m_groupIndexCount[0] + aZones[zoneId].m_indexStart; - int end = aZones[zoneId].m_groupIndexCount[1] + start; - - bool alreadyAdded = false; - - for (int k = start; k < end; k++) { - if (aIndices[k] == i) - alreadyAdded = true; - } - - if (!alreadyAdded) { - CBuilding *building2 = nil; - if (aPointersToBigBuildingsForTreadables[i] != -1) - building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForTreadables[i]); - if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) { - pTempArrayIndices[TempEntityIndicesUsed++] = i; - aZones[zoneId].m_groupIndexCount[2]++; - } - } - } - } } void @@ -219,14 +34,9 @@ CCullZones::Update(void) { bool invisible; - if(bCullZonesDisabled) - return; - switch(CTimer::GetFrameCounter() & 7){ case 0: case 4: - /* Update Cull zone */ - ForceCullZoneCoors(TheCamera.GetGameCamPosition()); break; case 2: @@ -250,28 +60,6 @@ CCullZones::Update(void) void CCullZones::ForceCullZoneCoors(CVector coors) { - int32 z; - z = FindCullZoneForCoors(coors); - if(z != OldCullZone){ - if(OldCullZone >= 0) - aZones[OldCullZone].DoStuffLeavingZone(); - if(z >= 0) - aZones[z].DoStuffEnteringZone(); - OldCullZone = z; - } -} - -int32 -CCullZones::FindCullZoneForCoors(CVector coors) -{ - int i; - - for(i = 0; i < NumCullZones; i++) - if(coors.x >= aZones[i].minx && coors.x <= aZones[i].maxx && - coors.y >= aZones[i].miny && coors.y <= aZones[i].maxy && - coors.z >= aZones[i].minz && coors.z <= aZones[i].maxz) - return i; - return -1; } int32 @@ -346,219 +134,16 @@ CCullZones::AddCullZone(CVector const &position, float minz, float maxz, uint16 flag, int16 wantedLevel) { - CCullZone *cull; CAttributeZone *attrib; - CVector v; - if((flag & ATTRZONE_NOTCULLZONE) == 0){ - cull = &aZones[NumCullZones++]; - v = position; - // WTF is this? - if((v-CVector(1032.14f, -624.255f, 24.93f)).Magnitude() < 1.0f) - v = CVector(1061.7f, -613.0f, 19.0f); - if((v-CVector(1029.48f, -495.757f, 21.98f)).Magnitude() < 1.0f) - v = CVector(1061.4f, -506.0f, 18.5f); - cull->position.x = clamp(v.x, minx, maxx); - cull->position.y = clamp(v.y, miny, maxy); - cull->position.z = clamp(v.z, minz, maxz); - cull->minx = minx; - cull->maxx = maxx; - cull->miny = miny; - cull->maxy = maxy; - cull->minz = minz; - cull->maxz = maxz; - cull->m_groupIndexCount[0] = 0; - cull->m_groupIndexCount[1] = 0; - cull->m_groupIndexCount[2] = 0; - cull->m_indexStart = 0; - } - if(flag & ~ATTRZONE_NOTCULLZONE){ - attrib = &aAttributeZones[NumAttributeZones++]; - attrib->minx = minx; - attrib->maxx = maxx; - attrib->miny = miny; - attrib->maxy = maxy; - attrib->minz = minz; - attrib->maxz = maxz; - attrib->attributes = flag; - attrib->wantedLevel = wantedLevel; - } -} - - -void -CCullZone::DoStuffLeavingZone(void) -{ - int i; - - for(i = 0; i < m_numBuildings; i++) - DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]); - for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables ; i++) - DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[m_indexStart + i]); -} - -void -CCullZone::DoStuffLeavingZone_OneBuilding(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = false; - bb = CCullZones::aPointersToBigBuildingsForBuildings[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffLeavingZone_OneTreadableBoth(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = false; - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = false; - bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffEnteringZone(void) -{ - int i; - - for(i = 0; i < m_numBuildings; i++) - DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]); - for(; i < m_numBuildings + m_numTreadablesPlus10m; i++) - DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[m_indexStart + i]); - for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables; i++) - DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[m_indexStart + i]); -} - -void -CCullZone::DoStuffEnteringZone_OneBuilding(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = true; - bb = CCullZones::aPointersToBigBuildingsForBuildings[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffEnteringZone_OneTreadablePlus10m(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true; - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = true; - bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffEnteringZone_OneTreadable(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true; - bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[i+j]); - } -} - -float -CCullZone::CalcDistToCullZoneSquared(float x, float y) -{ - float rx, ry; - - if (x < minx) rx = sq(x - minx); - else if (x > maxx) rx = sq(x - maxx); - else rx = 0.0f; - - if (y < miny) ry = sq(y - miny); - else if (y > maxy) ry = sq(y - maxy); - else ry = 0.0f; - - return rx + ry; -} - -bool -CCullZone::IsEntityCloseEnoughToZone(CEntity *entity, bool checkLevel) -{ - const CVector &pos = entity->GetPosition(); - - CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(entity->GetModelIndex()); - float distToZone = CalcDistToCullZone(pos.x, pos.y); - float lodDist; - if (minfo->m_isSubway) - lodDist = minfo->GetLargestLodDistance() + 30.0f; - else - lodDist = minfo->GetLargestLodDistance() + 50.0f; - - if (lodDist > distToZone) return true; - if (!checkLevel) return false; - CVector tempPos(minx, miny, minz); - return CTheZones::GetLevelFromPosition(&pos) == CTheZones::GetLevelFromPosition(&tempPos); -} - -bool -CCullZones::DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set) -{ - int32 curCount; - int32 start; - int32 size; - - for (int i = 0; i < NumCullZones; i++) { - curCount = 0; - for (int group = 0; group < 3; group++) { - aZones[i].GetGroupStartAndSize(group, start, size); - - int unk = 0; // TODO: figure out - for (int j = 0; j < size; j++) { - for (int k = 0; k < 3; k++) { - if (set[k] == pTempArrayIndices[start+j]) - unk++; - } - } - if (unk == 3 && ++curCount >= count) - return true; - } - } - return false; + assert(NumAttributeZones < NUMATTRIBZONES); + attrib = &aAttributeZones[NumAttributeZones++]; + attrib->minx = minx; + attrib->maxx = maxx; + attrib->miny = miny; + attrib->maxy = maxy; + attrib->minz = minz; + attrib->maxz = maxz; + attrib->attributes = flag; + attrib->wantedLevel = wantedLevel; } diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h index 9bc07b8c..e76b7a44 100644 --- a/src/core/ZoneCull.h +++ b/src/core/ZoneCull.h @@ -1,57 +1,5 @@ class CEntity; -class CCullZone -{ -public: - CVector position; - float minx; - float maxx; - float miny; - float maxy; - float minz; - float maxz; - - int32 m_indexStart; - int16 m_groupIndexCount[3]; - int16 m_numBuildings; - int16 m_numTreadablesPlus10m; - int16 m_numTreadables; - - void DoStuffLeavingZone(void); - static void DoStuffLeavingZone_OneBuilding(uint16 i); - static void DoStuffLeavingZone_OneTreadableBoth(uint16 i); - void DoStuffEnteringZone(void); - static void DoStuffEnteringZone_OneBuilding(uint16 i); - static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i); - static void DoStuffEnteringZone_OneTreadable(uint16 i); - - - static bool TestLine(CVector a1, CVector a2); - float CalcDistToCullZoneSquared(float x, float y); - float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); }; - bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel); - - void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) { - switch (groupid) { - case 1: - start = m_groupIndexCount[0] + m_indexStart; - size = m_groupIndexCount[1]; - break; - case 2: - start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart; - size = m_groupIndexCount[2]; - break; - default: - start = m_indexStart; - size = m_groupIndexCount[0]; - break; - } - } - - void FindTestPoints() {}; // todo - bool TestEntityVisibilityFromCullZone(CEntity*, float, CEntity*) { return false; }; // todo -}; - enum eZoneAttribs { ATTRZONE_CAMCLOSEIN = 1, @@ -79,27 +27,17 @@ struct CAttributeZone class CCullZones { public: - static int32 NumCullZones; - static CCullZone aZones[NUMCULLZONES]; static int32 NumAttributeZones; static CAttributeZone aAttributeZones[NUMATTRIBZONES]; - static uint16 aIndices[NUMZONEINDICES]; - static int16 aPointersToBigBuildingsForBuildings[NUMBUILDINGS]; - static int16 aPointersToBigBuildingsForTreadables[NUMTREADABLES]; static int32 CurrentWantedLevelDrop_Player; static int32 CurrentFlags_Camera; static int32 CurrentFlags_Player; - static int32 OldCullZone; - static int32 EntityIndicesUsed; static bool bCurrentSubwayIsInvisible; - static bool bCullZonesDisabled; static void Init(void); - static void ResolveVisibilities(void); static void Update(void); static void ForceCullZoneCoors(CVector coors); - static int32 FindCullZoneForCoors(CVector coors); static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel); static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void); static void MarkSubwayAsInvisible(bool visible); @@ -117,9 +55,6 @@ public: static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; } static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; } - static void BuildListForBigBuildings(); - static void DoVisibilityTestCullZone(int zoneId, bool doIt); - static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set); - - static void CompressIndicesArray() {};// todo + //--MIAMI: TODO + static bool PoliceAbandonCars(void) { return false; } }; diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 4f491a49..0e8606f3 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -9,133 +9,138 @@ #include "World.h" eLevelName CTheZones::m_CurrLevel; -CZone *CTheZones::m_pPlayersZone; int16 CTheZones::FindIndex; uint16 CTheZones::NumberOfAudioZones; int16 CTheZones::AudioZoneArray[NUMAUDIOZONES]; uint16 CTheZones::TotalNumberOfMapZones; -uint16 CTheZones::TotalNumberOfZones; -CZone CTheZones::ZoneArray[NUMZONES]; +uint16 CTheZones::TotalNumberOfInfoZones; +uint16 CTheZones::TotalNumberOfNavigationZones; +CZone CTheZones::InfoZoneArray[NUMINFOZONES]; CZone CTheZones::MapZoneArray[NUMMAPZONES]; +CZone CTheZones::NavigationZoneArray[NUMNAVIGZONES]; uint16 CTheZones::TotalNumberOfZoneInfos; -CZoneInfo CTheZones::ZoneInfoArray[2*NUMZONES]; +CZoneInfo CTheZones::ZoneInfoArray[2*NUMINFOZONES]; -#define SWAPF(a, b) { float t; t = a; a = b; b = t; } - -inline bool IsNormalZone(int type) { return type == ZONE_DEFAULT || type == ZONE_NAVIG || type == ZONE_INFO; } -static void -CheckZoneInfo(CZoneInfo *info) -{ - assert(info->carThreshold[0] >= 0); - assert(info->carThreshold[0] <= info->carThreshold[1]); - assert(info->carThreshold[1] <= info->carThreshold[2]); - assert(info->carThreshold[2] <= info->carThreshold[3]); - assert(info->carThreshold[3] <= info->carThreshold[4]); - assert(info->carThreshold[4] <= info->carThreshold[5]); - assert(info->carThreshold[5] <= info->copThreshold); - assert(info->copThreshold <= info->gangThreshold[0]); - assert(info->gangThreshold[0] <= info->gangThreshold[1]); - assert(info->gangThreshold[1] <= info->gangThreshold[2]); - assert(info->gangThreshold[2] <= info->gangThreshold[3]); - assert(info->gangThreshold[3] <= info->gangThreshold[4]); - assert(info->gangThreshold[4] <= info->gangThreshold[5]); - assert(info->gangThreshold[5] <= info->gangThreshold[6]); - assert(info->gangThreshold[6] <= info->gangThreshold[7]); - assert(info->gangThreshold[7] <= info->gangThreshold[8]); -} +#define SWAPF(a, b) { float t; t = a; a = b; b = t; } +//--MIAMI: done wchar* CZone::GetTranslatedName(void) { return TheText.Get(name); } +//--MIAMI: done void CTheZones::Init(void) { - int i; + int i, j; for(i = 0; i < NUMAUDIOZONES; i++) AudioZoneArray[i] = -1; NumberOfAudioZones = 0; - for(i = 0; i < NUMZONES; i++) - memset(&ZoneArray[i], 0, sizeof(CZone)); - - CZoneInfo *zonei; - int x = 1000/6; - for(i = 0; i < 2*NUMZONES; i++){ - zonei = &ZoneInfoArray[i]; - zonei->carDensity = 10; - zonei->carThreshold[0] = x; - zonei->carThreshold[1] = zonei->carThreshold[0] + x; - zonei->carThreshold[2] = zonei->carThreshold[1] + x; - zonei->carThreshold[3] = zonei->carThreshold[2] + x; - zonei->carThreshold[4] = zonei->carThreshold[3]; - zonei->carThreshold[5] = zonei->carThreshold[4]; - zonei->copThreshold = zonei->carThreshold[5] + x; - zonei->gangThreshold[0] = zonei->copThreshold; - zonei->gangThreshold[1] = zonei->gangThreshold[0]; - zonei->gangThreshold[2] = zonei->gangThreshold[1]; - zonei->gangThreshold[3] = zonei->gangThreshold[2]; - zonei->gangThreshold[4] = zonei->gangThreshold[3]; - zonei->gangThreshold[5] = zonei->gangThreshold[4]; - zonei->gangThreshold[6] = zonei->gangThreshold[5]; - zonei->gangThreshold[7] = zonei->gangThreshold[6]; - zonei->gangThreshold[8] = zonei->gangThreshold[7]; - CheckZoneInfo(zonei); + for(i = 0; i < NUMNAVIGZONES; i++) + memset(&NavigationZoneArray[i], 0, sizeof(CZone)); + + for(i = 0; i < NUMINFOZONES; i++) + memset(&InfoZoneArray[i], 0, sizeof(CZone)); + + int x = 1000/9; + for(i = 0; i < 2*NUMINFOZONES; i++){ + // Cars + + ZoneInfoArray[i].carDensity = 10; + ZoneInfoArray[i].carThreshold[0] = x; + ZoneInfoArray[i].carThreshold[1] = ZoneInfoArray[i].carThreshold[0] + x; + ZoneInfoArray[i].carThreshold[2] = ZoneInfoArray[i].carThreshold[1] + x; + ZoneInfoArray[i].carThreshold[3] = ZoneInfoArray[i].carThreshold[2] + x; + ZoneInfoArray[i].carThreshold[4] = ZoneInfoArray[i].carThreshold[3] + x; + ZoneInfoArray[i].carThreshold[5] = ZoneInfoArray[i].carThreshold[4] + x; + ZoneInfoArray[i].carThreshold[6] = ZoneInfoArray[i].carThreshold[5] + x; + ZoneInfoArray[i].carThreshold[7] = ZoneInfoArray[i].carThreshold[6] + x; + ZoneInfoArray[i].carThreshold[8] = 1000; + + ZoneInfoArray[i].boatThreshold[0] = 500; + ZoneInfoArray[i].boatThreshold[1] = 1000; + + // What's going on here? this looks more like density + ZoneInfoArray[i].copThreshold = 50; + for(j = 0; j < NUM_GANGS; j++) + ZoneInfoArray[i].gangThreshold[j] = ZoneInfoArray[i].copThreshold; + + // Peds + + ZoneInfoArray[i].pedDensity = 12; + + // What's going on here? this looks more like density + ZoneInfoArray[i].copPedThreshold = 50; + for(j = 0; j < NUM_GANGS; j++) + ZoneInfoArray[i].gangPedThreshold[j] = ZoneInfoArray[i].copPedThreshold; + + ZoneInfoArray[i].pedGroup = 0; } TotalNumberOfZoneInfos = 1; // why 1? - TotalNumberOfZones = 1; + TotalNumberOfNavigationZones = 1; + TotalNumberOfInfoZones = 1; + + strcpy(InfoZoneArray[0].name, "CITYINF"); + InfoZoneArray[0].minx = -2400.0f; + InfoZoneArray[0].miny = -2000.0f; + InfoZoneArray[0].minz = -500.0f; + InfoZoneArray[0].maxx = 1600.0f; + InfoZoneArray[0].maxy = 2000.0f; + InfoZoneArray[0].maxz = 500.0f; + InfoZoneArray[0].level = LEVEL_NONE; + InfoZoneArray[0].type = ZONE_INFO; + + strcpy(NavigationZoneArray[0].name, "VICE_C"); + NavigationZoneArray[0].minx = -2400.0f; + NavigationZoneArray[0].miny = -2000.0f; + NavigationZoneArray[0].minz = -500.0f; + NavigationZoneArray[0].maxx = 1600.0f; + NavigationZoneArray[0].maxy = 2000.0f; + NavigationZoneArray[0].maxz = 500.0f; + NavigationZoneArray[0].level = LEVEL_NONE; + NavigationZoneArray[0].type = ZONE_NAVIG; m_CurrLevel = LEVEL_NONE; - m_pPlayersZone = &ZoneArray[0]; - - strcpy(ZoneArray[0].name, "CITYZON"); - ZoneArray[0].minx = -4000.0f; - ZoneArray[0].miny = -4000.0f; - ZoneArray[0].minz = -500.0f; - ZoneArray[0].maxx = 4000.0f; - ZoneArray[0].maxy = 4000.0f; - ZoneArray[0].maxz = 500.0f; - ZoneArray[0].level = LEVEL_NONE; for(i = 0; i < NUMMAPZONES; i++){ memset(&MapZoneArray[i], 0, sizeof(CZone)); MapZoneArray[i].type = ZONE_MAPZONE; } - TotalNumberOfMapZones = 1; - strcpy(MapZoneArray[0].name, "THEMAP"); - MapZoneArray[0].minx = -4000.0f; - MapZoneArray[0].miny = -4000.0f; + MapZoneArray[0].minx = -2400.0f; + MapZoneArray[0].miny = -2000.0f; MapZoneArray[0].minz = -500.0f; - MapZoneArray[0].maxx = 4000.0f; - MapZoneArray[0].maxy = 4000.0f; + MapZoneArray[0].maxx = 1600.0f; + MapZoneArray[0].maxy = 2000.0f; MapZoneArray[0].maxz = 500.0f; MapZoneArray[0].level = LEVEL_NONE; } +//--MIAMI: done void CTheZones::Update(void) { CVector pos; pos = FindPlayerCoors(); - m_pPlayersZone = FindSmallestZonePosition(&pos); m_CurrLevel = GetLevelFromPosition(&pos); } +//--MIAMI: done void CTheZones::CreateZone(char *name, eZoneType type, float minx, float miny, float minz, float maxx, float maxy, float maxz, eLevelName level) { + char tmpname[24]; char *p; - char tmpname[8]; if(minx > maxx) SWAPF(minx, maxx); if(miny > maxy) SWAPF(miny, maxy); @@ -144,73 +149,94 @@ CTheZones::CreateZone(char *name, eZoneType type, // make upper case for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p); - // add zone strncpy(tmpname, name, 7); tmpname[7] = '\0'; - strcpy(ZoneArray[TotalNumberOfZones].name, tmpname); - ZoneArray[TotalNumberOfZones].type = type; - ZoneArray[TotalNumberOfZones].minx = minx; - ZoneArray[TotalNumberOfZones].miny = miny; - ZoneArray[TotalNumberOfZones].minz = minz; - ZoneArray[TotalNumberOfZones].maxx = maxx; - ZoneArray[TotalNumberOfZones].maxy = maxy; - ZoneArray[TotalNumberOfZones].maxz = maxz; - ZoneArray[TotalNumberOfZones].level = level; - if(IsNormalZone(type)){ - ZoneArray[TotalNumberOfZones].zoneinfoDay = TotalNumberOfZoneInfos++; - ZoneArray[TotalNumberOfZones].zoneinfoNight = TotalNumberOfZoneInfos++; - } - TotalNumberOfZones++; -} - -void -CTheZones::CreateMapZone(char *name, eZoneType type, - float minx, float miny, float minz, - float maxx, float maxy, float maxz, - eLevelName level) -{ - CZone *zone; - char *p; - - if(minx > maxx) SWAPF(minx, maxx); - if(miny > maxy) SWAPF(miny, maxy); - if(minz > maxz) SWAPF(minz, maxz); - - // make upper case - for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p); // add zone - zone = &MapZoneArray[TotalNumberOfMapZones++]; - strncpy(zone->name, name, 7); - zone->name[7] = '\0'; - zone->type = type; - zone->minx = minx; - zone->miny = miny; - zone->minz = minz; - zone->maxx = maxx; - zone->maxy = maxy; - zone->maxz = maxz; - zone->level = level; + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + assert(TotalNumberOfNavigationZones < NUMNAVIGZONES); + strcpy(NavigationZoneArray[TotalNumberOfNavigationZones].name, tmpname); + NavigationZoneArray[TotalNumberOfNavigationZones].type = type; + NavigationZoneArray[TotalNumberOfNavigationZones].minx = minx; + NavigationZoneArray[TotalNumberOfNavigationZones].miny = miny; + NavigationZoneArray[TotalNumberOfNavigationZones].minz = minz; + NavigationZoneArray[TotalNumberOfNavigationZones].maxx = maxx; + NavigationZoneArray[TotalNumberOfNavigationZones].maxy = maxy; + NavigationZoneArray[TotalNumberOfNavigationZones].maxz = maxz; + NavigationZoneArray[TotalNumberOfNavigationZones].level = level; + TotalNumberOfNavigationZones++; + break; + case ZONE_INFO: + assert(TotalNumberOfInfoZones < NUMINFOZONES); + strcpy(InfoZoneArray[TotalNumberOfInfoZones].name, tmpname); + InfoZoneArray[TotalNumberOfInfoZones].type = type; + InfoZoneArray[TotalNumberOfInfoZones].minx = minx; + InfoZoneArray[TotalNumberOfInfoZones].miny = miny; + InfoZoneArray[TotalNumberOfInfoZones].minz = minz; + InfoZoneArray[TotalNumberOfInfoZones].maxx = maxx; + InfoZoneArray[TotalNumberOfInfoZones].maxy = maxy; + InfoZoneArray[TotalNumberOfInfoZones].maxz = maxz; + InfoZoneArray[TotalNumberOfInfoZones].level = level; + InfoZoneArray[TotalNumberOfInfoZones].zoneinfoDay = TotalNumberOfZoneInfos++; + InfoZoneArray[TotalNumberOfInfoZones].zoneinfoNight = TotalNumberOfZoneInfos++; + TotalNumberOfInfoZones++; + break; + case ZONE_MAPZONE: + assert(TotalNumberOfMapZones < NUMMAPZONES); + strcpy(MapZoneArray[TotalNumberOfMapZones].name, tmpname); + MapZoneArray[TotalNumberOfMapZones].type = type; + MapZoneArray[TotalNumberOfMapZones].minx = minx; + MapZoneArray[TotalNumberOfMapZones].miny = miny; + MapZoneArray[TotalNumberOfMapZones].minz = minz; + MapZoneArray[TotalNumberOfMapZones].maxx = maxx; + MapZoneArray[TotalNumberOfMapZones].maxy = maxy; + MapZoneArray[TotalNumberOfMapZones].maxz = maxz; + MapZoneArray[TotalNumberOfMapZones].level = level; + TotalNumberOfMapZones++; + break; + } } +//--MIAMI: done void CTheZones::PostZoneCreation(void) { int i; - for(i = 1; i < TotalNumberOfZones; i++) - InsertZoneIntoZoneHierarchy(&ZoneArray[i]); + for(i = 1; i < TotalNumberOfNavigationZones; i++) + InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]); InitialiseAudioZoneArray(); } +//--MIAMI: done, but does nothing +void +CTheZones::CheckZonesForOverlap(void) +{ + int i, j; + char str[116]; + + for(i = 1; i < TotalNumberOfInfoZones; i++){ + ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[0]); + + for(j = 1; j < TotalNumberOfInfoZones; j++) + if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j])) + sprintf(str, "Info zone %s contains %s\n", + &InfoZoneArray[j].name, &InfoZoneArray[i].name); + } +} + +//--MIAMI: done void CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone) { zone->child = nil; zone->parent = nil; zone->next = nil; - InsertZoneIntoZoneHierRecursive(zone, &ZoneArray[0]); + InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]); } +//--MIAMI: done bool CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer) { @@ -254,6 +280,7 @@ CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer) return true; } +//--MIAMI: done bool CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer) { @@ -278,6 +305,7 @@ CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer) return true; } +//--MIAMI: done bool CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone) { @@ -286,6 +314,7 @@ CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone) zone->minz <= v->z && v->z <= zone->maxz; } +//--MIAMI: done eLevelName CTheZones::GetLevelFromPosition(CVector const *v) { @@ -299,35 +328,35 @@ CTheZones::GetLevelFromPosition(CVector const *v) return MapZoneArray[0].level; } +//--MIAMI: done CZone* -CTheZones::FindSmallestZonePosition(const CVector *v) +CTheZones::FindInformationZoneForPosition(const CVector *v) { - CZone *best = &ZoneArray[0]; - // zone to test next - CZone *zone = ZoneArray[0].child; - while(zone) - // if in zone, descent into children - if(PointLiesWithinZone(v, zone)){ - best = zone; - zone = zone->child; - // otherwise try next zone - }else - zone = zone->next; - return best; + int i; +// char tmp[116]; +// if(!PointLiesWithinZone(v, &InfoZoneArray[0])) +// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z); + for(i = 1; i < TotalNumberOfInfoZones; i++) + if(PointLiesWithinZone(v, &InfoZoneArray[i])) + return &InfoZoneArray[i]; + return &InfoZoneArray[0]; } +//--MIAMI: done CZone* -CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type) +CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig) { CZone *best = nil; - if(ZoneArray[0].type == type) - best = &ZoneArray[0]; + if(findDefault && NavigationZoneArray[0].type == ZONE_DEFAULT || + findNavig && NavigationZoneArray[0].type == ZONE_NAVIG) + best = &NavigationZoneArray[0]; // zone to test next - CZone *zone = ZoneArray[0].child; + CZone *zone = NavigationZoneArray[0].child; while(zone) // if in zone, descent into children if(PointLiesWithinZone(v, zone)){ - if(zone->type == type) + if(findDefault && zone->type == ZONE_DEFAULT || + findNavig && zone->type == ZONE_NAVIG) best = zone; zone = zone->child; // otherwise try next zone @@ -336,43 +365,73 @@ CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type) return best; } -CZone* -CTheZones::FindSmallestZonePositionILN(const CVector *v) +//--MIAMI: done +int16 +CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type) { - CZone *best = nil; - if(IsNormalZone(ZoneArray[0].type)) - best = &ZoneArray[0]; - // zone to test next - CZone *zone = ZoneArray[0].child; - while(zone) - // if in zone, descent into children - if(PointLiesWithinZone(v, zone)){ - if(IsNormalZone(zone->type)) - best = zone; - zone = zone->child; - // otherwise try next zone - }else - zone = zone->next; - return best; + char str[8]; + memset(str, 0, 8); + strncpy(str, name, 8); + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + for(FindIndex = 0; FindIndex < TotalNumberOfNavigationZones; FindIndex++) + if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_INFO: + for(FindIndex = 0; FindIndex < TotalNumberOfInfoZones; FindIndex++) + if(strcmp(GetInfoZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_MAPZONE: + for(FindIndex = 0; FindIndex < TotalNumberOfMapZones; FindIndex++) + if(strcmp(GetMapZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + } + return -1; } +//--MIAMI: done int16 -CTheZones::FindZoneByLabelAndReturnIndex(Const char *name) +CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type) { char str[8]; + ++FindIndex; memset(str, 0, 8); strncpy(str, name, 8); - for(FindIndex = 0; FindIndex < TotalNumberOfZones; FindIndex++) - if(strcmp(GetZone(FindIndex)->name, name) == 0) - return FindIndex; + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + for(; FindIndex < TotalNumberOfNavigationZones; FindIndex++) + if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_INFO: + for(; FindIndex < TotalNumberOfInfoZones; FindIndex++) + if(strcmp(GetInfoZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_MAPZONE: + for(; FindIndex < TotalNumberOfMapZones; FindIndex++) + if(strcmp(GetMapZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + } return -1; } +//--MIAMI: done CZoneInfo* CTheZones::GetZoneInfo(const CVector *v, uint8 day) { CZone *zone; - zone = FindSmallestZonePositionILN(v); + zone = FindInformationZoneForPosition(v); if(zone == nil) return &ZoneInfoArray[0]; return &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; @@ -383,6 +442,7 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info) { CZoneInfo *day, *night; float d, n; + int i; day = GetZoneInfo(pos, 1); night = GetZoneInfo(pos, 0); @@ -402,109 +462,60 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info) n = 1.0f - d; } info->carDensity = day->carDensity * d + night->carDensity * n; - info->carThreshold[0] = day->carThreshold[0] * d + night->carThreshold[0] * n; - info->carThreshold[1] = day->carThreshold[1] * d + night->carThreshold[1] * n; - info->carThreshold[2] = day->carThreshold[2] * d + night->carThreshold[2] * n; - info->carThreshold[3] = day->carThreshold[3] * d + night->carThreshold[3] * n; - info->carThreshold[4] = day->carThreshold[4] * d + night->carThreshold[4] * n; - info->carThreshold[5] = day->carThreshold[5] * d + night->carThreshold[5] * n; - info->copThreshold = day->copThreshold * d + night->copThreshold * n; - info->gangThreshold[0] = day->gangThreshold[0] * d + night->gangThreshold[0] * n; - info->gangThreshold[1] = day->gangThreshold[1] * d + night->gangThreshold[1] * n; - info->gangThreshold[2] = day->gangThreshold[2] * d + night->gangThreshold[2] * n; - info->gangThreshold[3] = day->gangThreshold[3] * d + night->gangThreshold[3] * n; - info->gangThreshold[4] = day->gangThreshold[4] * d + night->gangThreshold[4] * n; - info->gangThreshold[5] = day->gangThreshold[5] * d + night->gangThreshold[5] * n; - info->gangThreshold[6] = day->gangThreshold[6] * d + night->gangThreshold[6] * n; - info->gangThreshold[7] = day->gangThreshold[7] * d + night->gangThreshold[7] * n; - info->gangThreshold[8] = day->gangThreshold[8] * d + night->gangThreshold[8] * n; + for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++) + info->carThreshold[i] = day->carThreshold[i] * d + night->carThreshold[i] * n; + for(i = 0; i < ARRAY_SIZE(info->boatThreshold); i++) + info->boatThreshold[i] = day->boatThreshold[i] * d + night->boatThreshold[i] * n; + for(i = 0; i < ARRAY_SIZE(info->gangThreshold); i++) + info->gangThreshold[i] = day->gangThreshold[i] * d + night->gangThreshold[i] * n; + info->copThreshold = day->copThreshold * d + night->copThreshold * n; info->pedDensity = day->pedDensity * d + night->pedDensity * n; - info->copDensity = day->copDensity * d + night->copDensity * n; - info->gangDensity[0] = day->gangDensity[0] * d + night->gangDensity[0] * n; - info->gangDensity[1] = day->gangDensity[1] * d + night->gangDensity[1] * n; - info->gangDensity[2] = day->gangDensity[2] * d + night->gangDensity[2] * n; - info->gangDensity[3] = day->gangDensity[3] * d + night->gangDensity[3] * n; - info->gangDensity[4] = day->gangDensity[4] * d + night->gangDensity[4] * n; - info->gangDensity[5] = day->gangDensity[5] * d + night->gangDensity[5] * n; - info->gangDensity[6] = day->gangDensity[6] * d + night->gangDensity[6] * n; - info->gangDensity[7] = day->gangDensity[7] * d + night->gangDensity[7] * n; - info->gangDensity[8] = day->gangDensity[8] * d + night->gangDensity[8] * n; + info->copPedThreshold = day->copPedThreshold * d + night->copPedThreshold * n; + for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++) + info->gangPedThreshold[i] = day->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n; } if(CClock::GetIsTimeInRange(5, 19)) info->pedGroup = day->pedGroup; else info->pedGroup = night->pedGroup; - - CheckZoneInfo(info); } void CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity, - int16 gang0Num, int16 gang1Num, int16 gang2Num, - int16 gang3Num, int16 gang4Num, int16 gang5Num, - int16 gang6Num, int16 gang7Num, int16 gang8Num, - int16 copNum, - int16 car0Num, int16 car1Num, int16 car2Num, - int16 car3Num, int16 car4Num, int16 car5Num) + int16 copCarDensity, const int16 *gangCarDensities) { CZone *zone; CZoneInfo *info; - zone = GetZone(zoneid); + zone = GetInfoZone(zoneid); info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; - CheckZoneInfo(info); - - if(carDensity != -1) info->carDensity = carDensity; - int16 oldCar1Num = info->carThreshold[1] - info->carThreshold[0]; - int16 oldCar2Num = info->carThreshold[2] - info->carThreshold[1]; - int16 oldCar3Num = info->carThreshold[3] - info->carThreshold[2]; - int16 oldCar4Num = info->carThreshold[4] - info->carThreshold[3]; - int16 oldCar5Num = info->carThreshold[5] - info->carThreshold[4]; - int16 oldCopNum = info->copThreshold - info->carThreshold[5]; - int16 oldGang0Num = info->gangThreshold[0] - info->copThreshold; - int16 oldGang1Num = info->gangThreshold[1] - info->gangThreshold[0]; - int16 oldGang2Num = info->gangThreshold[2] - info->gangThreshold[1]; - int16 oldGang3Num = info->gangThreshold[3] - info->gangThreshold[2]; - int16 oldGang4Num = info->gangThreshold[4] - info->gangThreshold[3]; - int16 oldGang5Num = info->gangThreshold[5] - info->gangThreshold[4]; - int16 oldGang6Num = info->gangThreshold[6] - info->gangThreshold[5]; - int16 oldGang7Num = info->gangThreshold[7] - info->gangThreshold[6]; - int16 oldGang8Num = info->gangThreshold[8] - info->gangThreshold[7]; - - if(car0Num != -1) info->carThreshold[0] = car0Num; - if(car1Num != -1) info->carThreshold[1] = info->carThreshold[0] + car1Num; - else info->carThreshold[1] = info->carThreshold[0] + oldCar1Num; - if(car2Num != -1) info->carThreshold[2] = info->carThreshold[1] + car2Num; - else info->carThreshold[2] = info->carThreshold[1] + oldCar2Num; - if(car3Num != -1) info->carThreshold[3] = info->carThreshold[2] + car3Num; - else info->carThreshold[3] = info->carThreshold[2] + oldCar3Num; - if(car4Num != -1) info->carThreshold[4] = info->carThreshold[3] + car4Num; - else info->carThreshold[4] = info->carThreshold[3] + oldCar4Num; - if(car5Num != -1) info->carThreshold[5] = info->carThreshold[4] + car5Num; - else info->carThreshold[5] = info->carThreshold[4] + oldCar5Num; - if(copNum != -1) info->copThreshold = info->carThreshold[5] + copNum; - else info->copThreshold = info->carThreshold[5] + oldCopNum; - if(gang0Num != -1) info->gangThreshold[0] = info->copThreshold + gang0Num; - else info->gangThreshold[0] = info->copThreshold + oldGang0Num; - if(gang1Num != -1) info->gangThreshold[1] = info->gangThreshold[0] + gang1Num; - else info->gangThreshold[1] = info->gangThreshold[0] + oldGang1Num; - if(gang2Num != -1) info->gangThreshold[2] = info->gangThreshold[1] + gang2Num; - else info->gangThreshold[2] = info->gangThreshold[1] + oldGang2Num; - if(gang3Num != -1) info->gangThreshold[3] = info->gangThreshold[2] + gang3Num; - else info->gangThreshold[3] = info->gangThreshold[2] + oldGang3Num; - if(gang4Num != -1) info->gangThreshold[4] = info->gangThreshold[3] + gang4Num; - else info->gangThreshold[4] = info->gangThreshold[3] + oldGang4Num; - if(gang5Num != -1) info->gangThreshold[5] = info->gangThreshold[4] + gang5Num; - else info->gangThreshold[5] = info->gangThreshold[4] + oldGang5Num; - if(gang6Num != -1) info->gangThreshold[6] = info->gangThreshold[5] + gang6Num; - else info->gangThreshold[6] = info->gangThreshold[5] + oldGang6Num; - if(gang7Num != -1) info->gangThreshold[7] = info->gangThreshold[6] + gang7Num; - else info->gangThreshold[7] = info->gangThreshold[6] + oldGang7Num; - if(gang8Num != -1) info->gangThreshold[8] = info->gangThreshold[7] + gang8Num; - else info->gangThreshold[8] = info->gangThreshold[7] + oldGang8Num; - - CheckZoneInfo(info); + info->carDensity = carDensity; + info->copThreshold = copCarDensity; + info->gangThreshold[0] = gangCarDensities[0] + copCarDensity; + info->gangThreshold[1] = gangCarDensities[1] + info->gangThreshold[0]; + info->gangThreshold[2] = gangCarDensities[2] + info->gangThreshold[1]; + info->gangThreshold[3] = gangCarDensities[3] + info->gangThreshold[2]; + info->gangThreshold[4] = gangCarDensities[4] + info->gangThreshold[3]; + info->gangThreshold[5] = gangCarDensities[5] + info->gangThreshold[4]; + info->gangThreshold[6] = gangCarDensities[6] + info->gangThreshold[5]; + info->gangThreshold[7] = gangCarDensities[7] + info->gangThreshold[6]; + info->gangThreshold[8] = gangCarDensities[8] + info->gangThreshold[7]; +} + +void CTheZones::SetZoneCivilianCarInfo(uint16 zoneid, uint8 day, + const int16* carDensities, const int16* boatDensities) +{ + CZone* zone; + CZoneInfo* info; + zone = GetInfoZone(zoneid); + info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; + info->carThreshold[0] = carDensities[0]; + for (int i = 1; i < CCarCtrl::NUM_CAR_CLASSES; i++) + info->carThreshold[i] = carDensities[i] + info->carThreshold[i-1]; + info->boatThreshold[0] = boatDensities[0]; + for (int i = 1; i < CCarCtrl::NUM_BOAT_CLASSES; i++) + info->boatThreshold[i] = boatDensities[i] + info->boatThreshold[i - 1]; } void @@ -515,48 +526,59 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity, { CZone *zone; CZoneInfo *info; - zone = GetZone(zoneid); + zone = GetInfoZone(zoneid); info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; - if(pedDensity != -1) info->pedDensity = pedDensity; - if(copDensity != -1) info->copDensity = copDensity; - if(gang0Density != -1) info->gangDensity[0] = gang0Density; - if(gang1Density != -1) info->gangDensity[1] = gang1Density; - if(gang2Density != -1) info->gangDensity[2] = gang2Density; - if(gang3Density != -1) info->gangDensity[3] = gang3Density; - if(gang4Density != -1) info->gangDensity[4] = gang4Density; - if(gang5Density != -1) info->gangDensity[5] = gang5Density; - if(gang6Density != -1) info->gangDensity[6] = gang6Density; - if(gang7Density != -1) info->gangDensity[7] = gang7Density; - if(gang8Density != -1) info->gangDensity[8] = gang8Density; + info->pedDensity = pedDensity; + info->copPedThreshold = copDensity; + info->gangPedThreshold[0] = gang0Density; + info->gangPedThreshold[1] = gang1Density; + info->gangPedThreshold[2] = gang2Density; + info->gangPedThreshold[3] = gang3Density; + info->gangPedThreshold[4] = gang4Density; + info->gangPedThreshold[5] = gang5Density; + info->gangPedThreshold[6] = gang6Density; + info->gangPedThreshold[7] = gang7Density; + info->gangPedThreshold[8] = gang8Density; + + info->gangPedThreshold[0] += info->copPedThreshold; + info->gangPedThreshold[1] = info->gangPedThreshold[0]; + info->gangPedThreshold[2] = info->gangPedThreshold[1]; + info->gangPedThreshold[3] = info->gangPedThreshold[2]; + info->gangPedThreshold[4] = info->gangPedThreshold[3]; + info->gangPedThreshold[5] = info->gangPedThreshold[4]; + info->gangPedThreshold[6] = info->gangPedThreshold[5]; + info->gangPedThreshold[7] = info->gangPedThreshold[6]; + info->gangPedThreshold[8] = info->gangPedThreshold[7]; } +//--MIAMI: done, unused void CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity) { CZone *zone; - zone = GetZone(zoneid); - if(IsNormalZone(zone->type)) - ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity; } +//--MIAMI: done, unused void CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity) { CZone *zone; - zone = GetZone(zoneid); - if(IsNormalZone(zone->type)) - ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity; } +//--MIAMI: done void CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup) { CZone *zone; - zone = GetZone(zoneid); - if(IsNormalZone(zone->type)) - ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup; } +//--MIAMI: done int16 CTheZones::FindAudioZone(CVector *pos) { @@ -568,18 +590,7 @@ CTheZones::FindAudioZone(CVector *pos) return -1; } -eLevelName -CTheZones::FindZoneForPoint(const CVector &pos) -{ - if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("IND_ZON")))) - return LEVEL_INDUSTRIAL; - if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("COM_ZON")))) - return LEVEL_COMMERCIAL; - if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("SUB_ZON")))) - return LEVEL_SUBURBAN; - return LEVEL_NONE; -} - +//--MIAMI: done void CTheZones::AddZoneToAudioZoneArray(CZone *zone) { @@ -590,12 +601,14 @@ CTheZones::AddZoneToAudioZoneArray(CZone *zone) /* This is a bit stupid */ z = -1; - for(i = 0; i < NUMZONES; i++) - if(&ZoneArray[i] == zone) + for(i = 0; i < NUMNAVIGZONES; i++) + if(&NavigationZoneArray[i] == zone) z = i; + assert(NumberOfAudioZones < NUMAUDIOZONES); AudioZoneArray[NumberOfAudioZones++] = z; } +//--MIAMI: done void CTheZones::InitialiseAudioZoneArray(void) { @@ -603,7 +616,7 @@ CTheZones::InitialiseAudioZoneArray(void) CZone *zone; gonext = false; - zone = &ZoneArray[0]; + zone = &NavigationZoneArray[0]; // Go deep first, // set gonext when backing up a level to visit the next child while(zone) @@ -627,6 +640,7 @@ CTheZones::InitialiseAudioZoneArray(void) } } +//--MIAMI: TODO void CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) { @@ -634,32 +648,39 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) int i; *size = SAVE_HEADER_SIZE - + sizeof(int32) // GetIndexForZonePointer + sizeof(m_CurrLevel) + sizeof(FindIndex) + sizeof(int16) // padding - + sizeof(ZoneArray) + sizeof(ZoneInfoArray) - + sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos) + + sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray) + + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos) + sizeof(MapZoneArray) + sizeof(AudioZoneArray) + sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones); WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE); - WriteSaveBuf(buffer, GetIndexForZonePointer(m_pPlayersZone)); WriteSaveBuf(buffer, m_CurrLevel); WriteSaveBuf(buffer, FindIndex); WriteSaveBuf(buffer, (int16)0); // padding - for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){ - CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]); - zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child); - zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent); - zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next); +// TODO(MIAMI): implement SaveOneZone + for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){ + CZone *zone = WriteSaveBuf(buffer, NavigationZoneArray[i]); + zone->child = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].child); + zone->parent = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].parent); + zone->next = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].next); + } + + for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){ + CZone *zone = WriteSaveBuf(buffer, InfoZoneArray[i]); + zone->child = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].child); + zone->parent = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].parent); + zone->next = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].next); } for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) WriteSaveBuf(buffer, ZoneInfoArray[i]); - WriteSaveBuf(buffer, TotalNumberOfZones); + WriteSaveBuf(buffer, TotalNumberOfNavigationZones); + WriteSaveBuf(buffer, TotalNumberOfInfoZones); WriteSaveBuf(buffer, TotalNumberOfZoneInfos); for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) { @@ -687,6 +708,7 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) VALIDATESAVEBUF(*size) } +//--MIAMI: TODO void CTheZones::LoadAllZones(uint8 *buffer, uint32 size) { @@ -695,23 +717,32 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size) CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE); - m_pPlayersZone = GetPointerForZoneIndex(ReadSaveBuf<int32>(buffer)); m_CurrLevel = ReadSaveBuf<eLevelName>(buffer); FindIndex = ReadSaveBuf<int16>(buffer); ReadSaveBuf<int16>(buffer); - for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){ - ZoneArray[i] = ReadSaveBuf<CZone>(buffer); +// TODO(MIAMI): implement LoadOneZone + for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){ + NavigationZoneArray[i] = ReadSaveBuf<CZone>(buffer); + + NavigationZoneArray[i].child = GetPointerForZoneIndex((int32)NavigationZoneArray[i].child); + NavigationZoneArray[i].parent = GetPointerForZoneIndex((int32)NavigationZoneArray[i].parent); + NavigationZoneArray[i].next = GetPointerForZoneIndex((int32)NavigationZoneArray[i].next); + } + + for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){ + InfoZoneArray[i] = ReadSaveBuf<CZone>(buffer); - ZoneArray[i].child = GetPointerForZoneIndex((uintptr)ZoneArray[i].child); - ZoneArray[i].parent = GetPointerForZoneIndex((uintptr)ZoneArray[i].parent); - ZoneArray[i].next = GetPointerForZoneIndex((uintptr)ZoneArray[i].next); + InfoZoneArray[i].child = GetPointerForZoneIndex((int32)InfoZoneArray[i].child); + InfoZoneArray[i].parent = GetPointerForZoneIndex((int32)InfoZoneArray[i].parent); + InfoZoneArray[i].next = GetPointerForZoneIndex((int32)InfoZoneArray[i].next); } for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer); - TotalNumberOfZones = ReadSaveBuf<int16>(buffer); + TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer); + TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer); TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer); for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){ diff --git a/src/core/Zones.h b/src/core/Zones.h index 6549dad5..8d5af182 100644 --- a/src/core/Zones.h +++ b/src/core/Zones.h @@ -2,6 +2,7 @@ #include "Game.h" #include "Gangs.h" +#include "CarCtrl.h" enum eZoneType { @@ -37,31 +38,33 @@ class CZoneInfo public: // Car data int16 carDensity; - int16 carThreshold[6]; - int16 copThreshold; + int16 carThreshold[CCarCtrl::NUM_CAR_CLASSES]; + int16 boatThreshold[CCarCtrl::NUM_BOAT_CLASSES]; int16 gangThreshold[NUM_GANGS]; + int16 copThreshold; // Ped data uint16 pedDensity; - uint16 copDensity; - uint16 gangDensity[NUM_GANGS]; + uint16 gangPedThreshold[NUM_GANGS]; + uint16 copPedThreshold; uint16 pedGroup; }; class CTheZones { - static CZone *m_pPlayersZone; static int16 FindIndex; static uint16 NumberOfAudioZones; static int16 AudioZoneArray[NUMAUDIOZONES]; static uint16 TotalNumberOfMapZones; - static uint16 TotalNumberOfZones; - static CZone ZoneArray[NUMZONES]; + static uint16 TotalNumberOfInfoZones; + static uint16 TotalNumberOfNavigationZones; + static CZone InfoZoneArray[NUMINFOZONES]; static CZone MapZoneArray[NUMMAPZONES]; + static CZone NavigationZoneArray[NUMNAVIGZONES]; static uint16 TotalNumberOfZoneInfos; - static CZoneInfo ZoneInfoArray[2*NUMZONES]; + static CZoneInfo ZoneInfoArray[2*NUMINFOZONES]; public: static eLevelName m_CurrLevel; @@ -71,31 +74,27 @@ public: float minx, float miny, float minz, float maxx, float maxy, float maxz, eLevelName level); - static void CreateMapZone(char *name, eZoneType type, - float minx, float miny, float minz, - float maxx, float maxy, float maxz, - eLevelName level); - static CZone *GetZone(uint16 i) { return &ZoneArray[i]; } - static CZone *GetAudioZone(uint16 i) { return &ZoneArray[AudioZoneArray[i]]; } + static CZone *GetInfoZone(uint16 i) { return &InfoZoneArray[i]; } + static CZone *GetNavigationZone(uint16 i) { return &NavigationZoneArray[i]; } + static CZone *GetMapZone(uint16 i) { return &MapZoneArray[i]; } + static CZone *GetAudioZone(uint16 i) { return &InfoZoneArray[AudioZoneArray[i]]; } static void PostZoneCreation(void); + static void CheckZonesForOverlap(void); static void InsertZoneIntoZoneHierarchy(CZone *zone); static bool InsertZoneIntoZoneHierRecursive(CZone *z1, CZone *z2); static bool ZoneIsEntirelyContainedWithinOtherZone(CZone *z1, CZone *z2); static bool PointLiesWithinZone(const CVector *v, CZone *zone); static eLevelName GetLevelFromPosition(const CVector *v); - static CZone *FindSmallestZonePosition(const CVector *v); - static CZone *FindSmallestZonePositionType(const CVector *v, eZoneType type); - static CZone *FindSmallestZonePositionILN(const CVector *v); - static int16 FindZoneByLabelAndReturnIndex(Const char *name); + static CZone *FindInformationZoneForPosition(const CVector *v); + static CZone *FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig); + static int16 FindZoneByLabelAndReturnIndex(char *name, eZoneType type); + static int16 FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type); static CZoneInfo *GetZoneInfo(const CVector *v, uint8 day); static void GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info); static void SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity, - int16 gang0Num, int16 gang1Num, int16 gang2Num, - int16 gang3Num, int16 gang4Num, int16 gang5Num, - int16 gang6Num, int16 gang7Num, int16 gang8Num, - int16 copNum, - int16 car0Num, int16 car1Num, int16 car2Num, - int16 car3Num, int16 car4Num, int16 car5Num); + int16 copCarDensity, const int16 *gangCarDensities /*[NUMGANGS]*/); + static void SetZoneCivilianCarInfo(uint16 zoneid, uint8 day, + const int16* carDensities, const int16* boatDensities); static void SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity, int16 gang0Density, int16 gang1Density, int16 gang2Density, int16 gang3Density, int16 gang4Density, int16 gang5Density, int16 gang6Density, int16 gang7Density, @@ -104,9 +103,8 @@ public: static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity); static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup); static int16 FindAudioZone(CVector *pos); - static eLevelName FindZoneForPoint(const CVector &pos); - static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; } - static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; } + static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &InfoZoneArray[i]; } + static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - InfoZoneArray; } static void AddZoneToAudioZoneArray(CZone *zone); static void InitialiseAudioZoneArray(void); static void SaveAllZones(uint8 *buffer, uint32 *length); diff --git a/src/core/common.h b/src/core/common.h index f79b199b..ed331bbb 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -187,6 +187,7 @@ public: #if (defined(_MSC_VER)) extern int strcasecmp(const char *str1, const char *str2); +extern int strncasecmp(const char *str1, const char *str2, size_t len); #endif #define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v)) diff --git a/src/core/config.h b/src/core/config.h index 40882128..548092f7 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -3,71 +3,74 @@ enum Config { NUMPLAYERS = 1, - NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC) + NUMCDIMAGES = 6, // gta3.img duplicates (not used on PC) MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, - MODELINFOSIZE = 5500, - TXDSTORESIZE = 850, - EXTRADIRSIZE = 128, + MODELINFOSIZE = 6500, + TXDSTORESIZE = 1385, + COLSTORESIZE = 31, + EXTRADIRSIZE = 256, CUTSCENEDIRSIZE = 512, - SIMPLEMODELSIZE = 5000, - MLOMODELSIZE = 1, - MLOINSTANCESIZE = 1, - TIMEMODELSIZE = 30, + SIMPLEMODELSIZE = 3885, + TIMEMODELSIZE = 385, CLUMPMODELSIZE = 5, - PEDMODELSIZE = 90, - VEHICLEMODELSIZE = 120, - XTRACOMPSMODELSIZE = 2, - TWODFXSIZE = 2000, + WEAPONMODELSIZE = 37, + PEDMODELSIZE = 130, + VEHICLEMODELSIZE = 110, + TWODFXSIZE = 1210, MAXVEHICLESLOADED = 50, // 70 on mobile - NUMOBJECTINFO = 168, // object.dat + NUMOBJECTINFO = 400, // TODO(MIAMI): fantasy // object.dat // Pool sizes - NUMPTRNODES = 30000, // 26000 on PS2 - NUMENTRYINFOS = 5400, // 3200 on PS2 - NUMPEDS = 140, // 90 on PS2 - NUMVEHICLES = 110, // 70 on PS2 - NUMBUILDINGS = 5500, // 4915 on PS2 - NUMTREADABLES = 1214, - NUMOBJECTS = 450, - NUMDUMMIES = 2802, // 2368 on PS2 - NUMAUDIOSCRIPTOBJECTS = 256, - NUMCUTSCENEOBJECTS = 50, - - NUMANIMBLOCKS = 2, - NUMANIMATIONS = 250, + NUMPTRNODES = 50000, + NUMENTRYINFOS = 5400, // only 3200 in VC??? + NUMPEDS = 140, + NUMVEHICLES = 110, + NUMBUILDINGS = 7000, + NUMTREADABLES = 1214, // 1 in VC + NUMOBJECTS = 460, + NUMDUMMIES = 2802, // 2340 in VC + NUMAUDIOSCRIPTOBJECTS = 256, // 192 in VC + NUMCUTSCENEOBJECTS = 50, // does not exist in VC + // TODO(MIAMI): colmodel pool + + NUMANIMBLOCKS = 35, + NUMANIMATIONS = 450, NUMTEMPOBJECTS = 30, // Path data - NUM_PATHNODES = 4930, - NUM_CARPATHLINKS = 2076, + NUM_PATHNODES = 9650, + NUM_CARPATHLINKS = 3500, NUM_MAPOBJECTS = 1250, - NUM_PATHCONNECTIONS = 10260, + NUM_PATHCONNECTIONS = 20400, // Link list lengths NUMALPHALIST = 20, - NUMALPHAENTITYLIST = 150, + NUMBOATALPHALIST = 20, + NUMALPHAENTITYLIST = 200, + NUMALPHAUNTERWATERENTITYLIST = 30, NUMCOLCACHELINKS = 200, NUMREFERENCES = 800, // Zones - NUMAUDIOZONES = 36, - NUMZONES = 50, - NUMMAPZONES = 25, + NUMAUDIOZONES = 14, + NUMINFOZONES = 169, + NUMMAPZONES = 39, + NUMNAVIGZONES = 20, // Cull zones - NUMCULLZONES = 512, - NUMATTRIBZONES = 288, - NUMZONEINDICES = 55000, + NUMATTRIBZONES = 704, + + NUMOCCLUSIONVOLUMES = 350, PATHNODESIZE = 4500, - NUMWEATHERS = 4, + NUMWEATHERS = 7, NUMHOURS = 24, NUMEXTRADIRECTIONALS = 4, @@ -107,11 +110,11 @@ enum Config { NUMPEDROUTES = 200, NUMPHONES = 50, - NUMPEDGROUPS = 31, - NUMMODELSPERPEDGROUP = 8, + NUMPEDGROUPS = 67, + NUMMODELSPERPEDGROUP = 16, NUMSHOTINFOS = 100, - NUMROADBLOCKS = 600, + NUMROADBLOCKS = 300, NUMVISIBLEENTITIES = 2000, NUMINVISIBLEENTITIES = 150, @@ -127,7 +130,7 @@ enum Config { NUM_AUDIO_REFLECTIONS = 5, NUM_SCRIPT_MAX_ENTITIES = 40, - NUM_GARAGE_STORED_CARS = 6, + NUM_GARAGE_STORED_CARS = 4, NUM_CRANES = 8, @@ -191,7 +194,7 @@ enum Config { #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more #define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things -#define MORE_LANGUAGES // Add more translations to the game +//#define MORE_LANGUAGES // Add more translations to the game #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number diff --git a/src/core/main.cpp b/src/core/main.cpp index 1ea8dc7f..9b40b81d 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -81,7 +81,7 @@ RwRGBA gColourTop; bool gameAlreadyInitialised; float NumberOfChunksLoaded; -#define TOTALNUMCHUNKS 73.0f +#define TOTALNUMCHUNKS 95.0f bool g_SlowMode = false; char version_name[64]; @@ -356,6 +356,7 @@ Terminate3D(void) CSprite2d splash; int splashTxdId = -1; +//--MIAMI: done CSprite2d* LoadSplash(const char *name) { @@ -401,22 +402,23 @@ DestroySplashScreen(void) splashTxdId = -1; } +//--MIAMI: done Const char* GetRandomSplashScreen(void) { int index; static int index2 = 0; static char splashName[128]; - static int splashIndex[24] = { - 25, 22, 4, 13, - 1, 21, 14, 16, - 10, 12, 5, 9, - 11, 18, 3, 2, - 19, 23, 7, 17, - 15, 6, 8, 20 + static int splashIndex[12] = { + 1, 2, + 3, 4, + 5, 11, + 6, 8, + 9, 10, + 7, 12 }; - index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)]; + index = splashIndex[2*index2 + CGeneral::GetRandomNumberInRange(0, 2)]; index2++; if(index2 == 6) index2 = 0; @@ -443,17 +445,14 @@ ResetLoadingScreenBar() NumberOfChunksLoaded = 0.0f; } -// TODO: compare with PS2 +//--MIAMI: done void LoadingScreen(const char *str1, const char *str2, const char *splashscreen) { CSprite2d *splash; #ifndef RANDOMSPLASH - if(CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - splashscreen = "mainsc2"; - else - splashscreen = "mainsc1"; + splashscreen = "LOADSC0"; #endif splash = LoadSplash(splashscreen); @@ -474,36 +473,50 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) if(str1){ NumberOfChunksLoaded += 1; +#ifndef RANDOMSPLASH float hpos = SCREEN_SCALE_X(40); - float length = SCREEN_WIDTH - SCREEN_SCALE_X(100); - float vpos = SCREEN_HEIGHT - SCREEN_SCALE_Y(13); - float height = SCREEN_SCALE_Y(7); - CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(40, 53, 68, 255)); + float length = SCREEN_WIDTH - SCREEN_SCALE_X(80); + float top = SCREEN_HEIGHT - SCREEN_SCALE_Y(14); + float bottom = top + SCREEN_SCALE_Y(5); +#else + float hpos = SCREEN_STRETCH_X(40); + float length = SCREEN_STRETCH_X(440); + // this is rather weird + float top = SCREEN_STRETCH_Y(407.4f - 7.0f/3.0f); + float bottom = SCREEN_STRETCH_Y(407.4f + 7.0f/3.0f); +#endif + + CSprite2d::DrawRect(CRect(hpos-1.0f, top-1.0f, hpos+length+1.0f, bottom+1.0f), CRGBA(40, 53, 68, 255)); + + CSprite2d::DrawRect(CRect(hpos, top, hpos+length, bottom), CRGBA(155, 50, 125, 255)); length *= NumberOfChunksLoaded/TOTALNUMCHUNKS; - CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(81, 106, 137, 255)); + CSprite2d::DrawRect(CRect(hpos, top, hpos+length, bottom), CRGBA(255, 150, 225, 255)); // this is done by the game but is unused + CFont::SetBackgroundOff(); CFont::SetScale(SCREEN_SCALE_X(2), SCREEN_SCALE_Y(2)); CFont::SetPropOn(); CFont::SetRightJustifyOn(); + CFont::SetDropShadowPosition(1); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetFontStyle(FONT_HEADING); #ifdef CHATTYSPLASH // my attempt static wchar tmpstr[80]; float yscale = SCREEN_SCALE_Y(0.9f); - vpos -= 45*yscale; + top -= 45*yscale; CFont::SetScale(SCREEN_SCALE_X(0.75f), yscale); CFont::SetPropOn(); CFont::SetRightJustifyOff(); CFont::SetFontStyle(FONT_BANK); CFont::SetColor(CRGBA(255, 255, 255, 255)); AsciiToUnicode(str1, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); - vpos += 22*yscale; + CFont::PrintString(hpos, top, tmpstr); + top += 22*yscale; AsciiToUnicode(str2, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); + CFont::PrintString(hpos, top, tmpstr); #endif } @@ -778,14 +791,17 @@ RenderScene(void) DoRWRenderHorizon(); CRenderer::RenderRoads(); CCoronas::RenderReflections(); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); CRenderer::RenderEverythingBarRoads(); - CRenderer::RenderBoats(); - DefinedState(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWaterLevel::RenderWater(); + CRenderer::RenderBoats(); + CRenderer::RenderFadingInUnderwaterEntities(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); + // CWaterLevel::RenderTransparentWater(); CRenderer::RenderFadingInEntities(); - CRenderer::RenderVehiclesButNotBoats(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWeather::RenderRainStreaks(); + // CCoronas::RenderSunReflection } void @@ -1138,7 +1154,7 @@ void InitialiseGame(void) { LoadingScreen(nil, nil, "loadsc0"); - CGame::Initialise("DATA\\GTA3.DAT"); + CGame::Initialise("DATA\\GTA_VC.DAT"); } RsEventStatus diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 9bc6400c..0e62f3a5 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -199,11 +199,17 @@ ResetCamStatics(void) } static const char *carnames[] = { - "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony", - "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer", - "securica", "banshee", "predator", "bus", "rhino", "barracks", "train", "chopper", "dodo", "coach", "cabbie", "stallion", "rumpo", "rcbandit", - "bellyup", "mrwongs", "mafia", "yardie", "yakuza", "diablos", "columb", "hoods", "airtrain", "deaddodo", "speeder", "reefer", "panlant", "flatbed", - "yankee", "escape", "borgnine", "toyz", "ghost", + "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "rio", "firetruk", "trash", "stretch", "manana", + "infernus", "voodoo", "pony", "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "washing", + "bobcat", "mrwhoop", "bfinject", "hunter", "police", "enforcer", "securica", "banshee", "predator", "bus", + "rhino", "barracks", "cuban", "chopper", "angel", "coach", "cabbie", "stallion", "rumpo", "rcbandit", "romero", + "packer", "sentxs", "admiral", "squalo", "seaspar", "pizzaboy", "gangbur", "airtrain", "deaddodo", "speeder", + "reefer", "tropic", "flatbed", "yankee", "caddy", "zebra", "topfun", "skimmer", "pcj600", "faggio", "freeway", + "rcbaron", "rcraider", "glendale", "oceanic", "sanchez", "sparrow", "patriot", "lovefist", "coastg", "dinghy", + "hermes", "sabre", "sabretur", "pheonix", "walton", "regina", "comet", "deluxo", "burrito", "spand", "marquis", + "baggage", "kaufman", "maverick", "vcnmav", "rancher", "fbiranch", "virgo", "greenwoo", "jetmax", "hotring", + "sandking", "blistac", "polmav", "boxville", "benson", "mesa", "rcgoblin", "hotrina", "hotrinb", + "bloodra", "bloodrb", "vicechee" }; static CTweakVar** TweakVarsList; @@ -307,14 +313,12 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat); static int spawnCarId = MI_LANDSTAL; - e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_GHOST, carnames); + e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_VICECHEE, carnames); DebugMenuEntrySetWrap(e, true); DebugMenuAddCmd("Spawn", "Spawn Car", [](){ - if(spawnCarId == MI_TRAIN || - spawnCarId == MI_CHOPPER || + if(spawnCarId == MI_CHOPPER || spawnCarId == MI_AIRTRAIN || - spawnCarId == MI_DEADDODO || - spawnCarId == MI_ESCAPE) + spawnCarId == MI_DEADDODO) return; SpawnCar(spawnCarId); }); @@ -326,19 +330,20 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Spawn", "Spawn Cheetah", [](){ SpawnCar(MI_CHEETAH); }); DebugMenuAddCmd("Spawn", "Spawn Esperanto", [](){ SpawnCar(MI_ESPERANT); }); DebugMenuAddCmd("Spawn", "Spawn Stallion", [](){ SpawnCar(MI_STALLION); }); - DebugMenuAddCmd("Spawn", "Spawn Kuruma", [](){ SpawnCar(MI_KURUMA); }); + DebugMenuAddCmd("Spawn", "Spawn Washington", [](){ SpawnCar(MI_WASHING); }); DebugMenuAddCmd("Spawn", "Spawn Taxi", [](){ SpawnCar(MI_TAXI); }); DebugMenuAddCmd("Spawn", "Spawn Police", [](){ SpawnCar(MI_POLICE); }); DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); }); DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); }); - DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); }); - DebugMenuAddCmd("Spawn", "Spawn Yardie", [](){ SpawnCar(MI_YARDIE); }); - DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); }); + DebugMenuAddCmd("Spawn", "Spawn Cuban", [](){ SpawnCar(MI_CUBAN); }); + DebugMenuAddCmd("Spawn", "Spawn Voodoo", [](){ SpawnCar(MI_VOODOO); }); + DebugMenuAddCmd("Spawn", "Spawn Sparrow", [](){ SpawnCar(MI_SPARROW); }); DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); }); 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); + DebugMenuAddVarBool8("Render", "Backface Culling", &gBackfaceCulling, nil); #ifdef LIBRW DebugMenuAddVarBool8("Render", "PS2 Alpha test Emu", &gPS2alphaTest, nil); #endif @@ -348,8 +353,6 @@ DebugMenuPopulate(void) 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); diff --git a/src/core/templates.h b/src/core/templates.h index 4f7b8490..465e3bef 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -44,18 +44,20 @@ class CPool int m_allocPtr; public: + // TODO(MIAMI): remove ctor without name argument CPool(int size){ // TODO: use new here m_entries = (U*)malloc(sizeof(U)*size); m_flags = (Flags*)malloc(sizeof(Flags)*size); m_size = size; - m_allocPtr = 0; + m_allocPtr = -1; for(int i = 0; i < size; i++){ m_flags[i].id = 0; m_flags[i].free = 1; } } - + CPool(int size, const char *name) + : CPool(size) {} ~CPool() { Flush(); } @@ -131,7 +133,7 @@ public: // TODO: the cast is unsafe return (int)((U*)entry - m_entries); } - int GetNoOfUsedSpaces(void) const{ + int GetNoOfUsedSpaces(void) const { int i; int n = 0; for(i = 0; i < m_size; i++) @@ -162,6 +164,7 @@ public: memcpy(entries, m_entries, sizeof(U)*m_size); debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ } + int32 GetNoOfFreeSpaces() const { return GetSize() - GetNoOfUsedSpaces(); } }; template<typename T> |