diff options
Diffstat (limited to 'src/core')
56 files changed, 5218 insertions, 5062 deletions
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index f49f811f..35106a6b 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -368,13 +368,7 @@ CAnimViewer::Update(void) } else { // Originally it was GetPad(1)->LeftShoulder2 if (pad->NewState.Triangle) { -#ifdef PED_SKIN - if(IsClumpSkinned(pTarget->GetClump())) - ((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(pTarget->GetClump()); - else -#endif - CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->GetHitColModel(), - RpClumpGetFrame(pTarget->GetClump())); + ((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(pTarget->GetClump()); AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString); CMessages::AddMessage(gUString, 100, 0); } diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 53c49634..fd45a374 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -25,6 +25,7 @@ #include "Debug.h" #include "Camera.h" #include "DMAudio.h" +#include "Bike.h" bool PrintDebugCode = false; int16 DebugCamMode; @@ -281,12 +282,12 @@ CCam::Process(void) if(DirectionWasLooking != LOOKING_BEHIND) TheCamera.m_bJust_Switched = true; DirectionWasLooking = LOOKING_BEHIND; - }else if(CPad::GetPad(0)->GetLookLeft()){ + }else if(!((CVehicle*)CamTargetEntity)->IsRealHeli() && CPad::GetPad(0)->GetLookLeft()){ LookLeft(); if(DirectionWasLooking != LOOKING_LEFT) TheCamera.m_bJust_Switched = true; DirectionWasLooking = LOOKING_LEFT; - }else if(CPad::GetPad(0)->GetLookRight()){ + }else if(!((CVehicle*)CamTargetEntity)->IsRealHeli() && CPad::GetPad(0)->GetLookRight()){ LookRight(); if(DirectionWasLooking != LOOKING_RIGHT) TheCamera.m_bJust_Switched = true; @@ -309,7 +310,7 @@ CCam::Process(void) } if(Mode == MODE_SNIPER || Mode == MODE_ROCKETLAUNCHER || Mode == MODE_M16_1STPERSON || - Mode == MODE_1STPERSON || Mode == MODE_HELICANNON_1STPERSON || GetWeaponFirstPersonOn()) + Mode == MODE_1STPERSON || Mode == MODE_HELICANNON_1STPERSON || Mode == MODE_CAMERA || GetWeaponFirstPersonOn()) ClipIfPedInFrontOfPlayer(); } @@ -1597,7 +1598,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient CWorld::pIgnoreEntity = nil; float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); - float ViewPlaneWidth = ViewPlaneHeight * CDraw::FindAspectRatio() * fTweakFOV; + 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, false); @@ -1628,20 +1629,6 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient entity = nil; } - if(CamTargetEntity->m_rwObject){ - // what's going on here? - if(RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_PUMP) || - RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROW) || - RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROWU) || - RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_START_THROW)){ - CPed *player = FindPlayerPed(); - float PlayerDist = (Source - player->GetPosition()).Magnitude(); - if(PlayerDist < 2.75f) - Near = PlayerDist/2.75f * DEFAULT_NEAR - 0.3f; - RwCameraSetNearClipPlane(Scene.camera, Max(Near, 0.1f)); - } - } - TheCamera.m_bCamDirectlyInFront = false; TheCamera.m_bCamDirectlyBehind = false; @@ -2444,7 +2431,7 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2583,7 +2570,7 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) HeadPos.x = 0.0f; HeadPos.y = 0.0f; HeadPos.z = 0.0f; - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f * Cos(m_fInitialPlayerOrientation); @@ -2672,7 +2659,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2940,7 +2927,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float ResetStatics = false; } - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -3645,7 +3632,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) if(TheCamera.m_bUseSpecialFovTrain) FOV = TheCamera.m_fFovForTrain; - if(CMenuManager::m_ControlMethod == 0 && Using3rdPersonMouseCam()){ + if(FrontEndMenuManager.m_ControlMethod == 0 && Using3rdPersonMouseCam()){ CPed *player = FindPlayerPed(); if(player && player->CanStrafeOrMouseControl()){ float Heading = Front.Heading(); @@ -4539,6 +4526,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient Rotating = false; } + if(TheCamera.m_bUseTransitionBeta) + Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta)); if(TheCamera.m_bUseTransitionBeta) Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta)); @@ -4586,7 +4575,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient CWorld::pIgnoreEntity = nil; float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); - float ViewPlaneWidth = ViewPlaneHeight * CDraw::FindAspectRatio() * fTweakFOV; + 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, false); @@ -4640,9 +4629,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, uint8 camSetArrPos = 0; // We may need those later - bool isPlane = car->GetModelIndex() == MI_DODO; - bool isHeli = false; - bool isBike = false; + bool isPlane = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE; + bool isHeli = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI; + bool isBike = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE || car->IsBike(); bool isCar = car->IsCar() && !isPlane && !isHeli && !isBike; CPad* pad = CPad::GetPad(0); @@ -4653,8 +4642,10 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, if (car->GetModelIndex() == MI_FIRETRUCK) { camSetArrPos = 7; - } else if (car->GetModelIndex() == MI_RCBANDIT) { + } else if (car->GetModelIndex() == MI_RCBANDIT || car->GetModelIndex() == MI_RCBARON) { camSetArrPos = 5; + } else if (car->GetModelIndex() == MI_RCGOBLIN || car->GetModelIndex() == MI_RCRAIDER) { + camSetArrPos = 6; } else if (car->IsBoat()) { camSetArrPos = 4; } else if (isBike) { @@ -4711,6 +4702,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float newDistance = TheCamera.CarZoomValueSmooth + CARCAM_SET[camSetArrPos][1] + approxCarLength; + // Taken from VC CCam::Cam_On_A_String_Unobscured. If we don't this, we will end up seeing the world from the inside of RC Goblin/Raider. + // I couldn't find where SA does that. It's possible that they've increased the size of these veh.'s collision bounding box. + if (car->m_modelIndex == MI_RCRAIDER || car->m_modelIndex == MI_RCBANDIT) { + newDistance += 6.0f; + } else if (car->m_modelIndex == MI_RCBARON) { + newDistance += 9.5f; + } + float minDistForThisCar = approxCarLength * CARCAM_SET[camSetArrPos][3]; if (!isHeli || car->GetStatus() == STATUS_PLAYER_REMOTE) { @@ -4725,6 +4724,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, TargetCoors += 0.6f * car->GetUp() * colMaxZ; } + if (car->m_modelIndex == MI_RCGOBLIN) + zoomModeAlphaOffset += 0.178997f; + float minDistForVehType = CARCAM_SET[camSetArrPos][4]; if (TheCamera.CarZoomIndicator == CAM_ZOOM_1 && (camSetArrPos < 2 || camSetArrPos == 7)) { @@ -4739,6 +4741,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, if (ResetStatics) { FOV = DefaultFOV; + // TODO(Miami): Remove that when cam is done! // GTA 3 has this in veh. camera if (TheCamera.m_bIdleOn) TheCamera.m_uiTimeWeEnteredIdle = CTimer::GetTimeInMilliseconds(); @@ -4775,10 +4778,12 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, ResetStatics = false; Rotating = false; m_bCollisionChecksOn = true; - // TheCamera.m_bResetOldMatrix = 1; + + + // TODO(Miami): Uncomment that when cam is done! // Garage exit cam is not working well in III... - // if (!TheCamera.m_bJustCameOutOfGarage) // && !sthForScript) + // if (!TheCamera.m_bJustCameOutOfGarage) // { Alpha = 0.0f; Beta = car->GetForward().Heading() - HALFPI; @@ -4800,7 +4805,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, m_aTargetHistoryPosTwo = TargetCoors - newDistance * Front; m_nCurrentHistoryPoints = 0; - if (!TheCamera.m_bJustCameOutOfGarage) // && !sthForScript) + if (!TheCamera.m_bJustCameOutOfGarage) Alpha = -zoomModeAlphaOffset; } @@ -4852,9 +4857,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // This is also original LCS and SA bug, or some attempt to fix lag. We'll never know // if (car->m_vecMoveSpeed.MagnitudeSqr() < sq(0.2f)) - if (car->GetModelIndex() != MI_FIRETRUCK) { - // if (!isBike || GetMysteriousWheelRelatedThingBike(car) > 3) - // if (!isHeli && (!isPlane || car->GetWheelsOnGround())) { + if (car->GetModelIndex() != MI_FIRETRUCK) + if (!isBike || ((CBike*)car)->m_nWheelsOnGround > 3) + if (!isHeli && (!isPlane || ((CAutomobile*)car)->m_nWheelsOnGround)) { CVector left = CrossProduct(car->GetForward(), CVector(0.0f, 0.0f, 1.0f)); left.Normalise(); @@ -4908,7 +4913,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, bool correctAlpha = true; // if (SA checks if we aren't in work car, why?) { - if (!isCar || car->GetModelIndex() != MI_YARDIE) { + if (!isCar || car->GetModelIndex() != MI_VOODOO) { correctAlpha = false; } else { @@ -5012,8 +5017,8 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, Beta += TWOPI; if ((camSetArrPos <= 1 || camSetArrPos == 7) && targetAlpha < Alpha && carPosChange >= newDistance) { - if (isCar && ((CAutomobile*)car)->m_nWheelsOnGround > 1) - // || isBike && GetMysteriousWheelRelatedThingBike(car) > 1) + if (isCar && ((CAutomobile*)car)->m_nWheelsOnGround > 1 || + isBike && ((CBike*)car)->m_nWheelsOnGround > 1) alphaSpeedFromStickY += (targetAlpha - Alpha) * 0.075f; } @@ -5163,19 +5168,13 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, if (camSetArrPos == 5 && Source.z < 1.0f) // RC Bandit and Baron Source.z = 1.0f; - // Obviously some specific place in LC - if (Source.x > 11.0f && Source.x < 91.0f) { - if (Source.y > -680.0f && Source.y < -600.0f && Source.z < 24.4f) - Source.z = 24.4f; - } - // CCam::FixSourceAboveWaterLevel if (CameraTarget.z >= -2.0f) { float level = -6000.0; - // +0.5f is needed for III + if (CWaterLevel::GetWaterLevelNoWaves(Source.x, Source.y, Source.z, &level)) { - if (Source.z < level + 0.5f) - Source.z = level + 0.5f; + if (Source.z < level) + Source.z = level; } } Front = TargetCoors - Source; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 53bee20f..d9cc5c32 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -61,6 +61,8 @@ enum CCamera TheCamera; bool CCamera::m_bUseMouse3rdPerson = true; bool bDidWeProcessAnyCinemaCam; +float CCamera::m_f3rdPersonCHairMultX; +float CCamera::m_f3rdPersonCHairMultY; #ifdef IMPROVED_CAMERA #define KEYJUSTDOWN(k) ControlsManager.GetIsKeyboardKeyJustDown((RsKeyCodes)k) @@ -80,10 +82,6 @@ CCamera::CCamera(void) Init(); } -CCamera::CCamera(float) -{ -} - void CCamera::Init(void) { @@ -91,12 +89,7 @@ CCamera::Init(void) float fMouseAccelHorzntl = m_fMouseAccelHorzntl; float fMouseAccelVertical = m_fMouseAccelVertical; #endif -#ifdef FIX_BUGS - static const CCamera DummyCamera = CCamera(0.f); - *this = DummyCamera; -#else - memset(this, 0, sizeof(CCamera)); // getting rid of vtable, eh? -#endif + memset(this, 0, sizeof(CCamera)); // this is fine, no vtable #ifdef GTA3_1_1_PATCH m_fMouseAccelHorzntl = fMouseAccelHorzntl; m_fMouseAccelVertical = fMouseAccelVertical; @@ -642,7 +635,11 @@ CCamera::CamControl(void) m_bInitialNodeFound = false; m_bInitialNoNodeStaticsSet = false; } +#ifdef GTA_TRAIN Process_Train_Camera_Control(); +#else + assert(0 && "this can't happen"); +#endif }else{ if(((CVehicle*)pTargetEntity)->IsBoat()) boatTarget = true; @@ -701,8 +698,8 @@ CCamera::CamControl(void) garageDoorPos2.z = 0.0f; #endif } - garageCenter.x = (pToGarageWeAreIn->m_fX1 + pToGarageWeAreIn->m_fX2)/2.0f; - garageCenter.y = (pToGarageWeAreIn->m_fY1 + pToGarageWeAreIn->m_fY2)/2.0f; + garageCenter.x = pToGarageWeAreIn->GetGarageCenterX(); + garageCenter.y = pToGarageWeAreIn->GetGarageCenterY(); garageCenter.z = 0.0f; if(whichDoor == 1) garageCenterToDoor = garageDoorPos1 - garageCenter; @@ -940,11 +937,13 @@ CCamera::CamControl(void) if(CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer()) stairs = true; // Some hack for Mr Whoopee in a bomb shop +#ifndef MIAMI // uhh, check this if(Cams[ActiveCam].Using3rdPersonMouseCam() && CCollision::ms_collisionInMemory == LEVEL_COMMERCIAL){ if(pTargetEntity->GetPosition().x < 83.0f && pTargetEntity->GetPosition().x > 18.0f && pTargetEntity->GetPosition().y < -305.0f && pTargetEntity->GetPosition().y > -390.0f) disableGarageCam = true; } +#endif if(!disableGarageCam && (CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) || stairs)){ if(!m_bGarageFixedCamPositionSet && m_bLookingAtPlayer){ if(pToGarageWeAreIn || stairs){ @@ -983,8 +982,8 @@ CCamera::CamControl(void) } if(pToGarageWeAreIn){ - garageCenter.x = (pToGarageWeAreIn->m_fX1 + pToGarageWeAreIn->m_fX2)/2.0f; - garageCenter.y = (pToGarageWeAreIn->m_fY1 + pToGarageWeAreIn->m_fY2)/2.0f; + garageCenter.x = pToGarageWeAreIn->GetGarageCenterX(); + garageCenter.y = pToGarageWeAreIn->GetGarageCenterY(); garageCenter.z = 0.0f; }else{ garageDoorPos1.z = 0.0f; @@ -1017,8 +1016,8 @@ CCamera::CamControl(void) if(PedZoomIndicator == CAM_ZOOM_TOPDOWN && !stairs){ garageCamPos = garageCenter; garageCamPos.z += FindPlayerPed()->GetPosition().z + 2.1f; - if(pToGarageWeAreIn && garageCamPos.z > pToGarageWeAreIn->m_fX2) // What? - garageCamPos.z = pToGarageWeAreIn->m_fX2; + if(pToGarageWeAreIn && garageCamPos.z > pToGarageWeAreIn->m_fSupX) // What? + garageCamPos.z = pToGarageWeAreIn->m_fSupX; }else garageCamPos.z = ground + 3.1f; SetCamPositionForFixedMode(garageCamPos, CVector(0.0f, 0.0f, 0.0f)); @@ -1533,7 +1532,6 @@ CCamera::UpdateTargetEntity(void) pTargetEntity = FindPlayerVehicle(); else{ pTargetEntity = FindPlayerPed(); -#ifndef GTA_PS2_STUFF // this keeps the camera on the player while entering cars if(PLAYER->GetPedState() == PED_ENTER_CAR || PLAYER->GetPedState() == PED_CARJACK || @@ -1543,7 +1541,6 @@ CCamera::UpdateTargetEntity(void) if(!enteringCar) if(Cams[ActiveCam].CamTargetEntity != pTargetEntity) Cams[ActiveCam].CamTargetEntity = pTargetEntity; -#endif } bool cantOpen = true; @@ -1562,16 +1559,9 @@ CCamera::UpdateTargetEntity(void) if((PLAYER->GetPedState() == PED_CARJACK || PLAYER->GetPedState() == PED_OPEN_DOOR) && !cantOpen){ if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS) -#ifdef GTA_PS2_STUFF -// dunno if this has any amazing effects - { -#endif pTargetEntity = PLAYER->m_pMyVehicle; if(PLAYER->m_pMyVehicle == nil) pTargetEntity = PLAYER; -#ifdef GTA_PS2_STUFF - } -#endif } if(PLAYER->GetPedState() == PED_EXIT_CAR) @@ -2717,6 +2707,7 @@ CCamera::DontProcessObbeCinemaCamera(void) bDidWeProcessAnyCinemaCam = false; } +#ifdef GTA_TRAIN void CCamera::LoadTrainCamNodes(char const *name) { @@ -2894,6 +2885,7 @@ CCamera::Process_Train_Camera_Control(void) } } } +#endif void @@ -3045,33 +3037,25 @@ CCamera::SetNearClipScript(float clip) void CCamera::ProcessFade(void) { - float fade = (CTimer::GetTimeInMilliseconds() - m_uiFadeTimeStarted)/1000.0f; - // Why even set CDraw::FadeValue if m_fFLOATingFade sets it anyway? if(m_bFading){ if(m_iFadingDirection == FADE_IN){ if(m_fTimeToFadeOut != 0.0f){ - m_fFLOATingFade = 255.0f - 255.0f*fade/m_fTimeToFadeOut; - if(m_fFLOATingFade <= 0.0f){ - m_bFading = false; - CDraw::FadeValue = 0; - m_fFLOATingFade = 0.0f; - } + m_fFLOATingFade -= CTimer::GetTimeStepInSeconds() * 255.0f / m_fTimeToFadeOut; }else{ + m_fFLOATingFade = 0.0f; + } + if (m_fFLOATingFade <= 0.0f) { m_bFading = false; - CDraw::FadeValue = 0; m_fFLOATingFade = 0.0f; } }else if(m_iFadingDirection == FADE_OUT){ if(m_fTimeToFadeOut != 0.0f){ - m_fFLOATingFade = 255.0f*fade/m_fTimeToFadeOut; - if(m_fFLOATingFade >= 255.0f){ - m_bFading = false; - CDraw::FadeValue = 255; - m_fFLOATingFade = 255.0f; - } + m_fFLOATingFade += CTimer::GetTimeStepInSeconds() * 255.0f / m_fTimeToFadeOut; }else{ + m_fFLOATingFade = 255.0f; + } + if (m_fFLOATingFade >= 255.0f) { m_bFading = false; - CDraw::FadeValue = 255; m_fFLOATingFade = 255.0f; } } @@ -3133,22 +3117,13 @@ CCamera::Fade(float timeout, int16 direction) m_iMusicFadingDirection = direction; m_fTimeToFadeMusic = timeout; m_uiFadeTimeStartedMusic = CTimer::GetTimeInMilliseconds(); -// Not on PS2 - if(!m_bJustJumpedOutOf1stPersonBecauseOfTarget && m_iMusicFadingDirection == FADE_OUT){ - unknown++; - if(unknown >= 2){ - m_bJustJumpedOutOf1stPersonBecauseOfTarget = true; - unknown = 0; - }else - m_bMoveCamToAvoidGeom = true; - } } } void CCamera::SetFadeColour(uint8 r, uint8 g, uint8 b) { - m_FadeTargetIsSplashScreen = r == 0 && g == 0 && b == 0; + m_FadeTargetIsSplashScreen = r == 2 && g == 2 && b == 2; CDraw::FadeRed = r; CDraw::FadeGreen = g; CDraw::FadeBlue = b; @@ -3189,7 +3164,7 @@ CCamera::RenderMotionBlur(void) CMBlur::MotionBlurRender(m_pRwCamera, m_BlurRed, m_BlurGreen, m_BlurBlue, - m_motionBlur, m_BlurType, m_imotionBlurAddAlpha); + m_motionBlur, m_BlurType); } void @@ -3306,6 +3281,18 @@ CCamera::Find3rdPersonQuickAimPitch(void) return -(DEGTORAD(((0.5f - m_f3rdPersonCHairMultY) * 1.8f * 0.5f * Cams[ActiveCam].FOV)) + rot); } +bool +CCamera::Using1stPersonWeaponMode(void) +{ + switch(PlayerWeaponMode.Mode) + case CCam::MODE_SNIPER: + case CCam::MODE_M16_1STPERSON: + case CCam::MODE_ROCKETLAUNCHER: + case CCam::MODE_HELICANNON_1STPERSON: + case CCam::MODE_CAMERA: + return true; + return false; +} void @@ -3330,8 +3317,9 @@ CCamera::CalculateDerivedValues(void) // left plane m_vecFrustumNormals[1] = CVector(-c, -s, 0.0f); - c /= CDraw::FindAspectRatio(); - s /= CDraw::FindAspectRatio(); + CDraw::CalculateAspectRatio(); + c /= SCREEN_ASPECT_RATIO; + s /= SCREEN_ASPECT_RATIO; // bottom plane m_vecFrustumNormals[2] = CVector(0.0f, -s, -c); // top plane diff --git a/src/core/Camera.h b/src/core/Camera.h index 80fc878e..669ac740 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -85,13 +85,15 @@ public: MODE_SPECIAL_FIXED_FOR_SYPHON, MODE_FIGHT_CAM, MODE_TOP_DOWN_PED, + MODE_LIGHTHOUSE, MODE_SNIPER_RUNABOUT, MODE_ROCKETLAUNCHER_RUNABOUT, MODE_1STPERSON_RUNABOUT, MODE_M16_1STPERSON_RUNABOUT, MODE_FIGHT_CAM_RUNABOUT, MODE_EDITOR, - MODE_HELICANNON_1STPERSON, // vice city leftover + MODE_HELICANNON_1STPERSON, + MODE_CAMERA, }; bool bBelowMinDist; //used for follow ped mode @@ -380,6 +382,7 @@ public: bool m_WideScreenOn; bool m_1rstPersonRunCloseToAWall; bool m_bHeadBob; + bool m_bVehicleSuspenHigh; bool m_bFailedCullZoneTestPreviously; bool m_FadeTargetIsSplashScreen; @@ -472,8 +475,8 @@ public: // not static yet float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls - float m_f3rdPersonCHairMultX; - float m_f3rdPersonCHairMultY; + static float m_f3rdPersonCHairMultX; + static float m_f3rdPersonCHairMultY; CCam Cams[3]; @@ -549,7 +552,6 @@ public: // High level and misc CCamera(void); - CCamera(float); void Init(void); void Process(void); void CamControl(void); @@ -626,6 +628,7 @@ public: void UpdateAimingCoors(CVector const &coors); void Find3rdPersonCamTargetVector(float dist, CVector pos, CVector &source, CVector &target); float Find3rdPersonQuickAimPitch(void); + bool Using1stPersonWeaponMode(void); // Physical camera void SetRwCamera(RwCamera *cam); diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp new file mode 100644 index 00000000..070967e5 --- /dev/null +++ b/src/core/ColStore.cpp @@ -0,0 +1,237 @@ +#include "common.h" + +#include "templates.h" +#include "General.h" +#include "ModelInfo.h" +#include "Streaming.h" +#include "FileLoader.h" +#include "Script.h" +#include "Timer.h" +#include "Camera.h" +#include "Frontend.h" +#include "Physical.h" +#include "ColStore.h" + +CPool<ColDef,ColDef> *CColStore::ms_pColPool; + +void +CColStore::Initialise(void) +{ + if(ms_pColPool == nil) + ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles"); + AddColSlot("generic"); // slot 0. not streamed +} + +void +CColStore::Shutdown(void) +{ + int i; + for(i = 0; i < COLSTORESIZE; i++) + RemoveColSlot(i); + if(ms_pColPool) + delete ms_pColPool; + ms_pColPool = nil; +} + +int +CColStore::AddColSlot(const char *name) +{ + ColDef *def = ms_pColPool->New(); + assert(def); + def->isLoaded = false; + def->unused = 0; + def->bounds.left = 1000000.0f; + def->bounds.top = 1000000.0f; + def->bounds.right = -1000000.0f; + def->bounds.bottom = -1000000.0f; + def->minIndex = INT16_MAX; + def->maxIndex = INT16_MIN; + strcpy(def->name, name); + return ms_pColPool->GetJustIndex(def); +} + +void +CColStore::RemoveColSlot(int slot) +{ + if(GetSlot(slot)){ + if(GetSlot(slot)->isLoaded) + RemoveCol(slot); + ms_pColPool->Delete(GetSlot(slot)); + } +} + +int +CColStore::FindColSlot(const char *name) +{ + ColDef *def; + int size = ms_pColPool->GetSize(); + for(int i = 0; i < size; i++){ + def = GetSlot(i); + if(def && !CGeneral::faststricmp(def->name, name)) + return i; + } + return -1; +} + +char* +CColStore::GetColName(int32 slot) +{ + return GetSlot(slot)->name; +} + +CRect& +CColStore::GetBoundingBox(int32 slot) +{ + return GetSlot(slot)->bounds; +} + +void +CColStore::IncludeModelIndex(int32 slot, int32 modelIndex) +{ + ColDef *def = GetSlot(slot); + if(modelIndex < def->minIndex) + def->minIndex = modelIndex; + if(modelIndex > def->maxIndex) + def->maxIndex = modelIndex; +} + +bool +CColStore::LoadCol(int32 slot, uint8 *buffer, int32 bufsize) +{ + bool success; + ColDef *def = GetSlot(slot); + if(def->minIndex > def->maxIndex) + success = CFileLoader::LoadCollisionFileFirstTime(buffer, bufsize, slot); + else + success = CFileLoader::LoadCollisionFile(buffer, bufsize, slot); + if(success) + def->isLoaded = true; + else + debug("Failed to load Collision\n"); + return success; +} + +void +CColStore::RemoveCol(int32 slot) +{ + int id; + GetSlot(slot)->isLoaded = false; + for(id = 0; id < MODELINFOSIZE; id++){ + CBaseModelInfo *mi = CModelInfo::GetModelInfo(id); + if(mi){ + CColModel *col = mi->GetColModel(); + if(col && col->level == slot) + col->RemoveCollisionVolumes(); + } + } +} + +void +CColStore::LoadAllCollision(void) +{ + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i)) + CStreaming::RequestCol(i, 0); + + CStreaming::LoadAllRequestedModels(false); +} + +void +CColStore::RemoveAllCollision(void) +{ + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i)) + if(CStreaming::CanRemoveCol(i)) + CStreaming::RemoveCol(i); +} + +static bool bLoadAtSecondPosition; +static CVector2D secondPosition; + +void +CColStore::AddCollisionNeededAtPosn(const CVector2D &pos) +{ + bLoadAtSecondPosition = true; + secondPosition = pos; +} + +void +CColStore::LoadCollision(const CVector2D &pos) +{ + int i; + + if(CStreaming::ms_disableStreaming) + return; + + for(i = 1; i < COLSTORESIZE; i++){ + if(GetSlot(i) == nil) + continue; + + bool wantThisOne = false; + + if(GetBoundingBox(i).IsPointInside(pos) || + bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) || + CGeneral::faststrcmp(GetColName(i), "yacht") == 0){ + wantThisOne = true; + }else{ + for (int j = 0; j < MAX_CLEANUP; j++) { + CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j); + if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) { + if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f)) + wantThisOne = true; + } + } + } + + if(wantThisOne) + CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY); + else + CStreaming::RemoveCol(i); + } + bLoadAtSecondPosition = false; +} + +void +CColStore::RequestCollision(const CVector2D &pos) +{ + int i; + + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f)) + CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY); +} + +void +CColStore::EnsureCollisionIsInMemory(const CVector2D &pos) +{ + int i; + + if(CStreaming::ms_disableStreaming) + return; + + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) && + !CStreaming::HasColLoaded(i)){ + CStreaming::RequestCol(i, 0); + if(TheCamera.GetScreenFadeStatus() == FADE_0) + FrontEndMenuManager.MessageScreen("LOADCOL", false); + CTimer::Suspend(); + CStreaming::LoadAllRequestedModels(false); + CTimer::Resume(); + } +} + +//--MIAMI: done +bool +CColStore::HasCollisionLoaded(const CVector2D &pos) +{ + int i; + + for(i = 1; i < COLSTORESIZE; i++) + if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f) && + !GetSlot(i)->isLoaded) + return false; + return true; +} diff --git a/src/core/ColStore.h b/src/core/ColStore.h new file mode 100644 index 00000000..8e2a3a70 --- /dev/null +++ b/src/core/ColStore.h @@ -0,0 +1,43 @@ +#pragma once + +#include "templates.h" + +struct ColDef { // made up name + int32 unused; + bool isLoaded; + CRect bounds; + char name[20]; + int16 minIndex; + int16 maxIndex; +}; + +class CColStore +{ + static CPool<ColDef,ColDef> *ms_pColPool; + +public: + static void Initialise(void); + static void Shutdown(void); + static int AddColSlot(const char *name); + static void RemoveColSlot(int32 slot); + static int FindColSlot(const char *name); + static char *GetColName(int32 slot); + static CRect &GetBoundingBox(int32 slot); + static void IncludeModelIndex(int32 slot, int32 modelIndex); + static bool LoadCol(int32 storeID, uint8 *buffer, int32 bufsize); + static void RemoveCol(int32 slot); + static void AddCollisionNeededAtPosn(const CVector2D &pos); + static void LoadAllCollision(void); + static void RemoveAllCollision(void); + static void LoadCollision(const CVector2D &pos); + static void RequestCollision(const CVector2D &pos); + static void EnsureCollisionIsInMemory(const CVector2D &pos); + static bool HasCollisionLoaded(const CVector2D &pos); + + static ColDef *GetSlot(int slot) { + assert(slot >= 0); + assert(ms_pColPool); + assert(slot < ms_pColPool->GetSize()); + return ms_pColPool->GetSlot(slot); + } +}; diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 23eaa8dd..b68214af 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -20,6 +20,8 @@ #include "SurfaceTable.h" #include "Lines.h" #include "Collision.h" +#include "Camera.h" +#include "ColStore.h" enum Direction { @@ -34,57 +36,30 @@ enum Direction eLevelName CCollision::ms_collisionInMemory; CLinkList<CColModel*> CCollision::ms_colModelCache; +//--MIAMI: done void CCollision::Init(void) { ms_colModelCache.Init(NUMCOLCACHELINKS); ms_collisionInMemory = LEVEL_NONE; + CColStore::Initialise(); } +//--MIAMI: done void CCollision::Shutdown(void) { ms_colModelCache.Shutdown(); + CColStore::Shutdown(); } +//--MIAMI: done void CCollision::Update(void) { - CVector playerCoors; - playerCoors = FindPlayerCoors(); - eLevelName level = CTheZones::m_CurrLevel; - bool forceLevelChange = false; - - if(CTimer::GetTimeInMilliseconds() < 2000 || CCutsceneMgr::IsCutsceneProcessing()) - return; - - // hardcode a level if there are no zones - if(level == LEVEL_NONE){ - if(CGame::currLevel == LEVEL_INDUSTRIAL && - playerCoors.x < 400.0f){ - level = LEVEL_COMMERCIAL; - forceLevelChange = true; - }else if(CGame::currLevel == LEVEL_SUBURBAN && - playerCoors.x > -450.0f && playerCoors.y < -1400.0f){ - level = LEVEL_COMMERCIAL; - forceLevelChange = true; - }else{ - if(playerCoors.x > 800.0f){ - level = LEVEL_INDUSTRIAL; - forceLevelChange = true; - }else if(playerCoors.x < -800.0f){ - level = LEVEL_SUBURBAN; - forceLevelChange = true; - } - } - } - if(level != LEVEL_NONE && level != CGame::currLevel) - CGame::currLevel = level; - if(ms_collisionInMemory != CGame::currLevel) - LoadCollisionWhenINeedIt(forceLevelChange); - CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); } +//--MIAMI: unused eLevelName GetCollisionInSectorList(CPtrList &list) { @@ -101,6 +76,7 @@ GetCollisionInSectorList(CPtrList &list) return LEVEL_NONE; } +//--MIAMI: unused // Get a level this sector is in based on collision models eLevelName GetCollisionInSector(CSector §) @@ -121,111 +97,16 @@ GetCollisionInSector(CSector §) return (eLevelName)level; } +//--MIAMI: done void CCollision::LoadCollisionWhenINeedIt(bool forceChange) { - eLevelName level, l; - bool multipleLevels; - CVector playerCoors; - CVehicle *veh; - CEntryInfoNode *ei; - int sx, sy; - int xmin, xmax, ymin, ymax; - int x, y; - - level = LEVEL_NONE; - - playerCoors = FindPlayerCoors(); - sx = CWorld::GetSectorIndexX(playerCoors.x); - sy = CWorld::GetSectorIndexY(playerCoors.y); - multipleLevels = false; - - veh = FindPlayerVehicle(); - if(veh && veh->IsTrain()){ - if(((CTrain*)veh)->m_nDoorState != TRAIN_DOOR_OPEN) - return; - }else if(playerCoors.z < -4.0f && !CCullZones::DoINeedToLoadCollision()) - return; - - // Figure out whose level's collisions we're most likely to be interested in - if(!forceChange){ - if(veh && veh->IsBoat()){ - // on water we expect to be between levels - multipleLevels = true; - }else{ - xmin = Max(sx - 1, 0); - xmax = Min(sx + 1, NUMSECTORS_X-1); - ymin = Max(sy - 1, 0); - ymax = Min(sy + 1, NUMSECTORS_Y-1); - - for(x = xmin; x <= xmax; x++) - for(y = ymin; y <= ymax; y++){ - l = GetCollisionInSector(*CWorld::GetSector(x, y)); - if(l != LEVEL_NONE){ - if(level == LEVEL_NONE) - level = l; - if(level != l) - multipleLevels = true; - } - } - } - - if(multipleLevels && veh && veh->IsBoat()) - for(ei = veh->m_entryInfoList.first; ei; ei = ei->next){ - level = GetCollisionInSector(*ei->sector); - if(level != LEVEL_NONE) - break; - } - } - - if(level == CGame::currLevel || forceChange){ - CTimer::Stop(); - DMAudio.SetEffectsFadeVol(0); - CPad::StopPadsShaking(); - LoadCollisionScreen(CGame::currLevel); - DMAudio.Service(); - - CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false); - CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); - CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); - CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); - CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); - CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); - CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); - CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); - CStreaming::RemoveUnusedModelsInLoadedList(); - CGame::TidyUpMemory(true, true); - CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); - ms_collisionInMemory = CGame::currLevel; - CReplay::EmptyReplayBuffer(); - if(CGame::currLevel != LEVEL_NONE) - LoadSplash(GetLevelSplashScreen(CGame::currLevel)); - CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); - CStreaming::RemoveUnusedBuildings(CGame::currLevel); - CStreaming::RequestBigBuildings(CGame::currLevel); - CStreaming::LoadAllRequestedModels(true); - CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel); - - CGame::TidyUpMemory(true, true); - CTimer::Update(); - DMAudio.SetEffectsFadeVol(127); - } } +//--MIAMI: done void CCollision::SortOutCollisionAfterLoad(void) { - if(ms_collisionInMemory == CGame::currLevel) - return; - - CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); - if(CGame::currLevel != LEVEL_NONE){ - CFileLoader::LoadCollisionFromDatFile(CGame::currLevel); - if(!CGame::playingIntro) - LoadSplash(GetLevelSplashScreen(CGame::currLevel)); - } - ms_collisionInMemory = CGame::currLevel; - CGame::TidyUpMemory(true, false); } void @@ -249,14 +130,14 @@ CCollision::LoadCollisionScreen(eLevelName level) bool -CCollision::TestSphereSphere(const CColSphere &s1, const CColSphere &s2) +CCollision::TestSphereSphere(const CSphere &s1, const CSphere &s2) { float d = s1.radius + s2.radius; return (s1.center - s2.center).MagnitudeSqr() < d*d; } bool -CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box) +CCollision::TestSphereBox(const CSphere &sph, const CBox &box) { if(sph.center.x + sph.radius < box.min.x) return false; if(sph.center.x - sph.radius > box.max.x) return false; @@ -268,7 +149,7 @@ CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box) } bool -CCollision::TestLineBox(const CColLine &line, const CColBox &box) +CCollision::TestLineBox(const CColLine &line, const CBox &box) { float t, x, y, z; // If either line point is in the box, we have a collision @@ -353,7 +234,7 @@ CCollision::TestLineBox(const CColLine &line, const CColBox &box) } bool -CCollision::TestVerticalLineBox(const CColLine &line, const CColBox &box) +CCollision::TestVerticalLineBox(const CColLine &line, const CBox &box) { if(line.p0.x <= box.min.x) return false; if(line.p0.y <= box.min.y) return false; @@ -533,8 +414,9 @@ CCollision::TestSphereTriangle(const CColSphere &sphere, return dist < sphere.radius; } +//--MIAMI: TODO bool -CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough) +CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough, bool ignoreShootThrough) { static CMatrix matTransform; int i; @@ -1161,10 +1043,11 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere, return true; } +//--MIAMI: TODO bool CCollision::ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, - CColPoint &point, float &mindist, bool ignoreSeeThrough) + CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough) { static CMatrix matTransform; int i; @@ -1200,10 +1083,11 @@ CCollision::ProcessLineOfSight(const CColLine &line, return false; } +//--MIAMI: TODO bool CCollision::ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, - CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly) + CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough, CStoredCollPoly *poly) { static CStoredCollPoly TempStoredPoly; int i; @@ -1974,7 +1858,7 @@ CColModel::CColModel(void) vertices = nil; triangles = nil; trianglePlanes = nil; - level = CGame::currLevel; + level = 0; // generic col slot ownsCollisionVolumes = true; } diff --git a/src/core/Collision.h b/src/core/Collision.h index 895f012a..12af5225 100644 --- a/src/core/Collision.h +++ b/src/core/Collision.h @@ -10,26 +10,37 @@ #define MAX_COLLISION_POINTS 32 #endif -struct CColSphere +struct CSphere { CVector center; float radius; + void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; } +}; + +struct CBox +{ + CVector min; + CVector max; + CVector GetSize(void) { return max - min; } + void Set(const CVector &min, const CVector &max) { this->min = min; this->max = max; } +}; + +struct CColSphere : public CSphere +{ uint8 surface; uint8 piece; void Set(float radius, const CVector ¢er, uint8 surf, uint8 piece); - void Set(float radius, const CVector ¢er) { this->center = center; this->radius = radius; } + using CSphere::Set; }; -struct CColBox +struct CColBox : public CBox { - CVector min; - CVector max; uint8 surface; uint8 piece; void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece); - CVector GetSize(void) { return max - min; } + using CBox::Set; }; struct CColLine @@ -85,15 +96,16 @@ struct CStoredCollPoly bool valid; }; +//--MIAMI: done struct struct CColModel { - CColSphere boundingSphere; - CColBox boundingBox; + CSphere boundingSphere; + CBox boundingBox; int16 numSpheres; - int16 numLines; int16 numBoxes; int16 numTriangles; - int32 level; + int8 numLines; + uint8 level; // colstore slot but probably still named level bool ownsCollisionVolumes; CColSphere *spheres; CColLine *lines; @@ -132,14 +144,14 @@ public: static void CalculateTrianglePlanes(CColModel *model); // all these return true if there's a collision - static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2); - static bool TestSphereBox(const CColSphere &sph, const CColBox &box); - static bool TestLineBox(const CColLine &line, const CColBox &box); - static bool TestVerticalLineBox(const CColLine &line, const CColBox &box); + static bool TestSphereSphere(const CSphere &s1, const CSphere &s2); + static bool TestSphereBox(const CSphere &sph, const CBox &box); + static bool TestLineBox(const CColLine &line, const CBox &box); + static bool TestVerticalLineBox(const CColLine &line, const CBox &box); static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); static bool TestLineSphere(const CColLine &line, const CColSphere &sph); static bool TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane); - static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough); + static bool TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough, bool ignoreShootThrough); static bool ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CColPoint &point, float &mindistsq); static bool ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoint &point, float &mindistsq); @@ -148,8 +160,8 @@ public: static bool ProcessLineTriangle(const CColLine &line , const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindist); static bool ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CColPoint &point, float &mindist); static bool ProcessSphereTriangle(const CColSphere &sph, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane, CColPoint &point, float &mindistsq); - static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough); - static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly); + static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough); + static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, bool ignoreShootThrough, CStoredCollPoly *poly); static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists); static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly); diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index 6a5080e5..e48f2c3f 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -205,6 +205,8 @@ void CControllerConfigManager::InitDefaultControlConfiguration() SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsPADEND, KEYBOARD); SetControllerKeyAssociatedWithAction (PED_LOOKBEHIND, rsCAPSLK, OPTIONAL_EXTRA); + + SetControllerKeyAssociatedWithAction (PED_DUCK, 'C', KEYBOARD); SetControllerKeyAssociatedWithAction (PED_FIREWEAPON, rsPADINS, KEYBOARD); SetControllerKeyAssociatedWithAction (PED_FIREWEAPON, rsLCTRL, OPTIONAL_EXTRA); @@ -217,6 +219,8 @@ void CControllerConfigManager::InitDefaultControlConfiguration() SetControllerKeyAssociatedWithAction (PED_JUMPING, rsRCTRL, KEYBOARD); SetControllerKeyAssociatedWithAction (PED_JUMPING, ' ', OPTIONAL_EXTRA); + + SetControllerKeyAssociatedWithAction (PED_ANSWER_PHONE, rsTAB, KEYBOARD); if ( _dwOperatingSystemVersion == OS_WIN98 ) SetControllerKeyAssociatedWithAction(PED_SPRINT, rsSHIFT, OPTIONAL_EXTRA); // BUG: must be KEYBOARD ? @@ -259,7 +263,7 @@ void CControllerConfigManager::InitDefaultControlConfiguration() SetControllerKeyAssociatedWithAction (VEHICLE_TURRETDOWN, rsPADRIGHT, KEYBOARD); SetControllerKeyAssociatedWithAction (CAMERA_CHANGE_VIEW_ALL_SITUATIONS, rsHOME, KEYBOARD); - SetControllerKeyAssociatedWithAction (CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 'C', OPTIONAL_EXTRA); + SetControllerKeyAssociatedWithAction (CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 'V', OPTIONAL_EXTRA); for (int32 i = 0; i < MAX_SIMS; i++) { @@ -336,13 +340,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); case 10: SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK); case 9: SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); case 8: SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); case 7: - SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); case 6: SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); @@ -384,13 +389,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); case 10: SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK); case 9: SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); case 8: SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); case 7: - SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK); + SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); case 6: SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); @@ -431,6 +437,8 @@ void CControllerConfigManager::InitialiseControllerActionNameArray() SETACTIONNAME(PED_CYCLE_TARGET_LEFT); SETACTIONNAME(PED_CYCLE_TARGET_RIGHT); SETACTIONNAME(PED_CENTER_CAMERA_BEHIND_PLAYER); + SETACTIONNAME(PED_DUCK); + SETACTIONNAME(PED_ANSWER_PHONE); SETACTIONNAME(VEHICLE_LOOKBEHIND); SETACTIONNAME(VEHICLE_LOOKLEFT); SETACTIONNAME(VEHICLE_LOOKRIGHT); @@ -754,6 +762,8 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstPersonOnl state.Square = 255; if (button == GetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, type)) state.Cross = 255; + if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) + state.RightShock = 255; } void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnly(int32 button, eControllerType type, CControllerState &state) @@ -762,14 +772,18 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_ThirdPersonOnl state.RightShock = 255; if (button == GetControllerKeyAssociatedWithAction(PED_JUMPING, type)) state.Square = 255; + if (button == GetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, type)) + state.LeftShoulder1 = 255; if (button == GetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, type)) state.LeftShoulder2 = 255; if (button == GetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, type)) state.RightShoulder2 = 255; if (button == GetControllerKeyAssociatedWithAction(PED_SPRINT, type)) state.Cross = 255; + if (button == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) + state.RightShock = 255; - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (button == GetControllerKeyAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type)) state.LeftShoulder2 = 255; @@ -835,7 +849,7 @@ void CControllerConfigManager::AffectControllerStateOn_ButtonDown_FirstAndThirdP state.RightStickX = 128; } - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (button == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_UP, type)) { @@ -1616,8 +1630,12 @@ void CControllerConfigManager::DeleteMatching3rdPersonControls(e_ControllerActio ClearSettingsAssociatedWithAction(PED_JUMPING, type); if (key == GetControllerKeyAssociatedWithAction(PED_SPRINT, type)) ClearSettingsAssociatedWithAction(PED_SPRINT, type); + if (key == GetControllerKeyAssociatedWithAction(PED_DUCK, type)) + ClearSettingsAssociatedWithAction(PED_DUCK, type); + if (key == GetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, type)) + ClearSettingsAssociatedWithAction(PED_ANSWER_PHONE, type); - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (key == GetControllerKeyAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type)) ClearSettingsAssociatedWithAction(PED_CYCLE_TARGET_LEFT, type); @@ -1640,7 +1658,7 @@ void CControllerConfigManager::DeleteMatching1rst3rdPersonControls(e_ControllerA if (key == GetControllerKeyAssociatedWithAction(GO_BACK, type)) ClearSettingsAssociatedWithAction(GO_BACK, type); - if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) + if (FrontEndMenuManager.m_ControlMethod == CONTROL_CLASSIC) { if (key == GetControllerKeyAssociatedWithAction(PED_1RST_PERSON_LOOK_LEFT, type)) ClearSettingsAssociatedWithAction(PED_1RST_PERSON_LOOK_LEFT, type); @@ -1803,6 +1821,8 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio case PED_CYCLE_WEAPON_RIGHT: case PED_JUMPING: case PED_SPRINT: + case PED_DUCK: + case PED_ANSWER_PHONE: case PED_CYCLE_TARGET_LEFT: case PED_CYCLE_TARGET_RIGHT: case PED_CENTER_CAMERA_BEHIND_PLAYER: diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h index 7d0e1073..5f0b6862 100644 --- a/src/core/ControllerConfig.h +++ b/src/core/ControllerConfig.h @@ -32,6 +32,8 @@ enum e_ControllerAction PED_JUMPING, PED_SPRINT, PED_LOOKBEHIND, + PED_DUCK, + PED_ANSWER_PHONE, VEHICLE_ACCELERATE, VEHICLE_BRAKE, VEHICLE_CHANGE_RADIO_STATION, diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp index 675040ea..c3508a51 100644 --- a/src/core/EventList.cpp +++ b/src/core/EventList.cpp @@ -67,8 +67,6 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent switch(entityType){ case EVENT_ENTITY_PED: ref = CPools::GetPedRef((CPed*)ent); - if(ent->GetModelIndex() >= MI_GANG01 && ent->GetModelIndex() <= MI_CRIMINAL02) - copsDontCare = true; break; case EVENT_ENTITY_VEHICLE: ref = CPools::GetVehicleRef((CVehicle*)ent); diff --git a/src/core/EventList.h b/src/core/EventList.h index 8840afc4..f2c3d7a8 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -22,10 +22,12 @@ enum eEventType EVENT_PED_SET_ON_FIRE, EVENT_COP_SET_ON_FIRE, EVENT_CAR_SET_ON_FIRE, - EVENT_ASSAULT_NASTYWEAPON, // not sure + EVENT_ASSAULT_NASTYWEAPON, + EVENT_ASSAULT_NASTYWEAPON_POLICE, EVENT_ICECREAM, EVENT_ATM, - EVENT_SHOPSTALL, // used on graffitis + EVENT_SHOPSTALL, + EVENT_SHOPWINDOW, EVENT_LAST_EVENT }; diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 6e7188c5..1463b4a5 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -1,4 +1,5 @@ #include "common.h" +#include <ctype.h> #include "main.h" #include "Quaternion.h" @@ -24,6 +25,11 @@ #include "ZoneCull.h" #include "CdStream.h" #include "FileLoader.h" +#include "Streaming.h" +#include "ColStore.h" +#include "Occlusion.h" + +//--MIAMI: file done char CFileLoader::ms_line[256]; @@ -46,14 +52,12 @@ CFileLoader::LoadLevel(const char *filename) { int fd; RwTexDictionary *savedTxd; - eLevelName savedLevel; bool objectsLoaded; char *line; char txdname[64]; savedTxd = RwTexDictionaryGetCurrent(); objectsLoaded = false; - savedLevel = CGame::currLevel; if(savedTxd == nil){ savedTxd = RwTexDictionaryCreate(); RwTexDictionarySetCurrent(savedTxd); @@ -77,12 +81,8 @@ CFileLoader::LoadLevel(const char *filename) AddTexDictionaries(savedTxd, txd); RwTexDictionaryDestroy(txd); }else if(strncmp(line, "COLFILE", 7) == 0){ - int level; - sscanf(line+8, "%d", &level); - CGame::currLevel = (eLevelName)level; LoadingScreenLoadingFile(line+10); - LoadCollisionFile(line+10); - CGame::currLevel = savedLevel; + LoadCollisionFile(line+10, 0); }else if(strncmp(line, "MODELFILE", 9) == 0){ LoadingScreenLoadingFile(line + 10); LoadModelFile(line + 10); @@ -94,15 +94,17 @@ CFileLoader::LoadLevel(const char *filename) LoadObjectTypes(line + 4); }else if(strncmp(line, "IPL", 3) == 0){ if(!objectsLoaded){ - CModelInfo::ConstructMloClumps(); + LoadingScreenLoadingFile("Collision"); CObjectData::Initialise("DATA\\OBJECT.DAT"); + CStreaming::Init(); + CColStore::LoadAllCollision(); + for(int i = 0; i < MODELINFOSIZE; i++) + if(CModelInfo::GetModelInfo(i)) + CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex(); objectsLoaded = true; } LoadingScreenLoadingFile(line + 4); LoadScene(line + 4); - }else if(strncmp(line, "MAPZONE", 7) == 0){ - LoadingScreenLoadingFile(line + 8); - LoadMapZones(line + 8); }else if(strncmp(line, "SPLASH", 6) == 0){ LoadSplash(GetRandomSplashScreen()); }else if(strncmp(line, "CDIMAGE", 7) == 0){ @@ -112,30 +114,13 @@ CFileLoader::LoadLevel(const char *filename) CFileMgr::CloseFile(fd); RwTexDictionarySetCurrent(savedTxd); -} - -void -CFileLoader::LoadCollisionFromDatFile(int currlevel) -{ - int fd; - char *line; - - fd = CFileMgr::OpenFile(CGame::aDatFile, "r"); - assert(fd > 0); - - for(line = LoadLine(fd); line; line = LoadLine(fd)){ - if(*line == '#') - continue; - - if(strncmp(line, "COLFILE", 7) == 0){ - int level; - sscanf(line+8, "%d", &level); - if(currlevel == level) - LoadCollisionFile(line+10); - } - } - CFileMgr::CloseFile(fd); + int i; + for(i = 1; i < COLSTORESIZE; i++) + if(CColStore::GetSlot(i)) + CColStore::GetBoundingBox(i).Grow(120.0f); + CWorld::RepositionCertainDynamicObjects(); + CColStore::RemoveAllCollision(); } char* @@ -179,7 +164,7 @@ struct ColHeader }; void -CFileLoader::LoadCollisionFile(const char *filename) +CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot) { int fd; char modelname[24]; @@ -188,6 +173,7 @@ CFileLoader::LoadCollisionFile(const char *filename) debug("Loading collision file %s\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); + assert(fd > 0); while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){ assert(strncmp(header.ident, "COLL", 4) == 0); @@ -196,10 +182,11 @@ CFileLoader::LoadCollisionFile(const char *filename) mi = CModelInfo::GetModelInfo(modelname, nil); if(mi){ - if(mi->GetColModel()){ + if(mi->GetColModel() && mi->DoesOwnColModel()){ LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname); }else{ CColModel *model = new CColModel; + model->level = colSlot; LoadCollisionModel(work_buff+24, *model, modelname); mi->SetColModel(model, true); } @@ -211,6 +198,79 @@ CFileLoader::LoadCollisionFile(const char *filename) CFileMgr::CloseFile(fd); } + +bool +CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot) +{ + uint32 modelsize; + char modelname[24]; + CBaseModelInfo *mi; + ColHeader *header; + int modelIndex; + + while(size > 8){ + header = (ColHeader*)buffer; + modelsize = header->size; + if(strncmp(header->ident, "COLL", 4) != 0) + return size-8 < CDSTREAM_SECTOR_SIZE; + memcpy(modelname, buffer+8, 24); + memcpy(work_buff, buffer+32, modelsize-24); + size -= 32 + (modelsize-24); + buffer += 32 + (modelsize-24); + if(modelsize > 15*1024) + debug("colmodel %s is huge, size %d\n", modelname, modelsize); + + mi = CModelInfo::GetModelInfo(modelname, &modelIndex); + if(mi){ + CColStore::IncludeModelIndex(colSlot, modelIndex); + CColModel *model = new CColModel; + model->level = colSlot; + LoadCollisionModel(work_buff, *model, modelname); + mi->SetColModel(model, true); + }else{ + debug("colmodel %s can't find a modelinfo\n", modelname); + } + } + return true; +} + +bool +CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot) +{ + uint32 modelsize; + char modelname[24]; + CBaseModelInfo *mi; + ColHeader *header; + + while(size > 8){ + header = (ColHeader*)buffer; + modelsize = header->size; + if(strncmp(header->ident, "COLL", 4) != 0) + return size-8 < CDSTREAM_SECTOR_SIZE; + memcpy(modelname, buffer+8, 24); + memcpy(work_buff, buffer+32, modelsize-24); + size -= 32 + (modelsize-24); + buffer += 32 + (modelsize-24); + if(modelsize > 15*1024) + debug("colmodel %s is huge, size %d\n", modelname, modelsize); + + mi = CModelInfo::GetModelInfo(modelname, CColStore::GetSlot(colSlot)->minIndex, CColStore::GetSlot(colSlot)->maxIndex); + if(mi){ + if(mi->GetColModel()){ + LoadCollisionModel(work_buff, *mi->GetColModel(), modelname); + }else{ + CColModel *model = new CColModel; + model->level = colSlot; + LoadCollisionModel(work_buff, *model, modelname); + mi->SetColModel(model, true); + } + }else{ + debug("colmodel %s can't find a modelinfo\n", modelname); + } + } + return true; +} + void CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) { @@ -240,13 +300,15 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) model.numLines = *(int16*)buf; buf += 4; if(model.numLines > 0){ - model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); + //model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); for(i = 0; i < model.numLines; i++){ - model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); + //model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); buf += 24; } }else model.lines = nil; + model.numLines = 0; + model.lines = nil; model.numBoxes = *(int16*)buf; buf += 4; @@ -265,10 +327,12 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) model.vertices = (CVector*)RwMalloc(numVertices*sizeof(CVector)); for(i = 0; i < numVertices; i++){ model.vertices[i] = *(CVector*)buf; +#if 0 if(Abs(model.vertices[i].x) >= 256.0f || Abs(model.vertices[i].y) >= 256.0f || Abs(model.vertices[i].z) >= 256.0f) printf("%s:Collision volume too big\n", modelname); +#endif buf += 12; } }else @@ -291,7 +355,7 @@ GetNameAndLOD(char *nodename, char *name, int *n) { char *underscore = nil; for(char *s = nodename; *s != '\0'; s++){ - if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L')) + if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L') && isdigit(s[2])) underscore = s; } if(underscore){ @@ -317,11 +381,11 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data) mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil); if(mi){ assert(mi->IsSimple()); + CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); mi->SetAtomic(n, atomic); RpClumpRemoveAtomic(clump, atomic); RpAtomicSetFrame(atomic, RwFrameCreate()); CVisibilityPlugins::SetAtomicModelInfo(atomic, mi); - CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); }else{ debug("Can't find Atomic %s\n", name); } @@ -387,14 +451,6 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id) return false; mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id); mi->SetClump(clump); - if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) { - // Read LOD ped - clump = RpClumpStreamRead(stream); - if(clump){ - ((CPedModelInfo*)mi)->SetLowDetailClump(clump); - RpClumpDestroy(clump); - } - } return true; } @@ -456,11 +512,11 @@ CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, void *data) nodename = GetFrameNodeName(RpAtomicGetFrame(atomic)); GetNameAndLOD(nodename, name, &n); + CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); gpRelatedModelInfo->SetAtomic(n, atomic); RpClumpRemoveAtomic(clump, atomic); RpAtomicSetFrame(atomic, RwFrameCreate()); CVisibilityPlugins::SetAtomicModelInfo(atomic, gpRelatedModelInfo); - CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); return atomic; } @@ -498,8 +554,9 @@ CFileLoader::LoadObjectTypes(const char *filename) enum { NONE, OBJS, - MLO, + MLO, // unused but enum still has it TOBJ, + WEAP, HIER, CARS, PEDS, @@ -510,16 +567,17 @@ CFileLoader::LoadObjectTypes(const char *filename) int fd; int section; int pathIndex; - char pathTypeStr[20]; int id, pathType; - int mlo; + int minID, maxID; section = NONE; + minID = INT32_MAX; + maxID = -1; pathIndex = -1; - mlo = 0; debug("Loading object types from %s...\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); + assert(fd > 0); for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ if(*line == '\0' || *line == '#') continue; @@ -527,25 +585,27 @@ CFileLoader::LoadObjectTypes(const char *filename) if(section == NONE){ if(strncmp(line, "objs", 4) == 0) section = OBJS; else if(strncmp(line, "tobj", 4) == 0) section = TOBJ; + else if(strncmp(line, "weap", 4) == 0) section = WEAP; else if(strncmp(line, "hier", 4) == 0) section = HIER; else if(strncmp(line, "cars", 4) == 0) section = CARS; else if(strncmp(line, "peds", 4) == 0) section = PEDS; else if(strncmp(line, "path", 4) == 0) section = PATH; else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX; }else if(strncmp(line, "end", 3) == 0){ - section = section == MLO ? OBJS : NONE; + section = NONE; }else switch(section){ case OBJS: - if(strncmp(line, "sta", 3) == 0) - mlo = LoadMLO(line); - else - LoadObject(line); - break; - case MLO: - LoadMLOInstance(mlo, line); + id = LoadObject(line); + if(id > maxID) maxID = id; + if(id < minID) minID = id; break; case TOBJ: - LoadTimeObject(line); + id = LoadTimeObject(line); + if(id > maxID) maxID = id; + if(id < minID) minID = id; + break; + case WEAP: + LoadWeaponObject(line); break; case HIER: LoadClumpObject(line); @@ -558,17 +618,15 @@ CFileLoader::LoadObjectTypes(const char *filename) break; case PATH: if(pathIndex == -1){ - id = LoadPathHeader(line, pathTypeStr); - if(strncmp(pathTypeStr, "ped", 4) == 0) - pathType = 1; - else if(strncmp(pathTypeStr, "car", 4) == 0) - pathType = 0; + id = LoadPathHeader(line, pathType); pathIndex = 0; }else{ - if(pathType == 1) + if(pathType == 0) LoadPedPathNode(line, id, pathIndex); - else if(pathType == 0) - LoadCarPathNode(line, id, pathIndex); + else if (pathType == 1) + LoadCarPathNode(line, id, pathIndex, false); + else if (pathType == 2) + LoadCarPathNode(line, id, pathIndex, true); pathIndex++; if(pathIndex == 12) pathIndex = -1; @@ -581,26 +639,30 @@ CFileLoader::LoadObjectTypes(const char *filename) } CFileMgr::CloseFile(fd); - for(id = 0; id < MODELINFOSIZE; id++){ + for(id = minID; id <= maxID; id++){ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); - if(mi && mi->IsSimple()) - mi->SetupBigBuilding(); + if(mi && mi->IsBuilding()) + mi->SetupBigBuilding(minID, maxID); } } void SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags) { - mi->m_normalCull = !!(flags & 1); + mi->m_wetRoadReflection = !!(flags & 1); mi->m_noFade = !!(flags & 2); mi->m_drawLast = !!(flags & (4|8)); mi->m_additive = !!(flags & 8); mi->m_isSubway = !!(flags & 0x10); mi->m_ignoreLight = !!(flags & 0x20); mi->m_noZwrite = !!(flags & 0x40); + mi->m_noShadows = !!(flags & 0x80); + mi->m_ignoreDrawDist = !!(flags & 0x100); + mi->m_isCodeGlass = !!(flags & 0x200); + mi->m_isArtistGlass = !!(flags & 0x400); } -void +int CFileLoader::LoadObject(const char *line) { int id, numObjs; @@ -611,7 +673,7 @@ CFileLoader::LoadObject(const char *line) CSimpleModelInfo *mi; if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) - return; + return 0; // game returns return value switch(numObjs){ case 1: @@ -643,60 +705,11 @@ CFileLoader::LoadObject(const char *line) mi->m_firstDamaged = damaged; mi->SetTexDictionary(txd); MatchModelString(model, id); -} -int -CFileLoader::LoadMLO(const char *line) -{ - char smth[8]; - char name[24]; - int modelIndex; - float someFloat; - - sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat); - CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex); - minfo->SetName(name); - minfo->field_34 = someFloat; - int instId = CModelInfo::GetMloInstanceStore().allocPtr; - minfo->firstInstance = instId; - minfo->lastInstance = instId; - minfo->SetTexDictionary("generic"); - return modelIndex; -} - -void -CFileLoader::LoadMLOInstance(int id, const char *line) -{ - char name[24]; - RwV3d pos, scale, rot; - float angle; - int modelIndex; - - CMloModelInfo *minfo = (CMloModelInfo*)CModelInfo::GetModelInfo(id); - sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", - &modelIndex, - name, - &pos.x, &pos.y, &pos.z, - &scale.x, &scale.y, &scale.z, - &rot.x, &rot.y, &rot.z, - &angle); - float rad = Acos(angle) * 2.0f; - CInstance *inst = CModelInfo::GetMloInstanceStore().alloc(); - minfo->lastInstance++; - - RwMatrix *matrix = RwMatrixCreate(); - RwMatrixScale(matrix, &scale, rwCOMBINEREPLACE); - RwMatrixRotate(matrix, &rot, -RADTODEG(rad), rwCOMBINEPOSTCONCAT); - RwMatrixTranslate(matrix, &pos, rwCOMBINEPOSTCONCAT); - - inst->GetMatrix() = CMatrix(matrix); - inst->GetMatrix().UpdateRW(); - - inst->m_modelIndex = modelIndex; - RwMatrixDestroy(matrix); + return id; } -void +int CFileLoader::LoadTimeObject(const char *line) { int id, numObjs; @@ -708,7 +721,7 @@ CFileLoader::LoadTimeObject(const char *line) CTimeModelInfo *mi, *other; if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) - return; + return 0; // game returns return value switch(numObjs){ case 1: @@ -744,6 +757,29 @@ CFileLoader::LoadTimeObject(const char *line) if(other) other->SetOtherTimeModel(id); MatchModelString(model, id); + + return id; +} + +int +CFileLoader::LoadWeaponObject(const char *line) +{ + int id, numObjs; + char model[24], txd[24], animFile[16]; + float dist; + CWeaponModelInfo *mi; + + sscanf(line, "%d %s %s %s %d %f", &id, model, txd, animFile, &numObjs, &dist); + + mi = CModelInfo::AddWeaponModel(id); + mi->SetName(model); + mi->SetNumAtomics(1); + mi->m_lodDistances[0] = dist; + mi->SetTexDictionary(txd); + mi->SetAnimFile(animFile); + mi->SetColModel(&CTempColModels::ms_colModelWeapon); + MatchModelString(model, id); + return id; } void @@ -766,21 +802,22 @@ CFileLoader::LoadVehicleObject(const char *line) { int id; char model[24], txd[24]; - char type[8], handlingId[16], gamename[32], vehclass[12]; + char type[8], handlingId[16], gamename[32], animFile[16], vehclass[12]; uint32 frequency, comprules; int32 level, misc; float wheelScale; CVehicleModelInfo *mi; char *p; - sscanf(line, "%d %s %s %s %s %s %s %d %d %x %d %f", + sscanf(line, "%d %s %s %s %s %s %s %s %d %d %x %d %f", &id, model, txd, - type, handlingId, gamename, vehclass, + type, handlingId, gamename, animFile, vehclass, &frequency, &level, &comprules, &misc, &wheelScale); mi = CModelInfo::AddVehicleModel(id); mi->SetName(model); mi->SetTexDictionary(txd); + mi->SetAnimFile(animFile); for(p = gamename; *p; p++) if(*p == '_') *p = ' '; strcpy(mi->m_gameName, gamename); @@ -810,36 +847,34 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId); - // Well this is kinda dumb.... - if(strncmp(vehclass, "poorfamily", 11) == 0){ + if(strncmp(vehclass, "normal", 7) == 0) + mi->m_vehicleClass = CCarCtrl::NORMAL; + else if(strncmp(vehclass, "poorfamily", 11) == 0) mi->m_vehicleClass = CCarCtrl::POOR; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::POOR); - }else if(strncmp(vehclass, "richfamily", 11) == 0){ + else if(strncmp(vehclass, "richfamily", 11) == 0) mi->m_vehicleClass = CCarCtrl::RICH; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::RICH); - }else if(strncmp(vehclass, "executive", 10) == 0){ + else if(strncmp(vehclass, "executive", 10) == 0) mi->m_vehicleClass = CCarCtrl::EXEC; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::EXEC); - }else if(strncmp(vehclass, "worker", 7) == 0){ + else if(strncmp(vehclass, "worker", 7) == 0) mi->m_vehicleClass = CCarCtrl::WORKER; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::WORKER); - }else if(strncmp(vehclass, "special", 8) == 0){ - mi->m_vehicleClass = CCarCtrl::SPECIAL; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::SPECIAL); - }else if(strncmp(vehclass, "big", 4) == 0){ + else if(strncmp(vehclass, "big", 4) == 0) mi->m_vehicleClass = CCarCtrl::BIG; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::BIG); - }else if(strncmp(vehclass, "taxi", 5) == 0){ + else if(strncmp(vehclass, "taxi", 5) == 0) mi->m_vehicleClass = CCarCtrl::TAXI; - while(frequency-- > 0) - CCarCtrl::AddToCarArray(id, CCarCtrl::TAXI); + else if(strncmp(vehclass, "moped", 6) == 0) + mi->m_vehicleClass = CCarCtrl::MOPED; + else if(strncmp(vehclass, "motorbike", 10) == 0) + mi->m_vehicleClass = CCarCtrl::MOTORBIKE; + else if(strncmp(vehclass, "leisureboat", 12) == 0) + mi->m_vehicleClass = CCarCtrl::LEISUREBOAT; + else if(strncmp(vehclass, "workerboat", 11) == 0) + mi->m_vehicleClass = CCarCtrl::WORKERBOAT; + else if(strncmp(vehclass, "ignore", 11) == 0){ + mi->m_vehicleClass = -1; + return; } + CCarCtrl::AddToCarArray(id, mi->m_vehicleClass); + mi->m_frequency = frequency; } void @@ -847,67 +882,87 @@ CFileLoader::LoadPedObject(const char *line) { int id; char model[24], txd[24]; - char pedType[24], pedStats[24], animGroup[24]; + char pedType[24], pedStats[24], animGroup[24], animFile[16]; int carsCanDrive; CPedModelInfo *mi; int animGroupId; + int radio1, radio2; - if(sscanf(line, "%d %s %s %s %s %s %x", + sscanf(line, "%d %s %s %s %s %s %x %s %d %d", &id, model, txd, - pedType, pedStats, animGroup, &carsCanDrive) != 7) - return; + pedType, pedStats, animGroup, &carsCanDrive, + animFile, &radio1, &radio2); mi = CModelInfo::AddPedModel(id); mi->SetName(model); mi->SetTexDictionary(txd); + mi->SetAnimFile(animFile); mi->SetColModel(&CTempColModels::ms_colModelPed1); mi->m_pedType = CPedType::FindPedType(pedType); mi->m_pedStatType = CPedStats::GetPedStatType(pedStats); for(animGroupId = 0; animGroupId < NUM_ANIM_ASSOC_GROUPS; animGroupId++) if(strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)animGroupId)) == 0) break; + assert(animGroupId < NUM_ANIM_ASSOC_GROUPS); mi->m_animGroup = animGroupId; mi->m_carsCanDrive = carsCanDrive; - - // ??? - CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1); + mi->radio1 = radio1; + mi->radio2 = radio2; } int -CFileLoader::LoadPathHeader(const char *line, char *type) +CFileLoader::LoadPathHeader(const char *line, int &type) { int id; char modelname[32]; - sscanf(line, "%s %d %s", type, &id, modelname); + sscanf(line, "%d %d %s", &type, &id, modelname); return id; } void CFileLoader::LoadPedPathNode(const char *line, int id, int node) { - int type, next, cross; - float x, y, z, width; - - sscanf(line, "%d %d %d %f %f %f %f", &type, &next, &cross, &x, &y, &z, &width); - ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, 0, !!cross); + int type, next, cross, numLeft, numRight, speed, flags; + float x, y, z, width, spawnRate; + + if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f", + &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight, + &speed, &flags, &spawnRate) != 12) + spawnRate = 1.0f; + + if(id == -1) + ThePaths.StoreDetachedNodeInfoPed(node, type, next, x, y, z, + width, !!cross, !!(flags&1), !!(flags&4), spawnRate*15.0f); + else + ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, + width, !!cross, spawnRate*15.0f); } void -CFileLoader::LoadCarPathNode(const char *line, int id, int node) +CFileLoader::LoadCarPathNode(const char *line, int id, int node, bool waterPath) { - int type, next, cross, numLeft, numRight; - float x, y, z, width; - - sscanf(line, "%d %d %d %f %f %f %f %d %d", &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight); - ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight); + int type, next, cross, numLeft, numRight, speed, flags; + float x, y, z, width, spawnRate; + + if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f", + &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight, + &speed, &flags, &spawnRate) != 12) + spawnRate = 1.0f; + + if(id == -1) + ThePaths.StoreDetachedNodeInfoCar(node, type, next, x, y, z, width, numLeft, numRight, + !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15, false); + else + ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight, + !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15); } void CFileLoader::Load2dEffect(const char *line) { - int id, r, g, b, a, type; + int id, r, g, b, a, type, ptype; float x, y, z; char corona[32], shadow[32]; int shadowIntens, lightType, roadReflection, flare, flags, probability; @@ -980,6 +1035,18 @@ CFileLoader::Load2dEffect(const char *line) effect->attractor.flags = flags; effect->attractor.probability = probability; break; + case EFFECT_PED_ATTRACTOR: + sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %f %f %f", + &id, &x, &y, &z, &r, &g, &b, &a, &type, + &ptype, + &effect->pedattr.queueDir.x, + &effect->pedattr.queueDir.y, + &effect->pedattr.queueDir.z, + &effect->pedattr.useDir.x, + &effect->pedattr.useDir.y, + &effect->pedattr.useDir.z); + effect->pedattr.type = ptype; + break; } CTxdStore::PopCurrentTxd(); @@ -993,20 +1060,21 @@ CFileLoader::LoadScene(const char *filename) INST, ZONE, CULL, + OCCL, PICK, PATH, }; char *line; int fd; int section; - int pathIndex; - char pathTypeStr[20]; + int pathType, pathIndex; section = NONE; pathIndex = -1; debug("Creating objects from %s...\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); + assert(fd > 0); for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ if(*line == '\0' || *line == '#') continue; @@ -1017,6 +1085,7 @@ CFileLoader::LoadScene(const char *filename) else if(strncmp(line, "cull", 4) == 0) section = CULL; else if(strncmp(line, "pick", 4) == 0) section = PICK; else if(strncmp(line, "path", 4) == 0) section = PATH; + else if(strncmp(line, "occl", 4) == 0) section = OCCL; }else if(strncmp(line, "end", 3) == 0){ section = NONE; }else switch(section){ @@ -1029,18 +1098,24 @@ CFileLoader::LoadScene(const char *filename) case CULL: LoadCullZone(line); break; + case OCCL: + LoadOcclusionVolume(line); + break; case PICK: // unused LoadPickup(line); break; case PATH: - // unfinished in the game if(pathIndex == -1){ - LoadPathHeader(line, pathTypeStr); - // type not set + LoadPathHeader(line, pathType); pathIndex = 0; }else{ - // nodes not loaded + if(pathType == 0) + LoadPedPathNode(line, -1, pathIndex); + else if (pathType == 1) + LoadCarPathNode(line, -1, pathIndex, false); + else if (pathType == 2) + LoadCarPathNode(line, -1, pathIndex, true); pathIndex++; if(pathIndex == 12) pathIndex = -1; @@ -1063,18 +1138,30 @@ CFileLoader::LoadObjectInstance(const char *line) CSimpleModelInfo *mi; RwMatrix *xform; CEntity *entity; - if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", - &id, name, + float area; + + if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f %f", + &id, name, &area, &trans.x, &trans.y, &trans.z, &scale.x, &scale.y, &scale.z, - &axis.x, &axis.y, &axis.z, &angle) != 12) - return; + &axis.x, &axis.y, &axis.z, &angle) != 13){ + if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", + &id, name, + &trans.x, &trans.y, &trans.z, + &scale.x, &scale.y, &scale.z, + &axis.x, &axis.y, &axis.z, &angle) != 12) + return; + area = 0; + } mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); if(mi == nil) return; assert(mi->IsSimple()); + if(!CStreaming::IsObjectInCdImage(id)) + debug("Not in cdimage %s\n", mi->GetName()); + angle = -RADTODEG(2.0f * acosf(angle)); xform = RwMatrixCreate(); RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE); @@ -1089,7 +1176,8 @@ CFileLoader::LoadObjectInstance(const char *line) entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition()); - if(mi->IsSimple()){ + entity->m_area = area; + if(mi->IsBuilding()){ if(mi->m_isBigBuilding) entity->SetupBigBuilding(); if(mi->m_isSubway) @@ -1098,14 +1186,25 @@ CFileLoader::LoadObjectInstance(const char *line) if(mi->GetLargestLodDistance() < 2.0f) entity->bIsVisible = false; CWorld::Add(entity); + + CColModel *col = entity->GetColModel(); + if(col->numSpheres || col->numBoxes || col->numTriangles){ + if(col->level != 0) + CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect()); + }else + entity->bUsesCollision = false; + + if(entity->GetPosition().z + col->boundingBox.min.z < 6.0f) + entity->bUnderwater = true; }else{ entity = new CDummyObject; entity->SetModelIndexNoCreate(id); entity->GetMatrix() = CMatrix(xform); CWorld::Add(entity); - if(IsGlass(entity->GetModelIndex())) + if(IsGlass(entity->GetModelIndex()) && !mi->m_isArtistGlass) entity->bIsVisible = false; entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition()); + entity->m_area = area; } RwMatrixDestroy(xform); @@ -1151,53 +1250,21 @@ CFileLoader::LoadPickup(const char *line) } void -CFileLoader::LoadMapZones(const char *filename) +CFileLoader::LoadOcclusionVolume(const char *line) { - enum { - NONE, - INST, - ZONE, - CULL, - PICK, - PATH, - }; - char *line; - int fd; - int section; - - section = NONE; - debug("Creating zones from %s...\n", filename); - - fd = CFileMgr::OpenFile(filename, "rb"); - for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ - if(*line == '\0' || *line == '#') - continue; - - if(section == NONE){ - if(strncmp(line, "zone", 4) == 0) section = ZONE; - }else if(strncmp(line, "end", 3) == 0){ - section = NONE; - }else switch(section){ - case ZONE: { - char name[24]; - int type, level; - float minx, miny, minz; - float maxx, maxy, maxz; - if(sscanf(line, "%s %d %f %f %f %f %f %f %d", - name, &type, - &minx, &miny, &minz, - &maxx, &maxy, &maxz, - &level) == 9) - CTheZones::CreateMapZone(name, (eZoneType)type, minx, miny, minz, maxx, maxy, maxz, (eLevelName)level); - } - break; - } - } - CFileMgr::CloseFile(fd); + float x, y, z; + float width, length, height; + float angle; - debug("Finished loading IPL\n"); + sscanf(line, "%f %f %f %f %f %f %f", + &x, &y, &z, + &width, &length, &height, + &angle); + COcclusion::AddOne(x, y, z, width, length, z + height/2.0f, angle); } + +//--MIAMI: unused void CFileLoader::ReloadPaths(const char *filename) { @@ -1208,10 +1275,10 @@ CFileLoader::ReloadPaths(const char *filename) char *line; int section = NONE; int id, pathType, pathIndex = -1; - char pathTypeStr[20]; debug("Reloading paths from %s...\n", filename); int fd = CFileMgr::OpenFile(filename, "r"); + assert(fd > 0); for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { if (*line == '\0' || *line == '#') continue; @@ -1227,17 +1294,15 @@ CFileLoader::ReloadPaths(const char *filename) switch (section) { case PATH: if (pathIndex == -1) { - id = LoadPathHeader(line, pathTypeStr); - if (strncmp(pathTypeStr, "ped", 4) == 0) - pathType = 1; - else if (strncmp(pathTypeStr, "car", 4) == 0) - pathType = 0; + id = LoadPathHeader(line, pathType); pathIndex = 0; } else { - if (pathType == 1) + if(pathType == 0) LoadPedPathNode(line, id, pathIndex); - else if (pathType == 0) - LoadCarPathNode(line, id, pathIndex); + else if (pathType == 1) + LoadCarPathNode(line, id, pathIndex, false); + else if (pathType == 2) + LoadCarPathNode(line, id, pathIndex, true); pathIndex++; if (pathIndex == 12) pathIndex = -1; @@ -1267,6 +1332,7 @@ CFileLoader::ReloadObjectTypes(const char *filename) CFileMgr::ChangeDir("\\DATA\\MAPS\\"); int fd = CFileMgr::OpenFile(filename, "r"); + assert(fd > 0); CFileMgr::ChangeDir("\\"); for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { if (*line == '\0' || *line == '#') @@ -1342,6 +1408,7 @@ CFileLoader::ReLoadScene(const char *filename) char *line; CFileMgr::ChangeDir("\\DATA\\"); int fd = CFileMgr::OpenFile(filename, "r"); + assert(fd > 0); CFileMgr::ChangeDir("\\"); for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h index 87b8fe61..077e7bdd 100644 --- a/src/core/FileLoader.h +++ b/src/core/FileLoader.h @@ -5,10 +5,11 @@ class CFileLoader static char ms_line[256]; public: static void LoadLevel(const char *filename); - static void LoadCollisionFromDatFile(int currlevel); static char *LoadLine(int fd); static RwTexDictionary *LoadTexDictionary(const char *filename); - static void LoadCollisionFile(const char *filename); + static void LoadCollisionFile(const char *filename, uint8 colSlot); + static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot); + static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot); static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name); static void LoadModelFile(const char *filename); static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data); @@ -22,16 +23,15 @@ public: static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src); static void LoadObjectTypes(const char *filename); - static void LoadObject(const char *line); - static int LoadMLO(const char *line); - static void LoadMLOInstance(int id, const char *line); - static void LoadTimeObject(const char *line); + static int LoadObject(const char *line); + static int LoadTimeObject(const char *line); + static int LoadWeaponObject(const char *line); static void LoadClumpObject(const char *line); static void LoadVehicleObject(const char *line); static void LoadPedObject(const char *line); - static int LoadPathHeader(const char *line, char *type); + static int LoadPathHeader(const char *line, int &type); static void LoadPedPathNode(const char *line, int id, int node); - static void LoadCarPathNode(const char *line, int id, int node); + static void LoadCarPathNode(const char *line, int id, int node, bool waterPath); static void Load2dEffect(const char *line); static void LoadScene(const char *filename); @@ -39,8 +39,7 @@ public: static void LoadZone(const char *line); static void LoadCullZone(const char *line); static void LoadPickup(const char *line); - - static void LoadMapZones(const char *filename); + static void LoadOcclusionVolume(const char *line); static void ReloadPaths(const char *filename); static void ReloadObjectTypes(const char *filename); diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index 933c73da..3752f1ba 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -15,6 +15,7 @@ #include "DamageManager.h" #include "Ped.h" #include "Fire.h" +#include "GameLogic.h" CFireManager gFireManager; @@ -59,6 +60,12 @@ CFire::ProcessFire(void) Extinguish(); return; } +#if defined GTAVC_JP_PATCH && !defined FIX_BUGS + if (m_pEntity == CGameLogic::pShortCutTaxi && CGameLogic::ShortCutState == CGameLogic::SHORTCUT_TRANSITION) { + Extinguish(); + return; + } +#endif if (ped->m_nMoveState != PEDMOVE_RUN) m_vecPos.z -= 1.0f; if (ped->bInVehicle && ped->m_pMyVehicle) { @@ -84,6 +91,12 @@ CFire::ProcessFire(void) Extinguish(); return; } +#ifdef FIX_BUGS + if (m_pEntity == CGameLogic::pShortCutTaxi && CGameLogic::ShortCutState == CGameLogic::SHORTCUT_TRANSITION) { + Extinguish(); + return; + } +#endif if (!m_bIsScriptFire) { fDamageVehicle = 1.2f * CTimer::GetTimeStep(); veh->InflictDamage((CVehicle *)m_pSource, WEAPONTYPE_FLAMETHROWER, fDamageVehicle); diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 3ead688b..2cc34a95 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -23,6 +23,7 @@ #include "GenericGameStorage.h" #include "Script.h" #include "Camera.h" +#include "MenuScreens.h" #include "ControllerConfig.h" #include "Vehicle.h" #include "MBlur.h" @@ -35,7 +36,22 @@ #include "Stats.h" #include "Messages.h" #include "FileLoader.h" -#include "frontendoption.h" + +// TODO(Miami): This is -3 on VC but still -1 on AudioManager?!? What the hell? +#define INVALID_AUDIO_PROVIDER -1 + +// 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 MAPINFOBOX_COLOR(255, 150, 225, 150); #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 @@ -66,14 +82,6 @@ #define GetBackJustDown GetSquareJustDown #endif -#ifdef MENU_MAP -bool CMenuManager::bMenuMapActive = false; -bool CMenuManager::bMapMouseShownOnce = false; -bool CMenuManager::bMapLoaded = false; -float CMenuManager::fMapSize; -float CMenuManager::fMapCenterY; -float CMenuManager::fMapCenterX; -#endif #ifdef PS2_LIKE_MENU BottomBarOption bbNames[8]; @@ -86,35 +94,8 @@ int curBottomBarOption = -1; int hoveredBottomBarOption = -1; #endif -int32 CMenuManager::OS_Language = LANG_ENGLISH; -int8 CMenuManager::m_PrefsUseVibration; -int8 CMenuManager::m_DisplayControllerOnFoot; -int8 CMenuManager::m_PrefsVsync = 1; -int8 CMenuManager::m_PrefsVsyncDisp = 1; -int8 CMenuManager::m_PrefsFrameLimiter = 1; -int8 CMenuManager::m_PrefsShowSubtitles = 1; -int8 CMenuManager::m_PrefsSpeakers; -int32 CMenuManager::m_ControlMethod; -int8 CMenuManager::m_PrefsDMA = 1; -int32 CMenuManager::m_PrefsLanguage; uint8 CMenuManager::m_PrefsStereoMono; // unused except restore settings -bool CMenuManager::m_PrefsAllowNastyGame = true; -bool CMenuManager::m_bStartUpFrontEndRequested; -bool CMenuManager::m_bShutDownFrontEndRequested; - -int8 CMenuManager::m_PrefsUseWideScreen; -int8 CMenuManager::m_PrefsRadioStation; -int32 CMenuManager::m_PrefsBrightness = 256; -float CMenuManager::m_PrefsLOD = CRenderer::ms_lodDistScale; -int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt; -int32 CMenuManager::m_PrefsMusicVolume = 102; -int32 CMenuManager::m_PrefsSfxVolume = 102; - -char CMenuManager::m_PrefsSkinFile[256] = DEFAULT_SKIN_NAME; - -int32 CMenuManager::m_KeyPressedCode = -1; - // Originally that was PS2 option color, they forget it here and used in PrintBriefs once(but didn't use the output anyway) #ifdef PS2_LIKE_MENU const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); @@ -125,99 +106,53 @@ const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; -bool holdingScrollBar; // *(bool*)0x628D59; // not original name -int32 CMenuManager::m_SelectedMap; -int32 CMenuManager::m_SelectedGameType; - -// Used in a hidden menu -uint8 CMenuManager::m_PrefsPlayerRed = 255; -uint8 CMenuManager::m_PrefsPlayerGreen = 128; -uint8 CMenuManager::m_PrefsPlayerBlue; // why?? +bool holdingScrollBar; // *(bool*)0x7039B9; // not original name CMenuManager FrontEndMenuManager; +MenuTrapezoid menuBg(CGeneral::GetRandomNumber() % 40 + 65, CGeneral::GetRandomNumber() % 40 + 21, + CGeneral::GetRandomNumber() % 40 + 568, CGeneral::GetRandomNumber() % 40 + 44, + CGeneral::GetRandomNumber() % 40 + 36, CGeneral::GetRandomNumber() % 40 + 352, + CGeneral::GetRandomNumber() % 40 + 593, CGeneral::GetRandomNumber() % 40 + 312); -uint32 TimeToStopPadShaking; -char *pEditString; -int32 *pControlEdit; -bool DisplayComboButtonErrMsg; -int32 MouseButtonJustClicked; -int32 JoyButtonJustClicked; -//int32 *pControlTemp = 0; +MenuTrapezoid menuOptionHighlight(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + +// TODO(Miami): TEMPORARY +bool bMapLoaded = false; +bool bMapMouseShownOnce = false; #ifndef MASTER bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x5F311C +// 0x68C144 const char* FrontendFilenames[][2] = { - {"fe2_mainpanel_ul", "" }, - {"fe2_mainpanel_ur", "" }, - {"fe2_mainpanel_dl", "" }, - {"fe2_mainpanel_dr", "" }, - {"fe2_mainpanel_dr2", "" }, - {"fe2_tabactive", "" }, - {"fe_iconbrief", "" }, - {"fe_iconstats", "" }, - {"fe_iconcontrols", "" }, - {"fe_iconsave", "" }, - {"fe_iconaudio", "" }, - {"fe_icondisplay", "" }, - {"fe_iconlanguage", "" }, - {"fe_controller", "" }, - {"fe_controllersh", "" }, - {"fe_arrows1", "" }, - {"fe_arrows2", "" }, - {"fe_arrows3", "" }, - {"fe_arrows4", "" }, - {"fe_radio1", "" }, - {"fe_radio2", "" }, - {"fe_radio3", "" }, - {"fe_radio4", "" }, - {"fe_radio5", "" }, - {"fe_radio6", "" }, - {"fe_radio7", "" }, - {"fe_radio8", "" }, - {"fe_radio9", "" }, -}; - -#ifdef MENU_MAP -const char* MapFilenames[][2] = { + {"background", ""}, + {"vc_logo", "vc_logom"}, + {"mouse", "mousea"}, + {"mapTop01", "mapTop01A"}, + {"mapTop02", "mapTop02A"}, + {"mapTop03", "mapTop03A"}, {"mapMid01", "mapMid01A"}, {"mapMid02", "mapMid02A"}, {"mapMid03", "mapMid03A"}, {"mapBot01", "mapBot01A"}, {"mapBot02", "mapBot02A"}, {"mapBot03", "mapBot03A"}, - {"mapTop01", "mapTop01A"}, - {"mapTop02", "mapTop02A"}, - {"mapTop03", "mapTop03A"}, -}; -CSprite2d CMenuManager::m_aMapSprites[NUM_MAP_SPRITES]; -#endif - -// 0x5F3344 -const char* MenuFilenames[][2] = { - {"connection24", ""}, - {"findgame24", ""}, - {"hostgame24", ""}, - {"mainmenu24", ""}, - {"Playersetup24", ""}, - {"singleplayer24", ""}, - {"multiplayer24", ""}, - {"dmalogo128", "dmalogo128m"}, - {"gtaLogo128", "gtaLogo128"}, - {"rockstarLogo128", "rockstarlogo128m"}, - {"gamespy256", "gamespy256a"}, - {"mouse", "mousetimera"}, - {"mousetimer", "mousetimera"}, - {"mp3logo", "mp3logoA"}, - {"downOFF", "buttonA"}, - {"downON", "buttonA"}, + {"wildstyle", "wildstyleA"}, + {"flash", "flashA"}, + {"kchat", "kchatA"}, + {"fever", "feverA"}, + {"vrock", "vrockA"}, + {"vcpr", "vcprA"}, + {"espantoso", "espantosoA"}, + {"emotion", "emotionA"}, + {"wave103", "wave103A"}, + {"mp3", "mp3A"}, + {"downOff", "buttonA"}, + {"downOn", "buttonA"}, {"upOff", "buttonA"}, - {"upON", "buttonA"}, - {"gta3logo256", "gta3logo256m"}, - { nil, nil } + {"upOn", "buttonA"} }; #ifdef ASPECT_RATIO_SCALE @@ -246,77 +181,109 @@ ScaleAndCenterX(float x) #define MENU_Y(y) StretchY(y) #endif -#ifdef PS2_LIKE_MENU -#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \ - do { \ - if (reverseAlpha) { \ - m_nPrevScreen = m_nCurrScreen; \ - m_nCurrScreen = pendingScreen; \ - m_nCurrOption = pendingOption; \ - reverseAlpha = false; \ - if (updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - } \ - if (withReverseAlpha) { \ - pendingOption = option; \ - pendingScreen = screen; \ - reverseAlpha = true; \ - } else { \ - m_nPrevScreen = m_nCurrScreen; \ - m_nCurrScreen = screen; \ - m_nCurrOption = option; \ - if (updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - } \ - m_nMenuFadeAlpha = 255; \ - } while(0) -#else -#define ChangeScreen(screen, option, updateDelay, clearAlpha) \ - do { \ - m_nPrevScreen = m_nCurrScreen; \ - int newOpt = option; \ - m_nCurrScreen = screen; \ - m_nCurrOption = newOpt; \ - if(updateDelay) \ - m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode(); \ - if(clearAlpha) \ - m_nMenuFadeAlpha = 0; \ - } while(0) -#endif - #define PREPARE_MENU_HEADER \ - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \ CFont::SetRightJustifyOn(); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + CFont::SetDropShadowPosition(0); -#define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \ +#define ProcessSlider(value, y, increaseAction, decreaseAction, hoverStartX, hoverEndX) \ do { \ - lastActiveBarX = DisplaySlider(MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \ + 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(10.0f), MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \ + if (CheckHover(hoverStartX, lastActiveBarX - MENU_X(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ m_nHoverOption = decreaseAction; \ \ - if (!CheckHover(MENU_X(10.0f) + lastActiveBarX, hoverEndX, MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \ + if (!CheckHover(MENU_X(3.0f) + lastActiveBarX, hoverEndX, MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \ break; \ \ m_nHoverOption = increaseAction; \ - if (m_nMousePosX < MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth)) \ + if (m_nMousePosX < MENU_X_LEFT_ALIGNED(MENUSLIDER_X)) \ m_nHoverOption = HOVEROPTION_NOT_HOVERING; \ } while(0) +// TODO: this is COMPLETELY different in VC #define ProcessRadioIcon(sprite, x, y, radioId, hoverOpt) \ do { \ - sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170)); \ + sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(255, 255, 255, 100)); \ if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \ m_nHoverOption = hoverOpt; \ } while (0) // --- Functions not in the game/inlined starts +bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); +void DoRWStuffEndOfFrame(void); + +#ifdef PS2_LIKE_MENU +void +CMenuManager::SwitchToNewScreen(int8 screen) +{ + if (reverseAlpha) { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = pendingScreen; + m_nCurrOption = pendingOption; + reverseAlpha = false; + if (updateDelay) + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); + } + if (withReverseAlpha) { + pendingOption = option; + pendingScreen = screen; + reverseAlpha = true; + } else { + m_nPrevScreen = m_nCurrScreen; + m_nCurrScreen = screen; + m_nCurrOption = option; + if (updateDelay) + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); + } + m_nMenuFadeAlpha = 255; +} +#else + +// --MIAMI: Done except using VC's gMenuPages void +CMenuManager::SwitchToNewScreen(int8 screen) +{ + bMenuChangeOngoing = true; + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DrawBackground(true); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DrawBackground(true); + DoRWStuffEndOfFrame(); + m_nPrevScreen = m_nCurrScreen; + m_ShowEmptyBindingError = false; + ResetHelperText(); + + ThingsToDoBeforeLeavingPage(); + + if (screen == -2) { + int oldScreen = aScreens[m_nCurrScreen].m_PreviousPage; + int oldOption = (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry))); + + m_nCurrOption = oldOption; + m_nCurrScreen = oldScreen; + } else if (screen == 0) { + m_nCurrScreen = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu; + m_nCurrOption = 0; + } else { + m_nCurrOption = 0; + m_nCurrScreen = screen; + } + + if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) + m_nCurrOption = 8; + m_nMenuFadeAlpha = 0; + m_nOptionHighlightTransitionBlend = 0; + m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode(); +} +#endif + +inline void CMenuManager::ScrollUpListByOne() { if (m_nSelectedListRow == m_nFirstVisibleRowOnList) { @@ -330,7 +297,7 @@ CMenuManager::ScrollUpListByOne() } } -void +inline void CMenuManager::ScrollDownListByOne() { if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { @@ -346,13 +313,13 @@ CMenuManager::ScrollDownListByOne() } } -void +inline void CMenuManager::PageUpList(bool playSoundOnSuccess) { if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { if (m_nFirstVisibleRowOnList > 0) { if(playSoundOnSuccess) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); @@ -364,13 +331,13 @@ CMenuManager::PageUpList(bool playSoundOnSuccess) } } -void +inline void CMenuManager::PageDownList(bool playSoundOnSuccess) { if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { if(playSoundOnSuccess) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW); m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList); @@ -382,13 +349,14 @@ CMenuManager::PageDownList(bool playSoundOnSuccess) } } -void -CMenuManager::ThingsToDoBeforeGoingBack() +// TODO(Miami) +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 != -1) + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); #ifdef TIDY_UP_PBP DMAudio.StopFrontEndTrack(); @@ -396,6 +364,9 @@ CMenuManager::ThingsToDoBeforeGoingBack() #endif } else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { m_nDisplayVideoMode = m_nPrefsVideoMode; +#ifdef IMPROVED_VIDEOMODE + m_nSelectedScreenMode = m_nPrefsWindowed; +#endif } if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { @@ -405,50 +376,126 @@ CMenuManager::ThingsToDoBeforeGoingBack() if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { m_nTotalListRow = 0; } +} -#ifdef CUSTOM_FRONTEND_OPTIONS - for (int i = 0; i < numCustomFrontendOptions; i++) { - FrontendOption &option = customFrontendOptions[i]; - if (option.type != FEOPTION_REDIRECT && option.type != FEOPTION_GOBACK && m_nCurrScreen == option.screen) { - if (option.returnPrevPageFunc) - option.returnPrevPageFunc(); +// ------ Functions not in the game/inlined ends - if (m_nCurrOption == option.screenOptionOrder && option.type == FEOPTION_DYNAMIC) - option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); +CMenuManager::CMenuManager() +{ + m_StatsScrollSpeed = 150.0f; + m_StatsScrollDirection = 1; + m_PrefsSfxVolume = 49; + m_PrefsMusicVolume = 49; + m_PrefsRadioStation = 0; + field_2C = 1; + m_PrefsBrightness = 256; + m_PrefsLOD = 1.2f; + m_KeyPressedCode = -1; + m_bFrontEnd_ReloadObrTxtGxt = false; + m_PrefsMP3BoostVolume = 0; + m_PrefsShowSubtitles = 0; + m_PrefsShowLegends = 1; + m_PrefsUseWideScreen = 0; + m_PrefsVsync = 0; + m_PrefsVsyncDisp = 1; + m_PrefsFrameLimiter = 1; + m_PrefsLanguage = 0; + field_54 = 0; + m_PrefsAllowNastyGame = 1; + m_PrefsSpeakers = 0; + field_8 = 0; + m_PrefsUseVibration = 0; + m_PrefsShowHud = 1; + m_PrefsRadarMode = 0; + field_10 = 0; + m_bShutDownFrontEndRequested = false; + m_bStartUpFrontEndRequested = false; + pEditString = nil; + pControlEdit = nil; + DisplayComboButtonErrMsg = false; + m_PrefsDMA = 1; + OS_Language = LANG_ENGLISH; + m_ControlMethod = CONTROL_STANDARD; + CCamera::m_bUseMouse3rdPerson = true; + m_lastWorking3DAudioProvider = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0.0f; + m_nSelectedListRow = 0; + m_nSkinsTotal = 0; + m_nPrefsAudio3DProviderIndex = -99; + m_bGameNotLoaded = true; + m_nMousePosX = m_nMouseTempPosX; + m_nMousePosY = m_nMouseTempPosY; + m_nMouseOldPosX = m_nMousePosX; + m_nMouseOldPosY = m_nMousePosY; + m_bShowMouse = true; + m_nHoverOption = HOVEROPTION_NOT_HOVERING; - if (option.onlyApplyOnEnter) - option.displayedValue = *option.value; - } - } -#endif + // TODO(Miami) + // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + m_bMenuActive = false; + m_bActivateSaveMenu = false; + m_bWantToLoad = false; + m_nMenuFadeAlpha = 0; + m_OnlySaveMenu = false; + m_fMapSize = 162.0f; + m_fMapCenterX = 320.0f; + m_fMapCenterY = 225.0f; + DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); } -int8 -CMenuManager::GetPreviousPageOption() +void +CMenuManager::SetFrontEndRenderStates(void) { -#ifndef CUSTOM_FRONTEND_OPTIONS - return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; -#else - int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0]; - - if (prevPage == -1) // Game also does same - return 0; + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +} - prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage; +void +CMenuManager::Initialise(void) +{ + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + m_AllowNavigation = false; + m_menuTransitionProgress = -50; + 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; + CPad::StopPadsShaking(); + if (!m_OnlySaveMenu) + m_nCurrScreen = MENUPAGE_NONE; + DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0); + DMAudio.Service(); + DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); + m_PrefsRadioStation = DMAudio.GetRadioInCar(); - for (int i = 0; i < NUM_MENUROWS; i++) { - if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) { - return i; - } - } + // TODO(Miami) + // DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume); + if (DMAudio.IsMP3RadioChannelAvailable()) { + if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > USERTRACK) + m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; + } else if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > WAVE) + m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9; - // Couldn't find current screen option on previous page, use default behaviour (maybe save-related screen?) - return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; -#endif + CFileMgr::SetDir(""); + //CFileMgr::SetDir(""); + PcSaveHelper.PopulateSlotInfo(); + CTimer::StartUserPause(); } -// ------ Functions not in the game/inlined ends - void CMenuManager::BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2) { @@ -619,25 +666,15 @@ void CMenuManager::DisplayHelperText() { // there was a unused static bool - static uint32 LastFlash = 0; + static PauseModeTime LastFlash = 0; int32 alpha; if (m_nHelperTextMsgId != 0 && m_nHelperTextMsgId != 1) { - - // FIX: High fps bug -#ifndef FIX_BUGS if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 10) { LastFlash = CTimer::GetTimeInMillisecondsPauseMode(); m_nHelperTextAlpha -= 2; } -#else - static float fadeAlpha = 0.0f; // To keep it precisely - if (m_nHelperTextAlpha >= 255 && fadeAlpha < 250) fadeAlpha = m_nHelperTextAlpha; - // -2 per every 33 ms (1000.f/30.f - original frame limiter fps) - fadeAlpha -= (frameTime / 33.0f) * 2.0f; - m_nHelperTextAlpha = fadeAlpha; -#endif if (m_nHelperTextAlpha < 1) ResetHelperText(); @@ -681,23 +718,23 @@ CMenuManager::DisplayHelperText() CFont::SetRightJustifyOff(); } +// --MIAMI: Done int -CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress) +CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress, float spacing) { CRGBA color; float maxBarHeight; int lastActiveBarX = 0; float curBarX = 0.0f; - float spacing = SCREEN_SCALE_X(10.0f); for (int i = 0; i < 16; i++) { curBarX = i * rectSize/16.0f + x; if (i / 16.0f + 1 / 32.0f < progress) { - color = CRGBA(255, 217, 106, FadeIn(255)); + color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255)); lastActiveBarX = curBarX; } else - color = CRGBA(185, 120, 0, FadeIn(255)); + color = CRGBA(SLIDEROFF_COLOR.r, SLIDEROFF_COLOR.g, SLIDEROFF_COLOR.b, FadeIn(255)); maxBarHeight = Max(mostLeftBarSize, mostRightBarSize); @@ -713,6 +750,7 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR return lastActiveBarX; } +// TODO(Miami) void CMenuManager::DoSettingsBeforeStartingAGame() { @@ -720,76 +758,82 @@ CMenuManager::DoSettingsBeforeStartingAGame() if (m_PrefsVsyncDisp != m_PrefsVsync) m_PrefsVsync = m_PrefsVsyncDisp; + DMAudio.DestroyAllGameCreatedEntities(); DMAudio.Service(); + m_bShutDownFrontEndRequested = true; m_bWantToRestart = true; - - ShutdownJustMenu(); - UnloadTextures(); DMAudio.SetEffectsFadeVol(0); DMAudio.SetMusicFadeVol(0); + SwitchMenuOnAndOff(); DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); } void -CMenuManager::Draw() +CMenuManager::DrawStandardMenus(bool drawCurrScreen) { + float nextYToUse = 0.0f; // III leftover, set but unused in VC +#ifdef PS2_LIKE_MENU + bool itemsAreSelectable = !bottomBarActive; +#else + bool itemsAreSelectable = true; +#endif CFont::SetBackgroundOff(); CFont::SetPropOn(); CFont::SetCentreOff(); CFont::SetJustifyOn(); - CFont::SetBackGroundOnlyTextOn(); -#ifdef GTA3_1_1_PATCH - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); - CFont::SetRightJustifyOn(); - CFont::SetFontStyle(FONT_HEADING); - CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f)); - CFont::SetWrapx(SCREEN_WIDTH); - CFont::SetRightJustifyWrap(0.0f); - strcpy(gString, "V1.1"); - AsciiToUnicode(gString, gUString); - CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString); -#endif - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); + CFont::SetBackGroundOnlyTextOff(); + + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENU_UNK_WIDTH)); + CFont::SetCentreSize(SCREEN_WIDTH); switch (m_nCurrScreen) { + case MENUPAGE_CHOOSE_LOAD_SLOT: + case MENUPAGE_CHOOSE_DELETE_SLOT: + case MENUPAGE_CHOOSE_SAVE_SLOT: + 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(49, 101, 148, FadeIn(130))); + break; + /* + // TODO(Miami) + case MENUPAGE_SOUND_SETTINGS: + PrintSoundSettings(); + break; + */ case MENUPAGE_STATS: PrintStats(); break; case MENUPAGE_BRIEFS: PrintBriefs(); break; -#ifdef MENU_MAP - case MENUPAGE_MAP: - PrintMap(); - break; -#endif } - // Header height isn't accounted, we will add that later. - float nextYToUse = 40.0f; - // Page name -#ifdef PS2_SAVE_DIALOG - if(!m_bRenderGameInMenu) -#endif if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') { - + PREPARE_MENU_HEADER - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); - // Weird place to put that. - nextYToUse += 24.0f + 10.0f; + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); } - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_X), MENU_Y(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_Y)); - CFont::SetRightJustifyOff(); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); - // Label wchar *str; if (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) { + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENULABEL_X_MARGIN)); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENULABEL_WIDTH)); + CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + 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))); + switch (m_nCurrScreen) { case MENUPAGE_LOAD_SLOT_CONFIRM: if (m_bGameNotLoaded) @@ -797,8 +841,13 @@ CMenuManager::Draw() else str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName); break; + case MENUPAGE_DELETE_SLOT_CONFIRM: + str = TheText.Get(aScreens[MENUPAGE_DELETE_SLOT_CONFIRM].m_aEntries[0].m_EntryName); + break; case MENUPAGE_SAVE_OVERWRITE_CONFIRM: - if (Slots[m_nCurrSaveSlot + 1] == SLOT_EMPTY) + if (Slots[m_nCurrSaveSlot + 1] == SLOT_OK) + str = TheText.Get("FESZ_QO"); + else if (Slots[m_nCurrSaveSlot + 1] == SLOT_CORRUPTED) str = TheText.Get("FESZ_QZ"); else str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName); @@ -814,129 +863,18 @@ CMenuManager::Draw() break; } -#ifdef FIX_BUGS - // Label is wrapped from right by StretchX(40)px, but wrapped from left by 40px. And this is only place R* didn't use StretchX in here. - CFont::PrintString(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN), MENU_Y(MENUACTION_POS_Y), str); -#else - CFont::PrintString(MENU_X_MARGIN, MENUACTION_POS_Y, str); -#endif + 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(SCREEN_SCALE_X(MENU_UNK_WIDTH)); } - CFont::SetCentreSize(SCREEN_WIDTH); + if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + if (m_bWaitingForNewKeyBind) + itemsAreSelectable = false; -#ifdef PS2_LIKE_MENU - bool itemsAreSelectable = !bottomBarActive; -#else - bool itemsAreSelectable = true; -#endif - int lineHeight; - int headerHeight; - int columnWidth; - switch (m_nCurrScreen) { - case MENUPAGE_STATS: - case MENUPAGE_BRIEFS: - columnWidth = 320; - headerHeight = 240; - lineHeight = 24; - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); - CFont::SetCentreOn(); - break; - case MENUPAGE_SOUND_SETTINGS: - case MENUPAGE_GRAPHICS_SETTINGS: - case MENUPAGE_MULTIPLAYER_CREATE: - case MENUPAGE_SKIN_SELECT_OLD: - case MENUPAGE_CONTROLLER_PC_OLD1: - case MENUPAGE_CONTROLLER_PC_OLD2: - case MENUPAGE_CONTROLLER_PC_OLD3: - case MENUPAGE_CONTROLLER_PC_OLD4: - case MENUPAGE_CONTROLLER_DEBUG: - case MENUPAGE_MOUSE_CONTROLS: - columnWidth = 50; - headerHeight = 0; - lineHeight = 20; - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = MEDIUMTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = MEDIUMTEXT_Y_SCALE)); - CFont::SetRightJustifyOff(); - break; - case MENUPAGE_CHOOSE_LOAD_SLOT: - case MENUPAGE_CHOOSE_DELETE_SLOT: - case MENUPAGE_CHOOSE_SAVE_SLOT: - columnWidth = 120; - headerHeight = 38; - lineHeight = 20; - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE)); - CFont::SetRightJustifyOff(); - break; - case MENUPAGE_NEW_GAME_RELOAD: - case MENUPAGE_LOAD_SLOT_CONFIRM: - case MENUPAGE_DELETE_SLOT_CONFIRM: - case MENUPAGE_SAVE_OVERWRITE_CONFIRM: - case MENUPAGE_EXIT: - columnWidth = 320; - headerHeight = 60; - lineHeight = 24; - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); - CFont::SetCentreOn(); - break; - case MENUPAGE_START_MENU: - columnWidth = 320; - headerHeight = 140; - lineHeight = 24; - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); - CFont::SetCentreOn(); - break; - case MENUPAGE_PAUSE_MENU: - columnWidth = 320; - headerHeight = 117; - lineHeight = 24; - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); - CFont::SetCentreOn(); - break; -#ifdef PS2_SAVE_DIALOG - case MENUPAGE_SAVE: - columnWidth = 180; - headerHeight = 60; - lineHeight = 24; - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); - break; -#endif - default: - columnWidth = 320; - headerHeight = 40; - lineHeight = 24; - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); - CFont::SetCentreOn(); - break; + DrawControllerScreenExtraText(-8.0f, MENU_X_LEFT_ALIGNED(350), MENU_DEFAULT_LINE_HEIGHT); } -#ifdef PS2_LIKE_MENU - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); -#endif - - switch (m_nCurrScreen) { - case MENUPAGE_CONTROLLER_PC_OLD1: - case MENUPAGE_CONTROLLER_PC_OLD2: - case MENUPAGE_CONTROLLER_PC_OLD3: - case MENUPAGE_CONTROLLER_PC_OLD4: - case MENUPAGE_CONTROLLER_DEBUG: - if (m_bWaitingForNewKeyBind) - itemsAreSelectable = false; - - DrawControllerScreenExtraText(nextYToUse - 8.0f, MENU_X_LEFT_ALIGNED(350), lineHeight); - break; - default: - break; - } - - float usableLineHeight = lineHeight * 0.9f; // also height of biggest bar in slider - float smallestSliderBar = lineHeight * 0.1f; bool foundTheHoveringItem = false; wchar unicodeTemp[64]; char asciiTemp[32]; @@ -947,6 +885,9 @@ CMenuManager::Draw() wchar *backTx = TheText.Get("FEDS_TB"); CFont::SetDropShadowPosition(1); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); + CFont::SetRightJustifyOff(); + CFont::SetCentreOn(); CFont::PrintString(MENU_X(60.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), backTx); CFont::SetDropShadowPosition(0); if (!CheckHover(MENU_X(30.0f), MENU_X(30.0f) + CFont::GetStringWidth(backTx), SCREEN_SCALE_FROM_BOTTOM(125.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f))) { @@ -960,473 +901,482 @@ CMenuManager::Draw() } #endif -#ifdef CUSTOM_FRONTEND_OPTIONS - static int lastOption = m_nCurrOption; -#endif + bool weHaveLabel = aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL; + uint8 section = 0; // 0: highlight trapezoid 1: texts - for (int i = 0; i < NUM_MENUROWS; ++i) { -#ifdef CUSTOM_FRONTEND_OPTIONS - bool isOptionDisabled = false; -#endif - if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { - wchar *rightText = nil; - wchar *leftText; + while (section < 2) { + for (int i = 0; i < NUM_MENUROWS; ++i) { + 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) { + CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE)); + CFont::SetDropShadowPosition(0); + } else { + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); + 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))); + } + if (aScreens[m_nCurrScreen].m_aEntries[i].m_Align == MENUALIGN_LEFT) { + CFont::SetCentreOff(); + CFont::SetRightJustifyOff(); + } else if (aScreens[m_nCurrScreen].m_aEntries[i].m_Align == MENUALIGN_RIGHT) { + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + } else { CFont::SetRightJustifyOff(); - leftText = GetNameOfSavedGame(i - 1); + CFont::SetCentreOn(); + } + if (!aScreens[m_nCurrScreen].m_aEntries[i].m_X && !aScreens[m_nCurrScreen].m_aEntries[i].m_Y) { + if (i == 0 || (i == 1 && weHaveLabel)) { + aScreens[m_nCurrScreen].m_aEntries[i].m_X = MENU_DEFAULT_CONTENT_X; + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = MENU_DEFAULT_CONTENT_Y; + + } 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; + } + } - if (Slots[i] != SLOT_EMPTY) - rightText = GetSavedGameDateAndTime(i - 1); + if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { - if (leftText[0] == '\0') { - sprintf(gString, "FEM_SL%d", i); - leftText = TheText.Get(gString); + if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) { + CFont::SetRightJustifyOff(); + + leftText = nil; + if (Slots[i] == SLOT_OK) { + leftText = GetNameOfSavedGame(i); + rightText = GetSavedGameDateAndTime(i); + } + + if (!leftText || leftText[0] == '\0') { + sprintf(gString, "FEM_SL%d", i + 1); + leftText = TheText.Get(gString); + } + } else { + leftText = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName); } - } else { - leftText = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName); - } - switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { - case MENUACTION_CHANGEMENU: { - switch (aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu) { - case MENUPAGE_MULTIPLAYER_MAP: - switch (m_SelectedMap) { - case 0: - rightText = TheText.Get("FEM_MA0"); - break; - case 1: - rightText = TheText.Get("FEM_MA1"); - break; - case 2: - rightText = TheText.Get("FEM_MA2"); - break; - case 3: - rightText = TheText.Get("FEM_MA3"); - break; - case 4: - rightText = TheText.Get("FEM_MA4"); - break; - case 5: - rightText = TheText.Get("FEM_MA5"); - break; - case 6: - rightText = TheText.Get("FEM_MA6"); - break; - case 7: - rightText = TheText.Get("FEM_MA7"); - break; - default: - break; - } + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) { + if (strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD", 8) == 0) { + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + } + } + + switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { +#ifdef LEGACY_MENU_OPTIONS + case MENUACTION_CTRLVIBRATION: + if (m_PrefsUseVibration) + rightText = TheText.Get("FEM_ON"); + else + rightText = TheText.Get("FEM_OFF"); + break; + case MENUACTION_CTRLCONFIG: + switch (CPad::GetPad(0)->Mode) { + case 0: + rightText = TheText.Get("FEC_CF1"); break; - case MENUPAGE_MULTIPLAYER_MODE: - switch (m_SelectedGameType) { - case 0: - rightText = TheText.Get("FEN_TY0"); - break; - case 1: - rightText = TheText.Get("FEN_TY1"); - break; - case 2: - rightText = TheText.Get("FEN_TY2"); - break; - case 3: - rightText = TheText.Get("FEN_TY3"); - break; - case 4: - rightText = TheText.Get("FEN_TY4"); - break; - case 5: - rightText = TheText.Get("FEN_TY5"); - break; - case 6: - rightText = TheText.Get("FEN_TY6"); - break; - case 7: - rightText = TheText.Get("FEN_TY7"); - break; - default: - break; - } + case 1: + rightText = TheText.Get("FEC_CF2"); break; - default: + case 2: + rightText = TheText.Get("FEC_CF3"); break; - } - break; - } - case MENUACTION_CTRLVIBRATION: - if (m_PrefsUseVibration) - rightText = TheText.Get("FEM_ON"); - else - rightText = TheText.Get("FEM_OFF"); - break; - case MENUACTION_CTRLCONFIG: - switch (CPad::GetPad(0)->Mode) { - case 0: - rightText = TheText.Get("FEC_CF1"); + case 3: + rightText = TheText.Get("FEC_CF4"); + break; + } break; - case 1: - rightText = TheText.Get("FEC_CF2"); +#endif + case MENUACTION_FRAMESYNC: + rightText = TheText.Get(m_PrefsVsyncDisp ? "FEM_ON" : "FEM_OFF"); break; - case 2: - rightText = TheText.Get("FEC_CF3"); + case MENUACTION_FRAMELIMIT: + rightText = TheText.Get(m_PrefsFrameLimiter ? "FEM_ON" : "FEM_OFF"); break; - case 3: - rightText = TheText.Get("FEC_CF4"); + case MENUACTION_TRAILS: + rightText = TheText.Get(CMBlur::BlurOn ? "FEM_ON" : "FEM_OFF"); break; - } - break; - case MENUACTION_CTRLDISPLAY: - if (m_DisplayControllerOnFoot) - rightText = TheText.Get("FEC_ONF"); - else - rightText = TheText.Get("FEC_INC"); - break; - case MENUACTION_FRAMESYNC: - rightText = TheText.Get(m_PrefsVsyncDisp ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_FRAMELIMIT: - rightText = TheText.Get(m_PrefsFrameLimiter ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_TRAILS: - rightText = TheText.Get(CMBlur::BlurOn ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_SUBTITLES: - rightText = TheText.Get(m_PrefsShowSubtitles ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_WIDESCREEN: + case MENUACTION_SUBTITLES: + rightText = TheText.Get(m_PrefsShowSubtitles ? "FEM_ON" : "FEM_OFF"); + break; + case MENUACTION_WIDESCREEN: #ifndef ASPECT_RATIO_SCALE - rightText = TheText.Get(m_PrefsUseWideScreen ? "FEM_ON" : "FEM_OFF"); + rightText = TheText.Get(m_PrefsUseWideScreen ? "FEM_ON" : "FEM_OFF"); #else - switch (m_PrefsUseWideScreen) { - case AR_AUTO: - sprintf(asciiTemp, "AUTO"); - break; - case AR_4_3: - sprintf(asciiTemp, "4:3"); + switch (m_PrefsUseWideScreen) { + case AR_AUTO: + sprintf(asciiTemp, "AUTO"); + break; + case AR_4_3: + sprintf(asciiTemp, "4:3"); + break; + case AR_16_9: + sprintf(asciiTemp, "16:9"); + break; + } + + AsciiToUnicode(asciiTemp, unicodeTemp); + rightText = unicodeTemp; +#endif break; - case AR_16_9: - sprintf(asciiTemp, "16:9"); + + case MENUACTION_MUSICVOLUME: + case MENUACTION_SFXVOLUME: + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) + rightText = TheText.Get("FEA_NAH"); + break; - } + case MENUACTION_RADIO: + if (m_PrefsRadioStation > USERTRACK) + break; - AsciiToUnicode(asciiTemp, unicodeTemp); - rightText = unicodeTemp; + sprintf(gString, "FEA_FM%d", m_PrefsRadioStation); + rightText = TheText.Get(gString); + break; + case MENUACTION_LEGENDS: + rightText = TheText.Get(m_PrefsShowLegends ? "FEM_ON" : "FEM_OFF"); + break; + case MENUACTION_RADARMODE: + switch (m_PrefsRadarMode) { + case 0: + rightText = TheText.Get("FED_RDM"); + break; + case 1: + rightText = TheText.Get("FED_RDB"); + break; + case 2: + rightText = TheText.Get("FEM_OFF"); + break; + } + break; + case MENUACTION_HUD: + rightText = TheText.Get(m_PrefsShowHud ? "FEM_ON" : "FEM_OFF"); +#ifdef LEGACY_MENU_OPTIONS + case MENUACTION_SETDBGFLAG: + rightText = TheText.Get(CTheScripts::IsDebugOn() ? "FEM_ON" : "FEM_OFF"); + break; + case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT: + rightText = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF"); + break; + case MENUACTION_COLLISIONPOLYS: + rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF"); + break; #endif - break; - case MENUACTION_RADIO: - if (m_PrefsRadioStation > USERTRACK) + case MENUACTION_SHOWHEADBOB: + rightText = TheText.Get(TheCamera.m_bHeadBob ? "FEM_ON" : "FEM_OFF"); + break; + case MENUACTION_INVVERT: + rightText = TheText.Get(MousePointerStateHelper.bInvertVertically ? "FEM_OFF" : "FEM_ON"); break; + case MENUACTION_SCREENRES: + AsciiToUnicode(_psGetVideoModeList()[m_nDisplayVideoMode], unicodeTemp); + rightText = unicodeTemp; - sprintf(gString, "FEA_FM%d", m_PrefsRadioStation); - rightText = TheText.Get(gString); - break; - case MENUACTION_SETDBGFLAG: - rightText = TheText.Get(CTheScripts::IsDebugOn() ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT: - rightText = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_PEDROADGROUPS: - rightText = TheText.Get(gbShowPedRoadGroups ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_CARROADGROUPS: - rightText = TheText.Get(gbShowCarRoadGroups ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_COLLISIONPOLYS: - rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_SHOWCULL: - rightText = TheText.Get(gbShowCullZoneDebugStuff ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_SHOWHEADBOB: - rightText = TheText.Get(TheCamera.m_bHeadBob ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_INVVERT: - rightText = TheText.Get(MousePointerStateHelper.bInvertVertically ? "FEM_OFF" : "FEM_ON"); - break; - case MENUACTION_SCREENRES: - AsciiToUnicode(_psGetVideoModeList()[m_nDisplayVideoMode], unicodeTemp); - rightText = unicodeTemp; - break; - case MENUACTION_AUDIOHW: - if (m_nPrefsAudio3DProviderIndex == -1) - rightText = TheText.Get("FEA_NAH"); - else { - char *provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); - - if (!strcmp(strupr(provider), "DIRECTSOUND3D HARDWARE SUPPORT")) { - strcpy(provider, "DSOUND3D HARDWARE SUPPORT"); - } else if (!strcmp(strupr(provider), "DIRECTSOUND3D SOFTWARE EMULATION")) { - strcpy(provider, "DSOUND3D SOFTWARE EMULATION"); + if (!m_bGameNotLoaded) { + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } - AsciiToUnicode(provider, unicodeTemp); + break; +#ifdef IMPROVED_VIDEOMODE + case MENUACTION_SCREENMODE: + if (m_nSelectedScreenMode == 0) + sprintf(asciiTemp, "FULLSCREEN"); + else + sprintf(asciiTemp, "WINDOWED"); + + AsciiToUnicode(asciiTemp, unicodeTemp); rightText = unicodeTemp; + break; +#endif + case MENUACTION_AUDIOHW: + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) + rightText = TheText.Get("FEA_NAH"); + else if (m_nPrefsAudio3DProviderIndex == -1) + rightText = TheText.Get("FEA_ADP"); + else { + char* provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex); + + if (!strcmp(strupr(provider), "DIRECTSOUND3D HARDWARE SUPPORT")) { + strcpy(provider, "DSOUND3D HARDWARE SUPPORT"); + } + else if (!strcmp(strupr(provider), "DIRECTSOUND3D SOFTWARE EMULATION")) { + strcpy(provider, "DSOUND3D SOFTWARE EMULATION"); + } + AsciiToUnicode(provider, unicodeTemp); + rightText = unicodeTemp; + } + break; + case MENUACTION_SPEAKERCONF: { + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) + rightText = TheText.Get("FEA_NAH"); + else { + switch (m_PrefsSpeakers) { + case 0: + rightText = TheText.Get("FEA_2SP"); + break; + case 1: + rightText = TheText.Get("FEA_EAR"); + break; + case 2: + rightText = TheText.Get("FEA_4SP"); + break; + } + } + break; } - break; - case MENUACTION_SPEAKERCONF: { - if (m_nPrefsAudio3DProviderIndex == -1) - rightText = TheText.Get("FEA_NAH"); - else { - switch (m_PrefsSpeakers) { - case 0: - rightText = TheText.Get("FEA_2SP"); + case MENUACTION_CTRLMETHOD: { + switch (m_ControlMethod) { + case CONTROL_STANDARD: + leftText = TheText.Get("FET_STI"); break; - case 1: - rightText = TheText.Get("FEA_EAR"); - break; - case 2: - rightText = TheText.Get("FEA_4SP"); + case CONTROL_CLASSIC: + leftText = TheText.Get("FET_CTI"); break; } + break; } - break; - } - case MENUACTION_CTRLMETHOD: { - switch (m_ControlMethod) { - case 0: - leftText = TheText.Get("FET_SCN"); + case MENUACTION_DYNAMICACOUSTIC: + rightText = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF"); break; - case 1: - leftText = TheText.Get("FET_CCN"); + case MENUACTION_MOUSESTEER: + rightText = TheText.Get(CVehicle::m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON"); + if (m_ControlMethod == CONTROL_CLASSIC) { + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + } break; - } - break; - } - case MENUACTION_DYNAMICACOUSTIC: - rightText = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF"); - break; - case MENUACTION_MOUSESTEER: - rightText = TheText.Get(CVehicle::m_bDisableMouseSteering ? "FEM_OFF" : "FEM_ON"); - break; -#ifdef CUSTOM_FRONTEND_OPTIONS - case MENUACTION_TRIGGERFUNC: - FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; - if (m_nCurrScreen == option.screen && i == option.screenOptionOrder) { - leftText = (wchar*)option.leftText; - if (option.type == FEOPTION_SELECT) { - if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) - option.displayedValue = 0; - - rightText = (wchar*)option.rightTexts[option.displayedValue]; - - } else if (option.type == FEOPTION_DYNAMIC) { - if (option.drawFunc) { - rightText = option.drawFunc(&isOptionDisabled); - } + case MENUACTION_MP3VOLUMEBOOST: + if (!DMAudio.IsMP3RadioChannelAvailable()) { + rightText = TheText.Get("FEA_NM3"); } - } else - assert(0 && "Custom frontend options is borked"); - - break; -#endif - } + break; + } - float nextItemY = headerHeight + nextYToUse; - float bitAboveNextItemY = nextItemY - 2.0f; - int nextYToCheck = bitAboveNextItemY; - - if (!foundTheHoveringItem) { - for (int rowToCheck = aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL; rowToCheck < NUM_MENUROWS; ++rowToCheck) { - if(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_NOTHING) - break; + // Highlight trapezoid + if (drawCurrScreen && i == m_nCurrOption && itemsAreSelectable && section == 0) { - int extraOffset = 0; - if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_RADIO) - extraOffset = MENURADIO_ICON_SCALE; + int leftXMax, rightXMin; + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); + wchar *curOptionName = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName); + float curOptionWidth = CFont::GetStringWidth(curOptionName, true); - // There were many unused codes in here to calculate how much space will texts gonna take. + if (CFont::Details.centre) { + leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth / 2.f); + rightXMin = Min(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(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; + } + CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); + + int action = aScreens[m_nCurrScreen].m_aEntries[i].m_Action; + int saveSlot = aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot; + if (rightText || action == MENUACTION_DRAWDIST || action == MENUACTION_BRIGHTNESS || action == MENUACTION_MUSICVOLUME || + action == MENUACTION_SFXVOLUME || action == MENUACTION_MP3VOLUMEBOOST || action == MENUACTION_MOUSESENS || + saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8) { + rightXMin = 600; + leftXMax = 40; + } - // FIX: nextYToCheck already starts with Y - 2, let's sync it with green bar bounds. -#ifdef FIX_BUGS - if (m_nMousePosY > MENU_Y(nextYToCheck) && -#else - if (m_nMousePosY > MENU_Y(nextYToCheck - 2) && -#endif - m_nMousePosY < MENU_Y((nextYToCheck + 2) + usableLineHeight)) { + int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y; + int topYMax = y; + uint32 bottomYMin = y + 22; + int transition = m_nOptionHighlightTransitionBlend; - static int oldOption = -99; - static int oldScreen = m_nCurrScreen; + // 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. - m_nPrevOption = rowToCheck; - if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { - m_nCurrOption = rowToCheck; - m_bShowMouse = true; + if (transition == 0) { + if (m_menuTransitionProgress == 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), + MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomLeft_x), MENU_Y(menuOptionHighlight.bottomLeft_y), SELECTIONBORDER_COLOR); } - if (oldOption != m_nCurrOption) { - if (oldScreen == m_nCurrScreen && m_bShowMouse) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); - - oldOption = m_nCurrOption; - oldScreen = m_nCurrScreen; + menuOptionHighlight.SaveCurrentCoors(); + menuOptionHighlight.topLeft_x = leftXMax - 5 - CGeneral::GetRandomNumber() % 10; + menuOptionHighlight.topLeft_y = topYMax - CGeneral::GetRandomNumber() % 7; + menuOptionHighlight.topRight_x = rightXMin + 5 + CGeneral::GetRandomNumber() % 10; + menuOptionHighlight.topRight_y = topYMax - CGeneral::GetRandomNumber() % 7; + menuOptionHighlight.bottomLeft_x = rightXMin + 5 + CGeneral::GetRandomNumber() % 10; + menuOptionHighlight.bottomLeft_y = bottomYMin + CGeneral::GetRandomNumber() % 7; + menuOptionHighlight.bottomRight_x = leftXMax - 5 - CGeneral::GetRandomNumber() % 10; + menuOptionHighlight.bottomRight_y = bottomYMin + CGeneral::GetRandomNumber() % 7; + menuOptionHighlight.UpdateMultipliers(); + menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); + } else if (transition < 255) { + menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); + if (m_menuTransitionProgress == 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), + MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomLeft_x), MENU_Y(menuOptionHighlight.bottomLeft_y), SELECTIONBORDER_COLOR); + } + } else { + m_nOptionHighlightTransitionBlend = 255; + menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend); + if (m_menuTransitionProgress == 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), + MENU_X_LEFT_ALIGNED(menuOptionHighlight.bottomLeft_x), MENU_Y(menuOptionHighlight.bottomLeft_y), SELECTIONBORDER_COLOR); } - if (oldScreen == m_nPrevScreen) - oldScreen = m_nCurrScreen; - - m_nHoverOption = HOVEROPTION_RANDOM_ITEM; - foundTheHoveringItem = true; - break; } - m_nHoverOption = HOVEROPTION_NOT_HOVERING; - nextYToCheck += extraOffset + lineHeight; - } - } - // Green bar behind selected option -#ifdef PS2_SAVE_DIALOG - if (!m_bRenderGameInMenu) + static PauseModeTime lastBlendChange = 0; + if (m_nOptionHighlightTransitionBlend <= 255) { + static uint32 blendChangeCounter = 0; + if (CTimer::GetTimeInMillisecondsPauseMode() - lastBlendChange > 20 +#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND // Dirty dirty hack + || blendChangeCounter > 20 #endif - if (i == m_nCurrOption && itemsAreSelectable) { - // We keep stretching, because we also stretch background image and we want that bar to be aligned with borders of background - CSprite2d::DrawRect(CRect(StretchX(10.0f), MENU_Y(bitAboveNextItemY), - SCREEN_STRETCH_FROM_RIGHT(11.0f), MENU_Y(usableLineHeight + nextItemY)), - CRGBA(100, 200, 50, FadeIn(50))); - } + ) { + m_nOptionHighlightTransitionBlend += 50; + lastBlendChange = CTimer::GetTimeInMillisecondsPauseMode(); + blendChangeCounter = 0; + } + ++blendChangeCounter; + } + } - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90))); + if (section != 0) { - // Button and it's shadow - for(int textLayer = 0; textLayer < 2; textLayer++) { - if (!CFont::Details.centre) - CFont::SetRightJustifyOff(); + 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); + } - float itemY = MENU_Y(textLayer + nextItemY); - float itemX = MENU_X_LEFT_ALIGNED(textLayer + columnWidth); - CFont::PrintString(itemX, itemY, leftText); - if (rightText) { - if (!CFont::Details.centre) + if (rightText) { + CFont::SetCentreOff(); CFont::SetRightJustifyOn(); - - if(textLayer == 1) - if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_RES") - && !m_bGameNotLoaded -#ifdef CUSTOM_FRONTEND_OPTIONS - || isOptionDisabled -#endif - ) - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) { + CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + CFont::SetScale(MENU_X(MEDIUMTEXT_X_SCALE), MENU_Y(MEDIUMTEXT_Y_SCALE)); + } else { + 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_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); - } - if (i == m_nCurrOption && itemsAreSelectable){ - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); - } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); - } - } + if (m_nPrefsAudio3DProviderIndex == DMAudio.GetCurrent3DProviderIndex()) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") && m_nHelperTextMsgId == 1) + ResetHelperText(); + } + if (m_nDisplayVideoMode == m_nPrefsVideoMode) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") && m_nHelperTextMsgId == 1) + ResetHelperText(); + } + if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH")) + SetHelperText(1); + } + if (m_nDisplayVideoMode != m_nPrefsVideoMode) { + if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES")) + SetHelperText(1); + } + 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 != INVALID_AUDIO_PROVIDER) { - if (m_nPrefsAudio3DProviderIndex == DMAudio.GetCurrent3DProviderIndex()) { - if(!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") && m_nHelperTextMsgId == 1) - ResetHelperText(); - } - if (m_nDisplayVideoMode == m_nPrefsVideoMode) { - if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") && m_nHelperTextMsgId == 1) - ResetHelperText(); - } - if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { - if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH")) - SetHelperText(1); - } - if (m_nDisplayVideoMode != m_nPrefsVideoMode) { - if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES")) - SetHelperText(1); - } - 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 != -1) { + m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); + SetHelperText(3); + } + } + if (m_nDisplayVideoMode != m_nPrefsVideoMode) { + if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0 + && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { + 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_GRAPHICS_SETTINGS) { + m_nSelectedScreenMode = m_nPrefsWindowed; + } + } +#endif - m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); - SetHelperText(3); - } - } - if (m_nDisplayVideoMode != m_nPrefsVideoMode) { - if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0 - && m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) { - m_nDisplayVideoMode = m_nPrefsVideoMode; - SetHelperText(3); - } - } + // 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 != INVALID_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 != INVALID_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; + } -#ifdef CUSTOM_FRONTEND_OPTIONS - if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) { - FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu]; - if (option.onlyApplyOnEnter && m_nCurrOption != i) - option.displayedValue = *option.value; + nextYToUse = MENU_Y(150.f); // TODO(Miami): Temp - if (m_nCurrOption != lastOption && lastOption == i) { - FrontendOption &oldOption = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[lastOption].m_TargetMenu]; - if (oldOption.type == FEOPTION_DYNAMIC) - oldOption.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); - } - } -#endif + nextYToUse += MENU_DEFAULT_LINE_HEIGHT * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText); - // Sliders - int lastActiveBarX; - switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { - case MENUACTION_BRIGHTNESS: - ProcessSlider(m_PrefsBrightness / 512.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_DRAWDIST: - ProcessSlider((m_PrefsLOD - 0.8f) * 1.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_MUSICVOLUME: - ProcessSlider(m_PrefsMusicVolume / 128.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH); - break; - case MENUACTION_SFXVOLUME: - ProcessSlider(m_PrefsSfxVolume / 128.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, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, MENU_X_LEFT_ALIGNED(200.0f), SCREEN_WIDTH); - break; - } + // TODO(Miami): Remove here after audio page is done + // Radio icons + if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) { + 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); - // 60.0 is silly - nextYToUse += lineHeight * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText); - - // Radio icons - if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) { - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO1], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO2], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO5], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO7], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO8], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO3], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO4], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO6], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7); - ProcessRadioIcon(m_aFrontEndSprites[FE_RADIO9], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8); - - if (DMAudio.IsMP3RadioChannelAvailable()) - ProcessRadioIcon(m_aMenuSprites[MENUSPRITE_MP3LOGO], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9); - - nextYToUse += 70.0f; + nextYToUse += 70.0f; + } + } } } + section++; } -#ifdef CUSTOM_FRONTEND_OPTIONS - lastOption = m_nCurrOption; -#endif - + // TODO(Miami) + /* switch (m_nCurrScreen) { - case MENUPAGE_CONTROLLER_SETTINGS: - case MENUPAGE_SOUND_SETTINGS: - case MENUPAGE_GRAPHICS_SETTINGS: - case MENUPAGE_SKIN_SELECT: - case MENUPAGE_CONTROLLER_PC: - case MENUPAGE_MOUSE_CONTROLS: - DisplayHelperText(); - break; + case MENUPAGE_STATS: + case MENUPAGE_CONTROLLER_PC: + case MENUPAGE_SOUND_SETTINGS: + case MENUPAGE_GRAPHICS_SETTINGS: + case MENUPAGE_MOUSE_CONTROLS: + DisplayHelperText(nil); + break; + case MENUPAGE_OPTIONS: + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LOADRADIO) + DisplayHelperText("FEA_NAH"); + break; } + */ - if (m_nCurrScreen == MENUPAGE_CONTROLLER_SETTINGS) - PrintController(); - else if (m_nCurrScreen == MENUPAGE_SKIN_SELECT_OLD) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(180), MENU_Y(98), MENU_X_LEFT_ALIGNED(230), MENU_Y(123)), CRGBA(255, 255, 255, FadeIn(255))); - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(181), MENU_Y(99), MENU_X_LEFT_ALIGNED(229), MENU_Y(122)), CRGBA(m_PrefsPlayerRed, m_PrefsPlayerGreen, m_PrefsPlayerBlue, FadeIn(255))); + if (m_nCurrScreen == MENUPAGE_DELETING_IN_PROGRESS) { + SmallMessageScreen("FEDL_WR"); + } else if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { + SmallMessageScreen("FESZ_WR"); } - } int @@ -1434,12 +1384,14 @@ CMenuManager::GetNumOptionsCntrlConfigScreens(void) { int number = 0; switch (m_nCurrScreen) { +#ifdef LEGACY_MENU_OPTIONS case MENUPAGE_CONTROLLER_PC_OLD3: number = 2; break; case MENUPAGE_CONTROLLER_DEBUG: number = 4; break; +#endif case MENUPAGE_KEYBOARD_CONTROLS: switch (m_ControlMethod) { case CONTROL_STANDARD: @@ -1747,7 +1699,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 CFont::PrintString(nextX, nextY, seperator); nextX += CFont::GetStringWidth(seperator, true) + bindingMargin; } - static uint32 lastWaitingTextFlash = 0; + static PauseModeTime lastWaitingTextFlash = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastWaitingTextFlash > 150) { showWaitingText = !showWaitingText; lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode(); @@ -1832,7 +1784,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_IBT")); nextX = CFont::GetStringWidth(TheText.Get("FEC_IBT"), true) + spacing + nextX; } - static uint32 lastStateChange = 0; + static PauseModeTime lastStateChange = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastStateChange > 150) { waitingTextVisible = !waitingTextVisible; lastStateChange = CTimer::GetTimeInMillisecondsPauseMode(); @@ -1876,18 +1828,28 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetJustifyOn(); CFont::SetRightJustifyOff(); CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENU_UNK_WIDTH)); PREPARE_MENU_HEADER switch (m_ControlMethod) { case CONTROL_STANDARD: - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); break; case CONTROL_CLASSIC: - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), + CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255))); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X + 7.f), SCREEN_SCALE_Y(MENUHEADER_POS_Y + 7.f), + TheText.Get("FET_CTI")); + + PREPARE_MENU_HEADER + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_Y(MENUHEADER_POS_Y), TheText.Get("FET_CTI")); break; default: @@ -1974,7 +1936,7 @@ CMenuManager::DrawControllerSetupScreen() float curOptY = i * rowHeight + yStart; if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) { if (m_nPrevOption != i && m_nCurrExLayer == HOVEROPTION_LIST) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nPrevOption = i; if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { @@ -1988,7 +1950,7 @@ CMenuManager::DrawControllerSetupScreen() if (m_nMousePosX > MENU_X_LEFT_ALIGNED(0.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(370.0f)) { #endif if (m_nSelectedContSetupColumn != CONTSETUP_PED_COLUMN && m_nCurrExLayer == HOVEROPTION_LIST) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nSelectedContSetupColumn = CONTSETUP_PED_COLUMN; #ifdef FIX_BUGS @@ -1997,7 +1959,7 @@ CMenuManager::DrawControllerSetupScreen() } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(370.0f) && m_nMousePosX < SCREEN_WIDTH) { #endif if (m_nSelectedContSetupColumn != CONTSETUP_VEHICLE_COLUMN && m_nCurrExLayer == HOVEROPTION_LIST) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN; } @@ -2064,6 +2026,10 @@ void CMenuManager::DrawFrontEnd() { CFont::SetAlphaFade(255.0f); + CSprite2d::InitPerFrame(); + CFont::InitPerFrame(); + SetFrontEndRenderStates(); + m_NoEmptyBinding = true; #ifdef PS2_LIKE_MENU if (m_nCurrScreen == MENUPAGE_NONE) { @@ -2107,63 +2073,15 @@ CMenuManager::DrawFrontEnd() if (m_nCurrOption == 0 && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) m_nCurrOption = 1; -#ifdef PS2_SAVE_DIALOG - if(m_bRenderGameInMenu) - DrawFrontEndSaveZone(); - else -#endif - DrawFrontEndNormal(); - - PrintErrorMessage(); -} - -#ifdef PS2_SAVE_DIALOG -void -CMenuManager::DrawFrontEndSaveZone() -{ - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); - - // Not original dimensions, have been changed to fit PC screen & PC menu layout. - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(50.0f), MENU_X_RIGHT_ALIGNED(30.0f), SCREEN_SCALE_FROM_BOTTOM(50.0f)), CRGBA(0, 0, 0, 175)); - - m_nMenuFadeAlpha = 255; - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - Draw(); - - CFont::DrawFonts(); - - // Draw mouse - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - if (m_bShowMouse) { - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - - CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f)); - CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f)); + if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255) + bMenuChangeOngoing = false; - mouse.Translate(m_nMousePosX, m_nMousePosY); - shad.Translate(m_nMousePosX, m_nMousePosY); - if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); - }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); - } - } + DrawBackground(false); } -#endif #ifdef PS2_LIKE_MENU void -CMenuManager::DrawFrontEndNormal() +CMenuManager::DrawBackground() { CSprite2d::InitPerFrame(); CFont::InitPerFrame(); @@ -2280,7 +2198,7 @@ CMenuManager::DrawFrontEndNormal() DrawControllerSetupScreen(); break; default: - Draw(); + DrawStandardMenus(); break; } @@ -2343,168 +2261,191 @@ CMenuManager::DrawFrontEndNormal() mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); } } } #else + +// --MIAMI: Done except commented things void -CMenuManager::DrawFrontEndNormal() +CMenuManager::DrawBackground(bool transitionCall) { - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + if (!m_bSpritesLoaded) + return; - LoadSplash(nil); - - eMenuSprites previousSprite; - if (m_nMenuFadeAlpha < 255) { - switch (m_nPrevScreen) { + SetFrontEndRenderStates(); + + if (m_menuTransitionProgress < 255) { + CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255)); + } + + if (m_nMenuFadeAlpha != 0) { + + if (m_nMenuFadeAlpha < 255) { + + menuBg.Translate(m_nMenuFadeAlpha); + SetFrontEndRenderStates(); + 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(); + + // Left border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), 0.0f, SCREEN_HEIGHT, + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); + + // Top border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), SCREEN_WIDTH, 0.0f, 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); + + // Bottom border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), CRGBA(0, 0, 0, 255)); + + // Right border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + 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_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(); + + // Left border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), 0.0f, SCREEN_HEIGHT, + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); + + // Top border + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), + SCREEN_STRETCH_X(menuBg.topLeft_x), SCREEN_STRETCH_Y(menuBg.topLeft_y), SCREEN_WIDTH, 0.0f, 0.0f, 0.0f, CRGBA(0, 0, 0, 255)); + + // Bottom border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + SCREEN_STRETCH_X(menuBg.bottomLeft_x), SCREEN_STRETCH_Y(menuBg.bottomLeft_y), CRGBA(0, 0, 0, 255)); + + // Right border + CSprite2d::Draw2DPolygon(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_STRETCH_X(menuBg.bottomRight_x), SCREEN_STRETCH_Y(menuBg.bottomRight_y), + SCREEN_WIDTH, 0.0f, SCREEN_STRETCH_X(menuBg.topRight_x), SCREEN_STRETCH_Y(menuBg.topRight_y), CRGBA(0, 0, 0, 255)); + } + } else { + menuBg.SaveCurrentCoors(); + switch (m_nCurrScreen) { case MENUPAGE_STATS: - case MENUPAGE_START_MENU: - case MENUPAGE_PAUSE_MENU: - previousSprite = MENUSPRITE_MAINMENU; - break; - case MENUPAGE_NEW_GAME: - case MENUPAGE_CHOOSE_LOAD_SLOT: - case MENUPAGE_CHOOSE_DELETE_SLOT: - case MENUPAGE_NEW_GAME_RELOAD: - case MENUPAGE_LOAD_SLOT_CONFIRM: - case MENUPAGE_DELETE_SLOT_CONFIRM: - case MENUPAGE_EXIT: - previousSprite = MENUSPRITE_SINGLEPLAYER; + menuBg.topLeft_x = 70.0f; + menuBg.topLeft_y = 75.0f; + menuBg.topRight_x = 550.0f; + menuBg.topRight_y = 16.0f; + menuBg.bottomLeft_x = 74.0f; + menuBg.bottomLeft_y = 354.0f; + menuBg.bottomRight_x = 581.0f; + menuBg.bottomRight_y = 340.0f; break; - case MENUPAGE_MULTIPLAYER_MAIN: - previousSprite = MENUSPRITE_MULTIPLAYER; + case MENUPAGE_SOUND_SETTINGS: + 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 = 438.0f; + menuBg.bottomRight_x = 610.0f; + menuBg.bottomRight_y = 410.0f; break; - case MENUPAGE_MULTIPLAYER_MAP: - case MENUPAGE_MULTIPLAYER_FIND_GAME: case MENUPAGE_SKIN_SELECT: case MENUPAGE_KEYBOARD_CONTROLS: - case MENUPAGE_MOUSE_CONTROLS: - previousSprite = MENUSPRITE_FINDGAME; - break; - case MENUPAGE_MULTIPLAYER_CONNECTION: - case MENUPAGE_MULTIPLAYER_MODE: - previousSprite = MENUSPRITE_CONNECTION; + menuBg.topLeft_x = 14.0f; + menuBg.topLeft_y = 39.0f; + menuBg.topRight_x = 636.0f; + menuBg.topRight_y = 29.0f; + menuBg.bottomLeft_x = 15.0f; + menuBg.bottomLeft_y = 426.0f; + menuBg.bottomRight_x = 630.0f; + menuBg.bottomRight_y = 398.0f; break; - case MENUPAGE_MULTIPLAYER_CREATE: - previousSprite = MENUSPRITE_HOSTGAME; - break; - case MENUPAGE_SKIN_SELECT_OLD: - case MENUPAGE_OPTIONS: - previousSprite = MENUSPRITE_PLAYERSET; + case MENUPAGE_BRIEFS: + case MENUPAGE_GRAPHICS_SETTINGS: + case MENUPAGE_MAP: + case MENUPAGE_CHOOSE_LOAD_SLOT: + case MENUPAGE_CHOOSE_DELETE_SLOT: + case MENUPAGE_CHOOSE_SAVE_SLOT: + case MENUPAGE_MOUSE_CONTROLS: + 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; default: - previousSprite = MENUSPRITE_MAINMENU; + menuBg.topLeft_x = CGeneral::GetRandomNumber() % 40 + 65; + menuBg.topLeft_y = CGeneral::GetRandomNumber() % 40 + 21; + menuBg.topRight_x = CGeneral::GetRandomNumber() % 40 + 568; + menuBg.topRight_y = CGeneral::GetRandomNumber() % 40 + 44; + menuBg.bottomLeft_x = CGeneral::GetRandomNumber() % 40 + 36; + menuBg.bottomLeft_y = CGeneral::GetRandomNumber() % 40 + 382; + menuBg.bottomRight_x = CGeneral::GetRandomNumber() % 40 + 593; + menuBg.bottomRight_y = CGeneral::GetRandomNumber() % 40 + 342; break; } - - if (m_nPrevScreen == m_nCurrScreen) - CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255 - m_nMenuFadeAlpha)); - else - m_aMenuSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255 - m_nMenuFadeAlpha)); - } - - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); - eMenuSprites currentSprite = MENUSPRITE_MAINMENU; // actually uninitialized - switch (m_nCurrScreen) { - case MENUPAGE_STATS: - case MENUPAGE_START_MENU: - case MENUPAGE_PAUSE_MENU: - currentSprite = MENUSPRITE_MAINMENU; - break; - case MENUPAGE_NEW_GAME: - case MENUPAGE_CHOOSE_LOAD_SLOT: - case MENUPAGE_CHOOSE_DELETE_SLOT: - case MENUPAGE_NEW_GAME_RELOAD: - case MENUPAGE_LOAD_SLOT_CONFIRM: - case MENUPAGE_DELETE_SLOT_CONFIRM: - case MENUPAGE_EXIT: - currentSprite = MENUSPRITE_SINGLEPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAIN: - currentSprite = MENUSPRITE_MULTIPLAYER; - break; - case MENUPAGE_MULTIPLAYER_MAP: - case MENUPAGE_MULTIPLAYER_FIND_GAME: - case MENUPAGE_SKIN_SELECT: - case MENUPAGE_KEYBOARD_CONTROLS: - case MENUPAGE_MOUSE_CONTROLS: - currentSprite = MENUSPRITE_FINDGAME; - break; - case MENUPAGE_MULTIPLAYER_CONNECTION: - case MENUPAGE_MULTIPLAYER_MODE: - currentSprite = MENUSPRITE_CONNECTION; - break; - case MENUPAGE_MULTIPLAYER_CREATE: - currentSprite = MENUSPRITE_HOSTGAME; - break; - case MENUPAGE_SKIN_SELECT_OLD: - case MENUPAGE_OPTIONS: - currentSprite = MENUSPRITE_PLAYERSET; - break; + menuBg.UpdateMultipliers(); + if (m_menuTransitionProgress == 255) + m_nOptionHighlightTransitionBlend = 0; } - if (m_nMenuFadeAlpha < 255) { - - // Famous transparent menu bug -#ifdef FIX_BUGS - static float fadeAlpha = 0.0f; - if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f; - - // +20 per every 33 ms (1000.f/30.f - original frame limiter fps) - fadeAlpha += (frameTime) * 20.f / 33.f; - m_nMenuFadeAlpha = fadeAlpha; -#else - static uint32 LastFade = 0; + static PauseModeTime LastFade = 0; + static uint8 forceFadeInCounter = 0; - if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){ + if (m_nMenuFadeAlpha >= 255) { + if (m_nMenuFadeAlpha > 255) + m_nMenuFadeAlpha = 255; + } else { + 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); LastFade = CTimer::GetTimeInMillisecondsPauseMode(); } -#endif - - if (m_nMenuFadeAlpha > 255){ - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); - } else { - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha)); - } - } else { - m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); - // TODO: what is this? waiting mouse? - if(field_518 == 4){ - if(m_nHoverOption == HOVEROPTION_3 || m_nHoverOption == HOVEROPTION_4 || - m_nHoverOption == HOVEROPTION_5 || m_nHoverOption == HOVEROPTION_6 || m_nHoverOption == HOVEROPTION_7) - - field_518 = 2; - else - field_518 = 1; - } + forceFadeInCounter++; } - // GTA LOGO - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_PAUSE_MENU) { - if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - m_aMenuSprites[MENUSPRITE_GTA3LOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), MENU_Y(70.0f), MENU_X_LEFT_ALIGNED(435.0f), MENU_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255))); - else - m_aMenuSprites[MENUSPRITE_GTALOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), MENU_Y(40.0f), MENU_X_LEFT_ALIGNED(415.0f), MENU_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255))); + if (!transitionCall && m_menuTransitionProgress == 255) { + int actualAlpha = m_nMenuFadeAlpha; + if (actualAlpha < 255) { + int actualScreen = m_nCurrScreen; + SetFrontEndRenderStates(); + m_nCurrScreen = m_nPrevScreen; + m_nMenuFadeAlpha = 255 - m_nMenuFadeAlpha; + switch (m_nCurrScreen) { + case MENUPAGE_SKIN_SELECT: + CMenuManager::DrawPlayerSetupScreen(); + break; + case MENUPAGE_KEYBOARD_CONTROLS: + CMenuManager::DrawControllerSetupScreen(); + break; + case MENUPAGE_OUTRO: + CMenuManager::DrawQuitGameScreen(); + break; + default: + CMenuManager::DrawStandardMenus(false); + break; + } + m_nCurrScreen = actualScreen; + m_nMenuFadeAlpha = actualAlpha; + } } - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); switch (m_nCurrScreen) { case MENUPAGE_SKIN_SELECT: DrawPlayerSetupScreen(); @@ -2512,35 +2453,47 @@ CMenuManager::DrawFrontEndNormal() case MENUPAGE_KEYBOARD_CONTROLS: DrawControllerSetupScreen(); break; + case MENUPAGE_OUTRO: + CMenuManager::DrawQuitGameScreen(); + break; default: - Draw(); + DrawStandardMenus(true); break; } CFont::DrawFonts(); + SetFrontEndRenderStates(); - // Draw mouse - RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - if (m_bShowMouse) { - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + if (m_nCurrScreen != MENUPAGE_OUTRO) + if (m_menuTransitionProgress == 255) { + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(27.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255)); + } else { + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(27.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255))); + } - CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f)); - CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f)); + if (m_ShowEmptyBindingError) { + static PauseModeTime lastBindingError = CTimer::GetTimeInMillisecondsPauseMode(); + static bool bindingErrorShown = false; + if (bindingErrorShown) { + lastBindingError = CTimer::GetTimeInMillisecondsPauseMode(); + bindingErrorShown = false; + } + SmallMessageScreen("FEC_ERI"); + CFont::DrawFonts(); + if (CTimer::GetTimeInMillisecondsPauseMode() - lastBindingError > 4000) { + m_ShowEmptyBindingError = false; + bindingErrorShown = true; + } + } + + 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)); mouse.Translate(m_nMousePosX, m_nMousePosY); shad.Translate(m_nMousePosX, m_nMousePosY); - if(field_518 == 4){ - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255)); - }else{ - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); - m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); - } + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50)); + m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255)); } } #endif @@ -2555,8 +2508,8 @@ CMenuManager::DrawPlayerSetupScreen() CFont::SetJustifyOn(); CFont::SetRightJustifyOff(); CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENU_UNK_WIDTH)); PREPARE_MENU_HEADER @@ -2701,7 +2654,7 @@ CMenuManager::DrawPlayerSetupScreen() SaveSettings(); } } else { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nCurrExLayer = HOVEROPTION_LIST; m_nSelectedListRow = rowIdx; m_nHoverOption = HOVEROPTION_NOT_HOVERING; @@ -2781,21 +2734,21 @@ CMenuManager::DrawPlayerSetupScreen() // 2 - leaves gap between button and scrollbar if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP) { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(-20.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)), CRGBA(255, 255, 255, FadeIn(255))); #endif } else { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), + m_aFrontEndSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(-21.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)), CRGBA(255, 255, 255, FadeIn(255))); #endif @@ -2803,21 +2756,21 @@ CMenuManager::DrawPlayerSetupScreen() if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN) { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), + m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f), + m_aFrontEndSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f), MENU_X_RIGHT_ALIGNED(-20.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)), CRGBA(255, 255, 255, FadeIn(255))); #endif } else { #ifdef FIX_BUGS - m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), + m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)), CRGBA(255, 255, 255, FadeIn(255))); #else - m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f), + m_aFrontEndSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f), MENU_X_RIGHT_ALIGNED(-21.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)), CRGBA(255, 255, 255, FadeIn(255))); #endif @@ -2857,7 +2810,7 @@ CMenuManager::DrawPlayerSetupScreen() && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 26)) || m_nCurrExLayer == HOVEROPTION_BACK) { if (m_nHoverOption != HOVEROPTION_BACK) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nHoverOption = HOVEROPTION_BACK; @@ -2868,7 +2821,7 @@ CMenuManager::DrawPlayerSetupScreen() && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 26)) || m_nCurrExLayer == HOVEROPTION_USESKIN) { if (m_nHoverOption != HOVEROPTION_USESKIN) - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_nHoverOption = HOVEROPTION_USESKIN; @@ -2959,11 +2912,6 @@ CMenuManager::DrawPlayerSetupScreen() int CMenuManager::FadeIn(int alpha) { - if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS || - m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS || - m_nCurrScreen == MENUPAGE_DELETING) - return alpha; - return Min(m_nMenuFadeAlpha, alpha); } @@ -3000,12 +2948,14 @@ CMenuManager::GetStartOptionsCntrlConfigScreens() { int number = 0; switch (m_nCurrScreen) { +#ifdef LEGACY_MENU_OPTIONS case MENUPAGE_CONTROLLER_PC_OLD3: number = 34; break; case MENUPAGE_CONTROLLER_DEBUG: number = 35; break; +#endif case MENUPAGE_KEYBOARD_CONTROLS: number = 0; break; @@ -3063,11 +3013,6 @@ CMenuManager::InitialiseChangedLanguageSettings() default: break; } - -#ifdef CUSTOM_FRONTEND_OPTIONS - RemoveCustomFrontendOptions(); - CustomFrontendOptionsPopulate(); -#endif } } @@ -3077,70 +3022,57 @@ CMenuManager::LoadAllTextures() if (m_bSpritesLoaded) return; - CentreMousePointer(); - DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0); - m_nCurrOption = 0; - m_PrefsRadioStation = DMAudio.GetRadioInCar(); - - if (DMAudio.IsMP3RadioChannelAvailable()) { - if (m_PrefsRadioStation > USERTRACK) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; - } else if (m_PrefsRadioStation > CHATTERBOX) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9; - - CFileMgr::SetDir(""); - //CFileMgr::SetDir(""); + field_F0 = SCREEN_STRETCH_X(178.0f); // TODO(Miami) CTimer::Stop(); + CStreaming::MakeSpaceFor(350 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile CStreaming::ImGonnaUseStreamingMemory(); CGame::TidyUpMemory(false, true); CTxdStore::PushCurrentTxd(); - int frontendTxdSlot = CTxdStore::FindTxdSlot("frontend"); + int frontendTxdSlot1 = CTxdStore::FindTxdSlot("frontend1"); - if(frontendTxdSlot == -1) - frontendTxdSlot = CTxdStore::AddTxdSlot("frontend"); + if(frontendTxdSlot1 == -1) + frontendTxdSlot1 = CTxdStore::AddTxdSlot("frontend1"); - printf("LOAD frontend\n"); - CTxdStore::LoadTxd(frontendTxdSlot, "MODELS/FRONTEND.TXD"); - CTxdStore::AddRef(frontendTxdSlot); - CTxdStore::SetCurrentTxd(frontendTxdSlot); -#ifndef GTA3_1_1_PATCH - CStreaming::IHaveUsedStreamingMemory(); - CTimer::Update(); -#endif + printf("LOAD frontend1\n"); + CTxdStore::LoadTxd(frontendTxdSlot1, "MODELS/FRONTEN1.TXD"); + CTxdStore::AddRef(frontendTxdSlot1); + CTxdStore::SetCurrentTxd(frontendTxdSlot1); - for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) { + for (int i = 0; i < 3; i++) { m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]); m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } - int menuTxdSlot = CTxdStore::FindTxdSlot("menu"); + CTxdStore::PopCurrentTxd(); + CStreaming::IHaveUsedStreamingMemory(); - if (menuTxdSlot == -1) - menuTxdSlot = CTxdStore::AddTxdSlot("menu"); + if (!m_OnlySaveMenu) { + CStreaming::MakeSpaceFor(692 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile + CStreaming::ImGonnaUseStreamingMemory(); + CTxdStore::PushCurrentTxd(); - printf("LOAD sprite\n"); - CTxdStore::LoadTxd(menuTxdSlot, "MODELS/MENU.TXD"); - CTxdStore::AddRef(menuTxdSlot); - CTxdStore::SetCurrentTxd(menuTxdSlot); + int frontendTxdSlot2 = CTxdStore::FindTxdSlot("frontend2"); - for (int i = 0; i < ARRAY_SIZE(MenuFilenames); i++) { - m_aMenuSprites[i].SetTexture(MenuFilenames[i][0], MenuFilenames[i][1]); - m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); - } -#ifdef MENU_MAP - for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) { - m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]); - m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); + if (frontendTxdSlot2 == -1) + frontendTxdSlot2 = CTxdStore::AddTxdSlot("frontend2"); + + printf("LOAD frontend2\n"); + CTxdStore::LoadTxd(frontendTxdSlot2, "MODELS/FRONTEN2.TXD"); + CTxdStore::AddRef(frontendTxdSlot2); + CTxdStore::SetCurrentTxd(frontendTxdSlot2); + + for (int i = 3; i < NUM_MENU_SPRITES; i++) { + m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]); + m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); + } + + CTxdStore::PopCurrentTxd(); + CStreaming::IHaveUsedStreamingMemory(); } -#endif -#ifdef GTA3_1_1_PATCH - CStreaming::IHaveUsedStreamingMemory(); - CTimer::Update(); -#endif + m_bSpritesLoaded = true; - CTxdStore::PopCurrentTxd(); + CTimer::Update(); } void @@ -3225,9 +3157,11 @@ CMenuManager::LoadSettings() m_PrefsVsync = m_PrefsVsyncDisp; CRenderer::ms_lodDistScale = m_PrefsLOD; - if (m_nPrefsAudio3DProviderIndex == -1) + if (m_nPrefsAudio3DProviderIndex == INVALID_AUDIO_PROVIDER) m_nPrefsAudio3DProviderIndex = -2; + m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; + if (m_PrefsLanguage == prevLang) m_bLanguageLoaded = false; else { @@ -3310,16 +3244,14 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); #endif } + m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); } -bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); -void DoRWStuffEndOfFrame(void); - void -CMenuManager::MessageScreen(const char *text) +CMenuManager::MessageScreen(const char *text, bool blackBg) { CSprite2d *splash = LoadSplash(nil); if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)) @@ -3329,41 +3261,32 @@ CMenuManager::MessageScreen(const char *text) CSprite2d::InitPerFrame(); CFont::InitPerFrame(); DefinedState(); + // CRGBA unused(255, 255, 255, 255); + if (blackBg) { + CSprite2d::DrawRect(CRect(0, SCREEN_HEIGHT, SCREEN_WIDTH, 0), CRGBA(0, 0, 0, 255)); + } - RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP); - splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255)); + m_nMenuFadeAlpha = 255; + SmallMessageScreen(text); + CFont::DrawFonts(); + DoRWStuffEndOfFrame(); +} +// TODO(Miami) +void +CMenuManager::SmallMessageScreen(const char* text) +{ CFont::SetBackgroundOff(); CFont::SetPropOn(); CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f)); - CFont::SetRightJustifyWrap(SCREEN_SCALE_FROM_RIGHT(170.0f)); - CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_SCALE_FROM_BOTTOM(220.0f)), CRGBA(50, 50, 50, 210)); + CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(95.0f), SCREEN_SCALE_FROM_BOTTOM(165.0f), SCREEN_SCALE_FROM_RIGHT(95.0f), SCREEN_SCALE_Y(115.0f)), CRGBA(50, 50, 50, FadeIn(210))); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetCentreSize(SCREEN_SCALE_X(380.0f)); + CFont::SetCentreSize(SCREEN_SCALE_X(430.0f)); CFont::SetCentreOn(); - CFont::SetColor(CRGBA(255, 217, 106, 255)); + CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); CFont::SetScale(SCREEN_SCALE_X(SMALLTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLTEXT_Y_SCALE)); CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(170.0f), TheText.Get(text)); - CFont::DrawFonts(); - DoRWStuffEndOfFrame(); -} - -void -CMenuManager::PickNewPlayerColour() -{ - m_PrefsPlayerRed = 0; - m_PrefsPlayerGreen = 0; - m_PrefsPlayerBlue = 0; - while (true) { - int sum = m_PrefsPlayerRed + m_PrefsPlayerGreen + m_PrefsPlayerBlue; - if (sum >= 100 && sum <= 650) - break; - m_PrefsPlayerRed = CGeneral::GetRandomNumber(); - m_PrefsPlayerGreen = CGeneral::GetRandomNumber(); - m_PrefsPlayerBlue = CGeneral::GetRandomNumber(); - } } void @@ -3417,30 +3340,6 @@ CMenuManager::PrintBriefs() #endif } -// Not sure about name. Not to be confused with CPad::PrintErrorMessage -void -CMenuManager::PrintErrorMessage() -{ - if (!CPad::bDisplayNoControllerMessage && !CPad::bObsoleteControllerMessage) - return; - - CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(140.0f), SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f)), CRGBA(64, 16, 16, 224)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetBackgroundOff(); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f)); -#ifdef FIX_BUGS - CFont::PrintString(SCREEN_SCALE_X(50.0f), SCREEN_SCALE_Y(180.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT")); -#else - CFont::PrintString(SCREEN_SCALE_X(50.0f), SCREEN_SCALE_Y(40.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT")); -#endif - CFont::DrawFonts(); -} - void CMenuManager::PrintStats() { @@ -3454,7 +3353,7 @@ CMenuManager::PrintStats() // Scroll stats with mouse #ifdef SCROLLABLE_STATS_PAGE static float scrollY = 0; - static uint32 lastChange = m_nScreenChangeDelayTimer; + static PauseModeTime lastChange = m_LastScreenSwitch; if (CPad::GetPad(0)->GetLeftMouse()) { scrollY += (m_nMouseOldPosY - m_nMousePosY); lastChange = CTimer::GetTimeInMillisecondsPauseMode(); @@ -3464,7 +3363,7 @@ CMenuManager::PrintStats() } #else // MENU_Y(30.0f) per second - float scrollY = MENU_Y(STATS_SLIDE_Y_PER_SECOND) * (CTimer::GetTimeInMillisecondsPauseMode() - m_nScreenChangeDelayTimer) / 1000.0f; + float scrollY = MENU_Y(STATS_SLIDE_Y_PER_SECOND) * (CTimer::GetTimeInMillisecondsPauseMode() - m_LastScreenSwitch) / 1000.0f; #endif for (int row = 0; row < rowNum; ++row) { @@ -3527,177 +3426,95 @@ CMenuManager::PrintStats() // ::Draw already does that. /* PREPARE_MENU_HEADER - CFont::PrintString(MENU_X_RIGHT_ALIGNED(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); */ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y)); } +// --MIAMI: Done void CMenuManager::Process(void) { - m_bMenuStateChanged = false; - - if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0) + if (TheCamera.GetScreenFadeStatus() != FADE_0) return; - m_bWantToRestart = false; InitialiseChangedLanguageSettings(); - // Just a hack by R* to not make game continuously resume/pause. But we it seems we can live with it. - if (CPad::GetPad(0)->GetEscapeJustDown()) - RequestFrontEndStartUp(); - - SwitchMenuOnAndOff(); - - // Be able to re-open menu correctly. if (m_bMenuActive) { + ProcessButtonPresses(); + ProcessFileActions(); + DMAudio.Service(); - // Load frontend textures. - LoadAllTextures(); + // Game calls some texture pool cleanup functions in here + } - // Set save/delete game pages. - if (m_nCurrScreen == MENUPAGE_DELETING) { - bool SlotPopulated = false; + SwitchMenuOnAndOff(); +} - if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { - PcSaveHelper.PopulateSlotInfo(); - SlotPopulated = true; - } +// TODO(Miami) +void +CMenuManager::ProcessButtonPresses(void) +{ + if (m_nCurrScreen == MENUPAGE_OUTRO) + return; - if (SlotPopulated) - ChangeScreen(MENUPAGE_DELETE_SUCCESS, 0, true, false); - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) { - int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); - PcSaveHelper.PopulateSlotInfo(); - if (SaveSlot) - ChangeScreen(MENUPAGE_SAVE_SUCCESSFUL, 0, true, false); - else - SaveLoadFileError_SetUpErrorScreen(); - } - if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { -#ifdef MISSION_REPLAY - if (doingMissionRetry) { - RetryMission(2, 0); - m_nCurrSaveSlot = SLOT_COUNT; - doingMissionRetry = false; + if (m_bWaitingForNewKeyBind) { + if (m_bStartWaitingForKeyBind) + m_bStartWaitingForKeyBind = false; + else { + pControlEdit = CPad::EditCodesForControls(pControlEdit, 1); + JoyButtonJustClicked = false; + MouseButtonJustClicked = false; + + if (CPad::GetPad(0)->GetLeftMouseJustDown()) + MouseButtonJustClicked = 1; + else if (CPad::GetPad(0)->GetRightMouseJustUp()) + MouseButtonJustClicked = 3; + else if (CPad::GetPad(0)->GetMiddleMouseJustUp()) + MouseButtonJustClicked = 2; + else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) + MouseButtonJustClicked = 4; + else if (CPad::GetPad(0)->GetMouseWheelDownJustUp()) + MouseButtonJustClicked = 5; + // TODO two more buttons + + JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); + + int32 TypeOfControl = KEYBOARD; + if (JoyButtonJustClicked) + TypeOfControl = JOYSTICK; + if (MouseButtonJustClicked) + TypeOfControl = MOUSE; + if (*pControlEdit != rsNULL) + TypeOfControl = KEYBOARD; + + if (!m_bKeyIsOK) { + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); + pControlEdit = nil; + m_bWaitingForNewKeyBind = false; + m_KeyPressedCode = -1; + m_bStartWaitingForKeyBind = false; } -#endif - if (CheckSlotDataValid(m_nCurrSaveSlot)) { -#ifdef USE_DEBUG_SCRIPT_LOADER - scriptToLoad = 0; -#endif - TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; - if (m_PrefsVsyncDisp != m_PrefsVsync) - m_PrefsVsync = m_PrefsVsyncDisp; - DMAudio.Service(); - m_bWantToRestart = true; - RequestFrontEndShutDown(); - m_bWantToLoad = true; - b_FoundRecentSavedGameWantToLoad = true; - DMAudio.SetEffectsFadeVol(0); - DMAudio.SetMusicFadeVol(0); - DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); - } else - SaveLoadFileError_SetUpErrorScreen(); - } + else if (!m_bKeyChangeNotProcessed) { + if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked) + CheckCodesForControls(TypeOfControl); - ProcessButtonPresses(); - - // Set binding keys. - if (pEditString && CPad::EditString(pEditString, 0) == nil) { - if (*pEditString == 0) - strcpy(pEditString, "NoName"); - pEditString = nil; - SaveSettings(); - } - - if (m_bWaitingForNewKeyBind) { - if (m_bStartWaitingForKeyBind) - m_bStartWaitingForKeyBind = false; + field_159 = true; + } else { - pControlEdit = CPad::EditCodesForControls(pControlEdit, 1); - JoyButtonJustClicked = false; - MouseButtonJustClicked = false; - - if (CPad::GetPad(0)->GetLeftMouseJustDown()) - MouseButtonJustClicked = 1; - else if (CPad::GetPad(0)->GetRightMouseJustUp()) - MouseButtonJustClicked = 3; - else if (CPad::GetPad(0)->GetMiddleMouseJustUp()) - MouseButtonJustClicked = 2; - else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) - MouseButtonJustClicked = 4; - else if (CPad::GetPad(0)->GetMouseWheelDownJustUp()) - MouseButtonJustClicked = 5; - // TODO two more buttons - - JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); - - int32 TypeOfControl = KEYBOARD; - if (JoyButtonJustClicked) - TypeOfControl = JOYSTICK; - if (MouseButtonJustClicked) - TypeOfControl = MOUSE; - if (*pControlEdit != rsNULL) - TypeOfControl = KEYBOARD; - - if (!m_bKeyIsOK) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0); - pControlEdit = nil; - m_bWaitingForNewKeyBind = false; - m_KeyPressedCode = -1; - m_bStartWaitingForKeyBind = false; - } else if (!m_bKeyChangeNotProcessed) { - if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked) - CheckCodesForControls(TypeOfControl); - - field_535 = true; - } else { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - for (int i = 0; i < 4; i++) - ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i); - m_bKeyIsOK = false; - m_bKeyChangeNotProcessed = false; - pControlEdit = nil; - m_bWaitingForNewKeyBind = false; - m_KeyPressedCode = -1; - m_bStartWaitingForKeyBind = false; - } + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + for (int i = 0; i < 4; i++) + ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i); + m_bKeyIsOK = false; + m_bKeyChangeNotProcessed = false; + pControlEdit = nil; + m_bWaitingForNewKeyBind = false; + m_KeyPressedCode = -1; + m_bStartWaitingForKeyBind = false; } } - - if ((m_nCurrScreen == MENUPAGE_NO_MEMORY_CARD || m_nCurrScreen == MENUPAGE_PS2_LOAD_FAILED) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) { - m_nCurrScreen = m_nPrevScreen; - m_nCurrOption = 0; - } - - // Reset pad shaking. - if (TimeToStopPadShaking && TimeToStopPadShaking < CTimer::GetTimeInMillisecondsPauseMode()) { - CPad::StopPadsShaking(); - TimeToStopPadShaking = 0; - } - - } else { - UnloadTextures(); - m_bRenderGameInMenu = false; - // byte_5F33E4 = 1; // unused - ChangeScreen(MENUPAGE_NONE, 0, false, false); - pEditString = nil; - m_bWaitingForNewKeyBind = false; - } - - if (!m_bWantToRestart) { - if (m_bGameNotLoaded) - DMAudio.Service(); } -} -void -CMenuManager::ProcessButtonPresses(void) -{ if (pEditString || pControlEdit) return; @@ -3731,6 +3548,51 @@ CMenuManager::ProcessButtonPresses(void) m_bShowMouse = true; } + static int oldOption = -99; + oldOption = m_nCurrOption; + for (int rowToCheck = 0; rowToCheck < NUM_MENUROWS; ++rowToCheck) { + 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; + + 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)) { + static int oldScreen = m_nCurrScreen; + + m_nPrevOption = rowToCheck; + if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) { + m_nCurrOption = rowToCheck; + m_bShowMouse = true; + } + + int action = aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action; + if (action != MENUACTION_BRIGHTNESS && action != MENUACTION_DRAWDIST && action != MENUACTION_MUSICVOLUME + && action != MENUACTION_SFXVOLUME && action != MENUACTION_MOUSESENS && action != MENUACTION_MP3VOLUMEBOOST) + m_nHoverOption = HOVEROPTION_RANDOM_ITEM; + + break; + } + if (m_bShowMouse && m_nMenuFadeAlpha == 255) { + m_nPrevOption = oldOption; + m_nCurrOption = oldOption; + } + } + + if (m_bShowMouse) { + if (oldOption != m_nCurrOption) { + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LABEL) { + ++m_nCurrOption; + ++m_nPrevOption; + } + m_nOptionHighlightTransitionBlend = 0; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); + } + } + m_nMouseOldPosX = m_nMousePosX; m_nMouseOldPosY = m_nMousePosY; m_nMousePosX = m_nMouseTempPosX; @@ -3741,8 +3603,7 @@ CMenuManager::ProcessButtonPresses(void) if (m_nMousePosY < 0) m_nMousePosY = 0; if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT; - if (m_nCurrScreen == MENUPAGE_MULTIPLAYER_FIND_GAME || m_nCurrScreen == MENUPAGE_SKIN_SELECT - || m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + if (m_nCurrScreen == MENUPAGE_SKIN_SELECT || m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { m_nTotalListRow = m_nSkinsTotal; @@ -3753,13 +3614,11 @@ CMenuManager::ProcessButtonPresses(void) m_nSelectedListRow = m_nTotalListRow - 1; } -#ifndef TIDY_UP_PBP if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { m_bShowMouse = 0; optionSelected = true; } -#endif - if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_535) { + if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_159) { if (m_nCurrExLayer == HOVEROPTION_LIST) { m_nHoverOption = HOVEROPTION_NOT_HOVERING; m_bWaitingForNewKeyBind = true; @@ -3768,10 +3627,10 @@ CMenuManager::ProcessButtonPresses(void) pControlEdit = &m_KeyPressedCode; } } else { - field_535 = false; + field_159 = false; } - static uint32 lastTimeClickedScrollButton = 0; + static PauseModeTime lastTimeClickedScrollButton = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) { m_bPressedPgUpOnList = false; @@ -3783,7 +3642,7 @@ CMenuManager::ProcessButtonPresses(void) } if (CPad::GetPad(0)->GetTabJustDown()) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); m_bShowMouse = false; switch (m_nCurrExLayer) { case HOVEROPTION_BACK: @@ -3819,7 +3678,7 @@ CMenuManager::ProcessButtonPresses(void) if (!m_bPressedUpOnList) { m_bPressedUpOnList = true; lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); ScrollUpListByOne(); } } else { @@ -3841,7 +3700,7 @@ CMenuManager::ProcessButtonPresses(void) if (!m_bPressedDownOnList) { m_bPressedDownOnList = true; lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); ScrollDownListByOne(); } } else { @@ -3857,7 +3716,7 @@ CMenuManager::ProcessButtonPresses(void) m_bPressedPgUpOnList = true; lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); PageUpList(false); } } @@ -3869,14 +3728,14 @@ CMenuManager::ProcessButtonPresses(void) m_bPressedPgDnOnList = true; lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode(); m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); PageDownList(false); } } if (CPad::GetPad(0)->GetHome()) { m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { m_nFirstVisibleRowOnList = 0; } @@ -3886,7 +3745,7 @@ CMenuManager::ProcessButtonPresses(void) if (CPad::GetPad(0)->GetEnd()) { m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; } @@ -3895,12 +3754,10 @@ CMenuManager::ProcessButtonPresses(void) } } -#ifndef TIDY_UP_PBP if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) { m_bShowMouse = false; goBack = true; } -#endif if (CPad::GetPad(0)->GetLeftMouseJustDown()) { switch (m_nHoverOption) { @@ -3971,7 +3828,6 @@ CMenuManager::ProcessButtonPresses(void) } } } else if (isPlainTextScreen(m_nCurrScreen)) { -#ifndef TIDY_UP_PBP if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown() || CPad::GetPad(0)->GetLeftMouseJustDown()) { optionSelected = true; } @@ -3980,19 +3836,19 @@ CMenuManager::ProcessButtonPresses(void) goBack = true; } } -#endif } else { if (CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) { m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); goDown = true; + m_nOptionHighlightTransitionBlend = 0; } else if (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) { m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); goUp = true; + m_nOptionHighlightTransitionBlend = 0; } -#ifndef TIDY_UP_PBP if ((m_nCurrOption == 0) && (m_nCurrScreen == MENUPAGE_PAUSE_MENU)) { if (CPad::GetPad(0)->GetEnterJustUp() || CPad::GetPad(0)->GetCrossJustUp()) { m_bShowMouse = false; @@ -4004,7 +3860,6 @@ CMenuManager::ProcessButtonPresses(void) optionSelected = true; } } -#endif if (CPad::GetPad(0)->GetLeftMouseJustUp()) { #ifndef TIDY_UP_PBP @@ -4208,7 +4063,7 @@ CMenuManager::ProcessButtonPresses(void) TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; SaveSettings(); break; - } + } #else switch (m_nHoverOption) { case HOVEROPTION_INCREASE_BRIGHTNESS: @@ -4227,7 +4082,7 @@ CMenuManager::ProcessButtonPresses(void) break; } #endif - } + } if (CPad::GetPad(0)->GetLeftMouseJustUp() || CPad::GetPad(0)->GetLeftJustUp() || CPad::GetPad(0)->GetRightJustUp() || CPad::GetPad(0)->GetDPadLeftJustUp() || CPad::GetPad(0)->GetDPadRightJustUp() @@ -4242,7 +4097,6 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); } -#ifndef TIDY_UP_PBP if (CPad::GetPad(0)->GetBackJustDown()) { if (m_nCurrScreen != MENUPAGE_START_MENU && m_nCurrScreen != MENUPAGE_PAUSE_MENU) { m_bShowMouse = false; @@ -4260,53 +4114,19 @@ CMenuManager::ProcessButtonPresses(void) if (((goDown) || (goUp)) || (optionSelected)) { goBack = false; } -#endif - } - - // Centralized enter/back (except some conditions) -#ifdef TIDY_UP_PBP - if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESUME) { - if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown() || - (isPlainTextScreen(m_nCurrScreen) && CPad::GetPad(0)->GetLeftMouseJustDown())) { - - if (!isPlainTextScreen(m_nCurrScreen)) - m_bShowMouse = false; - - optionSelected = true; - } - } else { - if (CPad::GetPad(0)->GetEnterJustUp() || CPad::GetPad(0)->GetCrossJustUp()) { - m_bShowMouse = false; - optionSelected = true; - } } - if (!goDown && !goUp && !optionSelected) { - if (m_nCurrScreen != MENUPAGE_START_MENU) { - if (isPlainTextScreen(m_nCurrScreen)) { - if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustUp()) { - goBack = true; - } - } else { - if (CPad::GetPad(0)->GetEscapeJustDown() || (m_nCurrScreen != MENUPAGE_PAUSE_MENU && CPad::GetPad(0)->GetBackJustDown())) { - m_bShowMouse = false; - goBack = true; - } - } - } - } -#endif #ifdef PS2_LIKE_MENU if (CPad::GetPad(0)->GetLeftMouseJustDown() && hoveredBottomBarOption != -1) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); bottomBarActive = false; curBottomBarOption = hoveredBottomBarOption; ChangeScreen(bbNames[curBottomBarOption].screenId, 0, true, false); return; } else if (bottomBarActive) { if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); bottomBarActive = false; // If there's a menu change with fade ongoing, finish it now @@ -4316,7 +4136,7 @@ CMenuManager::ProcessButtonPresses(void) } else if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown() || CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown()) { m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); if (curBottomBarOption > 0) curBottomBarOption--; ChangeScreen(bbNames[curBottomBarOption].screenId, 0, true, true); @@ -4324,7 +4144,7 @@ CMenuManager::ProcessButtonPresses(void) } else if (CPad::GetPad(0)->GetRightJustDown() || CPad::GetPad(0)->GetAnaloguePadRight() || CPad::GetPad(0)->GetDPadRightJustDown() || CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown()) { m_bShowMouse = false; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); if (curBottomBarOption < bbTabCount-1) curBottomBarOption++; ChangeScreen(bbNames[curBottomBarOption].screenId, 0, true, true); @@ -4336,14 +4156,13 @@ CMenuManager::ProcessButtonPresses(void) } #endif - int prevOption = m_nCurrOption; - if (goDown && (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME)) { + if (goDown) { m_nCurrOption++; if (m_nCurrOption == NUM_MENUROWS || (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NOTHING)) { m_nCurrOption = 0; } } - if (goUp && (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME)) { + if (goUp) { if (m_nCurrOption == (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL)) { while (m_nCurrOption != NUM_MENUROWS - 1 && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption + 1].m_Action != MENUACTION_NOTHING) { @@ -4356,7 +4175,8 @@ CMenuManager::ProcessButtonPresses(void) if (optionSelected) { int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; - if ((option == MENUACTION_CHANGEMENU) || (option == MENUACTION_POPULATESLOTS_CHANGEMENU)) { + if (option == MENUACTION_CHANGEMENU || option == MENUACTION_POPULATESLOTS_CHANGEMENU || option == MENUACTION_GOBACK + || option == MENUACTION_YES || option == MENUACTION_NO) { if (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) != 0 && strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FESZ_CA", 8) != 0) { @@ -4387,8 +4207,9 @@ CMenuManager::ProcessButtonPresses(void) } } else if (option != MENUACTION_CHANGEMENU && option != MENUACTION_BRIGHTNESS && option != MENUACTION_DRAWDIST && option != MENUACTION_MUSICVOLUME && option != MENUACTION_SFXVOLUME - && option != MENUACTION_CHECKSAVE && option != MENUACTION_UNK24 - && option != MENUACTION_MOUSESENS && option != MENUACTION_SCREENRES) { + && option != MENUACTION_CHECKSAVE && option != MENUACTION_MOUSESENS + && option != MENUACTION_YES && option != MENUACTION_NO + && option != MENUACTION_SCREENRES) { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); } @@ -4432,14 +4253,9 @@ CMenuManager::ProcessButtonPresses(void) CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); SaveSettings(); } else { -#ifndef TIDY_UP_PBP - ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0], - GetPreviousPageOption(), true, true); -#else - goBack = true; -#endif + SwitchToNewScreen(-2); } - } else if (m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME) { + } else { option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; switch (option) { case MENUACTION_RADIO: @@ -4489,53 +4305,47 @@ CMenuManager::ProcessButtonPresses(void) InitialiseChangedLanguageSettings(); SaveSettings(); break; +#ifdef MORE_LANGUAGES + case MENUACTION_LANG_PL: + m_PrefsLanguage = LANGUAGE_POLISH; + m_bFrontEnd_ReloadObrTxtGxt = true; + InitialiseChangedLanguageSettings(); + SaveSettings(); + break; + case MENUACTION_LANG_RUS: + m_PrefsLanguage = LANGUAGE_RUSSIAN; + m_bFrontEnd_ReloadObrTxtGxt = true; + CMenuManager::InitialiseChangedLanguageSettings(); + SaveSettings(); + break; + case MENUACTION_LANG_JAP: + m_PrefsLanguage = LANGUAGE_JAPANESE; + m_bFrontEnd_ReloadObrTxtGxt = true; + InitialiseChangedLanguageSettings(); + SaveSettings(); + break; +#endif case MENUACTION_POPULATESLOTS_CHANGEMENU: PcSaveHelper.PopulateSlotInfo(); // fall through case MENUACTION_CHANGEMENU: + case MENUACTION_YES: + case MENUACTION_NO: { - bool changeMenu = true; - int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot; - - // This should be unused. - if (saveSlot >= 2 && saveSlot <= 9) { - m_nCurrSaveSlot = saveSlot - 2; - switch (m_nCurrScreen) { - case MENUPAGE_CHOOSE_LOAD_SLOT: - if (Slots[m_nCurrSaveSlot + 1] != SLOT_EMPTY) - changeMenu = false; - - break; - case MENUPAGE_CHOOSE_DELETE_SLOT: - if (Slots[m_nCurrSaveSlot + 1] == SLOT_EMPTY) - changeMenu = false; - - break; - } - } - if (changeMenu) { - if (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 0) { -#ifndef TIDY_UP_PBP - ResetHelperText(); - ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0], - GetPreviousPageOption(), true, true); -#else - goBack = true; - break; -#endif - } else { + // TODO(Miami): TEMP #ifdef MENU_MAP - if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_MAP) { - bMapLoaded = false; - } + if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_MAP) { + bMapLoaded = false; + } #endif - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); - } - } + SwitchToNewScreen(0); break; } + case MENUACTION_GOBACK: + goBack = true; + break; case MENUACTION_CHECKSAVE: { int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot; @@ -4543,7 +4353,11 @@ CMenuManager::ProcessButtonPresses(void) if (saveSlot >= 2 && saveSlot <= 9) { m_nCurrSaveSlot = saveSlot - 2; if (Slots[m_nCurrSaveSlot + 1] != SLOT_EMPTY && Slots[m_nCurrSaveSlot + 1] != SLOT_CORRUPTED) { - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); + if (m_nCurrScreen == MENUPAGE_CHOOSE_LOAD_SLOT) { + SwitchToNewScreen(MENUPAGE_LOAD_SLOT_CONFIRM); + } else if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT) { + SwitchToNewScreen(MENUPAGE_DELETE_SLOT_CONFIRM); + } } } break; @@ -4554,43 +4368,11 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_RELOADIDE: CFileLoader::ReloadObjectTypes("GTA3.IDE"); break; - case MENUACTION_RELOADIPL: - CGame::ReloadIPLs(); - break; - case MENUACTION_SHOWCULL: - gbShowCullZoneDebugStuff = !gbShowCullZoneDebugStuff; - break; - case MENUACTION_MEMCARDSAVECONFIRM: - return; case MENUACTION_RESUME_FROM_SAVEZONE: RequestFrontEndShutDown(); break; - case MENUACTION_MPMAP_LIBERTY: - case MENUACTION_MPMAP_REDLIGHT: - case MENUACTION_MPMAP_CHINATOWN: - case MENUACTION_MPMAP_TOWER: - case MENUACTION_MPMAP_SEWER: - case MENUACTION_MPMAP_INDUSTPARK: - case MENUACTION_MPMAP_DOCKS: - case MENUACTION_MPMAP_STAUNTON: - m_SelectedMap = option - MENUACTION_MPMAP_LIBERTY; - SaveSettings(); - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); - break; - case MENUACTION_MPMAP_DEATHMATCH1: - case MENUACTION_MPMAP_DEATHMATCH2: - case MENUACTION_MPMAP_TEAMDEATH1: - case MENUACTION_MPMAP_TEAMDEATH2: - case MENUACTION_MPMAP_STASH: - case MENUACTION_MPMAP_CAPTURE: - case MENUACTION_MPMAP_RATRACE: - case MENUACTION_MPMAP_DOMINATION: - m_SelectedGameType = option - MENUACTION_MPMAP_DEATHMATCH1; - SaveSettings(); - ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true); - break; case MENUACTION_KEYBOARDCTRLS: - ChangeScreen(MENUPAGE_KEYBOARD_CONTROLS, 0, true, true); + SwitchToNewScreen(MENUPAGE_KEYBOARD_CONTROLS); m_nSelectedListRow = 0; m_nCurrExLayer = HOVEROPTION_LIST; break; @@ -4603,34 +4385,45 @@ CMenuManager::ProcessButtonPresses(void) break; case MENUACTION_CANCELGAME: DMAudio.Service(); - RsEventHandler(rsQUITAPP, nil); + SwitchToNewScreen(MENUPAGE_OUTRO); break; case MENUACTION_RESUME: -#ifndef TIDY_UP_PBP if (m_PrefsVsyncDisp != m_PrefsVsync) { m_PrefsVsync = m_PrefsVsyncDisp; } RequestFrontEndShutDown(); -#else - goBack = true; -#endif break; case MENUACTION_DONTCANCEL: - ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0], - GetPreviousPageOption(), true, true); + SwitchToNewScreen(-2); break; case MENUACTION_SCREENRES: if (m_nDisplayVideoMode != m_nPrefsVideoMode) { m_nPrefsVideoMode = m_nDisplayVideoMode; _psSelectScreenVM(m_nPrefsVideoMode); + SetHelperText(0); // TODO(Miami): Remove that + DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); + DMAudio.Service(); + CentreMousePointer(); + m_bShowMouse = true; + // m_nCurrOption = 5; // Why? + m_nOptionHighlightTransitionBlend = 0; + SaveSettings(); + } + break; +#ifdef IMPROVED_VIDEOMODE + case MENUACTION_SCREENMODE: + if (m_nSelectedScreenMode != m_nPrefsWindowed) { + m_nPrefsWindowed = m_nSelectedScreenMode; + _psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution SetHelperText(0); SaveSettings(); } break; +#endif case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; - if (selectedProvider != -1) { + if (selectedProvider != INVALID_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex = DMAudio.SetCurrent3DProvider(m_nPrefsAudio3DProviderIndex); if (selectedProvider == m_nPrefsAudio3DProviderIndex) { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); @@ -4645,7 +4438,7 @@ CMenuManager::ProcessButtonPresses(void) } case MENUACTION_SPEAKERCONF: #ifndef TIDY_UP_PBP - if (m_nPrefsAudio3DProviderIndex != -1) { + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { if (--m_PrefsSpeakers < 0) m_PrefsSpeakers = 2; DMAudio.SetSpeakerConfig(m_PrefsSpeakers); @@ -4657,7 +4450,7 @@ CMenuManager::ProcessButtonPresses(void) break; case MENUACTION_PLAYERSETUP: CPlayerSkin::BeginFrontendSkinEdit(); - ChangeScreen(MENUPAGE_SKIN_SELECT, 0, true, true); + SwitchToNewScreen(MENUPAGE_SKIN_SELECT); m_nCurrExLayer = HOVEROPTION_LIST; m_bSkinsEnumerated = false; break; @@ -4667,7 +4460,7 @@ CMenuManager::ProcessButtonPresses(void) m_PrefsSpeakers = 0; m_PrefsMusicVolume = 102; m_PrefsStereoMono = 0; - m_PrefsRadioStation = HEAD_RADIO; + m_PrefsRadioStation = WILDSTYLE; DMAudio.SetMusicMasterVolume(102); DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume); DMAudio.SetRadioInCar(m_PrefsRadioStation); @@ -4696,7 +4489,7 @@ CMenuManager::ProcessButtonPresses(void) CMBlur::BlurOn = true; #endif SaveSettings(); - } else if ((m_nCurrScreen != MENUPAGE_SKIN_SELECT_OLD) && (m_nCurrScreen == MENUPAGE_CONTROLLER_PC)) { + } else if (m_nCurrScreen == MENUPAGE_CONTROLLER_PC) { ControlsManager.MakeControllerActionsBlank(); ControlsManager.InitDefaultControlConfiguration(); ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp()); @@ -4738,47 +4531,25 @@ CMenuManager::ProcessButtonPresses(void) #endif break; case MENUACTION_LOADRADIO: - ChangeScreen(MENUPAGE_SOUND_SETTINGS, 0, true, true); + SwitchToNewScreen(MENUPAGE_SOUND_SETTINGS); DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK"); break; -#ifdef MISSION_REPLAY - case MENUACTION_REJECT_RETRY: - doingMissionRetry = false; - AllowMissionReplay = 0; - RequestFrontEndShutDown(); - break; - case MENUACTION_UNK114: - doingMissionRetry = false; - RequestFrontEndShutDown(); - RetryMission(2, 0); - return; -#endif -#ifdef CUSTOM_FRONTEND_OPTIONS - case MENUACTION_TRIGGERFUNC: - FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; - if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { - if (option.type == FEOPTION_SELECT) { - if (!option.onlyApplyOnEnter) { - option.displayedValue++; - if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0) - option.displayedValue = 0; - } - option.changeFunc(option.displayedValue); - *option.value = option.displayedValue; - - } else if (option.type == FEOPTION_DYNAMIC) { - option.buttonPressFunc(FEOPTION_ACTION_SELECT); - } else if (option.type == FEOPTION_REDIRECT) { - ChangeScreen(option.to, option.option, true, option.fadeIn); - } else if (option.type == FEOPTION_GOBACK) { - goBack = true; - } - } else - assert(0 && "Custom frontend options are borked"); + case MENUACTION_SAVEGAME: + { + int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot; + if (saveSlot >= 2 && saveSlot <= 9) { + m_nCurrSaveSlot = m_nCurrOption; + SwitchToNewScreen(MENUPAGE_SAVE_OVERWRITE_CONFIRM); + } break; -#endif + } + //case MENUACTION_KEYBOARDCTRLS: + // SwitchToNewScreen(MENUPAGE_KEYBOARD_CONTROLS); + // m_nSelectedListRow = 0; + // m_nCurrExLayer = HOVEROPTION_LIST; + // break; } } ProcessOnOffMenuOptions(); @@ -4792,7 +4563,7 @@ CMenuManager::ProcessButtonPresses(void) #else if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) { #endif - if (!m_bGameNotLoaded && !m_bMenuStateChanged) { + if (!m_bGameNotLoaded) { if (m_PrefsVsyncDisp != m_PrefsVsync) { m_PrefsVsync = m_PrefsVsyncDisp; } @@ -4811,7 +4582,7 @@ CMenuManager::ProcessButtonPresses(void) #endif RequestFrontEndShutDown(); } - // It's now in ThingsToDoBeforeGoingBack() + // It's now in ThingsToDoBeforeLeavingPage() #ifndef TIDY_UP_PBP else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { DMAudio.StopFrontEndTrack(); @@ -4819,11 +4590,10 @@ CMenuManager::ProcessButtonPresses(void) } #endif - int oldScreen = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0]; - int oldOption = GetPreviousPageOption(); + int oldScreen = aScreens[m_nCurrScreen].m_PreviousPage; if (oldScreen != -1) { - ThingsToDoBeforeGoingBack(); + ThingsToDoBeforeLeavingPage(); #ifdef PS2_LIKE_MENU if (!bottomBarActive && @@ -4832,7 +4602,7 @@ CMenuManager::ProcessButtonPresses(void) } else #endif { - ChangeScreen(oldScreen, oldOption, true, true); + SwitchToNewScreen(-2); } // We will go back for sure at this point, why process other things?! @@ -4855,13 +4625,13 @@ CMenuManager::ProcessButtonPresses(void) bool increase = false; #endif if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) { - static uint32 lastSliderDecrease = 0; + static PauseModeTime lastSliderDecrease = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) { CheckSliderMovement(-1); lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode(); } } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) { - static uint32 lastSliderIncrease = 0; + static PauseModeTime lastSliderIncrease = 0; if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) { CheckSliderMovement(1); lastSliderIncrease = CTimer::GetTimeInMillisecondsPauseMode(); @@ -4901,15 +4671,15 @@ CMenuManager::ProcessButtonPresses(void) m_PrefsRadioStation += changeValueBy; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); if (DMAudio.IsMP3RadioChannelAvailable()) { - if (m_PrefsRadioStation < HEAD_RADIO) + if (m_PrefsRadioStation < WILDSTYLE) m_PrefsRadioStation = USERTRACK; if (m_PrefsRadioStation > USERTRACK) - m_PrefsRadioStation = HEAD_RADIO; + m_PrefsRadioStation = WILDSTYLE; } else { - if (m_PrefsRadioStation < HEAD_RADIO) - m_PrefsRadioStation = CHATTERBOX; - if (m_PrefsRadioStation > CHATTERBOX) - m_PrefsRadioStation = HEAD_RADIO; + if (m_PrefsRadioStation < WILDSTYLE) + m_PrefsRadioStation = WAVE; + if (m_PrefsRadioStation > WAVE) + m_PrefsRadioStation = WILDSTYLE; } SaveSettings(); DMAudio.SetRadioInCar(m_PrefsRadioStation); @@ -4934,7 +4704,7 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_SCREENRES: if (m_bGameNotLoaded) { RwChar** videoMods = _psGetVideoModeList(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); if (changeValueBy > 0) { do { ++m_nDisplayVideoMode; @@ -4952,15 +4722,21 @@ CMenuManager::ProcessButtonPresses(void) } } break; +#ifdef IMPROVED_VIDEOMODE + case MENUACTION_SCREENMODE: + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); + m_nSelectedScreenMode = !m_nSelectedScreenMode; + break; +#endif case MENUACTION_AUDIOHW: - if (m_nPrefsAudio3DProviderIndex != -1) { + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeValueBy; m_nPrefsAudio3DProviderIndex = clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1); } - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); break; case MENUACTION_SPEAKERCONF: - if (m_nPrefsAudio3DProviderIndex != -1) { + if (m_nPrefsAudio3DProviderIndex != INVALID_AUDIO_PROVIDER) { m_PrefsSpeakers -= changeValueBy; m_PrefsSpeakers = clamp(m_PrefsSpeakers, 0, 2); DMAudio.SetSpeakerConfig(m_PrefsSpeakers); @@ -4974,34 +4750,6 @@ CMenuManager::ProcessButtonPresses(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; -#ifdef CUSTOM_FRONTEND_OPTIONS - case MENUACTION_TRIGGERFUNC: - FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; - if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) { - if (option.type == FEOPTION_SELECT) { - if (changeValueBy > 0) { - option.displayedValue++; - if (option.displayedValue >= option.numRightTexts) - option.displayedValue = 0; - } else { - option.displayedValue--; - if (option.displayedValue < 0) - option.displayedValue = option.numRightTexts - 1; - } - if (!option.onlyApplyOnEnter) { - option.changeFunc(option.displayedValue); - *option.value = option.displayedValue; - } - } else if (option.type == FEOPTION_DYNAMIC) { - option.buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); - } - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - } - else - assert(0 && "Custom frontend options are borked"); - - break; -#endif } ProcessOnOffMenuOptions(); if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -5010,7 +4758,7 @@ CMenuManager::ProcessButtonPresses(void) } else { m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN; } - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NEW_PAGE, 0); } } } @@ -5021,11 +4769,6 @@ CMenuManager::ProcessOnOffMenuOptions() switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) { case MENUACTION_CTRLVIBRATION: m_PrefsUseVibration = !m_PrefsUseVibration; - - if (m_PrefsUseVibration) { - CPad::GetPad(0)->StartShake(350, 150); - TimeToStopPadShaking = CTimer::GetTimeInMillisecondsPauseMode() + 500; - } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; case MENUACTION_CTRLCONFIG: @@ -5034,10 +4777,6 @@ CMenuManager::ProcessOnOffMenuOptions() CPad::GetPad(0)->Mode = 0; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; - case MENUACTION_CTRLDISPLAY: - m_DisplayControllerOnFoot = !m_DisplayControllerOnFoot; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - break; case MENUACTION_FRAMESYNC: m_PrefsVsyncDisp = !m_PrefsVsyncDisp; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); @@ -5077,23 +4816,10 @@ CMenuManager::ProcessOnOffMenuOptions() gbBigWhiteDebugLightSwitchedOn = !gbBigWhiteDebugLightSwitchedOn; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; - case MENUACTION_PEDROADGROUPS: - gbShowPedRoadGroups = !gbShowPedRoadGroups; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - break; - case MENUACTION_CARROADGROUPS: - gbShowCarRoadGroups = !gbShowCarRoadGroups; - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - break; case MENUACTION_COLLISIONPOLYS: gbShowCollisionPolys = !gbShowCollisionPolys; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; - case MENUACTION_MP_PLAYERCOLOR: - PickNewPlayerColour(); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); - SaveSettings(); - break; case MENUACTION_SHOWHEADBOB: TheCamera.m_bHeadBob = !TheCamera.m_bHeadBob; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); @@ -5115,6 +4841,13 @@ CMenuManager::ProcessOnOffMenuOptions() DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); break; +#ifdef FREE_CAM + case MENUACTION_FREECAM: + TheCamera.bFreeCam = !TheCamera.bFreeCam; + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + SaveSettings(); + break; +#endif } } @@ -5122,7 +4855,6 @@ void CMenuManager::RequestFrontEndShutDown() { m_bShutDownFrontEndRequested = true; - DMAudio.ChangeMusicMode(MUSICMODE_GAME); } void @@ -5139,45 +4871,12 @@ CMenuManager::ResetHelperText() } void -CMenuManager::SaveLoadFileError_SetUpErrorScreen() -{ - switch (PcSaveHelper.nErrorCode) { - case SAVESTATUS_ERR_SAVE_CREATE: - case SAVESTATUS_ERR_SAVE_WRITE: - case SAVESTATUS_ERR_SAVE_CLOSE: - ChangeScreen(MENUPAGE_SAVE_FAILED, 0, true, false); - break; - case SAVESTATUS_ERR_LOAD_OPEN: - case SAVESTATUS_ERR_LOAD_READ: - case SAVESTATUS_ERR_LOAD_CLOSE: - ChangeScreen(MENUPAGE_LOAD_FAILED, 0, true, false); - break; - case SAVESTATUS_ERR_DATA_INVALID: - ChangeScreen(MENUPAGE_LOAD_FAILED_2, 0, true, false); - break; - case SAVESTATUS_DELETEFAILED8: - case SAVESTATUS_DELETEFAILED9: - case SAVESTATUS_DELETEFAILED10: - ChangeScreen(MENUPAGE_DELETE_FAILED, 0, true, false); - break; - default: break; - } -} - -void CMenuManager::SetHelperText(int text) { m_nHelperTextMsgId = text; m_nHelperTextAlpha = 300; } -void -CMenuManager::ShutdownJustMenu() -{ - m_bMenuActive = false; - CTimer::EndUserPause(); -} - float CMenuManager::StretchX(float x) { @@ -5198,80 +4897,164 @@ float CMenuManager::StretchY(float y) } void +CMenuManager::ProcessFileActions() +{ + switch (m_nCurrScreen) { + case MENUPAGE_LOADING_IN_PROGRESS: + if (CheckSlotDataValid(m_nCurrSaveSlot)) { +#ifdef USE_DEBUG_SCRIPT_LOADER + scriptToLoad = 0; +#endif + if (!m_bGameNotLoaded) + MessageScreen("FELD_WR", true); + + DoSettingsBeforeStartingAGame(); + m_bWantToLoad = true; + } else + SwitchToNewScreen(MENUPAGE_NEW_GAME); + + break; + case MENUPAGE_DELETING_IN_PROGRESS: + { + static bool waitedForScreen = false; + + if (waitedForScreen) { + bool SlotPopulated = false; + if (PcSaveHelper.DeleteSlot(m_nCurrSaveSlot)) { + PcSaveHelper.PopulateSlotInfo(); + SlotPopulated = true; + } + + if (SlotPopulated) { + SwitchToNewScreen(MENUPAGE_DELETE_SUCCESSFUL); + } else { + SwitchToNewScreen(MENUPAGE_SAVE_CUSTOM_WARNING); + strncpy(aScreens[m_nCurrScreen].m_ScreenName, "FES_DEL", 8); + strncpy(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName, "FES_DEE", 8); + } + waitedForScreen = false; + } else if (m_nMenuFadeAlpha >= 255) + waitedForScreen = true; + + break; + } + case MENUPAGE_SAVING_IN_PROGRESS: + { + static bool waitedForScreen = false; + + if (waitedForScreen) { + int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot); + PcSaveHelper.PopulateSlotInfo(); + if (SaveSlot) { + 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 + SwitchToNewScreen(MENUPAGE_SAVE_SUCCESSFUL); + + waitedForScreen = false; + } else if (m_nMenuFadeAlpha >= 255) + waitedForScreen = true; + + break; + } + } +} + +// --MIAMI: Done except DxInput things, are they even needed? +void CMenuManager::SwitchMenuOnAndOff() { - bool menuWasActive = GetIsMenuActive(); + if (!TheCamera.m_WideScreenOn) { + + // 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) { + + if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS) { + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + } - // Reminder: You need REGISTER_START_BUTTON defined to make it work. - if (CPad::GetPad(0)->GetStartJustDown() -#ifdef FIX_BUGS - && !m_bGameNotLoaded -#endif - || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) { + if (m_bShutDownFrontEndRequested) + m_bMenuActive = false; + else if (m_bStartUpFrontEndRequested) + m_bMenuActive = true; + else + m_bMenuActive = !m_bMenuActive; - m_bMenuActive = !m_bMenuActive; + if (m_bMenuActive) { + // TODO(Miami): DxInput?? - if (m_bShutDownFrontEndRequested) - m_bMenuActive = false; - if (m_bStartUpFrontEndRequested) - m_bMenuActive = true; + Initialise(); + LoadAllTextures(); + } else { + if (CMBlur::BlurOn) + CMBlur::MotionBlurOpen(Scene.camera); + else + CMBlur::MotionBlurClose(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + + // TODO(Miami): DxInput?? - if (m_bMenuActive) { - CTimer::StartUserPause(); - } else { #ifdef PS2_LIKE_MENU - bottomBarActive = false; -#endif -#ifdef FIX_BUGS - ThingsToDoBeforeGoingBack(); + bottomBarActive = false; #endif - ShutdownJustMenu(); - SaveSettings(); - m_bStartUpFrontEndRequested = false; - pControlEdit = nil; - m_bShutDownFrontEndRequested = false; - DisplayComboButtonErrMsg = false; + + m_StatsScrollSpeed = 150.0f; + SaveSettings(); + pControlEdit = nil; + pEditString = nil; + DisplayComboButtonErrMsg = false; + m_bShutDownFrontEndRequested = false; + m_bStartUpFrontEndRequested = false; + m_bWaitingForNewKeyBind = false; #ifdef REGISTER_START_BUTTON - int16 start1 = CPad::GetPad(0)->PCTempJoyState.Start, start2 = CPad::GetPad(0)->PCTempKeyState.Start, - start3 = CPad::GetPad(0)->OldState.Start, start4 = CPad::GetPad(0)->NewState.Start; + int16 start1 = CPad::GetPad(0)->PCTempJoyState.Start, start2 = CPad::GetPad(0)->PCTempKeyState.Start, + start3 = CPad::GetPad(0)->OldState.Start, start4 = CPad::GetPad(0)->NewState.Start; #endif - CPad::GetPad(0)->Clear(false); - CPad::GetPad(1)->Clear(false); + CPad::GetPad(0)->Clear(false); + CPad::GetPad(1)->Clear(false); #ifdef REGISTER_START_BUTTON - CPad::GetPad(0)->PCTempJoyState.Start = start1; - CPad::GetPad(0)->PCTempKeyState.Start = start2; - CPad::GetPad(0)->OldState.Start = start3; - CPad::GetPad(0)->NewState.Start = start4; + CPad::GetPad(0)->PCTempJoyState.Start = start1; + CPad::GetPad(0)->PCTempKeyState.Start = start2; + CPad::GetPad(0)->OldState.Start = start3; + CPad::GetPad(0)->NewState.Start = start4; #endif - m_nCurrScreen = MENUPAGE_NONE; + UnloadTextures(); + CTimer::EndUserPause(); + CTimer::Update(); + m_OnlySaveMenu = false; + } } } // Just entered the save/safe zone - if (m_bSaveMenuActive && !m_bQuitGameNoCD) { - m_bSaveMenuActive = false; + if (m_bActivateSaveMenu) { + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); + DoRWStuffEndOfFrame(); + m_bActivateSaveMenu = false; m_bMenuActive = true; - CTimer::StartUserPause(); -#ifdef PS2_SAVE_DIALOG - m_nCurrScreen = MENUPAGE_SAVE; - m_bRenderGameInMenu = true; -#else + m_OnlySaveMenu = true; + + // TODO(Miami): DxInput?? + + Initialise(); + LoadAllTextures(); + + // TODO(Miami): Cheat warning m_nCurrScreen = MENUPAGE_CHOOSE_SAVE_SLOT; -#endif - PcSaveHelper.PopulateSlotInfo(); - m_nCurrOption = 0; - } -/* // PS2 leftover - if (m_nCurrScreen != MENUPAGE_SOUND_SETTINGS && gMusicPlaying) - { - DMAudio.StopFrontEndTrack(); - OutputDebugString("FRONTEND AUDIO TRACK STOPPED"); - gMusicPlaying = 0; + m_nCurrOption = 8; } -*/ - if (m_bMenuActive != menuWasActive) - m_bMenuStateChanged = true; m_bStartUpFrontEndRequested = false; m_bShutDownFrontEndRequested = false; @@ -5280,27 +5063,31 @@ CMenuManager::SwitchMenuOnAndOff() void CMenuManager::UnloadTextures() { - if (!m_bSpritesLoaded) - return; + if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) + DMAudio.StopFrontEndTrack(); - printf("REMOVE frontend\n"); - for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); ++i) - m_aFrontEndSprites[i].Delete(); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0); + DMAudio.ChangeMusicMode(MUSICMODE_GAME); + if (m_bSpritesLoaded) { + printf("REMOVE frontend\n"); + int frontend = CTxdStore::FindTxdSlot("frontend1"); + for (int i = 0; i < 3; ++i) + m_aFrontEndSprites[i].Delete(); - int frontend = CTxdStore::FindTxdSlot("frontend"); - CTxdStore::RemoveTxd(frontend); + CTxdStore::RemoveTxd(frontend); - printf("REMOVE menu textures\n"); - for (int i = 0; i < ARRAY_SIZE(MenuFilenames); ++i) - m_aMenuSprites[i].Delete(); -#ifdef MENU_MAP - for (int i = 0; i < ARRAY_SIZE(MapFilenames); ++i) - m_aMapSprites[i].Delete(); -#endif - int menu = CTxdStore::FindTxdSlot("menu"); - CTxdStore::RemoveTxd(menu); + if (!m_OnlySaveMenu) { + int frontend2 = CTxdStore::FindTxdSlot("frontend2"); + for (int i = 3; i < NUM_MENU_SPRITES; ++i) + m_aFrontEndSprites[i].Delete(); - m_bSpritesLoaded = false; + CTxdStore::RemoveTxd(frontend2); + } + + m_bSpritesLoaded = false; + } + m_OnlySaveMenu = false; + // TODO(Miami): Place name thing } void @@ -5323,7 +5110,7 @@ CMenuManager::WaitForUserCD() HandleExit(); CPad::UpdatePads(); - MessageScreen("NO_PCCD"); + MessageScreen("NO_PCCD", true); if (CPad::GetPad(0)->GetEscapeJustDown()) { m_bQuitGameNoCD = true; @@ -5332,273 +5119,89 @@ CMenuManager::WaitForUserCD() } void -CMenuManager::PrintController(void) +CMenuManager::DrawQuitGameScreen(void) { - // FIX: Originally this function doesn't have StretchX/Y, everything had constant pixel size (due to screen was abandoned early?) - // Also texts and their alignment were very bad, so I tried to make them readable (commented out the original code, and marked the ones I added with X) - - m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(240.0f), MENU_Y(180.0f), CRGBA(0, 0, 0, 255)); - m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - if (m_DisplayControllerOnFoot) { - if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400) - m_aFrontEndSprites[FE_ARROWS1].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - else - m_aFrontEndSprites[FE_ARROWS3].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - } else { - if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400) - m_aFrontEndSprites[FE_ARROWS2].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - else - m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255)); - } - - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); // X - - // CFont::SetScale(0.4f, 0.4f); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); // X - - // CFont::SetColor(CRGBA(128, 128, 128, FadeIn(255))); - CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // X - CFont::SetDropShadowPosition(1); // X - CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); // X - - if (m_DisplayControllerOnFoot) { - switch (CPad::GetPad(0)->Mode) { - case 0: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - case 1: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - case 2: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_ENV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - case 3: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3")); - break; - default: - return; - } - } else { - switch (CPad::GetPad(0)->Mode) { - case 0: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_RSC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3")); - break; - case 1: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HOR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_RSC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3")); - break; - case 2: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_RS3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HOR")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3")); - break; - case 3: - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HAB")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_TUC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB")); - CFont::SetRightJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR")); - CFont::SetJustifyOn(); // X - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_CAW")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_SMT")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_RSC")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_NA")); - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_ACC")); - // FIX: Coordinates of this line is undefined in PC... - CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_BRA")); - break; - default: - return; - } + static int32 exitSignalTimer = 0; +#ifndef MUCH_SHORTER_OUTRO_SCREEN + static PauseModeTime lastTickIncrease = 0; + if (m_nMenuFadeAlpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - lastTickIncrease > 10) { + exitSignalTimer++; + lastTickIncrease = CTimer::GetTimeInMillisecondsPauseMode(); } +#else + static PauseModeTime sincePress = 0; + sincePress += frameTime; + if (sincePress > 500) + exitSignalTimer = 150; +#endif + static CSprite2d *splash = nil; + + if (splash == nil) + splash = LoadSplash("OUTRO"); + + m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(28.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, -(m_nMenuFadeAlpha + 1))); + + // Or we can see menu background from sides +#ifdef ASPECT_RATIO_SCALE + CSprite2d::DrawRect(CRect(0, 0, MENU_X_LEFT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(0, 0, 0, m_nMenuFadeAlpha)); + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(0.f), 0, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, m_nMenuFadeAlpha)); +#endif + + splash->Draw(CRect(MENU_X_LEFT_ALIGNED(0.f), 0, MENU_X_RIGHT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha)); + if (m_nMenuFadeAlpha == 255 && exitSignalTimer == 150) + RsEventHandler(rsQUITAPP, nil); - CFont::SetDropShadowPosition(0); // X + m_bShowMouse = false; + m_AllowNavigation = false; } #ifdef MENU_MAP #define ZOOM(x, y, in) \ do { \ - if(fMapSize > SCREEN_HEIGHT * 3.0f && in) \ + if(m_fMapSize > SCREEN_HEIGHT * 3.0f && in) \ break; \ float z2 = in? 1.1f : 1.f/1.1f; \ - fMapCenterX += (x - fMapCenterX) * (1.0f - z2); \ - fMapCenterY += (y - fMapCenterY) * (1.0f - z2); \ + m_fMapCenterX += (x - m_fMapCenterX) * (1.0f - z2); \ + m_fMapCenterY += (y - m_fMapCenterY) * (1.0f - z2); \ \ - if (fMapSize < SCREEN_HEIGHT / 2 && !in) \ + if (m_fMapSize < SCREEN_HEIGHT / 2 && !in) \ break; \ \ - fMapSize *= z2; \ + m_fMapSize *= z2; \ } while(0) \ void CMenuManager::PrintMap(void) { CFont::SetJustifyOn(); - bMenuMapActive = true; + m_bMenuMapActive = true; CRadar::InitFrontEndMap(); // Just entered to map if (!bMapLoaded) { - fMapSize = SCREEN_HEIGHT * 2.0f; - fMapCenterX = 0.0f; - fMapCenterY = 0.0f; + 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); - fMapCenterX = (-screenSpacePlayer.x) + SCREEN_WIDTH / 2; - fMapCenterY = (-screenSpacePlayer.y) + SCREEN_HEIGHT / 2; + 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) { - bMenuMapActive = false; + m_bMenuMapActive = false; return; } } - // Because fMapSize is half of the map length, and map consists of 3x3 tiles. - float halfTile = fMapSize / 3.0f; + // Because m_fMapSize is half of the map length, and map consists of 3x3 tiles. + float halfTile = m_fMapSize / 3.0f; // Darken background a bit CSprite2d::DrawRect(CRect(0, 0, @@ -5607,49 +5210,49 @@ CMenuManager::PrintMap(void) RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); - if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize, - fMapCenterX - halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) { + m_aFrontEndSprites[MENUSPRITE_MAPTOP01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY - m_fMapSize, + m_fMapCenterX - halfTile, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize, - fMapCenterX + halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) { + m_aFrontEndSprites[MENUSPRITE_MAPTOP02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY - m_fMapSize, + m_fMapCenterX + halfTile, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) { - m_aMapSprites[MAPTOP3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize, - fMapCenterX + fMapSize, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) { + m_aFrontEndSprites[MENUSPRITE_MAPTOP03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY - m_fMapSize, + m_fMapCenterX + m_fMapSize, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile, - fMapCenterX - halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPMID01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY - halfTile, + m_fMapCenterX - halfTile, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile, - fMapCenterX + halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPMID02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY - halfTile, + m_fMapCenterX + halfTile, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) { - m_aMapSprites[MAPMID3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile, - fMapCenterX + fMapSize, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPMID03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY - halfTile, + m_fMapCenterX + m_fMapSize, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile, - fMapCenterX - halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPBOT01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY + halfTile, + m_fMapCenterX - halfTile, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile, - fMapCenterX + halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPBOT02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY + halfTile, + m_fMapCenterX + halfTile, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } - if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) { - m_aMapSprites[MAPBOT3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile, - fMapCenterX + fMapSize, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255))); + if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) { + m_aFrontEndSprites[MENUSPRITE_MAPBOT03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY + halfTile, + m_fMapCenterX + m_fMapSize, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255))); } CRadar::DrawBlips(); @@ -5673,34 +5276,35 @@ CMenuManager::PrintMap(void) CRGBA(0, 0, 0, 150)); if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { - if (mapPoint.y > fMapCenterY - fMapSize && mapPoint.y < fMapCenterY + fMapSize && - mapPoint.x > fMapCenterX - fMapSize && mapPoint.x < fMapCenterX + fMapSize) { + 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) { - float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize; - float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f; - float y = 2000.0f - ((mapPoint.y - diffY) / (fMapSize * 2)) * 4000.0f; + // 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_MENU_SETTING_CHANGE, 0); } } if (CPad::GetPad(0)->GetLeftMouse()) { - fMapCenterX += m_nMousePosX - m_nMouseOldPosX; - fMapCenterY += m_nMousePosY - m_nMouseOldPosY; + m_fMapCenterX += m_nMousePosX - m_nMouseOldPosX; + m_fMapCenterY += m_nMousePosY - m_nMouseOldPosY; } else if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetDPadLeft()) { - fMapCenterX += 15.0f; + m_fMapCenterX += 15.0f; } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetDPadRight()) { - fMapCenterX -= 15.0f; + m_fMapCenterX -= 15.0f; } else if (CPad::GetPad(0)->GetLeftStickX()) { - fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f; + m_fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f; } if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetDPadUp()) { - fMapCenterY += 15.0f; + m_fMapCenterY += 15.0f; } else if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetDPadDown()) { - fMapCenterY -= 15.0f; + m_fMapCenterY -= 15.0f; } else if (CPad::GetPad(0)->GetLeftStickY()) { - fMapCenterY -= CPad::GetPad(0)->GetLeftStickY() / 128.0f * 20.0f; + m_fMapCenterY -= CPad::GetPad(0)->GetLeftStickY() / 128.0f * 20.0f; } if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) { @@ -5715,25 +5319,26 @@ CMenuManager::PrintMap(void) ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true); } - if (fMapCenterX - fMapSize > SCREEN_WIDTH / 2) - fMapCenterX = fMapSize + SCREEN_WIDTH / 2; + if (m_fMapCenterX - m_fMapSize > SCREEN_WIDTH / 2) + m_fMapCenterX = m_fMapSize + SCREEN_WIDTH / 2; - if (fMapCenterX + fMapSize < SCREEN_WIDTH / 2) - fMapCenterX = SCREEN_WIDTH / 2 - fMapSize; + if (m_fMapCenterX + m_fMapSize < SCREEN_WIDTH / 2) + m_fMapCenterX = SCREEN_WIDTH / 2 - m_fMapSize; - if (fMapCenterY + fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f)) - fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - fMapSize; + if (m_fMapCenterY + m_fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f)) + m_fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - m_fMapSize; - fMapCenterY = Min(fMapCenterY, fMapSize); // To not show beyond north border + if (m_fMapCenterY - m_fMapSize > SCREEN_HEIGHT / 2) + m_fMapCenterY = SCREEN_HEIGHT / 2 + m_fMapSize; - bMenuMapActive = false; + m_bMenuMapActive = false; // CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); // From VC // CFont::SetRightJustifyWrap(10.0f); CSprite2d::DrawRect(CRect(MENU_X(14.0f), SCREEN_STRETCH_FROM_BOTTOM(95.0f), SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)), - CRGBA(235, 170, 50, 255)); + CRGBA(MAPINFOBOX_COLOR.r, MAPINFOBOX_COLOR.g, MAPINFOBOX_COLOR.b, MAPINFOBOX_COLOR.a)); CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f)); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); @@ -5794,9 +5399,7 @@ CMenuManager::ConstructStatLine(int rowIdx) STAT_LINE("PL_STAT", nil, false, nil); - int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : - CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1)); - percentCompleted = Min(percentCompleted, 100); + int percentCompleted = CStats::GetPercentageProgress(); STAT_LINE("PER_COM", &percentCompleted, false, nil); STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); @@ -5970,4 +5573,3 @@ uint8 CMenuManager::GetNumberOfMenuOptions() #undef GetBackJustUp #undef GetBackJustDown -#undef ChangeScreen diff --git a/src/core/Frontend.h b/src/core/Frontend.h index f992b5c8..e22f878e 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -7,30 +7,43 @@ #define MENUHEADER_POS_Y 75.0f #define MENUHEADER_HEIGHT 1.3f #else -#define MENUHEADER_POS_X 35.0f -#define MENUHEADER_POS_Y 93.0f -#define MENUHEADER_HEIGHT 1.6f +#define MENUHEADER_POS_X 10.0f +#define MENUHEADER_POS_Y 10.0f +#define MENUHEADER_HEIGHT 2.0f #endif -#define MENUHEADER_WIDTH 0.84f +#define MENUHEADER_WIDTH 1.0f + +#define MENU_UNK_X_MARGIN 10.0f +#define MENU_UNK_WIDTH 10.0f -#define MENU_X_MARGIN 40.0f -#define MENUACTION_POS_Y 60.0f -#define MENUACTION_WIDTH 38.0f #define MENUACTION_SCALE_MULT 0.9f -#define MENURADIO_ICON_SCALE 60.0f +#define MENULABEL_X_MARGIN 80.0f +#define MENULABEL_WIDTH 80.0f +#define MENULABEL_POS_X 100.0f +#define MENULABEL_POS_Y 97.0f + +#define MENU_DEFAULT_CONTENT_X 320 +#define MENU_DEFAULT_CONTENT_Y 100 +#define MENU_DEFAULT_LINE_HEIGHT 29 -#define MENUSLIDER_X 256.0f -#define MENUSLIDER_UNK 256.0f +#define MENURADIO_ICON_SCALE 60.0f -#define BIGTEXT_X_SCALE 0.75f -#define BIGTEXT_Y_SCALE 0.9f -#define MEDIUMTEXT_X_SCALE 0.55f -#define MEDIUMTEXT_Y_SCALE 0.8f -#define SMALLTEXT_X_SCALE 0.45f -#define SMALLTEXT_Y_SCALE 0.7f -#define SMALLESTTEXT_X_SCALE 0.4f -#define SMALLESTTEXT_Y_SCALE 0.6f +#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_Y_SCALE 1.2f +#define BIGTEXT_X_SCALE 0.6f +#define BIGTEXT_Y_SCALE 1.0f +#define MEDIUMTEXT_X_SCALE 0.48f +#define MEDIUMTEXT_Y_SCALE 1.0f +#define SMALLTEXT_X_SCALE 0.42f +#define SMALLTEXT_Y_SCALE 0.9f +#define SMALLESTTEXT_X_SCALE 0.3f +#define SMALLESTTEXT_Y_SCALE 0.7f #define PLAYERSETUP_LIST_TOP 28.0f #define PLAYERSETUP_LIST_BOTTOM 125.0f @@ -95,62 +108,41 @@ enum eLanguages #endif }; -enum eFrontendSprites +enum { - FE2_MAINPANEL_UL, - FE2_MAINPANEL_UR, - FE2_MAINPANEL_DL, - FE2_MAINPANEL_DR, - FE2_MAINPANEL_DR2, - FE2_TABACTIVE, - FE_ICONBRIEF, - FE_ICONSTATS, - FE_ICONCONTROLS, - FE_ICONSAVE, - FE_ICONAUDIO, - FE_ICONDISPLAY, - FE_ICONLANGUAGE, - FE_CONTROLLER, - FE_CONTROLLERSH, - FE_ARROWS1, - FE_ARROWS2, - FE_ARROWS3, - FE_ARROWS4, - FE_RADIO1, - FE_RADIO2, - FE_RADIO3, - FE_RADIO4, - FE_RADIO5, - FE_RADIO6, - FE_RADIO7, - FE_RADIO8, - FE_RADIO9, - - NUM_FE_SPRITES + MENUALIGN_LEFT = 1, + MENUALIGN_RIGHT, + MENUALIGN_CENTER, }; enum eMenuSprites { - MENUSPRITE_CONNECTION, - MENUSPRITE_FINDGAME, - MENUSPRITE_HOSTGAME, - MENUSPRITE_MAINMENU, - MENUSPRITE_PLAYERSET, - MENUSPRITE_SINGLEPLAYER, - MENUSPRITE_MULTIPLAYER, - MENUSPRITE_DMALOGO, - MENUSPRITE_GTALOGO, - MENUSPRITE_RSTARLOGO, - MENUSPRITE_GAMESPY, + MENUSPRITE_BACKGROUND, + MENUSPRITE_VCLOGO, MENUSPRITE_MOUSE, - MENUSPRITE_MOUSET, - MENUSPRITE_MP3LOGO, + MENUSPRITE_MAPTOP01, + MENUSPRITE_MAPTOP02, + MENUSPRITE_MAPTOP03, + MENUSPRITE_MAPMID01, + MENUSPRITE_MAPMID02, + MENUSPRITE_MAPMID03, + MENUSPRITE_MAPBOT01, + MENUSPRITE_MAPBOT02, + MENUSPRITE_MAPBOT03, + MENUSPRITE_WILDSTYLE, + MENUSPRITE_FLASH, + MENUSPRITE_KCHAT, + MENUSPRITE_FEVER, + MENUSPRITE_VROCK, + MENUSPRITE_VCPR, + MENUSPRITE_ESPANTOSO, + MENUSPRITE_EMOTION, + MENUSPRITE_WAVE, + MENUSPRITE_MP3, MENUSPRITE_DOWNOFF, MENUSPRITE_DOWNON, MENUSPRITE_UPOFF, MENUSPRITE_UPON, - MENUSPRITE_GTA3LOGO, - MENUSPRITE_UNUSED, NUM_MENU_SPRITES }; @@ -169,86 +161,52 @@ enum eSaveSlot SAVESLOT_LABEL = 36 }; -#ifdef MENU_MAP -enum MapSprites -{ - MAPMID1, - MAPMID2, - MAPMID3, - MAPBOT1, - MAPBOT2, - MAPBOT3, - MAPTOP1, - MAPTOP2, - MAPTOP3, - NUM_MAP_SPRITES -}; -#endif - enum eMenuScreen { MENUPAGE_DISABLED = -1, - MENUPAGE_NONE = 0, - MENUPAGE_STATS = 1, - MENUPAGE_NEW_GAME = 2, - MENUPAGE_BRIEFS = 3, - MENUPAGE_CONTROLLER_SETTINGS = 4, - MENUPAGE_SOUND_SETTINGS = 5, - MENUPAGE_GRAPHICS_SETTINGS = 6, - MENUPAGE_LANGUAGE_SETTINGS = 7, + MENUPAGE_STATS = 0, + MENUPAGE_NEW_GAME = 1, + MENUPAGE_BRIEFS = 2, + MENUPAGE_SOUND_SETTINGS = 3, + MENUPAGE_GRAPHICS_SETTINGS = 4, + MENUPAGE_LANGUAGE_SETTINGS = 5, + MENUPAGE_MAP = 6, + MENUPAGE_NEW_GAME_RELOAD = 7, MENUPAGE_CHOOSE_LOAD_SLOT = 8, MENUPAGE_CHOOSE_DELETE_SLOT = 9, - MENUPAGE_NEW_GAME_RELOAD = 10, - MENUPAGE_LOAD_SLOT_CONFIRM = 11, - MENUPAGE_DELETE_SLOT_CONFIRM = 12, - MENUPAGE_NO_MEMORY_CARD = 13, // hud adjustment page in mobile - MENUPAGE_LOADING_IN_PROGRESS = 14, - MENUPAGE_DELETING_IN_PROGRESS = 15, - MENUPAGE_PS2_LOAD_FAILED = 16, - MENUPAGE_DELETE_FAILED = 17, - MENUPAGE_DEBUG_MENU = 18, - MENUPAGE_MEMORY_CARD_DEBUG = 19, - MENUPAGE_MEMORY_CARD_TEST = 20, - MENUPAGE_MULTIPLAYER_MAIN = 21, - MENUPAGE_PS2_SAVE_FAILED = 22, - MENUPAGE_PS2_SAVE_FAILED_2 = 23, - MENUPAGE_SAVE = 24, - MENUPAGE_NO_MEMORY_CARD_2 = 25, - MENUPAGE_CHOOSE_SAVE_SLOT = 26, - MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27, - MENUPAGE_MULTIPLAYER_MAP = 28, - MENUPAGE_MULTIPLAYER_CONNECTION = 29, - MENUPAGE_MULTIPLAYER_FIND_GAME = 30, - MENUPAGE_MULTIPLAYER_MODE = 31, - MENUPAGE_MULTIPLAYER_CREATE = 32, - MENUPAGE_MULTIPLAYER_START = 33, - MENUPAGE_SKIN_SELECT_OLD = 34, - MENUPAGE_CONTROLLER_PC = 35, - MENUPAGE_CONTROLLER_PC_OLD1 = 36, - MENUPAGE_CONTROLLER_PC_OLD2 = 37, - MENUPAGE_CONTROLLER_PC_OLD3 = 38, - MENUPAGE_CONTROLLER_PC_OLD4 = 39, - MENUPAGE_CONTROLLER_DEBUG = 40, - MENUPAGE_OPTIONS = 41, - MENUPAGE_EXIT = 42, - MENUPAGE_SAVING_IN_PROGRESS = 43, - MENUPAGE_SAVE_SUCCESSFUL = 44, - MENUPAGE_DELETING = 45, - MENUPAGE_DELETE_SUCCESS = 46, - MENUPAGE_SAVE_FAILED = 47, - MENUPAGE_LOAD_FAILED = 48, - MENUPAGE_LOAD_FAILED_2 = 49, - MENUPAGE_FILTER_GAME = 50, - MENUPAGE_START_MENU = 51, - MENUPAGE_PAUSE_MENU = 52, - MENUPAGE_CHOOSE_MODE = 53, - MENUPAGE_SKIN_SELECT = 54, - MENUPAGE_KEYBOARD_CONTROLS = 55, - MENUPAGE_MOUSE_CONTROLS = 56, - MENUPAGE_MISSION_RETRY = 57, - MENUPAGE_58 = 58, -#ifdef MENU_MAP - MENUPAGE_MAP = 59, + MENUPAGE_LOAD_SLOT_CONFIRM = 10, + MENUPAGE_DELETE_SLOT_CONFIRM = 11, + MENUPAGE_LOADING_IN_PROGRESS = 12, + MENUPAGE_DELETING_IN_PROGRESS = 13, + MENUPAGE_DELETE_SUCCESSFUL = 14, + MENUPAGE_CHOOSE_SAVE_SLOT = 15, + MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16, + MENUPAGE_SAVING_IN_PROGRESS = 17, + MENUPAGE_SAVE_SUCCESSFUL = 18, + MENUPAGE_SAVE_CUSTOM_WARNING = 19, + MENUPAGE_SAVE_CHEAT_WARNING = 20, + MENUPAGE_SKIN_SELECT = 21, + MENUPAGE_SAVE_UNUSED = 22, + MENUPAGE_SAVE_FAILED = 23, + MENUPAGE_SAVE_FAILED_2 = 24, + MENUPAGE_LOAD_FAILED = 25, + MENUPAGE_CONTROLLER_PC = 26, + MENUPAGE_OPTIONS = 27, + MENUPAGE_EXIT = 28, + MENUPAGE_START_MENU = 29, + MENUPAGE_KEYBOARD_CONTROLS = 30, + 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, + MENUPAGE_CONTROLLER_PC_OLD1, + MENUPAGE_CONTROLLER_PC_OLD2, + MENUPAGE_CONTROLLER_PC_OLD3, + MENUPAGE_CONTROLLER_PC_OLD4, + MENUPAGE_CONTROLLER_DEBUG, #endif MENUPAGES }; @@ -257,20 +215,19 @@ enum eMenuAction { MENUACTION_NOTHING, MENUACTION_LABEL, + MENUACTION_YES, + MENUACTION_NO, MENUACTION_CHANGEMENU, MENUACTION_CTRLVIBRATION, MENUACTION_CTRLCONFIG, - MENUACTION_CTRLDISPLAY, MENUACTION_FRAMESYNC, MENUACTION_FRAMELIMIT, MENUACTION_TRAILS, MENUACTION_SUBTITLES, MENUACTION_WIDESCREEN, MENUACTION_BRIGHTNESS, - MENUACTION_DRAWDIST, MENUACTION_MUSICVOLUME, MENUACTION_SFXVOLUME, - MENUACTION_UNK15, MENUACTION_RADIO, MENUACTION_LANG_ENG, MENUACTION_LANG_FRE, @@ -279,74 +236,33 @@ enum eMenuAction MENUACTION_LANG_SPA, MENUACTION_POPULATESLOTS_CHANGEMENU, MENUACTION_CHECKSAVE, - MENUACTION_UNK24, MENUACTION_NEWGAME, + MENUACTION_RESUME_FROM_SAVEZONE, MENUACTION_RELOADIDE, - MENUACTION_RELOADIPL, MENUACTION_SETDBGFLAG, + MENUACTION_LOADRADIO, + MENUACTION_SAVEGAME, + + // Below this is TODO(Miami) + MENUACTION_DRAWDIST, MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, - MENUACTION_PEDROADGROUPS, - MENUACTION_CARROADGROUPS, MENUACTION_COLLISIONPOLYS, - MENUACTION_REGMEMCARD1, - MENUACTION_TESTFORMATMEMCARD1, - MENUACTION_TESTUNFORMATMEMCARD1, - MENUACTION_CREATEROOTDIR, - MENUACTION_CREATELOADICONS, - MENUACTION_FILLWITHGUFF, - MENUACTION_SAVEONLYTHEGAME, - MENUACTION_SAVEGAME, - MENUACTION_SAVEGAMEUNDERGTA, - MENUACTION_CREATECOPYPROTECTED, - MENUACTION_TESTSAVE, - MENUACTION_TESTLOAD, - MENUACTION_TESTDELETE, + MENUACTION_LEGENDS, + MENUACTION_RADARMODE, + MENUACTION_HUD, + MENUACTION_GOBACK, + MENUACTION_KEYBOARDCTRLS, MENUACTION_PARSEHEAP, - MENUACTION_SHOWCULL, - MENUACTION_MEMCARDSAVECONFIRM, - MENUACTION_RESUME_FROM_SAVEZONE, - MENUACTION_UNK50, + // MENUACTION_MEMCARDSAVECONFIRM is that on VC enum?? MENUACTION_DEBUGSTREAM, - MENUACTION_MPMAP_LIBERTY, - MENUACTION_MPMAP_REDLIGHT, - MENUACTION_MPMAP_CHINATOWN, - MENUACTION_MPMAP_TOWER, - MENUACTION_MPMAP_SEWER, - MENUACTION_MPMAP_INDUSTPARK, - MENUACTION_MPMAP_DOCKS, - MENUACTION_MPMAP_STAUNTON, - MENUACTION_MPMAP_DEATHMATCH1, - MENUACTION_MPMAP_DEATHMATCH2, - MENUACTION_MPMAP_TEAMDEATH1, - MENUACTION_MPMAP_TEAMDEATH2, - MENUACTION_MPMAP_STASH, - MENUACTION_MPMAP_CAPTURE, - MENUACTION_MPMAP_RATRACE, - MENUACTION_MPMAP_DOMINATION, - MENUACTION_STARTMP, - MENUACTION_UNK69, - MENUACTION_UNK70, - MENUACTION_FINDMP, - MENUACTION_KEYBOARDCTRLS, - MENUACTION_UNK73, - MENUACTION_INITMP, - MENUACTION_MP_PLAYERCOLOR, - MENUACTION_MP_PLAYERNAME, - MENUACTION_MP_GAMENAME, + //MENUACTION_KEYBOARDCTRLS, MENUACTION_GETKEY, MENUACTION_SHOWHEADBOB, MENUACTION_UNK80, MENUACTION_INVVERT, MENUACTION_CANCELGAME, - MENUACTION_MP_PLAYERNUMBER, MENUACTION_MOUSESENS, - MENUACTION_CHECKMPGAMES, - MENUACTION_CHECKMPPING, - MENUACTION_MP_SERVER, - MENUACTION_MP_MAP, - MENUACTION_MP_GAMETYPE, - MENUACTION_MP_LAN, - MENUACTION_MP_INTERNET, + MENUACTION_MP3VOLUMEBOOST, MENUACTION_RESUME, MENUACTION_DONTCANCEL, MENUACTION_SCREENRES, @@ -356,7 +272,6 @@ enum eMenuAction MENUACTION_RESTOREDEF, MENUACTION_CTRLMETHOD, MENUACTION_DYNAMICACOUSTIC, - MENUACTION_LOADRADIO, MENUACTION_MOUSESTEER, MENUACTION_UNK103, MENUACTION_UNK104, @@ -366,12 +281,16 @@ enum eMenuAction MENUACTION_UNK108, MENUACTION_UNK109, MENUACTION_UNK110, - MENUACTION_UNK111, - MENUACTION_UNK112, - MENUACTION_REJECT_RETRY, - MENUACTION_UNK114, -#ifdef CUSTOM_FRONTEND_OPTIONS - MENUACTION_TRIGGERFUNC +#ifdef MORE_LANGUAGES + MENUACTION_LANG_PL, + MENUACTION_LANG_RUS, + MENUACTION_LANG_JAP, +#endif +#ifdef IMPROVED_VIDEOMODE + MENUACTION_SCREENMODE, +#endif +#ifdef FREE_CAM + MENUACTION_FREECAM #endif }; @@ -424,7 +343,11 @@ enum eCheckHover enum { - NUM_MENUROWS = 18, +#ifdef LEGACY_MENU_OPTIONS + NUM_MENUROWS = 14, +#else + NUM_MENUROWS = 12, +#endif }; enum eControlMethod @@ -458,82 +381,210 @@ struct BottomBarOption struct CMenuScreen { char m_ScreenName[8]; - int32 unk; // 2 on MENUPAGE_MULTIPLAYER_START, 1 on everywhere else - int32 m_PreviousPage[2]; // eMenuScreen - int32 m_ParentEntry[2]; // row + int32 m_PreviousPage; // eMenuScreen + int32 m_ParentEntry; // row struct CMenuEntry { int32 m_Action; // eMenuAction char m_EntryName[8]; int32 m_SaveSlot; // eSaveSlot - int32 m_TargetMenu; // eMenuScreen // FrontendOption ID if it's a custom option + int32 m_TargetMenu; // eMenuScreen + uint16 m_X; + uint16 m_Y; + uint8 m_Align; } m_aEntries[NUM_MENUROWS]; }; +struct MenuTrapezoid +{ + float topLeft_x; + float topLeft_y; + float topRight_x; + float topRight_y; + float bottomLeft_x; + float bottomLeft_y; + float bottomRight_x; + float bottomRight_y; + float old_topRight_x; + float old_topRight_y; + float old_topLeft_x; + float old_topLeft_y; + float old_bottomLeft_x; + float old_bottomLeft_y; + float old_bottomRight_x; + float old_bottomRight_y; + float mult_topRight_x; + float mult_topRight_y; + float mult_topLeft_x; + float mult_topLeft_y; + float mult_bottomLeft_x; + float mult_bottomLeft_y; + float mult_bottomRight_x; + float mult_bottomRight_y; + + MenuTrapezoid(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) { + topLeft_x = x1; + topLeft_y = y1; + topRight_x = x2; + topRight_y = y2; + bottomLeft_x = x3; + bottomLeft_y = y3; + bottomRight_x = x4; + bottomRight_y = y4; + }; + + void SaveCurrentCoors() { + old_topLeft_x = topLeft_x; + old_topLeft_y = topLeft_y; + old_topRight_x = topRight_x; + old_topRight_y = topRight_y; + old_bottomLeft_x = bottomLeft_x; + old_bottomLeft_y = bottomLeft_y; + old_bottomRight_x = bottomRight_x; + old_bottomRight_y = bottomRight_y; + } + + void Translate(int delta) { + bottomRight_x = delta * mult_bottomRight_x + old_bottomRight_x; + bottomRight_y = delta * mult_bottomRight_y + old_bottomRight_y; + bottomLeft_x = delta * mult_bottomLeft_x + old_bottomLeft_x; + bottomLeft_y = delta * mult_bottomLeft_y + old_bottomLeft_y; + topRight_x = delta * mult_topRight_x + old_topRight_x; + topRight_y = delta * mult_topRight_y + old_topRight_y; + topLeft_x = delta * mult_topLeft_x + old_topLeft_x; + topLeft_y = delta * mult_topLeft_y + old_topLeft_y; + } + + void UpdateMultipliers() { + mult_bottomRight_x = (bottomRight_x - old_bottomRight_x) / 255.0f; + mult_bottomRight_y = (bottomRight_y - old_bottomRight_y) / 255.0f; + mult_bottomLeft_x = (bottomLeft_x - old_bottomLeft_x) / 255.0f; + mult_bottomLeft_y = (bottomLeft_y - old_bottomLeft_y) / 255.0f; + mult_topRight_x = (topRight_x - old_topRight_x) / 255.0f; + mult_topRight_y = (topRight_y - old_topRight_y) / 255.0f; + mult_topLeft_x = (topLeft_x - old_topLeft_x) / 255.0f; + mult_topLeft_y = (topLeft_y - old_topLeft_y) / 255.0f; + } +}; + class CMenuManager { public: - int32 m_nPrefsVideoMode; - int32 m_nDisplayVideoMode; + int8 m_StatsScrollDirection; + float m_StatsScrollSpeed; + uint8 field_8; + bool m_PrefsUseVibration; + bool m_PrefsShowHud; + int32 m_PrefsRadarMode; + uint8 field_10; + bool m_bShutDownFrontEndRequested; + bool m_bStartUpFrontEndRequested; + int32 m_KeyPressedCode; + int32 m_PrefsBrightness; + float m_PrefsLOD; + int8 m_PrefsShowSubtitles; + int8 m_PrefsShowLegends; + int8 m_PrefsUseWideScreen; + int8 m_PrefsVsync; // TODO(Miami): Are we sure? + int8 m_PrefsVsyncDisp; + int8 m_PrefsFrameLimiter; int8 m_nPrefsAudio3DProviderIndex; - bool m_bKeyChangeNotProcessed; - char m_aSkinName[256]; - int32 m_nHelperTextMsgId; - bool m_bLanguageLoaded; + int8 m_PrefsSpeakers; + int8 m_PrefsDMA; + uint8 m_PrefsSfxVolume; + uint8 m_PrefsMusicVolume; + uint8 m_PrefsRadioStation; + uint8 field_2C; + int32 m_nCurrOption; + bool m_bQuitGameNoCD; + bool m_bMenuMapActive; + bool m_AllowNavigation; + uint8 field_37; bool m_bMenuActive; - bool m_bMenuStateChanged; - bool m_bWaitingForNewKeyBind; bool m_bWantToRestart; bool m_bFirstTime; - bool m_bGameNotLoaded; - int32 m_nMousePosX; - int32 m_nMousePosY; + bool m_bActivateSaveMenu; + bool m_bWantToLoad; + float m_fMapSize; + float m_fMapCenterX; + float m_fMapCenterY; + uint32 OS_Language; + int32 m_PrefsLanguage; + int32 field_54; + int8 m_bLanguageLoaded; + uint8 m_PrefsAllowNastyGame; + uint8 m_PrefsMP3BoostVolume; + uint8 m_ControlMethod; + int32 m_nPrefsVideoMode; + int32 m_nDisplayVideoMode; int32 m_nMouseTempPosX; int32 m_nMouseTempPosY; - bool m_bShowMouse; - tSkinInfo m_pSkinListHead; - tSkinInfo *m_pSelectedSkin; - int32 m_nFirstVisibleRowOnList; - float m_nScrollbarTopMargin; - int32 m_nTotalListRow; - int32 m_nSkinsTotal; - char _unk0[4]; - int32 m_nSelectedListRow; - bool m_bSkinsEnumerated; - bool m_bQuitGameNoCD; - bool m_bRenderGameInMenu; - bool m_bSaveMenuActive; - bool m_bWantToLoad; - char field_455; - bool m_bStartWaitingForKeyBind; + bool m_bGameNotLoaded; + int8 m_lastWorking3DAudioProvider; + bool m_bFrontEnd_ReloadObrTxtGxt; + int32 *pEditString; + uint8 field_74[4]; + int32 *pControlEdit; + bool m_OnlySaveMenu; + int32 m_menuTransitionProgress; + CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES]; bool m_bSpritesLoaded; - CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES]; - CSprite2d m_aMenuSprites[NUM_MENU_SPRITES]; - int32 field_518; + int32 field_F0; + int32 m_LastRadioScrollDir; + int32 m_nCurrScreen; + int32 m_nPrevScreen; + int32 m_nCurrSaveSlot; + uint32 m_LastScreenSwitch; int32 m_nMenuFadeAlpha; + int32 m_nOptionHighlightTransitionBlend; + bool bMenuChangeOngoing; + int32 MouseButtonJustClicked; + int32 JoyButtonJustClicked; + bool DisplayComboButtonErrMsg; + bool m_NoEmptyBinding; + bool m_ShowEmptyBindingError; + int32 m_nHelperTextAlpha; bool m_bPressedPgUpOnList; bool m_bPressedPgDnOnList; bool m_bPressedUpOnList; bool m_bPressedDownOnList; bool m_bPressedScrollButton; - int32 m_CurrCntrlAction; - char _unk1[4]; - int32 m_nSelectedContSetupColumn; - bool m_bKeyIsOK; - bool field_535; - int8 m_nCurrExLayer; - int32 m_nHelperTextAlpha; + uint8 field_129; + uint8 field_12A; + uint8 field_12B; + int32 m_nMousePosX; + int32 m_nMousePosY; int32 m_nMouseOldPosX; int32 m_nMouseOldPosY; int32 m_nHoverOption; - int32 m_nCurrScreen; - int32 m_nCurrOption; + bool m_bShowMouse; int32 m_nPrevOption; - int32 m_nPrevScreen; - uint32 field_558; - int32 m_nCurrSaveSlot; - int32 m_nScreenChangeDelayTimer; + bool m_bStartWaitingForKeyBind; + bool m_bWaitingForNewKeyBind; + bool m_bKeyChangeNotProcessed; + int32 m_CurrCntrlAction; + uint8 field_150; + uint8 field_151; + uint8 field_152; + uint8 field_153; + int32 m_nSelectedContSetupColumn; + bool m_bKeyIsOK; + bool field_159; + uint8 m_nCurrExLayer; + char m_PrefsSkinFile[256]; + char m_aSkinName[256]; + uint8 field_35B; + int32 m_nHelperTextMsgId; + tSkinInfo m_pSkinListHead; + tSkinInfo *m_pSelectedSkin; + int32 m_nFirstVisibleRowOnList; + float m_nScrollbarTopMargin; + int32 m_nTotalListRow; + int32 m_nSkinsTotal; + uint8 field_67C[4]; + int32 m_nSelectedListRow; + bool m_bSkinsEnumerated; #ifdef IMPROVED_VIDEOMODE int32 m_nPrefsWidth; @@ -544,123 +595,78 @@ public: int32 m_nSelectedScreenMode; #endif -public: bool GetIsMenuActive() {return !!m_bMenuActive;} -public: - static int32 OS_Language; - static int8 m_PrefsUseVibration; - static int8 m_DisplayControllerOnFoot; - static int8 m_PrefsUseWideScreen; - static int8 m_PrefsRadioStation; - static int8 m_PrefsVsync; - static int8 m_PrefsVsyncDisp; - static int8 m_PrefsFrameLimiter; - static int8 m_PrefsShowSubtitles; - static int8 m_PrefsSpeakers; - static int32 m_ControlMethod; - static int8 m_PrefsDMA; - static int32 m_PrefsLanguage; - static int32 m_PrefsBrightness; - static float m_PrefsLOD; - static int8 m_bFrontEnd_ReloadObrTxtGxt; - static int32 m_PrefsMusicVolume; - static int32 m_PrefsSfxVolume; - static char m_PrefsSkinFile[256]; - static int32 m_KeyPressedCode; - - static bool m_bStartUpFrontEndRequested; - static bool m_bShutDownFrontEndRequested; - static bool m_PrefsAllowNastyGame; - static uint8 m_PrefsStereoMono; - static int32 m_SelectedMap; - static int32 m_SelectedGameType; - static uint8 m_PrefsPlayerRed; - static uint8 m_PrefsPlayerGreen; - static uint8 m_PrefsPlayerBlue; #ifndef MASTER static bool m_PrefsMarketing; static bool m_PrefsDisableTutorials; #endif // !MASTER -#ifdef MENU_MAP - static bool bMenuMapActive; - static bool bMapMouseShownOnce; - static bool bMapLoaded; - static float fMapSize; - static float fMapCenterY; - static float fMapCenterX; - static CSprite2d m_aMapSprites[NUM_MAP_SPRITES]; + CMenuManager(void); + ~CMenuManager(void) { UnloadTextures(); } + + void Initialise(); void PrintMap(); -#endif - -public: + 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); void CheckSliderMovement(int); - int CostructStatLine(int); void DisplayHelperText(); - int DisplaySlider(float, float, float, float, float, float); + int DisplaySlider(float, float, float, float, float, float, float); void DoSettingsBeforeStartingAGame(); - void Draw(); + void DrawStandardMenus(bool); void DrawControllerBound(int32, int32, int32, int8); void DrawControllerScreenExtraText(int, int, int); void DrawControllerSetupScreen(); + void DrawQuitGameScreen(); void DrawFrontEnd(); - void DrawFrontEndNormal(); -#ifdef PS2_SAVE_DIALOG - void DrawFrontEndSaveZone(); -#endif + void DrawBackground(bool transitionCall); void DrawPlayerSetupScreen(); int FadeIn(int alpha); void FilterOutColorMarkersFromString(wchar*, CRGBA &); int GetStartOptionsCntrlConfigScreens(); - static void InitialiseChangedLanguageSettings(); + void InitialiseChangedLanguageSettings(); void LoadAllTextures(); void LoadSettings(); - void MessageScreen(const char *); - void PickNewPlayerColour(); + void MessageScreen(const char *str, bool); + void SmallMessageScreen(const char *str); void PrintBriefs(); static void PrintErrorMessage(); void PrintStats(); void Process(); void ProcessButtonPresses(); + void ProcessFileActions(); void ProcessOnOffMenuOptions(); - static void RequestFrontEndShutDown(); - static void RequestFrontEndStartUp(); + void RequestFrontEndShutDown(); + void RequestFrontEndStartUp(); void ResetHelperText(); - void SaveLoadFileError_SetUpErrorScreen(); void SaveSettings(); void SetHelperText(int text); - void ShutdownJustMenu(); float StretchX(float); float StretchY(float); void SwitchMenuOnAndOff(); void UnloadTextures(); void WaitForUserCD(); - void PrintController(); int GetNumOptionsCntrlConfigScreens(); int ConstructStatLine(int); + void SwitchToNewScreen(int8); - // Those are either inlined in game, not in function yet, or I can't believe that they're not inlined. - // Names were made up by me. - void ThingsToDoBeforeGoingBack(); + // New (not in function or inlined in the game) + void ThingsToDoBeforeLeavingPage(); void ScrollUpListByOne(); void ScrollDownListByOne(); void PageUpList(bool); void PageDownList(bool); - int8 GetPreviousPageOption(); // uint8 GetNumberOfMenuOptions(); }; #ifndef IMPROVED_VIDEOMODE -VALIDATE_SIZE(CMenuManager, 0x564); +VALIDATE_SIZE(CMenuManager, 0x688); #endif extern CMenuManager FrontEndMenuManager; -extern CMenuScreen aScreens[];
\ No newline at end of file diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 7983a7c3..3f75b46b 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -64,6 +64,7 @@ #include "Script.h" #include "Shadows.h" #include "Skidmarks.h" +#include "SetPieces.h" #include "SpecialFX.h" #include "Sprite2d.h" #include "Stats.h" @@ -84,10 +85,11 @@ #include "World.h" #include "ZoneCull.h" #include "Zones.h" +#include "Occlusion.h" #include "debugmenu.h" -#include "frontendoption.h" eLevelName CGame::currLevel; +int32 CGame::currArea; bool CGame::bDemoMode = true; bool CGame::nastyGame = true; bool CGame::frenchGame; @@ -218,20 +220,20 @@ bool CGame::InitialiseOnceAfterRW(void) if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 ) { - CMenuManager::m_PrefsSpeakers = 0; + FrontEndMenuManager.m_PrefsSpeakers = 0; int8 provider = DMAudio.AutoDetect3DProviders(); if ( provider != -1 ) FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = provider; } DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); - DMAudio.SetSpeakerConfig(CMenuManager::m_PrefsSpeakers); - DMAudio.SetDynamicAcousticModelingStatus(CMenuManager::m_PrefsDMA); - DMAudio.SetMusicMasterVolume(CMenuManager::m_PrefsMusicVolume); - DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume); + DMAudio.SetSpeakerConfig(FrontEndMenuManager.m_PrefsSpeakers); + DMAudio.SetDynamicAcousticModelingStatus(FrontEndMenuManager.m_PrefsDMA); + DMAudio.SetMusicMasterVolume(FrontEndMenuManager.m_PrefsMusicVolume); + DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume); DMAudio.SetEffectsFadeVol(127); DMAudio.SetMusicFadeVol(127); - CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile); + CWorld::Players[0].SetPlayerSkin(FrontEndMenuManager.m_PrefsSkinFile); #ifdef CUSTOM_FRONTEND_OPTIONS CustomFrontendOptionsPopulate(); @@ -253,7 +255,7 @@ bool CGame::Initialise(const char* datFile) strcpy(aDatFile, datFile); CPools::Initialise(); CIniFile::LoadIniFile(); - currLevel = LEVEL_INDUSTRIAL; + currLevel = LEVEL_BEACH; LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen()); gameTxdSlot = CTxdStore::AddTxdSlot("generic"); CTxdStore::Create(gameTxdSlot); @@ -273,7 +275,9 @@ bool CGame::Initialise(const char* datFile) ThePaths.AllocatePathFindInfoMem(4500); CWeather::Init(); CCullZones::Init(); + COcclusion::Init(); CCollision::Init(); + CSetPieces::Init(); CTheZones::Init(); CUserDisplay::Init(); CMessages::Init(); @@ -303,12 +307,11 @@ bool CGame::Initialise(const char* datFile) CWorld::Players[0].LoadPlayerSkin(); TestModelIndices(); LoadingScreen("Loading the Game", "Setup water", nil); - CWaterLevel::Initialise("DATA\\WATER.DAT"); + WaterLevelInitialise("DATA\\WATER.DAT"); TheConsole.Init(); CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; LoadingScreen("Loading the Game", "Setup streaming", nil); - CStreaming::Init(); CStreaming::LoadInitialVehicles(); CStreaming::LoadInitialPeds(); CStreaming::RequestBigBuildings(LEVEL_NONE); @@ -316,6 +319,7 @@ bool CGame::Initialise(const char* datFile) printf("Streaming uses %dK of its memory", CStreaming::ms_memoryUsed / 1024); LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen()); CAnimManager::LoadAnimFiles(); + CStreaming::LoadInitialWeapons(); CPed::Initialise(); CRouteNode::Initialise(); CEventList::Initialise(); @@ -356,10 +360,7 @@ bool CGame::Initialise(const char* datFile) CWaterCannons::Init(); CBridge::Init(); CGarages::Init(); - LoadingScreen("Loading the Game", "Position dynamic objects", nil); - CWorld::RepositionCertainDynamicObjects(); LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); - CCullZones::ResolveVisibilities(); CTrain::InitTrains(); CPlane::InitPlanes(); CCredits::Init(); @@ -370,7 +371,6 @@ bool CGame::Initialise(const char* datFile) CTheScripts::Process(); TheCamera.Process(); LoadingScreen("Loading the Game", "Load scene", nil); - CModelInfo::RemoveColModelsFromOtherLevels(currLevel); CCollision::ms_collisionInMemory = currLevel; for (int i = 0; i < MAX_PADS; i++) CPad::GetPad(i)->Clear(true); @@ -476,7 +476,6 @@ void CGame::ReInitGameObjectVariables(void) CSpecialFX::Init(); CWaterCannons::Init(); CParticle::ReloadConfig(); - CCullZones::ResolveVisibilities(); if ( !FrontEndMenuManager.m_bWantToLoad ) { @@ -494,24 +493,7 @@ void CGame::ReInitGameObjectVariables(void) void CGame::ReloadIPLs(void) { - CTimer::Stop(); - CWorld::RemoveStaticObjects(); - ThePaths.Init(); - CCullZones::Init(); - CFileLoader::ReloadPaths("GTA3.IDE"); - CFileLoader::LoadScene("INDUST.IPL"); - CFileLoader::LoadScene("COMMER.IPL"); - CFileLoader::LoadScene("SUBURBAN.IPL"); - CFileLoader::LoadScene("CULL.IPL"); - ThePaths.PreparePathData(); - CTrafficLights::ScanForLightsOnMap(); - CRoadBlocks::Init(); - CCranes::InitCranes(); - CGarages::Init(); - CWorld::RepositionCertainDynamicObjects(); - CCullZones::ResolveVisibilities(); - CRenderer::SortBIGBuildings(); - CTimer::Update(); + // Empty and unused } void CGame::ShutDownForRestart(void) @@ -527,6 +509,7 @@ void CGame::ShutDownForRestart(void) CTheScripts::UndoBuildingSwaps(); CTheScripts::UndoEntityInvisibilitySettings(); CWorld::ClearForRestart(); + CGameLogic::ClearShortCut(); CTimer::Shutdown(); CStreaming::FlushRequestList(); CStreaming::DeleteAllRwObjects(); @@ -535,6 +518,7 @@ void CGame::ShutDownForRestart(void) CRadar::RemoveRadarSections(); FrontEndMenuManager.UnloadTextures(); CParticleObject::RemoveAllParticleObjects(); + CSetPieces::Init(); CPedType::Shutdown(); CSpecialFX::Shutdown(); TidyUpMemory(true, false); @@ -547,7 +531,14 @@ void CGame::InitialiseWhenRestarting(void) CTimer::Initialise(); CSprite2d::SetRecipNearClip(); - + + if (b_FoundRecentSavedGameWantToLoad || FrontEndMenuManager.m_bWantToLoad) + { + LoadSplash("splash1"); + if (FrontEndMenuManager.m_bWantToLoad) + FrontEndMenuManager.MessageScreen("FELD_WR", true); + } + b_FoundRecentSavedGameWantToLoad = false; TheCamera.Init(); @@ -573,7 +564,7 @@ void CGame::InitialiseWhenRestarting(void) for ( int32 i = 0; i < 50; i++ ) { HandleExit(); - FrontEndMenuManager.MessageScreen("FED_LFL"); // Loading save game has failed. The game will restart now. + FrontEndMenuManager.MessageScreen("FED_LFL", true); // Loading save game has failed. The game will restart now. } ShutDownForRestart(); @@ -581,7 +572,7 @@ void CGame::InitialiseWhenRestarting(void) CTimer::Initialise(); FrontEndMenuManager.m_bWantToLoad = false; ReInitGameObjectVariables(); - currLevel = LEVEL_INDUSTRIAL; + currLevel = LEVEL_NONE; CCollision::SortOutCollisionAfterLoad(); } } @@ -628,6 +619,7 @@ void CGame::Process(void) CAntennas::Update(); CGlass::Update(); CSceneEdit::Update(); + CSetPieces::Update(); CEventList::Update(); CParticle::Update(); gFireManager.Update(); @@ -670,6 +662,30 @@ void CGame::Process(void) } } +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; +} + void CGame::DrasticTidyUpMemory(bool) { #ifdef PS2 diff --git a/src/core/Game.h b/src/core/Game.h index 48f31abc..49a3e67c 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -3,15 +3,37 @@ enum eLevelName { LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel LEVEL_NONE = 0, - LEVEL_INDUSTRIAL, - LEVEL_COMMERCIAL, - LEVEL_SUBURBAN + LEVEL_BEACH, + LEVEL_MAINLAND +}; + +enum eAreaName { + AREA_MAIN_MAP, + AREA_HOTEL, + AREA_MANSION, + AREA_BANK, + AREA_MALL, + AREA_STRIP_CLUB, + AREA_LAWYERS, + AREA_COFFEE_SHOP, + AREA_CONCERT_HALL, + AREA_STUDIO, + AREA_RIFLE_RANGE, + AREA_BIKER_BAR, + AREA_POLICE_STATION, + AREA_EVERYWHERE, + AREA_DIRT, + AREA_BLOOD, + AREA_OVALRING, + AREA_MALIBU_CLUB, + AREA_PRINT_WORKS }; class CGame { public: static eLevelName currLevel; + static int32 currArea; static bool bDemoMode; static bool nastyGame; static bool frenchGame; @@ -36,9 +58,17 @@ public: static void ShutDownForRestart(void); static void InitialiseWhenRestarting(void); static void Process(void); + + static void InitAfterFocusLoss(void); + + static bool IsInInterior(void) { return currArea != AREA_MAIN_MAP; } + static bool CanSeeWaterFromCurrArea(void); + static bool CanSeeOutSideFromCurrArea(void); // NB: these do something on PS2 static void TidyUpMemory(bool, bool); static void DrasticTidyUpMemory(bool); static void ProcessTidyUpMemory(void); }; + +inline bool IsAreaVisible(int area) { return area == CGame::currArea || area == AREA_EVERYWHERE; } diff --git a/src/core/General.h b/src/core/General.h index 7ffa99de..3188d82b 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -145,4 +145,6 @@ public: static int32 GetRandomNumberInRange(int32 low, int32 high) { return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); } + static void SetRandomSeed(int32 seed) + { mysrand(seed); } }; diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp deleted file mode 100644 index 7b66a27a..00000000 --- a/src/core/MenuScreens.cpp +++ /dev/null @@ -1,448 +0,0 @@ -#include "common.h" -#include "Frontend.h" - -// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp. - -CMenuScreen aScreens[] = { - // MENUPAGE_NONE = 0 - { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, }, - - // MENUPAGE_STATS = 1 - { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_NEW_GAME = 2 - { "FET_SGA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1, - MENUACTION_CHANGEMENU, "FES_SNG", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD, - MENUACTION_POPULATESLOTS_CHANGEMENU, "GMLOAD", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT, - MENUACTION_POPULATESLOTS_CHANGEMENU, "FES_DGA", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_BRIEFS = 3 - { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_CONTROLLER_SETTINGS = 4 - { "FET_CON", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0, - MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, - MENUACTION_CTRLDISPLAY, "FEC_CDP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, - MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_SOUND_SETTINGS = 5 - { "FET_AUD", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 1, 1, - MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_SFXVOLUME, "FEA_SFX", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_SPEAKERCONF, "FEA_SPK", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_DYNAMICACOUSTIC, "FET_DAM", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_RADIO, "FEA_RSS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_GRAPHICS_SETTINGS = 6 - { "FET_DIS", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2, - MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_LANGUAGE_SETTINGS = 7 - { "FET_LAN", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 3, 3, - MENUACTION_LANG_ENG, "FEL_ENG", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, - MENUACTION_LANG_FRE, "FEL_FRE", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, - MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, - MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, - MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_CHOOSE_LOAD_SLOT = 8 - { "FET_LG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 1, 1, - MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, - MENUACTION_CHECKSAVE, "FEM_SL0", SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM, - MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM, - MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_3, MENUPAGE_LOAD_SLOT_CONFIRM, - MENUACTION_CHECKSAVE, "FEM_SL3", SAVESLOT_4, MENUPAGE_LOAD_SLOT_CONFIRM, - MENUACTION_CHECKSAVE, "FEM_SL4", SAVESLOT_5, MENUPAGE_LOAD_SLOT_CONFIRM, - MENUACTION_CHECKSAVE, "FEM_SL5", SAVESLOT_6, MENUPAGE_LOAD_SLOT_CONFIRM, - MENUACTION_CHECKSAVE, "FEM_SL6", SAVESLOT_7, MENUPAGE_LOAD_SLOT_CONFIRM, - MENUACTION_CHECKSAVE, "FEM_SL7", SAVESLOT_8, MENUPAGE_LOAD_SLOT_CONFIRM, - }, - - // MENUPAGE_CHOOSE_DELETE_SLOT = 9 - { "FET_DG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 2, 2, - MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, - MENUACTION_CHANGEMENU, "FEM_SL0", SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL1", SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL2", SAVESLOT_3, MENUPAGE_DELETE_SLOT_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL3", SAVESLOT_4, MENUPAGE_DELETE_SLOT_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL4", SAVESLOT_5, MENUPAGE_DELETE_SLOT_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL5", SAVESLOT_6, MENUPAGE_DELETE_SLOT_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL6", SAVESLOT_7, MENUPAGE_DELETE_SLOT_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL7", SAVESLOT_8, MENUPAGE_DELETE_SLOT_CONFIRM, - }, - - // MENUPAGE_NEW_GAME_RELOAD = 10 - { "FET_NG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 0, 0, - MENUACTION_LABEL, "FESZ_QR", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NEW_GAME, - MENUACTION_NEWGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD, - }, - - // MENUPAGE_LOAD_SLOT_CONFIRM = 11 - { "FET_LG", 1, MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, 0, 0, - MENUACTION_LABEL, "FESZ_QL", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT, - MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS, - }, - - // MENUPAGE_DELETE_SLOT_CONFIRM = 12 - { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0, - MENUACTION_LABEL, "FESZ_QD", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, - MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_DELETING, - }, - - // MENUPAGE_NO_MEMORY_CARD = 13 - { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - // hud adjustment page in mobile - }, - - // MENUPAGE_LOADING_IN_PROGRESS = 14 - { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_LABEL, "FED_LDW", SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM, - }, - - // MENUPAGE_DELETING_IN_PROGRESS = 15 - { "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_LABEL, "FEDL_WR", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_PS2_LOAD_FAILED = 16 - { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_LABEL, "FES_LOE", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_DELETE_FAILED = 17 - { "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_LABEL, "FES_DEE", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, - }, - - // MENUPAGE_DEBUG_MENU = 18 - { "FED_DBG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 4, 0, - MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_RELOADIPL, "FED_RIP", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_PEDROADGROUPS, "FED_SPR", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CARROADGROUPS, "FED_SCR", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_COLLISIONPOLYS, "FED_SCP", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_PARSEHEAP, "FED_PAH", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_SHOWCULL, "FED_SCZ", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_DEBUGSTREAM, "FED_DSR", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_MEMORY_CARD_DEBUG = 19 - { "FEM_MCM", 1, MENUPAGE_NONE, MENUPAGE_NONE, 7, 0, - MENUACTION_REGMEMCARD1, "FEM_RMC", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_TESTFORMATMEMCARD1, "FEM_TFM", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_TESTUNFORMATMEMCARD1, "FEM_TUM", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CREATEROOTDIR, "FEM_CRD", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CREATELOADICONS, "FEM_CLI", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_FILLWITHGUFF, "FEM_FFF", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_SAVEONLYTHEGAME, "FEM_SOG", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_SAVEGAME, "FEM_STG", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_SAVEGAMEUNDERGTA, "FEM_STS", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CREATECOPYPROTECTED, "FEM_CPD", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_MEMORY_CARD_TEST = 20 - { "FEM_MC2", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_MULTIPLAYER_MAIN = 21 - { "FET_MP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_PS2_SAVE_FAILED = 22 - { "MCDNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_PS2_SAVE_FAILED_2 = 23 - { "MCGNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // Unused in PC but anyway - // MENUPAGE_SAVE = 24 -#ifdef PS2_SAVE_DIALOG - { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_CHANGEMENU, "FESZ_SA", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, - MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE, - }, -#else - { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_LABEL, "FES_SCG", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, - MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE, - }, -#endif - - // MENUPAGE_NO_MEMORY_CARD_2 = 25 - { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_CHOOSE_SAVE_SLOT = 26 - { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEM_SL1", SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL2", SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL3", SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL4", SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL5", SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL6", SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL7", SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - MENUACTION_CHANGEMENU, "FEM_SL8", SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM, - }, - - // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27 - { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, - MENUACTION_LABEL, "FESZ_QO", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS, - MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, - }, - - // MENUPAGE_MULTIPLAYER_MAP = 28 - { "FET_MAP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_MULTIPLAYER_CONNECTION = 29 - { "FET_CON", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_MULTIPLAYER_FIND_GAME = 30 - { "FET_FG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_MULTIPLAYER_MODE = 31 - { "FET_GT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_MULTIPLAYER_CREATE = 32 - { "FET_HG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_MULTIPLAYER_START = 33 - { "FEN_STA", 2, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_SKIN_SELECT_OLD = 34 - { "FET_PS", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_CONTROLLER_PC = 35 - { "FET_CTL", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0, - MENUACTION_CTRLMETHOD, "FET_CME", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, - MENUACTION_KEYBOARDCTRLS,"FET_RDK", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, - MENUACTION_CHANGEMENU, "FET_AMS", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_CONTROLLER_PC_OLD1 = 36 - { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 0, 0, - MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_CWR", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_LKT", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_PJP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_PSP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_TLF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_TRG", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_GETKEY, "FEC_CCM", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_CONTROLLER_PC_OLD2 = 37 - { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1, - - }, - - // MENUPAGE_CONTROLLER_PC_OLD3 = 38 - { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2, - MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, - MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, - MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, - MENUACTION_SHOWHEADBOB, "FEC_GSL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_CONTROLLER_PC_OLD4 = 39 - { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3, - - }, - - // MENUPAGE_CONTROLLER_DEBUG = 40 - { "FEC_DBG", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3, - MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, - MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, - MENUACTION_GETKEY, "FEC_TSS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, - MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_OPTIONS = 41 - { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4, - MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, - MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, - MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, - MENUACTION_CHANGEMENU, "FET_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, - MENUACTION_PLAYERSETUP, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_EXIT = 42 - { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5, - MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_SAVING_IN_PROGRESS = 43 - { "", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, - MENUACTION_LABEL, "FES_WAR", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_SAVE_SUCCESSFUL = 44 - { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, - MENUACTION_LABEL, "FES_SSC", SAVESLOT_LABEL, MENUPAGE_NONE, - MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, - }, - - // MENUPAGE_DELETING = 45 - { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0, - MENUACTION_LABEL, "FED_DLW", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_DELETE_SUCCESS = 46 - { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0, - MENUACTION_LABEL, "DEL_FNM", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, - }, - - // MENUPAGE_SAVE_FAILED = 47 - { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, - MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, - }, - - // MENUPAGE_LOAD_FAILED = 48 - { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, - MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_LOAD_FAILED_2 = 49 - { "FET_LG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, - MENUACTION_LABEL, "FEC_LUN", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT, - }, - - // MENUPAGE_FILTER_GAME = 50 - { "FIL_FLT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - - }, - - // MENUPAGE_START_MENU = 51 - { "FEM_MM", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, - MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, - MENUACTION_CHANGEMENU, "FEM_QT", SAVESLOT_NONE, MENUPAGE_EXIT, - }, - - // MENUPAGE_PAUSE_MENU = 52 - { "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, - MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS, - MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS, - MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, - MENUACTION_CHANGEMENU, "FEM_QT", SAVESLOT_NONE, MENUPAGE_EXIT, - }, - - // MENUPAGE_CHOOSE_MODE = 53 - { "FEN_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1, - MENUACTION_CHANGEMENU, "FET_SP", SAVESLOT_NONE, MENUPAGE_NEW_GAME, - MENUACTION_INITMP, "FET_MP", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - - // MENUPAGE_SKIN_SELECT = 54 - { "FET_PSU", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 4, 4, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN, - }, - - // MENUPAGE_KEYBOARD_CONTROLS = 55 - { "FET_STI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, - }, - - // MENUPAGE_MOUSE_CONTROLS = 56 - { "FET_MTI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2, - MENUACTION_MOUSESENS, "FEC_MSH", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, - MENUACTION_INVVERT, "FEC_IVV", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, - MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, - // MENUPAGE_MISSION_RETRY = 57 -#ifdef MISSION_REPLAY - - { "M_FAIL", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, - MENUACTION_LABEL, "FESZ_RM", SAVESLOT_NONE, MENUPAGE_NONE, - MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS, - MENUACTION_REJECT_RETRY, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE - }, -#else - { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0, - // mission failed, wanna restart page in mobile - }, -#endif - - // MENUPAGE_58 = 58 - { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0, - - }, - -#ifdef MENU_MAP - // MENUPAGE_MAP = 59 - { "FEG_MAP", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2, - MENUACTION_UNK110, "", SAVESLOT_NONE, MENUPAGE_NONE, // to prevent cross/enter to go back - MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, - }, -#endif -};
\ No newline at end of file diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.h new file mode 100644 index 00000000..cae65316 --- /dev/null +++ b/src/core/MenuScreens.h @@ -0,0 +1,345 @@ +#pragma once + +// --MIAMI: Done except commented things + +CMenuScreen aScreens[] = { + // MENUPAGE_STATS = 0 + { "FET_STA", MENUPAGE_NONE, 3, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_NEW_GAME = 1 + { "FEP_STG", MENUPAGE_NONE, 1, + MENUACTION_CHANGEMENU, "FES_NGA", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD, 320, 155, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_LOA", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_DEL", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_BRIEFS = 2 + { "FEH_BRI", MENUPAGE_NONE, 4, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_SOUND_SETTINGS = 3 + { "FEH_AUD", MENUPAGE_OPTIONS, 1, + MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 40, 76, MENUALIGN_LEFT, + MENUACTION_SFXVOLUME, "FEA_SFX", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT, + MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT, + MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT, + MENUACTION_SPEAKERCONF, "FEA_SPK", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT, + MENUACTION_DYNAMICACOUSTIC, "FET_DAM", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADIO, "FEA_RSS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 320, 367, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_GRAPHICS_SETTINGS = 4 +#ifdef LEGACY_MENU_OPTIONS + #define Y_OFFSET 50 +#else + #define Y_OFFSET 0 +#endif + + { "FEH_DIS", MENUPAGE_OPTIONS, 2, + MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 78, MENUALIGN_LEFT, + MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 103, MENUALIGN_LEFT, +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 128, MENUALIGN_LEFT, +#endif + MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 128 + Y_OFFSET/2, MENUALIGN_LEFT, +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 178, MENUALIGN_LEFT, +#endif + MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 153 + Y_OFFSET, MENUALIGN_LEFT, + MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 178 + Y_OFFSET, MENUALIGN_LEFT, + MENUACTION_LEGENDS, "MAP_LEG", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 202 + Y_OFFSET, MENUALIGN_LEFT, + MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT, + MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT, + MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT, +#ifdef IMPROVED_VIDEOMODE + MENUACTION_SCREENMODE, "FED_POS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT, + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_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_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 328 + Y_OFFSET, MENUALIGN_CENTER, +#endif + }, + +#undef Y_OFFSET + + // MENUPAGE_LANGUAGE_SETTINGS = 5 + { "FEH_LAN", MENUPAGE_OPTIONS, 3, + MENUACTION_LANG_ENG, "FEL_ENG", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 320, 132, MENUALIGN_CENTER, + MENUACTION_LANG_FRE, "FEL_FRE", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER, + }, + + // TODO(Miami): This is still my implementation + // MENUPAGE_MAP = 6 + { "FEH_MAP", MENUPAGE_NONE, 2, + MENUACTION_UNK110, "", SAVESLOT_NONE, 0, 0, 0, 0, // to prevent cross/enter to go back + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + }, + + // MENUPAGE_NEW_GAME_RELOAD = 7 + { "FES_NGA", MENUPAGE_NEW_GAME, 0, + MENUACTION_LABEL, "FESZ_QR", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 320, 200, MENUALIGN_CENTER, + MENUACTION_NEWGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_LOAD_SLOT = 8 + { "FET_LG", MENUPAGE_NEW_GAME, 1, + MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_1, 0, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_2, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", SAVESLOT_3, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", SAVESLOT_4, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", SAVESLOT_5, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", SAVESLOT_6, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", SAVESLOT_7, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", SAVESLOT_8, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_DELETE_SLOT = 9 + { "FES_DEL", MENUPAGE_NEW_GAME, 2, + MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_1, 0, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_2, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", SAVESLOT_3, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", SAVESLOT_4, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", SAVESLOT_5, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", SAVESLOT_6, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", SAVESLOT_7, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", SAVESLOT_8, 0, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOAD_SLOT_CONFIRM = 10 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, 0, + MENUACTION_LABEL, "FESZ_QL", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_DELETE_SLOT_CONFIRM = 11 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, 0, + MENUACTION_LABEL, "FESZ_QD", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", SAVESLOT_NONE, MENUPAGE_DELETING_IN_PROGRESS, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOADING_IN_PROGRESS = 12 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, 0, + }, + + // MENUPAGE_DELETING_IN_PROGRESS = 13 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, 0, + }, + + // MENUPAGE_DELETE_SUCCESSFUL = 14 + { "FES_DEL", MENUPAGE_NEW_GAME, 0, + MENUACTION_LABEL, "FES_DSC", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_SAVE_SLOT = 15 + { "FET_SG", MENUPAGE_DISABLED, 0, + MENUACTION_SAVEGAME, "FEM_SL1", SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 40, 90, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL2", SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL3", SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL4", SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL5", SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL6", SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL7", SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL8", SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", SAVESLOT_NONE, 0, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0, + MENUACTION_LABEL, "FESZ_QZ", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_NO, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVING_IN_PROGRESS = 17 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0, + }, + + // MENUPAGE_SAVE_SUCCESSFUL = 18 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0, + MENUACTION_LABEL, "FES_SSC", SAVESLOT_LABEL, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CUSTOM_WARNING = 19 + { "FET_SG", MENUPAGE_NONE, 0, + MENUACTION_LABEL, "", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CHEAT_WARNING = 20 + { "FET_SG", MENUPAGE_NEW_GAME, 0, + MENUACTION_LABEL, "FES_CHE", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SKIN_SELECT = 21 + { "FET_PS", MENUPAGE_OPTIONS, 4, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_OPTIONS, 0, 0, 0, + }, + + // MENUPAGE_SAVE_UNUSED = 22 + { "FET_SG", MENUPAGE_NEW_GAME, 0, + MENUACTION_LABEL, "FED_LWR", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED = 23 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0, + MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED_2 = 24 + { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, 0, + MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, 0, 0, 0, 0, + }, + + // MENUPAGE_LOAD_FAILED = 25 + { "FET_LG", MENUPAGE_NEW_GAME, 0, + MENUACTION_LABEL, "FEC_LUN", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC = 26 + { "FET_CTL", MENUPAGE_OPTIONS, 0, + MENUACTION_CTRLMETHOD, "FET_STI", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 150, MENUALIGN_CENTER, + 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, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_OPTIONS = 27 + { "FET_OPT", MENUPAGE_NONE, 5, + MENUACTION_CHANGEMENU, "FEO_CON", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 132, MENUALIGN_CENTER, + MENUACTION_LOADRADIO, "FEO_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEO_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEO_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS, 0, 0, MENUALIGN_CENTER, + MENUACTION_PLAYERSETUP, "FET_PS", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_EXIT = 28 + { "FET_QG", MENUPAGE_NONE, 6, + MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, 0, 0, 0, 0, + MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, 320, 200, MENUALIGN_CENTER, + MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_START_MENU = 29 + { "FEM_MM", MENUPAGE_DISABLED, 0, + MENUACTION_CHANGEMENU, "FEP_STG", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 320, 170, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, 0, 0, MENUALIGN_CENTER, + 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 + { "FEC_MOU", MENUPAGE_CONTROLLER_PC, 2, + MENUACTION_MOUSESENS, "FEC_MSH", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 40, 170, MENUALIGN_LEFT, + MENUACTION_INVVERT, "FEC_IVV", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_LEFT, + MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 320, 260, MENUALIGN_CENTER, + }, + + // MENUPAGE_PAUSE_MENU = 32 + { "FET_PAU", MENUPAGE_DISABLED, 0, + MENUACTION_RESUME, "FEP_RES", SAVESLOT_NONE, 0, 320, 120, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_SGA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_MAP", SAVESLOT_NONE, MENUPAGE_MAP, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_NONE = 33 + { "", 0, 0, }, + + // MENUPAGE_OUTRO = 34 + { "", 0, 0, }, + +#ifdef LEGACY_MENU_OPTIONS + // MENUPAGE_CONTROLLER_SETTINGS = 4 + { "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 + { "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, + MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_COLLISIONPOLYS, "FED_SCP", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_PARSEHEAP, "FED_PAH", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_DEBUGSTREAM, "FED_DSR", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD1 = 36 + { "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, + MENUACTION_GETKEY, "FEC_CWR", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, + MENUACTION_GETKEY, "FEC_LKT", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PJP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PSP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TLF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TRG", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CCM", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD2 = 37 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, 1, + + }, + + // MENUPAGE_CONTROLLER_PC_OLD3 = 38 + { "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, + MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, + MENUACTION_SHOWHEADBOB, "FEC_GSL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD4 = 39 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, 3, + + }, + + // MENUPAGE_CONTROLLER_DEBUG = 40 + { "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, + MENUACTION_GETKEY, "FEC_TSS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, + MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, + }, +#endif +}; diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 924d4724..a475bf7b 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -35,6 +35,7 @@ #include "Streaming.h" #include "PathFind.h" #include "Wanted.h" +#include "WaterLevel.h" #include "General.h" CPad Pads[MAX_PADS]; @@ -49,7 +50,7 @@ CKeyboardState CPad::OldKeyState; CKeyboardState CPad::NewKeyState; CKeyboardState CPad::TempKeyState; -char CPad::KeyBoardCheatString[20]; +char CPad::KeyBoardCheatString[30]; CMouseControllerState CPad::OldMouseControllerState; CMouseControllerState CPad::NewMouseControllerState; @@ -62,26 +63,116 @@ bool CPad::IsAffectedByController = false; _TODO("gbFastTime"); extern bool gbFastTime; -void WeaponCheat() +void WeaponCheat1() { CHud::SetHelpMessage(TheText.Get("CHEAT2"), true); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0); + + CStreaming::RequestModel(MI_BRASS_KNUCKLES, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_BASEBALL_BAT, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_MOLOTOV, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_COLT45, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SHOTGUN, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_TEC9, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_RUGER, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SNIPERRIFLE, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_FLAMETHROWER, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); + + FindPlayerPed()->GiveWeapon(WEAPONTYPE_BRASSKNUCKLE, 1); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 1); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 10); FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5); - FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 50); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_TEC9, 150); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_RUGER, 120); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 25); FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200); + + CStreaming::SetModelIsDeletable(MI_BRASS_KNUCKLES); + CStreaming::SetModelIsDeletable(MI_BASEBALL_BAT); + CStreaming::SetModelIsDeletable(MI_MOLOTOV); + CStreaming::SetModelIsDeletable(MI_COLT45); + CStreaming::SetModelIsDeletable(MI_SHOTGUN); + CStreaming::SetModelIsDeletable(MI_TEC9); + CStreaming::SetModelIsDeletable(MI_RUGER); + CStreaming::SetModelIsDeletable(MI_SNIPERRIFLE); + CStreaming::SetModelIsDeletable(MI_FLAMETHROWER); +} + +void WeaponCheat2() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT2"), true); + + CStreaming::RequestModel(MI_KATANA, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_GRENADE, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_BOMB, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_PYTHON, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_STUBBY_SHOTGUN, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SILENCEDINGRAM, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_M4, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_LASERSCOPE, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_ROCKETLAUNCHER, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); + + FindPlayerPed()->GiveWeapon(WEAPONTYPE_KATANA, 0); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR_GRENADE, 10); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_PYTHON, 40); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_STUBBY_SHOTGUN, 25); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_SILENCED_INGRAM, 100); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_M4, 150); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_LASERSCOPE, 21); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5); + + CStreaming::SetModelIsDeletable(MI_KATANA); + CStreaming::SetModelIsDeletable(MI_GRENADE); + CStreaming::SetModelIsDeletable(MI_BOMB); + CStreaming::SetModelIsDeletable(MI_PYTHON); + CStreaming::SetModelIsDeletable(MI_STUBBY_SHOTGUN); + CStreaming::SetModelIsDeletable(MI_SILENCEDINGRAM); + CStreaming::SetModelIsDeletable(MI_M4); + CStreaming::SetModelIsDeletable(MI_LASERSCOPE); + CStreaming::SetModelIsDeletable(MI_ROCKETLAUNCHER); +} + +void WeaponCheat3() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT2"), true); + + CStreaming::RequestModel(MI_CHAINSAW, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_GRENADE, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_PYTHON, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_SPAS12_SHOTGUN, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_MP5, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_M4, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_LASERSCOPE, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_MINIGUN, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_MINIGUN2, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); + + FindPlayerPed()->GiveWeapon(WEAPONTYPE_CHAINSAW, 0); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 10); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_PYTHON, 40); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_SPAS12_SHOTGUN, 30); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_MP5, 100); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_M4, 150); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_LASERSCOPE, 21); + FindPlayerPed()->GiveWeapon(WEAPONTYPE_MINIGUN, 500); + + CStreaming::SetModelIsDeletable(MI_CHAINSAW); + CStreaming::SetModelIsDeletable(MI_GRENADE); + CStreaming::SetModelIsDeletable(MI_PYTHON); + CStreaming::SetModelIsDeletable(MI_SPAS12_SHOTGUN); + CStreaming::SetModelIsDeletable(MI_MP5); + CStreaming::SetModelIsDeletable(MI_M4); + CStreaming::SetModelIsDeletable(MI_LASERSCOPE); + CStreaming::SetModelIsDeletable(MI_MINIGUN); + CStreaming::SetModelIsDeletable(MI_MINIGUN2); } void HealthCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT3"), true); - FindPlayerPed()->m_fHealth = 100.0f; + FindPlayerPed()->m_fHealth = CWorld::Players[0].m_nMaxHealth; if (FindPlayerVehicle()) { FindPlayerVehicle()->m_fHealth = 1000.0f; if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR) @@ -89,31 +180,31 @@ void HealthCheat() } } -void TankCheat() +void VehicleCheat(bool something, int model) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); - CStreaming::RequestModel(MI_RHINO, 0); - CStreaming::LoadAllRequestedModels(false); - if (CStreaming::ms_aInfoForModel[MI_RHINO].m_loadState == STREAMSTATE_LOADED) { + CStreaming::RequestModel(model, 0); + CStreaming::LoadAllRequestedModels(something); + if (CStreaming::ms_aInfoForModel[model].m_loadState == STREAMSTATE_LOADED) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f); if (node < 0) return; - + #ifdef FIX_BUGS - CAutomobile* tank = new CAutomobile(MI_RHINO, RANDOM_VEHICLE); + CAutomobile* vehicle = new CAutomobile(model, RANDOM_VEHICLE); #else - CAutomobile *tank = new CAutomobile(MI_RHINO, MISSION_VEHICLE); + CAutomobile* vehicle = new CAutomobile(MI_RHINO, MISSION_VEHICLE); #endif - if (tank != nil) { + if (vehicle != nil) { CVector pos = ThePaths.m_pathNodes[node].GetPosition(); pos.z += 4.0f; - tank->SetPosition(pos); - tank->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f)); + vehicle->SetPosition(pos); + vehicle->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f)); - tank->SetStatus(STATUS_ABANDONED); - tank->m_nDoorLock = CARLOCK_UNLOCKED; - CWorld::Add(tank); + vehicle->SetStatus(STATUS_ABANDONED); + vehicle->m_nDoorLock = CARLOCK_UNLOCKED; + CWorld::Add(vehicle); } } } @@ -140,9 +231,9 @@ void ChangePlayerCheat() do { do - modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1); + modelId = CGeneral::GetRandomNumberInRange(0, MI_WFYG2+1); while (!CModelInfo::GetModelInfo(modelId)); - } while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D); + } while (modelId == MI_TAXI_D); uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags; ped->DeleteRwObject(); @@ -205,7 +296,7 @@ void MoneyCheat() void ArmourCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT4"), true); - FindPlayerPed()->m_fArmour = 100.0f; + FindPlayerPed()->m_fArmour = CWorld::Players[0].m_nMaxArmour; } void WantedLevelUpCheat() @@ -232,6 +323,12 @@ void CloudyWeatherCheat() CWeather::ForceWeatherNow(WEATHER_CLOUDY); } +void StormyWeatherCheat() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT7"), true); + CWeather::ForceWeatherNow(WEATHER_HURRICANE); +} + void RainyWeatherCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT7"), true); @@ -273,6 +370,41 @@ void NastyLimbsCheat() { CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat; } + +void BlackCarsCheat() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + gbBlackCars = true; + gbPinkCars = false; +} + +void PinkCarsCheat() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + gbBlackCars = false; + gbPinkCars = true; +} + +void NoSeaBedCheat(void) +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + CWaterLevel::m_bRenderSeaBed = !CWaterLevel::m_bRenderSeaBed; +} + +void RenderWaterLayersCheat(void) +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + if ( ++CWaterLevel::m_nRenderWaterLayers > 5 ) + CWaterLevel::m_nRenderWaterLayers = 0; +} + +void BackToTheFuture(void) +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + CVehicle::bHoverCheat = !CVehicle::bHoverCheat; +} + + ////////////////////////////////////////////////////////////////////////// #ifdef KANGAROO_CHEAT @@ -329,15 +461,13 @@ void AltDodoCheat(void) } #endif -#ifdef DETECT_PAD_INPUT_SWITCH bool -CControllerState::IsAnyButtonPressed(void) +CControllerState::CheckForInput(void) { return !!LeftStickX || !!LeftStickY || !!RightStickX || !!RightStickY || !!LeftShoulder1 || !!LeftShoulder2 || !!RightShoulder1 || !!RightShoulder2 || - !!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight || !!Start || !!Select || !!Square || !!Triangle || !!Cross || !!Circle || !!LeftShock || - !!RightShock || !!NetworkTalk; + !!DPadUp || !!DPadDown || !!DPadLeft || !!DPadRight || !!Start || !!Select || !!Square || !!Triangle || !!Cross || !!Circle || !!LeftShock || + !!RightShock; } -#endif void CControllerState::Clear(void) @@ -435,6 +565,11 @@ void CPad::Clear(bool bResetPlayerControls) AverageEntries = 0; } +uint32 CPad::InputHowLongAgo() +{ + return CTimer::GetTimeInMilliseconds() - LastTimeTouched; +} + void CPad::ClearMouseHistory() { PCTempMouseControllerState.Clear(); @@ -668,7 +803,7 @@ CControllerState CPad::ReconcileTwoControllersInput(CControllerState const &Stat void CPad::StartShake(int16 nDur, uint8 nFreq) { - if ( !CMenuManager::m_PrefsUseVibration ) + if ( !FrontEndMenuManager.m_PrefsUseVibration ) return; if ( CCutsceneMgr::IsRunning() || CGame::playingIntro ) @@ -690,7 +825,7 @@ void CPad::StartShake(int16 nDur, uint8 nFreq) void CPad::StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fZ) { - if ( !CMenuManager::m_PrefsUseVibration ) + if ( !FrontEndMenuManager.m_PrefsUseVibration ) return; if ( CCutsceneMgr::IsRunning() || CGame::playingIntro ) @@ -717,7 +852,7 @@ void CPad::StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, floa void CPad::StartShake_Train(float fX, float fY) { - if ( !CMenuManager::m_PrefsUseVibration ) + if ( !FrontEndMenuManager.m_PrefsUseVibration ) return; if ( CCutsceneMgr::IsRunning() || CGame::playingIntro ) @@ -751,7 +886,7 @@ void CPad::AddToCheatString(char c) #define _CHEATCMP(str) strncmp(str, CheatString, sizeof(str)-1) // "4414LDRULDRU" - R2 R2 L1 R2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP if ( !_CHEATCMP("URDLURDL4144") ) - WeaponCheat(); + WeaponCheat1(); // "4411LDRULDRU" - R2 R2 L1 L1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP else if ( !_CHEATCMP("URDLURDL1144") ) @@ -791,7 +926,7 @@ void CPad::AddToCheatString(char c) // "CCCCCC321TCT" - CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE else if ( !_CHEATCMP("TCT123CCCCCC") ) - TankCheat(); + VehicleCheat(true, MI_RHINO); // "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE else if ( !_CHEATCMP("TCT1SSSSSCCC") ) @@ -844,113 +979,192 @@ void CPad::AddToCheatString(char c) } #endif +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 (int32 i = 0; i < strlen(origCheatStr); i++) { + if ((sourceStr[i] != origCheatStr[i] - cheatCodeVals[i]) || i >= ARRAY_SIZE(cheatCodeVals)) { + return 1; + } + } + return 0; +} + void CPad::AddToPCCheatString(char c) { - for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- ) + for (int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i--) KeyBoardCheatString[i + 1] = KeyBoardCheatString[i]; - + KeyBoardCheatString[0] = c; - - #define _CHEATCMP(str) strncmp(str, KeyBoardCheatString, sizeof(str)-1) - - // "GUNSGUNSGUNS" - if ( !_CHEATCMP("SNUGSNUGSNUG") ) - WeaponCheat(); - // "IFIWEREARICHMAN" - if ( !_CHEATCMP("NAMHCIRAEREWIFI") ) - MoneyCheat(); - - // "GESUNDHEIT" - if ( !_CHEATCMP("TIEHDNUSEG") ) +#define _CHEATCMP(str) strncmp(str, KeyBoardCheatString, sizeof(str)-1) + + // "THUGSTOOLS" + if (!Cheat_strncmp(KeyBoardCheatString, "VQVPanJ\\I_")) { + KeyBoardCheatString[0] = ' '; + WeaponCheat1(); + } + // "PROFESSIONALTOOLS" + else if (!Cheat_strncmp(KeyBoardCheatString, "VQVPagDUPT`[Lf\\Xl")) { + KeyBoardCheatString[0] = ' '; + WeaponCheat2(); + } + // "NUTTERTOOLS" + else if (!Cheat_strncmp(KeyBoardCheatString, "VQVPamH[U`[")) { + KeyBoardCheatString[0] = ' '; + WeaponCheat3(); + } + // "PRECIOUSPROTECTION" + else if (!Cheat_strncmp(KeyBoardCheatString, "QTPUP`WVS[`]ViPKnc")) { + KeyBoardCheatString[0] = ' '; + ArmourCheat(); + } + // "ASPIRINE" + else if (!Cheat_strncmp(KeyBoardCheatString, "HSPSVkVH")) { + KeyBoardCheatString[0] = ' '; HealthCheat(); - - // "MOREPOLICEPLEASE" - if ( !_CHEATCMP("ESAELPECILOPEROM") ) + } + // "YOUWONTTAKEMEALIVE" + else if (!Cheat_strncmp(KeyBoardCheatString, "H[PMN`PLLLa\\Uod[kl")) { + KeyBoardCheatString[0] = ' '; WantedLevelUpCheat(); - - // "NOPOLICEPLEASE" - if ( !_CHEATCMP("ESAELPECILOPON") ) + } + // "LEAVEMEALONE" + else if (!Cheat_strncmp(KeyBoardCheatString, "HSVMN`PLWLRT")) { + KeyBoardCheatString[0] = ' '; WantedLevelDownCheat(); - - // "GIVEUSATANK" - if ( !_CHEATCMP("KNATASUEVIG") ) - TankCheat(); - - // "BANGBANGBANG" - if ( !_CHEATCMP("GNABGNABGNAB") ) + } + // "APLEASANTDAY" + else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKU[\\VHFW]I")) { + KeyBoardCheatString[0] = ' '; + CloudyWeatherCheat(); + } + // "ALOVELYDAY" + else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKZY`YVML")) { + KeyBoardCheatString[0] = ' '; + SunnyWeatherCheat(); + } + // "ABITDRIEG" + + // "CATSANDDOGS" + else if (!Cheat_strncmp(KeyBoardCheatString, "VLVEQiDZULP")) { + KeyBoardCheatString[0] = ' '; + StormyWeatherCheat(); + } + // "CANTSEEATHING" + else if (!Cheat_strncmp(KeyBoardCheatString, "JSPIa\\HLT_[IJ")) { + KeyBoardCheatString[0] = ' '; + FoggyWeatherCheat(); + } + // "PANZER" + else if (!Cheat_strncmp(KeyBoardCheatString, "UJaONk")) { + KeyBoardCheatString[0] = ' '; + VehicleCheat(true, MI_RHINO); + } + // "LIFEISPASSINGMEBY" + + // "BIGBANG" + else if (!Cheat_strncmp(KeyBoardCheatString, "JSHCTdE")) { + KeyBoardCheatString[0] = ' '; BlowUpCarsCheat(); - - // "ILIKEDRESSINGUP" - if ( !_CHEATCMP("PUGNISSERDEKILI") ) + } + // "STILLLIKEDRESSINGUP" + else if (!Cheat_strncmp(KeyBoardCheatString, "SZNOVnVLSORSPlYReg]")) { + KeyBoardCheatString[0] = ' '; ChangePlayerCheat(); - - // "ITSALLGOINGMAAAD" - if ( !_CHEATCMP("DAAAMGNIOGLLASTI") ) + } + // "FIGHTFIGHTFIGHT" + else if (!Cheat_strncmp(KeyBoardCheatString, "WMNJSoKNJQaPNiS")) { + KeyBoardCheatString[0] = ' '; MayhemCheat(); - + } // "NOBODYLIKESME" - if ( !_CHEATCMP("EMSEKILYDOBON") ) + else if (!Cheat_strncmp(KeyBoardCheatString, "HRZFXdO`EZOWU")) { + KeyBoardCheatString[0] = ' '; EverybodyAttacksPlayerCheat(); - - // "WEAPONSFORALL" - if ( !_CHEATCMP("LLAROFSNOPAEW") ) + } + // "OURGODGIVENRIGHTTOBEARARMS" + else if (!Cheat_strncmp(KeyBoardCheatString, "VRYB_\\HIP_aPNi_TaiSJGTNSbj")) { + KeyBoardCheatString[0] = ' '; WeaponsForAllCheat(); - + } + // "TRAVELINSTYLE" + if (!_CHEATCMP("ELYTSNILEVART")) + VehicleCheat(true, MI_BLOODRA); + + // "GETTHEREQUICKLY" + if (!_CHEATCMP("YLKCIUQEREHTTEG")) + VehicleCheat(true, MI_BLOODRB); + + // "GETTHEREFAST" + if (!_CHEATCMP("TSAFEREHTTEG")) + VehicleCheat(true, MI_SABRETUR); + + // "GETTHEREVERYFASTINDEED" + if (!_CHEATCMP("DEEDNITSAFYREVEREHTTEG")) + VehicleCheat(true, MI_HOTRINA); + + // "GETTHEREAMAZINGLYFAST" + if (!_CHEATCMP("TSAFYLGNIZAMAEREHTTEG")) + VehicleCheat(true, MI_HOTRINB); + + // "THELASTRIDE" + if (!_CHEATCMP("EDIRTSALEHT")) + VehicleCheat(true, MI_ROMERO); + + // "ROCKANDROLLCAR" + if (!_CHEATCMP("RACLLORDNAKCOR")) + VehicleCheat(true, MI_LOVEFIST); + + // "RUBBISHCAR" + if (!_CHEATCMP("RACHSIBBUR")) + VehicleCheat(true, MI_TRASH); + + // "BETTERTHANWALKING" + if (!_CHEATCMP("GNIKLAWNAHTRETTEB")) + VehicleCheat(true, MI_CADDY); + // "TIMEFLIESWHENYOU" - if ( !_CHEATCMP("UOYNEHWSEILFEMIT") ) + if (!_CHEATCMP("UOYNEHWSEILFEMIT")) FastTimeCheat(); - + // "BOOOOORING" - if ( !_CHEATCMP("GNIROOOOOB") ) + if (!_CHEATCMP("GNIROOOOOB")) SlowTimeCheat(); - -#ifndef GTA3_1_1_PATCH - // "TURTOISE" - if ( !_CHEATCMP("ESIOTRUT") ) - ArmourCheat(); -#else - // "TORTOISE" - if ( !_CHEATCMP("ESIOTROT") ) - ArmourCheat(); -#endif - - // "SKINCANCERFORME" - if ( !_CHEATCMP("EMROFRECNACNIKS") ) - SunnyWeatherCheat(); - - // "ILIKESCOTLAND" - if ( !_CHEATCMP("DNALTOCSEKILI") ) - CloudyWeatherCheat(); - + // "ILOVESCOTLAND" - if ( !_CHEATCMP("DNALTOCSEVOLI") ) + if (!_CHEATCMP("DNALTOCSEVOLI")) RainyWeatherCheat(); - - // "PEASOUP" - if ( !_CHEATCMP("PUOSAEP") ) - FoggyWeatherCheat(); - + // "MADWEATHER" - if ( !_CHEATCMP("REHTAEWDAM") ) + if (!_CHEATCMP("REHTAEWDAM")) FastWeatherCheat(); - + // "ANICESETOFWHEELS" - if ( !_CHEATCMP("SLEEHWFOTESECINA") ) + if (!_CHEATCMP("SLEEHWFOTESECINA")) OnlyRenderWheelsCheat(); - + // "CHITTYCHITTYBB" - if ( !_CHEATCMP("BBYTTIHCYTTIHC") ) + if (!_CHEATCMP("BBYTTIHCYTTIHC")) ChittyChittyBangBangCheat(); - + // "CORNERSLIKEMAD" - if ( !_CHEATCMP("DAMEKILSRENROC") ) + if (!_CHEATCMP("DAMEKILSRENROC")) StrongGripCheat(); - + // "NASTYLIMBSCHEAT" - if ( !_CHEATCMP("TAEHCSBMILYTSAN") ) + if (!_CHEATCMP("TAEHCSBMILYTSAN")) NastyLimbsCheat(); + // "IWANTITPAINTEDBLACK" + if (!_CHEATCMP("KCALBDETNIAPTITNAWI")) + BlackCarsCheat(); + + // "AHAIRDRESSERSCAR" + if (!_CHEATCMP("RACSRESSERDRIAHA")) + PinkCarsCheat(); + #ifdef KANGAROO_CHEAT // "KANGAROO" if (!_CHEATCMP("OORAGNAK")) @@ -974,8 +1188,22 @@ void CPad::AddToPCCheatString(char c) if (!_CHEATCMP("ODODRETSAMOTTNAWI")) AltDodoCheat(); #endif - - #undef _CHEATCMP + +#if !defined(PC_WATER) && defined(WATER_CHEATS) + // SEABEDCHEAT + if (!_CHEATCMP("TAEHCDEBAESON")) + NoSeaBedCheat(); + + // WATERLAYERSCHEAT + if (!_CHEATCMP("TAEHCSREYALRETAW")) + RenderWaterLayersCheat(); +#endif + + // SEAWAYS + if (!_CHEATCMP("SYAWAES")) + BackToTheFuture(); + +#undef _CHEATCMP } #ifdef XINPUT @@ -1052,7 +1280,7 @@ void CPad::UpdatePads(void) CapturePad(0); #endif #ifdef DETECT_PAD_INPUT_SWITCH - if (GetPad(0)->PCTempJoyState.IsAnyButtonPressed()) + if (GetPad(0)->PCTempJoyState.CheckForInput()) IsAffectedByController = true; else { #endif @@ -1062,11 +1290,11 @@ void CPad::UpdatePads(void) #ifdef DETECT_PAD_INPUT_SWITCH } - if (IsAffectedByController && (GetPad(0)->PCTempKeyState.IsAnyButtonPressed() || GetPad(0)->PCTempMouseState.IsAnyButtonPressed())) + if (IsAffectedByController && (GetPad(0)->PCTempKeyState.CheckForInput() || GetPad(0)->PCTempMouseState.CheckForInput())) IsAffectedByController = false; #endif - if ( CReplay::IsPlayingBackFromFile() ) + if ( CReplay::IsPlayingBackFromFile() && !FrontEndMenuManager.m_bMenuActive ) bUpdate = false; if ( bUpdate ) @@ -1106,6 +1334,9 @@ void CPad::Update(int16 unk) PCTempMouseState.Clear(); ProcessPCSpecificStuff(); + + if (NewState.CheckForInput()) + LastTimeTouched = CTimer::GetTimeInMilliseconds(); if ( ++iCurrHornHistory >= HORNHISTORY_SIZE ) iCurrHornHistory = 0; @@ -2336,6 +2567,8 @@ void CPad::ResetCheats(void) CVehicle::bCheat3 = false; CVehicle::bCheat4 = false; CVehicle::bCheat5 = false; + gbBlackCars = false; + gbPinkCars = false; gbFastTime = false; CTimer::SetTimeScale(1.0f); diff --git a/src/core/Pad.h b/src/core/Pad.h index ea771f81..a1461575 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -10,6 +10,7 @@ enum { PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe PLAYERCONTROL_DISABLED_40 = 64, // used on phone calls PLAYERCONTROL_DISABLED_80 = 128,// used on cutscenes + PLAYERCONTROL_SHORTCUT_TAXI = 256, }; class CControllerState @@ -29,9 +30,7 @@ public: float GetRightStickX(void) { return RightStickX/32767.0f; }; float GetRightStickY(void) { return RightStickY/32767.0f; }; -#ifdef DETECT_PAD_INPUT_SWITCH - bool IsAnyButtonPressed(); -#endif + bool CheckForInput(); void Clear(void); }; VALIDATE_SIZE(CControllerState, 0x2A); @@ -152,10 +151,10 @@ public: int16 Phase; int16 Mode; int16 ShakeDur; + uint16 DisablePlayerControls; uint8 ShakeFreq; bool bHornHistory[HORNHISTORY_SIZE]; uint8 iCurrHornHistory; - uint8 DisablePlayerControls; int8 bApplyBrakes; char CheatString[12]; int32 LastTimeTouched; @@ -176,7 +175,7 @@ public: static CKeyboardState OldKeyState; static CKeyboardState NewKeyState; static CKeyboardState TempKeyState; - static char KeyBoardCheatString[20]; + static char KeyBoardCheatString[30]; static CMouseControllerState OldMouseControllerState; static CMouseControllerState NewMouseControllerState; static CMouseControllerState PCTempMouseControllerState; @@ -260,6 +259,7 @@ public: static void ResetCheats(void); static char *EditString(char *pStr, int32 nSize); static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize); + uint32 InputHowLongAgo(void); #ifdef XINPUT void AffectFromXinput(uint32 pad); @@ -450,9 +450,9 @@ public: int16 GetRightStickY(void) { return NewState.RightStickY; } bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; } - void SetDisablePlayerControls(uint8 who) { DisablePlayerControls |= who; } - void SetEnablePlayerControls(uint8 who) { DisablePlayerControls &= ~who; } - bool IsPlayerControlsDisabledBy(uint8 who) { return DisablePlayerControls & who; } + void SetDisablePlayerControls(uint16 who) { DisablePlayerControls |= who; } + void SetEnablePlayerControls(uint16 who) { DisablePlayerControls &= ~who; } + bool IsPlayerControlsDisabledBy(uint16 who) { return DisablePlayerControls & who; } }; VALIDATE_SIZE(CPad, 0xFC); diff --git a/src/core/Placeable.cpp b/src/core/Placeable.cpp index 69b3d3ea..6efc1540 100644 --- a/src/core/Placeable.cpp +++ b/src/core/Placeable.cpp @@ -7,8 +7,6 @@ CPlaceable::CPlaceable(void) m_matrix.SetScale(1.0f); } -CPlaceable::~CPlaceable(void) = default; - void CPlaceable::SetHeading(float angle) { diff --git a/src/core/Placeable.h b/src/core/Placeable.h index 970c0d48..22f7583c 100644 --- a/src/core/Placeable.h +++ b/src/core/Placeable.h @@ -9,7 +9,6 @@ public: CMatrix m_matrix; CPlaceable(void); - virtual ~CPlaceable(void); const CVector &GetPosition(void) { return m_matrix.GetPosition(); } void SetPosition(float x, float y, float z) { m_matrix.GetPosition().x = x; diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index c3cc0960..0be5f73e 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -140,20 +140,25 @@ CPlayerInfo::Clear(void) m_nUpsideDownCounter = 0; m_bInfiniteSprint = false; m_bFastReload = false; + m_nMaxHealth = m_nMaxArmour = 100; m_bGetOutOfJailFree = false; m_bGetOutOfHospitalFree = false; + m_bDriveByAllowed = true; m_nPreviousTimeRewardedForExplosion = 0; m_nExplosionsSinceLastReward = 0; + m_nCurrentBustedAudio = 1; + m_nBustedAudioStatus = BUSTEDAUDIO_NONE; } void -CPlayerInfo::BlowUpRCBuggy(void) +CPlayerInfo::BlowUpRCBuggy(bool actually) { if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) return; CRemote::TakeRemoteControlledCarFromPlayer(); - m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); + if (actually) + m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); } void @@ -171,7 +176,6 @@ void CPlayerInfo::MakePlayerSafe(bool toggle) { if (toggle) { - CTheScripts::ResetCountdownToMakePlayerUnsafe(); m_pPed->m_pWanted->m_bIgnoredByEveryone = true; CWorld::StopAllLawEnforcersInTheirTracks(); CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20; @@ -192,7 +196,8 @@ CPlayerInfo::MakePlayerSafe(bool toggle) CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); CReplay::DisableReplays(); - } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) { + } + else { m_pPed->m_pWanted->m_bIgnoredByEveryone = false; CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20; m_pPed->bBulletProof = false; @@ -348,7 +353,7 @@ CPlayerInfo::Process(void) bool startTaxiTimer = true; if (m_bUnusedTaxiThing && m_pPed->bInVehicle) { CVehicle *veh = m_pPed->m_pMyVehicle; - if ((veh->GetModelIndex() == MI_TAXI || veh->GetModelIndex() == MI_CABBIE || veh->GetModelIndex() == MI_BORGNINE) + if (veh->IsTaxi() && veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) { for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) { timePassed -= 1000; diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 94410753..11f51ac0 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -10,6 +10,13 @@ enum eWastedBustedState WBSTATE_FAILED_CRITICAL_MISSION, }; +enum eBustedAudioState : uint8 +{ + BUSTEDAUDIO_NONE, + BUSTEDAUDIO_LOADING, + BUSTEDAUDIO_DONE +}; + class CEntity; class CPed; class CVehicle; @@ -42,6 +49,7 @@ public: uint32 m_nTimeLastHealthLoss; uint32 m_nTimeLastArmourLoss; uint32 m_nTimeTankShotGun; + int32 m_nTimeNotFullyOnGround; int32 m_nUpsideDownCounter; int32 field_248; int16 m_nTrafficMultiplier; @@ -50,10 +58,18 @@ public: int32 m_nExplosionsSinceLastReward; int32 field_268; int32 field_272; + uint32 m_nHavocLevel; + float m_fMediaAttention; bool m_bInfiniteSprint; bool m_bFastReload; + bool m_bFireproof; + uint8 m_nMaxHealth; + uint8 m_nMaxArmour; bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; + bool m_bDriveByAllowed; + eBustedAudioState m_nBustedAudioStatus; + int16 m_nCurrentBustedAudio; char m_aSkinName[32]; RwTexture *m_pSkinTexture; @@ -69,7 +85,7 @@ public: bool IsPlayerInRemoteMode(void); void PlayerFailedCriticalMission(void); void Clear(void); - void BlowUpRCBuggy(void); + void BlowUpRCBuggy(bool); void CancelPlayerEnteringCars(CVehicle*); bool IsRestartingAfterDeath(void); bool IsRestartingAfterArrest(void); @@ -80,5 +96,3 @@ public: ~CPlayerInfo() { }; }; - -VALIDATE_SIZE(CPlayerInfo, 0x13C); diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index bd0814d0..6e3799f4 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -542,8 +542,20 @@ INITSAVEBUF pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy; pPed->m_currentWeapon = 0; pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed; - for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++) - pPed->m_weapons[i] = pBufferPlayer->m_weapons[i]; + for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { + if (pBufferPlayer->HasWeaponSlot(i)) { + int modelId = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModelId; + if (modelId != -1) { + CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY); + int modelId2 = CWeaponInfo::GetWeaponInfo(pBufferPlayer->GetWeapon(i).m_eWeaponType)->m_nModel2Id; + if (modelId2 != -1) + CStreaming::RequestModel(modelId2, STREAMFLAGS_DEPENDENCY); + + CStreaming::LoadAllRequestedModels(false); + } + pPed->GiveWeapon(pBufferPlayer->GetWeapon(i).m_eWeaponType, pBufferPlayer->GetWeapon(i).m_nAmmoTotal); + } + } if (pedtype == PEDTYPE_PLAYER1) { pPed->m_wepAccuracy = 100; diff --git a/src/core/Pools.h b/src/core/Pools.h index b0ba6598..2f0537ff 100644 --- a/src/core/Pools.h +++ b/src/core/Pools.h @@ -4,7 +4,7 @@ #include "Lists.h" #include "Treadable.h" #include "Object.h" -#include "CutsceneHead.h" +#include "CutsceneObject.h" #include "PlayerPed.h" #include "Automobile.h" #include "DummyPed.h" @@ -16,7 +16,7 @@ typedef CPool<CPed,CPlayerPed> CPedPool; typedef CPool<CVehicle,CAutomobile> CVehiclePool; typedef CPool<CBuilding> CBuildingPool; typedef CPool<CTreadable> CTreadablePool; -typedef CPool<CObject, CCutsceneHead> CObjectPool; +typedef CPool<CObject, CCutsceneObject> CObjectPool; typedef CPool<CDummy, CDummyPed> CDummyPool; typedef CPool<cAudioScriptObject> CAudioScriptObjectPool; diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 9406f1bd..475ca4d3 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -21,49 +21,87 @@ sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS]; CVector2D vec2DRadarOrigin; int32 gRadarTxdIds[64]; -CSprite2d CRadar::AsukaSprite; -CSprite2d CRadar::BombSprite; -CSprite2d CRadar::CatSprite; CSprite2d CRadar::CentreSprite; -CSprite2d CRadar::CopcarSprite; -CSprite2d CRadar::DonSprite; -CSprite2d CRadar::EightSprite; -CSprite2d CRadar::ElSprite; -CSprite2d CRadar::IceSprite; -CSprite2d CRadar::JoeySprite; -CSprite2d CRadar::KenjiSprite; -CSprite2d CRadar::LizSprite; -CSprite2d CRadar::LuigiSprite; +CSprite2d CRadar::MapHereSprite; CSprite2d CRadar::NorthSprite; -CSprite2d CRadar::RaySprite; -CSprite2d CRadar::SalSprite; -CSprite2d CRadar::SaveSprite; +CSprite2d CRadar::AverySprite; +CSprite2d CRadar::BikerSprite; +CSprite2d CRadar::CortezSprite; +CSprite2d CRadar::DiazSprite; +CSprite2d CRadar::KentSprite; +CSprite2d CRadar::LawyerSprite; +CSprite2d CRadar::PhilSprite; +CSprite2d CRadar::BikersSprite; +CSprite2d CRadar::BoatyardSprite; +CSprite2d CRadar::MalibuClubSprite; +CSprite2d CRadar::CubansSprite; +CSprite2d CRadar::FilmSprite; +CSprite2d CRadar::GunSprite; +CSprite2d CRadar::HaitiansSprite; +CSprite2d CRadar::HardwareSprite; +CSprite2d CRadar::SaveHouseSprite; +CSprite2d CRadar::StripSprite; +CSprite2d CRadar::IceSprite; +CSprite2d CRadar::KCabsSprite; +CSprite2d CRadar::LovefistSprite; +CSprite2d CRadar::PrintworksSprite; +CSprite2d CRadar::PropertySprite; +CSprite2d CRadar::SunYardSprite; CSprite2d CRadar::SpraySprite; -CSprite2d CRadar::TonySprite; -CSprite2d CRadar::WeaponSprite; +CSprite2d CRadar::TShirtSprite; +CSprite2d CRadar::TommySprite; +CSprite2d CRadar::PhoneSprite; +CSprite2d CRadar::RadioWildstyleSprite; +CSprite2d CRadar::RadioFlashSprite; +CSprite2d CRadar::RadioKChatSprite; +CSprite2d CRadar::RadioFeverSprite; +CSprite2d CRadar::RadioVRockSprite; +CSprite2d CRadar::RadioVCPRSprite; +CSprite2d CRadar::RadioEspantosoSprite; +CSprite2d CRadar::RadioEmotionSprite; +CSprite2d CRadar::RadioWaveSprite; CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = { nil, - &AsukaSprite, - &BombSprite, - &CatSprite, &CentreSprite, - &CopcarSprite, - &DonSprite, - &EightSprite, - &ElSprite, - &IceSprite, - &JoeySprite, - &KenjiSprite, - &LizSprite, - &LuigiSprite, + &MapHereSprite, &NorthSprite, - &RaySprite, - &SalSprite, - &SaveSprite, + &AverySprite, + &BikerSprite, + &CortezSprite, + &DiazSprite, + &KentSprite, + &LawyerSprite, + &PhilSprite, + &BikersSprite, + &BoatyardSprite, + &MalibuClubSprite, + &CubansSprite, + &FilmSprite, + &GunSprite, + &HaitiansSprite, + &HardwareSprite, + &SaveHouseSprite, + &StripSprite, + &IceSprite, + &KCabsSprite, + &LovefistSprite, + &PrintworksSprite, + &PropertySprite, + &SunYardSprite, &SpraySprite, - &TonySprite, - &WeaponSprite + &TShirtSprite, + &TommySprite, + &PhoneSprite, + &RadioWildstyleSprite, + &RadioFlashSprite, + &RadioKChatSprite, + &RadioFeverSprite, + &RadioVRockSprite, + &RadioVCPRSprite, + &RadioEspantosoSprite, + &RadioEmotionSprite, + &RadioWaveSprite }; // Why this doesn't coincide with world coordinates i don't know @@ -87,12 +125,11 @@ static_assert(RADAR_TILE_SIZE == (RADAR_SIZE_Y / RADAR_NUM_TILES), "CRadar: not CRGBA CRadar::ArrowBlipColour1; CRGBA CRadar::ArrowBlipColour2; uint16 CRadar::MapLegendCounter; -uint16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; +int16 CRadar::MapLegendList[NUM_MAP_LEGENDS]; int CRadar::TargetMarkerId = -1; CVector CRadar::TargetMarkerPos; #endif -// taken from VC float CRadar::cachedCos; float CRadar::cachedSin; @@ -227,7 +264,7 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D & uint8 CRadar::CalculateBlipAlpha(float dist) { #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) + if (FrontEndMenuManager.m_bMenuMapActive) return 255; #endif if (dist <= 1.0f) @@ -273,12 +310,9 @@ void CRadar::ClearBlip(int32 i) if (index != -1) { SetRadarMarkerState(index, false); ms_RadarTrace[index].m_bInUse = false; -#ifndef MENU_MAP - // Ssshhh ms_RadarTrace[index].m_eBlipType = BLIP_NONE; ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER; ms_RadarTrace[index].m_eRadarSprite = RADAR_SPRITE_NONE; -#endif } } @@ -378,9 +412,8 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect) bool CRadar::DisplayThisBlip(int32 counter) { switch (ms_RadarTrace[counter].m_eRadarSprite) { - case RADAR_SPRITE_BOMB: case RADAR_SPRITE_SPRAY: - case RADAR_SPRITE_WEAPON: + case RADAR_SPRITE_GUN: return true; default: return false; @@ -398,7 +431,7 @@ void CRadar::Draw3dMarkers() if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { CVector pos = entity->GetPosition(); pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f; - C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, 0, 128, 255, 255, 1024, 0.2f, 5); + C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, CARBLIP_MARKER_COLOR_R, CARBLIP_MARKER_COLOR_G, CARBLIP_MARKER_COLOR_B, CARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5); } break; } @@ -412,7 +445,7 @@ void CRadar::Draw3dMarkers() if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { CVector pos = entity->GetPosition(); pos.z += 3.0f; - C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, 0, 128, 255, 255, 1024, 0.2f, 5); + C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, CHARBLIP_MARKER_COLOR_R, CHARBLIP_MARKER_COLOR_G, CHARBLIP_MARKER_COLOR_B, CHARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5); } break; } @@ -422,7 +455,7 @@ void CRadar::Draw3dMarkers() if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) { CVector pos = entity->GetPosition(); pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f; - C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, 0, 128, 255, 255, 1024, 0.2f, 5); + C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, OBJECTBLIP_MARKER_COLOR_R, OBJECTBLIP_MARKER_COLOR_G, OBJECTBLIP_MARKER_COLOR_B, OBJECTBLIP_MARKER_COLOR_A, 1024, 0.2f, 5); } break; } @@ -431,7 +464,7 @@ void CRadar::Draw3dMarkers() case BLIP_CONTACT_POINT: if (!CTheScripts::IsPlayerOnAMission()) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) - C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, 0, 128, 255, 128, 2048, 0.2f, 0); + C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, COORDBLIP_MARKER_COLOR_R, COORDBLIP_MARKER_COLOR_G, COORDBLIP_MARKER_COLOR_B, COORDBLIP_MARKER_COLOR_A, 2048, 0.2f, 0); } break; } @@ -454,7 +487,7 @@ void CRadar::DrawBlips() TransformRadarPointToScreenSpace(out, in); #ifdef MENU_MAP - if (!CMenuManager::bMenuMapActive) { + if (!FrontEndMenuManager.m_bMenuMapActive) { #endif float angle; if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN) @@ -481,11 +514,6 @@ void CRadar::DrawBlips() CEntity *blipEntity = nil; for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) { -#ifdef MENU_MAP - // A little hack to reuse cleared blips in menu map. hehe - if (!CMenuManager::bMenuMapActive || ms_RadarTrace[blipId].m_eBlipType == BLIP_CAR || - ms_RadarTrace[blipId].m_eBlipType == BLIP_CHAR || ms_RadarTrace[blipId].m_eBlipType == BLIP_OBJECT) -#endif if (!ms_RadarTrace[blipId].m_bInUse) continue; @@ -493,8 +521,8 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON) { + if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE + || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) { switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: @@ -527,21 +555,24 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } else { -#ifdef TRIANGULAR_BLIPS - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + else { +#ifdef TRIANGULAR_BLIPS + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = blipEntity->GetPosition(); + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } } @@ -549,8 +580,8 @@ void CRadar::DrawBlips() break; case BLIP_COORD: case BLIP_CONTACT_POINT: - if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE - || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON) + if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE + || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_GUN) && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); @@ -566,21 +597,24 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - } else { -#ifdef TRIANGULAR_BLIPS - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) { + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); + else { +#ifdef TRIANGULAR_BLIPS + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } } @@ -597,8 +631,8 @@ void CRadar::DrawBlips() case BLIP_CAR: case BLIP_CHAR: case BLIP_OBJECT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN) { switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_CAR: @@ -632,23 +666,25 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition()); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + else #ifdef TRIANGULAR_BLIPS - { - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = blipEntity->GetPosition(); - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = blipEntity->GetPosition(); + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } } @@ -664,8 +700,8 @@ void CRadar::DrawBlips() switch (ms_RadarTrace[blipId].m_eBlipType) { case BLIP_COORD: case BLIP_CONTACT_POINT: - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE - && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE + && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_GUN && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) { uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim); @@ -681,23 +717,25 @@ void CRadar::DrawBlips() TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos); float dist = LimitRadarPoint(in); TransformRadarPointToScreenSpace(out, in); - if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) - DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); - else + if (!ms_RadarTrace[blipId].m_bShortRange || dist <= 1.0f || FrontEndMenuManager.m_bMenuMapActive) { + if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) + DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist)); + else #ifdef TRIANGULAR_BLIPS - { - const CVector &pos = FindPlayerCentreOfWorld_NoSniperShift(); - const CVector &blipPos = ms_RadarTrace[blipId].m_vecPos; - uint8 mode = BLIP_MODE_TRIANGULAR_UP; - if (blipPos.z - pos.z <= 2.0f) { - if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; - else mode = BLIP_MODE_SQUARE; + { + const CVector& pos = FindPlayerCentreOfWorld_NoSniperShift(); + const CVector& blipPos = ms_RadarTrace[blipId].m_vecPos; + uint8 mode = BLIP_MODE_TRIANGULAR_UP; + if (blipPos.z - pos.z <= 2.0f) { + if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN; + else mode = BLIP_MODE_SQUARE; + } + ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); } - ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode); - } #else - ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); + ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255); #endif + } } } break; @@ -706,7 +744,7 @@ void CRadar::DrawBlips() } } #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) { + if (FrontEndMenuManager.m_bMenuMapActive) { CVector2D in, out; TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift()); TransformRadarPointToScreenSpace(out, in); @@ -861,7 +899,7 @@ void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha) { RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha)); #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) { + if (FrontEndMenuManager.m_bMenuMapActive) { bool alreadyThere = false; for (int i = 0; i < NUM_MAP_LEGENDS; i++) { if (MapLegendList[i] == sprite) @@ -992,6 +1030,7 @@ CRadar::Initialise() ms_RadarTrace[i].m_BlipIndex = 1; SetRadarMarkerState(i, false); ms_RadarTrace[i].m_bInUse = false; + ms_RadarTrace[i].m_bShortRange = false; ms_RadarTrace[i].m_eBlipType = BLIP_NONE; ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER; ms_RadarTrace[i].m_eRadarSprite = RADAR_SPRITE_NONE; @@ -1008,7 +1047,7 @@ float CRadar::LimitRadarPoint(CVector2D &point) dist = point.Magnitude(); #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) + if (FrontEndMenuManager.m_bMenuMapActive) return dist; #endif if (dist > 1.0f) { @@ -1036,26 +1075,45 @@ CRadar::LoadTextures() { CTxdStore::PushCurrentTxd(); CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("hud")); - AsukaSprite.SetTexture("radar_asuka"); - BombSprite.SetTexture("radar_bomb"); - CatSprite.SetTexture("radar_cat"); CentreSprite.SetTexture("radar_centre"); - CopcarSprite.SetTexture("radar_copcar"); - DonSprite.SetTexture("radar_don"); - EightSprite.SetTexture("radar_eight"); - ElSprite.SetTexture("radar_el"); - IceSprite.SetTexture("radar_ice"); - JoeySprite.SetTexture("radar_joey"); - KenjiSprite.SetTexture("radar_kenji"); - LizSprite.SetTexture("radar_liz"); - LuigiSprite.SetTexture("radar_luigi"); + MapHereSprite.SetTexture("arrow"); NorthSprite.SetTexture("radar_north"); - RaySprite.SetTexture("radar_ray"); - SalSprite.SetTexture("radar_sal"); - SaveSprite.SetTexture("radar_save"); - SpraySprite.SetTexture("radar_spray"); - TonySprite.SetTexture("radar_tony"); - WeaponSprite.SetTexture("radar_weapon"); + AverySprite.SetTexture("radar_avery"); + BikerSprite.SetTexture("radar_biker"); + CortezSprite.SetTexture("radar_cortez"); + DiazSprite.SetTexture("radar_diaz"); + KentSprite.SetTexture("radar_kent"); + LawyerSprite.SetTexture("radar_lawyer"); + PhilSprite.SetTexture("radar_phil"); + BikersSprite.SetTexture("bikers"); + BoatyardSprite.SetTexture("boatyard"); + MalibuClubSprite.SetTexture("club"); + CubansSprite.SetTexture("cubans"); + FilmSprite.SetTexture("filmstudio"); + GunSprite.SetTexture("gun"); + HaitiansSprite.SetTexture("haitians"); + HardwareSprite.SetTexture("hardware"); + SaveHouseSprite.SetTexture("radar_save"); + StripSprite.SetTexture("radar_strip"); + IceSprite.SetTexture("icecream"); + KCabsSprite.SetTexture("kcabs"); + LovefistSprite.SetTexture("lovefist"); + PrintworksSprite.SetTexture("printworks"); + PropertySprite.SetTexture("property"); + SunYardSprite.SetTexture("SunYard"); + SpraySprite.SetTexture("spray"); + TShirtSprite.SetTexture("tshirt"); + TommySprite.SetTexture("tommy"); + PhoneSprite.SetTexture("phone"); + RadioWildstyleSprite.SetTexture("RWildstyle"); + RadioFlashSprite.SetTexture("RFlash"); + RadioKChatSprite.SetTexture("RKchat"); + RadioFeverSprite.SetTexture("RFever"); + RadioVRockSprite.SetTexture("RVRock"); + RadioVCPRSprite.SetTexture("RVCPR"); + RadioEspantosoSprite.SetTexture("REspantoso"); + RadioEmotionSprite.SetTexture("REmotion"); + RadioWaveSprite.SetTexture("RWave"); CTxdStore::PopCurrentTxd(); } @@ -1102,8 +1160,9 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay } ms_RadarTrace[nextBlip].m_eBlipType = type; ms_RadarTrace[nextBlip].m_nColor = color; - ms_RadarTrace[nextBlip].m_bDim = 1; - ms_RadarTrace[nextBlip].m_bInUse = 1; + ms_RadarTrace[nextBlip].m_bDim = true; + ms_RadarTrace[nextBlip].m_bInUse = true; + ms_RadarTrace[nextBlip].m_bShortRange = false; ms_RadarTrace[nextBlip].m_Radius = 1.0f; ms_RadarTrace[nextBlip].m_vec2DPos = pos; ms_RadarTrace[nextBlip].m_vecPos = pos; @@ -1114,6 +1173,15 @@ int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay return CRadar::GetNewUniqueBlipIndex(nextBlip); } +int CRadar::SetShortRangeCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display) +{ + int index = SetCoordBlip(type, pos, color, display); + if (index == -1) + return -1; + ms_RadarTrace[GetActualBlipArrayIndex(index)].m_bShortRange = true; + return index; +} + int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display) { int nextBlip; @@ -1123,8 +1191,9 @@ int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDispla } ms_RadarTrace[nextBlip].m_eBlipType = type; ms_RadarTrace[nextBlip].m_nColor = color; - ms_RadarTrace[nextBlip].m_bDim = 1; - ms_RadarTrace[nextBlip].m_bInUse = 1; + ms_RadarTrace[nextBlip].m_bDim = true; + ms_RadarTrace[nextBlip].m_bInUse = true; + ms_RadarTrace[nextBlip].m_bShortRange = false; ms_RadarTrace[nextBlip].m_Radius = 1.0f; ms_RadarTrace[nextBlip].m_nEntityHandle = handle; ms_RadarTrace[nextBlip].m_wScale = 1; @@ -1209,7 +1278,7 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, } #ifdef MENU_MAP // VC uses -1 for coords and -2 for entities but meh, I don't want to edit DrawBlips - if (CMenuManager::bMenuMapActive) { + if (FrontEndMenuManager.m_bMenuMapActive) { bool alreadyThere = false; for (int i = 0; i < NUM_MAP_LEGENDS; i++) { if (MapLegendList[i] == -1) @@ -1226,26 +1295,45 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, void CRadar::Shutdown() { - AsukaSprite.Delete(); - BombSprite.Delete(); - CatSprite.Delete(); CentreSprite.Delete(); - CopcarSprite.Delete(); - DonSprite.Delete(); - EightSprite.Delete(); - ElSprite.Delete(); - IceSprite.Delete(); - JoeySprite.Delete(); - KenjiSprite.Delete(); - LizSprite.Delete(); - LuigiSprite.Delete(); + MapHereSprite.Delete(); NorthSprite.Delete(); - RaySprite.Delete(); - SalSprite.Delete(); - SaveSprite.Delete(); + AverySprite.Delete(); + BikerSprite.Delete(); + CortezSprite.Delete(); + DiazSprite.Delete(); + KentSprite.Delete(); + LawyerSprite.Delete(); + PhilSprite.Delete(); + BikersSprite.Delete(); + BoatyardSprite.Delete(); + MalibuClubSprite.Delete(); + CubansSprite.Delete(); + FilmSprite.Delete(); + GunSprite.Delete(); + HaitiansSprite.Delete(); + HardwareSprite.Delete(); + SaveHouseSprite.Delete(); + StripSprite.Delete(); + IceSprite.Delete(); + KCabsSprite.Delete(); + LovefistSprite.Delete(); + PrintworksSprite.Delete(); + PropertySprite.Delete(); + SunYardSprite.Delete(); SpraySprite.Delete(); - TonySprite.Delete(); - WeaponSprite.Delete(); + TShirtSprite.Delete(); + TommySprite.Delete(); + PhoneSprite.Delete(); + RadioWildstyleSprite.Delete(); + RadioFlashSprite.Delete(); + RadioKChatSprite.Delete(); + RadioFeverSprite.Delete(); + RadioVRockSprite.Delete(); + RadioVCPRSprite.Delete(); + RadioEspantosoSprite.Delete(); + RadioEmotionSprite.Delete(); + RadioWaveSprite.Delete(); RemoveRadarSections(); } @@ -1315,10 +1403,9 @@ void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in) { #ifdef MENU_MAP - if (CMenuManager::bMenuMapActive) { - // fMapSize is actually half map size. Radar range is 1000, so if x is -2000, in.x + 2.0f is 0. - out.x = (CMenuManager::fMapCenterX - CMenuManager::fMapSize) + (in.x + 2.0f) * CMenuManager::fMapSize * 2.0f / 4.0f; - out.y = (CMenuManager::fMapCenterY - CMenuManager::fMapSize) + (2.0f - in.y) * CMenuManager::fMapSize * 2.0f / 4.0f; + if (FrontEndMenuManager.m_bMenuMapActive) { + out.x = (FrontEndMenuManager.m_fMapCenterX - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 + MENU_MAP_LEFT_OFFSET + in.x) * FrontEndMenuManager.m_fMapSize * MENU_MAP_WIDTH_SCALE * 2.0f / MENU_MAP_LENGTH; + out.y = (FrontEndMenuManager.m_fMapCenterY - FrontEndMenuManager.m_fMapSize) + (MENU_MAP_LENGTH / 2 - MENU_MAP_TOP_OFFSET - in.y) * FrontEndMenuManager.m_fMapSize * MENU_MAP_HEIGHT_SCALE * 2.0f / MENU_MAP_LENGTH; } else #endif { @@ -1376,7 +1463,7 @@ CRadar::CalculateCachedSinCos() { if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED #ifdef MENU_MAP - || CMenuManager::bMenuMapActive + || FrontEndMenuManager.m_bMenuMapActive #endif ) { cachedSin = 0.0f; @@ -1406,7 +1493,7 @@ CRadar::InitFrontEndMap() CalculateCachedSinCos(); vec2DRadarOrigin.x = 0.0f; vec2DRadarOrigin.y = 0.0f; - m_radarRange = 1000.0f; // doesn't mean anything, just affects the calculation in TransformRadarPointToScreenSpace + m_radarRange = MENU_MAP_LENGTH_UNIT; // just affects the multiplier in TransformRadarPointToScreenSpace for (int i = 0; i < NUM_MAP_LEGENDS; i++) { MapLegendList[i] = RADAR_SPRITE_NONE; } diff --git a/src/core/Radar.h b/src/core/Radar.h index ec2bacd0..95b74b84 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -1,6 +1,33 @@ #pragma once #include "Sprite2d.h" +#define CARBLIP_MARKER_COLOR_R 252 +#define CARBLIP_MARKER_COLOR_G 138 +#define CARBLIP_MARKER_COLOR_B 242 +#define CARBLIP_MARKER_COLOR_A 255 + +#define CHARBLIP_MARKER_COLOR_R 252 +#define CHARBLIP_MARKER_COLOR_G 138 +#define CHARBLIP_MARKER_COLOR_B 242 +#define CHARBLIP_MARKER_COLOR_A 255 + +#define OBJECTBLIP_MARKER_COLOR_R 252 +#define OBJECTBLIP_MARKER_COLOR_G 138 +#define OBJECTBLIP_MARKER_COLOR_B 242 +#define OBJECTBLIP_MARKER_COLOR_A 255 + +#define COORDBLIP_MARKER_COLOR_R 252 +#define COORDBLIP_MARKER_COLOR_G 138 +#define COORDBLIP_MARKER_COLOR_B 242 +#define COORDBLIP_MARKER_COLOR_A 255 + +#define MENU_MAP_LENGTH_UNIT 1190.0f // in game unit +#define MENU_MAP_WIDTH_SCALE 1.112f // in game unit (originally 1.112494151260504f) +#define MENU_MAP_HEIGHT_SCALE 1.119f // in game unit (originally 1.118714268907563f) +#define MENU_MAP_TOP_OFFSET 0.28f // in length unit defined above - ~333 game unit +#define MENU_MAP_LEFT_OFFSET 0.185f // in length unit defined above - ~220 game unit +#define MENU_MAP_LENGTH (4000.f / MENU_MAP_LENGTH_UNIT) + enum eBlipType { BLIP_NONE, @@ -26,26 +53,46 @@ enum eRadarSprite RADAR_SPRITE_COORD_BLIP = -1, #endif RADAR_SPRITE_NONE = 0, - RADAR_SPRITE_ASUKA, - RADAR_SPRITE_BOMB, - RADAR_SPRITE_CAT, RADAR_SPRITE_CENTRE, - RADAR_SPRITE_COPCAR, - RADAR_SPRITE_DON, - RADAR_SPRITE_EIGHT, - RADAR_SPRITE_EL, - RADAR_SPRITE_ICE, - RADAR_SPRITE_JOEY, - RADAR_SPRITE_KENJI, - RADAR_SPRITE_LIZ, - RADAR_SPRITE_LUIGI, + RADAR_SPRITE_MAP_HERE, RADAR_SPRITE_NORTH, - RADAR_SPRITE_RAY, - RADAR_SPRITE_SAL, + RADAR_SPRITE_AVERY, + RADAR_SPRITE_BIKER, + RADAR_SPRITE_CORTEZ, + RADAR_SPRITE_DIAZ, + RADAR_SPRITE_KENT, + RADAR_SPRITE_LAWYER, + RADAR_SPRITE_PHIL, + RADAR_SPRITE_BIKERS, + RADAR_SPRITE_BOATYARD, + RADAR_SPRITE_MALIBU_CLUB, + RADAR_SPRITE_CUBANS, + RADAR_SPRITE_FILM, + RADAR_SPRITE_GUN, + RADAR_SPRITE_HAITIANS, + RADAR_SPRITE_HARDWARE, RADAR_SPRITE_SAVE, + RADAR_SPRITE_STRIP, + RADAR_SPRITE_ICE, + RADAR_SPRITE_KCABS, + RADAR_SPRITE_LOVEFIST, + RADAR_SPRITE_PRINTWORKS, + RADAR_SPRITE_PROPERTY, + RADAR_SPRITE_SUNYARD, RADAR_SPRITE_SPRAY, - RADAR_SPRITE_TONY, - RADAR_SPRITE_WEAPON, + RADAR_SPRITE_TSHIRT, + RADAR_SPRITE_TOMMY, + RADAR_SPRITE_PHONE, + RADAR_SPRITE_RADIO_WILDSTYLE, + RADAR_SPRITE_RADIO_FLASH, + RADAR_SPRITE_RADIO_KCHAT, + RADAR_SPRITE_RADIO_FEVER, + RADAR_SPRITE_RADIO_VROCK, + RADAR_SPRITE_RADIO_VCPR, + RADAR_SPRITE_RADIO_ESPANTOSO, + RADAR_SPRITE_RADIO_EMOTION, + RADAR_SPRITE_RADIO_WAVE, + RADAR_SPRITE_COUNT }; @@ -66,16 +113,16 @@ struct sRadarTrace uint16 m_BlipIndex; bool m_bDim; bool m_bInUse; + bool m_bShortRange; float m_Radius; int16 m_wScale; uint16 m_eBlipDisplay; // eBlipDisplay uint16 m_eRadarSprite; // eRadarSprite }; -VALIDATE_SIZE(sRadarTrace, 0x30); // Values for screen space #define RADAR_LEFT (40.0f) -#define RADAR_BOTTOM (47.0f) +#define RADAR_BOTTOM (40.0f) #define RADAR_WIDTH (94.0f) #define RADAR_HEIGHT (76.0f) @@ -84,26 +131,45 @@ class CRadar public: static float m_radarRange; static sRadarTrace ms_RadarTrace[NUMRADARBLIPS]; - static CSprite2d AsukaSprite; - static CSprite2d BombSprite; - static CSprite2d CatSprite; static CSprite2d CentreSprite; - static CSprite2d CopcarSprite; - static CSprite2d DonSprite; - static CSprite2d EightSprite; - static CSprite2d ElSprite; - static CSprite2d IceSprite; - static CSprite2d JoeySprite; - static CSprite2d KenjiSprite; - static CSprite2d LizSprite; - static CSprite2d LuigiSprite; + static CSprite2d MapHereSprite; static CSprite2d NorthSprite; - static CSprite2d RaySprite; - static CSprite2d SalSprite; - static CSprite2d SaveSprite; + static CSprite2d AverySprite; + static CSprite2d BikerSprite; + static CSprite2d CortezSprite; + static CSprite2d DiazSprite; + static CSprite2d KentSprite; + static CSprite2d LawyerSprite; + static CSprite2d PhilSprite; + static CSprite2d BikersSprite; + static CSprite2d BoatyardSprite; + static CSprite2d MalibuClubSprite; + static CSprite2d CubansSprite; + static CSprite2d FilmSprite; + static CSprite2d GunSprite; + static CSprite2d HaitiansSprite; + static CSprite2d HardwareSprite; + static CSprite2d SaveHouseSprite; + static CSprite2d StripSprite; + static CSprite2d IceSprite; + static CSprite2d KCabsSprite; + static CSprite2d LovefistSprite; + static CSprite2d PrintworksSprite; + static CSprite2d PropertySprite; + static CSprite2d SunYardSprite; static CSprite2d SpraySprite; - static CSprite2d TonySprite; - static CSprite2d WeaponSprite; + static CSprite2d TShirtSprite; + static CSprite2d TommySprite; + static CSprite2d PhoneSprite; + static CSprite2d RadioWildstyleSprite; + static CSprite2d RadioFlashSprite; + static CSprite2d RadioKChatSprite; + static CSprite2d RadioFeverSprite; + static CSprite2d RadioVRockSprite; + static CSprite2d RadioVCPRSprite; + static CSprite2d RadioEspantosoSprite; + static CSprite2d RadioEmotionSprite; + static CSprite2d RadioWaveSprite; static CSprite2d *RadarSprites[RADAR_SPRITE_COUNT]; static float cachedCos; static float cachedSin; @@ -111,7 +177,7 @@ public: #define NUM_MAP_LEGENDS 75 static CRGBA ArrowBlipColour1; static CRGBA ArrowBlipColour2; - static uint16 MapLegendList[NUM_MAP_LEGENDS]; + static int16 MapLegendList[NUM_MAP_LEGENDS]; static uint16 MapLegendCounter; static int TargetMarkerId; static CVector TargetMarkerPos; @@ -149,6 +215,7 @@ public: static void SetBlipSprite(int32 i, int32 icon); static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay); + static int32 SetShortRangeCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay); static void SetRadarMarkerState(int32 i, bool flag); static void ShowRadarMarker(CVector pos, uint32 color, float radius); static void ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha); diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index 99274e04..91f583bd 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -4,6 +4,9 @@ #include "Text.h" #include "World.h" +//TODO +int32 CStats::SeagullsKilled; + int32 CStats::DaysPassed; int32 CStats::HeadsPopped; int32 CStats::CommercialPassed; @@ -57,6 +60,14 @@ int32 CStats::mmRain; int32 CStats::CarsCrushed; int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES]; int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES]; +int32 CStats::PropertyDestroyed; + +int32 CStats::Sprayings; +float CStats::AutoPaintingBudget; +int32 CStats::NoMoreHurricanes; +float CStats::FashionBudget; +int32 CStats::SafeHouseVisits; +int32 CStats::TyresPopped; void CStats::Init() { @@ -113,6 +124,11 @@ void CStats::Init() IndustrialPassed = 0; CommercialPassed = 0; SuburbanPassed = 0; + + Sprayings = 0; + AutoPaintingBudget = 0.0f; + NoMoreHurricanes = 0; + SafeHouseVisits = 0; } void CStats::RegisterFastestTime(int32 index, int32 time) @@ -241,6 +257,19 @@ int32 CStats::FindCriminalRatingNumber() return rating; } +float CStats::GetPercentageProgress() +{ + float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : + CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f)); + + return Min(percentCompleted, 100.0f); +} + +void CStats::MoneySpentOnFashion(int32 money) +{ + FashionBudget += money; +} + void CStats::SaveStats(uint8 *buf, uint32 *size) { CheckPointReachedSuccessfully(); diff --git a/src/core/Stats.h b/src/core/Stats.h index ae3c0cb4..33d4ef72 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -9,6 +9,9 @@ public: TOTAL_FASTEST_TIMES = 16, TOTAL_HIGHEST_SCORES = 16 }; + //TODO + static int32 SeagullsKilled; + static int32 DaysPassed; static int32 HeadsPopped; static int32 CommercialPassed; @@ -62,6 +65,13 @@ public: static int32 CarsCrushed; static int32 FastestTimes[TOTAL_FASTEST_TIMES]; static int32 HighestScores[TOTAL_HIGHEST_SCORES]; + static int32 PropertyDestroyed; + static int32 Sprayings; + static float AutoPaintingBudget; + static int32 NoMoreHurricanes; + static float FashionBudget; + static int32 SafeHouseVisits; + static int32 TyresPopped; public: static void Init(void); @@ -87,4 +97,7 @@ public: static int32 FindCriminalRatingNumber(); static void SaveStats(uint8 *buf, uint32 *size); static void LoadStats(uint8 *buf, uint32 size); + static float GetPercentageProgress(); + + static void MoneySpentOnFashion(int32); }; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index c961f53d..985b28c9 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -18,7 +18,6 @@ #include "FileMgr.h" #include "FileLoader.h" #include "Zones.h" -#include "ZoneCull.h" #include "Radar.h" #include "Camera.h" #include "Record.h" @@ -28,10 +27,10 @@ #include "CutsceneMgr.h" #include "CdStream.h" #include "Streaming.h" -#ifdef FIX_BUGS #include "Replay.h" -#endif #include "main.h" +#include "ColStore.h" +#include "DMAudio.h" bool CStreaming::ms_disableStreaming; bool CStreaming::ms_bLoadingBigModel; @@ -51,9 +50,9 @@ int32 CStreaming::ms_channelError; int32 CStreaming::ms_numVehiclesLoaded; int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED]; int32 CStreaming::ms_lastVehicleDeleted; +bool CStreaming::ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP]; CDirectory *CStreaming::ms_pExtraObjectsDir; int32 CStreaming::ms_numPriorityRequests; -bool CStreaming::ms_hasLoadedLODs; int32 CStreaming::ms_currentPedGrp; int32 CStreaming::ms_currentPedLoading; int32 CStreaming::ms_lastCullZone; @@ -66,17 +65,12 @@ uint32 CStreaming::ms_memoryAvailable; int32 desiredNumVehiclesLoaded = 12; -CEntity *pIslandLODindustEntity; -CEntity *pIslandLODcomIndEntity; -CEntity *pIslandLODcomSubEntity; -CEntity *pIslandLODsubIndEntity; -CEntity *pIslandLODsubComEntity; -int32 islandLODindust; -int32 islandLODcomInd; -int32 islandLODcomSub; -int32 islandLODsubInd; -int32 islandLODsubCom; +CEntity *pIslandLODmainlandEntity; +CEntity *pIslandLODbeachEntity; +int32 islandLODmainland; +int32 islandLODbeach; +//--MIAMI: done bool CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size) { @@ -87,6 +81,7 @@ CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size) return true; } +//--MIAMI: done void CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size) { @@ -94,6 +89,7 @@ CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size) m_size = size; } +//--MIAMI: done void CStreamingInfo::AddToList(CStreamingInfo *link) { @@ -104,6 +100,7 @@ CStreamingInfo::AddToList(CStreamingInfo *link) m_next->m_prev = this; } +//--MIAMI: done void CStreamingInfo::RemoveFromList(void) { @@ -113,6 +110,7 @@ CStreamingInfo::RemoveFromList(void) m_prev = nil; } +//--MIAMI: done void CStreaming::Init2(void) { @@ -182,13 +180,15 @@ CStreaming::Init2(void) ms_vehiclesLoaded[i] = -1; ms_numVehiclesLoaded = 0; + for(i = 0; i < ARRAY_SIZE(ms_bIsPedFromPedGroupLoaded); i++) + ms_bIsPedFromPedGroupLoaded[i] = false; + ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE); ms_numPriorityRequests = 0; - ms_hasLoadedLODs = true; ms_currentPedGrp = -1; ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone ms_loadedGangs = 0; - ms_currentPedLoading = 8; // unused, whatever it is + ms_currentPedLoading = NUMMODELSPERPEDGROUP; // unused, whatever it is LoadCdDirectory(); @@ -199,48 +199,20 @@ CStreaming::Init2(void) ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; debug("Streaming buffer size is %d sectors", ms_streamingBufferSize); - // PC only, figure out how much memory we got -#ifdef GTA_PC #define MB (1024*1024) - extern unsigned long _dwMemAvailPhys; - ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2; - if(ms_memoryAvailable < 50*MB) - ms_memoryAvailable = 50*MB; - desiredNumVehiclesLoaded = (ms_memoryAvailable/MB - 50)/3 + 12; - if(desiredNumVehiclesLoaded > MAXVEHICLESLOADED) - desiredNumVehiclesLoaded = MAXVEHICLESLOADED; + ms_memoryAvailable = 65*MB; + desiredNumVehiclesLoaded = 25; debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable/MB); #undef MB -#endif // find island LODs - pIslandLODindustEntity = nil; - pIslandLODcomIndEntity = nil; - pIslandLODcomSubEntity = nil; - pIslandLODsubIndEntity = nil; - pIslandLODsubComEntity = nil; - islandLODindust = -1; - islandLODcomInd = -1; - islandLODcomSub = -1; - islandLODsubInd = -1; - islandLODsubCom = -1; - CModelInfo::GetModelInfo("IslandLODInd", &islandLODindust); - CModelInfo::GetModelInfo("IslandLODcomIND", &islandLODcomInd); - CModelInfo::GetModelInfo("IslandLODcomSUB", &islandLODcomSub); - CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd); - CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom); - - for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ - CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); - if(building == nil) - continue; - if(building->GetModelIndex() == islandLODindust) pIslandLODindustEntity = building; - if(building->GetModelIndex() == islandLODcomInd) pIslandLODcomIndEntity = building; - if(building->GetModelIndex() == islandLODcomSub) pIslandLODcomSubEntity = building; - if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building; - if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building; - } + pIslandLODmainlandEntity = nil; + pIslandLODbeachEntity = nil; + islandLODmainland = -1; + islandLODbeach = -1; + CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland); + CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach); } void @@ -266,6 +238,7 @@ CStreaming::Init(void) #endif } +//--MIAMI: done void CStreaming::Shutdown(void) { @@ -275,10 +248,10 @@ CStreaming::Shutdown(void) delete ms_pExtraObjectsDir; } +//--MIAMI: done void CStreaming::Update(void) { - CEntity *train; CStreamingInfo *si, *prev; bool requestedSubway = false; @@ -292,31 +265,32 @@ CStreaming::Update(void) if(CTimer::GetIsPaused()) return; - train = FindPlayerTrain(); - if(train && train->GetPosition().z < 0.0f){ - RequestSubway(); - requestedSubway = true; - }else if(!ms_disableStreaming) + LoadBigBuildingsWhenNeeded(); + if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f) AddModelsToRequestList(TheCamera.GetPosition()); DeleteFarAwayRwObjects(TheCamera.GetPosition()); if(!ms_disableStreaming && - !CCutsceneMgr::IsRunning() && - !requestedSubway && - !CGame::playingIntro && + !CCutsceneMgr::IsCutsceneProcessing() && ms_numModelsRequested < 5 && - !CRenderer::m_loadingPriority -#ifdef FIX_BUGS - && !CReplay::IsPlayingBack() -#endif - ){ + !CRenderer::m_loadingPriority && + CGame::currArea == AREA_MAIN_MAP && + !CReplay::IsPlayingBack()){ StreamVehiclesAndPeds(); StreamZoneModels(FindPlayerCoors()); } LoadRequestedModels(); + if(CWorld::Players[0].m_pRemoteVehicle){ + CColStore::AddCollisionNeededAtPosn(FindPlayerCoors()); + CColStore::LoadCollision(CWorld::Players[0].m_pRemoteVehicle->GetPosition()); + CColStore::EnsureCollisionIsInMemory(CWorld::Players[0].m_pRemoteVehicle->GetPosition()); + }else{ + CColStore::LoadCollision(FindPlayerCoors()); + CColStore::EnsureCollisionIsInMemory(FindPlayerCoors()); + } for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){ prev = si->m_prev; @@ -325,6 +299,7 @@ CStreaming::Update(void) } } +//--MIAMI: done void CStreaming::LoadCdDirectory(void) { @@ -338,12 +313,6 @@ CStreaming::LoadCdDirectory(void) ms_imageOffsets[3] = -1; ms_imageOffsets[4] = -1; ms_imageOffsets[5] = -1; - ms_imageOffsets[6] = -1; - ms_imageOffsets[7] = -1; - ms_imageOffsets[8] = -1; - ms_imageOffsets[9] = -1; - ms_imageOffsets[10] = -1; - ms_imageOffsets[11] = -1; ms_imageSize = GetGTA3ImgSize(); // PS2 uses CFileMgr::GetCdFile on all IMG files to fill the array #endif @@ -359,12 +328,12 @@ CStreaming::LoadCdDirectory(void) ms_imageSize /= CDSTREAM_SECTOR_SIZE; } +//--MIAMI: done void CStreaming::LoadCdDirectory(const char *dirname, int n) { int fd, lastID, imgSelector; - int modelId, txdId; - uint32 posn, size; + int modelId; CDirectory::DirectoryInfo direntry; char *dot; @@ -375,23 +344,23 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) imgSelector = n<<24; assert(sizeof(direntry) == 32); while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){ - dot = strchr(direntry.name, '.'); - if(dot) *dot = '\0'; + bool bAddToStreaming = false; + if(direntry.size > (uint32)ms_streamingBufferSize) ms_streamingBufferSize = direntry.size; + direntry.name[23] = '\0'; + dot = strchr(direntry.name, '.'); + if(dot == nil || dot-direntry.name > 20){ + debug("%s is too long\n", direntry.name); + lastID = -1; + continue; + } + + *dot = '\0'; - if(!CGeneral::faststrcmp(dot+1, "DFF") || !CGeneral::faststrcmp(dot+1, "dff")){ + if(strncasecmp(dot+1, "DFF", 3) == 0){ if(CModelInfo::GetModelInfo(direntry.name, &modelId)){ - if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){ - debug("%s appears more than once in %s\n", direntry.name, dirname); - lastID = -1; - }else{ - direntry.offset |= imgSelector; - ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size); - if(lastID != -1) - ms_aInfoForModel[lastID].m_nextID = modelId; - lastID = modelId; - } + bAddToStreaming = true; }else{ #ifdef FIX_BUGS // remember which cdimage this came from @@ -401,27 +370,63 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) #endif lastID = -1; } - }else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){ - txdId = CTxdStore::FindTxdSlot(direntry.name); - if(txdId == -1) - txdId = CTxdStore::AddTxdSlot(direntry.name); - if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){ - debug("%s appears more than once in %s\n", direntry.name, dirname); + }else if(strncasecmp(dot+1, "TXD", 3) == 0){ + modelId = CTxdStore::FindTxdSlot(direntry.name); + if(modelId == -1) + modelId = CTxdStore::AddTxdSlot(direntry.name); + modelId += STREAM_OFFSET_TXD; + bAddToStreaming = true; + }else if(strncasecmp(dot+1, "COL", 3) == 0){ + modelId = CColStore::FindColSlot(direntry.name); + if(modelId == -1) + modelId = CColStore::AddColSlot(direntry.name); + modelId += STREAM_OFFSET_COL; + bAddToStreaming = true; + }else if(strncasecmp(dot+1, "IFP", 3) == 0){ + modelId = CAnimManager::RegisterAnimBlock(direntry.name); + modelId += STREAM_OFFSET_ANIM; + bAddToStreaming = true; + }else{ + *dot = '.'; + lastID = -1; + } + + if(bAddToStreaming){ + if(ms_aInfoForModel[modelId].GetCdSize()){ + debug("%s.%s appears more than once in %s\n", direntry.name, dot+1, dirname); lastID = -1; }else{ direntry.offset |= imgSelector; - ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size); + ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size); if(lastID != -1) - ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD; - lastID = txdId + STREAM_OFFSET_TXD; + ms_aInfoForModel[lastID].m_nextID = modelId; + lastID = modelId; } - }else - lastID = -1; + } } CFileMgr::CloseFile(fd); } +static char* +GetObjectName(int streamId) +{ + static char objname[32]; + if(streamId < STREAM_OFFSET_TXD) + sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetName()); + else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL) + sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD)); + else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM) + sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL)); + else{ + assert(streamId < NUMSTREAMINFO); + sprintf(objname, "%s.ifp", CAnimManager::GetAnimationBlock(streamId-STREAM_OFFSET_ANIM)->name); + } + return objname; +} + + +//--MIAMI: done bool CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) { @@ -443,22 +448,25 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) // Model mi = CModelInfo::GetModelInfo(streamId); - // Txd has to be loaded - if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil){ - debug("failed to load %s because TXD %s is not in memory\n", mi->GetName(), CTxdStore::GetTxdName(mi->GetTxdSlot())); + // Txd and anim have to be loaded + int animId = mi->GetAnimFileIndex(); + if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil || + animId != -1 && !CAnimManager::GetAnimationBlock(animId)->isLoaded){ RemoveModel(streamId); - RemoveTxd(mi->GetTxdSlot()); ReRequestModel(streamId); RwStreamClose(stream, &mem); return false; } - // Set Txd to use + // Set Txd and anims to use CTxdStore::AddRef(mi->GetTxdSlot()); + if(animId != -1) + CAnimManager::AddAnimBlockRef(animId); CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); if(mi->IsSimple()){ success = CFileLoader::LoadAtomicFile(stream, streamId); + // TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that } else if (mi->GetModelType() == MITYPE_VEHICLE) { // load vehicles in two parts CModelInfo::GetModelInfo(streamId)->AddRef(); @@ -470,9 +478,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) } UpdateMemoryUsed(); - // Txd no longer needed unless we only read part of the file - if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED) + // Txd and anims no longer needed unless we only read part of the file + if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){ CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); + if(animId != -1) + CAnimManager::RemoveAnimBlockRefWithoutDelete(animId); + } if(!success){ debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName()); @@ -481,9 +492,8 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } - }else{ + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // Txd - assert(streamId < NUMSTREAMINFO); if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 && !IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){ RemoveModel(streamId); @@ -506,20 +516,28 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) RwStreamClose(stream, &mem); return false; } + }else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){ + if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){ + debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL)); + RemoveModel(streamId); + ReRequestModel(streamId); + RwStreamClose(stream, &mem); + return false; + } + }else if(streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 && + !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){ + RemoveModel(streamId); + RwStreamClose(stream, &mem); + return false; + } + CAnimManager::LoadAnimFile(stream, true, nil); + CAnimManager::CreateAnimAssocGroups(); } RwStreamClose(stream, &mem); - // We shouldn't even end up here unless load was successful - if(!success){ - ReRequestModel(streamId); - if(streamId < STREAM_OFFSET_TXD) - debug("Failed to load %s.dff\n", mi->GetName()); - else - debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD)); - return false; - } - if(streamId < STREAM_OFFSET_TXD){ // Model // Vehicles and Peds not in loaded list @@ -534,12 +552,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) smi->m_alpha = 0; } - if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) + if(CanRemoveModel(streamId)) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); } - }else{ - // Txd - if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL || + streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + // Txd and anims + if(CanRemoveModel(streamId)) ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList); } @@ -551,17 +571,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); timeDiff = endTime - startTime; - if(timeDiff > 5){ - if(streamId < STREAM_OFFSET_TXD) - debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff); - else - debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); - } + if(timeDiff > 5) + debug("%s took %d ms\n", GetObjectName(streamId), timeDiff); return true; } - +//--MIAMI: done bool CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) { @@ -592,11 +608,15 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) success = AddToLoadedVehiclesList(streamId); mi->RemoveRef(); CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); - }else{ + if(mi->GetAnimFileIndex() != -1) + CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex()); + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // Txd CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD); success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream); CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD); + }else{ + assert(0 && "invalid streamId"); } RwStreamClose(stream, &mem); @@ -614,16 +634,13 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond(); timeDiff = endTime - startTime; - if(timeDiff > 5){ - if(streamId < STREAM_OFFSET_TXD) - debug("finish model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff); - else - debug("finish txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); - } + if(timeDiff > 5) + debug("%s took %d ms\n", GetObjectName(streamId), timeDiff); return true; } +//--MIAMI: done void CStreaming::RequestModel(int32 id, int32 flags) { @@ -652,15 +669,20 @@ CStreaming::RequestModel(int32 id, int32 flags) // reinsert into list if(ms_aInfoForModel[id].m_next){ ms_aInfoForModel[id].RemoveFromList(); - if((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0) + if(CanRemoveModel(id)) ms_aInfoForModel[id].AddToList(&ms_startLoadedList); } }else if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED || ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ // how can this be true again? if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED){ - if(id < STREAM_OFFSET_TXD) - RequestTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot(), flags); + if(id < STREAM_OFFSET_TXD){ + mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); + RequestTxd(mi->GetTxdSlot(), flags); + int anim = mi->GetAnimFileIndex(); + if(anim != -1) + RequestAnim(anim, STREAMFLAGS_DEPENDENCY); + } ms_aInfoForModel[id].AddToList(&ms_startRequestedList); ms_numModelsRequested++; if(flags & STREAMFLAGS_PRIORITY) @@ -672,52 +694,28 @@ CStreaming::RequestModel(int32 id, int32 flags) } } +#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE + +//--MIAMI: done void -CStreaming::RequestSubway(void) -{ - RequestModel(MI_SUBWAY1, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY2, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY3, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY4, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY5, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY6, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY7, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY8, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY9, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY10, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY11, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY12, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY13, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY14, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY15, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY16, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY17, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBWAY18, STREAMFLAGS_NOFADE); - - switch(CGame::currLevel){ - case LEVEL_INDUSTRIAL: - RequestModel(MI_SUBPLATFORM_IND, STREAMFLAGS_NOFADE); - break; - case LEVEL_COMMERCIAL: - if(FindPlayerTrain()->GetPosition().y < -700.0f){ - RequestModel(MI_SUBPLATFORM_COMS, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBPLATFORM_COMS2, STREAMFLAGS_NOFADE); - }else{ - RequestModel(MI_SUBPLATFORM_COMN, STREAMFLAGS_NOFADE); - } - break; - case LEVEL_SUBURBAN: - RequestModel(MI_SUBPLATFORM_SUB, STREAMFLAGS_NOFADE); - RequestModel(MI_SUBPLATFORM_SUB2, STREAMFLAGS_NOFADE); - break; - default: break; +CStreaming::RequestBigBuildings(eLevelName level) +{ + int i, n; + CBuilding *b; + + n = CPools::GetBuildingPool()->GetSize()-1; + for(i = n; i >= 0; i--){ + b = CPools::GetBuildingPool()->GetSlot(i); + if(b && b->bIsBIGBuilding && b->m_level == level) + if(!b->bStreamBIGBuilding) + RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } + RequestIslands(level); } -#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY - +//--MIAMI: done void -CStreaming::RequestBigBuildings(eLevelName level) +CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos) { int i, n; CBuilding *b; @@ -726,32 +724,91 @@ CStreaming::RequestBigBuildings(eLevelName level) for(i = n; i >= 0; i--){ b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding && b->m_level == level) - RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); + if(b->bStreamBIGBuilding){ + if(CRenderer::ShouldModelBeStreamed(b, pos)) + RequestModel(b->GetModelIndex(), 0); + }else + RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); } RequestIslands(level); - ms_hasLoadedLODs = false; } +//--MIAMI: done +void +CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos) +{ + int i, n; + CBuilding *b; + + n = CPools::GetBuildingPool()->GetSize()-1; + for(i = n; i >= 0; i--){ + b = CPools::GetBuildingPool()->GetSlot(i); + if(b && b->bIsBIGBuilding && b->m_level == level && + b->bStreamBIGBuilding && b->m_rwObject == nil) + if(CRenderer::ShouldModelBeStreamed(b, pos)) + b->CreateRwObject(); + } +} + +//--MIAMI: done +void +CStreaming::InstanceLoadedModelsInSectorList(CPtrList &list) +{ + CPtrNode *node; + CEntity *e; + for(node = list.first; node; node = node->next) { + e = (CEntity *)node->item; + if(IsAreaVisible(e->m_area) && e->m_rwObject == nil) + e->CreateRwObject(); + } +} + +//--MIAMI: done +void +CStreaming::InstanceLoadedModels(const CVector &pos) +{ + int minX = CWorld::GetSectorIndexX(pos.x - 80.0f); + if(minX <= 0) minX = 0; + + int minY = CWorld::GetSectorIndexY(pos.y - 80.0f); + if(minY <= 0) minY = 0; + + int maxX = CWorld::GetSectorIndexX(pos.x + 80.0f); + if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1; + + int maxY = CWorld::GetSectorIndexY(pos.y + 80.0f); + if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1; + + int x, y; + for(y = minY; y <= maxY; y++){ + for(x = minX; x <= maxX; x++){ + CSector *sector = CWorld::GetSector(x, y); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS]); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_OBJECTS]); + InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_DUMMIES]); + } + } +} + +//--MIAMI: done void CStreaming::RequestIslands(eLevelName level) { switch(level){ - case LEVEL_INDUSTRIAL: - RequestModel(islandLODcomInd, BIGBUILDINGFLAGS); - RequestModel(islandLODsubInd, BIGBUILDINGFLAGS); - break; - case LEVEL_COMMERCIAL: - RequestModel(islandLODindust, BIGBUILDINGFLAGS); - RequestModel(islandLODsubCom, BIGBUILDINGFLAGS); + case LEVEL_MAINLAND: + if(islandLODbeach != -1) + RequestModel(islandLODbeach, BIGBUILDINGFLAGS); break; - case LEVEL_SUBURBAN: - RequestModel(islandLODindust, BIGBUILDINGFLAGS); - RequestModel(islandLODcomSub, BIGBUILDINGFLAGS); + case LEVEL_BEACH: + if(islandLODmainland != -1) + RequestModel(islandLODmainland, BIGBUILDINGFLAGS); break; default: break; } } +//--MIAMI: TODO void CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flags) { @@ -793,24 +850,28 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag RequestModel(modelId, flags); } +//--MIAMI: done void CStreaming::RequestSpecialChar(int32 charId, const char *modelName, int32 flags) { RequestSpecialModel(charId + MI_SPECIAL01, modelName, flags); } +//--MIAMI: done bool CStreaming::HasSpecialCharLoaded(int32 id) { return HasModelLoaded(id + MI_SPECIAL01); } +//--MIAMI: done void CStreaming::SetMissionDoesntRequireSpecialChar(int32 id) { return SetMissionDoesntRequireModel(id + MI_SPECIAL01); } +//--MIAMI: done void CStreaming::DecrementRef(int32 id) { @@ -821,6 +882,7 @@ CStreaming::DecrementRef(int32 id) } } +//--MIAMI: done void CStreaming::RemoveModel(int32 id) { @@ -832,8 +894,14 @@ CStreaming::RemoveModel(int32 id) if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ if(id < STREAM_OFFSET_TXD) CModelInfo::GetModelInfo(id)->DeleteRwObject(); - else + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + else if(id >= STREAM_OFFSET_ANIM){ + assert(id < NUMSTREAMINFO); + CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM); + } ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE; } @@ -854,24 +922,30 @@ CStreaming::RemoveModel(int32 id) if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){ if(id < STREAM_OFFSET_TXD) RpClumpGtaCancelStream(); - else + else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL) CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD); + else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM) + CColStore::RemoveCol(id - STREAM_OFFSET_COL); + else if(id >= STREAM_OFFSET_ANIM){ + assert(id < NUMSTREAMINFO); + CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM); + } } ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED; } +//--MIAMI: done void CStreaming::RemoveUnusedBuildings(eLevelName level) { - if(level != LEVEL_INDUSTRIAL) - RemoveBuildings(LEVEL_INDUSTRIAL); - if(level != LEVEL_COMMERCIAL) - RemoveBuildings(LEVEL_COMMERCIAL); - if(level != LEVEL_SUBURBAN) - RemoveBuildings(LEVEL_SUBURBAN); + if(level != LEVEL_BEACH) + RemoveBuildings(LEVEL_BEACH); + if(level != LEVEL_MAINLAND) + RemoveBuildings(LEVEL_MAINLAND); } +//--MIAMI: done void CStreaming::RemoveBuildings(eLevelName level) { @@ -932,18 +1006,18 @@ CStreaming::RemoveBuildings(eLevelName level) } } +//--MIAMI: done void CStreaming::RemoveUnusedBigBuildings(eLevelName level) { - if(level != LEVEL_INDUSTRIAL) - RemoveBigBuildings(LEVEL_INDUSTRIAL); - if(level != LEVEL_COMMERCIAL) - RemoveBigBuildings(LEVEL_COMMERCIAL); - if(level != LEVEL_SUBURBAN) - RemoveBigBuildings(LEVEL_SUBURBAN); + if(level != LEVEL_BEACH) + RemoveBigBuildings(LEVEL_BEACH); + if(level != LEVEL_MAINLAND) + RemoveBigBuildings(LEVEL_MAINLAND); RemoveIslandsNotUsed(level); } +//--MIAMI: done void DeleteIsland(CEntity *island) { @@ -957,35 +1031,33 @@ DeleteIsland(CEntity *island) } } +//--MIAMI: done void CStreaming::RemoveIslandsNotUsed(eLevelName level) { + int i; + if(pIslandLODmainlandEntity == nil) + for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ + CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); + if(building == nil) + continue; + if(building->GetModelIndex() == islandLODmainland) + pIslandLODmainlandEntity = building; + if(building->GetModelIndex() == islandLODbeach) + pIslandLODbeachEntity = building; + } + switch(level){ - case LEVEL_INDUSTRIAL: - DeleteIsland(pIslandLODindustEntity); - DeleteIsland(pIslandLODcomSubEntity); - DeleteIsland(pIslandLODsubComEntity); - break; - case LEVEL_COMMERCIAL: - DeleteIsland(pIslandLODcomIndEntity); - DeleteIsland(pIslandLODcomSubEntity); - DeleteIsland(pIslandLODsubIndEntity); - break; - case LEVEL_SUBURBAN: - DeleteIsland(pIslandLODsubIndEntity); - DeleteIsland(pIslandLODsubComEntity); - DeleteIsland(pIslandLODcomIndEntity); + case LEVEL_MAINLAND: + DeleteIsland(pIslandLODmainlandEntity); break; - default: - DeleteIsland(pIslandLODindustEntity); - DeleteIsland(pIslandLODcomIndEntity); - DeleteIsland(pIslandLODcomSubEntity); - DeleteIsland(pIslandLODsubIndEntity); - DeleteIsland(pIslandLODsubComEntity); + case LEVEL_BEACH: + DeleteIsland(pIslandLODbeachEntity); break; } } +//--MIAMI: done void CStreaming::RemoveBigBuildings(eLevelName level) { @@ -1017,8 +1089,7 @@ CStreaming::RemoveLoadedVehicle(void) if(ms_lastVehicleDeleted == MAXVEHICLESLOADED) ms_lastVehicleDeleted = 0; id = ms_vehiclesLoaded[ms_lastVehicleDeleted]; - if(id != -1 && - (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 && + if(id != -1 && CanRemoveModel(id) && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 && ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED) goto found; } @@ -1027,33 +1098,47 @@ found: RemoveModel(ms_vehiclesLoaded[ms_lastVehicleDeleted]); ms_numVehiclesLoaded--; ms_vehiclesLoaded[ms_lastVehicleDeleted] = -1; + CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); + if (pVehicleInfo->m_vehicleClass != -1) + CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass); return true; } +//--MIAMI: done bool -CStreaming::RemoveLeastUsedModel(void) +CStreaming::RemoveLeastUsedModel(uint32 excludeMask) { CStreamingInfo *si; int streamId; for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){ + if(si->m_flags & excludeMask) + continue; streamId = si - ms_aInfoForModel; if(streamId < STREAM_OFFSET_TXD){ if (CModelInfo::GetModelInfo(streamId)->GetNumRefs() == 0) { RemoveModel(streamId); return true; } - }else{ + }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ if(CTxdStore::GetNumRefs(streamId - STREAM_OFFSET_TXD) == 0 && !IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){ RemoveModel(streamId); return true; } + }else if(streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + if(CAnimManager::GetNumRefsToAnimBlock(streamId - STREAM_OFFSET_ANIM) == 0 && + !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){ + RemoveModel(streamId); + return true; + } } } - return ms_numVehiclesLoaded > 7 && RemoveLoadedVehicle(); + return (ms_numVehiclesLoaded > 7 || CGame::currArea != AREA_MAIN_MAP && ms_numVehiclesLoaded > 4) && RemoveLoadedVehicle(); } +//--MIAMI: done void CStreaming::RemoveAllUnusedModels(void) { @@ -1064,7 +1149,6 @@ CStreaming::RemoveAllUnusedModels(void) for(i = NUM_DEFAULT_MODELS; i < MODELINFOSIZE; i++){ if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED && - ms_aInfoForModel[i].m_flags & STREAMFLAGS_DONT_REMOVE && CModelInfo::GetModelInfo(i)->GetNumRefs() == 0) { RemoveModel(i); ms_aInfoForModel[i].m_loadState = STREAMSTATE_NOTLOADED; @@ -1072,30 +1156,14 @@ CStreaming::RemoveAllUnusedModels(void) } } -bool -CStreaming::RemoveReferencedTxds(int32 mem) -{ - CStreamingInfo *si; - int streamId; - - for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){ - streamId = si - ms_aInfoForModel; - if(streamId >= STREAM_OFFSET_TXD && - CTxdStore::GetNumRefs(streamId-STREAM_OFFSET_TXD) == 0){ - RemoveModel(streamId); - if(ms_memoryUsed < mem) - return true; - } - } - return false; -} - +//--MIAMI: done void CStreaming::RemoveUnusedModelsInLoadedList(void) { // empty } +//--MIAMI: done bool CStreaming::IsTxdUsedByRequestedModels(int32 txdId) { @@ -1124,6 +1192,34 @@ CStreaming::IsTxdUsedByRequestedModels(int32 txdId) return false; } +bool +CStreaming::AreAnimsUsedByRequestedModels(int32 animId) +{ + CStreamingInfo *si; + int streamId; + int i; + + for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = si->m_next){ + streamId = si - ms_aInfoForModel; + if(streamId < STREAM_OFFSET_TXD && + CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId) + return true; + } + + for(i = 0; i < 4; i++){ + streamId = ms_channel[0].streamIds[i]; + if(streamId != -1 && streamId < STREAM_OFFSET_TXD && + CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId) + return true; + streamId = ms_channel[1].streamIds[i]; + if(streamId != -1 && streamId < STREAM_OFFSET_TXD && + CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId) + return true; + } + + return false; +} + int32 CStreaming::GetAvailableVehicleSlot(void) { @@ -1155,8 +1251,8 @@ CStreaming::AddToLoadedVehiclesList(int32 modelId) // find vehicle we can remove for(i = 0; i < MAXVEHICLESLOADED; i++){ id = ms_vehiclesLoaded[ms_lastVehicleDeleted]; - if(id != -1 && - (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0) + if(id != -1 && CanRemoveModel(id) && + CModelInfo::GetModelInfo(id)->GetNumRefs() == 0) goto found; ms_lastVehicleDeleted++; if(ms_lastVehicleDeleted == MAXVEHICLESLOADED) @@ -1172,13 +1268,21 @@ found: ms_lastVehicleDeleted = id; // this is more that we wanted actually ms_numVehiclesLoaded++; - }else + } + else{ RemoveModel(id); + CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); + if (pVehicleInfo->m_vehicleClass != -1) + CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass); + } } ms_vehiclesLoaded[ms_lastVehicleDeleted++] = modelId; if(ms_lastVehicleDeleted == MAXVEHICLESLOADED) ms_lastVehicleDeleted = 0; + CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(modelId); + if (pVehicleInfo->m_vehicleClass != -1) + CCarCtrl::AddToLoadedVehicleArray(modelId, pVehicleInfo->m_vehicleClass, pVehicleInfo->m_frequency); return true; } @@ -1190,41 +1294,6 @@ CStreaming::IsObjectInCdImage(int32 id) } void -CStreaming::HaveAllBigBuildingsLoaded(eLevelName level) -{ - int i, n; - CEntity *e; - - if(ms_hasLoadedLODs) - return; - - if(level == LEVEL_INDUSTRIAL){ - if(ms_aInfoForModel[islandLODcomInd].m_loadState != STREAMSTATE_LOADED || - ms_aInfoForModel[islandLODsubInd].m_loadState != STREAMSTATE_LOADED) - return; - }else if(level == LEVEL_COMMERCIAL){ - if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED || - ms_aInfoForModel[islandLODsubCom].m_loadState != STREAMSTATE_LOADED) - return; - }else if(level == LEVEL_SUBURBAN){ - if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED || - ms_aInfoForModel[islandLODcomSub].m_loadState != STREAMSTATE_LOADED) - return; - } - - n = CPools::GetBuildingPool()->GetSize()-1; - for(i = n; i >= 0; i--){ - e = CPools::GetBuildingPool()->GetSlot(i); - if(e && e->bIsBIGBuilding && e->m_level == level && - ms_aInfoForModel[e->GetModelIndex()].m_loadState != STREAMSTATE_LOADED) - return; - } - - RemoveUnusedBigBuildings(level); - ms_hasLoadedLODs = true; -} - -void CStreaming::SetModelIsDeletable(int32 id) { ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_DONT_REMOVE; @@ -1243,6 +1312,7 @@ CStreaming::SetModelTxdIsDeletable(int32 id) SetModelIsDeletable(CModelInfo::GetModelInfo(id)->GetTxdSlot() + STREAM_OFFSET_TXD); } +//--MIAMI: done void CStreaming::SetMissionDoesntRequireModel(int32 id) { @@ -1265,6 +1335,13 @@ CStreaming::LoadInitialPeds(void) } void +CStreaming::LoadInitialWeapons(void) +{ + CStreaming::RequestModel(MI_NIGHTSTICK, STREAMFLAGS_DONT_REMOVE); + CStreaming::RequestModel(MI_MISSILE, STREAMFLAGS_DONT_REMOVE); +} + +void CStreaming::LoadInitialVehicles(void) { int id; @@ -1327,28 +1404,73 @@ CStreaming::StreamVehiclesAndPeds(void) else SetModelIsDeletable(MI_CHOPPER); + if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired()) { + SetModelIsDeletable(MI_VICE1); + SetModelIsDeletable(MI_VICE2); + SetModelIsDeletable(MI_VICE3); + SetModelIsDeletable(MI_VICE4); + SetModelIsDeletable(MI_VICE5); + SetModelIsDeletable(MI_VICE6); + SetModelIsDeletable(MI_VICE7); + SetModelIsDeletable(MI_VICE8); + switch (CCarCtrl::MiamiViceCycle) { + case 0: + RequestModel(MI_VICE1, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE2, STREAMFLAGS_DONT_REMOVE); + break; + case 1: + RequestModel(MI_VICE3, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE4, STREAMFLAGS_DONT_REMOVE); + break; + case 2: + RequestModel(MI_VICE5, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE6, STREAMFLAGS_DONT_REMOVE); + break; + case 3: + RequestModel(MI_VICE7, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_VICE8, STREAMFLAGS_DONT_REMOVE); + break; + } + RequestModel(MI_VICECHEE, STREAMFLAGS_DONT_REMOVE); + } + else { + SetModelIsDeletable(MI_VICECHEE); + SetModelIsDeletable(MI_VICE1); + SetModelIsDeletable(MI_VICE2); + SetModelIsDeletable(MI_VICE3); + SetModelIsDeletable(MI_VICE4); + SetModelIsDeletable(MI_VICE5); + SetModelIsDeletable(MI_VICE6); + SetModelIsDeletable(MI_VICE7); + SetModelIsDeletable(MI_VICE8); + } + if(timeBeforeNextLoad >= 0) timeBeforeNextLoad--; else if(ms_numVehiclesLoaded <= desiredNumVehiclesLoaded){ - for(i = 1; i <= 10; i++){ - model = CCarCtrl::ChooseCarModel(modelQualityClass); - modelQualityClass++; - if(modelQualityClass >= CCarCtrl::TOTAL_CUSTOM_CLASSES) - modelQualityClass = 0; - - // check if we want to load this model - if(ms_aInfoForModel[model].m_loadState == STREAMSTATE_NOTLOADED && - ((CVehicleModelInfo*)CModelInfo::GetModelInfo(model))->m_level & (1 << (CGame::currLevel-1))) - break; + CZoneInfo zone; + CVector coors = FindPlayerCoors(); + CTheZones::GetZoneInfoForTimeOfDay(&coors, &zone); + int32 maxReq = -1; + int32 mostRequestedRating = 0; + for(i = 0; i < CCarCtrl::TOTAL_CUSTOM_CLASSES; i++){ + if(CCarCtrl::NumRequestsOfCarRating[i] > maxReq && + ((i == 0 && zone.carThreshold[0] != 0) || + (i != 0 && zone.carThreshold[i] != zone.carThreshold[i-1]))) { + maxReq = CCarCtrl::NumRequestsOfCarRating[i]; + mostRequestedRating = i; + } } - - if(i <= 10){ + model = CCarCtrl::ChooseCarModelToLoad(mostRequestedRating); + if(!HasModelLoaded(model)){ RequestModel(model, STREAMFLAGS_DEPENDENCY); - timeBeforeNextLoad = 500; + timeBeforeNextLoad = 350; } + CCarCtrl::NumRequestsOfCarRating[mostRequestedRating] = 0; } } +//--MIAMI: TODO void CStreaming::StreamZoneModels(const CVector &pos) { @@ -1374,58 +1496,54 @@ CStreaming::StreamZoneModels(const CVector &pos) for(i = 0; i < NUMMODELSPERPEDGROUP; i++){ if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1) break; - RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DONT_REMOVE); + RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DEPENDENCY); } } RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE); + //RequestModel(MI_HMOCA, STREAMFLAGS_DONT_REMOVE); gangsToLoad = 0; gangCarsToLoad = 0; - if(info.gangDensity[0] != 0) gangsToLoad |= 1<<0; - if(info.gangDensity[1] != 0) gangsToLoad |= 1<<1; - if(info.gangDensity[2] != 0) gangsToLoad |= 1<<2; - if(info.gangDensity[3] != 0) gangsToLoad |= 1<<3; - if(info.gangDensity[4] != 0) gangsToLoad |= 1<<4; - if(info.gangDensity[5] != 0) gangsToLoad |= 1<<5; - if(info.gangDensity[6] != 0) gangsToLoad |= 1<<6; - if(info.gangDensity[7] != 0) gangsToLoad |= 1<<7; - if(info.gangDensity[8] != 0) gangsToLoad |= 1<<8; - if(info.gangThreshold[0] != info.copDensity) gangCarsToLoad |= 1<<0; - if(info.gangThreshold[1] != info.gangThreshold[0]) gangCarsToLoad |= 1<<1; - if(info.gangThreshold[2] != info.gangThreshold[1]) gangCarsToLoad |= 1<<2; - if(info.gangThreshold[3] != info.gangThreshold[2]) gangCarsToLoad |= 1<<3; - if(info.gangThreshold[4] != info.gangThreshold[3]) gangCarsToLoad |= 1<<4; - if(info.gangThreshold[5] != info.gangThreshold[4]) gangCarsToLoad |= 1<<5; - if(info.gangThreshold[6] != info.gangThreshold[5]) gangCarsToLoad |= 1<<6; - if(info.gangThreshold[7] != info.gangThreshold[6]) gangCarsToLoad |= 1<<7; - if(info.gangThreshold[8] != info.gangThreshold[7]) gangCarsToLoad |= 1<<8; + if(info.gangPedThreshold[0] != info.copPedThreshold) + gangsToLoad = 1; + for(i = 1; i < NUM_GANGS; i++) + if(info.gangPedThreshold[i] != info.gangPedThreshold[i-1]) + gangsToLoad |= 1<<i; + if(info.gangThreshold[0] != info.copThreshold) + gangCarsToLoad = 1; + for(i = 1; i < NUM_GANGS; i++) + if(info.gangThreshold[i] != info.gangThreshold[i-1]) + gangCarsToLoad |= 1<<i; if(gangsToLoad == ms_loadedGangs && gangCarsToLoad == ms_loadedGangCars) return; - // This makes things simpler than the game does it gangsToLoad |= gangCarsToLoad; for(i = 0; i < NUM_GANGS; i++){ bit = 1<<i; if(gangsToLoad & bit && (ms_loadedGangs & bit) == 0){ - RequestModel(MI_GANG01 + i*2, STREAMFLAGS_DONT_REMOVE); - RequestModel(MI_GANG01 + i*2 + 1, STREAMFLAGS_DONT_REMOVE); + RequestModel(CGangs::GetGangPedModel1(i), STREAMFLAGS_DEPENDENCY); + RequestModel(CGangs::GetGangPedModel2(i), STREAMFLAGS_DEPENDENCY); ms_loadedGangs |= bit; }else if((gangsToLoad & bit) == 0 && ms_loadedGangs & bit){ - SetModelIsDeletable(MI_GANG01 + i*2); - SetModelIsDeletable(MI_GANG01 + i*2 + 1); - SetModelTxdIsDeletable(MI_GANG01 + i*2); - SetModelTxdIsDeletable(MI_GANG01 + i*2 + 1); + SetModelIsDeletable(CGangs::GetGangPedModel1(i)); + SetModelIsDeletable(CGangs::GetGangPedModel2(i)); + SetModelTxdIsDeletable(CGangs::GetGangPedModel1(i)); + SetModelTxdIsDeletable(CGangs::GetGangPedModel2(i)); ms_loadedGangs &= ~bit; } - if(gangCarsToLoad & bit && (ms_loadedGangCars & bit) == 0){ - RequestModel(CGangs::GetGangInfo(i)->m_nVehicleMI, STREAMFLAGS_DONT_REMOVE); + // TODO(MIAMI): check this + if(CGangs::GetGangVehicleModel(i) < 0) + continue; + + if((gangCarsToLoad & bit) && (ms_loadedGangCars & bit) == 0){ + RequestModel(CGangs::GetGangVehicleModel(i), STREAMFLAGS_DEPENDENCY); }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){ - SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); - SetModelTxdIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + SetModelIsDeletable(CGangs::GetGangVehicleModel(i)); + SetModelTxdIsDeletable(CGangs::GetGangVehicleModel(i)); } } ms_loadedGangCars = gangCarsToLoad; @@ -1437,7 +1555,7 @@ CStreaming::RemoveCurrentZonesModels(void) int i; if(ms_currentPedGrp != -1) - for(i = 0; i < 8; i++){ + for(i = 0; i < NUMMODELSPERPEDGROUP; i++){ if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1) break; if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) @@ -1445,10 +1563,10 @@ CStreaming::RemoveCurrentZonesModels(void) } for(i = 0; i < NUM_GANGS; i++){ - SetModelIsDeletable(MI_GANG01 + i*2); - SetModelIsDeletable(MI_GANG01 + i*2 + 1); - if(CGangs::GetGangInfo(i)->m_nVehicleMI != -1) - SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + SetModelIsDeletable(CGangs::GetGangPedModel1(i)); + SetModelIsDeletable(CGangs::GetGangPedModel2(i)); + if(CGangs::GetGangVehicleModel(i) != -1) + SetModelIsDeletable(CGangs::GetGangVehicleModel(i)); } ms_currentPedGrp = -1; @@ -1456,6 +1574,42 @@ CStreaming::RemoveCurrentZonesModels(void) ms_loadedGangCars = 0; } +void +CStreaming::LoadBigBuildingsWhenNeeded(void) +{ + // Very much like CCollision::Update and CCollision::LoadCollisionWhenINeedIt + if(CCutsceneMgr::IsCutsceneProcessing()) + return; + + if(CTheZones::m_CurrLevel == LEVEL_NONE || + CTheZones::m_CurrLevel == CGame::currLevel) + return; + + CTimer::Suspend(); + CGame::currLevel = CTheZones::m_CurrLevel; + DMAudio.SetEffectsFadeVol(0); + CPad::StopPadsShaking(); + CCollision::LoadCollisionScreen(CGame::currLevel); + DMAudio.Service(); + + // CPopulation::DealWithZoneChange is unused in VC + RemoveUnusedBigBuildings(CGame::currLevel); + RemoveUnusedBuildings(CGame::currLevel); + RemoveUnusedModelsInLoadedList(); + CGame::TidyUpMemory(true, true); + + CReplay::EmptyReplayBuffer(); + if(CGame::currLevel != LEVEL_NONE) + LoadSplash(GetLevelSplashScreen(CGame::currLevel)); + + CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); + CStreaming::LoadAllRequestedModels(true); + + CGame::TidyUpMemory(true, true); + CTimer::Resume(); + DMAudio.SetEffectsFadeVol(127); +} + // Find starting offset of the cdimage we next want to read // Not useful at all on PC... @@ -1502,6 +1656,7 @@ ModelNotLoaded(int32 modelId) } inline bool TxdNotLoaded(int32 txdId) { return ModelNotLoaded(txdId + STREAM_OFFSET_TXD); } +inline bool AnimNotLoaded(int32 animId) { return animId != -1 && ModelNotLoaded(animId + STREAM_OFFSET_ANIM); } // Find stream id of next requested file in cdimage int32 @@ -1526,14 +1681,20 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority) if(priority && ms_numPriorityRequests != 0 && !si->IsPriority()) continue; - // request Txd if necessary + // request Txds or anims if necessary if(streamId < STREAM_OFFSET_TXD){ int txdId = CModelInfo::GetModelInfo(streamId)->GetTxdSlot(); if(TxdNotLoaded(txdId)){ ReRequestTxd(txdId); continue; } - } + int animId = CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex(); + if(AnimNotLoaded(animId)){ + ReRequestAnim(animId); + continue; + } + }else if(streamId >= STREAM_OFFSET_ANIM && CCutsceneMgr::IsCutsceneProcessing()) + continue; if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){ if(posn < posnFirst){ @@ -1576,6 +1737,7 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority) * TODO: two-part files */ +//--MIAMI: done // Make channel read from disc void CStreaming::RequestModelStream(int32 ch) @@ -1590,13 +1752,18 @@ CStreaming::RequestModelStream(int32 ch) imgOffset = GetCdImageOffset(lastPosn); streamId = GetNextFileOnCd(lastPosn - imgOffset, true); - if(streamId == -1) - return; - - // remove Txds that aren't requested anymore - while(streamId >= STREAM_OFFSET_TXD){ - if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY || - IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)) + // remove Txds and Anims that aren't requested anymore + while(streamId != -1){ + if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) + break; + if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ + if(IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)) + break; + }else if(streamId >= STREAM_OFFSET_ANIM){ + assert(streamId < NUMSTREAMINFO); + if(AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)) + break; + }else break; RemoveModel(streamId); // so try next file @@ -1633,7 +1800,8 @@ CStreaming::RequestModelStream(int32 ch) if(streamId < STREAM_OFFSET_TXD){ if (havePed && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED || haveBigFile && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE || - TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot())) + TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()) || + AnimNotLoaded(CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex())) break; }else{ if(haveBigFile && size > 200) @@ -1680,6 +1848,7 @@ CStreaming::RequestModelStream(int32 ch) ms_channel[ch].numTries = 0; } +//--MIAMI: done // Load data previously read from disc bool CStreaming::ProcessLoadingChannel(int32 ch) @@ -1714,10 +1883,10 @@ CStreaming::ProcessLoadingChannel(int32 ch) if(id < STREAM_OFFSET_TXD && CModelInfo::GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && ms_numVehiclesLoaded >= desiredNumVehiclesLoaded && !RemoveLoadedVehicle() && - ((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 || GetAvailableVehicleSlot() == -1)){ + (CanRemoveModel(id) || GetAvailableVehicleSlot() == -1)){ // can't load vehicle RemoveModel(id); - if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) + if(!CanRemoveModel(id)) ReRequestModel(id); else if(CTxdStore::GetNumRefs(CModelInfo::GetModelInfo(id)->GetTxdSlot()) == 0) RemoveTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot()); @@ -1749,6 +1918,7 @@ CStreaming::ProcessLoadingChannel(int32 ch) return true; } +//--MIAMI: done void CStreaming::RetryLoadFile(int32 ch) { @@ -1785,6 +1955,7 @@ CStreaming::RetryLoadFile(int32 ch) } } +//--MIAMI: done void CStreaming::LoadRequestedModels(void) { @@ -1809,6 +1980,7 @@ CStreaming::LoadRequestedModels(void) } } +//--MIAMI: done void CStreaming::LoadAllRequestedModels(bool priority) { @@ -1862,6 +2034,7 @@ CStreaming::LoadAllRequestedModels(bool priority) bInsideLoadAll = false; } +//--MIAMI: done void CStreaming::FlushChannels(void) { @@ -1883,6 +2056,7 @@ CStreaming::FlushChannels(void) ProcessLoadingChannel(1); } +//--MIAMI: done void CStreaming::FlushRequestList(void) { @@ -1991,8 +2165,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float if(xmin < pos.x && pos.x < xmax && ymin < pos.y && pos.y < ymax && (CVector2D(x, y) - pos).MagnitudeSqr() < lodDistSq) - if(CRenderer::IsEntityCullZoneVisible(e)) - RequestModel(e->GetModelIndex(), 0); + RequestModel(e->GetModelIndex(), 0); } } } @@ -2015,8 +2188,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list) (!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){ CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()); if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) - if(CRenderer::IsEntityCullZoneVisible(e)) - RequestModel(e->GetModelIndex(), 0); + RequestModel(e->GetModelIndex(), 0); } } } @@ -2254,9 +2426,6 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem) } } - if(RemoveReferencedTxds(mem)) - return; - // As last resort, delete objects from the last step more aggressively for(y = ymin; y <= ymax; y++){ for(x = xmax; x != xmin; x -= inc){ @@ -2318,9 +2487,6 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem) } } - if(RemoveReferencedTxds(mem)) - return; - // As last resort, delete objects from the last step more aggressively for(x = xmin; x <= xmax; x++){ for(y = ymax; y != ymin; y -= inc){ @@ -2419,12 +2585,13 @@ CStreaming::MakeSpaceFor(int32 size) // but it's not nice.... while((uint32)ms_memoryUsed >= ms_memoryAvailable - size) - if(!RemoveLeastUsedModel()){ + if(!RemoveLeastUsedModel(STREAMFLAGS_20)){ DeleteRwObjectsBehindCamera(ms_memoryAvailable - size); return; } } +//--MIAMI: done void CStreaming::LoadScene(const CVector &pos) { @@ -2439,16 +2606,44 @@ CStreaming::LoadScene(const CVector &pos) RemoveModel(si - ms_aInfoForModel); } CRenderer::m_loadingPriority = false; - CCullZones::ForceCullZoneCoors(pos); DeleteAllRwObjects(); + if(level == LEVEL_NONE) + level = CGame::currLevel; + CGame::currLevel = level; + RemoveUnusedBigBuildings(level); + RequestBigBuildings(level, pos); + RequestBigBuildings(LEVEL_NONE, pos); + RemoveIslandsNotUsed(level); + LoadAllRequestedModels(false); + InstanceBigBuildings(level, pos); + InstanceBigBuildings(LEVEL_NONE, pos); AddModelsToRequestList(pos); CRadar::StreamRadarSections(pos); - RemoveUnusedBigBuildings(level); - RequestBigBuildings(level); + + if (!CGame::IsInInterior()) { + for (int i = 0; i < 5; i++) { + CZoneInfo zone; + CTheZones::GetZoneInfoForTimeOfDay(&pos, &zone); + int32 model = CCarCtrl::ChooseCarModelToLoad(CCarCtrl::ChooseCarRating(&zone)); + CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY); + } + } LoadAllRequestedModels(false); + InstanceLoadedModels(pos); + + for(int i = 0; i < NUMSTREAMINFO; i++) + ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20; debug("End load scene\n"); } +//--MIAMI: done +void +CStreaming::LoadSceneCollision(const CVector &pos) +{ + CColStore::LoadCollision(pos); + CStreaming::LoadAllRequestedModels(false); +} + void CStreaming::MemoryCardSave(uint8 *buf, uint32 *size) { diff --git a/src/core/Streaming.h b/src/core/Streaming.h index 84434769..8a92266f 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -4,7 +4,9 @@ enum { STREAM_OFFSET_TXD = MODELINFOSIZE, - NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE + STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE, + STREAM_OFFSET_ANIM = STREAM_OFFSET_COL+COLSTORESIZE, + NUMSTREAMINFO = STREAM_OFFSET_ANIM+NUMANIMBLOCKS }; enum StreamFlags @@ -14,6 +16,7 @@ enum StreamFlags STREAMFLAGS_DEPENDENCY = 0x04, // Is this right? STREAMFLAGS_PRIORITY = 0x08, STREAMFLAGS_NOFADE = 0x10, + STREAMFLAGS_20 = 0x20, // TODO(MIAMI): what's this STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED, STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY, @@ -92,9 +95,9 @@ public: static int32 ms_numVehiclesLoaded; static int32 ms_vehiclesLoaded[MAXVEHICLESLOADED]; static int32 ms_lastVehicleDeleted; + static bool ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP]; static CDirectory *ms_pExtraObjectsDir; static int32 ms_numPriorityRequests; - static bool ms_hasLoadedLODs; static int32 ms_currentPedGrp; static int32 ms_lastCullZone; static uint16 ms_loadedGangs; @@ -115,14 +118,25 @@ public: static bool FinishLoadingLargeFile(int8 *buf, int32 streamId); static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; } static bool HasTxdLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_TXD); } + static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); } + static bool HasAnimLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_ANIM); } static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; } static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); } + static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); } + static bool CanRemoveAnim(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_ANIM); } static void RequestModel(int32 model, int32 flags); static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); } static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); } static void ReRequestTxd(int32 txd) { ReRequestModel(txd + STREAM_OFFSET_TXD); } - static void RequestSubway(void); + static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); } + static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); } + static void RequestAnim(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_ANIM, flags); } + static void ReRequestAnim(int32 col) { ReRequestModel(col + STREAM_OFFSET_ANIM); } static void RequestBigBuildings(eLevelName level); + static void RequestBigBuildings(eLevelName level, const CVector &pos); + static void InstanceBigBuildings(eLevelName level, const CVector &pos); + static void InstanceLoadedModelsInSectorList(CPtrList &list); + static void InstanceLoadedModels(const CVector &pos); static void RequestIslands(eLevelName level); static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags); static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags); @@ -131,29 +145,32 @@ public: static void DecrementRef(int32 id); static void RemoveModel(int32 id); static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); } + static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); } + static void RemoveAnim(int32 id) { RemoveModel(id + STREAM_OFFSET_ANIM); } static void RemoveUnusedBuildings(eLevelName level); static void RemoveBuildings(eLevelName level); static void RemoveUnusedBigBuildings(eLevelName level); static void RemoveIslandsNotUsed(eLevelName level); static void RemoveBigBuildings(eLevelName level); static bool RemoveLoadedVehicle(void); - static bool RemoveLeastUsedModel(void); + static bool RemoveLeastUsedModel(uint32 excludeMask); static void RemoveAllUnusedModels(void); static void RemoveUnusedModelsInLoadedList(void); - static bool RemoveReferencedTxds(int32 mem); static int32 GetAvailableVehicleSlot(void); static bool IsTxdUsedByRequestedModels(int32 txdId); + static bool AreAnimsUsedByRequestedModels(int32 animId); static bool AddToLoadedVehiclesList(int32 modelId); static bool IsObjectInCdImage(int32 id); - static void HaveAllBigBuildingsLoaded(eLevelName level); static void SetModelIsDeletable(int32 id); static void SetModelTxdIsDeletable(int32 id); static void SetMissionDoesntRequireModel(int32 id); static void LoadInitialPeds(void); + static void LoadInitialWeapons(void); static void LoadInitialVehicles(void); static void StreamVehiclesAndPeds(void); static void StreamZoneModels(const CVector &pos); static void RemoveCurrentZonesModels(void); + static void LoadBigBuildingsWhenNeeded(void); static int32 GetCdImageOffset(int32 lastPosn); static int32 GetNextFileOnCd(int32 position, bool priority); @@ -183,6 +200,7 @@ public: static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem); static void LoadScene(const CVector &pos); + static void LoadSceneCollision(const CVector &pos); static void MemoryCardSave(uint8 *buffer, uint32 *length); static void MemoryCardLoad(uint8 *buffer, uint32 length); diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp index b1bcceb6..9076a9a6 100644 --- a/src/core/SurfaceTable.cpp +++ b/src/core/SurfaceTable.cpp @@ -74,7 +74,7 @@ CSurfaceTable::GetAdhesionGroup(uint8 surfaceType) case SURFACE_GIRDER: return ADHESIVE_HARD; case SURFACE_METAL_CHAIN_FENCE: return ADHESIVE_HARD; case SURFACE_PED: return ADHESIVE_RUBBER; - case SURFACE_SAND: return ADHESIVE_LOOSE; + case SURFACE_SAND: return ADHESIVE_SAND; case SURFACE_WATER: return ADHESIVE_WET; case SURFACE_WOOD_CRATES: return ADHESIVE_ROAD; case SURFACE_WOOD_BENCH: return ADHESIVE_ROAD; @@ -89,6 +89,8 @@ CSurfaceTable::GetAdhesionGroup(uint8 surfaceType) case SURFACE_CARDBOARDBOX: return ADHESIVE_LOOSE; case SURFACE_TRANSPARENT_STONE: return ADHESIVE_HARD; case SURFACE_METAL_GATE: return ADHESIVE_HARD; + case SURFACE_SAND_BEACH: return ADHESIVE_SAND; + case SURFACE_CONCRETE_BEACH: return ADHESIVE_ROAD; default: return ADHESIVE_ROAD; } } @@ -108,6 +110,7 @@ CSurfaceTable::GetWetMultiplier(uint8 surfaceType) case SURFACE_HEDGE: case SURFACE_CARDBOARDBOX: case SURFACE_TRANSPARENT_STONE: + case SURFACE_CONCRETE_BEACH: return 1.0f - CWeather::WetRoads*0.25f; case SURFACE_GRASS: @@ -131,6 +134,10 @@ CSurfaceTable::GetWetMultiplier(uint8 surfaceType) case SURFACE_METAL_GATE: return 1.0f - CWeather::WetRoads*0.4f; + case SURFACE_SAND: + case SURFACE_SAND_BEACH: + return 1.0f - CWeather::WetRoads*0.5f; + default: return 1.0f; } diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h index 25b5e57d..d8f9be3d 100644 --- a/src/core/SurfaceTable.h +++ b/src/core/SurfaceTable.h @@ -35,8 +35,6 @@ enum eSurfaceType SURFACE_CARDBOARDBOX, SURFACE_TRANSPARENT_STONE, SURFACE_METAL_GATE, - - // These are illegal SURFACE_SAND_BEACH, SURFACE_CONCRETE_BEACH, }; @@ -47,6 +45,7 @@ enum ADHESIVE_HARD, ADHESIVE_ROAD, ADHESIVE_LOOSE, + ADHESIVE_SAND, ADHESIVE_WET, NUMADHESIVEGROUPS diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp index 1252e2c7..c6a9d368 100644 --- a/src/core/TempColModels.cpp +++ b/src/core/TempColModels.cpp @@ -16,6 +16,7 @@ CColModel CTempColModels::ms_colModelPedGroundHit; CColModel CTempColModels::ms_colModelBoot1; CColModel CTempColModels::ms_colModelDoor1; CColModel CTempColModels::ms_colModelBonnet1; +CColModel CTempColModels::ms_colModelWeapon; CColSphere s_aPedSpheres[3]; @@ -41,13 +42,13 @@ CTempColModels::Initialise(void) int i; - ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0); + ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f)); ms_colModelBBox.level = LEVEL_NONE; for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) { - ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0); + ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f)); ms_colModelCutObj[i].level = LEVEL_NONE; } @@ -69,8 +70,8 @@ CTempColModels::Initialise(void) s_aPedSpheres[i].piece = 0; } - ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0); + ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f)); SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres); // Ped 2 Spheres @@ -88,8 +89,8 @@ CTempColModels::Initialise(void) s_aPed2Spheres[i].piece = 0; } - ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0); + ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f)); SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres); @@ -114,8 +115,8 @@ CTempColModels::Initialise(void) s_aPedGSpheres[2].piece = 0; s_aPedGSpheres[3].piece = 6; - ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0); + ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f)); SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres); @@ -134,8 +135,8 @@ CTempColModels::Initialise(void) s_aDoorSpheres[i].piece = 0; } - ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0); + ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f)); + ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f)); SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres); @@ -154,8 +155,8 @@ CTempColModels::Initialise(void) s_aBumperSpheres[i].piece = 0; } - ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f), SURFACE_DEFAULT, 0); + ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f)); + ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, 0.2f)); SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres); @@ -174,8 +175,8 @@ CTempColModels::Initialise(void) s_aPanelSpheres[i].piece = 0; } - ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0); + ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f)); SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres); @@ -194,8 +195,8 @@ CTempColModels::Initialise(void) s_aBonnetSpheres[i].piece = 0; } - ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f)); + ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres); @@ -214,8 +215,8 @@ CTempColModels::Initialise(void) s_aBootSpheres[i].piece = 0; } - ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f)); + ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres); @@ -236,8 +237,8 @@ CTempColModels::Initialise(void) s_aWheelSpheres[i].piece = 0; } - ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0); + ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f)); SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres); @@ -258,8 +259,8 @@ CTempColModels::Initialise(void) s_aBodyPartSpheres1[i].piece = 0; } - ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0); + ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f)); + ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f)); SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1); @@ -280,10 +281,14 @@ CTempColModels::Initialise(void) s_aBodyPartSpheres2[i].piece = 0; } - ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0); - ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0); + ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f)); + ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f)); SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2); + + ms_colModelWeapon.boundingSphere.Set(0.25f, CVector(0.0f, 0.0f, 0.0f)); + ms_colModelWeapon.boundingBox.Set(CVector(-0.25f, -0.25, -0.25f), CVector(0.25f, 0.25, 0.25f)); + #undef SET_COLMODEL_SPHERES } diff --git a/src/core/TempColModels.h b/src/core/TempColModels.h index 3e1dd5e1..0c936d6f 100644 --- a/src/core/TempColModels.h +++ b/src/core/TempColModels.h @@ -18,6 +18,7 @@ public: static CColModel ms_colModelBoot1; static CColModel ms_colModelDoor1; static CColModel ms_colModelBonnet1; + static CColModel ms_colModelWeapon; static void Initialise(void); }; diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp index ed5580fd..f60adf07 100644 --- a/src/core/Timer.cpp +++ b/src/core/Timer.cpp @@ -7,7 +7,8 @@ #include "Timer.h" uint32 CTimer::m_snTimeInMilliseconds; -uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1; +PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1; + uint32 CTimer::m_snTimeInMillisecondsNonClipped; uint32 CTimer::m_snPreviousTimeInMilliseconds; uint32 CTimer::m_FrameCounter; @@ -33,7 +34,7 @@ RsTimerType suspendPcTimer; uint32 suspendDepth; -#ifdef FIX_BUGS +#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND double frameTime; #endif @@ -97,7 +98,7 @@ void CTimer::Update(void) float updInCyclesScaled = updInCycles * ms_fTimeScale; // We need that real frame time to fix transparent menu bug. -#ifndef FIX_BUGS +#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND double #endif frameTime = updInCyclesScaled / (double)_nCyclesPerMS; @@ -121,7 +122,7 @@ void CTimer::Update(void) RsTimerType updInMs = timer - oldPcTimer; // We need that real frame time to fix transparent menu bug. -#ifndef FIX_BUGS +#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND double #endif frameTime = (double)updInMs * ms_fTimeScale; diff --git a/src/core/Timer.h b/src/core/Timer.h index 4e8b8805..6f100c63 100644 --- a/src/core/Timer.h +++ b/src/core/Timer.h @@ -1,10 +1,16 @@ #pragma once +#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND +#define PauseModeTime double +#else +#define PauseModeTime uint32 +#endif + class CTimer { static uint32 m_snTimeInMilliseconds; - static uint32 m_snTimeInMillisecondsPauseMode; + static PauseModeTime m_snTimeInMillisecondsPauseMode; static uint32 m_snTimeInMillisecondsNonClipped; static uint32 m_snPreviousTimeInMilliseconds; static uint32 m_FrameCounter; @@ -29,7 +35,7 @@ public: static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; } static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; } static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; } - static uint32 GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; } + static PauseModeTime GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; } static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; } static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; } static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; } @@ -63,6 +69,6 @@ public: #endif }; -#ifdef FIX_BUGS +#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND extern double frameTime; #endif diff --git a/src/core/User.cpp b/src/core/User.cpp index f906ae44..56e37ac4 100644 --- a/src/core/User.cpp +++ b/src/core/User.cpp @@ -1,6 +1,6 @@ #include "common.h" - +#include "GameLogic.h" #include "Hud.h" #include "PlayerPed.h" #include "Replay.h" @@ -32,8 +32,8 @@ void CPlaceName::Process() { CVector pos = CWorld::Players[CWorld::PlayerInFocus].GetPos(); - CZone *navigZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_NAVIG); - CZone *defaultZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_DEFAULT); + CZone *navigZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, false, true); + CZone *defaultZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, true, false); if (navigZone == nil) m_pZone = nil; if (defaultZone == nil) m_pZone2 = nil; @@ -99,7 +99,7 @@ void CCurrentVehicle::Display() { wchar *text = nil; - if (m_pCurrentVehicle != nil) + if (m_pCurrentVehicle != nil && m_pCurrentVehicle != CGameLogic::pShortCutTaxi) text = TheText.Get(((CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pCurrentVehicle->GetModelIndex()))->m_gameName); CHud::SetVehicleName(text); } diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp index 7508c9f4..d2623431 100644 --- a/src/core/Wanted.cpp +++ b/src/core/Wanted.cpp @@ -40,6 +40,12 @@ CWanted::Initialise() } bool +CWanted::AreMiamiViceRequired() +{ + return m_nWantedLevel >= 3; +} + +bool CWanted::AreSwatRequired() { return m_nWantedLevel == 4 || m_bSwatRequired; @@ -456,3 +462,10 @@ CWanted::UpdateCrimesQ(void) } } } + +void +CWanted::Suspend(void) +{ + // TODO(MIAMI)! + Reset(); // <- temporary +} diff --git a/src/core/Wanted.h b/src/core/Wanted.h index de36c442..ee72aa47 100644 --- a/src/core/Wanted.h +++ b/src/core/Wanted.h @@ -31,6 +31,7 @@ public: public: void Initialise(); + bool AreMiamiViceRequired(); bool AreSwatRequired(); bool AreFbiRequired(); bool AreArmyRequired(); @@ -48,6 +49,8 @@ public: void UpdateCrimesQ(); void Update(); + void Suspend(); + bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; } static int32 WorkOutPolicePresence(CVector posn, float radius); diff --git a/src/core/World.cpp b/src/core/World.cpp index c3633d77..53d36854 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -50,6 +50,8 @@ bool CWorld::bProcessCutsceneOnly; bool CWorld::bDoingCarCollisions; bool CWorld::bIncludeCarTyres; +CColPoint CWorld::m_aTempColPts[MAX_COLLISION_POINTS]; + void CWorld::Initialise() { @@ -165,7 +167,7 @@ CWorld::CameraToIgnoreThisObject(CEntity *ent) bool CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, - bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects) + bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough) { int x, xstart, xend; int y, ystart, yend; @@ -184,7 +186,7 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi #define LOSARGS \ CColLine(point1, point2), point, dist, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, \ - checkDummies, ignoreSeeThrough, ignoreSomeObjects + checkDummies, ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough if(xstart == xend && ystart == yend) { // Only one sector @@ -266,7 +268,7 @@ CWorld::ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoi bool CWorld::ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, - bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects) + bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough) { float mindist = dist; bool deadPeds = !!bIncludeDeadPeds; @@ -274,39 +276,39 @@ CWorld::ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoin if(checkBuildings) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_BUILDINGS_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); } if(checkVehicles) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_VEHICLES_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); } if(checkPeds) { if(deadPeds) bIncludeDeadPeds = true; ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_PEDS_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); bIncludeDeadPeds = false; } if(checkObjects) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS], line, point, mindist, entity, - ignoreSeeThrough, ignoreSomeObjects); + ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_OBJECTS_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough, ignoreSomeObjects); + ignoreSeeThrough, ignoreSomeObjects, ignoreShootThrough); } if(checkDummies) { ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); ProcessLineOfSightSectorList(sector.m_lists[ENTITYLIST_DUMMIES_OVERLAP], line, point, mindist, entity, - ignoreSeeThrough); + ignoreSeeThrough, false, ignoreShootThrough); } bIncludeDeadPeds = deadPeds; @@ -320,7 +322,7 @@ CWorld::ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoin bool CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, - CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects) + CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough) { bool deadPeds = false; float mindist = dist; @@ -339,31 +341,15 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP if(e->IsPed()) { if(e->bUsesCollision || deadPeds && ((CPed *)e)->m_nPedState == PED_DEAD) { -#ifdef PED_SKIN - if(IsClumpSkinned(e->GetClump())) - colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump()); - else -#endif - if(((CPed *)e)->UseGroundColModel()) - colmodel = &CTempColModels::ms_colModelPedGroundHit; - else -#ifdef ANIMATE_PED_COL_MODEL - colmodel = CPedModelInfo::AnimatePedColModel( - ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex())) - ->GetHitColModel(), - RpClumpGetFrame(e->GetClump())); -#else - colmodel = - ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex())) - ->GetHitColModel(); -#endif + colmodel = ((CPedModelInfo *)CModelInfo::GetModelInfo(e->GetModelIndex()))->AnimatePedColModelSkinned(e->GetClump()); } else colmodel = nil; + } else if(e->bUsesCollision) colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist, - ignoreSeeThrough)) + ignoreSeeThrough, ignoreShootThrough)) entity = e; } } @@ -382,7 +368,11 @@ CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, C { AdvanceCurrentScanCode(); CVector point2(point1.x, point1.y, z2); - return ProcessVerticalLineSector(*GetSector(GetSectorIndexX(point1.x), GetSectorIndexY(point1.y)), + int secX = GetSectorIndexX(point1.x); + int secY = GetSectorIndexY(point1.y); + secX = clamp(secX, 0, NUMSECTORS_X-1); + secY = clamp(secY, 0, NUMSECTORS_Y-1); + return ProcessVerticalLineSector(*GetSector(secX, secY), CColLine(point1, point2), point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly); } @@ -448,7 +438,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist, - ignoreSeeThrough, poly)) + ignoreSeeThrough, false, poly)) entity = e; } } @@ -649,7 +639,7 @@ CWorld::GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bo colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); - if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough)) + if(CCollision::TestLineOfSight(line, e->GetMatrix(), *colmodel, ignoreSeeThrough, false)) return false; } } @@ -920,6 +910,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad bool ignoreSomeObjects) { static CColModel sphereCol; + CColSphere sphere; sphereCol.boundingSphere.center.x = 0.0f; sphereCol.boundingSphere.center.y = 0.0f; @@ -932,7 +923,8 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad sphereCol.boundingBox.max.y = radius; sphereCol.boundingBox.max.z = radius; sphereCol.numSpheres = 1; - sphereCol.spheres = &sphereCol.boundingSphere; + sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f)); + sphereCol.spheres = &sphere; sphereCol.numLines = 0; sphereCol.numBoxes = 0; sphereCol.numTriangles = 0; @@ -1201,7 +1193,7 @@ CWorld::FindObjectsIntersectingCubeSectorList(CPtrList &list, const CVector &vec } void -CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, const CMatrix &matrix, +CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const CMatrix &matrix, const CVector &position, float fStartX, float fStartY, float fEndX, float fEndY, int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, @@ -1261,7 +1253,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co } void -CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CColBox &boundingBox, +CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CBox &boundingBox, const CMatrix &matrix, const CVector &position, int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities) @@ -1823,18 +1815,21 @@ void CWorld::RepositionOneObject(CEntity *pEntity) { int16 modelId = pEntity->GetModelIndex(); - if (IsStreetLight(modelId) || IsTreeModel(modelId) || modelId == MI_PARKINGMETER || - modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || modelId == MI_BIN || modelId == MI_POSTBOX1 || - modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || modelId == MI_DUMP1 || - modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 || - modelId == MI_PHONESIGN || modelId == MI_TAXISIGN || modelId == MI_FISHSTALL01 || - modelId == MI_FISHSTALL02 || modelId == MI_FISHSTALL03 || modelId == MI_FISHSTALL04 || - modelId == MI_BAGELSTAND2 || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT || - modelId == MI_PARKTABLE) { + if (modelId == MI_PARKINGMETER || modelId == MI_PHONEBOOTH1 || modelId == MI_WASTEBIN || + modelId == MI_BIN || modelId == MI_POSTBOX1 || modelId == MI_NEWSSTAND || modelId == MI_TRAFFICCONE || + modelId == MI_DUMP1 || modelId == MI_ROADWORKBARRIER1 || modelId == MI_BUSSIGN1 || modelId == MI_NOPARKINGSIGN1 || + modelId == MI_PHONESIGN || modelId == MI_FIRE_HYDRANT || modelId == MI_BOLLARDLIGHT || + modelId == MI_PARKTABLE || modelId == MI_PARKINGMETER2 || modelId == MI_TELPOLE02 || + modelId == MI_PARKBENCH || modelId == MI_BARRIER1 || IsTreeModel(modelId) || + IsLightThatNeedsRepositioning(modelId) + ) { CVector &position = pEntity->GetMatrix().GetPosition(); - float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z; + CColModel *pColModel = pEntity->GetColModel(); + float fBoundingBoxMinZ = pColModel->boundingBox.min.z; + float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z; + if(fHeight < OBJECT_REPOSITION_OFFSET_Z) fHeight = OBJECT_REPOSITION_OFFSET_Z; position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y, - position.z + OBJECT_REPOSITION_OFFSET_Z, nil) - + position.z + fHeight, nil) - fBoundingBoxMinZ; pEntity->m_matrix.UpdateRW(); pEntity->UpdateRwFrame(); @@ -1921,6 +1916,7 @@ CWorld::Process(void) if(csObj && csObj->m_entryInfoList.first) { if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) { +// TODO(MIAMI): doRender argument RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * (csObj->IsObject() ? CTimer::GetTimeStepNonClipped() @@ -1939,6 +1935,7 @@ CWorld::Process(void) CEntity *movingEnt = (CEntity *)node->item; if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) { +// TODO(MIAMI): doRender argument RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * (movingEnt->IsObject() ? CTimer::GetTimeStepNonClipped() @@ -2041,9 +2038,12 @@ CWorld::Process(void) movingPed->EnteringCar()) { CVehicle *movingCar = movingPed->m_pMyVehicle; if(movingCar) { +#ifdef GTA_TRAIN if(movingCar->IsTrain()) { movingPed->SetPedPositionInTrain(); - } else { + } else +#endif + { switch(movingPed->m_nPedState) { case PED_ENTER_CAR: case PED_CARJACK: movingPed->EnterCar(); break; @@ -2228,4 +2228,60 @@ CWorld::UseDetonator(CEntity *pEntity) pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity); } } + CProjectileInfo::RemoveDetonatorProjectiles(); +} + +bool +CWorld::IsWanderPathClear(CVector const& point1, CVector const& point2, float distance, int maxSteps) +{ + if (Abs(point1.z - point2.z) > distance) + return false; + if (!GetIsLineOfSightClear(point1, point2, true, false, false, false, false, false, false)) + return false; + CVector vecBetween = point2 - point1; + uint32 nSteps = Max(vecBetween.Magnitude(), maxSteps); + if (nSteps == 0) + return true; + vecBetween.Normalise(); + uint32 step = 1; + for (step = 1; step < nSteps; step++) { + CVector posThisStep = point1 + vecBetween * step; + float level; + if (!CWaterLevel::GetWaterLevel(posThisStep, &level, false)) + continue; + posThisStep.z = level; + AdvanceCurrentScanCode(); + + CVector vecCheckedPos(posThisStep.x, posThisStep.y, Max(point1.z, point2.z)); + CColPoint colpoint; + CEntity* entity; + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + } + + CVector posThisStep = point1; + AdvanceCurrentScanCode(); + CVector vecCheckedPos(posThisStep.x, posThisStep.y, point1.z - 5.0f); + + CColPoint colpoint; + CEntity* entity; + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + + float heightNextStep = colpoint.point.z + 0.5f; + for (step = 1; step < nSteps; step++) { + CVector posThisStep = point1 + vecBetween * step; + posThisStep.z = heightNextStep; + AdvanceCurrentScanCode(); + CVector vecCheckedPos(posThisStep.x, posThisStep.y, heightNextStep - 2.0f); + if (!ProcessVerticalLineSector(*GetSector(GetSectorIndexX(posThisStep.x), GetSectorIndexY(posThisStep.y)), + CColLine(posThisStep, vecCheckedPos), colpoint, entity, true, false, false, false, false, false, nil)) + return false; + if (Abs(colpoint.point.z - heightNextStep) > 1.0f) + return false; + heightNextStep = colpoint.point.z + 0.5f; + } + return true; } diff --git a/src/core/World.h b/src/core/World.h index 2bcc4e43..3da774ba 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -4,19 +4,19 @@ #include "Lists.h" #include "PlayerInfo.h" -/* Sectors span from -2000 to 2000 in x and y. - * With 100x100 sectors, each is 40x40 units. */ +/* Sectors span from -2400 to 1600 in x and -2000 to 2000 y. + * With 80x80 sectors, each is 50x50 units. */ -#define SECTOR_SIZE_X (40.0f) -#define SECTOR_SIZE_Y (40.0f) +#define SECTOR_SIZE_X (50.0f) +#define SECTOR_SIZE_Y (50.0f) -#define NUMSECTORS_X (100) -#define NUMSECTORS_Y (100) +#define NUMSECTORS_X (80) +#define NUMSECTORS_Y (80) #define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X) #define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y) -#define WORLD_MIN_X (-2000.0f) +#define WORLD_MIN_X (-2400.0f) #define WORLD_MIN_Y (-2000.0f) #define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X) @@ -71,6 +71,7 @@ public: static bool bProcessCutsceneOnly; static bool bDoingCarCollisions; static bool bIncludeCarTyres; + static CColPoint m_aTempColPts[MAX_COLLISION_POINTS]; static void Remove(CEntity *entity); static void Add(CEntity *entity); @@ -90,9 +91,9 @@ public: static bool CameraToIgnoreThisObject(CEntity *ent); - static bool ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false); - static bool ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false); - static bool ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects = false); + static bool ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false, bool ignoreShootThrough = false); + static bool ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough); + static bool ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects, bool ignoreShootThrough); static bool ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly); static bool ProcessVerticalLineSector(CSector §or, const CColLine &line, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly); static bool ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly); @@ -114,8 +115,8 @@ public: static void FindObjectsKindaCollidingSectorList(CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities); static void FindObjectsIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies); static void FindObjectsIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities); - static void FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool); - static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities); + static void FindObjectsIntersectingAngledCollisionBox(const CBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool); + static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities); static void FindMissionEntitiesIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bVehicles, bool bPeds, bool bObjects); static void FindMissionEntitiesIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bIsVehicleList, bool bIsPedList); @@ -125,6 +126,8 @@ public: static void CallOffChaseForAreaSectorListVehicles(CPtrList& list, float x1, float y1, float x2, float y2, float fStartX, float fStartY, float fEndX, float fEndY); static void CallOffChaseForAreaSectorListPeds(CPtrList& list, float x1, float y1, float x2, float y2); + static bool IsWanderPathClear(CVector const&, CVector const&, float, int); + static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); } static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); } static int GetSectorIndexX(float f) { return (int)GetSectorX(f); } diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp index c376e11f..729cc35d 100644 --- a/src/core/ZoneCull.cpp +++ b/src/core/ZoneCull.cpp @@ -11,207 +11,22 @@ #include "ZoneCull.h" #include "Zones.h" -int32 CCullZones::NumCullZones; -CCullZone CCullZones::aZones[NUMCULLZONES]; int32 CCullZones::NumAttributeZones; CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES]; -uint16 CCullZones::aIndices[NUMZONEINDICES]; -int16 CCullZones::aPointersToBigBuildingsForBuildings[NUMBUILDINGS]; -int16 CCullZones::aPointersToBigBuildingsForTreadables[NUMTREADABLES]; int32 CCullZones::CurrentWantedLevelDrop_Player; int32 CCullZones::CurrentFlags_Camera; int32 CCullZones::CurrentFlags_Player; -int32 CCullZones::OldCullZone; -int32 CCullZones::EntityIndicesUsed; bool CCullZones::bCurrentSubwayIsInvisible; -bool CCullZones::bCullZonesDisabled; - void CCullZones::Init(void) { - int i; - NumAttributeZones = 0; CurrentWantedLevelDrop_Player = 0; CurrentFlags_Camera = 0; CurrentFlags_Player = 0; bCurrentSubwayIsInvisible = false; - NumCullZones = 0; - OldCullZone = -1; - EntityIndicesUsed = 0; - - for(i = 0; i < NUMBUILDINGS; i++) - aPointersToBigBuildingsForBuildings[i] = -1; - for(i = 0; i < NUMTREADABLES; i++) - aPointersToBigBuildingsForTreadables[i] = -1; -} - -bool CCullZone::TestLine(CVector vec1, CVector vec2) -{ - CColPoint colPoint; - CEntity *entity; - - if (CWorld::ProcessLineOfSight(vec1, vec2, colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x + 0.05f, vec1.y, vec1.z), CVector(vec2.x + 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x - 0.05f, vec1.y, vec1.z), CVector(vec2.x - 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y + 0.05f, vec1.z), CVector(vec2.x, vec2.y + 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y - 0.05f, vec1.z), CVector(vec2.x, vec2.y - 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false)) - return true; - if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z + 0.05f), CVector(vec2.x, vec2.y, vec2.z + 0.05f), colPoint, entity, true, false, false, false, false, true, false)) - return true; - return CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z - 0.05f), CVector(vec2.x, vec2.y, vec2.z - 0.05f), colPoint, entity, true, false, false, false, false, true, false); -} - - -uint16* pTempArrayIndices; -int TempEntityIndicesUsed; - -void -CCullZones::ResolveVisibilities(void) -{ - int fd; - - CFileMgr::SetDir(""); - fd = CFileMgr::OpenFile("DATA\\cullzone.dat", "rb"); - if(fd > 0){ - CFileMgr::Read(fd, (char*)&NumCullZones, sizeof(NumCullZones)); - CFileMgr::Read(fd, (char*)aZones, sizeof(aZones)); - CFileMgr::Read(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones)); - CFileMgr::Read(fd, (char*)aAttributeZones, sizeof(aAttributeZones)); - CFileMgr::Read(fd, (char*)aIndices, sizeof(aIndices)); - CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings)); - CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables)); - CFileMgr::CloseFile(fd); - }else{ -#if 0 - // TODO: implement code from mobile to generate data here - EntityIndicesUsed = 0; - BuildListForBigBuildings(); - pTempArrayIndices = new uint16[140000]; - TempEntityIndicesUsed = 0; - - for (int i = 0; i < NumCullZones; i++) { - DoVisibilityTestCullZone(i, true); - } - - CompressIndicesArray(); - delete[] pTempArrayIndices; - - fd = CFileMgr::OpenFileForWriting("data\\cullzone.dat"); - if (fd != 0) { - CFileMgr::Write(fd, (char*)&NumCullZones, sizeof(NumCullZones)); - CFileMgr::Write(fd, (char*)aZones, sizeof(aZones)); - CFileMgr::Write(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones)); - CFileMgr::Write(fd, (char*)&aAttributeZones, sizeof(aAttributeZones)); - CFileMgr::Write(fd, (char*)&aIndices, sizeof(aIndices)); - CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings)); - CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables)); - CFileMgr::CloseFile(fd); - } -#endif - } -} - -void -CCullZones::BuildListForBigBuildings() -{ - for (int i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--) { - CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); - if (building == nil || !building->bIsBIGBuilding) continue; - CSimpleModelInfo *nonlod = (CSimpleModelInfo*)((CSimpleModelInfo *)CModelInfo::GetModelInfo(building->GetModelIndex()))->m_atomics[2]; - if (nonlod == nil) continue; - - for (int j = i; j >= 0; j--) { - CBuilding *building2 = CPools::GetBuildingPool()->GetSlot(j); - if (building2 == nil || building2->bIsBIGBuilding) continue; - if (CModelInfo::GetModelInfo(building2->GetModelIndex()) == nonlod) { - if ((building2->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) { - aPointersToBigBuildingsForBuildings[j] = i; - } - } - } - - for (int j = CPools::GetTreadablePool()->GetSize()-1; j >= 0; j--) { - CTreadable *treadable = CPools::GetTreadablePool()->GetSlot(j); - if (treadable == nil || treadable->bIsBIGBuilding) continue; - if (CModelInfo::GetModelInfo(treadable->GetModelIndex()) == nonlod) { - if ((treadable->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) { - aPointersToBigBuildingsForTreadables[j] = i; - } - } - } - } -} - -void -CCullZones::DoVisibilityTestCullZone(int zoneId, bool doIt) -{ - aZones[zoneId].m_groupIndexCount[0] = 0; - aZones[zoneId].m_groupIndexCount[1] = 0; - aZones[zoneId].m_groupIndexCount[2] = 0; - aZones[zoneId].m_indexStart = TempEntityIndicesUsed; - aZones[zoneId].FindTestPoints(); - - if (!doIt) return; - - for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) { - CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); - if (building != nil && !building->bIsBIGBuilding && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForBuildings[i] != -1)) { - CBuilding *building2 = nil; - if (aPointersToBigBuildingsForBuildings[i] != -1) - building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForBuildings[i]); - - if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) { - pTempArrayIndices[TempEntityIndicesUsed++] = i; - aZones[zoneId].m_groupIndexCount[0]++; - } - } - } - - for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) { - CTreadable* building = CPools::GetTreadablePool()->GetSlot(i); - if (building != nil && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForTreadables[i] != -1)) { - CTreadable* building2 = nil; - if (aPointersToBigBuildingsForTreadables[i] != -1) - building2 = CPools::GetTreadablePool()->GetSlot(aPointersToBigBuildingsForTreadables[i]); - - if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 10.0f, building2)) { - pTempArrayIndices[TempEntityIndicesUsed++] = i; - aZones[zoneId].m_groupIndexCount[1]++; - } - } - } - - for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) { - CTreadable *building = CPools::GetTreadablePool()->GetSlot(i); - if (building != nil && aZones[zoneId].CalcDistToCullZoneSquared(building->GetPosition().x, building->GetPosition().y) < 40000.0f) { - int start = aZones[zoneId].m_groupIndexCount[0] + aZones[zoneId].m_indexStart; - int end = aZones[zoneId].m_groupIndexCount[1] + start; - - bool alreadyAdded = false; - - for (int k = start; k < end; k++) { - if (aIndices[k] == i) - alreadyAdded = true; - } - - if (!alreadyAdded) { - CBuilding *building2 = nil; - if (aPointersToBigBuildingsForTreadables[i] != -1) - building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForTreadables[i]); - if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) { - pTempArrayIndices[TempEntityIndicesUsed++] = i; - aZones[zoneId].m_groupIndexCount[2]++; - } - } - } - } } void @@ -219,14 +34,9 @@ CCullZones::Update(void) { bool invisible; - if(bCullZonesDisabled) - return; - switch(CTimer::GetFrameCounter() & 7){ case 0: case 4: - /* Update Cull zone */ - ForceCullZoneCoors(TheCamera.GetGameCamPosition()); break; case 2: @@ -250,28 +60,6 @@ CCullZones::Update(void) void CCullZones::ForceCullZoneCoors(CVector coors) { - int32 z; - z = FindCullZoneForCoors(coors); - if(z != OldCullZone){ - if(OldCullZone >= 0) - aZones[OldCullZone].DoStuffLeavingZone(); - if(z >= 0) - aZones[z].DoStuffEnteringZone(); - OldCullZone = z; - } -} - -int32 -CCullZones::FindCullZoneForCoors(CVector coors) -{ - int i; - - for(i = 0; i < NumCullZones; i++) - if(coors.x >= aZones[i].minx && coors.x <= aZones[i].maxx && - coors.y >= aZones[i].miny && coors.y <= aZones[i].maxy && - coors.z >= aZones[i].minz && coors.z <= aZones[i].maxz) - return i; - return -1; } int32 @@ -346,219 +134,16 @@ CCullZones::AddCullZone(CVector const &position, float minz, float maxz, uint16 flag, int16 wantedLevel) { - CCullZone *cull; CAttributeZone *attrib; - CVector v; - if((flag & ATTRZONE_NOTCULLZONE) == 0){ - cull = &aZones[NumCullZones++]; - v = position; - // WTF is this? - if((v-CVector(1032.14f, -624.255f, 24.93f)).Magnitude() < 1.0f) - v = CVector(1061.7f, -613.0f, 19.0f); - if((v-CVector(1029.48f, -495.757f, 21.98f)).Magnitude() < 1.0f) - v = CVector(1061.4f, -506.0f, 18.5f); - cull->position.x = clamp(v.x, minx, maxx); - cull->position.y = clamp(v.y, miny, maxy); - cull->position.z = clamp(v.z, minz, maxz); - cull->minx = minx; - cull->maxx = maxx; - cull->miny = miny; - cull->maxy = maxy; - cull->minz = minz; - cull->maxz = maxz; - cull->m_groupIndexCount[0] = 0; - cull->m_groupIndexCount[1] = 0; - cull->m_groupIndexCount[2] = 0; - cull->m_indexStart = 0; - } - if(flag & ~ATTRZONE_NOTCULLZONE){ - attrib = &aAttributeZones[NumAttributeZones++]; - attrib->minx = minx; - attrib->maxx = maxx; - attrib->miny = miny; - attrib->maxy = maxy; - attrib->minz = minz; - attrib->maxz = maxz; - attrib->attributes = flag; - attrib->wantedLevel = wantedLevel; - } -} - - -void -CCullZone::DoStuffLeavingZone(void) -{ - int i; - - for(i = 0; i < m_numBuildings; i++) - DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]); - for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables ; i++) - DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[m_indexStart + i]); -} - -void -CCullZone::DoStuffLeavingZone_OneBuilding(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = false; - bb = CCullZones::aPointersToBigBuildingsForBuildings[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffLeavingZone_OneTreadableBoth(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = false; - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = false; - bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffEnteringZone(void) -{ - int i; - - for(i = 0; i < m_numBuildings; i++) - DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]); - for(; i < m_numBuildings + m_numTreadablesPlus10m; i++) - DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[m_indexStart + i]); - for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables; i++) - DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[m_indexStart + i]); -} - -void -CCullZone::DoStuffEnteringZone_OneBuilding(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = true; - bb = CCullZones::aPointersToBigBuildingsForBuildings[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffEnteringZone_OneTreadablePlus10m(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true; - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = true; - bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[i+j]); - } -} - -void -CCullZone::DoStuffEnteringZone_OneTreadable(uint16 i) -{ - int16 bb; - int j; - - if(i < 6000){ - CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true; - bb = CCullZones::aPointersToBigBuildingsForTreadables[i]; - if(bb != -1) - CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true; - }else{ - i -= 6000; - for(j = 0; j < 3; j++) - DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[i+j]); - } -} - -float -CCullZone::CalcDistToCullZoneSquared(float x, float y) -{ - float rx, ry; - - if (x < minx) rx = sq(x - minx); - else if (x > maxx) rx = sq(x - maxx); - else rx = 0.0f; - - if (y < miny) ry = sq(y - miny); - else if (y > maxy) ry = sq(y - maxy); - else ry = 0.0f; - - return rx + ry; -} - -bool -CCullZone::IsEntityCloseEnoughToZone(CEntity *entity, bool checkLevel) -{ - const CVector &pos = entity->GetPosition(); - - CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(entity->GetModelIndex()); - float distToZone = CalcDistToCullZone(pos.x, pos.y); - float lodDist; - if (minfo->m_isSubway) - lodDist = minfo->GetLargestLodDistance() + 30.0f; - else - lodDist = minfo->GetLargestLodDistance() + 50.0f; - - if (lodDist > distToZone) return true; - if (!checkLevel) return false; - CVector tempPos(minx, miny, minz); - return CTheZones::GetLevelFromPosition(&pos) == CTheZones::GetLevelFromPosition(&tempPos); -} - -bool -CCullZones::DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set) -{ - int32 curCount; - int32 start; - int32 size; - - for (int i = 0; i < NumCullZones; i++) { - curCount = 0; - for (int group = 0; group < 3; group++) { - aZones[i].GetGroupStartAndSize(group, start, size); - - int unk = 0; // TODO: figure out - for (int j = 0; j < size; j++) { - for (int k = 0; k < 3; k++) { - if (set[k] == pTempArrayIndices[start+j]) - unk++; - } - } - if (unk == 3 && ++curCount >= count) - return true; - } - } - return false; + assert(NumAttributeZones < NUMATTRIBZONES); + attrib = &aAttributeZones[NumAttributeZones++]; + attrib->minx = minx; + attrib->maxx = maxx; + attrib->miny = miny; + attrib->maxy = maxy; + attrib->minz = minz; + attrib->maxz = maxz; + attrib->attributes = flag; + attrib->wantedLevel = wantedLevel; } diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h index 9bc07b8c..aae06ca0 100644 --- a/src/core/ZoneCull.h +++ b/src/core/ZoneCull.h @@ -1,57 +1,5 @@ class CEntity; -class CCullZone -{ -public: - CVector position; - float minx; - float maxx; - float miny; - float maxy; - float minz; - float maxz; - - int32 m_indexStart; - int16 m_groupIndexCount[3]; - int16 m_numBuildings; - int16 m_numTreadablesPlus10m; - int16 m_numTreadables; - - void DoStuffLeavingZone(void); - static void DoStuffLeavingZone_OneBuilding(uint16 i); - static void DoStuffLeavingZone_OneTreadableBoth(uint16 i); - void DoStuffEnteringZone(void); - static void DoStuffEnteringZone_OneBuilding(uint16 i); - static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i); - static void DoStuffEnteringZone_OneTreadable(uint16 i); - - - static bool TestLine(CVector a1, CVector a2); - float CalcDistToCullZoneSquared(float x, float y); - float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); }; - bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel); - - void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) { - switch (groupid) { - case 1: - start = m_groupIndexCount[0] + m_indexStart; - size = m_groupIndexCount[1]; - break; - case 2: - start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart; - size = m_groupIndexCount[2]; - break; - default: - start = m_indexStart; - size = m_groupIndexCount[0]; - break; - } - } - - void FindTestPoints() {}; // todo - bool TestEntityVisibilityFromCullZone(CEntity*, float, CEntity*) { return false; }; // todo -}; - enum eZoneAttribs { ATTRZONE_CAMCLOSEIN = 1, @@ -62,6 +10,8 @@ enum eZoneAttribs ATTRZONE_NOTCULLZONE = 0x20, ATTRZONE_DOINEEDCOLLISION = 0x40, ATTRZONE_SUBWAYVISIBLE = 0x80, + + ATTRZONE_WATERFUDGE = 0x400, }; struct CAttributeZone @@ -79,27 +29,17 @@ struct CAttributeZone class CCullZones { public: - static int32 NumCullZones; - static CCullZone aZones[NUMCULLZONES]; static int32 NumAttributeZones; static CAttributeZone aAttributeZones[NUMATTRIBZONES]; - static uint16 aIndices[NUMZONEINDICES]; - static int16 aPointersToBigBuildingsForBuildings[NUMBUILDINGS]; - static int16 aPointersToBigBuildingsForTreadables[NUMTREADABLES]; static int32 CurrentWantedLevelDrop_Player; static int32 CurrentFlags_Camera; static int32 CurrentFlags_Player; - static int32 OldCullZone; - static int32 EntityIndicesUsed; static bool bCurrentSubwayIsInvisible; - static bool bCullZonesDisabled; static void Init(void); - static void ResolveVisibilities(void); static void Update(void); static void ForceCullZoneCoors(CVector coors); - static int32 FindCullZoneForCoors(CVector coors); static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel); static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void); static void MarkSubwayAsInvisible(bool visible); @@ -115,11 +55,9 @@ public: static bool DoINeedToLoadCollision(void) { return (CurrentFlags_Player & ATTRZONE_DOINEEDCOLLISION) != 0; } static bool PlayerNoRain(void) { return (CurrentFlags_Player & ATTRZONE_NORAIN) != 0; } static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; } + static bool WaterFudge(void) { return (CurrentFlags_Camera & ATTRZONE_WATERFUDGE) != 0; } static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; } - static void BuildListForBigBuildings(); - static void DoVisibilityTestCullZone(int zoneId, bool doIt); - static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set); - - static void CompressIndicesArray() {};// todo + //--MIAMI: TODO + static bool PoliceAbandonCars(void) { return false; } }; diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 4f491a49..84b5ca29 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -9,133 +9,138 @@ #include "World.h" eLevelName CTheZones::m_CurrLevel; -CZone *CTheZones::m_pPlayersZone; int16 CTheZones::FindIndex; uint16 CTheZones::NumberOfAudioZones; int16 CTheZones::AudioZoneArray[NUMAUDIOZONES]; uint16 CTheZones::TotalNumberOfMapZones; -uint16 CTheZones::TotalNumberOfZones; -CZone CTheZones::ZoneArray[NUMZONES]; +uint16 CTheZones::TotalNumberOfInfoZones; +uint16 CTheZones::TotalNumberOfNavigationZones; +CZone CTheZones::InfoZoneArray[NUMINFOZONES]; CZone CTheZones::MapZoneArray[NUMMAPZONES]; +CZone CTheZones::NavigationZoneArray[NUMNAVIGZONES]; uint16 CTheZones::TotalNumberOfZoneInfos; -CZoneInfo CTheZones::ZoneInfoArray[2*NUMZONES]; +CZoneInfo CTheZones::ZoneInfoArray[2*NUMINFOZONES]; -#define SWAPF(a, b) { float t; t = a; a = b; b = t; } - -inline bool IsNormalZone(int type) { return type == ZONE_DEFAULT || type == ZONE_NAVIG || type == ZONE_INFO; } -static void -CheckZoneInfo(CZoneInfo *info) -{ - assert(info->carThreshold[0] >= 0); - assert(info->carThreshold[0] <= info->carThreshold[1]); - assert(info->carThreshold[1] <= info->carThreshold[2]); - assert(info->carThreshold[2] <= info->carThreshold[3]); - assert(info->carThreshold[3] <= info->carThreshold[4]); - assert(info->carThreshold[4] <= info->carThreshold[5]); - assert(info->carThreshold[5] <= info->copThreshold); - assert(info->copThreshold <= info->gangThreshold[0]); - assert(info->gangThreshold[0] <= info->gangThreshold[1]); - assert(info->gangThreshold[1] <= info->gangThreshold[2]); - assert(info->gangThreshold[2] <= info->gangThreshold[3]); - assert(info->gangThreshold[3] <= info->gangThreshold[4]); - assert(info->gangThreshold[4] <= info->gangThreshold[5]); - assert(info->gangThreshold[5] <= info->gangThreshold[6]); - assert(info->gangThreshold[6] <= info->gangThreshold[7]); - assert(info->gangThreshold[7] <= info->gangThreshold[8]); -} +#define SWAPF(a, b) { float t; t = a; a = b; b = t; } +//--MIAMI: done wchar* CZone::GetTranslatedName(void) { return TheText.Get(name); } +//--MIAMI: done void CTheZones::Init(void) { - int i; + int i, j; for(i = 0; i < NUMAUDIOZONES; i++) AudioZoneArray[i] = -1; NumberOfAudioZones = 0; - for(i = 0; i < NUMZONES; i++) - memset(&ZoneArray[i], 0, sizeof(CZone)); - - CZoneInfo *zonei; - int x = 1000/6; - for(i = 0; i < 2*NUMZONES; i++){ - zonei = &ZoneInfoArray[i]; - zonei->carDensity = 10; - zonei->carThreshold[0] = x; - zonei->carThreshold[1] = zonei->carThreshold[0] + x; - zonei->carThreshold[2] = zonei->carThreshold[1] + x; - zonei->carThreshold[3] = zonei->carThreshold[2] + x; - zonei->carThreshold[4] = zonei->carThreshold[3]; - zonei->carThreshold[5] = zonei->carThreshold[4]; - zonei->copThreshold = zonei->carThreshold[5] + x; - zonei->gangThreshold[0] = zonei->copThreshold; - zonei->gangThreshold[1] = zonei->gangThreshold[0]; - zonei->gangThreshold[2] = zonei->gangThreshold[1]; - zonei->gangThreshold[3] = zonei->gangThreshold[2]; - zonei->gangThreshold[4] = zonei->gangThreshold[3]; - zonei->gangThreshold[5] = zonei->gangThreshold[4]; - zonei->gangThreshold[6] = zonei->gangThreshold[5]; - zonei->gangThreshold[7] = zonei->gangThreshold[6]; - zonei->gangThreshold[8] = zonei->gangThreshold[7]; - CheckZoneInfo(zonei); + for(i = 0; i < NUMNAVIGZONES; i++) + memset(&NavigationZoneArray[i], 0, sizeof(CZone)); + + for(i = 0; i < NUMINFOZONES; i++) + memset(&InfoZoneArray[i], 0, sizeof(CZone)); + + int x = 1000/9; + for(i = 0; i < 2*NUMINFOZONES; i++){ + // Cars + + ZoneInfoArray[i].carDensity = 10; + ZoneInfoArray[i].carThreshold[0] = x; + ZoneInfoArray[i].carThreshold[1] = ZoneInfoArray[i].carThreshold[0] + x; + ZoneInfoArray[i].carThreshold[2] = ZoneInfoArray[i].carThreshold[1] + x; + ZoneInfoArray[i].carThreshold[3] = ZoneInfoArray[i].carThreshold[2] + x; + ZoneInfoArray[i].carThreshold[4] = ZoneInfoArray[i].carThreshold[3] + x; + ZoneInfoArray[i].carThreshold[5] = ZoneInfoArray[i].carThreshold[4] + x; + ZoneInfoArray[i].carThreshold[6] = ZoneInfoArray[i].carThreshold[5] + x; + ZoneInfoArray[i].carThreshold[7] = ZoneInfoArray[i].carThreshold[6] + x; + ZoneInfoArray[i].carThreshold[8] = 1000; + + ZoneInfoArray[i].boatThreshold[0] = 500; + ZoneInfoArray[i].boatThreshold[1] = 1000; + + // What's going on here? this looks more like density + ZoneInfoArray[i].copThreshold = 50; + for(j = 0; j < NUM_GANGS; j++) + ZoneInfoArray[i].gangThreshold[j] = ZoneInfoArray[i].copThreshold; + + // Peds + + ZoneInfoArray[i].pedDensity = 12; + + // What's going on here? this looks more like density + ZoneInfoArray[i].copPedThreshold = 50; + for(j = 0; j < NUM_GANGS; j++) + ZoneInfoArray[i].gangPedThreshold[j] = ZoneInfoArray[i].copPedThreshold; + + ZoneInfoArray[i].pedGroup = 0; } TotalNumberOfZoneInfos = 1; // why 1? - TotalNumberOfZones = 1; + TotalNumberOfNavigationZones = 1; + TotalNumberOfInfoZones = 1; + + strcpy(InfoZoneArray[0].name, "CITYINF"); + InfoZoneArray[0].minx = -2400.0f; + InfoZoneArray[0].miny = -2000.0f; + InfoZoneArray[0].minz = -500.0f; + InfoZoneArray[0].maxx = 1600.0f; + InfoZoneArray[0].maxy = 2000.0f; + InfoZoneArray[0].maxz = 500.0f; + InfoZoneArray[0].level = LEVEL_NONE; + InfoZoneArray[0].type = ZONE_INFO; + + strcpy(NavigationZoneArray[0].name, "VICE_C"); + NavigationZoneArray[0].minx = -2400.0f; + NavigationZoneArray[0].miny = -2000.0f; + NavigationZoneArray[0].minz = -500.0f; + NavigationZoneArray[0].maxx = 1600.0f; + NavigationZoneArray[0].maxy = 2000.0f; + NavigationZoneArray[0].maxz = 500.0f; + NavigationZoneArray[0].level = LEVEL_NONE; + NavigationZoneArray[0].type = ZONE_NAVIG; m_CurrLevel = LEVEL_NONE; - m_pPlayersZone = &ZoneArray[0]; - - strcpy(ZoneArray[0].name, "CITYZON"); - ZoneArray[0].minx = -4000.0f; - ZoneArray[0].miny = -4000.0f; - ZoneArray[0].minz = -500.0f; - ZoneArray[0].maxx = 4000.0f; - ZoneArray[0].maxy = 4000.0f; - ZoneArray[0].maxz = 500.0f; - ZoneArray[0].level = LEVEL_NONE; for(i = 0; i < NUMMAPZONES; i++){ memset(&MapZoneArray[i], 0, sizeof(CZone)); MapZoneArray[i].type = ZONE_MAPZONE; } - TotalNumberOfMapZones = 1; - strcpy(MapZoneArray[0].name, "THEMAP"); - MapZoneArray[0].minx = -4000.0f; - MapZoneArray[0].miny = -4000.0f; + MapZoneArray[0].minx = -2400.0f; + MapZoneArray[0].miny = -2000.0f; MapZoneArray[0].minz = -500.0f; - MapZoneArray[0].maxx = 4000.0f; - MapZoneArray[0].maxy = 4000.0f; + MapZoneArray[0].maxx = 1600.0f; + MapZoneArray[0].maxy = 2000.0f; MapZoneArray[0].maxz = 500.0f; MapZoneArray[0].level = LEVEL_NONE; } +//--MIAMI: done void CTheZones::Update(void) { CVector pos; pos = FindPlayerCoors(); - m_pPlayersZone = FindSmallestZonePosition(&pos); m_CurrLevel = GetLevelFromPosition(&pos); } +//--MIAMI: done void CTheZones::CreateZone(char *name, eZoneType type, float minx, float miny, float minz, float maxx, float maxy, float maxz, eLevelName level) { + char tmpname[24]; char *p; - char tmpname[8]; if(minx > maxx) SWAPF(minx, maxx); if(miny > maxy) SWAPF(miny, maxy); @@ -144,73 +149,94 @@ CTheZones::CreateZone(char *name, eZoneType type, // make upper case for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p); - // add zone strncpy(tmpname, name, 7); tmpname[7] = '\0'; - strcpy(ZoneArray[TotalNumberOfZones].name, tmpname); - ZoneArray[TotalNumberOfZones].type = type; - ZoneArray[TotalNumberOfZones].minx = minx; - ZoneArray[TotalNumberOfZones].miny = miny; - ZoneArray[TotalNumberOfZones].minz = minz; - ZoneArray[TotalNumberOfZones].maxx = maxx; - ZoneArray[TotalNumberOfZones].maxy = maxy; - ZoneArray[TotalNumberOfZones].maxz = maxz; - ZoneArray[TotalNumberOfZones].level = level; - if(IsNormalZone(type)){ - ZoneArray[TotalNumberOfZones].zoneinfoDay = TotalNumberOfZoneInfos++; - ZoneArray[TotalNumberOfZones].zoneinfoNight = TotalNumberOfZoneInfos++; - } - TotalNumberOfZones++; -} - -void -CTheZones::CreateMapZone(char *name, eZoneType type, - float minx, float miny, float minz, - float maxx, float maxy, float maxz, - eLevelName level) -{ - CZone *zone; - char *p; - - if(minx > maxx) SWAPF(minx, maxx); - if(miny > maxy) SWAPF(miny, maxy); - if(minz > maxz) SWAPF(minz, maxz); - - // make upper case - for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p); // add zone - zone = &MapZoneArray[TotalNumberOfMapZones++]; - strncpy(zone->name, name, 7); - zone->name[7] = '\0'; - zone->type = type; - zone->minx = minx; - zone->miny = miny; - zone->minz = minz; - zone->maxx = maxx; - zone->maxy = maxy; - zone->maxz = maxz; - zone->level = level; + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + assert(TotalNumberOfNavigationZones < NUMNAVIGZONES); + strcpy(NavigationZoneArray[TotalNumberOfNavigationZones].name, tmpname); + NavigationZoneArray[TotalNumberOfNavigationZones].type = type; + NavigationZoneArray[TotalNumberOfNavigationZones].minx = minx; + NavigationZoneArray[TotalNumberOfNavigationZones].miny = miny; + NavigationZoneArray[TotalNumberOfNavigationZones].minz = minz; + NavigationZoneArray[TotalNumberOfNavigationZones].maxx = maxx; + NavigationZoneArray[TotalNumberOfNavigationZones].maxy = maxy; + NavigationZoneArray[TotalNumberOfNavigationZones].maxz = maxz; + NavigationZoneArray[TotalNumberOfNavigationZones].level = level; + TotalNumberOfNavigationZones++; + break; + case ZONE_INFO: + assert(TotalNumberOfInfoZones < NUMINFOZONES); + strcpy(InfoZoneArray[TotalNumberOfInfoZones].name, tmpname); + InfoZoneArray[TotalNumberOfInfoZones].type = type; + InfoZoneArray[TotalNumberOfInfoZones].minx = minx; + InfoZoneArray[TotalNumberOfInfoZones].miny = miny; + InfoZoneArray[TotalNumberOfInfoZones].minz = minz; + InfoZoneArray[TotalNumberOfInfoZones].maxx = maxx; + InfoZoneArray[TotalNumberOfInfoZones].maxy = maxy; + InfoZoneArray[TotalNumberOfInfoZones].maxz = maxz; + InfoZoneArray[TotalNumberOfInfoZones].level = level; + InfoZoneArray[TotalNumberOfInfoZones].zoneinfoDay = TotalNumberOfZoneInfos++; + InfoZoneArray[TotalNumberOfInfoZones].zoneinfoNight = TotalNumberOfZoneInfos++; + TotalNumberOfInfoZones++; + break; + case ZONE_MAPZONE: + assert(TotalNumberOfMapZones < NUMMAPZONES); + strcpy(MapZoneArray[TotalNumberOfMapZones].name, tmpname); + MapZoneArray[TotalNumberOfMapZones].type = type; + MapZoneArray[TotalNumberOfMapZones].minx = minx; + MapZoneArray[TotalNumberOfMapZones].miny = miny; + MapZoneArray[TotalNumberOfMapZones].minz = minz; + MapZoneArray[TotalNumberOfMapZones].maxx = maxx; + MapZoneArray[TotalNumberOfMapZones].maxy = maxy; + MapZoneArray[TotalNumberOfMapZones].maxz = maxz; + MapZoneArray[TotalNumberOfMapZones].level = level; + TotalNumberOfMapZones++; + break; + } } +//--MIAMI: done void CTheZones::PostZoneCreation(void) { int i; - for(i = 1; i < TotalNumberOfZones; i++) - InsertZoneIntoZoneHierarchy(&ZoneArray[i]); + for(i = 1; i < TotalNumberOfNavigationZones; i++) + InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]); InitialiseAudioZoneArray(); } +//--MIAMI: done, but does nothing +void +CTheZones::CheckZonesForOverlap(void) +{ + int i, j; + char str[116]; + + for(i = 1; i < TotalNumberOfInfoZones; i++){ + ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[0]); + + for(j = 1; j < TotalNumberOfInfoZones; j++) + if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j])) + sprintf(str, "Info zone %s contains %s\n", + &InfoZoneArray[j].name, &InfoZoneArray[i].name); + } +} + +//--MIAMI: done void CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone) { zone->child = nil; zone->parent = nil; zone->next = nil; - InsertZoneIntoZoneHierRecursive(zone, &ZoneArray[0]); + InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]); } +//--MIAMI: done bool CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer) { @@ -254,6 +280,7 @@ CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer) return true; } +//--MIAMI: done bool CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer) { @@ -278,6 +305,7 @@ CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer) return true; } +//--MIAMI: done bool CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone) { @@ -286,6 +314,7 @@ CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone) zone->minz <= v->z && v->z <= zone->maxz; } +//--MIAMI: done eLevelName CTheZones::GetLevelFromPosition(CVector const *v) { @@ -299,35 +328,35 @@ CTheZones::GetLevelFromPosition(CVector const *v) return MapZoneArray[0].level; } +//--MIAMI: done CZone* -CTheZones::FindSmallestZonePosition(const CVector *v) +CTheZones::FindInformationZoneForPosition(const CVector *v) { - CZone *best = &ZoneArray[0]; - // zone to test next - CZone *zone = ZoneArray[0].child; - while(zone) - // if in zone, descent into children - if(PointLiesWithinZone(v, zone)){ - best = zone; - zone = zone->child; - // otherwise try next zone - }else - zone = zone->next; - return best; + int i; +// char tmp[116]; +// if(!PointLiesWithinZone(v, &InfoZoneArray[0])) +// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z); + for(i = 1; i < TotalNumberOfInfoZones; i++) + if(PointLiesWithinZone(v, &InfoZoneArray[i])) + return &InfoZoneArray[i]; + return &InfoZoneArray[0]; } +//--MIAMI: done CZone* -CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type) +CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig) { CZone *best = nil; - if(ZoneArray[0].type == type) - best = &ZoneArray[0]; + if(findDefault && NavigationZoneArray[0].type == ZONE_DEFAULT || + findNavig && NavigationZoneArray[0].type == ZONE_NAVIG) + best = &NavigationZoneArray[0]; // zone to test next - CZone *zone = ZoneArray[0].child; + CZone *zone = NavigationZoneArray[0].child; while(zone) // if in zone, descent into children if(PointLiesWithinZone(v, zone)){ - if(zone->type == type) + if(findDefault && zone->type == ZONE_DEFAULT || + findNavig && zone->type == ZONE_NAVIG) best = zone; zone = zone->child; // otherwise try next zone @@ -336,43 +365,73 @@ CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type) return best; } -CZone* -CTheZones::FindSmallestZonePositionILN(const CVector *v) +//--MIAMI: done +int16 +CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type) { - CZone *best = nil; - if(IsNormalZone(ZoneArray[0].type)) - best = &ZoneArray[0]; - // zone to test next - CZone *zone = ZoneArray[0].child; - while(zone) - // if in zone, descent into children - if(PointLiesWithinZone(v, zone)){ - if(IsNormalZone(zone->type)) - best = zone; - zone = zone->child; - // otherwise try next zone - }else - zone = zone->next; - return best; + char str[8]; + memset(str, 0, 8); + strncpy(str, name, 8); + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + for(FindIndex = 0; FindIndex < TotalNumberOfNavigationZones; FindIndex++) + if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_INFO: + for(FindIndex = 0; FindIndex < TotalNumberOfInfoZones; FindIndex++) + if(strcmp(GetInfoZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_MAPZONE: + for(FindIndex = 0; FindIndex < TotalNumberOfMapZones; FindIndex++) + if(strcmp(GetMapZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + } + return -1; } +//--MIAMI: done int16 -CTheZones::FindZoneByLabelAndReturnIndex(Const char *name) +CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type) { char str[8]; + ++FindIndex; memset(str, 0, 8); strncpy(str, name, 8); - for(FindIndex = 0; FindIndex < TotalNumberOfZones; FindIndex++) - if(strcmp(GetZone(FindIndex)->name, name) == 0) - return FindIndex; + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + for(; FindIndex < TotalNumberOfNavigationZones; FindIndex++) + if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_INFO: + for(; FindIndex < TotalNumberOfInfoZones; FindIndex++) + if(strcmp(GetInfoZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_MAPZONE: + for(; FindIndex < TotalNumberOfMapZones; FindIndex++) + if(strcmp(GetMapZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + } return -1; } +//--MIAMI: done CZoneInfo* CTheZones::GetZoneInfo(const CVector *v, uint8 day) { CZone *zone; - zone = FindSmallestZonePositionILN(v); + zone = FindInformationZoneForPosition(v); if(zone == nil) return &ZoneInfoArray[0]; return &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; @@ -383,6 +442,7 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info) { CZoneInfo *day, *night; float d, n; + int i; day = GetZoneInfo(pos, 1); night = GetZoneInfo(pos, 0); @@ -402,109 +462,60 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info) n = 1.0f - d; } info->carDensity = day->carDensity * d + night->carDensity * n; - info->carThreshold[0] = day->carThreshold[0] * d + night->carThreshold[0] * n; - info->carThreshold[1] = day->carThreshold[1] * d + night->carThreshold[1] * n; - info->carThreshold[2] = day->carThreshold[2] * d + night->carThreshold[2] * n; - info->carThreshold[3] = day->carThreshold[3] * d + night->carThreshold[3] * n; - info->carThreshold[4] = day->carThreshold[4] * d + night->carThreshold[4] * n; - info->carThreshold[5] = day->carThreshold[5] * d + night->carThreshold[5] * n; - info->copThreshold = day->copThreshold * d + night->copThreshold * n; - info->gangThreshold[0] = day->gangThreshold[0] * d + night->gangThreshold[0] * n; - info->gangThreshold[1] = day->gangThreshold[1] * d + night->gangThreshold[1] * n; - info->gangThreshold[2] = day->gangThreshold[2] * d + night->gangThreshold[2] * n; - info->gangThreshold[3] = day->gangThreshold[3] * d + night->gangThreshold[3] * n; - info->gangThreshold[4] = day->gangThreshold[4] * d + night->gangThreshold[4] * n; - info->gangThreshold[5] = day->gangThreshold[5] * d + night->gangThreshold[5] * n; - info->gangThreshold[6] = day->gangThreshold[6] * d + night->gangThreshold[6] * n; - info->gangThreshold[7] = day->gangThreshold[7] * d + night->gangThreshold[7] * n; - info->gangThreshold[8] = day->gangThreshold[8] * d + night->gangThreshold[8] * n; + for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++) + info->carThreshold[i] = day->carThreshold[i] * d + night->carThreshold[i] * n; + for(i = 0; i < ARRAY_SIZE(info->boatThreshold); i++) + info->boatThreshold[i] = day->boatThreshold[i] * d + night->boatThreshold[i] * n; + for(i = 0; i < ARRAY_SIZE(info->gangThreshold); i++) + info->gangThreshold[i] = day->gangThreshold[i] * d + night->gangThreshold[i] * n; + info->copThreshold = day->copThreshold * d + night->copThreshold * n; info->pedDensity = day->pedDensity * d + night->pedDensity * n; - info->copDensity = day->copDensity * d + night->copDensity * n; - info->gangDensity[0] = day->gangDensity[0] * d + night->gangDensity[0] * n; - info->gangDensity[1] = day->gangDensity[1] * d + night->gangDensity[1] * n; - info->gangDensity[2] = day->gangDensity[2] * d + night->gangDensity[2] * n; - info->gangDensity[3] = day->gangDensity[3] * d + night->gangDensity[3] * n; - info->gangDensity[4] = day->gangDensity[4] * d + night->gangDensity[4] * n; - info->gangDensity[5] = day->gangDensity[5] * d + night->gangDensity[5] * n; - info->gangDensity[6] = day->gangDensity[6] * d + night->gangDensity[6] * n; - info->gangDensity[7] = day->gangDensity[7] * d + night->gangDensity[7] * n; - info->gangDensity[8] = day->gangDensity[8] * d + night->gangDensity[8] * n; + info->copPedThreshold = day->copPedThreshold * d + night->copPedThreshold * n; + for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++) + info->gangPedThreshold[i] = day->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n; } if(CClock::GetIsTimeInRange(5, 19)) info->pedGroup = day->pedGroup; else info->pedGroup = night->pedGroup; - - CheckZoneInfo(info); } void CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity, - int16 gang0Num, int16 gang1Num, int16 gang2Num, - int16 gang3Num, int16 gang4Num, int16 gang5Num, - int16 gang6Num, int16 gang7Num, int16 gang8Num, - int16 copNum, - int16 car0Num, int16 car1Num, int16 car2Num, - int16 car3Num, int16 car4Num, int16 car5Num) + int16 copCarDensity, const int16 *gangCarDensities) { CZone *zone; CZoneInfo *info; - zone = GetZone(zoneid); + zone = GetInfoZone(zoneid); info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; - CheckZoneInfo(info); - - if(carDensity != -1) info->carDensity = carDensity; - int16 oldCar1Num = info->carThreshold[1] - info->carThreshold[0]; - int16 oldCar2Num = info->carThreshold[2] - info->carThreshold[1]; - int16 oldCar3Num = info->carThreshold[3] - info->carThreshold[2]; - int16 oldCar4Num = info->carThreshold[4] - info->carThreshold[3]; - int16 oldCar5Num = info->carThreshold[5] - info->carThreshold[4]; - int16 oldCopNum = info->copThreshold - info->carThreshold[5]; - int16 oldGang0Num = info->gangThreshold[0] - info->copThreshold; - int16 oldGang1Num = info->gangThreshold[1] - info->gangThreshold[0]; - int16 oldGang2Num = info->gangThreshold[2] - info->gangThreshold[1]; - int16 oldGang3Num = info->gangThreshold[3] - info->gangThreshold[2]; - int16 oldGang4Num = info->gangThreshold[4] - info->gangThreshold[3]; - int16 oldGang5Num = info->gangThreshold[5] - info->gangThreshold[4]; - int16 oldGang6Num = info->gangThreshold[6] - info->gangThreshold[5]; - int16 oldGang7Num = info->gangThreshold[7] - info->gangThreshold[6]; - int16 oldGang8Num = info->gangThreshold[8] - info->gangThreshold[7]; - - if(car0Num != -1) info->carThreshold[0] = car0Num; - if(car1Num != -1) info->carThreshold[1] = info->carThreshold[0] + car1Num; - else info->carThreshold[1] = info->carThreshold[0] + oldCar1Num; - if(car2Num != -1) info->carThreshold[2] = info->carThreshold[1] + car2Num; - else info->carThreshold[2] = info->carThreshold[1] + oldCar2Num; - if(car3Num != -1) info->carThreshold[3] = info->carThreshold[2] + car3Num; - else info->carThreshold[3] = info->carThreshold[2] + oldCar3Num; - if(car4Num != -1) info->carThreshold[4] = info->carThreshold[3] + car4Num; - else info->carThreshold[4] = info->carThreshold[3] + oldCar4Num; - if(car5Num != -1) info->carThreshold[5] = info->carThreshold[4] + car5Num; - else info->carThreshold[5] = info->carThreshold[4] + oldCar5Num; - if(copNum != -1) info->copThreshold = info->carThreshold[5] + copNum; - else info->copThreshold = info->carThreshold[5] + oldCopNum; - if(gang0Num != -1) info->gangThreshold[0] = info->copThreshold + gang0Num; - else info->gangThreshold[0] = info->copThreshold + oldGang0Num; - if(gang1Num != -1) info->gangThreshold[1] = info->gangThreshold[0] + gang1Num; - else info->gangThreshold[1] = info->gangThreshold[0] + oldGang1Num; - if(gang2Num != -1) info->gangThreshold[2] = info->gangThreshold[1] + gang2Num; - else info->gangThreshold[2] = info->gangThreshold[1] + oldGang2Num; - if(gang3Num != -1) info->gangThreshold[3] = info->gangThreshold[2] + gang3Num; - else info->gangThreshold[3] = info->gangThreshold[2] + oldGang3Num; - if(gang4Num != -1) info->gangThreshold[4] = info->gangThreshold[3] + gang4Num; - else info->gangThreshold[4] = info->gangThreshold[3] + oldGang4Num; - if(gang5Num != -1) info->gangThreshold[5] = info->gangThreshold[4] + gang5Num; - else info->gangThreshold[5] = info->gangThreshold[4] + oldGang5Num; - if(gang6Num != -1) info->gangThreshold[6] = info->gangThreshold[5] + gang6Num; - else info->gangThreshold[6] = info->gangThreshold[5] + oldGang6Num; - if(gang7Num != -1) info->gangThreshold[7] = info->gangThreshold[6] + gang7Num; - else info->gangThreshold[7] = info->gangThreshold[6] + oldGang7Num; - if(gang8Num != -1) info->gangThreshold[8] = info->gangThreshold[7] + gang8Num; - else info->gangThreshold[8] = info->gangThreshold[7] + oldGang8Num; - - CheckZoneInfo(info); + info->carDensity = carDensity; + info->copThreshold = copCarDensity; + info->gangThreshold[0] = gangCarDensities[0] + copCarDensity; + info->gangThreshold[1] = gangCarDensities[1] + info->gangThreshold[0]; + info->gangThreshold[2] = gangCarDensities[2] + info->gangThreshold[1]; + info->gangThreshold[3] = gangCarDensities[3] + info->gangThreshold[2]; + info->gangThreshold[4] = gangCarDensities[4] + info->gangThreshold[3]; + info->gangThreshold[5] = gangCarDensities[5] + info->gangThreshold[4]; + info->gangThreshold[6] = gangCarDensities[6] + info->gangThreshold[5]; + info->gangThreshold[7] = gangCarDensities[7] + info->gangThreshold[6]; + info->gangThreshold[8] = gangCarDensities[8] + info->gangThreshold[7]; +} + +void CTheZones::SetZoneCivilianCarInfo(uint16 zoneid, uint8 day, + const int16* carDensities, const int16* boatDensities) +{ + CZone* zone; + CZoneInfo* info; + zone = GetInfoZone(zoneid); + info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; + info->carThreshold[0] = carDensities[0]; + for (int i = 1; i < CCarCtrl::NUM_CAR_CLASSES; i++) + info->carThreshold[i] = carDensities[i] + info->carThreshold[i-1]; + info->boatThreshold[0] = boatDensities[0]; + for (int i = 1; i < CCarCtrl::NUM_BOAT_CLASSES; i++) + info->boatThreshold[i] = boatDensities[i] + info->boatThreshold[i - 1]; } void @@ -515,48 +526,59 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity, { CZone *zone; CZoneInfo *info; - zone = GetZone(zoneid); + zone = GetInfoZone(zoneid); info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; - if(pedDensity != -1) info->pedDensity = pedDensity; - if(copDensity != -1) info->copDensity = copDensity; - if(gang0Density != -1) info->gangDensity[0] = gang0Density; - if(gang1Density != -1) info->gangDensity[1] = gang1Density; - if(gang2Density != -1) info->gangDensity[2] = gang2Density; - if(gang3Density != -1) info->gangDensity[3] = gang3Density; - if(gang4Density != -1) info->gangDensity[4] = gang4Density; - if(gang5Density != -1) info->gangDensity[5] = gang5Density; - if(gang6Density != -1) info->gangDensity[6] = gang6Density; - if(gang7Density != -1) info->gangDensity[7] = gang7Density; - if(gang8Density != -1) info->gangDensity[8] = gang8Density; + info->pedDensity = pedDensity; + info->copPedThreshold = copDensity; + info->gangPedThreshold[0] = gang0Density; + info->gangPedThreshold[1] = gang1Density; + info->gangPedThreshold[2] = gang2Density; + info->gangPedThreshold[3] = gang3Density; + info->gangPedThreshold[4] = gang4Density; + info->gangPedThreshold[5] = gang5Density; + info->gangPedThreshold[6] = gang6Density; + info->gangPedThreshold[7] = gang7Density; + info->gangPedThreshold[8] = gang8Density; + + info->gangPedThreshold[0] += info->copPedThreshold; + info->gangPedThreshold[1] = info->gangPedThreshold[0]; + info->gangPedThreshold[2] = info->gangPedThreshold[1]; + info->gangPedThreshold[3] = info->gangPedThreshold[2]; + info->gangPedThreshold[4] = info->gangPedThreshold[3]; + info->gangPedThreshold[5] = info->gangPedThreshold[4]; + info->gangPedThreshold[6] = info->gangPedThreshold[5]; + info->gangPedThreshold[7] = info->gangPedThreshold[6]; + info->gangPedThreshold[8] = info->gangPedThreshold[7]; } +//--MIAMI: done, unused void CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity) { CZone *zone; - zone = GetZone(zoneid); - if(IsNormalZone(zone->type)) - ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity; } +//--MIAMI: done, unused void CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity) { CZone *zone; - zone = GetZone(zoneid); - if(IsNormalZone(zone->type)) - ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity; } +//--MIAMI: done void CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup) { CZone *zone; - zone = GetZone(zoneid); - if(IsNormalZone(zone->type)) - ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup; } +//--MIAMI: done int16 CTheZones::FindAudioZone(CVector *pos) { @@ -568,18 +590,7 @@ CTheZones::FindAudioZone(CVector *pos) return -1; } -eLevelName -CTheZones::FindZoneForPoint(const CVector &pos) -{ - if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("IND_ZON")))) - return LEVEL_INDUSTRIAL; - if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("COM_ZON")))) - return LEVEL_COMMERCIAL; - if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("SUB_ZON")))) - return LEVEL_SUBURBAN; - return LEVEL_NONE; -} - +//--MIAMI: done void CTheZones::AddZoneToAudioZoneArray(CZone *zone) { @@ -590,12 +601,14 @@ CTheZones::AddZoneToAudioZoneArray(CZone *zone) /* This is a bit stupid */ z = -1; - for(i = 0; i < NUMZONES; i++) - if(&ZoneArray[i] == zone) + for(i = 0; i < NUMNAVIGZONES; i++) + if(&NavigationZoneArray[i] == zone) z = i; + assert(NumberOfAudioZones < NUMAUDIOZONES); AudioZoneArray[NumberOfAudioZones++] = z; } +//--MIAMI: done void CTheZones::InitialiseAudioZoneArray(void) { @@ -603,7 +616,7 @@ CTheZones::InitialiseAudioZoneArray(void) CZone *zone; gonext = false; - zone = &ZoneArray[0]; + zone = &NavigationZoneArray[0]; // Go deep first, // set gonext when backing up a level to visit the next child while(zone) @@ -627,6 +640,7 @@ CTheZones::InitialiseAudioZoneArray(void) } } +//--MIAMI: TODO void CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) { @@ -634,32 +648,39 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) int i; *size = SAVE_HEADER_SIZE - + sizeof(int32) // GetIndexForZonePointer + sizeof(m_CurrLevel) + sizeof(FindIndex) + sizeof(int16) // padding - + sizeof(ZoneArray) + sizeof(ZoneInfoArray) - + sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos) + + sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray) + + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos) + sizeof(MapZoneArray) + sizeof(AudioZoneArray) + sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones); WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE); - WriteSaveBuf(buffer, GetIndexForZonePointer(m_pPlayersZone)); WriteSaveBuf(buffer, m_CurrLevel); WriteSaveBuf(buffer, FindIndex); WriteSaveBuf(buffer, (int16)0); // padding - for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){ - CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]); - zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child); - zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent); - zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next); +// TODO(MIAMI): implement SaveOneZone + for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){ + CZone *zone = WriteSaveBuf(buffer, NavigationZoneArray[i]); + zone->child = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].child); + zone->parent = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].parent); + zone->next = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].next); + } + + for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){ + CZone *zone = WriteSaveBuf(buffer, InfoZoneArray[i]); + zone->child = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].child); + zone->parent = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].parent); + zone->next = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].next); } for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) WriteSaveBuf(buffer, ZoneInfoArray[i]); - WriteSaveBuf(buffer, TotalNumberOfZones); + WriteSaveBuf(buffer, TotalNumberOfNavigationZones); + WriteSaveBuf(buffer, TotalNumberOfInfoZones); WriteSaveBuf(buffer, TotalNumberOfZoneInfos); for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) { @@ -687,6 +708,7 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) VALIDATESAVEBUF(*size) } +//--MIAMI: TODO void CTheZones::LoadAllZones(uint8 *buffer, uint32 size) { @@ -695,23 +717,32 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size) CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE); - m_pPlayersZone = GetPointerForZoneIndex(ReadSaveBuf<int32>(buffer)); m_CurrLevel = ReadSaveBuf<eLevelName>(buffer); FindIndex = ReadSaveBuf<int16>(buffer); ReadSaveBuf<int16>(buffer); - for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){ - ZoneArray[i] = ReadSaveBuf<CZone>(buffer); +// TODO(MIAMI): implement LoadOneZone + for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){ + NavigationZoneArray[i] = ReadSaveBuf<CZone>(buffer); + + NavigationZoneArray[i].child = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].child); + NavigationZoneArray[i].parent = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].parent); + NavigationZoneArray[i].next = GetPointerForZoneIndex((uintptr)NavigationZoneArray[i].next); + } + + for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){ + InfoZoneArray[i] = ReadSaveBuf<CZone>(buffer); - ZoneArray[i].child = GetPointerForZoneIndex((uintptr)ZoneArray[i].child); - ZoneArray[i].parent = GetPointerForZoneIndex((uintptr)ZoneArray[i].parent); - ZoneArray[i].next = GetPointerForZoneIndex((uintptr)ZoneArray[i].next); + InfoZoneArray[i].child = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].child); + InfoZoneArray[i].parent = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].parent); + InfoZoneArray[i].next = GetPointerForZoneIndex((uintptr)InfoZoneArray[i].next); } for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer); - TotalNumberOfZones = ReadSaveBuf<int16>(buffer); + TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer); + TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer); TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer); for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){ diff --git a/src/core/Zones.h b/src/core/Zones.h index 6549dad5..8d5af182 100644 --- a/src/core/Zones.h +++ b/src/core/Zones.h @@ -2,6 +2,7 @@ #include "Game.h" #include "Gangs.h" +#include "CarCtrl.h" enum eZoneType { @@ -37,31 +38,33 @@ class CZoneInfo public: // Car data int16 carDensity; - int16 carThreshold[6]; - int16 copThreshold; + int16 carThreshold[CCarCtrl::NUM_CAR_CLASSES]; + int16 boatThreshold[CCarCtrl::NUM_BOAT_CLASSES]; int16 gangThreshold[NUM_GANGS]; + int16 copThreshold; // Ped data uint16 pedDensity; - uint16 copDensity; - uint16 gangDensity[NUM_GANGS]; + uint16 gangPedThreshold[NUM_GANGS]; + uint16 copPedThreshold; uint16 pedGroup; }; class CTheZones { - static CZone *m_pPlayersZone; static int16 FindIndex; static uint16 NumberOfAudioZones; static int16 AudioZoneArray[NUMAUDIOZONES]; static uint16 TotalNumberOfMapZones; - static uint16 TotalNumberOfZones; - static CZone ZoneArray[NUMZONES]; + static uint16 TotalNumberOfInfoZones; + static uint16 TotalNumberOfNavigationZones; + static CZone InfoZoneArray[NUMINFOZONES]; static CZone MapZoneArray[NUMMAPZONES]; + static CZone NavigationZoneArray[NUMNAVIGZONES]; static uint16 TotalNumberOfZoneInfos; - static CZoneInfo ZoneInfoArray[2*NUMZONES]; + static CZoneInfo ZoneInfoArray[2*NUMINFOZONES]; public: static eLevelName m_CurrLevel; @@ -71,31 +74,27 @@ public: float minx, float miny, float minz, float maxx, float maxy, float maxz, eLevelName level); - static void CreateMapZone(char *name, eZoneType type, - float minx, float miny, float minz, - float maxx, float maxy, float maxz, - eLevelName level); - static CZone *GetZone(uint16 i) { return &ZoneArray[i]; } - static CZone *GetAudioZone(uint16 i) { return &ZoneArray[AudioZoneArray[i]]; } + static CZone *GetInfoZone(uint16 i) { return &InfoZoneArray[i]; } + static CZone *GetNavigationZone(uint16 i) { return &NavigationZoneArray[i]; } + static CZone *GetMapZone(uint16 i) { return &MapZoneArray[i]; } + static CZone *GetAudioZone(uint16 i) { return &InfoZoneArray[AudioZoneArray[i]]; } static void PostZoneCreation(void); + static void CheckZonesForOverlap(void); static void InsertZoneIntoZoneHierarchy(CZone *zone); static bool InsertZoneIntoZoneHierRecursive(CZone *z1, CZone *z2); static bool ZoneIsEntirelyContainedWithinOtherZone(CZone *z1, CZone *z2); static bool PointLiesWithinZone(const CVector *v, CZone *zone); static eLevelName GetLevelFromPosition(const CVector *v); - static CZone *FindSmallestZonePosition(const CVector *v); - static CZone *FindSmallestZonePositionType(const CVector *v, eZoneType type); - static CZone *FindSmallestZonePositionILN(const CVector *v); - static int16 FindZoneByLabelAndReturnIndex(Const char *name); + static CZone *FindInformationZoneForPosition(const CVector *v); + static CZone *FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig); + static int16 FindZoneByLabelAndReturnIndex(char *name, eZoneType type); + static int16 FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type); static CZoneInfo *GetZoneInfo(const CVector *v, uint8 day); static void GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info); static void SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity, - int16 gang0Num, int16 gang1Num, int16 gang2Num, - int16 gang3Num, int16 gang4Num, int16 gang5Num, - int16 gang6Num, int16 gang7Num, int16 gang8Num, - int16 copNum, - int16 car0Num, int16 car1Num, int16 car2Num, - int16 car3Num, int16 car4Num, int16 car5Num); + int16 copCarDensity, const int16 *gangCarDensities /*[NUMGANGS]*/); + static void SetZoneCivilianCarInfo(uint16 zoneid, uint8 day, + const int16* carDensities, const int16* boatDensities); static void SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity, int16 gang0Density, int16 gang1Density, int16 gang2Density, int16 gang3Density, int16 gang4Density, int16 gang5Density, int16 gang6Density, int16 gang7Density, @@ -104,9 +103,8 @@ public: static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity); static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup); static int16 FindAudioZone(CVector *pos); - static eLevelName FindZoneForPoint(const CVector &pos); - static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; } - static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; } + static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &InfoZoneArray[i]; } + static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - InfoZoneArray; } static void AddZoneToAudioZoneArray(CZone *zone); static void InitialiseAudioZoneArray(void); static void SaveAllZones(uint8 *buffer, uint32 *length); diff --git a/src/core/common.h b/src/core/common.h index 7d339660..cc570bef 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -187,6 +187,7 @@ public: #if (defined(_MSC_VER)) extern int strcasecmp(const char *str1, const char *str2); +extern int strncasecmp(const char *str1, const char *str2, size_t len); #endif #define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v)) diff --git a/src/core/config.h b/src/core/config.h index 837d8165..b0ef3f67 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -3,71 +3,74 @@ enum Config { NUMPLAYERS = 1, - NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC) + NUMCDIMAGES = 6, // gta3.img duplicates (not used on PC) MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, - MODELINFOSIZE = 5500, - TXDSTORESIZE = 850, - EXTRADIRSIZE = 128, + MODELINFOSIZE = 6500, + TXDSTORESIZE = 1385, + COLSTORESIZE = 31, + EXTRADIRSIZE = 256, CUTSCENEDIRSIZE = 512, - SIMPLEMODELSIZE = 5000, - MLOMODELSIZE = 1, - MLOINSTANCESIZE = 1, - TIMEMODELSIZE = 30, + SIMPLEMODELSIZE = 3885, + TIMEMODELSIZE = 385, CLUMPMODELSIZE = 5, - PEDMODELSIZE = 90, - VEHICLEMODELSIZE = 120, - XTRACOMPSMODELSIZE = 2, - TWODFXSIZE = 2000, + WEAPONMODELSIZE = 37, + PEDMODELSIZE = 130, + VEHICLEMODELSIZE = 110, + TWODFXSIZE = 1210, MAXVEHICLESLOADED = 50, // 70 on mobile - NUMOBJECTINFO = 168, // object.dat + NUMOBJECTINFO = 400, // TODO(MIAMI): fantasy // object.dat // Pool sizes - NUMPTRNODES = 30000, // 26000 on PS2 - NUMENTRYINFOS = 5400, // 3200 on PS2 - NUMPEDS = 140, // 90 on PS2 - NUMVEHICLES = 110, // 70 on PS2 - NUMBUILDINGS = 5500, // 4915 on PS2 - NUMTREADABLES = 1214, - NUMOBJECTS = 450, - NUMDUMMIES = 2802, // 2368 on PS2 - NUMAUDIOSCRIPTOBJECTS = 256, - NUMCUTSCENEOBJECTS = 50, - - NUMANIMBLOCKS = 2, - NUMANIMATIONS = 250, - - NUMTEMPOBJECTS = 30, + NUMPTRNODES = 50000, + NUMENTRYINFOS = 5400, // only 3200 in VC??? + NUMPEDS = 140, + NUMVEHICLES = 110, + NUMBUILDINGS = 7000, + NUMTREADABLES = 1214, // 1 in VC + NUMOBJECTS = 460, + NUMDUMMIES = 2802, // 2340 in VC + NUMAUDIOSCRIPTOBJECTS = 256, // 192 in VC + NUMCUTSCENEOBJECTS = 50, // does not exist in VC + // TODO(MIAMI): colmodel pool + + NUMANIMBLOCKS = 35, + NUMANIMATIONS = 450, + + NUMTEMPOBJECTS = 40, // Path data - NUM_PATHNODES = 4930, - NUM_CARPATHLINKS = 2076, + NUM_PATHNODES = 9650, + NUM_CARPATHLINKS = 3500, NUM_MAPOBJECTS = 1250, - NUM_PATHCONNECTIONS = 10260, + NUM_PATHCONNECTIONS = 20400, // Link list lengths NUMALPHALIST = 20, - NUMALPHAENTITYLIST = 150, + NUMBOATALPHALIST = 20, + NUMALPHAENTITYLIST = 200, + NUMALPHAUNTERWATERENTITYLIST = 30, NUMCOLCACHELINKS = 200, NUMREFERENCES = 800, // Zones - NUMAUDIOZONES = 36, - NUMZONES = 50, - NUMMAPZONES = 25, + NUMAUDIOZONES = 14, + NUMINFOZONES = 169, + NUMMAPZONES = 39, + NUMNAVIGZONES = 20, // Cull zones - NUMCULLZONES = 512, - NUMATTRIBZONES = 288, - NUMZONEINDICES = 55000, + NUMATTRIBZONES = 704, + + NUMOCCLUSIONVOLUMES = 350, PATHNODESIZE = 4500, - NUMWEATHERS = 4, + NUMWEATHERS = 7, NUMHOURS = 24, NUMEXTRADIRECTIONALS = 4, @@ -92,7 +95,7 @@ enum Config { NUMPACMANPICKUPS = 256, NUMEVENTS = 64, - NUM_CARGENS = 160, + NUM_CARGENS = 185, NUM_PATH_NODES_IN_AUTOPILOT = 8, @@ -107,11 +110,12 @@ enum Config { NUMPEDROUTES = 200, NUMPHONES = 50, - NUMPEDGROUPS = 31, - NUMMODELSPERPEDGROUP = 8, + NUMPEDGROUPS = 67, + NUMMODELSPERPEDGROUP = 16, NUMSHOTINFOS = 100, - NUMROADBLOCKS = 600, + NUMROADBLOCKS = 300, + NUM_SCRIPT_ROADBLOCKS = 16, NUMVISIBLEENTITIES = 2000, NUMINVISIBLEENTITIES = 150, @@ -127,11 +131,14 @@ enum Config { NUM_AUDIO_REFLECTIONS = 5, NUM_SCRIPT_MAX_ENTITIES = 40, - NUM_GARAGE_STORED_CARS = 6, + NUM_GARAGE_STORED_CARS = 4, NUM_CRANES = 8, NUM_EXPLOSIONS = 48, + + NUM_SETPIECES = 96, + NUM_SHORTCUT_START_POINTS = 16 }; // We'll use this once we're ready to become independent of the game @@ -161,6 +168,7 @@ enum Config { #elif defined GTA_PC # define GTA3_1_1_PATCH //# define GTA3_STEAM_PATCH +//# define GTAVC_JP_PATCH # ifdef GTA_PS2_STUFF # define USE_PS2_RAND # define RANDOMSPLASH // use random splash as on PS2 @@ -190,9 +198,17 @@ enum Config { #endif #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more -#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. not too many things -#define MORE_LANGUAGES // Add more translations to the game +//#define MORE_LANGUAGES // Add more translations to the game #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible +#define FIX_HIGH_FPS_BUGS_ON_FRONTEND + +// Rendering/display +#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios +// Just debug menu entries +#ifdef DEBUGMENU +#define TOGGLEABLE_BETA_FEATURES // not too many things +#define RELOADABLES // some debug menu options to reload TXD files +#endif // Rendering/display #define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios @@ -201,9 +217,11 @@ enum Config { #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number //#define USE_TEXTURE_POOL -// Particle -//#define PC_PARTICLE +// Water & Particle +#define PC_PARTICLE //#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2 +// #define PC_WATER +#define WATER_CHEATS // Pad #if !defined(RW_GL3) && defined(_WIN32) @@ -217,7 +235,6 @@ enum Config { // Hud, frontend and radar #define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC -#define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box // #define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc. #define MENU_MAP // VC-like menu map. Make sure you have new menu.txd #define SCROLLABLE_STATS_PAGE // only draggable by mouse atm @@ -225,13 +242,15 @@ enum Config { // #define CIRCLE_BACK_BUTTON #define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better. #define BETA_SLIDING_TEXT -#define CUSTOM_FRONTEND_OPTIONS +//#define CUSTOM_FRONTEND_OPTIONS +#define LEGACY_MENU_OPTIONS +#define MUCH_SHORTER_OUTRO_SCREEN // 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 MISSION_REPLAY // mobile feature +//#define MISSION_REPLAY // mobile feature //#define SIMPLIER_MISSIONS // apply simplifications from mobile // Replay diff --git a/src/core/main.cpp b/src/core/main.cpp index eb39b287..547d3b37 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -84,7 +84,7 @@ RwRGBA gColourTop; bool gameAlreadyInitialised; float NumberOfChunksLoaded; -#define TOTALNUMCHUNKS 73.0f +#define TOTALNUMCHUNKS 95.0f bool g_SlowMode = false; char version_name[64]; @@ -139,11 +139,8 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR CRGBA TopColor(TopRed, TopGreen, TopBlue, Alpha); CRGBA BottomColor(BottomRed, BottomGreen, BottomBlue, Alpha); -#ifndef ASPECT_RATIO_SCALE - CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, (CMenuManager::m_PrefsUseWideScreen ? 16.f / 9.f : 4.f / 3.f)); -#else + CDraw::CalculateAspectRatio(); CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); -#endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &TopColor.rwRGBA, rwCAMERACLEARZ); @@ -161,11 +158,8 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha) { -#ifndef ASPECT_RATIO_SCALE - CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, (CMenuManager::m_PrefsUseWideScreen ? 16.f/9.f : 4.f/3.f)); -#else + CDraw::CalculateAspectRatio(); CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); -#endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); @@ -209,13 +203,13 @@ DoFade(void) } } - if(CDraw::FadeValue != 0 || CMenuManager::m_PrefsBrightness < 256){ + if(CDraw::FadeValue != 0 || FrontEndMenuManager.m_PrefsBrightness < 256){ CSprite2d *splash = LoadSplash(nil); CRGBA fadeColor; CRect rect; int fadeValue = CDraw::FadeValue; - float brightness = Min(CMenuManager::m_PrefsBrightness, 256); + float brightness = Min(FrontEndMenuManager.m_PrefsBrightness, 256); if(brightness <= 50) brightness = 50; if(FrontEndMenuManager.m_bMenuActive) @@ -366,6 +360,7 @@ Terminate3D(void) CSprite2d splash; int splashTxdId = -1; +//--MIAMI: done CSprite2d* LoadSplash(const char *name) { @@ -411,22 +406,23 @@ DestroySplashScreen(void) splashTxdId = -1; } +//--MIAMI: done Const char* GetRandomSplashScreen(void) { int index; static int index2 = 0; static char splashName[128]; - static int splashIndex[24] = { - 25, 22, 4, 13, - 1, 21, 14, 16, - 10, 12, 5, 9, - 11, 18, 3, 2, - 19, 23, 7, 17, - 15, 6, 8, 20 + static int splashIndex[12] = { + 1, 2, + 3, 4, + 5, 11, + 6, 8, + 9, 10, + 7, 12 }; - index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)]; + index = splashIndex[2*index2 + CGeneral::GetRandomNumberInRange(0, 2)]; index2++; if(index2 == 6) index2 = 0; @@ -453,17 +449,14 @@ ResetLoadingScreenBar() NumberOfChunksLoaded = 0.0f; } -// TODO: compare with PS2 +//--MIAMI: done void LoadingScreen(const char *str1, const char *str2, const char *splashscreen) { CSprite2d *splash; #ifndef RANDOMSPLASH - if(CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) - splashscreen = "mainsc2"; - else - splashscreen = "mainsc1"; + splashscreen = "LOADSC0"; #endif splash = LoadSplash(splashscreen); @@ -484,36 +477,50 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) if(str1){ NumberOfChunksLoaded += 1; +#ifndef RANDOMSPLASH float hpos = SCREEN_SCALE_X(40); - float length = SCREEN_WIDTH - SCREEN_SCALE_X(100); - float vpos = SCREEN_HEIGHT - SCREEN_SCALE_Y(13); - float height = SCREEN_SCALE_Y(7); - CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(40, 53, 68, 255)); + float length = SCREEN_WIDTH - SCREEN_SCALE_X(80); + float top = SCREEN_HEIGHT - SCREEN_SCALE_Y(14); + float bottom = top + SCREEN_SCALE_Y(5); +#else + float hpos = SCREEN_STRETCH_X(40); + float length = SCREEN_STRETCH_X(440); + // this is rather weird + float top = SCREEN_STRETCH_Y(407.4f - 7.0f/3.0f); + float bottom = SCREEN_STRETCH_Y(407.4f + 7.0f/3.0f); +#endif + + CSprite2d::DrawRect(CRect(hpos-1.0f, top-1.0f, hpos+length+1.0f, bottom+1.0f), CRGBA(40, 53, 68, 255)); + + CSprite2d::DrawRect(CRect(hpos, top, hpos+length, bottom), CRGBA(155, 50, 125, 255)); length *= NumberOfChunksLoaded/TOTALNUMCHUNKS; - CSprite2d::DrawRect(CRect(hpos, vpos, hpos + length, vpos + height), CRGBA(81, 106, 137, 255)); + CSprite2d::DrawRect(CRect(hpos, top, hpos+length, bottom), CRGBA(255, 150, 225, 255)); // this is done by the game but is unused + CFont::SetBackgroundOff(); CFont::SetScale(SCREEN_SCALE_X(2), SCREEN_SCALE_Y(2)); CFont::SetPropOn(); CFont::SetRightJustifyOn(); + CFont::SetDropShadowPosition(1); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetFontStyle(FONT_HEADING); #ifdef CHATTYSPLASH // my attempt static wchar tmpstr[80]; float yscale = SCREEN_SCALE_Y(0.9f); - vpos -= 45*yscale; + top -= 45*yscale; CFont::SetScale(SCREEN_SCALE_X(0.75f), yscale); CFont::SetPropOn(); CFont::SetRightJustifyOff(); CFont::SetFontStyle(FONT_BANK); CFont::SetColor(CRGBA(255, 255, 255, 255)); AsciiToUnicode(str1, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); - vpos += 22*yscale; + CFont::PrintString(hpos, top, tmpstr); + top += 22*yscale; AsciiToUnicode(str2, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); + CFont::PrintString(hpos, top, tmpstr); #endif } @@ -686,11 +693,13 @@ DisplayGameDebugText() { static bool bDisplayPosn = false; static bool bDisplayRate = false; + static bool bDisplayCheatStr = false; { SETTWEAKPATH("GameDebugText"); TWEAKBOOL(bDisplayPosn); TWEAKBOOL(bDisplayRate); + TWEAKBOOL(bDisplayCheatStr); } @@ -778,6 +787,26 @@ DisplayGameDebugText() CFont::SetColor(CRGBA(255, 108, 0, 255)); CFont::PrintString(40.0f, 40.0f, ustr); } + + if (bDisplayCheatStr) + { + sprintf(str, "%s", CPad::KeyBoardCheatString); + AsciiToUnicode(str, ustr); + + CFont::SetPropOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(0.7f, 1.5f); + CFont::SetCentreOn(); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetWrapx(640.0f); + CFont::SetFontStyle(FONT_HEADING); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.5f)+2.f, SCREEN_SCALE_FROM_BOTTOM(20.0f)+2.f, ustr); + + CFont::SetColor(CRGBA(255, 150, 225, 255)); + CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH * 0.5f), SCREEN_SCALE_FROM_BOTTOM(20.0f), ustr); + } } #endif @@ -788,14 +817,17 @@ RenderScene(void) DoRWRenderHorizon(); CRenderer::RenderRoads(); CCoronas::RenderReflections(); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); CRenderer::RenderEverythingBarRoads(); - CRenderer::RenderBoats(); - DefinedState(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWaterLevel::RenderWater(); + CRenderer::RenderBoats(); + CRenderer::RenderFadingInUnderwaterEntities(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); + CWaterLevel::RenderTransparentWater(); CRenderer::RenderFadingInEntities(); - CRenderer::RenderVehiclesButNotBoats(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWeather::RenderRainStreaks(); + // CCoronas::RenderSunReflection } void @@ -920,15 +952,12 @@ Render2dStuffAfterFade(void) CHud::DrawAfterFade(); CFont::DrawFonts(); + CCredits::Render(); } void Idle(void *arg) { -#ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); -#endif - CTimer::Update(); #ifdef TIMEBARS @@ -938,35 +967,6 @@ Idle(void *arg) CSprite2d::InitPerFrame(); CFont::InitPerFrame(); - // We're basically merging FrontendIdle and Idle (just like TheGame on PS2) -#ifdef PS2_SAVE_DIALOG - // Only exists on PC FrontendIdle, probably some PS2 bug fix - if (FrontEndMenuManager.m_bMenuActive) - CSprite2d::SetRecipNearClip(); - - if (FrontEndMenuManager.m_bGameNotLoaded) { - CPad::UpdatePads(); - FrontEndMenuManager.Process(); - } else { - CPointLights::InitPerFrame(); -#ifdef TIMEBARS - tbStartTimer(0, "CGame::Process"); -#endif - CGame::Process(); -#ifdef TIMEBARS - tbEndTimer("CGame::Process"); - tbStartTimer(0, "DMAudio.Service"); -#endif - DMAudio.Service(); - -#ifdef TIMEBARS - tbEndTimer("DMAudio.Service"); -#endif - } - - if (RsGlobal.quit) - return; -#else CPointLights::InitPerFrame(); #ifdef TIMEBARS tbStartTimer(0, "CGame::Process"); @@ -982,7 +982,6 @@ Idle(void *arg) #ifdef TIMEBARS tbEndTimer("DMAudio.Service"); #endif -#endif if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){ FrontEndMenuManager.m_bWantToRestart = true; @@ -998,21 +997,23 @@ Idle(void *arg) if(arg == nil) return; - if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) && + // m_bRenderGameInMenu is there in III PS2 but I don't know about VC PS2. + if((!FrontEndMenuManager.m_bMenuActive/* || FrontEndMenuManager.m_bRenderGameInMenu*/) && TheCamera.GetScreenFadeStatus() != FADE_2) { #ifdef GTA_PC - if (!FrontEndMenuManager.m_bRenderGameInMenu) { // 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); - } #endif #ifdef TIMEBARS tbStartTimer(0, "CnstrRenderList"); #endif +#ifdef PC_WATER + CWaterLevel::PreCalcWaterGeometry(); +#endif CRenderer::ConstructRenderList(); #ifdef TIMEBARS tbEndTimer("CnstrRenderList"); @@ -1065,6 +1066,7 @@ Idle(void *arg) tbEndTimer("Render2dStuff"); #endif }else{ + CDraw::CalculateAspectRatio(); #ifdef ASPECT_RATIO_SCALE CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); #else @@ -1076,10 +1078,6 @@ Idle(void *arg) return; } -#ifdef PS2_SAVE_DIALOG - if (FrontEndMenuManager.m_bMenuActive) - DefinedState(); -#endif #ifdef TIMEBARS tbStartTimer(0, "RenderMenus"); #endif @@ -1097,7 +1095,7 @@ Idle(void *arg) #ifdef TIMEBARS tbEndTimer("Render2dStuff-Fade"); #endif - CCredits::Render(); + // CCredits::Render(); // They added it to function above and also forgot it here #ifdef TIMEBARS @@ -1114,10 +1112,7 @@ Idle(void *arg) void FrontendIdle(void) { -#ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); -#endif - + CDraw::CalculateAspectRatio(); CTimer::Update(); CSprite2d::SetRecipNearClip(); // this should be on InitialiseRenderWare according to PS2 asm. seems like a bug fix CSprite2d::InitPerFrame(); @@ -1128,11 +1123,7 @@ FrontendIdle(void) if(RsGlobal.quit) return; -#ifdef ASPECT_RATIO_SCALE CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); -#else - CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO); -#endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); if(!RsCameraBeginUpdate(Scene.camera)) @@ -1142,7 +1133,7 @@ FrontendIdle(void) RenderMenus(); DoFade(); Render2dStuffAfterFade(); -// CFont::DrawFonts(); // redundant + CFont::DrawFonts(); DoRWStuffEndOfFrame(); } @@ -1150,7 +1141,7 @@ void InitialiseGame(void) { LoadingScreen(nil, nil, "loadsc0"); - CGame::Initialise("DATA\\GTA3.DAT"); + CGame::Initialise("DATA\\GTA_VC.DAT"); } RsEventStatus @@ -1213,11 +1204,7 @@ AppEventHandler(RsEvent event, void *param) case rsFRONTENDIDLE: { -#ifdef PS2_SAVE_DIALOG - Idle((void*)1); -#else FrontendIdle(); -#endif return rsEVENTPROCESSED; } @@ -1252,9 +1239,8 @@ TheModelViewer(void) #if (defined(GTA_PS2) || defined(GTA_XBOX)) //TODO #else -#ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); -#endif + + CDraw::CalculateAspectRatio(); CAnimViewer::Update(); CTimer::Update(); SetLightsWithTimeOfDayColour(Scene.world); @@ -1303,9 +1289,9 @@ void TheGame(void) strcpy(TheMemoryCard.LoadFileName, TheMemoryCard.field37); TheMemoryCard.b_FoundRecentSavedGameWantToLoad = true; - if (CMenuManager::m_PrefsLanguage != TheMemoryCard.GetLanguageToLoad()) + if (FrontEndMenuManager.m_PrefsLanguage != TheMemoryCard.GetLanguageToLoad()) { - CMenuManager::m_PrefsLanguage = TheMemoryCard.GetLanguageToLoad(); + FrontEndMenuManager.m_PrefsLanguage = TheMemoryCard.GetLanguageToLoad(); TheText.Unload(); TheText.Load(); } @@ -1379,7 +1365,8 @@ void TheGame(void) gMainHeap.PushMemId(_TODOCONST(15)); #endif - if (!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true && TheCamera.GetScreenFadeStatus() != FADE_2 ) + // 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 ) { #ifdef GTA_PS2 gMainHeap.PushMemId(_TODOCONST(11)); @@ -1586,30 +1573,30 @@ void SystemInit() CGame::frenchGame = false; CGame::germanGame = false; CGame::nastyGame = true; - CMenuManager::m_PrefsAllowNastyGame = true; + FrontEndMenuManager.m_PrefsAllowNastyGame = true; #ifdef GTA_PS2 int32 lang = sceScfGetLanguage(); if ( lang == SCE_ITALIAN_LANGUAGE ) - CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN; else if ( lang == SCE_SPANISH_LANGUAGE ) - CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_SPANISH; else if ( lang == SCE_GERMAN_LANGUAGE ) { CGame::germanGame = true; CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; - CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_GERMAN; } else if ( lang == SCE_FRENCH_LANGUAGE ) { CGame::frenchGame = true; CGame::nastyGame = false; - CMenuManager::m_PrefsAllowNastyGame = false; - CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH; + FrontEndMenuManager.m_PrefsAllowNastyGame = false; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_FRENCH; } else - CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN; + FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_AMERICAN; FrontEndMenuManager.InitialiseMenuContentsAfterLoadingGame(); #else diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 38854f25..77c387b3 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -16,6 +16,7 @@ #include "Boat.h" #include "Heli.h" #include "Automobile.h" +#include "Bike.h" #include "Ped.h" #include "Particle.h" #include "Console.h" @@ -164,9 +165,11 @@ CustomFrontendOptionsPopulate(void) #endif #ifdef DEBUGMENU -void WeaponCheat(); +void WeaponCheat1(); +void WeaponCheat2(); +void WeaponCheat3(); void HealthCheat(); -void TankCheat(); +void VehicleCheat(bool something, int model); void BlowUpCarsCheat(); void ChangePlayerCheat(); void MayhemCheat(); @@ -209,6 +212,8 @@ SpawnCar(int id) CVehicle *v; if(CModelInfo::IsBoatModel(id)) v = new CBoat(id, RANDOM_VEHICLE); + if(CModelInfo::IsBikeModel(id)) + v = new CBike(id, RANDOM_VEHICLE); else v = new CAutomobile(id, RANDOM_VEHICLE); @@ -238,10 +243,12 @@ FixCar(void) if(veh == nil) return; veh->m_fHealth = 1000.0f; - if(!veh->IsCar()) - return; - ((CAutomobile*)veh)->Damage.SetEngineStatus(0); - ((CAutomobile*)veh)->Fix(); + if(veh->IsCar()){ + ((CAutomobile*)veh)->Damage.SetEngineStatus(0); + ((CAutomobile*)veh)->Fix(); + }else if(veh->IsBike()){ + ((CBike*)veh)->Fix(); + } } #ifdef MENU_MAP @@ -303,11 +310,17 @@ ResetCamStatics(void) } static const char *carnames[] = { - "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony", - "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer", - "securica", "banshee", "predator", "bus", "rhino", "barracks", "train", "chopper", "dodo", "coach", "cabbie", "stallion", "rumpo", "rcbandit", - "bellyup", "mrwongs", "mafia", "yardie", "yakuza", "diablos", "columb", "hoods", "airtrain", "deaddodo", "speeder", "reefer", "panlant", "flatbed", - "yankee", "escape", "borgnine", "toyz", "ghost", + "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "rio", "firetruk", "trash", "stretch", "manana", + "infernus", "voodoo", "pony", "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "washing", + "bobcat", "mrwhoop", "bfinject", "hunter", "police", "enforcer", "securica", "banshee", "predator", "bus", + "rhino", "barracks", "cuban", "chopper", "angel", "coach", "cabbie", "stallion", "rumpo", "rcbandit", "romero", + "packer", "sentxs", "admiral", "squalo", "seaspar", "pizzaboy", "gangbur", "airtrain", "deaddodo", "speeder", + "reefer", "tropic", "flatbed", "yankee", "caddy", "zebra", "topfun", "skimmer", "pcj600", "faggio", "freeway", + "rcbaron", "rcraider", "glendale", "oceanic", "sanchez", "sparrow", "patriot", "lovefist", "coastg", "dinghy", + "hermes", "sabre", "sabretur", "pheonix", "walton", "regina", "comet", "deluxo", "burrito", "spand", "marquis", + "baggage", "kaufman", "maverick", "vcnmav", "rancher", "fbiranch", "virgo", "greenwoo", "jetmax", "hotring", + "sandking", "blistac", "polmav", "boxville", "benson", "mesa", "rcgoblin", "hotrina", "hotrinb", + "bloodra", "bloodrb", "vicechee" }; static CTweakVar** TweakVarsList; @@ -371,7 +384,7 @@ DebugMenuPopulate(void) { if(1){ static const char *weathers[] = { - "Sunny", "Cloudy", "Rainy", "Foggy" + "Sunny", "Cloudy", "Rainy", "Foggy", "Extrasunny", "Stormy" }; DebugMenuEntry *e; e = DebugMenuAddVar("Time & Weather", "Current Hour", &CClock::GetHoursRef(), nil, 1, 0, 23, nil); @@ -379,19 +392,21 @@ DebugMenuPopulate(void) e = DebugMenuAddVar("Time & Weather", "Current Minute", &CClock::GetMinutesRef(), [](){ CWeather::InterpolationValue = CClock::GetMinutes()/60.0f; }, 1, 0, 59, nil); DebugMenuEntrySetWrap(e, true); - e = DebugMenuAddVar("Time & Weather", "Old Weather", (int16*)&CWeather::OldWeatherType, nil, 1, 0, 3, weathers); + e = DebugMenuAddVar("Time & Weather", "Old Weather", (int16*)&CWeather::OldWeatherType, nil, 1, 0, 5, weathers); DebugMenuEntrySetWrap(e, true); - e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, nil, 1, 0, 3, weathers); + e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, nil, 1, 0, 5, weathers); DebugMenuEntrySetWrap(e, true); DebugMenuAddVar("Time & Weather", "Wind", (float*)&CWeather::Wind, nil, 0.1f, 0.0f, 1.0f); DebugMenuAddVar("Time & Weather", "Time scale", (float*)&CTimer::GetTimeScale(), nil, 0.1f, 0.0f, 10.0f); - DebugMenuAddCmd("Cheats", "Weapons", WeaponCheat); + DebugMenuAddCmd("Cheats", "Weapon set 1", WeaponCheat1); + DebugMenuAddCmd("Cheats", "Weapon set 2", WeaponCheat2); + DebugMenuAddCmd("Cheats", "Weapon set 3", WeaponCheat3); DebugMenuAddCmd("Cheats", "Money", MoneyCheat); DebugMenuAddCmd("Cheats", "Health", HealthCheat); DebugMenuAddCmd("Cheats", "Wanted level up", WantedLevelUpCheat); DebugMenuAddCmd("Cheats", "Wanted level down", WantedLevelDownCheat); - DebugMenuAddCmd("Cheats", "Tank", TankCheat); + DebugMenuAddCmd("Cheats", "Tank", []() { VehicleCheat(true, MI_TAXI); }); DebugMenuAddCmd("Cheats", "Blow up cars", BlowUpCarsCheat); DebugMenuAddCmd("Cheats", "Change player", ChangePlayerCheat); DebugMenuAddCmd("Cheats", "Mayhem", MayhemCheat); @@ -411,14 +426,12 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat); static int spawnCarId = MI_LANDSTAL; - e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_GHOST, carnames); + e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_VICECHEE, carnames); DebugMenuEntrySetWrap(e, true); DebugMenuAddCmd("Spawn", "Spawn Car", [](){ - if(spawnCarId == MI_TRAIN || - spawnCarId == MI_CHOPPER || + if(spawnCarId == MI_CHOPPER || spawnCarId == MI_AIRTRAIN || - spawnCarId == MI_DEADDODO || - spawnCarId == MI_ESCAPE) + spawnCarId == MI_DEADDODO) return; SpawnCar(spawnCarId); }); @@ -428,21 +441,32 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Spawn", "Spawn Stinger", [](){ SpawnCar(MI_STINGER); }); DebugMenuAddCmd("Spawn", "Spawn Infernus", [](){ SpawnCar(MI_INFERNUS); }); DebugMenuAddCmd("Spawn", "Spawn Cheetah", [](){ SpawnCar(MI_CHEETAH); }); + DebugMenuAddCmd("Spawn", "Spawn Phoenix", [](){ SpawnCar(MI_PHEONIX); }); + DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); }); DebugMenuAddCmd("Spawn", "Spawn Esperanto", [](){ SpawnCar(MI_ESPERANT); }); DebugMenuAddCmd("Spawn", "Spawn Stallion", [](){ SpawnCar(MI_STALLION); }); - DebugMenuAddCmd("Spawn", "Spawn Kuruma", [](){ SpawnCar(MI_KURUMA); }); + DebugMenuAddCmd("Spawn", "Spawn Admiral", [](){ SpawnCar(MI_ADMIRAL); }); + DebugMenuAddCmd("Spawn", "Spawn Washington", [](){ SpawnCar(MI_WASHING); }); DebugMenuAddCmd("Spawn", "Spawn Taxi", [](){ SpawnCar(MI_TAXI); }); DebugMenuAddCmd("Spawn", "Spawn Police", [](){ SpawnCar(MI_POLICE); }); DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); }); - DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); }); - DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); }); - DebugMenuAddCmd("Spawn", "Spawn Yardie", [](){ SpawnCar(MI_YARDIE); }); - DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); }); + DebugMenuAddCmd("Spawn", "Spawn Cuban", [](){ SpawnCar(MI_CUBAN); }); + DebugMenuAddCmd("Spawn", "Spawn Voodoo", [](){ SpawnCar(MI_VOODOO); }); + DebugMenuAddCmd("Spawn", "Spawn BF injection", [](){ SpawnCar(MI_BFINJECT); }); + DebugMenuAddCmd("Spawn", "Spawn Maverick", [](){ SpawnCar(MI_MAVERICK); }); + DebugMenuAddCmd("Spawn", "Spawn VCN Maverick", [](){ SpawnCar(MI_VCNMAV); }); + DebugMenuAddCmd("Spawn", "Spawn Sparrow", [](){ SpawnCar(MI_SPARROW); }); + DebugMenuAddCmd("Spawn", "Spawn Sea Sparrow", [](){ SpawnCar(MI_SEASPAR); }); + DebugMenuAddCmd("Spawn", "Spawn Hunter", [](){ SpawnCar(MI_HUNTER); }); DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); }); DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); }); DebugMenuAddCmd("Spawn", "Spawn Predator", [](){ SpawnCar(MI_PREDATOR); }); + DebugMenuAddCmd("Spawn", "Spawn PCJ 600", [](){ SpawnCar(MI_PCJ600); }); + DebugMenuAddCmd("Spawn", "Spawn Faggio", [](){ SpawnCar(MI_FAGGIO); }); + DebugMenuAddCmd("Spawn", "Spawn Freeway", [](){ SpawnCar(MI_FREEWAY); }); DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil); + DebugMenuAddVarBool8("Render", "Backface Culling", &gBackfaceCulling, nil); #ifdef LIBRW DebugMenuAddVarBool8("Render", "PS2 Alpha test Emu", &gPS2alphaTest, nil); #endif @@ -452,8 +476,6 @@ DebugMenuPopulate(void) DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil); DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil); DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil); - DebugMenuAddVarBool8("Render", "Show Ped Road Groups", &gbShowPedRoadGroups, nil); - DebugMenuAddVarBool8("Render", "Show Car Road Groups", &gbShowCarRoadGroups, nil); DebugMenuAddVarBool8("Render", "Show Collision Lines", &gbShowCollisionLines, nil); DebugMenuAddVarBool8("Render", "Show Collision Polys", &gbShowCollisionPolys, nil); DebugMenuAddVarBool8("Render", "Don't render Buildings", &gbDontRenderBuildings, nil); @@ -474,23 +496,17 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy); DebugMenuAddCmd("Debug", "Place Car on Road", PlaceOnRoad); - DebugMenuAddVarBool8("Debug", "Catalina Heli On", &CHeli::CatalinaHeliOn, nil); - DebugMenuAddCmd("Debug", "Catalina Fly By", CHeli::StartCatalinaFlyBy); - DebugMenuAddCmd("Debug", "Catalina Take Off", CHeli::CatalinaTakeOff); - DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway); DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil); #ifdef CUSTOM_FRONTEND_OPTIONS DebugMenuAddCmd("Debug", "Reload custom frontend options", ReloadFrontendOptions); #endif -#ifdef TOGGLEABLE_BETA_FEATURES - DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil); - DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", &CPed::bMakePedsRunToPhonesToReportCrimes, nil); -#endif - DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start); DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); +#ifdef RELOADABLES + DebugMenuAddCmd("Reload", "HUD.TXD", CHud::ReloadTXD); +#endif DebugMenuAddVarBool8("Debug", "Show DebugStuffInRelease", &gbDebugStuffInRelease, nil); #ifdef TIMEBARS DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil); diff --git a/src/core/templates.h b/src/core/templates.h index 4f7b8490..465e3bef 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -44,18 +44,20 @@ class CPool int m_allocPtr; public: + // TODO(MIAMI): remove ctor without name argument CPool(int size){ // TODO: use new here m_entries = (U*)malloc(sizeof(U)*size); m_flags = (Flags*)malloc(sizeof(Flags)*size); m_size = size; - m_allocPtr = 0; + m_allocPtr = -1; for(int i = 0; i < size; i++){ m_flags[i].id = 0; m_flags[i].free = 1; } } - + CPool(int size, const char *name) + : CPool(size) {} ~CPool() { Flush(); } @@ -131,7 +133,7 @@ public: // TODO: the cast is unsafe return (int)((U*)entry - m_entries); } - int GetNoOfUsedSpaces(void) const{ + int GetNoOfUsedSpaces(void) const { int i; int n = 0; for(i = 0; i < m_size; i++) @@ -162,6 +164,7 @@ public: memcpy(entries, m_entries, sizeof(U)*m_size); debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ } + int32 GetNoOfFreeSpaces() const { return GetSize() - GetNoOfUsedSpaces(); } }; template<typename T> |