diff options
Diffstat (limited to 'src/core')
41 files changed, 5871 insertions, 2409 deletions
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index d39be754..854ec7d4 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -18,6 +18,7 @@ #include "World.h" #include "Renderer.h" #include "AnimManager.h" +#include "AnimBlendAssocGroup.h" #include "AnimViewer.h" #include "PlayerPed.h" #include "Pools.h" @@ -46,7 +47,6 @@ CEntity *CAnimViewer::pTarget = nil; void CAnimViewer::Render(void) { if (pTarget) { -// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); if (pTarget) { #ifdef FIX_BUGS if(pTarget->IsPed()) @@ -60,11 +60,14 @@ CAnimViewer::Render(void) { void CAnimViewer::Initialise(void) { - LoadingScreen("Loading the ModelViewer", "", GetRandomSplashScreen()); - animTxdSlot = CTxdStore::AddTxdSlot("generic"); - CTxdStore::Create(animTxdSlot); + + // we need messages, messages needs hud, hud needs those int hudSlot = CTxdStore::AddTxdSlot("hud"); CTxdStore::LoadTxd(hudSlot, "MODELS/HUD.TXD"); + CHud::m_Wants_To_Draw_Hud = false; + + animTxdSlot = CTxdStore::AddTxdSlot("generic"); + CTxdStore::Create(animTxdSlot); int particleSlot = CTxdStore::AddTxdSlot("particle"); CTxdStore::LoadTxd(particleSlot, "MODELS/PARTICLE.TXD"); CTxdStore::SetCurrentTxd(animTxdSlot); @@ -73,10 +76,6 @@ CAnimViewer::Initialise(void) { TheCamera.Init(); TheCamera.SetRwCamera(Scene.camera); TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f; - - gbModelViewer = true; - CHud::m_Wants_To_Draw_Hud = false; - ThePaths.Init(); ThePaths.AllocatePathFindInfoMem(4500); CCollision::Init(); @@ -101,6 +100,9 @@ CAnimViewer::Initialise(void) { CStreaming::LoadAllRequestedModels(false); CRenderer::Init(); CVehicleModelInfo::LoadVehicleColours(); +#ifdef FIX_BUGS + CVehicleModelInfo::LoadEnvironmentMaps(); +#endif CAnimManager::LoadAnimFiles(); CWorld::PlayerInFocus = 0; CWeapon::InitialiseWeapons(); @@ -110,7 +112,7 @@ CAnimViewer::Initialise(void) { CTimeCycle::Initialise(); CCarCtrl::Init(); CPlayerPed *player = new CPlayerPed(); - player->SetPosition(0.0f, 0.0f, 0.0f); + player->SetPosition(1000.0f, 1000.0f, 1000.0f); CWorld::Players[0].m_pPed = player; CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; @@ -138,6 +140,25 @@ CAnimViewer::Initialise(void) { } else { // TODO? maybe request some special models here so the thing doesn't crash } + + // From LCS. idk if needed + int vanBlock = CAnimManager::GetAnimationBlockIndex("van"); + int bikesBlock = CAnimManager::GetAnimationBlockIndex("bikes"); + int bikevBlock = CAnimManager::GetAnimationBlockIndex("bikev"); + int bikehBlock = CAnimManager::GetAnimationBlockIndex("bikeh"); + int bikedBlock = CAnimManager::GetAnimationBlockIndex("biked"); + CStreaming::FlushRequestList(); + CStreaming::RequestAnim(vanBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikesBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikevBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikehBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::RequestAnim(bikedBlock, STREAMFLAGS_DEPENDENCY); + CStreaming::LoadAllRequestedModels(false); + CAnimManager::AddAnimBlockRef(vanBlock); + CAnimManager::AddAnimBlockRef(bikesBlock); + CAnimManager::AddAnimBlockRef(bikevBlock); + CAnimManager::AddAnimBlockRef(bikehBlock); + CAnimManager::AddAnimBlockRef(bikedBlock); } int @@ -215,8 +236,7 @@ CAnimViewer::Update(void) { static int modelId = 0; static int animId = 0; - // Please don't make this bool, static bool's are problematic on my side. - static int reloadIFP = 0; + static bool reloadIFP = false; AssocGroupId animGroup = ASSOCGRP_STD; int nextModelId = modelId; @@ -241,7 +261,7 @@ CAnimViewer::Update(void) CAnimManager::Initialise(); CAnimManager::LoadAnimFiles(); - reloadIFP = 0; + reloadIFP = false; } } else { animGroup = ASSOCGRP_STD; @@ -292,14 +312,19 @@ CAnimViewer::Update(void) if (pTarget->IsVehicle() || pTarget->IsPed() || pTarget->IsObject()) { ((CPhysical*)pTarget)->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); } +#ifdef FIX_BUGS + // so we don't end up in the water + pTarget->GetMatrix().GetPosition().z = 10.0f; +#else pTarget->GetMatrix().GetPosition().z = 0.0f; +#endif if (modelInfo->GetModelType() == MITYPE_PED) { ((CPed*)pTarget)->bKindaStayInSamePlace = true; // Triangle in mobile if (pad->GetSquareJustDown()) { - reloadIFP = 1; + reloadIFP = true; AsciiToUnicode("IFP reloaded", gUString); CMessages::AddMessage(gUString, 1000, 0); @@ -316,7 +341,7 @@ CAnimViewer::Update(void) } else if (pad->GetDPadUpJustDown()) { animId--; if (animId < 0) { - animId = NUM_ANIMS - 1; + animId = NUM_STD_ANIMS - 1; } PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId); @@ -325,7 +350,7 @@ CAnimViewer::Update(void) CMessages::AddMessage(gUString, 1000, 0); } else if (pad->GetDPadDownJustDown()) { - animId = (animId == (NUM_ANIMS - 1) ? 0 : animId + 1); + animId = (animId == (NUM_STD_ANIMS - 1) ? 0 : animId + 1); PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId); sprintf(gString, "Current anim: %d", animId); @@ -344,6 +369,11 @@ CAnimViewer::Update(void) AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString); CMessages::AddMessage(gUString, 100, 0); } + + // From LCS + if (CAnimManager::GetAnimAssocGroups()[animGroup].numAssociations <= animId) + animId = 0; + } else if (modelInfo->GetModelType() == MITYPE_VEHICLE) { if (pad->GetLeftShoulder1JustDown()) { diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 7560a86e..2cf1748c 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -180,9 +180,11 @@ CCam::Process(void) Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_FOLLOWPED: +#ifdef PC_PLAYER_CONTROLS if(CCamera::m_bUseMouse3rdPerson) Process_FollowPedWithMouse(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); else +#endif #ifdef FREE_CAM if(CCamera::bFreeCam) Process_FollowPed_Rotation(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); @@ -287,9 +289,11 @@ CCam::Process(void) case MODE_FIGHT_CAM_RUNABOUT: Process_1rstPersonPedOnPC(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; +#ifdef GTA_SCENE_EDIT case MODE_EDITOR: Process_Editor(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; +#endif default: Source = CVector(0.0f, 0.0f, 0.0f); Front = CVector(0.0f, 1.0f, 0.0f); @@ -2703,7 +2707,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(CamTargetEntity->GetClump()); int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD)); RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier); - RwV3dTransformPoints((RwV3d*)&HeadPos, (RwV3d*)&HeadPos, 1, &mats[idx]); + RwV3dTransformPoints(&HeadPos, &HeadPos, 1, &mats[idx]); RwV3d scl = { 0.0f, 0.0f, 0.0f }; RwMatrixScale(&mats[idx], &scl, rwCOMBINEPRECONCAT); @@ -2744,7 +2748,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, Source = HeadPos; // unused: - // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&MidPos, PED_MID); + // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(MidPos, PED_MID); // Source - MidPos; // Look around @@ -2920,8 +2924,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float UseMouse = false; int ZoomInButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_IN); int ZoomOutButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_OUT); - // TODO: enum? this should be mouse wheel up and down - if(ZoomInButton == 4 || ZoomInButton == 5 || ZoomOutButton == 4 || ZoomOutButton == 5){ + if(ZoomInButton == rsMOUSEWHEELUPBUTTON || ZoomInButton == rsMOUSEWHEELDOWNBUTTON || ZoomOutButton == rsMOUSEWHEELUPBUTTON || ZoomOutButton == rsMOUSEWHEELDOWNBUTTON){ if(CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetMouseWheelDown()){ if(CPad::GetPad(0)->SniperZoomIn()){ TargetFOV = FOV - 10.0f; @@ -3734,6 +3737,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) } } +#ifdef PC_PLAYER_CONTROLS if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){ CPed *player = FindPlayerPed(); if(player && player->CanStrafeOrMouseControl()){ @@ -3744,6 +3748,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) TheCamera.pTargetEntity->GetMatrix().UpdateRW(); } } +#endif } void @@ -4034,6 +4039,7 @@ CCam::Process_Debug(const CVector&, float, float, float) } #endif +#ifdef GTA_SCENE_EDIT void CCam::Process_Editor(const CVector&, float, float, float) { @@ -4112,6 +4118,7 @@ CCam::Process_Editor(const CVector&, float, float, float) sprintf(str, "Look@: %f, Look@: %f, Look@: %f ", Front.x + Source.x, Front.y + Source.y, Front.z + Source.z); } } +#endif void CCam::Process_ModelView(const CVector &CameraTarget, float, float, float) @@ -4125,6 +4132,12 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float) Distance += CPad::GetPad(0)->GetLeftStickY()/1000.0f; else Distance += CPad::GetPad(0)->GetLeftStickY() * ((Distance - 10.0f)/20.0f + 1.0f) / 1000.0f; +#ifdef IMPROVED_CAMERA + if(CPad::GetPad(0)->GetLeftMouse()){ + Distance += DEGTORAD(CPad::GetPad(0)->GetMouseY()/2.0f); + Angle += DEGTORAD(CPad::GetPad(0)->GetMouseX()/2.0f); + } +#endif if(Distance < 1.5f) Distance = 1.5f; @@ -4903,13 +4916,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, if (FOV > DefaultFOV) // 0.98f: CAR_FOV_FADE_MULT - FOV = pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; + FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; - if (FOV <= DefaultFOV + 30.0f) { - if (FOV < DefaultFOV) - FOV = DefaultFOV; - } else - FOV = DefaultFOV + 30.0f; + FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f); } // WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta) @@ -5036,7 +5045,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, targetAlpha = maxAlphaAllowed; } float maxAlphaBlendAmount = CTimer::GetTimeStep() * CARCAM_SET[camSetArrPos][6]; - float targetAlphaBlendAmount = (1.0f - pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); + float targetAlphaBlendAmount = (1.0f - Pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); if (targetAlphaBlendAmount <= maxAlphaBlendAmount) { if (targetAlphaBlendAmount < -maxAlphaBlendAmount) targetAlphaBlendAmount = -maxAlphaBlendAmount; @@ -5048,7 +5057,6 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float stickX = -(pad->GetCarGunLeftRight()); float stickY = pad->GetCarGunUpDown(); - // In SA this checks for m_bUseMouse3rdPerson so num2/num8 do not move camera when Keyboard & Mouse controls are used. if (CCamera::m_bUseMouse3rdPerson) stickY = 0.0f; @@ -5128,7 +5136,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float betaSpeedFromStickX = xMovement * CARCAM_SET[camSetArrPos][12]; float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9]; - float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); + float angleChangeStep = Pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f); if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount) @@ -5240,69 +5248,78 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // SA calls SetColVarsVehicle in here if (nextDirectionIsForward) { - // This is new in LCS! + // LCS uses exactly the same collision code as FollowPedWithMouse, so we will do so. + + // This is only in LCS! float timestepFactor = Pow(0.99f, CTimer::GetTimeStep()); dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude()); - // Move cam if on collision - CColPoint foundCol; - CEntity* foundEnt; + // Our addition +#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && IsLightObject(ent->GetModelIndex())) + + // Clip Source and fix near clip + CColPoint colPoint; + CEntity* entity; CWorld::pIgnoreEntity = CamTargetEntity; - if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { - float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - float obstacleCamDist = newDistance - obstacleTargetDist; - if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) { - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f)); - } - } else { - if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { - float lessClip = obstacleCamDist - 0.35f; - if (lessClip <= DEFAULT_NEAR) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - } else { - obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - float lessClip = obstacleTargetDist - 0.3f; - if (lessClip >= 0.05f) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, 0.05f); - } + if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) && !IS_TRAFFIC_LIGHT(entity)){ + float PedColDist = (TargetCoors - colPoint.point).Magnitude(); + float ColCamDist = newDistance - PedColDist; + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ + // Ped in the way but not clipping through + if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) || IS_TRAFFIC_LIGHT(entity)){ + PedColDist = (TargetCoors - colPoint.point).Magnitude(); + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); + }else{ + RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR)); } + }else{ + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); } } + CWorld::pIgnoreEntity = nil; - float nearClip = RwCameraGetNearClipPlane(Scene.camera); - float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; // If we're seeing blue hell due to camera intersects some surface, fix it. // SA and LCS have this unrolled. - for (int i = 0; - i <= 5 && CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false); - i++) { - - CVector surfaceCamDist = gaTempSphereColPoints->point - Source; - CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front; - float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius; - - if (newNearClip > nearClip) - newNearClip = nearClip; - if (newNearClip < 0.1f) - newNearClip = 0.1f; - if (nearClip > newNearClip) - RwCameraSetNearClipPlane(Scene.camera, newNearClip); - - if (newNearClip == 0.1f) - Source += (TargetCoors - Source) * 0.3f; - - nearClip = RwCameraGetNearClipPlane(Scene.camera); - radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; + + float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); + float ViewPlaneWidth = ViewPlaneHeight * CDraw::CalculateAspectRatio() * fTweakFOV; + float Near = RwCameraGetNearClipPlane(Scene.camera); + float radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + int i = 0; + while(entity){ + + if (IS_TRAFFIC_LIGHT(entity)) + break; + + CVector CamToCol = gaTempSphereColPoints[0].point - Source; + float frontDist = DotProduct(CamToCol, Front); + float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth; + + // Try to decrease near clip + dist = Max(Min(Near, dist), 0.1f); + if(dist < Near) + RwCameraSetNearClipPlane(Scene.camera, dist); + + // Move forward a bit + if(dist == 0.1f) + Source += (TargetCoors - Source)*0.3f; + + // Keep testing + Near = RwCameraGetNearClipPlane(Scene.camera); + radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + + i++; + if(i > 5) + entity = nil; } +#undef IS_TRAFFIC_LIGHT } TheCamera.m_bCamDirectlyBehind = false; TheCamera.m_bCamDirectlyInFront = false; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 2fa81d24..d245bb5a 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -69,7 +69,11 @@ enum // NB: removed explicit TheCamera from all functions CCamera TheCamera; +#ifdef PC_PLAYER_CONTROLS bool CCamera::m_bUseMouse3rdPerson = true; +#else +bool CCamera::m_bUseMouse3rdPerson = false; +#endif bool bDidWeProcessAnyCinemaCam; static bool bSwitchedToObbeCam; float CCamera::m_fMouseAccelHorzntl; @@ -612,7 +616,7 @@ CCamera::Process(void) // LOD dist if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()){ - LODDistMultiplier = 70.0f/CDraw::GetFOV() * CDraw::GetAspectRatio()/(4.0f/3.0f); + LODDistMultiplier = 70.0f/CDraw::GetFOV(); if(GetPosition().z > 55.0f && FindPlayerVehicle() && FindPlayerVehicle()->pHandling->Flags & (HANDLING_IS_HELI|HANDLING_IS_PLANE) || FindPlayerPed()->m_attachedTo){ @@ -1008,22 +1012,26 @@ CCamera::CamControl(void) ReqMode = CCam::MODE_FOLLOWPED; // Check 1st person mode - if(m_bLookingAtPlayer && pTargetEntity->IsPed() && !m_WideScreenOn && !Cams[0].Using3rdPersonMouseCam() + if((m_bLookingAtPlayer || m_bEnable1rstPersonCamCntrlsScript) && pTargetEntity->IsPed() && + (!m_WideScreenOn || m_bEnable1rstPersonCamCntrlsScript) && !Cams[0].Using3rdPersonMouseCam() #ifdef FREE_CAM - && !CCamera::bFreeCam + && (!CCamera::bFreeCam || m_bEnable1rstPersonCamCntrlsScript) #endif ){ // See if we want to enter first person mode if(CPad::GetPad(0)->LookAroundLeftRight() || CPad::GetPad(0)->LookAroundUpDown()){ m_uiFirstPersonCamLastInputTime = CTimer::GetTimeInMilliseconds(); m_bFirstPersonBeingUsed = true; - }else if(m_bFirstPersonBeingUsed){ + } + if(m_bFirstPersonBeingUsed){ // Or if we want to go back to 3rd person if(CPad::GetPad(0)->GetPedWalkLeftRight() || CPad::GetPad(0)->GetPedWalkUpDown() || CPad::GetPad(0)->GetSquare() || CPad::GetPad(0)->GetTriangle() || CPad::GetPad(0)->GetCross() || CPad::GetPad(0)->GetCircle() || CTimer::GetTimeInMilliseconds() - m_uiFirstPersonCamLastInputTime > 2850.0f){ m_bFirstPersonBeingUsed = false; + }else if(CPad::GetPad(0)->TargetJustDown()){ + m_bFirstPersonBeingUsed = false; m_bJustJumpedOutOf1stPersonBecauseOfTarget = true; } } @@ -1129,27 +1137,31 @@ CCamera::CamControl(void) }else{ whichDoor = 1; garageDoorPos1 = Cams[ActiveCam].Source; - garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2.0f, (stairsZone->miny+stairsZone->maxy)/2.0f, 0.0f); - if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f && - pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f && - pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){ -// if((garageCenter-garageDoorPos1).Magnitude() > 15.0f){ - bool bClearViewOutside = true; - CVector dirOutside = pTargetEntity->GetPosition() - garageCenter; - dirOutside.z = 0.0f; - dirOutside.Normalise(); - float zoneDim = stairsZone->maxx - stairsZone->minx; - if(zoneDim < stairsZone->maxy - stairsZone->miny) - zoneDim = stairsZone->maxy - stairsZone->miny; - zoneDim *= 2.0f; - CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside; - if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){ - posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside; - if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)) - bClearViewOutside = false; + + if(stairsZone){ // always true + garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2, (stairsZone->miny+stairsZone->maxy)/2, 0.0f); + if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f && + pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f && + pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){ + garageDoorPos1 = CVector(382.6f, -489.6f, 13.1f); + }else{ + bool bClearViewOutside = true; + CVector dirOutside = pTargetEntity->GetPosition() - garageCenter; + dirOutside.z = 0.0f; + dirOutside.Normalise(); + float zoneDim = stairsZone->maxx - stairsZone->minx; + if(zoneDim < stairsZone->maxy - stairsZone->miny) + zoneDim = stairsZone->maxy - stairsZone->miny; + zoneDim *= 2.0f; + CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside; + if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){ + posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside; + if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)) + bClearViewOutside = false; + } + if(bClearViewOutside) + garageDoorPos1 = posOutside; } - if(bClearViewOutside) - garageDoorPos1 = posOutside; } } @@ -1159,7 +1171,7 @@ CCamera::CamControl(void) garageCenter.z = 0.0f; }else{ garageDoorPos1.z = 0.0f; - if(stairs == nil) // how can this be true? + if(!stairs) // how can this be true? garageCenter = CVector(pTargetEntity->GetPosition().x, pTargetEntity->GetPosition().y, 0.0f); } if(whichDoor == 1) @@ -1598,8 +1610,10 @@ CCamera::CamControl(void) switchByJumpCut = true; } } +#ifdef GTA_SCENE_EDIT if(CSceneEdit::m_bEditOn) ReqMode = CCam::MODE_EDITOR; +#endif if((m_uiTransitionState == 0 || switchByJumpCut) && ReqMode != Cams[ActiveCam].Mode){ if(switchByJumpCut){ @@ -1698,7 +1712,7 @@ CCamera::CamControl(void) StartTransitionWhenNotFinishedInter(ReqMode); pTargetEntity->RegisterReference(&pTargetEntity); Cams[ActiveCam].CamTargetEntity->RegisterReference(&Cams[ActiveCam].CamTargetEntity); - }else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT){ + }else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT || jumpCutTo1stPrs){ m_uiTransitionState = 0; m_vecDoingSpecialInterPolation = false; if(m_bEnable1rstPersonCamCntrlsScript && ReqMode == CCam::MODE_1STPERSON) @@ -3385,12 +3399,12 @@ CCamera::LoadTrainCamNodes(char const *name) char token[16] = { 0 }; char filename[16] = { 0 }; uint8 *buf; - size_t bufpos = 0; + ssize_t bufpos = 0; int field = 0; int tokpos = 0; char c; int i; - size_t len; + ssize_t len; strcpy(filename, name); len = (int)strlen(filename); @@ -3617,6 +3631,8 @@ CCamera::LoadPathSplines(int file) m_arrPathArray[i].m_arr_PathData[j] = atof(token); i++; j = 0; + if (i == MAX_NUM_OF_SPLINETYPES) + reading = false; memset(token, 0, 32); n = 0; } diff --git a/src/core/Camera.h b/src/core/Camera.h index ff74931c..4da7b499 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -209,7 +209,9 @@ public: void PrintMode(void); void Process_Debug(const CVector&, float, float, float); +#ifdef GTA_SCENE_EDIT void Process_Editor(const CVector&, float, float, float); +#endif void Process_ModelView(const CVector &CameraTarget, float, float, float); void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float); diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp index c11fb72a..4bb31ea4 100644 --- a/src/core/CdStream.cpp +++ b/src/core/CdStream.cpp @@ -5,6 +5,7 @@ #include "CdStream.h" #include "rwcore.h" #include "RwHelper.h" +#include "MemoryMgr.h" #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) @@ -72,7 +73,11 @@ CdStreamInitThread(void) gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); +#ifdef FIX_BUGS + gCdStreamSema = CreateSemaphore(nil, 0, 5, nil); +#else gCdStreamSema = CreateSemaphore(nil, 0, 5, "CdStream"); +#endif if ( gCdStreamSema == nil ) { @@ -242,8 +247,15 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) else return STREAM_SUCCESS; } - + +#ifdef BIG_IMG + LARGE_INTEGER liDistanceToMove; + liDistanceToMove.QuadPart = _GET_OFFSET(offset); + liDistanceToMove.QuadPart *= CDSTREAM_SECTOR_SIZE; + SetFilePointerEx(hImage, liDistanceToMove, nil, FILE_BEGIN); +#else SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN); +#endif DWORD NumberOfBytesRead; diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 5c8d1b16..0854d850 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -16,7 +16,7 @@ #include "CdStream.h" #include "rwcore.h" -#include "RwHelper.h" +#include "MemoryMgr.h" #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) @@ -429,7 +429,7 @@ void *CdStreamThread(void *param) ASSERT(pChannel->hFile >= 0); ASSERT(pChannel->pBuffer != nil ); - lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET); + lseek(pChannel->hFile, (size_t)pChannel->nSectorOffset * (size_t)CDSTREAM_SECTOR_SIZE, SEEK_SET); if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) { // pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel // STREAM_WAITING is a little hack to make CStreaming not process this data diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp deleted file mode 100644 index bca1e9b7..00000000 --- a/src/core/ColStore.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#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(); - } -} - -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 deleted file mode 100644 index 8e2a3a70..00000000 --- a/src/core/ColStore.h +++ /dev/null @@ -1,43 +0,0 @@ -#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/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index 51e942d0..fe865865 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -2348,8 +2348,252 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act return num; } +#ifdef BIND_VEHICLE_FIREWEAPON +#define VFB(b) b, +#else +#define VFB(b) +#endif + +#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT) \ + {{ \ + O, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + nil, /* GO_LEFT */ \ + nil, /* GO_RIGHT */ \ + Q, /* PED_SNIPER_ZOOM_IN */ \ + X, /* PED_SNIPER_ZOOM_OUT */ \ + T, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + X, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + VFB(O) /* VEHICLE_FIREWEAPON */ \ + X, /* VEHICLE_ACCELERATE */ \ + Q, /* VEHICLE_BRAKE */ \ + L1, /* VEHICLE_CHANGE_RADIO_STATION */ \ + L3, /* VEHICLE_HORN */ \ + R3, /* TOGGLE_SUBMISSIONS */ \ + R1, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + nil, /* VEHICLE_TURRETLEFT */ \ + nil, /* VEHICLE_TURRETRIGHT */ \ + nil, /* VEHICLE_TURRETUP */ \ + nil, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + R1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }, \ + { \ + O, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + nil, /* GO_LEFT */ \ + nil, /* GO_RIGHT */ \ + Q, /* PED_SNIPER_ZOOM_IN */ \ + X, /* PED_SNIPER_ZOOM_OUT */ \ + T, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + X, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + VFB(O) /* VEHICLE_FIREWEAPON */ \ + X, /* VEHICLE_ACCELERATE */ \ + Q, /* VEHICLE_BRAKE */ \ + SELECT, /* VEHICLE_CHANGE_RADIO_STATION */ \ + L1, /* VEHICLE_HORN */ \ + R3, /* TOGGLE_SUBMISSIONS */ \ + R1, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + nil, /* VEHICLE_TURRETLEFT */ \ + nil, /* VEHICLE_TURRETRIGHT */ \ + nil, /* VEHICLE_TURRETUP */ \ + nil, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + R1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }, \ + { \ + X, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + nil, /* GO_LEFT */ \ + nil, /* GO_RIGHT */ \ + T, /* PED_SNIPER_ZOOM_IN */ \ + Q, /* PED_SNIPER_ZOOM_OUT */ \ + L1, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + O, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + VFB(O) /* VEHICLE_FIREWEAPON */ \ + X, /* VEHICLE_ACCELERATE */ \ + Q, /* VEHICLE_BRAKE */ \ + L3, /* VEHICLE_CHANGE_RADIO_STATION */ \ + R1, /* VEHICLE_HORN */ \ + R3, /* TOGGLE_SUBMISSIONS */ \ + T, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + nil, /* VEHICLE_TURRETLEFT */ \ + nil, /* VEHICLE_TURRETRIGHT */ \ + nil, /* VEHICLE_TURRETUP */ \ + nil, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + T, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + R1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }, \ + { \ + R1, /* PED_FIREWEAPON */ \ + R2, /* PED_CYCLE_WEAPON_RIGHT */ \ + L2, /* PED_CYCLE_WEAPON_LEFT */ \ + nil, /* GO_FORWARD */ \ + nil, /* GO_BACK */ \ + nil, /* GO_LEFT */ \ + nil, /* GO_RIGHT */ \ + Q, /* PED_SNIPER_ZOOM_IN */ \ + X, /* PED_SNIPER_ZOOM_OUT */ \ + T, /* VEHICLE_ENTER_EXIT */ \ + SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \ + Q, /* PED_JUMPING */ \ + X, /* PED_SPRINT */ \ + R3, /* PED_LOOKBEHIND */ \ + VFB(R1) /* VEHICLE_FIREWEAPON */ \ + nil, /* VEHICLE_ACCELERATE */ \ + nil, /* VEHICLE_BRAKE */ \ + O, /* VEHICLE_CHANGE_RADIO_STATION */ \ + L3, /* VEHICLE_HORN */ \ + Q, /* TOGGLE_SUBMISSIONS */ \ + L1, /* VEHICLE_HANDBRAKE */ \ + nil, /* PED_1RST_PERSON_LOOK_LEFT */ \ + nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \ + L2, /* VEHICLE_LOOKLEFT */ \ + R2, /* VEHICLE_LOOKRIGHT */ \ + nil, /* VEHICLE_LOOKBEHIND */ \ + nil, /* VEHICLE_TURRETLEFT */ \ + nil, /* VEHICLE_TURRETRIGHT */ \ + nil, /* VEHICLE_TURRETUP */ \ + nil, /* VEHICLE_TURRETDOWN */ \ + L2, /* PED_CYCLE_TARGET_LEFT */ \ + R2, /* PED_CYCLE_TARGET_RIGHT */ \ + O, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ + L1, /* PED_LOCK_TARGET */ \ + nil, /* NETWORK_TALK */ \ + nil, /* PED_1RST_PERSON_LOOK_UP */ \ + nil, /* PED_1RST_PERSON_LOOK_DOWN */ \ + nil, /* _CONTROLLERACTION_36 */ \ + nil, /* TOGGLE_DPAD */ \ + nil, /* SWITCH_DEBUG_CAM_ON */ \ + nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ + }} + + +const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK"); + +#ifdef BUTTON_ICONS +const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK"); +#endif + + +#if 0 // set 1 for ps2 fonts +#define PS2_TRIANGLE "\"" +#define PS2_CIRCLE "|" +#define PS2_CROSS "/" +#define PS2_SQUARE "^" +#elif defined(BUTTON_ICONS) +#define PS2_TRIANGLE "~T~" +#define PS2_CIRCLE "~O~" +#define PS2_CROSS "~X~" +#define PS2_SQUARE "~Q~" +#else +#define PS2_TRIANGLE "TRIANGLE" +#define PS2_CIRCLE "CIRCLE" +#define PS2_CROSS "CROSS" +#define PS2_SQUARE "SQUARE" +#endif + +const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] = + CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT"); + +#ifdef BUTTON_ICONS +const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] = + CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT"); +#endif + +#undef PS2_TRIANGLE +#undef PS2_CIRCLE +#undef PS2_CROSS +#undef PS2_SQUARE + +#undef CONTROLLER_BUTTONS +#undef VFB + void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *text, uint16 leight) { +#ifdef DETECT_PAD_INPUT_SWITCH + if (CPad::GetPad(0)->IsAffectedByController) { + wchar wstr[16]; + + // TODO: INI and/or menu setting for Xbox/PS switch +#ifdef BUTTON_ICONS + const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons; +#else + const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons; +#endif + + assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these + AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr); + + CMessages::WideStringCopy(text, wstr, leight); + return; + } +#endif + int32 nums = GetNumOfSettingsForAction((e_ControllerAction)action); int32 sets = 0; diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp index b22ddcb2..8e639656 100644 --- a/src/core/EventList.cpp +++ b/src/core/EventList.cpp @@ -59,7 +59,6 @@ CEventList::Update(void) } } -// ok void CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout) { @@ -121,7 +120,7 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent } if(criminal == FindPlayerPed()) - ReportCrimeForEvent(type, (uintptr)ent, copsDontCare); + ReportCrimeForEvent(type, (intptr)ent, copsDontCare); } void @@ -199,7 +198,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event) } void -CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare) +CEventList::ReportCrimeForEvent(eEventType type, intptr crimeId, bool copsDontCare) { eCrimeType crime; switch(type){ diff --git a/src/core/EventList.h b/src/core/EventList.h index dcca1270..3e9d8fd4 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -62,7 +62,7 @@ public: static bool GetEvent(eEventType type, int32 *event); static void ClearEvent(int32 event); static bool FindClosestEvent(eEventType type, CVector posn, int32 *event); - static void ReportCrimeForEvent(eEventType type, size_t, bool); + static void ReportCrimeForEvent(eEventType type, intptr, bool); }; extern CEvent gaEvent[NUMEVENTS];
\ No newline at end of file diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 1c9b4036..9aaba611 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -2,6 +2,7 @@ #include <ctype.h> #include "main.h" +#include "General.h" #include "Quaternion.h" #include "ModelInfo.h" #include "ModelIndices.h" @@ -11,7 +12,6 @@ #include "HandlingMgr.h" #include "CarCtrl.h" #include "PedType.h" -#include "PedStats.h" #include "AnimManager.h" #include "Game.h" #include "RwHelper.h" @@ -25,6 +25,7 @@ #include "ZoneCull.h" #include "CdStream.h" #include "FileLoader.h" +#include "MemoryHeap.h" #include "Streaming.h" #include "ColStore.h" #include "Occlusion.h" @@ -69,17 +70,19 @@ CFileLoader::LoadLevel(const char *filename) if(*line == '#') continue; - if(strncmp(line, "EXIT", 9) == 0) // BUG: 9? + if(strncmp(line, "EXIT", 4) == 0) break; if(strncmp(line, "IMAGEPATH", 9) == 0){ RwImageSetPath(line + 10); }else if(strncmp(line, "TEXDICTION", 10) == 0){ + PUSH_MEMID(MEMID_TEXTURES); strcpy(txdname, line+11); LoadingScreenLoadingFile(txdname); RwTexDictionary *txd = LoadTexDictionary(txdname); AddTexDictionaries(savedTxd, txd); RwTexDictionaryDestroy(txd); + POP_MEMID(); }else if(strncmp(line, "COLFILE", 7) == 0){ LoadingScreenLoadingFile(line+10); LoadCollisionFile(line+10, 0); @@ -95,22 +98,30 @@ CFileLoader::LoadLevel(const char *filename) }else if(strncmp(line, "IPL", 3) == 0){ if(!objectsLoaded){ LoadingScreenLoadingFile("Collision"); + PUSH_MEMID(MEMID_WORLD); CObjectData::Initialise("DATA\\OBJECT.DAT"); CStreaming::Init(); + POP_MEMID(); + PUSH_MEMID(MEMID_COLLISION); CColStore::LoadAllCollision(); + POP_MEMID(); for(int i = 0; i < MODELINFOSIZE; i++) if(CModelInfo::GetModelInfo(i)) CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex(); objectsLoaded = true; } + PUSH_MEMID(MEMID_WORLD); LoadingScreenLoadingFile(line + 4); LoadScene(line + 4); + POP_MEMID(); }else if(strncmp(line, "SPLASH", 6) == 0){ #ifndef DISABLE_LOADING_SCREEN LoadSplash(GetRandomSplashScreen()); #endif +#ifndef GTA_PS2 }else if(strncmp(line, "CDIMAGE", 7) == 0){ CdStreamAddImage(line + 8); +#endif } } @@ -161,7 +172,7 @@ CFileLoader::LoadTexDictionary(const char *filename) struct ColHeader { - char ident[4]; + uint32 ident; uint32 size; }; @@ -173,12 +184,14 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) CBaseModelInfo *mi; ColHeader header; + PUSH_MEMID(MEMID_COLLISION); + 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); + assert(header.ident == 'LLOC'); CFileMgr::Read(fd, (char*)work_buff, header.size); memcpy(modelname, work_buff, 24); @@ -198,6 +211,8 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) } CFileMgr::CloseFile(fd); + + POP_MEMID(); } @@ -213,7 +228,7 @@ CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlo while(size > 8){ header = (ColHeader*)buffer; modelsize = header->size; - if(strncmp(header->ident, "COLL", 4) != 0) + if(header->ident != 'LLOC') return size-8 < CDSTREAM_SECTOR_SIZE; memcpy(modelname, buffer+8, 24); memcpy(work_buff, buffer+32, modelsize-24); @@ -247,7 +262,7 @@ CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot) while(size > 8){ header = (ColHeader*)buffer; modelsize = header->size; - if(strncmp(header->ident, "COLL", 4) != 0) + if(header->ident != 'LLOC') return size-8 < CDSTREAM_SECTOR_SIZE; memcpy(modelname, buffer+8, 24); memcpy(work_buff, buffer+32, modelsize-24); @@ -292,6 +307,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 44; if(model.numSpheres > 0){ model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere)); + REGISTER_MEMPTR(&model.spheres); for(i = 0; i < model.numSpheres; i++){ model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]); buf += 20; @@ -316,6 +332,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(model.numBoxes > 0){ model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox)); + REGISTER_MEMPTR(&model.boxes); for(i = 0; i < model.numBoxes; i++){ model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]); buf += 28; @@ -327,6 +344,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(numVertices > 0){ model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector)); + REGISTER_MEMPTR(&model.vertices); for(i = 0; i < numVertices; i++){ model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8)); #if 0 @@ -344,6 +362,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(model.numTriangles > 0){ model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle)); + REGISTER_MEMPTR(&model.triangles); for(i = 0; i < model.numTriangles; i++){ model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]); buf += 16; @@ -567,6 +586,9 @@ CFileLoader::AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src) RwTexDictionaryForAllTextures(src, MoveTexturesCB, dst); } +#define isLine3(l, a, b, c) ((l[0] == a) && (l[1] == b) && (l[2] == c)) +#define isLine4(l, a, b, c, d) ((l[0] == a) && (l[1] == b) && (l[2] == c) && (l[3] == d)) + void CFileLoader::LoadObjectTypes(const char *filename) { @@ -602,15 +624,15 @@ CFileLoader::LoadObjectTypes(const char *filename) continue; 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){ + if(isLine4(line, 'o','b','j','s')) section = OBJS; + else if(isLine4(line, 't','o','b','j')) section = TOBJ; + else if(isLine4(line, 'w','e','a','p')) section = WEAP; + else if(isLine4(line, 'h','i','e','r')) section = HIER; + else if(isLine4(line, 'c','a','r','s')) section = CARS; + else if(isLine4(line, 'p','e','d','s')) section = PEDS; + else if(isLine4(line, 'p','a','t','h')) section = PATH; + else if(isLine4(line, '2','d','f','x')) section = TWODFX; + }else if(isLine3(line, 'e','n','d')){ section = NONE; }else switch(section){ case OBJS: @@ -843,21 +865,21 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_level = level; mi->m_compRules = comprules; - if(strncmp(type, "car", 4) == 0){ + if(strcmp(type, "car") == 0){ mi->m_wheelId = misc; mi->m_wheelScale = wheelScale; mi->m_vehicleType = VEHICLE_TYPE_CAR; - }else if(strncmp(type, "boat", 5) == 0){ + }else if(strcmp(type, "boat") == 0){ mi->m_vehicleType = VEHICLE_TYPE_BOAT; - }else if(strncmp(type, "train", 6) == 0){ + }else if(strcmp(type, "train") == 0){ mi->m_vehicleType = VEHICLE_TYPE_TRAIN; - }else if(strncmp(type, "heli", 5) == 0){ + }else if(strcmp(type, "heli") == 0){ mi->m_vehicleType = VEHICLE_TYPE_HELI; - }else if(strncmp(type, "plane", 6) == 0){ + }else if(strcmp(type, "plane") == 0){ mi->m_planeLodId = misc; mi->m_wheelScale = 1.0f; mi->m_vehicleType = VEHICLE_TYPE_PLANE; - }else if(strncmp(type, "bike", 5) == 0){ + }else if(strcmp(type, "bike") == 0){ mi->m_bikeSteerAngle = misc; mi->m_wheelScale = wheelScale; mi->m_vehicleType = VEHICLE_TYPE_BIKE; @@ -866,29 +888,29 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId); - if(strncmp(vehclass, "normal", 7) == 0) + if(strcmp(vehclass, "normal") == 0) mi->m_vehicleClass = CCarCtrl::NORMAL; - else if(strncmp(vehclass, "poorfamily", 11) == 0) + else if(strcmp(vehclass, "poorfamily") == 0) mi->m_vehicleClass = CCarCtrl::POOR; - else if(strncmp(vehclass, "richfamily", 11) == 0) + else if(strcmp(vehclass, "richfamily") == 0) mi->m_vehicleClass = CCarCtrl::RICH; - else if(strncmp(vehclass, "executive", 10) == 0) + else if(strcmp(vehclass, "executive") == 0) mi->m_vehicleClass = CCarCtrl::EXEC; - else if(strncmp(vehclass, "worker", 7) == 0) + else if(strcmp(vehclass, "worker") == 0) mi->m_vehicleClass = CCarCtrl::WORKER; - else if(strncmp(vehclass, "big", 4) == 0) + else if(strcmp(vehclass, "big") == 0) mi->m_vehicleClass = CCarCtrl::BIG; - else if(strncmp(vehclass, "taxi", 5) == 0) + else if(strcmp(vehclass, "taxi") == 0) mi->m_vehicleClass = CCarCtrl::TAXI; - else if(strncmp(vehclass, "moped", 6) == 0) + else if(strcmp(vehclass, "moped") == 0) mi->m_vehicleClass = CCarCtrl::MOPED; - else if(strncmp(vehclass, "motorbike", 10) == 0) + else if(strcmp(vehclass, "motorbike") == 0) mi->m_vehicleClass = CCarCtrl::MOTORBIKE; - else if(strncmp(vehclass, "leisureboat", 12) == 0) + else if(strcmp(vehclass, "leisureboat") == 0) mi->m_vehicleClass = CCarCtrl::LEISUREBOAT; - else if(strncmp(vehclass, "workerboat", 11) == 0) + else if(strcmp(vehclass, "workerboat") == 0) mi->m_vehicleClass = CCarCtrl::WORKERBOAT; - else if(strncmp(vehclass, "ignore", 11) == 0){ + else if(strcmp(vehclass, "ignore") == 0) { mi->m_vehicleClass = -1; return; } @@ -995,7 +1017,7 @@ CFileLoader::Load2dEffect(const char *line) CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); mi = CModelInfo::GetModelInfo(id); - effect = CModelInfo::Get2dEffectStore().alloc(); + effect = CModelInfo::Get2dEffectStore().Alloc(); mi->Add2dEffect(effect); effect->pos = CVector(x, y, z); effect->col = CRGBA(r, g, b, a); @@ -1103,13 +1125,13 @@ CFileLoader::LoadScene(const char *filename) continue; if(section == NONE){ - if(strncmp(line, "inst", 4) == 0) section = INST; - else if(strncmp(line, "zone", 4) == 0) section = ZONE; - 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){ + if(isLine4(line, 'i','n','s','t')) section = INST; + else if(isLine4(line, 'z','o','n','e')) section = ZONE; + else if(isLine4(line, 'c','u','l','l')) section = CULL; + else if(isLine4(line, 'p','i','c','k')) section = PICK; + else if(isLine4(line, 'p','a','t','h')) section = PATH; + else if(isLine4(line, 'o','c','c','l')) section = OCCL; + }else if(isLine3(line, 'e','n','d')){ section = NONE; }else switch(section){ case INST: @@ -1307,11 +1329,11 @@ CFileLoader::ReloadPaths(const char *filename) continue; if (section == NONE) { - if (strncmp(line, "path", 4) == 0) { + if (isLine4(line, 'p','a','t','h')) { section = PATH; ThePaths.AllocatePathFindInfoMem(4500); } - } else if (strncmp(line, "end", 3) == 0) { + } else if (isLine3(line, 'e','n','d')) { section = NONE; } else { switch (section) { @@ -1362,10 +1384,10 @@ CFileLoader::ReloadObjectTypes(const char *filename) continue; if (section == NONE) { - if (strncmp(line, "objs", 4) == 0) section = OBJS; - else if (strncmp(line, "tobj", 4) == 0) section = TOBJ; - else if (strncmp(line, "2dfx", 4) == 0) section = TWODFX; - } else if (strncmp(line, "end", 3) == 0) { + if (isLine4(line, 'o','b','j','s')) section = OBJS; + else if (isLine4(line, 't','o','b','j')) section = TOBJ; + else if (isLine4(line, '2','d','f','x')) section = TWODFX; + } else if (isLine3(line, 'e','n','d')) { section = NONE; } else { switch (section) { @@ -1438,7 +1460,7 @@ CFileLoader::ReLoadScene(const char *filename) if (*line == '#') continue; - if (strncmp(line, "EXIT", 9) == 0) // BUG: 9? + if (strncmp(line, "EXIT", 4) == 0) break; if (strncmp(line, "IDE", 3) == 0) { diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp index d3695cb4..99923ddf 100644 --- a/src/core/FileMgr.cpp +++ b/src/core/FileMgr.cpp @@ -240,20 +240,22 @@ CFileMgr::SetDirMyDocuments(void) mychdir(_psGetUserFilesFolder()); } -size_t +ssize_t CFileMgr::LoadFile(const char *file, uint8 *buf, int unused, const char *mode) { int fd; - size_t n, len; + ssize_t n, len; fd = myfopen(file, mode); if(fd == 0) - return 0; + return -1; len = 0; do{ n = myfread(buf + len, 1, 0x4000, fd); - if(n < 0) +#ifndef FIX_BUGS + if (n < 0) return -1; +#endif len += n; }while(n == 0x4000); buf[len] = 0; @@ -274,13 +276,13 @@ CFileMgr::OpenFileForWriting(const char *file) } size_t -CFileMgr::Read(int fd, const char *buf, size_t len) +CFileMgr::Read(int fd, const char *buf, ssize_t len) { return myfread((void*)buf, 1, len, fd); } size_t -CFileMgr::Write(int fd, const char *buf, size_t len) +CFileMgr::Write(int fd, const char *buf, ssize_t len) { return myfwrite((void*)buf, 1, len, fd); } diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h index 8278953b..98a78360 100644 --- a/src/core/FileMgr.h +++ b/src/core/FileMgr.h @@ -9,12 +9,12 @@ public: static void ChangeDir(const char *dir); static void SetDir(const char *dir); static void SetDirMyDocuments(void); - static size_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode); + static ssize_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode); static int OpenFile(const char *file, const char *mode); static int OpenFile(const char *file) { return OpenFile(file, "rb"); } static int OpenFileForWriting(const char *file); - static size_t Read(int fd, const char *buf, size_t len); - static size_t Write(int fd, const char *buf, size_t len); + static size_t Read(int fd, const char *buf, ssize_t len); + static size_t Write(int fd, const char *buf, ssize_t len); static bool Seek(int fd, int offset, int whence); static bool ReadLine(int fd, char *buf, int len); static int CloseFile(int fd); diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index a47ca3cf..c4c39b1f 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -46,7 +46,7 @@ CFire::ProcessFire(void) float fDamagePlayer; float fDamagePeds; float fDamageVehicle; - int8 nRandNumber; + int16 nRandNumber; float fGreen; float fRed; CVector lightpos; @@ -107,7 +107,11 @@ CFire::ProcessFire(void) } } } - if (!FindPlayerVehicle() && !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) + if (!FindPlayerVehicle() && +#ifdef FIX_BUGS + FindPlayerPed() && +#endif + !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) && ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) { FindPlayerPed()->DoStuffToGoOnFire(); gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1); @@ -148,11 +152,10 @@ CFire::ProcessFire(void) CShadows::StoreStaticShadow((uintptr)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos, 7.0f, 0.0f, 0.0f, -7.0f, 0, nRandNumber / 2, nRandNumber / 2, 0, 10.0f, 1.0f, 40.0f, 0, 0.0f); } - fGreen = nRandNumber / 128; - fRed = nRandNumber / 128; + fGreen = nRandNumber / 128.f; + fRed = nRandNumber / 128.f; - CPointLights::AddLight(0, m_vecPos, CVector(0.0f, 0.0f, 0.0f), - 12.0f, fRed, fGreen, 0, 0, 0); + CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0.0f, 0, 0); } else { Extinguish(); } @@ -391,19 +394,16 @@ CFireManager::ExtinguishPoint(CVector point, float range) bool CFireManager::ExtinguishPointWithWater(CVector point, float range) { - int fireI = 0; - for (int i = 0; i < NUM_FIRES; i++) { - if (m_aFires[i].m_bIsOngoing) { - if ((point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) { - fireI = i; - break; - } - } - } - if (fireI == NUM_FIRES) - return false; - - CFire *fireToExtinguish = &m_aFires[fireI]; + int i; + for (i = 0; i < NUM_FIRES;) { + if (m_aFires[i].m_bIsOngoing && (point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) { + break; + } + if (++i >= NUM_FIRES) + return false; + } + + CFire *fireToExtinguish = &m_aFires[i]; fireToExtinguish->m_fWaterExtinguishCountdown -= 0.012f * CTimer::GetTimeStep(); CVector steamPos = fireToExtinguish->m_vecPos + CVector((CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f, diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index a52b9bfc..db5da918 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -39,32 +39,61 @@ #include "User.h" #include "sampman.h" -// TODO(Miami): Remove that!! That was my map implementation for III, instead use MAP_ENHACEMENTS on some places -#define CUSTOM_MAP +// --MIAMI: file done // 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); -CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 255); - -#define TIDY_UP_PBP // ProcessUserInput +const CRGBA LABEL_COLOR(255, 150, 225, 255); +const CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255); +const CRGBA MENUOPTION_COLOR = LABEL_COLOR; +const CRGBA SELECTEDMENUOPTION_COLOR = LABEL_COLOR; +const CRGBA HEADER_COLOR = LABEL_COLOR; +const CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); +const CRGBA SLIDERON_COLOR(97, 194, 247, 255); +const CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); +const CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 130); +const CRGBA LIST_OPTION_COLOR(155, 155, 155, 255); +const CRGBA RADIO_SELECTOR_COLOR = SLIDEROFF_COLOR; +const CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100); +const CRGBA SCROLLBAR_COLOR = LABEL_COLOR; + +#define MAP_MIN_SIZE 162.f +#define MAP_SIZE_TO_ALLOW_X_MOVE 297.f + #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result +#define SCROLLABLE_PAGES + +#define hasNativeList(screen) (screen == MENUPAGE_SKIN_SELECT || screen == MENUPAGE_KEYBOARD_CONTROLS) + +#ifdef SCROLLABLE_PAGES +#define MAX_VISIBLE_OPTION 12 +#define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION) +#define SCREEN_HAS_AUTO_SCROLLBAR (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) + +int GetOptionCount(int screen) +{ + int i = 0; + for (; i < NUM_MENUROWS && aScreens[screen].m_aEntries[i].m_Action != MENUACTION_NOTHING; i++); + return i; +} -#ifdef USE_PRECISE_MEASUREMENT_CONVERTION -#define MILES_IN_METER 0.000621371192f -#define FEET_IN_METER 3.28084f +#define SETUP_SCROLLING(screen) \ + if (!hasNativeList(screen)) { \ + m_nTotalListRow = GetOptionCount(screen); \ + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { \ + m_nSelectedListRow = 0; \ + m_nFirstVisibleRowOnList = 0; \ + m_nScrollbarTopMargin = 0; \ + } \ + } + +#define MINUS_SCROLL_OFFSET - scrollOffset #else -#define MILES_IN_METER 0.00059880241f -#define FEET_IN_METER 3.33f +#define MAX_VISIBLE_OPTION_ON_SCREEN MAX_VISIBLE_LIST_ROW +#define SETUP_SCROLLING(screen) +#define MINUS_SCROLL_OFFSET #endif #ifdef TRIANGLE_BACK_BUTTON @@ -78,15 +107,14 @@ CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 255); #define GetBackJustDown GetSquareJustDown #endif +#ifdef MAP_ENHANCEMENTS +CVector2D mapCrosshair; +#endif + #ifdef CUTSCENE_BORDERS_SWITCH bool CMenuManager::m_PrefsCutsceneBorders = true; #endif -const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); // TODO(Miami): is this still here? - -float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; -float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; - bool holdingScrollBar; // *(bool*)0x7039B9; // not original name CMenuManager FrontEndMenuManager; @@ -97,17 +125,11 @@ MenuTrapezoid menuBg(CGeneral::GetRandomNumber() % 40 + 65, CGeneral::GetRandomN MenuTrapezoid menuOptionHighlight(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); -#ifdef CUSTOM_MAP -bool bMapLoaded = false; -bool bMapMouseShownOnce = false; -#endif - #ifndef MASTER bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x68C144 const char* FrontendFilenames[][2] = { {"background", ""}, {"vc_logo", "vc_logom"}, @@ -150,37 +172,59 @@ const char* FrontendFilenames[][2] = { #define MENU_Y(y) StretchY(y) #endif -#define PREPARE_MENU_HEADER \ +#ifdef XBOX_MESSAGE_SCREEN +bool CMenuManager::m_bDialogOpen = false; +uint32 CMenuManager::m_nDialogHideTimer = 0; +PauseModeTime CMenuManager::m_nDialogHideTimerPauseMode = 0; +bool CMenuManager::m_bSaveWasSuccessful = false; +wchar* CMenuManager::m_pDialogText = nil; +#endif + +#define SET_FONT_FOR_MENU_HEADER \ CFont::SetRightJustifyOn(); \ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetDropShadowPosition(0); -#define ProcessSlider(value, y, increaseAction, decreaseAction, hoverStartX, hoverEndX) \ +#define SET_FONT_FOR_LIST_ITEM \ + CFont::SetRightJustifyOff(); \ + CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE)); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + +#define RESET_FONT_FOR_NEW_PAGE \ + CFont::SetBackgroundOff(); \ + CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); \ + CFont::SetPropOn(); \ + CFont::SetCentreOff(); \ + CFont::SetJustifyOn(); \ + CFont::SetRightJustifyOff(); \ + CFont::SetBackGroundOnlyTextOn(); \ + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \ + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN)); + +#define ProcessSlider(value, origY, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \ do { \ + float y = origY MINUS_SCROLL_OFFSET; \ lastActiveBarX = DisplaySlider(MENU_X_LEFT_ALIGNED(MENUSLIDER_X), MENU_Y(y), MENU_Y(MENUSLIDER_SMALLEST_BAR), MENU_Y(MENUSLIDER_BIGGEST_BAR), MENU_X(MENUSLIDER_UNK), value, MENU_X(3.0f)); \ if (i != m_nCurrOption || !itemsAreSelectable) \ break; \ \ - if (CheckHover(hoverStartX, lastActiveBarX - MENU_X(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ + if (CheckHover(0, lastActiveBarX - MENU_X(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) { \ m_nHoverOption = decreaseAction; \ - \ - if (!CheckHover(MENU_X(3.0f) + lastActiveBarX, hoverEndX, MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ break; \ - \ + } \ + if (!CheckHover(MENU_X(3.0f) + lastActiveBarX, hoverEndX, MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) { \ + m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ + break; \ + } \ m_nHoverOption = increaseAction; \ if (m_nMousePosX < MENU_X_LEFT_ALIGNED(MENUSLIDER_X)) \ m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ + \ + if (onlyWhenHoveringRow && (m_nMousePosY < MENU_Y(y) || m_nMousePosY > MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ + 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(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) - // --- Functions not in the game/inlined starts inline void @@ -200,8 +244,8 @@ CMenuManager::ScrollUpListByOne() inline void CMenuManager::ScrollDownListByOne() { - if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { m_nSelectedListRow++; m_nFirstVisibleRowOnList++; m_nScrollbarTopMargin += SCROLLBAR_MAX_HEIGHT / m_nTotalListRow; @@ -216,13 +260,13 @@ CMenuManager::ScrollDownListByOne() inline void CMenuManager::PageUpList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { if (m_nFirstVisibleRowOnList > 0) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); - m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); + m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_OPTION_ON_SCREEN); + m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1); } else { m_nFirstVisibleRowOnList = 0; m_nSelectedListRow = 0; @@ -234,58 +278,144 @@ CMenuManager::PageUpList(bool playSoundOnSuccess) inline void CMenuManager::PageDownList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW); + m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN, m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN); m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList); } else { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; m_nSelectedListRow = m_nTotalListRow - 1; } m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; } } +#ifdef CUSTOM_FRONTEND_OPTIONS +#define PLUS_LINE_HEIGHT_ON_SCREEN + (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->lineHeight : MENU_DEFAULT_LINE_HEIGHT) +bool ScreenHasOption(int screen, const char* gxtKey) +{ + for (int i = 0; i < NUM_MENUROWS; i++) { + if (strcmp(gxtKey, aScreens[screen].m_aEntries[i].m_EntryName) == 0) + return true; + } + return false; +} + inline void CMenuManager::ThingsToDoBeforeLeavingPage() { if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) { CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); + } else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); -#ifdef TIDY_UP_PBP + DMAudio.StopFrontEndTrack(); OutputDebugString("FRONTEND AUDIO TRACK STOPPED"); -#endif - } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { + + } else if (ScreenHasOption(m_nCurrScreen, "FED_RES")) { m_nDisplayVideoMode = m_nPrefsVideoMode; -#ifdef IMPROVED_VIDEOMODE - m_nSelectedScreenMode = m_nPrefsWindowed; -#endif } if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { CPlayerSkin::EndFrontendSkinEdit(); } + +#ifdef SCROLLABLE_PAGES + if (SCREEN_HAS_AUTO_SCROLLBAR) { + m_nSelectedListRow = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0; + } +#endif + + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + + if (option.m_Action == MENUACTION_CFO_DYNAMIC) + if(option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + + if (option.m_Action == MENUACTION_CFO_SELECT && option.m_CFOSelect->onlyApplyOnEnter && option.m_CFOSelect->lastSavedValue != option.m_CFOSelect->displayedValue) + option.m_CFOSelect->displayedValue = *option.m_CFO->value = option.m_CFOSelect->lastSavedValue; + + if (aScreens[m_nCurrScreen].returnPrevPageFunc) { + aScreens[m_nCurrScreen].returnPrevPageFunc(); + } } -int8 +inline int8 +CMenuManager::GetPreviousPageOption() +{ + int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage : + (m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_OPTIONS || m_nCurrScreen == MENUPAGE_EXIT ? MENUPAGE_START_MENU : aScreens[m_nCurrScreen].m_PreviousPage); + + if (prevPage == -1) // Game also does same + return 0; + + prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage; + + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[prevPage].m_aEntries[i].m_Action >= MENUACTION_NOTHING) { // CFO check + if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) { + return i; + } + } + } + + // This shouldn't happen + return 0; +} + +#else +#define PLUS_LINE_HEIGHT_ON_SCREEN + MENU_DEFAULT_LINE_HEIGHT +inline void +CMenuManager::ThingsToDoBeforeLeavingPage() +{ + switch (m_nCurrScreen) { + case MENUPAGE_SOUND_SETTINGS: + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) + m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); + + DMAudio.StopFrontEndTrack(); + OutputDebugString("FRONTEND AUDIO TRACK STOPPED"); + break; + case MENUPAGE_DISPLAY_SETTINGS: + m_nDisplayVideoMode = m_nPrefsVideoMode; + break; + case MENUPAGE_SKIN_SELECT: + if (strcmp(m_aSkinName, m_PrefsSkinFile) != 0) + CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); + + CPlayerSkin::EndFrontendSkinEdit(); + break; + } + +#ifdef SCROLLABLE_PAGES + if (SCREEN_HAS_AUTO_SCROLLBAR) { + m_nSelectedListRow = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0; + } +#endif +} + +inline int8 CMenuManager::GetPreviousPageOption() { return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry : (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry)))); } +#endif // ------ Functions not in the game/inlined ends bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); -// --MIAMI: Done void CMenuManager::SwitchToNewScreen(int8 screen) { @@ -315,8 +445,9 @@ CMenuManager::SwitchToNewScreen(int8 screen) m_nCurrOption = 0; m_nCurrScreen = screen; } - - if (m_nPrevScreen == MENUPAGE_SKIN_SELECT || m_nPrevScreen == MENUPAGE_KEYBOARD_CONTROLS) + SETUP_SCROLLING(m_nCurrScreen) + + if (hasNativeList(m_nPrevScreen)) m_nTotalListRow = 0; if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) @@ -341,7 +472,11 @@ CMenuManager::CMenuManager() m_PrefsMP3BoostVolume = 0; m_PrefsShowSubtitles = 0; m_PrefsShowLegends = 1; +#ifdef ASPECT_RATIO_SCALE + m_PrefsUseWideScreen = AR_AUTO; +#else m_PrefsUseWideScreen = 0; +#endif m_PrefsVsync = 0; m_PrefsVsyncDisp = 1; m_PrefsFrameLimiter = 1; @@ -362,7 +497,11 @@ CMenuManager::CMenuManager() m_PrefsDMA = 1; OS_Language = LANG_ENGLISH; m_ControlMethod = CONTROL_STANDARD; +#ifdef PC_PLAYER_CONTROLS CCamera::m_bUseMouse3rdPerson = true; +#else + CCamera::m_bUseMouse3rdPerson = false; +#endif m_lastWorking3DAudioProvider = 0; m_nFirstVisibleRowOnList = 0; m_nScrollbarTopMargin = 0.0f; @@ -383,11 +522,15 @@ CMenuManager::CMenuManager() m_bWantToLoad = false; m_nMenuFadeAlpha = 0; m_OnlySaveMenu = false; - m_fMapSize = 162.0f; - m_fMapCenterX = 320.0f; - m_fMapCenterY = 225.0f; + m_fMapSize = MENU_Y(162.0f); // Y because of HOR+ + m_fMapCenterX = MENU_X_LEFT_ALIGNED(320.0f); + m_fMapCenterY = MENU_Y(225.0f); DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + +#ifdef NO_ISLAND_LOADING + m_PrefsIslandLoading = ISLAND_LOADING_LOW; +#endif } void @@ -408,15 +551,15 @@ CMenuManager::Initialise(void) DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); DoRWStuffEndOfFrame(); m_AllowNavigation = false; - m_menuTransitionProgress = -50; // to start from black + m_firstStartCounter = -50; // to start from black m_nMenuFadeAlpha = 0; m_nCurrOption = 0; m_nOptionHighlightTransitionBlend = 0; CentreMousePointer(); m_bShowMouse = true; - m_fMapSize = 162.0f; - m_fMapCenterX = 320.0f; - m_fMapCenterY = 225.0f; + m_fMapSize = MENU_Y(162.0f); // Y because of HOR+ + m_fMapCenterX = MENU_X_LEFT_ALIGNED(320.0f); + m_fMapCenterY = MENU_Y(225.0f); CPad::StopPadsShaking(); if (!m_OnlySaveMenu) m_nCurrScreen = MENUPAGE_NONE; @@ -440,37 +583,6 @@ CMenuManager::Initialise(void) } void -CMenuManager::BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2) -{ - if (!text) - return; - -#ifdef MORE_LANGUAGES - if (CFont::IsJapanese() && stat2) - if (itsFloat) - sprintf(gString2, " %.2f/%.2f", *(float*)stat, *(float*)stat2); - else - sprintf(gString2, " %d/%d", *(int*)stat, *(int*)stat2); - else -#endif - if (stat2) { - if (itsFloat) - sprintf(gString2, " %.2f %s %.2f", *(float*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(float*)stat2); - else - sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2); - } else if (stat) { - if (itsFloat) - sprintf(gString2, " %.2f", *(float*)stat); - else - sprintf(gString2, " %d", *(int*)stat); - } else - gString2[0] = '\0'; - - UnicodeStrcpy(gUString, TheText.Get(text)); - AsciiToUnicode(gString2, gUString2); -} - -void CMenuManager::CentreMousePointer() { if (SCREEN_WIDTH * 0.5f != 0.0f && 0.0f != SCREEN_HEIGHT * 0.5f) { @@ -489,7 +601,6 @@ CMenuManager::CentreMousePointer() } } -// --MIAMI: Done void CMenuManager::CheckCodesForControls(int typeOfControl) { @@ -558,7 +669,6 @@ CMenuManager::CheckHover(int x1, int x2, int y1, int y2) m_nMousePosY > y1 && m_nMousePosY < y2; } -// --MIAMI: Done void CMenuManager::CheckSliderMovement(int value) { @@ -601,6 +711,9 @@ CMenuManager::CheckSliderMovement(int value) case MENUACTION_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ??? TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f); +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f; +#endif break; default: return; @@ -608,7 +721,6 @@ CMenuManager::CheckSliderMovement(int value) SaveSettings(); } -// --MIAMI: Done void CMenuManager::DisplayHelperText(char *text) { @@ -624,9 +736,10 @@ CMenuManager::DisplayHelperText(char *text) CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetDropShadowPosition(0); + // We're using SCREEN_STRETCH_FROM_RIGHT, because we also stretch black borders if (text) { CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get(text)); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get(text)); return; } @@ -646,19 +759,19 @@ CMenuManager::DisplayHelperText(char *text) // TODO: name this cases? switch (m_nHelperTextMsgId) { case 1: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_APP")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_APP")); break; case 2: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_HRD")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_HRD")); break; case 3: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSO")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSO")); break; case 4: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_STS")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_STS")); break; case 5: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSC")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSC")); break; default: if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NO) @@ -667,7 +780,7 @@ CMenuManager::DisplayHelperText(char *text) if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MUSICVOLUME || aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SFXVOLUME) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } @@ -676,7 +789,7 @@ CMenuManager::DisplayHelperText(char *text) return; if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SCREENRES) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_bGameNotLoaded ? TheText.Get("FET_MIG") : TheText.Get("FEH_NA")); return; } @@ -684,7 +797,7 @@ CMenuManager::DisplayHelperText(char *text) if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_AUDIOHW || aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SPEAKERCONF) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } @@ -693,19 +806,18 @@ CMenuManager::DisplayHelperText(char *text) return; if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MP3VOLUMEBOOST) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nCurrScreen != MENUPAGE_STATS ? TheText.Get("FET_MIG") : TheText.Get("FEH_SSA")); break; } } -// --MIAMI: Done int CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress, float spacing) { @@ -737,7 +849,6 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR return lastActiveBarX; } -// TODO(Miami) void CMenuManager::DoSettingsBeforeStartingAGame() { @@ -751,6 +862,9 @@ CMenuManager::DoSettingsBeforeStartingAGame() m_bWantToRestart = true; DMAudio.SetEffectsFadeVol(0); DMAudio.SetMusicFadeVol(0); + for (int i = 0; i < NUM_RADIOS; i++) + CStats::FavoriteRadioStationList[i] = 0.0f; + SwitchMenuOnAndOff(); DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); } @@ -766,9 +880,19 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOff(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); +#ifdef CUSTOM_FRONTEND_OPTIONS + const int xMargin = aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->xMargin != 0 ? aScreens[m_nCurrScreen].layout->xMargin : MENU_X_MARGIN; +#else + const int xMargin = MENU_X_MARGIN; +#endif + + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin)); +#ifdef ASPECT_RATIO_SCALE CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); +#else + CFont::SetCentreSize(SCREEN_WIDTH); +#endif switch (m_nCurrScreen) { case MENUPAGE_CHOOSE_LOAD_SLOT: @@ -777,14 +901,11 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(38.0f), MENU_Y(85.0f), MENU_X_LEFT_ALIGNED(615.0f), MENU_Y(75.0f), MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(320.0f), - MENU_X_LEFT_ALIGNED(605.0f), MENU_Y(330.0f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(130))); + MENU_X_LEFT_ALIGNED(605.0f), MENU_Y(330.0f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); break; - /* - // TODO(Miami) case MENUPAGE_SOUND_SETTINGS: - PrintSoundSettings(); + PrintRadioSelector(); break; - */ case MENUPAGE_STATS: PrintStats(); break; @@ -796,7 +917,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) // Page name if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') { - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); @@ -812,7 +933,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetScale(MENU_X(BIGTEXT2_X_SCALE), MENU_Y(BIGTEXT2_Y_SCALE)); CFont::SetRightJustifyOff(); - CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); @@ -847,8 +967,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } CFont::PrintString(MENU_X_LEFT_ALIGNED(100.0f), MENU_Y(97.0f), str); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin)); } if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -858,7 +978,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) DrawControllerScreenExtraText(-8.0f, MENU_X_LEFT_ALIGNED(350), MENU_DEFAULT_LINE_HEIGHT); } - bool foundTheHoveringItem = false; wchar unicodeTemp[64]; char asciiTemp[32]; @@ -866,8 +985,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen) uint8 section = 0; // 0: highlight trapezoid 1: texts while (section < 2) { +#endif +#ifdef SCROLLABLE_PAGES + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; + int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y; + for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) { +#else for (int i = 0; i < NUM_MENUROWS; ++i) { +#endif wchar* rightText = nil; wchar* leftText; if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) { @@ -892,16 +1018,26 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetRightJustifyOff(); CFont::SetCentreOn(); } - if (!aScreens[m_nCurrScreen].m_aEntries[i].m_X && !aScreens[m_nCurrScreen].m_aEntries[i].m_Y) { + if (aScreens[m_nCurrScreen].m_aEntries[i].m_X == 0 && aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) { if (i == 0 || (i == 1 && weHaveLabel)) { +#ifdef CUSTOM_FRONTEND_OPTIONS + aScreens[m_nCurrScreen].m_aEntries[i].m_X = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startX : MENU_DEFAULT_CONTENT_X); + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startY : MENU_DEFAULT_CONTENT_Y); +#else aScreens[m_nCurrScreen].m_aEntries[i].m_X = MENU_DEFAULT_CONTENT_X; aScreens[m_nCurrScreen].m_aEntries[i].m_Y = MENU_DEFAULT_CONTENT_Y; +#endif } else { aScreens[m_nCurrScreen].m_aEntries[i].m_X = aScreens[m_nCurrScreen].m_aEntries[i-1].m_X; - aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y + MENU_DEFAULT_LINE_HEIGHT; + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN; } } +#ifdef CUSTOM_FRONTEND_OPTIONS + else if (aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) { + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN; + } +#endif if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { @@ -923,7 +1059,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) { - if (strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD", 8) == 0) { + if (strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD") == 0) { CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } } @@ -1000,11 +1136,38 @@ CMenuManager::DrawStandardMenus(bool activeScreen) break; case MENUACTION_RADIO: - if (m_PrefsRadioStation > USERTRACK) - break; - - sprintf(gString, "FEA_FM%d", m_PrefsRadioStation); - rightText = TheText.Get(gString); + switch (m_PrefsRadioStation) { + case WILDSTYLE: + rightText = TheText.Get("FEA_FM0"); + break; + case FLASH_FM: + rightText = TheText.Get("FEA_FM1"); + break; + case KCHAT: + rightText = TheText.Get("FEA_FM2"); + break; + case FEVER: + rightText = TheText.Get("FEA_FM3"); + break; + case V_ROCK: + rightText = TheText.Get("FEA_FM4"); + break; + case VCPR: + rightText = TheText.Get("FEA_FM5"); + break; + case RADIO_ESPANTOSO: + rightText = TheText.Get("FEA_FM6"); + break; + case EMOTION: + rightText = TheText.Get("FEA_FM7"); + break; + case WAVE: + rightText = TheText.Get("FEA_FM8"); + break; + case USERTRACK: + rightText = TheText.Get("FEA_MP3"); + break; + } break; case MENUACTION_LEGENDS: rightText = TheText.Get(m_PrefsShowLegends ? "FEM_ON" : "FEM_OFF"); @@ -1050,17 +1213,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - if (m_nSelectedScreenMode == 0) - sprintf(asciiTemp, "FULLSCREEN"); - else - sprintf(asciiTemp, "WINDOWED"); - - AsciiToUnicode(asciiTemp, unicodeTemp); - rightText = unicodeTemp; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); @@ -1123,6 +1275,30 @@ CMenuManager::DrawStandardMenus(bool activeScreen) rightText = TheText.Get("FEA_NM3"); } break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_DYNAMIC: + case MENUACTION_CFO_SELECT: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions) + if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; + + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = 0; + + rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]); + + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (option.m_CFODynamic->drawFunc) { + bool isOptionDisabled = false; + rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i); + if (isOptionDisabled) + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + } + } + break; +#endif } // Highlight trapezoid @@ -1130,7 +1306,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen) int leftXMax, rightXMin; - // FIX: Let's don't scale those so GetStringWidth will give unscaled width, which will be handy to other calculations below that's done without scaling in mind. + // FIX: Let's don't scale those so GetStringWidth can give us unscaled width, which will be handy to other calculations below that's done without scaling in mind, + // and scaling will be done eventually. // CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); CFont::SetScale(BIGTEXT_X_SCALE, BIGTEXT_Y_SCALE); @@ -1140,9 +1317,11 @@ CMenuManager::DrawStandardMenus(bool activeScreen) if (CFont::Details.centre) { leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth / 2.f); rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth / 2.f + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); + } else if (!CFont::Details.rightJustify) { leftXMax = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X; rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X); + } else { leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth); rightXMin = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X; @@ -1158,16 +1337,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen) leftXMax = 40; } - int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y; + int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y MINUS_SCROLL_OFFSET; int topYMax = y; - uint32 bottomYMin = y + 22; - int transition = m_nOptionHighlightTransitionBlend; + uint32 bottomYMin = y + MENU_DEFAULT_LINE_HEIGHT - 7; // Decreasing is not recommended. Because this actually is dependent to font scale, not line height. // Actually bottomRight and bottomLeft should be exchanged here(although this is original code). // So this shows us either R* didn't use same struct for menu BG and highlight, or they just kept fields as x1,y1 etc. Yikes. - if (transition == 0) { - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { + if (m_nOptionHighlightTransitionBlend == 0) { + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y), @@ -1184,9 +1362,10 @@ CMenuManager::DrawStandardMenus(bool activeScreen) menuOptionHighlight.bottomRight_y = bottomYMin + CGeneral::GetRandomNumber() % 7; menuOptionHighlight.UpdateMultipliers(); menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); - } else if (transition < 255) { + + } else if (m_nOptionHighlightTransitionBlend < 255) { menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y), @@ -1195,7 +1374,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } else { m_nOptionHighlightTransitionBlend = 255; menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) { CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(menuOptionHighlight.topLeft_x), MENU_Y(menuOptionHighlight.topLeft_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.topRight_x), MENU_Y(menuOptionHighlight.topRight_y), MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomRight_x), MENU_Y(menuOptionHighlight.bottomRight_y), @@ -1219,10 +1398,9 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } } - if (section != 0) { - + if (section == 1) { if (leftText) { - CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), leftText); + CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), leftText); } if (rightText) { @@ -1235,7 +1413,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); } - CFont::PrintString(MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), rightText); + CFont::PrintString(MENU_X_LEFT_ALIGNED(DEFAULT_SCREEN_WIDTH - RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin)), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), rightText); } if (m_nPrefsAudio3DProviderIndex == DMAudio.GetCurrent3DProviderIndex()) { @@ -1256,7 +1434,12 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 - && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FEA_3DH") +#else + && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS +#endif + && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); SetHelperText(3); @@ -1264,41 +1447,40 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nDisplayVideoMode != m_nPrefsVideoMode) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0 +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FED_RES")) { +#else && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { +#endif m_nDisplayVideoMode = m_nPrefsVideoMode; SetHelperText(3); } } -#ifdef IMPROVED_VIDEOMODE - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_POS") != 0 - && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { - m_nSelectedScreenMode = m_nPrefsWindowed; - } - } -#endif - // TODO(Miami): check // Sliders int lastActiveBarX; switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { - case MENUACTION_BRIGHTNESS: - ProcessSlider(m_PrefsBrightness / 384.0f, 70.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_DRAWDIST: - ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 99.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_MUSICVOLUME: - if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) - ProcessSlider(m_PrefsMusicVolume / 64.0f, 70.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_SFXVOLUME: - if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) - ProcessSlider(m_PrefsSfxVolume / 64.0f, 99.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_MOUSESENS: - ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, 170.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, MENU_X_LEFT_ALIGNED(200.0f), SCREEN_WIDTH); - break; + case MENUACTION_BRIGHTNESS: + ProcessSlider(m_PrefsBrightness / 384.0f, 70.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, SCREEN_WIDTH, true); + break; + case MENUACTION_DRAWDIST: + ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 99.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, SCREEN_WIDTH, true); + break; + case MENUACTION_MUSICVOLUME: + if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) + ProcessSlider(m_PrefsMusicVolume / 64.0f, 70.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, SCREEN_WIDTH, true); + break; + case MENUACTION_SFXVOLUME: + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) + ProcessSlider(m_PrefsSfxVolume / 64.0f, 99.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, SCREEN_WIDTH, true); + break; + case MENUACTION_MOUSESENS: + ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, 170.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, SCREEN_WIDTH, false); + break; + case MENUACTION_MP3VOLUMEBOOST: + if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER && DMAudio.IsMP3RadioChannelAvailable()) + ProcessSlider(m_PrefsMP3BoostVolume / 64.f, 128.0f, HOVEROPTION_INCREASE_MP3BOOST, HOVEROPTION_DECREASE_MP3BOOST, SCREEN_WIDTH, true); + break; } // Not just unused, but also collides with the bug fix in Font.cpp. Yikes. @@ -1306,25 +1488,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen) nextYToUse += MENU_DEFAULT_LINE_HEIGHT * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText); #endif - nextYToUse = 300.0f; // TODO(Miami): temp - // Radio icons if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) { - - // TODO(Miami): Remove those after audio page is done - 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_aFrontEndSprites[MENUSPRITE_MP3], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9); - - nextYToUse += 70.0f; + nextYToUse += MENURADIO_SELECTOR_HEIGHT + 5.f; // unused } } } @@ -1332,6 +1497,35 @@ CMenuManager::DrawStandardMenus(bool activeScreen) section++; } +#ifdef SCROLLABLE_PAGES + #define SCROLLBAR_BOTTOM_Y 105.0f // only for background, scrollbar's itself is calculated + #define SCROLLBAR_RIGHT_X 26.0f + #define SCROLLBAR_WIDTH 9.5f + #define SCROLLBAR_TOP_Y 84 + + if (activeScreen && SCREEN_HAS_AUTO_SCROLLBAR) { + // Scrollbar background + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_Y), + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_Y)), CRGBA(30, 30, 30, FadeIn(150))); + + float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nTotalListRow / (float) MAX_VISIBLE_OPTION); + float scrollbarBottom, scrollbarTop; + + scrollbarBottom = MENU_Y(SCROLLBAR_TOP_Y - 6 + m_nScrollbarTopMargin + scrollbarHeight); + scrollbarTop = MENU_Y(SCROLLBAR_TOP_Y + 2 + m_nScrollbarTopMargin); + // Scrollbar shadow + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 1 - SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), + CRGBA(50, 50, 50, FadeIn(255))); + + // Scrollbar + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - SCROLLBAR_WIDTH), scrollbarBottom), + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); + + } +#endif + switch (m_nCurrScreen) { case MENUPAGE_STATS: case MENUPAGE_CONTROLLER_PC: @@ -1344,16 +1538,27 @@ CMenuManager::DrawStandardMenus(bool activeScreen) if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LOADRADIO) DisplayHelperText("FEA_NAH"); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + default: + if (aScreens[m_nCurrScreen].layout) { + if (aScreens[m_nCurrScreen].layout->showLeftRightHelper) { + DisplayHelperText(nil); + } + } + break; +#endif } if (m_nCurrScreen == MENUPAGE_DELETING_IN_PROGRESS) { SmallMessageScreen("FEDL_WR"); - } else if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { + } +#ifndef XBOX_MESSAGE_SCREEN + else if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { SmallMessageScreen("FESZ_WR"); } +#endif } -// --MIAMI: Done int CMenuManager::GetNumOptionsCntrlConfigScreens(void) { @@ -1387,6 +1592,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 int controllerAction = PED_FIREWEAPON; // GetStartOptionsCntrlConfigScreens(); int numOptions = GetNumOptionsCntrlConfigScreens(); + int nextY = MENU_Y(yStart); int bindingMargin = MENU_X(3.0f); float rowHeight; switch (m_ControlMethod) { @@ -1400,11 +1606,11 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 break; } - // MENU_Y(rowHeight * 0.0f + yStart); - for (int optionIdx = 0, nextY = MENU_Y(yStart); optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { + for (int optionIdx = 0; optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { int nextX = xStart; int bindingsForThisOpt = 0; - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + int contSetOrder = SETORDER_1; + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); if (column == CONTSETUP_PED_COLUMN) { switch (optionIdx) { @@ -1442,10 +1648,10 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 11: case 12: case 16: - case 18: - case 19: case 20: case 21: + case 22: + case 23: controllerAction = -1; break; case 13: @@ -1460,34 +1666,40 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 17: controllerAction = PED_LOCK_TARGET; break; - case 22: + case 18: + controllerAction = PED_DUCK; + break; + case 19: + controllerAction = PED_ANSWER_PHONE; + break; + case 24: controllerAction = PED_LOOKBEHIND; break; - case 23: + case 25: if (m_ControlMethod == CONTROL_STANDARD) controllerAction = -1; else controllerAction = PED_1RST_PERSON_LOOK_LEFT; break; - case 24: + case 26: if (m_ControlMethod == CONTROL_STANDARD) controllerAction = -1; else controllerAction = PED_1RST_PERSON_LOOK_RIGHT; break; - case 25: + case 27: controllerAction = PED_1RST_PERSON_LOOK_UP; break; - case 26: + case 28: controllerAction = PED_1RST_PERSON_LOOK_DOWN; break; - case 27: + case 29: controllerAction = PED_CYCLE_TARGET_LEFT; break; - case 28: + case 30: controllerAction = PED_CYCLE_TARGET_RIGHT; break; - case 29: + case 31: controllerAction = PED_CENTER_CAMERA_BEHIND_PLAYER; break; default: @@ -1509,11 +1721,13 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 14: case 15: case 17: - case 25: - case 26: + case 18: + case 19: case 27: case 28: case 29: + case 30: + case 31: controllerAction = -1; break; case 3: @@ -1546,32 +1760,31 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 case 16: controllerAction = VEHICLE_HANDBRAKE; break; - case 18: + case 20: controllerAction = VEHICLE_TURRETLEFT; break; - case 19: + case 21: controllerAction = VEHICLE_TURRETRIGHT; break; - case 20: + case 22: controllerAction = VEHICLE_TURRETUP; break; - case 21: + case 23: controllerAction = VEHICLE_TURRETDOWN; break; - case 22: + case 24: controllerAction = -2; break; - case 23: + case 25: controllerAction = VEHICLE_LOOKLEFT; break; - case 24: + case 26: controllerAction = VEHICLE_LOOKRIGHT; break; default: break; } } - int bindingWhite = 155; // Highlight selected column(and make its text black) if (m_nSelectedListRow == optionIdx) { @@ -1580,58 +1793,38 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 if (column == CONTSETUP_PED_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_PED_COLUMN) { #ifdef FIX_BUGS - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #else - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), + MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), + CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #endif - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); - bindingWhite = 0; + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); } else if (column == CONTSETUP_VEHICLE_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_VEHICLE_COLUMN) { #ifdef FIX_BUGS - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #else - if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(235, 170, 50, FadeIn(150))); - } else { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(255, 217, 106, FadeIn(210))); - } + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), + CRGBA(SELECTIONBORDER_COLOR.r, SELECTIONBORDER_COLOR.g, SELECTIONBORDER_COLOR.b, FadeIn(255))); #endif - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); - bindingWhite = 0; + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); } } } // Print bindings, including seperator (-) between them - CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f)); - for (int contSetOrder = SETORDER_1; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { + CFont::SetScale(MENU_X(0.25f), MENU_Y(LISTITEM_Y_SCALE)); + for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder); if (settingText) { ++bindingsForThisOpt; if (bindingsForThisOpt > 1) { wchar *seperator = TheText.Get("FEC_IBT"); - CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80))); + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); CFont::PrintString(nextX, nextY, seperator); - CFont::SetColor(CRGBA(bindingWhite, bindingWhite, bindingWhite, FadeIn(255))); nextX += CFont::GetStringWidth(seperator, true) + bindingMargin; } CFont::PrintString(nextX, nextY, settingText); @@ -1644,23 +1837,27 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } } if (controllerAction == -1) { - CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_NUS")); // not used + } else if (controllerAction == -2) { - CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_CMP")); // combo: l+r + } else if (bindingsForThisOpt == 0) { + m_NoEmptyBinding = false; if (m_nSelectedListRow != optionIdx) { - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound + } else if (m_bWaitingForNewKeyBind) { if (column != m_nSelectedContSetupColumn) { - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound } } else { if (column != m_nSelectedContSetupColumn) { - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); } CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound } @@ -1684,51 +1881,32 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode(); } if (showWaitingText) { - CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_QUE")); // "???" } - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); - if (m_bKeyChangeNotProcessed) { - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE - } else { - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_RIG")); // SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL - } - - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + if (m_bKeyChangeNotProcessed) + DisplayHelperText("FET_CIG"); + else + DisplayHelperText("FET_RIG"); + + SET_FONT_FOR_LIST_ITEM m_bKeyIsOK = true; } else { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + DisplayHelperText("FET_CIG"); + SET_FONT_FOR_LIST_ITEM + m_bKeyIsOK = false; m_bKeyChangeNotProcessed = false; } } else if (optionIdx == m_nSelectedListRow) { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); - CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_EIG")); // CANNOT SET A CONTROL FOR THIS ACTION - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + DisplayHelperText("FET_EIG"); + SET_FONT_FOR_LIST_ITEM } } } } -// --MIAMI: Done void CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeight) { @@ -1799,39 +1977,25 @@ CMenuManager::DrawControllerSetupScreen() default: break; } - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); - PREPARE_MENU_HEADER + RESET_FONT_FOR_NEW_PAGE + SET_FONT_FOR_MENU_HEADER - switch (m_ControlMethod) { - case CONTROL_STANDARD: - CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), - TheText.Get("FET_STI")); + // Shadow + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), - TheText.Get("FET_STI")); - break; - case CONTROL_CLASSIC: - CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), - TheText.Get("FET_CTI")); + if (m_ControlMethod == CONTROL_STANDARD) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_STI")); + else if (m_ControlMethod == CONTROL_CLASSIC) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_CTI")); + + // Real header + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); + + if (m_ControlMethod == CONTROL_STANDARD) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_STI")); + else if (m_ControlMethod == CONTROL_CLASSIC) + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_CTI")); - CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), - TheText.Get("FET_CTI")); - break; - default: - break; - } wchar *actionTexts[33]; actionTexts[0] = TheText.Get("FEC_FIR"); actionTexts[1] = TheText.Get("FEC_NWE"); @@ -1878,43 +2042,44 @@ CMenuManager::DrawControllerSetupScreen() actionTexts[27] = nil; } - // Gray panel background + // Blue panel background CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT), MENU_Y(CONTSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(CONTSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)), - CRGBA(200, 200, 50, FadeIn(50))); + CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); if (m_nCurrExLayer == HOVEROPTION_LIST) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); // List header CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); CFont::SetRightJustifyOff(); - CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CAC")); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR")); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X_LEFT_ALIGNED(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + CFont::SetDropShadowPosition(0); + SET_FONT_FOR_LIST_ITEM + int yStart; if (m_ControlMethod == CONTROL_CLASSIC) - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 29; + yStart = CONTSETUP_LIST_TOP + 18; else - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 34; + yStart = CONTSETUP_LIST_TOP + 21; + float optionYBottom = yStart + rowHeight; for (int i = 0; i < ARRAY_SIZE(actionTexts); ++i) { wchar *actionText = actionTexts[i]; if (!actionText) break; if (!m_bWaitingForNewKeyBind) { - if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && + if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT - 10.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)) { - float curOptY = i * rowHeight + yStart; - if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) { + if (m_nMousePosY > MENU_Y(i * rowHeight + yStart) && m_nMousePosY < MENU_Y(i * rowHeight + optionYBottom)) { m_nOptionMouseHovering = i; if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { m_nCurrExLayer = HOVEROPTION_LIST; @@ -1954,10 +2119,10 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOff(); - if (m_PrefsLanguage != LANGUAGE_GERMAN || i != 20 && i != 21) - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); + if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21 || i == 22 || i == 23)) + CFont::SetScale(MENU_X(0.32f), MENU_Y(LISTITEM_Y_SCALE)); else - CFont::SetScale(MENU_X(0.32f), MENU_Y(SMALLESTTEXT_Y_SCALE)); + CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE)); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText); } @@ -1965,15 +2130,15 @@ CMenuManager::DrawControllerSetupScreen() DrawControllerBound(yStart, MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), rowHeight, CONTSETUP_VEHICLE_COLUMN); if (!m_bWaitingForNewKeyBind) { - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true) && m_nMousePosX < MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - CONTSETUP_BACK_HEIGHT)) || m_nCurrExLayer == HOVEROPTION_BACK) { m_nHoverOption = HOVEROPTION_BACK; - } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH) - && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM + 5.0f)) { + } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT - 10.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH) + && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP - 10.0f) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)) { m_nHoverOption = HOVEROPTION_LIST; } else { @@ -1983,18 +2148,12 @@ CMenuManager::DrawControllerSetupScreen() // Back button and it's shadow CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); CFont::SetRightJustifyOn(); - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90))); - for (int i = 0; i < 2; i++) { - CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f - i), - SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f - i), TheText.Get("FEDS_TB")); - - if (m_nHoverOption == HOVEROPTION_BACK) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); - else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); - } + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); + CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f), TheText.Get("FEDS_TB")); } void @@ -2012,18 +2171,18 @@ CMenuManager::DrawFrontEnd() } else { m_nCurrScreen = MENUPAGE_PAUSE_MENU; } + SETUP_SCROLLING(m_nCurrScreen) } if (m_nCurrOption == 0 && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) m_nCurrOption = 1; - if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255) + if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255) bMenuChangeOngoing = false; DrawBackground(false); } -// --MIAMI: Done except commented things void CMenuManager::DrawBackground(bool transitionCall) { @@ -2032,7 +2191,7 @@ CMenuManager::DrawBackground(bool transitionCall) SetFrontEndRenderStates(); - if (m_menuTransitionProgress < 255) { + if (m_firstStartCounter < 255) { CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255)); } @@ -2063,7 +2222,7 @@ CMenuManager::DrawBackground(bool transitionCall) SCREEN_WIDTH, 0.0f, SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), CRGBA(0, 0, 0, 255)); } else { m_nMenuFadeAlpha = 255; - m_menuTransitionProgress = 255; + m_firstStartCounter = 255; m_aFrontEndSprites[MENUSPRITE_BACKGROUND].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, FadeIn(255))); if (m_nCurrScreen == MENUPAGE_MAP) PrintMap(); @@ -2135,6 +2294,20 @@ CMenuManager::DrawBackground(bool transitionCall) menuBg.bottomRight_y = 398.0f; break; default: +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->noInvasiveBorders) { + // Taken from the case above + menuBg.topLeft_x = 26.0f; + menuBg.topLeft_y = 59.0f; + menuBg.topRight_x = 629.0f; + menuBg.topRight_y = 29.0f; + menuBg.bottomLeft_x = 15.0f; + menuBg.bottomLeft_y = 426.0f; + menuBg.bottomRight_x = 610.0f; + menuBg.bottomRight_y = 398.0f; + break; + } +#endif menuBg.topLeft_x = CGeneral::GetRandomNumber() % 40 + 65; menuBg.topLeft_y = CGeneral::GetRandomNumber() % 40 + 21; menuBg.topRight_x = CGeneral::GetRandomNumber() % 40 + 568; @@ -2147,30 +2320,30 @@ CMenuManager::DrawBackground(bool transitionCall) } menuBg.UpdateMultipliers(); - if (m_menuTransitionProgress == 255) + if (m_firstStartCounter == 255) m_nOptionHighlightTransitionBlend = 0; } static PauseModeTime LastFade = 0; - static uint8 forceFadeInCounter = 0; - if (m_nMenuFadeAlpha >= 255) { - if (m_nMenuFadeAlpha > 255) - m_nMenuFadeAlpha = 255; - } else { + if (m_nMenuFadeAlpha < 255) { + static uint8 forceFadeInCounter = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 30 #ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND // Dirty dirty hack || forceFadeInCounter > 30 #endif ) { m_nMenuFadeAlpha += 20; - m_menuTransitionProgress = Min(m_menuTransitionProgress + 20, 255); + if (m_firstStartCounter < 255) { + m_firstStartCounter = Min(m_firstStartCounter + 20, 255); + } LastFade = CTimer::GetTimeInMillisecondsPauseMode(); } forceFadeInCounter++; - } + } else if (m_nMenuFadeAlpha > 255) + m_nMenuFadeAlpha = 255; - if (!transitionCall && m_menuTransitionProgress == 255) { + if (!transitionCall && m_firstStartCounter == 255) { int actualAlpha = m_nMenuFadeAlpha; if (actualAlpha < 255) { int actualScreen = m_nCurrScreen; @@ -2204,7 +2377,7 @@ CMenuManager::DrawBackground(bool transitionCall) DrawControllerSetupScreen(); break; case MENUPAGE_OUTRO: - CMenuManager::DrawQuitGameScreen(); + DrawQuitGameScreen(); break; default: DrawStandardMenus(true); @@ -2215,7 +2388,7 @@ CMenuManager::DrawBackground(bool transitionCall) SetFrontEndRenderStates(); if (m_nCurrScreen != MENUPAGE_OUTRO) - if (m_menuTransitionProgress == 255) { + if (m_firstStartCounter == 255) { m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255)); } else { m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255))); @@ -2237,8 +2410,8 @@ CMenuManager::DrawBackground(bool transitionCall) } if (m_bShowMouse) { - 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)); + CRect mouse(0.0f, 0.0f, MENU_X(35.0f), MENU_Y(35.0f)); + CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(45.0f), MENU_Y(38.0f)); mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); @@ -2247,19 +2420,10 @@ CMenuManager::DrawBackground(bool transitionCall) } } -// --MIAMI: Done void CMenuManager::DrawPlayerSetupScreen(bool activeScreen) { - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + RESET_FONT_FOR_NEW_PAGE // lstrcpy's changed with strcpy if (!m_bSkinsEnumerated) { @@ -2278,7 +2442,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) SYSTEMTIME SystemTime; HANDLE handle = FindFirstFile("skins\\*.bmp", &FindFileData); for (int i = 1; handle != INVALID_HANDLE_VALUE && i; i = FindNextFile(handle, &FindFileData)) { - if (strncmp(FindFileData.cFileName, DEFAULT_SKIN_NAME, 5) != 0) { + if (strcmp(FindFileData.cFileName, DEFAULT_SKIN_NAME) != 0) { m_pSelectedSkin->nextSkin = new tSkinInfo; m_pSelectedSkin = m_pSelectedSkin->nextSkin; m_pSelectedSkin->skinId = nextSkinId; @@ -2325,7 +2489,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "(", 1); if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "}", 1)) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], ")", 1); - if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "�", 1)) + if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "£", 1)) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "$", 1); } @@ -2344,9 +2508,9 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) m_bSkinsEnumerated = true; } CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), - MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(49, 101, 148, FadeIn(130))); + MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(MENUHEADER_POS_X) - MENU_X(7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get("FET_PS")); @@ -2378,9 +2542,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) CFont::SetDropShadowPosition(0); // Skin list - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM if (m_nSkinsTotal > 0) { for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList; m_pSelectedSkin = m_pSelectedSkin->nextSkin); @@ -2427,7 +2589,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) } else if (!strcmp(m_PrefsSkinFile, m_pSelectedSkin->skinNameOriginal)) { CFont::SetColor(CRGBA(255, 255, 155, FadeIn(255))); } else { - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a))); } wchar unicodeTemp[80]; AsciiToUnicode(m_pSelectedSkin->skinNameDisplayed, unicodeTemp); @@ -2449,18 +2611,17 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) ++rowIdx; m_pSelectedSkin = m_pSelectedSkin->nextSkin; } - // Scrollbar background + // Scrollbar background - it's unchanged since III and still yellowish... CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(100, 100, 66, FadeIn(205))); - // Scrollbar - float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal * (float) MAX_VISIBLE_LIST_ROW; + float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nSkinsTotal / (float) MAX_VISIBLE_LIST_ROW); float scrollbarBottom, scrollbarTop; if (m_nSkinsTotal <= MAX_VISIBLE_LIST_ROW) { scrollbarBottom = SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 4.0f); scrollbarTop = MENU_Y(PLAYERSETUP_LIST_BODY_TOP); - // Shadow + // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255))); } else { @@ -2471,15 +2632,16 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) scrollbarBottom = MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 4 + m_nScrollbarTopMargin + scrollbarHeight - SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal); scrollbarTop = MENU_Y(SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal + PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin); #endif - // Shadow + // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255))); } + // Scrollbar CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom), - CRGBA(255, 150, 225, FadeIn(255))); + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); // FIX: Scroll button dimensions are buggy, because: // 1 - stretches the original image @@ -2647,32 +2809,12 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) CFont::SetDropShadowPosition(0); } -// --MIAMI: Done int CMenuManager::FadeIn(int alpha) { return Min(m_nMenuFadeAlpha, alpha); } -void -CMenuManager::FilterOutColorMarkersFromString(wchar *str) -{ - int newIdx = 0; - wchar copy[256], *c; - UnicodeStrcpy(copy, str); - - for (c = copy; *c != '\0'; c++) { - if (*c == '~') { - c++; - while (*c != '~') c++; - } else { - str[newIdx++] = *c; - } - } - str[newIdx] = '\0'; -} - -// --MIAMI: Done int CMenuManager::GetStartOptionsCntrlConfigScreens() { @@ -2753,7 +2895,8 @@ CMenuManager::LoadAllTextures() if (m_bSpritesLoaded) return; - field_F0 = SCREEN_STRETCH_X(178.0f); // TODO(Miami) + // First icon is hidden behind arrow + m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE); CTimer::Stop(); CStreaming::MakeSpaceFor(350 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile @@ -2806,7 +2949,6 @@ CMenuManager::LoadAllTextures() CTimer::Update(); } -// --MIAMI: Done void CMenuManager::LoadSettings() { @@ -2855,12 +2997,7 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, gString, 20); CFileMgr::Read(fileHandle, gString, 4); CFileMgr::Read(fileHandle, gString, 4); -#ifdef FREE_CAM - CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1); -#else CFileMgr::Read(fileHandle, gString, 1); -#endif - #ifdef LEGACY_MENU_OPTIONS CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1); @@ -2891,16 +3028,18 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, (char*)&m_PrefsShowHud, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsRadarMode, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsShowLegends, 1); -#ifdef CUTSCENE_BORDERS_SWITCH - CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); -#endif } } CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f; +#endif +#ifdef PC_PLAYER_CONTROLS CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; +#endif #ifdef LEGACY_MENU_OPTIONS m_PrefsVsync = m_PrefsVsyncDisp; #endif @@ -2940,9 +3079,12 @@ CMenuManager::LoadSettings() strcpy(m_PrefsSkinFile, DEFAULT_SKIN_NAME); strcpy(m_aSkinName, DEFAULT_SKIN_NAME); } + +#ifdef LOAD_INI_SETTINGS + LoadINISettings(); // needs frontend options to be loaded +#endif } -// --MIAMI: Done void CMenuManager::SaveSettings() { @@ -2967,12 +3109,7 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, RubbishString, 20); CFileMgr::Write(fileHandle, RubbishString, 4); CFileMgr::Write(fileHandle, RubbishString, 4); -#ifdef FREE_CAM - CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); -#else CFileMgr::Write(fileHandle, RubbishString, 1); -#endif - #ifdef LEGACY_MENU_OPTIONS CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1); @@ -3003,14 +3140,15 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, (char*)&m_PrefsShowHud, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsRadarMode, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsShowLegends, 1); -#ifdef CUTSCENE_BORDERS_SWITCH - CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); -#endif } m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); + +#ifdef LOAD_INI_SETTINGS + SaveINISettings(); +#endif } void @@ -3035,7 +3173,6 @@ CMenuManager::MessageScreen(const char *text, bool blackBg) DoRWStuffEndOfFrame(); } -// --MIAMI: Done void CMenuManager::SmallMessageScreen(const char* text) { @@ -3062,7 +3199,6 @@ CMenuManager::SmallMessageScreen(const char* text) CFont::PrintString(SCREEN_WIDTH / 2.f, y, TheText.Get(text)); } -// --MIAMI: Done, but FilterOutColorMarkersFromString is actually in CFont void CMenuManager::PrintBriefs() { @@ -3086,7 +3222,7 @@ CMenuManager::PrintBriefs() brief.m_nNumber[4], brief.m_nNumber[5], gUString); CMessages::InsertStringInString(gUString, brief.m_pString); CMessages::InsertPlayerControlKeysInString(gUString); - FilterOutColorMarkersFromString(gUString); + CFont::FilterOutTokensFromString(gUString); nextY -= CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString) * BRIEFS_LINE_HEIGHT + BRIEFS_LINE_SPACING; CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), MENU_Y(nextY), gUString); @@ -3094,18 +3230,17 @@ CMenuManager::PrintBriefs() } } -// --MIAMI: Done void CMenuManager::PrintStats() { static uint8 pirateCheck = 0; static float scrollY = 0; - int rowNum = ConstructStatLine(99999); + int rowNum = CStats::ConstructStatLine(99999); CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(142.0f), MENU_X_LEFT_ALIGNED(543.0f), MENU_Y(142.f), MENU_X_LEFT_ALIGNED(107.0f), MENU_Y(316.f), - MENU_X_LEFT_ALIGNED(531.f), MENU_Y(299.f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(130))); + MENU_X_LEFT_ALIGNED(531.f), MENU_Y(299.f), CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetPropOn(); @@ -3155,7 +3290,7 @@ CMenuManager::PrintStats() // If it's still on screen if (y > MENU_Y(STATS_VISIBLE_START_Y) && y < MENU_Y(STATS_VISIBLE_END_Y)) { - ConstructStatLine(row); + CStats::ConstructStatLine(row); // But about to dim from bottom if (y < MENU_Y(STATS_BOTTOM_Y)) { @@ -3200,17 +3335,24 @@ CMenuManager::PrintStats() UnicodeStrcat(gUString2, gUString); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); +#ifndef FIX_BUGS CFont::SetScale(MENU_X(0.5f), MENU_Y(0.9f)); +#else + CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE)); +#endif CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetDropShadowPosition(0); CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_RATING_X) - CFont::GetStringWidth(gUString2, true) / 2.f, MENU_Y(STATS_RATING_Y_2), gUString2); } -// --MIAMI: Done void CMenuManager::Process(void) { +#ifdef XBOX_MESSAGE_SCREEN + ProcessDialogTimer(); +#endif + if (TheCamera.GetScreenFadeStatus() != FADE_0) return; @@ -3228,6 +3370,535 @@ CMenuManager::Process(void) SwitchMenuOnAndOff(); } +#ifdef MAP_ENHANCEMENTS +#define ZOOM(x, y, in) \ + do { \ + if(m_fMapSize >= MENU_Y(1000.0f) && in) \ + break; \ + float z2 = in? 1.1f : 1.f/1.1f; \ + m_fMapCenterX += (x - m_fMapCenterX) * (1.0f - z2); \ + m_fMapCenterY += (y - m_fMapCenterY) * (1.0f - z2); \ + \ + if (m_fMapSize <= MENU_Y(MAP_MIN_SIZE) && !in) \ + break; \ + \ + m_fMapSize *= z2; \ + m_fMapCenterX = clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2); \ + m_fMapCenterY = clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2); \ + } while(0) + +#endif + +// Handles Map, Audio and Stats +void +CMenuManager::AdditionalOptionInput(bool &goBack) +{ + switch (m_nCurrScreen) { + case MENUPAGE_MAP: + { + static PauseModeTime lastMapTick = 0; + + // FIX: All those macros were hardcoded values originally. + +#ifndef MAP_ENHANCEMENTS + if (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) { + if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) { + m_fMapSize = Min(MENU_Y(1000.0f), m_fMapSize + MENU_Y(15.f)); + } + } + if (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustUp() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) { + if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) { + if (m_fMapSize > MENU_Y(MAP_MIN_SIZE)) { + if (m_fMapCenterY > SCREEN_HEIGHT/2) + m_fMapCenterY -= (m_fMapCenterY - SCREEN_HEIGHT/2) / ((m_fMapSize - MENU_Y(MAP_MIN_SIZE)) * 1/15.f); + + if (m_fMapCenterY < SCREEN_HEIGHT/2) + m_fMapCenterY += (SCREEN_HEIGHT/2 - m_fMapCenterY) / ((m_fMapSize - MENU_Y(MAP_MIN_SIZE)) * 1/15.f); + + if (m_fMapCenterX > SCREEN_WIDTH/2) + m_fMapCenterX -= (m_fMapCenterX - SCREEN_WIDTH/2) / ((m_fMapSize - MENU_X(MAP_MIN_SIZE)) * 1/15.f); + + if (m_fMapCenterX < SCREEN_WIDTH/2) + m_fMapCenterX += (SCREEN_WIDTH/2 - m_fMapCenterX) / ((m_fMapSize - MENU_X(MAP_MIN_SIZE)) * 1/15.f); + + m_fMapSize = Max(MENU_Y(MAP_MIN_SIZE), m_fMapSize - MENU_Y(15.f)); + m_fMapCenterX = clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2); + m_fMapCenterY = clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2); + } else { + m_fMapSize = MENU_Y(MAP_MIN_SIZE); + } + } + } +#else + // Adding marker + if (m_nMenuFadeAlpha == 255) { + if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { + if (mapCrosshair.y > m_fMapCenterY - m_fMapSize && mapCrosshair.y < m_fMapCenterY + m_fMapSize && + mapCrosshair.x > m_fMapCenterX - m_fMapSize && mapCrosshair.x < m_fMapCenterX + m_fMapSize) { + + // Don't ask me the meanings, I don't know. Found them by trying + float diffX = m_fMapCenterX - m_fMapSize, diffY = m_fMapCenterY - m_fMapSize; + float x = ((mapCrosshair.x - diffX) / (m_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) - ((mapCrosshair.y - diffY) / (m_fMapSize * 2)) * (WORLD_SIZE_Y / MENU_MAP_HEIGHT_SCALE); + CRadar::ToggleTargetMarker(x, y); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); + } + } + } + + if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) { + if (CPad::GetPad(0)->GetMouseWheelDown() && m_fMapSize > MENU_X(MAP_SIZE_TO_ALLOW_X_MOVE)) + ZOOM(mapCrosshair.x, mapCrosshair.y, false); + else + ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, false); + + } else if (CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) { + if (CPad::GetPad(0)->GetMouseWheelUp()) + ZOOM(mapCrosshair.x, mapCrosshair.y, true); + else + ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true); + } + + static bool justResetPointer = false; + if (CPad::GetPad(0)->GetLeftMouse()) { + if (!justResetPointer) { + m_fMapCenterX += m_nMousePosX - m_nMouseOldPosX; + m_fMapCenterY += m_nMousePosY - m_nMouseOldPosY; + m_fMapCenterX = clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2); + m_fMapCenterY = clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2); + } + justResetPointer = false; + + } else +#undef ZOOM +#endif + + { + // This is else block of GetLeftMouse() if MAP_ENHANCEMENTS defined, so all of GetLeftMouse() conditions below being rendered useless. + + if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosY < m_nMouseOldPosY || CPad::GetPad(0)->GetUp() || + CPad::GetPad(0)->GetDPadUp() || CPad::GetPad(0)->GetAnalogueUpDown() < 0) { + if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) { + if ((m_fMapSize - MENU_Y(MAP_MIN_SIZE)) + SCREEN_HEIGHT/2 > m_fMapCenterY) + m_fMapCenterY += MENU_Y(15.f); + m_bShowMouse = false; + } + } + + if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosY > m_nMouseOldPosY || CPad::GetPad(0)->GetDown() || + CPad::GetPad(0)->GetDPadDown() || CPad::GetPad(0)->GetAnalogueUpDown() > 0) { + if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) { + if (SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)) < m_fMapCenterY) + m_fMapCenterY -= MENU_Y(15.f); + m_bShowMouse = false; + } + } + + if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosX < m_nMouseOldPosX || CPad::GetPad(0)->GetLeft() || + CPad::GetPad(0)->GetDPadLeft() || CPad::GetPad(0)->GetAnalogueLeftRight() < 0) { + if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) { + if (m_fMapSize > MENU_X(MAP_SIZE_TO_ALLOW_X_MOVE) && m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2 > m_fMapCenterX) + m_fMapCenterX += MENU_X(15.f); + m_bShowMouse = false; + } + } + + if (CPad::GetPad(0)->GetLeftMouseJustUp()) { + // The coordinates in aScreens->MENUPAGE_MAP. + if (m_nMousePosX > MENU_X_LEFT_ALIGNED(60.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(140.0f)) { + if (m_nMousePosY > MENU_Y(375.0f) && m_nMousePosY < MENU_Y(400.0f)) { + m_nHoverOption = HOVEROPTION_RANDOM_ITEM; + goBack = true; + } + } + } + + if (CPad::GetPad(0)->GetLeftMouse() && m_nMousePosX > m_nMouseOldPosX || CPad::GetPad(0)->GetRight() || + CPad::GetPad(0)->GetDPadRight() || CPad::GetPad(0)->GetAnalogueLeftRight() > 0) { + if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) { + if (m_fMapSize > MENU_X(MAP_SIZE_TO_ALLOW_X_MOVE) && SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)) < m_fMapCenterX) + m_fMapCenterX -= MENU_X(15.f); + m_bShowMouse = false; + } + } + } + + + if (CTimer::GetTimeInMillisecondsPauseMode() - lastMapTick > 10) + lastMapTick = CTimer::GetTimeInMillisecondsPauseMode(); + +#ifndef MAP_ENHANCEMENTS + if (CPad::GetPad(0)->GetLeftMouseJustUp()) + CentreMousePointer(); +#endif + + if (CPad::GetPad(0)->GetLeftMouse()) { + if (m_nMousePosX < SCREEN_STRETCH_X(20.0f) || m_nMousePosX > SCREEN_STRETCH_X(620.0f) || m_nMousePosY < SCREEN_STRETCH_Y(20.0f) || m_nMousePosY > SCREEN_STRETCH_Y(428.0f)) { +#ifdef MAP_ENHANCEMENTS + justResetPointer = true; +#endif + CentreMousePointer(); + } + } + if (!CPad::GetPad(0)->GetLeftMouse() && !m_bShowMouse && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) { + m_bShowMouse = true; + } + + static bool pressedL = false; + + if (!CPad::GetPad(0)->GetChar('L') && !CPad::GetPad(0)->GetChar('l')) { + pressedL = false; + } + + if (!pressedL) { + if (CPad::GetPad(0)->GetChar('L') || CPad::GetPad(0)->GetChar('l')) { + m_PrefsShowLegends = !m_PrefsShowLegends; + pressedL = true; + } + } + break; + } + case MENUPAGE_SOUND_SETTINGS: + if (CheckHover(MENU_X_LEFT_ALIGNED(177.f), MENU_X_LEFT_ALIGNED(238.f), MENU_Y(MENURADIO_SELECTOR_START_Y - 13.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT - 8.f))) { + m_nHoverOption = HOVEROPTION_PREV_RADIO; + } + + if (CheckHover(MENU_X_LEFT_ALIGNED(422.f), MENU_X_LEFT_ALIGNED(491.f), MENU_Y(MENURADIO_SELECTOR_START_Y - 13.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT - 8.f))) { + m_nHoverOption = HOVEROPTION_NEXT_RADIO; + } + break; + case MENUPAGE_STATS: + { + if (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustUp() || CPad::GetPad(0)->GetUp() || + CPad::GetPad(0)->GetDPadUp() || CPad::GetPad(0)->GetAnalogueUpDown() < 0) { + + m_StatsScrollSpeed = 20.0f; + m_StatsScrollDirection = 0; + + } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustUp() || CPad::GetPad(0)->GetDown() || + CPad::GetPad(0)->GetDPadDown() || CPad::GetPad(0)->GetAnalogueUpDown() > 0) { + + m_StatsScrollSpeed = 20.0f; + m_StatsScrollDirection = 1; + + } else if (CPad::GetPad(0)->GetChar(' ')) { + m_StatsScrollSpeed = 0.0f; + } else + m_StatsScrollSpeed = 150.0f; + + static bool pressedS = false; + + if (!CPad::GetPad(0)->GetChar('S') && !CPad::GetPad(0)->GetChar('s')) { + pressedS = false; + } + + if (!pressedS) { + if (CPad::GetPad(0)->GetChar('S') || CPad::GetPad(0)->GetChar('s')) { + ExportStats(); + m_nHelperTextMsgId = 4; + m_nHelperTextAlpha = 300; + pressedS = true; + } + } + break; + } + } +} + +// Not original name +void +CMenuManager::ExportStats() +{ + char date[10]; + CFileMgr::SetDirMyDocuments(); + _strdate(date); + wchar *lastMission = TheText.Get(CStats::LastMissionPassedName[0] == '\0' ? "ITBEG" : CStats::LastMissionPassedName); + FILE *txtFile = fopen("stats.txt", "w"); + + if (txtFile) { + int statLines = CStats::ConstructStatLine(99999); + fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"); + fprintf(txtFile, "\t\t\tGTA VICE CITY %s\n", UnicodeToAscii(TheText.Get("FEH_STA"))); + fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n\n"); + fprintf(txtFile, "%s: ", UnicodeToAscii(TheText.Get("FES_CMI"))); + fprintf(txtFile, "%s\n", UnicodeToAscii(lastMission)); + fprintf(txtFile, "%s: ", UnicodeToAscii(TheText.Get("FES_DAT"))); + fprintf(txtFile, "%s\n\n\n", date); + fprintf(txtFile, "%s ", UnicodeToAscii(TheText.Get("CRIMRA"))); + UnicodeStrcpy(gUString, CStats::FindCriminalRatingString()); + fprintf(txtFile, "%s (%d)\n\n\n", UnicodeToAscii(gUString), CStats::FindCriminalRatingNumber()); + for (int i = 0; i < statLines; ++i) { + CStats::ConstructStatLine(i); + char *statKey = UnicodeToAscii(gUString); + if (statKey[0] != '\0') + fprintf(txtFile, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n%s\n", statKey); + + char *statValue = UnicodeToAscii(gUString2); + for (int j = 0; statValue[j] != '\0'; ++j) { + if (statValue[j] == '_') + statValue[j] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation + } + if (statValue) + fprintf(txtFile, "%s\n\n", statValue); + } + fprintf(txtFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n"); + } + fclose(txtFile); + FILE *htmlFile = fopen("stats.html", "w"); + if (htmlFile) { + int statLines = CStats::ConstructStatLine(99999); + fprintf(htmlFile, "<title>Grand Theft Auto Vice City Stats</title>\n"); + fprintf(htmlFile, "<body bgcolor=\"#FF00CC\" leftmargin=\"10\" topmargin=\"10\" marginwidth=\"10\" marginheight=\"10\">\n"); + fprintf(htmlFile, "<table width=\"560\" align=\"center\" border=\"0\" cellpadding=\"5\" cellspacing=\"0\">\n"); + fprintf(htmlFile, "<tr align=\"center\" valign=\"top\"> \n"); + fprintf(htmlFile, "<td height=\"59\" colspan=\"2\" bgcolor=\"#FFCCFF\"><div align=\"center\"><font color=\"#FF00CC\" size=\"3\" " + "face=\"Arial, \n"); + fprintf(htmlFile, "Helvetica, sans-serif\">-------------------------------------------------------------------------</font><font \n"); + fprintf(htmlFile, "size=\"3\" face=\"Arial, Helvetica, sans-serif\"><br>\n"); + fprintf(htmlFile, "<strong><font color=\"#000000\">GRAND THEFT AUTO VICE CITY "); + fprintf(htmlFile, "%s</font></strong><br><font\n", UnicodeToAscii(TheText.Get("FEH_STA"))); + fprintf(htmlFile, "color=\"#FF00CC\">-------------------------------------------------------------------------</font></font></div></td> </tr>\n"); + fprintf(htmlFile, "<tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> <td height=\"22\" colspan=\"2\"> </td> </tr>\n"); + fprintf(htmlFile, "<tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> \n"); + fprintf(htmlFile, + "<td height=\"40\" colspan=\"2\"> <p><font color=\"#00CC00\" size=\"2\" face=\"Arial, Helvetica, sans-serif\">" + "<strong><font color=\"#009900\" size=\"1\">%s: \n", UnicodeToAscii(TheText.Get("FES_DAT"))); + fprintf(htmlFile, "%s</font><br> %s: </strong>", date, UnicodeToAscii(TheText.Get("FES_CMI"))); + fprintf(htmlFile, "%s<strong><br></strong> </font></p></td></tr>\n", UnicodeToAscii(lastMission)); + fprintf(htmlFile, "<tr align=\"left\" valign=\"top\" bgcolor=\"#CCCCCC\"> <td height=\"5\" colspan=\"2\"></td> </tr> <tr align=\"" + "left\" valign=\"top\" bgcolor=\"#FFFFFF\"> \n"); + fprintf(htmlFile, "<td height=\"10\" colspan=\"2\"></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> \n"); + fprintf(htmlFile, "<td height=\"20\" colspan=\"2\"><font color=\"#FF00CC\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><str" + "ong>%s</strong>\n", UnicodeToAscii(TheText.Get("CRIMRA"))); + + UnicodeStrcpy(gUString, CStats::FindCriminalRatingString()); + char *statKey = UnicodeToAscii(gUString); + int rating = CStats::FindCriminalRatingNumber(); + fprintf(htmlFile, "%s (%d)</font></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"><td height=\"10\" colspan=\"" + "2\"></td> </tr>\n", statKey, rating); + + for (int k = 0; k < statLines; ++k) { + CStats::ConstructStatLine(k); + statKey = UnicodeToAscii(gUString); + if (statKey[0] != '\0') + fprintf(htmlFile, "</font></strong></div></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> <td height=\"10" + "\" colspan=\"2\"></td> </tr>\n"); + + fprintf(htmlFile, "<tr align=\"left\" valign=\"top\"><td width=\"500\" height=\"22\" bgcolor=\"#FFCCFF\"><font color=\"#FF00CC" + "\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><strong>\n"); + + if (statKey[0] != '\0') + fprintf(htmlFile, "%s", statKey); + else + fprintf(htmlFile, " "); + + fprintf(htmlFile, "</strong></font></td> <td width=\"500\" align=\"right\" valign=\"middle\" bgcolor=\"#FFCCFF\"> <div align=\"" + "right\"><strong><font color=\"#FF00CC\">\n"); + + char *statValue = UnicodeToAscii(gUString2); + for (int l = 0; statValue[l] != '\0'; ++l) { + if (statValue[l] == '_') + statValue[l] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation + } + if (statValue) + fprintf(htmlFile, "%s", statValue); + else + fprintf(htmlFile, " "); + } + fprintf(htmlFile, "</font></strong></div></td> </tr> <tr align=\"left\" valign=\"top\" bgcolor=\"#FFFFFF\"> <td height=\"10\" c" + "olspan=\"2\"></td> </tr>\n"); + fprintf(htmlFile, "</table><br><table width=\"560\" border=\"0\" align=\"center\" cellspacing=\"0\" cellpadding=\"5\"><tr align" + "=\"center\" valign=\"middle\" bgcolor=\"#FFCCFF\">"); + fprintf(htmlFile, "<td><font color=\"#000000\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><a href=\"http://www.rockstargam" + "es.com/vicecity\">rockstargames.com/vicecity</a></font></td>\n"); + fprintf(htmlFile, "<td><font color=\"#000000\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"><a href=\"http://www.rockstargam" + "es.com\">rockstargames.com</a></font></td>\n"); + fprintf(htmlFile, "<td><font color=\"#000000\" size=\"2\" face=\"Arial, Helvetica, sans-serif\"> <a href=\"http://www.rocks" + "tarnorth.com\">rockstarnorth.com</a></font></td></tr>\n"); + fprintf(htmlFile, "</table>\n</body>\n"); + } + fclose(htmlFile); + CFileMgr::SetDir(""); +} + +// Original name is unknown +void +CMenuManager::PrintRadioSelector(void) +{ + static PauseModeTime lastRadioChange = 0; + + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(418.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), + MENU_X_LEFT_ALIGNED(228.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), + MENU_X_LEFT_ALIGNED(428.f), MENU_Y(MENURADIO_SELECTOR_START_Y), + MENU_X_LEFT_ALIGNED(238.f), MENU_Y(MENURADIO_SELECTOR_START_Y), CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(180))); + + int rightMostSprite, rightMostStation; + if (DMAudio.IsMP3RadioChannelAvailable()) { + rightMostSprite = MENUSPRITE_MP3; + rightMostStation = USERTRACK; + } else { + rightMostSprite = MENUSPRITE_WAVE; + rightMostStation = WAVE; + } + #ifdef THIS_IS_STUPID + + // First radio + if (m_ScrollRadioBy == 1) { + if (m_PrefsRadioStation == 1) { + m_aFrontEndSprites[rightMostSprite].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else if ( m_PrefsRadioStation == 0) { + m_aFrontEndSprites[rightMostSprite - 1].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else { + m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE - 2].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } + } + + // Second + if (m_PrefsRadioStation == 0) { + m_aFrontEndSprites[rightMostSprite].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else { + m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE - 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), + MENU_Y(MENURADIO_ICON_SIZE), CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } + + // Third (middle) + int prevStation = m_PrefsRadioStation - 1; + if (prevStation == rightMostStation) { + m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else if ( prevStation == rightMostStation - 1) { + m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else { + m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } + + // Fifth + if (m_ScrollRadioBy == -1) { + int prevStation = m_PrefsRadioStation - 1; + if (prevStation == rightMostStation) { + m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 4].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else if (prevStation == rightMostStation - 1) { + m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else if ( prevStation == rightMostStation - 2) { + m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else { + m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE + 2].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } + } + + // Fourth + if (m_ScrollRadioBy == 0) { + m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2 - 10.f), MENU_Y(MENURADIO_ICON_Y - 10.f), MENU_X(MENURADIO_ICON_SIZE) + MENU_X(20.f), MENU_Y(MENURADIO_ICON_SIZE) + MENU_Y(20.f), + CRGBA(255, 255, 255, FadeIn(255))); + } else { + if (m_PrefsRadioStation - 1 == rightMostStation) { + m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else { + m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } + } +#else + int first = ((m_PrefsRadioStation - 2) + rightMostStation + 1) % (rightMostStation + 1); + int second = ((m_PrefsRadioStation - 1) + rightMostStation + 1) % (rightMostStation + 1); + int third = ((m_PrefsRadioStation) + rightMostStation + 1) % (rightMostStation + 1); + int fourth = ((m_PrefsRadioStation + 1) + rightMostStation + 1) % (rightMostStation + 1); + int fifth = ((m_PrefsRadioStation + 2) + rightMostStation + 1) % (rightMostStation + 1); + + // First one is only drawn on transition to next + if (m_ScrollRadioBy == 1) { + m_aFrontEndSprites[first + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } + + // Second + m_aFrontEndSprites[second + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + + // Fourth + m_aFrontEndSprites[fourth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + + // Fifth one is only drawn on transition to prev. + if (m_ScrollRadioBy == -1) { + m_aFrontEndSprites[fifth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } + + // Middle one(third) is colored differently depending on if it's in transition. + // If not in transition then this icon indicates selected radio, and should be on top of all icons. thus drawn last + if (m_ScrollRadioBy != 0) { + m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE), + CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a))); + } else { + m_aFrontEndSprites[third + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2 - 10.f), MENU_Y(MENURADIO_ICON_Y - 10.f), MENU_X(MENURADIO_ICON_SIZE) + MENU_X(20.f), MENU_Y(MENURADIO_ICON_SIZE) + MENU_Y(20.f), + CRGBA(255, 255, 255, FadeIn(255))); + } +#endif + + static bool radioChangeRequested = false; + static PauseModeTime lastScrollCheck = 0; + if (CTimer::GetTimeInMillisecondsPauseMode() - lastScrollCheck > 17) { + if (m_ScrollRadioBy == 1) { + if (m_LeftMostRadioX > MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE)) { + m_LeftMostRadioX -= MENU_X(6.f); + } else { + m_ScrollRadioBy = 0; + lastRadioChange = CTimer::GetTimeInMillisecondsPauseMode(); + radioChangeRequested = true; + } + } + if (m_ScrollRadioBy == -1) { + if (m_LeftMostRadioX < MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE)) { + m_LeftMostRadioX += MENU_X(6.f); + } else { + m_ScrollRadioBy = 0; + lastRadioChange = CTimer::GetTimeInMillisecondsPauseMode(); + radioChangeRequested = true; + } + } + lastScrollCheck = CTimer::GetTimeInMillisecondsPauseMode(); + } + // Background behind arrows + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(228.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), + MENU_X_LEFT_ALIGNED(168.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), + MENU_X_LEFT_ALIGNED(238.f), MENU_Y(MENURADIO_SELECTOR_START_Y), + MENU_X_LEFT_ALIGNED(178.f), MENU_Y(MENURADIO_SELECTOR_START_Y), + CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(255))); + + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(478.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), + MENU_X_LEFT_ALIGNED(418.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT), + MENU_X_LEFT_ALIGNED(488.f), MENU_Y(MENURADIO_SELECTOR_START_Y), + MENU_X_LEFT_ALIGNED(428.f), MENU_Y(MENURADIO_SELECTOR_START_Y), + CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(255))); + + // Arrows and their shadows + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255))); + if (radioChangeRequested) { + if (CTimer::GetTimeInMillisecondsPauseMode() - lastRadioChange > 50) { + DMAudio.SetRadioInCar(m_PrefsRadioStation); + DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); + OutputDebugString("FRONTEND RADIO STATION CHANGED"); + lastRadioChange = CTimer::GetTimeInMillisecondsPauseMode(); + radioChangeRequested = false; + } + } +} + // Original name is unknown void CMenuManager::ProcessList(bool &optionSelected, bool &goBack) @@ -3239,7 +3910,8 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nTotalListRow = m_nSkinsTotal; } if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { - m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25; + // GetNumOptionsCntrlConfigScreens would have been a better choice + m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 32 : 27; if (m_nSelectedListRow > m_nTotalListRow) m_nSelectedListRow = m_nTotalListRow - 1; } @@ -3366,7 +4038,7 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { m_nFirstVisibleRowOnList = 0; } m_nSelectedListRow = 0; @@ -3376,8 +4048,8 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; } m_nSelectedListRow = m_nTotalListRow - 1; m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; @@ -3467,7 +4139,7 @@ CMenuManager::UserInput(void) bool goDown = false; int8 changeValueBy; - if (!m_AllowNavigation && m_menuTransitionProgress == 255) + if (!m_AllowNavigation && m_firstStartCounter == 255) m_AllowNavigation = true; if (!m_bShowMouse && m_nCurrScreen != MENUPAGE_MAP && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) { m_bShowMouse = true; @@ -3475,17 +4147,22 @@ CMenuManager::UserInput(void) static int oldOption = -99; oldOption = m_nCurrOption; +#ifdef SCROLLABLE_PAGES + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; + int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y; + for (int rowToCheck = firstOption; rowToCheck < firstOption + MAX_VISIBLE_OPTION && rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#else for (int rowToCheck = 0; rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#endif if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_NOTHING || aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_LABEL) continue; - int extraOffset = 0; - if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_RADIO) - extraOffset = MENURADIO_ICON_SCALE; + // unused: CFont::GetStringWidth(TheText.Get(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName), true); + // So they also wanted the compare X, but they abandoned the idea later on - if (m_nMousePosY > MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y) && - m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y + MENU_DEFAULT_LINE_HEIGHT)) { + if (m_nMousePosY > MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET) && + m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET PLUS_LINE_HEIGHT_ON_SCREEN)) { static int oldScreen = m_nCurrScreen; m_nOptionMouseHovering = rowToCheck; @@ -3529,11 +4206,10 @@ CMenuManager::UserInput(void) if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT; changeValueBy = 0; - if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS || m_nCurrScreen == MENUPAGE_SKIN_SELECT) { + if (hasNativeList(m_nCurrScreen)) { ProcessList(optionSelected, goBack); } else { - // TODO(Miami): Seperate that code into a new function from ProcessUserInput - // ProcessScrollingExceptLists(goBack); + AdditionalOptionInput(goBack); if (m_AllowNavigation && (CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown())) { @@ -3541,8 +4217,7 @@ CMenuManager::UserInput(void) goDown = true; m_nOptionHighlightTransitionBlend = 0; - } - else if (m_AllowNavigation && + } else if (m_AllowNavigation && (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown())) { m_bShowMouse = false; goUp = true; @@ -3554,8 +4229,7 @@ CMenuManager::UserInput(void) m_bShowMouse = false; optionSelected = true; } - } - else { + } else { if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { m_bShowMouse = false; optionSelected = true; @@ -3563,16 +4237,12 @@ CMenuManager::UserInput(void) } if (CPad::GetPad(0)->GetLeftMouseJustUp() && m_nCurrScreen != MENUPAGE_MAP) { - // TODO(Miami): New radio selector - if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM) { + if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM) optionSelected = true; - } - } - // TODO(Miami): This part is old radio selector, remove when new is reversed!! - else if (CPad::GetPad(0)->GetLeftMouseJustDown()) { - if (m_nHoverOption >= HOVEROPTION_RADIO_0 && m_nHoverOption <= HOVEROPTION_RADIO_9) { - ChangeRadioStation(m_nHoverOption - HOVEROPTION_RADIO_0 - m_PrefsRadioStation); - } + else if (m_nHoverOption == HOVEROPTION_NEXT_RADIO) + ChangeRadioStation(1); + else if (m_nHoverOption == HOVEROPTION_PREV_RADIO) + ChangeRadioStation(-1); } if (CPad::GetPad(0)->GetLeftMouse()) { @@ -3596,6 +4266,27 @@ CMenuManager::UserInput(void) } } +#ifdef SCROLLABLE_PAGES + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { + bool temp = false; + + m_nSelectedListRow = m_nCurrOption; + + // ignore detected back/select states, it's our screen's job + ProcessList(temp, temp); + + // and ignore our screen's goUp/Down, now it's ProcessList's job + goUp = false; + goDown = false; + m_nCurrOption = m_nSelectedListRow; + + if (oldOption != m_nCurrOption) + m_nOptionHighlightTransitionBlend = 0; + } + + // Prevent sound on scroll. Mouse wheel is now belongs to us! + if (!(m_nTotalListRow > MAX_VISIBLE_OPTION && (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()))) +#endif if (CPad::GetPad(0)->GetLeftMouseJustUp() || CPad::GetPad(0)->GetLeftJustUp() || CPad::GetPad(0)->GetRightJustUp() || CPad::GetPad(0)->GetDPadLeftJustUp() || CPad::GetPad(0)->GetDPadRightJustUp() || CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp() @@ -3605,7 +4296,7 @@ CMenuManager::UserInput(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); else if (option == MENUACTION_SFXVOLUME) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0); - else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESTEER) + else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESENS) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); } @@ -3649,10 +4340,15 @@ CMenuManager::UserInput(void) } } - if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) { - changeValueBy = 1; - } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { - changeValueBy = -1; +#ifdef SCROLLABLE_PAGES + if (!SCREEN_HAS_AUTO_SCROLLBAR) +#endif + { + if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) { + changeValueBy = 1; + } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { + changeValueBy = -1; + } } if (m_AllowNavigation) { @@ -3685,9 +4381,30 @@ CMenuManager::UserInput(void) } } ProcessUserInput(goDown, goUp, optionSelected, goBack, changeValueBy); +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].m_aEntries[oldOption].m_Action < MENUACTION_NOTHING) { // CFO check + CMenuScreenCustom::CMenuEntry &oldEntry = aScreens[m_nCurrScreen].m_aEntries[oldOption]; + if (m_nCurrOption != oldOption) { + if (oldEntry.m_Action == MENUACTION_CFO_DYNAMIC) + if(oldEntry.m_CFODynamic->buttonPressFunc) + oldEntry.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + + if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) { + if (oldEntry.m_CFOSelect->displayedValue != oldEntry.m_CFOSelect->lastSavedValue) + SetHelperText(3); // Restored original value + + oldEntry.m_CFOSelect->displayedValue = oldEntry.m_CFOSelect->lastSavedValue = *oldEntry.m_CFO->value; + } + } else if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) { + if (oldEntry.m_CFOSelect->displayedValue != *oldEntry.m_CFO->value) + SetHelperText(1); // Enter to apply + else if (m_nHelperTextMsgId == 1) + ResetHelperText(); // Applied + } + } +#endif } -// --MIAMI: Done except TODOs void CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, uint8 goBack, int8 changeAmount) { @@ -3798,7 +4515,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (optionSelected && m_nMenuFadeAlpha == 255) { if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_NEW_GAME_RELOAD && m_bGameNotLoaded) { DoSettingsBeforeStartingAGame(); - } else if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) || (m_nCurrScreen == MENUPAGE_SKIN_SELECT)) { + } else if (hasNativeList(m_nCurrScreen)) { switch (m_nCurrExLayer) { case HOVEROPTION_LIST: if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -3835,16 +4552,14 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; +#ifdef FIX_BUGS + int currScreen = m_nCurrScreen; + int currOption = m_nCurrOption; +#endif switch (option) { case MENUACTION_CHANGEMENU: case MENUACTION_YES: case MENUACTION_NO: -#ifdef CUSTOM_MAP - if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_MAP) { - bMapLoaded = false; - } - -#endif SwitchToNewScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu); break; case MENUACTION_RADIO: @@ -3884,8 +4599,8 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u { int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot; - if (saveSlot >= 2 && saveSlot <= 9) { - m_nCurrSaveSlot = saveSlot - 2; + if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8) { + m_nCurrSaveSlot = saveSlot - SAVESLOT_1; if (Slots[m_nCurrSaveSlot] != SLOT_EMPTY && Slots[m_nCurrSaveSlot] != SLOT_CORRUPTED) { if (m_nCurrScreen == MENUPAGE_CHOOSE_LOAD_SLOT) { SwitchToNewScreen(MENUPAGE_LOAD_SLOT_CONFIRM); @@ -3972,15 +4687,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u SaveSettings(); } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - m_nPrefsWindowed = m_nSelectedScreenMode; - _psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution - SaveSettings(); - } - break; -#endif case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; @@ -4034,7 +4740,11 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u #endif CRenderer::ms_lodDistScale = m_PrefsLOD; m_PrefsShowSubtitles = false; +#ifdef ASPECT_RATIO_SCALE + m_PrefsUseWideScreen = AR_AUTO; +#else m_PrefsUseWideScreen = false; +#endif m_PrefsShowLegends = true; m_PrefsVsyncDisp = true; m_PrefsFrameLimiter = true; @@ -4042,6 +4752,13 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u m_PrefsShowHud = true; m_nDisplayVideoMode = m_nPrefsVideoMode; CMBlur::BlurOn = false; +#ifdef CUSTOM_FRONTEND_OPTIONS + extern void RestoreDefGraphics(int8); + extern void RestoreDefDisplay(int8); + + RestoreDefGraphics(FEOPTION_ACTION_SELECT); + RestoreDefDisplay(FEOPTION_ACTION_SELECT); +#endif SaveSettings(); } else if (m_nCurrScreen == MENUPAGE_CONTROLLER_PC) { ControlsManager.MakeControllerActionsBlank(); @@ -4063,6 +4780,9 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u #endif MousePointerStateHelper.bInvertVertically = true; TheCamera.m_bHeadBob = false; +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = 0.003f; +#endif TheCamera.m_fMouseAccelHorzntl = 0.0025f; CVehicle::m_bDisableMouseSteering = true; m_ControlMethod = CONTROL_STANDARD; @@ -4081,12 +4801,43 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_SELECT: + case MENUACTION_CFO_DYNAMIC: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + if (!option.m_CFOSelect->onlyApplyOnEnter) { + option.m_CFOSelect->displayedValue++; + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = 0; + } + int8 oldValue = *option.m_CFO->value; + + *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; + + if (option.m_CFOSelect->save) + SaveSettings(); + + if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) + option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue); + + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_SELECT); + } + + break; +#endif } ProcessOnOffMenuOptions(); if (!goBack) { +#ifdef FIX_BUGS + int saveSlot = aScreens[currScreen].m_aEntries[currOption].m_SaveSlot; + if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[currOption] != SLOT_OK) +#else int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot; - - if (saveSlot >= 2 && saveSlot <= 9 && Slots[m_nCurrOption] != SLOT_OK) + if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[m_nCurrOption] != SLOT_OK) +#endif DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); else DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); @@ -4097,7 +4848,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (m_NoEmptyBinding) { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_BACK, 0); SwitchToNewScreen(-2); - if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { + if (hasNativeList(m_nCurrScreen)) { m_nTotalListRow = 0; } } else { @@ -4152,11 +4903,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - m_nSelectedScreenMode = !m_nSelectedScreenMode; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeAmount; @@ -4203,6 +4949,36 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u CCamera::m_bUseMouse3rdPerson = !m_ControlMethod; SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_SELECT: + case MENUACTION_CFO_DYNAMIC: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + if (changeAmount > 0) { + option.m_CFOSelect->displayedValue++; + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts) + option.m_CFOSelect->displayedValue = 0; + } else { + option.m_CFOSelect->displayedValue--; + if (option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->numRightTexts - 1; + } + if (!option.m_CFOSelect->onlyApplyOnEnter) { + int8 oldValue = *option.m_CFO->value; + + *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; + + if (option.m_CFOSelect->save) + SaveSettings(); + + if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) + option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue); + } + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC && option.m_CFODynamic->buttonPressFunc) { + option.m_CFODynamic->buttonPressFunc(changeAmount > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); + } + break; +#endif } CheckSliderMovement(changeAmount); ProcessOnOffMenuOptions(); @@ -4216,7 +4992,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } } -// --MIAMI: Done void CMenuManager::ProcessOnOffMenuOptions() { @@ -4345,6 +5120,129 @@ float CMenuManager::StretchY(float y) return SCREEN_STRETCH_Y(y); } +#ifdef XBOX_MESSAGE_SCREEN +void +CMenuManager::CloseDialog(void) +{ + // We don't have this on PC GXT :shrug: + static wchar* gameSaved = AllocUnicode("Game saved successfully!"); + + if (m_bSaveWasSuccessful && DialogTextCmp("FESZ_WR")) { + m_bSaveWasSuccessful = false; // i don't know where XBOX resets that + m_pDialogText = gameSaved; + SetDialogTimer(1000); + ProcessDialogTimer(); + } else { + ToggleDialog(false); + } + +} + +void +CMenuManager::ProcessDialogTimer(void) +{ + if (!m_bDialogOpen || m_nDialogHideTimer == 0) + return; + + // Also XBOX has unified time source for in-game/menu, but we don't have that + if (m_bMenuActive && CTimer::GetTimeInMilliseconds() > m_nDialogHideTimer || !m_bMenuActive && CTimer::GetTimeInMillisecondsPauseMode() > m_nDialogHideTimerPauseMode) { + + // This is originally activePage.funcs->closePage() + CloseDialog(); + } +} + +void +CMenuManager::SetDialogTimer(uint32 timer) +{ + // XBOX iterates some page list(actives?) and then sets timer variable of specified page to specified value. We only have dialog right now. + // Also XBOX has unified time source for in-game/menu, but we don't have that, thus 2 timer variables... + + m_nDialogHideTimer = CTimer::GetTimeInMilliseconds() + timer; + m_nDialogHideTimerPauseMode = CTimer::GetTimeInMillisecondsPauseMode() + timer; +} + +void +CMenuManager::SetDialogText(const char* key) +{ + // There are many things going around here, idk why + m_pDialogText = TheText.Get(key); +} + +bool +CMenuManager::DialogTextCmp(const char* key) +{ + wchar *value = TheText.Get(key); + wchar *i = m_pDialogText; + for (; *i != '\0' && *value != '\0'; i++, value++) { + if (*i != *value) + return false; + } + return *i == '\0' && *value == '\0'; +} + +void +CMenuManager::ToggleDialog(bool toggle) +{ + // This originally calls some mysterious function on enable and close CB on disable, along with decreasing some counter. Which is no use for dialog + + // XBOX doesn't do that + if (toggle) + m_nDialogHideTimer = 0; + + m_bDialogOpen = toggle; +} + +void +DrawDialogBg(float offset, uint8 alpha) +{ + CSprite2d::Draw2DPolygon(SCALE_AND_CENTER_X(84.f + offset), MENU_Y(126.f + offset), + SCALE_AND_CENTER_X(512.f + offset), MENU_Y(109.f + offset), + SCALE_AND_CENTER_X(100.f + offset), MENU_Y(303.f + offset), + SCALE_AND_CENTER_X(474.f + offset), MENU_Y(311.f + offset), CRGBA(107, 193, 236, alpha)); + CSprite2d::Draw2DPolygon(SCALE_AND_CENTER_X(523.f + offset), MENU_Y(108.f + offset), + SCALE_AND_CENTER_X(542.f + offset), MENU_Y(107.f + offset), + SCALE_AND_CENTER_X(485.f + offset), MENU_Y(310.f + offset), + SCALE_AND_CENTER_X(516.f + offset), MENU_Y(311.f + offset), CRGBA(107, 193, 236, alpha)); +} + +void +CMenuManager::DrawOverlays(void) +{ + // This is stripped to show only Dialog box, XBOX does much more in here. + + if (!m_bDialogOpen) + return; + + DefinedState(); + + CSprite2d::DrawRect(CRect(0, SCREEN_HEIGHT, SCREEN_WIDTH, 0), CRGBA(0, 0, 0, 160)); + + // Ofc this is not hardcoded like that on Xbox, it should be a texture + DrawDialogBg(20.f, 160); // shadow + DrawDialogBg(0.f, 255); + + CFont::SetBackgroundOff(); + CFont::SetPropOn(); + CFont::SetJustifyOn(); + CFont::SetBackGroundOnlyTextOn(); + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + CFont::SetCentreSize(SCREEN_SCALE_X(380.0f)); + CFont::SetCentreOn(); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, 255)); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + // Both of those are 0.9 on Xbox, which is ofcouse wrong... + CFont::SetScale(SCREEN_SCALE_X(BIGTEXT_X_SCALE), SCREEN_SCALE_Y(BIGTEXT_Y_SCALE)); + + int x = SCREEN_WIDTH / 2.f - SCREEN_SCALE_X(30.0f); + int y = SCREEN_HEIGHT / 2.f - SCREEN_SCALE_Y(30.0f); + int numOfLines = CFont::GetNumberLines(x, y, m_pDialogText); + CFont::PrintString(x, y - SCREEN_SCALE_Y(numOfLines / 2.f), m_pDialogText); + CFont::DrawFonts(); +} +#endif + void CMenuManager::ProcessFileActions() { @@ -4354,9 +5252,14 @@ CMenuManager::ProcessFileActions() #ifdef USE_DEBUG_SCRIPT_LOADER scriptToLoad = 0; #endif + +#ifdef XBOX_MESSAGE_SCREEN + SetDialogText("FELD_WR"); + ToggleDialog(true); +#else if (!m_bGameNotLoaded) MessageScreen("FELD_WR", true); - +#endif DoSettingsBeforeStartingAGame(); m_bWantToLoad = true; } else @@ -4389,6 +5292,41 @@ CMenuManager::ProcessFileActions() } case MENUPAGE_SAVING_IN_PROGRESS: { +#ifdef XBOX_MESSAGE_SCREEN + if (m_bDialogOpen && DialogTextCmp("FESZ_WR")) { + PauseModeTime startTime = CTimer::GetTimeInMillisecondsPauseMode(); + int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); + PcSaveHelper.PopulateSlotInfo(); + + // Original code, but we don't want redundant saving text if it doesn't +#if 0 + CTimer::Update(); // not on Xbox, who updates it? + + // it compensates the lag to show saving text always one second... how cute + int dialogDur = Max(1, startTime - CTimer::GetTimeInMillisecondsPauseMode() + 1000); +#else + int dialogDur = 1; +#endif + + if (SaveSlot) { + // error. PC code + ToggleDialog(false); + SwitchToNewScreen(MENUPAGE_SAVE_CUSTOM_WARNING); + strncpy(aScreens[m_nCurrScreen].m_ScreenName, "FET_SG", 8); + strncpy(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName, "FES_CMP", 8); + + } else { + m_bSaveWasSuccessful = true; + SetDialogTimer(dialogDur); + ProcessDialogTimer(); + RequestFrontEndShutDown(); + } + + } else { + SetDialogText("FESZ_WR"); + ToggleDialog(true); + } +#else static bool waitedForScreen = false; if (waitedForScreen) { @@ -4404,13 +5342,12 @@ CMenuManager::ProcessFileActions() waitedForScreen = false; } else if (m_nMenuFadeAlpha >= 255) waitedForScreen = true; - +#endif break; } } } -// --MIAMI: Done void CMenuManager::SwitchMenuOnAndOff() { @@ -4419,9 +5356,17 @@ CMenuManager::SwitchMenuOnAndOff() // Reminder: You need REGISTER_START_BUTTON defined to make it work. if ((CPad::GetPad(0)->GetStartJustDown() || CPad::GetPad(0)->GetEscapeJustDown()) && (!m_bMenuActive || m_nCurrScreen == MENUPAGE_PAUSE_MENU || m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT || m_nCurrScreen == MENUPAGE_SAVE_CHEAT_WARNING) - || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) { + || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested +#ifdef REGISTER_START_BUTTON + || CPad::GetPad(0)->GetStartJustDown() && !m_bGameNotLoaded +#endif + ) { - if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS) { + if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS +#ifdef XBOX_MESSAGE_SCREEN + && m_nCurrScreen != MENUPAGE_SAVING_IN_PROGRESS +#endif + ) { DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); DoRWStuffEndOfFrame(); DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); @@ -4443,6 +5388,10 @@ CMenuManager::SwitchMenuOnAndOff() Initialise(); LoadAllTextures(); } else { +#ifdef EXTENDED_COLOURFILTER + // we always expect CPostFX to be open + CMBlur::BlurOn = true; +#endif if (CMBlur::BlurOn) CMBlur::MotionBlurOpen(Scene.camera); else @@ -4457,6 +5406,9 @@ CMenuManager::SwitchMenuOnAndOff() } m_StatsScrollSpeed = 150.0f; +#ifdef FIX_BUGS + ThingsToDoBeforeLeavingPage(); +#endif SaveSettings(); pControlEdit = nil; pEditString = nil; @@ -4546,7 +5498,6 @@ CMenuManager::UnloadTextures() CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown(); } -// --MIAMI: Done void CMenuManager::WaitForUserCD() { @@ -4605,56 +5556,14 @@ CMenuManager::DrawQuitGameScreen(void) m_AllowNavigation = false; } -#ifdef CUSTOM_MAP - -#define ZOOM(x, y, in) \ - do { \ - if(m_fMapSize > SCREEN_HEIGHT * 3.0f && in) \ - break; \ - float z2 = in? 1.1f : 1.f/1.1f; \ - m_fMapCenterX += (x - m_fMapCenterX) * (1.0f - z2); \ - m_fMapCenterY += (y - m_fMapCenterY) * (1.0f - z2); \ - \ - if (m_fMapSize < SCREEN_HEIGHT / 2 && !in) \ - break; \ - \ - m_fMapSize *= z2; \ - } while(0) - -#endif - void CMenuManager::PrintMap(void) { m_bMenuMapActive = true; CRadar::InitFrontEndMap(); -#ifdef CUSTOM_MAP - // Just entered to map - if (!bMapLoaded) { - m_fMapSize = SCREEN_HEIGHT * 2.0f; - m_fMapCenterX = 0.0f; - m_fMapCenterY = 0.0f; - CVector2D radarSpacePlayer; - CVector2D screenSpacePlayer; - CRadar::TransformRealWorldPointToRadarSpace(radarSpacePlayer, CVector2D(FindPlayerCoors())); - CRadar::TransformRadarPointToScreenSpace(screenSpacePlayer, radarSpacePlayer); - - m_fMapCenterX = (-screenSpacePlayer.x) + SCREEN_WIDTH / 2; - m_fMapCenterY = (-screenSpacePlayer.y) + SCREEN_HEIGHT / 2; - bMapMouseShownOnce = false; - bMapLoaded = true; - - // Let's wait for a frame to not toggle the waypoint - if (CPad::GetPad(0)->NewState.Cross) { - m_bMenuMapActive = false; - return; - } - } -#endif - - // Because m_fMapSize is half of the map length, and map consists of 3x3 tiles. - float halfTile = m_fMapSize / 3.0f; + // Because m_fMapSize is half of the map length(hence * 2), and map consists of 3x3 tiles(hence / 3). + float halfTile = m_fMapSize * 2.f / 3.f / 2.f; RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); @@ -4752,266 +5661,45 @@ CMenuManager::PrintMap(void) } } -#ifdef CUSTOM_MAP - CVector2D mapPoint; - mapPoint.x = m_nMousePosX; - mapPoint.y = m_nMousePosY; - - if (m_bShowMouse) { - bMapMouseShownOnce = true; - } else if (!bMapMouseShownOnce) { - mapPoint.x = SCREEN_WIDTH / 2; - mapPoint.y = SCREEN_HEIGHT / 2; +#ifdef MAP_ENHANCEMENTS + if (m_nMenuFadeAlpha != 255 && !m_bShowMouse) { + mapCrosshair.x = SCREEN_WIDTH / 2; + mapCrosshair.y = SCREEN_HEIGHT / 2; + } else if (m_bShowMouse) { + mapCrosshair.x = m_nMousePosX; + mapCrosshair.y = m_nMousePosY; } - CSprite2d::DrawRect(CRect(mapPoint.x - MENU_X(1.0f), 0.0f, - mapPoint.x + MENU_X(1.0f), SCREEN_HEIGHT), + CSprite2d::DrawRect(CRect(mapCrosshair.x - MENU_X(1.0f), 0.0f, + mapCrosshair.x + MENU_X(1.0f), SCREEN_HEIGHT), CRGBA(0, 0, 0, 150)); - CSprite2d::DrawRect(CRect(0.0f, mapPoint.y + MENU_X(1.0f), - SCREEN_WIDTH, mapPoint.y - MENU_X(1.0f)), + CSprite2d::DrawRect(CRect(0.0f, mapCrosshair.y + MENU_X(1.0f), + SCREEN_WIDTH, mapCrosshair.y - MENU_X(1.0f)), CRGBA(0, 0, 0, 150)); - if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { - if (mapPoint.y > m_fMapCenterY - m_fMapSize && mapPoint.y < m_fMapCenterY + m_fMapSize && - mapPoint.x > m_fMapCenterX - m_fMapSize && mapPoint.x < m_fMapCenterX + m_fMapSize) { - - // Don't ask me the meanings, I don't know. Found them by trying - float diffX = m_fMapCenterX - m_fMapSize, diffY = m_fMapCenterY - m_fMapSize; - float x = ((mapPoint.x - diffX) / (m_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) / (m_fMapSize * 2)) * (WORLD_SIZE_Y / MENU_MAP_HEIGHT_SCALE); - CRadar::ToggleTargetMarker(x, y); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_BACK, 0); - } - } - - if (CPad::GetPad(0)->GetLeftMouse()) { - m_fMapCenterX += m_nMousePosX - m_nMouseOldPosX; - m_fMapCenterY += m_nMousePosY - m_nMouseOldPosY; - } else if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetDPadLeft()) { - m_fMapCenterX += 15.0f; - } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetDPadRight()) { - m_fMapCenterX -= 15.0f; - } else if (CPad::GetPad(0)->GetLeftStickX()) { - m_fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f; - } - - if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetDPadUp()) { - m_fMapCenterY += 15.0f; - } else if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetDPadDown()) { - m_fMapCenterY -= 15.0f; - } else if (CPad::GetPad(0)->GetLeftStickY()) { - m_fMapCenterY -= CPad::GetPad(0)->GetLeftStickY() / 128.0f * 20.0f; - } - - if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) { - if (CPad::GetPad(0)->GetMouseWheelDown()) - ZOOM(mapPoint.x, mapPoint.y, false); - else - ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, false); - } else if (CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) { - if (CPad::GetPad(0)->GetMouseWheelUp()) - ZOOM(mapPoint.x, mapPoint.y, true); - else - ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true); - } - - if (m_fMapCenterX - m_fMapSize > SCREEN_WIDTH / 2) - m_fMapCenterX = m_fMapSize + SCREEN_WIDTH / 2; - - if (m_fMapCenterX + m_fMapSize < SCREEN_WIDTH / 2) - m_fMapCenterX = SCREEN_WIDTH / 2 - m_fMapSize; - - if (m_fMapCenterY + m_fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f)) - m_fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - m_fMapSize; - - if (m_fMapCenterY - m_fMapSize > SCREEN_HEIGHT / 2) - m_fMapCenterY = SCREEN_HEIGHT / 2 + m_fMapSize; #endif m_bMenuMapActive = false; - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN)); DisplayHelperText("FEH_MPH"); } -#ifdef CUSTOM_MAP -#undef ZOOM -#endif - -// rowIdx 99999 returns total numbers of rows. otherwise it returns 0. -int -CMenuManager::ConstructStatLine(int rowIdx) -{ -#define STAT_LINE(str, left, isFloat, right) \ - do { \ - if(counter == rowIdx){ \ - BuildStatLine(str, left, isFloat, right); \ - return 0; \ - } counter++; \ - } while(0) - - int counter = 0, nTemp; - - STAT_LINE("PL_STAT", nil, false, nil); - - int percentCompleted = CStats::GetPercentageProgress(); - - STAT_LINE("PER_COM", &percentCompleted, false, nil); - STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); - STAT_LINE("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions); - if (CGame::nastyGame) { - STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, false, &CStats::TotalNumberKillFrenzies); - } - - CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus]; - float packagesPercent = 0.0f; - if (player.m_nTotalPackages != 0) - packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages; - - int nPackagesPercent = packagesPercent; - STAT_LINE("PERPIC", &nPackagesPercent, false, &(nTemp = 100)); - STAT_LINE("NOUNIF", &CStats::NumberOfUniqueJumpsFound, false, &CStats::TotalNumberOfUniqueJumps); - STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil); - if (CGame::nastyGame) { - STAT_LINE("PE_WAST", &CStats::PeopleKilledByPlayer, false, nil); - STAT_LINE("PE_WSOT", &CStats::PeopleKilledByOthers, false, nil); - } - STAT_LINE("CAR_EXP", &CStats::CarsExploded, false, nil); - STAT_LINE("TM_BUST", &CStats::TimesArrested, false, nil); - STAT_LINE("TM_DED", &CStats::TimesDied, false, nil); - STAT_LINE("GNG_WST", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG7] + CStats::PedsKilledOfThisType[PEDTYPE_GANG6] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG5] + CStats::PedsKilledOfThisType[PEDTYPE_GANG4] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG3] + CStats::PedsKilledOfThisType[PEDTYPE_GANG2] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]), false, nil); - STAT_LINE("DED_CRI", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]), false, nil); - STAT_LINE("HEL_DST", &CStats::HelisDestroyed, false, nil); - STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, false, nil); - - if (CStats::HighestScores[0] > 0) { - STAT_LINE("FEST_BB", nil, false, nil); - STAT_LINE("FEST_H0", &CStats::HighestScores[0], false, nil); - } - if (CStats::HighestScores[4] + CStats::HighestScores[3] + CStats::HighestScores[2] + CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_GC", nil, false, nil); - } - if (CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_H1", &CStats::HighestScores[1], false, nil); - } - if (CStats::HighestScores[2] > 0) { - STAT_LINE("FEST_H2", &CStats::HighestScores[2], false, nil); - } - if (CStats::HighestScores[3] > 0) { - STAT_LINE("FEST_H3", &CStats::HighestScores[3], false, nil); - } - if (CStats::HighestScores[4] > 0) { - STAT_LINE("FEST_H4", &CStats::HighestScores[4], false, nil); - } - - switch (m_PrefsLanguage) { - case LANGUAGE_AMERICAN: -#ifndef USE_MEASUREMENTS_IN_METERS - float fTemp; - STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil); - STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledByCar * MILES_IN_METER), true, nil); - STAT_LINE("DISTBIK", &(fTemp = CStats::DistanceTravelledByBike * MILES_IN_METER), true, nil); - STAT_LINE("DISTBOA", &(fTemp = CStats::DistanceTravelledByBoat * MILES_IN_METER), true, nil); - STAT_LINE("DISTGOL", &(fTemp = CStats::DistanceTravelledByGolfCart * MILES_IN_METER), true, nil); - STAT_LINE("DISTHEL", &(fTemp = CStats::DistanceTravelledByHelicoptor * MILES_IN_METER), true, nil); - STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil); - STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil); - break; -#endif - case LANGUAGE_FRENCH: - case LANGUAGE_GERMAN: - case LANGUAGE_ITALIAN: - case LANGUAGE_SPANISH: -#ifdef MORE_LANGUAGES - case LANGUAGE_POLISH: - case LANGUAGE_RUSSIAN: - case LANGUAGE_JAPANESE: -#endif - STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil); - STAT_LINE("FESTDCM", &CStats::DistanceTravelledByCar, true, nil); - STAT_LINE("DISTBIM", &CStats::DistanceTravelledByBike, true, nil); - STAT_LINE("DISTBOM", &CStats::DistanceTravelledByBoat, true, nil); - STAT_LINE("DISTGOM", &CStats::DistanceTravelledByGolfCart, true, nil); - STAT_LINE("DISTHEM", &CStats::DistanceTravelledByHelicoptor, true, nil); - STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil); - STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil); - break; - default: - break; - } - - STAT_LINE("MXFLIP", &CStats::MaximumJumpFlips, false, nil); - STAT_LINE("MXJUMP", &CStats::MaximumJumpSpins, false, nil); - STAT_LINE("BSTSTU", nil, false, nil); - - if (counter == rowIdx) { - gUString[0] = '\0'; - switch (CStats::BestStuntJump) { - case 1: - UnicodeStrcpy(gUString2, TheText.Get("INSTUN")); - return 0; - case 2: - UnicodeStrcpy(gUString2, TheText.Get("PRINST")); - return 0; - case 3: - UnicodeStrcpy(gUString2, TheText.Get("DBINST")); - return 0; - case 4: - UnicodeStrcpy(gUString2, TheText.Get("DBPINS")); - return 0; - case 5: - UnicodeStrcpy(gUString2, TheText.Get("TRINST")); - return 0; - case 6: - UnicodeStrcpy(gUString2, TheText.Get("PRTRST")); - return 0; - case 7: - UnicodeStrcpy(gUString2, TheText.Get("QUINST")); - return 0; - case 8: - UnicodeStrcpy(gUString2, TheText.Get("PQUINS")); - return 0; - default: - UnicodeStrcpy(gUString2, TheText.Get("NOSTUC")); - return 0; - } - } - counter++; - STAT_LINE("PASDRO", &CStats::PassengersDroppedOffWithTaxi, false, nil); - STAT_LINE("MONTAX", &CStats::MoneyMadeWithTaxi, false, nil); - STAT_LINE("FEST_LS", &CStats::LivesSavedWithAmbulance, false, nil); - STAT_LINE("FEST_HA", &CStats::HighestLevelAmbulanceMission, false, nil); - STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil); - STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil); - STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil); - //TODO(MIAMI): move this function to the CStats and add reading of Stat lines tied with "MEDIA" for the "CHASESTAT" cheatcode - return counter; - -#undef STAT_LINE -} - -// TODO(Miami): These #if 0's are here because we still use III radio selector. Remove them when new one reversed void -CMenuManager::ChangeRadioStation(uint8 increaseBy) +CMenuManager::ChangeRadioStation(int8 increaseBy) { if (m_ScrollRadioBy != 0) return; m_PrefsRadioStation += increaseBy; -#if 0 m_ScrollRadioBy = increaseBy; if (m_ScrollRadioBy == 1) { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); - field_F0 = 238.0f; + m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X); } else { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); - field_F0 = 118.0f; + m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - (2 * MENURADIO_ICON_SIZE)); } -#endif if (DMAudio.IsMP3RadioChannelAvailable()) { if (m_PrefsRadioStation < WILDSTYLE) @@ -5024,15 +5712,8 @@ CMenuManager::ChangeRadioStation(uint8 increaseBy) if (m_PrefsRadioStation > WAVE) m_PrefsRadioStation = WILDSTYLE; } -#if 0 DMAudio.StopFrontEndTrack(); DMAudio.PlayFrontEndSound(SOUND_RADIO_CHANGE, 0); -#else - SaveSettings(); - DMAudio.SetRadioInCar(m_PrefsRadioStation); - DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); - OutputDebugString("FRONTEND RADIO STATION CHANGED"); -#endif } #if 0 @@ -5051,5 +5732,3 @@ uint8 CMenuManager::GetNumberOfMenuOptions() #undef GetBackJustUp #undef GetBackJustDown - -#endif diff --git a/src/core/Frontend.h b/src/core/Frontend.h index d2091a52..5e18c29a 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -4,13 +4,14 @@ #else #include "Sprite2d.h" +#include "Timer.h" #define MENUHEADER_POS_X 10.0f #define MENUHEADER_POS_Y 10.0f #define MENUHEADER_HEIGHT 2.0f #define MENUHEADER_WIDTH 1.0f -#define MENU_UNK_X_MARGIN 10.0f +#define MENU_X_MARGIN 10.0f #define MENUACTION_SCALE_MULT 0.9f @@ -22,24 +23,36 @@ #define MENU_DEFAULT_CONTENT_Y 100 #define MENU_DEFAULT_LINE_HEIGHT 29 -#define MENURADIO_ICON_SCALE 60.0f +#define RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin) (xMargin + 30.0f) + +#define MENURADIO_ICON_FIRST_X 238.f +#define MENURADIO_ICON_Y 288.0f +#define MENURADIO_ICON_SIZE 60.0f +#define MENURADIO_SELECTOR_START_Y 285.f // other options should leave room on the screen +#define MENURADIO_SELECTOR_HEIGHT 65.f #define MENUSLIDER_X 500.0f #define MENUSLIDER_UNK 100.0f #define MENUSLIDER_SMALLEST_BAR 8.0f #define MENUSLIDER_BIGGEST_BAR 25.0f -#define BIGTEXT2_X_SCALE 0.6f +#define BIGTEXT2_X_SCALE 0.6f // For FONT_STANDARD #define BIGTEXT2_Y_SCALE 1.2f -#define BIGTEXT_X_SCALE 0.6f +#define BIGTEXT_X_SCALE 0.6f // For FONT_HEADING #define BIGTEXT_Y_SCALE 1.0f -#define MEDIUMTEXT_X_SCALE 0.48f +#define MEDIUMTEXT_X_SCALE 0.48f // For FONT_STANDARD #define MEDIUMTEXT_Y_SCALE 1.0f -#define SMALLTEXT_X_SCALE 0.42f +#define SMALLTEXT_X_SCALE 0.42f // For FONT_STANDARD #define SMALLTEXT_Y_SCALE 0.9f -#define SMALLESTTEXT_X_SCALE 0.3f +#define SMALLESTTEXT_X_SCALE 0.3f // For FONT_STANDARD #define SMALLESTTEXT_Y_SCALE 0.7f +#define LISTITEM_X_SCALE 0.4f // Only unproportional and commonly used scale for FONT_STANDARD +#define LISTITEM_Y_SCALE 0.6f + +#define HELPER_TEXT_RIGHT_MARGIN MENU_X_MARGIN +#define HELPER_TEXT_BOTTOM_MARGIN 18.f + #define PLAYERSETUP_LIST_TOP 58.0f #define PLAYERSETUP_LIST_BOTTOM 95.0f #define PLAYERSETUP_LIST_LEFT 200.0f @@ -51,8 +64,6 @@ #endif #define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f #define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64 -#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f -#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f #define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f #define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f #define PLAYERSETUP_LIST_BODY_TOP 77 @@ -80,16 +91,15 @@ #define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f #define CONTSETUP_BOUND_HIGHLIGHT_HEIGHT 10 #define CONTSETUP_BOUND_COLUMN_WIDTH 190.0f -#define CONTSETUP_LIST_HEADER_HEIGHT 20.0f -#define CONTSETUP_LIST_TOP 28.0f +#define CONTSETUP_LIST_TOP 58.0f #define CONTSETUP_LIST_RIGHT 18.0f -#define CONTSETUP_LIST_BOTTOM 120.0f -#define CONTSETUP_LIST_LEFT 18.0f +#define CONTSETUP_LIST_BOTTOM 78.0f +#define CONTSETUP_LIST_LEFT 30.0f #define CONTSETUP_COLUMN_1_X 40.0f #define CONTSETUP_COLUMN_2_X 210.0f #define CONTSETUP_COLUMN_3_X (CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH + 10.0f) #define CONTSETUP_BACK_RIGHT 35.0f -#define CONTSETUP_BACK_BOTTOM 122.0f +#define CONTSETUP_BACK_BOTTOM 82.0f #define CONTSETUP_BACK_HEIGHT 25.0f enum @@ -182,7 +192,6 @@ enum eMenuScreen MENUPAGE_MOUSE_CONTROLS = 31, MENUPAGE_PAUSE_MENU = 32, MENUPAGE_NONE = 33, // Then chooses main menu or pause menu - MENUPAGE_OUTRO = 34, #ifdef LEGACY_MENU_OPTIONS MENUPAGE_CONTROLLER_SETTINGS, MENUPAGE_DEBUG_MENU, @@ -192,14 +201,26 @@ enum eMenuScreen MENUPAGE_CONTROLLER_PC_OLD4, MENUPAGE_CONTROLLER_DEBUG, #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + #ifdef GRAPHICS_MENU_OPTIONS MENUPAGE_GRAPHICS_SETTINGS, #endif +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + MENUPAGE_DETECT_JOYSTICK, +#endif + +#endif + MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages MENUPAGES }; enum eMenuAction { +#ifdef CUSTOM_FRONTEND_OPTIONS + MENUACTION_CFO_SELECT = -2, + MENUACTION_CFO_DYNAMIC = -1, +#endif MENUACTION_NOTHING, MENUACTION_LABEL, MENUACTION_YES, @@ -254,29 +275,10 @@ enum eMenuAction MENUACTION_DRAWDIST, MENUACTION_MOUSESENS, MENUACTION_MP3VOLUMEBOOST, -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENFORMAT, -#endif #ifdef LEGACY_MENU_OPTIONS MENUACTION_CTRLVIBRATION, MENUACTION_CTRLCONFIG, #endif -#ifdef ANISOTROPIC_FILTERING - MENUACTION_MIPMAPS, - MENUACTION_TEXTURE_FILTERING, -#endif -#ifdef MULTISAMPLING - MENUACTION_MULTISAMPLING, -#endif -#ifdef NO_ISLAND_LOADING - MENUACTION_ISLANDLOADING, -#endif -#ifdef PS2_ALPHA_TEST - MENUACTION_PS2_ALPHA_TEST, -#endif -#ifdef CUTSCENE_BORDERS_SWITCH - MENUACTION_CUTSCENEBORDERS, -#endif }; enum eCheckHover @@ -303,16 +305,8 @@ enum eCheckHover HOVEROPTION_LIST, // also layer in controller setup and skin menu HOVEROPTION_SKIN, HOVEROPTION_USESKIN, // also layer in controller setup and skin menu - HOVEROPTION_RADIO_0, - HOVEROPTION_RADIO_1, - HOVEROPTION_RADIO_2, - HOVEROPTION_RADIO_3, - HOVEROPTION_RADIO_4, - HOVEROPTION_RADIO_5, - HOVEROPTION_RADIO_6, - HOVEROPTION_RADIO_7, - HOVEROPTION_RADIO_8, - HOVEROPTION_RADIO_9, + HOVEROPTION_NEXT_RADIO, + HOVEROPTION_PREV_RADIO, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, HOVEROPTION_INCREASE_DRAWDIST, @@ -330,8 +324,8 @@ enum eCheckHover enum { -#ifdef LEGACY_MENU_OPTIONS - NUM_MENUROWS = 14, +#if defined LEGACY_MENU_OPTIONS || defined CUSTOM_FRONTEND_OPTIONS + NUM_MENUROWS = 18, #else NUM_MENUROWS = 12, #endif @@ -347,7 +341,7 @@ enum eControlMethod enum ControllerSetupColumn { CONTSETUP_PED_COLUMN = 0, - CONTSETUP_VEHICLE_COLUMN = 14, + CONTSETUP_VEHICLE_COLUMN = 16, }; struct tSkinInfo @@ -365,6 +359,7 @@ struct BottomBarOption int32 screenId; }; +#ifndef CUSTOM_FRONTEND_OPTIONS struct CMenuScreen { char m_ScreenName[8]; @@ -382,6 +377,88 @@ struct CMenuScreen uint8 m_Align; } m_aEntries[NUM_MENUROWS]; }; +extern CMenuScreen aScreens[MENUPAGES]; +#else +#include "frontendoption.h" +struct CCustomScreenLayout { + int startX; // not used at all if first entry has X and Y values + int startY; // not used at all if first entry has X and Y values + int lineHeight; // used to determine next entry's Y coordinate, if it has 0-0 as coordinates + bool showLeftRightHelper; + bool noInvasiveBorders; // not needed on pages already handled by game + int xMargin; // useful for two part texts - 0/empty = MENU_X_MARGIN +}; + +struct CCFO +{ + int8 *value; + const char *save; +}; + +struct CCFOSelect : CCFO +{ + char** rightTexts; + int8 numRightTexts; + bool onlyApplyOnEnter; + int8 displayedValue; // only if onlyApplyOnEnter enabled for now + int8 lastSavedValue; // only if onlyApplyOnEnter enabled + ChangeFunc changeFunc; + + CCFOSelect() {}; + CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc){ + this->value = value; + if (value) + this->lastSavedValue = this->displayedValue = *value; + + this->save = save; + this->rightTexts = (char**)rightTexts; + this->numRightTexts = numRightTexts; + this->onlyApplyOnEnter = onlyApplyOnEnter; + this->changeFunc = changeFunc; + } +}; + +struct CCFODynamic : CCFO +{ + DrawFunc drawFunc; + ButtonPressFunc buttonPressFunc; + + CCFODynamic() {}; + CCFODynamic(int8* value, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){ + this->value = value; + this->save = save; + this->drawFunc = drawFunc; + this->buttonPressFunc = buttonPressFunc; + } +}; + +struct CMenuScreenCustom +{ + char m_ScreenName[8]; + int32 m_PreviousPage; // eMenuScreen + CCustomScreenLayout *layout; + ReturnPrevPageFunc returnPrevPageFunc; + + struct CMenuEntry + { + int32 m_Action; // eMenuAction - below zero is CFO + char m_EntryName[8]; + struct { + union { + CCFO *m_CFO; // for initializing + CCFOSelect *m_CFOSelect; + CCFODynamic *m_CFODynamic; + }; + int32 m_SaveSlot; // eSaveSlot + int32 m_TargetMenu; // eMenuScreen + }; + uint16 m_X; + uint16 m_Y; + uint8 m_Align; + } m_aEntries[NUM_MENUROWS]; +}; +extern CMenuScreenCustom aScreens[MENUPAGES]; +#endif struct MenuTrapezoid { @@ -473,7 +550,7 @@ public: int8 m_PrefsShowSubtitles; int8 m_PrefsShowLegends; int8 m_PrefsUseWideScreen; - int8 m_PrefsVsync; // TODO(Miami): Are we sure? + int8 m_PrefsVsync; int8 m_PrefsVsyncDisp; int8 m_PrefsFrameLimiter; int8 m_nPrefsAudio3DProviderIndex; @@ -481,7 +558,7 @@ public: int8 m_PrefsDMA; int8 m_PrefsSfxVolume; int8 m_PrefsMusicVolume; - uint8 m_PrefsRadioStation; + int8 m_PrefsRadioStation; uint8 m_PrefsStereoMono; // unused except restore settings int32 m_nCurrOption; bool m_bQuitGameNoCD; @@ -501,7 +578,7 @@ public: int32 field_54; int8 m_bLanguageLoaded; uint8 m_PrefsAllowNastyGame; - uint8 m_PrefsMP3BoostVolume; + int8 m_PrefsMP3BoostVolume; uint8 m_ControlMethod; int32 m_nPrefsVideoMode; int32 m_nDisplayVideoMode; @@ -514,10 +591,10 @@ public: uint8 field_74[4]; int32 *pControlEdit; bool m_OnlySaveMenu; - int32 m_menuTransitionProgress; + int32 m_firstStartCounter; CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES]; bool m_bSpritesLoaded; - int32 field_F0; + int32 m_LeftMostRadioX; int32 m_ScrollRadioBy; int32 m_nCurrScreen; int32 m_nPrevScreen; @@ -621,20 +698,34 @@ public: ISLAND_LOADING_HIGH }; - static int8 m_DisplayIslandLoading; - static int8 m_PrefsIslandLoading; + int8 m_PrefsIslandLoading; - #define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p) - #define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p) + #define ISLAND_LOADING_IS(p) if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p) + #define ISLAND_LOADING_ISNT(p) if (FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p) #else #define ISLAND_LOADING_IS(p) #define ISLAND_LOADING_ISNT(p) #endif +#ifdef XBOX_MESSAGE_SCREEN + static uint32 m_nDialogHideTimer; + static PauseModeTime m_nDialogHideTimerPauseMode; + static bool m_bDialogOpen; + static wchar *m_pDialogText; + static bool m_bSaveWasSuccessful; + + static void SetDialogText(const char*); + static bool DialogTextCmp(const char*); + static void ToggleDialog(bool); + static void SetDialogTimer(uint32); + void ProcessDialogTimer(void); + void DrawOverlays(void); + void CloseDialog(void); +#endif + void Initialise(); void PrintMap(); void SetFrontEndRenderStates(); - static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2); static void CentreMousePointer(); void CheckCodesForControls(int); bool CheckHover(int x1, int x2, int y1, int y2); @@ -651,7 +742,6 @@ public: void DrawBackground(bool transitionCall); void DrawPlayerSetupScreen(bool); int FadeIn(int alpha); - void FilterOutColorMarkersFromString(wchar*); int GetStartOptionsCntrlConfigScreens(); void InitialiseChangedLanguageSettings(); void LoadAllTextures(); @@ -665,7 +755,7 @@ public: void ProcessList(bool &optionSelected, bool &goBack); void UserInput(); void ProcessUserInput(uint8, uint8, uint8, uint8, int8); - void ChangeRadioStation(uint8); + void ChangeRadioStation(int8); void ProcessFileActions(); void ProcessOnOffMenuOptions(); void RequestFrontEndShutDown(); @@ -679,8 +769,10 @@ public: void UnloadTextures(); void WaitForUserCD(); int GetNumOptionsCntrlConfigScreens(); - int ConstructStatLine(int); void SwitchToNewScreen(int8); + void AdditionalOptionInput(bool &goBack); + void ExportStats(void); + void PrintRadioSelector(void); // New (not in function or inlined in the game) void ThingsToDoBeforeLeavingPage(); @@ -698,6 +790,5 @@ VALIDATE_SIZE(CMenuManager, 0x688); #endif extern CMenuManager FrontEndMenuManager; -extern CMenuScreen aScreens[]; #endif diff --git a/src/core/Frontend_PS2.cpp b/src/core/Frontend_PS2.cpp index c9264f7d..1ccb658b 100644 --- a/src/core/Frontend_PS2.cpp +++ b/src/core/Frontend_PS2.cpp @@ -22,7 +22,7 @@ #include "Game.h" #include "World.h" #include "PlayerInfo.h" -#include "FrontendControls.h" +#include "FrontEndControls.h" #include "MemoryCard.h" #define CRect_SZ(x, y, w, h) CRect(x, y, x+w, y+h) @@ -3017,4 +3017,4 @@ CMenuManager::FilterOutColorMarkersFromString(wchar *string, CRGBA &color) *dst = '\0'; } -#endif
\ No newline at end of file +#endif diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 4034c4b6..348ac26d 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -32,6 +32,7 @@ #include "Fluff.h" #include "Font.h" #include "Frontend.h" +#include "frontendoption.h" #include "GameLogic.h" #include "Garages.h" #include "GenericGameStorage.h" @@ -44,6 +45,7 @@ #include "MBlur.h" #include "Messages.h" #include "MemoryCard.h" +#include "MemoryHeap.h" #include "Pad.h" #include "Particle.h" #include "ParticleObject.h" @@ -93,6 +95,10 @@ #include "WaterCreatures.h" #include "postfx.h" #include "custompipes.h" +#include "screendroplets.h" +#ifdef USE_TEXTURE_POOL +#include "TexturePools.h" +#endif eLevelName CGame::currLevel; int32 CGame::currArea; @@ -163,6 +169,11 @@ CGame::InitialiseOnceBeforeRW(void) #ifdef EXTENDED_COLOURFILTER CPostFX::InitOnce(); #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + // Not needed here but may be needed in future + // if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) + CustomFrontendOptionsPopulate(); +#endif return true; } @@ -182,12 +193,22 @@ CGame::InitialiseRenderWare(void) #ifdef USE_TEXTURE_POOL _TexturePoolsInitialise(); #endif - + CTxdStore::Initialise(); CVisibilityPlugins::Initialise(); - + +#ifdef GTA_PS2 + RpSkySelectTrueTSClipper(TRUE); + RpSkySelectTrueTLClipper(TRUE); + + // PS2ManagerApplyDirectionalLightingCB() uploads the GTA lights + // directly without going through RpWorld and all that + SetupPS2ManagerDefaultLightingCallback(); + PreAllocateRwObjects(); +#endif + /* Create camera */ - Scene.camera = CameraCreate(RsGlobal.width, RsGlobal.height, TRUE); + Scene.camera = CameraCreate(SCREEN_WIDTH, SCREEN_HEIGHT, TRUE); ASSERT(Scene.camera != nil); if (!Scene.camera) { @@ -217,7 +238,7 @@ CGame::InitialiseRenderWare(void) /* Add the camera to the world */ RpWorldAddCamera(Scene.world, Scene.camera); LightsCreate(Scene.world); - + CreateDebugFont(); #ifdef LIBRW @@ -234,23 +255,39 @@ CGame::InitialiseRenderWare(void) ReplaceAtomicPipeCallback(); #endif // PS2_ALPHA_TEST #endif // LIBRW - + + PUSH_MEMID(MEMID_TEXTURES); CFont::Initialise(); CHud::Initialise(); CPlayerSkin::Initialise(); - + POP_MEMID(); + +#ifdef EXTENDED_PIPELINES + CustomPipes::CustomPipeInit(); // need Scene.world for this +#endif +#ifdef SCREEN_DROPLETS + ScreenDroplets::InitDraw(); +#endif + return (true); } void CGame::ShutdownRenderWare(void) { +#ifdef SCREEN_DROPLETS + ScreenDroplets::Shutdown(); +#endif +#ifdef EXTENDED_PIPELINES + CustomPipes::CustomPipeShutdown(); +#endif + DestroySplashScreen(); CHud::Shutdown(); CFont::Shutdown(); for ( int32 i = 0; i < NUMPLAYERS; i++ ) CWorld::Players[i].DeletePlayerSkin(); - + CPlayerSkin::Shutdown(); DestroyDebugFont(); @@ -282,7 +319,12 @@ bool CGame::InitialiseOnceAfterRW(void) CSurfaceTable::Initialise("DATA\\SURFACE.DAT"); CPedStats::Initialise(); CTimeCycle::Initialise(); +#ifdef GTA_PS2 + LoadingScreen("Loading the Game", "Initialising audio", GetRandomSplashScreen()); +#endif DMAudio.Initialise(); + +#ifndef GTA_PS2 if ( DMAudio.GetNum3DProvidersAvailable() == 0 ) FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER; @@ -299,6 +341,7 @@ bool CGame::InitialiseOnceAfterRW(void) DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); DMAudio.SetEffectsFadeVol(127); DMAudio.SetMusicFadeVol(127); +#endif return true; } @@ -314,23 +357,40 @@ bool CGame::Initialise(const char* datFile) { ResetLoadingScreenBar(); strcpy(aDatFile, datFile); + +#ifdef GTA_PS2 + // TODO: upload VU0 collision code here +#endif + CPools::Initialise(); + +#ifndef GTA_PS2 CIniFile::LoadIniFile(); +#endif #ifdef USE_TEXTURE_POOL _TexturePoolsUnknown(false); #endif currLevel = LEVEL_BEACH; currArea = AREA_MAIN_MAP; + + PUSH_MEMID(MEMID_TEXTURES); LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen()); gameTxdSlot = CTxdStore::AddTxdSlot("generic"); CTxdStore::Create(gameTxdSlot); CTxdStore::AddRef(gameTxdSlot); + LoadingScreen("Loading the Game", "Loading particles", nil); int particleTxdSlot = CTxdStore::AddTxdSlot("particle"); CTxdStore::LoadTxd(particleTxdSlot, "MODELS/PARTICLE.TXD"); CTxdStore::AddRef(particleTxdSlot); CTxdStore::SetCurrentTxd(gameTxdSlot); LoadingScreen("Loading the Game", "Setup game variables", nil); + POP_MEMID(); + +#ifdef GTA_PS2 + CDma::SyncChannel(0, true); +#endif + CGameLogic::InitAtStartOfGame(); CReferences::Init(); TheCamera.Init(); @@ -350,21 +410,32 @@ bool CGame::Initialise(const char* datFile) CMessages::ClearAllMessagesDisplayedByGame(); CRecordDataForGame::Init(); CRestart::Initialise(); + + PUSH_MEMID(MEMID_WORLD); CWorld::Initialise(); + POP_MEMID(); + + PUSH_MEMID(MEMID_TEXTURES); CParticle::Initialise(); -#ifdef PS2 - gStartX = -180.0f; - gStartY = 180.0f; - gStartZ = 14.0f; -#endif + POP_MEMID(); + + PUSH_MEMID(MEMID_ANIMATION); CAnimManager::Initialise(); CCutsceneMgr::Initialise(); + POP_MEMID(); + + PUSH_MEMID(MEMID_CARS); CCarCtrl::Init(); + POP_MEMID(); + + PUSH_MEMID(MEMID_DEF_MODELS); InitModelIndices(); CModelInfo::Initialise(); CPickups::Init(); CTheCarGenerators::Init(); + CdStreamAddImage("MODELS\\GTA3.IMG"); + CFileLoader::LoadLevel("DATA\\DEFAULT.DAT"); CFileLoader::LoadLevel(datFile); #ifdef EXTENDED_PIPELINES @@ -376,17 +447,21 @@ bool CGame::Initialise(const char* datFile) CVehicleModelInfo::LoadVehicleColours(); CVehicleModelInfo::LoadEnvironmentMaps(); CTheZones::PostZoneCreation(); + POP_MEMID(); + LoadingScreen("Loading the Game", "Setup paths", nil); ThePaths.PreparePathData(); for (int i = 0; i < NUMPLAYERS; i++) CWorld::Players[i].Clear(); CWorld::Players[0].LoadPlayerSkin(); TestModelIndices(); + LoadingScreen("Loading the Game", "Setup water", nil); WaterLevelInitialise("DATA\\WATER.DAT"); TheConsole.Init(); CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; + LoadingScreen("Loading the Game", "Setup streaming", nil); CStreaming::LoadInitialVehicles(); CStreaming::LoadInitialPeds(); @@ -394,22 +469,32 @@ bool CGame::Initialise(const char* datFile) CStreaming::LoadAllRequestedModels(false); CStreaming::RemoveIslandsNotUsed(currLevel); printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d + LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen()); + PUSH_MEMID(MEMID_ANIMATION); CAnimManager::LoadAnimFiles(); + POP_MEMID(); + CStreaming::LoadInitialWeapons(); CStreaming::LoadAllRequestedModels(0); CPed::Initialise(); CRouteNode::Initialise(); CEventList::Initialise(); +#ifdef SCREEN_DROPLETS + ScreenDroplets::Initialise(); +#endif LoadingScreen("Loading the Game", "Find big buildings", nil); CRenderer::Init(); + LoadingScreen("Loading the Game", "Setup game variables", nil); CRadar::Initialise(); CRadar::LoadTextures(); CWeapon::InitialiseWeapons(); + LoadingScreen("Loading the Game", "Setup traffic lights", nil); CTrafficLights::ScanForLightsOnMap(); CRoadBlocks::Init(); + LoadingScreen("Loading the Game", "Setup game variables", nil); CPopulation::Initialise(); CWorld::PlayerInFocus = 0; @@ -420,10 +505,16 @@ bool CGame::Initialise(const char* datFile) CAntennas::Init(); CGlass::Init(); gPhoneInfo.Initialise(); +#ifdef GTA_SCENE_EDIT CSceneEdit::Initialise(); +#endif + LoadingScreen("Loading the Game", "Load scripts", nil); + PUSH_MEMID(MEMID_SCRIPT); CTheScripts::Init(); CGangs::Initialise(); + POP_MEMID(); + LoadingScreen("Loading the Game", "Setup game variables", nil); CClock::Initialise(1000); CHeli::InitHelis(); @@ -439,24 +530,26 @@ bool CGame::Initialise(const char* datFile) CWaterCannons::Init(); CBridge::Init(); CGarages::Init(); + LoadingScreen("Loading the Game", "Position dynamic objects", nil); LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); + CTrain::InitTrains(); CPlane::InitPlanes(); CCredits::Init(); CRecordDataForChase::Init(); CReplay::Init(); + + LoadingScreen("Loading the Game", "Start script", nil); #ifdef PS2_MENU if ( !TheMemoryCard.m_bWantToLoad ) - { #endif - LoadingScreen("Loading the Game", "Start script", nil); - CTheScripts::StartTestScript(); - CTheScripts::Process(); - TheCamera.Process(); -#ifdef PS2_MENU + { + CTheScripts::StartTestScript(); + CTheScripts::Process(); + TheCamera.Process(); } -#endif + LoadingScreen("Loading the Game", "Load scene", nil); CCollision::ms_collisionInMemory = currLevel; for (int i = 0; i < MAX_PADS; i++) @@ -481,9 +574,7 @@ bool CGame::ShutDown(void) CScriptPaths::Shutdown(); CWaterCreatures::RemoveAll(); CSpecialFX::Shutdown(); -#ifndef PS2 CGarages::Shutdown(); -#endif CMovingThings::Shutdown(); gPhoneInfo.Shutdown(); CWeapon::ShutdownWeapons(); @@ -537,13 +628,11 @@ void CGame::ReInitGameObjectVariables(void) CGameLogic::InitAtStartOfGame(); #ifdef PS2_MENU if ( !TheMemoryCard.m_bWantToLoad ) - { #endif - TheCamera.Init(); - TheCamera.SetRwCamera(Scene.camera); -#ifdef PS2_MENU + { + TheCamera.Init(); + TheCamera.SetRwCamera(Scene.camera); } -#endif CDebug::DebugInitTextBuffer(); CWeather::Init(); CUserDisplay::Init(); @@ -552,11 +641,6 @@ void CGame::ReInitGameObjectVariables(void) CWorld::bDoingCarCollisions = false; CHud::ReInitialise(); CRadar::Initialise(); -#ifdef PS2 - gStartX = -180.0f; - gStartY = 180.0f; - gStartZ = 14.0f; -#endif CCarCtrl::ReInit(); CTimeCycle::Initialise(); CDraw::SetFOV(120.0f); @@ -568,6 +652,9 @@ void CGame::ReInitGameObjectVariables(void) currArea = AREA_MAIN_MAP; CPed::Initialise(); CEventList::Initialise(); +#ifdef SCREEN_DROPLETS + ScreenDroplets::Initialise(); +#endif CWeapon::InitialiseWeapons(); CPopulation::Initialise(); @@ -575,15 +662,15 @@ void CGame::ReInitGameObjectVariables(void) CWorld::Players[i].Clear(); CWorld::PlayerInFocus = 0; -#ifdef PS2 - CWeaponEffects::Init(); - CSkidmarks::Init(); -#endif CAntennas::Init(); CGlass::Init(); gPhoneInfo.Initialise(); + + PUSH_MEMID(MEMID_SCRIPT); CTheScripts::Init(); CGangs::Initialise(); + POP_MEMID(); + CTimer::Initialise(); CClock::Initialise(1000); CTheCarGenerators::Init(); @@ -594,10 +681,6 @@ void CGame::ReInitGameObjectVariables(void) CPickups::Init(); CPacManPickups::Init(); CGarages::Init(); -#ifdef PS2 - CClouds::Init(); - CRemote::Init(); -#endif CSpecialFX::Init(); CRopes::Init(); CWaterCannons::Init(); @@ -667,8 +750,10 @@ void CGame::InitialiseWhenRestarting(void) if (b_FoundRecentSavedGameWantToLoad || FrontEndMenuManager.m_bWantToLoad) { LoadSplash("splash1"); +#ifndef XBOX_MESSAGE_SCREEN if (FrontEndMenuManager.m_bWantToLoad) FrontEndMenuManager.MessageScreen("FELD_WR", true); +#endif } b_FoundRecentSavedGameWantToLoad = false; @@ -677,6 +762,14 @@ void CGame::InitialiseWhenRestarting(void) if ( FrontEndMenuManager.m_bWantToLoad == true ) { +#ifdef XBOX_MESSAGE_SCREEN + FrontEndMenuManager.SetDialogTimer(1000); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 0); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + FrontEndMenuManager.DrawOverlays(); + DoRWStuffEndOfFrame(); +#endif RestoreForStartLoad(); } @@ -685,8 +778,7 @@ void CGame::InitialiseWhenRestarting(void) if ( FrontEndMenuManager.m_bWantToLoad == true ) { FrontEndMenuManager.m_bWantToLoad = false; - // TODO(Miami) - //InitRadioStationPositionList(); + InitRadioStationPositionList(); if ( GenericLoad() == true ) { DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); @@ -710,6 +802,9 @@ void CGame::InitialiseWhenRestarting(void) currLevel = LEVEL_GENERIC; CCollision::SortOutCollisionAfterLoad(); } +#ifdef XBOX_MESSAGE_SCREEN + FrontEndMenuManager.ProcessDialogTimer(); +#endif } CTimer::Update(); @@ -723,15 +818,17 @@ void CGame::InitialiseWhenRestarting(void) void CGame::Process(void) { CPad::UpdatePads(); -#ifdef GTA_PS2 +#ifdef USE_CUSTOM_ALLOCATOR ProcessTidyUpMemory(); #endif #ifdef DEBUGMENU DebugMenuProcess(); #endif CCutsceneMgr::Update(); + if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused()) FrontEndMenuManager.Process(); + CTheZones::Update(); // DRM call in here uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); @@ -748,7 +845,11 @@ void CGame::Process(void) CPad::DoCheats(); CClock::Update(); CWeather::Update(); + + PUSH_MEMID(MEMID_SCRIPT); CTheScripts::Process(); + POP_MEMID(); + CCollision::Update(); CScriptPaths::Update(); CTrain::UpdateTrains(); @@ -758,7 +859,9 @@ void CGame::Process(void) CSkidmarks::Update(); CAntennas::Update(); CGlass::Update(); +#ifdef GTA_SCENE_EDIT CSceneEdit::Update(); +#endif CSetPieces::Update(); CEventList::Update(); CParticle::Update(); @@ -780,7 +883,11 @@ void CGame::Process(void) CWaterCannons::Update(); CUserDisplay::Process(); CReplay::Update(); + + PUSH_MEMID(MEMID_WORLD); CWorld::Process(); + POP_MEMID(); + gAccidentManager.Update(); CPacManPickups::Update(); CPickups::Update(); @@ -802,62 +909,399 @@ void CGame::Process(void) gPhoneInfo.Update(); if (!CReplay::IsPlayingBack()) { + PUSH_MEMID(MEMID_CARS); if (processTime < 2) CCarCtrl::GenerateRandomCars(); CRoadBlocks::GenerateRoadBlocks(); CCarCtrl::RemoveDistantCars(); CCarCtrl::RemoveCarsIfThePoolGetsFull(); + POP_MEMID(); } } +#ifdef GTA_PS2 + CMemCheck::DoTest(); +#endif } -void -CGame::InitAfterFocusLoss() +#ifdef USE_CUSTOM_ALLOCATOR + +// TODO(MIAMI) + +int32 gNumMemMoved; + +bool +MoveMem(void** ptr) { - FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = FrontEndMenuManager.m_lastWorking3DAudioProvider; - DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_lastWorking3DAudioProvider); + if (*ptr) { + gNumMemMoved++; + void* newPtr = gMainHeap.MoveMemory(*ptr); + if (*ptr != newPtr) { + *ptr = newPtr; + return true; + } + } + return false; +} - if (!FrontEndMenuManager.m_bGameNotLoaded && !FrontEndMenuManager.m_bMenuActive) - FrontEndMenuManager.m_bStartUpFrontEndRequested = true; +// Some convenience structs +struct SkyDataPrefix +{ + uint32 pktSize1; + uint32 data; // pointer to data as read from TXD + uint32 pktSize2; + uint32 unused; +}; + +struct DMAGIFUpload +{ + uint32 tag1_qwc, tag1_addr; // dmaref + uint32 nop1, vif_direct1; + + uint32 giftag[4]; + uint32 gs_bitbltbuf[4]; + + uint32 tag2_qwc, tag2_addr; // dmaref + uint32 nop2, vif_direct2; +}; + +// This is very scary. it depends on the exact memory layout of the DMA chains and whatnot +RwTexture* +MoveTextureMemoryCB(RwTexture* texture, void* pData) +{ +#ifdef GTA_PS2 + bool* pRet = (bool*)pData; + RwRaster* raster = RwTextureGetRaster(texture); + _SkyRasterExt* rasterExt = RASTEREXTFROMRASTER(raster); + if (raster->originalPixels == nil || // the raw data + raster->cpPixels == raster->originalPixels || // old format, can't handle it + rasterExt->dmaRefCount != 0 && rasterExt->dmaClrCount != 0) + return texture; + + // this is the allocated pointer we will move + SkyDataPrefix* prefix = (SkyDataPrefix*)raster->originalPixels; + DMAGIFUpload* uploads = (DMAGIFUpload*)(prefix + 1); + + // We have 4qw for each upload, + // i.e. for each buffer width of mip levels, + // and the palette if there is one. + // NB: this code does NOT support mipmaps! + // so we assume two uploads (pixels and palette) + // + // each upload looks like this: + // (DMAcnt; NOP; VIF DIRECT(2)) + // giftag (1, A+D) + // GS_BITBLTBUF + // (DMAref->pixel data; NOP; VIF DIRECT(5)) + // the DMArefs are what we have to adjust + uintptr dataDiff, upload1Diff, upload2Diff, pixelDiff, paletteDiff; + dataDiff = prefix->data - (uintptr)raster->originalPixels; + upload1Diff = uploads[0].tag2_addr - (uintptr)raster->originalPixels; + if (raster->palette) + upload2Diff = uploads[1].tag2_addr - (uintptr)raster->originalPixels; + pixelDiff = (uintptr)raster->cpPixels - (uintptr)raster->originalPixels; + if (raster->palette) + paletteDiff = (uintptr)raster->palette - (uintptr)raster->originalPixels; + uint8* newptr = (uint8*)gMainHeap.MoveMemory(raster->originalPixels); + if (newptr != raster->originalPixels) { + // adjust everything + prefix->data = (uintptr)newptr + dataDiff; + uploads[0].tag2_addr = (uintptr)newptr + upload1Diff; + if (raster->palette) + uploads[1].tag2_addr = (uintptr)newptr + upload2Diff; + raster->originalPixels = newptr; + raster->cpPixels = newptr + pixelDiff; + if (raster->palette) + raster->palette = newptr + paletteDiff; + + if (pRet) { + *pRet = true; + return nil; + } + } +#else + // nothing to do here really, everything should be in videomemory +#endif + return texture; } bool -CGame::CanSeeWaterFromCurrArea(void) +MoveAtomicMemory(RpAtomic* atomic, bool onlyOne) { - return currArea == AREA_MAIN_MAP || currArea == AREA_MANSION - || currArea == AREA_HOTEL; + RpGeometry* geo = RpAtomicGetGeometry(atomic); + +#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31 + if (MoveMem((void**)&geo->triangles) && onlyOne) + return true; + if (MoveMem((void**)&geo->matList.materials) && onlyOne) + return true; + if (MoveMem((void**)&geo->preLitLum) && onlyOne) + return true; + if (MoveMem((void**)&geo->texCoords[0]) && onlyOne) + return true; + if (MoveMem((void**)&geo->texCoords[1]) && onlyOne) + return true; + + // verts and normals of morph target are allocated together + int vertDiff; + if (geo->morphTarget->normals) + vertDiff = geo->morphTarget->normals - geo->morphTarget->verts; + if (MoveMem((void**)&geo->morphTarget->verts)) { + if (geo->morphTarget->normals) + geo->morphTarget->normals = geo->morphTarget->verts + vertDiff; + if (onlyOne) + return true; + } + + RpMeshHeader* oldmesh = geo->mesh; + if (MoveMem((void**)&geo->mesh)) { + // index pointers are allocated together with meshes, + // have to relocate those too + RpMesh* mesh = (RpMesh*)(geo->mesh + 1); + uintptr reloc = (uintptr)geo->mesh - (uintptr)oldmesh; + for (int i = 0; i < geo->mesh->numMeshes; i++) + mesh[i].indices = (RxVertexIndex*)((uintptr)mesh[i].indices + reloc); + if (onlyOne) + return true; + } +#else + // we could do something in librw here +#endif + return false; } bool -CGame::CanSeeOutSideFromCurrArea(void) +MoveColModelMemory(CColModel& colModel, bool onlyOne) { - return currArea == AREA_MAIN_MAP || currArea == AREA_MALL || - currArea == AREA_MANSION || currArea == AREA_HOTEL; +#if GTA_VERSION >= GTA3_PS2_160 + // hm...should probably only do this if ownsCollisionVolumes + // but it doesn't exist on PS2... + if (!colModel.ownsCollisionVolumes) + return false; +#endif + + if (MoveMem((void**)&colModel.spheres) && onlyOne) + return true; + if (MoveMem((void**)&colModel.lines) && onlyOne) + return true; + if (MoveMem((void**)&colModel.boxes) && onlyOne) + return true; + if (MoveMem((void**)&colModel.vertices) && onlyOne) + return true; + if (MoveMem((void**)&colModel.triangles) && onlyOne) + return true; + if (MoveMem((void**)&colModel.trianglePlanes) && onlyOne) + return true; + return false; } -void CGame::DrasticTidyUpMemory(bool) +RpAtomic* +MoveAtomicMemoryCB(RpAtomic* atomic, void* pData) { -#ifdef USE_TEXTURE_POOL - // TODO + bool* pRet = (bool*)pData; + if (pRet == nil) + MoveAtomicMemory(atomic, false); + else if (MoveAtomicMemory(atomic, true)) { + *pRet = true; + return nil; + } + return atomic; +} + +bool +TidyUpModelInfo(CBaseModelInfo* modelInfo, bool onlyone) +{ + if (modelInfo->GetColModel() && modelInfo->DoesOwnColModel()) + if (MoveColModelMemory(*modelInfo->GetColModel(), onlyone)) + return true; + + RwObject* rwobj = modelInfo->GetRwObject(); + if (RwObjectGetType(rwobj) == rpATOMIC) + if (MoveAtomicMemory((RpAtomic*)rwobj, onlyone)) + return true; + if (RwObjectGetType(rwobj) == rpCLUMP) { + bool ret = false; + if (onlyone) + RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, &ret); + else + RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, nil); + if (ret) + return true; + } + + if (modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel) + if (MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone)) + return true; + + return false; +} #endif -#ifdef PS2 - // meow + + +void CGame::DrasticTidyUpMemory(bool flushDraw) +{ +#ifdef USE_CUSTOM_ALLOCATOR + bool removedCol = false; + + TidyUpMemory(true, flushDraw); + + if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) { + CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); + TidyUpMemory(true, flushDraw); + } + + if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) { + CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC); + TidyUpMemory(true, flushDraw); + removedCol = true; + } + + if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) { + CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); + CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); + CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); + TidyUpMemory(true, flushDraw); + } + + if (removedCol) { + // different on PS2 + CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory); + } + + if (!playingIntro) + CStreaming::RequestBigBuildings(currLevel); + + CStreaming::LoadAllRequestedModels(true); #endif } -void CGame::TidyUpMemory(bool unk1, bool unk2) +void CGame::TidyUpMemory(bool moveTextures, bool flushDraw) { -#ifdef PS2 - // meow +#ifdef USE_CUSTOM_ALLOCATOR + printf("Largest free block before tidy %d\n", gMainHeap.GetLargestFreeBlock()); + + if (moveTextures) { + if (flushDraw) { +#ifdef GTA_PS2 + for (int i = 0; i < sweMaxFlips + 1; i++) { +#else + for (int i = 0; i < 5; i++) { // probably more than needed +#endif + RwCameraBeginUpdate(Scene.camera); + RwCameraEndUpdate(Scene.camera); + RwCameraShowRaster(Scene.camera, nil, 0); + } + } + int fontSlot = CTxdStore::FindTxdSlot("fonts"); + + for (int i = 0; i < TXDSTORESIZE; i++) { + if (i == fontSlot || + CTxdStore::GetSlot(i) == nil) + continue; + RwTexDictionary* txd = CTxdStore::GetSlot(i)->texDict; + if (txd) + RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, nil); + } + } + + // animations + for (int i = 0; i < NUMANIMATIONS; i++) { + CAnimBlendHierarchy* anim = CAnimManager::GetAnimation(i); + if (anim == nil) + continue; // cannot happen + anim->MoveMemory(); + } + + // model info + for (int i = 0; i < MODELINFOSIZE; i++) { + CBaseModelInfo* mi = CModelInfo::GetModelInfo(i); + if (mi == nil) + continue; + TidyUpModelInfo(mi, false); + } + + printf("Largest free block after tidy %d\n", gMainHeap.GetLargestFreeBlock()); #endif - if (unk2) { - DrasticTidyUpMemory(true); // parameter is unknown too } -} void CGame::ProcessTidyUpMemory(void) { -#ifdef PS2 - // meow +#ifdef USE_CUSTOM_ALLOCATOR + static int32 modelIndex = 0; + static int32 animIndex = 0; + static int32 txdIndex = 0; + bool txdReturn = false; + RwTexDictionary* txd = nil; + gNumMemMoved = 0; + + // model infos + for (int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++) { + CBaseModelInfo* mi; + do { + mi = CModelInfo::GetModelInfo(modelIndex); + modelIndex++; + if (modelIndex >= MODELINFOSIZE) + modelIndex = 0; + } while (mi == nil); + + if (TidyUpModelInfo(mi, true)) + return; + } + + // tex dicts + for (int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++) { + if (gNumMemMoved > 80) + break; + + do { +#ifdef FIX_BUGS + txd = nil; #endif + if (CTxdStore::GetSlot(txdIndex)) + txd = CTxdStore::GetSlot(txdIndex)->texDict; + txdIndex++; + if (txdIndex >= TXDSTORESIZE) + txdIndex = 0; + } while (txd == nil); + + RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, &txdReturn); + if (txdReturn) + return; + } + + // animations + CAnimBlendHierarchy* anim; + do { + anim = CAnimManager::GetAnimation(animIndex); + animIndex++; + if (animIndex >= NUMANIMATIONS) + animIndex = 0; + } while (anim == nil); // always != nil + anim->MoveMemory(true); +#endif +} + +void +CGame::InitAfterFocusLoss() +{ + FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = FrontEndMenuManager.m_lastWorking3DAudioProvider; + DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_lastWorking3DAudioProvider); + + if (!FrontEndMenuManager.m_bGameNotLoaded && !FrontEndMenuManager.m_bMenuActive) + FrontEndMenuManager.m_bStartUpFrontEndRequested = true; +} + +bool +CGame::CanSeeWaterFromCurrArea(void) +{ + return currArea == AREA_MAIN_MAP || currArea == AREA_MANSION + || currArea == AREA_HOTEL; +} + +bool +CGame::CanSeeOutSideFromCurrArea(void) +{ + return currArea == AREA_MAIN_MAP || currArea == AREA_MALL || + currArea == AREA_MANSION || currArea == AREA_HOTEL; } diff --git a/src/core/General.h b/src/core/General.h index 7e06b96e..69492fb8 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -123,6 +123,15 @@ public: return *str2 != '\0'; } + static bool faststrncmp(const char *str1, const char *str2, uint32 count) + { + for(uint32 i = 0; *str1 && i < count; str1++, str2++, i++) { + if (*str1 != *str2) + return true; + } + return false; + } + static bool faststricmp(const char *str1, const char *str2) { for (; *str1; str1++, str2++) { diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index 11cd3078..173de805 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -2,44 +2,10 @@ #include "Frontend.h" #ifdef PC_MENU -#ifdef CUTSCENE_BORDERS_SWITCH -#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen, -#else -#define MENU_CUTSCENE_BORDERS_SWITCH(screen) -#endif - -#ifdef IMPROVED_VIDEOMODE -#define MENU_IMPROVED_VIDEOMODE(screen) MENUACTION_SCREENFORMAT, "FEM_SCF", SAVESLOT_NONE, screen, -#else -#define MENU_IMPROVED_VIDEOMODE(screen) -#endif - -#ifdef ANISOTROPIC_FILTERING -#define MENU_MIPMAPS(screen) MENUACTION_MIPMAPS, "FED_MIP", SAVESLOT_NONE, screen, -#define MENU_TEXTURE_FILTERING(screen) MENUACTION_TEXTURE_FILTERING, "FED_FIL", SAVESLOT_NONE, screen, -#else -#define MENU_MIPMAPS(screen) -#define MENU_TEXTURE_FILTERING(screen) -#endif - -#ifdef MULTISAMPLING -#define MENU_MULTISAMPLING(screen) MENUACTION_MULTISAMPLING, "FED_AAS", SAVESLOT_NONE, screen, -#else -#define MENU_MULTISAMPLING(screen) -#endif - -#ifdef NO_ISLAND_LOADING -#define MENU_ISLAND_LOADING(screen) MENUACTION_ISLANDLOADING, "FEM_ISL", SAVESLOT_NONE, screen, -#else -#define MENU_ISLAND_LOADING(screen) -#endif - -#ifdef PS2_ALPHA_TEST -#define MENU_PS2_ALPHA_TEST(screen) MENUACTION_PS2_ALPHA_TEST, "FEM_2PR", SAVESLOT_NONE, screen, -#else -#define MENU_PS2_ALPHA_TEST(screen) -#endif +// Please don't touch this file, except for bug fixing or ports. +// Check MenuScreensCustom.cpp +#ifndef CUSTOM_FRONTEND_OPTIONS CMenuScreen aScreens[] = { // MENUPAGE_STATS = 0 { "FEH_STA", MENUPAGE_NONE, 3, @@ -72,7 +38,7 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER, }, - // MENUPAGE_GRAPHICS_SETTINGS = 4 + // MENUPAGE_DISPLAY_SETTINGS = 4 #ifdef LEGACY_MENU_OPTIONS #define Y_OFFSET 50 #else @@ -95,14 +61,8 @@ CMenuScreen aScreens[] = { MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT, MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT, MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT, -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENFORMAT,"FED_POS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT, - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 328 + Y_OFFSET, MENUALIGN_CENTER, - MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 353 + Y_OFFSET, MENUALIGN_CENTER, -#else - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER, + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 328 + Y_OFFSET, MENUALIGN_CENTER, -#endif }, #undef Y_OFFSET @@ -255,7 +215,9 @@ CMenuScreen aScreens[] = { // MENUPAGE_CONTROLLER_PC = 26 { "FET_CTL", MENUPAGE_OPTIONS, 0, +#ifdef PC_PLAYER_CONTROLS MENUACTION_CTRLMETHOD, "FET_STI", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 150, MENUALIGN_CENTER, +#endif MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 0, 0, MENUALIGN_CENTER, MENUACTION_CHANGEMENU, "FEC_MOU", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_CENTER, MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, MENUALIGN_CENTER, @@ -286,10 +248,8 @@ CMenuScreen aScreens[] = { MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER, }, - // TODO(Miami) // MENUPAGE_KEYBOARD_CONTROLS = 30 { "FET_STI", MENUPAGE_CONTROLLER_PC, 1, - MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, 0, }, // MENUPAGE_MOUSE_CONTROLS = 31 @@ -314,18 +274,15 @@ CMenuScreen aScreens[] = { // MENUPAGE_NONE = 33 { "", 0, 0, }, - // MENUPAGE_OUTRO = 34 - { "", 0, 0, }, - #ifdef LEGACY_MENU_OPTIONS - // MENUPAGE_CONTROLLER_SETTINGS = 4 + // MENUPAGE_CONTROLLER_SETTINGS { "FET_CON", MENUPAGE_OPTIONS, 0, MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0, MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_DEBUG_MENU = 18 + // MENUPAGE_DEBUG_MENU { "FED_DBG", MENUPAGE_NONE, 0, MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, @@ -334,7 +291,7 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD1 = 36 + // MENUPAGE_CONTROLLER_PC_OLD1 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 0, MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, @@ -348,12 +305,12 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD2 = 37 + // MENUPAGE_CONTROLLER_PC_OLD2 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 1, }, - // MENUPAGE_CONTROLLER_PC_OLD3 = 38 + // MENUPAGE_CONTROLLER_PC_OLD3 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 2, MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, @@ -362,12 +319,12 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD4 = 39 + // MENUPAGE_CONTROLLER_PC_OLD4 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 3, }, - // MENUPAGE_CONTROLLER_DEBUG = 40 + // MENUPAGE_CONTROLLER_DEBUG { "FEC_DBG", MENUPAGE_CONTROLLER_PC, 3, MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, @@ -376,6 +333,10 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, #endif + + // MENUPAGE_OUTRO - Originally 34 + { "", 0, 0, }, }; #endif +#endif diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp new file mode 100644 index 00000000..96e3be07 --- /dev/null +++ b/src/core/MenuScreensCustom.cpp @@ -0,0 +1,716 @@ +#include "common.h" +#include "platform.h" +#include "crossplatform.h" +#include "Renderer.h" +#include "Frontend.h" +#include "Font.h" +#include "Camera.h" +#include "main.h" +#include "MBlur.h" +#include "postfx.h" +#include "custompipes.h" +#include "RwHelper.h" +#include "Text.h" +#include "Streaming.h" +#include "FileLoader.h" +#include "Collision.h" +#include "ModelInfo.h" +#include "Pad.h" + +// Menu screens array is at the bottom of the file. + +#ifdef PC_MENU + +#ifdef CUSTOM_FRONTEND_OPTIONS + +#ifdef IMPROVED_VIDEOMODE + #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) }, 0, 0, MENUALIGN_LEFT, +#else + #define VIDEOMODE_SELECTOR +#endif + +#ifdef MULTISAMPLING + #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, 0, 0, MENUALIGN_LEFT, +#else + #define MULTISAMPLING_SELECTOR +#endif + +#ifdef CUTSCENE_BORDERS_SWITCH + #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define CUTSCENE_BORDERS_TOGGLE +#endif + +#ifdef FREE_CAM + #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define FREE_CAM_TOGGLE +#endif + +#ifdef PS2_ALPHA_TEST + #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define DUALPASS_SELECTOR +#endif + +#ifdef NO_ISLAND_LOADING + #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT, +#else + #define ISLAND_LOADING_SELECTOR +#endif + +#ifdef EXTENDED_COLOURFILTER + #define POSTFX_SELECTORS \ + MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, 0, 0, MENUALIGN_LEFT, \ + MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define POSTFX_SELECTORS +#endif + +#ifdef INVERT_LOOK_FOR_PAD + #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, nil, off_on, 2, false, nil) }, 150, 0, MENUALIGN_LEFT, +#else + #define INVERT_PAD_SELECTOR +#endif + +const char *filterNames[] = { "FEM_NON", "FEM_SIM", "FEM_NRM", "FEM_MOB" }; +const char *off_on[] = { "FEM_OFF", "FEM_ON" }; + +void RestoreDefGraphics(int8 action) { + if (action != FEOPTION_ACTION_SELECT) + return; + + #ifdef PS2_ALPHA_TEST + gPS2alphaTest = false; + #endif + #ifdef MULTISAMPLING + FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0; + #endif + #ifdef NO_ISLAND_LOADING + if (!FrontEndMenuManager.m_bGameNotLoaded) { + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + CStreaming::LoadAllRequestedModels(true); + } else + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + #endif + #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those + FrontEndMenuManager.m_PrefsFrameLimiter = true; + FrontEndMenuManager.m_PrefsVsyncDisp = true; + #ifdef LEGACY_MENU_OPTIONS + FrontEndMenuManager.m_PrefsVsync = true; + #endif + FrontEndMenuManager.m_PrefsUseWideScreen = false; + FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode; + CMBlur::BlurOn = false; + FrontEndMenuManager.SaveSettings(); + #endif +} + +void RestoreDefDisplay(int8 action) { + if (action != FEOPTION_ACTION_SELECT) + return; + + #ifdef CUTSCENE_BORDERS_SWITCH + FrontEndMenuManager.m_PrefsCutsceneBorders = true; + #endif + #ifdef FREE_CAM + TheCamera.bFreeCam = false; + #endif + #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those + FrontEndMenuManager.m_PrefsBrightness = 256; + FrontEndMenuManager.m_PrefsLOD = 1.2f; + CRenderer::ms_lodDistScale = 1.2f; + FrontEndMenuManager.m_PrefsShowSubtitles = false; + FrontEndMenuManager.m_PrefsShowLegends = true; + FrontEndMenuManager.m_PrefsRadarMode = 0; + FrontEndMenuManager.m_PrefsShowHud = true; + FrontEndMenuManager.SaveSettings(); + #endif +} + +#ifdef NO_ISLAND_LOADING +const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" }; +void IslandLoadingAfterChange(int8 before, int8 after) { + if (!FrontEndMenuManager.m_bGameNotLoaded) { + if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) { + FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug: + + if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH) { + CStreaming::RemoveIslandsNotUsed(LEVEL_BEACH); + CStreaming::RemoveIslandsNotUsed(LEVEL_MAINLAND); + } + if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) { + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestBigBuildings(CGame::currLevel); + + } else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) { + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestIslands(CGame::currLevel); + } else + FrontEndMenuManager.m_PrefsIslandLoading = after; + + } else { // low + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + + CStreaming::LoadAllRequestedModels(true); + } + + FrontEndMenuManager.SetHelperText(0); +} +#endif + +#ifdef MORE_LANGUAGES +void LangPolSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangRusSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangJapSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} +#endif + +#ifndef MULTISAMPLING +void GraphicsGoBack() { +} +#else +void GraphicsGoBack() { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; +} + +void MultiSamplingButtonPress(int8 action) { + if (action == FEOPTION_ACTION_SELECT) { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel; + _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); + FrontEndMenuManager.SetHelperText(0); + FrontEndMenuManager.SaveSettings(); + } + } else if (action == FEOPTION_ACTION_LEFT || action == FEOPTION_ACTION_RIGHT) { + if (FrontEndMenuManager.m_bGameNotLoaded) { + FrontEndMenuManager.m_nDisplayMSAALevel += (action == FEOPTION_ACTION_RIGHT ? 1 : -1); + + int i = 0; + int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels(); + while (maxAA != 1) { + i++; + maxAA >>= 1; + } + + if (FrontEndMenuManager.m_nDisplayMSAALevel < 0) + FrontEndMenuManager.m_nDisplayMSAALevel = i; + else if (FrontEndMenuManager.m_nDisplayMSAALevel > i) + FrontEndMenuManager.m_nDisplayMSAALevel = 0; + } + } else if (action == FEOPTION_ACTION_FOCUSLOSS) { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; + FrontEndMenuManager.SetHelperText(3); + } + } +} + +wchar* MultiSamplingDraw(bool *disabled, bool userHovering) { + static wchar unicodeTemp[64]; + if (userHovering) { + if (FrontEndMenuManager.m_nDisplayMSAALevel == FrontEndMenuManager.m_nPrefsMSAALevel) { + if (FrontEndMenuManager.m_nHelperTextMsgId == 1) // Press enter to apply + FrontEndMenuManager.ResetHelperText(); + } else { + FrontEndMenuManager.SetHelperText(1); + } + } else { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; + } + } + + if (!FrontEndMenuManager.m_bGameNotLoaded) + *disabled = true; + + switch (FrontEndMenuManager.m_nDisplayMSAALevel) { + case 0: + return TheText.Get("FEM_OFF"); + default: + sprintf(gString, "%iX", 1 << (FrontEndMenuManager.m_nDisplayMSAALevel)); + AsciiToUnicode(gString, unicodeTemp); + return unicodeTemp; + } +} +#endif + +#ifdef IMPROVED_VIDEOMODE +const char* screenModes[] = { "FED_FLS", "FED_WND" }; +void ScreenModeAfterChange(int8 before, int8 after) +{ + _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution + FrontEndMenuManager.SetHelperText(0); +} + +#endif + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +wchar selectedJoystickUnicode[128]; + +wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { + int numButtons; + int found = -1; + const char *joyname; + if (userHovering) { + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { + if ((joyname = glfwGetJoystickName(i))) { + const uint8* buttons = glfwGetJoystickButtons(i, &numButtons); + for (int j = 0; j < numButtons; j++) { + if (buttons[j]) { + found = i; + break; + } + } + if (found != -1) + break; + } + } + + if (found != -1 && PSGLOBAL(joy1id) != found) { + if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found) + PSGLOBAL(joy2id) = PSGLOBAL(joy1id); + else + PSGLOBAL(joy2id) = -1; + + strcpy(gSelectedJoystickName, joyname); + PSGLOBAL(joy1id) = found; + } + } + if (PSGLOBAL(joy1id) == -1) + AsciiToUnicode("Not found", selectedJoystickUnicode); + else + AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode); + + return selectedJoystickUnicode; +} +#endif + +CMenuScreenCustom aScreens[] = { + // MENUPAGE_STATS = 0 + { "FEH_STA", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_NEW_GAME = 1 + { "FEP_STG", MENUPAGE_NONE, nil, nil, + MENUACTION_CHANGEMENU, "FES_NGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 155, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_LOA", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_DEL", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_BRIEFS = 2 + { "FEH_BRI", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_SOUND_SETTINGS = 3 + { "FEH_AUD", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_MUSICVOLUME, "FEA_MUS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 40, 76, MENUALIGN_LEFT, + MENUACTION_SFXVOLUME, "FEA_SFX", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_AUDIOHW, "FEA_3DH", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SPEAKERCONF, "FEA_SPK", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_DYNAMICACOUSTIC, "FET_DAM", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADIO, "FEA_RSS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 367, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_DISPLAY_SETTINGS = 4 +#ifndef GRAPHICS_MENU_OPTIONS + { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil, + MENUACTION_BRIGHTNESS, "FED_BRI", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_FRAMELIMIT, "FEM_FRM", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#if defined LEGACY_MENU_OPTIONS && !defined EXTENDED_COLOURFILTER + MENUACTION_TRAILS, "FED_TRA", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_SUBTITLES, "FED_SUB", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_WIDESCREEN, "FED_WIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_LEGENDS, "MAP_LEG", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADARMODE, "FED_RDR", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_HUD, "FED_HUD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SCREENRES, "FED_RES", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + VIDEOMODE_SELECTOR + MULTISAMPLING_SELECTOR + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + POSTFX_SELECTORS + // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#else + { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil, + MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADARMODE, "FED_RDR", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_HUD, "FED_HUD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefDisplay) }, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#endif + + // MENUPAGE_LANGUAGE_SETTINGS = 5 + { "FEH_LAN", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_LANG_ENG, "FEL_ENG", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 320, 132, MENUALIGN_CENTER, + MENUACTION_LANG_FRE, "FEL_FRE", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_GER, "FEL_GER", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_ITA, "FEL_ITA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_SPA, "FEL_SPA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#ifdef MORE_LANGUAGES + MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER, + MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER + MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_MAP = 6 + { "FEH_MAP", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER, + }, + + // MENUPAGE_NEW_GAME_RELOAD = 7 + { "FES_NGA", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FESZ_QR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 200, MENUALIGN_CENTER, + MENUACTION_NEWGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_LOAD_SLOT = 8 + { "FET_LG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_DELETE_SLOT = 9 + { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOAD_SLOT_CONFIRM = 10 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QL", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_DELETE_SLOT_CONFIRM = 11 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QD", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_DELETING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOADING_IN_PROGRESS = 12 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil, + }, + + // MENUPAGE_DELETING_IN_PROGRESS = 13 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil, + }, + + // MENUPAGE_DELETE_SUCCESSFUL = 14 + { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FES_DSC", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_SAVE_SLOT = 15 + { "FET_SG", MENUPAGE_DISABLED, nil, nil, + MENUACTION_SAVEGAME, "FEM_SL1", {nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 40, 90, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL2", {nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL3", {nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL4", {nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL5", {nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL6", {nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL7", {nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL8", {nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QZ", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVING_IN_PROGRESS = 17 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + }, + + // MENUPAGE_SAVE_SUCCESSFUL = 18 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FES_SSC", {nil, SAVESLOT_LABEL, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CUSTOM_WARNING = 19 + { "FET_SG", MENUPAGE_NONE, nil, nil, + MENUACTION_LABEL, "", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CHEAT_WARNING = 20 + { "FET_SG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FES_CHE", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SKIN_SELECT = 21 + { "FET_PS", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_UNUSED = 22 + { "FET_SG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FED_LWR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED = 23 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED_2 = 24 + { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + }, + + // MENUPAGE_LOAD_FAILED = 25 + { "FET_LG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FEC_LUN", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC = 26 + { "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil, +#ifdef PC_PLAYER_CONTROLS + MENUACTION_CTRLMETHOD, "FET_STI", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 150, MENUALIGN_CENTER, +#endif + MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 0, 0, MENUALIGN_CENTER, +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_CHANGEMENU, "FEC_MOU", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_CENTER, + INVERT_PAD_SELECTOR + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_OPTIONS = 27 + { "FET_OPT", MENUPAGE_NONE, nil, nil, + MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 132, MENUALIGN_CENTER, + MENUACTION_LOADRADIO, "FEO_AUD", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEO_DIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#ifdef GRAPHICS_MENU_OPTIONS + MENUACTION_CHANGEMENU, "FET_GRA", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_CHANGEMENU, "FEO_LAN", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_PLAYERSETUP, "FET_PS", {nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_EXIT = 28 + { "FET_QG", MENUPAGE_NONE, nil, nil, + MENUACTION_LABEL, "FEQ_SRE", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_DONTCANCEL, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 200, MENUALIGN_CENTER, + MENUACTION_CANCELGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_START_MENU = 29 + { "FEM_MM", MENUPAGE_DISABLED, nil, nil, + MENUACTION_CHANGEMENU, "FEP_STG", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 170, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_KEYBOARD_CONTROLS = 30 + { "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil, + }, + + // MENUPAGE_MOUSE_CONTROLS = 31 + { "FEC_MOU", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_MOUSESENS, "FEC_MSH", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 40, 170, MENUALIGN_LEFT, + MENUACTION_INVVERT, "FEC_IVV", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_MOUSESTEER, "FET_MST", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 260, MENUALIGN_CENTER, + }, + + // MENUPAGE_PAUSE_MENU = 32 + { "FET_PAU", MENUPAGE_DISABLED, nil, nil, + MENUACTION_RESUME, "FEP_RES", {nil, SAVESLOT_NONE, 0}, 320, 120, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_SGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_MAP", {nil, SAVESLOT_NONE, MENUPAGE_MAP}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_STA", {nil, SAVESLOT_NONE, MENUPAGE_STATS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_BRI", {nil, SAVESLOT_NONE, MENUPAGE_BRIEFS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FET_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_NONE = 33 + { "", 0, nil, nil, }, + + +#ifdef LEGACY_MENU_OPTIONS + // MENUPAGE_CONTROLLER_SETTINGS = 4 + { "FET_CON", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_CTRLCONFIG, "FEC_CCF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0, + MENUACTION_CTRLVIBRATION, "FEC_VIB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_DEBUG_MENU = 18 + { "FED_DBG", MENUPAGE_NONE, nil, nil, + MENUACTION_RELOADIDE, "FED_RID", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_SETDBGFLAG, "FED_DFL", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_COLLISIONPOLYS, "FED_SCP", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD1 = 36 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_PLB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CWL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CWR", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_LKT", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PJP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PSP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TLF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TRG", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CCM", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD2 = 37 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + + }, + + // MENUPAGE_CONTROLLER_PC_OLD3 = 38 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_LUP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_LDN", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_SHOWHEADBOB, "FEC_GSL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD4 = 39 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + + }, + + // MENUPAGE_CONTROLLER_DEBUG = 40 + { "FEC_DBG", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_TGD", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TDO", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TSS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, +#endif + +#ifdef GRAPHICS_MENU_OPTIONS + // MENUPAGE_GRAPHICS_SETTINGS + { "FET_GRA", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack, + + MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + VIDEOMODE_SELECTOR +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MULTISAMPLING_SELECTOR + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR +#ifdef EXTENDED_COLOURFILTER + POSTFX_SELECTORS +#elif defined LEGACY_MENU_OPTIONS + MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, +#endif + // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#endif + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + // MENUPAGE_DETECT_JOYSTICK + { "FEC_JOD", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({0, 0, 0, false, false, 30}), nil, + + MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0, + MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) }, 80, 200, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER, + }, +#endif + + // MENUPAGE_OUTRO = 34 + { "", 0, nil, nil, }, +}; + +#endif +#endif diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 91e2d704..7d53009d 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -1213,14 +1213,46 @@ void CPad::AddToCheatString(char c) int Cheat_strncmp(char* sourceStr, char* origCheatStr) { - char cheatCodeVals[] = { 3,5,7,1,13,27,3,7,1,11,13,8,7,32,13,6,28,19,10,3,3,5,7,1,13,27,3,7 }; - - for (uint32 i = 0; i < strlen(origCheatStr); i++) { - if ((sourceStr[i] != origCheatStr[i] - cheatCodeVals[i]) || i >= ARRAY_SIZE(cheatCodeVals)) { - return 1; - } +#define ccmp(n) if((uint8)sourceStr[i] != (uint8)origCheatStr[i] - n) return 1; + int i = 0; + while(origCheatStr[i]) + { + switch(i) + { + case 0: ccmp(3); break; + case 1: ccmp(5); break; + case 2: ccmp(7); break; + case 3: ccmp(1); break; + case 4: ccmp(13); break; + case 5: ccmp(27); break; + case 6: ccmp(3); break; + case 7: ccmp(7); break; + case 8: ccmp(1); break; + case 9: ccmp(11); break; + case 10: ccmp(13); break; + case 11: ccmp(8); break; + case 12: ccmp(7); break; + case 13: ccmp(32); break; + case 14: ccmp(13); break; + case 15: ccmp(6); break; + case 16: ccmp(28); break; + case 17: ccmp(19); break; + case 18: ccmp(10); break; + case 19: ccmp(3); break; + case 20: ccmp(3); break; + case 21: ccmp(5); break; + case 22: ccmp(7); break; + case 23: ccmp(1); break; + case 24: ccmp(13); break; + case 25: ccmp(27); break; + case 26: ccmp(3); break; + case 27: ccmp(7); break; + default: return 1; + } + i++; } return 0; +#undef ccmp } // TODO(Miami): Mobile has changed some of the cheats to include debugging things diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 61e2f67a..77ddfdb1 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -3,6 +3,7 @@ #include "Automobile.h" #include "Bridge.h" #include "Camera.h" +#include "CarCtrl.h" #include "Cranes.h" #include "Darkel.h" #include "Explosion.h" @@ -34,93 +35,10 @@ #include "Automobile.h" #include "GameLogic.h" -CVector lastPlayerPos; - -// --MIAMI: Done -void -CPlayerInfo::SetPlayerSkin(char *skin) -{ - strncpy(m_aSkinName, skin, 32); - LoadPlayerSkin(); -} - -// --MIAMI: Done -const CVector & -CPlayerInfo::GetPos() -{ -#ifdef FIX_BUGS - if (!m_pPed) - return TheCamera.GetPosition(); -#endif - if (m_pPed->InVehicle()) - return m_pPed->m_pMyVehicle->GetPosition(); - return m_pPed->GetPosition(); -} - -// --MIAMI: Done -void -CPlayerInfo::LoadPlayerSkin() -{ - DeletePlayerSkin(); - - m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); -} - -// --MIAMI: Done -void -CPlayerInfo::DeletePlayerSkin() -{ - if (m_pSkinTexture) { - RwTextureDestroy(m_pSkinTexture); - m_pSkinTexture = nil; - } -} - -// --MIAMI: Done -void -CPlayerInfo::KillPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; - - m_WBState = WBSTATE_WASTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); - CStats::TimesDied++; -} - -// --MIAMI: Done -void -CPlayerInfo::ArrestPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; +// --MIAMI: File done - m_WBState = WBSTATE_BUSTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - m_nBustedAudioStatus = BUSTEDAUDIO_NONE; - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); - CStats::TimesArrested++; -} - -// --MIAMI: Done -bool -CPlayerInfo::IsPlayerInRemoteMode() -{ - return m_pRemoteVehicle || m_bInRemoteMode; -} - -void -CPlayerInfo::PlayerFailedCriticalMission() -{ - if (m_WBState != WBSTATE_PLAYING) - return; - m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); -} +CVector lastPlayerPos; -// --MIAMI: Done void CPlayerInfo::Clear(void) { @@ -181,192 +99,6 @@ CPlayerInfo::Clear(void) m_nBustedAudioStatus = BUSTEDAUDIO_NONE; } -// --MIAMI: Done -void -CPlayerInfo::BlowUpRCBuggy(bool actually) -{ - if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) - return; - - CRemote::TakeRemoteControlledCarFromPlayer(actually); - if (actually) - m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); -} - -// --MIAMI: Done -void -CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) -{ - if (!car || car == m_pPed->m_pMyVehicle) { - if (m_pPed->EnteringCar()) - m_pPed->QuitEnteringCar(); - } - if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) - m_pPed->ClearObjective(); -} - -// --MIAMI: Done -void -CPlayerInfo::MakePlayerSafe(bool toggle) -{ - if (toggle) { - m_pPed->m_pWanted->m_bIgnoredByEveryone = true; - CWorld::StopAllLawEnforcersInTheirTracks(); - CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); - CPad::StopPadsShaking(); - m_pPed->bBulletProof = true; - m_pPed->bFireProof = true; - m_pPed->bCollisionProof = true; - m_pPed->bMeleeProof = true; - m_pPed->bOnlyDamagedByPlayer = true; - m_pPed->bExplosionProof = true; - m_pPed->m_bCanBeDamaged = false; - ((CPlayerPed*)m_pPed)->ClearAdrenaline(); - CancelPlayerEnteringCars(nil); - gFireManager.ExtinguishPoint(GetPos(), 4000.0f); - CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); - CProjectileInfo::RemoveAllProjectiles(); - CWorld::SetAllCarsCanBeDamaged(false); - CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); - CReplay::DisableReplays(); - - } else { - m_pPed->m_pWanted->m_bIgnoredByEveryone = false; - CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); - m_pPed->bBulletProof = false; - m_pPed->bFireProof = false; - m_pPed->bCollisionProof = false; - m_pPed->bMeleeProof = false; - m_pPed->bOnlyDamagedByPlayer = false; - m_pPed->bExplosionProof = false; - m_pPed->m_bCanBeDamaged = true; - CWorld::SetAllCarsCanBeDamaged(true); - CReplay::EnableReplays(); - } -} - -// --MIAMI: Done -bool -CPlayerInfo::IsRestartingAfterDeath() -{ - return m_WBState == WBSTATE_WASTED; -} - -// --MIAMI: Done -bool -CPlayerInfo::IsRestartingAfterArrest() -{ - return m_WBState == WBSTATE_BUSTED; -} - -// --MIAMI: Done -// lastCloseness is passed to other calls of this function -void -CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) -{ - // This dist used for determining the angle to face - CVector2D dist(carToTest->GetPosition() - player->GetPosition()); - float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); - while (neededTurn >= PI) { - neededTurn -= 2 * PI; - } - - while (neededTurn < -PI) { - neededTurn += 2 * PI; - } - - // This dist used for evaluating cars' distances, weird... - // Accounts inverted needed turn (or needed turn in long way) and car dist. - float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); - if (closeness > *lastCloseness) { - *lastCloseness = closeness; - *closestCarOutput = (CVehicle*)carToTest; - } -} - -// --MIAMI: Done -void -CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) -{ - // Interesting - *size = sizeof(CPlayerInfo); - -#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio); -#undef CopyToBuf -} - -// --MIAMI: Done -void -CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) -{ -#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio) -#undef CopyFromBuf -} - -// --MIAMI: Done -void -CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) -{ - for (CPtrNode* node = carList.first; node; node = node->next) { - CVehicle *car = (CVehicle*)node->item; - if(car->m_scanCode != CWorld::GetCurrentScanCode()) { - if (!car->bUsesCollision || !car->IsVehicle()) - continue; - - car->m_scanCode = CWorld::GetCurrentScanCode(); - if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING - && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { - CVector carCentre = car->GetBoundCentre(); - - if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) { - float dist = (ped->GetPosition() - carCentre).Magnitude2D(); - if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { - EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); - } - } - } - } - } -} - void CPlayerInfo::Process(void) { @@ -673,13 +405,13 @@ CPlayerInfo::Process(void) uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar; if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING && field_D6) { TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 0); + TheCamera.Fade(1.0f, FADE_OUT); } if (timeWithoutRemoteCar > 2000) { if (m_WBState == WBSTATE_PLAYING && field_D6) { TheCamera.RestoreWithJumpCut(); TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 1); + TheCamera.Fade(1.0f, FADE_IN); TheCamera.Process(); CTimer::Stop(); CCullZones::ForceCullZoneCoors(TheCamera.GetPosition()); @@ -796,3 +528,355 @@ CPlayerInfo::Process(void) m_nMoney = Min(999999999, m_nMoney); m_nVisibleMoney = Min(999999999, m_nVisibleMoney); } + +bool +CPlayerInfo::IsPlayerInRemoteMode() +{ + return m_pRemoteVehicle || m_bInRemoteMode; +} + +void +CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) +{ + // Interesting + *size = sizeof(CPlayerInfo); + +#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio); +#undef CopyToBuf +} + +void +CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) +{ +#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio) +#undef CopyFromBuf +} + +void +CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) +{ + for (CPtrNode* node = carList.first; node; node = node->next) { + CVehicle *car = (CVehicle*)node->item; + if(car->m_scanCode != CWorld::GetCurrentScanCode()) { + if (!car->bUsesCollision || !car->IsVehicle()) + continue; + + car->m_scanCode = CWorld::GetCurrentScanCode(); + if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING + && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { + CVector carCentre = car->GetBoundCentre(); + + if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) { + float dist = (ped->GetPosition() - carCentre).Magnitude2D(); + if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { + EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); + } + } + } + } + } +} + +// lastCloseness is passed to other calls of this function +void +CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) +{ + // This dist used for determining the angle to face + CVector2D dist(carToTest->GetPosition() - player->GetPosition()); + float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); + while (neededTurn >= PI) { + neededTurn -= 2 * PI; + } + + while (neededTurn < -PI) { + neededTurn += 2 * PI; + } + + // This dist used for evaluating cars' distances, weird... + // Accounts inverted needed turn (or needed turn in long way) and car dist. + float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); + if (closeness > *lastCloseness) { + *lastCloseness = closeness; + *closestCarOutput = (CVehicle*)carToTest; + } +} + +const CVector & +CPlayerInfo::GetPos() +{ +#ifdef FIX_BUGS + if (!m_pPed) + return TheCamera.GetPosition(); +#endif + if (m_pPed->InVehicle()) + return m_pPed->m_pMyVehicle->GetPosition(); + return m_pPed->GetPosition(); +} + +CVector +FindPlayerCoors(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) + return TheCamera.GetPosition(); +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->GetPosition(); + else + return ped->GetPosition(); +} + +const CVector & +FindPlayerSpeed(void) +{ +#ifdef FIX_BUGS + static CVector vecTmpVector(0.0f, 0.0f, 0.0f); + if (CReplay::IsPlayingBack()) + return vecTmpVector; +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->m_vecMoveSpeed; + else + return ped->m_vecMoveSpeed; +} + +CVehicle * +FindPlayerVehicle(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped && ped->InVehicle()) return ped->m_pMyVehicle; + return nil; +} + +CEntity * +FindPlayerEntity(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle; + else + return ped; +} + +CVehicle * +FindPlayerTrain(void) +{ + if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) + return FindPlayerVehicle(); + else + return nil; +} + +CPlayerPed * +FindPlayerPed(void) +{ + return CWorld::Players[CWorld::PlayerInFocus].m_pPed; +} + +const CVector & +FindPlayerCentreOfWorld(int32 player) +{ +#ifdef FIX_BUGS + if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return CWorld::Players[player].m_pPed->GetPosition(); +} + +const CVector & +FindPlayerCentreOfWorld_NoSniperShift(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return FindPlayerPed()->GetPosition(); +} + +float +FindPlayerHeading(void) +{ + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); + return FindPlayerPed()->GetForward().Heading(); +} + +bool +CPlayerInfo::IsRestartingAfterDeath() +{ + return m_WBState == WBSTATE_WASTED; +} + +bool +CPlayerInfo::IsRestartingAfterArrest() +{ + return m_WBState == WBSTATE_BUSTED; +} + +void +CPlayerInfo::KillPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_WASTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); + CStats::TimesDied++; +} + +void +CPlayerInfo::ArrestPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_BUSTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + m_nBustedAudioStatus = BUSTEDAUDIO_NONE; + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); + CStats::TimesArrested++; +} + +void +CPlayerInfo::PlayerFailedCriticalMission() +{ + if (m_WBState != WBSTATE_PLAYING) + return; + m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); +} + +void +CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) +{ + if (!car || car == m_pPed->m_pMyVehicle) { + if (m_pPed->EnteringCar()) + m_pPed->QuitEnteringCar(); + } + if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) + m_pPed->ClearObjective(); +} + +void +CPlayerInfo::MakePlayerSafe(bool toggle) +{ + if (toggle) { + m_pPed->m_pWanted->m_bIgnoredByEveryone = true; + CWorld::StopAllLawEnforcersInTheirTracks(); + CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); + CPad::StopPadsShaking(); + m_pPed->bBulletProof = true; + m_pPed->bFireProof = true; + m_pPed->bCollisionProof = true; + m_pPed->bMeleeProof = true; + m_pPed->bOnlyDamagedByPlayer = true; + m_pPed->bExplosionProof = true; + m_pPed->m_bCanBeDamaged = false; + ((CPlayerPed*)m_pPed)->ClearAdrenaline(); + CancelPlayerEnteringCars(nil); + gFireManager.ExtinguishPoint(GetPos(), 4000.0f); + CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); + CProjectileInfo::RemoveAllProjectiles(); + CWorld::SetAllCarsCanBeDamaged(false); + CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); + CReplay::DisableReplays(); + + } else { + m_pPed->m_pWanted->m_bIgnoredByEveryone = false; + CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); + m_pPed->bBulletProof = false; + m_pPed->bFireProof = false; + m_pPed->bCollisionProof = false; + m_pPed->bMeleeProof = false; + m_pPed->bOnlyDamagedByPlayer = false; + m_pPed->bExplosionProof = false; + m_pPed->m_bCanBeDamaged = true; + CWorld::SetAllCarsCanBeDamaged(true); + CReplay::EnableReplays(); + } +} + +void +CPlayerInfo::BlowUpRCBuggy(bool actually) +{ + if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) + return; + + CRemote::TakeRemoteControlledCarFromPlayer(actually); + if (actually) + m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); +} + +#ifdef GTA_PC +void +CPlayerInfo::SetPlayerSkin(const char *skin) +{ + strncpy(m_aSkinName, skin, 32); + LoadPlayerSkin(); +} + +void +CPlayerInfo::LoadPlayerSkin() +{ + DeletePlayerSkin(); + + m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); +} + +void +CPlayerInfo::DeletePlayerSkin() +{ + if (m_pSkinTexture) { + RwTextureDestroy(m_pSkinTexture); + m_pSkinTexture = nil; + } +} +#endif diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 7d99a4e0..a3896ebb 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -10,7 +10,7 @@ enum eWastedBustedState WBSTATE_FAILED_CRITICAL_MISSION, }; -enum eBustedAudioState : uint8 +enum eBustedAudioState { BUSTEDAUDIO_NONE, BUSTEDAUDIO_LOADING, @@ -82,15 +82,14 @@ public: bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; bool m_bDriveByAllowed; - eBustedAudioState m_nBustedAudioStatus; + uint8 m_nBustedAudioStatus; int16 m_nCurrentBustedAudio; +#ifdef GTA_PC char m_aSkinName[32]; RwTexture *m_pSkinTexture; +#endif void MakePlayerSafe(bool); - void LoadPlayerSkin(); - void DeletePlayerSkin(); - void SetPlayerSkin(char* skin); const CVector &GetPos(); void Process(void); void KillPlayer(void); @@ -107,5 +106,19 @@ public: void SavePlayerInfo(uint8 *buf, uint32* size); void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**); - ~CPlayerInfo() { }; +#ifdef GTA_PC + void LoadPlayerSkin(); + void SetPlayerSkin(const char *skin); + void DeletePlayerSkin(); +#endif }; + +CPlayerPed *FindPlayerPed(void); +CVehicle *FindPlayerVehicle(void); +CVehicle *FindPlayerTrain(void); +CEntity *FindPlayerEntity(void); +CVector FindPlayerCoors(void); +const CVector &FindPlayerSpeed(void); +const CVector &FindPlayerCentreOfWorld(int32 player); +const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); +float FindPlayerHeading(void);
\ No newline at end of file diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index cbc57902..dfc7a82f 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -13,6 +13,7 @@ #include "Streaming.h" #include "Wanted.h" #include "World.h" +#include "MemoryHeap.h" //--MIAMI: file done @@ -27,19 +28,39 @@ CDummyPool *CPools::ms_pDummyPool; CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool; CColModelPool *CPools::ms_pColModelPool; +#if defined GTA_PS2 && !defined MASTER // or USE_CUSTOM_ALLOCATOR +// not in VC. perhaps ifdef'ed away +#define CHECKMEM(msg) CMemCheck::AllocateMemCheckBlock(msg) +#else +#define CHECKMEM(msg) +#endif + void CPools::Initialise(void) { + PUSH_MEMID(MEMID_POOLS); + CHECKMEM("before pools"); ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES, "PtrNode"); + CHECKMEM("after CPtrNodePool"); ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS, "EntryInfoNode"); + CHECKMEM("after CEntryInfoNodePool"); ms_pPedPool = new CPedPool(NUMPEDS, "Peds"); + CHECKMEM("after CPedPool"); ms_pVehiclePool = new CVehiclePool(NUMVEHICLES, "Vehicles"); + CHECKMEM("after CVehiclePool"); ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS, "Buildings"); + CHECKMEM("after CBuildingPool"); ms_pTreadablePool = new CTreadablePool(NUMTREADABLES, "Treadables"); + CHECKMEM("after CTreadablePool"); ms_pObjectPool = new CObjectPool(NUMOBJECTS, "Objects"); + CHECKMEM("after CObjectPool"); ms_pDummyPool = new CDummyPool(NUMDUMMIES, "Dummys"); + CHECKMEM("after CDummyPool"); ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS, "AudioScriptObj"); + CHECKMEM("after cAudioScriptObjectPool"); ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel"); + CHECKMEM("after pools"); + POP_MEMID(); } void diff --git a/src/core/References.cpp b/src/core/References.cpp index 52abbc3e..dc83d96d 100644 --- a/src/core/References.cpp +++ b/src/core/References.cpp @@ -22,6 +22,83 @@ CReferences::Init(void) } void +CEntity::RegisterReference(CEntity **pent) +{ + if(IsBuilding()) + return; + CReference *ref; + // check if already registered + for(ref = m_pFirstReference; ref; ref = ref->next) + if(ref->pentity == pent) + return; + // have to allocate new reference + ref = CReferences::pEmptyList; + if(ref){ + CReferences::pEmptyList = ref->next; + + ref->pentity = pent; + ref->next = m_pFirstReference; + m_pFirstReference = ref; + return; + } + return; +} + +// Clean up the reference from *pent -> 'this' +void +CEntity::CleanUpOldReference(CEntity **pent) +{ + CReference* ref, ** lastnextp; + lastnextp = &m_pFirstReference; + for (ref = m_pFirstReference; ref; ref = ref->next) { + if (ref->pentity == pent) { + *lastnextp = ref->next; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = ref; + break; + } + lastnextp = &ref->next; + } +} + +// Clear all references to this entity +void +CEntity::ResolveReferences(void) +{ + CReference *ref; + // clear pointers to this entity + for(ref = m_pFirstReference; ref; ref = ref->next) + if(*ref->pentity == this) + *ref->pentity = nil; + // free list + if(m_pFirstReference){ + for(ref = m_pFirstReference; ref->next; ref = ref->next) + ; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = m_pFirstReference; + m_pFirstReference = nil; + } +} + +// Free all references that no longer point to this entity +void +CEntity::PruneReferences(void) +{ + CReference *ref, *next, **lastnextp; + lastnextp = &m_pFirstReference; + for(ref = m_pFirstReference; ref; ref = next){ + next = ref->next; + if(*ref->pentity == this) + lastnextp = &ref->next; + else{ + *lastnextp = ref->next; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = ref; + } + } +} + +void CReferences::RemoveReferencesToPlayer(void) { if(FindPlayerVehicle()) diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index e078e6d0..8d61c484 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -5,9 +5,21 @@ #include "World.h" #include "Pad.h" #include "DMAudio.h" +#include "main.h" +#include "Font.h" +#include "Frontend.h" +#include "audio_enums.h" #include <climits> +#ifdef USE_PRECISE_MEASUREMENT_CONVERTION +#define MILES_IN_METER 0.000621371192f +#define FEET_IN_METER 3.28084f +#else +#define MILES_IN_METER (1 / 1670.f) +#define FEET_IN_METER 3.33f +#endif + int32 CStats::SeagullsKilled; int32 CStats::BoatsExploded; int32 CStats::WantedStarsAttained; @@ -43,8 +55,8 @@ float CStats::GarbagePickups; float CStats::IceCreamSold; float CStats::TopShootingRangeScore; float CStats::ShootingRank; -int32 CStats::ProgressMade; -int32 CStats::TotalProgressInGame; +float CStats::ProgressMade; +float CStats::TotalProgressInGame; int32 CStats::CarsExploded; int32 CStats::PeopleKilledByPlayer; float CStats::MaximumJumpDistance; @@ -115,7 +127,7 @@ void CStats::Init() for (int i = 0; i < NUM_PEDTYPES; i++) PedsKilledOfThisType[i] = 0; HelisDestroyed = 0; - ProgressMade = 0; + ProgressMade = 0.0f; KgsOfExplosivesUsed = 0; BulletsThatHit = 0; TyresPopped = 0; @@ -346,27 +358,27 @@ wchar *CStats::FindCriminalRatingString() } wchar *CStats::FindChaseString(float fMediaLevel) { - if (fMediaLevel < 20.0f) return TheText.Get("MEDIA1"); - if (fMediaLevel < 50.0f) return TheText.Get("MEDIA2"); - if (fMediaLevel < 75.0f) return TheText.Get("MEDIA3"); - if (fMediaLevel < 100.0f) return TheText.Get("MEDIA4"); - if (fMediaLevel < 150.0f) return TheText.Get("MEDIA5"); - if (fMediaLevel < 200.0f) return TheText.Get("MEDIA6"); - if (fMediaLevel < 250.0f) return TheText.Get("MEDIA7"); - if (fMediaLevel < 300.0f) return TheText.Get("MEDIA8"); - if (fMediaLevel < 350.0f) return TheText.Get("MEDIA9"); - if (fMediaLevel < 400.0f) return TheText.Get("MEDIA10"); - if (fMediaLevel < 500.0f) return TheText.Get("MEDIA11"); - if (fMediaLevel < 600.0f) return TheText.Get("MEDIA12"); - if (fMediaLevel < 700.0f) return TheText.Get("MEDIA13"); - if (fMediaLevel < 800.0f) return TheText.Get("MEDIA14"); - if (fMediaLevel < 900.0f) return TheText.Get("MEDIA15"); - if (fMediaLevel < 1000.0f) return TheText.Get("MEDIA16"); - if (fMediaLevel < 1200.0f) return TheText.Get("MEDIA17"); - if (fMediaLevel < 1400.0f) return TheText.Get("MEDIA18"); - if (fMediaLevel < 1600.0f) return TheText.Get("MEDIA19"); - if (fMediaLevel < 1800.0f) return TheText.Get("MEDIA20"); - return TheText.Get("MEDIA21"); + if (fMediaLevel < 20.0f) return TheText.Get("CHASE1"); + if (fMediaLevel < 50.0f) return TheText.Get("CHASE2"); + if (fMediaLevel < 75.0f) return TheText.Get("CHASE3"); + if (fMediaLevel < 100.0f) return TheText.Get("CHASE4"); + if (fMediaLevel < 150.0f) return TheText.Get("CHASE5"); + if (fMediaLevel < 200.0f) return TheText.Get("CHASE6"); + if (fMediaLevel < 250.0f) return TheText.Get("CHASE7"); + if (fMediaLevel < 300.0f) return TheText.Get("CHASE8"); + if (fMediaLevel < 350.0f) return TheText.Get("CHASE9"); + if (fMediaLevel < 400.0f) return TheText.Get("CHASE10"); + if (fMediaLevel < 500.0f) return TheText.Get("CHASE11"); + if (fMediaLevel < 600.0f) return TheText.Get("CHASE12"); + if (fMediaLevel < 700.0f) return TheText.Get("CHASE13"); + if (fMediaLevel < 800.0f) return TheText.Get("CHASE14"); + if (fMediaLevel < 900.0f) return TheText.Get("CHASE15"); + if (fMediaLevel < 1000.0f) return TheText.Get("CHASE16"); + if (fMediaLevel < 1200.0f) return TheText.Get("CHASE17"); + if (fMediaLevel < 1400.0f) return TheText.Get("CHASE18"); + if (fMediaLevel < 1600.0f) return TheText.Get("CHASE19"); + if (fMediaLevel < 1800.0f) return TheText.Get("CHASE20"); + return TheText.Get("CHASE21"); } int32 CStats::FindCriminalRatingNumber() @@ -387,16 +399,16 @@ int32 CStats::FindCriminalRatingNumber() } if (RoundsFiredByPlayer > 100) - rating += (float)CStats::BulletsThatHit / (float)CStats::RoundsFiredByPlayer * 500.0f; + rating += (float)BulletsThatHit / (float)RoundsFiredByPlayer * 500.0f; if (TotalProgressInGame) - rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f; + rating += ProgressMade / TotalProgressInGame * 1000.0f; return rating; } float CStats::GetPercentageProgress() { - float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : - CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f)); + float percentCompleted = (TotalProgressInGame == 0.f ? 0.f : + 100.0f * ProgressMade / (CGame::nastyGame ? TotalProgressInGame : TotalProgressInGame - 1.0f)); return Min(percentCompleted, 100.0f); } @@ -773,4 +785,657 @@ CStats::PopulateFavoriteRadioStationList() float* pListenTimeArray = DMAudio.GetListenTimeArray(); for (int i = 0; i < NUM_RADIOS; i++) FavoriteRadioStationList[i] = pListenTimeArray[i]; -}
\ No newline at end of file +} + +void +CStats::BuildStatLine(Const char *text, void *stat, int displayType, void *stat2, int isTime) +{ +#define STAT_D *(int*)stat +#define STAT_F *(float*)stat +#define STAT2_D *(int*)stat2 +#define STAT2_F *(float*)stat2 + if (!text) + return; + + gString2[0] = '\0'; + if (isTime == 1) { + if (*((int*)stat2) >= 10) + sprintf(gString2, " %d:%d", STAT_D, STAT2_D); + else + sprintf(gString2, " %d:0%d", STAT_D, STAT2_D); + + } else if (stat2) { +#ifdef MORE_LANGUAGES + if (CFont::IsJapanese()) { + switch (displayType) { + case 0: + case 4: + sprintf(gString2, " %d/%d", STAT_D, STAT2_D); + break; + case 1: + sprintf(gString2, " %.2f/%.2f", STAT_F, STAT2_F); + break; + case 2: + sprintf(gString2, " %d%%/%d%%", STAT_D, STAT2_D); + break; + case 3: + sprintf(gString2, " $%.2f/$%.2f", STAT_F, STAT2_F); + break; + default: + break; + } + } else +#endif + { + switch (displayType) { + case 0: + sprintf(gString2, " %d %s %d", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D); + break; + case 1: + sprintf(gString2, " %.2f %s %.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F); + break; + case 2: + sprintf(gString2, " %d%% %s %d%%", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D); + break; + case 3: + sprintf(gString2, " $%.2f %s $%.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F); + break; + case 4: + sprintf(gString2, " %d_ %s %d_", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D); + break; + default: + break; + } + } + } else if (stat) { + switch (displayType) { + case 0: + sprintf(gString2, "%d", STAT_D); + break; + case 1: + sprintf(gString2, "%.2f", STAT_F); + break; + case 2: + sprintf(gString2, "%d%%", STAT_D); + break; + case 3: + sprintf(gString2, "$%.2f", STAT_F); + break; + case 4: +#ifdef MORE_LANGUAGES + if (CFont::IsJapanese()) + sprintf(gString2, "%d", STAT_D); + else +#endif + sprintf(gString2, "%d_", STAT_D); + break; + default: + break; + } + } + UnicodeStrcpy(gUString, TheText.Get(text)); + CFont::FilterOutTokensFromString(gUString); + AsciiToUnicode(gString2, gUString2); +#undef STAT_D +#undef STAT_F +#undef STAT2_D +#undef STAT2_F +} + +// rowIdx 99999 returns total numbers of rows. otherwise it returns 0. +int +CStats::ConstructStatLine(int rowIdx) +{ + +#define STAT_LINE_1(varType, left, right1, type) \ + do { \ + if(counter == rowIdx){ \ + varType a = right1; \ + BuildStatLine(left, &a, type, nil, 0); \ + return 0; \ + } counter++; \ + } while(0) + +#define STAT_LINE_2(varType, left, right1, type, right2, time) \ + do { \ + if(counter == rowIdx){ \ + varType a = right1; \ + varType b = right2; \ + BuildStatLine(left, &a, type, &b, time); \ + return 0; \ + } counter++; \ + } while(0) + +#define TEXT_ON_LEFT_GXT(name) \ + do { \ + if(counter == rowIdx){ \ + BuildStatLine(name, nil, 0, nil, 0); \ + return 0; \ + } counter++; \ + } while(0) + +#define TEXT_ON_RIGHT(text) \ + do { \ + if(counter == rowIdx){ \ + gUString[0] = '\0'; \ + UnicodeStrcpy(gUString2, text); \ + return 0; \ + } counter++; \ + } while(0) + +#define FASTEST_TIME(id, str) \ + do { \ + if(FastestTimes[id]) { \ + if(counter == rowIdx){ \ + int hour = 0, minute; \ + for (int i = FastestTimes[id]; i > 59; i -= 60) hour++; \ + for (minute = FastestTimes[id]; minute > 59; minute -= 60); \ + if (minute < 0) minute = -minute; \ + BuildStatLine(str, &hour, 0, &minute, 1); \ + return 0; \ + } \ + counter++; \ + } \ + } while(0) + + switch (rowIdx) { + case 0: { + int percentCompleted = GetPercentageProgress(); + BuildStatLine("PER_COM", &percentCompleted, 2, nil, 0); + return 0; + } + case 1: { + BuildStatLine("NMISON", &MissionsGiven, 0, nil, 0); + return 0; + } + case 2: { + int hour = (CTimer::GetTimeInMilliseconds() / 60000) / 60; + int minute = (CTimer::GetTimeInMilliseconds() / 60000) % 60; + BuildStatLine("ST_TIME", &hour, 0, &minute, 1); + return 0; + } + case 3: { + BuildStatLine("DAYSPS", &DaysPassed, 0, nil, 0); + return 0; + } + case 4: { + BuildStatLine("NUMSHV", &SafeHouseVisits, 0, nil, 0); + return 0; + } + } + int counter = 5; + + if (CGame::nastyGame) { + STAT_LINE_2(int, "FEST_RP", NumberKillFrenziesPassed, 0, TotalNumberKillFrenzies, 0); + } + + CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus]; + + // Hidden packages shouldn't be shown with percent +#ifdef FIX_BUGS + STAT_LINE_2(int, "PERPIC", player.m_nCollectedPackages, 0, player.m_nTotalPackages, 0); +#else + float fPackagesPercent = 0.0f; + if (player.m_nTotalPackages != 0) + fPackagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages; + + STAT_LINE_2(int, "PERPIC", fPackagesPercent, 0, 100, 0); +#endif + + if (CGame::nastyGame) { + STAT_LINE_1(int, "PE_WAST", PeopleKilledByPlayer, 0); + STAT_LINE_1(int, "PE_WSOT", PeopleKilledByOthers, 0); + } + STAT_LINE_1(int, "CAR_EXP", CarsExploded, 0); + STAT_LINE_1(int, "BOA_EXP", BoatsExploded, 0); + STAT_LINE_1(int, "HEL_DST", HelisDestroyed, 0); + STAT_LINE_1(int, "TYREPOP", TyresPopped, 0); + STAT_LINE_1(int, "ST_STAR", WantedStarsAttained, 0); + STAT_LINE_1(int, "ST_STGN", WantedStarsEvaded, 0); + STAT_LINE_1(int, "TM_BUST", TimesArrested, 0); + STAT_LINE_1(int, "TM_DED", TimesDied, 0); + +#ifdef MORE_LANGUAGES + // JP version removed it altogether actually + if (!CFont::IsJapanese()) +#endif + STAT_LINE_1(int, "ST_HEAD", HeadsPopped, 0); + + static uint32 lastProcessedDay = UINT32_MAX; + static uint32 lastPoliceSpending = 0; + + // What a random stat... + if (lastProcessedDay != DaysPassed) { + lastProcessedDay = DaysPassed; + lastPoliceSpending = (CTimer::GetTimeInMilliseconds() & 255 + 80) * 255.44f; + } + STAT_LINE_1(float, "DAYPLC", lastPoliceSpending, 3); + + int mostPatheticGang = 0; + int mostKill = 0; + for (int i = PEDTYPE_GANG1; i < PEDTYPE_GANG9; ++i) { + if (CStats::PedsKilledOfThisType[i] > mostKill) { + mostKill = CStats::PedsKilledOfThisType[i]; + mostPatheticGang = i; + } + } + if (mostPatheticGang > 0) { + TEXT_ON_LEFT_GXT("ST_GANG"); + + switch (mostPatheticGang) { + case PEDTYPE_GANG1: + TEXT_ON_RIGHT(TheText.Get("ST_GNG1")); + break; + case PEDTYPE_GANG2: + TEXT_ON_RIGHT(TheText.Get("ST_GNG2")); + break; + case PEDTYPE_GANG3: + TEXT_ON_RIGHT(TheText.Get("ST_GNG3")); + break; + case PEDTYPE_GANG4: + TEXT_ON_RIGHT(TheText.Get("ST_GNG4")); + break; + case PEDTYPE_GANG5: + TEXT_ON_RIGHT(TheText.Get("ST_GNG5")); + break; + case PEDTYPE_GANG6: + TEXT_ON_RIGHT(TheText.Get("ST_GNG6")); + break; + case PEDTYPE_GANG7: + TEXT_ON_RIGHT(TheText.Get("ST_GNG7")); + break; + case PEDTYPE_GANG8: + TEXT_ON_RIGHT(TheText.Get("ST_GNG8")); + break; + default: + break; + } + } + + STAT_LINE_1(int, "GNG_WST", PedsKilledOfThisType[PEDTYPE_GANG9] + PedsKilledOfThisType[PEDTYPE_GANG8] + + PedsKilledOfThisType[PEDTYPE_GANG7] + PedsKilledOfThisType[PEDTYPE_GANG6] + + PedsKilledOfThisType[PEDTYPE_GANG5] + PedsKilledOfThisType[PEDTYPE_GANG4] + + PedsKilledOfThisType[PEDTYPE_GANG3] + PedsKilledOfThisType[PEDTYPE_GANG2] + + PedsKilledOfThisType[PEDTYPE_GANG1], 0); + + STAT_LINE_1(int, "DED_CRI", PedsKilledOfThisType[PEDTYPE_CRIMINAL], 0); + STAT_LINE_1(int, "KGS_EXP", KgsOfExplosivesUsed, 0); + STAT_LINE_1(int, "BUL_FIR", RoundsFiredByPlayer, 0); + STAT_LINE_1(int, "BUL_HIT", BulletsThatHit, 0); +; + STAT_LINE_1(int, "ACCURA", RoundsFiredByPlayer == 0 ? 0 : (BulletsThatHit * 100.0f / (float)RoundsFiredByPlayer), 2); + + switch (FrontEndMenuManager.m_PrefsLanguage) { + case CMenuManager::LANGUAGE_AMERICAN: +#ifndef USE_MEASUREMENTS_IN_METERS + STAT_LINE_1(float, "FEST_DF", DistanceTravelledOnFoot * MILES_IN_METER, 1); + STAT_LINE_1(float, "FEST_DC", DistanceTravelledByCar * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTBIK", DistanceTravelledByBike * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTBOA", DistanceTravelledByBoat * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTGOL", DistanceTravelledByGolfCart * MILES_IN_METER, 1); + STAT_LINE_1(float, "DISTHEL", DistanceTravelledByHelicoptor * MILES_IN_METER, 1); +#ifdef FIX_BUGS + STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike + + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane) * MILES_IN_METER, 1); + STAT_LINE_1(float, "MXCARD", MaximumJumpDistance * FEET_IN_METER, 1); + STAT_LINE_1(float, "MXCARJ", MaximumJumpHeight * FEET_IN_METER, 1); +#else + STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike + + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor) * MILES_IN_METER, 1); +#endif + break; +#endif + case CMenuManager::LANGUAGE_FRENCH: + case CMenuManager::LANGUAGE_GERMAN: + case CMenuManager::LANGUAGE_ITALIAN: + case CMenuManager::LANGUAGE_SPANISH: +#ifdef MORE_LANGUAGES + case CMenuManager::LANGUAGE_POLISH: + case CMenuManager::LANGUAGE_RUSSIAN: + case CMenuManager::LANGUAGE_JAPANESE: +#endif + STAT_LINE_1(float, "FESTDFM", DistanceTravelledOnFoot, 1); + STAT_LINE_1(float, "FESTDCM", DistanceTravelledByCar, 1); + STAT_LINE_1(float, "DISTBIM", DistanceTravelledByBike, 1); + STAT_LINE_1(float, "DISTBOM", DistanceTravelledByBoat, 1); + STAT_LINE_1(float, "DISTGOM", DistanceTravelledByGolfCart, 1); + STAT_LINE_1(float, "DISTHEM", DistanceTravelledByHelicoptor, 1); +#ifdef FIX_BUGS + STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + + DistanceTravelledByBike + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane, 1); + STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1); + STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1); +#else + STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor, 1); +#endif + break; + default: + break; + } + + // They were selecting the unit according to language in III, but they deleted the feet code in VC. Weird +#ifndef FIX_BUGS + STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1); + STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1); +#endif + STAT_LINE_1(int, "MXFLIP", MaximumJumpFlips, 0); + STAT_LINE_2(int, "NOUNIF", NumberOfUniqueJumpsFound, 0, TotalNumberOfUniqueJumps, 0); + STAT_LINE_1(int, "MXJUMP", MaximumJumpSpins, 4); + + TEXT_ON_LEFT_GXT("BSTSTU"); + switch (BestStuntJump) { + case 1: + TEXT_ON_RIGHT(TheText.Get("INSTUN")); + break; + case 2: + TEXT_ON_RIGHT(TheText.Get("PRINST")); + break; + case 3: + TEXT_ON_RIGHT(TheText.Get("DBINST")); + break; + case 4: + TEXT_ON_RIGHT(TheText.Get("DBPINS")); + break; + case 5: + TEXT_ON_RIGHT(TheText.Get("TRINST")); + break; + case 6: + TEXT_ON_RIGHT(TheText.Get("PRTRST")); + break; + case 7: + TEXT_ON_RIGHT(TheText.Get("QUINST")); + break; + case 8: + TEXT_ON_RIGHT(TheText.Get("PQUINS")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("NOSTUC")); + break; + } + STAT_LINE_1(int, "ST_WHEE", LongestWheelie, 0); + STAT_LINE_1(float, "ST_WHED", LongestWheelieDist, 1); + STAT_LINE_1(int, "ST_STOP", LongestStoppie, 0); + STAT_LINE_1(float, "ST_STOD", LongestStoppieDist, 1); + STAT_LINE_1(int, "ST_2WHE", Longest2Wheel, 0); + STAT_LINE_1(float, "ST_2WHD", Longest2WheelDist, 1); + + if (LoanSharks > 0.0f) + STAT_LINE_1(int, "ST_LOAN", LoanSharks, 0); + + STAT_LINE_1(int, "FEST_CC", CriminalsCaught, 0); + STAT_LINE_1(int, "FEST_HV", HighestLevelVigilanteMission, 0); + STAT_LINE_1(int, "PASDRO", PassengersDroppedOffWithTaxi, 0); + STAT_LINE_1(float, "MONTAX", MoneyMadeWithTaxi, 3); + STAT_LINE_1(int, "FEST_LS", LivesSavedWithAmbulance, 0); + STAT_LINE_1(int, "FEST_HA", HighestLevelAmbulanceMission, 0); + STAT_LINE_1(int, "FEST_FE", FiresExtinguished, 0); + STAT_LINE_1(int, "FIRELVL", HighestLevelFireMission, 0); + + STAT_LINE_2(int, "ST_STOR", StoresKnockedOff, 0, 15, 0); + + if (MovieStunts > 0.0f) + STAT_LINE_1(int, "ST_MOVI", MovieStunts, 0); + + STAT_LINE_2(int, "ST_ASSI", Assassinations, 0, 5, 0); + + if (PhotosTaken > 0) + STAT_LINE_1(int, "ST_PHOT", PhotosTaken, 0); + + if (PizzasDelivered > 0.0f) + STAT_LINE_1(int, "ST_PIZZ", PizzasDelivered, 0); + + if (GarbagePickups > 0.0f) + STAT_LINE_1(int, "ST_GARB", GarbagePickups, 0); + + if (IceCreamSold > 0.0f) + STAT_LINE_1(int, "ST_ICEC", IceCreamSold, 0); + + if (HighestScores[1]) + STAT_LINE_1(int, "STHC_02", HighestScores[1], 0); + + FASTEST_TIME(0, "STFT_01"); + FASTEST_TIME(1, "STFT_02"); + FASTEST_TIME(2, "STFT_03"); + FASTEST_TIME(3, "STFT_04"); + FASTEST_TIME(4, "STFT_05"); + FASTEST_TIME(5, "STFT_06"); + FASTEST_TIME(6, "STFT_07"); + FASTEST_TIME(7, "STFT_08"); + FASTEST_TIME(8, "STFT_09"); + FASTEST_TIME(9, "STFT_10"); + FASTEST_TIME(10, "STFT_11"); + FASTEST_TIME(11, "STFT_12"); + FASTEST_TIME(12, "STFT_13"); + FASTEST_TIME(13, "STFT_14"); + FASTEST_TIME(14, "STFT_15"); + FASTEST_TIME(15, "STFT_16"); + FASTEST_TIME(16, "STFT_17"); + FASTEST_TIME(17, "STFT_18"); + FASTEST_TIME(18, "STFT_19"); + FASTEST_TIME(19, "STFT_20"); + FASTEST_TIME(22, "STFT_23"); + + if (HighestScores[0]) + STAT_LINE_1(int, "STHC_01", HighestScores[0], 0); + + if (HighestScores[3]) + STAT_LINE_1(int, "STHC_04", HighestScores[3], 0); + + if (HighestScores[2]) + STAT_LINE_1(int, "STHC_03", HighestScores[2], 0); + + if (BestPositions[0] != INT_MAX) + STAT_LINE_1(int, "STHC_05", BestPositions[0], 0); + + FASTEST_TIME(20, "STFT_21"); + + if (FastestTimes[21]) + STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1); + + if (TopShootingRangeScore > 0.0f) + STAT_LINE_1(int, "TOP_SHO", TopShootingRangeScore, 0); + + if (ShootingRank > 0.0f) + STAT_LINE_1(int, "SHO_RAN", ShootingRank, 0); + + int flightMinute = (FlightTime / 60000) % 60; + int flightHour = (FlightTime / 60000) / 60; + STAT_LINE_2(int, "ST_FTIM", flightHour, 0, flightMinute, 1); + + // We always have pilot rank if we flew more then 5 minutes +#ifndef FIX_BUGS + if (flightHour != 0) + TEXT_ON_LEFT_GXT("ST_PRAN"); +#endif + +#ifdef FIX_BUGS +#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || (flightHour == hour && flightMinute >= minute)) +#else +#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || flightMinute >= minute) +#endif + + if (FL_TIME_MORE_THAN(0,5)) { + +#ifdef FIX_BUGS + TEXT_ON_LEFT_GXT("ST_PRAN"); +#endif + if (!FL_TIME_MORE_THAN(0,10)) TEXT_ON_RIGHT(TheText.Get("ST_PR01")); + else if (!FL_TIME_MORE_THAN(0,20)) TEXT_ON_RIGHT(TheText.Get("ST_PR02")); + else if (!FL_TIME_MORE_THAN(0,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR03")); + else if (!FL_TIME_MORE_THAN(1,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR04")); + else if (!FL_TIME_MORE_THAN(1,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR05")); + else if (!FL_TIME_MORE_THAN(2,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR06")); + else if (!FL_TIME_MORE_THAN(2,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR07")); + else if (!FL_TIME_MORE_THAN(3,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR08")); + else if (!FL_TIME_MORE_THAN(3,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR09")); + else if (!FL_TIME_MORE_THAN(4,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR10")); + else if (!FL_TIME_MORE_THAN(5,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR11")); + else if (!FL_TIME_MORE_THAN(10,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR12")); + else if (!FL_TIME_MORE_THAN(20,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR13")); + else if (!FL_TIME_MORE_THAN(25,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR14")); + else if (!FL_TIME_MORE_THAN(30,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR15")); + else if (!FL_TIME_MORE_THAN(49,2)) TEXT_ON_RIGHT(TheText.Get("ST_PR16")); + else if (!FL_TIME_MORE_THAN(50,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR17")); + else if (!FL_TIME_MORE_THAN(100,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR18")); + else TEXT_ON_RIGHT(TheText.Get("ST_PR19")); + } +#undef FL_TIME_MORE_THAN + + if (BloodRingKills > 0) + STAT_LINE_1(int, "ST_BRK", BloodRingKills, 0); + + if (BloodRingTime > 0) + STAT_LINE_1(int, "ST_LTBR", BloodRingTime, 0); + + STAT_LINE_1(int, "ST_DRWN", TimesDrowned, 0); + + if (SeagullsKilled > 0) + STAT_LINE_1(int, "SEAGULL", SeagullsKilled, 0); + + bool playerHatesRadio = true; + float* pListenTimeArray = DMAudio.GetListenTimeArray(); + for (int i = 0; i < NUM_RADIOS; i++) { + FavoriteRadioStationList[i] = pListenTimeArray[i]; + if (FavoriteRadioStationList[i] != 0.0) // double + playerHatesRadio = false; + } + + if (!playerHatesRadio) { + // Most listened + TEXT_ON_LEFT_GXT("FST_MFR"); + float mostListenTime = FavoriteRadioStationList[0]; + int mostListenedRadio = 0; + for (int i = 0; i < NUM_RADIOS; i++) { + if (FavoriteRadioStationList[i] > mostListenTime) { + mostListenTime = FavoriteRadioStationList[i]; + mostListenedRadio = i; + } + } + switch (mostListenedRadio) { + case WILDSTYLE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM0")); + break; + case FLASH_FM: + TEXT_ON_RIGHT(TheText.Get("FEA_FM1")); + break; + case KCHAT: + TEXT_ON_RIGHT(TheText.Get("FEA_FM2")); + break; + case FEVER: + TEXT_ON_RIGHT(TheText.Get("FEA_FM3")); + break; + case V_ROCK: + TEXT_ON_RIGHT(TheText.Get("FEA_FM4")); + break; + case VCPR: + TEXT_ON_RIGHT(TheText.Get("FEA_FM5")); + break; + case RADIO_ESPANTOSO: + TEXT_ON_RIGHT(TheText.Get("FEA_FM6")); + break; + case EMOTION: + TEXT_ON_RIGHT(TheText.Get("FEA_FM7")); + break; + case WAVE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); + break; + case USERTRACK: + TEXT_ON_RIGHT(TheText.Get("FEA_MP3")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh + break; + } + + // Least listened + TEXT_ON_LEFT_GXT("FST_LFR"); + float leastListenTime = FavoriteRadioStationList[0]; + int leastListenedRadio = 0; + for (int i = 0; i < NUM_RADIOS; i++) { +#ifdef FIX_BUGS + if (!DMAudio.IsMP3RadioChannelAvailable() && i == USERTRACK) + continue; +#endif + if (FavoriteRadioStationList[i] < leastListenTime) { + leastListenTime = FavoriteRadioStationList[i]; + leastListenedRadio = i; + } + } +#ifndef FIX_BUGS + if (!DMAudio.IsMP3RadioChannelAvailable() && leastListenedRadio == USERTRACK) + leastListenedRadio = WAVE; +#endif + + switch (leastListenedRadio) { + case WILDSTYLE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM0")); + break; + case FLASH_FM: + TEXT_ON_RIGHT(TheText.Get("FEA_FM1")); + break; + case KCHAT: + TEXT_ON_RIGHT(TheText.Get("FEA_FM2")); + break; + case FEVER: + TEXT_ON_RIGHT(TheText.Get("FEA_FM3")); + break; + case V_ROCK: + TEXT_ON_RIGHT(TheText.Get("FEA_FM4")); + break; + case VCPR: + TEXT_ON_RIGHT(TheText.Get("FEA_FM5")); + break; + case RADIO_ESPANTOSO: + TEXT_ON_RIGHT(TheText.Get("FEA_FM6")); + break; + case EMOTION: + TEXT_ON_RIGHT(TheText.Get("FEA_FM7")); + break; + case WAVE: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); + break; + case USERTRACK: + TEXT_ON_RIGHT(TheText.Get("FEA_MP3")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh + break; + } + } + STAT_LINE_1(int, "SPRAYIN", Sprayings, 0); + STAT_LINE_1(float, "ST_WEAP", WeaponBudget, 3); + STAT_LINE_1(float, "ST_FASH", FashionBudget, 3); + STAT_LINE_1(float, "ST_PROP", PropertyBudget, 3); + STAT_LINE_1(float, "ST_AUTO", AutoPaintingBudget, 3); + STAT_LINE_1(float, "ST_DAMA", PropertyBudget, 3); + + if (NumPropertyOwned > 0) { + STAT_LINE_1(int, "PROPOWN", NumPropertyOwned, 0); + if (PropertyOwned[0]) TEXT_ON_RIGHT(TheText.Get("STPR_1")); + if (PropertyOwned[1]) TEXT_ON_RIGHT(TheText.Get("STPR_2")); + if (PropertyOwned[2]) TEXT_ON_RIGHT(TheText.Get("STPR_3")); + if (PropertyOwned[3]) TEXT_ON_RIGHT(TheText.Get("STPR_4")); + if (PropertyOwned[4]) TEXT_ON_RIGHT(TheText.Get("STPR_5")); + if (PropertyOwned[5]) TEXT_ON_RIGHT(TheText.Get("STPR_6")); + if (PropertyOwned[6]) TEXT_ON_RIGHT(TheText.Get("STPR_7")); + if (PropertyOwned[7]) TEXT_ON_RIGHT(TheText.Get("STPR_8")); + if (PropertyOwned[8]) TEXT_ON_RIGHT(TheText.Get("STPR_9")); + if (PropertyOwned[9]) TEXT_ON_RIGHT(TheText.Get("STPR_10")); + if (PropertyOwned[10]) TEXT_ON_RIGHT(TheText.Get("STPR_11")); + if (PropertyOwned[11]) TEXT_ON_RIGHT(TheText.Get("STPR_12")); + if (PropertyOwned[12]) TEXT_ON_RIGHT(TheText.Get("STPR_13")); + if (PropertyOwned[13]) TEXT_ON_RIGHT(TheText.Get("STPR_14")); + if (PropertyOwned[14]) TEXT_ON_RIGHT(TheText.Get("STPR_15")); + } + STAT_LINE_1(int, "CHASE", HighestChaseValue, 0); + TEXT_ON_RIGHT(FindChaseString(HighestChaseValue)); + + return counter; + +#undef STAT_LINE_1 +#undef STAT_LINE_2 +#undef TEXT_ON_LEFT_GXT +#undef TEXT_ON_RIGHT +#undef FASTEST_TIME +} diff --git a/src/core/Stats.h b/src/core/Stats.h index 49f84657..7fa69396 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -49,8 +49,8 @@ public: static int32 WantedStarsAttained; static int32 WantedStarsEvaded; static int32 PeopleKilledByPlayer; - static int32 ProgressMade; - static int32 TotalProgressInGame; + static float ProgressMade; + static float TotalProgressInGame; static float MaximumJumpDistance; static float MaximumJumpHeight; static int32 MaximumJumpFlips; @@ -147,4 +147,6 @@ public: static void AddPropertyAsOwned(int32); static void PopulateFavoriteRadioStationList(); static float GetFavoriteRadioStationList(int32); + static void BuildStatLine(Const char *, void *, int, void *, int); + static int ConstructStatLine(int); }; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 40d4acee..2fd8bf1c 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -32,6 +32,10 @@ #include "ColStore.h" #include "DMAudio.h" #include "Script.h" +#include "MemoryMgr.h" +#include "MemoryHeap.h" +#include "Font.h" +#include "Frontend.h" //--MIAMI: file done (possibly bugs) @@ -289,12 +293,22 @@ CStreaming::Shutdown(void) } } +#ifndef MASTER +uint64 timeProcessingTXD; +uint64 timeProcessingDFF; +#endif + void CStreaming::Update(void) { CStreamingInfo *si, *prev; bool requestedSubway = false; +#ifndef MASTER + timeProcessingTXD = 0; + timeProcessingDFF = 0; +#endif + UpdateMemoryUsed(); if(ms_channelError != -1){ @@ -332,6 +346,10 @@ CStreaming::Update(void) CColStore::EnsureCollisionIsInMemory(FindPlayerCoors()); } + // TODO: PrintRequestList + //if (CPad::GetPad(1)->GetLeftShoulder2JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2()) + // PrintRequestList(); + for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){ prev = si->m_prev; if((si->m_flags & (STREAMFLAGS_KEEP_IN_MEMORY|STREAMFLAGS_PRIORITY)) == 0) @@ -463,6 +481,14 @@ GetObjectName(int streamId) return objname; } +#ifdef USE_CUSTOM_ALLOCATOR +RpAtomic* +RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data) +{ + // empty because we expect models to be pre-instanced + return atomic; +} +#endif bool CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) @@ -497,10 +523,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) // Set Txd and anims to use CTxdStore::AddRef(mi->GetTxdSlot()); +#if GTA_VERSION > GTAVC_PS2 if(animId != -1) CAnimManager::AddAnimBlockRef(animId); - CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); +#endif + PUSH_MEMID(MEMID_STREAM_MODELS); + 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 @@ -512,14 +541,21 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED; }else{ success = CFileLoader::LoadClumpFile(stream, streamId); +#ifdef USE_CUSTOM_ALLOCATOR + if(success) + RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil); +#endif } + POP_MEMID(); UpdateMemoryUsed(); // 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 GTA_VERSION > GTAVC_PS2 if(animId != -1) CAnimManager::RemoveAnimBlockRefWithoutDelete(animId); +#endif } if(!success){ @@ -538,12 +574,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) return false; } + PUSH_MEMID(MEMID_STREAM_TEXUTRES); if(ms_bLoadingBigModel || cdsize > 200){ success = CTxdStore::StartLoadTxd(streamId - STREAM_OFFSET_TXD, stream); if(success) ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED; }else success = CTxdStore::LoadTxd(streamId - STREAM_OFFSET_TXD, stream); + POP_MEMID(); UpdateMemoryUsed(); if(!success){ @@ -554,7 +592,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) return false; } }else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){ - if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){ + PUSH_MEMID(MEMID_STREAM_COLLISION); + bool success = CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length); + POP_MEMID(); + if(!success){ debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL)); RemoveModel(streamId); ReRequestModel(streamId); @@ -569,8 +610,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } + PUSH_MEMID(MEMID_STREAM_ANIMATION); CAnimManager::LoadAnimFile(stream, true, nil); CAnimManager::CreateAnimAssocGroups(); + POP_MEMID(); } RwStreamClose(stream, &mem); @@ -603,7 +646,9 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) // Mark objects as loaded if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){ ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; +#ifndef USE_CUSTOM_ALLOCATOR ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE; +#endif } endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); @@ -638,26 +683,39 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) if(streamId < STREAM_OFFSET_TXD){ // Model mi = CModelInfo::GetModelInfo(streamId); + PUSH_MEMID(MEMID_STREAM_MODELS); CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); success = CFileLoader::FinishLoadClumpFile(stream, streamId); - if(success) + if(success){ +#ifdef USE_CUSTOM_ALLOCATOR + RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil); +#endif success = AddToLoadedVehiclesList(streamId); + } + POP_MEMID(); mi->RemoveRef(); CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); +#if GTA_VERSION > GTAVC_PS2 if(mi->GetAnimFileIndex() != -1) CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex()); +#endif }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // Txd CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD); + PUSH_MEMID(MEMID_STREAM_TEXUTRES); success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream); + POP_MEMID(); CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD); }else{ assert(0 && "invalid streamId"); } RwStreamClose(stream, &mem); + ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; +#ifndef USE_CUSTOM_ALLOCATOR ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE; +#endif if(!success){ RemoveModel(streamId); @@ -740,7 +798,15 @@ CStreaming::RequestBigBuildings(eLevelName level) 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 && b->bIsBIGBuilding +#ifdef NO_ISLAND_LOADING + && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && + (b != pIslandLODbeachEntity)) || + (b->m_level == level)) +#else + && b->m_level == level +#endif + ) if(!b->bStreamBIGBuilding) RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } @@ -757,8 +823,11 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos) for(i = n; i >= 0; i--){ b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding -#ifndef NO_ISLAND_LOADING - && b->m_level == level +#ifdef NO_ISLAND_LOADING + && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && (b != pIslandLODbeachEntity) + ) || (b->m_level == level)) +#else + && b->m_level == level #endif ) if(b->bStreamBIGBuilding){ @@ -828,7 +897,7 @@ CStreaming::InstanceLoadedModels(const CVector &pos) void CStreaming::RequestIslands(eLevelName level) { -#ifndef NO_ISLAND_LOADING + ISLAND_LOADING_ISNT(HIGH) switch(level){ case LEVEL_MAINLAND: if(islandLODbeach != -1) @@ -840,7 +909,6 @@ CStreaming::RequestIslands(eLevelName level) break; default: break; } -#endif } static char *IGnames[] = { @@ -1170,12 +1238,13 @@ CStreaming::RemoveBuildingsNotInArea(int32 area) void CStreaming::RemoveUnusedBigBuildings(eLevelName level) { -#ifndef NO_ISLAND_LOADING + ISLAND_LOADING_IS(LOW) + { if(level != LEVEL_BEACH) RemoveBigBuildings(LEVEL_BEACH); if(level != LEVEL_MAINLAND) RemoveBigBuildings(LEVEL_MAINLAND); -#endif + } RemoveIslandsNotUsed(level); } @@ -1195,7 +1264,6 @@ DeleteIsland(CEntity *island) void CStreaming::RemoveIslandsNotUsed(eLevelName level) { -#ifndef NO_ISLAND_LOADING int i; if(pIslandLODmainlandEntity == nil) for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ @@ -1207,7 +1275,12 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level) if(building->GetModelIndex() == islandLODbeach) pIslandLODbeachEntity = building; } - +#ifdef NO_ISLAND_LOADING + if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { + DeleteIsland(pIslandLODmainlandEntity); + DeleteIsland(pIslandLODbeachEntity); + } else +#endif switch(level){ case LEVEL_MAINLAND: DeleteIsland(pIslandLODmainlandEntity); @@ -1217,7 +1290,6 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level) break; } -#endif // !NO_ISLAND_LOADING } void @@ -1818,26 +1890,36 @@ CStreaming::LoadBigBuildingsWhenNeeded(void) CTimer::Suspend(); CGame::currLevel = CTheZones::m_CurrLevel; - DMAudio.SetEffectsFadeVol(0); - CPad::StopPadsShaking(); - CCollision::LoadCollisionScreen(CGame::currLevel); - DMAudio.Service(); - - RemoveUnusedBigBuildings(CGame::currLevel); - RemoveUnusedBuildings(CGame::currLevel); - RemoveUnusedModelsInLoadedList(); - CGame::TidyUpMemory(true, true); - + ISLAND_LOADING_IS(LOW) + { + DMAudio.SetEffectsFadeVol(0); + CPad::StopPadsShaking(); + CCollision::LoadCollisionScreen(CGame::currLevel); + DMAudio.Service(); + + RemoveUnusedBigBuildings(CGame::currLevel); + RemoveUnusedBuildings(CGame::currLevel); + RemoveUnusedModelsInLoadedList(); + CGame::TidyUpMemory(true, true); + } CReplay::EmptyReplayBuffer(); if(CGame::currLevel != LEVEL_GENERIC) LoadSplash(GetLevelSplashScreen(CGame::currLevel)); - CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); + ISLAND_LOADING_IS(LOW) + CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); + else if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) { + RemoveIslandsNotUsed(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + CStreaming::LoadAllRequestedModels(false); CGame::TidyUpMemory(true, true); CTimer::Resume(); - DMAudio.SetEffectsFadeVol(127); + + ISLAND_LOADING_IS(LOW) + DMAudio.SetEffectsFadeVol(127); } @@ -2415,19 +2497,27 @@ CStreaming::FlushRequestList(void) void CStreaming::ImGonnaUseStreamingMemory(void) { - // empty + PUSH_MEMID(MEMID_STREAM); } void CStreaming::IHaveUsedStreamingMemory(void) { + POP_MEMID(); UpdateMemoryUsed(); } void CStreaming::UpdateMemoryUsed(void) { - // empty +#ifdef USE_CUSTOM_ALLOCATOR + ms_memoryUsed = + gMainHeap.GetMemoryUsed(MEMID_STREAM) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION) + + gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION); +#endif } #define STREAM_DIST 80.0f @@ -3041,3 +3131,71 @@ CStreaming::UpdateForAnimViewer(void) CStreaming::RetryLoadFile(CStreaming::ms_channelError); } } + + +void +CStreaming::PrintStreamingBufferState() +{ + char str[128]; + wchar wstr[128]; + uint32 offset, size; + + CTimer::Stop(); + int i = 0; + while (i < NUMSTREAMINFO) { + while (true) { + int j = 0; + DoRWStuffStartOfFrame(50, 50, 50, 0, 0, 0, 255); + CPad::UpdatePads(); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + DefinedState(); + + CRect unusedRect(0, 0, RsGlobal.maximumWidth, RsGlobal.maximumHeight); + CRGBA unusedColor(255, 255, 255, 255); + CFont::SetFontStyle(FONT_BANK); + CFont::SetBackgroundOff(); + CFont::SetWrapx(DEFAULT_SCREEN_WIDTH); + CFont::SetScale(0.5f, 0.75f); + CFont::SetCentreOff(); + CFont::SetCentreSize(DEFAULT_SCREEN_WIDTH); + CFont::SetJustifyOff(); + CFont::SetColor(CRGBA(200, 200, 200, 200)); + CFont::SetBackGroundOnlyTextOff(); + int modelIndex = i; + if (modelIndex < NUMSTREAMINFO) { + int y = 24; + for ( ; j < 34 && modelIndex < NUMSTREAMINFO; modelIndex++) { + CStreamingInfo *streamingInfo = &ms_aInfoForModel[modelIndex]; + CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelIndex); + if (streamingInfo->m_loadState != STREAMSTATE_LOADED || !streamingInfo->GetCdPosnAndSize(offset, size)) + continue; + + if (modelIndex >= STREAM_OFFSET_TXD) + sprintf(str, "txd %s, refs %d, size %dK, flags 0x%x", CTxdStore::GetTxdName(modelIndex - STREAM_OFFSET_TXD), + CTxdStore::GetNumRefs(modelIndex - STREAM_OFFSET_TXD), 2 * size, streamingInfo->m_flags); + else + sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetName(), modelInfo->GetNumRefs(), 2 * size, + streamingInfo->m_flags); + AsciiToUnicode(str, wstr); + CFont::PrintString(24.0f, y, wstr); + y += 12; + j++; + } + } + + if (CPad::GetPad(1)->GetCrossJustDown()) + i = modelIndex; + + if (!CPad::GetPad(1)->GetTriangleJustDown()) + break; + + i = 0; + CFont::DrawFonts(); + DoRWStuffEndOfFrame(); + } + CFont::DrawFonts(); + DoRWStuffEndOfFrame(); + } + CTimer::Update(); +}
\ No newline at end of file diff --git a/src/core/Streaming.h b/src/core/Streaming.h index dd85ce97..a67384f6 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -197,11 +197,11 @@ public: static void DeleteFarAwayRwObjects(const CVector &pos); static void DeleteAllRwObjects(void); static void DeleteRwObjectsAfterDeath(const CVector &pos); - static void DeleteRwObjectsBehindCamera(size_t mem); + static void DeleteRwObjectsBehindCamera(size_t mem); // originally signed static void DeleteRwObjectsInSectorList(CPtrList &list); static void DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y); - static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); - static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); + static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); // originally signed + static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); // originally signed static void LoadScene(const CVector &pos); static void LoadSceneCollision(const CVector &pos); @@ -210,4 +210,6 @@ public: static void MemoryCardLoad(uint8 *buffer, uint32 length); static void UpdateForAnimViewer(void); + + static void PrintStreamingBufferState(); }; diff --git a/src/core/World.cpp b/src/core/World.cpp index 4c700f10..6413a620 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -35,7 +35,7 @@ CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; -CPtrList CWorld::ms_bigBuildingsList[4]; +CPtrList CWorld::ms_bigBuildingsList[NUM_LEVELS]; CPtrList CWorld::ms_listMovingEntityPtrs; CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; uint16 CWorld::ms_nCurrentScanCode; @@ -147,13 +147,13 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov } } CCarCtrl::RemoveFromInterestingVehicleList(pVehicle); - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } CObject::DeleteAllTempObjectsInArea(pos, radius); gFireManager.ExtinguishPoint(pos, radius); - CWorld::ExtinguishAllCarFiresInArea(pos, radius); + ExtinguishAllCarFiresInArea(pos, radius); CExplosion::RemoveAllExplosionsInArea(pos, radius); if(bRemoveProjectilesAndTidyUpShadows) { CProjectileInfo::RemoveAllProjectiles(); @@ -796,7 +796,7 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nEntitiesFound = 0; const CVector2D vecSectorStartPos(position.x - radius, position.y - radius); const CVector2D vecSectorEndPos(position.x + radius, position.y + radius); @@ -813,42 +813,42 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } @@ -942,26 +942,26 @@ CEntity * CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore, bool ignoreSomeObjects) { - static CColModel sphereCol; + static CColModel OurColModel; CColSphere sphere; - sphereCol.boundingSphere.center.x = 0.0f; - sphereCol.boundingSphere.center.y = 0.0f; - sphereCol.boundingSphere.center.z = 0.0f; - sphereCol.boundingSphere.radius = radius; - sphereCol.boundingBox.min.x = -radius; - sphereCol.boundingBox.min.y = -radius; - sphereCol.boundingBox.min.z = -radius; - sphereCol.boundingBox.max.x = radius; - sphereCol.boundingBox.max.y = radius; - sphereCol.boundingBox.max.z = radius; - sphereCol.numSpheres = 1; + OurColModel.boundingSphere.center.x = 0.0f; + OurColModel.boundingSphere.center.y = 0.0f; + OurColModel.boundingSphere.center.z = 0.0f; + OurColModel.boundingSphere.radius = radius; + OurColModel.boundingBox.min.x = -radius; + OurColModel.boundingBox.min.y = -radius; + OurColModel.boundingBox.min.z = -radius; + OurColModel.boundingBox.max.x = radius; + OurColModel.boundingBox.max.y = radius; + OurColModel.boundingBox.max.z = radius; + OurColModel.numSpheres = 1; sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f)); - sphereCol.spheres = &sphere; - sphereCol.numLines = 0; - sphereCol.numBoxes = 0; - sphereCol.numTriangles = 0; - sphereCol.ownsCollisionVolumes = false; + OurColModel.spheres = &sphere; + OurColModel.numLines = 0; + OurColModel.numBoxes = 0; + OurColModel.numTriangles = 0; + OurColModel.ownsCollisionVolumes = false; CMatrix sphereMat; sphereMat.SetTranslate(spherePos); @@ -980,7 +980,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad if(e->GetBoundRadius() + radius > distance) { CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); int collidedSpheres = - CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol, + CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol, gaTempSphereColPoints, nil, nil); if(collidedSpheres != 0 || @@ -1070,7 +1070,7 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nCollidingEntities = 0; const CVector2D vecSectorStartPos(position.x - radius, position.y - radius); const CVector2D vecSectorEndPos(position.x + radius, position.y + radius); @@ -1087,42 +1087,42 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, + FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } @@ -1156,7 +1156,7 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nIntersecting = 0; const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0); const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0); @@ -1164,49 +1164,49 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X - 1); const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y - 1); #else - const int32 nEndX = Min(GetSectorIndexX(vecSectorPos.x), NUMSECTORS_X); - const int32 nEndY = Min(GetSectorIndexY(vecSectorPos.y), NUMSECTORS_Y); + const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X); + const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y); #endif for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } @@ -1242,7 +1242,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nEntitiesFound = 0; const int32 nStartX = Max(GetSectorIndexX(fStartX), 0); const int32 nStartY = Max(GetSectorIndexY(fStartY), 0); @@ -1257,42 +1257,42 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_PEDS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_DUMMIES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } @@ -1327,7 +1327,7 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV int16 maxEntitiesToFind, CEntity **aEntities, bool bVehicles, bool bPeds, bool bObjects) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nIntersecting = 0; const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0); const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0); @@ -1342,26 +1342,26 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); if(bVehicles) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false); } if(bPeds) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true); } if(bObjects) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false); } @@ -1399,102 +1399,6 @@ CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList &list, const CVec } } -CPlayerPed * -FindPlayerPed(void) -{ - return CWorld::Players[CWorld::PlayerInFocus].m_pPed; -} - -CVehicle * -FindPlayerVehicle(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped && ped->InVehicle()) return ped->m_pMyVehicle; - return nil; -} - -CVehicle * -FindPlayerTrain(void) -{ - if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) - return FindPlayerVehicle(); - else - return nil; -} - -CEntity * -FindPlayerEntity(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle; - else - return ped; -} - -CVector -FindPlayerCoors(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) - return TheCamera.GetPosition(); -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->GetPosition(); - else - return ped->GetPosition(); -} - -CVector & -FindPlayerSpeed(void) -{ -#ifdef FIX_BUGS - static CVector vecTmpVector(0.0f, 0.0f, 0.0f); - if (CReplay::IsPlayingBack()) - return vecTmpVector; -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->m_vecMoveSpeed; - else - return ped->m_vecMoveSpeed; -} - -const CVector & -FindPlayerCentreOfWorld(int32 player) -{ -#ifdef FIX_BUGS - if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return CWorld::Players[player].m_pPed->GetPosition(); -} - -const CVector & -FindPlayerCentreOfWorld_NoSniperShift(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return FindPlayerPed()->GetPosition(); -} - -float -FindPlayerHeading(void) -{ - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); - return FindPlayerPed()->GetForward().Heading(); -} - void CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2) { @@ -1517,7 +1421,7 @@ CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, floa } } CCarCtrl::RemoveFromInterestingVehicleList(pVehicle); - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } @@ -1543,7 +1447,7 @@ CWorld::ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, floa void CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); float fStartX = x1 - 10.0f; float fStartY = y1 - 10.0f; float fEndX = x2 + 10.0f; @@ -1560,12 +1464,12 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2) for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); - CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2, + CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY); - CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1, + CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY); - CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2); - CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2, + CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2); + CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2, y2); } } @@ -1580,7 +1484,7 @@ CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1 if(pVehicle->m_scanCode != GetCurrentScanCode()) { pVehicle->m_scanCode = GetCurrentScanCode(); const CVector &vehiclePos = pVehicle->GetPosition(); - eCarMission carMission = pVehicle->AutoPilot.m_nCarMission; + uint8 carMission = pVehicle->AutoPilot.m_nCarMission; if(pVehicle != FindPlayerVehicle() && vehiclePos.x > fStartX && vehiclePos.x < fEndX && vehiclePos.y > fStartY && vehiclePos.y < fEndY && pVehicle->bIsLawEnforcer && (carMission == MISSION_RAMPLAYER_FARAWAY || carMission == MISSION_RAMPLAYER_CLOSE || @@ -1739,14 +1643,24 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range) } } +inline void +AddSteamsFromGround(CPtrList& list) +{ + CPtrNode* pNode = list.first; + while (pNode) { + ((CEntity*)pNode->item)->AddSteamsFromGround(nil); + pNode = pNode->next; + } +} + void CWorld::AddParticles(void) { for(int32 y = 0; y < NUMSECTORS_Y; y++) { for(int32 x = 0; x < NUMSECTORS_X; x++) { CSector *pSector = GetSector(x, y); - CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]); - CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]); + AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]); + AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]); } } } @@ -1758,44 +1672,52 @@ CWorld::ShutDown(void) CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } +#ifndef FIX_BUGS pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush(); pSector->m_lists[ENTITYLIST_DUMMIES].Flush(); pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush(); +#endif } - for(int32 i = 0; i < 4; i++) { - for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) { + for(int32 i = 0; i < NUM_LEVELS; i++) { + for(CPtrNode *pNode = ms_bigBuildingsList[i].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; // Maybe remove from world here? delete pEntity; } - GetBigBuildingList((eLevelName)i).Flush(); + ms_bigBuildingsList[i].Flush(); } for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) { CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); +#ifdef FIX_BUGS + pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); + pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush(); + pSector->m_lists[ENTITYLIST_DUMMIES].Flush(); + pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush(); +#endif if(pSector->m_lists[ENTITYLIST_BUILDINGS].first) { sprintf(gString, "Building list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y); pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); @@ -1840,19 +1762,19 @@ CWorld::ClearForRestart(void) CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = GetBigBuildingList(LEVEL_GENERIC).first; pNode; pNode = pNode->next) { CVehicle *pVehicle = (CVehicle *)pNode->item; if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) { - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } } @@ -1885,7 +1807,7 @@ CWorld::RepositionOneObject(CEntity *pEntity) 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 = FindGroundZFor3DCoord(position.x, position.y, position.z + fHeight, nil) - fBoundingBoxMinZ; pEntity->m_matrix.UpdateRW(); @@ -1918,7 +1840,7 @@ CWorld::RepositionOneObject(CEntity *pEntity) if(modelId == MI_BUOY) { bool bFound = true; const CVector &position = pEntity->GetPosition(); - float fGroundZ = CWorld::FindGroundZFor3DCoord(position.x, position.y, + float fGroundZ = FindGroundZFor3DCoord(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound); CColModel *pColModel = pEntity->GetColModel(); float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z; @@ -1983,17 +1905,17 @@ CWorld::RemoveStaticObjects() CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); @@ -2017,7 +1939,8 @@ CWorld::Process(void) if (csObj->IsObject()) RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped()); else { - csObj->bOffscreen = !csObj->GetIsOnScreen(); + if (!csObj->bOffscreen) + csObj->bOffscreen = !csObj->GetIsOnScreen(); RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStep(), !csObj->bOffscreen); } } @@ -2032,17 +1955,13 @@ CWorld::Process(void) } else { for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { CEntity *movingEnt = (CEntity *)node->item; -#ifdef SQUEEZE_PERFORMANCE - if (movingEnt->bRemoveFromWorld) { - RemoveEntityInsteadOfProcessingIt(movingEnt); - } else -#endif - if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && + if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) { if (movingEnt->IsObject()) RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped()); else { - movingEnt->bOffscreen = !movingEnt->GetIsOnScreen(); + if (!movingEnt->bOffscreen) + movingEnt->bOffscreen = !movingEnt->GetIsOnScreen(); RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStep(), !movingEnt->bOffscreen); } } @@ -2200,11 +2119,11 @@ CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, C for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { CSector *pSector = GetSector(x, y); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); } } @@ -2262,7 +2181,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa if(!pEntity->GetIsStatic()) { float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f); CVector vecForceDir = - vecDistance * (fPower * pEntity->m_fMass / 14000.0f * fDamageMultiplier / + vecDistance * (fPower * pEntity->m_fMass / 1400.0f * fDamageMultiplier / Max(fMagnitude, 0.01f)); vecForceDir.z = Max(vecForceDir.z, 0.0f); if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f); diff --git a/src/core/World.h b/src/core/World.h index be32db20..59bf634c 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -55,7 +55,7 @@ struct CStoredCollPoly; class CWorld { - static CPtrList ms_bigBuildingsList[4]; + static CPtrList ms_bigBuildingsList[NUM_LEVELS]; static CPtrList ms_listMovingEntityPtrs; static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; static uint16 ms_nCurrentScanCode; @@ -178,15 +178,3 @@ public: }; extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; - -class CPlayerPed; -class CVehicle; -CPlayerPed *FindPlayerPed(void); -CVehicle *FindPlayerVehicle(void); -CVehicle *FindPlayerTrain(void); -CEntity *FindPlayerEntity(void); -CVector FindPlayerCoors(void); -CVector &FindPlayerSpeed(void); -const CVector &FindPlayerCentreOfWorld(int32 player); -const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); -float FindPlayerHeading(void); diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h index 8200b09a..d7780caf 100644 --- a/src/core/ZoneCull.h +++ b/src/core/ZoneCull.h @@ -17,12 +17,12 @@ enum eZoneAttribs struct CAttributeZone { - float minx; - float maxx; - float miny; - float maxy; - float minz; - float maxz; + int16 minx; + int16 maxx; + int16 miny; + int16 maxy; + int16 minz; + int16 maxz; int16 attributes; int16 wantedLevel; }; diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 8abe0f1e..55b43c10 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -209,6 +209,9 @@ CTheZones::PostZoneCreation(void) for(i = 1; i < TotalNumberOfNavigationZones; i++) InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]); InitialiseAudioZoneArray(); +#ifndef MASTER + CheckZonesForOverlap(); +#endif } void @@ -222,8 +225,7 @@ CTheZones::CheckZonesForOverlap(void) 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); + sprintf(str, "Info zone %s contains %s\n", InfoZoneArray[j].name, InfoZoneArray[i].name); } } diff --git a/src/core/common.h b/src/core/common.h index 0e6bd60f..155b5dba 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -73,21 +73,24 @@ typedef int16_t int16; typedef uint32_t uint32; typedef int32_t int32; typedef uintptr_t uintptr; +typedef intptr_t intptr; typedef uint64_t uint64; typedef int64_t int64; // hardcode ucs-2 typedef uint16_t wchar; +#if defined(_MSC_VER) +typedef ptrdiff_t ssize_t; +#endif + #ifndef nil #define nil NULL #endif #include "config.h" -#ifdef PED_SKIN #include <rphanim.h> #include <rpskin.h> -#endif #ifdef __GNUC__ #define TYPEALIGN(n) __attribute__ ((aligned (n))) @@ -220,6 +223,8 @@ extern int strcasecmp(const char *str1, const char *str2); extern int strncasecmp(const char *str1, const char *str2, size_t len); #endif +extern wchar *AllocUnicode(const char*src); + #define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v)) #define clamp2(v, center, radius) ((v) < (center) ? Max(v, center - radius) : Min(v, center + radius)) @@ -249,8 +254,14 @@ void re3_usererror(const char *format, ...); #define DEBUGBREAK() __debugbreak(); -#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) +// Switch to enable development messages. +#if 1 +#define DEV(f, ...) +#else #define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__) +#endif + +#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) #define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__) #define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__) #define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__) @@ -487,4 +498,4 @@ inline T *WriteSaveBuf(uint8 *&buf, uint32 &length, const T &value) assert(ReadSaveBuf<uint32>(buf,len) == size); -void cprintf(char*, ...);
\ No newline at end of file +void cprintf(char*, ...); diff --git a/src/core/config.h b/src/core/config.h index 822cf83f..8fd3bc1c 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -7,7 +7,7 @@ enum Config { MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, - MODELINFOSIZE = 6500, + MODELINFOSIZE = 6500, // 4900 on PS2 TXDSTORESIZE = 1385, COLSTORESIZE = 31, EXTRADIRSIZE = 256, @@ -36,7 +36,7 @@ enum Config { NUMDUMMIES = 2340, NUMAUDIOSCRIPTOBJECTS = 192, NUMCOLMODELS = 4400, - NUMCUTSCENEOBJECTS = 50, // does not exist in VC + NUMCUTSCENEOBJECTS = 50, // not a pool in VC NUMANIMBLOCKS = 35, NUMANIMATIONS = 450, @@ -146,10 +146,6 @@ enum Config { NUM_SHORTCUT_START_POINTS = 16 }; -// We'll use this once we're ready to become independent of the game -// Use it to mark bugs in the code that will prevent the game from working then -//#define STANDALONE - // We don't expect to compile for PS2 or Xbox // but it might be interesting for documentation purposes #define GTA_PC @@ -176,6 +172,19 @@ enum Config { #define FINAL #endif +// Version defines +#define GTAVC_PS2 400 +#define GTAVC_PC_10 410 +#define GTAVC_PC_11 411 +#define GTAVC_PC_JAP 412 +// TODO? maybe something for xbox or android? + +#define GTA_VERSION GTAVC_PC_11 + +// TODO(MIAMI): someone ought to find and check out uses of these defines: +//#define GTA3_STEAM_PATCH +//#define GTAVC_JP_PATCH + // quality of life fixes that should also be in FINAL #define NASTY_GAME // nasty game for all languages #define NO_CDCHECK @@ -183,23 +192,30 @@ enum Config { // those infamous texts #define DRAW_GAME_VERSION_TEXT +// Memory allocation and compression +// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet +//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices +//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed + #if defined GTA_PS2 # define GTA_PS2_STUFF # define RANDOMSPLASH +//# define USE_CUSTOM_ALLOCATOR # define VU_COLLISION #elif defined GTA_PC -//# define GTA3_STEAM_PATCH -//# define GTAVC_JP_PATCH # ifdef GTA_PS2_STUFF # define USE_PS2_RAND # define RANDOMSPLASH // use random splash as on PS2 # define PS2_MATFX # endif +# define PC_PLAYER_CONTROLS // mouse player/cam mode +# define GTA_REPLAY +# define GTA_SCENE_EDIT #elif defined GTA_XBOX #endif #ifdef VU_COLLISION -#define COMPRESSED_COL_VECTORS // current need compressed vectors in this code +#define COMPRESSED_COL_VECTORS // currently need compressed vectors in this code #endif #ifdef MASTER @@ -225,6 +241,7 @@ enum Config { #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more //#define MORE_LANGUAGES // Add more translations to the game #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible +#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS #define FIX_HIGH_FPS_BUGS_ON_FRONTEND // Just debug menu entries @@ -240,24 +257,20 @@ enum Config { #define PS2_ALPHA_TEST // emulate ps2 alpha test #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number #define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time -//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU +#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync //#define USE_TEXTURE_POOL -//#define CUTSCENE_BORDERS_SWITCH #ifdef LIBRW -//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) -//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) -//#define NEW_RENDERER // leeds-like world rendering, needs librw +#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) +#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) +#define SCREEN_DROPLETS // neo water droplets +#define NEW_RENDERER // leeds-like world rendering, needs librw #endif -//#define MULTISAMPLING // adds MSAA option TODO -#ifdef LIBRW -// these are not supported with librw yet -# undef MULTISAMPLING +#ifndef EXTENDED_COLOURFILTER +#undef SCREEN_DROPLETS // we need the backbuffer for this effect #endif // Water & Particle -#define PC_PARTICLE -//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2 // #define PC_WATER #define WATER_CHEATS @@ -278,32 +291,48 @@ enum Config { #define WALLCLIMB_CHEAT #define REGISTER_START_BUTTON //#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls +#define BUTTON_ICONS // use textures to show controller buttons // Hud, frontend and radar -//#define BETA_SLIDING_TEXT #define PC_MENU #ifndef PC_MENU # define PS2_MENU //# define PS2_MENU_USEALLPAGEICONS #else -# define MAP_ENHANCEMENTS // Adding waypoint etc. +# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support # define TRIANGLE_BACK_BUTTON //# define CIRCLE_BACK_BUTTON -//#define CUSTOM_FRONTEND_OPTIONS -# define GRAPHICS_MENU_OPTIONS -#define LEGACY_MENU_OPTIONS +#define LEGACY_MENU_OPTIONS // i.e. frame sync(vsync) #define MUCH_SHORTER_OUTRO_SCREEN +// #define XBOX_MESSAGE_SCREEN // Blue background, no "saved successfully press OK" screen etc. +# define CUSTOM_FRONTEND_OPTIONS + +# ifdef CUSTOM_FRONTEND_OPTIONS +# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable +# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU +# define CUTSCENE_BORDERS_SWITCH +//# define MULTISAMPLING // adds MSAA option +# define INVERT_LOOK_FOR_PAD // enable the hidden option +# endif +#endif // Script #define USE_DEBUG_SCRIPT_LOADER // Loads main.scm by default. Hold R for main_freeroam.scm and D for main_d.scm #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely +#define SUPPORT_JAPANESE_SCRIPT +//#define SUPPORT_XBOX_SCRIPT +//#define SUPPORT_MOBILE_SCRIPT +#if (defined SUPPORT_XBOX_SCRIPT && defined SUPPORT_MOBILE_SCRIPT) +static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive"); +#endif +#ifdef PC_MENU //#define MISSION_REPLAY // mobile feature #endif //#define SIMPLIER_MISSIONS // apply simplifications from mobile #define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT -#define SCRIPT_LOG_FILE_LEVEL 1 // 0 == no log, 1 == overwrite every frame, 2 == full log +#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log #ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT #define USE_BASIC_SCRIPT_DEBUG_OUTPUT @@ -322,9 +351,6 @@ enum Config { #define CAMERA_PICKUP // Peds -#define PED_SKIN // support for skinned geometry on peds -#define ANIMATE_PED_COL_MODEL -#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle #define CANCELLABLE_CAR_ENTER // Camera @@ -336,10 +362,15 @@ enum Config { //#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS +#ifdef LIBRW +// these are not supported with librw yet +# undef MULTISAMPLING +#endif +// IMG +#define BIG_IMG // allows to read larger img files + //#define SQUEEZE_PERFORMANCE #ifdef SQUEEZE_PERFORMANCE #undef PS2_ALPHA_TEST #undef NO_ISLAND_LOADING - #define PC_PARTICLE - #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial #endif diff --git a/src/core/main.cpp b/src/core/main.cpp index 48e0ff76..85e04540 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -63,12 +63,15 @@ #include "timebars.h" #include "GenericGameStorage.h" #include "MemoryCard.h" +#include "MemoryHeap.h" #include "SceneEdit.h" #include "debugmenu.h" #include "Clock.h" #include "Occlusion.h" #include "Ropes.h" +#include "postfx.h" #include "custompipes.h" +#include "screendroplets.h" GlobalScene Scene; @@ -86,7 +89,7 @@ bool gbModelViewer; bool gbShowTimebars; #endif -int32 frameCount; +volatile int32 frameCount; RwRGBA gColourTop; @@ -107,8 +110,24 @@ void TheGame(void); void DebugMenuPopulate(void); #endif +#ifndef FINAL +bool gbPrintMemoryUsage; +#endif + +#ifdef GTA_PS2 +#define WANT_TO_LOAD TheMemoryCard.m_bWantToLoad +#define FOUND_GAME_TO_LOAD TheMemoryCard.b_FoundRecentSavedGameWantToLoad +#else +#define WANT_TO_LOAD FrontEndMenuManager.m_bWantToLoad +#define FOUND_GAME_TO_LOAD b_FoundRecentSavedGameWantToLoad +#endif + #ifdef NEW_RENDERER bool gbNewRenderer; +#endif +#ifdef FIX_BUGS +// need to clear stencil for mblur fx. no idea why it works in the original game +// also for clearing out water rects in new renderer #define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL) #else #define CLEARMODE (rwCAMERACLEARZ) @@ -389,21 +408,82 @@ PluginAttach(void) return TRUE; } +#ifdef GTA_PS2 +#define NUM_PREALLOC_ATOMICS 1800 +#define NUM_PREALLOC_CLUMPS 80 +#define NUM_PREALLOC_FRAMES 2600 +#define NUM_PREALLOC_GEOMETRIES 850 +#define NUM_PREALLOC_TEXDICTS 121 +#define NUM_PREALLOC_TEXTURES 1700 +#define NUM_PREALLOC_MATERIALS 2600 +bool preAlloc; + +void +PreAllocateRwObjects(void) +{ + int i; + + PUSH_MEMID(MEMID_PRE_ALLOC); + void **tmp = new void*[0x8000]; + preAlloc = true; + + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + tmp[i] = RpAtomicCreate(); + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + RpAtomicDestroy((RpAtomic*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + tmp[i] = RpClumpCreate(); + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + RpClumpDestroy((RpClump*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + tmp[i] = RwFrameCreate(); + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + RwFrameDestroy((RwFrame*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + tmp[i] = RpGeometryCreate(0, 0, 0); + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + RpGeometryDestroy((RpGeometry*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + tmp[i] = RwTexDictionaryCreate(); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTexDictionaryDestroy((RwTexDictionary*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXTURES; i++) + tmp[i] = RwTextureCreate(RwRasterCreate(0, 0, 0, 0)); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTextureDestroy((RwTexture*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + tmp[i] = RpMaterialCreate(); + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + RpMaterialDestroy((RpMaterial*)tmp[i]); + + delete[] tmp; + preAlloc = false; + POP_MEMID(); +} +#endif + static RwBool Initialise3D(void *param) { + PUSH_MEMID(MEMID_RENDER); + if (RsRwInitialize(param)) { + POP_MEMID(); + #ifdef DEBUGMENU DebugMenuInit(); DebugMenuPopulate(); #endif // !DEBUGMENU - bool ret = CGame::InitialiseRenderWare(); -#ifdef EXTENDED_PIPELINES - CustomPipes::CustomPipeInit(); // need Scene.world for this -#endif - return ret; + return CGame::InitialiseRenderWare(); } + POP_MEMID(); return (FALSE); } @@ -411,9 +491,6 @@ Initialise3D(void *param) static void Terminate3D(void) { -#ifdef EXTENDED_PIPELINES - CustomPipes::CustomPipeShutdown(); -#endif CGame::ShutdownRenderWare(); #ifdef DEBUGMENU DebugMenuShutdown(); @@ -591,8 +668,10 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) AsciiToUnicode(str1, tmpstr); CFont::PrintString(hpos, top, tmpstr); top += 22*yscale; - AsciiToUnicode(str2, tmpstr); - CFont::PrintString(hpos, top, tmpstr); + if (str2) { + AsciiToUnicode(str2, tmpstr); + CFont::PrintString(hpos, top, tmpstr); + } #endif } @@ -747,6 +826,185 @@ tZonePrint ZonePrint[] = }; #ifndef MASTER + +void +PrintMemoryUsage(void) +{ +// little hack +if(CPools::GetPtrNodePool() == nil) +return; + + // Style taken from LCS, modified for III +// CFont::SetFontStyle(FONT_PAGER); + CFont::SetFontStyle(FONT_BANK); + CFont::SetBackgroundOff(); + CFont::SetWrapx(640.0f); +// CFont::SetScale(0.5f, 0.75f); + CFont::SetScale(0.4f, 0.75f); + CFont::SetCentreOff(); + CFont::SetCentreSize(640.0f); + CFont::SetJustifyOff(); + CFont::SetPropOn(); + CFont::SetColor(CRGBA(200, 200, 200, 200)); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetDropShadowPosition(0); + + float y; + +#ifdef USE_CUSTOM_ALLOCATOR + y = 24.0f; + sprintf(gString, "Total: %d blocks, %d bytes", gMainHeap.m_totalBlocksUsed, gMainHeap.m_totalMemUsed); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Game: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME), gMainHeap.GetMemoryUsed(MEMID_GAME)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "World: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_WORLD), gMainHeap.GetMemoryUsed(MEMID_WORLD)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Render: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_RENDER), gMainHeap.GetMemoryUsed(MEMID_RENDER)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "PreAlloc: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PRE_ALLOC), gMainHeap.GetMemoryUsed(MEMID_PRE_ALLOC)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Default Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_DEF_MODELS), gMainHeap.GetMemoryUsed(MEMID_DEF_MODELS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_TEXTURES), gMainHeap.GetMemoryUsed(MEMID_TEXTURES)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streaming: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM), gMainHeap.GetMemoryUsed(MEMID_STREAM)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_MODELS), gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed LODs: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_LODS), gMainHeap.GetMemoryUsed(MEMID_STREAM_LODS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_TEXUTRES), gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_COLLISION), gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Streamed Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Ped Attr: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PED_ATTR), gMainHeap.GetMemoryUsed(MEMID_PED_ATTR)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_ANIMATION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Pools: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_POOLS), gMainHeap.GetMemoryUsed(MEMID_POOLS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_COLLISION), gMainHeap.GetMemoryUsed(MEMID_COLLISION)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Game Process: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME_PROCESS), gMainHeap.GetMemoryUsed(MEMID_GAME_PROCESS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Script: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_SCRIPT), gMainHeap.GetMemoryUsed(MEMID_SCRIPT)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Cars: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_CARS), gMainHeap.GetMemoryUsed(MEMID_CARS)); + AsciiToUnicode(gString, gUString); + CFont::PrintString(24.0f, y, gUString); + y += 12.0f; +#endif + + y = 132.0f; + AsciiToUnicode("Pools usage:", gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "PtrNode: %d/%d", CPools::GetPtrNodePool()->GetNoOfUsedSpaces(), CPools::GetPtrNodePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "EntryInfoNode: %d/%d", CPools::GetEntryInfoNodePool()->GetNoOfUsedSpaces(), CPools::GetEntryInfoNodePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Ped: %d/%d", CPools::GetPedPool()->GetNoOfUsedSpaces(), CPools::GetPedPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Vehicle: %d/%d", CPools::GetVehiclePool()->GetNoOfUsedSpaces(), CPools::GetVehiclePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Building: %d/%d", CPools::GetBuildingPool()->GetNoOfUsedSpaces(), CPools::GetBuildingPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Treadable: %d/%d", CPools::GetTreadablePool()->GetNoOfUsedSpaces(), CPools::GetTreadablePool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Object: %d/%d", CPools::GetObjectPool()->GetNoOfUsedSpaces(), CPools::GetObjectPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "Dummy: %d/%d", CPools::GetDummyPool()->GetNoOfUsedSpaces(), CPools::GetDummyPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; + + sprintf(gString, "AudioScriptObjects: %d/%d", CPools::GetAudioScriptObjectPool()->GetNoOfUsedSpaces(), CPools::GetAudioScriptObjectPool()->GetSize()); + AsciiToUnicode(gString, gUString); + CFont::PrintString(400.0f, y, gUString); + y += 12.0f; +} + void DisplayGameDebugText() { @@ -759,8 +1017,10 @@ DisplayGameDebugText() TWEAKBOOL(bDisplayPosn); TWEAKBOOL(bDisplayCheatStr); } -#endif + if(gbPrintMemoryUsage) + PrintMemoryUsage(); +#endif char str[200]; wchar ustr[200]; @@ -872,18 +1132,19 @@ void MattRenderScene(void) { // this calls CMattRenderer::Render - CWorld::AdvanceCurrentScanCode(); + /// CWorld::AdvanceCurrentScanCode(); // CMattRenderer::ResetRenderStates - CRenderer::ClearForFrame(); + /// CRenderer::ClearForFrame(); // before ConstructRenderList // CClock::CalcEnvMapTimeMultiplicator + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWaterLevel::RenderWater(); // actually CMattRenderer::RenderWater // CClock::ms_EnvMapTimeMultiplicator = 1.0f; // cWorldStream::ClearDynamics - CRenderer::ConstructRenderList(); + /// CRenderer::ConstructRenderList(); // before PreRender if(gbRenderWorld0) CRenderer::RenderWorld(0); // roads // CMattRenderer::ResetRenderStates - CRenderer::PreRender(); + /// CRenderer::PreRender(); // has to be called before BeginUpdate because of cutscene shadows CCoronas::RenderReflections(); if(gbRenderWorld1) CRenderer::RenderWorld(1); // opaque @@ -897,6 +1158,7 @@ if(gbRenderBoats) CRenderer::RenderBoats(); if(gbRenderFadingInUnderwaterEntities) CRenderer::RenderFadingInUnderwaterEntities(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); if(gbRenderWater) CRenderer::RenderTransparentWater(); @@ -920,8 +1182,7 @@ RenderScene_new(void) } // TODO -bool FredIsInFirstPersonCam(void) { return true; } // this seems to give the best result in all cases - +bool FredIsInFirstPersonCam(void) { return false; } void RenderEffects_new(void) { @@ -941,10 +1202,11 @@ if(gbRenderWorld2) if(gbRenderVehicles) CRenderer::RenderVehicles(); }else{ -if(gbRenderVehicles) - CRenderer::RenderVehicles(); + // flipped these two, seems to give the best result if(gbRenderWorld2) CRenderer::RenderWorld(2); // transparent +if(gbRenderVehicles) + CRenderer::RenderVehicles(); } // better render these after transparent world if(gbRenderFadingInEntities) @@ -1090,9 +1352,11 @@ Render2dStuff(void) MusicManager.DisplayRadioStationName(); TheConsole.Display(); +#ifdef GTA_SCENE_EDIT if(CSceneEdit::m_bEditOn) CSceneEdit::Draw(); else +#endif CHud::Draw(); CSpecialFX::Render2DFXs(); @@ -1116,13 +1380,7 @@ RenderMenus(void) { if (FrontEndMenuManager.m_bMenuActive) { -#ifdef PS2 - gMainHeap.PushMemId(_TODOCONST(17)); -#endif FrontEndMenuManager.DrawFrontEnd(); -#ifdef PS2 - gMainHeap.PopMemId(); -#endif } } @@ -1162,21 +1420,12 @@ Idle(void *arg) tbEndTimer("DMAudio.Service"); if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){ -#ifdef PS2_MENU - TheMemoryCard.m_bWantToLoad = false; - FrontEndMenuManager.m_bWantToRestart = true; -#else + WANT_TO_LOAD = false; FrontEndMenuManager.m_bWantToRestart = true; - FrontEndMenuManager.m_bWantToLoad = false; -#endif return; } -#ifdef PS2_MENU - if ( FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad ) -#else - if(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad) -#endif + if(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD) { return; } @@ -1188,28 +1437,30 @@ Idle(void *arg) if(!FrontEndMenuManager.m_bMenuActive && TheCamera.GetScreenFadeStatus() != FADE_2) { -#ifdef GTA_PC - // This is from SA, but it's nice for windowed mode - RwV2d pos; - pos.x = SCREEN_WIDTH / 2.0f; - pos.y = SCREEN_HEIGHT / 2.0f; - RsMouseSetPos(&pos); + // This is from SA, but it's nice for windowed mode +#if defined(GTA_PC) && !defined(RW_GL3) + RwV2d pos; + pos.x = SCREEN_WIDTH / 2.0f; + pos.y = SCREEN_HEIGHT / 2.0f; + RsMouseSetPos(&pos); #endif -#ifdef NEW_RENDERER - if(!gbNewRenderer) -#endif -{ + tbStartTimer(0, "CnstrRenderList"); #ifdef PC_WATER CWaterLevel::PreCalcWaterGeometry(); #endif +#ifdef NEW_RENDERER + if(gbNewRenderer){ + CWorld::AdvanceCurrentScanCode(); // don't think this is even necessary + CRenderer::ClearForFrame(); + } +#endif CRenderer::ConstructRenderList(); tbEndTimer("CnstrRenderList"); tbStartTimer(0, "PreRender"); CRenderer::PreRender(); tbEndTimer("PreRender"); -} #ifdef FIX_BUGS RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); // TODO: temp? this fixes OpenGL render but there should be a better place for this @@ -1220,12 +1471,12 @@ Idle(void *arg) if(CWeather::LightningFlash && !CCullZones::CamNoRain()){ if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255)) - return; + goto popret; }else{ if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255)) - return; + goto popret; } DefinedState(); @@ -1246,10 +1497,17 @@ Idle(void *arg) RenderDebugShit(); RenderEffects(); - tbStartTimer(0, "RenderMotionBlur"); if((TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE) && TheCamera.m_ScreenReductionPercentage > 0.0f) TheCamera.SetMotionBlurAlpha(150); + +#ifdef SCREEN_DROPLETS + CPostFX::GetBackBuffer(Scene.camera); + ScreenDroplets::Process(); + ScreenDroplets::Render(); +#endif + + tbStartTimer(0, "RenderMotionBlur"); TheCamera.RenderMotionBlur(); tbEndTimer("RenderMotionBlur"); @@ -1266,7 +1524,7 @@ Idle(void *arg) CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); if(!RsCameraBeginUpdate(Scene.camera)) - return; + goto popret; } tbStartTimer(0, "RenderMenus"); @@ -1275,7 +1533,7 @@ Idle(void *arg) #ifdef PS2_MENU if ( TheMemoryCard.m_bWantToLoad ) - return; + goto popret; #endif tbStartTimer(0, "DoFade"); @@ -1286,15 +1544,22 @@ Idle(void *arg) Render2dStuffAfterFade(); tbEndTimer("Render2dStuff-Fade"); // CCredits::Render(); // They added it to function above and also forgot it here - +#ifdef XBOX_MESSAGE_SCREEN + FrontEndMenuManager.DrawOverlays(); +#endif if (gbShowTimebars) tbDisplay(); DoRWStuffEndOfFrame(); + POP_MEMID(); // MEMID_RENDER + if(g_SlowMode) ProcessSlowMode(); + return; + +popret: POP_MEMID(); // MEMID_RENDER } void @@ -1319,6 +1584,9 @@ FrontendIdle(void) DefinedState(); // seems redundant, but breaks resolution change. RenderMenus(); +#ifdef XBOX_MESSAGE_SCREEN + FrontEndMenuManager.DrawOverlays(); +#endif DoFade(); Render2dStuffAfterFade(); CFont::DrawFonts(); @@ -1404,15 +1672,6 @@ AppEventHandler(RsEvent event, void *param) return rsEVENTPROCESSED; } -#ifndef MASTER - case rsANIMVIEWER: - { - TheModelViewer(); - - return rsEVENTPROCESSED; - } -#endif - default: { return rsEVENTNOTPROCESSED; @@ -1428,48 +1687,49 @@ TheModelViewer(void) //TODO #else - CDraw::CalculateAspectRatio(); + // This is not original. Because; + // 1- We want 2D things to be initalized, whereas original AnimViewer doesn't use them. my additions marked with X + // 2- VC Mobile code run it like main function(as opposed to III and LCS), so it has it's own loop inside it, but our func. already called in a loop. + + CDraw::CalculateAspectRatio(); // X CAnimViewer::Update(); - CTimer::Update(); SetLightsWithTimeOfDayColour(Scene.world); CRenderer::ConstructRenderList(); DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed()*0.5f, CTimeCycle::GetSkyTopGreen()*0.5f, CTimeCycle::GetSkyTopBlue()*0.5f, CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255); - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); + CSprite2d::SetRecipNearClip(); // X + CSprite2d::InitPerFrame(); // X + CFont::InitPerFrame(); // X DefinedState(); CVisibilityPlugins::InitAlphaEntityList(); CAnimViewer::Render(); - Render2dStuff(); + Render2dStuff(); // X DoRWStuffEndOfFrame(); + CTimer::Update(); #endif } #endif -#ifdef PS2 + +#ifdef GTA_PS2 void TheGame(void) { printf("Into TheGame!!!\n"); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(1)); -#endif + PUSH_MEMID(MEMID_GAME); // NB: not popped CTimer::Initialise(); -#ifdef GTA_PS2 - CGame::Initialise(); -#else CGame::Initialise("DATA\\GTA3.DAT"); -#endif Const char *splash = GetRandomSplashScreen(); // inlined here LoadingScreen("Starting Game", NULL, splash); #ifdef GTA_PS2 + // TODO(MIAMI): not checked yet if ( TheMemoryCard.CheckCardInserted(CARD_ONE) == CMemoryCard::NO_ERR_SUCCESS && TheMemoryCard.ChangeDirectory(CARD_ONE, TheMemoryCard.Cards[CARD_ONE].dir) && TheMemoryCard.FindMostRecentFileName(CARD_ONE, TheMemoryCard.MostRecentFile) == true @@ -1493,77 +1753,53 @@ void TheGame(void) while (true) { -#ifdef PS2 - if (TheMemoryCard.m_bWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToLoad) -#endif + if (FOUND_GAME_TO_LOAD) { Const char *splash1 = GetLevelSplashScreen(CGame::currLevel); LoadSplash(splash1); } -#ifdef PS2 - TheMemoryCard.m_bWantToLoad = false; -#else - FrontEndMenuManager.m_bWantToLoad = false; -#endif + WANT_TO_LOAD = false; CTimer::Update(); -#ifdef PS2 - while (!(FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)) -#else - while (!(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)) -#endif + while (!(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)) { CSprite2d::InitPerFrame(); CFont::InitPerFrame(); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(12)); -#endif - CPointLights::NumLights = 0; + PUSH_MEMID(MEMID_GAME_PROCESS) + CPointLights::InitPerFrame(); CGame::Process(); -#ifdef GTA_PS2 - gMainHeap.PopMemId(); -#endif + POP_MEMID(); DMAudio.Service(); if (CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()) { -#ifdef PS2 - TheMemoryCard.m_bWantToLoad = false; -#else - FrontEndMenuManager.m_bWantToLoad = false; -#endif + WANT_TO_LOAD = false; FrontEndMenuManager.m_bWantToRestart = true; break; } -#ifdef PS2 - if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad) -#endif + if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD) break; SetLightsWithTimeOfDayColour(Scene.world); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(15)); -#endif - // m_bRenderGameInMenu is there in III PS2 but I don't know about VC PS2. - if (!FrontEndMenuManager.m_bMenuActive || /*FrontEndMenuManager.m_bRenderGameInMenu == true && */TheCamera.GetScreenFadeStatus() != FADE_2 ) + PUSH_MEMID(MEMID_RENDER); + + CRenderer::ConstructRenderList(); + + if ((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true) && TheCamera.GetScreenFadeStatus() != FADE_2 ) { -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(11)); -#endif - CRenderer::ConstructRenderList(); CRenderer::PreRender(); -#ifdef GTA_PS2 - gMainHeap.PopMemId(); + // TODO(MIAMI): something ps2all specific + +#ifdef FIX_BUGS + // This has to be done BEFORE RwCameraBeginUpdate + RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); + RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); #endif if (CWeather::LightningFlash && !CCullZones::CamNoRain()) @@ -1572,8 +1808,10 @@ void TheGame(void) DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255); DefinedState(); +#ifndef FIX_BUGS RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); +#endif RenderScene(); RenderDebugShit(); @@ -1590,21 +1828,14 @@ void TheGame(void) CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); - if (!RsCameraBeginUpdate(Scene.camera)) - break; + RsCameraBeginUpdate(Scene.camera); } RenderMenus(); -#ifdef PS2 - if (TheMemoryCard.m_bWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToLoad) -#endif + if (WANT_TO_LOAD) { -#ifdef GTA_PS2 - gMainHeap.PopMemId(); -#endif + POP_MEMID(); // MEMID_RENDER break; } @@ -1621,9 +1852,7 @@ void TheGame(void) CTimer::Update(); -#ifdef GTA_PS2 - gMainHeap.PopMemId(); -#endif + POP_MEMID(): // MEMID_RENDER if (g_SlowMode) ProcessSlowMode(); @@ -1635,24 +1864,12 @@ void TheGame(void) CGame::ShutDownForRestart(); CTimer::Stop(); -#ifdef PS2 - if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad) -#else - if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad) -#endif + if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD) { -#ifdef PS2 - if (TheMemoryCard.b_FoundRecentSavedGameWantToLoad) -#else - if (b_FoundRecentSavedGameWantToLoad) -#endif + if (FOUND_GAME_TO_LOAD) { FrontEndMenuManager.m_bWantToRestart = true; -#ifdef PS2 - TheMemoryCard.m_bWantToLoad = true; -#else - FrontEndMenuManager.m_bWantToLoad = true; -#endif + WANT_TO_LOAD = true; } CGame::InitialiseWhenRestarting(); @@ -1671,11 +1888,7 @@ void TheGame(void) void SystemInit() { -#ifdef __MWERKS__ - mwInit(); -#endif - -#ifdef GTA_PS2 +#ifdef USE_CUSTOM_ALLOCATOR InitMemoryMgr(); #endif @@ -1684,7 +1897,7 @@ void SystemInit() char path[256]; - sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP23.IMG"); + sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP241.IMG"); sceSifInitRpc(0); @@ -1698,14 +1911,10 @@ void SystemInit() CFileMgr::InitCdSystem(); sceFsReset(); -#endif - CFileMgr::Initialise(); - -#ifdef GTA_PS2 CFileMgr::InitCd(); - Char modulepath[256]; + char modulepath[256]; strcpy(modulepath, "cdrom0:\\"); strcat(modulepath, "SYSTEM\\"); @@ -1736,6 +1945,16 @@ void SystemInit() strcat(modulepath, "SYSTEM\\"); strcat(modulepath, "MCSERV.IRX"); LoadModule(modulepath); + + strcpy(modulepath, "cdrom0:\\"); + strcat(modulepath, "SYSTEM\\"); + strcat(modulepath, "CDSTREAM.IRX"); + LoadModule(modulepath); + + strcpy(modulepath, "cdrom0:\\"); + strcat(modulepath, "SYSTEM\\"); + strcat(modulepath, "SAMPMAN2.IRX"); + LoadModule(modulepath); #endif @@ -1765,6 +1984,7 @@ void SystemInit() FrontEndMenuManager.m_PrefsAllowNastyGame = true; #ifdef GTA_PS2 + // TODO(MIAMI): this code probably went elsewhere? int32 lang = sceScfGetLanguage(); if ( lang == SCE_ITALIAN_LANGUAGE ) FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN; @@ -1792,59 +2012,160 @@ void SystemInit() // #endif -#ifdef PS2 +#ifdef GTA_PS2 TheMemoryCard.Init(); #endif } -void GameInit() +int VBlankCounter(int ca) +{ + frameCount++; + ExitHandler(); + return 0; +} + +// linked against by RW! +extern "C" void WaitVBlank(void) +{ + int32 startFrame = frameCount; + while(startFrame == frameCount); +} + +void GameInit(bool onlyRW) { - if ( !gameAlreadyInitialised ) + if(onlyRW) { #ifdef GTA_PS2 - char path[256]; - - strcpy(path, "cdrom0:\\"); - strcat(path, "SYSTEM\\"); - strcat(path, "CDSTREAM.IRX"); - LoadModule(path); - - strcpy(path, "cdrom0:\\"); - strcat(path, "SYSTEM\\"); - strcat(path, "SAMPMAN.IRX"); - LoadModule(path); - - strcpy(path, "cdrom0:\\"); - strcat(path, "SYSTEM\\"); - strcat(path, "MUSICSTR.IRX"); - LoadModule(path); + Initialise3D(nil); +#else + Initialise3D(nil); //TODO: window parameter #endif - CdStreamInit(MAX_CDCHANNELS); - -#ifdef PS2 - Initialise3D(); //no params + gameAlreadyInitialised = true; + } + else + { + if ( !gameAlreadyInitialised ) +#ifdef GTA_PS2 + Initialise3D(nil); #else - //TODO + Initialise3D(nil); //TODO: window parameter #endif - + } + #ifdef GTA_PS2 char *files[] = { "\\ANIM\\CUTS.IMG;1", "\\ANIM\\CUTS.DIR;1", "\\ANIM\\PED.IFP;1", - "\\MODELS\\FRONTEND.TXD;1", + "\\MODELS\\FRONTEN1.TXD;1", + "\\MODELS\\FRONTEN2.TXD;1", "\\MODELS\\FONTS.TXD;1", "\\MODELS\\HUD.TXD;1", "\\MODELS\\PARTICLE.TXD;1", "\\MODELS\\MISC.TXD;1", "\\MODELS\\GENERIC.TXD;1", "\\MODELS\\GTA3.DIR;1", + // TODO: japanese? +#ifdef GTA_PAL "\\TEXT\\ENGLISH.GXT;1", "\\TEXT\\FRENCH.GXT;1", "\\TEXT\\GERMAN.GXT;1", "\\TEXT\\ITALIAN.GXT;1", "\\TEXT\\SPANISH.GXT;1", +#else + "\\TEXT\\AMERICAN.GXT;1", +#endif + "\\MODELS\\COLL\\GENERIC.COL;1", + "\\MODELS\\COLL\\VEHICLES.COL;1", + "\\MODELS\\COLL\\PEDS.COL;1", + "\\MODELS\\COLL\\WEAPONS.COL;1", + "\\MODELS\\GENERIC\\AIR_VLO.DFF;1", + "\\MODELS\\GENERIC\\WHEELS.DFF;1", + "\\MODELS\\GENERIC\\ARROW.DFF;1", + "\\MODELS\\GENERIC\\ZONECYLB.DFF;1", + "\\DATA\\HANDLING.CFG;1", + "\\DATA\\SURFACE.DAT;1", + "\\DATA\\PEDSTATS.DAT;1", + "\\DATA\\TIMECYC.DAT;1", + "\\DATA\\PARTICLE.CFG;1", + "\\DATA\\DEFAULT.DAT;1", + "\\DATA\\DEFAULT.IDE;1", + "\\DATA\\GTA_VC.DAT;1", + "\\DATA\\OBJECT.DAT;1", + "\\DATA\\MAP.ZON;1", + "\\DATA\\NAVIG.ZON;1", + "\\DATA\\INFO.ZON;1", + "\\DATA\\WATERPRO.DAT;1", + "\\DATA\\MAIN.SCM;1", + "\\DATA\\CARCOLS.DAT;1", + "\\DATA\\PED.DAT;1", + "\\DATA\\FISTFITE.DAT;1", + "\\DATA\\WEAPON.DAT;1", + "\\DATA\\PEDGRP.DAT;1", + "\\DATA\\PATHS\\FLIGHT.DAT;1", + "\\DATA\\PATHS\\FLIGHT2.DAT;1", + "\\DATA\\PATHS\\FLIGHT3.DAT;1", + "\\DATA\\PATHS\\SPATH0.DAT;1", + "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IDE;1", + "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IDE;1", + "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IDE;1", + "\\DATA\\MAPS\\DOCKS\\DOCKS.IDE;1", + "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IDE;1", + "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IDE;1", + "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IDE;1", + "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IDE;1", + "\\DATA\\MAPS\\GOLF\\GOLF.IDE;1", + "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IDE;1", + "\\DATA\\MAPS\\STARISL\\STARISL.IDE;1", + "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IDE;1", + "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IDE;1", + "\\DATA\\MAPS\\NBEACH\\NBEACH.IDE;1", + "\\DATA\\MAPS\\BANK\\BANK.IDE;1", + "\\DATA\\MAPS\\MALL\\MALL.IDE;1", + "\\DATA\\MAPS\\YACHT\\YACHT.IDE;1", + "\\DATA\\MAPS\\CISLAND\\CISLAND.IDE;1", + "\\DATA\\MAPS\\CLUB\\CLUB.IDE;1", + "\\DATA\\MAPS\\HOTEL\\HOTEL.IDE;1", + "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IDE;1", + "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IDE;1", + "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IDE;1", + "\\DATA\\MAPS\\HAITI\\HAITI.IDE;1", + "\\DATA\\MAPS\\HAITIN\\HAITIN.IDE;1", + "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IDE;1", + "\\DATA\\MAPS\\MANSION\\MANSION.IDE;1", + "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IDE;1", + "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IPL;1", + "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IPL;1", + "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IPL;1", + "\\DATA\\MAPS\\DOCKS\\DOCKS.IPL;1", + "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IPL;1", + "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IPL;1", + "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IPL;1", + "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IPL;1", + "\\DATA\\MAPS\\GOLF\\GOLF.IPL;1", + "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IPL;1", + "\\DATA\\MAPS\\STARISL\\STARISL.IPL;1", + "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IPL;1", + "\\DATA\\MAPS\\NBEACH\\NBEACH.IPL;1", + "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IPL;1", + "\\DATA\\MAPS\\CISLAND\\CISLAND.IPL;1", + "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IPL;1", + "\\DATA\\MAPS\\HAITI\\HAITI.IPL;1", + "\\DATA\\MAPS\\HAITIN\\HAITIN.IPL;1", + "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IPL;1", + "\\DATA\\MAPS\\BANK\\BANK.IPL;1", + "\\DATA\\MAPS\\MALL\\MALL.IPL;1", + "\\DATA\\MAPS\\YACHT\\YACHT.IPL;1", + "\\DATA\\MAPS\\CLUB\\CLUB.IPL;1", + "\\DATA\\MAPS\\HOTEL\\HOTEL.IPL;1", + "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IPL;1", + "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IPL;1", + "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IPL;1", + "\\DATA\\MAPS\\MANSION\\MANSION.IPL;1", + "\\DATA\\MAPS\\GENERIC.IDE;1", + "\\DATA\\OCCLU.IPL;1", + "\\DATA\\MAPS\\PATHS.IPL;1", "\\TXD\\LOADSC0.TXD;1", "\\TXD\\LOADSC1.TXD;1", "\\TXD\\LOADSC2.TXD;1", @@ -1859,93 +2180,17 @@ void GameInit() "\\TXD\\LOADSC11.TXD;1", "\\TXD\\LOADSC12.TXD;1", "\\TXD\\LOADSC13.TXD;1", - "\\TXD\\LOADSC14.TXD;1", - "\\TXD\\LOADSC15.TXD;1", - "\\TXD\\LOADSC16.TXD;1", - "\\TXD\\LOADSC17.TXD;1", - "\\TXD\\LOADSC18.TXD;1", - "\\TXD\\LOADSC19.TXD;1", - "\\TXD\\LOADSC20.TXD;1", - "\\TXD\\LOADSC21.TXD;1", - "\\TXD\\LOADSC22.TXD;1", - "\\TXD\\LOADSC23.TXD;1", - "\\TXD\\LOADSC24.TXD;1", - "\\TXD\\LOADSC25.TXD;1", - "\\TXD\\NEWS.TXD;1", - "\\MODELS\\COLL\\GENERIC.COL;1", - "\\MODELS\\COLL\\INDUST.COL;1", - "\\MODELS\\COLL\\COMMER.COL;1", - "\\MODELS\\COLL\\SUBURB.COL;1", - "\\MODELS\\COLL\\WEAPONS.COL;1", - "\\MODELS\\COLL\\VEHICLES.COL;1", - "\\MODELS\\COLL\\PEDS.COL;1", - "\\MODELS\\GENERIC\\AIR_VLO.DFF;1", - "\\MODELS\\GENERIC\\WEAPONS.DFF;1", - "\\MODELS\\GENERIC\\WHEELS.DFF;1", - "\\MODELS\\GENERIC\\LOPLYGUY.DFF;1", - "\\MODELS\\GENERIC\\ARROW.DFF;1", - "\\MODELS\\GENERIC\\ZONECYLB.DFF;1", - "\\DATA\\MAPS\\COMNTOP.IPL;1", - "\\DATA\\MAPS\\COMNBTM.IPL;1", - "\\DATA\\MAPS\\COMSE.IPL;1", - "\\DATA\\MAPS\\COMSW.IPL;1", - "\\DATA\\MAPS\\CULL.IPL;1", - "\\DATA\\MAPS\\INDUSTNE.IPL;1", - "\\DATA\\MAPS\\INDUSTNW.IPL;1", - "\\DATA\\MAPS\\INDUSTSE.IPL;1", - "\\DATA\\MAPS\\INDUSTSW.IPL;1", - "\\DATA\\MAPS\\SUBURBNE.IPL;1", - "\\DATA\\MAPS\\SUBURBSW.IPL;1", - "\\DATA\\MAPS\\OVERVIEW.IPL;1", - "\\DATA\\MAPS\\PROPS.IPL;1", - "\\DATA\\MAPS\\GTA3.IDE;1", - "\\DATA\\PATHS\\FLIGHT.DAT;1", - "\\DATA\\PATHS\\FLIGHT2.DAT;1", - "\\DATA\\PATHS\\FLIGHT3.DAT;1", - "\\DATA\\PATHS\\FLIGHT4.DAT;1", - "\\DATA\\PATHS\\TRACKS.DAT;1", - "\\DATA\\PATHS\\TRACKS2.DAT;1", - "\\DATA\\PATHS\\CHASE0.DAT;1", - "\\DATA\\PATHS\\CHASE1.DAT;1", - "\\DATA\\PATHS\\CHASE2.DAT;1", - "\\DATA\\PATHS\\CHASE3.DAT;1", - "\\DATA\\PATHS\\CHASE4.DAT;1", - "\\DATA\\PATHS\\CHASE5.DAT;1", - "\\DATA\\PATHS\\CHASE6.DAT;1", - "\\DATA\\PATHS\\CHASE7.DAT;1", - "\\DATA\\PATHS\\CHASE10.DAT;1", - "\\DATA\\PATHS\\CHASE11.DAT;1", - "\\DATA\\PATHS\\CHASE14.DAT;1", - "\\DATA\\PATHS\\CHASE16.DAT;1", - "\\DATA\\PATHS\\CHASE18.DAT;1", - "\\DATA\\PATHS\\CHASE19.DAT;1" + "\\TXD\\SPLASH1.TXD;1" }; for ( int32 i = 0; i < ARRAY_SIZE(files); i++ ) SkyRegisterFileOnCd([i]); #endif - CreateDebugFont(); - #ifdef GTA_PS2 - AddIntcHandler(_TODOCONST(2), VBlankCounter, 0); + AddIntcHandler(INTC_VBLANK_S, VBlankCounter, 0); #endif - CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO); - - CSprite2d::SetRecipNearClip(); - CTxdStore::Initialise(); -#ifdef GTA_PS2 - gMainHeap.PushMemId(_TODOCONST(9)); -#endif - CFont::Initialise(); - CHud::Initialise(); -#ifdef GTA_PS2 - gMainHeap.PopMemId(); -#endif - - ValidateVersion(); - #ifdef GTA_PS2 sceCdCLOCK rtc; sceCdReadClock(&rtc); @@ -1957,8 +2202,57 @@ void GameInit() //TODO: mysrand(); #endif - gameAlreadyInitialised = true; + // gameAlreadyInitialised = true; // why is this gone? + } +} + +int32 SkipAllMPEGs; +int32 gMemoryStickLoadOK; + +void PlayIntroMPEGs() +{ +#ifdef GTA_PS2 + if (gameAlreadyInitialised) + RpSkySuspend(); + + InitMPEGPlayer(); + + float skipTime; // wrong type, should be int +#ifdef GTA_PAL + if(gMemoryStickLoadOK) + skipTime = 2500000; + else + skipTime = 5300000; + + if(!SkipAllMPEGs) + PlayMPEG("cdrom0:\\MOVIES\\VCPAL.PSS;1", false, unk); + + if(!SkipAllMPEGs){ + SkipAllMPEGs = true; + PlayMPEG("cdrom0:\\MOVIES\\VICEPAL.PSS;1", true, 0); + } +#else + if(gMemoryStickLoadOK) + skipTime = 2750000; + else + skipTime = 5500000; + + if(!SkipAllMPEGs) + PlayMPEG("cdrom0:\\MOVIES\\VCNTSC.PSS;1", false, unk); + + if(!SkipAllMPEGs){ + SkipAllMPEGs = true; + PlayMPEG("cdrom0:\\MOVIES\\VICE.PSS;1", true, 0); } +#endif + + ShutdownMPEGPlayer(); + + if ( gameAlreadyInitialised ) + RpSkyResume(); +#else + //TODO +#endif } int @@ -1969,14 +2263,16 @@ main(int argc, char *argv[]) #endif SystemInit(); - -#ifdef PS2 + + if(RsEventHandler(rsINITIALIZE, nil) == rsEVENTERROR) + return 0; + +#ifdef GTA_PS2 int32 r = TheMemoryCard.CheckCardStateAtGameStartUp(CARD_ONE); - if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT - && r != CMemoryCard::ERR_OPENNOENTRY && r != CMemoryCard::ERR_NONE ) + if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT ) { - GameInit(); + GameInit(true); TheText.Unload(); TheText.Load(); @@ -1984,43 +2280,24 @@ main(int argc, char *argv[]) CFont::Initialise(); FrontEndMenuManager.DrawMemoryCardStartUpMenus(); - } + }else if(r == CMemoryCard::ERR_OPENNOENTRY) + gMemoryStickLoadOK = false; + else if(r == CMemoryCard::ERR_NONE) + gMemoryStickLoadOK = true; #endif - -#ifdef GTA_PS2 - { - if (gameAlreadyInitialised) - RpSkySuspend(); - - InitMPEGPlayer(); - - PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false); - if (CGame::frenchGame || CGame::germanGame) - PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true); - else - PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true); + PlayIntroMPEGs(); - ShutdownMPEGPlayer(); + GameInit(false); - if ( gameAlreadyInitialised ) - RpSkyResume(); - } -#else - //TODO -#endif + frameCount = 0; + while(frameCount < 100); - GameInit(); + CGame::InitialiseOnceAfterRW(); - if ( CGame::frenchGame || CGame::germanGame ) - LoadingScreen(NULL, version_name, "loadsc24"); - else - LoadingScreen(NULL, version_name, "loadsc0"); - - DMAudio.Initialise(); - TheGame(); - + +#if 0 // maybe ifndef FINAL or MASTER? CGame::ShutDown(); RwEngineStop(); @@ -2030,7 +2307,7 @@ main(int argc, char *argv[]) #ifdef __MWERKS__ mwExit(); // metrowerks shutdown #endif - +#endif return 0; } #endif diff --git a/src/core/main.h b/src/core/main.h index f428224e..37a82fb2 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -20,11 +20,16 @@ extern bool gbShowTimebars; #define gbShowTimebars false #endif +#ifndef FINAL +extern bool gbPrintMemoryUsage; +#endif + class CSprite2d; bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); +void PreAllocateRwObjects(void); void InitialiseGame(void); void LoadingScreen(const char *str1, const char *str2, const char *splashscreen); void LoadingIslandScreen(const char *levelName); @@ -39,6 +44,11 @@ void ResetLoadingScreenBar(void); void TheModelViewer(void); #endif +#ifdef LOAD_INI_SETTINGS +void LoadINISettings(); +void SaveINISettings(); +#endif + #ifdef NEW_RENDERER extern bool gbNewRenderer; bool FredIsInFirstPersonCam(void); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index ebfa8de5..5e3d8922 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -13,13 +13,10 @@ #include "Vehicle.h" #include "ModelIndices.h" #include "Streaming.h" -#include "PathFind.h" #include "Boat.h" #include "Heli.h" #include "Automobile.h" #include "Bike.h" -#include "Ped.h" -#include "Particle.h" #include "Console.h" #include "Debug.h" #include "Hud.h" @@ -29,13 +26,18 @@ #include "Radar.h" #include "debugmenu.h" #include "Frontend.h" -#include "Text.h" #include "WaterLevel.h" #include "main.h" #include "Script.h" #include "MBlur.h" #include "postfx.h" #include "custompipes.h" +#include "MemoryHeap.h" +#include "FileMgr.h" + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +#include "ControllerConfig.h" +#endif #ifndef _WIN32 #include "assert.h" @@ -75,6 +77,195 @@ mysrand(unsigned int seed) myrand_seed = seed; } +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "frontendoption.h" + +void +CustomFrontendOptionsPopulate(void) +{ + // Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h + + // These work only if we have neo folder, so they're dynamically added +#ifdef EXTENDED_PIPELINES + const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" }; + const char *off_on[] = { "FEM_OFF", "FEM_ON" }; + int fd = CFileMgr::OpenFile("neo/neo.txd","r"); + if (fd) { +#ifdef GRAPHICS_MENU_OPTIONS + FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false); + FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline"); + FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight"); + FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps"); + FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss"); +#else + FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false); + FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline"); + FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight"); + FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps"); + FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss"); +#endif + CFileMgr::CloseFile(fd); + } +#endif + +} +#endif + +#ifdef LOAD_INI_SETTINGS +#include "ini_parser.hpp" + +linb::ini cfg; +int CheckAndReadIniInt(const char *cat, const char *key, int original) +{ + std::string strval = cfg.get(cat, key, ""); + const char *value = strval.c_str(); + if (value && value[0] != '\0') + return atoi(value); + + return original; +} + +float CheckAndReadIniFloat(const char *cat, const char *key, float original) +{ + std::string strval = cfg.get(cat, key, ""); + const char *value = strval.c_str(); + if (value && value[0] != '\0') + return atof(value); + + return original; +} + +void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed) +{ + char temp[10]; + if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it + changed = true; + sprintf(temp, "%u", val); + cfg.set(cat, key, temp); + } +} + +void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed) +{ + char temp[10]; + if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it + changed = true; + sprintf(temp, "%f", val); + cfg.set(cat, key, temp); + } +} + +void LoadINISettings() +{ + cfg.load_file("reVC.ini"); + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + // Written by assuming the codes below will run after _InputInitialiseJoys(). + strcpy(gSelectedJoystickName, cfg.get("DetectJoystick", "JoystickName", "").c_str()); + + if(gSelectedJoystickName[0] != '\0') { + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { + if (glfwJoystickPresent(i) && strncmp(gSelectedJoystickName, glfwGetJoystickName(i), strlen(gSelectedJoystickName)) == 0) { + if (PSGLOBAL(joy1id) != -1) { + PSGLOBAL(joy2id) = PSGLOBAL(joy1id); + } + PSGLOBAL(joy1id) = i; + int count; + glfwGetJoystickButtons(PSGLOBAL(joy1id), &count); + + // We need to init and reload bindings, because; + // 1-joypad button number may differ with saved/prvly connected one + // 2-bindings are not init'ed if there is no joypad at the start + ControlsManager.InitDefaultControlConfigJoyPad(count); + CFileMgr::SetDirMyDocuments(); + int32 gta3set = CFileMgr::OpenFile("gta3.set", "r"); + if (gta3set) { + ControlsManager.LoadSettings(gta3set); + CFileMgr::CloseFile(gta3set); + } + CFileMgr::SetDir(""); + break; + } + } + } +#endif + +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < MENUPAGES; i++) { + for (int j = 0; j < NUM_MENUROWS; j++) { + CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; + if (option.m_Action == MENUACTION_NOTHING) + break; + + // CFO check + if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { + // CFO only supports saving uint8 right now + *option.m_CFO->value = CheckAndReadIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value); + if (option.m_Action == MENUACTION_CFO_SELECT) { + option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value; + } + } + } + } +#endif + +#ifdef EXTENDED_COLOURFILTER + CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity); +#endif +#ifdef EXTENDED_PIPELINES + CustomPipes::VehicleShininess = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess); + CustomPipes::VehicleSpecularity = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity); + CustomPipes::RimlightMult = CheckAndReadIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult); + CustomPipes::LightmapMult = CheckAndReadIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult); + CustomPipes::GlossMult = CheckAndReadIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult); +#endif + gBackfaceCulling = CheckAndReadIniInt("Rendering", "BackfaceCulling", gBackfaceCulling); +} + +void SaveINISettings() +{ + bool changed = false; + char temp[4]; + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) { + changed = true; + cfg.set("DetectJoystick", "JoystickName", gSelectedJoystickName); + } +#endif +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < MENUPAGES; i++) { + for (int j = 0; j < NUM_MENUROWS; j++) { + CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; + if (option.m_Action == MENUACTION_NOTHING) + break; + + if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { + // Beware: CFO only supports saving uint8 right now + CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed); + } + } + } +#endif + +#ifdef EXTENDED_COLOURFILTER + CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed); +#endif +#ifdef EXTENDED_PIPELINES + CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed); + CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed); + CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed); + CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed); + CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed); +#endif + CheckAndSaveIniInt("Rendering", "BackfaceCulling", gBackfaceCulling, changed); + + if (changed) + cfg.write_file("reVC.ini"); +} + +#endif + #ifdef DEBUGMENU void WeaponCheat1(); void WeaponCheat2(); @@ -256,7 +447,7 @@ void CTweakVars::Add(CTweakVar *var) TweakVarsListSize = 0; } if(TweakVarsListSize > 63) - TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(var)); + TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(*var)); TweakVarsList[TweakVarsListSize++] = var; // TweakVarsList.push_back(var); @@ -484,8 +675,17 @@ extern bool gbRenderWorld2; DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil); DebugMenuAddVarBool8("Render", "Don't Render Water", &gbDontRenderWater, nil); +#ifndef FINAL + DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil); +#ifdef USE_CUSTOM_ALLOCATOR + DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap); +#endif +#endif + DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil); +#ifdef GTA_SCENE_EDIT DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil); +#endif #ifdef MAP_ENHANCEMENTS DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint); #endif diff --git a/src/core/templates.h b/src/core/templates.h index 9f5bd5ea..19881219 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -1,31 +1,31 @@ #pragma once -template<typename T, int n> +template<typename T, int32 n> class CStore { public: - int allocPtr; + int32 allocPtr; T store[n]; - T *alloc(void){ - if(this->allocPtr >= n){ + T *Alloc(void){ + if(allocPtr >= n){ printf("Size of this thing:%d needs increasing\n", n); assert(0); } - return &this->store[this->allocPtr++]; + return &store[allocPtr++]; } - void clear(void){ - this->allocPtr = 0; + void Clear(void){ + allocPtr = 0; } - int getIndex(T *item){ - assert(item >= &this->store[0]); - assert(item < &this->store[n]); - return item - this->store; + int32 GetIndex(T *item){ + assert(item >= &store[0]); + assert(item < &store[n]); + return item - store; } - T *getItem(int index){ + T *GetItem(int32 index){ assert(index >= 0); assert(index < n); - return &this->store[index]; + return &store[index]; } }; @@ -40,15 +40,13 @@ class CPool }; uint8 u; } *m_flags; - int m_size; - int m_allocPtr; + int32 m_size; + int32 m_allocPtr; public: - // TODO(MIAMI): remove ctor without name argument - CPool(int size, const char *name){ - // TODO: use new here - m_entries = (U*)malloc(sizeof(U)*size); - m_flags = (Flags*)malloc(sizeof(Flags)*size); + CPool(int32 size, const char *name){ + m_entries = (U*)new uint8[sizeof(U)*size]; + m_flags = (Flags*)new uint8[sizeof(Flags)*size]; m_size = size; m_allocPtr = -1; for(int i = 0; i < size; i++){ @@ -61,15 +59,15 @@ public: } void Flush() { if (m_size > 0) { - free(m_entries); - free(m_flags); + delete[] (uint8*)m_entries; + delete[] (uint8*)m_flags; m_entries = nil; m_flags = nil; m_size = 0; m_allocPtr = 0; } } - int GetSize(void) const { return m_size; } + int32 GetSize(void) const { return m_size; } T *New(void){ bool wrapped = false; do @@ -93,12 +91,12 @@ public: m_flags[m_allocPtr].id++; return (T*)&m_entries[m_allocPtr]; } - T *New(int handle){ + T *New(int32 handle){ T *entry = (T*)&m_entries[handle>>8]; SetNotFreeAt(handle); return entry; } - void SetNotFreeAt(int handle){ + void SetNotFreeAt(int32 handle){ int idx = handle>>8; m_flags[idx].free = 0; m_flags[idx].id = handle & 0x7F; @@ -123,15 +121,22 @@ public: return m_flags[handle>>8].u == (handle & 0xFF) ? (T*)&m_entries[handle >> 8] : nil; } - int GetIndex(T *entry){ - int i = GetJustIndex(entry); - return m_flags[i].u + (i<<8); + int32 GetIndex(T* entry) { + int i = GetJustIndex_NoFreeAssert(entry); + return m_flags[i].u + (i << 8); + } + int32 GetJustIndex(T* entry) { + int index = GetJustIndex_NoFreeAssert(entry); + assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required + assert(!IsFreeSlot(index)); + return index; } - int GetJustIndex(T *entry){ - // TODO: the cast is unsafe - return (int)((U*)entry - m_entries); + int32 GetJustIndex_NoFreeAssert(T* entry) { + int index = ((U*)entry - m_entries); + // Please don't add unsafe assert here, because at least one func. use this to check if entity is ped or vehicle. + return index; } - int GetNoOfUsedSpaces(void) const { + int32 GetNoOfUsedSpaces(void) const { int i; int n = 0; for(i = 0; i < m_size; i++) @@ -141,8 +146,8 @@ public: } bool IsFreeSlot(int i) { return !!m_flags[i].free; } void ClearStorage(uint8 *&flags, U *&entries){ - free(flags); - free(entries); + delete[] (uint8*)flags; + delete[] (uint8*)entries; flags = nil; entries = nil; } @@ -156,8 +161,8 @@ public: debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ } void Store(uint8 *&flags, U *&entries){ - flags = (uint8*)malloc(sizeof(uint8)*m_size); - entries = (U*)malloc(sizeof(U)*m_size); + flags = (uint8*)new uint8[sizeof(uint8)*m_size]; + entries = (U*)new uint8[sizeof(U)*m_size]; memcpy(flags, m_flags, sizeof(uint8)*m_size); memcpy(entries, m_entries, sizeof(U)*m_size); debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ @@ -236,7 +241,7 @@ public: link->Remove(); // remove from list freeHead.Insert(link); // insert into free list } - int Count(void){ + int32 Count(void){ int n = 0; CLink<T> *lnk; for(lnk = head.next; lnk != &tail; lnk = lnk->next) |