diff options
Diffstat (limited to 'src/core')
49 files changed, 4432 insertions, 1756 deletions
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp index c8d8cb56..946693a7 100644 --- a/src/core/AnimViewer.cpp +++ b/src/core/AnimViewer.cpp @@ -45,11 +45,11 @@ CEntity *CAnimViewer::pTarget = nil; void CAnimViewer::Render(void) { if (pTarget) { -// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); +// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); // Only on Mobile if (pTarget) { #ifdef FIX_BUGS #ifdef PED_SKIN - if(pTarget->IsPed()) + if(pTarget->IsPed() && IsClumpSkinned(pTarget->GetClump())) ((CPed*)pTarget)->UpdateRpHAnim(); #endif #endif @@ -61,7 +61,9 @@ CAnimViewer::Render(void) { void CAnimViewer::Initialise(void) { - LoadingScreen("Loading the ModelViewer", "", GetRandomSplashScreen()); + // we need messages, messages needs hud, hud needs this + CHud::m_Wants_To_Draw_Hud = false; + animTxdSlot = CTxdStore::AddTxdSlot("generic"); CTxdStore::Create(animTxdSlot); int hudSlot = CTxdStore::AddTxdSlot("hud"); @@ -75,9 +77,6 @@ CAnimViewer::Initialise(void) { TheCamera.SetRwCamera(Scene.camera); TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f; - gbModelViewer = true; - CHud::m_Wants_To_Draw_Hud = false; - ThePaths.Init(); ThePaths.AllocatePathFindInfoMem(4500); CCollision::Init(); @@ -100,6 +99,9 @@ CAnimViewer::Initialise(void) { CRadar::Initialise(); CRadar::LoadTextures(); CVehicleModelInfo::LoadVehicleColours(); +#ifdef FIX_BUGS + CVehicleModelInfo::LoadEnvironmentMaps(); +#endif CAnimManager::LoadAnimFiles(); CWorld::PlayerInFocus = 0; CWeapon::InitialiseWeapons(); @@ -110,7 +112,7 @@ CAnimViewer::Initialise(void) { CTimeCycle::Initialise(); CCarCtrl::Init(); CPlayerPed *player = new CPlayerPed(); - player->SetPosition(0.0f, 0.0f, 0.0f); + player->SetPosition(0.0f, 0.0f, 0.0f); // This is 1000.f for all axes on Xbox, but 0.f on mobile? CWorld::Players[0].m_pPed = player; CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; @@ -219,8 +221,7 @@ CAnimViewer::Update(void) { static int modelId = 0; static int animId = 0; - // Please don't make this bool, static bool's are problematic on my side. - static int reloadIFP = 0; + static bool reloadIFP = false; AssocGroupId animGroup = ASSOCGRP_STD; int nextModelId = modelId; @@ -229,7 +230,7 @@ CAnimViewer::Update(void) if (modelInfo->GetModelType() == MITYPE_PED) { int animGroup = ((CPedModelInfo*)modelInfo)->m_animGroup; - if (animId > ANIM_IDLE_STANCE) + if (animId > ANIM_STD_IDLE) animGroup = ASSOCGRP_STD; if (reloadIFP) { @@ -245,7 +246,7 @@ CAnimViewer::Update(void) CAnimManager::Initialise(); CAnimManager::LoadAnimFiles(); - reloadIFP = 0; + reloadIFP = false; } } else { animGroup = ASSOCGRP_STD; @@ -294,14 +295,20 @@ CAnimViewer::Update(void) if (pTarget->IsVehicle() || pTarget->IsPed() || pTarget->IsObject()) { ((CPhysical*)pTarget)->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); } +#ifdef FIX_BUGS + // so we don't end up in the water + pTarget->GetMatrix().GetPosition().z = 10.0f; +#else pTarget->GetMatrix().GetPosition().z = 0.0f; +#endif + if (modelInfo->GetModelType() == MITYPE_PED) { ((CPed*)pTarget)->bKindaStayInSamePlace = true; // Triangle in mobile if (pad->GetSquareJustDown()) { - reloadIFP = 1; + reloadIFP = true; AsciiToUnicode("IFP reloaded", gUString); CMessages::AddMessage(gUString, 1000, 0); @@ -311,14 +318,14 @@ CAnimViewer::Update(void) CMessages::AddMessage(gUString, 1000, 0); } else if (pad->GetCircleJustDown()) { - PlayAnimation(pTarget->GetClump(), animGroup, ANIM_IDLE_STANCE); + PlayAnimation(pTarget->GetClump(), animGroup, ANIM_STD_IDLE); AsciiToUnicode("Idle animation playing", gUString); CMessages::AddMessage(gUString, 1000, 0); } else if (pad->GetDPadUpJustDown()) { animId--; if (animId < 0) { - animId = NUM_ANIMS - 1; + animId = ANIM_STD_NUM - 1; } PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId); @@ -327,7 +334,7 @@ CAnimViewer::Update(void) CMessages::AddMessage(gUString, 1000, 0); } else if (pad->GetDPadDownJustDown()) { - animId = (animId == (NUM_ANIMS - 1) ? 0 : animId + 1); + animId = (animId == (ANIM_STD_NUM - 1) ? 0 : animId + 1); PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId); sprintf(gString, "Current anim: %d", animId); diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 3e016667..2a32ed1f 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -144,9 +144,11 @@ CCam::Process(void) Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_FOLLOWPED: +#ifdef PC_PLAYER_CONTROLS if(CCamera::m_bUseMouse3rdPerson) Process_FollowPedWithMouse(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); else +#endif #ifdef FREE_CAM if(CCamera::bFreeCam) Process_FollowPed_Rotation(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); @@ -191,7 +193,7 @@ CCam::Process(void) break; case MODE_CAM_ON_A_STRING: #ifdef FREE_CAM - if(CCamera::bFreeCam) + if(CCamera::bFreeCam && !CVehicle::bCheat5) Process_FollowCar_SA(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); else #endif @@ -263,9 +265,11 @@ CCam::Process(void) case MODE_FIGHT_CAM_RUNABOUT: Process_1rstPersonPedOnPC(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; +#ifdef GTA_SCENE_EDIT case MODE_EDITOR: Process_Editor(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; +#endif default: Source = CVector(0.0f, 0.0f, 0.0f); Front = CVector(0.0f, 1.0f, 0.0f); @@ -942,7 +946,7 @@ CVector CCam::DoAverageOnVector(const CVector &vec) { int i; - CVector Average = { 0.0f, 0.0f, 0.0f }; + CVector Average(0.0f, 0.0f, 0.0f); if(ResetStatics){ m_iRunningVectorArrayPos = 0; @@ -1640,10 +1644,10 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient 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)){ + if(RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_WEAPON_PUMP) || + RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_WEAPON_THROW) || + RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_THROW_UNDER) || + RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_STD_START_THROW)){ CPed *player = FindPlayerPed(); float PlayerDist = (Source - player->GetPosition()).Magnitude(); if(PlayerDist < 2.75f) @@ -2470,7 +2474,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); @@ -2570,8 +2574,8 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) ResetStatics = false; } -#ifndef GTA3_1_1_PATCH - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); +#if GTA_VERSION < GTA3_PC_11 + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); @@ -2605,11 +2609,11 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); -#ifdef GTA3_1_1_PATCH +#if GTA_VERSION >= GTA3_PC_11 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); @@ -2698,7 +2702,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); @@ -2866,7 +2870,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, Source = HeadPos; // unused: - // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&MidPos, PED_MID); + // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(MidPos, PED_MID); // Source - MidPos; // Look around @@ -2961,7 +2965,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); @@ -3001,8 +3005,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float UseMouse = false; int ZoomInButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_IN); int ZoomOutButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_OUT); - // TODO: enum? this should be mouse wheel up and down - if(ZoomInButton == 4 || ZoomInButton == 5 || ZoomOutButton == 4 || ZoomOutButton == 5){ + if(ZoomInButton == rsMOUSEWHEELUPBUTTON || ZoomInButton == rsMOUSEWHEELDOWNBUTTON || ZoomOutButton == rsMOUSEWHEELUPBUTTON || ZoomOutButton == rsMOUSEWHEELDOWNBUTTON){ if(CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetMouseWheelDown()){ if(CPad::GetPad(0)->SniperZoomIn()){ TargetFOV = FOV - 10.0f; @@ -3672,6 +3675,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) if(TheCamera.m_bUseSpecialFovTrain) FOV = TheCamera.m_fFovForTrain; +#ifdef PC_PLAYER_CONTROLS if(CMenuManager::m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){ CPed *player = FindPlayerPed(); if(player && player->CanStrafeOrMouseControl()){ @@ -3682,6 +3686,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float) TheCamera.pTargetEntity->GetMatrix().UpdateRW(); } } +#endif } void @@ -3824,11 +3829,11 @@ CCam::Process_Debug(const CVector&, float, float, float) } // stay inside sectors - while(CWorld::GetSectorX(Source.x) > 95.0f) + while(CWorld::GetSectorX(Source.x) > NUMSECTORS_X-5.0f) Source.x -= 1.0f; while(CWorld::GetSectorX(Source.x) < 5.0f) Source.x += 1.0f; - while(CWorld::GetSectorY(Source.y) > 95.0f) + while(CWorld::GetSectorY(Source.y) > NUMSECTORS_X-5.0f) Source.y -= 1.0f; while(CWorld::GetSectorY(Source.y) < 5.0f) Source.y += 1.0f; @@ -3895,11 +3900,11 @@ CCam::Process_Debug(const CVector&, float, float, float) } // stay inside sectors - while(CWorld::GetSectorX(Source.x) > 95.0f) + while(CWorld::GetSectorX(Source.x) > NUMSECTORS_X-5.0f) Source.x -= 1.0f; while(CWorld::GetSectorX(Source.x) < 5.0f) Source.x += 1.0f; - while(CWorld::GetSectorY(Source.y) > 95.0f) + while(CWorld::GetSectorY(Source.y) > NUMSECTORS_X-5.0f) Source.y -= 1.0f; while(CWorld::GetSectorY(Source.y) < 5.0f) Source.y += 1.0f; @@ -3919,6 +3924,7 @@ CCam::Process_Debug(const CVector&, float, float, float) } #endif +#ifdef GTA_SCENE_EDIT void CCam::Process_Editor(const CVector&, float, float, float) { @@ -3975,11 +3981,11 @@ CCam::Process_Editor(const CVector&, float, float, float) } // stay inside sectors - while(CWorld::GetSectorX(Source.x) > 95.0f) + while(CWorld::GetSectorX(Source.x) > NUMSECTORS_X-5.0f) Source.x -= 1.0f; while(CWorld::GetSectorX(Source.x) < 5.0f) Source.x += 1.0f; - while(CWorld::GetSectorY(Source.y) > 95.0f) + while(CWorld::GetSectorY(Source.y) > NUMSECTORS_X-5.0f) Source.y -= 1.0f; while(CWorld::GetSectorY(Source.y) < 5.0f) Source.y += 1.0f; @@ -3997,6 +4003,7 @@ CCam::Process_Editor(const CVector&, float, float, float) sprintf(str, "Look@: %f, Look@: %f, Look@: %f ", Front.x + Source.x, Front.y + Source.y, Front.z + Source.z); } } +#endif void CCam::Process_ModelView(const CVector &CameraTarget, float, float, float) @@ -4010,6 +4017,12 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float) Distance += CPad::GetPad(0)->GetLeftStickY()/1000.0f; else Distance += CPad::GetPad(0)->GetLeftStickY() * ((Distance - 10.0f)/20.0f + 1.0f) / 1000.0f; +#ifdef IMPROVED_CAMERA + if(CPad::GetPad(0)->GetLeftMouse()){ + Distance += DEGTORAD(CPad::GetPad(0)->GetMouseY()/2.0f); + Angle += DEGTORAD(CPad::GetPad(0)->GetMouseX()/2.0f); + } +#endif if(Distance < 1.5f) Distance = 1.5f; @@ -4884,13 +4897,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, if (FOV > DefaultFOV) // 0.98f: CAR_FOV_FADE_MULT - FOV = pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; + FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; - if (FOV <= DefaultFOV + 30.0f) { - if (FOV < DefaultFOV) - FOV = DefaultFOV; - } else - FOV = DefaultFOV + 30.0f; + FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f); } // WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta) @@ -5020,7 +5029,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, targetAlpha = maxAlphaAllowed; } float maxAlphaBlendAmount = CTimer::GetTimeStep() * CARCAM_SET[camSetArrPos][6]; - float targetAlphaBlendAmount = (1.0f - pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); + float targetAlphaBlendAmount = (1.0f - Pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha); if (targetAlphaBlendAmount <= maxAlphaBlendAmount) { if (targetAlphaBlendAmount < -maxAlphaBlendAmount) targetAlphaBlendAmount = -maxAlphaBlendAmount; @@ -5030,11 +5039,15 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // Using GetCarGun(LR/UD) will give us same unprocessed RightStick value as SA float stickX = -(pad->GetCarGunLeftRight()); - float stickY = pad->GetCarGunUpDown(); - - // In SA this checks for m_bUseMouse3rdPerson so num2/num8 do not move camera when Keyboard & Mouse controls are used. - if (CCamera::m_bUseMouse3rdPerson) - stickY = 0.0f; + float stickY = -pad->GetCarGunUpDown(); + + // In SA this is for not let num2/num8 move camera when Keyboard & Mouse controls are used. + // if (CCamera::m_bUseMouse3rdPerson) + // stickY = 0.0f; +#ifdef INVERT_LOOK_FOR_PAD + if (CPad::bInvertLook4Pad) + stickY = -stickY; +#endif float xMovement = Abs(stickX) * (FOV / 80.0f * 5.f / 70.f) * stickX * 0.007f * 0.007f; float yMovement = Abs(stickY) * (FOV / 80.0f * 3.f / 70.f) * stickY * 0.007f * 0.007f; @@ -5112,7 +5125,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float betaSpeedFromStickX = xMovement * CARCAM_SET[camSetArrPos][12]; float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9]; - float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); + float angleChangeStep = Pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep()); float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f); if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount) @@ -5224,69 +5237,78 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // SA calls SetColVarsVehicle in here if (nextDirectionIsForward) { - // This is new in LCS! + // LCS uses exactly the same collision code as FollowPedWithMouse, so we will do so. + + // This is only in LCS! float timestepFactor = Pow(0.99f, CTimer::GetTimeStep()); dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude()); - // Move cam if on collision - CColPoint foundCol; - CEntity* foundEnt; + // Our addition +#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && (IsStreetLight(ent->GetModelIndex()))) + + // Clip Source and fix near clip + CColPoint colPoint; + CEntity* entity; CWorld::pIgnoreEntity = CamTargetEntity; - if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { - float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - float obstacleCamDist = newDistance - obstacleTargetDist; - if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) { - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f)); - } - } else { - if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { - float lessClip = obstacleCamDist - 0.35f; - if (lessClip <= DEFAULT_NEAR) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - } else { - obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); - Source = foundCol.point; - if (obstacleTargetDist < 1.2f) { - float lessClip = obstacleTargetDist - 0.3f; - if (lessClip >= 0.05f) - RwCameraSetNearClipPlane(Scene.camera, lessClip); - else - RwCameraSetNearClipPlane(Scene.camera, 0.05f); - } + if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) && !IS_TRAFFIC_LIGHT(entity)){ + float PedColDist = (TargetCoors - colPoint.point).Magnitude(); + float ColCamDist = newDistance - PedColDist; + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ + // Ped in the way but not clipping through + if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) || IS_TRAFFIC_LIGHT(entity)){ + PedColDist = (TargetCoors - colPoint.point).Magnitude(); + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); + }else{ + RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR)); } + }else{ + Source = colPoint.point; + if(PedColDist < DEFAULT_NEAR + 0.3f) + RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f)); } } + CWorld::pIgnoreEntity = nil; - float nearClip = RwCameraGetNearClipPlane(Scene.camera); - float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; // If we're seeing blue hell due to camera intersects some surface, fix it. // SA and LCS have this unrolled. - for (int i = 0; - i <= 5 && CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false); - i++) { - - CVector surfaceCamDist = gaTempSphereColPoints->point - Source; - CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front; - float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius; - - if (newNearClip > nearClip) - newNearClip = nearClip; - if (newNearClip < 0.1f) - newNearClip = 0.1f; - if (nearClip > newNearClip) - RwCameraSetNearClipPlane(Scene.camera, newNearClip); - - if (newNearClip == 0.1f) - Source += (TargetCoors - Source) * 0.3f; - - nearClip = RwCameraGetNearClipPlane(Scene.camera); - radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; + + float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); + float ViewPlaneWidth = ViewPlaneHeight * CDraw::FindAspectRatio() * fTweakFOV; + float Near = RwCameraGetNearClipPlane(Scene.camera); + float radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + int i = 0; + while(entity){ + + if (IS_TRAFFIC_LIGHT(entity)) + break; + + CVector CamToCol = gaTempSphereColPoints[0].point - Source; + float frontDist = DotProduct(CamToCol, Front); + float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth; + + // Try to decrease near clip + dist = Max(Min(Near, dist), 0.1f); + if(dist < Near) + RwCameraSetNearClipPlane(Scene.camera, dist); + + // Move forward a bit + if(dist == 0.1f) + Source += (TargetCoors - Source)*0.3f; + + // Keep testing + Near = RwCameraGetNearClipPlane(Scene.camera); + radius = ViewPlaneWidth*Near; + entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true); + + i++; + if(i > 5) + entity = nil; } +#undef IS_TRAFFIC_LIGHT } TheCamera.m_bCamDirectlyBehind = false; TheCamera.m_bCamDirectlyInFront = false; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 56225fed..2ce4e754 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -60,7 +60,11 @@ enum // NB: removed explicit TheCamera from all functions CCamera TheCamera; +#ifdef PC_PLAYER_CONTROLS bool CCamera::m_bUseMouse3rdPerson = true; +#else +bool CCamera::m_bUseMouse3rdPerson = false; +#endif bool bDidWeProcessAnyCinemaCam; #ifdef IMPROVED_CAMERA @@ -74,7 +78,7 @@ bool bDidWeProcessAnyCinemaCam; CCamera::CCamera(void) { -#if defined(GTA3_1_1_PATCH) || defined(FIX_BUGS) +#if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS) m_fMouseAccelHorzntl = 0.0025f; m_fMouseAccelVertical = 0.003f; #endif @@ -88,15 +92,15 @@ CCamera::CCamera(float) void CCamera::Init(void) { -#if defined(GTA3_1_1_PATCH) || defined(FIX_BUGS) +#if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS) float fMouseAccelHorzntl = m_fMouseAccelHorzntl; float fMouseAccelVertical = m_fMouseAccelVertical; #endif #ifdef PS2_MENU - if ( !TheMemoryCard.m_bWantToLoad && !FrontEndMenuManager.m_bWantToRestart ) { + if ( !TheMemoryCard.m_bWantToLoad && !FrontEndMenuManager.m_bWantToRestart ) #endif - + { #ifdef FIX_BUGS static const CCamera DummyCamera = CCamera(0.f); *this = DummyCamera; @@ -104,15 +108,13 @@ CCamera::Init(void) memset(this, 0, sizeof(CCamera)); // getting rid of vtable, eh? #endif - #if defined(GTA3_1_1_PATCH) || defined(FIX_BUGS) + #if GTA_VERSION >= GTA3_PC_11 || defined(FIX_BUGS) m_fMouseAccelHorzntl = fMouseAccelHorzntl; m_fMouseAccelVertical = fMouseAccelVertical; #endif m_pRwCamera = nil; -#ifdef PS2_MENU } -#endif m_1rstPersonRunCloseToAWall = false; m_fPositionAlongSpline = 0.0f; @@ -237,7 +239,7 @@ CCamera::Init(void) m_uiTransitionState = 0; m_uiTimeTransitionStart = 0; m_bLookingAtPlayer = true; -#if !defined(GTA3_1_1_PATCH) && !defined(FIX_BUGS) +#if GTA_VERSION < GTA3_PC_11 && !defined(FIX_BUGS) m_fMouseAccelHorzntl = 0.0025f; m_fMouseAccelVertical = 0.003f; #endif @@ -715,14 +717,18 @@ CCamera::Process(void) DistanceToWater = CWaterLevel::CalcDistanceToWater(GetPosition().x, GetPosition().y); // LOD dist - if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()) - LODDistMultiplier = 70.0f/CDraw::GetFOV() * CDraw::GetAspectRatio()/(4.0f/3.0f); - else + if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()){ + LODDistMultiplier = 70.0f/CDraw::GetFOV(); +#ifndef FIX_BUGS + // makes no sense and gone in VC + LODDistMultiplier *= CDraw::GetAspectRatio()/(4.0f/3.0f); +#endif + }else LODDistMultiplier = 1.0f; - // missing on PS2 +#if GTA_VERSION > GTA3_PS2_160 GenerationDistMultiplier = LODDistMultiplier; LODDistMultiplier *= CRenderer::ms_lodDistScale; - // +#endif // Keep track of speed if(m_bJustInitalised || m_bJust_Switched){ @@ -1574,8 +1580,10 @@ CCamera::CamControl(void) switchByJumpCut = true; } } +#ifdef GTA_SCENE_EDIT if(CSceneEdit::m_bEditOn) ReqMode = CCam::MODE_EDITOR; +#endif if((m_uiTransitionState == 0 || switchByJumpCut) && ReqMode != Cams[ActiveCam].Mode){ if(switchByJumpCut){ @@ -2204,7 +2212,7 @@ CCamera::StartTransition(int16 newMode) while(deltaBeta < -PI) deltaBeta += 2*PI; deltaBeta = Abs(deltaBeta); - door = FindPlayerPed()->m_vehEnterType; + door = FindPlayerPed()->m_vehDoor; if(deltaBeta > HALFPI){ if(((CPed*)pTargetEntity)->m_carInObjective){ if(((CPed*)pTargetEntity)->m_carInObjective->IsUpsideDown()){ @@ -2285,7 +2293,7 @@ CCamera::StartTransition(int16 newMode) } #endif - door = FindPlayerPed()->m_vehEnterType; + door = FindPlayerPed()->m_vehDoor; if(deltaBeta > HALFPI){ if(((CVehicle*)pTargetEntity)->IsUpsideDown()){ if(door == CAR_DOOR_LF || door == CAR_DOOR_LR) // BUG: game checks LF twice @@ -2775,7 +2783,7 @@ CCamera::TryToStartNewCamMode(int obbeMode) if (CReplay::IsPlayingBack()) return false; #endif - if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1) + if(FindPlayerPed()->m_pWanted->GetWantedLevel() < 1) return false; if(FindPlayerVehicle() == nil) return false; @@ -2803,7 +2811,7 @@ CCamera::TryToStartNewCamMode(int obbeMode) if (CReplay::IsPlayingBack()) return false; #endif - if(FindPlayerPed()->m_pWanted->m_nWantedLevel < 1) + if(FindPlayerPed()->m_pWanted->GetWantedLevel() < 1) return false; if(FindPlayerVehicle() == nil) return false; @@ -2978,12 +2986,12 @@ CCamera::LoadTrainCamNodes(char const *name) char token[16] = { 0 }; char filename[16] = { 0 }; uint8 *buf; - size_t bufpos = 0; + ssize_t bufpos = 0; int field = 0; int tokpos = 0; char c; int i; - size_t len; + ssize_t len; strcpy(filename, name); len = (int)strlen(filename); @@ -3621,9 +3629,17 @@ CCamera::CalculateDerivedValues(void) bool CCamera::IsPointVisible(const CVector ¢er, const CMatrix *mat) { - RwV3d c; - c = center; - RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix); +#ifdef GTA_PS2 + CVuVector c; + TransformPoint(c, *mat, center); +#else + CVector c = center; + #ifdef FIX_BUGS + c = *mat * center; + #else + RwV3dTransformPoints(&c, &c, 1, (RwMatrix*)mat); + #endif +#endif if(c.y < CDraw::GetNearClipZ()) return false; if(c.y > CDraw::GetFarClipZ()) return false; if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > 0.0f) return false; @@ -3636,9 +3652,17 @@ CCamera::IsPointVisible(const CVector ¢er, const CMatrix *mat) bool CCamera::IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat) { - RwV3d c; - c = center; - RwV3dTransformPoints(&c, &c, 1, &mat->m_matrix); +#ifdef GTA_PS2 + CVuVector c; + TransformPoint(c, *mat, center); +#else + CVector c = center; + #ifdef FIX_BUGS + c = *mat * center; + #else + RwV3dTransformPoints(&c, &c, 1, (RwMatrix*)mat); + #endif +#endif if(c.y + radius < CDraw::GetNearClipZ()) return false; if(c.y - radius > CDraw::GetFarClipZ()) return false; if(c.x*m_vecFrustumNormals[0].x + c.y*m_vecFrustumNormals[0].y > radius) return false; @@ -3656,11 +3680,24 @@ CCamera::IsSphereVisible(const CVector ¢er, float radius) } bool -CCamera::IsBoxVisible(RwV3d *box, const CMatrix *mat) +#ifdef GTA_PS2 +CCamera::IsBoxVisible(CVuVector *box, const CMatrix *mat) +#else +CCamera::IsBoxVisible(CVector *box, const CMatrix *mat) +#endif { int i; int frustumTests[6] = { 0 }; - RwV3dTransformPoints(box, box, 8, &mat->m_matrix); +#ifdef GTA_PS2 + TransformPoints(box, 8, *mat, box); +#else + #ifdef FIX_BUGS + for (i = 0; i < 8; i++) + box[i] = *mat * box[i]; + #else + RwV3dTransformPoints(box, box, 8, (RwMatrix*)mat); + #endif +#endif for(i = 0; i < 8; i++){ if(box[i].y < CDraw::GetNearClipZ()) frustumTests[0]++; diff --git a/src/core/Camera.h b/src/core/Camera.h index 0797db9b..d7293e20 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -213,7 +213,9 @@ public: void PrintMode(void); void Process_Debug(const CVector&, float, float, float); +#ifdef GTA_SCENE_EDIT void Process_Editor(const CVector&, float, float, float); +#endif void Process_ModelView(const CVector &CameraTarget, float, float, float); void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float); @@ -639,7 +641,11 @@ public: bool IsPointVisible(const CVector ¢er, const CMatrix *mat); bool IsSphereVisible(const CVector ¢er, float radius, const CMatrix *mat); bool IsSphereVisible(const CVector ¢er, float radius); - bool IsBoxVisible(RwV3d *box, const CMatrix *mat); +#ifdef GTA_PS2 + bool IsBoxVisible(CVuVector *box, const CMatrix *mat); +#else + bool IsBoxVisible(CVector *box, const CMatrix *mat); +#endif }; VALIDATE_SIZE(CCamera, 0xE9D8); diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp index f987dea5..da85a238 100644 --- a/src/core/CdStream.cpp +++ b/src/core/CdStream.cpp @@ -7,9 +7,6 @@ #include "RwHelper.h" #include "MemoryMgr.h" -#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) -#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) - struct CdReadInfo { uint32 nSectorOffset; @@ -60,7 +57,7 @@ CdStreamInitThread(void) if ( gpReadInfo[i].hSemaphore == nil ) { - CDTRACE("failed to create sync semaphore"); + printf("%s: failed to create sync semaphore\n", "cdvd_stream"); ASSERT(0); return; } @@ -73,11 +70,15 @@ CdStreamInitThread(void) gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); +#ifdef FIX_BUGS + gCdStreamSema = CreateSemaphore(nil, 0, 5, nil); +#else gCdStreamSema = CreateSemaphore(nil, 0, 5, "CdStream"); +#endif if ( gCdStreamSema == nil ) { - CDTRACE("failed to create stream semaphore"); + printf("%s: failed to create stream semaphore\n", "cdvd_stream"); ASSERT(0); return; } @@ -86,7 +87,7 @@ CdStreamInitThread(void) if ( _gCdStreamThread == nil ) { - CDTRACE("failed to create streaming thread"); + printf("%s: failed to create streaming thread\n", "cdvd_stream"); ASSERT(0); return; } @@ -134,7 +135,7 @@ CdStreamInit(int32 numChannels) gpReadInfo = (CdReadInfo *)LocalAlloc(LMEM_ZEROINIT, sizeof(CdReadInfo) * numChannels); ASSERT( gpReadInfo != nil ); - CDDEBUG("read info %p", gpReadInfo); + debug("%s: read info %p\n", "cdvd_stream", gpReadInfo); CdStreamAddImage("MODELS\\GTA3.IMG"); diff --git a/src/core/CdStream.h b/src/core/CdStream.h index d0f9a855..516cef48 100644 --- a/src/core/CdStream.h +++ b/src/core/CdStream.h @@ -43,6 +43,6 @@ char *CdStreamGetImageName(int32 cd); void CdStreamRemoveImages(void); int32 CdStreamGetNumImages(void); -#ifndef _WIN32 +#ifdef FLUSHABLE_STREAMING extern bool flushStream[MAX_CDCHANNELS]; #endif diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp index 0854d850..e18280e5 100644 --- a/src/core/CdStreamPosix.cpp +++ b/src/core/CdStreamPosix.cpp @@ -21,9 +21,9 @@ #define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) #define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__) -// #define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash. (Also you may want to benefit from this via using all channels in Streaming.cpp) - +#ifdef FLUSHABLE_STREAMING bool flushStream[MAX_CDCHANNELS]; +#endif struct CdReadInfo { @@ -76,7 +76,7 @@ CdStreamInitThread(void) gChannelRequestQ.tail = 0; gChannelRequestQ.size = gNumChannels + 1; ASSERT(gChannelRequestQ.items != nil ); - gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 1); + gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 0); if (gCdStreamSema == SEM_FAILED) { @@ -91,7 +91,7 @@ CdStreamInitThread(void) for ( int32 i = 0; i < gNumChannels; i++ ) { sprintf(semName,"/semaphore_done%d",i); - gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 1); + gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 0); if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED) { @@ -99,9 +99,10 @@ CdStreamInitThread(void) ASSERT(0); return; } + #ifdef ONE_THREAD_PER_CHANNEL sprintf(semName,"/semaphore_start%d",i); - gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 1); + gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 0); if (gpReadInfo[i].pStartSemaphore == SEM_FAILED) { @@ -170,6 +171,7 @@ CdStreamInit(int32 numChannels) gNumImages = 0; gNumChannels = numChannels; + ASSERT( gNumChannels != 0 ); gpReadInfo = (CdReadInfo *)calloc(numChannels, sizeof(CdReadInfo)); ASSERT( gpReadInfo != nil ); @@ -245,10 +247,12 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size) if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) { if (pChannel->hFile == hImage - 1 && pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size) return STREAM_SUCCESS; - +#ifdef FLUSHABLE_STREAMING flushStream[channel] = 1; CdStreamSync(channel); - //return STREAM_NONE; +#else + return STREAM_NONE; +#endif } pChannel->hFile = hImage - 1; @@ -316,34 +320,34 @@ CdStreamSync(int32 channel) CdReadInfo *pChannel = &gpReadInfo[channel]; ASSERT( pChannel != nil ); +#ifdef FLUSHABLE_STREAMING if (flushStream[channel]) { -#ifdef ONE_THREAD_PER_CHANNEL pChannel->nSectorsToRead = 0; +#ifdef ONE_THREAD_PER_CHANNEL pthread_kill(pChannel->pChannelThread, SIGUSR1); if (pChannel->bReading) { pChannel->bLocked = true; - while (pChannel->bLocked) - sem_wait(pChannel->pDoneSemaphore); - } #else - pChannel->nSectorsToRead = 0; if (pChannel->bReading) { pChannel->bLocked = true; pthread_kill(_gCdStreamThread, SIGUSR1); +#endif while (pChannel->bLocked) sem_wait(pChannel->pDoneSemaphore); } -#endif pChannel->bReading = false; flushStream[channel] = false; return STREAM_NONE; } +#endif if ( pChannel->nSectorsToRead != 0 ) { pChannel->bLocked = true; - while (pChannel->bLocked) + while (pChannel->bLocked && pChannel->nSectorsToRead != 0){ sem_wait(pChannel->pDoneSemaphore); + } + pChannel->bLocked = false; } pChannel->bReading = false; @@ -395,7 +399,12 @@ void *CdStreamThread(void *param) #ifndef ONE_THREAD_PER_CHANNEL while (gCdStreamThreadStatus != 2) { sem_wait(gCdStreamSema); + int32 channel = GetFirstInQueue(&gChannelRequestQ); + + // spurious wakeup + if (channel == -1) + continue; #else int channel = *((int*)param); while (gpReadInfo[channel].nThreadStatus != 2){ @@ -447,7 +456,7 @@ void *CdStreamThread(void *param) if ( pChannel->bLocked ) { pChannel->bLocked = 0; - sem_post(pChannel->pDoneSemaphore); + sem_post(pChannel->pDoneSemaphore); } pChannel->bReading = false; } @@ -524,7 +533,9 @@ void CdStreamRemoveImages(void) { for ( int32 i = 0; i < gNumChannels; i++ ) { +#ifdef FLUSHABLE_STREAMING flushStream[i] = 1; +#endif CdStreamSync(i); } diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index cadba7f2..83d0f669 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -1,11 +1,7 @@ -#if defined RW_D3D9 || defined RWLIBS -#define DIRECTINPUT_VERSION 0x0800 -#include <dinput.h> -#endif - +#define WITHDINPUT #include "common.h" #include "platform.h" -#include "crossplatform.h" // for Windows version +#include "crossplatform.h" #include "ControllerConfig.h" #include "Pad.h" #include "FileMgr.h" @@ -35,6 +31,9 @@ CControllerConfigManager::CControllerConfigManager() void CControllerConfigManager::MakeControllerActionsBlank() { +#ifdef LOAD_INI_SETTINGS + ms_padButtonsInited = 0; +#endif for (int32 i = 0; i < MAX_CONTROLLERTYPES; i++) { for (int32 j = 0; j < MAX_CONTROLLERACTIONS; j++) @@ -132,6 +131,10 @@ void CControllerConfigManager::LoadSettings(int32 file) { bool bValid = true; +#ifdef BIND_VEHICLE_FIREWEAPON + bool skipVehicleFireWeapon = false; +#endif + if (file) { char buff[29]; @@ -139,18 +142,55 @@ void CControllerConfigManager::LoadSettings(int32 file) if (!strncmp(buff, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1)) bValid = false; - else + else { CFileMgr::Seek(file, 0, 0); + +#ifdef BIND_VEHICLE_FIREWEAPON + // HACK! + // All of this is hacky as fuck. + // We are checking the file size to read the .set file correctly. + // But because .set file is opened in text mode we have to read + // the WHOLE file to get the size we should be working with. + // Joy, ain't it? + char tempBuf[0x1000]; + size_t fileSize = 0, blockSize; + do + { + blockSize = CFileMgr::Read(file, tempBuf, sizeof(tempBuf)); + fileSize += blockSize; + } while (blockSize == sizeof(tempBuf)); + + CFileMgr::Seek(file, 0, 0); + + if (fileSize == 0x671) + skipVehicleFireWeapon = true; +#endif + } } if (bValid) { ControlsManager.MakeControllerActionsBlank(); +#ifdef BIND_VEHICLE_FIREWEAPON + // Set the default settings of VEHICLE_FIREWEAPON + if (skipVehicleFireWeapon) { + SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, rsPADINS, KEYBOARD); + SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, rsLCTRL, OPTIONAL_EXTRA); + if (m_bMouseAssociated) + SetMouseButtonAssociatedWithAction(VEHICLE_FIREWEAPON, 1); + } +#endif + for (int32 i = 0; i < MAX_CONTROLLERTYPES; i++) { for (int32 j = 0; j < MAX_CONTROLLERACTIONS; j++) { +#ifdef BIND_VEHICLE_FIREWEAPON + // Skip file read + if (skipVehicleFireWeapon && j == VEHICLE_FIREWEAPON) + continue; +#endif CFileMgr::Read(file, (char *)&ControlsManager.m_aSettings[j][i], sizeof(tControllerConfigBind)); } } @@ -308,6 +348,10 @@ void CControllerConfigManager::InitDefaultControlConfigMouse(CMouseControllerSta } } +#ifdef LOAD_INI_SETTINGS +uint32 CControllerConfigManager::ms_padButtonsInited = 0; +#endif + void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) { m_bFirstCapture = true; @@ -316,6 +360,22 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) if (buttons > 16) btn = 16; +#ifdef LOAD_INI_SETTINGS + uint32 buttonMin = ms_padButtonsInited; + if (buttonMin >= btn) + return; + + ms_padButtonsInited = btn; + + #define IF_BTN_IN_RANGE(n) \ + case n: \ + if (n <= buttonMin) \ + return; +#else + #define IF_BTN_IN_RANGE(n) \ + case n: +#endif + // Now we use SDL Game Controller DB #if defined RW_D3D9 || defined RWLIBS if ( AllValidWinJoys.m_aJoys[JOYSTICK1].m_nVendorID == 0x3427 @@ -328,49 +388,49 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) switch (btn) { - case 16: + IF_BTN_IN_RANGE(16) SetControllerKeyAssociatedWithAction(GO_LEFT, 16, JOYSTICK); - case 15: + IF_BTN_IN_RANGE(15) SetControllerKeyAssociatedWithAction(GO_BACK, 15, JOYSTICK); - case 14: + IF_BTN_IN_RANGE(14) SetControllerKeyAssociatedWithAction(GO_RIGHT, 14, JOYSTICK); - case 13: + IF_BTN_IN_RANGE(13) SetControllerKeyAssociatedWithAction(GO_FORWARD, 13, JOYSTICK); - case 12: - case 11: + IF_BTN_IN_RANGE(12) + IF_BTN_IN_RANGE(11) SetControllerKeyAssociatedWithAction(PED_LOOKBEHIND, 11, JOYSTICK); SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); - case 10: + IF_BTN_IN_RANGE(10) SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); - case 9: + IF_BTN_IN_RANGE(9) SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); - case 8: + IF_BTN_IN_RANGE(8) SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); - case 7: + IF_BTN_IN_RANGE(7) SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); - case 6: + IF_BTN_IN_RANGE(6) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKRIGHT, 6, JOYSTICK); - case 5: + IF_BTN_IN_RANGE(5) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, 5, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKLEFT, 5, JOYSTICK); /*******************************************************************************************/ - case 4: + IF_BTN_IN_RANGE(4) SetControllerKeyAssociatedWithAction(VEHICLE_BRAKE, 4, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_JUMPING, 4, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_IN, 4, JOYSTICK); - case 3: + IF_BTN_IN_RANGE(3) SetControllerKeyAssociatedWithAction(VEHICLE_ACCELERATE, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SPRINT, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, 3, JOYSTICK); - case 2: + IF_BTN_IN_RANGE(2) SetControllerKeyAssociatedWithAction(PED_FIREWEAPON, 2, JOYSTICK); #ifdef BIND_VEHICLE_FIREWEAPON SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, 2, JOYSTICK); #endif - case 1: + IF_BTN_IN_RANGE(1) SetControllerKeyAssociatedWithAction(VEHICLE_ENTER_EXIT, 1, JOYSTICK); /*******************************************************************************************/ } @@ -379,46 +439,46 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons) { switch (btn) { - case 16: + IF_BTN_IN_RANGE(16) SetControllerKeyAssociatedWithAction(GO_LEFT, 16, JOYSTICK); - case 15: + IF_BTN_IN_RANGE(15) SetControllerKeyAssociatedWithAction(GO_BACK, 15, JOYSTICK); - case 14: + IF_BTN_IN_RANGE(14) SetControllerKeyAssociatedWithAction(GO_RIGHT, 14, JOYSTICK); - case 13: + IF_BTN_IN_RANGE(13) SetControllerKeyAssociatedWithAction(GO_FORWARD, 13, JOYSTICK); - case 12: - case 11: + IF_BTN_IN_RANGE(12) + IF_BTN_IN_RANGE(11) SetControllerKeyAssociatedWithAction(PED_LOOKBEHIND, 11, JOYSTICK); SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK); - case 10: + IF_BTN_IN_RANGE(10) SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK); - case 9: + IF_BTN_IN_RANGE(9) SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK); - case 8: + IF_BTN_IN_RANGE(8) SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK); - case 7: + IF_BTN_IN_RANGE(7) SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK); - case 6: + IF_BTN_IN_RANGE(6) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKRIGHT, 6, JOYSTICK); - case 5: + IF_BTN_IN_RANGE(5) SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_LEFT, 5, JOYSTICK); SetControllerKeyAssociatedWithAction(VEHICLE_LOOKLEFT, 5, JOYSTICK); /*******************************************************************************************/ - case 4: + IF_BTN_IN_RANGE(4) SetControllerKeyAssociatedWithAction(VEHICLE_ENTER_EXIT, 4, JOYSTICK); - case 3: + IF_BTN_IN_RANGE(3) SetControllerKeyAssociatedWithAction(VEHICLE_BRAKE, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_JUMPING, 3, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_IN, 3, JOYSTICK); - case 2: + IF_BTN_IN_RANGE(2) SetControllerKeyAssociatedWithAction(VEHICLE_ACCELERATE, 2, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SPRINT, 2, JOYSTICK); SetControllerKeyAssociatedWithAction(PED_SNIPER_ZOOM_OUT, 2, JOYSTICK); - case 1: + IF_BTN_IN_RANGE(1) SetControllerKeyAssociatedWithAction(PED_FIREWEAPON, 1, JOYSTICK); #ifdef BIND_VEHICLE_FIREWEAPON SetControllerKeyAssociatedWithAction(VEHICLE_FIREWEAPON, 1, JOYSTICK); @@ -1718,6 +1778,52 @@ void CControllerConfigManager::DeleteMatching1rstPersonControls(e_ControllerActi #undef CLEAR_ACTION_IF_NEEDED +#ifdef RADIO_SCROLL_TO_PREV_STATION +#define CHECK_ACTION(action) \ +if (key == GetControllerKeyAssociatedWithAction(action, type))\ + return true; + +bool CControllerConfigManager::IsAnyVehicleActionAssignedToMouseKey(int32 key) +{ + const eControllerType type = MOUSE; + if (!GetIsKeyBlank(key, type)) + { +#ifdef BIND_VEHICLE_FIREWEAPON + CHECK_ACTION(VEHICLE_FIREWEAPON); +#endif + CHECK_ACTION(VEHICLE_LOOKBEHIND); + CHECK_ACTION(VEHICLE_LOOKLEFT); + CHECK_ACTION(VEHICLE_LOOKRIGHT); + CHECK_ACTION(VEHICLE_LOOKBEHIND); // note: duplicate + CHECK_ACTION(VEHICLE_HORN); + CHECK_ACTION(VEHICLE_HANDBRAKE); + CHECK_ACTION(VEHICLE_ACCELERATE); + CHECK_ACTION(VEHICLE_BRAKE); + CHECK_ACTION(VEHICLE_CHANGE_RADIO_STATION); + CHECK_ACTION(TOGGLE_SUBMISSIONS); + CHECK_ACTION(VEHICLE_TURRETLEFT); + CHECK_ACTION(VEHICLE_TURRETRIGHT); + CHECK_ACTION(VEHICLE_TURRETUP); + CHECK_ACTION(VEHICLE_TURRETDOWN); + CHECK_ACTION(VEHICLE_ENTER_EXIT); + CHECK_ACTION(CAMERA_CHANGE_VIEW_ALL_SITUATIONS); +#ifndef BIND_VEHICLE_FIREWEAPON + CHECK_ACTION(PED_FIREWEAPON); +#endif + CHECK_ACTION(GO_LEFT); + CHECK_ACTION(GO_RIGHT); + CHECK_ACTION(NETWORK_TALK); + CHECK_ACTION(SWITCH_DEBUG_CAM_ON); + CHECK_ACTION(TOGGLE_DPAD); + CHECK_ACTION(TAKE_SCREEN_SHOT); + CHECK_ACTION(SHOW_MOUSE_POINTER_TOGGLE); + } + return false; +} + +#undef CHECK_ACTION +#endif + void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction action, int32 key, eControllerType type) { if (!GetIsKeyBlank(key, type)) @@ -2513,11 +2619,6 @@ const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O #define PS2_CIRCLE "|" #define PS2_CROSS "/" #define PS2_SQUARE "^" -#elif defined(BUTTON_ICONS) -#define PS2_TRIANGLE "~T~" -#define PS2_CIRCLE "~O~" -#define PS2_CROSS "~X~" -#define PS2_SQUARE "~Q~" #else #define PS2_TRIANGLE "TRIANGLE" #define PS2_CIRCLE "CIRCLE" @@ -2530,7 +2631,7 @@ const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] = #ifdef BUTTON_ICONS const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] = - CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT"); + CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT"); #endif #undef PS2_TRIANGLE @@ -2547,11 +2648,36 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar * if (CPad::GetPad(0)->IsAffectedByController) { wchar wstr[16]; - // TODO: INI and/or menu setting for Xbox/PS switch + const char* (*Buttons)[MAX_CONTROLLERACTIONS]; + #ifdef BUTTON_ICONS - const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons; + #ifdef GAMEPAD_MENU + switch (FrontEndMenuManager.m_PrefsControllerType) + { + case CMenuManager::CONTROLLER_DUALSHOCK2: + case CMenuManager::CONTROLLER_DUALSHOCK3: + case CMenuManager::CONTROLLER_DUALSHOCK4: + Buttons = CFont::ButtonsSlot != -1 ? PlayStationButtons : PlayStationButtons_noIcons; + break; + default: + #endif + Buttons = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons; + #ifdef GAMEPAD_MENU + break; + } + #endif #else - const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons; + switch (FrontEndMenuManager.m_PrefsControllerType) + { + case CMenuManager::CONTROLLER_DUALSHOCK2: + case CMenuManager::CONTROLLER_DUALSHOCK3: + case CMenuManager::CONTROLLER_DUALSHOCK4: + Buttons = PlayStationButtons_noIcons; + break; + default: + Buttons = XboxButtons_noIcons; + break; + } #endif assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these @@ -2678,9 +2804,10 @@ wchar *CControllerConfigManager::GetButtonComboText(e_ControllerAction action) void CControllerConfigManager::SetControllerKeyAssociatedWithAction(e_ControllerAction action, int32 key, eControllerType type) { ResetSettingOrder(action); + int numOfSettings = GetNumOfSettingsForAction(action); m_aSettings[action][type].m_Key = key; - m_aSettings[action][type].m_ContSetOrder = GetNumOfSettingsForAction(action) + 1; + m_aSettings[action][type].m_ContSetOrder = numOfSettings + 1; } int32 CControllerConfigManager::GetMouseButtonAssociatedWithAction(e_ControllerAction action) @@ -2690,8 +2817,10 @@ int32 CControllerConfigManager::GetMouseButtonAssociatedWithAction(e_ControllerA void CControllerConfigManager::SetMouseButtonAssociatedWithAction(e_ControllerAction action, int32 button) { + int numOfSettings = GetNumOfSettingsForAction(action); + m_aSettings[action][MOUSE].m_Key = button; - m_aSettings[action][MOUSE].m_ContSetOrder = GetNumOfSettingsForAction(action) + 1; + m_aSettings[action][MOUSE].m_ContSetOrder = numOfSettings + 1; } void CControllerConfigManager::ResetSettingOrder(e_ControllerAction action) @@ -2714,7 +2843,7 @@ void CControllerConfigManager::ResetSettingOrder(e_ControllerAction action) for (int32 k = 0; k < MAX_CONTROLLERTYPES; k++) { int32 setorder = m_aSettings[action][k].m_ContSetOrder; - if (setorder > i && setorder != KEYBOARD) + if (setorder > i && setorder != 0) { if (init) { diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h index 92017a93..295f03b9 100644 --- a/src/core/ControllerConfig.h +++ b/src/core/ControllerConfig.h @@ -141,6 +141,10 @@ public: tControllerConfigBind m_aSettings[MAX_CONTROLLERACTIONS][MAX_CONTROLLERTYPES]; bool m_aSimCheckers[MAX_SIMS][MAX_CONTROLLERTYPES]; bool m_bMouseAssociated; + +#ifdef LOAD_INI_SETTINGS + static uint32 ms_padButtonsInited; +#endif CControllerConfigManager(); @@ -188,6 +192,10 @@ public: void DeleteMatching1rstPersonControls (e_ControllerAction action, int32 key, eControllerType type); void DeleteMatchingActionInitiators (e_ControllerAction action, int32 key, eControllerType type); +#ifdef RADIO_SCROLL_TO_PREV_STATION + bool IsAnyVehicleActionAssignedToMouseKey(int32 key); +#endif + bool GetIsKeyBlank(int32 key, eControllerType type); e_ControllerActionType GetActionType(e_ControllerAction action); diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp index 8d69ba78..93f72d4e 100644 --- a/src/core/EventList.cpp +++ b/src/core/EventList.cpp @@ -120,7 +120,7 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent } if(criminal == FindPlayerPed()) - ReportCrimeForEvent(type, (uintptr)ent, copsDontCare); + ReportCrimeForEvent(type, (intptr)ent, copsDontCare); } void @@ -198,7 +198,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event) } void -CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCare) +CEventList::ReportCrimeForEvent(eEventType type, intptr crimeId, bool copsDontCare) { eCrimeType crime; switch(type){ diff --git a/src/core/EventList.h b/src/core/EventList.h index 8840afc4..4ced3a83 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -59,7 +59,7 @@ public: static bool GetEvent(eEventType type, int32 *event); static void ClearEvent(int32 event); static bool FindClosestEvent(eEventType type, CVector posn, int32 *event); - static void ReportCrimeForEvent(eEventType type, int32, bool); + static void ReportCrimeForEvent(eEventType type, intptr, bool); }; extern CEvent gaEvent[NUMEVENTS];
\ No newline at end of file diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 88a99fa9..22e0159c 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -59,14 +59,24 @@ CFileLoader::LoadLevel(const char *filename) savedTxd = RwTexDictionaryCreate(); RwTexDictionarySetCurrent(savedTxd); } +#if GTA_VERSION <= GTA3_PS2_160 + CFileMgr::ChangeDir("\\DATA\\"); fd = CFileMgr::OpenFile(filename, "r"); + CFileMgr::ChangeDir("\\"); +#else + fd = CFileMgr::OpenFile(filename, "r"); +#endif assert(fd > 0); for(line = LoadLine(fd); line; line = LoadLine(fd)){ if(*line == '#') continue; - if(strncmp(line, "EXIT", 9) == 0) // BUG: 9? +#ifdef FIX_BUGS + if(strncmp(line, "EXIT", 4) == 0) +#else + if(strncmp(line, "EXIT", 9) == 0) +#endif break; if(strncmp(line, "IMAGEPATH", 9) == 0){ @@ -114,8 +124,10 @@ CFileLoader::LoadLevel(const char *filename) #ifndef DISABLE_LOADING_SCREEN LoadSplash(GetRandomSplashScreen()); #endif +#ifndef GTA_PS2 }else if(strncmp(line, "CDIMAGE", 7) == 0){ CdStreamAddImage(line + 8); +#endif } } @@ -183,7 +195,7 @@ CFileLoader::LoadTexDictionary(const char *filename) struct ColHeader { - char ident[4]; + uint32 ident; uint32 size; }; @@ -201,7 +213,7 @@ CFileLoader::LoadCollisionFile(const char *filename) fd = CFileMgr::OpenFile(filename, "rb"); while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){ - assert(strncmp(header.ident, "COLL", 4) == 0); + assert(header.ident == 'LLOC'); CFileMgr::Read(fd, (char*)work_buff, header.size); memcpy(modelname, work_buff, 24); @@ -243,6 +255,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 44; if(model.numSpheres > 0){ model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere)); + REGISTER_MEMPTR(&model.spheres); for(i = 0; i < model.numSpheres; i++){ model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]); buf += 20; @@ -254,6 +267,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(model.numLines > 0){ model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine)); + REGISTER_MEMPTR(&model.lines); for(i = 0; i < model.numLines; i++){ model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12)); buf += 24; @@ -265,6 +279,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(model.numBoxes > 0){ model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox)); + REGISTER_MEMPTR(&model.boxes); for(i = 0; i < model.numBoxes; i++){ model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]); buf += 28; @@ -276,6 +291,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(numVertices > 0){ model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector)); + REGISTER_MEMPTR(&model.vertices); for(i = 0; i < numVertices; i++){ model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8)); if(Abs(*(float*)buf) >= 256.0f || @@ -291,6 +307,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname) buf += 4; if(model.numTriangles > 0){ model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle)); + REGISTER_MEMPTR(&model.triangles); for(i = 0; i < model.numTriangles; i++){ model.triangles[i].Set(model.vertices, *(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12], buf[13]); buf += 16; @@ -428,7 +445,7 @@ bool CFileLoader::StartLoadClumpFile(RwStream *stream, uint32 id) { if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){ - printf("Start loading %s\n", CModelInfo::GetModelInfo(id)->GetName()); + printf("Start loading %s\n", CModelInfo::GetModelInfo(id)->GetModelName()); return RpClumpGtaStreamRead1(stream); }else{ printf("FAILED\n"); @@ -442,7 +459,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id) RpClump *clump; CClumpModelInfo *mi; - printf("Finish loading %s\n", CModelInfo::GetModelInfo(id)->GetName()); + printf("Finish loading %s\n", CModelInfo::GetModelInfo(id)->GetModelName()); clump = RpClumpGtaStreamRead2(stream); if(clump){ @@ -540,7 +557,6 @@ char *DoubleSidedNames[] = { "overpass_comse", "newdockbuilding", "newdockbuilding2", - "newdockbuilding", "policeballhall", "fuzballdoor", "ind_land106", @@ -564,7 +580,98 @@ char *DoubleSidedNames[] = { "railtrax_2b", "railtrax_straightss", "railtrax_bentr", + "ind_land125", + "salvstrans", + "bridge_liftsec", + "subsign1", + "carparkfence", + "newairportwall4", + "apair_terminal", + "Helipad", + "bar_barrier10", + "damissionfence", + "sub_floodlite", + "suburbbridge1", + "damfencing", + "demfence08", + "damfence07", + "damfence06", + "damfence05", + "damfence04", + "damfence03", + "damfence02", + "damfence01", + "Dam_pod2", + "Dam_pod1", + "columansion_wall", + "wrckdhse020", + "wrckdhse01", + "arc_bridge", + "gRD_overpass19kbc", + "gRD_overpass19bkb", + "gRD_overpass19kb", + "gRD_overpass18kb", + "road_under", + "com_roadkb23", + "com_roadkb22", + "nbbridgerda", + "nbbridgerdb", + "policetenkb1", + "block3_scraper2", + "Clnm_cthdrlfcde", + "broadwaybuild", + "combillboard03", + "com_park3b", + "com_docksaa", + "newdockbuilding2", + "com_roadkb22", + "sidebarrier_gaz2", + "tunnelsupport1", + "skyscrpunbuilt2", + "cons_buid02", + "rail_platformw", + "railtrax_bent1", + "nrailstepswest", + "building_fucked", + "franksclb02", + "salvsdetail", + "crgoshp01", + "shp_wlkway", + "bar_barriergate1", + "plnt_pylon01", + "fishfctory", + "doc_crane_cab", + "nrailsteps", + "iten_club01", + "mak_Watertank", + "basketballcourt" + "carlift01", + "carlift02", + "iten_chinatown4", + "iten_details7", + "ind_customroad002" + "ind_brgrd1way", + "ind_customroad060", + "ind_customroad002", + "ind_land108", + "ind_customroad004", + "ind_customroad003", + "nbbridgcabls01", + "sbwy_tunl_bit", + "sbwy_tunl_bend", + "sbwy_tunl_cstm11", + "sbwy_tunl_cstm10", + "sbwy_tunl_cstm9", + "sbwy_tunl_cstm8", + "sbwy_tunl_cstm7", + "sbwy_tunl_cstm6", + "sbwy_tunl_cstm5", + "sbwy_tunl_cstm4", + "sbwy_tunl_cstm3", + "sbwy_tunl_cstm2", + "sbwy_tunl_cstm1", "" + }; char *TreeNames[] = { "coast_treepatch", @@ -850,6 +957,9 @@ CFileLoader::AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src) RwTexDictionaryForAllTextures(src, MoveTexturesCB, dst); } +#define isLine3(l, a, b, c) ((l[0] == a) && (l[1] == b) && (l[2] == c)) +#define isLine4(l, a, b, c, d) ((l[0] == a) && (l[1] == b) && (l[2] == c) && (l[3] == d)) + void CFileLoader::LoadObjectTypes(const char *filename) { @@ -883,18 +993,18 @@ CFileLoader::LoadObjectTypes(const char *filename) continue; if(section == NONE){ - if(strncmp(line, "objs", 4) == 0) section = OBJS; - else if(strncmp(line, "tobj", 4) == 0) section = TOBJ; - else if(strncmp(line, "hier", 4) == 0) section = HIER; - else if(strncmp(line, "cars", 4) == 0) section = CARS; - else if(strncmp(line, "peds", 4) == 0) section = PEDS; - else if(strncmp(line, "path", 4) == 0) section = PATH; - else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX; - }else if(strncmp(line, "end", 3) == 0){ + if(isLine4(line, 'o','b','j','s')) section = OBJS; + else if(isLine4(line, 't','o','b','j')) section = TOBJ; + else if(isLine4(line, 'h','i','e','r')) section = HIER; + else if(isLine4(line, 'c','a','r','s')) section = CARS; + else if(isLine4(line, 'p','e','d','s')) section = PEDS; + else if(isLine4(line, 'p','a','t','h')) section = PATH; + else if(isLine4(line, '2','d','f','x')) section = TWODFX; + }else if(isLine3(line, 'e','n','d')){ section = section == MLO ? OBJS : NONE; }else switch(section){ case OBJS: - if(strncmp(line, "sta", 3) == 0) + if(isLine3(line, 's','t','a')) mlo = LoadMLO(line); else LoadObject(line); @@ -917,9 +1027,9 @@ CFileLoader::LoadObjectTypes(const char *filename) case PATH: if(pathIndex == -1){ id = LoadPathHeader(line, pathTypeStr); - if(strncmp(pathTypeStr, "ped", 4) == 0) + if(strcmp(pathTypeStr, "ped") == 0) pathType = 1; - else if(strncmp(pathTypeStr, "car", 4) == 0) + else if(strcmp(pathTypeStr, "car") == 0) pathType = 0; pathIndex = 0; }else{ @@ -965,9 +1075,9 @@ SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags) #ifdef HARDCODED_MODEL_FLAGS // mobile sets these flags in CFileLoader::SetRelatedModelInfoCB, but that's stupid - if(MatchModelName(mi->GetName(), DoubleSidedNames)) mi->m_bIsDoubleSided = true; - if(MatchModelName(mi->GetName(), TreeNames)) mi->m_bIsTree = true; - if(MatchModelName(mi->GetName(), OptimizedNames)) mi->m_bCanBeIgnored = true; + if(MatchModelName(mi->GetModelName(), DoubleSidedNames)) mi->m_bIsDoubleSided = true; + if(MatchModelName(mi->GetModelName(), TreeNames)) mi->m_bIsTree = true; + if(MatchModelName(mi->GetModelName(), OptimizedNames)) mi->m_bCanBeIgnored = true; #endif #endif @@ -1009,7 +1119,7 @@ CFileLoader::LoadObject(const char *line) } mi = CModelInfo::AddSimpleModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetNumAtomics(numObjs); mi->SetLodDistances(dist); SetModelInfoFlags(mi, flags); @@ -1028,7 +1138,7 @@ CFileLoader::LoadMLO(const char *line) sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat); CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex); - minfo->SetName(name); + minfo->SetModelName(name); minfo->field_34 = someFloat; int instId = CModelInfo::GetMloInstanceStore().allocPtr; minfo->firstInstance = instId; @@ -1054,7 +1164,7 @@ CFileLoader::LoadMLOInstance(int id, const char *line) &rot.x, &rot.y, &rot.z, &angle); float rad = Acos(angle) * 2.0f; - CInstance *inst = CModelInfo::GetMloInstanceStore().alloc(); + CInstance *inst = CModelInfo::GetMloInstanceStore().Alloc(); minfo->lastInstance++; RwMatrix *matrix = RwMatrixCreate(); @@ -1106,7 +1216,7 @@ CFileLoader::LoadTimeObject(const char *line) } mi = CModelInfo::AddTimeModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetNumAtomics(numObjs); mi->SetLodDistances(dist); SetModelInfoFlags(mi, flags); @@ -1128,7 +1238,7 @@ CFileLoader::LoadClumpObject(const char *line) if(sscanf(line, "%d %s %s", &id, model, txd) == 3){ mi = CModelInfo::AddClumpModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetTexDictionary(txd); mi->SetColModel(&CTempColModels::ms_colModelBBox); } @@ -1152,7 +1262,7 @@ CFileLoader::LoadVehicleObject(const char *line) &frequency, &level, &comprules, &misc, &wheelScale); mi = CModelInfo::AddVehicleModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetTexDictionary(txd); for(p = gamename; *p; p++) if(*p == '_') *p = ' '; @@ -1160,21 +1270,21 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_level = level; mi->m_compRules = comprules; - if(strncmp(type, "car", 4) == 0){ + if(strcmp(type, "car") == 0){ mi->m_wheelId = misc; mi->m_wheelScale = wheelScale; mi->m_vehicleType = VEHICLE_TYPE_CAR; - }else if(strncmp(type, "boat", 5) == 0){ + }else if(strcmp(type, "boat") == 0){ mi->m_vehicleType = VEHICLE_TYPE_BOAT; - }else if(strncmp(type, "train", 6) == 0){ + }else if(strcmp(type, "train") == 0){ mi->m_vehicleType = VEHICLE_TYPE_TRAIN; - }else if(strncmp(type, "heli", 5) == 0){ + }else if(strcmp(type, "heli") == 0){ mi->m_vehicleType = VEHICLE_TYPE_HELI; - }else if(strncmp(type, "plane", 6) == 0){ + }else if(strcmp(type, "plane") == 0){ mi->m_planeLodId = misc; mi->m_wheelScale = 1.0f; mi->m_vehicleType = VEHICLE_TYPE_PLANE; - }else if(strncmp(type, "bike", 5) == 0){ + }else if(strcmp(type, "bike") == 0){ mi->m_bikeSteerAngle = misc; mi->m_wheelScale = wheelScale; mi->m_vehicleType = VEHICLE_TYPE_BIKE; @@ -1184,31 +1294,31 @@ CFileLoader::LoadVehicleObject(const char *line) mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId); // Well this is kinda dumb.... - if(strncmp(vehclass, "poorfamily", 11) == 0){ + if(strcmp(vehclass, "poorfamily") == 0){ mi->m_vehicleClass = CCarCtrl::POOR; while(frequency-- > 0) CCarCtrl::AddToCarArray(id, CCarCtrl::POOR); - }else if(strncmp(vehclass, "richfamily", 11) == 0){ + }else if(strcmp(vehclass, "richfamily") == 0){ mi->m_vehicleClass = CCarCtrl::RICH; while(frequency-- > 0) CCarCtrl::AddToCarArray(id, CCarCtrl::RICH); - }else if(strncmp(vehclass, "executive", 10) == 0){ + }else if(strcmp(vehclass, "executive") == 0){ mi->m_vehicleClass = CCarCtrl::EXEC; while(frequency-- > 0) CCarCtrl::AddToCarArray(id, CCarCtrl::EXEC); - }else if(strncmp(vehclass, "worker", 7) == 0){ + }else if(strcmp(vehclass, "worker") == 0){ mi->m_vehicleClass = CCarCtrl::WORKER; while(frequency-- > 0) CCarCtrl::AddToCarArray(id, CCarCtrl::WORKER); - }else if(strncmp(vehclass, "special", 8) == 0){ + }else if(strcmp(vehclass, "special") == 0){ mi->m_vehicleClass = CCarCtrl::SPECIAL; while(frequency-- > 0) CCarCtrl::AddToCarArray(id, CCarCtrl::SPECIAL); - }else if(strncmp(vehclass, "big", 4) == 0){ + }else if(strcmp(vehclass, "big") == 0){ mi->m_vehicleClass = CCarCtrl::BIG; while(frequency-- > 0) CCarCtrl::AddToCarArray(id, CCarCtrl::BIG); - }else if(strncmp(vehclass, "taxi", 5) == 0){ + }else if(strcmp(vehclass, "taxi") == 0){ mi->m_vehicleClass = CCarCtrl::TAXI; while(frequency-- > 0) CCarCtrl::AddToCarArray(id, CCarCtrl::TAXI); @@ -1231,7 +1341,7 @@ CFileLoader::LoadPedObject(const char *line) return; mi = CModelInfo::AddPedModel(id); - mi->SetName(model); + mi->SetModelName(model); mi->SetTexDictionary(txd); mi->SetColModel(&CTempColModels::ms_colModelPed1); mi->m_pedType = CPedType::FindPedType(pedType); @@ -1294,7 +1404,7 @@ CFileLoader::Load2dEffect(const char *line) CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle")); mi = CModelInfo::GetModelInfo(id); - effect = CModelInfo::Get2dEffectStore().alloc(); + effect = CModelInfo::Get2dEffectStore().Alloc(); mi->Add2dEffect(effect); effect->pos = CVector(x, y, z); effect->col = CRGBA(r, g, b, a); @@ -1389,12 +1499,12 @@ CFileLoader::LoadScene(const char *filename) continue; if(section == NONE){ - if(strncmp(line, "inst", 4) == 0) section = INST; - else if(strncmp(line, "zone", 4) == 0) section = ZONE; - else if(strncmp(line, "cull", 4) == 0) section = CULL; - else if(strncmp(line, "pick", 4) == 0) section = PICK; - else if(strncmp(line, "path", 4) == 0) section = PATH; - }else if(strncmp(line, "end", 3) == 0){ + if(isLine4(line, 'i','n','s','t')) section = INST; + else if(isLine4(line, 'z','o','n','e')) section = ZONE; + else if(isLine4(line, 'c','u','l','l')) section = CULL; + else if(isLine4(line, 'p','i','c','k')) section = PICK; + else if(isLine4(line, 'p','a','t','h')) section = PATH; + }else if(isLine3(line, 'e','n','d')){ section = NONE; }else switch(section){ case INST: @@ -1414,6 +1524,7 @@ CFileLoader::LoadScene(const char *filename) // unfinished in the game if(pathIndex == -1){ LoadPathHeader(line, pathTypeStr); + strcmp(pathTypeStr, "ped"); // type not set pathIndex = 0; }else{ @@ -1551,8 +1662,8 @@ CFileLoader::LoadMapZones(const char *filename) continue; if(section == NONE){ - if(strncmp(line, "zone", 4) == 0) section = ZONE; - }else if(strncmp(line, "end", 3) == 0){ + if(isLine4(line, 'z','o','n','e')) section = ZONE; + }else if(isLine3(line, 'e','n','d')){ section = NONE; }else switch(section){ case ZONE: { @@ -1594,20 +1705,20 @@ CFileLoader::ReloadPaths(const char *filename) continue; if (section == NONE) { - if (strncmp(line, "path", 4) == 0) { + if (isLine4(line, 'p','a','t','h')) { section = PATH; ThePaths.AllocatePathFindInfoMem(4500); } - } else if (strncmp(line, "end", 3) == 0) { + } else if (isLine3(line, 'e','n','d')) { section = NONE; } else { switch (section) { case PATH: if (pathIndex == -1) { id = LoadPathHeader(line, pathTypeStr); - if (strncmp(pathTypeStr, "ped", 4) == 0) + if (strcmp(pathTypeStr, "ped") == 0) pathType = 1; - else if (strncmp(pathTypeStr, "car", 4) == 0) + else if (strcmp(pathTypeStr, "car") == 0) pathType = 0; pathIndex = 0; } else { @@ -1650,10 +1761,10 @@ CFileLoader::ReloadObjectTypes(const char *filename) continue; if (section == NONE) { - if (strncmp(line, "objs", 4) == 0) section = OBJS; - else if (strncmp(line, "tobj", 4) == 0) section = TOBJ; - else if (strncmp(line, "2dfx", 4) == 0) section = TWODFX; - } else if (strncmp(line, "end", 3) == 0) { + if (isLine4(line, 'o','b','j','s')) section = OBJS; + else if (isLine4(line, 't','o','b','j')) section = TOBJ; + else if (isLine4(line, '2','d','f','x')) section = TWODFX; + } else if (isLine3(line, 'e','n','d')) { section = NONE; } else { switch (section) { @@ -1704,7 +1815,7 @@ CFileLoader::ReloadObject(const char *line) #ifdef FIX_BUGS mi && #endif - mi->GetModelType() == MITYPE_SIMPLE && !strcmp(mi->GetName(), model) && mi->m_numAtomics == numObjs) { + mi->GetModelType() == MITYPE_SIMPLE && !strcmp(mi->GetModelName(), model) && mi->m_numAtomics == numObjs) { mi->SetLodDistances(dist); SetModelInfoFlags(mi, flags); } else { @@ -1725,7 +1836,11 @@ CFileLoader::ReLoadScene(const char *filename) if (*line == '#') continue; - if (strncmp(line, "EXIT", 9) == 0) // BUG: 9? +#ifdef FIX_BUGS + if (strncmp(line, "EXIT", 4) == 0) +#else + if (strncmp(line, "EXIT", 9) == 0) +#endif break; if (strncmp(line, "IDE", 3) == 0) { diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp index 6e6a8efc..32aa4041 100644 --- a/src/core/FileMgr.cpp +++ b/src/core/FileMgr.cpp @@ -240,21 +240,24 @@ CFileMgr::SetDirMyDocuments(void) mychdir(_psGetUserFilesFolder()); } -size_t -CFileMgr::LoadFile(const char *file, uint8 *buf, int unused, const char *mode) +ssize_t +CFileMgr::LoadFile(const char *file, uint8 *buf, int maxlen, const char *mode) { int fd; - size_t n, len; + ssize_t n, len; fd = myfopen(file, mode); if(fd == 0) - return 0; + return -1; len = 0; do{ n = myfread(buf + len, 1, 0x4000, fd); - if(n < 0) +#ifndef FIX_BUGS + if (n < 0) return -1; +#endif len += n; + assert(len < maxlen); }while(n == 0x4000); buf[len] = 0; myfclose(fd); @@ -274,13 +277,13 @@ CFileMgr::OpenFileForWriting(const char *file) } size_t -CFileMgr::Read(int fd, const char *buf, int len) +CFileMgr::Read(int fd, const char *buf, ssize_t len) { return myfread((void*)buf, 1, len, fd); } size_t -CFileMgr::Write(int fd, const char *buf, int len) +CFileMgr::Write(int fd, const char *buf, ssize_t len) { return myfwrite((void*)buf, 1, len, fd); } diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h index 4734720e..f70451b7 100644 --- a/src/core/FileMgr.h +++ b/src/core/FileMgr.h @@ -9,12 +9,12 @@ public: static void ChangeDir(const char *dir); static void SetDir(const char *dir); static void SetDirMyDocuments(void); - static size_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode); + static ssize_t LoadFile(const char *file, uint8 *buf, int maxlen, const char *mode); static int OpenFile(const char *file, const char *mode); static int OpenFile(const char *file) { return OpenFile(file, "rb"); } static int OpenFileForWriting(const char *file); - static size_t Read(int fd, const char *buf, int len); - static size_t Write(int fd, const char *buf, int len); + static size_t Read(int fd, const char *buf, ssize_t len); + static size_t Write(int fd, const char *buf, ssize_t len); static bool Seek(int fd, int offset, int whence); static bool ReadLine(int fd, char *buf, int len); static int CloseFile(int fd); diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index c6dece6a..984b21bb 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -43,7 +43,7 @@ CFire::ProcessFire(void) float fDamagePlayer; float fDamagePeds; float fDamageVehicle; - int8 nRandNumber; + int16 nRandNumber; float fGreen; float fRed; CVector lightpos; @@ -90,7 +90,11 @@ CFire::ProcessFire(void) } } } - if (!FindPlayerVehicle() && !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) + if (!FindPlayerVehicle() && +#ifdef FIX_BUGS + FindPlayerPed() && +#endif + !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof) && ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) { FindPlayerPed()->DoStuffToGoOnFire(); gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1); @@ -131,11 +135,10 @@ CFire::ProcessFire(void) CShadows::StoreStaticShadow((uintptr)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos, 7.0f, 0.0f, 0.0f, -7.0f, 0, nRandNumber / 2, nRandNumber / 2, 0, 10.0f, 1.0f, 40.0f, 0, 0.0f); } - fGreen = nRandNumber / 128; - fRed = nRandNumber / 128; + fGreen = nRandNumber / 128.f; + fRed = nRandNumber / 128.f; - CPointLights::AddLight(0, m_vecPos, CVector(0.0f, 0.0f, 0.0f), - 12.0f, fRed, fGreen, 0, 0, 0); + CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0, 0, 0); } else { Extinguish(); } @@ -224,7 +227,7 @@ CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength ped->bDrawLast = false; ped->SetMoveState(PEDMOVE_SPRINT); ped->SetMoveAnim(); - ped->m_nPedState = PED_ON_FIRE; + ped->SetPedState(PED_ON_FIRE); } if (fleeFrom) { if (ped->m_nPedType == PEDTYPE_COP) { @@ -397,7 +400,7 @@ CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strengt CVector2D pos = target->GetPosition(); ped->SetFlee(pos, 10000); ped->SetMoveAnim(); - ped->m_nPedState = PED_ON_FIRE; + ped->SetPedState(PED_ON_FIRE); } } else if (target->IsVehicle()) { veh->m_pCarFire = fire; diff --git a/src/core/FrontEndControls.cpp b/src/core/FrontEndControls.cpp index 68992e16..18f6b3b2 100644 --- a/src/core/FrontEndControls.cpp +++ b/src/core/FrontEndControls.cpp @@ -7,7 +7,7 @@ #include "FrontEndControls.h" #define X SCREEN_SCALE_X -#define Y(x) SCREEN_SCALE_Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(DEFAULT_SCREEN_HEIGHT_PAL))) +#define Y(x) SCREEN_SCALE_Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(SCREEN_HEIGHT_PAL))) void CPlaceableShText::Draw(float x, float y) diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 318e5903..5e9f6d0d 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -1,9 +1,6 @@ -#if defined RW_D3D9 || defined RWLIBS -#define DIRECTINPUT_VERSION 0x0800 -#include <dinput.h> -#endif - +#define FORCE_PC_SCALING #define WITHWINDOWS +#define WITHDINPUT #include "common.h" #ifndef PS2_MENU #include "crossplatform.h" @@ -38,10 +35,35 @@ #include "FileLoader.h" #include "frontendoption.h" +// Game has colors inlined in code. +// For easier modification we collect them here: +const CRGBA LABEL_COLOR(235, 170, 50, 255); +const CRGBA SELECTION_HIGHLIGHTBG_COLOR(100, 200, 50, 50); +const CRGBA MENUOPTION_COLOR = LABEL_COLOR; +const CRGBA SELECTEDMENUOPTION_COLOR(255, 217, 106, 255); +const CRGBA HEADER_COLOR(0, 0, 0, 255); +const CRGBA DARKMENUOPTION_COLOR(155, 117, 6, 255); +const CRGBA SLIDERON_COLOR = SELECTEDMENUOPTION_COLOR; +const CRGBA SLIDEROFF_COLOR(185, 120, 0, 255); +const CRGBA LIST_BACKGROUND_COLOR(200, 200, 50, 50); +const CRGBA LIST_OPTION_COLOR(155, 155, 155, 255); +const CRGBA INACTIVE_RADIO_COLOR(225, 0, 0, 170); +const CRGBA SCROLLBAR_COLOR = LABEL_COLOR; +const CRGBA CONTSETUP_HIGHLIGHTBG_COLOR(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, 210); +const CRGBA CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, 150); + +// This is PS2 menu leftover, and variable name is original. They forgot it here and used in PrintBriefs once (but didn't use the output) +#if defined(FIX_BUGS) && !defined(PS2_LIKE_MENU) +const CRGBA TEXT_COLOR = LABEL_COLOR; +#else +const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); // PS2 option color +#endif + #define TIDY_UP_PBP // ProcessButtonPresses #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result #define SCROLLABLE_PAGES +#define RED_DELETE_BACKGROUND #ifdef SCROLLABLE_STATS_PAGE #define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS) @@ -55,6 +77,7 @@ #ifdef SCROLLABLE_PAGES #define MAX_VISIBLE_OPTION 12 #define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION) +#define SCREEN_HAS_AUTO_SCROLLBAR (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) int GetOptionCount(int screen) { @@ -90,8 +113,6 @@ int GetOptionCount(int screen) #ifdef MENU_MAP bool CMenuManager::bMenuMapActive = false; -bool CMenuManager::bMapMouseShownOnce = false; -bool CMenuManager::bMapLoaded = false; float CMenuManager::fMapSize; float CMenuManager::fMapCenterY; float CMenuManager::fMapCenterX; @@ -120,19 +141,8 @@ int8 CMenuManager::m_nDisplayMSAALevel = 0; int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW; #endif -// 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); -#else -const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color -#endif - -#ifdef USE_PRECISE_MEASUREMENT_CONVERTION -#define MILES_IN_METER 0.000621371192f -#define FEET_IN_METER 3.28084f -#else -#define MILES_IN_METER 0.00059880241f -#define FEET_IN_METER 3.33f +#ifdef GAMEPAD_MENU +int8 CMenuManager::m_PrefsControllerType = CONTROLLER_XBOXONE; #endif int32 CMenuManager::OS_Language = LANG_ENGLISH; @@ -152,7 +162,12 @@ bool CMenuManager::m_PrefsAllowNastyGame = true; bool CMenuManager::m_bStartUpFrontEndRequested; bool CMenuManager::m_bShutDownFrontEndRequested; +#ifdef ASPECT_RATIO_SCALE +int8 CMenuManager::m_PrefsUseWideScreen = AR_AUTO; +#else int8 CMenuManager::m_PrefsUseWideScreen; +#endif + int8 CMenuManager::m_PrefsRadioStation; int32 CMenuManager::m_PrefsBrightness = 256; float CMenuManager::m_PrefsLOD = CRenderer::ms_lodDistScale; @@ -160,7 +175,6 @@ 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; @@ -192,7 +206,6 @@ bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x5F311C const char* FrontendFilenames[][2] = { {"fe2_mainpanel_ul", "" }, {"fe2_mainpanel_ur", "" }, @@ -296,12 +309,33 @@ const char* MenuFilenames[][2] = { m_nMenuFadeAlpha = 0; \ } while(0) -#define PREPARE_MENU_HEADER \ - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \ +#define SET_FONT_FOR_MENU_HEADER \ + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); \ CFont::SetRightJustifyOn(); \ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); +#define RESET_FONT_FOR_NEW_PAGE \ + CFont::SetBackgroundOff(); \ + CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); \ + CFont::SetPropOn(); \ + CFont::SetCentreOff(); \ + CFont::SetJustifyOn(); \ + CFont::SetRightJustifyOff(); \ + CFont::SetBackGroundOnlyTextOn(); \ + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \ + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); + +#define SET_FONT_FOR_HELPER_TEXT \ + CFont::SetCentreOn(); \ + CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + +#define SET_FONT_FOR_LIST_ITEM \ + CFont::SetRightJustifyOff(); \ + CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + #define ProcessSlider(value, 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); \ @@ -321,7 +355,8 @@ const char* MenuFilenames[][2] = { #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(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, INACTIVE_RADIO_COLOR.a)); \ if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \ m_nHoverOption = hoverOpt; \ } while (0) @@ -439,7 +474,7 @@ CMenuManager::ThingsToDoBeforeGoingBack() } #ifdef SCROLLABLE_PAGES - if (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) { + if (SCREEN_HAS_AUTO_SCROLLBAR) { m_nSelectedListRow = 0; m_nFirstVisibleRowOnList = 0; m_nScrollbarTopMargin = 0; @@ -495,6 +530,7 @@ CMenuManager::ProcessList(bool &goBack, bool &optionSelected) m_nTotalListRow = m_nSkinsTotal; } if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { + // GetNumOptionsCntrlConfigScreens would have been a better choice m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25; if (m_nSelectedListRow > m_nTotalListRow) m_nSelectedListRow = m_nTotalListRow - 1; @@ -830,7 +866,11 @@ CMenuManager::CheckCodesForControls(int typeOfControl) m_bWaitingForNewKeyBind = false; m_KeyPressedCode = -1; m_bStartWaitingForKeyBind = false; +#ifdef LOAD_INI_SETTINGS + SaveINIControllerSettings(); +#else SaveSettings(); +#endif } if (escPressed) { @@ -838,7 +878,11 @@ CMenuManager::CheckCodesForControls(int typeOfControl) m_bWaitingForNewKeyBind = false; m_KeyPressedCode = -1; m_bStartWaitingForKeyBind = false; +#ifdef LOAD_INI_SETTINGS + SaveINIControllerSettings(); +#else SaveSettings(); +#endif } } @@ -878,7 +922,11 @@ CMenuManager::CheckSliderMovement(int value) case MENUACTION_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ??? TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f); +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f; +#else TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; +#endif break; default: return; @@ -915,10 +963,7 @@ CMenuManager::DisplayHelperText() alpha = m_nHelperTextAlpha > 255 ? 255 : m_nHelperTextAlpha; } - CFont::SetCentreOn(); - CFont::SetScale(SCREEN_SCALE_X(SMALLESTTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); - + SET_FONT_FOR_HELPER_TEXT // TODO: name this cases? switch (m_nHelperTextMsgId) { case 0: @@ -926,25 +971,25 @@ CMenuManager::DisplayHelperText() int action = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; if (action != MENUACTION_CHANGEMENU && action != MENUACTION_KEYBOARDCTRLS && action != MENUACTION_RESTOREDEF) { CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_MIG")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_MIG")); } break; } case 1: CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_APP")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_APP")); break; case 2: CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_HRD")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_HRD")); break; case 3: CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSO")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSO")); break; case 4: CFont::SetColor(CRGBA(255, 255, 255, alpha)); - CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(HELPER_TEXT_LEFT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSC")); break; default: break; @@ -965,10 +1010,10 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR 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); @@ -987,7 +1032,9 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR void CMenuManager::DoSettingsBeforeStartingAGame() { +#ifdef PC_PLAYER_CONTROLS CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; +#endif if (m_PrefsVsyncDisp != m_PrefsVsync) m_PrefsVsync = m_PrefsVsyncDisp; @@ -1009,9 +1056,8 @@ CMenuManager::Draw() CFont::SetCentreOff(); CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOn(); -#ifdef GTA3_1_1_PATCH -#ifdef DRAW_MENU_VERSION_TEXT - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); +#if GTA_VERSION >= GTA3_PC_11 && defined(DRAW_MENU_VERSION_TEXT) + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOn(); CFont::SetFontStyle(FONT_HEADING); CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f)); @@ -1021,7 +1067,6 @@ CMenuManager::Draw() AsciiToUnicode(gString, gUString); CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString); #endif -#endif CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); @@ -1048,7 +1093,7 @@ CMenuManager::Draw() #endif if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') { - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName)); // Weird place to put that. @@ -1058,7 +1103,7 @@ CMenuManager::Draw() CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_X), MENU_Y(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_Y)); CFont::SetRightJustifyOff(); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); // Label wchar *str; @@ -1095,6 +1140,7 @@ CMenuManager::Draw() #endif } + // Not a bug, we just want HFoV+ on menu #ifdef ASPECT_RATIO_SCALE CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); #else @@ -1119,6 +1165,16 @@ CMenuManager::Draw() CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE)); CFont::SetCentreOn(); break; +#ifdef FIX_BUGS + case MENUPAGE_CONTROLLER_SETTINGS: + columnWidth = 50; + headerHeight = -50; + 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; +#endif case MENUPAGE_SOUND_SETTINGS: case MENUPAGE_DISPLAY_SETTINGS: case MENUPAGE_MULTIPLAYER_CREATE: @@ -1239,14 +1295,16 @@ CMenuManager::Draw() float smallestSliderBar = lineHeight * 0.1f; bool foundTheHoveringItem = false; wchar unicodeTemp[64]; +#ifdef ASPECT_RATIO_SCALE char asciiTemp[32]; +#endif #ifdef MENU_MAP if (m_nCurrScreen == MENUPAGE_MAP) { // Back button wchar *backTx = TheText.Get("FEDS_TB"); CFont::SetDropShadowPosition(1); - CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); 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))) { @@ -1261,11 +1319,12 @@ CMenuManager::Draw() #endif #ifdef CUSTOM_FRONTEND_OPTIONS + // Thanks R*, for checking mouse hovering in Draw(). static int lastSelectedOpt = m_nCurrOption; #endif #ifdef SCROLLABLE_PAGES - int firstOption = m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen) ? m_nFirstVisibleRowOnList : 0; + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) { #else for (int i = 0; i < NUM_MENUROWS; ++i) { @@ -1276,7 +1335,7 @@ CMenuManager::Draw() #endif // Hide back button #ifdef PS2_LIKE_MENU - if ((i == NUM_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[i+1].m_EntryName[0] == '\0') && strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEDS_TB", 8) == 0) + if ((i == NUM_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[i+1].m_EntryName[0] == '\0') && strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEDS_TB") == 0) break; #endif if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { @@ -1298,38 +1357,6 @@ CMenuManager::Draw() leftText = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName); } -#ifdef CUSTOM_FRONTEND_OPTIONS - if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action < MENUACTION_NOTHING) { // CFO check - CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; - if (option.m_Action == MENUACTION_CFO_SELECT) { - if (option.m_CFOSelect->onlyApplyOnEnter){ - if (m_nCurrOption != i) { - if (option.m_CFOSelect->displayedValue != option.m_CFOSelect->lastSavedValue) - SetHelperText(3); // Restored original value - -// option.displayedValue = option.lastSavedValue = *option.m_CFO->value; - - } else { - if (option.m_CFOSelect->displayedValue != *option.m_CFO->value) - SetHelperText(1); // Enter to apply - else if (m_nHelperTextMsgId == 1) - ResetHelperText(); // Applied - } - } - } - - if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) { - CMenuScreenCustom::CMenuEntry &oldOption = aScreens[m_nCurrScreen].m_aEntries[lastSelectedOpt]; - if (oldOption.m_Action == MENUACTION_CFO_DYNAMIC) - if(oldOption.m_CFODynamic->buttonPressFunc) - oldOption.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); - - if (oldOption.m_Action == MENUACTION_CFO_SELECT && oldOption.m_CFOSelect->onlyApplyOnEnter) - oldOption.m_CFOSelect->displayedValue = oldOption.m_CFOSelect->lastSavedValue = *oldOption.m_CFO->value; - } - } -#endif - switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { case MENUACTION_CHANGEMENU: { switch (aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu) { @@ -1444,18 +1471,34 @@ CMenuManager::Draw() #else switch (m_PrefsUseWideScreen) { case AR_AUTO: - sprintf(asciiTemp, "AUTO"); + rightText = TheText.Get("FEM_AUT"); break; case AR_4_3: sprintf(asciiTemp, "4:3"); + AsciiToUnicode(asciiTemp, unicodeTemp); + rightText = unicodeTemp; + break; + case AR_5_4: + sprintf(asciiTemp, "5:4"); + AsciiToUnicode(asciiTemp, unicodeTemp); + rightText = unicodeTemp; + break; + case AR_16_10: + sprintf(asciiTemp, "16:10"); + AsciiToUnicode(asciiTemp, unicodeTemp); + rightText = unicodeTemp; break; case AR_16_9: sprintf(asciiTemp, "16:9"); + AsciiToUnicode(asciiTemp, unicodeTemp); + rightText = unicodeTemp; + break; + case AR_21_9: + sprintf(asciiTemp, "21:9"); + AsciiToUnicode(asciiTemp, unicodeTemp); + rightText = unicodeTemp; break; } - - AsciiToUnicode(asciiTemp, unicodeTemp); - rightText = unicodeTemp; #endif break; case MENUACTION_RADIO: @@ -1548,7 +1591,26 @@ CMenuManager::Draw() case MENUACTION_CFO_SELECT: CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; if (option.m_Action == MENUACTION_CFO_SELECT) { - // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions) + + isOptionDisabled = option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded; + if (option.m_CFOSelect->onlyApplyOnEnter){ + if (m_nCurrOption != i) { + if (option.m_CFOSelect->displayedValue != option.m_CFOSelect->lastSavedValue) + SetHelperText(3); // Restored original value + + // If that was previously selected option, restore it to default value. + // if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; + + } else { + if (option.m_CFOSelect->displayedValue != *option.m_CFO->value) + SetHelperText(1); // Enter to apply + else if (m_nHelperTextMsgId == 1) + ResetHelperText(); // Applied + } + } + + // To whom manipulate option.m_CFO->value of select options externally (like RestoreDef functions) if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue) option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; @@ -1558,6 +1620,11 @@ CMenuManager::Draw() rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]); } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i) { + if(option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + } + if (option.m_CFODynamic->drawFunc) { rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i); } @@ -1582,7 +1649,7 @@ CMenuManager::Draw() // Hide back button #ifdef PS2_LIKE_MENU if ((rowToCheck == NUM_MENUROWS - 1 || aScreens[m_nCurrScreen].m_aEntries[rowToCheck+1].m_EntryName[0] == '\0') && - strncmp(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName, "FEDS_TB", 8) == 0) + strcmp(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName, "FEDS_TB") == 0) break; #endif @@ -1635,12 +1702,12 @@ CMenuManager::Draw() #ifdef PS2_LIKE_MENU CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(29.0f), MENU_Y(bitAboveNextItemY), MENU_X_RIGHT_ALIGNED(29.0f), MENU_Y(usableLineHeight + nextItemY)), - CRGBA(100, 200, 50, FadeIn(50))); + CRGBA(SELECTION_HIGHLIGHTBG_COLOR.r, SELECTION_HIGHLIGHTBG_COLOR.g, SELECTION_HIGHLIGHTBG_COLOR.b, FadeIn(SELECTION_HIGHLIGHTBG_COLOR.a))); #else // We keep stretching, because we also stretch background image and we want that bar to be aligned with borders of background CSprite2d::DrawRect(CRect(StretchX(10.0f), MENU_Y(bitAboveNextItemY), SCREEN_STRETCH_FROM_RIGHT(11.0f), MENU_Y(usableLineHeight + nextItemY)), - CRGBA(100, 200, 50, FadeIn(50))); + CRGBA(SELECTION_HIGHLIGHTBG_COLOR.r, SELECTION_HIGHLIGHTBG_COLOR.g, SELECTION_HIGHLIGHTBG_COLOR.b, FadeIn(SELECTION_HIGHLIGHTBG_COLOR.a))); #endif } @@ -1664,14 +1731,14 @@ CMenuManager::Draw() || isOptionDisabled #endif ) - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); } if (i == m_nCurrOption && itemsAreSelectable){ - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } @@ -1694,7 +1761,9 @@ CMenuManager::Draw() if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 // To make assigning built-in actions to new custom options possible. -#ifndef CUSTOM_FRONTEND_OPTIONS +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FEA_3DH") +#else && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS #endif && m_nPrefsAudio3DProviderIndex != -1) { @@ -1771,21 +1840,21 @@ CMenuManager::Draw() #endif #ifdef SCROLLABLE_PAGES - #define SCROLLBAR_BOTTOM_X 125.0f // only for background, scrollbar's itself is calculated + #define SCROLLBAR_BOTTOM_Y 125.0f // only for background, scrollbar's itself is calculated #define SCROLLBAR_RIGHT_X 36.0f #define SCROLLBAR_WIDTH 9.5f - #define SCROLLBAR_TOP_X 64 + #define SCROLLBAR_TOP_Y 64 - if (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) { + if (SCREEN_HAS_AUTO_SCROLLBAR) { // Scrollbar background - CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_X), - MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_X)), CRGBA(100, 100, 66, FadeIn(205))); + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_Y), + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_Y)), CRGBA(100, 100, 66, FadeIn(205))); float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nTotalListRow / (float) MAX_VISIBLE_OPTION); float scrollbarBottom, scrollbarTop; - scrollbarBottom = MENU_Y(SCROLLBAR_TOP_X - 8 + m_nScrollbarTopMargin + scrollbarHeight); - scrollbarTop = MENU_Y(SCROLLBAR_TOP_X + m_nScrollbarTopMargin); + scrollbarBottom = MENU_Y(SCROLLBAR_TOP_Y - 8 + m_nScrollbarTopMargin + scrollbarHeight); + scrollbarTop = MENU_Y(SCROLLBAR_TOP_Y + m_nScrollbarTopMargin); // Scrollbar shadow CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 1 - SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), @@ -1794,7 +1863,7 @@ CMenuManager::Draw() // Scrollbar CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - SCROLLBAR_WIDTH), scrollbarBottom), - CRGBA(235, 170, 50, FadeIn(255))); + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); } #endif @@ -1859,6 +1928,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 int controllerAction = PED_FIREWEAPON; // GetStartOptionsCntrlConfigScreens(); int numOptions = GetNumOptionsCntrlConfigScreens(); + int nextY = MENU_Y(yStart); int bindingMargin = MENU_X(3.0f); float rowHeight; switch (m_ControlMethod) { @@ -1873,10 +1943,11 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } // MENU_Y(rowHeight * 0.0f + yStart); - for (int optionIdx = 0, nextY = MENU_Y(yStart); optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { + for (int optionIdx = 0; optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) { int nextX = xStart; int bindingsForThisOpt = 0; - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + int contSetOrder = SETORDER_1; + CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a))); if (column == CONTSETUP_PED_COLUMN) { switch (optionIdx) { @@ -2054,18 +2125,18 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 #ifdef FIX_BUGS if (controllerAction == -1) { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #else if (controllerAction == -1) { CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); + MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY), - MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); + MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #endif CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); @@ -2075,16 +2146,16 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 #ifdef FIX_BUGS if (controllerAction == -1) { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH), - MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210))); + MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #else if (controllerAction == -1) { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(235, 170, 50, FadeIn(150))); + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.r, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.g, CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_DISABLED_HIGHLIGHTBG_COLOR.a))); } else { - CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(255, 217, 106, FadeIn(210))); + CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(CONTSETUP_HIGHLIGHTBG_COLOR.r, CONTSETUP_HIGHLIGHTBG_COLOR.g, CONTSETUP_HIGHLIGHTBG_COLOR.b, FadeIn(CONTSETUP_HIGHLIGHTBG_COLOR.a))); } #endif CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); @@ -2094,8 +2165,8 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } // Print bindings, including seperator (-) between them - CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f)); - for (int contSetOrder = SETORDER_1; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { + CFont::SetScale(MENU_X(0.25f), MENU_Y(SMALLESTTEXT_Y_SCALE)); + for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder); if (settingText) { ++bindingsForThisOpt; @@ -2159,9 +2230,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); CFont::PrintString(nextX, nextY, TheText.Get("FEC_QUE")); // "???" } - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + SET_FONT_FOR_HELPER_TEXT CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); if (m_bKeyChangeNotProcessed) { CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE @@ -2169,34 +2238,24 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_RIG")); // SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL } - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM if (!m_bKeyIsOK) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); m_bKeyIsOK = true; } else { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + SET_FONT_FOR_HELPER_TEXT CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM m_bKeyIsOK = false; m_bKeyChangeNotProcessed = false; } } else if (optionIdx == m_nSelectedListRow) { - CFont::SetCentreOn(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); + SET_FONT_FOR_HELPER_TEXT CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255))); CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_EIG")); // CANNOT SET A CONTROL FOR THIS ACTION - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM } } } @@ -2243,7 +2302,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig if (waitingTextVisible) { CFont::SetColor(CRGBA(255, 255, 0, FadeIn(255))); CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_QUE")); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } yStart += lineHeight; @@ -2272,17 +2331,9 @@ CMenuManager::DrawControllerSetupScreen() default: break; } - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); + RESET_FONT_FOR_NEW_PAGE - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER switch (m_ControlMethod) { case CONTROL_STANDARD: @@ -2343,12 +2394,12 @@ CMenuManager::DrawControllerSetupScreen() // Gray panel background CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT), MENU_Y(CONTSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(CONTSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)), - CRGBA(200, 200, 50, FadeIn(50))); + CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); if (m_nCurrExLayer == HOVEROPTION_LIST) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); // List header CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); @@ -2357,15 +2408,15 @@ CMenuManager::DrawControllerSetupScreen() CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CAC")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR")); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X_LEFT_ALIGNED(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM + int yStart; if (m_ControlMethod == CONTROL_CLASSIC) - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 29; + yStart = CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT + 1; else - yStart = CONTSETUP_LIST_HEADER_HEIGHT + 34; + yStart = CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT + 5; + float optionYBottom = yStart + rowHeight; for (int i = 0; i < ARRAY_SIZE(actionTexts); ++i) { wchar *actionText = actionTexts[i]; if (!actionText) @@ -2374,8 +2425,7 @@ CMenuManager::DrawControllerSetupScreen() if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)) { - float curOptY = i * rowHeight + yStart; - if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) { + if (m_nMousePosY > MENU_Y(i * rowHeight + yStart) && m_nMousePosY < MENU_Y(i * rowHeight + optionYBottom)) { if (m_nOptionMouseHovering != i && m_nCurrExLayer == HOVEROPTION_LIST) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0); @@ -2417,16 +2467,16 @@ CMenuManager::DrawControllerSetupScreen() m_nHoverOption = HOVEROPTION_NOT_HOVERING; } } - if (m_nSelectedListRow != 35) - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + if (m_nSelectedListRow != i) + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); else if (m_nCurrExLayer == HOVEROPTION_LIST) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOff(); - if (m_PrefsLanguage != LANGUAGE_GERMAN || i != 20 && i != 21) - CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); - else + if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21)) CFont::SetScale(MENU_X(0.32f), MENU_Y(SMALLESTTEXT_Y_SCALE)); + else + CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText); } @@ -2457,9 +2507,9 @@ CMenuManager::DrawControllerSetupScreen() SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f - i), TheText.Get("FEDS_TB")); if (m_nHoverOption == HOVEROPTION_BACK) - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); else - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } @@ -2729,12 +2779,12 @@ CMenuManager::DrawFrontEndNormal() CFont::SetScale(MENU_X(0.35f), MENU_Y(0.7f)); CFont::SetRightJustifyOff(); if (hoveredBottomBarOption == i && hoveredBottomBarOption != curBottomBarOption) - CFont::SetColor(CRGBA(235, 170, 50, 255)); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, 255)); else { if(bottomBarActive || curBottomBarOption == i) - CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, 255)); else - CFont::SetColor(CRGBA(0, 0, 0, 110)); + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, 110)); } str = TheText.Get(bbNames[i].name); @@ -2930,6 +2980,45 @@ CMenuManager::DrawFrontEndNormal() } } +#ifdef RED_DELETE_BACKGROUND + if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT || m_nCurrScreen == MENUPAGE_DELETE_SLOT_CONFIRM) { + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(18.0f), MENU_Y(8.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), MENU_Y(8.0f), + SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f), + SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f), + SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f), + SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f), + CRGBA(150, 0, 0, 140)); + + CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f), + SCREEN_STRETCH_X(18.0f), SCREEN_SCALE_Y(438.0f), + SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_Y(438.0f), + CRGBA(150, 0, 0, 140)); + + // yellow bar + CSprite2d::DrawRect(CRect(MENU_X(13.0f), SCREEN_STRETCH_FROM_BOTTOM(96.0f), + SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)), + CRGBA(235, 170, 50, 255)); + } +#endif + // GTA LOGO RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); @@ -2986,17 +3075,9 @@ CMenuManager::DrawFrontEndNormal() void CMenuManager::DrawPlayerSetupScreen() { - CFont::SetBackgroundOff(); - CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); - CFont::SetPropOn(); - CFont::SetCentreOff(); - CFont::SetJustifyOn(); - CFont::SetRightJustifyOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN - 2.0f)); + RESET_FONT_FOR_NEW_PAGE - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS")); @@ -3018,7 +3099,7 @@ CMenuManager::DrawPlayerSetupScreen() SYSTEMTIME SystemTime; HANDLE handle = FindFirstFile("skins\\*.bmp", &FindFileData); for (int i = 1; handle != INVALID_HANDLE_VALUE && i; i = FindNextFile(handle, &FindFileData)) { - if (strncmp(FindFileData.cFileName, DEFAULT_SKIN_NAME, 5) != 0) { + if (strcmp(FindFileData.cFileName, DEFAULT_SKIN_NAME) != 0) { m_pSelectedSkin->nextSkin = new tSkinInfo; m_pSelectedSkin = m_pSelectedSkin->nextSkin; m_pSelectedSkin->skinId = nextSkinId; @@ -3065,7 +3146,7 @@ CMenuManager::DrawPlayerSetupScreen() strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "(", 1); if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "}", 1)) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], ")", 1); - if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "�", 1)) + if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "£", 1)) strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "$", 1); } @@ -3084,13 +3165,14 @@ CMenuManager::DrawPlayerSetupScreen() m_bSkinsEnumerated = true; } CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), - MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(200, 200, 50, FadeIn(50))); + MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), + CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a))); // Header (Skin - Date) if (m_nCurrExLayer == HOVEROPTION_LIST) { - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); @@ -3109,9 +3191,7 @@ CMenuManager::DrawPlayerSetupScreen() CFont::PrintString(MENU_X_LEFT_ALIGNED(PLAYERSETUP_SKIN_COLUMN_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), TheText.Get("FES_SKN")); // Skin list - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + SET_FONT_FOR_LIST_ITEM if (m_nSkinsTotal > 0) { for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList; m_pSelectedSkin = m_pSelectedSkin->nextSkin); @@ -3160,7 +3240,7 @@ CMenuManager::DrawPlayerSetupScreen() } else if (!strcmp(m_PrefsSkinFile, m_pSelectedSkin->skinNameOriginal)) { CFont::SetColor(CRGBA(255, 255, 155, FadeIn(255))); } else { - CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255))); + CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a))); } wchar unicodeTemp[80]; AsciiToUnicode(m_pSelectedSkin->skinNameDisplayed, unicodeTemp); @@ -3212,7 +3292,7 @@ CMenuManager::DrawPlayerSetupScreen() // Scrollbar CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom), - CRGBA(235, 170, 50, FadeIn(255))); + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); // FIX: Scroll button dimensions are buggy, because: // 1 - stretches the original image @@ -3281,7 +3361,7 @@ CMenuManager::DrawPlayerSetupScreen() CFont::SetScale(MENU_X(1.9f), MENU_Y(1.9f)); break; } - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(120))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(120))); CFont::SetRightJustifyOff(); CFont::PrintString(MENU_X_LEFT_ALIGNED(20.0f), MENU_Y(220.0f), TheText.Get("FET_APL")); } @@ -3372,9 +3452,9 @@ CMenuManager::DrawPlayerSetupScreen() for (int i = 0; i < 2; i++) { CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - i), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FEDS_TB")); if (m_nHoverOption == HOVEROPTION_BACK) { - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } CFont::SetRightJustifyOff(); @@ -3384,11 +3464,11 @@ CMenuManager::DrawPlayerSetupScreen() for (int i = 0; i < 2; i++) { CFont::PrintString(MENU_X_LEFT_ALIGNED(i + PLAYERSETUP_LIST_LEFT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FES_SET")); if (!strcmp(m_aSkinName, m_PrefsSkinFile)) { - CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } else if (m_nHoverOption == HOVEROPTION_USESKIN) { - CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255))); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255))); } else { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); } } @@ -3514,13 +3594,21 @@ CMenuManager::LoadAllTextures() DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0); m_nCurrOption = 0; + +#ifdef FIX_BUGS + static bool firstTime = true; + if (firstTime) { + DMAudio.SetRadioInCar(m_PrefsRadioStation); + firstTime = false; + } else +#endif m_PrefsRadioStation = DMAudio.GetRadioInCar(); if (DMAudio.IsMP3RadioChannelAvailable()) { if (m_PrefsRadioStation > USERTRACK) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10; + m_PrefsRadioStation = CGeneral::GetRandomNumber() % (USERTRACK + 1); } else if (m_PrefsRadioStation > CHATTERBOX) - m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9; + m_PrefsRadioStation = CGeneral::GetRandomNumber() % (CHATTERBOX + 1); CFileMgr::SetDir(""); //CFileMgr::SetDir(""); @@ -3538,7 +3626,7 @@ CMenuManager::LoadAllTextures() CTxdStore::LoadTxd(frontendTxdSlot, "MODELS/FRONTEND.TXD"); CTxdStore::AddRef(frontendTxdSlot); CTxdStore::SetCurrentTxd(frontendTxdSlot); -#ifndef GTA3_1_1_PATCH +#if GTA_VERSION < GTA3_PC_11 CStreaming::IHaveUsedStreamingMemory(); CTimer::Update(); #endif @@ -3548,6 +3636,10 @@ CMenuManager::LoadAllTextures() m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } +#ifdef GAMEPAD_MENU + LoadController(m_PrefsControllerType); +#endif + int menuTxdSlot = CTxdStore::FindTxdSlot("menu"); if (menuTxdSlot == -1) @@ -3567,8 +3659,11 @@ CMenuManager::LoadAllTextures() m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]); m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); } + fMapSize = SCREEN_HEIGHT * 2.0f; + fMapCenterX = 0.0f; + fMapCenterY = 0.0f; #endif -#ifdef GTA3_1_1_PATCH +#if GTA_VERSION >= GTA3_PC_11 CStreaming::IHaveUsedStreamingMemory(); CTimer::Update(); #endif @@ -3576,6 +3671,71 @@ CMenuManager::LoadAllTextures() CTxdStore::PopCurrentTxd(); } +#ifdef GAMEPAD_MENU +const char* controllerTypesPaths[] = { + nil, + "MODELS/FRONTEND_DS3.TXD", + "MODELS/FRONTEND_DS4.TXD", + "MODELS/FRONTEND_X360.TXD", + "MODELS/FRONTEND_XONE.TXD", +}; + +void +CMenuManager::LoadController(int8 type) +{ + switch (type) + { + case CONTROLLER_DUALSHOCK2: + case CONTROLLER_DUALSHOCK3: + case CONTROLLER_DUALSHOCK4: + CFont::LoadButtons("MODELS/PS3BTNS.TXD"); + break; + default: + CFont::LoadButtons("MODELS/X360BTNS.TXD"); + break; + } + + // Unload current textures + for (int i = FE_CONTROLLER; i <= FE_ARROWS4; i++) + m_aFrontEndSprites[i].Delete(); + + // Unload txd + int frontend_controller = CTxdStore::FindTxdSlot("frontend_controller"); + if (frontend_controller != -1) + CTxdStore::RemoveTxd(frontend_controller); + + // Find the new txd to load + bool bTxdMissing = true; + if (controllerTypesPaths[type]) + if (int file = CFileMgr::OpenFile(controllerTypesPaths[type])) { + CFileMgr::CloseFile(file); + bTxdMissing = false; + } + + int txdSlot = -1; + + if (bTxdMissing) + // Not found, fall back to original textures + txdSlot = CTxdStore::FindTxdSlot("frontend"); + else { + // Found, load txd + txdSlot = frontend_controller; + if (txdSlot == -1) + txdSlot = CTxdStore::AddTxdSlot("frontend_controller"); + CTxdStore::LoadTxd(txdSlot, controllerTypesPaths[type]); + CTxdStore::AddRef(txdSlot); + } + + assert(txdSlot != -1); + // Load new textures + CTxdStore::SetCurrentTxd(txdSlot); + for (int i = FE_CONTROLLER; i <= FE_ARROWS4; i++) { + m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]); + m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER); + } +} +#endif // GAMEPAD_MENU + void CMenuManager::LoadSettings() { @@ -3583,7 +3743,7 @@ CMenuManager::LoadSettings() int fileHandle = CFileMgr::OpenFile("gta3.set", "r"); int32 prevLang = m_PrefsLanguage; -#ifdef GTA3_1_1_PATCH +#if GTA_VERSION >= GTA3_PC_11 CMBlur::BlurOn = (_dwOperatingSystemVersion != OS_WIN98); #else CMBlur::BlurOn = true; @@ -3652,6 +3812,16 @@ CMenuManager::LoadSettings() CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); +#ifdef LOAD_INI_SETTINGS + if (LoadINISettings()) { + LoadINIControllerSettings(); + } else { + // no re3.ini, create it + SaveINISettings(); + SaveINIControllerSettings(); + } +#endif + m_PrefsVsync = m_PrefsVsyncDisp; CRenderer::ms_lodDistScale = m_PrefsLOD; @@ -3690,14 +3860,12 @@ CMenuManager::LoadSettings() strcpy(m_PrefsSkinFile, DEFAULT_SKIN_NAME); strcpy(m_aSkinName, DEFAULT_SKIN_NAME); } -#ifdef LOAD_INI_SETTINGS - LoadINISettings(); // needs frontend options to be loaded -#endif } void CMenuManager::SaveSettings() { +#ifndef LOAD_INI_SETTINGS static char RubbishString[48] = "stuffmorestuffevenmorestuff etc"; CFileMgr::SetDirMyDocuments(); @@ -3747,7 +3915,7 @@ CMenuManager::SaveSettings() CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); -#ifdef LOAD_INI_SETTINGS +#else SaveINISettings(); #endif } @@ -3780,7 +3948,7 @@ CMenuManager::MessageScreen(const char *text) CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetCentreSize(SCREEN_SCALE_X(380.0f)); CFont::SetCentreOn(); - CFont::SetColor(CRGBA(255, 217, 106, 255)); + CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, 255)); CFont::SetScale(SCREEN_SCALE_X(SMALLTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLTEXT_Y_SCALE)); CFont::PrintString(StretchX(320.0f), StretchY(170.0f), TheText.Get(text)); CFont::DrawFonts(); @@ -3806,7 +3974,7 @@ CMenuManager::PickNewPlayerColour() void CMenuManager::PrintBriefs() { - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); CFont::SetRightJustifyOff(); CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why @@ -3824,19 +3992,14 @@ CMenuManager::PrintBriefs() CMessages::InsertPlayerControlKeysInString(gUString); newColor = TEXT_COLOR; FilterOutColorMarkersFromString(gUString, newColor); - -#ifdef PS2_LIKE_MENU - // This PS2 code was always here, but unused - bool rgSame = newColor.r == TEXT_COLOR.r && newColor.g == TEXT_COLOR.g; - bool bSame = rgSame && newColor.b == TEXT_COLOR.b; - bool colorNotChanged = bSame; /* && newColor.a == TEXT_COLOR.a; */ - - if (!colorNotChanged) { + if (newColor != TEXT_COLOR) { newColor.r /= 2; newColor.g /= 2; newColor.b /= 2; } - CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // But this is from PS2 + +#ifdef PS2_LIKE_MENU + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetDropShadowPosition(1); #endif @@ -3882,7 +4045,7 @@ void CMenuManager::PrintStats() { int rowNum = ConstructStatLine(99999); -#ifdef GTA3_1_1_PATCH +#if GTA_VERSION >= GTA3_PC_11 CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); #endif CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why @@ -3930,7 +4093,7 @@ CMenuManager::PrintStats() } else alphaMult = 1.0f; - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255.0f * alphaMult))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255.0f * alphaMult))); CFont::SetRightJustifyOff(); CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString); CFont::SetRightJustifyOn(); @@ -3940,7 +4103,7 @@ CMenuManager::PrintStats() // Game doesn't do that, but it's better float nextX = MENU_X_LEFT_ALIGNED(STATS_RATING_X); - CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255))); + CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetRightJustifyOff(); CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), TheText.Get("CRIMRA")); #ifdef MORE_LANGUAGES @@ -3963,7 +4126,7 @@ CMenuManager::PrintStats() // ::Draw already does that. /* - PREPARE_MENU_HEADER + SET_FONT_FOR_MENU_HEADER CFont::PrintString(PAGE_NAME_X(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)); @@ -4026,7 +4189,9 @@ CMenuManager::Process(void) #ifdef USE_DEBUG_SCRIPT_LOADER scriptToLoad = 0; #endif +#ifdef PC_PLAYER_CONTROLS TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; +#endif if (m_PrefsVsyncDisp != m_PrefsVsync) m_PrefsVsync = m_PrefsVsyncDisp; DMAudio.Service(); @@ -4060,19 +4225,19 @@ CMenuManager::Process(void) MouseButtonJustClicked = false; if (CPad::GetPad(0)->GetLeftMouseJustDown()) - MouseButtonJustClicked = 1; + MouseButtonJustClicked = rsMOUSELEFTBUTTON; else if (CPad::GetPad(0)->GetRightMouseJustUp()) - MouseButtonJustClicked = 3; + MouseButtonJustClicked = rsMOUSERIGHTBUTTON; else if (CPad::GetPad(0)->GetMiddleMouseJustUp()) - MouseButtonJustClicked = 2; + MouseButtonJustClicked = rsMOUSMIDDLEBUTTON; else if (CPad::GetPad(0)->GetMouseWheelUpJustUp()) - MouseButtonJustClicked = 4; + MouseButtonJustClicked = rsMOUSEWHEELUPBUTTON; else if (CPad::GetPad(0)->GetMouseWheelDownJustUp()) - MouseButtonJustClicked = 5; + MouseButtonJustClicked = rsMOUSEWHEELDOWNBUTTON; else if (CPad::GetPad(0)->GetMouseX1JustUp()) - MouseButtonJustClicked = 6; + MouseButtonJustClicked = rsMOUSEX1BUTTON; else if (CPad::GetPad(0)->GetMouseX2JustUp()) - MouseButtonJustClicked = 7; + MouseButtonJustClicked = rsMOUSEX2BUTTON; JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown(); @@ -4424,13 +4589,21 @@ CMenuManager::ProcessButtonPresses(void) case HOVEROPTION_INCREASE_MOUSESENS: TheCamera.m_fMouseAccelHorzntl += (1.0f / 3000); TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200); +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f; +#else TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; +#endif SaveSettings(); break; case HOVEROPTION_DECREASE_MOUSESENS: TheCamera.m_fMouseAccelHorzntl -= (1.0f / 3000); TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200); +#ifdef FIX_BUGS + TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f; +#else TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl; +#endif SaveSettings(); break; } @@ -4603,15 +4776,15 @@ CMenuManager::ProcessButtonPresses(void) // Hide back button #ifdef PS2_LIKE_MENU - if ((goUp || goDown) && m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME && strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 0) + if ((goUp || goDown) && m_nCurrScreen != MENUPAGE_MULTIPLAYER_FIND_GAME && strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB") == 0) m_nCurrOption = goUp ? m_nCurrOption - 1 : (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL); #endif if (optionSelected) { int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action; if ((option == MENUACTION_CHANGEMENU) || (option == MENUACTION_POPULATESLOTS_CHANGEMENU)) { - 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) { + if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB") != 0 && + strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FESZ_CA") != 0) { if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT) { if (Slots[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot - 1] == SLOT_EMPTY) @@ -4768,7 +4941,7 @@ CMenuManager::ProcessButtonPresses(void) } } if (changeMenu) { - if (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 0) { + if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB") == 0) { #ifndef TIDY_UP_PBP ResetHelperText(); ChangeScreen(!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0], @@ -4778,12 +4951,6 @@ CMenuManager::ProcessButtonPresses(void) break; #endif } else { -#ifdef MENU_MAP - 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); } } @@ -4933,10 +5100,14 @@ CMenuManager::ProcessButtonPresses(void) m_PrefsLOD = 1.2f; m_PrefsVsync = true; CRenderer::ms_lodDistScale = 1.2f; +#ifdef ASPECT_RATIO_SCALE + m_PrefsUseWideScreen = AR_AUTO; +#else m_PrefsUseWideScreen = false; +#endif m_PrefsShowSubtitles = true; m_nDisplayVideoMode = m_nPrefsVideoMode; -#ifdef GTA3_1_1_PATCH +#if GTA_VERSION >= GTA3_PC_11 if (_dwOperatingSystemVersion == OS_WIN98) { CMBlur::BlurOn = false; CMBlur::MotionBlurClose(); @@ -4974,11 +5145,19 @@ CMenuManager::ProcessButtonPresses(void) } #endif m_ControlMethod = CONTROL_STANDARD; +#ifdef FIX_BUGS + MousePointerStateHelper.bInvertVertically = true; + TheCamera.m_fMouseAccelVertical = 0.003f; +#else MousePointerStateHelper.bInvertVertically = false; +#endif TheCamera.m_fMouseAccelHorzntl = 0.0025f; CVehicle::m_bDisableMouseSteering = true; TheCamera.m_bHeadBob = false; SaveSettings(); +#ifdef LOAD_INI_SETTINGS + SaveINIControllerSettings(); +#endif } SetHelperText(2); break; @@ -5018,6 +5197,9 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_CFO_DYNAMIC: CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + break; + if (!option.m_CFOSelect->onlyApplyOnEnter) { option.m_CFOSelect->displayedValue++; if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) @@ -5027,7 +5209,8 @@ CMenuManager::ProcessButtonPresses(void) *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; - if (option.m_CFOSelect->save) + // Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO + // if (option.m_CFOSelect->save) SaveSettings(); if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) @@ -5134,7 +5317,7 @@ CMenuManager::ProcessButtonPresses(void) increase = true; } else if ( #ifdef SCROLLABLE_PAGES - !(m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) && + !SCREEN_HAS_AUTO_SCROLLBAR && #endif CPad::GetPad(0)->GetMouseWheelUpJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { increase = true; @@ -5147,7 +5330,7 @@ CMenuManager::ProcessButtonPresses(void) decrease = true; } else if ( #ifdef SCROLLABLE_PAGES - !(m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) && + !SCREEN_HAS_AUTO_SCROLLBAR && #endif CPad::GetPad(0)->GetMouseWheelDownJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) { decrease = true; @@ -5162,6 +5345,17 @@ CMenuManager::ProcessButtonPresses(void) if (changeValueBy != 0) { switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) { +#ifdef FIX_BUGS + case MENUACTION_CTRLCONFIG: + CPad::GetPad(0)->Mode += changeValueBy; + if (CPad::GetPad(0)->Mode > 3) + CPad::GetPad(0)->Mode = 0; + else if (CPad::GetPad(0)->Mode < 0) + CPad::GetPad(0)->Mode = 3; + SaveSettings(); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + break; +#endif case MENUACTION_RADIO: m_PrefsRadioStation += changeValueBy; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); @@ -5185,12 +5379,12 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_WIDESCREEN: if (changeValueBy > 0) { m_PrefsUseWideScreen++; - if (m_PrefsUseWideScreen > 2) + if (m_PrefsUseWideScreen > AR_MAX-1) m_PrefsUseWideScreen = 0; } else { m_PrefsUseWideScreen--; if (m_PrefsUseWideScreen < 0) - m_PrefsUseWideScreen = 2; + m_PrefsUseWideScreen = AR_MAX-1; } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); SaveSettings(); @@ -5244,6 +5438,9 @@ CMenuManager::ProcessButtonPresses(void) case MENUACTION_CFO_DYNAMIC: CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + break; + if (changeValueBy > 0) { option.m_CFOSelect->displayedValue++; if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts) @@ -5258,7 +5455,8 @@ CMenuManager::ProcessButtonPresses(void) *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; - if (option.m_CFOSelect->save) + // Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO + // if (option.m_CFOSelect->save) SaveSettings(); if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) @@ -5296,13 +5494,18 @@ CMenuManager::ProcessOnOffMenuOptions() TimeToStopPadShaking = CTimer::GetTimeInMillisecondsPauseMode() + 500; } DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); +#ifdef FIX_BUGS + SaveSettings(); +#endif // !FIX_BUGS break; +#ifndef FIX_BUGS case MENUACTION_CTRLCONFIG: CPad::GetPad(0)->Mode++; if (CPad::GetPad(0)->Mode > 3) CPad::GetPad(0)->Mode = 0; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); break; +#endif // !FIX_BUGS case MENUACTION_CTRLDISPLAY: m_DisplayControllerOnFoot = !m_DisplayControllerOnFoot; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); @@ -5500,6 +5703,9 @@ CMenuManager::SwitchMenuOnAndOff() #endif ShutdownJustMenu(); SaveSettings(); +#ifdef LOAD_INI_SETTINGS + SaveINIControllerSettings(); +#endif m_bStartUpFrontEndRequested = false; pControlEdit = nil; m_bShutDownFrontEndRequested = false; @@ -5569,6 +5775,12 @@ CMenuManager::UnloadTextures() int frontend = CTxdStore::FindTxdSlot("frontend"); CTxdStore::RemoveTxd(frontend); +#ifdef GAMEPAD_MENU + int frontend_controllerTxdSlot = CTxdStore::FindTxdSlot("frontend_controller"); + if (frontend_controllerTxdSlot != -1) + CTxdStore::RemoveTxd(frontend_controllerTxdSlot); +#endif + printf("REMOVE menu textures\n"); for (int i = 0; i < ARRAY_SIZE(MenuFilenames); ++i) m_aMenuSprites[i].Delete(); @@ -5588,7 +5800,7 @@ CMenuManager::WaitForUserCD() CSprite2d *splash; char *splashscreen = nil; -#if (!(defined RANDOMSPLASH) && !(defined GTA3_1_1_PATCH)) +#if (!(defined RANDOMSPLASH) && GTA_VERSION < GTA3_PC_11) if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame) splashscreen = "mainsc2"; else @@ -5610,6 +5822,301 @@ CMenuManager::WaitForUserCD() } } +#ifdef GAMEPAD_MENU +void +CMenuManager::PrintController(void) +{ + const float scale = 0.9f; + const float CONTROLLER_SIZE_X = 235.2f; + const float CONTROLLER_SIZE_Y = 175.2f; + const float CONTROLLER_POS_X = (DEFAULT_SCREEN_WIDTH - CONTROLLER_SIZE_X) / 2.0f; + const float CONTROLLER_POS_Y = 160.0f; + + float centerX = CONTROLLER_POS_X + CONTROLLER_SIZE_X / 2; + float centerY = CONTROLLER_POS_Y + CONTROLLER_SIZE_Y / 2; + +#define X(f) ((f)*scale + centerX) +#define Y(f) ((f)*scale + centerY) + + m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X((CONTROLLER_SIZE_X + 4.8f) * scale), MENU_Y((CONTROLLER_SIZE_Y + 4.8f) * scale), CRGBA(0, 0, 0, 255)); + m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255)); + if (m_DisplayControllerOnFoot) { + if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400) + m_aFrontEndSprites[FE_ARROWS1].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255)); + else + m_aFrontEndSprites[FE_ARROWS3].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255)); + } else { + if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400) + m_aFrontEndSprites[FE_ARROWS2].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255)); + else + m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(X(-CONTROLLER_SIZE_X / 2)), MENU_Y(Y(-CONTROLLER_SIZE_Y / 2)), MENU_X(CONTROLLER_SIZE_X * scale), MENU_Y(CONTROLLER_SIZE_Y * scale), CRGBA(255, 255, 255, 255)); + } + + CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); + CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE * scale), MENU_Y(SMALLESTTEXT_Y_SCALE * scale)); // X + + // CFont::SetColor(CRGBA(128, 128, 128, FadeIn(255))); + CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetDropShadowPosition(1); + CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); + CFont::SetWrapx(SCREEN_WIDTH); + + float TEXT_L2_X = 50.0f + CONTROLLER_POS_X - centerX, TEXT_L2_Y = -14.0f + CONTROLLER_POS_Y - centerY; + float TEXT_L1_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_L1_Y = 25.0f + CONTROLLER_POS_Y - centerY, TEXT_L1_Y_VEH = 3.0f + TEXT_L1_Y; + float TEXT_DPAD_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_DPAD_Y = 65.0f + CONTROLLER_POS_Y - centerY; + float TEXT_LSTICK_X = -4.0f + CONTROLLER_POS_X - centerX, TEXT_LSTICK_Y = 97.0f + CONTROLLER_POS_Y - centerY; + float TEXT_SELECT_X = 103.0f + CONTROLLER_POS_X - centerX, TEXT_SELECT_Y = 141.0f + CONTROLLER_POS_Y - centerY; + float TEXT_START_X = 130.0f + CONTROLLER_POS_X - centerX, TEXT_START_Y = 128.0f + CONTROLLER_POS_Y - centerY; + float TEXT_R2_X = 184.0F + CONTROLLER_POS_X - centerX, TEXT_R2_Y = -14.0f + CONTROLLER_POS_Y - centerY; + float TEXT_R1_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_R1_Y = 25.0f + CONTROLLER_POS_Y - centerY; + + float TEXT_SQUARE_X = 144.0f + CONTROLLER_POS_X - centerX, TEXT_SQUARE_Y = 18.0f + CONTROLLER_POS_Y - centerY; + float TEXT_TRIANGLE_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_TRIANGLE_Y = 52.0f + CONTROLLER_POS_Y - centerY; + float TEXT_CIRCLE_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_CIRCLE_Y = 65.0f + CONTROLLER_POS_Y - centerY; + float TEXT_CROSS_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_CROSS_Y = 78.0f + CONTROLLER_POS_Y - centerY; + float TEXT_RSTICK_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_RSTICK_Y = 94.0f + CONTROLLER_POS_Y - centerY; + float TEXT_R3_X = 238.0f + CONTROLLER_POS_X - centerX, TEXT_R3_Y = 109.0f + CONTROLLER_POS_Y - centerY; + float TEXT_L3_X = 84.0f + CONTROLLER_POS_X - centerX, TEXT_L3_Y = 162.0f + CONTROLLER_POS_Y - centerY; + float TEXT_L2R2_X = 74.0f + CONTROLLER_POS_X - centerX, TEXT_L2R2_Y = -6.0f + CONTROLLER_POS_Y - centerY; + + switch (m_PrefsControllerType) + { + case CONTROLLER_DUALSHOCK4: + TEXT_L1_Y += 7.0f; + TEXT_L1_Y_VEH = TEXT_L1_Y; + TEXT_R1_Y += 7.0f; + TEXT_TRIANGLE_Y -= 1.0f; + TEXT_CIRCLE_Y -= 1.0f; + TEXT_CROSS_Y -= 1.0f; + TEXT_RSTICK_Y -= 4.0f; + TEXT_R3_Y -= 4.0f; + TEXT_DPAD_Y -= 1.0f; + TEXT_LSTICK_Y -= 6.0f; + TEXT_L3_X -= 2.0f; + break; + case CONTROLLER_XBOXONE: + TEXT_L2_X -= 2.0f; + TEXT_R2_X += 2.0f; + TEXT_L1_Y += 15.0f; + TEXT_L1_Y_VEH = TEXT_L1_Y; + TEXT_R1_Y += 15.0f; + TEXT_TRIANGLE_Y += 4.0f; + TEXT_CIRCLE_Y += 4.0f; + TEXT_CROSS_Y += 4.0f; + TEXT_RSTICK_Y += 1.0f; + TEXT_R3_Y += 1.0f; + TEXT_DPAD_Y += 29.0f; + TEXT_LSTICK_Y -= 22.0f; + TEXT_L3_X -= 36.0f; + TEXT_L2R2_Y += 5.0f; + TEXT_SELECT_X += 4.0f; + break; + case CONTROLLER_XBOX360: + TEXT_L2_X += 8.0f; + TEXT_R2_X -= 8.0f; + TEXT_L1_Y += 15.0f; + TEXT_L1_Y_VEH = TEXT_L1_Y; + TEXT_R1_Y += 15.0f; + TEXT_TRIANGLE_Y += 4.0f; + TEXT_CIRCLE_Y += 4.0f; + TEXT_CROSS_Y += 4.0f; + TEXT_RSTICK_Y += 4.0f; + TEXT_R3_Y += 4.0f; + TEXT_DPAD_Y += 30.0f; + TEXT_LSTICK_Y -= 21.0f; + TEXT_L3_X -= 36.0f; + TEXT_L2R2_Y += 5.0f; + TEXT_SELECT_X += 3.0f; + break; + }; + + if (m_DisplayControllerOnFoot) { + switch (CPad::GetPad(0)->Mode) { + case 0: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_LOF")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_MOV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_ATT")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3")); + break; + case 1: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_LOF")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_NA")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_ENV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_ATT")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_RUN")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3")); + break; + case 2: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_ENV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_MOV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_LOF")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_RUN")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ATT")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3")); + break; + case 3: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_CWL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y)), TheText.Get("FEC_TAR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_NA")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_MOV")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_CWR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_TAR")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_JUM")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_LOF")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_RUN")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ATT")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_FPC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_LB3")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y + 13.0f)), TheText.Get("FEC_R3")); + break; + default: + return; + } + } else { + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2R2_X)), MENU_Y(Y(TEXT_L2R2_Y)), TheText.Get("FEC_LB")); + switch (CPad::GetPad(0)->Mode) { + case 0: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_RSC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_VES")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_HO3")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HAB")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3")); + break; + case 1: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_HOR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_NA")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_RSC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HAB")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3")); + break; + case 2: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_EXV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_VES")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_RS3")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_HOR")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_BRA")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_HAB")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_CAW")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_ACC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_TUC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_SM3")); + break; + case 3: + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L2_X)), MENU_Y(Y(TEXT_L2_Y)), TheText.Get("FEC_LL")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L1_X)), MENU_Y(Y(TEXT_L1_Y_VEH)), TheText.Get("FEC_HAB")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_DPAD_X)), MENU_Y(Y(TEXT_DPAD_Y)), TheText.Get("FEC_TUC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_LSTICK_X)), MENU_Y(Y(TEXT_LSTICK_Y)), TheText.Get("FEC_VES")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_L3_X)), MENU_Y(Y(TEXT_L3_Y)), TheText.Get("FEC_HO3")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SELECT_X)), MENU_Y(Y(TEXT_SELECT_Y)), TheText.Get("FEC_CAM")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_START_X)), MENU_Y(Y(TEXT_START_Y)), TheText.Get("FEC_PAU")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R2_X)), MENU_Y(Y(TEXT_R2_Y)), TheText.Get("FEC_LR")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R1_X)), MENU_Y(Y(TEXT_R1_Y)), TheText.Get("FEC_CAW")); + CFont::SetRightJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_SQUARE_X)), MENU_Y(Y(TEXT_SQUARE_Y)), TheText.Get("FEC_SMT")); + CFont::SetJustifyOn(); // X + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_TRIANGLE_X)), MENU_Y(Y(TEXT_TRIANGLE_Y)), TheText.Get("FEC_EXV")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CIRCLE_X)), MENU_Y(Y(TEXT_CIRCLE_Y)), TheText.Get("FEC_RSC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_CROSS_X)), MENU_Y(Y(TEXT_CROSS_Y)), TheText.Get("FEC_NA")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_RSTICK_X)), MENU_Y(Y(TEXT_RSTICK_Y)), TheText.Get("FEC_ACC")); + CFont::PrintString(MENU_X_LEFT_ALIGNED(X(TEXT_R3_X)), MENU_Y(Y(TEXT_R3_Y)), TheText.Get("FEC_BRA")); + break; + default: + return; + } + } + + CFont::SetDropShadowPosition(0); // X + +#undef X +#undef Y +} +#else void CMenuManager::PrintController(void) { @@ -5830,6 +6337,7 @@ CMenuManager::PrintController(void) CFont::SetDropShadowPosition(0); // X } +#endif #ifdef MENU_MAP @@ -5854,26 +6362,14 @@ CMenuManager::PrintMap(void) bMenuMapActive = true; CRadar::InitFrontEndMap(); - // Just entered to map - if (!bMapLoaded) { - fMapSize = SCREEN_HEIGHT * 2.0f; - fMapCenterX = 0.0f; - fMapCenterY = 0.0f; + if (m_nMenuFadeAlpha < 255 && fMapCenterX == 0.f && fMapCenterY == 0.f) { + // Just entered. We need to do these transformations in here, because Radar knows whether map is active or not 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; - bMapMouseShownOnce = false; - bMapLoaded = true; - - // Let's wait for a frame to not toggle the waypoint - if (CPad::GetPad(0)->NewState.Cross) { - bMenuMapActive = false; - return; - } } // Because fMapSize is half of the map length, and map consists of 3x3 tiles. @@ -5932,34 +6428,35 @@ CMenuManager::PrintMap(void) } CRadar::DrawBlips(); + static CVector2D mapCrosshair; - CVector2D mapPoint; - mapPoint.x = m_nMousePosX; - mapPoint.y = m_nMousePosY; - - if (m_bShowMouse) { - bMapMouseShownOnce = true; - } else if (!bMapMouseShownOnce) { - mapPoint.x = SCREEN_WIDTH / 2; - mapPoint.y = SCREEN_HEIGHT / 2; + if (m_nMenuFadeAlpha != 255 && !m_bShowMouse) { + mapCrosshair.x = SCREEN_WIDTH / 2; + mapCrosshair.y = SCREEN_HEIGHT / 2; + } else if (m_bShowMouse) { + mapCrosshair.x = m_nMousePosX; + mapCrosshair.y = m_nMousePosY; } - CSprite2d::DrawRect(CRect(mapPoint.x - MENU_X(1.0f), 0.0f, - mapPoint.x + MENU_X(1.0f), SCREEN_HEIGHT), + CSprite2d::DrawRect(CRect(mapCrosshair.x - MENU_X(1.0f), 0.0f, + mapCrosshair.x + MENU_X(1.0f), SCREEN_HEIGHT), CRGBA(0, 0, 0, 150)); - CSprite2d::DrawRect(CRect(0.0f, mapPoint.y + MENU_X(1.0f), - SCREEN_WIDTH, mapPoint.y - MENU_X(1.0f)), + CSprite2d::DrawRect(CRect(0.0f, mapCrosshair.y + MENU_X(1.0f), + SCREEN_WIDTH, mapCrosshair.y - MENU_X(1.0f)), CRGBA(0, 0, 0, 150)); - if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { - if (mapPoint.y > fMapCenterY - fMapSize && mapPoint.y < fMapCenterY + fMapSize && - mapPoint.x > fMapCenterX - fMapSize && mapPoint.x < fMapCenterX + fMapSize) { + // Adding marker + if (m_nMenuFadeAlpha >= 255) { + if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { + if (mapCrosshair.y > fMapCenterY - fMapSize && mapCrosshair.y < fMapCenterY + fMapSize && + mapCrosshair.x > fMapCenterX - fMapSize && mapCrosshair.x < fMapCenterX + 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; - CRadar::ToggleTargetMarker(x, y); - DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize; + float x = ((mapCrosshair.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f; + float y = 2000.0f - ((mapCrosshair.y - diffY) / (fMapSize * 2)) * 4000.0f; + CRadar::ToggleTargetMarker(x, y); + DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); + } } } @@ -5984,12 +6481,12 @@ CMenuManager::PrintMap(void) if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) { if (CPad::GetPad(0)->GetMouseWheelDown()) - ZOOM(mapPoint.x, mapPoint.y, false); + ZOOM(mapCrosshair.x, mapCrosshair.y, false); else ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, false); } else if (CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) { if (CPad::GetPad(0)->GetMouseWheelUp()) - ZOOM(mapPoint.x, mapPoint.y, true); + ZOOM(mapCrosshair.x, mapCrosshair.y, true); else ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true); } @@ -6007,16 +6504,13 @@ CMenuManager::PrintMap(void) 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)); CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f)); CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); - CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); + CFont::SetColor(CRGBA(HEADER_COLOR.r, HEADER_COLOR.g, HEADER_COLOR.b, FadeIn(255))); float nextX = MENU_X(30.0f), nextY = 95.0f; wchar *text; @@ -6050,7 +6544,7 @@ CMenuManager::PrintMap(void) CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_MOV")); nextX = MENU_X(30.0f); nextY -= 11.0f; TEXT_PIECE("FEC_MSR", 2.0f); TEXT_PIECE("FEC_IBT", 1.0f); - CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_TAR")); + CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEM_TWP")); #undef TEXT_PIECE } @@ -6061,108 +6555,157 @@ CMenuManager::PrintMap(void) int CMenuManager::ConstructStatLine(int rowIdx) { -#define STAT_LINE(str, left, isFloat, right) \ +#define int_STAT_IS_FLOAT false +#define float_STAT_IS_FLOAT true +#define STAT_LINE_1(varType, left, right1) \ do { \ if(counter == rowIdx){ \ - BuildStatLine(str, left, isFloat, right); \ + varType a = right1; \ + BuildStatLine(left, &a, varType##_STAT_IS_FLOAT, nil); \ return 0; \ } counter++; \ } while(0) - int counter = 0, nTemp; +#define STAT_LINE_2(varType, left, right1, right2) \ + do { \ + if(counter == rowIdx){ \ + varType a = right1; \ + varType b = right2; \ + BuildStatLine(left, &a, varType##_STAT_IS_FLOAT, &b); \ + return 0; \ + } counter++; \ + } while(0) - STAT_LINE("PL_STAT", nil, false, nil); +#define TEXT_ON_LEFT_GXT(name) \ + do { \ + if(counter == rowIdx){ \ + BuildStatLine(name, nil, false, nil); \ + return 0; \ + } counter++; \ + } while(0) + +#define TEXT_ON_RIGHT(text) \ + do { \ + if(counter == rowIdx){ \ + gUString[0] = '\0'; \ + UnicodeStrcpy(gUString2, text); \ + return 0; \ + } counter++; \ + } while(0) + + // Like TEXT_ON_LEFT_GXT, but counter wasn't initialized yet I think + if (rowIdx == 0) { + BuildStatLine("PL_STAT", nil, false, nil); + return 0; + } int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 : CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1)); percentCompleted = Min(percentCompleted, 100); - STAT_LINE("PER_COM", &percentCompleted, false, nil); - STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil); - STAT_LINE("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions); - if (CGame::nastyGame) { - STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, false, &CStats::TotalNumberKillFrenzies); + switch (rowIdx) { + // 0 is the heading text above + case 1: { + BuildStatLine("PER_COM", &percentCompleted, false, nil); + return 0; + } + case 2: { + BuildStatLine("NMISON", &CStats::MissionsGiven, false, nil); + return 0; + } + case 3: { + BuildStatLine("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions); + return 0; + } } + int counter = 4; + + if (CGame::nastyGame) + STAT_LINE_2(int, "FEST_RP", CStats::NumberKillFrenziesPassed, CStats::TotalNumberKillFrenzies); CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus]; + + // Hidden packages shouldn't be shown with percent +#ifdef FIX_BUGS + STAT_LINE_2(int, "PERPIC", player.m_nCollectedPackages, player.m_nTotalPackages); +#else float packagesPercent = 0.0f; if (player.m_nTotalPackages != 0) packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages; - int nPackagesPercent = packagesPercent; - STAT_LINE("PERPIC", &nPackagesPercent, false, &(nTemp = 100)); - STAT_LINE("NOUNIF", &CStats::NumberOfUniqueJumpsFound, false, &CStats::TotalNumberOfUniqueJumps); - STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil); + STAT_LINE_2(int, "PERPIC", packagesPercent, 100); +#endif + STAT_LINE_2(int, "NOUNIF", CStats::NumberOfUniqueJumpsFound, CStats::TotalNumberOfUniqueJumps); + STAT_LINE_1(int, "DAYSPS", CStats::DaysPassed); if (CGame::nastyGame) { - STAT_LINE("PE_WAST", &CStats::PeopleKilledByPlayer, false, nil); - STAT_LINE("PE_WSOT", &CStats::PeopleKilledByOthers, false, nil); + STAT_LINE_1(int, "PE_WAST", CStats::PeopleKilledByPlayer); + STAT_LINE_1(int, "PE_WSOT", CStats::PeopleKilledByOthers); } - STAT_LINE("CAR_EXP", &CStats::CarsExploded, false, nil); - STAT_LINE("TM_BUST", &CStats::TimesArrested, false, nil); - STAT_LINE("TM_DED", &CStats::TimesDied, false, nil); - STAT_LINE("GNG_WST", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8] + STAT_LINE_1(int, "CAR_EXP", CStats::CarsExploded); + STAT_LINE_1(int, "TM_BUST", CStats::TimesArrested); + STAT_LINE_1(int, "TM_DED", CStats::TimesDied); + STAT_LINE_1(int, "GNG_WST", CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8] + CStats::PedsKilledOfThisType[PEDTYPE_GANG7] + CStats::PedsKilledOfThisType[PEDTYPE_GANG6] + CStats::PedsKilledOfThisType[PEDTYPE_GANG5] + CStats::PedsKilledOfThisType[PEDTYPE_GANG4] + CStats::PedsKilledOfThisType[PEDTYPE_GANG3] + CStats::PedsKilledOfThisType[PEDTYPE_GANG2] - + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]), false, nil); - STAT_LINE("DED_CRI", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]), false, nil); - STAT_LINE("HEL_DST", &CStats::HelisDestroyed, false, nil); - STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, false, nil); - STAT_LINE("ACCURA", &(nTemp = (CStats::InstantHitsFiredByPlayer == 0 ? 0 : - CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer)), false, nil); + + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]); + STAT_LINE_1(int, "DED_CRI", CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]); + STAT_LINE_1(int, "HEL_DST", CStats::HelisDestroyed); + STAT_LINE_1(int, "KGS_EXP", CStats::KgsOfExplosivesUsed); + STAT_LINE_1(int, "ACCURA", (CStats::InstantHitsFiredByPlayer == 0 ? 0 : + CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer)); if (CStats::ElBurroTime > 0) { - STAT_LINE("ELBURRO", &CStats::ElBurroTime, false, nil); + STAT_LINE_1(int, "ELBURRO", CStats::ElBurroTime); } if (CStats::Record4x4One > 0) { - STAT_LINE("FEST_R1", &CStats::Record4x4One, false, nil); + STAT_LINE_1(int, "FEST_R1", CStats::Record4x4One); } if (CStats::Record4x4Two > 0) { - STAT_LINE("FEST_R2", &CStats::Record4x4Two, false, nil); + STAT_LINE_1(int, "FEST_R2", CStats::Record4x4Two); } if (CStats::Record4x4Three > 0) { - STAT_LINE("FEST_R3", &CStats::Record4x4Three, false, nil); + STAT_LINE_1(int, "FEST_R3", CStats::Record4x4Three); } if (CStats::Record4x4Mayhem > 0) { - STAT_LINE("FEST_RM", &CStats::Record4x4Mayhem, false, nil); + STAT_LINE_1(int, "FEST_RM", CStats::Record4x4Mayhem); } if (CStats::LongestFlightInDodo > 0) { - STAT_LINE("FEST_LF", &CStats::LongestFlightInDodo, false, nil); + STAT_LINE_1(int, "FEST_LF", CStats::LongestFlightInDodo); } if (CStats::TimeTakenDefuseMission > 0) { - STAT_LINE("FEST_BD", &CStats::TimeTakenDefuseMission, false, nil); + STAT_LINE_1(int, "FEST_BD", CStats::TimeTakenDefuseMission); } - STAT_LINE("CAR_CRU", &CStats::CarsCrushed, false, nil); + STAT_LINE_1(int, "CAR_CRU", CStats::CarsCrushed); if (CStats::HighestScores[0] > 0) { - STAT_LINE("FEST_BB", nil, false, nil); - STAT_LINE("FEST_H0", &CStats::HighestScores[0], false, nil); + TEXT_ON_LEFT_GXT("FEST_BB"); + STAT_LINE_1(int, "FEST_H0", CStats::HighestScores[0]); } if (CStats::HighestScores[4] + CStats::HighestScores[3] + CStats::HighestScores[2] + CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_GC", nil, false, nil); + TEXT_ON_LEFT_GXT("FEST_GC"); } if (CStats::HighestScores[1] > 0) { - STAT_LINE("FEST_H1", &CStats::HighestScores[1], false, nil); + STAT_LINE_1(int, "FEST_H1", CStats::HighestScores[1]); } if (CStats::HighestScores[2] > 0) { - STAT_LINE("FEST_H2", &CStats::HighestScores[2], false, nil); + STAT_LINE_1(int, "FEST_H2", CStats::HighestScores[2]); } if (CStats::HighestScores[3] > 0) { - STAT_LINE("FEST_H3", &CStats::HighestScores[3], false, nil); + STAT_LINE_1(int, "FEST_H3", CStats::HighestScores[3]); } if (CStats::HighestScores[4] > 0) { - STAT_LINE("FEST_H4", &CStats::HighestScores[4], false, nil); + STAT_LINE_1(int, "FEST_H4", CStats::HighestScores[4]); } switch (m_PrefsLanguage) { case LANGUAGE_AMERICAN: #ifndef USE_MEASUREMENTS_IN_METERS - float fTemp; - STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil); - STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledInVehicle * MILES_IN_METER), true, nil); - STAT_LINE("MMRAIN", &CStats::mmRain, false, nil); - STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil); - STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil); + STAT_LINE_1(float, "FEST_DF", CStats::DistanceTravelledOnFoot * MILES_IN_METER); + STAT_LINE_1(float, "FEST_DC", CStats::DistanceTravelledInVehicle * MILES_IN_METER); + STAT_LINE_1(int, "MMRAIN", CStats::mmRain); + STAT_LINE_1(float, "MXCARD", CStats::MaximumJumpDistance * FEET_IN_METER); + STAT_LINE_1(float, "MXCARJ", CStats::MaximumJumpHeight * FEET_IN_METER); break; #endif case LANGUAGE_FRENCH: @@ -6174,63 +6717,65 @@ CMenuManager::ConstructStatLine(int rowIdx) case LANGUAGE_RUSSIAN: case LANGUAGE_JAPANESE: #endif - STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil); - STAT_LINE("FESTDCM", &CStats::DistanceTravelledInVehicle, true, nil); - STAT_LINE("MMRAIN", &CStats::mmRain, false, nil); - STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil); - STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil); + STAT_LINE_1(float, "FESTDFM", CStats::DistanceTravelledOnFoot); + STAT_LINE_1(float, "FESTDCM", CStats::DistanceTravelledInVehicle); + STAT_LINE_1(int, "MMRAIN", CStats::mmRain); + STAT_LINE_1(float, "MXCARDM", CStats::MaximumJumpDistance); + STAT_LINE_1(float, "MXCARJM", CStats::MaximumJumpHeight); break; default: break; } - STAT_LINE("MXFLIP", &CStats::MaximumJumpFlips, false, nil); - STAT_LINE("MXJUMP", &CStats::MaximumJumpSpins, false, nil); - STAT_LINE("BSTSTU", nil, false, nil); + STAT_LINE_1(int, "MXFLIP", CStats::MaximumJumpFlips); + STAT_LINE_1(int, "MXJUMP", CStats::MaximumJumpSpins); + TEXT_ON_LEFT_GXT("BSTSTU"); - if (counter == rowIdx) { - gUString[0] = '\0'; - switch (CStats::BestStuntJump) { - case 1: - UnicodeStrcpy(gUString2, TheText.Get("INSTUN")); - return 0; - case 2: - UnicodeStrcpy(gUString2, TheText.Get("PRINST")); - return 0; - case 3: - UnicodeStrcpy(gUString2, TheText.Get("DBINST")); - return 0; - case 4: - UnicodeStrcpy(gUString2, TheText.Get("DBPINS")); - return 0; - case 5: - UnicodeStrcpy(gUString2, TheText.Get("TRINST")); - return 0; - case 6: - UnicodeStrcpy(gUString2, TheText.Get("PRTRST")); - return 0; - case 7: - UnicodeStrcpy(gUString2, TheText.Get("QUINST")); - return 0; - case 8: - UnicodeStrcpy(gUString2, TheText.Get("PQUINS")); - return 0; - default: - UnicodeStrcpy(gUString2, TheText.Get("NOSTUC")); - return 0; - } + switch (CStats::BestStuntJump) { + case 1: + TEXT_ON_RIGHT(TheText.Get("INSTUN")); + break; + case 2: + TEXT_ON_RIGHT(TheText.Get("PRINST")); + break; + case 3: + TEXT_ON_RIGHT(TheText.Get("DBINST")); + break; + case 4: + TEXT_ON_RIGHT(TheText.Get("DBPINS")); + break; + case 5: + TEXT_ON_RIGHT(TheText.Get("TRINST")); + break; + case 6: + TEXT_ON_RIGHT(TheText.Get("PRTRST")); + break; + case 7: + TEXT_ON_RIGHT(TheText.Get("QUINST")); + break; + case 8: + TEXT_ON_RIGHT(TheText.Get("PQUINS")); + break; + default: + TEXT_ON_RIGHT(TheText.Get("NOSTUC")); + break; } - counter++; - STAT_LINE("PASDRO", &CStats::PassengersDroppedOffWithTaxi, false, nil); - STAT_LINE("MONTAX", &CStats::MoneyMadeWithTaxi, false, nil); - STAT_LINE("FEST_LS", &CStats::LivesSavedWithAmbulance, false, nil); - STAT_LINE("FEST_HA", &CStats::HighestLevelAmbulanceMission, false, nil); - STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil); - STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil); - STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil); + + STAT_LINE_1(int, "PASDRO", CStats::PassengersDroppedOffWithTaxi); + STAT_LINE_1(int, "MONTAX", CStats::MoneyMadeWithTaxi); + STAT_LINE_1(int, "FEST_LS", CStats::LivesSavedWithAmbulance); + STAT_LINE_1(int, "FEST_HA", CStats::HighestLevelAmbulanceMission); + STAT_LINE_1(int, "FEST_CC", CStats::CriminalsCaught); + STAT_LINE_1(int, "FEST_FE", CStats::FiresExtinguished); + STAT_LINE_1(int, "DAYPLC", CTimer::GetTimeInMilliseconds() + 100); return counter; -#undef STAT_LINE +#undef STAT_LINE_1 +#undef STAT_LINE_2 +#undef TEXT_ON_LEFT_GXT +#undef TEXT_ON_RIGHT +#undef int_STAT_IS_FLOAT +#undef float_STAT_IS_FLOAT } #undef GetBackJustUp diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 21124fdb..9c666809 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -25,15 +25,18 @@ #define MENUSLIDER_X 256.0f #define MENUSLIDER_UNK 256.0f -#define BIGTEXT_X_SCALE 0.75f +#define BIGTEXT_X_SCALE 0.75f // For FONT_HEADING #define BIGTEXT_Y_SCALE 0.9f -#define MEDIUMTEXT_X_SCALE 0.55f +#define MEDIUMTEXT_X_SCALE 0.55f // For FONT_HEADING #define MEDIUMTEXT_Y_SCALE 0.8f -#define SMALLTEXT_X_SCALE 0.45f +#define SMALLTEXT_X_SCALE 0.45f // used for FONT_HEADING and FONT_BANK, but looks off for HEADING #define SMALLTEXT_Y_SCALE 0.7f -#define SMALLESTTEXT_X_SCALE 0.4f +#define SMALLESTTEXT_X_SCALE 0.4f // used for both FONT_HEADING and FONT_BANK #define SMALLESTTEXT_Y_SCALE 0.6f +#define HELPER_TEXT_LEFT_MARGIN 320.0f +#define HELPER_TEXT_BOTTOM_MARGIN 120.0f + #define PLAYERSETUP_LIST_TOP 28.0f #define PLAYERSETUP_LIST_BOTTOM 125.0f #define PLAYERSETUP_LIST_LEFT 200.0f @@ -45,8 +48,6 @@ #endif #define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f #define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64 -#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f -#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f #define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f #define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f #define PLAYERSETUP_LIST_BODY_TOP 47 @@ -241,8 +242,6 @@ enum eMenuScreen #ifdef GRAPHICS_MENU_OPTIONS MENUPAGE_GRAPHICS_SETTINGS, -#else - MENUPAGE_ADVANCED_DISPLAY_SETTINGS, #endif #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS MENUPAGE_DETECT_JOYSTICK, @@ -495,6 +494,7 @@ struct CCustomScreenLayout { struct CCFO { int8 *value; + const char *saveCat; const char *save; }; @@ -506,18 +506,21 @@ struct CCFOSelect : CCFO int8 displayedValue; // only if onlyApplyOnEnter enabled for now int8 lastSavedValue; // only if onlyApplyOnEnter enabled ChangeFunc changeFunc; + bool disableIfGameLoaded; CCFOSelect() {}; - CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc){ + CCFOSelect(int8* value, const char* saveCat, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc = nil, bool disableIfGameLoaded = false){ this->value = value; if (value) this->lastSavedValue = this->displayedValue = *value; + this->saveCat = saveCat; this->save = save; this->rightTexts = (char**)rightTexts; this->numRightTexts = numRightTexts; this->onlyApplyOnEnter = onlyApplyOnEnter; this->changeFunc = changeFunc; + this->disableIfGameLoaded = disableIfGameLoaded; } }; @@ -527,8 +530,9 @@ struct CCFODynamic : CCFO ButtonPressFunc buttonPressFunc; CCFODynamic() {}; - CCFODynamic(int8* value, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){ + CCFODynamic(int8* value, const char* saveCat, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){ this->value = value; + this->saveCat = saveCat; this->save = save; this->drawFunc = drawFunc; this->buttonPressFunc = buttonPressFunc; @@ -697,8 +701,6 @@ public: #ifdef MENU_MAP static bool bMenuMapActive; - static bool bMapMouseShownOnce; - static bool bMapLoaded; static float fMapSize; static float fMapCenterY; static float fMapCenterX; @@ -723,6 +725,19 @@ public: #define ISLAND_LOADING_ISNT(p) #endif +#ifdef GAMEPAD_MENU + enum + { + CONTROLLER_DUALSHOCK2 = 0, + CONTROLLER_DUALSHOCK3, + CONTROLLER_DUALSHOCK4, + CONTROLLER_XBOX360, + CONTROLLER_XBOXONE, + }; + + static int8 m_PrefsControllerType; +#endif + public: static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2); static void CentreMousePointer(); @@ -782,6 +797,9 @@ public: void PageDownList(bool); int8 GetPreviousPageOption(); void ProcessList(bool &goBack, bool &optionSelected); +#ifdef GAMEPAD_MENU + void LoadController(int8 type); +#endif }; #ifndef IMPROVED_VIDEOMODE diff --git a/src/core/Frontend_PS2.cpp b/src/core/Frontend_PS2.cpp index 824f342b..1cb944d1 100644 --- a/src/core/Frontend_PS2.cpp +++ b/src/core/Frontend_PS2.cpp @@ -43,7 +43,7 @@ void DoRWStuffEndOfFrame(void); #define X SCREEN_SCALE_X #define Y SCREEN_SCALE_Y -#define YF(x) Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(DEFAULT_SCREEN_HEIGHT_PAL))) +#define YF(x) Y(float(x)*(float(DEFAULT_SCREEN_HEIGHT)/float(SCREEN_HEIGHT_PAL))) //#define X(x) ((x)/640.0f*SCRW) //#define Y(y) ((y)/448.0f*SCRH) diff --git a/src/core/Game.cpp b/src/core/Game.cpp index d22a7184..4fd30b53 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -1,6 +1,3 @@ -#pragma warning( push ) -#pragma warning( disable : 4005) -#pragma warning( pop ) #include "common.h" #include "platform.h" @@ -10,7 +7,6 @@ #include "Accident.h" #include "Antennas.h" #include "Bridge.h" -#include "Camera.h" #include "CarCtrl.h" #include "CarGen.h" #include "CdStream.h" @@ -32,6 +28,7 @@ #include "Fluff.h" #include "Font.h" #include "Frontend.h" +#include "frontendoption.h" #include "GameLogic.h" #include "Garages.h" #include "GenericGameStorage.h" @@ -66,7 +63,6 @@ #include "Shadows.h" #include "Skidmarks.h" #include "SpecialFX.h" -#include "Sprite2d.h" #include "Stats.h" #include "Streaming.h" #include "SurfaceTable.h" @@ -91,6 +87,9 @@ #include "screendroplets.h" #include "crossplatform.h" #include "MemoryHeap.h" +#ifdef USE_TEXTURE_POOL +#include "TexturePools.h" +#endif eLevelName CGame::currLevel; bool CGame::bDemoMode = true; @@ -113,8 +112,6 @@ void DoRWStuffEndOfFrame(void); #ifdef PS2_MENU void MessageScreen(char *msg) { - //TODO: stretch_screen - CRect rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); CRGBA color(255, 255, 255, 255); @@ -126,20 +123,32 @@ void MessageScreen(char *msg) CSprite2d *splash = LoadSplash(NULL); splash->Draw(rect, color, color, color, color); - splash->DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(110.0f), SCREEN_SCALE_X(620.0f), SCREEN_SCALE_Y(300.0f)), CRGBA(50, 50, 50, 192)); - +#ifdef FIX_BUGS + splash->DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(110.0f), SCREEN_WIDTH-SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(300.0f)), CRGBA(50, 50, 50, 192)); +#else + splash->DrawRect(CRect(20.0f, 110.0f, SCREEN_WIDTH-20.0f, 300.0f), CRGBA(50, 50, 50, 192)); +#endif CFont::SetFontStyle(FONT_BANK); CFont::SetBackgroundOff(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190)); +#ifdef FIX_BUGS CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f)); +#else + CFont::SetScale(1.0f, 1.0f); +#endif CFont::SetCentreOn(); - CFont::SetCentreSize(SCREEN_SCALE_X(450.0f)); // 450.0f + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 190)); // 450.0f CFont::SetJustifyOff(); CFont::SetColor(CRGBA(255, 255, 255, 255)); CFont::SetDropColor(CRGBA(32, 32, 32, 255)); CFont::SetDropShadowPosition(3); + CFont::SetBackGroundOnlyTextOff(); CFont::SetPropOn(); - CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(130.0f), TheText.Get(msg)); +#ifdef FIX_BUGS + CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(130.0f), TheText.Get(msg)); +#else + CFont::PrintString(SCREEN_WIDTH/2, 130.0f, TheText.Get(msg)); +#endif CFont::DrawFonts(); DoRWStuffEndOfFrame(); @@ -155,6 +164,11 @@ CGame::InitialiseOnceBeforeRW(void) #ifdef EXTENDED_COLOURFILTER CPostFX::InitOnce(); #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + // Not needed here but may be needed in future + // if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) + CustomFrontendOptionsPopulate(); +#endif return true; } @@ -173,19 +187,33 @@ CGame::InitialiseRenderWare(void) #ifdef USE_TEXTURE_POOL _TexturePoolsInitialise(); #endif - - CTxdStore::Initialise(); - CVisibilityPlugins::Initialise(); - + +#if GTA_VERSION > GTA3_PS2_160 + CTxdStore::Initialise(); // in GameInit on ps2 + CVisibilityPlugins::Initialise(); // in plugin attach on ps2 +#endif + + //InitialiseScene(Scene); // PS2 only, only clears Scene.camera + +#ifdef GTA_PS2 + RpSkySelectTrueTSClipper(TRUE); + RpSkySelectTrueTLClipper(TRUE); + + // PS2ManagerApplyDirectionalLightingCB() uploads the GTA lights + // directly without going through RpWorld and all that + SetupPS2ManagerDefaultLightingCallback(); + PreAllocateRwObjects(); +#endif + /* Create camera */ - Scene.camera = CameraCreate(RsGlobal.width, RsGlobal.height, TRUE); + Scene.camera = CameraCreate(SCREEN_WIDTH, SCREEN_HEIGHT, TRUE); ASSERT(Scene.camera != nil); if (!Scene.camera) { return (false); } - RwCameraSetFarClipPlane(Scene.camera, 2000.0f); + RwCameraSetFarClipPlane(Scene.camera, 2000.0f); // 250.0f on PS2 but who cares RwCameraSetNearClipPlane(Scene.camera, 0.9f); CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO); @@ -208,8 +236,12 @@ CGame::InitialiseRenderWare(void) /* Add the camera to the world */ RpWorldAddCamera(Scene.world, Scene.camera); LightsCreate(Scene.world); - - CreateDebugFont(); + +#if GTA_VERSION > GTA3_PS2_160 + CreateDebugFont(); // in GameInit on PS2 +#else + RwImageSetPath("textures"); +#endif #ifdef LIBRW #ifdef PS2_MATFX @@ -225,16 +257,38 @@ CGame::InitialiseRenderWare(void) ReplaceAtomicPipeCallback(); #endif // PS2_ALPHA_TEST #endif // LIBRW - + + +#if GTA_VERSION > GTA3_PS2_160 + // in GameInit on PS2 + PUSH_MEMID(MEMID_TEXTURES); CFont::Initialise(); CHud::Initialise(); + POP_MEMID(); + // TODO: define CPlayerSkin::Initialise(); +#endif +#ifdef EXTENDED_PIPELINES + CustomPipes::CustomPipeInit(); // need Scene.world for this +#endif +#ifdef SCREEN_DROPLETS + ScreenDroplets::InitDraw(); +#endif + return (true); } +// missing altogether on PS2 void CGame::ShutdownRenderWare(void) { +#ifdef SCREEN_DROPLETS + ScreenDroplets::Shutdown(); +#endif +#ifdef EXTENDED_PIPELINES + CustomPipes::CustomPipeShutdown(); +#endif + CMBlur::MotionBlurClose(); DestroySplashScreen(); CHud::Shutdown(); @@ -242,7 +296,8 @@ void CGame::ShutdownRenderWare(void) for ( int32 i = 0; i < NUMPLAYERS; i++ ) CWorld::Players[i].DeletePlayerSkin(); - + + // TODO: define CPlayerSkin::Shutdown(); DestroyDebugFont(); @@ -265,10 +320,12 @@ void CGame::ShutdownRenderWare(void) #endif } +// missing altogether on PS2 bool CGame::InitialiseOnceAfterRW(void) { +#if GTA_VERSION > GTA3_PS2_160 TheText.Load(); - DMAudio.Initialise(); + DMAudio.Initialise(); // before TheGame() on PS2 CTimer::Initialise(); CTempColModels::Initialise(); mod_HandlingManager.Initialise(); @@ -276,6 +333,7 @@ bool CGame::InitialiseOnceAfterRW(void) CPedStats::Initialise(); CTimeCycle::Initialise(); +#ifndef GTA_PS2 if ( DMAudio.GetNum3DProvidersAvailable() == 0 ) FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = -1; @@ -313,11 +371,13 @@ bool CGame::InitialiseOnceAfterRW(void) DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume); DMAudio.SetEffectsFadeVol(127); DMAudio.SetMusicFadeVol(127); +#endif CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile); - +#endif return true; } +// missing altogether on PS2 void CGame::FinalShutdown(void) { @@ -326,14 +386,23 @@ CGame::FinalShutdown(void) CdStreamShutdown(); } +#if GTA_VERSION <= GTA3_PS2_160 +bool CGame::Initialise(void) +#else bool CGame::Initialise(const char* datFile) +#endif { #ifdef GTA_PS2 // TODO: upload VU0 collision code here -#else +#endif + +#if GTA_VERSION > GTA3_PS2_160 ResetLoadingScreenBar(); strcpy(aDatFile, datFile); CPools::Initialise(); // done in CWorld on PS2 +#endif + +#ifndef GTA_PS2 CIniFile::LoadIniFile(); #endif @@ -367,13 +436,15 @@ bool CGame::Initialise(const char* datFile) CWeather::Init(); CCullZones::Init(); CCollision::Init(); -#ifdef PS2_MENU +#ifdef PS2_MENU // TODO: is this the right define? TheText.Load(); #endif CTheZones::Init(); CUserDisplay::Init(); CMessages::Init(); +#if GTA_VERSION > GTA3_PS2_160 CMessages::ClearAllMessagesDisplayedByGame(); +#endif CRecordDataForGame::Init(); CRestart::Initialise(); @@ -381,11 +452,17 @@ bool CGame::Initialise(const char* datFile) CWorld::Initialise(); POP_MEMID(); +#if GTA_VERSION <= GTA3_PS2_160 + mod_HandlingManager.Initialise(); + CSurfaceTable::Initialise("DATA\\SURFACE.DAT"); + CTempColModels::Initialise(); +#endif + PUSH_MEMID(MEMID_TEXTURES); CParticle::Initialise(); POP_MEMID(); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 gStartX = -180.0f; gStartY = 180.0f; gStartZ = 14.0f; @@ -400,20 +477,27 @@ bool CGame::Initialise(const char* datFile) CCarCtrl::Init(); POP_MEMID(); -#ifndef GTA_PS2 + PUSH_MEMID(MEMID_DEF_MODELS); +#if GTA_VERSION > GTA3_PS2_160 InitModelIndices(); #endif - - PUSH_MEMID(MEMID_DEF_MODELS); CModelInfo::Initialise(); -#ifndef GTA_PS2 + +#if GTA_VERSION > GTA3_PS2_160 // probably moved before LoadLevel for multiplayer maps? CPickups::Init(); CTheCarGenerators::Init(); -#endif + CdStreamAddImage("MODELS\\GTA3.IMG"); + CFileLoader::LoadLevel("DATA\\DEFAULT.DAT"); CFileLoader::LoadLevel(datFile); +#else + CPedStats::Initialise(); // InitialiseOnceAfterRW + + CFileLoader::LoadLevel("GTA3.DAT"); +#endif + #ifdef EXTENDED_PIPELINES // for generic fallback CustomPipes::SetTxdFindCallback(); @@ -424,18 +508,25 @@ bool CGame::Initialise(const char* datFile) CTheZones::PostZoneCreation(); POP_MEMID(); +#if GTA_VERSION <= GTA3_PS2_160 + TestModelIndices(); +#endif LoadingScreen("Loading the Game", "Setup paths", GetRandomSplashScreen()); ThePaths.PreparePathData(); - // done elsewhere on PS2 +#if GTA_VERSION > GTA3_PS2_160 for (int i = 0; i < NUMPLAYERS; i++) CWorld::Players[i].Clear(); CWorld::Players[0].LoadPlayerSkin(); TestModelIndices(); - // +#endif LoadingScreen("Loading the Game", "Setup water", nil); CWaterLevel::Initialise("DATA\\WATER.DAT"); +#if GTA_VERSION <= GTA3_PS2_160 + CTimeCycle::Initialise(); // InitialiseOnceAfterRW +#else TheConsole.Init(); +#endif CDraw::SetFOV(120.0f); CDraw::ms_fLODDistance = 500.0f; @@ -445,7 +536,9 @@ bool CGame::Initialise(const char* datFile) CStreaming::LoadInitialPeds(); CStreaming::RequestBigBuildings(LEVEL_GENERIC); CStreaming::LoadAllRequestedModels(false); +#if GTA_VERSION > GTA3_PS2_160 printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d +#endif LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen()); PUSH_MEMID(MEMID_ANIMATION); @@ -472,6 +565,11 @@ bool CGame::Initialise(const char* datFile) LoadingScreen("Loading the Game", "Setup game variables", nil); CPopulation::Initialise(); +#if GTA_VERSION <= GTA3_PS2_160 + for (int i = 0; i < NUMPLAYERS; i++) + CWorld::Players[i].Clear(); +// CWorld::Players[0].LoadPlayerSkin(); // TODO: use a define for this +#endif CWorld::PlayerInFocus = 0; CCoronas::Init(); CShadows::Init(); @@ -480,7 +578,7 @@ bool CGame::Initialise(const char* datFile) CAntennas::Init(); CGlass::Init(); gPhoneInfo.Initialise(); -#ifndef GTA_PS2 +#ifdef GTA_SCENE_EDIT CSceneEdit::Initialise(); #endif @@ -491,11 +589,11 @@ bool CGame::Initialise(const char* datFile) POP_MEMID(); LoadingScreen("Loading the Game", "Setup game variables", nil); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CTimer::Initialise(); #endif CClock::Initialise(1000); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CTheCarGenerators::Init(); #endif CHeli::InitHelis(); @@ -503,44 +601,50 @@ bool CGame::Initialise(const char* datFile) CMovingThings::Init(); CDarkel::Init(); CStats::Init(); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CPickups::Init(); #endif CPacManPickups::Init(); - // CGarages::Init(); here on PS2 instead +#if GTA_VERSION <= GTA3_PS2_160 + CGarages::Init(); +#endif CRubbish::Init(); CClouds::Init(); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CRemote::Init(); #endif CSpecialFX::Init(); CWaterCannons::Init(); CBridge::Init(); +#if GTA_VERSION > GTA3_PS2_160 CGarages::Init(); +#endif LoadingScreen("Loading the Game", "Position dynamic objects", nil); CWorld::RepositionCertainDynamicObjects(); - // CCullZones::ResolveVisibilities(); on PS2 here instead +#if GTA_VERSION <= GTA3_PS2_160 + CCullZones::ResolveVisibilities(); +#endif LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); +#if GTA_VERSION > GTA3_PS2_160 CCullZones::ResolveVisibilities(); +#endif CTrain::InitTrains(); CPlane::InitPlanes(); CCredits::Init(); CRecordDataForChase::Init(); CReplay::Init(); + LoadingScreen("Loading the Game", "Start script", nil); #ifdef PS2_MENU if ( !TheMemoryCard.m_bWantToLoad ) - { #endif - LoadingScreen("Loading the Game", "Start script", nil); - CTheScripts::StartTestScript(); - CTheScripts::Process(); - TheCamera.Process(); -#ifdef PS2_MENU + { + CTheScripts::StartTestScript(); + CTheScripts::Process(); + TheCamera.Process(); } -#endif LoadingScreen("Loading the Game", "Load scene", nil); CModelInfo::RemoveColModelsFromOtherLevels(currLevel); @@ -556,7 +660,7 @@ bool CGame::ShutDown(void) CPlane::Shutdown(); CTrain::Shutdown(); CSpecialFX::Shutdown(); -#ifndef PS2 +#if GTA_VERSION > GTA3_PS2_160 CGarages::Shutdown(); #endif CMovingThings::Shutdown(); @@ -597,7 +701,9 @@ bool CGame::ShutDown(void) CSkidmarks::Shutdown(); CWeaponEffects::Shutdown(); CParticle::Shutdown(); +#if GTA_VERSION > GTA3_PS2_160 CPools::ShutDown(); +#endif CTxdStore::RemoveTxdSlot(gameTxdSlot); CdStreamRemoveImages(); return true; @@ -608,13 +714,11 @@ void CGame::ReInitGameObjectVariables(void) CGameLogic::InitAtStartOfGame(); #ifdef PS2_MENU if ( !TheMemoryCard.m_bWantToLoad ) - { #endif - TheCamera.Init(); - TheCamera.SetRwCamera(Scene.camera); -#ifdef PS2_MENU + { + TheCamera.Init(); + TheCamera.SetRwCamera(Scene.camera); } -#endif CDebug::DebugInitTextBuffer(); CWeather::Init(); CUserDisplay::Init(); @@ -623,7 +727,7 @@ void CGame::ReInitGameObjectVariables(void) CWorld::bDoingCarCollisions = false; CHud::ReInitialise(); CRadar::Initialise(); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 gStartX = -180.0f; gStartY = 180.0f; gStartZ = 14.0f; @@ -646,7 +750,7 @@ void CGame::ReInitGameObjectVariables(void) CWorld::Players[i].Clear(); CWorld::PlayerInFocus = 0; -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CWeaponEffects::Init(); CSkidmarks::Init(); #endif @@ -669,7 +773,7 @@ void CGame::ReInitGameObjectVariables(void) CPickups::Init(); CPacManPickups::Init(); CGarages::Init(); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CClouds::Init(); CRemote::Init(); #endif @@ -739,7 +843,7 @@ void CGame::ShutDownForRestart(void) CRadar::RemoveRadarSections(); FrontEndMenuManager.UnloadTextures(); CParticleObject::RemoveAllParticleObjects(); -#ifndef PS2 +#if GTA_VERSION >= GTA3_PS2_160 CPedType::Shutdown(); CSpecialFX::Shutdown(); #endif @@ -813,12 +917,19 @@ void CGame::InitialiseWhenRestarting(void) DefinedState(); CSprite2d *splash = LoadSplash(NULL); - splash->Draw(rect, color, color, color, color); - splash->DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(110.0f), SCREEN_SCALE_X(620.0f), SCREEN_SCALE_Y(300.0f)), CRGBA(50, 50, 50, 192)); - - //CFont::SetFontStyle(?); + splash->Draw(rect, color, color, color, color); +#ifdef FIX_BUGS + splash->DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(110.0f), SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_Y(300.0f)), CRGBA(50, 50, 50, 192)); +#else + splash->DrawRect(CRect(20.0f, 110.0f, SCREEN_WIDTH-20.0f, 300.0f), CRGBA(50, 50, 50, 192)); +#endif + CFont::SetBackgroundOff(); - CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f +#ifdef ASPECT_RATIO_SCALE + CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // because SCREEN_SCALE_FROM_RIGHT(x) != SCREEN_SCALE_X(640-x) +#else + CFont::SetWrapx(SCREEN_SCALE_X(480.0f)); +#endif CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f)); CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_SCALE_X(480.0f)); @@ -828,9 +939,15 @@ void CGame::InitialiseWhenRestarting(void) CFont::SetDropColor(CRGBA(32, 32, 32, 255)); CFont::SetDropShadowPosition(3); CFont::SetPropOn(); - CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(130.0f), TheText.Get("MC_LDFL")); // Load Failed! - CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(170.0f), TheText.Get("FES_NOC")); // No Memory Card (PS2) in MEMORY CARD slot 1. - CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(240.0f), TheText.Get("MC_NWRE")); // Now Restarting Game. +#ifdef FIX_BUGS + CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(130.0f), TheText.Get("MC_LDFL")); // Load Failed! + CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(170.0f), TheText.Get("FES_NOC")); // No Memory Card (PS2) in MEMORY CARD slot 1. + CFont::PrintString(SCREEN_WIDTH/2, SCREEN_SCALE_Y(240.0f), TheText.Get("MC_NWRE")); // Now Restarting Game. +#else + CFont::PrintString(SCREEN_WIDTH/2, 130.0f, TheText.Get("MC_LDFL")); // Load Failed! + CFont::PrintString(SCREEN_WIDTH/2, 170.0f, TheText.Get("FES_NOC")); // No Memory Card (PS2) in MEMORY CARD slot 1. + CFont::PrintString(SCREEN_WIDTH/2, 240.0f, TheText.Get("MC_NWRE")); // Now Restarting Game. +#endif CFont::DrawFonts(); DoRWStuffEndOfFrame(); @@ -925,7 +1042,9 @@ void CGame::Process(void) CSkidmarks::Update(); CAntennas::Update(); CGlass::Update(); +#ifdef GTA_SCENE_EDIT CSceneEdit::Update(); +#endif CEventList::Update(); CParticle::Update(); gFireManager.Update(); @@ -977,23 +1096,358 @@ void CGame::Process(void) #endif } -void CGame::DrasticTidyUpMemory(bool) +#ifdef USE_CUSTOM_ALLOCATOR + +int32 gNumMemMoved; + +bool +MoveMem(void **ptr) +{ + if(*ptr){ + gNumMemMoved++; + void *newPtr = gMainHeap.MoveMemory(*ptr); + if(*ptr != newPtr){ + *ptr = newPtr; + return true; + } + } + return false; +} + +// Some convenience structs +struct SkyDataPrefix +{ + uint32 pktSize1; + uint32 data; // pointer to data as read from TXD + uint32 pktSize2; + uint32 unused; +}; + +struct DMAGIFUpload +{ + uint32 tag1_qwc, tag1_addr; // dmaref + uint32 nop1, vif_direct1; + + uint32 giftag[4]; + uint32 gs_bitbltbuf[4]; + + uint32 tag2_qwc, tag2_addr; // dmaref + uint32 nop2, vif_direct2; +}; + +// This is very scary. it depends on the exact memory layout of the DMA chains and whatnot +RwTexture * +MoveTextureMemoryCB(RwTexture *texture, void *pData) +{ +#ifdef GTA_PS2 + bool *pRet = (bool*)pData; + RwRaster *raster = RwTextureGetRaster(texture); + _SkyRasterExt *rasterExt = RASTEREXTFROMRASTER(raster); + if(raster->originalPixels == nil || // the raw data + raster->cpPixels == raster->originalPixels || // old format, can't handle it + rasterExt->dmaRefCount != 0 && rasterExt->dmaClrCount != 0) + return texture; + + // this is the allocated pointer we will move + SkyDataPrefix *prefix = (SkyDataPrefix*)raster->originalPixels; + DMAGIFUpload *uploads = (DMAGIFUpload*)(prefix+1); + + // We have 4qw for each upload, + // i.e. for each buffer width of mip levels, + // and the palette if there is one. + // NB: this code does NOT support mipmaps! + // so we assume two uploads (pixels and palette) + // + // each upload looks like this: + // (DMAcnt; NOP; VIF DIRECT(2)) + // giftag (1, A+D) + // GS_BITBLTBUF + // (DMAref->pixel data; NOP; VIF DIRECT(5)) + // the DMArefs are what we have to adjust + uintptr dataDiff, upload1Diff, upload2Diff, pixelDiff, paletteDiff; + dataDiff = prefix->data - (uintptr)raster->originalPixels; + upload1Diff = uploads[0].tag2_addr - (uintptr)raster->originalPixels; + if(raster->palette) + upload2Diff = uploads[1].tag2_addr - (uintptr)raster->originalPixels; + pixelDiff = (uintptr)raster->cpPixels - (uintptr)raster->originalPixels; + if(raster->palette) + paletteDiff = (uintptr)raster->palette - (uintptr)raster->originalPixels; + uint8 *newptr = (uint8*)gMainHeap.MoveMemory(raster->originalPixels); + if(newptr != raster->originalPixels){ + // adjust everything + prefix->data = (uintptr)newptr + dataDiff; + uploads[0].tag2_addr = (uintptr)newptr + upload1Diff; + if(raster->palette) + uploads[1].tag2_addr = (uintptr)newptr + upload2Diff; + raster->originalPixels = newptr; + raster->cpPixels = newptr + pixelDiff; + if(raster->palette) + raster->palette = newptr + paletteDiff; + + if(pRet){ + *pRet = true; + return nil; + } + } +#else + // nothing to do here really, everything should be in videomemory +#endif + return texture; +} + +bool +MoveAtomicMemory(RpAtomic *atomic, bool onlyOne) +{ + RpGeometry *geo = RpAtomicGetGeometry(atomic); + +#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31 + if(MoveMem((void**)&geo->triangles) && onlyOne) + return true; + if(MoveMem((void**)&geo->matList.materials) && onlyOne) + return true; + if(MoveMem((void**)&geo->preLitLum) && onlyOne) + return true; + if(MoveMem((void**)&geo->texCoords[0]) && onlyOne) + return true; + if(MoveMem((void**)&geo->texCoords[1]) && onlyOne) + return true; + + // verts and normals of morph target are allocated together + int vertDiff; + if(geo->morphTarget->normals) + vertDiff = geo->morphTarget->normals - geo->morphTarget->verts; + if(MoveMem((void**)&geo->morphTarget->verts)){ + if(geo->morphTarget->normals) + geo->morphTarget->normals = geo->morphTarget->verts + vertDiff; + if(onlyOne) + return true; + } + + RpMeshHeader *oldmesh = geo->mesh; + if(MoveMem((void**)&geo->mesh)){ + // index pointers are allocated together with meshes, + // have to relocate those too + RpMesh *mesh = (RpMesh*)(geo->mesh+1); + uintptr reloc = (uintptr)geo->mesh - (uintptr)oldmesh; + for(int i = 0; i < geo->mesh->numMeshes; i++) + mesh[i].indices = (RxVertexIndex*)((uintptr)mesh[i].indices + reloc); + if(onlyOne) + return true; + } +#else + // we could do something in librw here +#endif + return false; +} + +bool +MoveColModelMemory(CColModel &colModel, bool onlyOne) +{ +#if GTA_VERSION >= GTA3_PS2_160 + // hm...should probably only do this if ownsCollisionVolumes + // but it doesn't exist on PS2... + if(!colModel.ownsCollisionVolumes) + return false; +#endif + + if(MoveMem((void**)&colModel.spheres) && onlyOne) + return true; + if(MoveMem((void**)&colModel.lines) && onlyOne) + return true; + if(MoveMem((void**)&colModel.boxes) && onlyOne) + return true; + if(MoveMem((void**)&colModel.vertices) && onlyOne) + return true; + if(MoveMem((void**)&colModel.triangles) && onlyOne) + return true; + if(MoveMem((void**)&colModel.trianglePlanes) && onlyOne) + return true; + return false; +} + +RpAtomic* +MoveAtomicMemoryCB(RpAtomic *atomic, void *pData) +{ + bool *pRet = (bool*)pData; + if(pRet == nil) + MoveAtomicMemory(atomic, false); + else if(MoveAtomicMemory(atomic, true)){ + *pRet = true; + return nil; + } + return atomic; +} + +bool +TidyUpModelInfo(CBaseModelInfo *modelInfo, bool onlyone) +{ + if(modelInfo->GetColModel() && modelInfo->DoesOwnColModel()) + if(MoveColModelMemory(*modelInfo->GetColModel(), onlyone)) + return true; + + RwObject *rwobj = modelInfo->GetRwObject(); + if(RwObjectGetType(rwobj) == rpATOMIC) + if(MoveAtomicMemory((RpAtomic*)rwobj, onlyone)) + return true; + if(RwObjectGetType(rwobj) == rpCLUMP){ + bool ret = false; + if(onlyone) + RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, &ret); + else + RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, nil); + if(ret) + return true; + } + + if(modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel) + if(MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone)) + return true; + + return false; +} +#endif + +void CGame::DrasticTidyUpMemory(bool flushDraw) { #ifdef USE_CUSTOM_ALLOCATOR - // meow + bool removedCol = false; + + TidyUpMemory(true, flushDraw); + + if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){ + CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL); + CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN); + TidyUpMemory(true, flushDraw); + } + + if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){ + CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC); + TidyUpMemory(true, flushDraw); + removedCol = true; + } + + if(gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro){ + CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL); + CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL); + CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN); + TidyUpMemory(true, flushDraw); + } + + if(removedCol){ + // different on PS2 + CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory); + } + + if(!playingIntro) + CStreaming::RequestBigBuildings(currLevel); + + CStreaming::LoadAllRequestedModels(true); #endif } -void CGame::TidyUpMemory(bool, bool) +void CGame::TidyUpMemory(bool moveTextures, bool flushDraw) { #ifdef USE_CUSTOM_ALLOCATOR - // meow + printf("Largest free block before tidy %d\n", gMainHeap.GetLargestFreeBlock()); + + if(moveTextures){ + if(flushDraw){ +#ifdef GTA_PS2 + for(int i = 0; i < sweMaxFlips+1; i++){ +#else + for(int i = 0; i < 5; i++){ // probably more than needed +#endif + RwCameraBeginUpdate(Scene.camera); + RwCameraEndUpdate(Scene.camera); + RwCameraShowRaster(Scene.camera, nil, 0); + } + } + int fontSlot = CTxdStore::FindTxdSlot("fonts"); + + for(int i = 0; i < TXDSTORESIZE; i++){ + if(i == fontSlot || + CTxdStore::GetSlot(i) == nil) + continue; + RwTexDictionary *txd = CTxdStore::GetSlot(i)->texDict; + if(txd) + RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, nil); + } + } + + // animations + for(int i = 0; i < NUMANIMATIONS; i++){ + CAnimBlendHierarchy *anim = CAnimManager::GetAnimation(i); + if(anim == nil) + continue; // cannot happen + anim->MoveMemory(); + } + + // model info + for(int i = 0; i < MODELINFOSIZE; i++){ + CBaseModelInfo *mi = CModelInfo::GetModelInfo(i); + if(mi == nil) + continue; + TidyUpModelInfo(mi, false); + } + + printf("Largest free block after tidy %d\n", gMainHeap.GetLargestFreeBlock()); #endif } void CGame::ProcessTidyUpMemory(void) { #ifdef USE_CUSTOM_ALLOCATOR - // meow + static int32 modelIndex = 0; + static int32 animIndex = 0; + static int32 txdIndex = 0; + bool txdReturn = false; + RwTexDictionary *txd = nil; + gNumMemMoved = 0; + + // model infos + for(int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++){ + CBaseModelInfo *mi; + do{ + mi = CModelInfo::GetModelInfo(modelIndex); + modelIndex++; + if(modelIndex >= MODELINFOSIZE) + modelIndex = 0; + }while(mi == nil); + + if(TidyUpModelInfo(mi, true)) + return; + } + + // tex dicts + for(int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++){ + if(gNumMemMoved > 80) + break; + + do{ +#ifdef FIX_BUGS + txd = nil; +#endif + if(CTxdStore::GetSlot(txdIndex)) + txd = CTxdStore::GetSlot(txdIndex)->texDict; + txdIndex++; + if(txdIndex >= TXDSTORESIZE) + txdIndex = 0; + }while(txd == nil); + + RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, &txdReturn); + if(txdReturn) + return; + } + + // animations + CAnimBlendHierarchy *anim; + do{ + anim = CAnimManager::GetAnimation(animIndex); + animIndex++; + if(animIndex >= NUMANIMATIONS) + animIndex = 0; + }while(anim == nil); // always != nil + anim->MoveMemory(true); #endif } diff --git a/src/core/Game.h b/src/core/Game.h index 46e8fc68..002033a0 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -5,7 +5,8 @@ enum eLevelName { LEVEL_GENERIC = 0, LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, - LEVEL_SUBURBAN + LEVEL_SUBURBAN, + NUM_LEVELS }; class CGame @@ -29,7 +30,11 @@ public: static void ShutdownRenderWare(void); static bool InitialiseOnceAfterRW(void); static void FinalShutdown(void); +#if GTA_VERSION <= GTA3_PS2_160 + static bool Initialise(void); +#else static bool Initialise(const char *datFile); +#endif static bool ShutDown(void); static void ReInitGameObjectVariables(void); static void ReloadIPLs(void); diff --git a/src/core/General.h b/src/core/General.h index dde43c0f..478ef027 100644 --- a/src/core/General.h +++ b/src/core/General.h @@ -121,10 +121,19 @@ public: return *str2 != '\0'; } + static bool faststrncmp(const char *str1, const char *str2, uint32 count) + { + for(uint32 i = 0; *str1 && i < count; str1++, str2++, i++) { + if (*str1 != *str2) + return true; + } + return false; + } + static bool faststricmp(const char *str1, const char *str2) { for (; *str1; str1++, str2++) { -#if MUCH_SLOWER || !defined _WIN32 || defined __MINGW32__ +#ifndef ASCII_STRCMP if (toupper(*str1) != toupper(*str2)) #else if (__ascii_toupper(*str1) != __ascii_toupper(*str2)) diff --git a/src/core/Lists.h b/src/core/Lists.h index ecf24740..7572e882 100644 --- a/src/core/Lists.h +++ b/src/core/Lists.h @@ -1,7 +1,5 @@ #pragma once -#include "common.h" - class CPtrNode { public: diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index 9eff09e6..7c90ea12 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -271,7 +271,9 @@ CMenuScreen aScreens[MENUPAGES] = { // MENUPAGE_CONTROLLER_PC = 35 { "FET_CTL", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0, +#ifdef PC_PLAYER_CONTROLS MENUACTION_CTRLMETHOD, "FET_CME", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, +#endif 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, diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp index f8ff3acf..357f136b 100644 --- a/src/core/MenuScreensCustom.cpp +++ b/src/core/MenuScreensCustom.cpp @@ -16,6 +16,7 @@ #include "Collision.h" #include "ModelInfo.h" #include "Pad.h" +#include "ControllerConfig.h" // Menu screens array is at the bottom of the file. @@ -24,67 +25,62 @@ #ifdef CUSTOM_FRONTEND_OPTIONS #ifdef IMPROVED_VIDEOMODE - #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) }, + #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) }, #else #define VIDEOMODE_SELECTOR #endif #ifdef MULTISAMPLING - #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, + #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "Graphics", "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, #else #define MULTISAMPLING_SELECTOR #endif #ifdef CUTSCENE_BORDERS_SWITCH - #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&CMenuManager::m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false, nil) }, + #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&CMenuManager::m_PrefsCutsceneBorders, "Display", "CutsceneBorders", off_on, 2, false) }, #else #define CUTSCENE_BORDERS_TOGGLE #endif #ifdef FREE_CAM - #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false, nil) }, + #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "Display", "FreeCam", off_on, 2, false) }, #else #define FREE_CAM_TOGGLE #endif #ifdef PS2_ALPHA_TEST - #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false, nil) }, + #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) }, #else #define DUALPASS_SELECTOR #endif #ifdef NO_ISLAND_LOADING - #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, + #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, #else #define ISLAND_LOADING_SELECTOR #endif #ifdef EXTENDED_COLOURFILTER #define POSTFX_SELECTORS \ - MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, \ - MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) }, + MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "Graphics", "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, \ + MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "Graphics", "MotionBlur", off_on, 2, false) }, #else #define POSTFX_SELECTORS #endif -#ifdef EXTENDED_PIPELINES - #define PIPELINES_SELECTOR \ - MENUACTION_CFO_SELECT, "FED_VPL", { new CCFOSelect((int8*)&CustomPipes::VehiclePipeSwitch, "VehiclePipeline", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), false, nil) }, \ - MENUACTION_CFO_SELECT, "FED_PRM", { new CCFOSelect((int8*)&CustomPipes::RimlightEnable, "NeoRimLight", off_on, 2, false, nil) }, \ - MENUACTION_CFO_SELECT, "FED_WLM", { new CCFOSelect((int8*)&CustomPipes::LightmapEnable, "NeoLightMaps", off_on, 2, false, nil) }, \ - MENUACTION_CFO_SELECT, "FED_RGL", { new CCFOSelect((int8*)&CustomPipes::GlossEnable, "NeoRoadGloss", off_on, 2, false, nil) }, +#ifdef INVERT_LOOK_FOR_PAD + #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "Controller", "InvertPad", off_on, 2, false) }, #else - #define PIPELINES_SELECTOR + #define INVERT_PAD_SELECTOR #endif -#ifdef INVERT_LOOK_FOR_PAD - #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "InvertPad", off_on, 2, false, nil) }, +#ifdef GAMEPAD_MENU + #define SELECT_CONTROLLER_TYPE MENUACTION_CFO_SELECT, "FEC_TYP", { new CCFOSelect((int8*)&CMenuManager::m_PrefsControllerType, "Controller", "Type", controllerTypes, ARRAY_SIZE(controllerTypes), false, ControllerTypeAfterChange) }, #else - #define INVERT_PAD_SELECTOR + #define SELECT_CONTROLLER_TYPE #endif const char *filterNames[] = { "FEM_NON", "FEM_SIM", "FEM_NRM", "FEM_MOB" }; -const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" }; const char *off_on[] = { "FEM_OFF", "FEM_ON" }; void RestoreDefGraphics(int8 action) { @@ -115,7 +111,7 @@ void RestoreDefGraphics(int8 action) { CMenuManager::m_PrefsVsync = true; CMenuManager::m_PrefsUseWideScreen = false; FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode; - #ifdef GTA3_1_1_PATCH + #if GTA_VERSION >= GTA3_PC_11 if (_dwOperatingSystemVersion == OS_WIN98) { CMBlur::BlurOn = false; CMBlur::MotionBlurClose(); @@ -303,6 +299,7 @@ void ScreenModeAfterChange(int8 before, int8 after) #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS wchar selectedJoystickUnicode[128]; +int cachedButtonNum = -1; wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { int numButtons; @@ -331,6 +328,7 @@ wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { strcpy(gSelectedJoystickName, joyname); PSGLOBAL(joy1id) = found; + cachedButtonNum = numButtons; } } if (PSGLOBAL(joy1id) == -1) @@ -340,6 +338,26 @@ wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { return selectedJoystickUnicode; } + +void DetectJoystickGoBack() { + if (cachedButtonNum != -1) { +#ifdef LOAD_INI_SETTINGS + ControlsManager.InitDefaultControlConfigJoyPad(cachedButtonNum); + SaveINIControllerSettings(); +#else + // Otherwise no way to save gSelectedJoystickName or ms_padButtonsInited anyway :shrug: Why do you even use this config.?? +#endif + cachedButtonNum = -1; + } +} +#endif + +#ifdef GAMEPAD_MENU +const char* controllerTypes[] = { "FEC_DS2", "FEC_DS3", "FEC_DS4", "FEC_360", "FEC_ONE" }; +void ControllerTypeAfterChange(int8 before, int8 after) +{ + FrontEndMenuManager.LoadController(after); +} #endif CMenuScreenCustom aScreens[MENUPAGES] = { @@ -365,10 +383,16 @@ CMenuScreenCustom aScreens[MENUPAGES] = { }, // MENUPAGE_CONTROLLER_SETTINGS = 4 +#ifdef GAMEPAD_MENU + { "FET_AGS", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil, +#else { "FET_CON", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil, +#endif MENUACTION_CTRLCONFIG, "FEC_CCF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, + INVERT_PAD_SELECTOR MENUACTION_CTRLVIBRATION, "FEC_VIB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, + SELECT_CONTROLLER_TYPE MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, @@ -399,7 +423,12 @@ CMenuScreenCustom aScreens[MENUPAGES] = { MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, VIDEOMODE_SELECTOR MULTISAMPLING_SELECTOR - MENUACTION_CHANGEMENU, "FET_ADV", { nil, SAVESLOT_NONE, MENUPAGE_ADVANCED_DISPLAY_SETTINGS }, + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + POSTFX_SELECTORS + // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, @@ -411,7 +440,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = { CUTSCENE_BORDERS_TOGGLE FREE_CAM_TOGGLE MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, - MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefDisplay) }, + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefDisplay) }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, #endif @@ -424,9 +453,9 @@ CMenuScreenCustom aScreens[MENUPAGES] = { MENUACTION_LANG_ITA, "FEL_ITA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS }, MENUACTION_LANG_SPA, "FEL_SPA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS }, #ifdef MORE_LANGUAGES - MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) }, - MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) }, - MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) }, + MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, nil, LangPolSelect) }, + MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, nil, LangRusSelect) }, + MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, nil, LangJapSelect) }, #endif MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, @@ -630,8 +659,13 @@ CMenuScreenCustom aScreens[MENUPAGES] = { // MENUPAGE_CONTROLLER_PC = 35 { "FET_CTL", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil, +#ifdef PC_PLAYER_CONTROLS MENUACTION_CTRLMETHOD, "FET_CME", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC }, +#endif MENUACTION_KEYBOARDCTRLS,"FET_RDK", { nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS }, +#ifdef GAMEPAD_MENU + MENUACTION_CHANGEMENU, "FET_AGS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS }, +#endif #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS MENUACTION_CHANGEMENU, "FEC_JOD", { nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK }, #endif @@ -787,7 +821,9 @@ CMenuScreenCustom aScreens[MENUPAGES] = { { "FET_MTI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil, MENUACTION_MOUSESENS, "FEC_MSH", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS }, MENUACTION_INVVERT, "FEC_IVV", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS }, +#ifndef GAMEPAD_MENU INVERT_PAD_SELECTOR +#endif MENUACTION_MOUSESTEER, "FET_MST", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, @@ -824,34 +860,15 @@ CMenuScreenCustom aScreens[MENUPAGES] = { MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, MULTISAMPLING_SELECTOR -#ifdef EXTENDED_COLOURFILTER - POSTFX_SELECTORS -#else - MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, -#endif -#ifdef EXTENDED_PIPELINES - PIPELINES_SELECTOR -#endif - ISLAND_LOADING_SELECTOR - DUALPASS_SELECTOR - MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, - MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, - }, -#else - // MENUPAGE_ADVANCED_DISPLAY_SETTINGS - { "FET_ADV", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, - new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil, - ISLAND_LOADING_SELECTOR DUALPASS_SELECTOR - CUTSCENE_BORDERS_TOGGLE - FREE_CAM_TOGGLE #ifdef EXTENDED_COLOURFILTER POSTFX_SELECTORS +#else + MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, #endif -#ifdef EXTENDED_PIPELINES - PIPELINES_SELECTOR -#endif + // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefGraphics) }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, #endif @@ -859,10 +876,10 @@ CMenuScreenCustom aScreens[MENUPAGES] = { #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS // MENUPAGE_DETECT_JOYSTICK { "FEC_JOD", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, - new CCustomScreenLayout({MENUSPRITE_MAINMENU, 40, 60, 20, FONT_BANK, FESCREEN_LEFT_ALIGN, false, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil, + new CCustomScreenLayout({MENUSPRITE_MAINMENU, 40, 60, 20, FONT_BANK, FESCREEN_LEFT_ALIGN, false, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), DetectJoystickGoBack, MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, - MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) }, + MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, nil, DetectJoystickDraw, nil) }, MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, }, #endif diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 9c6bdc98..9bcac613 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -1,11 +1,4 @@ -#pragma warning( push ) -#pragma warning( disable : 4005) -#if defined RW_D3D9 || defined RWLIBS -#define DIRECTINPUT_VERSION 0x0800 -#include <dinput.h> -#endif -#pragma warning( pop ) - +#define WITHDINPUT #include "common.h" #include "crossplatform.h" #include "platform.h" @@ -233,7 +226,7 @@ void ArmourCheat() void WantedLevelUpCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT5"), true); - FindPlayerPed()->SetWantedLevel(Min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6)); + FindPlayerPed()->SetWantedLevel(Min(FindPlayerPed()->m_pWanted->GetWantedLevel() + 2, 6)); } void WantedLevelDownCheat() @@ -872,6 +865,30 @@ void CPad::AddToCheatString(char c) // "S1CD13TR1X" - SQUARE L1 CIRCLE DOWN L1 R1 TRIANGLE RIGHT L1 CROSS else if ( !_CHEATCMP("X1RT31DC1S") ) NastyLimbsCheat(); + +#ifdef KANGAROO_CHEAT + // "X1DUC3RLS3" - R1 SQUARE LEFT RIGHT R1 CIRCLE UP DOWN L1 CROSS + else if (!_CHEATCMP("X1DUC3RLS3")) + KangarooCheat(); +#endif + +#ifndef MASTER + // "31UD13XUD" - DOWN UP CROSS R1 L1 DOWN UP L1 R1 + else if (!_CHEATCMP("31UD13XUD")) + CPed::SwitchDebugDisplay(); +#endif + +#ifdef ALLCARSHELI_CHEAT + // "UCCL3R1TT" - TRIANGLE TRIANGLE L1 RIGHT R1 LEFT CIRCLE CIRCLE UP + else if (!_CHEATCMP("UCCL3R1TT")) + AllCarsHeliCheat(); +#endif + +#ifdef ALT_DODO_CHEAT + // "DUU31XX13" - R1 L1 CROSS CROSS L1 R1 UP UP DOWN + else if (!_CHEATCMP("DUU31XX13")) + AltDodoCheat(); +#endif #undef _CHEATCMP } #endif @@ -937,7 +954,7 @@ void CPad::AddToPCCheatString(char c) if ( !_CHEATCMP("GNIROOOOOB") ) SlowTimeCheat(); -#ifndef GTA3_1_1_PATCH +#if GTA_VERSION < GTA3_PC_11 // "TURTOISE" if ( !_CHEATCMP("ESIOTRUT") ) ArmourCheat(); @@ -1109,14 +1126,11 @@ void CPad::UpdatePads(void) bUpdate = false; if ( bUpdate ) - { GetPad(0)->Update(0); -#ifndef SQUEEZE_PERFORMANCE - GetPad(1)->Update(0); -#endif - } -#if defined(MASTER) && !defined(XINPUT) +#ifndef MASTER + GetPad(1)->Update(1); +#else GetPad(1)->NewState.Clear(); GetPad(1)->OldState.Clear(); #endif @@ -2322,6 +2336,121 @@ bool CPad::ShiftTargetRightJustDown(void) return !!(NewState.RightShoulder2 && !OldState.RightShoulder2); } +#ifdef FIX_BUGS +// FIX: fixes from VC for the bug of double switching the controller setup +bool CPad::GetAnaloguePadUp(void) +{ + static int16 oldfStickY = 0; + + int16 leftStickY = CPad::GetPad(0)->GetLeftStickY(); + + if ( leftStickY < -15 && oldfStickY >= -5 ) + { + oldfStickY = leftStickY; + return true; + } + else + { + oldfStickY = leftStickY; + return false; + } +} + +bool CPad::GetAnaloguePadDown(void) +{ + static int16 oldfStickY = 0; + + int16 leftStickY = CPad::GetPad(0)->GetLeftStickY(); + + if ( leftStickY > 15 && oldfStickY <= 5 ) + { + oldfStickY = leftStickY; + return true; + } + else + { + oldfStickY = leftStickY; + return false; + } +} + +bool CPad::GetAnaloguePadLeft(void) +{ + static int16 oldfStickX = 0; + + int16 leftStickX = CPad::GetPad(0)->GetLeftStickX(); + + if ( leftStickX < -15 && oldfStickX >= -5 ) + { + oldfStickX = leftStickX; + return true; + } + else + { + oldfStickX = leftStickX; + return false; + } +} + +bool CPad::GetAnaloguePadRight(void) +{ + static int16 oldfStickX = 0; + + int16 leftStickX = CPad::GetPad(0)->GetLeftStickX(); + + if ( leftStickX > 15 && oldfStickX <= 5 ) + { + oldfStickX = leftStickX; + return true; + } + else + { + oldfStickX = leftStickX; + return false; + } +} + +bool CPad::GetAnaloguePadLeftJustUp(void) +{ + static int16 oldfStickX = 0; + + int16 X = GetPad(0)->GetPedWalkLeftRight(); + + if ( X == 0 && oldfStickX < 0 ) + { + oldfStickX = 0; + + return true; + } + else + { + oldfStickX = X; + + return false; + } +} + +bool CPad::GetAnaloguePadRightJustUp(void) +{ + static int16 oldfStickX = 0; + + int16 X = GetPad(0)->GetPedWalkLeftRight(); + + if ( X == 0 && oldfStickX > 0 ) + { + oldfStickX = 0; + + return true; + } + else + { + oldfStickX = X; + + return false; + } +} + +#else bool CPad::GetAnaloguePadUp(void) { static int16 oldfStickY = 0; @@ -2433,6 +2562,7 @@ bool CPad::GetAnaloguePadRightJustUp(void) return false; } } +#endif bool CPad::ForceCameraBehindPlayer(void) { @@ -2607,10 +2737,18 @@ void CPad::PrintErrorMessage(void) { if ( bDisplayNoControllerMessage && !CGame::playingIntro && !FrontEndMenuManager.m_bMenuActive ) { +#ifdef FIX_BUGS + CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f)); +#else CFont::SetScale(0.85f, 1.0f); +#endif CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20)); +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20)); +#else + CFont::SetCentreSize(SCREEN_WIDTH - 20); +#endif CFont::SetCentreOn(); CFont::SetPropOn(); CFont::SetColor(CRGBA(255, 255, 200, 200)); @@ -2624,10 +2762,18 @@ void CPad::PrintErrorMessage(void) } else if ( bObsoleteControllerMessage ) { +#ifdef FIX_BUGS + CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f)); +#else CFont::SetScale(0.85f, 1.0f); +#endif CFont::SetJustifyOff(); CFont::SetBackgroundOff(); - CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20)); +#ifdef FIX_BUGS + CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20)); +#else + CFont::SetCentreSize(SCREEN_WIDTH - 20); +#endif CFont::SetCentreOn(); CFont::SetPropOn(); CFont::SetColor(CRGBA(255, 255, 200, 200)); diff --git a/src/core/Placeable.cpp b/src/core/Placeable.cpp index 69b3d3ea..162148f7 100644 --- a/src/core/Placeable.cpp +++ b/src/core/Placeable.cpp @@ -7,7 +7,9 @@ CPlaceable::CPlaceable(void) m_matrix.SetScale(1.0f); } -CPlaceable::~CPlaceable(void) = default; +CPlaceable::~CPlaceable(void) +{ +} void CPlaceable::SetHeading(float angle) diff --git a/src/core/Placeable.h b/src/core/Placeable.h index 970c0d48..1d51f306 100644 --- a/src/core/Placeable.h +++ b/src/core/Placeable.h @@ -4,7 +4,7 @@ class CPlaceable { public: // disable allocation - static void *operator new(size_t) = delete; + static void *operator new(size_t); CMatrix m_matrix; diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index 09b3a499..bd6feeed 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -3,6 +3,7 @@ #include "Automobile.h" #include "Bridge.h" #include "Camera.h" +#include "CarCtrl.h" #include "Cranes.h" #include "Darkel.h" #include "Explosion.h" @@ -31,83 +32,6 @@ #include "ZoneCull.h" #include "main.h" -void -CPlayerInfo::SetPlayerSkin(char *skin) -{ - strncpy(m_aSkinName, skin, 32); - LoadPlayerSkin(); -} - -const CVector & -CPlayerInfo::GetPos() -{ -#ifdef FIX_BUGS - if (!m_pPed) - return TheCamera.GetPosition(); -#endif - if (m_pPed->InVehicle()) - return m_pPed->m_pMyVehicle->GetPosition(); - return m_pPed->GetPosition(); -} - -void -CPlayerInfo::LoadPlayerSkin() -{ - DeletePlayerSkin(); - - m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); - if (!m_pSkinTexture) - m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME); -} - -void -CPlayerInfo::DeletePlayerSkin() -{ - if (m_pSkinTexture) { - RwTextureDestroy(m_pSkinTexture); - m_pSkinTexture = nil; - } -} - -void -CPlayerInfo::KillPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; - - m_WBState = WBSTATE_WASTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); - CStats::TimesDied++; -} - -void -CPlayerInfo::ArrestPlayer() -{ - if (m_WBState != WBSTATE_PLAYING) return; - - m_WBState = WBSTATE_BUSTED; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); - CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); - CStats::TimesArrested++; -} - -bool -CPlayerInfo::IsPlayerInRemoteMode() -{ - return m_pRemoteVehicle || m_bInRemoteMode; -} - -void -CPlayerInfo::PlayerFailedCriticalMission() -{ - if (m_WBState != WBSTATE_PLAYING) - return; - m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; - m_nWBTime = CTimer::GetTimeInMilliseconds(); - CDarkel::ResetOnPlayerDeath(); -} void CPlayerInfo::Clear(void) @@ -147,197 +71,6 @@ CPlayerInfo::Clear(void) } void -CPlayerInfo::BlowUpRCBuggy(void) -{ - if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) - return; - - CRemote::TakeRemoteControlledCarFromPlayer(); - m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); -} - -void -CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) -{ - if (!car || car == m_pPed->m_pMyVehicle) { - if (m_pPed->EnteringCar()) - m_pPed->QuitEnteringCar(); - } - if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) - m_pPed->ClearObjective(); -} - -void -CPlayerInfo::MakePlayerSafe(bool toggle) -{ - if (toggle) { - CTheScripts::ResetCountdownToMakePlayerUnsafe(); - m_pPed->m_pWanted->m_bIgnoredByEveryone = true; - CWorld::StopAllLawEnforcersInTheirTracks(); - CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); - CPad::StopPadsShaking(); - m_pPed->bBulletProof = true; - m_pPed->bFireProof = true; - m_pPed->bCollisionProof = true; - m_pPed->bMeleeProof = true; - m_pPed->bOnlyDamagedByPlayer = true; - m_pPed->bExplosionProof = true; - m_pPed->m_bCanBeDamaged = false; - ((CPlayerPed*)m_pPed)->ClearAdrenaline(); - CancelPlayerEnteringCars(nil); - gFireManager.ExtinguishPoint(GetPos(), 4000.0f); - CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); - CProjectileInfo::RemoveAllProjectiles(); - CWorld::SetAllCarsCanBeDamaged(false); - CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); - CReplay::DisableReplays(); - - } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) { - m_pPed->m_pWanted->m_bIgnoredByEveryone = false; - CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); - m_pPed->bBulletProof = false; - m_pPed->bFireProof = false; - m_pPed->bCollisionProof = false; - m_pPed->bMeleeProof = false; - m_pPed->bOnlyDamagedByPlayer = false; - m_pPed->bExplosionProof = false; - m_pPed->m_bCanBeDamaged = true; - CWorld::SetAllCarsCanBeDamaged(true); - CReplay::EnableReplays(); - } -} - -bool -CPlayerInfo::IsRestartingAfterDeath() -{ - return m_WBState == WBSTATE_WASTED; -} - -bool -CPlayerInfo::IsRestartingAfterArrest() -{ - return m_WBState == WBSTATE_BUSTED; -} - -// lastCloseness is passed to other calls of this function -void -CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) -{ - // This dist used for determining the angle to face - CVector2D dist(carToTest->GetPosition() - player->GetPosition()); - float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); - while (neededTurn >= PI) { - neededTurn -= 2 * PI; - } - - while (neededTurn < -PI) { - neededTurn += 2 * PI; - } - - // This dist used for evaluating cars' distances, weird... - // Accounts inverted needed turn (or needed turn in long way) and car dist. - float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); - if (closeness > *lastCloseness) { - *lastCloseness = closeness; - *closestCarOutput = (CVehicle*)carToTest; - } -} - -// There is something unfinished in here... Sadly all IDBs we have have it unfinished. -void -CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar) -{ - if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000) - ++m_nExplosionsSinceLastReward; - else - m_nExplosionsSinceLastReward = 1; - - m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds(); - int award = wreckedCar->pHandling->nMonetaryValue * 0.002f; - sprintf(gString, "$%d", award); -#ifdef MONEY_MESSAGES - // This line is a leftover from PS2, I don't know what it was meant to be. - // CVector sth(TheCamera.GetPosition() * 4.0f); - - CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f); -#endif - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; - - for (int i = m_nExplosionsSinceLastReward; i > 1; --i) { - CGeneral::GetRandomNumber(); - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; - } -} - -void -CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) -{ - // Interesting - *size = sizeof(CPlayerInfo); - -#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); -#undef CopyToBuf -} - -void -CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) -{ -#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); - CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName) -#undef CopyFromBuf -} - -void -CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) -{ - for (CPtrNode* node = carList.first; node; node = node->next) { - CVehicle *car = (CVehicle*)node->item; - if(car->m_scanCode != CWorld::GetCurrentScanCode()) { - if (!car->bUsesCollision || !car->IsVehicle()) - continue; - - car->m_scanCode = CWorld::GetCurrentScanCode(); - if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING - && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { - CVector carCentre = car->GetBoundCentre(); - - if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) { - float dist = (ped->GetPosition() - carCentre).Magnitude2D(); - if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { - EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); - } - } - } - } - } -} - -void CPlayerInfo::Process(void) { #ifdef FIX_BUGS @@ -419,11 +152,11 @@ CPlayerInfo::Process(void) if (found) sth.z = 1.0f + groundZ; - m_pPed->m_nPedState = PED_IDLE; + m_pPed->SetPedState(PED_IDLE); m_pPed->SetMoveState(PEDMOVE_STILL); CPed::PedSetOutCarCB(0, m_pPed); - CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f); - CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f); + CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_STD_IDLE, 100.0f); + CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_STD_FALL_LAND, 100.0f); m_pPed->SetPosition(sth); m_pPed->SetMoveState(PEDMOVE_STILL); m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed; @@ -489,8 +222,8 @@ CPlayerInfo::Process(void) m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow); } else if (carBelow->IsBoat()) { if (!carBelow->pDriver) { - m_pPed->m_vehEnterType = 0; - m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType); + m_pPed->m_vehDoor = 0; + m_pPed->SetEnterCar(carBelow, m_pPed->m_vehDoor); } } else { m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow); @@ -503,13 +236,13 @@ CPlayerInfo::Process(void) uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar; if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) { TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 0); + TheCamera.Fade(1.0f, FADE_OUT); } if (timeWithoutRemoteCar > 2000) { if (m_WBState == WBSTATE_PLAYING) { TheCamera.RestoreWithJumpCut(); TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(1.0f, 1); + TheCamera.Fade(1.0f, FADE_IN); TheCamera.Process(); CTimer::Stop(); CCullZones::ForceCullZoneCoors(TheCamera.GetPosition()); @@ -560,3 +293,370 @@ CPlayerInfo::Process(void) CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled; } } + +bool +CPlayerInfo::IsPlayerInRemoteMode() +{ + return m_pRemoteVehicle || m_bInRemoteMode; +} + +void +CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) +{ + // Interesting + *size = sizeof(CPlayerInfo); + +#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); +#undef CopyToBuf +} + +void +CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) +{ +#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName) +#undef CopyFromBuf +} + +void +CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput) +{ + for (CPtrNode* node = carList.first; node; node = node->next) { + CVehicle *car = (CVehicle*)node->item; + if(car->m_scanCode != CWorld::GetCurrentScanCode()) { + if (!car->bUsesCollision || !car->IsVehicle()) + continue; + + car->m_scanCode = CWorld::GetCurrentScanCode(); + if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING + && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) { + CVector carCentre = car->GetBoundCentre(); + + if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) { + float dist = (ped->GetPosition() - carCentre).Magnitude2D(); + if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) { + EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput); + } + } + } + } + } +} + +// lastCloseness is passed to other calls of this function +void +CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput) +{ + // This dist used for determining the angle to face + CVector2D dist(carToTest->GetPosition() - player->GetPosition()); + float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); + while (neededTurn >= PI) { + neededTurn -= 2 * PI; + } + + while (neededTurn < -PI) { + neededTurn += 2 * PI; + } + + // This dist used for evaluating cars' distances, weird... + // Accounts inverted needed turn (or needed turn in long way) and car dist. + float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); + if (closeness > *lastCloseness) { + *lastCloseness = closeness; + *closestCarOutput = (CVehicle*)carToTest; + } +} + +const CVector & +CPlayerInfo::GetPos() +{ +#ifdef FIX_BUGS + if (!m_pPed) + return TheCamera.GetPosition(); +#endif + if (m_pPed->InVehicle()) + return m_pPed->m_pMyVehicle->GetPosition(); + return m_pPed->GetPosition(); +} + +CVector +FindPlayerCoors(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) + return TheCamera.GetPosition(); +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->GetPosition(); + else + return ped->GetPosition(); +} + +const CVector & +FindPlayerSpeed(void) +{ +#ifdef FIX_BUGS + static CVector vecTmpVector(0.0f, 0.0f, 0.0f); + if (CReplay::IsPlayingBack()) + return vecTmpVector; +#endif + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle->m_vecMoveSpeed; + else + return ped->m_vecMoveSpeed; +} + +CVehicle * +FindPlayerVehicle(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped && ped->InVehicle()) return ped->m_pMyVehicle; + return nil; +} + +CEntity * +FindPlayerEntity(void) +{ + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) + return ped->m_pMyVehicle; + else + return ped; +} + +CVehicle * +FindPlayerTrain(void) +{ + if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) + return FindPlayerVehicle(); + else + return nil; +} + +CPlayerPed * +FindPlayerPed(void) +{ + return CWorld::Players[CWorld::PlayerInFocus].m_pPed; +} + +const CVector & +FindPlayerCentreOfWorld(int32 player) +{ +#ifdef FIX_BUGS + if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return CWorld::Players[player].m_pPed->GetPosition(); +} + +const CVector & +FindPlayerCentreOfWorld_NoSniperShift(void) +{ +#ifdef FIX_BUGS + if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); +#endif + if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); + return FindPlayerPed()->GetPosition(); +} + +float +FindPlayerHeading(void) +{ + if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) + return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); + if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); + return FindPlayerPed()->GetForward().Heading(); +} + +bool +CPlayerInfo::IsRestartingAfterDeath() +{ + return m_WBState == WBSTATE_WASTED; +} + +bool +CPlayerInfo::IsRestartingAfterArrest() +{ + return m_WBState == WBSTATE_BUSTED; +} + +void +CPlayerInfo::KillPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_WASTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2); + CStats::TimesDied++; +} + +void +CPlayerInfo::ArrestPlayer() +{ + if (m_WBState != WBSTATE_PLAYING) return; + + m_WBState = WBSTATE_BUSTED; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); + CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2); + CStats::TimesArrested++; +} + +void +CPlayerInfo::PlayerFailedCriticalMission() +{ + if (m_WBState != WBSTATE_PLAYING) + return; + m_WBState = WBSTATE_FAILED_CRITICAL_MISSION; + m_nWBTime = CTimer::GetTimeInMilliseconds(); + CDarkel::ResetOnPlayerDeath(); +} + +void +CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) +{ + if (!car || car == m_pPed->m_pMyVehicle) { + if (m_pPed->EnteringCar()) + m_pPed->QuitEnteringCar(); + } + if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) + m_pPed->ClearObjective(); +} + +void +CPlayerInfo::MakePlayerSafe(bool toggle) +{ + if (toggle) { + CTheScripts::ResetCountdownToMakePlayerUnsafe(); + m_pPed->m_pWanted->m_bIgnoredByEveryone = true; + CWorld::StopAllLawEnforcersInTheirTracks(); + CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO); + CPad::StopPadsShaking(); + m_pPed->bBulletProof = true; + m_pPed->bFireProof = true; + m_pPed->bCollisionProof = true; + m_pPed->bMeleeProof = true; + m_pPed->bOnlyDamagedByPlayer = true; + m_pPed->bExplosionProof = true; + m_pPed->m_bCanBeDamaged = false; + ((CPlayerPed*)m_pPed)->ClearAdrenaline(); + CancelPlayerEnteringCars(nil); + gFireManager.ExtinguishPoint(GetPos(), 4000.0f); + CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); + CProjectileInfo::RemoveAllProjectiles(); + CWorld::SetAllCarsCanBeDamaged(false); + CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); + CReplay::DisableReplays(); + + } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) { + m_pPed->m_pWanted->m_bIgnoredByEveryone = false; + CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO); + m_pPed->bBulletProof = false; + m_pPed->bFireProof = false; + m_pPed->bCollisionProof = false; + m_pPed->bMeleeProof = false; + m_pPed->bOnlyDamagedByPlayer = false; + m_pPed->bExplosionProof = false; + m_pPed->m_bCanBeDamaged = true; + CWorld::SetAllCarsCanBeDamaged(true); + CReplay::EnableReplays(); + } +} + +void +CPlayerInfo::BlowUpRCBuggy(void) +{ + if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) + return; + + CRemote::TakeRemoteControlledCarFromPlayer(); + m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); +} + +// There is something unfinished in here... Sadly all IDBs we have have it unfinished. +void +CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar) +{ + if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000) + ++m_nExplosionsSinceLastReward; + else + m_nExplosionsSinceLastReward = 1; + + m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds(); + int award = wreckedCar->pHandling->nMonetaryValue * 0.002f; + sprintf(gString, "$%d", award); +#ifdef MONEY_MESSAGES + // This line is a leftover from PS2, I don't know what it was meant to be. + // CVector sth(TheCamera.GetPosition() * 4.0f); + + CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f); +#endif + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; + + for (int i = m_nExplosionsSinceLastReward; i > 1; --i) { + CGeneral::GetRandomNumber(); + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; + } +} + +#ifdef GTA_PC +void +CPlayerInfo::SetPlayerSkin(const char *skin) +{ + strncpy(m_aSkinName, skin, 32); + LoadPlayerSkin(); +} + +void +CPlayerInfo::LoadPlayerSkin() +{ + DeletePlayerSkin(); + + m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName); + if (!m_pSkinTexture) + m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME); +} + +void +CPlayerInfo::DeletePlayerSkin() +{ + if (m_pSkinTexture) { + RwTextureDestroy(m_pSkinTexture); + m_pSkinTexture = nil; + } +} +#endif
\ No newline at end of file diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 94410753..956756e4 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -1,6 +1,6 @@ #pragma once -#include "Collision.h" +#include "ColModel.h" enum eWastedBustedState { @@ -54,14 +54,13 @@ public: bool m_bFastReload; bool m_bGetOutOfJailFree; bool m_bGetOutOfHospitalFree; +#ifdef GTA_PC char m_aSkinName[32]; RwTexture *m_pSkinTexture; +#endif void MakePlayerSafe(bool); - void LoadPlayerSkin(); - void DeletePlayerSkin(); void AwardMoneyForExplosion(CVehicle *vehicle); - void SetPlayerSkin(char* skin); const CVector &GetPos(); void Process(void); void KillPlayer(void); @@ -78,7 +77,21 @@ public: void SavePlayerInfo(uint8 *buf, uint32* size); void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**); - ~CPlayerInfo() { }; +#ifdef GTA_PC + void LoadPlayerSkin(); + void SetPlayerSkin(const char *skin); + void DeletePlayerSkin(); +#endif }; +CPlayerPed *FindPlayerPed(void); +CVehicle *FindPlayerVehicle(void); +CVehicle *FindPlayerTrain(void); +CEntity *FindPlayerEntity(void); +CVector FindPlayerCoors(void); +const CVector &FindPlayerSpeed(void); +const CVector &FindPlayerCentreOfWorld(int32 player); +const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); +float FindPlayerHeading(void); + VALIDATE_SIZE(CPlayerInfo, 0x13C); diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp index 79841c14..39cfb1d4 100644 --- a/src/core/Pools.cpp +++ b/src/core/Pools.cpp @@ -102,7 +102,7 @@ CPools::CheckPoolsEmpty() void CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot) { - if (ms_pObjectPool->IsFreeSlot(slot)) return; + if (ms_pObjectPool->GetIsFree(slot)) return; CObject *object = ms_pObjectPool->GetSlot(slot); if (object->ObjectCreatedBy == TEMP_OBJECT) { @@ -485,7 +485,7 @@ INITSAVEBUF #endif CopyToBuf(buf, CWanted::MaximumWantedLevel); CopyToBuf(buf, CWanted::nMaximumWantedLevel); - memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName(), MAX_MODEL_NAME); + memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetModelName(), MAX_MODEL_NAME); SkipSaveBuf(buf, MAX_MODEL_NAME); } } diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index 816da6b9..4fd7f1a5 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -1,3 +1,6 @@ +#if (!defined(GTA_PS2_STUFF) && defined(RWLIBS)) || defined(__MWERKS__) +#define WITHD3D +#endif #include "config.h" #include "common.h" @@ -295,10 +298,10 @@ void CRadar::ClearBlipForEntity(eBlipType type, int32 id) int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect) { CVector2D corners[4] = { - { 1.0f, -1.0f }, // top right - { 1.0f, 1.0f }, // bottom right - { -1.0f, 1.0f }, // bottom left - { -1.0f, -1.0f }, // top left + CVector2D( 1.0f, -1.0f ), // top right + CVector2D( 1.0f, 1.0f ), // bottom right + CVector2D( -1.0f, 1.0f ), // bottom left + CVector2D( -1.0f, -1.0f ), // top left }; CVector2D tmp; int i, j, n; @@ -778,7 +781,7 @@ void CRadar::DrawRadarMask() CVector2D(-1.0, -1.0f) }; - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)nil); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); @@ -905,7 +908,7 @@ int32 CRadar::GetNewUniqueBlipIndex(int32 i) uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright) { - int32 c; + uint32 c; switch (color) { case RADAR_TRACE_RED: if (bright) diff --git a/src/core/Radar.h b/src/core/Radar.h index 793d62b0..5b38d350 100644 --- a/src/core/Radar.h +++ b/src/core/Radar.h @@ -1,5 +1,6 @@ #pragma once #include "Sprite2d.h" +#include "Draw.h" enum eBlipType { @@ -86,9 +87,33 @@ VALIDATE_SIZE(sRadarTrace, 0x30); // Values for screen space #define RADAR_LEFT (40.0f) +#ifdef PS2_HUD +#define RADAR_BOTTOM (44.0f) +#else #define RADAR_BOTTOM (47.0f) +#endif + +#ifdef FIX_RADAR +/* + The values are from an early screenshot taken before R* broke radar + #define RADAR_WIDTH (82.0f) + #define RADAR_HEIGHT (82.0f) +*/ +#define RADAR_WIDTH ((CDraw::ms_bFixRadar) ? (82.0f) : (94.0f)) +#define RADAR_HEIGHT ((CDraw::ms_bFixRadar) ? (82.0f) : (76.0f)) +#else +/* + broken since forever, someone tried to fix size for 640x512(PAL) + http://aap.rockstarvision.com/pics/gta3/ps2screens/gta3_interface.jpg + but failed: + http://aap.rockstarvision.com/pics/gta3/artwork/gta3_artwork_16.jpg + most likely the guy used something like this: + int y = 82 * (640.0/512.0)/(640.0/480.0); + int x = y * (640.0/512.0); +*/ #define RADAR_WIDTH (94.0f) #define RADAR_HEIGHT (76.0f) +#endif class CRadar { diff --git a/src/core/References.cpp b/src/core/References.cpp index 52abbc3e..6b0c868c 100644 --- a/src/core/References.cpp +++ b/src/core/References.cpp @@ -22,6 +22,66 @@ CReferences::Init(void) } void +CEntity::RegisterReference(CEntity **pent) +{ + if(IsBuilding()) + return; + CReference *ref; + // check if already registered + for(ref = m_pFirstReference; ref; ref = ref->next) + if(ref->pentity == pent) + return; + // have to allocate new reference + ref = CReferences::pEmptyList; + if(ref){ + CReferences::pEmptyList = ref->next; + + ref->pentity = pent; + ref->next = m_pFirstReference; + m_pFirstReference = ref; + return; + } + return; +} + +// Clear all references to this entity +void +CEntity::ResolveReferences(void) +{ + CReference *ref; + // clear pointers to this entity + for(ref = m_pFirstReference; ref; ref = ref->next) + if(*ref->pentity == this) + *ref->pentity = nil; + // free list + if(m_pFirstReference){ + for(ref = m_pFirstReference; ref->next; ref = ref->next) + ; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = m_pFirstReference; + m_pFirstReference = nil; + } +} + +// Free all references that no longer point to this entity +void +CEntity::PruneReferences(void) +{ + CReference *ref, *next, **lastnextp; + lastnextp = &m_pFirstReference; + for(ref = m_pFirstReference; ref; ref = next){ + next = ref->next; + if(*ref->pentity == this) + lastnextp = &ref->next; + else{ + *lastnextp = ref->next; + ref->next = CReferences::pEmptyList; + CReferences::pEmptyList = ref; + } + } +} + +void CReferences::RemoveReferencesToPlayer(void) { if(FindPlayerVehicle()) diff --git a/src/core/Stats.h b/src/core/Stats.h index 5dfcf803..6abcfb61 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -17,7 +17,7 @@ public: static int32 NumberKillFrenziesPassed; static int32 PeopleKilledByOthers; static int32 HelisDestroyed; - static int32 PedsKilledOfThisType[ePedType::NUM_PEDTYPES]; + static int32 PedsKilledOfThisType[NUM_PEDTYPES]; static int32 TimesDied; static int32 TimesArrested; static int32 KillsSinceLastCheckpoint; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index a28fe39d..9ac22096 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -202,11 +202,15 @@ CStreaming::Init2(void) // allocate streaming buffers if(ms_streamingBufferSize & 1) ms_streamingBufferSize++; +#ifndef ONE_THREAD_PER_CHANNEL ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); ms_streamingBufferSize /= 2; ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; -#ifdef ONE_THREAD_PER_CHANNEL - ms_pStreamingBuffer[2] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); +#else + ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE); + ms_streamingBufferSize /= 2; + ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; + ms_pStreamingBuffer[2] = ms_pStreamingBuffer[1] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; ms_pStreamingBuffer[3] = ms_pStreamingBuffer[2] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE; #endif debug("Streaming buffer size is %d sectors", ms_streamingBufferSize); @@ -458,6 +462,35 @@ CStreaming::LoadCdDirectory(const char *dirname, int n) CFileMgr::CloseFile(fd); } +#ifdef USE_CUSTOM_ALLOCATOR +RpAtomic* +RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data) +{ +#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31 + // not quite sure what's going on here: + // gta3's RW 3.1 allocates separate memory for geometry data of RpGeometry. + // Is that a R* change? rpDefaultGeometryInstance also depends on it + RpGeometry *geo = RpAtomicGetGeometry(atomic); + if(geo->triangles) + REGISTER_MEMPTR(&geo->triangles); + if(geo->matList.materials) + REGISTER_MEMPTR(&geo->matList.materials); + if(geo->preLitLum) + REGISTER_MEMPTR(&geo->preLitLum); + if(geo->texCoords[0]) + REGISTER_MEMPTR(&geo->texCoords[0]); + if(geo->texCoords[1]) + REGISTER_MEMPTR(&geo->texCoords[1]); +#else + // normally RpGeometry is allocated in one block (excluding morph targets) + // so we don't really have allocated pointers in the struct. + // NB: in librw we actually do it in two allocations (geometry itself and data) + // so we could conceivably come up with something here +#endif + return atomic; +} +#endif + bool CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) { @@ -480,10 +513,18 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) mi = CModelInfo::GetModelInfo(streamId); // Txd has to be loaded +#ifdef FIX_BUGS + if(!HasTxdLoaded(mi->GetTxdSlot())){ +#else + // texDict will exist even if only first part has 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())); +#endif + debug("failed to load %s because TXD %s is not in memory\n", mi->GetModelName(), CTxdStore::GetTxdName(mi->GetTxdSlot())); RemoveModel(streamId); +#ifndef FIX_BUGS + // if we're just waiting for it to load, don't remove this RemoveTxd(mi->GetTxdSlot()); +#endif ReRequestModel(streamId); RwStreamClose(stream, &mem); return false; @@ -494,9 +535,11 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) PUSH_MEMID(MEMID_STREAM_MODELS); CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); -// TODO(USE_CUSTOM_ALLOCATOR): register mem pointers if(mi->IsSimple()){ success = CFileLoader::LoadAtomicFile(stream, streamId); +#ifdef USE_CUSTOM_ALLOCATOR + RegisterAtomicMemPtrsCB(((CSimpleModelInfo*)mi)->m_atomics[0], nil); +#endif } else if (mi->GetModelType() == MITYPE_VEHICLE) { // load vehicles in two parts CModelInfo::GetModelInfo(streamId)->AddRef(); @@ -505,6 +548,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED; }else{ success = CFileLoader::LoadClumpFile(stream, streamId); +#ifdef USE_CUSTOM_ALLOCATOR + if(success) + RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil); +#endif } POP_MEMID(); UpdateMemoryUsed(); @@ -514,7 +561,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); if(!success){ - debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName()); + debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetModelName()); RemoveModel(streamId); ReRequestModel(streamId); RwStreamClose(stream, &mem); @@ -555,7 +602,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) if(!success){ ReRequestModel(streamId); if(streamId < STREAM_OFFSET_TXD) - debug("Failed to load %s.dff\n", mi->GetName()); + debug("Failed to load %s.dff\n", mi->GetModelName()); else debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD)); return false; @@ -596,7 +643,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId) timeDiff = endTime - startTime; if(timeDiff > 5){ if(streamId < STREAM_OFFSET_TXD) - debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff); + debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetModelName(), timeDiff); else debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); } @@ -628,13 +675,16 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) if(streamId < STREAM_OFFSET_TXD){ // Model -// TODO(USE_CUSTOM_ALLOCATOR): register pointers mi = CModelInfo::GetModelInfo(streamId); PUSH_MEMID(MEMID_STREAM_MODELS); CTxdStore::SetCurrentTxd(mi->GetTxdSlot()); success = CFileLoader::FinishLoadClumpFile(stream, streamId); - if(success) + if(success){ +#ifdef USE_CUSTOM_ALLOCATOR + RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil); +#endif success = AddToLoadedVehiclesList(streamId); + } POP_MEMID(); mi->RemoveRef(); CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot()); @@ -667,7 +717,7 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId) timeDiff = endTime - startTime; if(timeDiff > 5){ if(streamId < STREAM_OFFSET_TXD) - debug("finish model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff); + debug("finish model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetModelName(), timeDiff); else debug("finish txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff); } @@ -821,14 +871,14 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag uint32 pos, size; mi = CModelInfo::GetModelInfo(modelId); - if(!CGeneral::faststrcmp(mi->GetName(), modelName)){ + if(!CGeneral::faststrcmp(mi->GetModelName(), modelName)){ // Already have the correct name, just request it RequestModel(modelId, flags); return; } - strcpy(oldName, mi->GetName()); - mi->SetName(modelName); + strcpy(oldName, mi->GetModelName()); + mi->SetModelName(modelName); // What exactly is going on here? if(CModelInfo::GetModelInfo(oldName, nil)){ @@ -1886,9 +1936,10 @@ CStreaming::LoadRequestedModels(void) } -// Let's load models first, then process it. Unfortunately processing models are still single-threaded. +// Let's load models in 4 threads; when one of them becomes idle, process the file, and fill thread with another file. Unfortunately processing models are still single-threaded. // Currently only supported on POSIX streamer. -#ifdef ONE_THREAD_PER_CHANNEL +// WIP - some files are loaded swapped (CdStreamPosix problem?) +#if 0 //def ONE_THREAD_PER_CHANNEL void CStreaming::LoadAllRequestedModels(bool priority) { @@ -1906,14 +1957,18 @@ CStreaming::LoadAllRequestedModels(bool priority) int streamIds[ARRAY_SIZE(ms_pStreamingBuffer)]; int streamSizes[ARRAY_SIZE(ms_pStreamingBuffer)]; int streamPoses[ARRAY_SIZE(ms_pStreamingBuffer)]; - bool first = true; + int readOrder[4] = {-1}; // Channel IDs ordered by read time + int readI = 0; int processI = 0; + bool first = true; + + // All those "first" checks are because of variables aren't initialized in first pass. while (true) { - // Enumerate files and start reading for (int i=0; i<ARRAY_SIZE(ms_pStreamingBuffer); i++) { + + // Channel has file to load if (!first && streamIds[i] != -1) { - processI = i; continue; } @@ -1926,12 +1981,16 @@ CStreaming::LoadAllRequestedModels(bool priority) if (ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)) { streamIds[i] = -1; + + // Big file, needs 2 buffer if (size > (uint32)ms_streamingBufferSize) { if (i + 1 == ARRAY_SIZE(ms_pStreamingBuffer)) - continue; + break; else if (!first && streamIds[i+1] != -1) continue; + } else { + // Buffer of current channel is part of a "big file", pass if (i != 0 && streamIds[i-1] != -1 && streamSizes[i-1] > (uint32)ms_streamingBufferSize) continue; } @@ -1941,8 +2000,18 @@ CStreaming::LoadAllRequestedModels(bool priority) streamIds[i] = streamId; streamSizes[i] = size; streamPoses[i] = posn; + + if (!first) + assert(readOrder[readI] == -1); + + //printf("read: order %d, ch %d, id %d, size %d\n", readI, i, streamId, size); + CdStreamRead(i, ms_pStreamingBuffer[i], imgOffset+posn, size); - processI = i; + readOrder[readI] = i; + if (first && readI+1 != ARRAY_SIZE(readOrder)) + readOrder[readI+1] = -1; + + readI = (readI + 1) % ARRAY_SIZE(readOrder); } else { ms_aInfoForModel[streamId].RemoveFromList(); DecrementRef(streamId); @@ -1950,33 +2019,40 @@ CStreaming::LoadAllRequestedModels(bool priority) ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED; streamIds[i] = -1; } - } else + } else { streamIds[i] = -1; + break; + } } first = false; + int nextChannel = readOrder[processI]; - // Now process - if (streamIds[processI] == -1) + // Now start processing + if (nextChannel == -1 || streamIds[nextChannel] == -1) break; + //printf("process: order %d, ch %d, id %d\n", processI, nextChannel, streamIds[nextChannel]); + // Try again on error - while (CdStreamSync(processI) != STREAM_NONE) { - CdStreamRead(processI, ms_pStreamingBuffer[processI], imgOffset+streamPoses[processI], streamSizes[processI]); - } - ms_aInfoForModel[streamIds[processI]].m_loadState = STREAMSTATE_READING; - - MakeSpaceFor(streamSizes[processI] * CDSTREAM_SECTOR_SIZE); - ConvertBufferToObject(ms_pStreamingBuffer[processI], streamIds[processI]); - if(ms_aInfoForModel[streamIds[processI]].m_loadState == STREAMSTATE_STARTED) - FinishLoadingLargeFile(ms_pStreamingBuffer[processI], streamIds[processI]); - - if(streamIds[processI] < STREAM_OFFSET_TXD){ - CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[processI]); + while (CdStreamSync(nextChannel) != STREAM_NONE) { + CdStreamRead(nextChannel, ms_pStreamingBuffer[nextChannel], imgOffset+streamPoses[nextChannel], streamSizes[nextChannel]); + } + ms_aInfoForModel[streamIds[nextChannel]].m_loadState = STREAMSTATE_READING; + + MakeSpaceFor(streamSizes[nextChannel] * CDSTREAM_SECTOR_SIZE); + ConvertBufferToObject(ms_pStreamingBuffer[nextChannel], streamIds[nextChannel]); + if(ms_aInfoForModel[streamIds[nextChannel]].m_loadState == STREAMSTATE_STARTED) + FinishLoadingLargeFile(ms_pStreamingBuffer[nextChannel], streamIds[nextChannel]); + + if(streamIds[nextChannel] < STREAM_OFFSET_TXD){ + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[nextChannel]); if(mi->IsSimple()) mi->m_alpha = 255; } - streamIds[processI] = -1; + streamIds[nextChannel] = -1; + readOrder[processI] = -1; + processI = (processI + 1) % ARRAY_SIZE(readOrder); } ms_bLoadingBigModel = false; @@ -2015,7 +2091,7 @@ CStreaming::LoadAllRequestedModels(bool priority) status = CdStreamRead(0, ms_pStreamingBuffer[0], imgOffset+posn, size); while(CdStreamSync(0) || status == STREAM_NONE); ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_READING; - + MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE); ConvertBufferToObject(ms_pStreamingBuffer[0], streamId); if(ms_aInfoForModel[streamId].m_loadState == STREAMSTATE_STARTED) @@ -2072,7 +2148,7 @@ CStreaming::FlushRequestList(void) next = si->m_next; RemoveModel(si - ms_aInfoForModel); } -#ifndef _WIN32 +#ifdef FLUSHABLE_STREAMING if(ms_channel[0].state == CHANNELSTATE_READING) { flushStream[0] = 1; } @@ -2729,7 +2805,7 @@ CStreaming::PrintStreamingBufferState() sprintf(str, "txd %s, refs %d, size %dK, flags 0x%x", CTxdStore::GetTxdName(modelIndex - STREAM_OFFSET_TXD), CTxdStore::GetNumRefs(modelIndex - STREAM_OFFSET_TXD), 2 * size, streamingInfo->m_flags); else - sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetName(), modelInfo->GetNumRefs(), 2 * size, + sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetModelName(), modelInfo->GetNumRefs(), 2 * size, streamingInfo->m_flags); AsciiToUnicode(str, wstr); CFont::PrintString(24.0f, y, wstr); @@ -2752,4 +2828,4 @@ CStreaming::PrintStreamingBufferState() DoRWStuffEndOfFrame(); } CTimer::Update(); -}
\ No newline at end of file +} diff --git a/src/core/Streaming.h b/src/core/Streaming.h index ee9183a5..3294a88e 100644 --- a/src/core/Streaming.h +++ b/src/core/Streaming.h @@ -85,7 +85,11 @@ public: static int32 ms_oldSectorX; static int32 ms_oldSectorY; static int32 ms_streamingBufferSize; +#ifndef ONE_THREAD_PER_CHANNEL static int8 *ms_pStreamingBuffer[2]; +#else + static int8 *ms_pStreamingBuffer[4]; +#endif static size_t ms_memoryUsed; static CStreamingChannel ms_channel[2]; static int32 ms_channelError; @@ -140,7 +144,7 @@ public: static bool RemoveLeastUsedModel(void); static void RemoveAllUnusedModels(void); static void RemoveUnusedModelsInLoadedList(void); - static bool RemoveReferencedTxds(size_t mem); + static bool RemoveReferencedTxds(size_t mem); // originally signed static int32 GetAvailableVehicleSlot(void); static bool IsTxdUsedByRequestedModels(int32 txdId); static bool AddToLoadedVehiclesList(int32 modelId); @@ -176,11 +180,11 @@ public: static void DeleteFarAwayRwObjects(const CVector &pos); static void DeleteAllRwObjects(void); static void DeleteRwObjectsAfterDeath(const CVector &pos); - static void DeleteRwObjectsBehindCamera(size_t mem); + static void DeleteRwObjectsBehindCamera(size_t mem); // originally signed static void DeleteRwObjectsInSectorList(CPtrList &list); static void DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y); - static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); - static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); + static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); // originally signed + static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); // originally signed static void LoadScene(const CVector &pos); diff --git a/src/core/Wanted.h b/src/core/Wanted.h index de36c442..9f08e752 100644 --- a/src/core/Wanted.h +++ b/src/core/Wanted.h @@ -37,6 +37,7 @@ public: int32 NumOfHelisRequired(); void SetWantedLevel(int32); void SetWantedLevelNoDrop(int32 level); + int32 GetWantedLevel() { return m_nWantedLevel; } void RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare); void RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare); void ClearQdCrimes(); diff --git a/src/core/World.cpp b/src/core/World.cpp index 33c2f1c1..90d73b09 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -4,7 +4,6 @@ #include "CopPed.h" #include "CutsceneMgr.h" #include "DMAudio.h" -#include "Entity.h" #include "EventList.h" #include "Explosion.h" #include "Fire.h" @@ -12,10 +11,7 @@ #include "Glass.h" #include "Messages.h" #include "ModelIndices.h" -#include "Object.h" #include "ParticleObject.h" -#include "Ped.h" -#include "PlayerPed.h" #include "Population.h" #include "ProjectileInfo.h" #include "Record.h" @@ -24,7 +20,6 @@ #include "RpAnimBlend.h" #include "Shadows.h" #include "TempColModels.h" -#include "Vehicle.h" #include "WaterLevel.h" #include "World.h" @@ -33,7 +28,7 @@ CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; -CPtrList CWorld::ms_bigBuildingsList[4]; +CPtrList CWorld::ms_bigBuildingsList[NUM_LEVELS]; CPtrList CWorld::ms_listMovingEntityPtrs; CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; uint16 CWorld::ms_nCurrentScanCode; @@ -53,7 +48,7 @@ bool CWorld::bIncludeCarTyres; void CWorld::Initialise() { -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CPools::Initialise(); #endif pIgnoreEntity = nil; @@ -144,13 +139,13 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov } } CCarCtrl::RemoveFromInterestingVehicleList(pVehicle); - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } CObject::DeleteAllTempObjectsInArea(pos, radius); gFireManager.ExtinguishPoint(pos, radius); - CWorld::ExtinguishAllCarFiresInArea(pos, radius); + ExtinguishAllCarFiresInArea(pos, radius); CExplosion::RemoveAllExplosionsInArea(pos, radius); if(bRemoveProjectilesAndTidyUpShadows) { CProjectileInfo::RemoveAllProjectiles(); @@ -365,7 +360,7 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP } else if(e->bUsesCollision) colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); - if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist, + if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, mindist, ignoreSeeThrough)) entity = e; } @@ -450,7 +445,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol e->m_scanCode = GetCurrentScanCode(); colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); - if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist, + if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, mindist, ignoreSeeThrough, poly)) entity = e; } @@ -781,54 +776,54 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nEntitiesFound = 0; const CVector2D vecSectorStartPos(position.x - radius, position.y - radius); const CVector2D vecSectorEndPos(position.x + radius, position.y + radius); - const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0); - const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0); - const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1); - const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1); + const int32 nStartX = Max(GetSectorIndexX(vecSectorStartPos.x), 0); + const int32 nStartY = Max(GetSectorIndexY(vecSectorStartPos.y), 0); + const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1); + const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1); for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { - CSector *pSector = CWorld::GetSector(x, y); + CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsOfTypeInRangeSectorList( + FindObjectsOfTypeInRangeSectorList( modelId, pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities); } @@ -922,24 +917,24 @@ CEntity * CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore, bool ignoreSomeObjects) { - static CColModel sphereCol; - - sphereCol.boundingSphere.center.x = 0.0f; - sphereCol.boundingSphere.center.y = 0.0f; - sphereCol.boundingSphere.center.z = 0.0f; - sphereCol.boundingSphere.radius = radius; - sphereCol.boundingBox.min.x = -radius; - sphereCol.boundingBox.min.y = -radius; - sphereCol.boundingBox.min.z = -radius; - sphereCol.boundingBox.max.x = radius; - sphereCol.boundingBox.max.y = radius; - sphereCol.boundingBox.max.z = radius; - sphereCol.numSpheres = 1; - sphereCol.spheres = &sphereCol.boundingSphere; - sphereCol.numLines = 0; - sphereCol.numBoxes = 0; - sphereCol.numTriangles = 0; - sphereCol.ownsCollisionVolumes = false; + static CColModel OurColModel; + + OurColModel.boundingSphere.center.x = 0.0f; + OurColModel.boundingSphere.center.y = 0.0f; + OurColModel.boundingSphere.center.z = 0.0f; + OurColModel.boundingSphere.radius = radius; + OurColModel.boundingBox.min.x = -radius; + OurColModel.boundingBox.min.y = -radius; + OurColModel.boundingBox.min.z = -radius; + OurColModel.boundingBox.max.x = radius; + OurColModel.boundingBox.max.y = radius; + OurColModel.boundingBox.max.z = radius; + OurColModel.numSpheres = 1; + OurColModel.spheres = &OurColModel.boundingSphere; + OurColModel.numLines = 0; + OurColModel.numBoxes = 0; + OurColModel.numTriangles = 0; + OurColModel.ownsCollisionVolumes = false; CMatrix sphereMat; sphereMat.SetTranslate(spherePos); @@ -962,7 +957,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad if(e->GetBoundRadius() + radius > distance) { CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(); int collidedSpheres = - CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol, + CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol, gaTempSphereColPoints, nil, nil); if(collidedSpheres != 0 || @@ -1052,54 +1047,54 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nCollidingEntities = 0; const CVector2D vecSectorStartPos(position.x - radius, position.y - radius); const CVector2D vecSectorEndPos(position.x + radius, position.y + radius); - const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0); - const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0); - const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1); - const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1); + const int32 nStartX = Max(GetSectorIndexX(vecSectorStartPos.x), 0); + const int32 nStartY = Max(GetSectorIndexY(vecSectorStartPos.y), 0); + const int32 nEndX = Min(GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1); + const int32 nEndY = Min(GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1); for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { - CSector *pSector = CWorld::GetSector(x, y); + CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, + FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); - CWorld::FindObjectsKindaCollidingSectorList( + FindObjectsKindaCollidingSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities); } @@ -1133,52 +1128,52 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nIntersecting = 0; - const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0); - const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0); - const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1); - const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1); + const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0); + const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0); + const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1); + const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1); for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { - CSector *pSector = CWorld::GetSector(x, y); + CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], + FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingCubeSectorList( + FindObjectsIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities); } @@ -1214,52 +1209,52 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nEntitiesFound = 0; - const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0); - const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0); - const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1); - const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1); + const int32 nStartX = Max(GetSectorIndexX(fStartX), 0); + const int32 nStartY = Max(GetSectorIndexY(fStartY), 0); + const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X - 1); + const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y - 1); for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { - CSector *pSector = CWorld::GetSector(x, y); + CSector *pSector = GetSector(x, y); if(bBuildings) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bVehicles) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bPeds) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_PEDS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bObjects) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } if(bDummies) { - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_DUMMIES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); - CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList( + FindObjectsIntersectingAngledCollisionBoxSectorList( pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities); } @@ -1294,36 +1289,36 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV int16 maxEntitiesToFind, CEntity **aEntities, bool bVehicles, bool bPeds, bool bObjects) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); *nIntersecting = 0; - const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0); - const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0); - const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1); - const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1); + const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0); + const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0); + const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1); + const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1); for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { - CSector *pSector = CWorld::GetSector(x, y); + CSector *pSector = GetSector(x, y); if(bVehicles) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false); } if(bPeds) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true); } if(bObjects) { - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false); - CWorld::FindMissionEntitiesIntersectingCubeSectorList( + FindMissionEntitiesIntersectingCubeSectorList( pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false); } @@ -1361,102 +1356,6 @@ CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList &list, const CVec } } -CPlayerPed * -FindPlayerPed(void) -{ - return CWorld::Players[CWorld::PlayerInFocus].m_pPed; -} - -CVehicle * -FindPlayerVehicle(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped && ped->InVehicle()) return ped->m_pMyVehicle; - return nil; -} - -CVehicle * -FindPlayerTrain(void) -{ - if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain()) - return FindPlayerVehicle(); - else - return nil; -} - -CEntity * -FindPlayerEntity(void) -{ - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle; - else - return ped; -} - -CVector -FindPlayerCoors(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) - return TheCamera.GetPosition(); -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->GetPosition(); - else - return ped->GetPosition(); -} - -CVector & -FindPlayerSpeed(void) -{ -#ifdef FIX_BUGS - static CVector vecTmpVector(0.0f, 0.0f, 0.0f); - if (CReplay::IsPlayingBack()) - return vecTmpVector; -#endif - CPlayerPed *ped = FindPlayerPed(); - if(ped->InVehicle()) - return ped->m_pMyVehicle->m_vecMoveSpeed; - else - return ped->m_vecMoveSpeed; -} - -const CVector & -FindPlayerCentreOfWorld(int32 player) -{ -#ifdef FIX_BUGS - if(CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return CWorld::Players[player].m_pPed->GetPosition(); -} - -const CVector & -FindPlayerCentreOfWorld_NoSniperShift(void) -{ -#ifdef FIX_BUGS - if (CReplay::IsPlayingBack()) return TheCamera.GetPosition(); -#endif - if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition(); - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return FindPlayerPed()->GetPosition(); -} - -float -FindPlayerHeading(void) -{ - if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle) - return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); - if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); - return FindPlayerPed()->GetForward().Heading(); -} - void CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2) { @@ -1479,7 +1378,7 @@ CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, floa } } CCarCtrl::RemoveFromInterestingVehicleList(pVehicle); - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } @@ -1505,24 +1404,24 @@ CWorld::ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, floa void CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2) { - CWorld::AdvanceCurrentScanCode(); + AdvanceCurrentScanCode(); float fStartX = x1 - 10.0f; float fStartY = y1 - 10.0f; float fEndX = x2 + 10.0f; float fEndY = y2 + 10.0f; - const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0); - const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0); - const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1); - const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1); + const int32 nStartX = Max(GetSectorIndexX(fStartX), 0); + const int32 nStartY = Max(GetSectorIndexY(fStartY), 0); + const int32 nEndX = Min(GetSectorIndexX(fEndX), NUMSECTORS_X - 1); + const int32 nEndY = Min(GetSectorIndexY(fEndY), NUMSECTORS_Y - 1); for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { - CSector *pSector = CWorld::GetSector(x, y); - CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2, + CSector *pSector = GetSector(x, y); + CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY); - CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1, + CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY); - CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2); - CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2, + CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2); + CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2, y2); } } @@ -1537,7 +1436,7 @@ CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1 if(pVehicle->m_scanCode != GetCurrentScanCode()) { pVehicle->m_scanCode = GetCurrentScanCode(); const CVector &vehiclePos = pVehicle->GetPosition(); - eCarMission carMission = pVehicle->AutoPilot.m_nCarMission; + uint8 carMission = pVehicle->AutoPilot.m_nCarMission; if(pVehicle != FindPlayerVehicle() && vehiclePos.x > fStartX && vehiclePos.x < fEndX && vehiclePos.y > fStartY && vehiclePos.y < fEndY && pVehicle->bIsLawEnforcer && (carMission == MISSION_RAMPLAYER_FARAWAY || carMission == MISSION_RAMPLAYER_CLOSE || @@ -1696,14 +1595,24 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range) } } +inline void +AddSteamsFromGround(CPtrList& list) +{ + CPtrNode *pNode = list.first; + while (pNode) { + ((CEntity*)pNode->item)->AddSteamsFromGround(nil); + pNode = pNode->next; + } +} + void CWorld::AddParticles(void) { for(int32 y = 0; y < NUMSECTORS_Y; y++) { for(int32 x = 0; x < NUMSECTORS_X; x++) { CSector *pSector = GetSector(x, y); - CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]); - CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]); + AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]); + AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]); } } } @@ -1715,44 +1624,52 @@ CWorld::ShutDown(void) CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } +#ifndef FIX_BUGS pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush(); pSector->m_lists[ENTITYLIST_DUMMIES].Flush(); pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush(); +#endif } - for(int32 i = 0; i < 4; i++) { - for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) { + for(int32 i = 0; i < NUM_LEVELS; i++) { + for(CPtrNode *pNode = ms_bigBuildingsList[i].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; // Maybe remove from world here? delete pEntity; } - GetBigBuildingList((eLevelName)i).Flush(); + ms_bigBuildingsList[i].Flush(); } for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) { CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); +#ifdef FIX_BUGS + pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); + pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush(); + pSector->m_lists[ENTITYLIST_DUMMIES].Flush(); + pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush(); +#endif if(pSector->m_lists[ENTITYLIST_BUILDINGS].first) { sprintf(gString, "Building list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y); pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); @@ -1783,6 +1700,9 @@ CWorld::ShutDown(void) } } ms_listMovingEntityPtrs.Flush(); +#if GTA_VERSION <= GTA3_PS2_160 + CPools::Shutdown(); +#endif } void @@ -1797,19 +1717,19 @@ CWorld::ClearForRestart(void) CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = GetBigBuildingList(LEVEL_GENERIC).first; pNode; pNode = pNode->next) { CVehicle *pVehicle = (CVehicle *)pNode->item; if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) { - CWorld::Remove(pVehicle); + Remove(pVehicle); delete pVehicle; } } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } } @@ -1840,7 +1760,7 @@ CWorld::RepositionOneObject(CEntity *pEntity) modelId == MI_PARKTABLE) { CVector &position = pEntity->GetMatrix().GetPosition(); float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z; - position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y, + position.z = FindGroundZFor3DCoord(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, nil) - fBoundingBoxMinZ; pEntity->m_matrix.UpdateRW(); @@ -1849,7 +1769,7 @@ CWorld::RepositionOneObject(CEntity *pEntity) float fWaterLevel = 0.0f; bool bFound = true; const CVector &position = pEntity->GetPosition(); - float fGroundZ = CWorld::FindGroundZFor3DCoord(position.x, position.y, + float fGroundZ = FindGroundZFor3DCoord(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound); if(CWaterLevel::GetWaterLevelNoWaves(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, &fWaterLevel)) { @@ -1897,17 +1817,17 @@ CWorld::RemoveStaticObjects() CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y); for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) { CEntity *pEntity = (CEntity *)pNode->item; - CWorld::Remove(pEntity); + Remove(pEntity); delete pEntity; } pSector->m_lists[ENTITYLIST_BUILDINGS].Flush(); @@ -1929,9 +1849,9 @@ CWorld::Process(void) if(csObj->m_rwObject && RwObjectGetType(csObj->m_rwObject) == rpCLUMP && RpAnimBlendClumpGetFirstAssociation(csObj->GetClump())) { RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), - 0.02f * (csObj->IsObject() - ? CTimer::GetTimeStepNonClipped() - : CTimer::GetTimeStep())); + csObj->IsObject() + ? CTimer::GetTimeStepNonClippedInSeconds() + : CTimer::GetTimeStepInSeconds()); } csObj->ProcessControl(); csObj->ProcessCollision(); @@ -1944,17 +1864,16 @@ CWorld::Process(void) } else { for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { CEntity *movingEnt = (CEntity *)node->item; -#ifdef SQUEEZE_PERFORMANCE - if (movingEnt->bRemoveFromWorld) { - RemoveEntityInsteadOfProcessingIt(movingEnt); - } else -#endif +#ifdef FIX_BUGS // from VC + if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && +#else if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP && +#endif RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) { RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), - 0.02f * (movingEnt->IsObject() - ? CTimer::GetTimeStepNonClipped() - : CTimer::GetTimeStep())); + movingEnt->IsObject() + ? CTimer::GetTimeStepNonClippedInSeconds() + : CTimer::GetTimeStepInSeconds()); } } for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) { @@ -2096,18 +2015,18 @@ CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, C { CVector2D vecStartPos(position.x - fRadius, position.y - fRadius); CVector2D vecEndPos(position.x + fRadius, position.y + fRadius); - const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0); - const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0); - const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1); - const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1); + const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0); + const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0); + const int32 nEndX = Min(GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1); + const int32 nEndY = Min(GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1); for(int32 y = nStartY; y <= nEndY; y++) { for(int32 x = nStartX; x <= nEndX; x++) { - CSector *pSector = CWorld::GetSector(x, y); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius, + CSector *pSector = GetSector(x, y); + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); - CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius, + TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer); } } @@ -2165,7 +2084,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa if(!pEntity->GetIsStatic()) { float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f); CVector vecForceDir = - vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier / + vecDistance * (fPower * pEntity->m_fMass / 1400.0f * fDamageMultiplier / Max(fMagnitude, 0.01f)); vecForceDir.z = Max(vecForceDir.z, 0.0f); if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f); @@ -2204,7 +2123,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa PEDPIECE_TORSO, direction); if(pPed->m_nPedState != PED_DIE) pPed->SetFall(2000, - (AnimationId)(direction + ANIM_KO_SKID_FRONT), 0); + (AnimationId)(direction + ANIM_STD_HIGHIMPACT_FRONT), 0); if(pCreator && pCreator->IsPed()) { eEventType eventType = EVENT_SHOOT_PED; if(pPed->m_nPedType == PEDTYPE_COP) eventType = EVENT_SHOOT_COP; diff --git a/src/core/World.h b/src/core/World.h index 9465a914..3d553752 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -3,6 +3,7 @@ #include "Game.h" #include "Lists.h" #include "PlayerInfo.h" +#include "Collision.h" /* Sectors span from -2000 to 2000 in x and y. * With 100x100 sectors, each is 40x40 units. */ @@ -48,14 +49,9 @@ public: VALIDATE_SIZE(CSector, 0x28); -class CEntity; -struct CColPoint; -struct CColLine; -struct CStoredCollPoly; - class CWorld { - static CPtrList ms_bigBuildingsList[4]; + static CPtrList ms_bigBuildingsList[NUM_LEVELS]; static CPtrList ms_listMovingEntityPtrs; static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X]; static uint16 ms_nCurrentScanCode; @@ -157,14 +153,3 @@ public: extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS]; -class CPlayerPed; -class CVehicle; -CPlayerPed *FindPlayerPed(void); -CVehicle *FindPlayerVehicle(void); -CVehicle *FindPlayerTrain(void); -CEntity *FindPlayerEntity(void); -CVector FindPlayerCoors(void); -CVector &FindPlayerSpeed(void); -const CVector &FindPlayerCentreOfWorld(int32 player); -const CVector &FindPlayerCentreOfWorld_NoSniperShift(void); -float FindPlayerHeading(void); diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp index 075a13bc..33586a4e 100644 --- a/src/core/ZoneCull.cpp +++ b/src/core/ZoneCull.cpp @@ -855,66 +855,66 @@ CCullZone::PointFallsWithinZone(CVector pos, float radius) CVector ExtraFudgePointsCoors[] = { - CVector(978.0, -394.0, 18.0), - CVector(1189.7, -414.6, 27.0), - CVector(978.8, -391.0, 19.0), - CVector(1199.0, -502.3, 28.0), - CVector(1037.0, -391.9, 18.4), - CVector(1140.0, -608.7, 16.0), - CVector(1051.0, -26.0, 11.0), - CVector(951.5, -345.1, 12.0), - CVector(958.2, -394.6, 16.0), - CVector(1036.5, -390.0, 15.2), - CVector(960.6, -390.5, 20.9), - CVector(1061.0, -640.6, 16.3), - CVector(1034.5, -388.96, 14.78), - CVector(1038.4, -13.98, 12.2), - CVector(1047.2, -16.7, 10.6), - CVector(1257.9, -333.3, 40.0), - CVector(885.6, -424.9, 17.0), - CVector(1127.5, -795.8, 17.7), - CVector(1133.0, -716.0, 19.0), - CVector(1125.0, -694.0, 18.5), - CVector(1125.0, -670.0, 16.3), - CVector(1051.6, 36.3, 17.9), - CVector(1054.6, -11.4, 15.0), - CVector(1058.9, -278.0, 15.0), - CVector(1059.4, -261.0, 10.9), - CVector(1051.5, -638.5, 16.5), - CVector(1058.2, -643.4, 15.5), - CVector(1058.2, -643.4, 18.0), - CVector(826.0, -260.0, 7.0), - CVector(826.0, -260.0, 11.0), - CVector(833.0, -603.6, 16.4), - CVector(833.0, -603.6, 20.0), - CVector(1002.0, -318.5, 10.5), - CVector(998.0, -318.0, 9.8), - CVector(1127.0, -183.0, 18.1), - CVector(1123.0, -331.5, 23.8), - CVector(1123.8, -429.0, 24.0), - CVector(1197.0, -30.0, 13.7), - CVector(1117.5, -230.0, 17.3), - CVector(1117.5, -230.0, 20.0), - CVector(1120.0, -281.6, 21.5), - CVector(1120.0, -281.6, 24.0), - CVector(1084.5, -1022.7, 17.0), - CVector(1071.5, 5.4, 4.6), - CVector(1177.2, -215.7, 27.6), - CVector(841.6, -460.0, 19.7), - CVector(874.8, -456.6, 16.6), - CVector(918.3, -451.8, 17.8), - CVector(844.0, -495.7, 16.7), - CVector(842.0, -493.4, 21.0), - CVector(1433.5, -774.4, 16.9), - CVector(1051.0, -205.0, 7.5), - CVector(885.5, -425.6, 15.6), - CVector(182.6, -470.4, 27.8), - CVector(132.5, -930.2, 29.0), - CVector(124.7, -904.0, 28.0), - CVector(-50.0, -686.0, 22.0), - CVector(-49.1, -694.5, 22.5), - CVector(1063.8, -404.45, 16.2), - CVector(1062.2, -405.5, 17.0) + CVector(978.0f, -394.0f, 18.0f), + CVector(1189.7f, -414.6f, 27.0f), + CVector(978.8f, -391.0f, 19.0f), + CVector(1199.0f, -502.3f, 28.0f), + CVector(1037.0f, -391.9f, 18.4f), + CVector(1140.0f, -608.7f, 16.0f), + CVector(1051.0f, -26.0f, 11.0f), + CVector(951.5f, -345.1f, 12.0f), + CVector(958.2f, -394.6f, 16.0f), + CVector(1036.5f, -390.0f, 15.2f), + CVector(960.6f, -390.5f, 20.9f), + CVector(1061.0f, -640.6f, 16.3f), + CVector(1034.5f, -388.96f, 14.78f), + CVector(1038.4f, -13.98f, 12.2f), + CVector(1047.2f, -16.7f, 10.6f), + CVector(1257.9f, -333.3f, 40.0f), + CVector(885.6f, -424.9f, 17.0f), + CVector(1127.5f, -795.8f, 17.7f), + CVector(1133.0f, -716.0f, 19.0f), + CVector(1125.0f, -694.0f, 18.5f), + CVector(1125.0f, -670.0f, 16.3f), + CVector(1051.6f, 36.3f, 17.9f), + CVector(1054.6f, -11.4f, 15.0f), + CVector(1058.9f, -278.0f, 15.0f), + CVector(1059.4f, -261.0f, 10.9f), + CVector(1051.5f, -638.5f, 16.5f), + CVector(1058.2f, -643.4f, 15.5f), + CVector(1058.2f, -643.4f, 18.0f), + CVector(826.0f, -260.0f, 7.0f), + CVector(826.0f, -260.0f, 11.0f), + CVector(833.0f, -603.6f, 16.4f), + CVector(833.0f, -603.6f, 20.0f), + CVector(1002.0f, -318.5f, 10.5f), + CVector(998.0f, -318.0f, 9.8f), + CVector(1127.0f, -183.0f, 18.1f), + CVector(1123.0f, -331.5f, 23.8f), + CVector(1123.8f, -429.0f, 24.0f), + CVector(1197.0f, -30.0f, 13.7f), + CVector(1117.5f, -230.0f, 17.3f), + CVector(1117.5f, -230.0f, 20.0f), + CVector(1120.0f, -281.6f, 21.5f), + CVector(1120.0f, -281.6f, 24.0f), + CVector(1084.5f, -1022.7f, 17.0f), + CVector(1071.5f, 5.4f, 4.6f), + CVector(1177.2f, -215.7f, 27.6f), + CVector(841.6f, -460.0f, 19.7f), + CVector(874.8f, -456.6f, 16.6f), + CVector(918.3f, -451.8f, 17.8f), + CVector(844.0f, -495.7f, 16.7f), + CVector(842.0f, -493.4f, 21.0f), + CVector(1433.5f, -774.4f, 16.9f), + CVector(1051.0f, -205.0f, 7.5f), + CVector(885.5f, -425.6f, 15.6f), + CVector(182.6f, -470.4f, 27.8f), + CVector(132.5f, -930.2f, 29.0f), + CVector(124.7f, -904.0f, 28.0f), + CVector(-50.0f, -686.0f, 22.0f), + CVector(-49.1f, -694.5f, 22.5f), + CVector(1063.8f, -404.45f, 16.2f), + CVector(1062.2f, -405.5f, 17.0f) }; int32 NumTestPoints; int32 aTestPointsX[100]; diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp index 2e3e0f6e..cdae85e1 100644 --- a/src/core/Zones.cpp +++ b/src/core/Zones.cpp @@ -649,7 +649,7 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE); - WriteSaveBuf(buffer, GetIndexForZonePointer(m_pPlayersZone)); + WriteSaveBuf(buffer, (int32)GetIndexForZonePointer(m_pPlayersZone)); WriteSaveBuf(buffer, m_CurrLevel); WriteSaveBuf(buffer, FindIndex); WriteSaveBuf(buffer, (int16)0); // padding diff --git a/src/core/Zones.h b/src/core/Zones.h index 6549dad5..aa0466e8 100644 --- a/src/core/Zones.h +++ b/src/core/Zones.h @@ -105,8 +105,8 @@ public: 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(ssize_t i) { return i == -1 ? nil : &ZoneArray[i]; } + static ssize_t GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; } 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 48b20884..33d8910d 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -7,21 +7,47 @@ #pragma warning(disable: 4838) // narrowing conversion #pragma warning(disable: 4996) // POSIX names +#ifdef __MWERKS__ +#define __STDC_LIMIT_MACROS // so we get UINT32_MAX etc +#endif + #include <stdint.h> #include <string.h> #include <math.h> -#if defined _WIN32 && defined WITHWINDOWS -#include <windows.h> +#ifdef __MWERKS__ +#define AUDIO_MSS +#define RWLIBS // codewarrior doesn't support project level defines - so not even this is enough, but still catches most ifdefs +#endif + +#if !defined RW_D3D9 && defined LIBRW +#undef WITHD3D +#undef WITHDINPUT +#endif + +#if (defined WITHD3D && !defined LIBRW) +#define WITHWINDOWS #endif -#if defined _WIN32 && defined WITHD3D +#if defined _WIN32 && defined WITHWINDOWS && !defined _INC_WINDOWS #include <windows.h> -#ifndef USE_D3D9 -#include <d3d8types.h> -#else -#include <d3d9types.h> #endif + +#ifdef WITHD3D + #ifdef LIBRW + #define WITH_D3D // librw includes d3d9 itself via this right now + #else + #ifndef USE_D3D9 + #include <d3d8.h> + #else + #include <d3d9.h> + #endif + #endif +#endif + +#ifdef WITHDINPUT +#define DIRECTINPUT_VERSION 0x0800 +#include <dinput.h> #endif #include <rwcore.h> @@ -52,14 +78,6 @@ #define rwVENDORID_ROCKSTAR 0x0253F2 -// Get rid of bullshit windows definitions, we're not running on an 8086 -#ifdef far -#undef far -#endif -#ifdef near -#undef near -#endif - #define Max(a,b) ((a) > (b) ? (a) : (b)) #define Min(a,b) ((a) < (b) ? (a) : (b)) @@ -70,14 +88,28 @@ typedef uint8_t uint8; typedef int8_t int8; typedef uint16_t uint16; typedef int16_t int16; +#ifndef __MWERKS__ typedef uint32_t uint32; typedef int32_t int32; +#else +typedef unsigned int uint32; +typedef int int32; +#endif typedef uintptr_t uintptr; +typedef intptr_t intptr; typedef uint64_t uint64; typedef int64_t int64; // hardcode ucs-2 typedef uint16_t wchar; +typedef uint8 bool8; +typedef uint16 bool16; +typedef uint32 bool32; + +#if defined(_MSC_VER) || defined (__MWERKS__) +typedef ptrdiff_t ssize_t; +#endif + #ifndef nil #define nil NULL #endif @@ -116,17 +148,43 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w) #include "skeleton.h" #include "Draw.h" -#define DEFAULT_SCREEN_WIDTH (640) -#define DEFAULT_SCREEN_HEIGHT (448) -#define DEFAULT_SCREEN_HEIGHT_PAL (512) -#define DEFAULT_SCREEN_HEIGHT_NTSC (448) +#if defined(PROPER_SCALING) || defined(PS2_HUD) + #ifdef FORCE_PC_SCALING + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (448) + #else + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (480) + #endif +#elif defined(GTA_PS2) + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (480) +#else //elif defined(GTA_PC) + #define DEFAULT_SCREEN_WIDTH (640) + #define DEFAULT_SCREEN_HEIGHT (448) +#endif + #define DEFAULT_ASPECT_RATIO (4.0f/3.0f) #define DEFAULT_VIEWWINDOW (0.7f) // game uses maximumWidth/Height, but this probably won't work // with RW windowed mode -#define SCREEN_WIDTH ((float)RsGlobal.width) +#ifdef GTA_PS2 + #ifdef GTA_PAL + #define SCREEN_WIDTH ((float)640) + #define SCREEN_HEIGHT ((float)512) + #else + #define SCREEN_WIDTH ((float)640) + #define SCREEN_HEIGHT ((float)448) + #endif +#else +#define SCREEN_WIDTH ((float)RsGlobal.width) #define SCREEN_HEIGHT ((float)RsGlobal.height) +#endif + +#define SCREEN_HEIGHT_PAL ((float)512) +#define SCREEN_HEIGHT_NTSC ((float)448) + #define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio()) #define SCREEN_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetScaledFOV() * 0.5f))) @@ -144,8 +202,13 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w) #ifdef ASPECT_RATIO_SCALE #define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) -extern float ScaleAndCenterX(float x); -#define SCALE_AND_CENTER_X(x) ScaleAndCenterX(x) +#define SCALE_AND_CENTER_X(x) ((SCREEN_WIDTH == DEFAULT_SCREEN_WIDTH) ? (x) : (SCREEN_WIDTH - SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)) / 2 + SCREEN_SCALE_X((x))) +#ifdef PROPER_SCALING + #ifndef FORCE_PC_SCALING + #undef SCREEN_SCALE_Y + #define SCREEN_SCALE_Y(a) CDraw::ScaleY(SCREEN_STRETCH_Y(a)) + #endif +#endif #else #define SCREEN_SCALE_AR(a) (a) #define SCALE_AND_CENTER_X(x) SCREEN_STRETCH_X(x) @@ -226,6 +289,22 @@ extern wchar *AllocUnicode(const char*src); inline float sq(float x) { return x*x; } #define SQR(x) ((x) * (x)) +#ifdef __MWERKS__ +#define M_E 2.71828182845904523536 // e +#define M_LOG2E 1.44269504088896340736 // log2(e) +#define M_LOG10E 0.434294481903251827651 // log10(e) +#define M_LN2 0.693147180559945309417 // ln(2) +#define M_LN10 2.30258509299404568402 // ln(10) +#define M_PI 3.14159265358979323846 // pi +#define M_PI_2 1.57079632679489661923 // pi/2 +#define M_PI_4 0.785398163397448309616 // pi/4 +#define M_1_PI 0.318309886183790671538 // 1/pi +#define M_2_PI 0.636619772367581343076 // 2/pi +#define M_2_SQRTPI 1.12837916709551257390 // 2/sqrt(pi) +#define M_SQRT2 1.41421356237309504880 // sqrt(2) +#define M_SQRT1_2 0.707106781186547524401 // 1/sqrt(2) +#endif + #define PI (float)M_PI #define TWOPI (PI*2) #define HALFPI (PI/2) @@ -248,20 +327,49 @@ void re3_usererror(const char *format, ...); #define DEBUGBREAK() __debugbreak(); -#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) +// Switch to enable development messages. +#if 1 +#define DEV(f, ...) +#else #define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__) -#define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__) +#endif + +#ifdef __MWERKS__ +void debug(char *f, ...); +void Error(char *f, ...); +__inline__ void TRACE(char *f, ...) { } // this is re3 only, and so the function needs to be inline - this way no call actually gets placed +// USERERROR only gets used in oal builds ... once +#else +#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) #define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__) +#ifndef MASTER +#define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__) #define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__) +#else +#define TRACE(f, ...) +#define USERERROR(f, ...) +#endif +#endif +#ifndef MASTER #define assert(_Expression) (void)( (!!(_Expression)) || (re3_assert(#_Expression, __FILE__, __LINE__, __FUNCTION__), 0) ) +#else +#define assert(_Expression) +#endif #define ASSERT assert +#ifdef __MWERKS__ +#define static_assert(bool_constexpr, message) +#endif + #define _TODO(x) #define _TODOCONST(x) (x) -#ifdef CHECK_STRUCT_SIZES -#define VALIDATE_SIZE(struc, size) static_assert(sizeof(struc) == size, "Invalid structure size of " #struc) +#ifdef CHECK_STRUCT_SIZES +template<int s, int t> struct check_size { + static_assert(s == t, "Invalid structure size"); +}; +#define VALIDATE_SIZE(struc, size) check_size<sizeof(struc), size> struc ## Check #else #define VALIDATE_SIZE(struc, size) #endif @@ -280,6 +388,7 @@ void re3_usererror(const char *format, ...); #define CONCAT_(x,y) x##y #define CONCAT(x,y) CONCAT_(x,y) +#ifdef DEBUGMENU // Tweaking stuff for debugmenu #define TWEAKPATH ___tw___TWEAKPATH #define SETTWEAKPATH(path) static const char *___tw___TWEAKPATH = path; @@ -393,6 +502,7 @@ _TWEEKCLASS(CTweakUInt32, uint32); _TWEEKCLASS(CTweakFloat, float); #undef _TWEEKCLASS +#endif #ifdef VALIDATE_SAVE_SIZE extern int32 _saveBufCount; diff --git a/src/core/config.h b/src/core/config.h index 99c5f6ef..79323ef1 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -1,27 +1,33 @@ #pragma once +// disables (most) stuff that wasn't in original gta3.exe - check section at the bottom of this file +//#define VANILLA_DEFINES + enum Config { - NUMPLAYERS = 1, + NUMPLAYERS = 1, // 4 on PS2 NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC) MAX_CDIMAGES = 8, // additional cdimages MAX_CDCHANNELS = 5, - MODELINFOSIZE = 5500, -// TXDSTORESIZE = 850, + MODELINFOSIZE = 5500, // 3150 on PS2 +#if defined __MWERKS__ || defined VANILLA_DEFINES + TXDSTORESIZE = 850, +#else TXDSTORESIZE = 1024, // for Xbox map +#endif EXTRADIRSIZE = 128, CUTSCENEDIRSIZE = 512, - SIMPLEMODELSIZE = 5000, + SIMPLEMODELSIZE = 5000, // 2910 on PS2 MLOMODELSIZE = 1, MLOINSTANCESIZE = 1, TIMEMODELSIZE = 30, CLUMPMODELSIZE = 5, PEDMODELSIZE = 90, - VEHICLEMODELSIZE = 120, + VEHICLEMODELSIZE = 120, // 70 on PS2 XTRACOMPSMODELSIZE = 2, - TWODFXSIZE = 2000, + TWODFXSIZE = 2000, // 1210 on PS2 MAXVEHICLESLOADED = 50, // 70 on mobile @@ -135,10 +141,6 @@ enum Config { NUM_EXPLOSIONS = 48, }; -// We'll use this once we're ready to become independent of the game -// Use it to mark bugs in the code that will prevent the game from working then -//#define STANDALONE - // We don't expect to compile for PS2 or Xbox // but it might be interesting for documentation purposes #define GTA_PC @@ -165,6 +167,16 @@ enum Config { #define FINAL #endif +// Version defines +#define GTA3_PS2_140 300 +#define GTA3_PS2_160 301 +#define GTA3_PC_10 310 +#define GTA3_PC_11 311 +#define GTA3_PC_STEAM 312 +// TODO? maybe something for xbox or android? + +#define GTA_VERSION GTA3_PC_11 + // quality of life fixes that should also be in FINAL #define NASTY_GAME // nasty game for all languages #define NO_CDCHECK @@ -173,24 +185,31 @@ enum Config { #define DRAW_GAME_VERSION_TEXT #define DRAW_MENU_VERSION_TEXT +// Memory allocation and compression +// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet +//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices +//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed + #if defined GTA_PS2 # define GTA_PS2_STUFF # define RANDOMSPLASH +# define USE_CUSTOM_ALLOCATOR # define VU_COLLISION # define ANIM_COMPRESSION #elif defined GTA_PC -# define GTA3_1_1_PATCH -//# define GTA3_STEAM_PATCH # ifdef GTA_PS2_STUFF # define USE_PS2_RAND # define RANDOMSPLASH // use random splash as on PS2 # define PS2_MATFX # endif +# define PC_PLAYER_CONTROLS // mouse player/cam mode +# define GTA_REPLAY +# define GTA_SCENE_EDIT #elif defined GTA_XBOX #endif #ifdef VU_COLLISION -#define COMPRESSED_COL_VECTORS // current need compressed vectors in this code +#define COMPRESSED_COL_VECTORS // currently need compressed vectors in this code #endif #ifdef MASTER @@ -213,11 +232,21 @@ enum Config { # define TIMEBARS // print debug timers #endif -#define FIX_BUGS // fixes bugs that we've came across during reversing +#define FIX_BUGS // fixes bugs that we've came across during reversing. You can undefine this only on release builds. #define MORE_LANGUAGES // Add more translations to the game #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible #define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS +#if defined(__LP64__) || defined(_WIN64) +#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build +#endif + +#define ASCII_STRCMP // use faster ascii str comparisons + +#if !defined _WIN32 || defined __MWERKS__ || defined __MINGW32__ || defined VANILLA_DEFINES +#undef ASCII_STRCMP +#endif + // Just debug menu entries #ifdef DEBUGMENU #define MISSION_SWITCHER // from debug menu @@ -228,24 +257,26 @@ enum Config { //# define HARDCODED_MODEL_FLAGS // sets the flags enabled above from hardcoded model names. // NB: keep this enabled unless your map IDEs have these flags baked in #define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios +#define PROPER_SCALING // use original DEFAULT_SCREEN_WIDTH/DEFAULT_SCREEN_HEIGHT from PS2 instead of PC(R* changed HEIGHT here to make radar look better, but broke other hud elements aspect ratio). #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch) #define USE_TXD_CDIMAGE // generate and load textures from txd.img #define PS2_ALPHA_TEST // emulate ps2 alpha test #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number #define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time #define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync +#define ANISOTROPIC_FILTERING // set all textures to max anisotropic filtering //#define USE_TEXTURE_POOL #ifdef LIBRW -//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) -//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) -//#define SCREEN_DROPLETS // neo water droplets +#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) +#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) +#define SCREEN_DROPLETS // neo water droplets +#define NEW_RENDERER // leeds-like world rendering, needs librw #endif +#define FIX_SPRITES // fix sprites aspect ratio(moon, coronas, particle etc) + #ifndef EXTENDED_COLOURFILTER -#undef SCREEN_DROPLETS // we need the frontbuffer for this effect -#endif -#ifndef EXTENDED_PIPELINES -#undef SCREEN_DROPLETS // we need neo.txd +#undef SCREEN_DROPLETS // we need the backbuffer for this effect #endif // Particle @@ -264,14 +295,17 @@ enum Config { #define ALLCARSHELI_CHEAT #define ALT_DODO_CHEAT #define REGISTER_START_BUTTON -//#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls +#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls #define BUTTON_ICONS // use textures to show controller buttons // Hud, frontend and radar +//#define PS2_HUD #define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better. // #define BETA_SLIDING_TEXT #define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC +#define FIX_RADAR // use radar size from early version before R* broke it // #define XBOX_SUBTITLES // the infamous outlines +#define RADIO_OFF_TEXT #define PC_MENU #ifndef PC_MENU @@ -279,6 +313,11 @@ enum Config { //# define PS2_MENU_USEALLPAGEICONS #else # define MENU_MAP // VC-like menu map. Make sure you have new menu.txd + +# ifdef XINPUT +# define GAMEPAD_MENU // Add gamepad menu +# endif + # define SCROLLABLE_STATS_PAGE // only draggable by mouse atm # define TRIANGLE_BACK_BUTTON //# define CIRCLE_BACK_BUTTON @@ -287,7 +326,7 @@ enum Config { # define CUSTOM_FRONTEND_OPTIONS # ifdef CUSTOM_FRONTEND_OPTIONS -# define GRAPHICS_MENU_OPTIONS // otherwise Advanced Options menu will appear if Display is full +# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable # define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU # define CUTSCENE_BORDERS_SWITCH # define MULTISAMPLING // adds MSAA option @@ -306,10 +345,19 @@ enum Config { #define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT #define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log +#if SCRIPT_LOG_FILE_LEVEL == 0 +#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT +#endif + #ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT #define USE_BASIC_SCRIPT_DEBUG_OUTPUT #endif +#ifdef MASTER +#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT +#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT +#endif + // Replay //#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool! //#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!) @@ -336,13 +384,30 @@ enum Config { #define FREE_CAM // Rotating cam // Audio -#ifndef AUDIO_OAL // is not working yet for openal -#define AUDIO_CACHE // cache sound lengths to speed up the cold boot +#define RADIO_SCROLL_TO_PREV_STATION +#define AUDIO_CACHE +//#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds) +//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder +#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files + +#ifdef AUDIO_OPUS +#define AUDIO_OAL_USE_OPUS // enable support of opus files +#define OPUS_AUDIO_PATHS // changes audio paths to opus paths (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled) +#define OPUS_SFX // enable if your sfx.raw is encoded with opus (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled) + +#ifndef AUDIO_OAL_USE_OPUS +#undef OPUS_AUDIO_PATHS +#undef OPUS_SFX #endif -//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS -// IMG -#define BIG_IMG // allows to read larger img files +#endif + +// Streaming +#if !defined(_WIN32) && !defined(__SWITCH__) + //#define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash - also not utilized too much right now(see commented LoadAllRequestedModels in Streaming.cpp) + #define FLUSHABLE_STREAMING // Make it possible to interrupt reading when processing file isn't needed anymore. +#endif +#define BIG_IMG // Not complete - allows to read larger img files //#define SQUEEZE_PERFORMANCE #ifdef SQUEEZE_PERFORMANCE @@ -350,8 +415,94 @@ enum Config { #undef NO_ISLAND_LOADING #define PC_PARTICLE #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial + #define VC_RAIN_NERF // Reduces number of rain particles #endif -#ifdef LIBRW -// these are not supported with librw yet +// ------- + +#if defined __MWERKS__ || defined VANILLA_DEFINES +#define FINAL +#undef CHATTYSPLASH +#undef TIMEBARS +//#define USE_MY_DOCUMENTS + +#define MASTER +#undef VALIDATE_SAVE_SIZE +#undef NO_MOVIES +#undef DEBUGMENU + +//#undef NASTY_GAME +//#undef NO_CDCHECK + +#undef DRAW_GAME_VERSION_TEXT +#undef DRAW_MENU_VERSION_TEXT + +#undef GTA_PS2_STUFF +#undef USE_PS2_RAND +#undef RANDOMSPLASH +#undef PS2_MATFX + +#undef FIX_BUGS +#define THIS_IS_STUPID +#undef MORE_LANGUAGES +#undef COMPATIBLE_SAVES +#undef LOAD_INI_SETTINGS + +#undef ASPECT_RATIO_SCALE +#undef PROPER_SCALING +//#undef DEFAULT_NATIVE_RESOLUTION +#undef PS2_ALPHA_TEST +#undef IMPROVED_VIDEOMODE +#undef DISABLE_LOADING_SCREEN +#undef DISABLE_VSYNC_ON_TEXTURE_CONVERSION +#undef ANISOTROPIC_FILTERING +//#define USE_TEXTURE_POOL // not possible because R* used custom RW33 + +#undef FIX_SPRITES + +#define PC_PARTICLE + +#undef XINPUT +#undef DETECT_PAD_INPUT_SWITCH +#undef KANGAROO_CHEAT +#undef ALLCARSHELI_CHEAT +#undef ALT_DODO_CHEAT +#undef REGISTER_START_BUTTON +#undef BIND_VEHICLE_FIREWEAPON +#undef BUTTON_ICONS + +#undef HUD_ENHANCEMENTS +#undef TRIANGULAR_BLIPS +#undef FIX_RADAR +#undef RADIO_OFF_TEXT + +#undef MENU_MAP +#undef GAMEPAD_MENU +#undef SCROLLABLE_STATS_PAGE +#undef CUSTOM_FRONTEND_OPTIONS + +#undef GRAPHICS_MENU_OPTIONS +#undef NO_ISLAND_LOADING +#undef CUTSCENE_BORDERS_SWITCH +#undef MULTISAMPLING +#undef INVERT_LOOK_FOR_PAD + +#undef USE_DEBUG_SCRIPT_LOADER +#undef USE_MEASUREMENTS_IN_METERS +#undef USE_PRECISE_MEASUREMENT_CONVERTION +#undef MISSION_REPLAY +#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT +#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT + +#define DONT_FIX_REPLAY_BUGS + +#undef EXPLODING_AIRTRAIN +#undef CAMERA_PICKUP +#undef PED_SKIN +#undef ANIMATE_PED_COL_MODEL +#undef CANCELLABLE_CAR_ENTER +#undef IMPROVED_CAMERA +#undef FREE_CAM +#undef RADIO_SCROLL_TO_PREV_STATION +#undef BIG_IMG #endif diff --git a/src/core/main.cpp b/src/core/main.cpp index d34eb8f3..af0d556a 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -3,6 +3,9 @@ #include "rphanim.h" #include "rpskin.h" #include "rtbmp.h" +#ifdef ANISOTROPIC_FILTERING +#include "rpanisot.h" +#endif #include "main.h" #include "CdStream.h" @@ -66,7 +69,6 @@ #include "postfx.h" #include "custompipes.h" #include "screendroplets.h" -#include "frontendoption.h" #include "MemoryHeap.h" GlobalScene Scene; @@ -85,7 +87,7 @@ bool gbModelViewer; bool gbShowTimebars; #endif -int32 frameCount; +volatile int32 frameCount; RwRGBA gColourTop; @@ -110,8 +112,11 @@ void TheGame(void); void DebugMenuPopulate(void); #endif +#ifndef FINAL +bool gbPrintMemoryUsage; +#endif -#ifdef GTA_PS2 +#ifdef PS2_MENU #define WANT_TO_LOAD TheMemoryCard.m_bWantToLoad #define FOUND_GAME_TO_LOAD TheMemoryCard.b_FoundRecentSavedGameWantToLoad #else @@ -119,6 +124,31 @@ void DebugMenuPopulate(void); #define FOUND_GAME_TO_LOAD b_FoundRecentSavedGameWantToLoad #endif +#ifdef NEW_RENDERER +bool gbNewRenderer; +#define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL) +#else +#define CLEARMODE (rwCAMERACLEARZ) +#endif + +#ifdef __MWERKS__ +void +debug(char *fmt, ...) +{ +#ifndef MASTER + // TODO put something here +#endif +} + +void +Error(char *fmt, ...) +{ +#ifndef MASTER + // TODO put something here +#endif +} +#endif + void ValidateVersion() { @@ -166,11 +196,14 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); #endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); - RwCameraClear(Scene.camera, &TopColor.rwRGBA, rwCAMERACLEARZ); + RwCameraClear(Scene.camera, &TopColor.rwRGBA, CLEARMODE); if(!RsCameraBeginUpdate(Scene.camera)) return false; +#ifdef FIX_BUGS + CSprite2d::SetRecipNearClip(); +#endif CSprite2d::InitPerFrame(); if(Alpha != 0) @@ -188,7 +221,7 @@ DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); #endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); - RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); + RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); if(!RsCameraBeginUpdate(Scene.camera)) return false; @@ -405,6 +438,9 @@ PluginAttach(void) return FALSE; } +#ifdef ANISOTROPIC_FILTERING + RpAnisotPluginAttach(); +#endif #ifdef EXTENDED_PIPELINES CustomPipes::CustomPipeRegister(); #endif @@ -412,6 +448,63 @@ PluginAttach(void) return TRUE; } +#ifdef GTA_PS2 +#define NUM_PREALLOC_ATOMICS 3245 +#define NUM_PREALLOC_CLUMPS 101 +#define NUM_PREALLOC_FRAMES 2821 +#define NUM_PREALLOC_GEOMETRIES 1404 +#define NUM_PREALLOC_TEXDICTS 106 +#define NUM_PREALLOC_TEXTURES 1900 +#define NUM_PREALLOC_MATERIALS 3300 +bool preAlloc; + +void +PreAllocateRwObjects(void) +{ + int i; + void **tmp = new void*[0x8000]; + preAlloc = true; + + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + tmp[i] = RpAtomicCreate(); + for(i = 0; i < NUM_PREALLOC_ATOMICS; i++) + RpAtomicDestroy((RpAtomic*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + tmp[i] = RpClumpCreate(); + for(i = 0; i < NUM_PREALLOC_CLUMPS; i++) + RpClumpDestroy((RpClump*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + tmp[i] = RwFrameCreate(); + for(i = 0; i < NUM_PREALLOC_FRAMES; i++) + RwFrameDestroy((RwFrame*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + tmp[i] = RpGeometryCreate(0, 0, 0); + for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++) + RpGeometryDestroy((RpGeometry*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + tmp[i] = RwTexDictionaryCreate(); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTexDictionaryDestroy((RwTexDictionary*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_TEXTURES; i++) + tmp[i] = RwTextureCreate(RwRasterCreate(0, 0, 0, 0)); + for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++) + RwTextureDestroy((RwTexture*)tmp[i]); + + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + tmp[i] = RpMaterialCreate(); + for(i = 0; i < NUM_PREALLOC_MATERIALS; i++) + RpMaterialDestroy((RpMaterial*)tmp[i]); + + delete[] tmp; + preAlloc = false; +} +#endif + static RwBool Initialise3D(void *param) { @@ -421,21 +514,7 @@ Initialise3D(void *param) DebugMenuInit(); DebugMenuPopulate(); #endif // !DEBUGMENU -#ifdef CUSTOM_FRONTEND_OPTIONS - // Apparently this func. can be run multiple times at the start. - if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) { - // needs stored language and TheText to be loaded, and last TheText reload is at the start of here - CustomFrontendOptionsPopulate(); - } -#endif - bool ret = CGame::InitialiseRenderWare(); -#ifdef EXTENDED_PIPELINES - CustomPipes::CustomPipeInit(); // need Scene.world for this -#endif -#ifdef SCREEN_DROPLETS - ScreenDroplets::InitDraw(); -#endif - return ret; + return CGame::InitialiseRenderWare(); } return (FALSE); @@ -444,12 +523,6 @@ Initialise3D(void *param) static void Terminate3D(void) { -#ifdef SCREEN_DROPLETS - ScreenDroplets::Shutdown(); -#endif -#ifdef EXTENDED_PIPELINES - CustomPipes::CustomPipeShutdown(); -#endif CGame::ShutdownRenderWare(); #ifdef DEBUGMENU DebugMenuShutdown(); @@ -574,7 +647,12 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) return; #endif - if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)){ +#ifndef GTA_PS2 + if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)) +#else + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); +#endif + { CSprite2d::SetRecipNearClip(); CSprite2d::InitPerFrame(); CFont::InitPerFrame(); @@ -613,8 +691,10 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen) AsciiToUnicode(str1, tmpstr); CFont::PrintString(hpos, vpos, tmpstr); vpos += 22*yscale; - AsciiToUnicode(str2, tmpstr); - CFont::PrintString(hpos, vpos, tmpstr); + if (str2) { + AsciiToUnicode(str2, tmpstr); + CFont::PrintString(hpos, vpos, tmpstr); + } #endif } @@ -634,8 +714,13 @@ LoadingIslandScreen(const char *levelName) splash = LoadSplash(nil); name = TheText.Get(levelName); + +#ifndef GTA_PS2 if(!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)) return; +#else + DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255); +#endif CSprite2d::SetRecipNearClip(); CSprite2d::InitPerFrame(); @@ -644,23 +729,61 @@ LoadingIslandScreen(const char *levelName) col = CRGBA(255, 255, 255, 255); splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), col, col, col, col); CFont::SetBackgroundOff(); +#ifdef FIX_BUGS + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); +#else CFont::SetScale(1.5f, 1.5f); +#endif CFont::SetPropOn(); CFont::SetRightJustifyOn(); +#ifdef FIX_BUGS CFont::SetRightJustifyWrap(SCREEN_SCALE_X(150.0f)); +#else + CFont::SetRightJustifyWrap(150.0f); +#endif CFont::SetFontStyle(FONT_HEADING); sprintf(str, "WELCOME TO"); AsciiToUnicode(str, wstr); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetDropShadowPosition(3); CFont::SetColor(CRGBA(243, 237, 71, 255)); +#if !defined(PS2_HUD) && defined(GTA_PC) CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME")); +#endif + +#ifdef PS2_HUD + #ifdef FIX_BUGS + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(140.0f), TheText.Get("WELCOME")); + #else + CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_HEIGHT - 140, TheText.Get("WELCOME")); + #endif +#else + #ifdef FIX_BUGS + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(110.0f), TheText.Get("WELCOME")); + #else + CFont::PrintString(SCREEN_WIDTH - 20, SCREEN_SCALE_FROM_BOTTOM(110.0f), TheText.Get("WELCOME")); + #endif +#endif TextCopy(wstr, name); TheText.UpperCase(wstr); CFont::SetColor(CRGBA(243, 237, 71, 255)); +#if !defined(PS2_HUD) && defined(GTA_PC) CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr); +#endif + +#ifdef PS2_HUD + #ifdef FIX_BUGS + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(110.0f), wstr); + #else + CFont::PrintString(SCREEN_WIDTH-20, SCREEN_HEIGHT - 110, wstr); + #endif +#else + #ifdef FIX_BUGS + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(80.0f), wstr); + #else + CFont::PrintString(SCREEN_WIDTH-20, SCREEN_SCALE_FROM_BOTTOM(80.0f), wstr); + #endif +#endif CFont::DrawFonts(); DoRWStuffEndOfFrame(); } @@ -761,6 +884,7 @@ ProcessSlowMode(void) float FramesPerSecondCounter; int32 FrameSamples; +#ifndef MASTER struct tZonePrint { char name[12]; @@ -781,8 +905,6 @@ tZonePrint ZonePrint[] = { "no zone", CRect( 0.0f, 0.0f, 0.0f, 0.0f) } }; -#ifndef MASTER - void PrintMemoryUsage(void) { @@ -957,9 +1079,10 @@ DisplayGameDebugText() TWEAKBOOL(bDisplayPosn); TWEAKBOOL(bDisplayRate); } -#endif -// PrintMemoryUsage(); // TODO: put this somewhere else + if(gbPrintMemoryUsage) + PrintMemoryUsage(); +#endif char str[200]; wchar ustr[200]; @@ -979,12 +1102,21 @@ DisplayGameDebugText() CFont::SetJustifyOff(); CFont::SetBackGroundOnlyTextOff(); CFont::SetColor(CRGBA(255, 108, 0, 255)); +#ifdef FIX_BUGS CFont::PrintString(SCREEN_SCALE_X(10.0f), SCREEN_SCALE_Y(10.0f), ver); +#else + CFont::PrintString(10.0f, 10.0f, ver); #endif +#endif // #ifdef DRAW_GAME_VERSION_TEXT FrameSamples++; +#ifdef FIX_BUGS + FramesPerSecondCounter += frameTime / 1000.f; // convert to seconds + FramesPerSecond = FrameSamples / FramesPerSecondCounter; +#else FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f); FramesPerSecond = FramesPerSecondCounter / FrameSamples; +#endif if ( FrameSamples > 30 ) { @@ -1031,29 +1163,161 @@ DisplayGameDebugText() AsciiToUnicode(str, ustr); - // Let's not scale those numbers, they look better that way :eyes: CFont::SetPropOff(); CFont::SetBackgroundOff(); +#ifdef FIX_BUGS + CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(1.5f)); +#else CFont::SetScale(0.7f, 1.5f); +#endif CFont::SetCentreOff(); CFont::SetRightJustifyOff(); CFont::SetJustifyOff(); CFont::SetBackGroundOnlyTextOff(); +#ifdef FIX_BUGS CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH)); +#else + CFont::SetWrapx(DEFAULT_SCREEN_WIDTH); +#endif CFont::SetFontStyle(FONT_HEADING); CFont::SetColor(CRGBA(0, 0, 0, 255)); - CFont::PrintString(42.0f, 42.0f, ustr); +#ifdef FIX_BUGS + CFont::PrintString(SCREEN_SCALE_X(40.0f+2.0f), SCREEN_SCALE_Y(40.0f+2.0f), ustr); +#else + CFont::PrintString(40.0f+2.0f, 40.0f+2.0f, ustr); +#endif CFont::SetColor(CRGBA(255, 108, 0, 255)); +#ifdef FIX_BUGS + CFont::PrintString(SCREEN_SCALE_X(40.0f), SCREEN_SCALE_Y(40.0f), ustr); +#else CFont::PrintString(40.0f, 40.0f, ustr); +#endif + } +} +#endif + +#ifdef NEW_RENDERER +bool gbRenderRoads = true; +bool gbRenderEverythingBarRoads = true; +//bool gbRenderFadingInUnderwaterEntities = true; +bool gbRenderFadingInEntities = true; +bool gbRenderWater = true; +bool gbRenderBoats = true; +bool gbRenderVehicles = true; +bool gbRenderWorld0 = true; +bool gbRenderWorld1 = true; +bool gbRenderWorld2 = true; + +void +MattRenderScene(void) +{ + // this calls CMattRenderer::Render + /// CWorld::AdvanceCurrentScanCode(); + // CMattRenderer::ResetRenderStates + /// CRenderer::ClearForFrame(); // before ConstructRenderList + // CClock::CalcEnvMapTimeMultiplicator +if(gbRenderWater) + CRenderer::RenderWater(); // actually CMattRenderer::RenderWater + // CClock::ms_EnvMapTimeMultiplicator = 1.0f; + // cWorldStream::ClearDynamics + /// CRenderer::ConstructRenderList(); // before PreRender +if(gbRenderWorld0) + CRenderer::RenderWorld(0); // roads + // CMattRenderer::ResetRenderStates + /// CRenderer::PreRender(); // has to be called before BeginUpdate because of cutscene shadows + CCoronas::RenderReflections(); +if(gbRenderWorld1) + CRenderer::RenderWorld(1); // opaque +if(gbRenderRoads) + CRenderer::RenderRoads(); + + CRenderer::RenderPeds(); + +if(gbRenderBoats) + CRenderer::RenderBoats(); +//if(gbRenderFadingInUnderwaterEntities) +// CRenderer::RenderFadingInUnderwaterEntities(); + +if(gbRenderEverythingBarRoads) + CRenderer::RenderEverythingBarRoads(); + // seam fixer + // moved this: + // CRenderer::RenderFadingInEntities(); +} + +void +RenderScene_new(void) +{ + CClouds::Render(); + DoRWRenderHorizon(); + + MattRenderScene(); + DefinedState(); + // CMattRenderer::ResetRenderStates + // moved CRenderer::RenderBoats to before transparent water +} + +// TODO +bool FredIsInFirstPersonCam(void) { return false; } +void +RenderEffects_new(void) +{ + CShadows::RenderStaticShadows(); + // CRenderer::GenerateEnvironmentMap + CShadows::RenderStoredShadows(); + CSkidmarks::Render(); + CRubbish::Render(); + + // these aren't really effects + DefinedState(); + if(FredIsInFirstPersonCam()){ + DefinedState(); + C3dMarkers::Render(); // normally rendered in CSpecialFX::Render() +if(gbRenderWorld2) + CRenderer::RenderWorld(2); // transparent +if(gbRenderVehicles) + CRenderer::RenderVehicles(); + }else{ + // flipped these two, seems to give the best result +if(gbRenderWorld2) + CRenderer::RenderWorld(2); // transparent +if(gbRenderVehicles) + CRenderer::RenderVehicles(); } + // better render these after transparent world +if(gbRenderFadingInEntities) + CRenderer::RenderFadingInEntities(); + + // actual effects here + CGlass::Render(); + // CMattRenderer::ResetRenderStates + DefinedState(); + CWeather::RenderRainStreaks(); + // CWeather::AddSnow + CWaterCannons::Render(); + CAntennas::Render(); + CSpecialFX::Render(); + CCoronas::Render(); + CParticle::Render(); + CPacManPickups::Render(); + CWeaponEffects::Render(); + CPointLights::RenderFogEffect(); + CMovingThings::Render(); + CRenderer::RenderFirstPersonVehicle(); } #endif void RenderScene(void) { +#ifdef NEW_RENDERER + if(gbNewRenderer){ + RenderScene_new(); + return; + } +#endif CClouds::Render(); DoRWRenderHorizon(); CRenderer::RenderRoads(); @@ -1086,6 +1350,12 @@ RenderDebugShit(void) void RenderEffects(void) { +#ifdef NEW_RENDERER + if(gbNewRenderer){ + RenderEffects_new(); + return; + } +#endif CGlass::Render(); CWaterCannons::Render(); CSpecialFX::Render(); @@ -1155,9 +1425,11 @@ Render2dStuff(void) MusicManager.DisplayRadioStationName(); TheConsole.Display(); +#ifdef GTA_SCENE_EDIT if(CSceneEdit::m_bEditOn) CSceneEdit::Draw(); else +#endif CHud::Draw(); CUserDisplay::OnscnTimer.ProcessForDisplay(); CMessages::Display(); @@ -1267,8 +1539,8 @@ Idle(void *arg) if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) && TheCamera.GetScreenFadeStatus() != FADE_2) { +#if defined(GTA_PC) && !defined(RW_GL3) && defined(FIX_BUGS) // This is from SA, but it's nice for windowed mode -#if defined(GTA_PC) && !defined(RW_GL3) if (!FrontEndMenuManager.m_bRenderGameInMenu) { RwV2d pos; pos.x = SCREEN_WIDTH / 2.0f; @@ -1279,6 +1551,12 @@ Idle(void *arg) PUSH_MEMID(MEMID_RENDERLIST); tbStartTimer(0, "CnstrRenderList"); +#ifdef NEW_RENDERER + if(gbNewRenderer){ + CWorld::AdvanceCurrentScanCode(); // don't think this is even necessary + CRenderer::ClearForFrame(); + } +#endif CRenderer::ConstructRenderList(); tbEndTimer("CnstrRenderList"); @@ -1346,7 +1624,7 @@ Idle(void *arg) CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO); #endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); - RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); + RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); if(!RsCameraBeginUpdate(Scene.camera)) goto popret; } @@ -1412,7 +1690,7 @@ FrontendIdle(void) CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO); #endif CVisibilityPlugins::SetRenderWareCamera(Scene.camera); - RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ); + RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); if(!RsCameraBeginUpdate(Scene.camera)) return; @@ -1507,15 +1785,6 @@ AppEventHandler(RsEvent event, void *param) return rsEVENTPROCESSED; } -#ifndef MASTER - case rsANIMVIEWER: - { - TheModelViewer(); - - return rsEVENTPROCESSED; - } -#endif - default: { return rsEVENTNOTPROCESSED; @@ -1530,8 +1799,11 @@ TheModelViewer(void) #if (defined(GTA_PS2) || defined(GTA_XBOX)) //TODO #else + // This is III Mobile code. III Xbox code run it like main function, which is impossible to implement on PC's state machine implementation. + // Also we want 2D things initialized in here to print animation ids etc., our additions for that marked with X + #ifdef ASPECT_RATIO_SCALE - CDraw::SetAspectRatio(CDraw::FindAspectRatio()); + CDraw::SetAspectRatio(CDraw::FindAspectRatio()); // X #endif CAnimViewer::Update(); CTimer::Update(); @@ -1541,12 +1813,12 @@ TheModelViewer(void) CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255); - CSprite2d::InitPerFrame(); - CFont::InitPerFrame(); + CSprite2d::InitPerFrame(); // X + CFont::InitPerFrame(); // X DefinedState(); CVisibilityPlugins::InitAlphaEntityList(); CAnimViewer::Render(); - Render2dStuff(); + Render2dStuff(); // X DoRWStuffEndOfFrame(); #endif } @@ -1562,7 +1834,7 @@ void TheGame(void) CTimer::Initialise(); -#ifdef GTA_PS2 +#if GTA_VERSION <= GTA3_PS2_160 CGame::Initialise(); #else CGame::Initialise("DATA\\GTA3.DAT"); @@ -1632,7 +1904,7 @@ void TheGame(void) PUSH_MEMID(MEMID_RENDER); - if (!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true && TheCamera.GetScreenFadeStatus() != FADE_2 ) + if ((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true) && TheCamera.GetScreenFadeStatus() != FADE_2 ) { PUSH_MEMID(MEMID_RENDERLIST); @@ -1640,14 +1912,22 @@ void TheGame(void) CRenderer::PreRender(); POP_MEMID(); +#ifdef FIX_BUGS + // This has to be done BEFORE RwCameraBeginUpdate + RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); + RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); +#endif + if (CWeather::LightningFlash && !CCullZones::CamNoRain()) DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255); else DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255); DefinedState(); +#ifndef FIX_BUGS RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip()); RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart()); +#endif RenderScene(); RenderDebugShit(); @@ -1661,11 +1941,14 @@ void TheGame(void) } else { - CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO); +#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)) - break; + RwCameraClear(Scene.camera, &gColourTop, CLEARMODE); + RsCameraBeginUpdate(Scene.camera); } RenderMenus(); @@ -1759,7 +2042,7 @@ void SystemInit() #ifdef GTA_PS2 CFileMgr::InitCd(); - Char modulepath[256]; + char modulepath[256]; strcpy(modulepath, "cdrom0:\\"); strcat(modulepath, "SYSTEM\\"); @@ -1851,6 +2134,20 @@ void SystemInit() #endif } +int VBlankCounter(int ca) +{ + frameCount++; + ExitHandler(); + return 0; +} + +// linked against by RW! +extern "C" void WaitVBlank(void) +{ + int32 startFrame = frameCount; + while(startFrame == frameCount); +} + void GameInit() { if ( !gameAlreadyInitialised ) @@ -1894,11 +2191,16 @@ void GameInit() "\\MODELS\\MISC.TXD;1", "\\MODELS\\GENERIC.TXD;1", "\\MODELS\\GTA3.DIR;1", + // TODO: japanese? +#ifdef GTA_PAL "\\TEXT\\ENGLISH.GXT;1", "\\TEXT\\FRENCH.GXT;1", "\\TEXT\\GERMAN.GXT;1", "\\TEXT\\ITALIAN.GXT;1", "\\TEXT\\SPANISH.GXT;1", +#else + "\\TEXT\\AMERICAN.GXT;1", +#endif "\\TXD\\LOADSC0.TXD;1", "\\TXD\\LOADSC1.TXD;1", "\\TXD\\LOADSC2.TXD;1", @@ -1982,7 +2284,7 @@ void GameInit() CreateDebugFont(); #ifdef GTA_PS2 - AddIntcHandler(_TODOCONST(2), VBlankCounter, 0); + AddIntcHandler(INTC_VBLANK_S, VBlankCounter, 0); #endif CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO); @@ -2012,6 +2314,36 @@ void GameInit() } } +void PlayIntroMPEGs() +{ +#ifdef GTA_PS2 + if (gameAlreadyInitialised) + RpSkySuspend(); + + InitMPEGPlayer(); + +#ifdef GTA_PAL + PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false); + + if (CGame::frenchGame || CGame::germanGame) + PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true); + else + PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true); +#else + PlayMPEG("cdrom0:\\MOVIES\\DMANTSC.PSS;1", false); + + PlayMPEG("cdrom0:\\MOVIES\\INTRNTSC.PSS;1", true); +#endif + + ShutdownMPEGPlayer(); + + if ( gameAlreadyInitialised ) + RpSkyResume(); +#else + //TODO +#endif +} + int main(int argc, char *argv[]) { @@ -2024,8 +2356,7 @@ main(int argc, char *argv[]) #ifdef GTA_PS2 int32 r = TheMemoryCard.CheckCardStateAtGameStartUp(CARD_ONE); - if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT - && r != CMemoryCard::ERR_OPENNOENTRY && r != CMemoryCard::ERR_NONE ) + if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT ) { GameInit(); @@ -2035,31 +2366,12 @@ main(int argc, char *argv[]) CFont::Initialise(); FrontEndMenuManager.DrawMemoryCardStartUpMenus(); + }else if(r == CMemoryCard::ERR_OPENNOENTRY || r == CMemoryCard::ERR_NONE){ + // eh? } #endif - -#ifdef GTA_PS2 - { - if (gameAlreadyInitialised) - RpSkySuspend(); - - InitMPEGPlayer(); - - PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false); - - if (CGame::frenchGame || CGame::germanGame) - PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true); - else - PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true); - - ShutdownMPEGPlayer(); - if ( gameAlreadyInitialised ) - RpSkyResume(); - } -#else - //TODO -#endif + PlayIntroMPEGs(); GameInit(); diff --git a/src/core/main.h b/src/core/main.h index 13fff447..9f181101 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -20,11 +20,16 @@ extern bool gbShowTimebars; #define gbShowTimebars false #endif +#ifndef FINAL +extern bool gbPrintMemoryUsage; +#endif + class CSprite2d; bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); +void PreAllocateRwObjects(void); void InitialiseGame(void); void LoadingScreen(const char *str1, const char *str2, const char *splashscreen); void LoadingIslandScreen(const char *levelName); @@ -40,6 +45,13 @@ void TheModelViewer(void); #endif #ifdef LOAD_INI_SETTINGS -void LoadINISettings(); +bool LoadINISettings(); void SaveINISettings(); +void LoadINIControllerSettings(); +void SaveINIControllerSettings(); +#endif + +#ifdef NEW_RENDERER +extern bool gbNewRenderer; +bool FredIsInFirstPersonCam(void); #endif diff --git a/src/core/re3.cpp b/src/core/re3.cpp index ee747218..62d963ca 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -1,7 +1,6 @@ #include <csignal> #define WITHWINDOWS #include "common.h" -#include "crossplatform.h" #include "Renderer.h" #include "Credits.h" #include "Camera.h" @@ -29,10 +28,14 @@ #include "Script.h" #include "postfx.h" #include "custompipes.h" - -#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +#include "MemoryHeap.h" #include "FileMgr.h" +#include "Camera.h" +#include "MBlur.h" #include "ControllerConfig.h" + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +#include "crossplatform.h" #endif #ifndef _WIN32 @@ -78,6 +81,30 @@ void CustomFrontendOptionsPopulate(void) { // Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h + + // These work only if we have neo folder, so they're dynamically added +#ifdef EXTENDED_PIPELINES + const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" }; + const char *off_on[] = { "FEM_OFF", "FEM_ON" }; + int fd = CFileMgr::OpenFile("neo/neo.txd","r"); + if (fd) { +#ifdef GRAPHICS_MENU_OPTIONS + FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false); + FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline"); + FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight"); + FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps"); + FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss"); +#else + FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false); + FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline"); + FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight"); + FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps"); + FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss"); +#endif + CFileMgr::CloseFile(fd); + } +#endif + } #endif @@ -85,82 +112,307 @@ CustomFrontendOptionsPopulate(void) #include "ini_parser.hpp" linb::ini cfg; -int CheckAndReadIniInt(const char *cat, const char *key, int original) +bool ReadIniIfExists(const char *cat, const char *key, uint32 *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtoul(value, &endPtr, 0); + return true; + } + return false; +} + +bool ReadIniIfExists(const char *cat, const char *key, bool *out) { - std::string strval = cfg.get(cat, key, ""); + std::string strval = cfg.get(cat, key, "\xBA"); const char *value = strval.c_str(); - if (value && value[0] != '\0') - return atoi(value); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtoul(value, &endPtr, 0); + return true; + } + return false; +} - return original; +bool ReadIniIfExists(const char *cat, const char *key, int32 *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtol(value, &endPtr, 0); + return true; + } + return false; } -float CheckAndReadIniFloat(const char *cat, const char *key, float original) +bool ReadIniIfExists(const char *cat, const char *key, int8 *out) { - std::string strval = cfg.get(cat, key, ""); + std::string strval = cfg.get(cat, key, "\xBA"); const char *value = strval.c_str(); - if (value && value[0] != '\0') - return atof(value); + char *endPtr; + if (value && value[0] != '\xBA') { + *out = strtol(value, &endPtr, 0); + return true; + } + return false; +} - return original; +bool ReadIniIfExists(const char *cat, const char *key, float *out) +{ + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + if (value && value[0] != '\xBA') { + *out = atof(value); + return true; + } + return false; } -void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed) +bool ReadIniIfExists(const char *cat, const char *key, char *out, int size) { - char temp[10]; - if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it - changed = true; - sprintf(temp, "%u", val); - cfg.set(cat, key, temp); + std::string strval = cfg.get(cat, key, "\xBA"); + const char *value = strval.c_str(); + if (value && value[0] != '\xBA') { + strncpy(out, value, size); + return true; } + return false; } -void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed) +void StoreIni(const char *cat, const char *key, uint32 val) { char temp[10]; - if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it - changed = true; - sprintf(temp, "%f", val); - cfg.set(cat, key, temp); - } + sprintf(temp, "%u", val); + cfg.set(cat, key, temp); } -void LoadINISettings() +void StoreIni(const char *cat, const char *key, uint8 val) { - cfg.load_file("re3.ini"); + char temp[10]; + sprintf(temp, "%u", (uint32)val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, int32 val) +{ + char temp[10]; + sprintf(temp, "%d", val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, int8 val) +{ + char temp[10]; + sprintf(temp, "%d", (int32)val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, float val) +{ + char temp[10]; + sprintf(temp, "%f", val); + cfg.set(cat, key, temp); +} + +void StoreIni(const char *cat, const char *key, char *val, int size) +{ + cfg.set(cat, key, val); +} + +const char *iniControllerActions[] = { "PED_FIREWEAPON", "PED_CYCLE_WEAPON_RIGHT", "PED_CYCLE_WEAPON_LEFT", "GO_FORWARD", "GO_BACK", "GO_LEFT", "GO_RIGHT", "PED_SNIPER_ZOOM_IN", + "PED_SNIPER_ZOOM_OUT", "VEHICLE_ENTER_EXIT", "CAMERA_CHANGE_VIEW_ALL_SITUATIONS", "PED_JUMPING", "PED_SPRINT", "PED_LOOKBEHIND", +#ifdef BIND_VEHICLE_FIREWEAPON + "VEHICLE_FIREWEAPON", +#endif + "VEHICLE_ACCELERATE", "VEHICLE_BRAKE", "VEHICLE_CHANGE_RADIO_STATION", "VEHICLE_HORN", "TOGGLE_SUBMISSIONS", "VEHICLE_HANDBRAKE", "PED_1RST_PERSON_LOOK_LEFT", + "PED_1RST_PERSON_LOOK_RIGHT", "VEHICLE_LOOKLEFT", "VEHICLE_LOOKRIGHT", "VEHICLE_LOOKBEHIND", "VEHICLE_TURRETLEFT", "VEHICLE_TURRETRIGHT", "VEHICLE_TURRETUP", "VEHICLE_TURRETDOWN", + "PED_CYCLE_TARGET_LEFT", "PED_CYCLE_TARGET_RIGHT", "PED_CENTER_CAMERA_BEHIND_PLAYER", "PED_LOCK_TARGET", "NETWORK_TALK", "PED_1RST_PERSON_LOOK_UP", "PED_1RST_PERSON_LOOK_DOWN", + "_CONTROLLERACTION_36", "TOGGLE_DPAD", "SWITCH_DEBUG_CAM_ON", "TAKE_SCREEN_SHOT", "SHOW_MOUSE_POINTER_TOGGLE" }; + +const char *iniControllerTypes[] = { "kbd:", "2ndKbd:", "mouse:", "joy:" }; +const char *iniMouseButtons[] = {"LEFT","MIDDLE","RIGHT","WHLUP","WHLDOWN","X1","X2"}; + +const char *iniKeyboardButtons[] = {"ESC","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12", + "INS","DEL","HOME","END","PGUP","PGDN","UP","DOWN","LEFT","RIGHT","DIVIDE","TIMES","PLUS","MINUS","PADDEL", + "PADEND","PADDOWN","PADPGDN","PADLEFT","PAD5","NUMLOCK","PADRIGHT","PADHOME","PADUP","PADPGUP","PADINS", + "PADENTER", "SCROLL","PAUSE","BACKSP","TAB","CAPSLK","ENTER","LSHIFT","RSHIFT","SHIFT","LCTRL","RCTRL","LALT", + "RALT", "LWIN", "RWIN", "APPS", "NULL"}; + +void LoadINIControllerSettings() +{ #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS - // Written by assuming the codes below will run after _InputInitialiseJoys(). - strcpy(gSelectedJoystickName, cfg.get("DetectJoystick", "JoystickName", "").c_str()); - - if(gSelectedJoystickName[0] != '\0') { - for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { - if (glfwJoystickPresent(i) && strncmp(gSelectedJoystickName, glfwGetJoystickName(i), strlen(gSelectedJoystickName)) == 0) { - if (PSGLOBAL(joy1id) != -1) { - PSGLOBAL(joy2id) = PSGLOBAL(joy1id); + ReadIniIfExists("Controller", "JoystickName", gSelectedJoystickName, 128); +#endif + // force to default GTA behaviour (never overwrite bindings on joy change/initialization) if user init'ed/set bindings before we introduced that + if (!ReadIniIfExists("Controller", "PadButtonsInited", &ControlsManager.ms_padButtonsInited)) { + ControlsManager.ms_padButtonsInited = cfg.category_size("Bindings") != 0 ? 16 : 0; + } + + for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) { + char value[128]; + if (ReadIniIfExists("Bindings", iniControllerActions[i], value, 128)) { + for (int32 j = 0; j < MAX_CONTROLLERTYPES; j++){ + ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)i, (eControllerType)j); + } + + for (char *binding = strtok(value,", "); binding != nil; binding = strtok(nil, ", ")) { + int contType = -1; + for (int32 k = 0; k < ARRAY_SIZE(iniControllerTypes); k++) { + int len = strlen(iniControllerTypes[k]); + if (strncmp(binding, iniControllerTypes[k], len) == 0) { + contType = k; + binding += len; + break; + } + } + if (contType == -1) + continue; + + int contKey; + if (contType == JOYSTICK) { + char *temp; + contKey = strtol(binding, &temp, 0); + + } else if (contType == KEYBOARD || contType == OPTIONAL_EXTRA) { + if (strlen(binding) == 1) { + contKey = binding[0]; + } else if(strcmp(binding, "SPC") == 0) { + contKey = ' '; + } else { + for (int32 k = 0; k < ARRAY_SIZE(iniKeyboardButtons); k++) { + if(strcmp(binding, iniKeyboardButtons[k]) == 0) { + contKey = 1000 + k; + break; + } + } + } + } else if (contType == MOUSE) { + for (int32 k = 0; k < ARRAY_SIZE(iniMouseButtons); k++) { + if(strcmp(binding, iniMouseButtons[k]) == 0) { + contKey = 1 + k; + break; + } + } } - PSGLOBAL(joy1id) = i; - int count; - glfwGetJoystickButtons(PSGLOBAL(joy1id), &count); - // We need to init and reload bindings, because; - // 1-joypad button number may differ with saved/prvly connected one - // 2-bindings are not init'ed if there is no joypad at the start - ControlsManager.InitDefaultControlConfigJoyPad(count); - CFileMgr::SetDirMyDocuments(); - int32 gta3set = CFileMgr::OpenFile("gta3.set", "r"); - if (gta3set) { - ControlsManager.LoadSettings(gta3set); - CFileMgr::CloseFile(gta3set); + ControlsManager.SetControllerKeyAssociatedWithAction((e_ControllerAction)i, contKey, (eControllerType)contType); + } + } + } +} + +void SaveINIControllerSettings() +{ + for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) { + char value[128] = { '\0' }; + + // upper limit should've been GetNumOfSettingsForAction(i), but sadly even R* doesn't use it's own system correctly, and there are gaps between orders. + for (int32 j = SETORDER_1; j < MAX_SETORDERS; j++){ + + // We respect the m_ContSetOrder, and join/implode/order the bindings according to that; using comma as seperator. + for (int32 k = 0; k < MAX_CONTROLLERTYPES; k++){ + if (ControlsManager.m_aSettings[i][k].m_ContSetOrder == j) { + char next[32]; + if (k == JOYSTICK) { + snprintf(next, 32, "%s%d,", iniControllerTypes[k], ControlsManager.m_aSettings[i][k].m_Key); + + } else if (k == KEYBOARD || k == OPTIONAL_EXTRA) { + if (ControlsManager.m_aSettings[i][k].m_Key == ' ') + snprintf(next, 32, "%sSPC,", iniControllerTypes[k]); + else if (ControlsManager.m_aSettings[i][k].m_Key < 256) + snprintf(next, 32, "%s%c,", iniControllerTypes[k], ControlsManager.m_aSettings[i][k].m_Key); + else + snprintf(next, 32, "%s%s,", iniControllerTypes[k], iniKeyboardButtons[ControlsManager.m_aSettings[i][k].m_Key - 1000]); + + } else if (k == MOUSE) { + snprintf(next, 32, "%s%s,", iniControllerTypes[k], iniMouseButtons[ControlsManager.m_aSettings[i][k].m_Key - 1]); + } + strcat(value, next); + break; } - CFileMgr::SetDir(""); - break; } } + int len = strlen(value); + if (len > 0) + value[len - 1] = '\0'; // to remove comma + + StoreIni("Bindings", iniControllerActions[i], value, 128); } + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + StoreIni("Controller", "JoystickName", gSelectedJoystickName, 128); +#endif + StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited); + cfg.write_file("re3.ini"); +} + +bool LoadINISettings() +{ + if (!cfg.load_file("re3.ini")) + return false; + +#ifdef IMPROVED_VIDEOMODE + ReadIniIfExists("VideoMode", "Width", &FrontEndMenuManager.m_nPrefsWidth); + ReadIniIfExists("VideoMode", "Height", &FrontEndMenuManager.m_nPrefsHeight); + ReadIniIfExists("VideoMode", "Depth", &FrontEndMenuManager.m_nPrefsDepth); + ReadIniIfExists("VideoMode", "Subsystem", &FrontEndMenuManager.m_nPrefsSubsystem); + // Windowed mode is loaded below in CUSTOM_FRONTEND_OPTIONS section +#else + ReadIniIfExists("Graphics", "VideoMode", &FrontEndMenuManager.m_nDisplayVideoMode); +#endif + ReadIniIfExists("Controller", "HeadBob1stPerson", &TheCamera.m_bHeadBob); + ReadIniIfExists("Controller", "VerticalMouseSens", &TheCamera.m_fMouseAccelVertical); + ReadIniIfExists("Controller", "HorizantalMouseSens", &TheCamera.m_fMouseAccelHorzntl); + ReadIniIfExists("Controller", "InvertMouseVertically", &MousePointerStateHelper.bInvertVertically); + ReadIniIfExists("Controller", "DisableMouseSteering", &CVehicle::m_bDisableMouseSteering); + ReadIniIfExists("Controller", "Vibration", &FrontEndMenuManager.m_PrefsUseVibration); + ReadIniIfExists("Audio", "SfxVolume", &FrontEndMenuManager.m_PrefsSfxVolume); + ReadIniIfExists("Audio", "MusicVolume", &FrontEndMenuManager.m_PrefsMusicVolume); + ReadIniIfExists("Audio", "Radio", &FrontEndMenuManager.m_PrefsRadioStation); + ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers); + ReadIniIfExists("Audio", "Provider", &FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); + ReadIniIfExists("Audio", "DynamicAcoustics", &FrontEndMenuManager.m_PrefsDMA); + ReadIniIfExists("Display", "Brightness", &FrontEndMenuManager.m_PrefsBrightness); + ReadIniIfExists("Display", "DrawDistance", &FrontEndMenuManager.m_PrefsLOD); + ReadIniIfExists("Display", "Subtitles", &FrontEndMenuManager.m_PrefsShowSubtitles); + ReadIniIfExists("Graphics", "AspectRatio", &FrontEndMenuManager.m_PrefsUseWideScreen); + ReadIniIfExists("Graphics", "VSync", &FrontEndMenuManager.m_PrefsVsyncDisp); + ReadIniIfExists("Graphics", "FrameLimiter", &FrontEndMenuManager.m_PrefsFrameLimiter); + ReadIniIfExists("Graphics", "Trails", &CMBlur::BlurOn); + ReadIniIfExists("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256); + ReadIniIfExists("Controller", "Method", &FrontEndMenuManager.m_ControlMethod); + ReadIniIfExists("General", "Language", &FrontEndMenuManager.m_PrefsLanguage); + +#ifdef EXTENDED_COLOURFILTER + ReadIniIfExists("CustomPipesValues", "PostFXIntensity", &CPostFX::Intensity); +#endif +#ifdef EXTENDED_PIPELINES + ReadIniIfExists("CustomPipesValues", "NeoVehicleShininess", &CustomPipes::VehicleShininess); + ReadIniIfExists("CustomPipesValues", "NeoVehicleSpecularity", &CustomPipes::VehicleSpecularity); + ReadIniIfExists("CustomPipesValues", "RimlightMult", &CustomPipes::RimlightMult); + ReadIniIfExists("CustomPipesValues", "LightmapMult", &CustomPipes::LightmapMult); + ReadIniIfExists("CustomPipesValues", "GlossMult", &CustomPipes::GlossMult); +#endif +#ifdef NEW_RENDERER + ReadIniIfExists("Rendering", "NewRenderer", &gbNewRenderer); +#endif + +#ifdef PROPER_SCALING + ReadIniIfExists("Draw", "ProperScaling", &CDraw::ms_bProperScaling); +#endif +#ifdef FIX_RADAR + ReadIniIfExists("Draw", "FixRadar", &CDraw::ms_bFixRadar); +#endif +#ifdef FIX_SPRITES + ReadIniIfExists("Draw", "FixSprites", &CDraw::ms_bFixSprites); #endif #ifdef CUSTOM_FRONTEND_OPTIONS + bool migrate = cfg.category_size("FrontendOptions") != 0; for (int i = 0; i < MENUPAGES; i++) { for (int j = 0; j < NUM_MENUROWS; j++) { CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; @@ -170,7 +422,13 @@ void LoadINISettings() // CFO check if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { // CFO only supports saving uint8 right now - *option.m_CFO->value = CheckAndReadIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value); + + // Migrate from old .ini to new .ini + if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, option.m_CFO->value)) + cfg.remove("FrontendOptions", option.m_CFO->save); + else + ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value); + if (option.m_Action == MENUACTION_CFO_SELECT) { option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value; } @@ -179,28 +437,65 @@ void LoadINISettings() } #endif -#ifdef EXTENDED_COLOURFILTER - CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity); -#endif -#ifdef EXTENDED_PIPELINES - CustomPipes::VehicleShininess = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess); - CustomPipes::VehicleSpecularity = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity); - CustomPipes::RimlightMult = CheckAndReadIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult); - CustomPipes::LightmapMult = CheckAndReadIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult); - CustomPipes::GlossMult = CheckAndReadIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult); -#endif + return true; } void SaveINISettings() { - bool changed = false; - char temp[4]; +#ifdef IMPROVED_VIDEOMODE + StoreIni("VideoMode", "Width", FrontEndMenuManager.m_nPrefsWidth); + StoreIni("VideoMode", "Height", FrontEndMenuManager.m_nPrefsHeight); + StoreIni("VideoMode", "Depth", FrontEndMenuManager.m_nPrefsDepth); + StoreIni("VideoMode", "Subsystem", FrontEndMenuManager.m_nPrefsSubsystem); + // Windowed mode is loaded below in CUSTOM_FRONTEND_OPTIONS section +#else + StoreIni("Graphics", "VideoMode", FrontEndMenuManager.m_nDisplayVideoMode); +#endif + StoreIni("Controller", "HeadBob1stPerson", TheCamera.m_bHeadBob); + StoreIni("Controller", "VerticalMouseSens", TheCamera.m_fMouseAccelVertical); + StoreIni("Controller", "HorizantalMouseSens", TheCamera.m_fMouseAccelHorzntl); + StoreIni("Controller", "InvertMouseVertically", MousePointerStateHelper.bInvertVertically); + StoreIni("Controller", "DisableMouseSteering", CVehicle::m_bDisableMouseSteering); + StoreIni("Controller", "Vibration", FrontEndMenuManager.m_PrefsUseVibration); + StoreIni("Audio", "SfxVolume", FrontEndMenuManager.m_PrefsSfxVolume); + StoreIni("Audio", "MusicVolume", FrontEndMenuManager.m_PrefsMusicVolume); + StoreIni("Audio", "Radio", FrontEndMenuManager.m_PrefsRadioStation); + StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers); + StoreIni("Audio", "Provider", FrontEndMenuManager.m_nPrefsAudio3DProviderIndex); + StoreIni("Audio", "DynamicAcoustics", FrontEndMenuManager.m_PrefsDMA); + StoreIni("Display", "Brightness", FrontEndMenuManager.m_PrefsBrightness); + StoreIni("Display", "DrawDistance", FrontEndMenuManager.m_PrefsLOD); + StoreIni("Display", "Subtitles", FrontEndMenuManager.m_PrefsShowSubtitles); + StoreIni("Graphics", "AspectRatio", FrontEndMenuManager.m_PrefsUseWideScreen); + StoreIni("Graphics", "VSync", FrontEndMenuManager.m_PrefsVsyncDisp); + StoreIni("Graphics", "FrameLimiter", FrontEndMenuManager.m_PrefsFrameLimiter); + StoreIni("Graphics", "Trails", CMBlur::BlurOn); + StoreIni("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256); + StoreIni("Controller", "Method", FrontEndMenuManager.m_ControlMethod); + StoreIni("General", "Language", FrontEndMenuManager.m_PrefsLanguage); -#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS - if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) { - changed = true; - cfg.set("DetectJoystick", "JoystickName", gSelectedJoystickName); - } +#ifdef EXTENDED_COLOURFILTER + StoreIni("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity); +#endif +#ifdef EXTENDED_PIPELINES + StoreIni("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess); + StoreIni("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity); + StoreIni("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult); + StoreIni("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult); + StoreIni("CustomPipesValues", "GlossMult", CustomPipes::GlossMult); +#endif +#ifdef NEW_RENDERER + StoreIni("Rendering", "NewRenderer", gbNewRenderer); +#endif + +#ifdef PROPER_SCALING + StoreIni("Draw", "ProperScaling", CDraw::ms_bProperScaling); +#endif +#ifdef FIX_RADAR + StoreIni("Draw", "FixRadar", CDraw::ms_bFixRadar); +#endif +#ifdef FIX_SPRITES + StoreIni("Draw", "FixSprites", CDraw::ms_bFixSprites); #endif #ifdef CUSTOM_FRONTEND_OPTIONS for (int i = 0; i < MENUPAGES; i++) { @@ -211,25 +506,13 @@ void SaveINISettings() if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { // Beware: CFO only supports saving uint8 right now - CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed); + StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *option.m_CFO->value); } } } #endif -#ifdef EXTENDED_COLOURFILTER - CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed); -#endif -#ifdef EXTENDED_PIPELINES - CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed); - CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed); - CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed); - CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed); - CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed); -#endif - - if (changed) - cfg.write_file("re3.ini"); + cfg.write_file("re3.ini"); } #endif @@ -383,6 +666,10 @@ SwitchToMission(void) } #endif +#ifdef USE_CUSTOM_ALLOCATOR +static void ParseHeap(void) { gMainHeap.ParseHeap(); } +#endif + 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", @@ -405,7 +692,7 @@ void CTweakVars::Add(CTweakVar *var) TweakVarsListSize = 0; } if(TweakVarsListSize > 63) - TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(var)); + TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(CTweakVar*)); TweakVarsList[TweakVarsListSize++] = var; // TweakVarsList.push_back(var); @@ -530,6 +817,30 @@ DebugMenuPopulate(void) DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil); DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil); DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil); +#ifdef NEW_RENDERER + DebugMenuAddVarBool8("Render", "new renderer", &gbNewRenderer, nil); +extern bool gbRenderRoads; +extern bool gbRenderEverythingBarRoads; +//extern bool gbRenderFadingInUnderwaterEntities; +extern bool gbRenderFadingInEntities; +extern bool gbRenderWater; +extern bool gbRenderBoats; +extern bool gbRenderVehicles; +extern bool gbRenderWorld0; +extern bool gbRenderWorld1; +extern bool gbRenderWorld2; + DebugMenuAddVarBool8("Render", "gbRenderRoads", &gbRenderRoads, nil); + DebugMenuAddVarBool8("Render", "gbRenderEverythingBarRoads", &gbRenderEverythingBarRoads, nil); +// DebugMenuAddVarBool8("Render", "gbRenderFadingInUnderwaterEntities", &gbRenderFadingInUnderwaterEntities, nil); + DebugMenuAddVarBool8("Render", "gbRenderFadingInEntities", &gbRenderFadingInEntities, nil); + DebugMenuAddVarBool8("Render", "gbRenderWater", &gbRenderWater, nil); + DebugMenuAddVarBool8("Render", "gbRenderBoats", &gbRenderBoats, nil); + DebugMenuAddVarBool8("Render", "gbRenderVehicles", &gbRenderVehicles, nil); + DebugMenuAddVarBool8("Render", "gbRenderWorld0", &gbRenderWorld0, nil); + DebugMenuAddVarBool8("Render", "gbRenderWorld1", &gbRenderWorld1, nil); + DebugMenuAddVarBool8("Render", "gbRenderWorld2", &gbRenderWorld2, nil); +#endif + #ifdef EXTENDED_COLOURFILTER static const char *filternames[] = { "None", "Simple", "Normal", "Mobile" }; e = DebugMenuAddVar("Render", "Colourfilter", &CPostFX::EffectSwitch, nil, 1, CPostFX::POSTFX_OFF, CPostFX::POSTFX_MOBILE, filternames); @@ -564,12 +875,32 @@ DebugMenuPopulate(void) DebugMenuAddVarBool8("Render", "Don't render Vehicles", &gbDontRenderVehicles, nil); DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil); DebugMenuAddVarBool8("Render", "Don't Render Water", &gbDontRenderWater, nil); + +#ifdef PROPER_SCALING + DebugMenuAddVarBool8("Draw", "Proper Scaling", &CDraw::ms_bProperScaling, nil); +#endif +#ifdef FIX_RADAR + DebugMenuAddVarBool8("Draw", "Fix Radar", &CDraw::ms_bFixRadar, nil); +#endif +#ifdef FIX_SPRITES + DebugMenuAddVarBool8("Draw", "Fix Sprites", &CDraw::ms_bFixSprites, nil); +#endif + + +#ifndef FINAL + DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil); +#ifdef USE_CUSTOM_ALLOCATOR + DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap); +#endif +#endif DebugMenuAddVarBool8("Debug", "Show cullzone debug stuff", &gbShowCullZoneDebugStuff, nil); DebugMenuAddVarBool8("Debug", "Disable zone cull", &gbDisableZoneCull, nil); DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil); +#ifdef GTA_SCENE_EDIT DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil); +#endif #ifdef MENU_MAP DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint); #endif @@ -613,7 +944,7 @@ DebugMenuPopulate(void) "Uzi Money", "Toyminator", "Rigged To Blow", "Bullion Run", "Rumble", "The Exchange" }; - missionEntry = DebugMenuAddVar("Debug", "Select mission", &nextMissionToSwitch, nil, 1, 0, 79, missions); + missionEntry = DebugMenuAddVar("Debug", "Select mission", &nextMissionToSwitch, nil, 1, 0, ARRAY_SIZE(missions) - 1, missions); DebugMenuEntrySetWrap(missionEntry, true); DebugMenuAddCmd("Debug", "Start selected mission ", SwitchToMission); #endif @@ -637,9 +968,13 @@ DebugMenuPopulate(void) } #endif +#ifndef __MWERKS__ +#ifndef MASTER const int re3_buffsize = 1024; static char re3_buff[re3_buffsize]; +#endif +#ifndef MASTER void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func) { #ifdef _WIN32 @@ -693,9 +1028,11 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con assert(false); #endif } +#endif void re3_debug(const char *format, ...) { +#ifndef MASTER va_list va; va_start(va, format); #ifdef _WIN32 @@ -707,8 +1044,10 @@ void re3_debug(const char *format, ...) printf("%s", re3_buff); CDebug::DebugAddText(re3_buff); +#endif } +#ifndef MASTER void re3_trace(const char *filename, unsigned int lineno, const char *func, const char *format, ...) { char buff[re3_buffsize *2]; @@ -728,7 +1067,9 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons OutputDebugString(buff); } +#endif +#ifndef MASTER void re3_usererror(const char *format, ...) { va_list va; @@ -748,6 +1089,8 @@ void re3_usererror(const char *format, ...) assert(false); #endif } +#endif +#endif #ifdef VALIDATE_SAVE_SIZE int32 _saveBufCount; diff --git a/src/core/templates.h b/src/core/templates.h index 86239664..545dac39 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -1,75 +1,94 @@ #pragma once -template<typename T, int n> +template<typename T, int32 n> class CStore { public: - int allocPtr; + int32 allocPtr; T store[n]; - T *alloc(void){ - if(this->allocPtr >= n){ + T *Alloc(void){ + if(allocPtr >= n){ printf("Size of this thing:%d needs increasing\n", n); assert(0); } - return &this->store[this->allocPtr++]; + return &store[allocPtr++]; } - void clear(void){ - this->allocPtr = 0; + void Clear(void){ + allocPtr = 0; } - int getIndex(T *item){ - assert(item >= &this->store[0]); - assert(item < &this->store[n]); - return item - this->store; + int32 GetIndex(T *item){ + assert(item >= &store[0]); + assert(item < &store[n]); + return item - store; } - T *getItem(int index){ + T *GetItem(int32 index){ assert(index >= 0); assert(index < n); - return &this->store[index]; + return &store[index]; } }; +#define POOLFLAG_ID 0x7f +#define POOLFLAG_ISFREE 0x80 + template<typename T, typename U = T> class CPool { U *m_entries; - union Flags { - struct { - uint8 id : 7; - uint8 free : 1; - }; - uint8 u; - } *m_flags; - int m_size; - int m_allocPtr; + uint8 *m_flags; + int32 m_size; + int32 m_allocPtr; public: - CPool(int size){ - // TODO: use new here + CPool(int32 size){ m_entries = (U*)new uint8[sizeof(U)*size]; - m_flags = (Flags*)new uint8[sizeof(Flags)*size]; + m_flags = new uint8[size]; m_size = size; m_allocPtr = 0; for(int i = 0; i < size; i++){ - m_flags[i].id = 0; - m_flags[i].free = 1; + SetId(i, 0); + SetIsFree(i, true); } } + int GetId(int i) const + { + return m_flags[i] & POOLFLAG_ID; + } + + bool GetIsFree(int i) const + { + return !!(m_flags[i] & POOLFLAG_ISFREE); + } + + void SetId(int i, int id) + { + m_flags[i] = (m_flags[i] & POOLFLAG_ISFREE) | (id & POOLFLAG_ID); + } + + void SetIsFree(int i, bool isFree) + { + if (isFree) + m_flags[i] |= POOLFLAG_ISFREE; + else + m_flags[i] &= ~POOLFLAG_ISFREE; + } + ~CPool() { Flush(); } void Flush() { if (m_size > 0) { delete[] (uint8*)m_entries; - delete[] (uint8*)m_flags; + delete[] m_flags; m_entries = nil; m_flags = nil; m_size = 0; m_allocPtr = 0; } } - int GetSize(void) const { return m_size; } + int32 GetSize(void) const { return m_size; } T *New(void){ bool wrapped = false; do @@ -88,60 +107,65 @@ public: m_allocPtr = 0; } #endif - while(!m_flags[m_allocPtr].free); - m_flags[m_allocPtr].free = 0; - m_flags[m_allocPtr].id++; + while(!GetIsFree(m_allocPtr)); + SetIsFree(m_allocPtr, false); + SetId(m_allocPtr, GetId(m_allocPtr)+1); return (T*)&m_entries[m_allocPtr]; } - T *New(int handle){ + T *New(int32 handle){ T *entry = (T*)&m_entries[handle>>8]; SetNotFreeAt(handle); return entry; } - void SetNotFreeAt(int handle){ + void SetNotFreeAt(int32 handle){ int idx = handle>>8; - m_flags[idx].free = 0; - m_flags[idx].id = handle & 0x7F; + SetIsFree(idx, false); + SetId(idx, handle & POOLFLAG_ID); for(m_allocPtr = 0; m_allocPtr < m_size; m_allocPtr++) - if(m_flags[m_allocPtr].free) + if(GetIsFree(m_allocPtr)) return; } void Delete(T *entry){ int i = GetJustIndex(entry); - m_flags[i].free = 1; + SetIsFree(i, true); if(i < m_allocPtr) m_allocPtr = i; } T *GetSlot(int i){ - return m_flags[i].free ? nil : (T*)&m_entries[i]; + return GetIsFree(i) ? nil : (T*)&m_entries[i]; } T *GetAt(int handle){ #ifdef FIX_BUGS if (handle == -1) return nil; #endif - return m_flags[handle>>8].u == (handle & 0xFF) ? + return m_flags[handle>>8] == (handle & 0xFF) ? (T*)&m_entries[handle >> 8] : nil; } - int GetIndex(T *entry){ - int i = GetJustIndex(entry); - return m_flags[i].u + (i<<8); + int32 GetIndex(T *entry){ + int i = GetJustIndex_NoFreeAssert(entry); + return m_flags[i] + (i<<8); + } + int32 GetJustIndex(T *entry){ + int index = GetJustIndex_NoFreeAssert(entry); + assert(!GetIsFree(index)); + return index; } - int GetJustIndex(T *entry){ - // TODO: the cast is unsafe - return (int)((U*)entry - m_entries); + int32 GetJustIndex_NoFreeAssert(T* entry){ + int index = ((U*)entry - m_entries); + assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required + return index; } - int GetNoOfUsedSpaces(void) const{ + int32 GetNoOfUsedSpaces(void) const{ int i; int n = 0; for(i = 0; i < m_size; i++) - if(!m_flags[i].free) + if(!GetIsFree(i)) n++; return n; } - bool IsFreeSlot(int i) { return !!m_flags[i].free; } void ClearStorage(uint8 *&flags, U *&entries){ - delete[] (uint8*)flags; + delete[] flags; delete[] (uint8*)entries; flags = nil; entries = nil; @@ -150,7 +174,7 @@ public: void CopyBack(uint8 *&flags, U *&entries){ memcpy(m_flags, flags, sizeof(uint8)*m_size); memcpy(m_entries, entries, sizeof(U)*m_size); - debug("Size copied:%d (%d)\n", sizeof(U)*m_size, sizeof(Flags)*m_size); + debug("Size copied:%d (%d)\n", sizeof(U)*m_size, m_size); m_allocPtr = 0; ClearStorage(flags, entries); debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */ @@ -235,7 +259,7 @@ public: link->Remove(); // remove from list freeHead.Insert(link); // insert into free list } - int Count(void){ + int32 Count(void){ int n = 0; CLink<T> *lnk; for(lnk = head.next; lnk != &tail; lnk = lnk->next) |