Merge branch 'miami' into lcs-dev

This commit is contained in:
Nikolay Korolev
2021-01-01 13:21:42 +03:00
603 changed files with 117632 additions and 327000 deletions

View File

@ -18,6 +18,7 @@
#include "World.h"
#include "Renderer.h"
#include "AnimManager.h"
#include "AnimBlendAssocGroup.h"
#include "AnimViewer.h"
#include "PlayerPed.h"
#include "Pools.h"
@ -46,7 +47,6 @@ CEntity *CAnimViewer::pTarget = nil;
void
CAnimViewer::Render(void) {
if (pTarget) {
// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f);
if (pTarget) {
#ifdef FIX_BUGS
if(pTarget->IsPed())
@ -60,11 +60,14 @@ CAnimViewer::Render(void) {
void
CAnimViewer::Initialise(void) {
LoadingScreen("Loading the ModelViewer", "", GetRandomSplashScreen());
animTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(animTxdSlot);
// we need messages, messages needs hud, hud needs those
int hudSlot = CTxdStore::AddTxdSlot("hud");
CTxdStore::LoadTxd(hudSlot, "MODELS/HUD.TXD");
CHud::m_Wants_To_Draw_Hud = false;
animTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(animTxdSlot);
int particleSlot = CTxdStore::AddTxdSlot("particle");
CTxdStore::LoadTxd(particleSlot, "MODELS/PARTICLE.TXD");
CTxdStore::SetCurrentTxd(animTxdSlot);
@ -73,10 +76,6 @@ CAnimViewer::Initialise(void) {
TheCamera.Init();
TheCamera.SetRwCamera(Scene.camera);
TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f;
gbModelViewer = true;
CHud::m_Wants_To_Draw_Hud = false;
ThePaths.Init();
ThePaths.AllocatePathFindInfoMem(4500);
CCollision::Init();
@ -101,6 +100,9 @@ CAnimViewer::Initialise(void) {
CStreaming::LoadAllRequestedModels(false);
CRenderer::Init();
CVehicleModelInfo::LoadVehicleColours();
#ifdef FIX_BUGS
CVehicleModelInfo::LoadEnvironmentMaps();
#endif
CAnimManager::LoadAnimFiles();
CWorld::PlayerInFocus = 0;
CWeapon::InitialiseWeapons();
@ -110,7 +112,7 @@ CAnimViewer::Initialise(void) {
CTimeCycle::Initialise();
CCarCtrl::Init();
CPlayerPed *player = new CPlayerPed();
player->SetPosition(0.0f, 0.0f, 0.0f);
player->SetPosition(1000.0f, 1000.0f, 1000.0f);
CWorld::Players[0].m_pPed = player;
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
@ -138,6 +140,25 @@ CAnimViewer::Initialise(void) {
} else {
// TODO? maybe request some special models here so the thing doesn't crash
}
// From LCS. idk if needed
int vanBlock = CAnimManager::GetAnimationBlockIndex("van");
int bikesBlock = CAnimManager::GetAnimationBlockIndex("bikes");
int bikevBlock = CAnimManager::GetAnimationBlockIndex("bikev");
int bikehBlock = CAnimManager::GetAnimationBlockIndex("bikeh");
int bikedBlock = CAnimManager::GetAnimationBlockIndex("biked");
CStreaming::FlushRequestList();
CStreaming::RequestAnim(vanBlock, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestAnim(bikesBlock, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestAnim(bikevBlock, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestAnim(bikehBlock, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestAnim(bikedBlock, STREAMFLAGS_DEPENDENCY);
CStreaming::LoadAllRequestedModels(false);
CAnimManager::AddAnimBlockRef(vanBlock);
CAnimManager::AddAnimBlockRef(bikesBlock);
CAnimManager::AddAnimBlockRef(bikevBlock);
CAnimManager::AddAnimBlockRef(bikehBlock);
CAnimManager::AddAnimBlockRef(bikedBlock);
}
int
@ -215,8 +236,7 @@ CAnimViewer::Update(void)
{
static int modelId = 0;
static int animId = 0;
// Please don't make this bool, static bool's are problematic on my side.
static int reloadIFP = 0;
static bool reloadIFP = false;
AssocGroupId animGroup = ASSOCGRP_STD;
int nextModelId = modelId;
@ -241,7 +261,7 @@ CAnimViewer::Update(void)
CAnimManager::Initialise();
CAnimManager::LoadAnimFiles();
reloadIFP = 0;
reloadIFP = false;
}
} else {
animGroup = ASSOCGRP_STD;
@ -292,14 +312,19 @@ CAnimViewer::Update(void)
if (pTarget->IsVehicle() || pTarget->IsPed() || pTarget->IsObject()) {
((CPhysical*)pTarget)->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
}
#ifdef FIX_BUGS
// so we don't end up in the water
pTarget->GetMatrix().GetPosition().z = 10.0f;
#else
pTarget->GetMatrix().GetPosition().z = 0.0f;
#endif
if (modelInfo->GetModelType() == MITYPE_PED) {
((CPed*)pTarget)->bKindaStayInSamePlace = true;
// Triangle in mobile
if (pad->GetSquareJustDown()) {
reloadIFP = 1;
reloadIFP = true;
AsciiToUnicode("IFP reloaded", gUString);
CMessages::AddMessage(gUString, 1000, 0);
@ -316,7 +341,7 @@ CAnimViewer::Update(void)
} else if (pad->GetDPadUpJustDown()) {
animId--;
if (animId < 0) {
animId = NUM_ANIMS - 1;
animId = NUM_STD_ANIMS - 1;
}
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
@ -325,7 +350,7 @@ CAnimViewer::Update(void)
CMessages::AddMessage(gUString, 1000, 0);
} else if (pad->GetDPadDownJustDown()) {
animId = (animId == (NUM_ANIMS - 1) ? 0 : animId + 1);
animId = (animId == (NUM_STD_ANIMS - 1) ? 0 : animId + 1);
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
sprintf(gString, "Current anim: %d", animId);
@ -344,6 +369,11 @@ CAnimViewer::Update(void)
AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString);
CMessages::AddMessage(gUString, 100, 0);
}
// From LCS
if (CAnimManager::GetAnimAssocGroups()[animGroup].numAssociations <= animId)
animId = 0;
} else if (modelInfo->GetModelType() == MITYPE_VEHICLE) {
if (pad->GetLeftShoulder1JustDown()) {

View File

@ -180,9 +180,11 @@ CCam::Process(void)
Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_FOLLOWPED:
#ifdef PC_PLAYER_CONTROLS
if(CCamera::m_bUseMouse3rdPerson)
Process_FollowPedWithMouse(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
else
#endif
#ifdef FREE_CAM
if(CCamera::bFreeCam)
Process_FollowPed_Rotation(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
@ -287,9 +289,11 @@ CCam::Process(void)
case MODE_FIGHT_CAM_RUNABOUT:
Process_1rstPersonPedOnPC(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
#ifdef GTA_SCENE_EDIT
case MODE_EDITOR:
Process_Editor(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
#endif
default:
Source = CVector(0.0f, 0.0f, 0.0f);
Front = CVector(0.0f, 1.0f, 0.0f);
@ -2703,7 +2707,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(CamTargetEntity->GetClump());
int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
RwV3dTransformPoints((RwV3d*)&HeadPos, (RwV3d*)&HeadPos, 1, &mats[idx]);
RwV3dTransformPoints(&HeadPos, &HeadPos, 1, &mats[idx]);
RwV3d scl = { 0.0f, 0.0f, 0.0f };
RwMatrixScale(&mats[idx], &scl, rwCOMBINEPRECONCAT);
@ -2744,7 +2748,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
Source = HeadPos;
// unused:
// ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&MidPos, PED_MID);
// ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(MidPos, PED_MID);
// Source - MidPos;
// Look around
@ -2920,8 +2924,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float
UseMouse = false;
int ZoomInButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_IN);
int ZoomOutButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_OUT);
// TODO: enum? this should be mouse wheel up and down
if(ZoomInButton == 4 || ZoomInButton == 5 || ZoomOutButton == 4 || ZoomOutButton == 5){
if(ZoomInButton == rsMOUSEWHEELUPBUTTON || ZoomInButton == rsMOUSEWHEELDOWNBUTTON || ZoomOutButton == rsMOUSEWHEELUPBUTTON || ZoomOutButton == rsMOUSEWHEELDOWNBUTTON){
if(CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetMouseWheelDown()){
if(CPad::GetPad(0)->SniperZoomIn()){
TargetFOV = FOV - 10.0f;
@ -3734,6 +3737,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
}
}
#ifdef PC_PLAYER_CONTROLS
if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){
CPed *player = FindPlayerPed();
if(player && player->CanStrafeOrMouseControl()){
@ -3744,6 +3748,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
TheCamera.pTargetEntity->GetMatrix().UpdateRW();
}
}
#endif
}
void
@ -4034,6 +4039,7 @@ CCam::Process_Debug(const CVector&, float, float, float)
}
#endif
#ifdef GTA_SCENE_EDIT
void
CCam::Process_Editor(const CVector&, float, float, float)
{
@ -4112,6 +4118,7 @@ CCam::Process_Editor(const CVector&, float, float, float)
sprintf(str, "Look@: %f, Look@: %f, Look@: %f ", Front.x + Source.x, Front.y + Source.y, Front.z + Source.z);
}
}
#endif
void
CCam::Process_ModelView(const CVector &CameraTarget, float, float, float)
@ -4125,6 +4132,12 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float)
Distance += CPad::GetPad(0)->GetLeftStickY()/1000.0f;
else
Distance += CPad::GetPad(0)->GetLeftStickY() * ((Distance - 10.0f)/20.0f + 1.0f) / 1000.0f;
#ifdef IMPROVED_CAMERA
if(CPad::GetPad(0)->GetLeftMouse()){
Distance += DEGTORAD(CPad::GetPad(0)->GetMouseY()/2.0f);
Angle += DEGTORAD(CPad::GetPad(0)->GetMouseX()/2.0f);
}
#endif
if(Distance < 1.5f)
Distance = 1.5f;
@ -4903,13 +4916,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (FOV > DefaultFOV)
// 0.98f: CAR_FOV_FADE_MULT
FOV = pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV;
FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV;
if (FOV <= DefaultFOV + 30.0f) {
if (FOV < DefaultFOV)
FOV = DefaultFOV;
} else
FOV = DefaultFOV + 30.0f;
FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f);
}
// WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta)
@ -5036,7 +5045,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
targetAlpha = maxAlphaAllowed;
}
float maxAlphaBlendAmount = CTimer::GetTimeStep() * CARCAM_SET[camSetArrPos][6];
float targetAlphaBlendAmount = (1.0f - pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha);
float targetAlphaBlendAmount = (1.0f - Pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha);
if (targetAlphaBlendAmount <= maxAlphaBlendAmount) {
if (targetAlphaBlendAmount < -maxAlphaBlendAmount)
targetAlphaBlendAmount = -maxAlphaBlendAmount;
@ -5048,7 +5057,6 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float stickX = -(pad->GetCarGunLeftRight());
float stickY = pad->GetCarGunUpDown();
// In SA this checks for m_bUseMouse3rdPerson so num2/num8 do not move camera when Keyboard & Mouse controls are used.
if (CCamera::m_bUseMouse3rdPerson)
stickY = 0.0f;
@ -5128,7 +5136,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float betaSpeedFromStickX = xMovement * CARCAM_SET[camSetArrPos][12];
float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9];
float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep());
float angleChangeStep = Pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep());
float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f);
if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount)
@ -5240,69 +5248,78 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// SA calls SetColVarsVehicle in here
if (nextDirectionIsForward) {
// This is new in LCS!
// LCS uses exactly the same collision code as FollowPedWithMouse, so we will do so.
// This is only in LCS!
float timestepFactor = Pow(0.99f, CTimer::GetTimeStep());
dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude());
// Move cam if on collision
CColPoint foundCol;
CEntity* foundEnt;
// Our addition
#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && IsLightObject(ent->GetModelIndex()))
// Clip Source and fix near clip
CColPoint colPoint;
CEntity* entity;
CWorld::pIgnoreEntity = CamTargetEntity;
if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) {
float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude();
float obstacleCamDist = newDistance - obstacleTargetDist;
if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) {
Source = foundCol.point;
if (obstacleTargetDist < 1.2f) {
RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f));
}
} else {
if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) {
float lessClip = obstacleCamDist - 0.35f;
if (lessClip <= DEFAULT_NEAR)
RwCameraSetNearClipPlane(Scene.camera, lessClip);
else
RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
} else {
obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude();
Source = foundCol.point;
if (obstacleTargetDist < 1.2f) {
float lessClip = obstacleTargetDist - 0.3f;
if (lessClip >= 0.05f)
RwCameraSetNearClipPlane(Scene.camera, lessClip);
else
RwCameraSetNearClipPlane(Scene.camera, 0.05f);
}
if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) && !IS_TRAFFIC_LIGHT(entity)){
float PedColDist = (TargetCoors - colPoint.point).Magnitude();
float ColCamDist = newDistance - PedColDist;
if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){
// Ped in the way but not clipping through
if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) || IS_TRAFFIC_LIGHT(entity)){
PedColDist = (TargetCoors - colPoint.point).Magnitude();
Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f)
RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}else{
RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR));
}
}else{
Source = colPoint.point;
if(PedColDist < DEFAULT_NEAR + 0.3f)
RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}
}
CWorld::pIgnoreEntity = nil;
float nearClip = RwCameraGetNearClipPlane(Scene.camera);
float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f;
// If we're seeing blue hell due to camera intersects some surface, fix it.
// SA and LCS have this unrolled.
for (int i = 0;
i <= 5 && CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false);
i++) {
CVector surfaceCamDist = gaTempSphereColPoints->point - Source;
CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front;
float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius;
float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f);
float ViewPlaneWidth = ViewPlaneHeight * CDraw::CalculateAspectRatio() * fTweakFOV;
float Near = RwCameraGetNearClipPlane(Scene.camera);
float radius = ViewPlaneWidth*Near;
entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true);
int i = 0;
while(entity){
if (newNearClip > nearClip)
newNearClip = nearClip;
if (newNearClip < 0.1f)
newNearClip = 0.1f;
if (nearClip > newNearClip)
RwCameraSetNearClipPlane(Scene.camera, newNearClip);
if (IS_TRAFFIC_LIGHT(entity))
break;
if (newNearClip == 0.1f)
Source += (TargetCoors - Source) * 0.3f;
CVector CamToCol = gaTempSphereColPoints[0].point - Source;
float frontDist = DotProduct(CamToCol, Front);
float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth;
nearClip = RwCameraGetNearClipPlane(Scene.camera);
radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f;
// 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;

View File

@ -69,7 +69,11 @@ enum
// NB: removed explicit TheCamera from all functions
CCamera TheCamera;
#ifdef PC_PLAYER_CONTROLS
bool CCamera::m_bUseMouse3rdPerson = true;
#else
bool CCamera::m_bUseMouse3rdPerson = false;
#endif
bool bDidWeProcessAnyCinemaCam;
static bool bSwitchedToObbeCam;
float CCamera::m_fMouseAccelHorzntl;
@ -612,7 +616,7 @@ CCamera::Process(void)
// LOD dist
if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()){
LODDistMultiplier = 70.0f/CDraw::GetFOV() * CDraw::GetAspectRatio()/(4.0f/3.0f);
LODDistMultiplier = 70.0f/CDraw::GetFOV();
if(GetPosition().z > 55.0f && FindPlayerVehicle() && FindPlayerVehicle()->pHandling->Flags & (HANDLING_IS_HELI|HANDLING_IS_PLANE) ||
FindPlayerPed()->m_attachedTo){
@ -1008,22 +1012,26 @@ CCamera::CamControl(void)
ReqMode = CCam::MODE_FOLLOWPED;
// Check 1st person mode
if(m_bLookingAtPlayer && pTargetEntity->IsPed() && !m_WideScreenOn && !Cams[0].Using3rdPersonMouseCam()
if((m_bLookingAtPlayer || m_bEnable1rstPersonCamCntrlsScript) && pTargetEntity->IsPed() &&
(!m_WideScreenOn || m_bEnable1rstPersonCamCntrlsScript) && !Cams[0].Using3rdPersonMouseCam()
#ifdef FREE_CAM
&& !CCamera::bFreeCam
&& (!CCamera::bFreeCam || m_bEnable1rstPersonCamCntrlsScript)
#endif
){
// See if we want to enter first person mode
if(CPad::GetPad(0)->LookAroundLeftRight() || CPad::GetPad(0)->LookAroundUpDown()){
m_uiFirstPersonCamLastInputTime = CTimer::GetTimeInMilliseconds();
m_bFirstPersonBeingUsed = true;
}else if(m_bFirstPersonBeingUsed){
}
if(m_bFirstPersonBeingUsed){
// Or if we want to go back to 3rd person
if(CPad::GetPad(0)->GetPedWalkLeftRight() || CPad::GetPad(0)->GetPedWalkUpDown() ||
CPad::GetPad(0)->GetSquare() || CPad::GetPad(0)->GetTriangle() ||
CPad::GetPad(0)->GetCross() || CPad::GetPad(0)->GetCircle() ||
CTimer::GetTimeInMilliseconds() - m_uiFirstPersonCamLastInputTime > 2850.0f){
m_bFirstPersonBeingUsed = false;
}else if(CPad::GetPad(0)->TargetJustDown()){
m_bFirstPersonBeingUsed = false;
m_bJustJumpedOutOf1stPersonBecauseOfTarget = true;
}
}
@ -1129,27 +1137,31 @@ CCamera::CamControl(void)
}else{
whichDoor = 1;
garageDoorPos1 = Cams[ActiveCam].Source;
garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2.0f, (stairsZone->miny+stairsZone->maxy)/2.0f, 0.0f);
if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f &&
pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f &&
pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){
// if((garageCenter-garageDoorPos1).Magnitude() > 15.0f){
bool bClearViewOutside = true;
CVector dirOutside = pTargetEntity->GetPosition() - garageCenter;
dirOutside.z = 0.0f;
dirOutside.Normalise();
float zoneDim = stairsZone->maxx - stairsZone->minx;
if(zoneDim < stairsZone->maxy - stairsZone->miny)
zoneDim = stairsZone->maxy - stairsZone->miny;
zoneDim *= 2.0f;
CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside;
if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){
posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside;
if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true))
bClearViewOutside = false;
if(stairsZone){ // always true
garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2, (stairsZone->miny+stairsZone->maxy)/2, 0.0f);
if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f &&
pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f &&
pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){
garageDoorPos1 = CVector(382.6f, -489.6f, 13.1f);
}else{
bool bClearViewOutside = true;
CVector dirOutside = pTargetEntity->GetPosition() - garageCenter;
dirOutside.z = 0.0f;
dirOutside.Normalise();
float zoneDim = stairsZone->maxx - stairsZone->minx;
if(zoneDim < stairsZone->maxy - stairsZone->miny)
zoneDim = stairsZone->maxy - stairsZone->miny;
zoneDim *= 2.0f;
CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside;
if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){
posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside;
if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true))
bClearViewOutside = false;
}
if(bClearViewOutside)
garageDoorPos1 = posOutside;
}
if(bClearViewOutside)
garageDoorPos1 = posOutside;
}
}
@ -1159,7 +1171,7 @@ CCamera::CamControl(void)
garageCenter.z = 0.0f;
}else{
garageDoorPos1.z = 0.0f;
if(stairs == nil) // how can this be true?
if(!stairs) // how can this be true?
garageCenter = CVector(pTargetEntity->GetPosition().x, pTargetEntity->GetPosition().y, 0.0f);
}
if(whichDoor == 1)
@ -1598,8 +1610,10 @@ CCamera::CamControl(void)
switchByJumpCut = true;
}
}
#ifdef GTA_SCENE_EDIT
if(CSceneEdit::m_bEditOn)
ReqMode = CCam::MODE_EDITOR;
#endif
if((m_uiTransitionState == 0 || switchByJumpCut) && ReqMode != Cams[ActiveCam].Mode){
if(switchByJumpCut){
@ -1698,7 +1712,7 @@ CCamera::CamControl(void)
StartTransitionWhenNotFinishedInter(ReqMode);
pTargetEntity->RegisterReference(&pTargetEntity);
Cams[ActiveCam].CamTargetEntity->RegisterReference(&Cams[ActiveCam].CamTargetEntity);
}else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT){
}else if(m_bStartInterScript && m_iTypeOfSwitch == JUMP_CUT || jumpCutTo1stPrs){
m_uiTransitionState = 0;
m_vecDoingSpecialInterPolation = false;
if(m_bEnable1rstPersonCamCntrlsScript && ReqMode == CCam::MODE_1STPERSON)
@ -3385,12 +3399,12 @@ CCamera::LoadTrainCamNodes(char const *name)
char token[16] = { 0 };
char filename[16] = { 0 };
uint8 *buf;
size_t bufpos = 0;
ssize_t bufpos = 0;
int field = 0;
int tokpos = 0;
char c;
int i;
size_t len;
ssize_t len;
strcpy(filename, name);
len = (int)strlen(filename);
@ -3617,6 +3631,8 @@ CCamera::LoadPathSplines(int file)
m_arrPathArray[i].m_arr_PathData[j] = atof(token);
i++;
j = 0;
if (i == MAX_NUM_OF_SPLINETYPES)
reading = false;
memset(token, 0, 32);
n = 0;
}

View File

@ -209,7 +209,9 @@ public:
void PrintMode(void);
void Process_Debug(const CVector&, float, float, float);
#ifdef GTA_SCENE_EDIT
void Process_Editor(const CVector&, float, float, float);
#endif
void Process_ModelView(const CVector &CameraTarget, float, float, float);
void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float);

View File

@ -5,6 +5,7 @@
#include "CdStream.h"
#include "rwcore.h"
#include "RwHelper.h"
#include "MemoryMgr.h"
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
@ -72,7 +73,11 @@ CdStreamInitThread(void)
gChannelRequestQ.size = gNumChannels + 1;
ASSERT(gChannelRequestQ.items != nil );
#ifdef FIX_BUGS
gCdStreamSema = CreateSemaphore(nil, 0, 5, nil);
#else
gCdStreamSema = CreateSemaphore(nil, 0, 5, "CdStream");
#endif
if ( gCdStreamSema == nil )
{
@ -242,8 +247,15 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
else
return STREAM_SUCCESS;
}
#ifdef BIG_IMG
LARGE_INTEGER liDistanceToMove;
liDistanceToMove.QuadPart = _GET_OFFSET(offset);
liDistanceToMove.QuadPart *= CDSTREAM_SECTOR_SIZE;
SetFilePointerEx(hImage, liDistanceToMove, nil, FILE_BEGIN);
#else
SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN);
#endif
DWORD NumberOfBytesRead;

View File

@ -16,7 +16,7 @@
#include "CdStream.h"
#include "rwcore.h"
#include "RwHelper.h"
#include "MemoryMgr.h"
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
@ -429,7 +429,7 @@ void *CdStreamThread(void *param)
ASSERT(pChannel->hFile >= 0);
ASSERT(pChannel->pBuffer != nil );
lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET);
lseek(pChannel->hFile, (size_t)pChannel->nSectorOffset * (size_t)CDSTREAM_SECTOR_SIZE, SEEK_SET);
if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) {
// pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel
// STREAM_WAITING is a little hack to make CStreaming not process this data

View File

@ -1,236 +0,0 @@
#include "common.h"
#include "templates.h"
#include "General.h"
#include "ModelInfo.h"
#include "Streaming.h"
#include "FileLoader.h"
#include "Script.h"
#include "Timer.h"
#include "Camera.h"
#include "Frontend.h"
#include "Physical.h"
#include "ColStore.h"
CPool<ColDef,ColDef> *CColStore::ms_pColPool;
void
CColStore::Initialise(void)
{
if(ms_pColPool == nil)
ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles");
AddColSlot("generic"); // slot 0. not streamed
}
void
CColStore::Shutdown(void)
{
int i;
for(i = 0; i < COLSTORESIZE; i++)
RemoveColSlot(i);
if(ms_pColPool)
delete ms_pColPool;
ms_pColPool = nil;
}
int
CColStore::AddColSlot(const char *name)
{
ColDef *def = ms_pColPool->New();
assert(def);
def->isLoaded = false;
def->unused = 0;
def->bounds.left = 1000000.0f;
def->bounds.top = 1000000.0f;
def->bounds.right = -1000000.0f;
def->bounds.bottom = -1000000.0f;
def->minIndex = INT16_MAX;
def->maxIndex = INT16_MIN;
strcpy(def->name, name);
return ms_pColPool->GetJustIndex(def);
}
void
CColStore::RemoveColSlot(int slot)
{
if(GetSlot(slot)){
if(GetSlot(slot)->isLoaded)
RemoveCol(slot);
ms_pColPool->Delete(GetSlot(slot));
}
}
int
CColStore::FindColSlot(const char *name)
{
ColDef *def;
int size = ms_pColPool->GetSize();
for(int i = 0; i < size; i++){
def = GetSlot(i);
if(def && !CGeneral::faststricmp(def->name, name))
return i;
}
return -1;
}
char*
CColStore::GetColName(int32 slot)
{
return GetSlot(slot)->name;
}
CRect&
CColStore::GetBoundingBox(int32 slot)
{
return GetSlot(slot)->bounds;
}
void
CColStore::IncludeModelIndex(int32 slot, int32 modelIndex)
{
ColDef *def = GetSlot(slot);
if(modelIndex < def->minIndex)
def->minIndex = modelIndex;
if(modelIndex > def->maxIndex)
def->maxIndex = modelIndex;
}
bool
CColStore::LoadCol(int32 slot, uint8 *buffer, int32 bufsize)
{
bool success;
ColDef *def = GetSlot(slot);
if(def->minIndex > def->maxIndex)
success = CFileLoader::LoadCollisionFileFirstTime(buffer, bufsize, slot);
else
success = CFileLoader::LoadCollisionFile(buffer, bufsize, slot);
if(success)
def->isLoaded = true;
else
debug("Failed to load Collision\n");
return success;
}
void
CColStore::RemoveCol(int32 slot)
{
int id;
GetSlot(slot)->isLoaded = false;
for(id = 0; id < MODELINFOSIZE; id++){
CBaseModelInfo *mi = CModelInfo::GetModelInfo(id);
if(mi){
CColModel *col = mi->GetColModel();
if(col && col->level == slot)
col->RemoveCollisionVolumes();
}
}
}
void
CColStore::LoadAllCollision(void)
{
int i;
for(i = 1; i < COLSTORESIZE; i++)
if(GetSlot(i))
CStreaming::RequestCol(i, 0);
CStreaming::LoadAllRequestedModels(false);
}
void
CColStore::RemoveAllCollision(void)
{
int i;
for(i = 1; i < COLSTORESIZE; i++)
if(GetSlot(i))
if(CStreaming::CanRemoveCol(i))
CStreaming::RemoveCol(i);
}
static bool bLoadAtSecondPosition;
static CVector2D secondPosition;
void
CColStore::AddCollisionNeededAtPosn(const CVector2D &pos)
{
bLoadAtSecondPosition = true;
secondPosition = pos;
}
void
CColStore::LoadCollision(const CVector2D &pos)
{
int i;
if(CStreaming::ms_disableStreaming)
return;
for(i = 1; i < COLSTORESIZE; i++){
if(GetSlot(i) == nil)
continue;
bool wantThisOne = false;
if(GetBoundingBox(i).IsPointInside(pos) ||
bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) ||
CGeneral::faststrcmp(GetColName(i), "yacht") == 0){
wantThisOne = true;
}else{
for (int j = 0; j < MAX_CLEANUP; j++) {
CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j);
if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) {
if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f))
wantThisOne = true;
}
}
}
if(wantThisOne)
CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
else
CStreaming::RemoveCol(i);
}
bLoadAtSecondPosition = false;
}
void
CColStore::RequestCollision(const CVector2D &pos)
{
int i;
for(i = 1; i < COLSTORESIZE; i++)
if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f))
CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
}
void
CColStore::EnsureCollisionIsInMemory(const CVector2D &pos)
{
int i;
if(CStreaming::ms_disableStreaming)
return;
for(i = 1; i < COLSTORESIZE; i++)
if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) &&
!CStreaming::HasColLoaded(i)){
CStreaming::RequestCol(i, 0);
if(TheCamera.GetScreenFadeStatus() == FADE_0)
FrontEndMenuManager.MessageScreen("LOADCOL", false);
CTimer::Suspend();
CStreaming::LoadAllRequestedModels(false);
CTimer::Resume();
}
}
bool
CColStore::HasCollisionLoaded(const CVector2D &pos)
{
int i;
for(i = 1; i < COLSTORESIZE; i++)
if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f) &&
!GetSlot(i)->isLoaded)
return false;
return true;
}

View File

@ -1,43 +0,0 @@
#pragma once
#include "templates.h"
struct ColDef { // made up name
int32 unused;
bool isLoaded;
CRect bounds;
char name[20];
int16 minIndex;
int16 maxIndex;
};
class CColStore
{
static CPool<ColDef,ColDef> *ms_pColPool;
public:
static void Initialise(void);
static void Shutdown(void);
static int AddColSlot(const char *name);
static void RemoveColSlot(int32 slot);
static int FindColSlot(const char *name);
static char *GetColName(int32 slot);
static CRect &GetBoundingBox(int32 slot);
static void IncludeModelIndex(int32 slot, int32 modelIndex);
static bool LoadCol(int32 storeID, uint8 *buffer, int32 bufsize);
static void RemoveCol(int32 slot);
static void AddCollisionNeededAtPosn(const CVector2D &pos);
static void LoadAllCollision(void);
static void RemoveAllCollision(void);
static void LoadCollision(const CVector2D &pos);
static void RequestCollision(const CVector2D &pos);
static void EnsureCollisionIsInMemory(const CVector2D &pos);
static bool HasCollisionLoaded(const CVector2D &pos);
static ColDef *GetSlot(int slot) {
assert(slot >= 0);
assert(ms_pColPool);
assert(slot < ms_pColPool->GetSize());
return ms_pColPool->GetSlot(slot);
}
};

View File

@ -2348,8 +2348,252 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
return num;
}
#ifdef BIND_VEHICLE_FIREWEAPON
#define VFB(b) b,
#else
#define VFB(b)
#endif
#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT) \
{{ \
O, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
L1, /* VEHICLE_CHANGE_RADIO_STATION */ \
L3, /* VEHICLE_HORN */ \
R3, /* TOGGLE_SUBMISSIONS */ \
R1, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
R1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
O, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
SELECT, /* VEHICLE_CHANGE_RADIO_STATION */ \
L1, /* VEHICLE_HORN */ \
R3, /* TOGGLE_SUBMISSIONS */ \
R1, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
R1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
X, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
T, /* PED_SNIPER_ZOOM_IN */ \
Q, /* PED_SNIPER_ZOOM_OUT */ \
L1, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
O, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(O) /* VEHICLE_FIREWEAPON */ \
X, /* VEHICLE_ACCELERATE */ \
Q, /* VEHICLE_BRAKE */ \
L3, /* VEHICLE_CHANGE_RADIO_STATION */ \
R1, /* VEHICLE_HORN */ \
R3, /* TOGGLE_SUBMISSIONS */ \
T, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
T, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
R1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}, \
{ \
R1, /* PED_FIREWEAPON */ \
R2, /* PED_CYCLE_WEAPON_RIGHT */ \
L2, /* PED_CYCLE_WEAPON_LEFT */ \
nil, /* GO_FORWARD */ \
nil, /* GO_BACK */ \
nil, /* GO_LEFT */ \
nil, /* GO_RIGHT */ \
Q, /* PED_SNIPER_ZOOM_IN */ \
X, /* PED_SNIPER_ZOOM_OUT */ \
T, /* VEHICLE_ENTER_EXIT */ \
SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
Q, /* PED_JUMPING */ \
X, /* PED_SPRINT */ \
R3, /* PED_LOOKBEHIND */ \
VFB(R1) /* VEHICLE_FIREWEAPON */ \
nil, /* VEHICLE_ACCELERATE */ \
nil, /* VEHICLE_BRAKE */ \
O, /* VEHICLE_CHANGE_RADIO_STATION */ \
L3, /* VEHICLE_HORN */ \
Q, /* TOGGLE_SUBMISSIONS */ \
L1, /* VEHICLE_HANDBRAKE */ \
nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
L2, /* VEHICLE_LOOKLEFT */ \
R2, /* VEHICLE_LOOKRIGHT */ \
nil, /* VEHICLE_LOOKBEHIND */ \
nil, /* VEHICLE_TURRETLEFT */ \
nil, /* VEHICLE_TURRETRIGHT */ \
nil, /* VEHICLE_TURRETUP */ \
nil, /* VEHICLE_TURRETDOWN */ \
L2, /* PED_CYCLE_TARGET_LEFT */ \
R2, /* PED_CYCLE_TARGET_RIGHT */ \
O, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
L1, /* PED_LOCK_TARGET */ \
nil, /* NETWORK_TALK */ \
nil, /* PED_1RST_PERSON_LOOK_UP */ \
nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
nil, /* _CONTROLLERACTION_36 */ \
nil, /* TOGGLE_DPAD */ \
nil, /* SWITCH_DEBUG_CAM_ON */ \
nil, /* TAKE_SCREEN_SHOT */ \
nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
}}
const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK");
#ifdef BUTTON_ICONS
const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK");
#endif
#if 0 // set 1 for ps2 fonts
#define PS2_TRIANGLE "\""
#define PS2_CIRCLE "|"
#define PS2_CROSS "/"
#define PS2_SQUARE "^"
#elif defined(BUTTON_ICONS)
#define PS2_TRIANGLE "~T~"
#define PS2_CIRCLE "~O~"
#define PS2_CROSS "~X~"
#define PS2_SQUARE "~Q~"
#else
#define PS2_TRIANGLE "TRIANGLE"
#define PS2_CIRCLE "CIRCLE"
#define PS2_CROSS "CROSS"
#define PS2_SQUARE "SQUARE"
#endif
const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT");
#ifdef BUTTON_ICONS
const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT");
#endif
#undef PS2_TRIANGLE
#undef PS2_CIRCLE
#undef PS2_CROSS
#undef PS2_SQUARE
#undef CONTROLLER_BUTTONS
#undef VFB
void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *text, uint16 leight)
{
#ifdef DETECT_PAD_INPUT_SWITCH
if (CPad::GetPad(0)->IsAffectedByController) {
wchar wstr[16];
// TODO: INI and/or menu setting for Xbox/PS switch
#ifdef BUTTON_ICONS
const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
#else
const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons;
#endif
assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these
AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr);
CMessages::WideStringCopy(text, wstr, leight);
return;
}
#endif
int32 nums = GetNumOfSettingsForAction((e_ControllerAction)action);
int32 sets = 0;

View File

@ -59,7 +59,6 @@ CEventList::Update(void)
}
}
// ok
void
CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout)
{
@ -121,7 +120,7 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent
}
if(criminal == FindPlayerPed())
ReportCrimeForEvent(type, (uintptr)ent, copsDontCare);
ReportCrimeForEvent(type, (intptr)ent, copsDontCare);
}
void
@ -199,7 +198,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event)
}
void
CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare)
CEventList::ReportCrimeForEvent(eEventType type, intptr crimeId, bool copsDontCare)
{
eCrimeType crime;
switch(type){

View File

@ -62,7 +62,7 @@ public:
static bool GetEvent(eEventType type, int32 *event);
static void ClearEvent(int32 event);
static bool FindClosestEvent(eEventType type, CVector posn, int32 *event);
static void ReportCrimeForEvent(eEventType type, size_t, bool);
static void ReportCrimeForEvent(eEventType type, intptr, bool);
};
extern CEvent gaEvent[NUMEVENTS];

View File

@ -2,6 +2,7 @@
#include <ctype.h>
#include "main.h"
#include "General.h"
#include "Quaternion.h"
#include "ModelInfo.h"
#include "ModelIndices.h"
@ -11,7 +12,6 @@
#include "HandlingMgr.h"
#include "CarCtrl.h"
#include "PedType.h"
#include "PedStats.h"
#include "AnimManager.h"
#include "Game.h"
#include "RwHelper.h"
@ -25,6 +25,7 @@
#include "ZoneCull.h"
#include "CdStream.h"
#include "FileLoader.h"
#include "MemoryHeap.h"
#include "Streaming.h"
#include "ColStore.h"
#include "Occlusion.h"
@ -69,17 +70,19 @@ CFileLoader::LoadLevel(const char *filename)
if(*line == '#')
continue;
if(strncmp(line, "EXIT", 9) == 0) // BUG: 9?
if(strncmp(line, "EXIT", 4) == 0)
break;
if(strncmp(line, "IMAGEPATH", 9) == 0){
RwImageSetPath(line + 10);
}else if(strncmp(line, "TEXDICTION", 10) == 0){
PUSH_MEMID(MEMID_TEXTURES);
strcpy(txdname, line+11);
LoadingScreenLoadingFile(txdname);
RwTexDictionary *txd = LoadTexDictionary(txdname);
AddTexDictionaries(savedTxd, txd);
RwTexDictionaryDestroy(txd);
POP_MEMID();
}else if(strncmp(line, "COLFILE", 7) == 0){
LoadingScreenLoadingFile(line+10);
LoadCollisionFile(line+10, 0);
@ -95,22 +98,30 @@ CFileLoader::LoadLevel(const char *filename)
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
LoadingScreenLoadingFile("Collision");
PUSH_MEMID(MEMID_WORLD);
CObjectData::Initialise("DATA\\OBJECT.DAT");
CStreaming::Init();
POP_MEMID();
PUSH_MEMID(MEMID_COLLISION);
CColStore::LoadAllCollision();
POP_MEMID();
for(int i = 0; i < MODELINFOSIZE; i++)
if(CModelInfo::GetModelInfo(i))
CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex();
objectsLoaded = true;
}
PUSH_MEMID(MEMID_WORLD);
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
POP_MEMID();
}else if(strncmp(line, "SPLASH", 6) == 0){
#ifndef DISABLE_LOADING_SCREEN
LoadSplash(GetRandomSplashScreen());
#endif
#ifndef GTA_PS2
}else if(strncmp(line, "CDIMAGE", 7) == 0){
CdStreamAddImage(line + 8);
#endif
}
}
@ -161,7 +172,7 @@ CFileLoader::LoadTexDictionary(const char *filename)
struct ColHeader
{
char ident[4];
uint32 ident;
uint32 size;
};
@ -173,12 +184,14 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
CBaseModelInfo *mi;
ColHeader header;
PUSH_MEMID(MEMID_COLLISION);
debug("Loading collision file %s\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
assert(fd > 0);
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
assert(strncmp(header.ident, "COLL", 4) == 0);
assert(header.ident == 'LLOC');
CFileMgr::Read(fd, (char*)work_buff, header.size);
memcpy(modelname, work_buff, 24);
@ -198,6 +211,8 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
}
CFileMgr::CloseFile(fd);
POP_MEMID();
}
@ -213,7 +228,7 @@ CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlo
while(size > 8){
header = (ColHeader*)buffer;
modelsize = header->size;
if(strncmp(header->ident, "COLL", 4) != 0)
if(header->ident != 'LLOC')
return size-8 < CDSTREAM_SECTOR_SIZE;
memcpy(modelname, buffer+8, 24);
memcpy(work_buff, buffer+32, modelsize-24);
@ -247,7 +262,7 @@ CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot)
while(size > 8){
header = (ColHeader*)buffer;
modelsize = header->size;
if(strncmp(header->ident, "COLL", 4) != 0)
if(header->ident != 'LLOC')
return size-8 < CDSTREAM_SECTOR_SIZE;
memcpy(modelname, buffer+8, 24);
memcpy(work_buff, buffer+32, modelsize-24);
@ -292,6 +307,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 44;
if(model.numSpheres > 0){
model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere));
REGISTER_MEMPTR(&model.spheres);
for(i = 0; i < model.numSpheres; i++){
model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]);
buf += 20;
@ -316,6 +332,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(model.numBoxes > 0){
model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox));
REGISTER_MEMPTR(&model.boxes);
for(i = 0; i < model.numBoxes; i++){
model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]);
buf += 28;
@ -327,6 +344,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(numVertices > 0){
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
REGISTER_MEMPTR(&model.vertices);
for(i = 0; i < numVertices; i++){
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
#if 0
@ -344,6 +362,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(model.numTriangles > 0){
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
REGISTER_MEMPTR(&model.triangles);
for(i = 0; i < model.numTriangles; i++){
model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]);
buf += 16;
@ -567,6 +586,9 @@ CFileLoader::AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src)
RwTexDictionaryForAllTextures(src, MoveTexturesCB, dst);
}
#define isLine3(l, a, b, c) ((l[0] == a) && (l[1] == b) && (l[2] == c))
#define isLine4(l, a, b, c, d) ((l[0] == a) && (l[1] == b) && (l[2] == c) && (l[3] == d))
void
CFileLoader::LoadObjectTypes(const char *filename)
{
@ -602,15 +624,15 @@ CFileLoader::LoadObjectTypes(const char *filename)
continue;
if(section == NONE){
if(strncmp(line, "objs", 4) == 0) section = OBJS;
else if(strncmp(line, "tobj", 4) == 0) section = TOBJ;
else if(strncmp(line, "weap", 4) == 0) section = WEAP;
else if(strncmp(line, "hier", 4) == 0) section = HIER;
else if(strncmp(line, "cars", 4) == 0) section = CARS;
else if(strncmp(line, "peds", 4) == 0) section = PEDS;
else if(strncmp(line, "path", 4) == 0) section = PATH;
else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX;
}else if(strncmp(line, "end", 3) == 0){
if(isLine4(line, 'o','b','j','s')) section = OBJS;
else if(isLine4(line, 't','o','b','j')) section = TOBJ;
else if(isLine4(line, 'w','e','a','p')) section = WEAP;
else if(isLine4(line, 'h','i','e','r')) section = HIER;
else if(isLine4(line, 'c','a','r','s')) section = CARS;
else if(isLine4(line, 'p','e','d','s')) section = PEDS;
else if(isLine4(line, 'p','a','t','h')) section = PATH;
else if(isLine4(line, '2','d','f','x')) section = TWODFX;
}else if(isLine3(line, 'e','n','d')){
section = NONE;
}else switch(section){
case OBJS:
@ -843,21 +865,21 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_level = level;
mi->m_compRules = comprules;
if(strncmp(type, "car", 4) == 0){
if(strcmp(type, "car") == 0){
mi->m_wheelId = misc;
mi->m_wheelScale = wheelScale;
mi->m_vehicleType = VEHICLE_TYPE_CAR;
}else if(strncmp(type, "boat", 5) == 0){
}else if(strcmp(type, "boat") == 0){
mi->m_vehicleType = VEHICLE_TYPE_BOAT;
}else if(strncmp(type, "train", 6) == 0){
}else if(strcmp(type, "train") == 0){
mi->m_vehicleType = VEHICLE_TYPE_TRAIN;
}else if(strncmp(type, "heli", 5) == 0){
}else if(strcmp(type, "heli") == 0){
mi->m_vehicleType = VEHICLE_TYPE_HELI;
}else if(strncmp(type, "plane", 6) == 0){
}else if(strcmp(type, "plane") == 0){
mi->m_planeLodId = misc;
mi->m_wheelScale = 1.0f;
mi->m_vehicleType = VEHICLE_TYPE_PLANE;
}else if(strncmp(type, "bike", 5) == 0){
}else if(strcmp(type, "bike") == 0){
mi->m_bikeSteerAngle = misc;
mi->m_wheelScale = wheelScale;
mi->m_vehicleType = VEHICLE_TYPE_BIKE;
@ -866,29 +888,29 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId);
if(strncmp(vehclass, "normal", 7) == 0)
if(strcmp(vehclass, "normal") == 0)
mi->m_vehicleClass = CCarCtrl::NORMAL;
else if(strncmp(vehclass, "poorfamily", 11) == 0)
else if(strcmp(vehclass, "poorfamily") == 0)
mi->m_vehicleClass = CCarCtrl::POOR;
else if(strncmp(vehclass, "richfamily", 11) == 0)
else if(strcmp(vehclass, "richfamily") == 0)
mi->m_vehicleClass = CCarCtrl::RICH;
else if(strncmp(vehclass, "executive", 10) == 0)
else if(strcmp(vehclass, "executive") == 0)
mi->m_vehicleClass = CCarCtrl::EXEC;
else if(strncmp(vehclass, "worker", 7) == 0)
else if(strcmp(vehclass, "worker") == 0)
mi->m_vehicleClass = CCarCtrl::WORKER;
else if(strncmp(vehclass, "big", 4) == 0)
else if(strcmp(vehclass, "big") == 0)
mi->m_vehicleClass = CCarCtrl::BIG;
else if(strncmp(vehclass, "taxi", 5) == 0)
else if(strcmp(vehclass, "taxi") == 0)
mi->m_vehicleClass = CCarCtrl::TAXI;
else if(strncmp(vehclass, "moped", 6) == 0)
else if(strcmp(vehclass, "moped") == 0)
mi->m_vehicleClass = CCarCtrl::MOPED;
else if(strncmp(vehclass, "motorbike", 10) == 0)
else if(strcmp(vehclass, "motorbike") == 0)
mi->m_vehicleClass = CCarCtrl::MOTORBIKE;
else if(strncmp(vehclass, "leisureboat", 12) == 0)
else if(strcmp(vehclass, "leisureboat") == 0)
mi->m_vehicleClass = CCarCtrl::LEISUREBOAT;
else if(strncmp(vehclass, "workerboat", 11) == 0)
else if(strcmp(vehclass, "workerboat") == 0)
mi->m_vehicleClass = CCarCtrl::WORKERBOAT;
else if(strncmp(vehclass, "ignore", 11) == 0){
else if(strcmp(vehclass, "ignore") == 0) {
mi->m_vehicleClass = -1;
return;
}
@ -995,7 +1017,7 @@ CFileLoader::Load2dEffect(const char *line)
CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle"));
mi = CModelInfo::GetModelInfo(id);
effect = CModelInfo::Get2dEffectStore().alloc();
effect = CModelInfo::Get2dEffectStore().Alloc();
mi->Add2dEffect(effect);
effect->pos = CVector(x, y, z);
effect->col = CRGBA(r, g, b, a);
@ -1103,13 +1125,13 @@ CFileLoader::LoadScene(const char *filename)
continue;
if(section == NONE){
if(strncmp(line, "inst", 4) == 0) section = INST;
else if(strncmp(line, "zone", 4) == 0) section = ZONE;
else if(strncmp(line, "cull", 4) == 0) section = CULL;
else if(strncmp(line, "pick", 4) == 0) section = PICK;
else if(strncmp(line, "path", 4) == 0) section = PATH;
else if(strncmp(line, "occl", 4) == 0) section = OCCL;
}else if(strncmp(line, "end", 3) == 0){
if(isLine4(line, 'i','n','s','t')) section = INST;
else if(isLine4(line, 'z','o','n','e')) section = ZONE;
else if(isLine4(line, 'c','u','l','l')) section = CULL;
else if(isLine4(line, 'p','i','c','k')) section = PICK;
else if(isLine4(line, 'p','a','t','h')) section = PATH;
else if(isLine4(line, 'o','c','c','l')) section = OCCL;
}else if(isLine3(line, 'e','n','d')){
section = NONE;
}else switch(section){
case INST:
@ -1307,11 +1329,11 @@ CFileLoader::ReloadPaths(const char *filename)
continue;
if (section == NONE) {
if (strncmp(line, "path", 4) == 0) {
if (isLine4(line, 'p','a','t','h')) {
section = PATH;
ThePaths.AllocatePathFindInfoMem(4500);
}
} else if (strncmp(line, "end", 3) == 0) {
} else if (isLine3(line, 'e','n','d')) {
section = NONE;
} else {
switch (section) {
@ -1362,10 +1384,10 @@ CFileLoader::ReloadObjectTypes(const char *filename)
continue;
if (section == NONE) {
if (strncmp(line, "objs", 4) == 0) section = OBJS;
else if (strncmp(line, "tobj", 4) == 0) section = TOBJ;
else if (strncmp(line, "2dfx", 4) == 0) section = TWODFX;
} else if (strncmp(line, "end", 3) == 0) {
if (isLine4(line, 'o','b','j','s')) section = OBJS;
else if (isLine4(line, 't','o','b','j')) section = TOBJ;
else if (isLine4(line, '2','d','f','x')) section = TWODFX;
} else if (isLine3(line, 'e','n','d')) {
section = NONE;
} else {
switch (section) {
@ -1438,7 +1460,7 @@ CFileLoader::ReLoadScene(const char *filename)
if (*line == '#')
continue;
if (strncmp(line, "EXIT", 9) == 0) // BUG: 9?
if (strncmp(line, "EXIT", 4) == 0)
break;
if (strncmp(line, "IDE", 3) == 0) {

View File

@ -240,20 +240,22 @@ CFileMgr::SetDirMyDocuments(void)
mychdir(_psGetUserFilesFolder());
}
size_t
ssize_t
CFileMgr::LoadFile(const char *file, uint8 *buf, int unused, const char *mode)
{
int fd;
size_t n, len;
ssize_t n, len;
fd = myfopen(file, mode);
if(fd == 0)
return 0;
return -1;
len = 0;
do{
n = myfread(buf + len, 1, 0x4000, fd);
if(n < 0)
#ifndef FIX_BUGS
if (n < 0)
return -1;
#endif
len += n;
}while(n == 0x4000);
buf[len] = 0;
@ -274,13 +276,13 @@ CFileMgr::OpenFileForWriting(const char *file)
}
size_t
CFileMgr::Read(int fd, const char *buf, size_t len)
CFileMgr::Read(int fd, const char *buf, ssize_t len)
{
return myfread((void*)buf, 1, len, fd);
}
size_t
CFileMgr::Write(int fd, const char *buf, size_t len)
CFileMgr::Write(int fd, const char *buf, ssize_t len)
{
return myfwrite((void*)buf, 1, len, fd);
}

View File

@ -9,12 +9,12 @@ public:
static void ChangeDir(const char *dir);
static void SetDir(const char *dir);
static void SetDirMyDocuments(void);
static size_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
static ssize_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
static int OpenFile(const char *file, const char *mode);
static int OpenFile(const char *file) { return OpenFile(file, "rb"); }
static int OpenFileForWriting(const char *file);
static size_t Read(int fd, const char *buf, size_t len);
static size_t Write(int fd, const char *buf, size_t len);
static size_t Read(int fd, const char *buf, ssize_t len);
static size_t Write(int fd, const char *buf, ssize_t len);
static bool Seek(int fd, int offset, int whence);
static bool ReadLine(int fd, char *buf, int len);
static int CloseFile(int fd);

View File

@ -46,7 +46,7 @@ CFire::ProcessFire(void)
float fDamagePlayer;
float fDamagePeds;
float fDamageVehicle;
int8 nRandNumber;
int16 nRandNumber;
float fGreen;
float fRed;
CVector lightpos;
@ -107,7 +107,11 @@ CFire::ProcessFire(void)
}
}
}
if (!FindPlayerVehicle() && !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof)
if (!FindPlayerVehicle() &&
#ifdef FIX_BUGS
FindPlayerPed() &&
#endif
!FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof)
&& ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) {
FindPlayerPed()->DoStuffToGoOnFire();
gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1);
@ -148,11 +152,10 @@ CFire::ProcessFire(void)
CShadows::StoreStaticShadow((uintptr)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos, 7.0f, 0.0f, 0.0f, -7.0f, 0, nRandNumber / 2,
nRandNumber / 2, 0, 10.0f, 1.0f, 40.0f, 0, 0.0f);
}
fGreen = nRandNumber / 128;
fRed = nRandNumber / 128;
fGreen = nRandNumber / 128.f;
fRed = nRandNumber / 128.f;
CPointLights::AddLight(0, m_vecPos, CVector(0.0f, 0.0f, 0.0f),
12.0f, fRed, fGreen, 0, 0, 0);
CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0.0f, 0, 0);
} else {
Extinguish();
}
@ -391,19 +394,16 @@ CFireManager::ExtinguishPoint(CVector point, float range)
bool
CFireManager::ExtinguishPointWithWater(CVector point, float range)
{
int fireI = 0;
for (int i = 0; i < NUM_FIRES; i++) {
if (m_aFires[i].m_bIsOngoing) {
if ((point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) {
fireI = i;
break;
}
}
}
if (fireI == NUM_FIRES)
return false;
CFire *fireToExtinguish = &m_aFires[fireI];
int i;
for (i = 0; i < NUM_FIRES;) {
if (m_aFires[i].m_bIsOngoing && (point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) {
break;
}
if (++i >= NUM_FIRES)
return false;
}
CFire *fireToExtinguish = &m_aFires[i];
fireToExtinguish->m_fWaterExtinguishCountdown -= 0.012f * CTimer::GetTimeStep();
CVector steamPos = fireToExtinguish->m_vecPos +
CVector((CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f,

File diff suppressed because it is too large Load Diff

View File

@ -4,13 +4,14 @@
#else
#include "Sprite2d.h"
#include "Timer.h"
#define MENUHEADER_POS_X 10.0f
#define MENUHEADER_POS_Y 10.0f
#define MENUHEADER_HEIGHT 2.0f
#define MENUHEADER_WIDTH 1.0f
#define MENU_UNK_X_MARGIN 10.0f
#define MENU_X_MARGIN 10.0f
#define MENUACTION_SCALE_MULT 0.9f
@ -22,24 +23,36 @@
#define MENU_DEFAULT_CONTENT_Y 100
#define MENU_DEFAULT_LINE_HEIGHT 29
#define MENURADIO_ICON_SCALE 60.0f
#define RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin) (xMargin + 30.0f)
#define MENURADIO_ICON_FIRST_X 238.f
#define MENURADIO_ICON_Y 288.0f
#define MENURADIO_ICON_SIZE 60.0f
#define MENURADIO_SELECTOR_START_Y 285.f // other options should leave room on the screen
#define MENURADIO_SELECTOR_HEIGHT 65.f
#define MENUSLIDER_X 500.0f
#define MENUSLIDER_UNK 100.0f
#define MENUSLIDER_SMALLEST_BAR 8.0f
#define MENUSLIDER_BIGGEST_BAR 25.0f
#define BIGTEXT2_X_SCALE 0.6f
#define BIGTEXT2_X_SCALE 0.6f // For FONT_STANDARD
#define BIGTEXT2_Y_SCALE 1.2f
#define BIGTEXT_X_SCALE 0.6f
#define BIGTEXT_X_SCALE 0.6f // For FONT_HEADING
#define BIGTEXT_Y_SCALE 1.0f
#define MEDIUMTEXT_X_SCALE 0.48f
#define MEDIUMTEXT_X_SCALE 0.48f // For FONT_STANDARD
#define MEDIUMTEXT_Y_SCALE 1.0f
#define SMALLTEXT_X_SCALE 0.42f
#define SMALLTEXT_X_SCALE 0.42f // For FONT_STANDARD
#define SMALLTEXT_Y_SCALE 0.9f
#define SMALLESTTEXT_X_SCALE 0.3f
#define SMALLESTTEXT_X_SCALE 0.3f // For FONT_STANDARD
#define SMALLESTTEXT_Y_SCALE 0.7f
#define LISTITEM_X_SCALE 0.4f // Only unproportional and commonly used scale for FONT_STANDARD
#define LISTITEM_Y_SCALE 0.6f
#define HELPER_TEXT_RIGHT_MARGIN MENU_X_MARGIN
#define HELPER_TEXT_BOTTOM_MARGIN 18.f
#define PLAYERSETUP_LIST_TOP 58.0f
#define PLAYERSETUP_LIST_BOTTOM 95.0f
#define PLAYERSETUP_LIST_LEFT 200.0f
@ -51,8 +64,6 @@
#endif
#define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f
#define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64
#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f
#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f
#define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f
#define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f
#define PLAYERSETUP_LIST_BODY_TOP 77
@ -80,16 +91,15 @@
#define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f
#define CONTSETUP_BOUND_HIGHLIGHT_HEIGHT 10
#define CONTSETUP_BOUND_COLUMN_WIDTH 190.0f
#define CONTSETUP_LIST_HEADER_HEIGHT 20.0f
#define CONTSETUP_LIST_TOP 28.0f
#define CONTSETUP_LIST_TOP 58.0f
#define CONTSETUP_LIST_RIGHT 18.0f
#define CONTSETUP_LIST_BOTTOM 120.0f
#define CONTSETUP_LIST_LEFT 18.0f
#define CONTSETUP_LIST_BOTTOM 78.0f
#define CONTSETUP_LIST_LEFT 30.0f
#define CONTSETUP_COLUMN_1_X 40.0f
#define CONTSETUP_COLUMN_2_X 210.0f
#define CONTSETUP_COLUMN_3_X (CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH + 10.0f)
#define CONTSETUP_BACK_RIGHT 35.0f
#define CONTSETUP_BACK_BOTTOM 122.0f
#define CONTSETUP_BACK_BOTTOM 82.0f
#define CONTSETUP_BACK_HEIGHT 25.0f
enum
@ -182,7 +192,6 @@ enum eMenuScreen
MENUPAGE_MOUSE_CONTROLS = 31,
MENUPAGE_PAUSE_MENU = 32,
MENUPAGE_NONE = 33, // Then chooses main menu or pause menu
MENUPAGE_OUTRO = 34,
#ifdef LEGACY_MENU_OPTIONS
MENUPAGE_CONTROLLER_SETTINGS,
MENUPAGE_DEBUG_MENU,
@ -192,14 +201,26 @@ enum eMenuScreen
MENUPAGE_CONTROLLER_PC_OLD4,
MENUPAGE_CONTROLLER_DEBUG,
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
#ifdef GRAPHICS_MENU_OPTIONS
MENUPAGE_GRAPHICS_SETTINGS,
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
MENUPAGE_DETECT_JOYSTICK,
#endif
#endif
MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages
MENUPAGES
};
enum eMenuAction
{
#ifdef CUSTOM_FRONTEND_OPTIONS
MENUACTION_CFO_SELECT = -2,
MENUACTION_CFO_DYNAMIC = -1,
#endif
MENUACTION_NOTHING,
MENUACTION_LABEL,
MENUACTION_YES,
@ -254,29 +275,10 @@ enum eMenuAction
MENUACTION_DRAWDIST,
MENUACTION_MOUSESENS,
MENUACTION_MP3VOLUMEBOOST,
#ifdef IMPROVED_VIDEOMODE
MENUACTION_SCREENFORMAT,
#endif
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_CTRLVIBRATION,
MENUACTION_CTRLCONFIG,
#endif
#ifdef ANISOTROPIC_FILTERING
MENUACTION_MIPMAPS,
MENUACTION_TEXTURE_FILTERING,
#endif
#ifdef MULTISAMPLING
MENUACTION_MULTISAMPLING,
#endif
#ifdef NO_ISLAND_LOADING
MENUACTION_ISLANDLOADING,
#endif
#ifdef PS2_ALPHA_TEST
MENUACTION_PS2_ALPHA_TEST,
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
MENUACTION_CUTSCENEBORDERS,
#endif
};
enum eCheckHover
@ -303,16 +305,8 @@ enum eCheckHover
HOVEROPTION_LIST, // also layer in controller setup and skin menu
HOVEROPTION_SKIN,
HOVEROPTION_USESKIN, // also layer in controller setup and skin menu
HOVEROPTION_RADIO_0,
HOVEROPTION_RADIO_1,
HOVEROPTION_RADIO_2,
HOVEROPTION_RADIO_3,
HOVEROPTION_RADIO_4,
HOVEROPTION_RADIO_5,
HOVEROPTION_RADIO_6,
HOVEROPTION_RADIO_7,
HOVEROPTION_RADIO_8,
HOVEROPTION_RADIO_9,
HOVEROPTION_NEXT_RADIO,
HOVEROPTION_PREV_RADIO,
HOVEROPTION_INCREASE_BRIGHTNESS,
HOVEROPTION_DECREASE_BRIGHTNESS,
HOVEROPTION_INCREASE_DRAWDIST,
@ -330,8 +324,8 @@ enum eCheckHover
enum
{
#ifdef LEGACY_MENU_OPTIONS
NUM_MENUROWS = 14,
#if defined LEGACY_MENU_OPTIONS || defined CUSTOM_FRONTEND_OPTIONS
NUM_MENUROWS = 18,
#else
NUM_MENUROWS = 12,
#endif
@ -347,7 +341,7 @@ enum eControlMethod
enum ControllerSetupColumn
{
CONTSETUP_PED_COLUMN = 0,
CONTSETUP_VEHICLE_COLUMN = 14,
CONTSETUP_VEHICLE_COLUMN = 16,
};
struct tSkinInfo
@ -365,6 +359,7 @@ struct BottomBarOption
int32 screenId;
};
#ifndef CUSTOM_FRONTEND_OPTIONS
struct CMenuScreen
{
char m_ScreenName[8];
@ -382,6 +377,88 @@ struct CMenuScreen
uint8 m_Align;
} m_aEntries[NUM_MENUROWS];
};
extern CMenuScreen aScreens[MENUPAGES];
#else
#include "frontendoption.h"
struct CCustomScreenLayout {
int startX; // not used at all if first entry has X and Y values
int startY; // not used at all if first entry has X and Y values
int lineHeight; // used to determine next entry's Y coordinate, if it has 0-0 as coordinates
bool showLeftRightHelper;
bool noInvasiveBorders; // not needed on pages already handled by game
int xMargin; // useful for two part texts - 0/empty = MENU_X_MARGIN
};
struct CCFO
{
int8 *value;
const char *save;
};
struct CCFOSelect : CCFO
{
char** rightTexts;
int8 numRightTexts;
bool onlyApplyOnEnter;
int8 displayedValue; // only if onlyApplyOnEnter enabled for now
int8 lastSavedValue; // only if onlyApplyOnEnter enabled
ChangeFunc changeFunc;
CCFOSelect() {};
CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc){
this->value = value;
if (value)
this->lastSavedValue = this->displayedValue = *value;
this->save = save;
this->rightTexts = (char**)rightTexts;
this->numRightTexts = numRightTexts;
this->onlyApplyOnEnter = onlyApplyOnEnter;
this->changeFunc = changeFunc;
}
};
struct CCFODynamic : CCFO
{
DrawFunc drawFunc;
ButtonPressFunc buttonPressFunc;
CCFODynamic() {};
CCFODynamic(int8* value, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){
this->value = value;
this->save = save;
this->drawFunc = drawFunc;
this->buttonPressFunc = buttonPressFunc;
}
};
struct CMenuScreenCustom
{
char m_ScreenName[8];
int32 m_PreviousPage; // eMenuScreen
CCustomScreenLayout *layout;
ReturnPrevPageFunc returnPrevPageFunc;
struct CMenuEntry
{
int32 m_Action; // eMenuAction - below zero is CFO
char m_EntryName[8];
struct {
union {
CCFO *m_CFO; // for initializing
CCFOSelect *m_CFOSelect;
CCFODynamic *m_CFODynamic;
};
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen
};
uint16 m_X;
uint16 m_Y;
uint8 m_Align;
} m_aEntries[NUM_MENUROWS];
};
extern CMenuScreenCustom aScreens[MENUPAGES];
#endif
struct MenuTrapezoid
{
@ -473,7 +550,7 @@ public:
int8 m_PrefsShowSubtitles;
int8 m_PrefsShowLegends;
int8 m_PrefsUseWideScreen;
int8 m_PrefsVsync; // TODO(Miami): Are we sure?
int8 m_PrefsVsync;
int8 m_PrefsVsyncDisp;
int8 m_PrefsFrameLimiter;
int8 m_nPrefsAudio3DProviderIndex;
@ -481,7 +558,7 @@ public:
int8 m_PrefsDMA;
int8 m_PrefsSfxVolume;
int8 m_PrefsMusicVolume;
uint8 m_PrefsRadioStation;
int8 m_PrefsRadioStation;
uint8 m_PrefsStereoMono; // unused except restore settings
int32 m_nCurrOption;
bool m_bQuitGameNoCD;
@ -501,7 +578,7 @@ public:
int32 field_54;
int8 m_bLanguageLoaded;
uint8 m_PrefsAllowNastyGame;
uint8 m_PrefsMP3BoostVolume;
int8 m_PrefsMP3BoostVolume;
uint8 m_ControlMethod;
int32 m_nPrefsVideoMode;
int32 m_nDisplayVideoMode;
@ -514,10 +591,10 @@ public:
uint8 field_74[4];
int32 *pControlEdit;
bool m_OnlySaveMenu;
int32 m_menuTransitionProgress;
int32 m_firstStartCounter;
CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES];
bool m_bSpritesLoaded;
int32 field_F0;
int32 m_LeftMostRadioX;
int32 m_ScrollRadioBy;
int32 m_nCurrScreen;
int32 m_nPrevScreen;
@ -621,20 +698,34 @@ public:
ISLAND_LOADING_HIGH
};
static int8 m_DisplayIslandLoading;
static int8 m_PrefsIslandLoading;
int8 m_PrefsIslandLoading;
#define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
#define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
#define ISLAND_LOADING_IS(p) if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
#define ISLAND_LOADING_ISNT(p) if (FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
#else
#define ISLAND_LOADING_IS(p)
#define ISLAND_LOADING_ISNT(p)
#endif
#ifdef XBOX_MESSAGE_SCREEN
static uint32 m_nDialogHideTimer;
static PauseModeTime m_nDialogHideTimerPauseMode;
static bool m_bDialogOpen;
static wchar *m_pDialogText;
static bool m_bSaveWasSuccessful;
static void SetDialogText(const char*);
static bool DialogTextCmp(const char*);
static void ToggleDialog(bool);
static void SetDialogTimer(uint32);
void ProcessDialogTimer(void);
void DrawOverlays(void);
void CloseDialog(void);
#endif
void Initialise();
void PrintMap();
void SetFrontEndRenderStates();
static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2);
static void CentreMousePointer();
void CheckCodesForControls(int);
bool CheckHover(int x1, int x2, int y1, int y2);
@ -651,7 +742,6 @@ public:
void DrawBackground(bool transitionCall);
void DrawPlayerSetupScreen(bool);
int FadeIn(int alpha);
void FilterOutColorMarkersFromString(wchar*);
int GetStartOptionsCntrlConfigScreens();
void InitialiseChangedLanguageSettings();
void LoadAllTextures();
@ -665,7 +755,7 @@ public:
void ProcessList(bool &optionSelected, bool &goBack);
void UserInput();
void ProcessUserInput(uint8, uint8, uint8, uint8, int8);
void ChangeRadioStation(uint8);
void ChangeRadioStation(int8);
void ProcessFileActions();
void ProcessOnOffMenuOptions();
void RequestFrontEndShutDown();
@ -679,8 +769,10 @@ public:
void UnloadTextures();
void WaitForUserCD();
int GetNumOptionsCntrlConfigScreens();
int ConstructStatLine(int);
void SwitchToNewScreen(int8);
void AdditionalOptionInput(bool &goBack);
void ExportStats(void);
void PrintRadioSelector(void);
// New (not in function or inlined in the game)
void ThingsToDoBeforeLeavingPage();
@ -698,6 +790,5 @@ VALIDATE_SIZE(CMenuManager, 0x688);
#endif
extern CMenuManager FrontEndMenuManager;
extern CMenuScreen aScreens[];
#endif

View File

@ -22,7 +22,7 @@
#include "Game.h"
#include "World.h"
#include "PlayerInfo.h"
#include "FrontendControls.h"
#include "FrontEndControls.h"
#include "MemoryCard.h"
#define CRect_SZ(x, y, w, h) CRect(x, y, x+w, y+h)
@ -3017,4 +3017,4 @@ CMenuManager::FilterOutColorMarkersFromString(wchar *string, CRGBA &color)
*dst = '\0';
}
#endif
#endif

View File

@ -32,6 +32,7 @@
#include "Fluff.h"
#include "Font.h"
#include "Frontend.h"
#include "frontendoption.h"
#include "GameLogic.h"
#include "Garages.h"
#include "GenericGameStorage.h"
@ -44,6 +45,7 @@
#include "MBlur.h"
#include "Messages.h"
#include "MemoryCard.h"
#include "MemoryHeap.h"
#include "Pad.h"
#include "Particle.h"
#include "ParticleObject.h"
@ -93,6 +95,10 @@
#include "WaterCreatures.h"
#include "postfx.h"
#include "custompipes.h"
#include "screendroplets.h"
#ifdef USE_TEXTURE_POOL
#include "TexturePools.h"
#endif
eLevelName CGame::currLevel;
int32 CGame::currArea;
@ -162,6 +168,11 @@ CGame::InitialiseOnceBeforeRW(void)
debug("size of dummy %d\n", sizeof(CDummy));
#ifdef EXTENDED_COLOURFILTER
CPostFX::InitOnce();
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
// Not needed here but may be needed in future
// if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0)
CustomFrontendOptionsPopulate();
#endif
return true;
}
@ -182,12 +193,22 @@ CGame::InitialiseRenderWare(void)
#ifdef USE_TEXTURE_POOL
_TexturePoolsInitialise();
#endif
CTxdStore::Initialise();
CVisibilityPlugins::Initialise();
#ifdef GTA_PS2
RpSkySelectTrueTSClipper(TRUE);
RpSkySelectTrueTLClipper(TRUE);
// PS2ManagerApplyDirectionalLightingCB() uploads the GTA lights
// directly without going through RpWorld and all that
SetupPS2ManagerDefaultLightingCallback();
PreAllocateRwObjects();
#endif
/* Create camera */
Scene.camera = CameraCreate(RsGlobal.width, RsGlobal.height, TRUE);
Scene.camera = CameraCreate(SCREEN_WIDTH, SCREEN_HEIGHT, TRUE);
ASSERT(Scene.camera != nil);
if (!Scene.camera)
{
@ -217,7 +238,7 @@ CGame::InitialiseRenderWare(void)
/* Add the camera to the world */
RpWorldAddCamera(Scene.world, Scene.camera);
LightsCreate(Scene.world);
CreateDebugFont();
#ifdef LIBRW
@ -234,23 +255,39 @@ CGame::InitialiseRenderWare(void)
ReplaceAtomicPipeCallback();
#endif // PS2_ALPHA_TEST
#endif // LIBRW
PUSH_MEMID(MEMID_TEXTURES);
CFont::Initialise();
CHud::Initialise();
CPlayerSkin::Initialise();
POP_MEMID();
#ifdef EXTENDED_PIPELINES
CustomPipes::CustomPipeInit(); // need Scene.world for this
#endif
#ifdef SCREEN_DROPLETS
ScreenDroplets::InitDraw();
#endif
return (true);
}
void CGame::ShutdownRenderWare(void)
{
#ifdef SCREEN_DROPLETS
ScreenDroplets::Shutdown();
#endif
#ifdef EXTENDED_PIPELINES
CustomPipes::CustomPipeShutdown();
#endif
DestroySplashScreen();
CHud::Shutdown();
CFont::Shutdown();
for ( int32 i = 0; i < NUMPLAYERS; i++ )
CWorld::Players[i].DeletePlayerSkin();
CPlayerSkin::Shutdown();
DestroyDebugFont();
@ -282,7 +319,12 @@ bool CGame::InitialiseOnceAfterRW(void)
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
CTimeCycle::Initialise();
#ifdef GTA_PS2
LoadingScreen("Loading the Game", "Initialising audio", GetRandomSplashScreen());
#endif
DMAudio.Initialise();
#ifndef GTA_PS2
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER;
@ -299,6 +341,7 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume);
DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127);
#endif
return true;
}
@ -314,23 +357,40 @@ bool CGame::Initialise(const char* datFile)
{
ResetLoadingScreenBar();
strcpy(aDatFile, datFile);
#ifdef GTA_PS2
// TODO: upload VU0 collision code here
#endif
CPools::Initialise();
#ifndef GTA_PS2
CIniFile::LoadIniFile();
#endif
#ifdef USE_TEXTURE_POOL
_TexturePoolsUnknown(false);
#endif
currLevel = LEVEL_BEACH;
currArea = AREA_MAIN_MAP;
PUSH_MEMID(MEMID_TEXTURES);
LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen());
gameTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(gameTxdSlot);
CTxdStore::AddRef(gameTxdSlot);
LoadingScreen("Loading the Game", "Loading particles", nil);
int particleTxdSlot = CTxdStore::AddTxdSlot("particle");
CTxdStore::LoadTxd(particleTxdSlot, "MODELS/PARTICLE.TXD");
CTxdStore::AddRef(particleTxdSlot);
CTxdStore::SetCurrentTxd(gameTxdSlot);
LoadingScreen("Loading the Game", "Setup game variables", nil);
POP_MEMID();
#ifdef GTA_PS2
CDma::SyncChannel(0, true);
#endif
CGameLogic::InitAtStartOfGame();
CReferences::Init();
TheCamera.Init();
@ -350,21 +410,32 @@ bool CGame::Initialise(const char* datFile)
CMessages::ClearAllMessagesDisplayedByGame();
CRecordDataForGame::Init();
CRestart::Initialise();
PUSH_MEMID(MEMID_WORLD);
CWorld::Initialise();
POP_MEMID();
PUSH_MEMID(MEMID_TEXTURES);
CParticle::Initialise();
#ifdef PS2
gStartX = -180.0f;
gStartY = 180.0f;
gStartZ = 14.0f;
#endif
POP_MEMID();
PUSH_MEMID(MEMID_ANIMATION);
CAnimManager::Initialise();
CCutsceneMgr::Initialise();
POP_MEMID();
PUSH_MEMID(MEMID_CARS);
CCarCtrl::Init();
POP_MEMID();
PUSH_MEMID(MEMID_DEF_MODELS);
InitModelIndices();
CModelInfo::Initialise();
CPickups::Init();
CTheCarGenerators::Init();
CdStreamAddImage("MODELS\\GTA3.IMG");
CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel(datFile);
#ifdef EXTENDED_PIPELINES
@ -376,17 +447,21 @@ bool CGame::Initialise(const char* datFile)
CVehicleModelInfo::LoadVehicleColours();
CVehicleModelInfo::LoadEnvironmentMaps();
CTheZones::PostZoneCreation();
POP_MEMID();
LoadingScreen("Loading the Game", "Setup paths", nil);
ThePaths.PreparePathData();
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
CWorld::Players[0].LoadPlayerSkin();
TestModelIndices();
LoadingScreen("Loading the Game", "Setup water", nil);
WaterLevelInitialise("DATA\\WATER.DAT");
TheConsole.Init();
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
LoadingScreen("Loading the Game", "Setup streaming", nil);
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
@ -394,22 +469,32 @@ bool CGame::Initialise(const char* datFile)
CStreaming::LoadAllRequestedModels(false);
CStreaming::RemoveIslandsNotUsed(currLevel);
printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d
LoadingScreen("Loading the Game", "Load animations", GetRandomSplashScreen());
PUSH_MEMID(MEMID_ANIMATION);
CAnimManager::LoadAnimFiles();
POP_MEMID();
CStreaming::LoadInitialWeapons();
CStreaming::LoadAllRequestedModels(0);
CPed::Initialise();
CRouteNode::Initialise();
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
ScreenDroplets::Initialise();
#endif
LoadingScreen("Loading the Game", "Find big buildings", nil);
CRenderer::Init();
LoadingScreen("Loading the Game", "Setup game variables", nil);
CRadar::Initialise();
CRadar::LoadTextures();
CWeapon::InitialiseWeapons();
LoadingScreen("Loading the Game", "Setup traffic lights", nil);
CTrafficLights::ScanForLightsOnMap();
CRoadBlocks::Init();
LoadingScreen("Loading the Game", "Setup game variables", nil);
CPopulation::Initialise();
CWorld::PlayerInFocus = 0;
@ -420,10 +505,16 @@ bool CGame::Initialise(const char* datFile)
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
#ifdef GTA_SCENE_EDIT
CSceneEdit::Initialise();
#endif
LoadingScreen("Loading the Game", "Load scripts", nil);
PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Init();
CGangs::Initialise();
POP_MEMID();
LoadingScreen("Loading the Game", "Setup game variables", nil);
CClock::Initialise(1000);
CHeli::InitHelis();
@ -439,24 +530,26 @@ bool CGame::Initialise(const char* datFile)
CWaterCannons::Init();
CBridge::Init();
CGarages::Init();
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
CTrain::InitTrains();
CPlane::InitPlanes();
CCredits::Init();
CRecordDataForChase::Init();
CReplay::Init();
LoadingScreen("Loading the Game", "Start script", nil);
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad )
#endif
{
#endif
LoadingScreen("Loading the Game", "Start script", nil);
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
#ifdef PS2_MENU
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
}
#endif
LoadingScreen("Loading the Game", "Load scene", nil);
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
@ -481,9 +574,7 @@ bool CGame::ShutDown(void)
CScriptPaths::Shutdown();
CWaterCreatures::RemoveAll();
CSpecialFX::Shutdown();
#ifndef PS2
CGarages::Shutdown();
#endif
CMovingThings::Shutdown();
gPhoneInfo.Shutdown();
CWeapon::ShutdownWeapons();
@ -537,13 +628,11 @@ void CGame::ReInitGameObjectVariables(void)
CGameLogic::InitAtStartOfGame();
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad )
#endif
{
#endif
TheCamera.Init();
TheCamera.SetRwCamera(Scene.camera);
#ifdef PS2_MENU
TheCamera.Init();
TheCamera.SetRwCamera(Scene.camera);
}
#endif
CDebug::DebugInitTextBuffer();
CWeather::Init();
CUserDisplay::Init();
@ -552,11 +641,6 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::bDoingCarCollisions = false;
CHud::ReInitialise();
CRadar::Initialise();
#ifdef PS2
gStartX = -180.0f;
gStartY = 180.0f;
gStartZ = 14.0f;
#endif
CCarCtrl::ReInit();
CTimeCycle::Initialise();
CDraw::SetFOV(120.0f);
@ -568,6 +652,9 @@ void CGame::ReInitGameObjectVariables(void)
currArea = AREA_MAIN_MAP;
CPed::Initialise();
CEventList::Initialise();
#ifdef SCREEN_DROPLETS
ScreenDroplets::Initialise();
#endif
CWeapon::InitialiseWeapons();
CPopulation::Initialise();
@ -575,15 +662,15 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::Players[i].Clear();
CWorld::PlayerInFocus = 0;
#ifdef PS2
CWeaponEffects::Init();
CSkidmarks::Init();
#endif
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Init();
CGangs::Initialise();
POP_MEMID();
CTimer::Initialise();
CClock::Initialise(1000);
CTheCarGenerators::Init();
@ -594,10 +681,6 @@ void CGame::ReInitGameObjectVariables(void)
CPickups::Init();
CPacManPickups::Init();
CGarages::Init();
#ifdef PS2
CClouds::Init();
CRemote::Init();
#endif
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
@ -667,8 +750,10 @@ void CGame::InitialiseWhenRestarting(void)
if (b_FoundRecentSavedGameWantToLoad || FrontEndMenuManager.m_bWantToLoad)
{
LoadSplash("splash1");
#ifndef XBOX_MESSAGE_SCREEN
if (FrontEndMenuManager.m_bWantToLoad)
FrontEndMenuManager.MessageScreen("FELD_WR", true);
#endif
}
b_FoundRecentSavedGameWantToLoad = false;
@ -677,6 +762,14 @@ void CGame::InitialiseWhenRestarting(void)
if ( FrontEndMenuManager.m_bWantToLoad == true )
{
#ifdef XBOX_MESSAGE_SCREEN
FrontEndMenuManager.SetDialogTimer(1000);
DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 0);
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
FrontEndMenuManager.DrawOverlays();
DoRWStuffEndOfFrame();
#endif
RestoreForStartLoad();
}
@ -685,8 +778,7 @@ void CGame::InitialiseWhenRestarting(void)
if ( FrontEndMenuManager.m_bWantToLoad == true )
{
FrontEndMenuManager.m_bWantToLoad = false;
// TODO(Miami)
//InitRadioStationPositionList();
InitRadioStationPositionList();
if ( GenericLoad() == true )
{
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
@ -710,6 +802,9 @@ void CGame::InitialiseWhenRestarting(void)
currLevel = LEVEL_GENERIC;
CCollision::SortOutCollisionAfterLoad();
}
#ifdef XBOX_MESSAGE_SCREEN
FrontEndMenuManager.ProcessDialogTimer();
#endif
}
CTimer::Update();
@ -723,15 +818,17 @@ void CGame::InitialiseWhenRestarting(void)
void CGame::Process(void)
{
CPad::UpdatePads();
#ifdef GTA_PS2
#ifdef USE_CUSTOM_ALLOCATOR
ProcessTidyUpMemory();
#endif
#ifdef DEBUGMENU
DebugMenuProcess();
#endif
CCutsceneMgr::Update();
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process();
CTheZones::Update();
// DRM call in here
uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
@ -748,7 +845,11 @@ void CGame::Process(void)
CPad::DoCheats();
CClock::Update();
CWeather::Update();
PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Process();
POP_MEMID();
CCollision::Update();
CScriptPaths::Update();
CTrain::UpdateTrains();
@ -758,7 +859,9 @@ void CGame::Process(void)
CSkidmarks::Update();
CAntennas::Update();
CGlass::Update();
#ifdef GTA_SCENE_EDIT
CSceneEdit::Update();
#endif
CSetPieces::Update();
CEventList::Update();
CParticle::Update();
@ -780,7 +883,11 @@ void CGame::Process(void)
CWaterCannons::Update();
CUserDisplay::Process();
CReplay::Update();
PUSH_MEMID(MEMID_WORLD);
CWorld::Process();
POP_MEMID();
gAccidentManager.Update();
CPacManPickups::Update();
CPickups::Update();
@ -802,13 +909,377 @@ void CGame::Process(void)
gPhoneInfo.Update();
if (!CReplay::IsPlayingBack())
{
PUSH_MEMID(MEMID_CARS);
if (processTime < 2)
CCarCtrl::GenerateRandomCars();
CRoadBlocks::GenerateRoadBlocks();
CCarCtrl::RemoveDistantCars();
CCarCtrl::RemoveCarsIfThePoolGetsFull();
POP_MEMID();
}
}
#ifdef GTA_PS2
CMemCheck::DoTest();
#endif
}
#ifdef USE_CUSTOM_ALLOCATOR
// TODO(MIAMI)
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
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 moveTextures, bool flushDraw)
{
#ifdef USE_CUSTOM_ALLOCATOR
printf("Largest free block before tidy %d\n", gMainHeap.GetLargestFreeBlock());
if (moveTextures) {
if (flushDraw) {
#ifdef GTA_PS2
for (int i = 0; i < sweMaxFlips + 1; i++) {
#else
for (int i = 0; i < 5; i++) { // probably more than needed
#endif
RwCameraBeginUpdate(Scene.camera);
RwCameraEndUpdate(Scene.camera);
RwCameraShowRaster(Scene.camera, nil, 0);
}
}
int fontSlot = CTxdStore::FindTxdSlot("fonts");
for (int i = 0; i < TXDSTORESIZE; i++) {
if (i == fontSlot ||
CTxdStore::GetSlot(i) == nil)
continue;
RwTexDictionary* txd = CTxdStore::GetSlot(i)->texDict;
if (txd)
RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, nil);
}
}
// animations
for (int i = 0; i < NUMANIMATIONS; i++) {
CAnimBlendHierarchy* anim = CAnimManager::GetAnimation(i);
if (anim == nil)
continue; // cannot happen
anim->MoveMemory();
}
// model info
for (int i = 0; i < MODELINFOSIZE; i++) {
CBaseModelInfo* mi = CModelInfo::GetModelInfo(i);
if (mi == nil)
continue;
TidyUpModelInfo(mi, false);
}
printf("Largest free block after tidy %d\n", gMainHeap.GetLargestFreeBlock());
#endif
}
void CGame::ProcessTidyUpMemory(void)
{
#ifdef USE_CUSTOM_ALLOCATOR
static int32 modelIndex = 0;
static int32 animIndex = 0;
static int32 txdIndex = 0;
bool txdReturn = false;
RwTexDictionary* txd = nil;
gNumMemMoved = 0;
// model infos
for (int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++) {
CBaseModelInfo* mi;
do {
mi = CModelInfo::GetModelInfo(modelIndex);
modelIndex++;
if (modelIndex >= MODELINFOSIZE)
modelIndex = 0;
} while (mi == nil);
if (TidyUpModelInfo(mi, true))
return;
}
// tex dicts
for (int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++) {
if (gNumMemMoved > 80)
break;
do {
#ifdef FIX_BUGS
txd = nil;
#endif
if (CTxdStore::GetSlot(txdIndex))
txd = CTxdStore::GetSlot(txdIndex)->texDict;
txdIndex++;
if (txdIndex >= TXDSTORESIZE)
txdIndex = 0;
} while (txd == nil);
RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, &txdReturn);
if (txdReturn)
return;
}
// animations
CAnimBlendHierarchy* anim;
do {
anim = CAnimManager::GetAnimation(animIndex);
animIndex++;
if (animIndex >= NUMANIMATIONS)
animIndex = 0;
} while (anim == nil); // always != nil
anim->MoveMemory(true);
#endif
}
void
@ -831,33 +1302,6 @@ CGame::CanSeeWaterFromCurrArea(void)
bool
CGame::CanSeeOutSideFromCurrArea(void)
{
return currArea == AREA_MAIN_MAP || currArea == AREA_MALL ||
return currArea == AREA_MAIN_MAP || currArea == AREA_MALL ||
currArea == AREA_MANSION || currArea == AREA_HOTEL;
}
void CGame::DrasticTidyUpMemory(bool)
{
#ifdef USE_TEXTURE_POOL
// TODO
#endif
#ifdef PS2
// meow
#endif
}
void CGame::TidyUpMemory(bool unk1, bool unk2)
{
#ifdef PS2
// meow
#endif
if (unk2) {
DrasticTidyUpMemory(true); // parameter is unknown too
}
}
void CGame::ProcessTidyUpMemory(void)
{
#ifdef PS2
// meow
#endif
}

View File

@ -123,6 +123,15 @@ public:
return *str2 != '\0';
}
static bool faststrncmp(const char *str1, const char *str2, uint32 count)
{
for(uint32 i = 0; *str1 && i < count; str1++, str2++, i++) {
if (*str1 != *str2)
return true;
}
return false;
}
static bool faststricmp(const char *str1, const char *str2)
{
for (; *str1; str1++, str2++) {

View File

@ -2,44 +2,10 @@
#include "Frontend.h"
#ifdef PC_MENU
#ifdef CUTSCENE_BORDERS_SWITCH
#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen,
#else
#define MENU_CUTSCENE_BORDERS_SWITCH(screen)
#endif
#ifdef IMPROVED_VIDEOMODE
#define MENU_IMPROVED_VIDEOMODE(screen) MENUACTION_SCREENFORMAT, "FEM_SCF", SAVESLOT_NONE, screen,
#else
#define MENU_IMPROVED_VIDEOMODE(screen)
#endif
#ifdef ANISOTROPIC_FILTERING
#define MENU_MIPMAPS(screen) MENUACTION_MIPMAPS, "FED_MIP", SAVESLOT_NONE, screen,
#define MENU_TEXTURE_FILTERING(screen) MENUACTION_TEXTURE_FILTERING, "FED_FIL", SAVESLOT_NONE, screen,
#else
#define MENU_MIPMAPS(screen)
#define MENU_TEXTURE_FILTERING(screen)
#endif
#ifdef MULTISAMPLING
#define MENU_MULTISAMPLING(screen) MENUACTION_MULTISAMPLING, "FED_AAS", SAVESLOT_NONE, screen,
#else
#define MENU_MULTISAMPLING(screen)
#endif
#ifdef NO_ISLAND_LOADING
#define MENU_ISLAND_LOADING(screen) MENUACTION_ISLANDLOADING, "FEM_ISL", SAVESLOT_NONE, screen,
#else
#define MENU_ISLAND_LOADING(screen)
#endif
#ifdef PS2_ALPHA_TEST
#define MENU_PS2_ALPHA_TEST(screen) MENUACTION_PS2_ALPHA_TEST, "FEM_2PR", SAVESLOT_NONE, screen,
#else
#define MENU_PS2_ALPHA_TEST(screen)
#endif
// Please don't touch this file, except for bug fixing or ports.
// Check MenuScreensCustom.cpp
#ifndef CUSTOM_FRONTEND_OPTIONS
CMenuScreen aScreens[] = {
// MENUPAGE_STATS = 0
{ "FEH_STA", MENUPAGE_NONE, 3,
@ -72,7 +38,7 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
// MENUPAGE_GRAPHICS_SETTINGS = 4
// MENUPAGE_DISPLAY_SETTINGS = 4
#ifdef LEGACY_MENU_OPTIONS
#define Y_OFFSET 50
#else
@ -95,14 +61,8 @@ CMenuScreen aScreens[] = {
MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT,
MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT,
MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT,
#ifdef IMPROVED_VIDEOMODE
MENUACTION_SCREENFORMAT,"FED_POS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT,
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 328 + Y_OFFSET, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 353 + Y_OFFSET, MENUALIGN_CENTER,
#else
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER,
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 328 + Y_OFFSET, MENUALIGN_CENTER,
#endif
},
#undef Y_OFFSET
@ -255,7 +215,9 @@ CMenuScreen aScreens[] = {
// MENUPAGE_CONTROLLER_PC = 26
{ "FET_CTL", MENUPAGE_OPTIONS, 0,
#ifdef PC_PLAYER_CONTROLS
MENUACTION_CTRLMETHOD, "FET_STI", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 150, MENUALIGN_CENTER,
#endif
MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEC_MOU", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_CENTER,
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, MENUALIGN_CENTER,
@ -286,10 +248,8 @@ CMenuScreen aScreens[] = {
MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER,
},
// TODO(Miami)
// MENUPAGE_KEYBOARD_CONTROLS = 30
{ "FET_STI", MENUPAGE_CONTROLLER_PC, 1,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, 0,
},
// MENUPAGE_MOUSE_CONTROLS = 31
@ -314,18 +274,15 @@ CMenuScreen aScreens[] = {
// MENUPAGE_NONE = 33
{ "", 0, 0, },
// MENUPAGE_OUTRO = 34
{ "", 0, 0, },
#ifdef LEGACY_MENU_OPTIONS
// MENUPAGE_CONTROLLER_SETTINGS = 4
// MENUPAGE_CONTROLLER_SETTINGS
{ "FET_CON", MENUPAGE_OPTIONS, 0,
MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0,
MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
// MENUPAGE_DEBUG_MENU = 18
// MENUPAGE_DEBUG_MENU
{ "FED_DBG", MENUPAGE_NONE, 0,
MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
@ -334,7 +291,7 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
// MENUPAGE_CONTROLLER_PC_OLD1 = 36
// MENUPAGE_CONTROLLER_PC_OLD1
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, 0,
MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0,
@ -348,12 +305,12 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
// MENUPAGE_CONTROLLER_PC_OLD2 = 37
// MENUPAGE_CONTROLLER_PC_OLD2
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, 1,
},
// MENUPAGE_CONTROLLER_PC_OLD3 = 38
// MENUPAGE_CONTROLLER_PC_OLD3
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, 2,
MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0,
MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0,
@ -362,12 +319,12 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
// MENUPAGE_CONTROLLER_PC_OLD4 = 39
// MENUPAGE_CONTROLLER_PC_OLD4
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, 3,
},
// MENUPAGE_CONTROLLER_DEBUG = 40
// MENUPAGE_CONTROLLER_DEBUG
{ "FEC_DBG", MENUPAGE_CONTROLLER_PC, 3,
MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0,
MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0,
@ -376,6 +333,10 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
#endif
// MENUPAGE_OUTRO - Originally 34
{ "", 0, 0, },
};
#endif
#endif

View File

@ -0,0 +1,716 @@
#include "common.h"
#include "platform.h"
#include "crossplatform.h"
#include "Renderer.h"
#include "Frontend.h"
#include "Font.h"
#include "Camera.h"
#include "main.h"
#include "MBlur.h"
#include "postfx.h"
#include "custompipes.h"
#include "RwHelper.h"
#include "Text.h"
#include "Streaming.h"
#include "FileLoader.h"
#include "Collision.h"
#include "ModelInfo.h"
#include "Pad.h"
// Menu screens array is at the bottom of the file.
#ifdef PC_MENU
#ifdef CUSTOM_FRONTEND_OPTIONS
#ifdef IMPROVED_VIDEOMODE
#define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) }, 0, 0, MENUALIGN_LEFT,
#else
#define VIDEOMODE_SELECTOR
#endif
#ifdef MULTISAMPLING
#define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, 0, 0, MENUALIGN_LEFT,
#else
#define MULTISAMPLING_SELECTOR
#endif
#ifdef CUTSCENE_BORDERS_SWITCH
#define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT,
#else
#define CUTSCENE_BORDERS_TOGGLE
#endif
#ifdef FREE_CAM
#define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT,
#else
#define FREE_CAM_TOGGLE
#endif
#ifdef PS2_ALPHA_TEST
#define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT,
#else
#define DUALPASS_SELECTOR
#endif
#ifdef NO_ISLAND_LOADING
#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT,
#else
#define ISLAND_LOADING_SELECTOR
#endif
#ifdef EXTENDED_COLOURFILTER
#define POSTFX_SELECTORS \
MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, 0, 0, MENUALIGN_LEFT, \
MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT,
#else
#define POSTFX_SELECTORS
#endif
#ifdef INVERT_LOOK_FOR_PAD
#define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, nil, off_on, 2, false, nil) }, 150, 0, MENUALIGN_LEFT,
#else
#define INVERT_PAD_SELECTOR
#endif
const char *filterNames[] = { "FEM_NON", "FEM_SIM", "FEM_NRM", "FEM_MOB" };
const char *off_on[] = { "FEM_OFF", "FEM_ON" };
void RestoreDefGraphics(int8 action) {
if (action != FEOPTION_ACTION_SELECT)
return;
#ifdef PS2_ALPHA_TEST
gPS2alphaTest = false;
#endif
#ifdef MULTISAMPLING
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0;
#endif
#ifdef NO_ISLAND_LOADING
if (!FrontEndMenuManager.m_bGameNotLoaded) {
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
CStreaming::RequestIslands(CGame::currLevel);
CStreaming::LoadAllRequestedModels(true);
} else
FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
FrontEndMenuManager.m_PrefsFrameLimiter = true;
FrontEndMenuManager.m_PrefsVsyncDisp = true;
#ifdef LEGACY_MENU_OPTIONS
FrontEndMenuManager.m_PrefsVsync = true;
#endif
FrontEndMenuManager.m_PrefsUseWideScreen = false;
FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode;
CMBlur::BlurOn = false;
FrontEndMenuManager.SaveSettings();
#endif
}
void RestoreDefDisplay(int8 action) {
if (action != FEOPTION_ACTION_SELECT)
return;
#ifdef CUTSCENE_BORDERS_SWITCH
FrontEndMenuManager.m_PrefsCutsceneBorders = true;
#endif
#ifdef FREE_CAM
TheCamera.bFreeCam = false;
#endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
FrontEndMenuManager.m_PrefsBrightness = 256;
FrontEndMenuManager.m_PrefsLOD = 1.2f;
CRenderer::ms_lodDistScale = 1.2f;
FrontEndMenuManager.m_PrefsShowSubtitles = false;
FrontEndMenuManager.m_PrefsShowLegends = true;
FrontEndMenuManager.m_PrefsRadarMode = 0;
FrontEndMenuManager.m_PrefsShowHud = true;
FrontEndMenuManager.SaveSettings();
#endif
}
#ifdef NO_ISLAND_LOADING
const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" };
void IslandLoadingAfterChange(int8 before, int8 after) {
if (!FrontEndMenuManager.m_bGameNotLoaded) {
if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) {
FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug:
if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH) {
CStreaming::RemoveIslandsNotUsed(LEVEL_BEACH);
CStreaming::RemoveIslandsNotUsed(LEVEL_MAINLAND);
}
if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) {
FrontEndMenuManager.m_PrefsIslandLoading = after;
CStreaming::RequestBigBuildings(CGame::currLevel);
} else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) {
FrontEndMenuManager.m_PrefsIslandLoading = after;
CStreaming::RequestIslands(CGame::currLevel);
} else
FrontEndMenuManager.m_PrefsIslandLoading = after;
} else { // low
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
CStreaming::RequestIslands(CGame::currLevel);
}
CStreaming::LoadAllRequestedModels(true);
}
FrontEndMenuManager.SetHelperText(0);
}
#endif
#ifdef MORE_LANGUAGES
void LangPolSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangRusSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangJapSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
#endif
#ifndef MULTISAMPLING
void GraphicsGoBack() {
}
#else
void GraphicsGoBack() {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
}
void MultiSamplingButtonPress(int8 action) {
if (action == FEOPTION_ACTION_SELECT) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel;
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode);
FrontEndMenuManager.SetHelperText(0);
FrontEndMenuManager.SaveSettings();
}
} else if (action == FEOPTION_ACTION_LEFT || action == FEOPTION_ACTION_RIGHT) {
if (FrontEndMenuManager.m_bGameNotLoaded) {
FrontEndMenuManager.m_nDisplayMSAALevel += (action == FEOPTION_ACTION_RIGHT ? 1 : -1);
int i = 0;
int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels();
while (maxAA != 1) {
i++;
maxAA >>= 1;
}
if (FrontEndMenuManager.m_nDisplayMSAALevel < 0)
FrontEndMenuManager.m_nDisplayMSAALevel = i;
else if (FrontEndMenuManager.m_nDisplayMSAALevel > i)
FrontEndMenuManager.m_nDisplayMSAALevel = 0;
}
} else if (action == FEOPTION_ACTION_FOCUSLOSS) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
FrontEndMenuManager.SetHelperText(3);
}
}
}
wchar* MultiSamplingDraw(bool *disabled, bool userHovering) {
static wchar unicodeTemp[64];
if (userHovering) {
if (FrontEndMenuManager.m_nDisplayMSAALevel == FrontEndMenuManager.m_nPrefsMSAALevel) {
if (FrontEndMenuManager.m_nHelperTextMsgId == 1) // Press enter to apply
FrontEndMenuManager.ResetHelperText();
} else {
FrontEndMenuManager.SetHelperText(1);
}
} else {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
}
}
if (!FrontEndMenuManager.m_bGameNotLoaded)
*disabled = true;
switch (FrontEndMenuManager.m_nDisplayMSAALevel) {
case 0:
return TheText.Get("FEM_OFF");
default:
sprintf(gString, "%iX", 1 << (FrontEndMenuManager.m_nDisplayMSAALevel));
AsciiToUnicode(gString, unicodeTemp);
return unicodeTemp;
}
}
#endif
#ifdef IMPROVED_VIDEOMODE
const char* screenModes[] = { "FED_FLS", "FED_WND" };
void ScreenModeAfterChange(int8 before, int8 after)
{
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
FrontEndMenuManager.SetHelperText(0);
}
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
wchar selectedJoystickUnicode[128];
wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
int numButtons;
int found = -1;
const char *joyname;
if (userHovering) {
for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
if ((joyname = glfwGetJoystickName(i))) {
const uint8* buttons = glfwGetJoystickButtons(i, &numButtons);
for (int j = 0; j < numButtons; j++) {
if (buttons[j]) {
found = i;
break;
}
}
if (found != -1)
break;
}
}
if (found != -1 && PSGLOBAL(joy1id) != found) {
if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found)
PSGLOBAL(joy2id) = PSGLOBAL(joy1id);
else
PSGLOBAL(joy2id) = -1;
strcpy(gSelectedJoystickName, joyname);
PSGLOBAL(joy1id) = found;
}
}
if (PSGLOBAL(joy1id) == -1)
AsciiToUnicode("Not found", selectedJoystickUnicode);
else
AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode);
return selectedJoystickUnicode;
}
#endif
CMenuScreenCustom aScreens[] = {
// MENUPAGE_STATS = 0
{ "FEH_STA", MENUPAGE_NONE, nil, nil,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT,
},
// MENUPAGE_NEW_GAME = 1
{ "FEP_STG", MENUPAGE_NONE, nil, nil,
MENUACTION_CHANGEMENU, "FES_NGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 155, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FES_LOA", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FES_DEL", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 0, 0, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER,
},
// MENUPAGE_BRIEFS = 2
{ "FEH_BRI", MENUPAGE_NONE, nil, nil,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT,
},
// MENUPAGE_SOUND_SETTINGS = 3
{ "FEH_AUD", MENUPAGE_OPTIONS, nil, nil,
MENUACTION_MUSICVOLUME, "FEA_MUS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 40, 76, MENUALIGN_LEFT,
MENUACTION_SFXVOLUME, "FEA_SFX", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_AUDIOHW, "FEA_3DH", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SPEAKERCONF, "FEA_SPK", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_DYNAMICACOUSTIC, "FET_DAM", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_RADIO, "FEA_RSS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 367, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
},
// MENUPAGE_DISPLAY_SETTINGS = 4
#ifndef GRAPHICS_MENU_OPTIONS
{ "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
MENUACTION_BRIGHTNESS, "FED_BRI", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#endif
MENUACTION_FRAMELIMIT, "FEM_FRM", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#if defined LEGACY_MENU_OPTIONS && !defined EXTENDED_COLOURFILTER
MENUACTION_TRAILS, "FED_TRA", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#endif
MENUACTION_SUBTITLES, "FED_SUB", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_WIDESCREEN, "FED_WIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_LEGENDS, "MAP_LEG", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_RADARMODE, "FED_RDR", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_HUD, "FED_HUD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SCREENRES, "FED_RES", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
VIDEOMODE_SELECTOR
MULTISAMPLING_SELECTOR
ISLAND_LOADING_SELECTOR
DUALPASS_SELECTOR
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
POSTFX_SELECTORS
// re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 320, 0, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#else
{ "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MENUACTION_RADARMODE, "FED_RDR", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MENUACTION_HUD, "FED_HUD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefDisplay) }, 320, 0, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#endif
// MENUPAGE_LANGUAGE_SETTINGS = 5
{ "FEH_LAN", MENUPAGE_OPTIONS, nil, nil,
MENUACTION_LANG_ENG, "FEL_ENG", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 320, 132, MENUALIGN_CENTER,
MENUACTION_LANG_FRE, "FEL_FRE", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_LANG_GER, "FEL_GER", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_LANG_ITA, "FEL_ITA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_LANG_SPA, "FEL_SPA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#ifdef MORE_LANGUAGES
MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER,
MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER
MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER,
#endif
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
},
// MENUPAGE_MAP = 6
{ "FEH_MAP", MENUPAGE_NONE, nil, nil,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER,
},
// MENUPAGE_NEW_GAME_RELOAD = 7
{ "FES_NGA", MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_LABEL, "FESZ_QR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 200, MENUALIGN_CENTER,
MENUACTION_NEWGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_CHOOSE_LOAD_SLOT = 8
{ "FET_LG", MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER,
},
// MENUPAGE_CHOOSE_DELETE_SLOT = 9
{ "FES_DEL", MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER,
},
// MENUPAGE_LOAD_SLOT_CONFIRM = 10
{ "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
MENUACTION_LABEL, "FESZ_QL", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 320, 200, MENUALIGN_CENTER,
MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_DELETE_SLOT_CONFIRM = 11
{ "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
MENUACTION_LABEL, "FESZ_QD", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 320, 200, MENUALIGN_CENTER,
MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_DELETING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_LOADING_IN_PROGRESS = 12
{ "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
},
// MENUPAGE_DELETING_IN_PROGRESS = 13
{ "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
},
// MENUPAGE_DELETE_SUCCESSFUL = 14
{ "FES_DEL", MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_LABEL, "FES_DSC", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_CHOOSE_SAVE_SLOT = 15
{ "FET_SG", MENUPAGE_DISABLED, nil, nil,
MENUACTION_SAVEGAME, "FEM_SL1", {nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 40, 90, MENUALIGN_LEFT,
MENUACTION_SAVEGAME, "FEM_SL2", {nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SAVEGAME, "FEM_SL3", {nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SAVEGAME, "FEM_SL4", {nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SAVEGAME, "FEM_SL5", {nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SAVEGAME, "FEM_SL6", {nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SAVEGAME, "FEM_SL7", {nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
MENUACTION_SAVEGAME, "FEM_SL8", {nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER,
},
// MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FESZ_QZ", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 200, MENUALIGN_CENTER,
MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_SAVING_IN_PROGRESS = 17
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
},
// MENUPAGE_SAVE_SUCCESSFUL = 18
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FES_SSC", {nil, SAVESLOT_LABEL, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_SAVE_CUSTOM_WARNING = 19
{ "FET_SG", MENUPAGE_NONE, nil, nil,
MENUACTION_LABEL, "", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_SAVE_CHEAT_WARNING = 20
{ "FET_SG", MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_LABEL, "FES_CHE", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_SKIN_SELECT = 21
{ "FET_PS", MENUPAGE_OPTIONS, nil, nil,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0,
},
// MENUPAGE_SAVE_UNUSED = 22
{ "FET_SG", MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_LABEL, "FED_LWR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0,
},
// MENUPAGE_SAVE_FAILED = 23
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0,
},
// MENUPAGE_SAVE_FAILED_2 = 24
{ "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
},
// MENUPAGE_LOAD_FAILED = 25
{ "FET_LG", MENUPAGE_NEW_GAME, nil, nil,
MENUACTION_LABEL, "FEC_LUN", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, 0,
},
// MENUPAGE_CONTROLLER_PC = 26
{ "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil,
#ifdef PC_PLAYER_CONTROLS
MENUACTION_CTRLMETHOD, "FET_STI", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 150, MENUALIGN_CENTER,
#endif
MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 0, 0, MENUALIGN_CENTER,
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER,
#endif
MENUACTION_CHANGEMENU, "FEC_MOU", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_CENTER,
INVERT_PAD_SELECTOR
MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 0, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 0, MENUALIGN_CENTER,
},
// MENUPAGE_OPTIONS = 27
{ "FET_OPT", MENUPAGE_NONE, nil, nil,
MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 132, MENUALIGN_CENTER,
MENUACTION_LOADRADIO, "FEO_AUD", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEO_DIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#ifdef GRAPHICS_MENU_OPTIONS
MENUACTION_CHANGEMENU, "FET_GRA", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#endif
MENUACTION_CHANGEMENU, "FEO_LAN", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_PLAYERSETUP, "FET_PS", {nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT}, 0, 0, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER,
},
// MENUPAGE_EXIT = 28
{ "FET_QG", MENUPAGE_NONE, nil, nil,
MENUACTION_LABEL, "FEQ_SRE", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
MENUACTION_DONTCANCEL, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 200, MENUALIGN_CENTER,
MENUACTION_CANCELGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER,
},
// MENUPAGE_START_MENU = 29
{ "FEM_MM", MENUPAGE_DISABLED, nil, nil,
MENUACTION_CHANGEMENU, "FEP_STG", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 170, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEP_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER,
},
// MENUPAGE_KEYBOARD_CONTROLS = 30
{ "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil,
},
// MENUPAGE_MOUSE_CONTROLS = 31
{ "FEC_MOU", MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_MOUSESENS, "FEC_MSH", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 40, 170, MENUALIGN_LEFT,
MENUACTION_INVVERT, "FEC_IVV", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_MOUSESTEER, "FET_MST", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 260, MENUALIGN_CENTER,
},
// MENUPAGE_PAUSE_MENU = 32
{ "FET_PAU", MENUPAGE_DISABLED, nil, nil,
MENUACTION_RESUME, "FEP_RES", {nil, SAVESLOT_NONE, 0}, 320, 120, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEH_SGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEH_MAP", {nil, SAVESLOT_NONE, MENUPAGE_MAP}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEP_STA", {nil, SAVESLOT_NONE, MENUPAGE_STATS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEH_BRI", {nil, SAVESLOT_NONE, MENUPAGE_BRIEFS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FET_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER,
},
// MENUPAGE_NONE = 33
{ "", 0, nil, nil, },
#ifdef LEGACY_MENU_OPTIONS
// MENUPAGE_CONTROLLER_SETTINGS = 4
{ "FET_CON", MENUPAGE_OPTIONS, nil, nil,
MENUACTION_CTRLCONFIG, "FEC_CCF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0,
MENUACTION_CTRLVIBRATION, "FEC_VIB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
// MENUPAGE_DEBUG_MENU = 18
{ "FED_DBG", MENUPAGE_NONE, nil, nil,
MENUACTION_RELOADIDE, "FED_RID", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_SETDBGFLAG, "FED_DFL", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_COLLISIONPOLYS, "FED_SCP", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
// MENUPAGE_CONTROLLER_PC_OLD1 = 36
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_GETKEY, "FEC_PLB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_CWL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_CWR", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_LKT", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_PJP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_PSP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_TLF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_TRG", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_CCM", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
// MENUPAGE_CONTROLLER_PC_OLD2 = 37
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
},
// MENUPAGE_CONTROLLER_PC_OLD3 = 38
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_GETKEY, "FEC_LUP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_LDN", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
MENUACTION_SHOWHEADBOB, "FEC_GSL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
// MENUPAGE_CONTROLLER_PC_OLD4 = 39
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
},
// MENUPAGE_CONTROLLER_DEBUG = 40
{ "FEC_DBG", MENUPAGE_CONTROLLER_PC, nil, nil,
MENUACTION_GETKEY, "FEC_TGD", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_TDO", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_TSS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
#endif
#ifdef GRAPHICS_MENU_OPTIONS
// MENUPAGE_GRAPHICS_SETTINGS
{ "FET_GRA", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack,
MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
VIDEOMODE_SELECTOR
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_LEFT,
#endif
MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
MULTISAMPLING_SELECTOR
ISLAND_LOADING_SELECTOR
DUALPASS_SELECTOR
#ifdef EXTENDED_COLOURFILTER
POSTFX_SELECTORS
#elif defined LEGACY_MENU_OPTIONS
MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
#endif
// re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
// MENUPAGE_DETECT_JOYSTICK
{ "FEC_JOD", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({0, 0, 0, false, false, 30}), nil,
MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0,
MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) }, 80, 200, MENUALIGN_LEFT,
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER,
},
#endif
// MENUPAGE_OUTRO = 34
{ "", 0, nil, nil, },
};
#endif
#endif

View File

@ -1213,14 +1213,46 @@ void CPad::AddToCheatString(char c)
int Cheat_strncmp(char* sourceStr, char* origCheatStr)
{
char cheatCodeVals[] = { 3,5,7,1,13,27,3,7,1,11,13,8,7,32,13,6,28,19,10,3,3,5,7,1,13,27,3,7 };
for (uint32 i = 0; i < strlen(origCheatStr); i++) {
if ((sourceStr[i] != origCheatStr[i] - cheatCodeVals[i]) || i >= ARRAY_SIZE(cheatCodeVals)) {
return 1;
#define ccmp(n) if((uint8)sourceStr[i] != (uint8)origCheatStr[i] - n) return 1;
int i = 0;
while(origCheatStr[i])
{
switch(i)
{
case 0: ccmp(3); break;
case 1: ccmp(5); break;
case 2: ccmp(7); break;
case 3: ccmp(1); break;
case 4: ccmp(13); break;
case 5: ccmp(27); break;
case 6: ccmp(3); break;
case 7: ccmp(7); break;
case 8: ccmp(1); break;
case 9: ccmp(11); break;
case 10: ccmp(13); break;
case 11: ccmp(8); break;
case 12: ccmp(7); break;
case 13: ccmp(32); break;
case 14: ccmp(13); break;
case 15: ccmp(6); break;
case 16: ccmp(28); break;
case 17: ccmp(19); break;
case 18: ccmp(10); break;
case 19: ccmp(3); break;
case 20: ccmp(3); break;
case 21: ccmp(5); break;
case 22: ccmp(7); break;
case 23: ccmp(1); break;
case 24: ccmp(13); break;
case 25: ccmp(27); break;
case 26: ccmp(3); break;
case 27: ccmp(7); break;
default: return 1;
}
i++;
}
return 0;
#undef ccmp
}
// TODO(Miami): Mobile has changed some of the cheats to include debugging things

View File

@ -3,6 +3,7 @@
#include "Automobile.h"
#include "Bridge.h"
#include "Camera.h"
#include "CarCtrl.h"
#include "Cranes.h"
#include "Darkel.h"
#include "Explosion.h"
@ -34,93 +35,10 @@
#include "Automobile.h"
#include "GameLogic.h"
// --MIAMI: File done
CVector lastPlayerPos;
// --MIAMI: Done
void
CPlayerInfo::SetPlayerSkin(char *skin)
{
strncpy(m_aSkinName, skin, 32);
LoadPlayerSkin();
}
// --MIAMI: Done
const CVector &
CPlayerInfo::GetPos()
{
#ifdef FIX_BUGS
if (!m_pPed)
return TheCamera.GetPosition();
#endif
if (m_pPed->InVehicle())
return m_pPed->m_pMyVehicle->GetPosition();
return m_pPed->GetPosition();
}
// --MIAMI: Done
void
CPlayerInfo::LoadPlayerSkin()
{
DeletePlayerSkin();
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
}
// --MIAMI: Done
void
CPlayerInfo::DeletePlayerSkin()
{
if (m_pSkinTexture) {
RwTextureDestroy(m_pSkinTexture);
m_pSkinTexture = nil;
}
}
// --MIAMI: Done
void
CPlayerInfo::KillPlayer()
{
if (m_WBState != WBSTATE_PLAYING) return;
m_WBState = WBSTATE_WASTED;
m_nWBTime = CTimer::GetTimeInMilliseconds();
CDarkel::ResetOnPlayerDeath();
CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
CStats::TimesDied++;
}
// --MIAMI: Done
void
CPlayerInfo::ArrestPlayer()
{
if (m_WBState != WBSTATE_PLAYING) return;
m_WBState = WBSTATE_BUSTED;
m_nWBTime = CTimer::GetTimeInMilliseconds();
m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
CDarkel::ResetOnPlayerDeath();
CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
CStats::TimesArrested++;
}
// --MIAMI: Done
bool
CPlayerInfo::IsPlayerInRemoteMode()
{
return m_pRemoteVehicle || m_bInRemoteMode;
}
void
CPlayerInfo::PlayerFailedCriticalMission()
{
if (m_WBState != WBSTATE_PLAYING)
return;
m_WBState = WBSTATE_FAILED_CRITICAL_MISSION;
m_nWBTime = CTimer::GetTimeInMilliseconds();
CDarkel::ResetOnPlayerDeath();
}
// --MIAMI: Done
void
CPlayerInfo::Clear(void)
{
@ -181,192 +99,6 @@ CPlayerInfo::Clear(void)
m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
}
// --MIAMI: Done
void
CPlayerInfo::BlowUpRCBuggy(bool actually)
{
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
return;
CRemote::TakeRemoteControlledCarFromPlayer(actually);
if (actually)
m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
}
// --MIAMI: Done
void
CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
{
if (!car || car == m_pPed->m_pMyVehicle) {
if (m_pPed->EnteringCar())
m_pPed->QuitEnteringCar();
}
if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
m_pPed->ClearObjective();
}
// --MIAMI: Done
void
CPlayerInfo::MakePlayerSafe(bool toggle)
{
if (toggle) {
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
CWorld::StopAllLawEnforcersInTheirTracks();
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO);
CPad::StopPadsShaking();
m_pPed->bBulletProof = true;
m_pPed->bFireProof = true;
m_pPed->bCollisionProof = true;
m_pPed->bMeleeProof = true;
m_pPed->bOnlyDamagedByPlayer = true;
m_pPed->bExplosionProof = true;
m_pPed->m_bCanBeDamaged = false;
((CPlayerPed*)m_pPed)->ClearAdrenaline();
CancelPlayerEnteringCars(nil);
gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
CProjectileInfo::RemoveAllProjectiles();
CWorld::SetAllCarsCanBeDamaged(false);
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
CReplay::DisableReplays();
} else {
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO);
m_pPed->bBulletProof = false;
m_pPed->bFireProof = false;
m_pPed->bCollisionProof = false;
m_pPed->bMeleeProof = false;
m_pPed->bOnlyDamagedByPlayer = false;
m_pPed->bExplosionProof = false;
m_pPed->m_bCanBeDamaged = true;
CWorld::SetAllCarsCanBeDamaged(true);
CReplay::EnableReplays();
}
}
// --MIAMI: Done
bool
CPlayerInfo::IsRestartingAfterDeath()
{
return m_WBState == WBSTATE_WASTED;
}
// --MIAMI: Done
bool
CPlayerInfo::IsRestartingAfterArrest()
{
return m_WBState == WBSTATE_BUSTED;
}
// --MIAMI: Done
// lastCloseness is passed to other calls of this function
void
CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
{
// This dist used for determining the angle to face
CVector2D dist(carToTest->GetPosition() - player->GetPosition());
float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
while (neededTurn >= PI) {
neededTurn -= 2 * PI;
}
while (neededTurn < -PI) {
neededTurn += 2 * PI;
}
// This dist used for evaluating cars' distances, weird...
// Accounts inverted needed turn (or needed turn in long way) and car dist.
float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
if (closeness > *lastCloseness) {
*lastCloseness = closeness;
*closestCarOutput = (CVehicle*)carToTest;
}
}
// --MIAMI: Done
void
CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
{
// Interesting
*size = sizeof(CPlayerInfo);
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio);
#undef CopyToBuf
}
// --MIAMI: Done
void
CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
{
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio)
#undef CopyFromBuf
}
// --MIAMI: Done
void
CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
{
for (CPtrNode* node = carList.first; node; node = node->next) {
CVehicle *car = (CVehicle*)node->item;
if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
if (!car->bUsesCollision || !car->IsVehicle())
continue;
car->m_scanCode = CWorld::GetCurrentScanCode();
if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
CVector carCentre = car->GetBoundCentre();
if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) {
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
}
}
}
}
}
}
void
CPlayerInfo::Process(void)
{
@ -673,13 +405,13 @@ CPlayerInfo::Process(void)
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, 0);
TheCamera.Fade(1.0f, FADE_OUT);
}
if (timeWithoutRemoteCar > 2000) {
if (m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.RestoreWithJumpCut();
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, 1);
TheCamera.Fade(1.0f, FADE_IN);
TheCamera.Process();
CTimer::Stop();
CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
@ -796,3 +528,355 @@ CPlayerInfo::Process(void)
m_nMoney = Min(999999999, m_nMoney);
m_nVisibleMoney = Min(999999999, m_nVisibleMoney);
}
bool
CPlayerInfo::IsPlayerInRemoteMode()
{
return m_pRemoteVehicle || m_bInRemoteMode;
}
void
CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
{
// Interesting
*size = sizeof(CPlayerInfo);
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio);
#undef CopyToBuf
}
void
CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
{
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFireproof);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bDriveByAllowed);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nBustedAudioStatus);
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCurrentBustedAudio)
#undef CopyFromBuf
}
void
CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
{
for (CPtrNode* node = carList.first; node; node = node->next) {
CVehicle *car = (CVehicle*)node->item;
if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
if (!car->bUsesCollision || !car->IsVehicle())
continue;
car->m_scanCode = CWorld::GetCurrentScanCode();
if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
CVector carCentre = car->GetBoundCentre();
if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f || car->IsCar() && carCentre.z < ped->GetPosition().z && ped->GetPosition().z - 4.f < carCentre.z) {
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
}
}
}
}
}
}
// lastCloseness is passed to other calls of this function
void
CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
{
// This dist used for determining the angle to face
CVector2D dist(carToTest->GetPosition() - player->GetPosition());
float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
while (neededTurn >= PI) {
neededTurn -= 2 * PI;
}
while (neededTurn < -PI) {
neededTurn += 2 * PI;
}
// This dist used for evaluating cars' distances, weird...
// Accounts inverted needed turn (or needed turn in long way) and car dist.
float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
if (closeness > *lastCloseness) {
*lastCloseness = closeness;
*closestCarOutput = (CVehicle*)carToTest;
}
}
const CVector &
CPlayerInfo::GetPos()
{
#ifdef FIX_BUGS
if (!m_pPed)
return TheCamera.GetPosition();
#endif
if (m_pPed->InVehicle())
return m_pPed->m_pMyVehicle->GetPosition();
return m_pPed->GetPosition();
}
CVector
FindPlayerCoors(void)
{
#ifdef FIX_BUGS
if (CReplay::IsPlayingBack())
return TheCamera.GetPosition();
#endif
CPlayerPed *ped = FindPlayerPed();
if(ped->InVehicle())
return ped->m_pMyVehicle->GetPosition();
else
return ped->GetPosition();
}
const CVector &
FindPlayerSpeed(void)
{
#ifdef FIX_BUGS
static CVector vecTmpVector(0.0f, 0.0f, 0.0f);
if (CReplay::IsPlayingBack())
return vecTmpVector;
#endif
CPlayerPed *ped = FindPlayerPed();
if(ped->InVehicle())
return ped->m_pMyVehicle->m_vecMoveSpeed;
else
return ped->m_vecMoveSpeed;
}
CVehicle *
FindPlayerVehicle(void)
{
CPlayerPed *ped = FindPlayerPed();
if(ped && ped->InVehicle()) return ped->m_pMyVehicle;
return nil;
}
CEntity *
FindPlayerEntity(void)
{
CPlayerPed *ped = FindPlayerPed();
if(ped->InVehicle())
return ped->m_pMyVehicle;
else
return ped;
}
CVehicle *
FindPlayerTrain(void)
{
if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain())
return FindPlayerVehicle();
else
return nil;
}
CPlayerPed *
FindPlayerPed(void)
{
return CWorld::Players[CWorld::PlayerInFocus].m_pPed;
}
const CVector &
FindPlayerCentreOfWorld(int32 player)
{
#ifdef FIX_BUGS
if(CReplay::IsPlayingBack()) return TheCamera.GetPosition();
#endif
if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition();
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
return CWorld::Players[player].m_pPed->GetPosition();
}
const CVector &
FindPlayerCentreOfWorld_NoSniperShift(void)
{
#ifdef FIX_BUGS
if (CReplay::IsPlayingBack()) return TheCamera.GetPosition();
#endif
if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
return FindPlayerPed()->GetPosition();
}
float
FindPlayerHeading(void)
{
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading();
return FindPlayerPed()->GetForward().Heading();
}
bool
CPlayerInfo::IsRestartingAfterDeath()
{
return m_WBState == WBSTATE_WASTED;
}
bool
CPlayerInfo::IsRestartingAfterArrest()
{
return m_WBState == WBSTATE_BUSTED;
}
void
CPlayerInfo::KillPlayer()
{
if (m_WBState != WBSTATE_PLAYING) return;
m_WBState = WBSTATE_WASTED;
m_nWBTime = CTimer::GetTimeInMilliseconds();
CDarkel::ResetOnPlayerDeath();
CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
CStats::TimesDied++;
}
void
CPlayerInfo::ArrestPlayer()
{
if (m_WBState != WBSTATE_PLAYING) return;
m_WBState = WBSTATE_BUSTED;
m_nWBTime = CTimer::GetTimeInMilliseconds();
m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
CDarkel::ResetOnPlayerDeath();
CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
CStats::TimesArrested++;
}
void
CPlayerInfo::PlayerFailedCriticalMission()
{
if (m_WBState != WBSTATE_PLAYING)
return;
m_WBState = WBSTATE_FAILED_CRITICAL_MISSION;
m_nWBTime = CTimer::GetTimeInMilliseconds();
CDarkel::ResetOnPlayerDeath();
}
void
CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
{
if (!car || car == m_pPed->m_pMyVehicle) {
if (m_pPed->EnteringCar())
m_pPed->QuitEnteringCar();
}
if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
m_pPed->ClearObjective();
}
void
CPlayerInfo::MakePlayerSafe(bool toggle)
{
if (toggle) {
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
CWorld::StopAllLawEnforcersInTheirTracks();
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO);
CPad::StopPadsShaking();
m_pPed->bBulletProof = true;
m_pPed->bFireProof = true;
m_pPed->bCollisionProof = true;
m_pPed->bMeleeProof = true;
m_pPed->bOnlyDamagedByPlayer = true;
m_pPed->bExplosionProof = true;
m_pPed->m_bCanBeDamaged = false;
((CPlayerPed*)m_pPed)->ClearAdrenaline();
CancelPlayerEnteringCars(nil);
gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
CProjectileInfo::RemoveAllProjectiles();
CWorld::SetAllCarsCanBeDamaged(false);
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
CReplay::DisableReplays();
} else {
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO);
m_pPed->bBulletProof = false;
m_pPed->bFireProof = false;
m_pPed->bCollisionProof = false;
m_pPed->bMeleeProof = false;
m_pPed->bOnlyDamagedByPlayer = false;
m_pPed->bExplosionProof = false;
m_pPed->m_bCanBeDamaged = true;
CWorld::SetAllCarsCanBeDamaged(true);
CReplay::EnableReplays();
}
}
void
CPlayerInfo::BlowUpRCBuggy(bool actually)
{
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
return;
CRemote::TakeRemoteControlledCarFromPlayer(actually);
if (actually)
m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
}
#ifdef GTA_PC
void
CPlayerInfo::SetPlayerSkin(const char *skin)
{
strncpy(m_aSkinName, skin, 32);
LoadPlayerSkin();
}
void
CPlayerInfo::LoadPlayerSkin()
{
DeletePlayerSkin();
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
}
void
CPlayerInfo::DeletePlayerSkin()
{
if (m_pSkinTexture) {
RwTextureDestroy(m_pSkinTexture);
m_pSkinTexture = nil;
}
}
#endif

View File

@ -10,7 +10,7 @@ enum eWastedBustedState
WBSTATE_FAILED_CRITICAL_MISSION,
};
enum eBustedAudioState : uint8
enum eBustedAudioState
{
BUSTEDAUDIO_NONE,
BUSTEDAUDIO_LOADING,
@ -82,15 +82,14 @@ public:
bool m_bGetOutOfJailFree;
bool m_bGetOutOfHospitalFree;
bool m_bDriveByAllowed;
eBustedAudioState m_nBustedAudioStatus;
uint8 m_nBustedAudioStatus;
int16 m_nCurrentBustedAudio;
#ifdef GTA_PC
char m_aSkinName[32];
RwTexture *m_pSkinTexture;
#endif
void MakePlayerSafe(bool);
void LoadPlayerSkin();
void DeletePlayerSkin();
void SetPlayerSkin(char* skin);
const CVector &GetPos();
void Process(void);
void KillPlayer(void);
@ -107,5 +106,19 @@ public:
void SavePlayerInfo(uint8 *buf, uint32* size);
void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**);
~CPlayerInfo() { };
#ifdef GTA_PC
void LoadPlayerSkin();
void SetPlayerSkin(const char *skin);
void DeletePlayerSkin();
#endif
};
CPlayerPed *FindPlayerPed(void);
CVehicle *FindPlayerVehicle(void);
CVehicle *FindPlayerTrain(void);
CEntity *FindPlayerEntity(void);
CVector FindPlayerCoors(void);
const CVector &FindPlayerSpeed(void);
const CVector &FindPlayerCentreOfWorld(int32 player);
const CVector &FindPlayerCentreOfWorld_NoSniperShift(void);
float FindPlayerHeading(void);

View File

@ -13,6 +13,7 @@
#include "Streaming.h"
#include "Wanted.h"
#include "World.h"
#include "MemoryHeap.h"
//--MIAMI: file done
@ -27,19 +28,39 @@ CDummyPool *CPools::ms_pDummyPool;
CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool;
CColModelPool *CPools::ms_pColModelPool;
#if defined GTA_PS2 && !defined MASTER // or USE_CUSTOM_ALLOCATOR
// not in VC. perhaps ifdef'ed away
#define CHECKMEM(msg) CMemCheck::AllocateMemCheckBlock(msg)
#else
#define CHECKMEM(msg)
#endif
void
CPools::Initialise(void)
{
PUSH_MEMID(MEMID_POOLS);
CHECKMEM("before pools");
ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES, "PtrNode");
CHECKMEM("after CPtrNodePool");
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS, "EntryInfoNode");
CHECKMEM("after CEntryInfoNodePool");
ms_pPedPool = new CPedPool(NUMPEDS, "Peds");
CHECKMEM("after CPedPool");
ms_pVehiclePool = new CVehiclePool(NUMVEHICLES, "Vehicles");
CHECKMEM("after CVehiclePool");
ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS, "Buildings");
CHECKMEM("after CBuildingPool");
ms_pTreadablePool = new CTreadablePool(NUMTREADABLES, "Treadables");
CHECKMEM("after CTreadablePool");
ms_pObjectPool = new CObjectPool(NUMOBJECTS, "Objects");
CHECKMEM("after CObjectPool");
ms_pDummyPool = new CDummyPool(NUMDUMMIES, "Dummys");
CHECKMEM("after CDummyPool");
ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS, "AudioScriptObj");
CHECKMEM("after cAudioScriptObjectPool");
ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel");
CHECKMEM("after pools");
POP_MEMID();
}
void

View File

@ -21,6 +21,83 @@ CReferences::Init(void)
aRefs[NUMREFERENCES-1].next = nil;
}
void
CEntity::RegisterReference(CEntity **pent)
{
if(IsBuilding())
return;
CReference *ref;
// check if already registered
for(ref = m_pFirstReference; ref; ref = ref->next)
if(ref->pentity == pent)
return;
// have to allocate new reference
ref = CReferences::pEmptyList;
if(ref){
CReferences::pEmptyList = ref->next;
ref->pentity = pent;
ref->next = m_pFirstReference;
m_pFirstReference = ref;
return;
}
return;
}
// Clean up the reference from *pent -> 'this'
void
CEntity::CleanUpOldReference(CEntity **pent)
{
CReference* ref, ** lastnextp;
lastnextp = &m_pFirstReference;
for (ref = m_pFirstReference; ref; ref = ref->next) {
if (ref->pentity == pent) {
*lastnextp = ref->next;
ref->next = CReferences::pEmptyList;
CReferences::pEmptyList = ref;
break;
}
lastnextp = &ref->next;
}
}
// Clear all references to this entity
void
CEntity::ResolveReferences(void)
{
CReference *ref;
// clear pointers to this entity
for(ref = m_pFirstReference; ref; ref = ref->next)
if(*ref->pentity == this)
*ref->pentity = nil;
// free list
if(m_pFirstReference){
for(ref = m_pFirstReference; ref->next; ref = ref->next)
;
ref->next = CReferences::pEmptyList;
CReferences::pEmptyList = m_pFirstReference;
m_pFirstReference = nil;
}
}
// Free all references that no longer point to this entity
void
CEntity::PruneReferences(void)
{
CReference *ref, *next, **lastnextp;
lastnextp = &m_pFirstReference;
for(ref = m_pFirstReference; ref; ref = next){
next = ref->next;
if(*ref->pentity == this)
lastnextp = &ref->next;
else{
*lastnextp = ref->next;
ref->next = CReferences::pEmptyList;
CReferences::pEmptyList = ref;
}
}
}
void
CReferences::RemoveReferencesToPlayer(void)
{

View File

@ -5,9 +5,21 @@
#include "World.h"
#include "Pad.h"
#include "DMAudio.h"
#include "main.h"
#include "Font.h"
#include "Frontend.h"
#include "audio_enums.h"
#include <climits>
#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
#define MILES_IN_METER 0.000621371192f
#define FEET_IN_METER 3.28084f
#else
#define MILES_IN_METER (1 / 1670.f)
#define FEET_IN_METER 3.33f
#endif
int32 CStats::SeagullsKilled;
int32 CStats::BoatsExploded;
int32 CStats::WantedStarsAttained;
@ -43,8 +55,8 @@ float CStats::GarbagePickups;
float CStats::IceCreamSold;
float CStats::TopShootingRangeScore;
float CStats::ShootingRank;
int32 CStats::ProgressMade;
int32 CStats::TotalProgressInGame;
float CStats::ProgressMade;
float CStats::TotalProgressInGame;
int32 CStats::CarsExploded;
int32 CStats::PeopleKilledByPlayer;
float CStats::MaximumJumpDistance;
@ -115,7 +127,7 @@ void CStats::Init()
for (int i = 0; i < NUM_PEDTYPES; i++)
PedsKilledOfThisType[i] = 0;
HelisDestroyed = 0;
ProgressMade = 0;
ProgressMade = 0.0f;
KgsOfExplosivesUsed = 0;
BulletsThatHit = 0;
TyresPopped = 0;
@ -346,27 +358,27 @@ wchar *CStats::FindCriminalRatingString()
}
wchar *CStats::FindChaseString(float fMediaLevel) {
if (fMediaLevel < 20.0f) return TheText.Get("MEDIA1");
if (fMediaLevel < 50.0f) return TheText.Get("MEDIA2");
if (fMediaLevel < 75.0f) return TheText.Get("MEDIA3");
if (fMediaLevel < 100.0f) return TheText.Get("MEDIA4");
if (fMediaLevel < 150.0f) return TheText.Get("MEDIA5");
if (fMediaLevel < 200.0f) return TheText.Get("MEDIA6");
if (fMediaLevel < 250.0f) return TheText.Get("MEDIA7");
if (fMediaLevel < 300.0f) return TheText.Get("MEDIA8");
if (fMediaLevel < 350.0f) return TheText.Get("MEDIA9");
if (fMediaLevel < 400.0f) return TheText.Get("MEDIA10");
if (fMediaLevel < 500.0f) return TheText.Get("MEDIA11");
if (fMediaLevel < 600.0f) return TheText.Get("MEDIA12");
if (fMediaLevel < 700.0f) return TheText.Get("MEDIA13");
if (fMediaLevel < 800.0f) return TheText.Get("MEDIA14");
if (fMediaLevel < 900.0f) return TheText.Get("MEDIA15");
if (fMediaLevel < 1000.0f) return TheText.Get("MEDIA16");
if (fMediaLevel < 1200.0f) return TheText.Get("MEDIA17");
if (fMediaLevel < 1400.0f) return TheText.Get("MEDIA18");
if (fMediaLevel < 1600.0f) return TheText.Get("MEDIA19");
if (fMediaLevel < 1800.0f) return TheText.Get("MEDIA20");
return TheText.Get("MEDIA21");
if (fMediaLevel < 20.0f) return TheText.Get("CHASE1");
if (fMediaLevel < 50.0f) return TheText.Get("CHASE2");
if (fMediaLevel < 75.0f) return TheText.Get("CHASE3");
if (fMediaLevel < 100.0f) return TheText.Get("CHASE4");
if (fMediaLevel < 150.0f) return TheText.Get("CHASE5");
if (fMediaLevel < 200.0f) return TheText.Get("CHASE6");
if (fMediaLevel < 250.0f) return TheText.Get("CHASE7");
if (fMediaLevel < 300.0f) return TheText.Get("CHASE8");
if (fMediaLevel < 350.0f) return TheText.Get("CHASE9");
if (fMediaLevel < 400.0f) return TheText.Get("CHASE10");
if (fMediaLevel < 500.0f) return TheText.Get("CHASE11");
if (fMediaLevel < 600.0f) return TheText.Get("CHASE12");
if (fMediaLevel < 700.0f) return TheText.Get("CHASE13");
if (fMediaLevel < 800.0f) return TheText.Get("CHASE14");
if (fMediaLevel < 900.0f) return TheText.Get("CHASE15");
if (fMediaLevel < 1000.0f) return TheText.Get("CHASE16");
if (fMediaLevel < 1200.0f) return TheText.Get("CHASE17");
if (fMediaLevel < 1400.0f) return TheText.Get("CHASE18");
if (fMediaLevel < 1600.0f) return TheText.Get("CHASE19");
if (fMediaLevel < 1800.0f) return TheText.Get("CHASE20");
return TheText.Get("CHASE21");
}
int32 CStats::FindCriminalRatingNumber()
@ -387,16 +399,16 @@ int32 CStats::FindCriminalRatingNumber()
}
if (RoundsFiredByPlayer > 100)
rating += (float)CStats::BulletsThatHit / (float)CStats::RoundsFiredByPlayer * 500.0f;
rating += (float)BulletsThatHit / (float)RoundsFiredByPlayer * 500.0f;
if (TotalProgressInGame)
rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
rating += ProgressMade / TotalProgressInGame * 1000.0f;
return rating;
}
float CStats::GetPercentageProgress()
{
float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f));
float percentCompleted = (TotalProgressInGame == 0.f ? 0.f :
100.0f * ProgressMade / (CGame::nastyGame ? TotalProgressInGame : TotalProgressInGame - 1.0f));
return Min(percentCompleted, 100.0f);
}
@ -773,4 +785,657 @@ CStats::PopulateFavoriteRadioStationList()
float* pListenTimeArray = DMAudio.GetListenTimeArray();
for (int i = 0; i < NUM_RADIOS; i++)
FavoriteRadioStationList[i] = pListenTimeArray[i];
}
}
void
CStats::BuildStatLine(Const char *text, void *stat, int displayType, void *stat2, int isTime)
{
#define STAT_D *(int*)stat
#define STAT_F *(float*)stat
#define STAT2_D *(int*)stat2
#define STAT2_F *(float*)stat2
if (!text)
return;
gString2[0] = '\0';
if (isTime == 1) {
if (*((int*)stat2) >= 10)
sprintf(gString2, " %d:%d", STAT_D, STAT2_D);
else
sprintf(gString2, " %d:0%d", STAT_D, STAT2_D);
} else if (stat2) {
#ifdef MORE_LANGUAGES
if (CFont::IsJapanese()) {
switch (displayType) {
case 0:
case 4:
sprintf(gString2, " %d/%d", STAT_D, STAT2_D);
break;
case 1:
sprintf(gString2, " %.2f/%.2f", STAT_F, STAT2_F);
break;
case 2:
sprintf(gString2, " %d%%/%d%%", STAT_D, STAT2_D);
break;
case 3:
sprintf(gString2, " $%.2f/$%.2f", STAT_F, STAT2_F);
break;
default:
break;
}
} else
#endif
{
switch (displayType) {
case 0:
sprintf(gString2, " %d %s %d", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D);
break;
case 1:
sprintf(gString2, " %.2f %s %.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F);
break;
case 2:
sprintf(gString2, " %d%% %s %d%%", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D);
break;
case 3:
sprintf(gString2, " $%.2f %s $%.2f", STAT_F, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_F);
break;
case 4:
sprintf(gString2, " %d_ %s %d_", STAT_D, UnicodeToAscii(TheText.Get("FEST_OO")), STAT2_D);
break;
default:
break;
}
}
} else if (stat) {
switch (displayType) {
case 0:
sprintf(gString2, "%d", STAT_D);
break;
case 1:
sprintf(gString2, "%.2f", STAT_F);
break;
case 2:
sprintf(gString2, "%d%%", STAT_D);
break;
case 3:
sprintf(gString2, "$%.2f", STAT_F);
break;
case 4:
#ifdef MORE_LANGUAGES
if (CFont::IsJapanese())
sprintf(gString2, "%d", STAT_D);
else
#endif
sprintf(gString2, "%d_", STAT_D);
break;
default:
break;
}
}
UnicodeStrcpy(gUString, TheText.Get(text));
CFont::FilterOutTokensFromString(gUString);
AsciiToUnicode(gString2, gUString2);
#undef STAT_D
#undef STAT_F
#undef STAT2_D
#undef STAT2_F
}
// rowIdx 99999 returns total numbers of rows. otherwise it returns 0.
int
CStats::ConstructStatLine(int rowIdx)
{
#define STAT_LINE_1(varType, left, right1, type) \
do { \
if(counter == rowIdx){ \
varType a = right1; \
BuildStatLine(left, &a, type, nil, 0); \
return 0; \
} counter++; \
} while(0)
#define STAT_LINE_2(varType, left, right1, type, right2, time) \
do { \
if(counter == rowIdx){ \
varType a = right1; \
varType b = right2; \
BuildStatLine(left, &a, type, &b, time); \
return 0; \
} counter++; \
} while(0)
#define TEXT_ON_LEFT_GXT(name) \
do { \
if(counter == rowIdx){ \
BuildStatLine(name, nil, 0, nil, 0); \
return 0; \
} counter++; \
} while(0)
#define TEXT_ON_RIGHT(text) \
do { \
if(counter == rowIdx){ \
gUString[0] = '\0'; \
UnicodeStrcpy(gUString2, text); \
return 0; \
} counter++; \
} while(0)
#define FASTEST_TIME(id, str) \
do { \
if(FastestTimes[id]) { \
if(counter == rowIdx){ \
int hour = 0, minute; \
for (int i = FastestTimes[id]; i > 59; i -= 60) hour++; \
for (minute = FastestTimes[id]; minute > 59; minute -= 60); \
if (minute < 0) minute = -minute; \
BuildStatLine(str, &hour, 0, &minute, 1); \
return 0; \
} \
counter++; \
} \
} while(0)
switch (rowIdx) {
case 0: {
int percentCompleted = GetPercentageProgress();
BuildStatLine("PER_COM", &percentCompleted, 2, nil, 0);
return 0;
}
case 1: {
BuildStatLine("NMISON", &MissionsGiven, 0, nil, 0);
return 0;
}
case 2: {
int hour = (CTimer::GetTimeInMilliseconds() / 60000) / 60;
int minute = (CTimer::GetTimeInMilliseconds() / 60000) % 60;
BuildStatLine("ST_TIME", &hour, 0, &minute, 1);
return 0;
}
case 3: {
BuildStatLine("DAYSPS", &DaysPassed, 0, nil, 0);
return 0;
}
case 4: {
BuildStatLine("NUMSHV", &SafeHouseVisits, 0, nil, 0);
return 0;
}
}
int counter = 5;
if (CGame::nastyGame) {
STAT_LINE_2(int, "FEST_RP", NumberKillFrenziesPassed, 0, TotalNumberKillFrenzies, 0);
}
CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus];
// Hidden packages shouldn't be shown with percent
#ifdef FIX_BUGS
STAT_LINE_2(int, "PERPIC", player.m_nCollectedPackages, 0, player.m_nTotalPackages, 0);
#else
float fPackagesPercent = 0.0f;
if (player.m_nTotalPackages != 0)
fPackagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages;
STAT_LINE_2(int, "PERPIC", fPackagesPercent, 0, 100, 0);
#endif
if (CGame::nastyGame) {
STAT_LINE_1(int, "PE_WAST", PeopleKilledByPlayer, 0);
STAT_LINE_1(int, "PE_WSOT", PeopleKilledByOthers, 0);
}
STAT_LINE_1(int, "CAR_EXP", CarsExploded, 0);
STAT_LINE_1(int, "BOA_EXP", BoatsExploded, 0);
STAT_LINE_1(int, "HEL_DST", HelisDestroyed, 0);
STAT_LINE_1(int, "TYREPOP", TyresPopped, 0);
STAT_LINE_1(int, "ST_STAR", WantedStarsAttained, 0);
STAT_LINE_1(int, "ST_STGN", WantedStarsEvaded, 0);
STAT_LINE_1(int, "TM_BUST", TimesArrested, 0);
STAT_LINE_1(int, "TM_DED", TimesDied, 0);
#ifdef MORE_LANGUAGES
// JP version removed it altogether actually
if (!CFont::IsJapanese())
#endif
STAT_LINE_1(int, "ST_HEAD", HeadsPopped, 0);
static uint32 lastProcessedDay = UINT32_MAX;
static uint32 lastPoliceSpending = 0;
// What a random stat...
if (lastProcessedDay != DaysPassed) {
lastProcessedDay = DaysPassed;
lastPoliceSpending = (CTimer::GetTimeInMilliseconds() & 255 + 80) * 255.44f;
}
STAT_LINE_1(float, "DAYPLC", lastPoliceSpending, 3);
int mostPatheticGang = 0;
int mostKill = 0;
for (int i = PEDTYPE_GANG1; i < PEDTYPE_GANG9; ++i) {
if (CStats::PedsKilledOfThisType[i] > mostKill) {
mostKill = CStats::PedsKilledOfThisType[i];
mostPatheticGang = i;
}
}
if (mostPatheticGang > 0) {
TEXT_ON_LEFT_GXT("ST_GANG");
switch (mostPatheticGang) {
case PEDTYPE_GANG1:
TEXT_ON_RIGHT(TheText.Get("ST_GNG1"));
break;
case PEDTYPE_GANG2:
TEXT_ON_RIGHT(TheText.Get("ST_GNG2"));
break;
case PEDTYPE_GANG3:
TEXT_ON_RIGHT(TheText.Get("ST_GNG3"));
break;
case PEDTYPE_GANG4:
TEXT_ON_RIGHT(TheText.Get("ST_GNG4"));
break;
case PEDTYPE_GANG5:
TEXT_ON_RIGHT(TheText.Get("ST_GNG5"));
break;
case PEDTYPE_GANG6:
TEXT_ON_RIGHT(TheText.Get("ST_GNG6"));
break;
case PEDTYPE_GANG7:
TEXT_ON_RIGHT(TheText.Get("ST_GNG7"));
break;
case PEDTYPE_GANG8:
TEXT_ON_RIGHT(TheText.Get("ST_GNG8"));
break;
default:
break;
}
}
STAT_LINE_1(int, "GNG_WST", PedsKilledOfThisType[PEDTYPE_GANG9] + PedsKilledOfThisType[PEDTYPE_GANG8]
+ PedsKilledOfThisType[PEDTYPE_GANG7] + PedsKilledOfThisType[PEDTYPE_GANG6]
+ PedsKilledOfThisType[PEDTYPE_GANG5] + PedsKilledOfThisType[PEDTYPE_GANG4]
+ PedsKilledOfThisType[PEDTYPE_GANG3] + PedsKilledOfThisType[PEDTYPE_GANG2]
+ PedsKilledOfThisType[PEDTYPE_GANG1], 0);
STAT_LINE_1(int, "DED_CRI", PedsKilledOfThisType[PEDTYPE_CRIMINAL], 0);
STAT_LINE_1(int, "KGS_EXP", KgsOfExplosivesUsed, 0);
STAT_LINE_1(int, "BUL_FIR", RoundsFiredByPlayer, 0);
STAT_LINE_1(int, "BUL_HIT", BulletsThatHit, 0);
;
STAT_LINE_1(int, "ACCURA", RoundsFiredByPlayer == 0 ? 0 : (BulletsThatHit * 100.0f / (float)RoundsFiredByPlayer), 2);
switch (FrontEndMenuManager.m_PrefsLanguage) {
case CMenuManager::LANGUAGE_AMERICAN:
#ifndef USE_MEASUREMENTS_IN_METERS
STAT_LINE_1(float, "FEST_DF", DistanceTravelledOnFoot * MILES_IN_METER, 1);
STAT_LINE_1(float, "FEST_DC", DistanceTravelledByCar * MILES_IN_METER, 1);
STAT_LINE_1(float, "DISTBIK", DistanceTravelledByBike * MILES_IN_METER, 1);
STAT_LINE_1(float, "DISTBOA", DistanceTravelledByBoat * MILES_IN_METER, 1);
STAT_LINE_1(float, "DISTGOL", DistanceTravelledByGolfCart * MILES_IN_METER, 1);
STAT_LINE_1(float, "DISTHEL", DistanceTravelledByHelicoptor * MILES_IN_METER, 1);
#ifdef FIX_BUGS
STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike
+ DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane) * MILES_IN_METER, 1);
STAT_LINE_1(float, "MXCARD", MaximumJumpDistance * FEET_IN_METER, 1);
STAT_LINE_1(float, "MXCARJ", MaximumJumpHeight * FEET_IN_METER, 1);
#else
STAT_LINE_1(float, "TOT_DIS", (DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat + DistanceTravelledByBike
+ DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor) * MILES_IN_METER, 1);
#endif
break;
#endif
case CMenuManager::LANGUAGE_FRENCH:
case CMenuManager::LANGUAGE_GERMAN:
case CMenuManager::LANGUAGE_ITALIAN:
case CMenuManager::LANGUAGE_SPANISH:
#ifdef MORE_LANGUAGES
case CMenuManager::LANGUAGE_POLISH:
case CMenuManager::LANGUAGE_RUSSIAN:
case CMenuManager::LANGUAGE_JAPANESE:
#endif
STAT_LINE_1(float, "FESTDFM", DistanceTravelledOnFoot, 1);
STAT_LINE_1(float, "FESTDCM", DistanceTravelledByCar, 1);
STAT_LINE_1(float, "DISTBIM", DistanceTravelledByBike, 1);
STAT_LINE_1(float, "DISTBOM", DistanceTravelledByBoat, 1);
STAT_LINE_1(float, "DISTGOM", DistanceTravelledByGolfCart, 1);
STAT_LINE_1(float, "DISTHEM", DistanceTravelledByHelicoptor, 1);
#ifdef FIX_BUGS
STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat
+ DistanceTravelledByBike + DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor + DistanceTravelledByPlane, 1);
STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1);
STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1);
#else
STAT_LINE_1(float, "TOTDISM", DistanceTravelledOnFoot + DistanceTravelledByCar + DistanceTravelledByBoat
+ DistanceTravelledByGolfCart + DistanceTravelledByHelicoptor, 1);
#endif
break;
default:
break;
}
// They were selecting the unit according to language in III, but they deleted the feet code in VC. Weird
#ifndef FIX_BUGS
STAT_LINE_1(float, "MXCARDM", MaximumJumpDistance, 1);
STAT_LINE_1(float, "MXCARJM", MaximumJumpHeight, 1);
#endif
STAT_LINE_1(int, "MXFLIP", MaximumJumpFlips, 0);
STAT_LINE_2(int, "NOUNIF", NumberOfUniqueJumpsFound, 0, TotalNumberOfUniqueJumps, 0);
STAT_LINE_1(int, "MXJUMP", MaximumJumpSpins, 4);
TEXT_ON_LEFT_GXT("BSTSTU");
switch (BestStuntJump) {
case 1:
TEXT_ON_RIGHT(TheText.Get("INSTUN"));
break;
case 2:
TEXT_ON_RIGHT(TheText.Get("PRINST"));
break;
case 3:
TEXT_ON_RIGHT(TheText.Get("DBINST"));
break;
case 4:
TEXT_ON_RIGHT(TheText.Get("DBPINS"));
break;
case 5:
TEXT_ON_RIGHT(TheText.Get("TRINST"));
break;
case 6:
TEXT_ON_RIGHT(TheText.Get("PRTRST"));
break;
case 7:
TEXT_ON_RIGHT(TheText.Get("QUINST"));
break;
case 8:
TEXT_ON_RIGHT(TheText.Get("PQUINS"));
break;
default:
TEXT_ON_RIGHT(TheText.Get("NOSTUC"));
break;
}
STAT_LINE_1(int, "ST_WHEE", LongestWheelie, 0);
STAT_LINE_1(float, "ST_WHED", LongestWheelieDist, 1);
STAT_LINE_1(int, "ST_STOP", LongestStoppie, 0);
STAT_LINE_1(float, "ST_STOD", LongestStoppieDist, 1);
STAT_LINE_1(int, "ST_2WHE", Longest2Wheel, 0);
STAT_LINE_1(float, "ST_2WHD", Longest2WheelDist, 1);
if (LoanSharks > 0.0f)
STAT_LINE_1(int, "ST_LOAN", LoanSharks, 0);
STAT_LINE_1(int, "FEST_CC", CriminalsCaught, 0);
STAT_LINE_1(int, "FEST_HV", HighestLevelVigilanteMission, 0);
STAT_LINE_1(int, "PASDRO", PassengersDroppedOffWithTaxi, 0);
STAT_LINE_1(float, "MONTAX", MoneyMadeWithTaxi, 3);
STAT_LINE_1(int, "FEST_LS", LivesSavedWithAmbulance, 0);
STAT_LINE_1(int, "FEST_HA", HighestLevelAmbulanceMission, 0);
STAT_LINE_1(int, "FEST_FE", FiresExtinguished, 0);
STAT_LINE_1(int, "FIRELVL", HighestLevelFireMission, 0);
STAT_LINE_2(int, "ST_STOR", StoresKnockedOff, 0, 15, 0);
if (MovieStunts > 0.0f)
STAT_LINE_1(int, "ST_MOVI", MovieStunts, 0);
STAT_LINE_2(int, "ST_ASSI", Assassinations, 0, 5, 0);
if (PhotosTaken > 0)
STAT_LINE_1(int, "ST_PHOT", PhotosTaken, 0);
if (PizzasDelivered > 0.0f)
STAT_LINE_1(int, "ST_PIZZ", PizzasDelivered, 0);
if (GarbagePickups > 0.0f)
STAT_LINE_1(int, "ST_GARB", GarbagePickups, 0);
if (IceCreamSold > 0.0f)
STAT_LINE_1(int, "ST_ICEC", IceCreamSold, 0);
if (HighestScores[1])
STAT_LINE_1(int, "STHC_02", HighestScores[1], 0);
FASTEST_TIME(0, "STFT_01");
FASTEST_TIME(1, "STFT_02");
FASTEST_TIME(2, "STFT_03");
FASTEST_TIME(3, "STFT_04");
FASTEST_TIME(4, "STFT_05");
FASTEST_TIME(5, "STFT_06");
FASTEST_TIME(6, "STFT_07");
FASTEST_TIME(7, "STFT_08");
FASTEST_TIME(8, "STFT_09");
FASTEST_TIME(9, "STFT_10");
FASTEST_TIME(10, "STFT_11");
FASTEST_TIME(11, "STFT_12");
FASTEST_TIME(12, "STFT_13");
FASTEST_TIME(13, "STFT_14");
FASTEST_TIME(14, "STFT_15");
FASTEST_TIME(15, "STFT_16");
FASTEST_TIME(16, "STFT_17");
FASTEST_TIME(17, "STFT_18");
FASTEST_TIME(18, "STFT_19");
FASTEST_TIME(19, "STFT_20");
FASTEST_TIME(22, "STFT_23");
if (HighestScores[0])
STAT_LINE_1(int, "STHC_01", HighestScores[0], 0);
if (HighestScores[3])
STAT_LINE_1(int, "STHC_04", HighestScores[3], 0);
if (HighestScores[2])
STAT_LINE_1(int, "STHC_03", HighestScores[2], 0);
if (BestPositions[0] != INT_MAX)
STAT_LINE_1(int, "STHC_05", BestPositions[0], 0);
FASTEST_TIME(20, "STFT_21");
if (FastestTimes[21])
STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1);
if (TopShootingRangeScore > 0.0f)
STAT_LINE_1(int, "TOP_SHO", TopShootingRangeScore, 0);
if (ShootingRank > 0.0f)
STAT_LINE_1(int, "SHO_RAN", ShootingRank, 0);
int flightMinute = (FlightTime / 60000) % 60;
int flightHour = (FlightTime / 60000) / 60;
STAT_LINE_2(int, "ST_FTIM", flightHour, 0, flightMinute, 1);
// We always have pilot rank if we flew more then 5 minutes
#ifndef FIX_BUGS
if (flightHour != 0)
TEXT_ON_LEFT_GXT("ST_PRAN");
#endif
#ifdef FIX_BUGS
#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || (flightHour == hour && flightMinute >= minute))
#else
#define FL_TIME_MORE_THAN(hour, minute) (flightHour > hour || flightMinute >= minute)
#endif
if (FL_TIME_MORE_THAN(0,5)) {
#ifdef FIX_BUGS
TEXT_ON_LEFT_GXT("ST_PRAN");
#endif
if (!FL_TIME_MORE_THAN(0,10)) TEXT_ON_RIGHT(TheText.Get("ST_PR01"));
else if (!FL_TIME_MORE_THAN(0,20)) TEXT_ON_RIGHT(TheText.Get("ST_PR02"));
else if (!FL_TIME_MORE_THAN(0,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR03"));
else if (!FL_TIME_MORE_THAN(1,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR04"));
else if (!FL_TIME_MORE_THAN(1,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR05"));
else if (!FL_TIME_MORE_THAN(2,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR06"));
else if (!FL_TIME_MORE_THAN(2,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR07"));
else if (!FL_TIME_MORE_THAN(3,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR08"));
else if (!FL_TIME_MORE_THAN(3,30)) TEXT_ON_RIGHT(TheText.Get("ST_PR09"));
else if (!FL_TIME_MORE_THAN(4,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR10"));
else if (!FL_TIME_MORE_THAN(5,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR11"));
else if (!FL_TIME_MORE_THAN(10,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR12"));
else if (!FL_TIME_MORE_THAN(20,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR13"));
else if (!FL_TIME_MORE_THAN(25,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR14"));
else if (!FL_TIME_MORE_THAN(30,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR15"));
else if (!FL_TIME_MORE_THAN(49,2)) TEXT_ON_RIGHT(TheText.Get("ST_PR16"));
else if (!FL_TIME_MORE_THAN(50,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR17"));
else if (!FL_TIME_MORE_THAN(100,0)) TEXT_ON_RIGHT(TheText.Get("ST_PR18"));
else TEXT_ON_RIGHT(TheText.Get("ST_PR19"));
}
#undef FL_TIME_MORE_THAN
if (BloodRingKills > 0)
STAT_LINE_1(int, "ST_BRK", BloodRingKills, 0);
if (BloodRingTime > 0)
STAT_LINE_1(int, "ST_LTBR", BloodRingTime, 0);
STAT_LINE_1(int, "ST_DRWN", TimesDrowned, 0);
if (SeagullsKilled > 0)
STAT_LINE_1(int, "SEAGULL", SeagullsKilled, 0);
bool playerHatesRadio = true;
float* pListenTimeArray = DMAudio.GetListenTimeArray();
for (int i = 0; i < NUM_RADIOS; i++) {
FavoriteRadioStationList[i] = pListenTimeArray[i];
if (FavoriteRadioStationList[i] != 0.0) // double
playerHatesRadio = false;
}
if (!playerHatesRadio) {
// Most listened
TEXT_ON_LEFT_GXT("FST_MFR");
float mostListenTime = FavoriteRadioStationList[0];
int mostListenedRadio = 0;
for (int i = 0; i < NUM_RADIOS; i++) {
if (FavoriteRadioStationList[i] > mostListenTime) {
mostListenTime = FavoriteRadioStationList[i];
mostListenedRadio = i;
}
}
switch (mostListenedRadio) {
case WILDSTYLE:
TEXT_ON_RIGHT(TheText.Get("FEA_FM0"));
break;
case FLASH_FM:
TEXT_ON_RIGHT(TheText.Get("FEA_FM1"));
break;
case KCHAT:
TEXT_ON_RIGHT(TheText.Get("FEA_FM2"));
break;
case FEVER:
TEXT_ON_RIGHT(TheText.Get("FEA_FM3"));
break;
case V_ROCK:
TEXT_ON_RIGHT(TheText.Get("FEA_FM4"));
break;
case VCPR:
TEXT_ON_RIGHT(TheText.Get("FEA_FM5"));
break;
case RADIO_ESPANTOSO:
TEXT_ON_RIGHT(TheText.Get("FEA_FM6"));
break;
case EMOTION:
TEXT_ON_RIGHT(TheText.Get("FEA_FM7"));
break;
case WAVE:
TEXT_ON_RIGHT(TheText.Get("FEA_FM8"));
break;
case USERTRACK:
TEXT_ON_RIGHT(TheText.Get("FEA_MP3"));
break;
default:
TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh
break;
}
// Least listened
TEXT_ON_LEFT_GXT("FST_LFR");
float leastListenTime = FavoriteRadioStationList[0];
int leastListenedRadio = 0;
for (int i = 0; i < NUM_RADIOS; i++) {
#ifdef FIX_BUGS
if (!DMAudio.IsMP3RadioChannelAvailable() && i == USERTRACK)
continue;
#endif
if (FavoriteRadioStationList[i] < leastListenTime) {
leastListenTime = FavoriteRadioStationList[i];
leastListenedRadio = i;
}
}
#ifndef FIX_BUGS
if (!DMAudio.IsMP3RadioChannelAvailable() && leastListenedRadio == USERTRACK)
leastListenedRadio = WAVE;
#endif
switch (leastListenedRadio) {
case WILDSTYLE:
TEXT_ON_RIGHT(TheText.Get("FEA_FM0"));
break;
case FLASH_FM:
TEXT_ON_RIGHT(TheText.Get("FEA_FM1"));
break;
case KCHAT:
TEXT_ON_RIGHT(TheText.Get("FEA_FM2"));
break;
case FEVER:
TEXT_ON_RIGHT(TheText.Get("FEA_FM3"));
break;
case V_ROCK:
TEXT_ON_RIGHT(TheText.Get("FEA_FM4"));
break;
case VCPR:
TEXT_ON_RIGHT(TheText.Get("FEA_FM5"));
break;
case RADIO_ESPANTOSO:
TEXT_ON_RIGHT(TheText.Get("FEA_FM6"));
break;
case EMOTION:
TEXT_ON_RIGHT(TheText.Get("FEA_FM7"));
break;
case WAVE:
TEXT_ON_RIGHT(TheText.Get("FEA_FM8"));
break;
case USERTRACK:
TEXT_ON_RIGHT(TheText.Get("FEA_MP3"));
break;
default:
TEXT_ON_RIGHT(TheText.Get("FEA_FM8")); // heh
break;
}
}
STAT_LINE_1(int, "SPRAYIN", Sprayings, 0);
STAT_LINE_1(float, "ST_WEAP", WeaponBudget, 3);
STAT_LINE_1(float, "ST_FASH", FashionBudget, 3);
STAT_LINE_1(float, "ST_PROP", PropertyBudget, 3);
STAT_LINE_1(float, "ST_AUTO", AutoPaintingBudget, 3);
STAT_LINE_1(float, "ST_DAMA", PropertyBudget, 3);
if (NumPropertyOwned > 0) {
STAT_LINE_1(int, "PROPOWN", NumPropertyOwned, 0);
if (PropertyOwned[0]) TEXT_ON_RIGHT(TheText.Get("STPR_1"));
if (PropertyOwned[1]) TEXT_ON_RIGHT(TheText.Get("STPR_2"));
if (PropertyOwned[2]) TEXT_ON_RIGHT(TheText.Get("STPR_3"));
if (PropertyOwned[3]) TEXT_ON_RIGHT(TheText.Get("STPR_4"));
if (PropertyOwned[4]) TEXT_ON_RIGHT(TheText.Get("STPR_5"));
if (PropertyOwned[5]) TEXT_ON_RIGHT(TheText.Get("STPR_6"));
if (PropertyOwned[6]) TEXT_ON_RIGHT(TheText.Get("STPR_7"));
if (PropertyOwned[7]) TEXT_ON_RIGHT(TheText.Get("STPR_8"));
if (PropertyOwned[8]) TEXT_ON_RIGHT(TheText.Get("STPR_9"));
if (PropertyOwned[9]) TEXT_ON_RIGHT(TheText.Get("STPR_10"));
if (PropertyOwned[10]) TEXT_ON_RIGHT(TheText.Get("STPR_11"));
if (PropertyOwned[11]) TEXT_ON_RIGHT(TheText.Get("STPR_12"));
if (PropertyOwned[12]) TEXT_ON_RIGHT(TheText.Get("STPR_13"));
if (PropertyOwned[13]) TEXT_ON_RIGHT(TheText.Get("STPR_14"));
if (PropertyOwned[14]) TEXT_ON_RIGHT(TheText.Get("STPR_15"));
}
STAT_LINE_1(int, "CHASE", HighestChaseValue, 0);
TEXT_ON_RIGHT(FindChaseString(HighestChaseValue));
return counter;
#undef STAT_LINE_1
#undef STAT_LINE_2
#undef TEXT_ON_LEFT_GXT
#undef TEXT_ON_RIGHT
#undef FASTEST_TIME
}

View File

@ -49,8 +49,8 @@ public:
static int32 WantedStarsAttained;
static int32 WantedStarsEvaded;
static int32 PeopleKilledByPlayer;
static int32 ProgressMade;
static int32 TotalProgressInGame;
static float ProgressMade;
static float TotalProgressInGame;
static float MaximumJumpDistance;
static float MaximumJumpHeight;
static int32 MaximumJumpFlips;
@ -147,4 +147,6 @@ public:
static void AddPropertyAsOwned(int32);
static void PopulateFavoriteRadioStationList();
static float GetFavoriteRadioStationList(int32);
static void BuildStatLine(Const char *, void *, int, void *, int);
static int ConstructStatLine(int);
};

View File

@ -32,6 +32,10 @@
#include "ColStore.h"
#include "DMAudio.h"
#include "Script.h"
#include "MemoryMgr.h"
#include "MemoryHeap.h"
#include "Font.h"
#include "Frontend.h"
//--MIAMI: file done (possibly bugs)
@ -289,12 +293,22 @@ CStreaming::Shutdown(void)
}
}
#ifndef MASTER
uint64 timeProcessingTXD;
uint64 timeProcessingDFF;
#endif
void
CStreaming::Update(void)
{
CStreamingInfo *si, *prev;
bool requestedSubway = false;
#ifndef MASTER
timeProcessingTXD = 0;
timeProcessingDFF = 0;
#endif
UpdateMemoryUsed();
if(ms_channelError != -1){
@ -332,6 +346,10 @@ CStreaming::Update(void)
CColStore::EnsureCollisionIsInMemory(FindPlayerCoors());
}
// TODO: PrintRequestList
//if (CPad::GetPad(1)->GetLeftShoulder2JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2())
// PrintRequestList();
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
if((si->m_flags & (STREAMFLAGS_KEEP_IN_MEMORY|STREAMFLAGS_PRIORITY)) == 0)
@ -463,6 +481,14 @@ GetObjectName(int streamId)
return objname;
}
#ifdef USE_CUSTOM_ALLOCATOR
RpAtomic*
RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data)
{
// empty because we expect models to be pre-instanced
return atomic;
}
#endif
bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
@ -497,10 +523,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Set Txd and anims to use
CTxdStore::AddRef(mi->GetTxdSlot());
#if GTA_VERSION > GTAVC_PS2
if(animId != -1)
CAnimManager::AddAnimBlockRef(animId);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
#endif
PUSH_MEMID(MEMID_STREAM_MODELS);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
if(mi->IsSimple()){
success = CFileLoader::LoadAtomicFile(stream, streamId);
// TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that
@ -512,14 +541,21 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else{
success = CFileLoader::LoadClumpFile(stream, streamId);
#ifdef USE_CUSTOM_ALLOCATOR
if(success)
RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
#endif
}
POP_MEMID();
UpdateMemoryUsed();
// Txd and anims no longer needed unless we only read part of the file
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
#if GTA_VERSION > GTAVC_PS2
if(animId != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(animId);
#endif
}
if(!success){
@ -538,12 +574,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return false;
}
PUSH_MEMID(MEMID_STREAM_TEXUTRES);
if(ms_bLoadingBigModel || cdsize > 200){
success = CTxdStore::StartLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
if(success)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else
success = CTxdStore::LoadTxd(streamId - STREAM_OFFSET_TXD, stream);
POP_MEMID();
UpdateMemoryUsed();
if(!success){
@ -554,7 +592,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return false;
}
}else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){
if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){
PUSH_MEMID(MEMID_STREAM_COLLISION);
bool success = CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length);
POP_MEMID();
if(!success){
debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL));
RemoveModel(streamId);
ReRequestModel(streamId);
@ -569,8 +610,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
PUSH_MEMID(MEMID_STREAM_ANIMATION);
CAnimManager::LoadAnimFile(stream, true, nil);
CAnimManager::CreateAnimAssocGroups();
POP_MEMID();
}
RwStreamClose(stream, &mem);
@ -603,7 +646,9 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Mark objects as loaded
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
#endif
}
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
@ -638,26 +683,39 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
if(streamId < STREAM_OFFSET_TXD){
// Model
mi = CModelInfo::GetModelInfo(streamId);
PUSH_MEMID(MEMID_STREAM_MODELS);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
success = CFileLoader::FinishLoadClumpFile(stream, streamId);
if(success)
if(success){
#ifdef USE_CUSTOM_ALLOCATOR
RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
#endif
success = AddToLoadedVehiclesList(streamId);
}
POP_MEMID();
mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
#if GTA_VERSION > GTAVC_PS2
if(mi->GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex());
#endif
}else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD);
PUSH_MEMID(MEMID_STREAM_TEXUTRES);
success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
POP_MEMID();
CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD);
}else{
assert(0 && "invalid streamId");
}
RwStreamClose(stream, &mem);
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
#endif
if(!success){
RemoveModel(streamId);
@ -740,7 +798,15 @@ CStreaming::RequestBigBuildings(eLevelName level)
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
if(b && b->bIsBIGBuilding
#ifdef NO_ISLAND_LOADING
&& (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) &&
(b != pIslandLODbeachEntity)) ||
(b->m_level == level))
#else
&& b->m_level == level
#endif
)
if(!b->bStreamBIGBuilding)
RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
@ -757,8 +823,11 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding
#ifndef NO_ISLAND_LOADING
&& b->m_level == level
#ifdef NO_ISLAND_LOADING
&& (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && (b != pIslandLODbeachEntity)
) || (b->m_level == level))
#else
&& b->m_level == level
#endif
)
if(b->bStreamBIGBuilding){
@ -828,7 +897,7 @@ CStreaming::InstanceLoadedModels(const CVector &pos)
void
CStreaming::RequestIslands(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
ISLAND_LOADING_ISNT(HIGH)
switch(level){
case LEVEL_MAINLAND:
if(islandLODbeach != -1)
@ -840,7 +909,6 @@ CStreaming::RequestIslands(eLevelName level)
break;
default: break;
}
#endif
}
static char *IGnames[] = {
@ -1170,12 +1238,13 @@ CStreaming::RemoveBuildingsNotInArea(int32 area)
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
ISLAND_LOADING_IS(LOW)
{
if(level != LEVEL_BEACH)
RemoveBigBuildings(LEVEL_BEACH);
if(level != LEVEL_MAINLAND)
RemoveBigBuildings(LEVEL_MAINLAND);
#endif
}
RemoveIslandsNotUsed(level);
}
@ -1195,7 +1264,6 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
#ifndef NO_ISLAND_LOADING
int i;
if(pIslandLODmainlandEntity == nil)
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
@ -1207,7 +1275,12 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
if(building->GetModelIndex() == islandLODbeach)
pIslandLODbeachEntity = building;
}
#ifdef NO_ISLAND_LOADING
if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
DeleteIsland(pIslandLODmainlandEntity);
DeleteIsland(pIslandLODbeachEntity);
} else
#endif
switch(level){
case LEVEL_MAINLAND:
DeleteIsland(pIslandLODmainlandEntity);
@ -1217,7 +1290,6 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
break;
}
#endif // !NO_ISLAND_LOADING
}
void
@ -1818,26 +1890,36 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
CTimer::Suspend();
CGame::currLevel = CTheZones::m_CurrLevel;
DMAudio.SetEffectsFadeVol(0);
CPad::StopPadsShaking();
CCollision::LoadCollisionScreen(CGame::currLevel);
DMAudio.Service();
RemoveUnusedBigBuildings(CGame::currLevel);
RemoveUnusedBuildings(CGame::currLevel);
RemoveUnusedModelsInLoadedList();
CGame::TidyUpMemory(true, true);
ISLAND_LOADING_IS(LOW)
{
DMAudio.SetEffectsFadeVol(0);
CPad::StopPadsShaking();
CCollision::LoadCollisionScreen(CGame::currLevel);
DMAudio.Service();
RemoveUnusedBigBuildings(CGame::currLevel);
RemoveUnusedBuildings(CGame::currLevel);
RemoveUnusedModelsInLoadedList();
CGame::TidyUpMemory(true, true);
}
CReplay::EmptyReplayBuffer();
if(CGame::currLevel != LEVEL_GENERIC)
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
ISLAND_LOADING_IS(LOW)
CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
else if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) {
RemoveIslandsNotUsed(CGame::currLevel);
CStreaming::RequestIslands(CGame::currLevel);
}
CStreaming::LoadAllRequestedModels(false);
CGame::TidyUpMemory(true, true);
CTimer::Resume();
DMAudio.SetEffectsFadeVol(127);
ISLAND_LOADING_IS(LOW)
DMAudio.SetEffectsFadeVol(127);
}
@ -2415,19 +2497,27 @@ CStreaming::FlushRequestList(void)
void
CStreaming::ImGonnaUseStreamingMemory(void)
{
// empty
PUSH_MEMID(MEMID_STREAM);
}
void
CStreaming::IHaveUsedStreamingMemory(void)
{
POP_MEMID();
UpdateMemoryUsed();
}
void
CStreaming::UpdateMemoryUsed(void)
{
// empty
#ifdef USE_CUSTOM_ALLOCATOR
ms_memoryUsed =
gMainHeap.GetMemoryUsed(MEMID_STREAM) +
gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS) +
gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES) +
gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION) +
gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION);
#endif
}
#define STREAM_DIST 80.0f
@ -3041,3 +3131,71 @@ CStreaming::UpdateForAnimViewer(void)
CStreaming::RetryLoadFile(CStreaming::ms_channelError);
}
}
void
CStreaming::PrintStreamingBufferState()
{
char str[128];
wchar wstr[128];
uint32 offset, size;
CTimer::Stop();
int i = 0;
while (i < NUMSTREAMINFO) {
while (true) {
int j = 0;
DoRWStuffStartOfFrame(50, 50, 50, 0, 0, 0, 255);
CPad::UpdatePads();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
DefinedState();
CRect unusedRect(0, 0, RsGlobal.maximumWidth, RsGlobal.maximumHeight);
CRGBA unusedColor(255, 255, 255, 255);
CFont::SetFontStyle(FONT_BANK);
CFont::SetBackgroundOff();
CFont::SetWrapx(DEFAULT_SCREEN_WIDTH);
CFont::SetScale(0.5f, 0.75f);
CFont::SetCentreOff();
CFont::SetCentreSize(DEFAULT_SCREEN_WIDTH);
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(200, 200, 200, 200));
CFont::SetBackGroundOnlyTextOff();
int modelIndex = i;
if (modelIndex < NUMSTREAMINFO) {
int y = 24;
for ( ; j < 34 && modelIndex < NUMSTREAMINFO; modelIndex++) {
CStreamingInfo *streamingInfo = &ms_aInfoForModel[modelIndex];
CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelIndex);
if (streamingInfo->m_loadState != STREAMSTATE_LOADED || !streamingInfo->GetCdPosnAndSize(offset, size))
continue;
if (modelIndex >= STREAM_OFFSET_TXD)
sprintf(str, "txd %s, refs %d, size %dK, flags 0x%x", CTxdStore::GetTxdName(modelIndex - STREAM_OFFSET_TXD),
CTxdStore::GetNumRefs(modelIndex - STREAM_OFFSET_TXD), 2 * size, streamingInfo->m_flags);
else
sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetName(), modelInfo->GetNumRefs(), 2 * size,
streamingInfo->m_flags);
AsciiToUnicode(str, wstr);
CFont::PrintString(24.0f, y, wstr);
y += 12;
j++;
}
}
if (CPad::GetPad(1)->GetCrossJustDown())
i = modelIndex;
if (!CPad::GetPad(1)->GetTriangleJustDown())
break;
i = 0;
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
CTimer::Update();
}

View File

@ -197,11 +197,11 @@ public:
static void DeleteFarAwayRwObjects(const CVector &pos);
static void DeleteAllRwObjects(void);
static void DeleteRwObjectsAfterDeath(const CVector &pos);
static void DeleteRwObjectsBehindCamera(size_t mem);
static void DeleteRwObjectsBehindCamera(size_t mem); // originally signed
static void DeleteRwObjectsInSectorList(CPtrList &list);
static void DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y);
static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem);
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem);
static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); // originally signed
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); // originally signed
static void LoadScene(const CVector &pos);
static void LoadSceneCollision(const CVector &pos);
@ -210,4 +210,6 @@ public:
static void MemoryCardLoad(uint8 *buffer, uint32 length);
static void UpdateForAnimViewer(void);
static void PrintStreamingBufferState();
};

View File

@ -35,7 +35,7 @@
CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
CPtrList CWorld::ms_bigBuildingsList[4];
CPtrList CWorld::ms_bigBuildingsList[NUM_LEVELS];
CPtrList CWorld::ms_listMovingEntityPtrs;
CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];
uint16 CWorld::ms_nCurrentScanCode;
@ -147,13 +147,13 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov
}
}
CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
CWorld::Remove(pVehicle);
Remove(pVehicle);
delete pVehicle;
}
}
CObject::DeleteAllTempObjectsInArea(pos, radius);
gFireManager.ExtinguishPoint(pos, radius);
CWorld::ExtinguishAllCarFiresInArea(pos, radius);
ExtinguishAllCarFiresInArea(pos, radius);
CExplosion::RemoveAllExplosionsInArea(pos, radius);
if(bRemoveProjectilesAndTidyUpShadows) {
CProjectileInfo::RemoveAllProjectiles();
@ -796,7 +796,7 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings,
bool bVehicles, bool bPeds, bool bObjects, bool bDummies)
{
CWorld::AdvanceCurrentScanCode();
AdvanceCurrentScanCode();
*nEntitiesFound = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
@ -813,42 +813,42 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bPeds) {
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bObjects) {
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bDummies) {
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
CWorld::FindObjectsOfTypeInRangeSectorList(
FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
@ -942,26 +942,26 @@ CEntity *
CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore,
bool ignoreSomeObjects)
{
static CColModel sphereCol;
static CColModel OurColModel;
CColSphere sphere;
sphereCol.boundingSphere.center.x = 0.0f;
sphereCol.boundingSphere.center.y = 0.0f;
sphereCol.boundingSphere.center.z = 0.0f;
sphereCol.boundingSphere.radius = radius;
sphereCol.boundingBox.min.x = -radius;
sphereCol.boundingBox.min.y = -radius;
sphereCol.boundingBox.min.z = -radius;
sphereCol.boundingBox.max.x = radius;
sphereCol.boundingBox.max.y = radius;
sphereCol.boundingBox.max.z = radius;
sphereCol.numSpheres = 1;
OurColModel.boundingSphere.center.x = 0.0f;
OurColModel.boundingSphere.center.y = 0.0f;
OurColModel.boundingSphere.center.z = 0.0f;
OurColModel.boundingSphere.radius = radius;
OurColModel.boundingBox.min.x = -radius;
OurColModel.boundingBox.min.y = -radius;
OurColModel.boundingBox.min.z = -radius;
OurColModel.boundingBox.max.x = radius;
OurColModel.boundingBox.max.y = radius;
OurColModel.boundingBox.max.z = radius;
OurColModel.numSpheres = 1;
sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f));
sphereCol.spheres = &sphere;
sphereCol.numLines = 0;
sphereCol.numBoxes = 0;
sphereCol.numTriangles = 0;
sphereCol.ownsCollisionVolumes = false;
OurColModel.spheres = &sphere;
OurColModel.numLines = 0;
OurColModel.numBoxes = 0;
OurColModel.numTriangles = 0;
OurColModel.ownsCollisionVolumes = false;
CMatrix sphereMat;
sphereMat.SetTranslate(spherePos);
@ -980,7 +980,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
if(e->GetBoundRadius() + radius > distance) {
CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
int collidedSpheres =
CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol,
CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol,
gaTempSphereColPoints, nil, nil);
if(collidedSpheres != 0 ||
@ -1070,7 +1070,7 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles,
bool bPeds, bool bObjects, bool bDummies)
{
CWorld::AdvanceCurrentScanCode();
AdvanceCurrentScanCode();
*nCollidingEntities = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
@ -1087,42 +1087,42 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bPeds) {
CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position,
FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position,
radius, bCheck2DOnly, nCollidingEntities,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bObjects) {
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bDummies) {
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
CWorld::FindObjectsKindaCollidingSectorList(
FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
@ -1156,7 +1156,7 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles,
bool bPeds, bool bObjects, bool bDummies)
{
CWorld::AdvanceCurrentScanCode();
AdvanceCurrentScanCode();
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
@ -1164,49 +1164,49 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X - 1);
const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y - 1);
#else
const int32 nEndX = Min(GetSectorIndexX(vecSectorPos.x), NUMSECTORS_X);
const int32 nEndY = Min(GetSectorIndexY(vecSectorPos.y), NUMSECTORS_Y);
const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X);
const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y);
#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS],
FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingCubeSectorList(
FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], vecStartPos, vecEndPos,
nIntersecting, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES],
FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingCubeSectorList(
FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos,
nIntersecting, maxEntitiesToFind, aEntities);
}
if(bPeds) {
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS],
FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP],
FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
}
if(bObjects) {
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS],
FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingCubeSectorList(
FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
}
if(bDummies) {
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES],
FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingCubeSectorList(
FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
}
@ -1242,7 +1242,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const
CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds,
bool bObjects, bool bDummies)
{
CWorld::AdvanceCurrentScanCode();
AdvanceCurrentScanCode();
*nEntitiesFound = 0;
const int32 nStartX = Max(GetSectorIndexX(fStartX), 0);
const int32 nStartY = Max(GetSectorIndexY(fStartY), 0);
@ -1257,42 +1257,42 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bPeds) {
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_PEDS], boundingBox, matrix, position, nEntitiesFound,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bObjects) {
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS], boundingBox, matrix, position, nEntitiesFound,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bDummies) {
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES], boundingBox, matrix, position, nEntitiesFound,
maxEntitiesToFind, aEntities);
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
@ -1327,7 +1327,7 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
int16 maxEntitiesToFind, CEntity **aEntities, bool bVehicles, bool bPeds,
bool bObjects)
{
CWorld::AdvanceCurrentScanCode();
AdvanceCurrentScanCode();
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
@ -1342,26 +1342,26 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bVehicles) {
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, true, false);
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos,
nIntersecting, maxEntitiesToFind, aEntities, true, false);
}
if(bPeds) {
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, true);
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, true);
}
if(bObjects) {
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, false);
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, false);
}
@ -1399,102 +1399,6 @@ CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList &list, const CVec
}
}
CPlayerPed *
FindPlayerPed(void)
{
return CWorld::Players[CWorld::PlayerInFocus].m_pPed;
}
CVehicle *
FindPlayerVehicle(void)
{
CPlayerPed *ped = FindPlayerPed();
if(ped && ped->InVehicle()) return ped->m_pMyVehicle;
return nil;
}
CVehicle *
FindPlayerTrain(void)
{
if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain())
return FindPlayerVehicle();
else
return nil;
}
CEntity *
FindPlayerEntity(void)
{
CPlayerPed *ped = FindPlayerPed();
if(ped->InVehicle())
return ped->m_pMyVehicle;
else
return ped;
}
CVector
FindPlayerCoors(void)
{
#ifdef FIX_BUGS
if (CReplay::IsPlayingBack())
return TheCamera.GetPosition();
#endif
CPlayerPed *ped = FindPlayerPed();
if(ped->InVehicle())
return ped->m_pMyVehicle->GetPosition();
else
return ped->GetPosition();
}
CVector &
FindPlayerSpeed(void)
{
#ifdef FIX_BUGS
static CVector vecTmpVector(0.0f, 0.0f, 0.0f);
if (CReplay::IsPlayingBack())
return vecTmpVector;
#endif
CPlayerPed *ped = FindPlayerPed();
if(ped->InVehicle())
return ped->m_pMyVehicle->m_vecMoveSpeed;
else
return ped->m_vecMoveSpeed;
}
const CVector &
FindPlayerCentreOfWorld(int32 player)
{
#ifdef FIX_BUGS
if(CReplay::IsPlayingBack()) return TheCamera.GetPosition();
#endif
if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition();
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
return CWorld::Players[player].m_pPed->GetPosition();
}
const CVector &
FindPlayerCentreOfWorld_NoSniperShift(void)
{
#ifdef FIX_BUGS
if (CReplay::IsPlayingBack()) return TheCamera.GetPosition();
#endif
if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
return FindPlayerPed()->GetPosition();
}
float
FindPlayerHeading(void)
{
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading();
return FindPlayerPed()->GetForward().Heading();
}
void
CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2)
{
@ -1517,7 +1421,7 @@ CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, floa
}
}
CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
CWorld::Remove(pVehicle);
Remove(pVehicle);
delete pVehicle;
}
}
@ -1543,7 +1447,7 @@ CWorld::ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, floa
void
CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
{
CWorld::AdvanceCurrentScanCode();
AdvanceCurrentScanCode();
float fStartX = x1 - 10.0f;
float fStartY = y1 - 10.0f;
float fEndX = x2 + 10.0f;
@ -1560,12 +1464,12 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2,
CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2,
y2, fStartX, fStartY, fEndX, fEndY);
CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1,
CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1,
y1, x2, y2, fStartX, fStartY, fEndX, fEndY);
CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2);
CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2,
CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2);
CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2,
y2);
}
}
@ -1580,7 +1484,7 @@ CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1
if(pVehicle->m_scanCode != GetCurrentScanCode()) {
pVehicle->m_scanCode = GetCurrentScanCode();
const CVector &vehiclePos = pVehicle->GetPosition();
eCarMission carMission = pVehicle->AutoPilot.m_nCarMission;
uint8 carMission = pVehicle->AutoPilot.m_nCarMission;
if(pVehicle != FindPlayerVehicle() && vehiclePos.x > fStartX && vehiclePos.x < fEndX &&
vehiclePos.y > fStartY && vehiclePos.y < fEndY && pVehicle->bIsLawEnforcer &&
(carMission == MISSION_RAMPLAYER_FARAWAY || carMission == MISSION_RAMPLAYER_CLOSE ||
@ -1739,14 +1643,24 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
}
}
inline void
AddSteamsFromGround(CPtrList& list)
{
CPtrNode* pNode = list.first;
while (pNode) {
((CEntity*)pNode->item)->AddSteamsFromGround(nil);
pNode = pNode->next;
}
}
void
CWorld::AddParticles(void)
{
for(int32 y = 0; y < NUMSECTORS_Y; y++) {
for(int32 x = 0; x < NUMSECTORS_X; x++) {
CSector *pSector = GetSector(x, y);
CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
}
}
}
@ -1758,44 +1672,52 @@ CWorld::ShutDown(void)
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
#ifndef FIX_BUGS
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
#endif
}
for(int32 i = 0; i < 4; i++) {
for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) {
for(int32 i = 0; i < NUM_LEVELS; i++) {
for(CPtrNode *pNode = ms_bigBuildingsList[i].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
// Maybe remove from world here?
delete pEntity;
}
GetBigBuildingList((eLevelName)i).Flush();
ms_bigBuildingsList[i].Flush();
}
for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) {
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
#ifdef FIX_BUGS
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
#endif
if(pSector->m_lists[ENTITYLIST_BUILDINGS].first) {
sprintf(gString, "Building list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
@ -1840,19 +1762,19 @@ CWorld::ClearForRestart(void)
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = GetBigBuildingList(LEVEL_GENERIC).first; pNode; pNode = pNode->next) {
CVehicle *pVehicle = (CVehicle *)pNode->item;
if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) {
CWorld::Remove(pVehicle);
Remove(pVehicle);
delete pVehicle;
}
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
}
@ -1885,7 +1807,7 @@ CWorld::RepositionOneObject(CEntity *pEntity)
float fBoundingBoxMinZ = pColModel->boundingBox.min.z;
float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
if (fHeight < OBJECT_REPOSITION_OFFSET_Z) fHeight = OBJECT_REPOSITION_OFFSET_Z;
position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y,
position.z = FindGroundZFor3DCoord(position.x, position.y,
position.z + fHeight, nil) -
fBoundingBoxMinZ;
pEntity->m_matrix.UpdateRW();
@ -1918,7 +1840,7 @@ CWorld::RepositionOneObject(CEntity *pEntity)
if(modelId == MI_BUOY) {
bool bFound = true;
const CVector &position = pEntity->GetPosition();
float fGroundZ = CWorld::FindGroundZFor3DCoord(position.x, position.y,
float fGroundZ = FindGroundZFor3DCoord(position.x, position.y,
position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound);
CColModel *pColModel = pEntity->GetColModel();
float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
@ -1983,17 +1905,17 @@ CWorld::RemoveStaticObjects()
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
CWorld::Remove(pEntity);
Remove(pEntity);
delete pEntity;
}
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
@ -2017,7 +1939,8 @@ CWorld::Process(void)
if (csObj->IsObject())
RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
else {
csObj->bOffscreen = !csObj->GetIsOnScreen();
if (!csObj->bOffscreen)
csObj->bOffscreen = !csObj->GetIsOnScreen();
RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStep(), !csObj->bOffscreen);
}
}
@ -2032,17 +1955,13 @@ CWorld::Process(void)
} else {
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CEntity *movingEnt = (CEntity *)node->item;
#ifdef SQUEEZE_PERFORMANCE
if (movingEnt->bRemoveFromWorld) {
RemoveEntityInsteadOfProcessingIt(movingEnt);
} else
#endif
if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
if (movingEnt->IsObject())
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
else {
movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
if (!movingEnt->bOffscreen)
movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStep(), !movingEnt->bOffscreen);
}
}
@ -2200,11 +2119,11 @@ CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, C
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius,
TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius,
fPower, pCreator, bProcessVehicleBombTimer);
CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower,
TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower,
pCreator, bProcessVehicleBombTimer);
CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius,
TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius,
fPower, pCreator, bProcessVehicleBombTimer);
}
}
@ -2262,7 +2181,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
if(!pEntity->GetIsStatic()) {
float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f);
CVector vecForceDir =
vecDistance * (fPower * pEntity->m_fMass / 14000.0f * fDamageMultiplier /
vecDistance * (fPower * pEntity->m_fMass / 1400.0f * fDamageMultiplier /
Max(fMagnitude, 0.01f));
vecForceDir.z = Max(vecForceDir.z, 0.0f);
if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f);

View File

@ -55,7 +55,7 @@ struct CStoredCollPoly;
class CWorld
{
static CPtrList ms_bigBuildingsList[4];
static CPtrList ms_bigBuildingsList[NUM_LEVELS];
static CPtrList ms_listMovingEntityPtrs;
static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];
static uint16 ms_nCurrentScanCode;
@ -178,15 +178,3 @@ public:
};
extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
class CPlayerPed;
class CVehicle;
CPlayerPed *FindPlayerPed(void);
CVehicle *FindPlayerVehicle(void);
CVehicle *FindPlayerTrain(void);
CEntity *FindPlayerEntity(void);
CVector FindPlayerCoors(void);
CVector &FindPlayerSpeed(void);
const CVector &FindPlayerCentreOfWorld(int32 player);
const CVector &FindPlayerCentreOfWorld_NoSniperShift(void);
float FindPlayerHeading(void);

View File

@ -17,12 +17,12 @@ enum eZoneAttribs
struct CAttributeZone
{
float minx;
float maxx;
float miny;
float maxy;
float minz;
float maxz;
int16 minx;
int16 maxx;
int16 miny;
int16 maxy;
int16 minz;
int16 maxz;
int16 attributes;
int16 wantedLevel;
};

View File

@ -209,6 +209,9 @@ CTheZones::PostZoneCreation(void)
for(i = 1; i < TotalNumberOfNavigationZones; i++)
InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]);
InitialiseAudioZoneArray();
#ifndef MASTER
CheckZonesForOverlap();
#endif
}
void
@ -222,8 +225,7 @@ CTheZones::CheckZonesForOverlap(void)
for(j = 1; j < TotalNumberOfInfoZones; j++)
if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j]))
sprintf(str, "Info zone %s contains %s\n",
&InfoZoneArray[j].name, &InfoZoneArray[i].name);
sprintf(str, "Info zone %s contains %s\n", InfoZoneArray[j].name, InfoZoneArray[i].name);
}
}

View File

@ -73,21 +73,24 @@ typedef int16_t int16;
typedef uint32_t uint32;
typedef int32_t int32;
typedef uintptr_t uintptr;
typedef intptr_t intptr;
typedef uint64_t uint64;
typedef int64_t int64;
// hardcode ucs-2
typedef uint16_t wchar;
#if defined(_MSC_VER)
typedef ptrdiff_t ssize_t;
#endif
#ifndef nil
#define nil NULL
#endif
#include "config.h"
#ifdef PED_SKIN
#include <rphanim.h>
#include <rpskin.h>
#endif
#ifdef __GNUC__
#define TYPEALIGN(n) __attribute__ ((aligned (n)))
@ -220,6 +223,8 @@ extern int strcasecmp(const char *str1, const char *str2);
extern int strncasecmp(const char *str1, const char *str2, size_t len);
#endif
extern wchar *AllocUnicode(const char*src);
#define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
#define clamp2(v, center, radius) ((v) < (center) ? Max(v, center - radius) : Min(v, center + radius))
@ -249,8 +254,14 @@ void re3_usererror(const char *format, ...);
#define DEBUGBREAK() __debugbreak();
#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__)
// Switch to enable development messages.
#if 1
#define DEV(f, ...)
#else
#define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__)
#endif
#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__)
#define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__)
#define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__)
#define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__)
@ -487,4 +498,4 @@ inline T *WriteSaveBuf(uint8 *&buf, uint32 &length, const T &value)
assert(ReadSaveBuf<uint32>(buf,len) == size);
void cprintf(char*, ...);
void cprintf(char*, ...);

View File

@ -7,7 +7,7 @@ enum Config {
MAX_CDIMAGES = 8, // additional cdimages
MAX_CDCHANNELS = 5,
MODELINFOSIZE = 6500,
MODELINFOSIZE = 6500, // 4900 on PS2
TXDSTORESIZE = 1385,
COLSTORESIZE = 31,
EXTRADIRSIZE = 256,
@ -36,7 +36,7 @@ enum Config {
NUMDUMMIES = 2340,
NUMAUDIOSCRIPTOBJECTS = 192,
NUMCOLMODELS = 4400,
NUMCUTSCENEOBJECTS = 50, // does not exist in VC
NUMCUTSCENEOBJECTS = 50, // not a pool in VC
NUMANIMBLOCKS = 35,
NUMANIMATIONS = 450,
@ -146,10 +146,6 @@ enum Config {
NUM_SHORTCUT_START_POINTS = 16
};
// We'll use this once we're ready to become independent of the game
// Use it to mark bugs in the code that will prevent the game from working then
//#define STANDALONE
// We don't expect to compile for PS2 or Xbox
// but it might be interesting for documentation purposes
#define GTA_PC
@ -176,6 +172,19 @@ enum Config {
#define FINAL
#endif
// Version defines
#define GTAVC_PS2 400
#define GTAVC_PC_10 410
#define GTAVC_PC_11 411
#define GTAVC_PC_JAP 412
// TODO? maybe something for xbox or android?
#define GTA_VERSION GTAVC_PC_11
// TODO(MIAMI): someone ought to find and check out uses of these defines:
//#define GTA3_STEAM_PATCH
//#define GTAVC_JP_PATCH
// quality of life fixes that should also be in FINAL
#define NASTY_GAME // nasty game for all languages
#define NO_CDCHECK
@ -183,23 +192,30 @@ enum Config {
// those infamous texts
#define DRAW_GAME_VERSION_TEXT
// Memory allocation and compression
// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet
//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
//# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
#elif defined GTA_PC
//# define GTA3_STEAM_PATCH
//# define GTAVC_JP_PATCH
# ifdef GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
# endif
# define PC_PLAYER_CONTROLS // mouse player/cam mode
# define GTA_REPLAY
# define GTA_SCENE_EDIT
#elif defined GTA_XBOX
#endif
#ifdef VU_COLLISION
#define COMPRESSED_COL_VECTORS // current need compressed vectors in this code
#define COMPRESSED_COL_VECTORS // currently need compressed vectors in this code
#endif
#ifdef MASTER
@ -225,6 +241,7 @@ enum Config {
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
//#define MORE_LANGUAGES // Add more translations to the game
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
#define FIX_HIGH_FPS_BUGS_ON_FRONTEND
// Just debug menu entries
@ -240,24 +257,20 @@ enum Config {
#define PS2_ALPHA_TEST // emulate ps2 alpha test
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync
//#define USE_TEXTURE_POOL
//#define CUTSCENE_BORDERS_SWITCH
#ifdef LIBRW
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
//#define NEW_RENDERER // leeds-like world rendering, needs librw
#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
#define SCREEN_DROPLETS // neo water droplets
#define NEW_RENDERER // leeds-like world rendering, needs librw
#endif
//#define MULTISAMPLING // adds MSAA option TODO
#ifdef LIBRW
// these are not supported with librw yet
# undef MULTISAMPLING
#ifndef EXTENDED_COLOURFILTER
#undef SCREEN_DROPLETS // we need the backbuffer for this effect
#endif
// Water & Particle
#define PC_PARTICLE
//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
// #define PC_WATER
#define WATER_CHEATS
@ -278,32 +291,48 @@ enum Config {
#define WALLCLIMB_CHEAT
#define REGISTER_START_BUTTON
//#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls
#define BUTTON_ICONS // use textures to show controller buttons
// Hud, frontend and radar
//#define BETA_SLIDING_TEXT
#define PC_MENU
#ifndef PC_MENU
# define PS2_MENU
//# define PS2_MENU_USEALLPAGEICONS
#else
# define MAP_ENHANCEMENTS // Adding waypoint etc.
# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support
# define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON
//#define CUSTOM_FRONTEND_OPTIONS
# define GRAPHICS_MENU_OPTIONS
#define LEGACY_MENU_OPTIONS
#define LEGACY_MENU_OPTIONS // i.e. frame sync(vsync)
#define MUCH_SHORTER_OUTRO_SCREEN
// #define XBOX_MESSAGE_SCREEN // Blue background, no "saved successfully press OK" screen etc.
# define CUSTOM_FRONTEND_OPTIONS
# ifdef CUSTOM_FRONTEND_OPTIONS
# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable
# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
# define CUTSCENE_BORDERS_SWITCH
//# define MULTISAMPLING // adds MSAA option
# define INVERT_LOOK_FOR_PAD // enable the hidden option
# endif
#endif
// Script
#define USE_DEBUG_SCRIPT_LOADER // Loads main.scm by default. Hold R for main_freeroam.scm and D for main_d.scm
#define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script
#define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely
#define SUPPORT_JAPANESE_SCRIPT
//#define SUPPORT_XBOX_SCRIPT
//#define SUPPORT_MOBILE_SCRIPT
#if (defined SUPPORT_XBOX_SCRIPT && defined SUPPORT_MOBILE_SCRIPT)
static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually exclusive");
#endif
#ifdef PC_MENU
//#define MISSION_REPLAY // mobile feature
#endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 1 // 0 == no log, 1 == overwrite every frame, 2 == full log
#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
#ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define USE_BASIC_SCRIPT_DEBUG_OUTPUT
@ -322,9 +351,6 @@ enum Config {
#define CAMERA_PICKUP
// Peds
#define PED_SKIN // support for skinned geometry on peds
#define ANIMATE_PED_COL_MODEL
#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
#define CANCELLABLE_CAR_ENTER
// Camera
@ -336,10 +362,15 @@ enum Config {
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS
#ifdef LIBRW
// these are not supported with librw yet
# undef MULTISAMPLING
#endif
// IMG
#define BIG_IMG // allows to read larger img files
//#define SQUEEZE_PERFORMANCE
#ifdef SQUEEZE_PERFORMANCE
#undef PS2_ALPHA_TEST
#undef NO_ISLAND_LOADING
#define PC_PARTICLE
#define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
#endif

File diff suppressed because it is too large Load Diff

View File

@ -20,11 +20,16 @@ extern bool gbShowTimebars;
#define gbShowTimebars false
#endif
#ifndef FINAL
extern bool gbPrintMemoryUsage;
#endif
class CSprite2d;
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
void PreAllocateRwObjects(void);
void InitialiseGame(void);
void LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
void LoadingIslandScreen(const char *levelName);
@ -39,6 +44,11 @@ void ResetLoadingScreenBar(void);
void TheModelViewer(void);
#endif
#ifdef LOAD_INI_SETTINGS
void LoadINISettings();
void SaveINISettings();
#endif
#ifdef NEW_RENDERER
extern bool gbNewRenderer;
bool FredIsInFirstPersonCam(void);

View File

@ -13,13 +13,10 @@
#include "Vehicle.h"
#include "ModelIndices.h"
#include "Streaming.h"
#include "PathFind.h"
#include "Boat.h"
#include "Heli.h"
#include "Automobile.h"
#include "Bike.h"
#include "Ped.h"
#include "Particle.h"
#include "Console.h"
#include "Debug.h"
#include "Hud.h"
@ -29,13 +26,18 @@
#include "Radar.h"
#include "debugmenu.h"
#include "Frontend.h"
#include "Text.h"
#include "WaterLevel.h"
#include "main.h"
#include "Script.h"
#include "MBlur.h"
#include "postfx.h"
#include "custompipes.h"
#include "MemoryHeap.h"
#include "FileMgr.h"
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
#include "ControllerConfig.h"
#endif
#ifndef _WIN32
#include "assert.h"
@ -75,6 +77,195 @@ mysrand(unsigned int seed)
myrand_seed = seed;
}
#ifdef CUSTOM_FRONTEND_OPTIONS
#include "frontendoption.h"
void
CustomFrontendOptionsPopulate(void)
{
// Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h
// These work only if we have neo folder, so they're dynamically added
#ifdef EXTENDED_PIPELINES
const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" };
const char *off_on[] = { "FEM_OFF", "FEM_ON" };
int fd = CFileMgr::OpenFile("neo/neo.txd","r");
if (fd) {
#ifdef GRAPHICS_MENU_OPTIONS
FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
#else
FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false);
FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
#endif
CFileMgr::CloseFile(fd);
}
#endif
}
#endif
#ifdef LOAD_INI_SETTINGS
#include "ini_parser.hpp"
linb::ini cfg;
int CheckAndReadIniInt(const char *cat, const char *key, int original)
{
std::string strval = cfg.get(cat, key, "");
const char *value = strval.c_str();
if (value && value[0] != '\0')
return atoi(value);
return original;
}
float CheckAndReadIniFloat(const char *cat, const char *key, float original)
{
std::string strval = cfg.get(cat, key, "");
const char *value = strval.c_str();
if (value && value[0] != '\0')
return atof(value);
return original;
}
void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed)
{
char temp[10];
if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
changed = true;
sprintf(temp, "%u", val);
cfg.set(cat, key, temp);
}
}
void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed)
{
char temp[10];
if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
changed = true;
sprintf(temp, "%f", val);
cfg.set(cat, key, temp);
}
}
void LoadINISettings()
{
cfg.load_file("reVC.ini");
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
// Written by assuming the codes below will run after _InputInitialiseJoys().
strcpy(gSelectedJoystickName, cfg.get("DetectJoystick", "JoystickName", "").c_str());
if(gSelectedJoystickName[0] != '\0') {
for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
if (glfwJoystickPresent(i) && strncmp(gSelectedJoystickName, glfwGetJoystickName(i), strlen(gSelectedJoystickName)) == 0) {
if (PSGLOBAL(joy1id) != -1) {
PSGLOBAL(joy2id) = PSGLOBAL(joy1id);
}
PSGLOBAL(joy1id) = i;
int count;
glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
// We need to init and reload bindings, because;
// 1-joypad button number may differ with saved/prvly connected one
// 2-bindings are not init'ed if there is no joypad at the start
ControlsManager.InitDefaultControlConfigJoyPad(count);
CFileMgr::SetDirMyDocuments();
int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
if (gta3set) {
ControlsManager.LoadSettings(gta3set);
CFileMgr::CloseFile(gta3set);
}
CFileMgr::SetDir("");
break;
}
}
}
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
for (int i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) {
CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
if (option.m_Action == MENUACTION_NOTHING)
break;
// CFO check
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// CFO only supports saving uint8 right now
*option.m_CFO->value = CheckAndReadIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value);
if (option.m_Action == MENUACTION_CFO_SELECT) {
option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value;
}
}
}
}
#endif
#ifdef EXTENDED_COLOURFILTER
CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
#endif
#ifdef EXTENDED_PIPELINES
CustomPipes::VehicleShininess = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess);
CustomPipes::VehicleSpecularity = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity);
CustomPipes::RimlightMult = CheckAndReadIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult);
CustomPipes::LightmapMult = CheckAndReadIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult);
CustomPipes::GlossMult = CheckAndReadIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
#endif
gBackfaceCulling = CheckAndReadIniInt("Rendering", "BackfaceCulling", gBackfaceCulling);
}
void SaveINISettings()
{
bool changed = false;
char temp[4];
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) {
changed = true;
cfg.set("DetectJoystick", "JoystickName", gSelectedJoystickName);
}
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
for (int i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) {
CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
if (option.m_Action == MENUACTION_NOTHING)
break;
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
// Beware: CFO only supports saving uint8 right now
CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed);
}
}
}
#endif
#ifdef EXTENDED_COLOURFILTER
CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed);
#endif
#ifdef EXTENDED_PIPELINES
CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed);
CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed);
CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed);
CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed);
CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed);
#endif
CheckAndSaveIniInt("Rendering", "BackfaceCulling", gBackfaceCulling, changed);
if (changed)
cfg.write_file("reVC.ini");
}
#endif
#ifdef DEBUGMENU
void WeaponCheat1();
void WeaponCheat2();
@ -256,7 +447,7 @@ void CTweakVars::Add(CTweakVar *var)
TweakVarsListSize = 0;
}
if(TweakVarsListSize > 63)
TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(var));
TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(*var));
TweakVarsList[TweakVarsListSize++] = var;
// TweakVarsList.push_back(var);
@ -484,8 +675,17 @@ extern bool gbRenderWorld2;
DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil);
DebugMenuAddVarBool8("Render", "Don't Render Water", &gbDontRenderWater, nil);
#ifndef FINAL
DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil);
#ifdef USE_CUSTOM_ALLOCATOR
DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap);
#endif
#endif
DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil);
#ifdef GTA_SCENE_EDIT
DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil);
#endif
#ifdef MAP_ENHANCEMENTS
DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
#endif

View File

@ -1,31 +1,31 @@
#pragma once
template<typename T, int n>
template<typename T, int32 n>
class CStore
{
public:
int allocPtr;
int32 allocPtr;
T store[n];
T *alloc(void){
if(this->allocPtr >= n){
T *Alloc(void){
if(allocPtr >= n){
printf("Size of this thing:%d needs increasing\n", n);
assert(0);
}
return &this->store[this->allocPtr++];
return &store[allocPtr++];
}
void clear(void){
this->allocPtr = 0;
void Clear(void){
allocPtr = 0;
}
int getIndex(T *item){
assert(item >= &this->store[0]);
assert(item < &this->store[n]);
return item - this->store;
int32 GetIndex(T *item){
assert(item >= &store[0]);
assert(item < &store[n]);
return item - store;
}
T *getItem(int index){
T *GetItem(int32 index){
assert(index >= 0);
assert(index < n);
return &this->store[index];
return &store[index];
}
};
@ -40,15 +40,13 @@ class CPool
};
uint8 u;
} *m_flags;
int m_size;
int m_allocPtr;
int32 m_size;
int32 m_allocPtr;
public:
// TODO(MIAMI): remove ctor without name argument
CPool(int size, const char *name){
// TODO: use new here
m_entries = (U*)malloc(sizeof(U)*size);
m_flags = (Flags*)malloc(sizeof(Flags)*size);
CPool(int32 size, const char *name){
m_entries = (U*)new uint8[sizeof(U)*size];
m_flags = (Flags*)new uint8[sizeof(Flags)*size];
m_size = size;
m_allocPtr = -1;
for(int i = 0; i < size; i++){
@ -61,15 +59,15 @@ public:
}
void Flush() {
if (m_size > 0) {
free(m_entries);
free(m_flags);
delete[] (uint8*)m_entries;
delete[] (uint8*)m_flags;
m_entries = nil;
m_flags = nil;
m_size = 0;
m_allocPtr = 0;
}
}
int GetSize(void) const { return m_size; }
int32 GetSize(void) const { return m_size; }
T *New(void){
bool wrapped = false;
do
@ -93,12 +91,12 @@ public:
m_flags[m_allocPtr].id++;
return (T*)&m_entries[m_allocPtr];
}
T *New(int handle){
T *New(int32 handle){
T *entry = (T*)&m_entries[handle>>8];
SetNotFreeAt(handle);
return entry;
}
void SetNotFreeAt(int handle){
void SetNotFreeAt(int32 handle){
int idx = handle>>8;
m_flags[idx].free = 0;
m_flags[idx].id = handle & 0x7F;
@ -123,15 +121,22 @@ public:
return m_flags[handle>>8].u == (handle & 0xFF) ?
(T*)&m_entries[handle >> 8] : nil;
}
int GetIndex(T *entry){
int i = GetJustIndex(entry);
return m_flags[i].u + (i<<8);
int32 GetIndex(T* entry) {
int i = GetJustIndex_NoFreeAssert(entry);
return m_flags[i].u + (i << 8);
}
int GetJustIndex(T *entry){
// TODO: the cast is unsafe
return (int)((U*)entry - m_entries);
int32 GetJustIndex(T* entry) {
int index = GetJustIndex_NoFreeAssert(entry);
assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required
assert(!IsFreeSlot(index));
return index;
}
int GetNoOfUsedSpaces(void) const {
int32 GetJustIndex_NoFreeAssert(T* entry) {
int index = ((U*)entry - m_entries);
// Please don't add unsafe assert here, because at least one func. use this to check if entity is ped or vehicle.
return index;
}
int32 GetNoOfUsedSpaces(void) const {
int i;
int n = 0;
for(i = 0; i < m_size; i++)
@ -141,8 +146,8 @@ public:
}
bool IsFreeSlot(int i) { return !!m_flags[i].free; }
void ClearStorage(uint8 *&flags, U *&entries){
free(flags);
free(entries);
delete[] (uint8*)flags;
delete[] (uint8*)entries;
flags = nil;
entries = nil;
}
@ -156,8 +161,8 @@ public:
debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
}
void Store(uint8 *&flags, U *&entries){
flags = (uint8*)malloc(sizeof(uint8)*m_size);
entries = (U*)malloc(sizeof(U)*m_size);
flags = (uint8*)new uint8[sizeof(uint8)*m_size];
entries = (U*)new uint8[sizeof(U)*m_size];
memcpy(flags, m_flags, sizeof(uint8)*m_size);
memcpy(entries, m_entries, sizeof(U)*m_size);
debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
@ -236,7 +241,7 @@ public:
link->Remove(); // remove from list
freeHead.Insert(link); // insert into free list
}
int Count(void){
int32 Count(void){
int n = 0;
CLink<T> *lnk;
for(lnk = head.next; lnk != &tail; lnk = lnk->next)