mirror of
https://gitlab.com/shinovon/re3-symbian.git
synced 2026-05-23 01:57:21 +03:00
Initial commit
This commit is contained in:
commit
77cdaaf97e
827 changed files with 418745 additions and 0 deletions
128
src/core/Accident.cpp
Normal file
128
src/core/Accident.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Accident.h"
|
||||
|
||||
#include "Ped.h"
|
||||
#include "Pools.h"
|
||||
#include "World.h"
|
||||
|
||||
CAccidentManager gAccidentManager;
|
||||
|
||||
CAccident*
|
||||
CAccidentManager::GetNextFreeAccident()
|
||||
{
|
||||
for (int i = 0; i < NUM_ACCIDENTS; i++) {
|
||||
if (m_aAccidents[i].m_pVictim == nil)
|
||||
return &m_aAccidents[i];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
CAccidentManager::ReportAccident(CPed *ped)
|
||||
{
|
||||
if (!ped->IsPlayer() && ped->CharCreatedBy != MISSION_CHAR && !ped->bRenderScorched && !ped->bBodyPartJustCameOff && ped->bAllowMedicsToReviveMe && !ped->bIsInWater) {
|
||||
for (int i = 0; i < NUM_ACCIDENTS; i++) {
|
||||
if (m_aAccidents[i].m_pVictim != nil && m_aAccidents[i].m_pVictim == ped)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ped->m_pCurrentPhysSurface == nil) {
|
||||
CVector point = ped->GetPosition();
|
||||
point.z -= 2.0f;
|
||||
|
||||
CColPoint colPoint;
|
||||
CEntity *pEntity;
|
||||
|
||||
if (!CWorld::ProcessVerticalLine(point, -100.0f, colPoint, pEntity, true, false, false, false, false, false, nil)) {
|
||||
CAccident *accident = GetNextFreeAccident();
|
||||
if (accident != nil) {
|
||||
accident->m_pVictim = ped;
|
||||
ped->RegisterReference((CEntity**)&accident->m_pVictim);
|
||||
accident->m_nMedicsPerformingCPR = 0;
|
||||
accident->m_nMedicsAttending = 0;
|
||||
ped->m_lastAccident = accident;
|
||||
WorkToDoForMedics();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CAccidentManager::Update()
|
||||
{
|
||||
#ifdef SQUEEZE_PERFORMANCE
|
||||
// Handled after injury registered.
|
||||
return;
|
||||
#endif
|
||||
int32 e;
|
||||
if (CEventList::GetEvent(EVENT_INJURED_PED, &e)) {
|
||||
CPed *ped = CPools::GetPed(gaEvent[e].entityRef);
|
||||
if (ped) {
|
||||
ReportAccident(ped);
|
||||
CEventList::ClearEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAccident*
|
||||
CAccidentManager::FindNearestAccident(CVector vecPos, float *pDistance)
|
||||
{
|
||||
for (int i = 0; i < MAX_MEDICS_TO_ATTEND_ACCIDENT; i++){
|
||||
int accidentId = -1;
|
||||
float minDistance = 999999;
|
||||
for (int j = 0; j < NUM_ACCIDENTS; j++){
|
||||
CPed* pVictim = m_aAccidents[j].m_pVictim;
|
||||
if (!pVictim)
|
||||
continue;
|
||||
if (pVictim->CharCreatedBy == MISSION_CHAR)
|
||||
continue;
|
||||
if (pVictim->m_fHealth != 0.0f)
|
||||
continue;
|
||||
if (m_aAccidents[j].m_nMedicsPerformingCPR != i)
|
||||
continue;
|
||||
float distance = (pVictim->GetPosition() - vecPos).Magnitude2D();
|
||||
if (distance / 2 > pVictim->GetPosition().z - vecPos.z && distance < minDistance){
|
||||
minDistance = distance;
|
||||
accidentId = j;
|
||||
}
|
||||
}
|
||||
*pDistance = minDistance;
|
||||
if (accidentId != -1)
|
||||
return &m_aAccidents[accidentId];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
uint16
|
||||
CAccidentManager::CountActiveAccidents()
|
||||
{
|
||||
uint16 accidents = 0;
|
||||
for (int i = 0; i < NUM_ACCIDENTS; i++) {
|
||||
if (m_aAccidents[i].m_pVictim)
|
||||
accidents++;
|
||||
}
|
||||
return accidents;
|
||||
}
|
||||
|
||||
bool
|
||||
CAccidentManager::WorkToDoForMedics()
|
||||
{
|
||||
for (int i = 0; i < NUM_ACCIDENTS; i++) {
|
||||
if (m_aAccidents[i].m_pVictim != nil && m_aAccidents[i].m_nMedicsAttending < MAX_MEDICS_TO_ATTEND_ACCIDENT)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CAccidentManager::UnattendedAccidents()
|
||||
{
|
||||
for (int i = 0; i < NUM_ACCIDENTS; i++) {
|
||||
if (m_aAccidents[i].m_pVictim != nil && m_aAccidents[i].m_nMedicsAttending == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
31
src/core/Accident.h
Normal file
31
src/core/Accident.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include "config.h"
|
||||
|
||||
class CPed;
|
||||
|
||||
class CAccident
|
||||
{
|
||||
public:
|
||||
CPed *m_pVictim;
|
||||
uint32 m_nMedicsAttending;
|
||||
uint32 m_nMedicsPerformingCPR;
|
||||
CAccident() : m_pVictim(nil), m_nMedicsAttending(0), m_nMedicsPerformingCPR(0) {}
|
||||
};
|
||||
|
||||
class CAccidentManager
|
||||
{
|
||||
CAccident m_aAccidents[NUM_ACCIDENTS];
|
||||
enum {
|
||||
MAX_MEDICS_TO_ATTEND_ACCIDENT = 2
|
||||
};
|
||||
public:
|
||||
CAccident *GetNextFreeAccident();
|
||||
void ReportAccident(CPed *ped);
|
||||
void Update();
|
||||
CAccident *FindNearestAccident(CVector vecPos, float *pDistance);
|
||||
uint16 CountActiveAccidents();
|
||||
bool UnattendedAccidents();
|
||||
bool WorkToDoForMedics();
|
||||
};
|
||||
|
||||
extern CAccidentManager gAccidentManager;
|
||||
422
src/core/AnimViewer.cpp
Normal file
422
src/core/AnimViewer.cpp
Normal file
|
|
@ -0,0 +1,422 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Font.h"
|
||||
#include "Pad.h"
|
||||
#include "Text.h"
|
||||
#include "main.h"
|
||||
#include "Timer.h"
|
||||
#include "DMAudio.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Streaming.h"
|
||||
#include "TxdStore.h"
|
||||
#include "General.h"
|
||||
#include "Camera.h"
|
||||
#include "Vehicle.h"
|
||||
#include "PlayerSkin.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "World.h"
|
||||
#include "Renderer.h"
|
||||
#include "AnimManager.h"
|
||||
#include "AnimViewer.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Pools.h"
|
||||
#include "References.h"
|
||||
#include "PathFind.h"
|
||||
#include "HandlingMgr.h"
|
||||
#include "TempColModels.h"
|
||||
#include "Particle.h"
|
||||
#include "CdStream.h"
|
||||
#include "Messages.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "FileLoader.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "Clock.h"
|
||||
#include "Timecycle.h"
|
||||
#include "RpAnimBlend.h"
|
||||
#include "AnimBlendAssociation.h"
|
||||
#include "Shadows.h"
|
||||
#include "Radar.h"
|
||||
#include "Hud.h"
|
||||
#include "debugmenu.h"
|
||||
|
||||
int CAnimViewer::animTxdSlot = 0;
|
||||
CEntity *CAnimViewer::pTarget = nil;
|
||||
|
||||
void
|
||||
CAnimViewer::Render(void) {
|
||||
if (pTarget) {
|
||||
// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f); // Only on Mobile
|
||||
if (pTarget) {
|
||||
#ifdef FIX_BUGS
|
||||
#ifdef PED_SKIN
|
||||
if(pTarget->IsPed() && IsClumpSkinned(pTarget->GetClump()))
|
||||
((CPed*)pTarget)->UpdateRpHAnim();
|
||||
#endif
|
||||
#endif
|
||||
pTarget->Render();
|
||||
CRenderer::RenderOneNonRoad(pTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CAnimViewer::Initialise(void) {
|
||||
// we need messages, messages needs hud, hud needs this
|
||||
CHud::m_Wants_To_Draw_Hud = false;
|
||||
|
||||
animTxdSlot = CTxdStore::AddTxdSlot("generic");
|
||||
CTxdStore::Create(animTxdSlot);
|
||||
int hudSlot = CTxdStore::AddTxdSlot("hud");
|
||||
CTxdStore::LoadTxd(hudSlot, "MODELS/HUD.TXD");
|
||||
int particleSlot = CTxdStore::AddTxdSlot("particle");
|
||||
CTxdStore::LoadTxd(particleSlot, "MODELS/PARTICLE.TXD");
|
||||
CTxdStore::SetCurrentTxd(animTxdSlot);
|
||||
CPools::Initialise();
|
||||
CReferences::Init();
|
||||
TheCamera.Init();
|
||||
TheCamera.SetRwCamera(Scene.camera);
|
||||
TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f;
|
||||
|
||||
ThePaths.Init();
|
||||
ThePaths.AllocatePathFindInfoMem(4500);
|
||||
CCollision::Init();
|
||||
CWorld::Initialise();
|
||||
mod_HandlingManager.Initialise();
|
||||
CTempColModels::Initialise();
|
||||
CAnimManager::Initialise();
|
||||
CModelInfo::Initialise();
|
||||
CParticle::Initialise();
|
||||
CCarCtrl::Init();
|
||||
CPedStats::Initialise();
|
||||
CMessages::Init();
|
||||
CdStreamAddImage("MODELS\\GTA3.IMG");
|
||||
CFileLoader::LoadLevel("DATA\\ANIMVIEWER.DAT");
|
||||
CStreaming::Init();
|
||||
CStreaming::LoadInitialPeds();
|
||||
CStreaming::RequestSpecialModel(MI_PLAYER, "player", STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
CRenderer::Init();
|
||||
CRadar::Initialise();
|
||||
CRadar::LoadTextures();
|
||||
CVehicleModelInfo::LoadVehicleColours();
|
||||
#ifdef FIX_BUGS
|
||||
CVehicleModelInfo::LoadEnvironmentMaps();
|
||||
#endif
|
||||
CAnimManager::LoadAnimFiles();
|
||||
CWorld::PlayerInFocus = 0;
|
||||
CWeapon::InitialiseWeapons();
|
||||
CShadows::Init();
|
||||
CPed::Initialise();
|
||||
CTimer::Initialise();
|
||||
CClock::Initialise(60000);
|
||||
CTimeCycle::Initialise();
|
||||
CCarCtrl::Init();
|
||||
CPlayerPed *player = new CPlayerPed();
|
||||
player->SetPosition(0.0f, 0.0f, 0.0f); // This is 1000.f for all axes on Xbox, but 0.f on mobile?
|
||||
CWorld::Players[0].m_pPed = player;
|
||||
CDraw::SetFOV(120.0f);
|
||||
CDraw::ms_fLODDistance = 500.0f;
|
||||
|
||||
int fd = CFileMgr::OpenFile("DATA\\SPECIAL.TXT", "r");
|
||||
char animGroup[32], modelName[32];
|
||||
if (fd) {
|
||||
for (int lineId = 0; lineId < NUM_OF_SPECIAL_CHARS; lineId++) {
|
||||
if (!CFileMgr::ReadLine(fd, gString, 255))
|
||||
break;
|
||||
|
||||
sscanf(gString, "%s %s", modelName, animGroup);
|
||||
int groupId;
|
||||
for (groupId = 0; groupId < NUM_ANIM_ASSOC_GROUPS; groupId++) {
|
||||
if (!strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)groupId)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (groupId != NUM_ANIM_ASSOC_GROUPS)
|
||||
((CPedModelInfo*)CModelInfo::GetModelInfo(MI_SPECIAL01 + lineId))->m_animGroup = groupId;
|
||||
|
||||
CStreaming::RequestSpecialChar(lineId, modelName, STREAMFLAGS_DONT_REMOVE);
|
||||
}
|
||||
CFileMgr::CloseFile(fd);
|
||||
} else {
|
||||
// From xbox
|
||||
CStreaming::RequestSpecialChar(0, "luigi", STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::RequestSpecialChar(1, "joey", STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::RequestSpecialChar(2, "tony", STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::RequestSpecialChar(3, "curly", STREAMFLAGS_DONT_REMOVE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
LastPedModelId(int modelId)
|
||||
{
|
||||
CBaseModelInfo *model;
|
||||
for(;;){
|
||||
assert(modelId < MODELINFOSIZE);
|
||||
model = CModelInfo::GetModelInfo(modelId);
|
||||
if (model && model->GetModelType() == MITYPE_PED)
|
||||
break;
|
||||
modelId--;
|
||||
}
|
||||
return modelId;
|
||||
}
|
||||
|
||||
int
|
||||
FirstCarModelId(int modelId)
|
||||
{
|
||||
CBaseModelInfo *model;
|
||||
for(;;){
|
||||
assert(modelId < MODELINFOSIZE);
|
||||
model = CModelInfo::GetModelInfo(modelId);
|
||||
if (model && model->GetModelType() == MITYPE_VEHICLE)
|
||||
break;
|
||||
modelId++;
|
||||
}
|
||||
return modelId;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NextModelId(int modelId, int wantedChange)
|
||||
{
|
||||
// Max. 2 trials wasn't here, it's me that added it.
|
||||
|
||||
int tryCount = 2;
|
||||
int ogModelId = modelId;
|
||||
|
||||
while(tryCount != 0) {
|
||||
modelId += wantedChange;
|
||||
if (modelId < 0 || modelId >= MODELINFOSIZE) {
|
||||
tryCount--;
|
||||
wantedChange = -wantedChange;
|
||||
} else if (modelId != 5 && modelId != 6 && modelId != 405) {
|
||||
CBaseModelInfo *model = CModelInfo::GetModelInfo(modelId);
|
||||
if (model)
|
||||
{
|
||||
//int type = model->m_type;
|
||||
return modelId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ogModelId;
|
||||
}
|
||||
|
||||
void
|
||||
PlayAnimation(RpClump *clump, AssocGroupId animGroup, AnimationId anim)
|
||||
{
|
||||
CAnimBlendAssociation *currentAssoc = RpAnimBlendClumpGetAssociation(clump, anim);
|
||||
|
||||
if (currentAssoc && currentAssoc->IsPartial())
|
||||
delete currentAssoc;
|
||||
|
||||
RpAnimBlendClumpSetBlendDeltas(clump, ASSOC_PARTIAL, -8.0f);
|
||||
|
||||
CAnimBlendAssociation *animAssoc = CAnimManager::BlendAnimation(clump, animGroup, anim, 8.0f);
|
||||
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||
animAssoc->SetCurrentTime(0.0f);
|
||||
animAssoc->SetRun();
|
||||
}
|
||||
|
||||
void
|
||||
CAnimViewer::Update(void)
|
||||
{
|
||||
static int modelId = 0;
|
||||
static int animId = 0;
|
||||
static bool reloadIFP = false;
|
||||
|
||||
AssocGroupId animGroup = ASSOCGRP_STD;
|
||||
int nextModelId = modelId;
|
||||
CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelId);
|
||||
|
||||
if (modelInfo->GetModelType() == MITYPE_PED) {
|
||||
int animGroup = ((CPedModelInfo*)modelInfo)->m_animGroup;
|
||||
|
||||
if (animId > ANIM_STD_IDLE)
|
||||
animGroup = ASSOCGRP_STD;
|
||||
|
||||
if (reloadIFP) {
|
||||
if (pTarget) {
|
||||
CWorld::Remove(pTarget);
|
||||
if (pTarget)
|
||||
delete pTarget;
|
||||
}
|
||||
pTarget = nil;
|
||||
|
||||
// These calls were inside of LoadIFP function.
|
||||
CAnimManager::Shutdown();
|
||||
CAnimManager::Initialise();
|
||||
CAnimManager::LoadAnimFiles();
|
||||
|
||||
reloadIFP = false;
|
||||
}
|
||||
} else {
|
||||
animGroup = ASSOCGRP_STD;
|
||||
}
|
||||
CPad::UpdatePads();
|
||||
CPad* pad = CPad::GetPad(0);
|
||||
#ifdef DEBUGMENU
|
||||
DebugMenuProcess();
|
||||
#endif
|
||||
|
||||
CStreaming::UpdateForAnimViewer();
|
||||
CStreaming::RequestModel(modelId, 0);
|
||||
if (CStreaming::HasModelLoaded(modelId)) {
|
||||
|
||||
if (!pTarget) {
|
||||
|
||||
if (modelInfo->GetModelType() == MITYPE_VEHICLE) {
|
||||
|
||||
CVehicleModelInfo* veh = (CVehicleModelInfo*)modelInfo;
|
||||
if (veh->m_vehicleType == VEHICLE_TYPE_CAR) {
|
||||
pTarget = new CAutomobile(modelId, RANDOM_VEHICLE);
|
||||
} else if (veh->m_vehicleType == VEHICLE_TYPE_BOAT) {
|
||||
pTarget = new CBoat(modelId, RANDOM_VEHICLE);
|
||||
} else {
|
||||
pTarget = new CObject(modelId, true);
|
||||
if (!modelInfo->GetColModel()) {
|
||||
modelInfo->SetColModel(&CTempColModels::ms_colModelWheel1);
|
||||
}
|
||||
}
|
||||
pTarget->SetStatus(STATUS_ABANDONED);
|
||||
} else if (modelInfo->GetModelType() == MITYPE_PED) {
|
||||
pTarget = new CPed(PEDTYPE_CIVMALE);
|
||||
pTarget->SetModelIndex(modelId);
|
||||
} else {
|
||||
pTarget = new CObject(modelId, true);
|
||||
if (!modelInfo->GetColModel())
|
||||
{
|
||||
modelInfo->SetColModel(&CTempColModels::ms_colModelWheel1);
|
||||
}
|
||||
pTarget->SetStatus(STATUS_ABANDONED);
|
||||
}
|
||||
pTarget->SetPosition(0.0f, 0.0f, 0.0f);
|
||||
CWorld::Add(pTarget);
|
||||
TheCamera.TakeControl(pTarget, CCam::MODE_MODELVIEW, JUMP_CUT, CAMCONTROL_SCRIPT);
|
||||
}
|
||||
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 = true;
|
||||
AsciiToUnicode("IFP reloaded", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->GetCrossJustDown()) {
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
|
||||
AsciiToUnicode("Animation restarted", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->GetCircleJustDown()) {
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, ANIM_STD_IDLE);
|
||||
AsciiToUnicode("Idle animation playing", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->GetDPadUpJustDown()) {
|
||||
animId--;
|
||||
if (animId < 0) {
|
||||
animId = ANIM_STD_NUM - 1;
|
||||
}
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
|
||||
|
||||
sprintf(gString, "Current anim: %d", animId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->GetDPadDownJustDown()) {
|
||||
animId = (animId == (ANIM_STD_NUM - 1) ? 0 : animId + 1);
|
||||
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
|
||||
|
||||
sprintf(gString, "Current anim: %d", animId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->GetStartJustDown()) {
|
||||
|
||||
} else if (pad->GetLeftShoulder1JustDown()) {
|
||||
nextModelId = FirstCarModelId(modelId);
|
||||
AsciiToUnicode("Switched to vehicles", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
// Originally it was GetPad(1)->LeftShoulder2
|
||||
} else if (pad->NewState.Triangle) {
|
||||
#ifdef PED_SKIN
|
||||
if(IsClumpSkinned(pTarget->GetClump()))
|
||||
((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->AnimatePedColModelSkinned(pTarget->GetClump());
|
||||
else
|
||||
#endif
|
||||
CPedModelInfo::AnimatePedColModel(((CPedModelInfo *)CModelInfo::GetModelInfo(pTarget->GetModelIndex()))->GetHitColModel(),
|
||||
RpClumpGetFrame(pTarget->GetClump()));
|
||||
AsciiToUnicode("Ped Col model will be animated as long as you hold the button", gUString);
|
||||
CMessages::AddMessage(gUString, 100, 0);
|
||||
}
|
||||
} else if (modelInfo->GetModelType() == MITYPE_VEHICLE) {
|
||||
|
||||
if (pad->GetLeftShoulder1JustDown()) {
|
||||
nextModelId = LastPedModelId(modelId);
|
||||
AsciiToUnicode("Switched to peds", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
// Start in mobile
|
||||
} else if (pad->GetSquareJustDown()) {
|
||||
CVehicleModelInfo::LoadVehicleColours();
|
||||
AsciiToUnicode("Carcols.dat reloaded", gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pad->GetDPadLeftJustDown()) {
|
||||
nextModelId = NextModelId(modelId, -1);
|
||||
|
||||
sprintf(gString, "Current model ID: %d", nextModelId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
|
||||
} else if (pad->GetDPadRightJustDown()) {
|
||||
nextModelId = NextModelId(modelId, 1);
|
||||
|
||||
sprintf(gString, "Current model ID: %d", nextModelId);
|
||||
AsciiToUnicode(gString, gUString);
|
||||
CMessages::AddMessage(gUString, 1000, 0);
|
||||
}
|
||||
// There were extra codes here to let us change model id by 50, but xbox CPad struct is different, so I couldn't port.
|
||||
|
||||
if (nextModelId != modelId) {
|
||||
modelId = nextModelId;
|
||||
if (pTarget) {
|
||||
CWorld::Remove(pTarget);
|
||||
if (pTarget)
|
||||
delete pTarget;
|
||||
}
|
||||
pTarget = nil;
|
||||
return;
|
||||
}
|
||||
|
||||
CTimeCycle::Update();
|
||||
CWorld::Process();
|
||||
if (pTarget)
|
||||
TheCamera.Process();
|
||||
}
|
||||
|
||||
void
|
||||
CAnimViewer::Shutdown(void)
|
||||
{
|
||||
if (CWorld::Players[0].m_pPed)
|
||||
delete CWorld::Players[0].m_pPed;
|
||||
|
||||
CWorld::ShutDown();
|
||||
CModelInfo::ShutDown();
|
||||
CAnimManager::Shutdown();
|
||||
CTimer::Shutdown();
|
||||
CStreaming::Shutdown();
|
||||
CTxdStore::RemoveTxdSlot(animTxdSlot);
|
||||
}
|
||||
12
src/core/AnimViewer.h
Normal file
12
src/core/AnimViewer.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
class CAnimViewer {
|
||||
public:
|
||||
static int animTxdSlot;
|
||||
static CEntity *pTarget;
|
||||
|
||||
static void Initialise();
|
||||
static void Render();
|
||||
static void Shutdown();
|
||||
static void Update();
|
||||
};
|
||||
5410
src/core/Cam.cpp
Normal file
5410
src/core/Cam.cpp
Normal file
File diff suppressed because it is too large
Load diff
3726
src/core/Camera.cpp
Normal file
3726
src/core/Camera.cpp
Normal file
File diff suppressed because it is too large
Load diff
653
src/core/Camera.h
Normal file
653
src/core/Camera.h
Normal file
|
|
@ -0,0 +1,653 @@
|
|||
#pragma once
|
||||
#include "Placeable.h"
|
||||
|
||||
class CEntity;
|
||||
class CPed;
|
||||
class CAutomobile;
|
||||
class CGarage;
|
||||
|
||||
extern int16 DebugCamMode;
|
||||
|
||||
enum
|
||||
{
|
||||
NUMBER_OF_VECTORS_FOR_AVERAGE = 2,
|
||||
MAX_NUM_OF_SPLINETYPES = 4,
|
||||
MAX_NUM_OF_NODES = 800 // for trains
|
||||
};
|
||||
|
||||
#define DEFAULT_NEAR (0.9f)
|
||||
enum
|
||||
{
|
||||
CAM_ZOOM_1STPRS,
|
||||
CAM_ZOOM_1,
|
||||
CAM_ZOOM_2,
|
||||
CAM_ZOOM_3,
|
||||
CAM_ZOOM_TOPDOWN,
|
||||
CAM_ZOOM_CINEMATIC,
|
||||
};
|
||||
|
||||
#ifdef FREE_CAM // LCS values
|
||||
#define FREE_CAR_ZOOM_VALUE_1 (-1.0f)
|
||||
#define FREE_CAR_ZOOM_VALUE_2 (2.0f)
|
||||
#define FREE_CAR_ZOOM_VALUE_3 (6.0f)
|
||||
|
||||
#define FREE_BOAT_ZOOM_VALUE_1 (-2.41f)
|
||||
#define FREE_BOAT_ZOOM_VALUE_2 (6.49f)
|
||||
#define FREE_BOAT_ZOOM_VALUE_3 (15.0f)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_CAR_ZOOM_VALUE_1 (0.05f)
|
||||
#define DEFAULT_CAR_ZOOM_VALUE_2 (1.9f)
|
||||
#define DEFAULT_CAR_ZOOM_VALUE_3 (3.9f)
|
||||
|
||||
const float DefaultFOV = 70.0f; // beta: 80.0f
|
||||
|
||||
class CCam
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MODE_NONE = 0,
|
||||
MODE_TOPDOWN,
|
||||
MODE_GTACLASSIC,
|
||||
MODE_BEHINDCAR,
|
||||
MODE_FOLLOWPED,
|
||||
MODE_AIMING,
|
||||
MODE_DEBUG,
|
||||
MODE_SNIPER,
|
||||
MODE_ROCKETLAUNCHER,
|
||||
MODE_MODELVIEW,
|
||||
MODE_BILL,
|
||||
MODE_SYPHON,
|
||||
MODE_CIRCLE,
|
||||
MODE_CHEESYZOOM,
|
||||
MODE_WHEELCAM,
|
||||
MODE_FIXED,
|
||||
MODE_1STPERSON,
|
||||
MODE_FLYBY,
|
||||
MODE_CAM_ON_A_STRING,
|
||||
MODE_REACTION,
|
||||
MODE_FOLLOW_PED_WITH_BIND,
|
||||
MODE_CHRIS,
|
||||
MODE_BEHINDBOAT,
|
||||
MODE_PLAYER_FALLEN_WATER,
|
||||
MODE_CAM_ON_TRAIN_ROOF,
|
||||
MODE_CAM_RUNNING_SIDE_TRAIN,
|
||||
MODE_BLOOD_ON_THE_TRACKS,
|
||||
MODE_IM_THE_PASSENGER_WOOWOO,
|
||||
MODE_SYPHON_CRIM_IN_FRONT,
|
||||
MODE_PED_DEAD_BABY,
|
||||
MODE_PILLOWS_PAPS,
|
||||
MODE_LOOK_AT_CARS,
|
||||
MODE_ARRESTCAM_ONE,
|
||||
MODE_ARRESTCAM_TWO,
|
||||
MODE_M16_1STPERSON,
|
||||
MODE_SPECIAL_FIXED_FOR_SYPHON,
|
||||
MODE_FIGHT_CAM,
|
||||
MODE_TOP_DOWN_PED,
|
||||
MODE_SNIPER_RUNABOUT,
|
||||
MODE_ROCKETLAUNCHER_RUNABOUT,
|
||||
MODE_1STPERSON_RUNABOUT,
|
||||
MODE_M16_1STPERSON_RUNABOUT,
|
||||
MODE_FIGHT_CAM_RUNABOUT,
|
||||
MODE_EDITOR,
|
||||
MODE_HELICANNON_1STPERSON, // vice city leftover
|
||||
};
|
||||
|
||||
bool bBelowMinDist; //used for follow ped mode
|
||||
bool bBehindPlayerDesired; //used for follow ped mode
|
||||
bool m_bCamLookingAtVector;
|
||||
bool m_bCollisionChecksOn;
|
||||
bool m_bFixingBeta; //used for camera on a string
|
||||
bool m_bTheHeightFixerVehicleIsATrain;
|
||||
bool LookBehindCamWasInFront;
|
||||
bool LookingBehind;
|
||||
bool LookingLeft;
|
||||
bool LookingRight;
|
||||
bool ResetStatics; //for interpolation type stuff to work
|
||||
bool Rotating;
|
||||
|
||||
int16 Mode; // CameraMode
|
||||
uint32 m_uiFinishTime;
|
||||
|
||||
int m_iDoCollisionChecksOnFrameNum;
|
||||
int m_iDoCollisionCheckEveryNumOfFrames;
|
||||
int m_iFrameNumWereAt;
|
||||
int m_iRunningVectorArrayPos;
|
||||
int m_iRunningVectorCounter;
|
||||
int DirectionWasLooking;
|
||||
|
||||
float f_max_role_angle; //=DEGTORAD(5.0f);
|
||||
float f_Roll; //used for adding a slight roll to the camera in the
|
||||
float f_rollSpeed;
|
||||
float m_fSyphonModeTargetZOffSet;
|
||||
float m_fRoadOffSet;
|
||||
float m_fAmountFractionObscured;
|
||||
float m_fAlphaSpeedOverOneFrame;
|
||||
float m_fBetaSpeedOverOneFrame;
|
||||
float m_fBufferedTargetBeta;
|
||||
float m_fBufferedTargetOrientation;
|
||||
float m_fBufferedTargetOrientationSpeed;
|
||||
float m_fCamBufferedHeight;
|
||||
float m_fCamBufferedHeightSpeed;
|
||||
float m_fCloseInPedHeightOffset;
|
||||
float m_fCloseInPedHeightOffsetSpeed;
|
||||
float m_fCloseInCarHeightOffset;
|
||||
float m_fCloseInCarHeightOffsetSpeed;
|
||||
float m_fDimensionOfHighestNearCar;
|
||||
float m_fDistanceBeforeChanges;
|
||||
float m_fFovSpeedOverOneFrame;
|
||||
float m_fMinDistAwayFromCamWhenInterPolating;
|
||||
float m_fPedBetweenCameraHeightOffset;
|
||||
float m_fPlayerInFrontSyphonAngleOffSet;
|
||||
float m_fRadiusForDead;
|
||||
float m_fRealGroundDist; //used for follow ped mode
|
||||
float m_fTargetBeta;
|
||||
float m_fTimeElapsedFloat;
|
||||
|
||||
float m_fTransitionBeta;
|
||||
float m_fTrueBeta;
|
||||
float m_fTrueAlpha;
|
||||
float m_fInitialPlayerOrientation; //used for first person
|
||||
|
||||
float Alpha;
|
||||
float AlphaSpeed;
|
||||
float FOV;
|
||||
float FOVSpeed;
|
||||
float Beta;
|
||||
float BetaSpeed;
|
||||
float Distance;
|
||||
float DistanceSpeed;
|
||||
float CA_MIN_DISTANCE;
|
||||
float CA_MAX_DISTANCE;
|
||||
float SpeedVar;
|
||||
|
||||
CVector m_cvecSourceSpeedOverOneFrame;
|
||||
CVector m_cvecTargetSpeedOverOneFrame;
|
||||
CVector m_cvecUpOverOneFrame;
|
||||
|
||||
CVector m_cvecTargetCoorsForFudgeInter;
|
||||
CVector m_cvecCamFixedModeVector;
|
||||
CVector m_cvecCamFixedModeSource;
|
||||
CVector m_cvecCamFixedModeUpOffSet;
|
||||
CVector m_vecLastAboveWaterCamPosition; //helper for when the player has gone under the water
|
||||
CVector m_vecBufferedPlayerBodyOffset;
|
||||
|
||||
// The three vectors that determine this camera for this frame
|
||||
CVector Front; // Direction of looking in
|
||||
CVector Source; // Coors in world space
|
||||
CVector SourceBeforeLookBehind;
|
||||
CVector Up; // Just that
|
||||
CVector m_arrPreviousVectors[NUMBER_OF_VECTORS_FOR_AVERAGE]; // used to average stuff
|
||||
CEntity *CamTargetEntity;
|
||||
|
||||
float m_fCameraDistance;
|
||||
float m_fIdealAlpha;
|
||||
float m_fPlayerVelocity;
|
||||
CAutomobile *m_pLastCarEntered; // So interpolation works
|
||||
CPed *m_pLastPedLookedAt;// So interpolation works
|
||||
bool m_bFirstPersonRunAboutActive;
|
||||
|
||||
CCam(void) { Init(); }
|
||||
void Init(void);
|
||||
void Process(void);
|
||||
void ProcessSpecialHeightRoutines(void);
|
||||
void GetVectorsReadyForRW(void);
|
||||
CVector DoAverageOnVector(const CVector &vec);
|
||||
float GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies);
|
||||
void WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation);
|
||||
void WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight);
|
||||
bool RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation);
|
||||
bool FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation);
|
||||
void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist);
|
||||
void FixCamWhenObscuredByVehicle(const CVector &TargetCoors);
|
||||
void LookBehind(void);
|
||||
void LookLeft(void);
|
||||
void LookRight(void);
|
||||
void ClipIfPedInFrontOfPlayer(void);
|
||||
void KeepTrackOfTheSpeed(const CVector &source, const CVector &target, const CVector &up, const float &alpha, const float &beta, const float &fov);
|
||||
bool Using3rdPersonMouseCam(void);
|
||||
bool GetWeaponFirstPersonOn(void);
|
||||
bool IsTargetInWater(const CVector &CamCoors);
|
||||
void AvoidWallsTopDownPed(const CVector &TargetCoors, const CVector &Offset, float *Adjuster, float *AdjusterSpeed, float yDistLimit);
|
||||
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);
|
||||
void Process_BehindCar(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_TopDown(const CVector &CameraTarget, float TargetOrientation, float SpeedVar, float TargetSpeedVar);
|
||||
void Process_TopDownPed(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Rocket(const CVector &CameraTarget, float, float, float);
|
||||
void Process_M16_1stPerson(const CVector &CameraTarget, float, float, float);
|
||||
void Process_1stPerson(const CVector &CameraTarget, float, float, float);
|
||||
void Process_1rstPersonPedOnPC(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Sniper(const CVector &CameraTarget, float, float, float);
|
||||
void Process_Syphon(const CVector &CameraTarget, float, float, float);
|
||||
void Process_Syphon_Crim_In_Front(const CVector &CameraTarget, float, float, float);
|
||||
void Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_FlyBy(const CVector&, float, float, float);
|
||||
void Process_WheelCam(const CVector&, float, float, float);
|
||||
void Process_Fixed(const CVector &CameraTarget, float, float, float);
|
||||
void Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Circle(const CVector &CameraTarget, float, float, float);
|
||||
void Process_SpecialFixedForSyphon(const CVector &CameraTarget, float, float, float);
|
||||
void ProcessPedsDeadBaby(void);
|
||||
bool ProcessArrestCamOne(void);
|
||||
bool ProcessArrestCamTwo(void);
|
||||
|
||||
/* Some of the unused PS2 cams */
|
||||
void Process_Chris_With_Binding_PlusRotation(const CVector &CameraTarget, float, float, float);
|
||||
void Process_ReactionCam(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_FollowPed_WithBinding(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
// TODO:
|
||||
// CCam::Process_CushyPillows_Arse
|
||||
// CCam::Process_Look_At_Cars
|
||||
// CCam::Process_CheesyZoom
|
||||
// CCam::Process_Aiming
|
||||
void Process_Bill(const CVector &CameraTarget, float TargetOrientation, float SpeedVar, float TargetSpeedVar);
|
||||
void Process_Im_The_Passenger_Woo_Woo(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Blood_On_The_Tracks(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Cam_Running_Side_Train(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_Cam_On_Train_Roof(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
|
||||
// custom stuff
|
||||
void Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
void Process_FollowCar_SA(const CVector &CameraTarget, float TargetOrientation, float, float);
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CCam, 0x1A4);
|
||||
|
||||
class CCamPathSplines
|
||||
{
|
||||
public:
|
||||
enum {MAXPATHLENGTH=800};
|
||||
float m_arr_PathData[MAXPATHLENGTH];
|
||||
CCamPathSplines(void);
|
||||
};
|
||||
|
||||
struct CTrainCamNode
|
||||
{
|
||||
CVector m_cvecCamPosition;
|
||||
CVector m_cvecPointToLookAt;
|
||||
CVector m_cvecMinPointInRange;
|
||||
CVector m_cvecMaxPointInRange;
|
||||
float m_fDesiredFOV;
|
||||
float m_fNearClip;
|
||||
};
|
||||
|
||||
struct CQueuedMode
|
||||
{
|
||||
int16 Mode;
|
||||
float Duration;
|
||||
int16 MinZoom;
|
||||
int16 MaxZoom;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOOKING_BEHIND,
|
||||
LOOKING_LEFT,
|
||||
LOOKING_RIGHT,
|
||||
LOOKING_FORWARD,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// TODO: find better names
|
||||
FADE_0, // faded in
|
||||
FADE_1, // mid fade
|
||||
FADE_2, // faded out
|
||||
|
||||
// Direction
|
||||
FADE_OUT = 0,
|
||||
FADE_IN,
|
||||
FADE_NONE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MOTION_BLUR_NONE = 0,
|
||||
MOTION_BLUR_SNIPER,
|
||||
MOTION_BLUR_LIGHT_SCENE,
|
||||
MOTION_BLUR_SECURITY_CAM,
|
||||
MOTION_BLUR_CUT_SCENE,
|
||||
MOTION_BLUR_INTRO,
|
||||
MOTION_BLUR_INTRO2,
|
||||
MOTION_BLUR_SNIPER_ZOOM,
|
||||
MOTION_BLUR_INTRO3,
|
||||
MOTION_BLUR_INTRO4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NONE = 0,
|
||||
INTERPOLATION,
|
||||
JUMP_CUT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CAMCONTROL_GAME,
|
||||
CAMCONTROL_SCRIPT,
|
||||
CAMCONTROL_OBBE
|
||||
};
|
||||
|
||||
class CCamera : public CPlaceable
|
||||
{
|
||||
public:
|
||||
bool m_bAboveGroundTrainNodesLoaded;
|
||||
bool m_bBelowGroundTrainNodesLoaded;
|
||||
bool m_bCamDirectlyBehind;
|
||||
bool m_bCamDirectlyInFront;
|
||||
bool m_bCameraJustRestored;
|
||||
bool m_bcutsceneFinished;
|
||||
bool m_bCullZoneChecksOn;
|
||||
bool m_bFirstPersonBeingUsed;
|
||||
bool m_bUnknown;
|
||||
bool m_bIdleOn;
|
||||
bool m_bInATunnelAndABigVehicle;
|
||||
bool m_bInitialNodeFound;
|
||||
bool m_bInitialNoNodeStaticsSet;
|
||||
bool m_bIgnoreFadingStuffForMusic;
|
||||
bool m_bPlayerIsInGarage;
|
||||
bool m_bJustCameOutOfGarage;
|
||||
bool m_bJustInitalised;
|
||||
bool m_bJust_Switched;
|
||||
bool m_bLookingAtPlayer;
|
||||
bool m_bLookingAtVector;
|
||||
bool m_bMoveCamToAvoidGeom;
|
||||
bool m_bObbeCinematicPedCamOn;
|
||||
bool m_bObbeCinematicCarCamOn;
|
||||
bool m_bRestoreByJumpCut;
|
||||
bool m_bUseNearClipScript;
|
||||
bool m_bStartInterScript;
|
||||
bool m_bStartingSpline;
|
||||
bool m_bTargetJustBeenOnTrain;
|
||||
bool m_bTargetJustCameOffTrain;
|
||||
bool m_bUseSpecialFovTrain;
|
||||
bool m_bUseTransitionBeta;
|
||||
bool m_bUseScriptZoomValuePed;
|
||||
bool m_bUseScriptZoomValueCar;
|
||||
bool m_bWaitForInterpolToFinish;
|
||||
bool m_bItsOkToLookJustAtThePlayer;
|
||||
bool m_bWantsToSwitchWidescreenOff;
|
||||
bool m_WideScreenOn;
|
||||
bool m_1rstPersonRunCloseToAWall;
|
||||
bool m_bHeadBob;
|
||||
bool m_bFailedCullZoneTestPreviously;
|
||||
|
||||
bool m_FadeTargetIsSplashScreen;
|
||||
|
||||
bool WorldViewerBeingUsed;
|
||||
uint8 ActiveCam;
|
||||
uint32 m_uiCamShakeStart;
|
||||
uint32 m_uiFirstPersonCamLastInputTime;
|
||||
|
||||
uint32 m_uiLongestTimeInMill;
|
||||
uint32 m_uiNumberOfTrainCamNodes;
|
||||
uint8 m_uiTransitionJUSTStarted;
|
||||
uint8 m_uiTransitionState; // 0:one mode 1:transition
|
||||
|
||||
uint32 m_uiTimeLastChange;
|
||||
uint32 m_uiTimeWeEnteredIdle;
|
||||
uint32 m_uiTimeTransitionStart;
|
||||
uint32 m_uiTransitionDuration;
|
||||
int m_BlurBlue;
|
||||
int m_BlurGreen;
|
||||
int m_BlurRed;
|
||||
int m_BlurType;
|
||||
|
||||
uint32 unknown; // some counter having to do with music
|
||||
int m_iWorkOutSpeedThisNumFrames;
|
||||
int m_iNumFramesSoFar;
|
||||
|
||||
|
||||
int m_iCurrentTrainCamNode;
|
||||
int m_motionBlur;
|
||||
int m_imotionBlurAddAlpha;
|
||||
int m_iCheckCullZoneThisNumFrames;
|
||||
int m_iZoneCullFrameNumWereAt;
|
||||
int WhoIsInControlOfTheCamera;
|
||||
|
||||
float CamFrontXNorm;
|
||||
float CamFrontYNorm;
|
||||
#ifdef FIX_BUGS
|
||||
int32 CarZoomIndicator;
|
||||
#else
|
||||
float CarZoomIndicator;
|
||||
#endif
|
||||
float CarZoomValue;
|
||||
float CarZoomValueSmooth;
|
||||
|
||||
float DistanceToWater;
|
||||
#ifndef PS2_CAM_TRANSITION
|
||||
float FOVDuringInter;
|
||||
#endif
|
||||
float LODDistMultiplier;
|
||||
float GenerationDistMultiplier;
|
||||
#ifndef PS2_CAM_TRANSITION
|
||||
float m_fAlphaSpeedAtStartInter;
|
||||
float m_fAlphaWhenInterPol;
|
||||
float m_fAlphaDuringInterPol;
|
||||
float m_fBetaDuringInterPol;
|
||||
float m_fBetaSpeedAtStartInter;
|
||||
float m_fBetaWhenInterPol;
|
||||
float m_fFOVWhenInterPol;
|
||||
float m_fFOVSpeedAtStartInter;
|
||||
float m_fStartingBetaForInterPol;
|
||||
float m_fStartingAlphaForInterPol;
|
||||
#endif
|
||||
float m_PedOrientForBehindOrInFront;
|
||||
float m_CameraAverageSpeed;
|
||||
float m_CameraSpeedSoFar;
|
||||
float m_fCamShakeForce;
|
||||
float m_fCarZoomValueScript;
|
||||
float m_fFovForTrain;
|
||||
float m_fFOV_Wide_Screen;
|
||||
float m_fNearClipScript;
|
||||
float m_fOldBetaDiff;
|
||||
float m_fPedZoomValue;
|
||||
|
||||
float m_fPedZoomValueScript;
|
||||
float m_fPedZoomValueSmooth;
|
||||
float m_fPositionAlongSpline;
|
||||
float m_ScreenReductionPercentage;
|
||||
float m_ScreenReductionSpeed;
|
||||
float m_AlphaForPlayerAnim1rstPerson;
|
||||
float Orientation;
|
||||
#ifdef FIX_BUGS
|
||||
int32 PedZoomIndicator;
|
||||
#else
|
||||
float PedZoomIndicator;
|
||||
#endif
|
||||
float PlayerExhaustion;
|
||||
float SoundDistUp, SoundDistLeft, SoundDistRight;
|
||||
float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead;
|
||||
float SoundDistUpAsReadOld, SoundDistLeftAsReadOld, SoundDistRightAsReadOld;
|
||||
float m_fWideScreenReductionAmount;
|
||||
float m_fStartingFOVForInterPol;
|
||||
|
||||
// not static yet
|
||||
float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls
|
||||
float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls
|
||||
float m_f3rdPersonCHairMultX;
|
||||
float m_f3rdPersonCHairMultY;
|
||||
|
||||
|
||||
CCam Cams[3];
|
||||
CGarage *pToGarageWeAreIn;
|
||||
CGarage *pToGarageWeAreInForHackAvoidFirstPerson;
|
||||
CQueuedMode m_PlayerMode;
|
||||
CQueuedMode PlayerWeaponMode;
|
||||
CVector m_PreviousCameraPosition;
|
||||
CVector m_RealPreviousCameraPosition;
|
||||
CVector m_cvecAimingTargetCoors;
|
||||
CVector m_vecFixedModeVector;
|
||||
CVector m_vecFixedModeSource;
|
||||
CVector m_vecFixedModeUpOffSet;
|
||||
CVector m_vecCutSceneOffset;
|
||||
#ifndef PS2_CAM_TRANSITION
|
||||
CVector m_cvecStartingSourceForInterPol;
|
||||
CVector m_cvecStartingTargetForInterPol;
|
||||
CVector m_cvecStartingUpForInterPol;
|
||||
CVector m_cvecSourceSpeedAtStartInter;
|
||||
CVector m_cvecTargetSpeedAtStartInter;
|
||||
CVector m_cvecUpSpeedAtStartInter;
|
||||
CVector m_vecSourceWhenInterPol;
|
||||
CVector m_vecTargetWhenInterPol;
|
||||
CVector m_vecUpWhenInterPol;
|
||||
#endif
|
||||
CVector m_vecGameCamPos;
|
||||
#ifndef PS2_CAM_TRANSITION
|
||||
CVector SourceDuringInter;
|
||||
CVector TargetDuringInter;
|
||||
CVector UpDuringInter;
|
||||
#endif
|
||||
RwCamera *m_pRwCamera;
|
||||
CEntity *pTargetEntity;
|
||||
CCamPathSplines m_arrPathArray[MAX_NUM_OF_SPLINETYPES];
|
||||
CTrainCamNode m_arrTrainCamNode[MAX_NUM_OF_NODES];
|
||||
CMatrix m_cameraMatrix;
|
||||
bool m_bGarageFixedCamPositionSet;
|
||||
bool m_vecDoingSpecialInterPolation;
|
||||
bool m_bScriptParametersSetForInterPol;
|
||||
bool m_bFading;
|
||||
bool m_bMusicFading;
|
||||
CMatrix m_viewMatrix;
|
||||
CVector m_vecFrustumNormals[4];
|
||||
CVector m_vecOldSourceForInter;
|
||||
CVector m_vecOldFrontForInter;
|
||||
CVector m_vecOldUpForInter;
|
||||
float m_vecOldFOVForInter;
|
||||
float m_fFLOATingFade;
|
||||
float m_fFLOATingFadeMusic;
|
||||
float m_fTimeToFadeOut;
|
||||
float m_fTimeToFadeMusic;
|
||||
float m_fFractionInterToStopMoving;
|
||||
float m_fFractionInterToStopCatchUp;
|
||||
float m_fGaitSwayBuffer;
|
||||
float m_fScriptPercentageInterToStopMoving;
|
||||
float m_fScriptPercentageInterToCatchUp;
|
||||
|
||||
uint32 m_fScriptTimeForInterPolation;
|
||||
|
||||
|
||||
int16 m_iFadingDirection;
|
||||
int m_iModeObbeCamIsInForCar;
|
||||
int16 m_iModeToGoTo;
|
||||
int16 m_iMusicFadingDirection;
|
||||
int16 m_iTypeOfSwitch;
|
||||
|
||||
uint32 m_uiFadeTimeStarted;
|
||||
uint32 m_uiFadeTimeStartedMusic;
|
||||
|
||||
static bool m_bUseMouse3rdPerson;
|
||||
#ifdef FREE_CAM
|
||||
static bool bFreeCam;
|
||||
#endif
|
||||
|
||||
// High level and misc
|
||||
CCamera(void);
|
||||
CCamera(float);
|
||||
void Init(void);
|
||||
void Process(void);
|
||||
void CamControl(void);
|
||||
void UpdateTargetEntity(void);
|
||||
void UpdateSoundDistances(void);
|
||||
void InitialiseCameraForDebugMode(void);
|
||||
void CamShake(float strength, float x, float y, float z);
|
||||
bool Get_Just_Switched_Status() { return m_bJust_Switched; }
|
||||
|
||||
// Who's in control
|
||||
void TakeControl(CEntity *target, int16 mode, int16 typeOfSwitch, int32 controller);
|
||||
void TakeControlNoEntity(const CVector &position, int16 typeOfSwitch, int32 controller);
|
||||
void TakeControlWithSpline(int16 typeOfSwitch);
|
||||
void Restore(void);
|
||||
void RestoreWithJumpCut(void);
|
||||
void SetCamPositionForFixedMode(const CVector &Source, const CVector &UppOffSet);
|
||||
|
||||
// Transition
|
||||
void StartTransition(int16 mode);
|
||||
void StartTransitionWhenNotFinishedInter(int16 mode);
|
||||
void StoreValuesDuringInterPol(CVector &source, CVector &target, CVector &up, float &FOV);
|
||||
|
||||
// Widescreen borders
|
||||
void SetWideScreenOn(void);
|
||||
void SetWideScreenOff(void);
|
||||
void ProcessWideScreenOn(void);
|
||||
void DrawBordersForWideScreen(void);
|
||||
|
||||
// Obbe's cam
|
||||
bool IsItTimeForNewcam(int32 obbeMode, int32 time);
|
||||
bool TryToStartNewCamMode(int32 obbeMode);
|
||||
void DontProcessObbeCinemaCamera(void);
|
||||
void ProcessObbeCinemaCameraCar(void);
|
||||
void ProcessObbeCinemaCameraPed(void);
|
||||
|
||||
// Train
|
||||
void LoadTrainCamNodes(char const *name);
|
||||
void Process_Train_Camera_Control(void);
|
||||
|
||||
// Script
|
||||
void LoadPathSplines(int file);
|
||||
void FinishCutscene(void);
|
||||
float GetPositionAlongSpline(void) { return m_fPositionAlongSpline; }
|
||||
uint32 GetCutSceneFinishTime(void);
|
||||
void SetCamCutSceneOffSet(const CVector &pos);
|
||||
void SetPercentAlongCutScene(float percent);
|
||||
void SetParametersForScriptInterpolation(float stopMoving, float catchUp, int32 time);
|
||||
void SetZoomValueFollowPedScript(int16 dist);
|
||||
void SetZoomValueCamStringScript(int16 dist);
|
||||
void SetNearClipScript(float);
|
||||
|
||||
// Fading
|
||||
void ProcessFade(void);
|
||||
void ProcessMusicFade(void);
|
||||
void Fade(float timeout, int16 direction);
|
||||
void SetFadeColour(uint8 r, uint8 g, uint8 b);
|
||||
bool GetFading(void);
|
||||
int GetFadingDirection(void);
|
||||
int GetScreenFadeStatus(void);
|
||||
|
||||
// Motion blur
|
||||
void RenderMotionBlur(void);
|
||||
void SetMotionBlur(int r, int g, int b, int a, int type);
|
||||
void SetMotionBlurAlpha(int a);
|
||||
|
||||
// Player looking and aiming
|
||||
int GetLookDirection(void);
|
||||
bool GetLookingForwardFirstPerson(void);
|
||||
bool GetLookingLRBFirstPerson(void);
|
||||
void SetCameraDirectlyInFrontForFollowPed_CamOnAString(void);
|
||||
void SetCameraDirectlyBehindForFollowPed_CamOnAString(void);
|
||||
void SetNewPlayerWeaponMode(int16 mode, int16 minZoom, int16 maxZoom);
|
||||
void ClearPlayerWeaponMode(void);
|
||||
void UpdateAimingCoors(CVector const &coors);
|
||||
bool Find3rdPersonCamTargetVector(float dist, CVector pos, CVector &source, CVector &target);
|
||||
float Find3rdPersonQuickAimPitch(void);
|
||||
|
||||
// Physical camera
|
||||
void SetRwCamera(RwCamera *cam);
|
||||
const CMatrix& GetCameraMatrix(void) { return m_cameraMatrix; }
|
||||
CVector &GetGameCamPosition(void) { return m_vecGameCamPos; }
|
||||
void CalculateDerivedValues(void);
|
||||
bool IsPointVisible(const CVector ¢er, const CMatrix *mat);
|
||||
bool IsSphereVisible(const CVector ¢er, float radius, Const CMatrix *mat);
|
||||
bool IsSphereVisible(const CVector ¢er, float radius);
|
||||
bool IsBoxVisible(CVUVECTOR *box, const CMatrix *mat);
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CCamera, 0xE9D8);
|
||||
|
||||
extern CCamera TheCamera;
|
||||
|
||||
void CamShakeNoPos(CCamera*, float);
|
||||
void MakeAngleLessThan180(float &Angle);
|
||||
void WellBufferMe(float Target, float *CurrentValue, float *CurrentSpeed, float MaxSpeed, float Acceleration, bool IsAngle);
|
||||
538
src/core/CdStream.cpp
Normal file
538
src/core/CdStream.cpp
Normal file
|
|
@ -0,0 +1,538 @@
|
|||
#ifdef _WIN32
|
||||
#define WITHWINDOWS
|
||||
#include "common.h"
|
||||
|
||||
#include "CdStream.h"
|
||||
#include "rwcore.h"
|
||||
#include "RwHelper.h"
|
||||
#include "MemoryMgr.h"
|
||||
|
||||
struct CdReadInfo
|
||||
{
|
||||
uint32 nSectorOffset;
|
||||
uint32 nSectorsToRead;
|
||||
void *pBuffer;
|
||||
char field_C;
|
||||
bool bLocked;
|
||||
bool bReading;
|
||||
int32 nStatus;
|
||||
HANDLE pDoneSemaphore; // used for CdStreamSync
|
||||
HANDLE hFile;
|
||||
OVERLAPPED Overlapped;
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CdReadInfo, 0x30);
|
||||
|
||||
char gCdImageNames[MAX_CDIMAGES+1][64];
|
||||
int32 gNumImages;
|
||||
int32 gNumChannels;
|
||||
|
||||
HANDLE gImgFiles[MAX_CDIMAGES];
|
||||
|
||||
HANDLE _gCdStreamThread;
|
||||
HANDLE gCdStreamSema; // released when we have new thing to read(so channel is set)
|
||||
DWORD _gCdStreamThreadId;
|
||||
|
||||
CdReadInfo *gpReadInfo;
|
||||
Queue gChannelRequestQ;
|
||||
|
||||
int32 lastPosnRead;
|
||||
|
||||
BOOL _gbCdStreamOverlapped;
|
||||
BOOL _gbCdStreamAsync;
|
||||
DWORD _gdwCdStreamFlags;
|
||||
|
||||
DWORD WINAPI CdStreamThread(LPVOID lpThreadParameter);
|
||||
|
||||
void
|
||||
CdStreamInitThread(void)
|
||||
{
|
||||
SetLastError(0);
|
||||
|
||||
if ( gNumChannels > 0 )
|
||||
{
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
{
|
||||
gpReadInfo[i].pDoneSemaphore = CreateSemaphore(nil, 0, 2, nil);
|
||||
|
||||
if ( gpReadInfo[i].pDoneSemaphore == nil )
|
||||
{
|
||||
printf("%s: failed to create sync semaphore\n", "cdvd_stream");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gChannelRequestQ.items = (int32 *)LocalAlloc(LMEM_ZEROINIT, sizeof(int32) * (gNumChannels + 1));
|
||||
gChannelRequestQ.head = 0;
|
||||
gChannelRequestQ.tail = 0;
|
||||
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 )
|
||||
{
|
||||
printf("%s: failed to create stream semaphore\n", "cdvd_stream");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
_gCdStreamThread = CreateThread(nil, 64*1024/*64KB*/, CdStreamThread, nil, CREATE_SUSPENDED, &_gCdStreamThreadId);
|
||||
|
||||
if ( _gCdStreamThread == nil )
|
||||
{
|
||||
printf("%s: failed to create streaming thread\n", "cdvd_stream");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
SetThreadPriority(_gCdStreamThread, GetThreadPriority(GetCurrentThread()) - 1);
|
||||
|
||||
ResumeThread(_gCdStreamThread);
|
||||
}
|
||||
|
||||
void
|
||||
CdStreamInit(int32 numChannels)
|
||||
{
|
||||
DWORD SectorsPerCluster;
|
||||
DWORD BytesPerSector;
|
||||
DWORD NumberOfFreeClusters;
|
||||
DWORD TotalNumberOfClusters;
|
||||
|
||||
GetDiskFreeSpace(nil, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
|
||||
|
||||
_gdwCdStreamFlags = 0;
|
||||
|
||||
#ifndef FIX_BUGS // this just slows down streaming
|
||||
if ( BytesPerSector <= CDSTREAM_SECTOR_SIZE )
|
||||
{
|
||||
_gdwCdStreamFlags |= FILE_FLAG_NO_BUFFERING;
|
||||
debug("Using no buffered loading for streaming\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
_gbCdStreamOverlapped = TRUE;
|
||||
|
||||
_gdwCdStreamFlags |= FILE_FLAG_OVERLAPPED;
|
||||
|
||||
_gbCdStreamAsync = FALSE;
|
||||
|
||||
void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, BytesPerSector);
|
||||
ASSERT( pBuffer != nil );
|
||||
|
||||
SetLastError(0);
|
||||
|
||||
gNumImages = 0;
|
||||
|
||||
gNumChannels = numChannels;
|
||||
|
||||
gpReadInfo = (CdReadInfo *)LocalAlloc(LMEM_ZEROINIT, sizeof(CdReadInfo) * numChannels);
|
||||
ASSERT( gpReadInfo != nil );
|
||||
|
||||
debug("%s: read info %p\n", "cdvd_stream", gpReadInfo);
|
||||
|
||||
CdStreamAddImage("MODELS\\GTA3.IMG");
|
||||
|
||||
int32 nStatus = CdStreamRead(0, pBuffer, 0, 1);
|
||||
|
||||
CdStreamRemoveImages();
|
||||
|
||||
if ( nStatus == STREAM_SUCCESS )
|
||||
{
|
||||
_gbCdStreamAsync = TRUE;
|
||||
|
||||
debug("Using async loading for streaming\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
_gdwCdStreamFlags &= ~FILE_FLAG_OVERLAPPED;
|
||||
|
||||
_gbCdStreamOverlapped = FALSE;
|
||||
|
||||
_gbCdStreamAsync = TRUE;
|
||||
|
||||
debug("Using sync loading for streaming\n");
|
||||
}
|
||||
|
||||
CdStreamInitThread();
|
||||
|
||||
ASSERT( pBuffer != nil );
|
||||
RwFreeAlign(pBuffer);
|
||||
}
|
||||
|
||||
uint32
|
||||
GetGTA3ImgSize(void)
|
||||
{
|
||||
ASSERT( gImgFiles[0] != nil );
|
||||
return (uint32)GetFileSize(gImgFiles[0], nil);
|
||||
}
|
||||
|
||||
void
|
||||
CdStreamShutdown(void)
|
||||
{
|
||||
if ( _gbCdStreamAsync )
|
||||
{
|
||||
LocalFree(gChannelRequestQ.items);
|
||||
CloseHandle(gCdStreamSema);
|
||||
CloseHandle(_gCdStreamThread);
|
||||
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
CloseHandle(gpReadInfo[i].pDoneSemaphore);
|
||||
}
|
||||
|
||||
LocalFree(gpReadInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32
|
||||
CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
|
||||
{
|
||||
ASSERT( channel < gNumChannels );
|
||||
ASSERT( buffer != nil );
|
||||
|
||||
lastPosnRead = size + offset;
|
||||
|
||||
ASSERT( _GET_INDEX(offset) < MAX_CDIMAGES );
|
||||
HANDLE hImage = gImgFiles[_GET_INDEX(offset)];
|
||||
ASSERT( hImage != nil );
|
||||
|
||||
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
pChannel->hFile = hImage;
|
||||
|
||||
SetLastError(0);
|
||||
|
||||
if ( _gbCdStreamAsync )
|
||||
{
|
||||
if ( pChannel->nSectorsToRead != 0 || pChannel->bReading )
|
||||
return STREAM_NONE;
|
||||
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
pChannel->nSectorOffset = _GET_OFFSET(offset);
|
||||
pChannel->nSectorsToRead = size;
|
||||
pChannel->pBuffer = buffer;
|
||||
pChannel->bLocked = 0;
|
||||
|
||||
AddToQueue(&gChannelRequestQ, channel);
|
||||
|
||||
if ( !ReleaseSemaphore(gCdStreamSema, 1, nil) )
|
||||
printf("Signal Sema Error\n");
|
||||
|
||||
return STREAM_SUCCESS;
|
||||
}
|
||||
|
||||
if ( _gbCdStreamOverlapped )
|
||||
{
|
||||
ASSERT( channel < gNumChannels );
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
pChannel->Overlapped.Offset = _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE;
|
||||
|
||||
if ( !ReadFile(hImage, buffer, size * CDSTREAM_SECTOR_SIZE, NULL, &pChannel->Overlapped)
|
||||
&& GetLastError() != ERROR_IO_PENDING )
|
||||
return STREAM_NONE;
|
||||
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;
|
||||
|
||||
if ( !ReadFile(hImage, buffer, size * CDSTREAM_SECTOR_SIZE, &NumberOfBytesRead, nil) )
|
||||
return STREAM_NONE;
|
||||
else
|
||||
return STREAM_SUCCESS;
|
||||
}
|
||||
|
||||
int32
|
||||
CdStreamGetStatus(int32 channel)
|
||||
{
|
||||
ASSERT( channel < gNumChannels );
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
if ( _gbCdStreamAsync )
|
||||
{
|
||||
if ( pChannel->bReading )
|
||||
return STREAM_READING;
|
||||
|
||||
if ( pChannel->nSectorsToRead != 0 )
|
||||
return STREAM_WAITING;
|
||||
|
||||
if ( pChannel->nStatus != STREAM_NONE )
|
||||
{
|
||||
int32 status = pChannel->nStatus;
|
||||
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return STREAM_NONE;
|
||||
}
|
||||
|
||||
if ( _gbCdStreamOverlapped )
|
||||
{
|
||||
ASSERT( pChannel->hFile != nil );
|
||||
if ( WaitForSingleObjectEx(pChannel->hFile, 0, TRUE) == WAIT_OBJECT_0 )
|
||||
return STREAM_NONE;
|
||||
else
|
||||
return STREAM_READING;
|
||||
}
|
||||
|
||||
return STREAM_NONE;
|
||||
}
|
||||
|
||||
int32
|
||||
CdStreamGetLastPosn(void)
|
||||
{
|
||||
return lastPosnRead;
|
||||
}
|
||||
|
||||
// wait for channel to finish reading
|
||||
int32
|
||||
CdStreamSync(int32 channel)
|
||||
{
|
||||
ASSERT( channel < gNumChannels );
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
if ( _gbCdStreamAsync )
|
||||
{
|
||||
if ( pChannel->nSectorsToRead != 0 )
|
||||
{
|
||||
pChannel->bLocked = true;
|
||||
|
||||
ASSERT( pChannel->pDoneSemaphore != nil );
|
||||
|
||||
// Deadlock fix 1
|
||||
#ifdef FIX_BUGS
|
||||
// This is while loop on Posix streamer, for spurious wakeups
|
||||
if (pChannel->bLocked && pChannel->nSectorsToRead != 0){
|
||||
WaitForSingleObject(pChannel->pDoneSemaphore, INFINITE);
|
||||
}
|
||||
pChannel->bLocked = false;
|
||||
#else
|
||||
WaitForSingleObject(pChannel->pDoneSemaphore, INFINITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
pChannel->bReading = false;
|
||||
|
||||
return pChannel->nStatus;
|
||||
}
|
||||
|
||||
DWORD NumberOfBytesTransferred;
|
||||
|
||||
if ( _gbCdStreamOverlapped && pChannel->hFile )
|
||||
{
|
||||
ASSERT(pChannel->hFile != nil );
|
||||
// Beware: This is blocking call (because of last parameter)
|
||||
if ( GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
|
||||
return STREAM_NONE;
|
||||
else
|
||||
return STREAM_ERROR;
|
||||
}
|
||||
|
||||
return STREAM_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
AddToQueue(Queue *queue, int32 item)
|
||||
{
|
||||
ASSERT( queue != nil );
|
||||
ASSERT( queue->items != nil );
|
||||
queue->items[queue->tail] = item;
|
||||
|
||||
queue->tail = (queue->tail + 1) % queue->size;
|
||||
|
||||
if ( queue->head == queue->tail )
|
||||
debug("Queue is full\n");
|
||||
}
|
||||
|
||||
int32
|
||||
GetFirstInQueue(Queue *queue)
|
||||
{
|
||||
ASSERT( queue != nil );
|
||||
if ( queue->head == queue->tail )
|
||||
return -1;
|
||||
|
||||
ASSERT( queue->items != nil );
|
||||
return queue->items[queue->head];
|
||||
}
|
||||
|
||||
void
|
||||
RemoveFirstInQueue(Queue *queue)
|
||||
{
|
||||
ASSERT( queue != nil );
|
||||
if ( queue->head == queue->tail )
|
||||
{
|
||||
debug("Queue is empty\n");
|
||||
return;
|
||||
}
|
||||
|
||||
queue->head = (queue->head + 1) % queue->size;
|
||||
}
|
||||
|
||||
DWORD
|
||||
WINAPI CdStreamThread(LPVOID lpThreadParameter)
|
||||
{
|
||||
debug("Created cdstream thread\n");
|
||||
|
||||
while ( true )
|
||||
{
|
||||
WaitForSingleObject(gCdStreamSema, INFINITE);
|
||||
|
||||
int32 channel = GetFirstInQueue(&gChannelRequestQ);
|
||||
ASSERT( channel < gNumChannels );
|
||||
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
pChannel->bReading = true;
|
||||
|
||||
if ( pChannel->nStatus == STREAM_NONE )
|
||||
{
|
||||
if ( _gbCdStreamOverlapped )
|
||||
{
|
||||
pChannel->Overlapped.Offset = pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE;
|
||||
|
||||
ASSERT(pChannel->hFile != nil );
|
||||
ASSERT(pChannel->pBuffer != nil );
|
||||
|
||||
DWORD NumberOfBytesTransferred;
|
||||
|
||||
if ( ReadFile(pChannel->hFile,
|
||||
pChannel->pBuffer,
|
||||
pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE,
|
||||
NULL,
|
||||
&pChannel->Overlapped) )
|
||||
{
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
}
|
||||
// Beware: This is blocking call (because of last parameter)
|
||||
else if ( GetLastError() == ERROR_IO_PENDING
|
||||
&& GetOverlappedResult(pChannel->hFile, &pChannel->Overlapped, &NumberOfBytesTransferred, TRUE) )
|
||||
{
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pChannel->nStatus = STREAM_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(pChannel->hFile != nil );
|
||||
ASSERT(pChannel->pBuffer != nil );
|
||||
|
||||
SetFilePointer(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN);
|
||||
|
||||
DWORD NumberOfBytesRead;
|
||||
if ( ReadFile(pChannel->hFile,
|
||||
pChannel->pBuffer,
|
||||
pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE,
|
||||
&NumberOfBytesRead,
|
||||
NULL) )
|
||||
{
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RemoveFirstInQueue(&gChannelRequestQ);
|
||||
|
||||
pChannel->nSectorsToRead = 0;
|
||||
|
||||
if ( pChannel->bLocked )
|
||||
{
|
||||
ASSERT( pChannel->pDoneSemaphore != nil );
|
||||
// Deadlock fix 2
|
||||
#ifdef FIX_BUGS
|
||||
pChannel->bLocked = 0;
|
||||
#endif
|
||||
ReleaseSemaphore(pChannel->pDoneSemaphore, 1, NULL);
|
||||
}
|
||||
|
||||
pChannel->bReading = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CdStreamAddImage(char const *path)
|
||||
{
|
||||
ASSERT(path != nil);
|
||||
ASSERT(gNumImages < MAX_CDIMAGES);
|
||||
|
||||
SetLastError(0);
|
||||
|
||||
gImgFiles[gNumImages] = CreateFile(path,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
nil,
|
||||
OPEN_EXISTING,
|
||||
_gdwCdStreamFlags | FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_READONLY,
|
||||
nil);
|
||||
|
||||
ASSERT( gImgFiles[gNumImages] != nil );
|
||||
if ( gImgFiles[gNumImages] == NULL )
|
||||
return false;
|
||||
|
||||
strcpy(gCdImageNames[gNumImages], path);
|
||||
|
||||
gNumImages++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *
|
||||
CdStreamGetImageName(int32 cd)
|
||||
{
|
||||
ASSERT(cd < MAX_CDIMAGES);
|
||||
if ( gImgFiles[cd] != nil )
|
||||
return gCdImageNames[cd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
CdStreamRemoveImages(void)
|
||||
{
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
CdStreamSync(i);
|
||||
|
||||
for ( int32 i = 0; i < gNumImages; i++ )
|
||||
{
|
||||
SetLastError(0);
|
||||
|
||||
CloseHandle(gImgFiles[i]);
|
||||
gImgFiles[i] = nil;
|
||||
}
|
||||
|
||||
gNumImages = 0;
|
||||
}
|
||||
|
||||
int32
|
||||
CdStreamGetNumImages(void)
|
||||
{
|
||||
return gNumImages;
|
||||
}
|
||||
#endif
|
||||
48
src/core/CdStream.h
Normal file
48
src/core/CdStream.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#define CDSTREAM_SECTOR_SIZE 2048
|
||||
|
||||
#define _GET_INDEX(a) (a >> 24)
|
||||
#define _GET_OFFSET(a) (a & 0xFFFFFF)
|
||||
|
||||
enum
|
||||
{
|
||||
STREAM_NONE = uint8( 0),
|
||||
STREAM_SUCCESS = uint8( 1),
|
||||
STREAM_READING = uint8(-1), // 0xFF,
|
||||
STREAM_ERROR = uint8(-2), // 0xFE,
|
||||
STREAM_ERROR_NOCD = uint8(-3), // 0xFD,
|
||||
STREAM_ERROR_WRONGCD = uint8(-4), // 0xFC,
|
||||
STREAM_ERROR_OPENCD = uint8(-5), // 0xFB,
|
||||
STREAM_WAITING = uint8(-6) // 0xFA,
|
||||
};
|
||||
|
||||
struct Queue
|
||||
{
|
||||
int32 *items;
|
||||
int32 head;
|
||||
int32 tail;
|
||||
int32 size;
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(Queue, 0x10);
|
||||
|
||||
void CdStreamInitThread(void);
|
||||
void CdStreamInit(int32 numChannels);
|
||||
uint32 GetGTA3ImgSize(void);
|
||||
void CdStreamShutdown(void);
|
||||
int32 CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size);
|
||||
int32 CdStreamGetStatus(int32 channel);
|
||||
int32 CdStreamGetLastPosn(void);
|
||||
int32 CdStreamSync(int32 channel);
|
||||
void AddToQueue(Queue *queue, int32 item);
|
||||
int32 GetFirstInQueue(Queue *queue);
|
||||
void RemoveFirstInQueue(Queue *queue);
|
||||
bool CdStreamAddImage(char const *path);
|
||||
char *CdStreamGetImageName(int32 cd);
|
||||
void CdStreamRemoveImages(void);
|
||||
int32 CdStreamGetNumImages(void);
|
||||
|
||||
#ifdef FLUSHABLE_STREAMING
|
||||
extern bool flushStream[MAX_CDCHANNELS];
|
||||
#endif
|
||||
604
src/core/CdStreamPosix.cpp
Normal file
604
src/core/CdStreamPosix.cpp
Normal file
|
|
@ -0,0 +1,604 @@
|
|||
#ifndef _WIN32
|
||||
#include "common.h"
|
||||
#include "crossplatform.h"
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#include "CdStream.h"
|
||||
#include "rwcore.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__)
|
||||
|
||||
#ifdef FLUSHABLE_STREAMING
|
||||
bool flushStream[MAX_CDCHANNELS];
|
||||
#endif
|
||||
|
||||
#ifdef USE_UNNAMED_SEM
|
||||
|
||||
#define RE3_SEM_OPEN(name, ...) re3_sem_open()
|
||||
sem_t*
|
||||
re3_sem_open(void)
|
||||
{
|
||||
sem_t* sem = (sem_t*)malloc(sizeof(sem_t));
|
||||
if (sem_init(sem, 0, 1) == -1) {
|
||||
sem = SEM_FAILED;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
#define RE3_SEM_CLOSE(sem, format, ...) re3_sem_close(sem)
|
||||
void
|
||||
re3_sem_close(sem_t* sem)
|
||||
{
|
||||
sem_destroy(sem);
|
||||
free(sem);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define RE3_SEM_OPEN re3_sem_open
|
||||
sem_t*
|
||||
re3_sem_open(const char* format, ...)
|
||||
{
|
||||
char semName[21];
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
vsprintf(semName, format, va);
|
||||
|
||||
return sem_open(semName, O_CREAT, 0644, 1);
|
||||
}
|
||||
|
||||
#define RE3_SEM_CLOSE re3_sem_close
|
||||
void
|
||||
re3_sem_close(sem_t* sem, const char* format, ...)
|
||||
{
|
||||
sem_close(sem);
|
||||
|
||||
char semName[21];
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
vsprintf(semName, format, va);
|
||||
|
||||
sem_unlink(semName);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct CdReadInfo
|
||||
{
|
||||
uint32 nSectorOffset;
|
||||
uint32 nSectorsToRead;
|
||||
void *pBuffer;
|
||||
bool bLocked;
|
||||
bool bReading;
|
||||
int32 nStatus;
|
||||
#ifdef ONE_THREAD_PER_CHANNEL
|
||||
int8 nThreadStatus; // 0: created 1:priority set up 2:abort now
|
||||
pthread_t pChannelThread;
|
||||
sem_t *pStartSemaphore;
|
||||
#endif
|
||||
sem_t *pDoneSemaphore; // used for CdStreamSync
|
||||
int32 hFile;
|
||||
};
|
||||
|
||||
char gCdImageNames[MAX_CDIMAGES+1][64];
|
||||
int32 gNumImages;
|
||||
int32 gNumChannels;
|
||||
|
||||
int32 gImgFiles[MAX_CDIMAGES]; // -1: error 0:unused otherwise: fd
|
||||
char *gImgNames[MAX_CDIMAGES];
|
||||
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
pthread_t _gCdStreamThread;
|
||||
sem_t *gCdStreamSema; // released when we have new thing to read(so channel is set)
|
||||
int8 gCdStreamThreadStatus; // 0: created 1:priority set up 2:abort now
|
||||
Queue gChannelRequestQ;
|
||||
bool _gbCdStreamOverlapped;
|
||||
#endif
|
||||
|
||||
CdReadInfo *gpReadInfo;
|
||||
|
||||
int32 lastPosnRead;
|
||||
|
||||
int _gdwCdStreamFlags;
|
||||
|
||||
void *CdStreamThread(void* channelId);
|
||||
|
||||
void
|
||||
CdStreamInitThread(void)
|
||||
{
|
||||
int status;
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
gChannelRequestQ.items = (int32 *)calloc(gNumChannels + 1, sizeof(int32));
|
||||
gChannelRequestQ.head = 0;
|
||||
gChannelRequestQ.tail = 0;
|
||||
gChannelRequestQ.size = gNumChannels + 1;
|
||||
ASSERT(gChannelRequestQ.items != nil );
|
||||
gCdStreamSema = RE3_SEM_OPEN("/semaphore_cd_stream");
|
||||
|
||||
|
||||
if (gCdStreamSema == SEM_FAILED) {
|
||||
CDTRACE("failed to create stream semaphore");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( gNumChannels > 0 )
|
||||
{
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
{
|
||||
gpReadInfo[i].pDoneSemaphore = RE3_SEM_OPEN("/semaphore_done%d", i);
|
||||
|
||||
if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED)
|
||||
{
|
||||
CDTRACE("failed to create sync semaphore");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ONE_THREAD_PER_CHANNEL
|
||||
gpReadInfo[i].pStartSemaphore = RE3_SEM_OPEN("/semaphore_start%d", i);
|
||||
|
||||
if (gpReadInfo[i].pStartSemaphore == SEM_FAILED)
|
||||
{
|
||||
CDTRACE("failed to create start semaphore");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
gpReadInfo[i].nThreadStatus = 0;
|
||||
int *channelI = (int*)malloc(sizeof(int));
|
||||
*channelI = i;
|
||||
status = pthread_create(&gpReadInfo[i].pChannelThread, NULL, CdStreamThread, (void*)channelI);
|
||||
|
||||
if (status == -1)
|
||||
{
|
||||
CDTRACE("failed to create sync thread");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
debug("Using one streaming thread for all channels\n");
|
||||
gCdStreamThreadStatus = 0;
|
||||
status = pthread_create(&_gCdStreamThread, NULL, CdStreamThread, nil);
|
||||
|
||||
if (status == -1)
|
||||
{
|
||||
CDTRACE("failed to create sync thread");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
debug("Using separate streaming threads for each channel\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CdStreamInit(int32 numChannels)
|
||||
{
|
||||
struct statvfs fsInfo;
|
||||
|
||||
if((statvfs("models/gta3.img", &fsInfo)) < 0)
|
||||
{
|
||||
CDTRACE("can't get filesystem info");
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
#ifdef __linux__
|
||||
_gdwCdStreamFlags = O_RDONLY | O_NOATIME;
|
||||
#else
|
||||
_gdwCdStreamFlags = O_RDONLY;
|
||||
#endif
|
||||
// People say it's slower
|
||||
/*
|
||||
if ( fsInfo.f_bsize <= CDSTREAM_SECTOR_SIZE )
|
||||
{
|
||||
_gdwCdStreamFlags |= O_DIRECT;
|
||||
debug("Using no buffered loading for streaming\n");
|
||||
}
|
||||
*/
|
||||
void *pBuffer = (void *)RwMallocAlign(CDSTREAM_SECTOR_SIZE, (RwUInt32)fsInfo.f_bsize);
|
||||
ASSERT( pBuffer != nil );
|
||||
|
||||
gNumImages = 0;
|
||||
|
||||
gNumChannels = numChannels;
|
||||
ASSERT( gNumChannels != 0 );
|
||||
|
||||
gpReadInfo = (CdReadInfo *)calloc(numChannels, sizeof(CdReadInfo));
|
||||
ASSERT( gpReadInfo != nil );
|
||||
|
||||
CDDEBUG("read info %p", gpReadInfo);
|
||||
|
||||
CdStreamInitThread();
|
||||
|
||||
ASSERT( pBuffer != nil );
|
||||
RwFreeAlign(pBuffer);
|
||||
}
|
||||
|
||||
uint32
|
||||
GetGTA3ImgSize(void)
|
||||
{
|
||||
ASSERT( gImgFiles[0] > 0 );
|
||||
struct stat statbuf;
|
||||
|
||||
char path[PATH_MAX];
|
||||
realpath(gImgNames[0], path);
|
||||
if (stat(path, &statbuf) == -1) {
|
||||
// Try case-insensitivity
|
||||
char* real = casepath(gImgNames[0], false);
|
||||
if (real)
|
||||
{
|
||||
realpath(real, path);
|
||||
free(real);
|
||||
if (stat(path, &statbuf) != -1)
|
||||
goto ok;
|
||||
}
|
||||
|
||||
CDTRACE("can't get size of gta3.img");
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
ok:
|
||||
return (uint32)statbuf.st_size;
|
||||
}
|
||||
|
||||
void
|
||||
CdStreamShutdown(void)
|
||||
{
|
||||
// Destroying semaphores and free(gpReadInfo) will be done at threads
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
gCdStreamThreadStatus = 2;
|
||||
sem_post(gCdStreamSema);
|
||||
pthread_join(_gCdStreamThread, nil);
|
||||
#else
|
||||
for ( int32 i = 0; i < gNumChannels; i++ ) {
|
||||
gpReadInfo[i].nThreadStatus = 2;
|
||||
sem_post(gpReadInfo[i].pStartSemaphore);
|
||||
pthread_join(gpReadInfo[i].pChannelThread, nil);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
|
||||
{
|
||||
ASSERT( channel < gNumChannels );
|
||||
ASSERT( buffer != nil );
|
||||
|
||||
lastPosnRead = size + offset;
|
||||
|
||||
ASSERT( _GET_INDEX(offset) < MAX_CDIMAGES );
|
||||
int32 hImage = gImgFiles[_GET_INDEX(offset)];
|
||||
ASSERT( hImage > 0 );
|
||||
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) {
|
||||
if (pChannel->hFile == hImage - 1 && pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size)
|
||||
return STREAM_SUCCESS;
|
||||
#ifdef FLUSHABLE_STREAMING
|
||||
flushStream[channel] = 1;
|
||||
CdStreamSync(channel);
|
||||
#else
|
||||
return STREAM_NONE;
|
||||
#endif
|
||||
}
|
||||
|
||||
pChannel->hFile = hImage - 1;
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
pChannel->nSectorOffset = _GET_OFFSET(offset);
|
||||
pChannel->nSectorsToRead = size;
|
||||
pChannel->pBuffer = buffer;
|
||||
pChannel->bLocked = 0;
|
||||
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
AddToQueue(&gChannelRequestQ, channel);
|
||||
if ( sem_post(gCdStreamSema) != 0 )
|
||||
printf("Signal Sema Error\n");
|
||||
#else
|
||||
if ( sem_post(pChannel->pStartSemaphore) != 0 )
|
||||
printf("Signal Sema Error\n");
|
||||
#endif
|
||||
|
||||
return STREAM_SUCCESS;
|
||||
}
|
||||
|
||||
int32
|
||||
CdStreamGetStatus(int32 channel)
|
||||
{
|
||||
ASSERT( channel < gNumChannels );
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
#ifdef ONE_THREAD_PER_CHANNEL
|
||||
if (pChannel->nThreadStatus == 2)
|
||||
return STREAM_NONE;
|
||||
#else
|
||||
if (gCdStreamThreadStatus == 2)
|
||||
return STREAM_NONE;
|
||||
#endif
|
||||
|
||||
if ( pChannel->bReading )
|
||||
return STREAM_READING;
|
||||
|
||||
if ( pChannel->nSectorsToRead != 0 )
|
||||
return STREAM_WAITING;
|
||||
|
||||
if ( pChannel->nStatus != STREAM_NONE )
|
||||
{
|
||||
int32 status = pChannel->nStatus;
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return STREAM_NONE;
|
||||
}
|
||||
|
||||
int32
|
||||
CdStreamGetLastPosn(void)
|
||||
{
|
||||
return lastPosnRead;
|
||||
}
|
||||
|
||||
// wait for channel to finish reading
|
||||
int32
|
||||
CdStreamSync(int32 channel)
|
||||
{
|
||||
ASSERT( channel < gNumChannels );
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
#ifdef FLUSHABLE_STREAMING
|
||||
if (flushStream[channel]) {
|
||||
pChannel->nSectorsToRead = 0;
|
||||
#ifdef ONE_THREAD_PER_CHANNEL
|
||||
pthread_kill(pChannel->pChannelThread, SIGUSR1);
|
||||
if (pChannel->bReading) {
|
||||
pChannel->bLocked = true;
|
||||
#else
|
||||
if (pChannel->bReading) {
|
||||
pChannel->bLocked = true;
|
||||
pthread_kill(_gCdStreamThread, SIGUSR1);
|
||||
#endif
|
||||
while (pChannel->bLocked)
|
||||
sem_wait(pChannel->pDoneSemaphore);
|
||||
}
|
||||
pChannel->bReading = false;
|
||||
flushStream[channel] = false;
|
||||
return STREAM_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( pChannel->nSectorsToRead != 0 )
|
||||
{
|
||||
pChannel->bLocked = true;
|
||||
while (pChannel->bLocked && pChannel->nSectorsToRead != 0){
|
||||
sem_wait(pChannel->pDoneSemaphore);
|
||||
}
|
||||
pChannel->bLocked = false;
|
||||
}
|
||||
|
||||
pChannel->bReading = false;
|
||||
|
||||
return pChannel->nStatus;
|
||||
}
|
||||
|
||||
void
|
||||
AddToQueue(Queue *queue, int32 item)
|
||||
{
|
||||
ASSERT( queue != nil );
|
||||
ASSERT( queue->items != nil );
|
||||
queue->items[queue->tail] = item;
|
||||
|
||||
queue->tail = (queue->tail + 1) % queue->size;
|
||||
|
||||
if ( queue->head == queue->tail )
|
||||
debug("Queue is full\n");
|
||||
}
|
||||
|
||||
int32
|
||||
GetFirstInQueue(Queue *queue)
|
||||
{
|
||||
ASSERT( queue != nil );
|
||||
if ( queue->head == queue->tail )
|
||||
return -1;
|
||||
|
||||
ASSERT( queue->items != nil );
|
||||
return queue->items[queue->head];
|
||||
}
|
||||
|
||||
void
|
||||
RemoveFirstInQueue(Queue *queue)
|
||||
{
|
||||
ASSERT( queue != nil );
|
||||
if ( queue->head == queue->tail )
|
||||
{
|
||||
debug("Queue is empty\n");
|
||||
return;
|
||||
}
|
||||
|
||||
queue->head = (queue->head + 1) % queue->size;
|
||||
}
|
||||
|
||||
void *CdStreamThread(void *param)
|
||||
{
|
||||
debug("Created cdstream thread\n");
|
||||
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
while (gCdStreamThreadStatus != 2) {
|
||||
sem_wait(gCdStreamSema);
|
||||
|
||||
int32 channel = GetFirstInQueue(&gChannelRequestQ);
|
||||
|
||||
// spurious wakeup
|
||||
if (channel == -1)
|
||||
continue;
|
||||
#else
|
||||
int channel = *((int*)param);
|
||||
while (gpReadInfo[channel].nThreadStatus != 2){
|
||||
sem_wait(gpReadInfo[channel].pStartSemaphore);
|
||||
#endif
|
||||
|
||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
// spurious wakeup or we sent interrupt signal for flushing
|
||||
if(pChannel->nSectorsToRead == 0)
|
||||
continue;
|
||||
|
||||
pChannel->bReading = true;
|
||||
|
||||
// Not standard POSIX :shrug:
|
||||
#ifdef __linux__
|
||||
#ifdef ONE_THREAD_PER_CHANNEL
|
||||
if (gpReadInfo[channel].nThreadStatus == 0){
|
||||
gpReadInfo[channel].nThreadStatus = 1;
|
||||
#else
|
||||
if (gCdStreamThreadStatus == 0){
|
||||
gCdStreamThreadStatus = 1;
|
||||
#endif
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
int ret = setpriority(PRIO_PROCESS, tid, getpriority(PRIO_PROCESS, getpid()) + 1);
|
||||
}
|
||||
#endif
|
||||
if ( pChannel->nStatus == STREAM_NONE )
|
||||
{
|
||||
ASSERT(pChannel->hFile >= 0);
|
||||
ASSERT(pChannel->pBuffer != nil );
|
||||
|
||||
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
|
||||
pChannel->nStatus = pChannel->nSectorsToRead == 0 ? STREAM_WAITING : STREAM_ERROR;
|
||||
} else {
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
RemoveFirstInQueue(&gChannelRequestQ);
|
||||
#endif
|
||||
|
||||
pChannel->nSectorsToRead = 0;
|
||||
if ( pChannel->bLocked )
|
||||
{
|
||||
pChannel->bLocked = 0;
|
||||
sem_post(pChannel->pDoneSemaphore);
|
||||
}
|
||||
pChannel->bReading = false;
|
||||
}
|
||||
char semName[20];
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
{
|
||||
RE3_SEM_CLOSE(gpReadInfo[i].pDoneSemaphore, "/semaphore_done%d", i);
|
||||
}
|
||||
RE3_SEM_CLOSE(gCdStreamSema, "/semaphore_cd_stream");
|
||||
free(gChannelRequestQ.items);
|
||||
#else
|
||||
RE3_SEM_CLOSE(gpReadInfo[channel].pStartSemaphore, "/semaphore_start%d", channel);
|
||||
|
||||
RE3_SEM_CLOSE(gpReadInfo[channel].pDoneSemaphore, "/semaphore_done%d", channel);
|
||||
#endif
|
||||
if (gpReadInfo)
|
||||
free(gpReadInfo);
|
||||
gpReadInfo = nil;
|
||||
pthread_exit(nil);
|
||||
}
|
||||
|
||||
bool
|
||||
CdStreamAddImage(char const *path)
|
||||
{
|
||||
ASSERT(path != nil);
|
||||
ASSERT(gNumImages < MAX_CDIMAGES);
|
||||
|
||||
gImgFiles[gNumImages] = open(path, _gdwCdStreamFlags);
|
||||
|
||||
// Fix case sensitivity and backslashes.
|
||||
if (gImgFiles[gNumImages] == -1) {
|
||||
char* real = casepath(path, false);
|
||||
if (real)
|
||||
{
|
||||
gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags);
|
||||
free(real);
|
||||
}
|
||||
}
|
||||
|
||||
if ( gImgFiles[gNumImages] == -1 ) {
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
gImgNames[gNumImages] = strdup(path);
|
||||
gImgFiles[gNumImages]++; // because -1: error 0: not used
|
||||
|
||||
strcpy(gCdImageNames[gNumImages], path);
|
||||
|
||||
gNumImages++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *
|
||||
CdStreamGetImageName(int32 cd)
|
||||
{
|
||||
ASSERT(cd < MAX_CDIMAGES);
|
||||
if ( gImgFiles[cd] > 0)
|
||||
return gCdImageNames[cd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
CdStreamRemoveImages(void)
|
||||
{
|
||||
for ( int32 i = 0; i < gNumChannels; i++ ) {
|
||||
#ifdef FLUSHABLE_STREAMING
|
||||
flushStream[i] = 1;
|
||||
#endif
|
||||
CdStreamSync(i);
|
||||
}
|
||||
|
||||
for ( int32 i = 0; i < gNumImages; i++ )
|
||||
{
|
||||
close(gImgFiles[i] - 1);
|
||||
free(gImgNames[i]);
|
||||
gImgFiles[i] = 0;
|
||||
}
|
||||
|
||||
gNumImages = 0;
|
||||
}
|
||||
|
||||
int32
|
||||
CdStreamGetNumImages(void)
|
||||
{
|
||||
return gNumImages;
|
||||
}
|
||||
#endif
|
||||
117
src/core/Clock.cpp
Normal file
117
src/core/Clock.cpp
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Timer.h"
|
||||
#include "Pad.h"
|
||||
#include "Clock.h"
|
||||
#include "Stats.h"
|
||||
|
||||
_TODO("gbFastTime");
|
||||
bool gbFastTime;
|
||||
|
||||
uint8 CClock::ms_nGameClockHours;
|
||||
uint8 CClock::ms_nGameClockMinutes;
|
||||
uint16 CClock::ms_nGameClockSeconds;
|
||||
uint8 CClock::ms_Stored_nGameClockHours;
|
||||
uint8 CClock::ms_Stored_nGameClockMinutes;
|
||||
uint16 CClock::ms_Stored_nGameClockSeconds;
|
||||
uint32 CClock::ms_nMillisecondsPerGameMinute;
|
||||
uint32 CClock::ms_nLastClockTick;
|
||||
bool CClock::ms_bClockHasBeenStored;
|
||||
|
||||
void
|
||||
CClock::Initialise(uint32 scale)
|
||||
{
|
||||
debug("Initialising CClock...\n");
|
||||
ms_nGameClockHours = 12;
|
||||
ms_nGameClockMinutes = 0;
|
||||
ms_nGameClockSeconds = 0;
|
||||
ms_nMillisecondsPerGameMinute = scale;
|
||||
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
|
||||
ms_bClockHasBeenStored = false;
|
||||
debug("CClock ready\n");
|
||||
}
|
||||
|
||||
void
|
||||
CClock::Update(void)
|
||||
{
|
||||
if(CPad::GetPad(1)->GetRightShoulder1())
|
||||
{
|
||||
ms_nGameClockMinutes += 8;
|
||||
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
if(ms_nGameClockMinutes >= 60)
|
||||
{
|
||||
ms_nGameClockHours++;
|
||||
ms_nGameClockMinutes = 0;
|
||||
if(ms_nGameClockHours >= 24)
|
||||
ms_nGameClockHours = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else if(CTimer::GetTimeInMilliseconds() - ms_nLastClockTick > ms_nMillisecondsPerGameMinute || gbFastTime)
|
||||
{
|
||||
ms_nGameClockMinutes++;
|
||||
ms_nLastClockTick += ms_nMillisecondsPerGameMinute;
|
||||
|
||||
if ( gbFastTime )
|
||||
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
if(ms_nGameClockMinutes >= 60)
|
||||
{
|
||||
ms_nGameClockHours++;
|
||||
ms_nGameClockMinutes = 0;
|
||||
if(ms_nGameClockHours >= 24)
|
||||
{
|
||||
CStats::DaysPassed++;
|
||||
ms_nGameClockHours = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ms_nGameClockSeconds = 60 * (CTimer::GetTimeInMilliseconds() - ms_nLastClockTick) / ms_nMillisecondsPerGameMinute;
|
||||
}
|
||||
|
||||
void
|
||||
CClock::SetGameClock(uint8 h, uint8 m)
|
||||
{
|
||||
ms_nGameClockHours = h;
|
||||
ms_nGameClockMinutes = m;
|
||||
ms_nGameClockSeconds = 0;
|
||||
ms_nLastClockTick = CTimer::GetTimeInMilliseconds();
|
||||
}
|
||||
|
||||
int32
|
||||
CClock::GetGameClockMinutesUntil(uint8 h, uint8 m)
|
||||
{
|
||||
int32 now, then;
|
||||
now = ms_nGameClockHours*60 + ms_nGameClockMinutes;
|
||||
then = h*60 + m;
|
||||
if(then < now)
|
||||
then += 24*60;
|
||||
return then-now;
|
||||
}
|
||||
|
||||
bool
|
||||
CClock::GetIsTimeInRange(uint8 h1, uint8 h2)
|
||||
{
|
||||
if(h1 > h2)
|
||||
return ms_nGameClockHours >= h1 || ms_nGameClockHours < h2;
|
||||
else
|
||||
return ms_nGameClockHours >= h1 && ms_nGameClockHours < h2;
|
||||
}
|
||||
|
||||
void
|
||||
CClock::StoreClock(void)
|
||||
{
|
||||
ms_Stored_nGameClockHours = ms_nGameClockHours;
|
||||
ms_Stored_nGameClockMinutes = ms_nGameClockMinutes;
|
||||
ms_Stored_nGameClockSeconds = ms_nGameClockSeconds;
|
||||
ms_bClockHasBeenStored = true;
|
||||
}
|
||||
|
||||
void
|
||||
CClock::RestoreClock(void)
|
||||
{
|
||||
ms_nGameClockHours = ms_Stored_nGameClockHours;
|
||||
ms_nGameClockMinutes = ms_Stored_nGameClockMinutes;
|
||||
ms_nGameClockSeconds = ms_Stored_nGameClockSeconds;
|
||||
}
|
||||
31
src/core/Clock.h
Normal file
31
src/core/Clock.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
class CClock
|
||||
{
|
||||
public:
|
||||
static uint8 ms_nGameClockHours;
|
||||
static uint8 ms_nGameClockMinutes;
|
||||
static uint16 ms_nGameClockSeconds;
|
||||
static uint8 ms_Stored_nGameClockHours;
|
||||
static uint8 ms_Stored_nGameClockMinutes;
|
||||
static uint16 ms_Stored_nGameClockSeconds;
|
||||
static uint32 ms_nMillisecondsPerGameMinute;
|
||||
static uint32 ms_nLastClockTick;
|
||||
static bool ms_bClockHasBeenStored;
|
||||
|
||||
static void Initialise(uint32 scale);
|
||||
static void Update(void);
|
||||
static void SetGameClock(uint8 h, uint8 m);
|
||||
static int32 GetGameClockMinutesUntil(uint8 h, uint8 m);
|
||||
static bool GetIsTimeInRange(uint8 h1, uint8 h2);
|
||||
static void StoreClock(void);
|
||||
static void RestoreClock(void);
|
||||
|
||||
static uint8 GetHours(void) { return ms_nGameClockHours; }
|
||||
static uint8 GetMinutes(void) { return ms_nGameClockMinutes; }
|
||||
static int16 GetSeconds(void) { return ms_nGameClockSeconds; }
|
||||
|
||||
|
||||
static uint8 &GetHoursRef(void) { return ms_nGameClockHours; }
|
||||
static uint8 &GetMinutesRef(void) { return ms_nGameClockMinutes; }
|
||||
};
|
||||
2884
src/core/ControllerConfig.cpp
Normal file
2884
src/core/ControllerConfig.cpp
Normal file
File diff suppressed because it is too large
Load diff
226
src/core/ControllerConfig.h
Normal file
226
src/core/ControllerConfig.h
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
#pragma once
|
||||
|
||||
#if defined RW_D3D9 || defined RWLIBS
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
#endif
|
||||
|
||||
// based on x-gtasa
|
||||
|
||||
enum eControllerType
|
||||
{
|
||||
KEYBOARD = 0,
|
||||
OPTIONAL_EXTRA,
|
||||
MOUSE,
|
||||
JOYSTICK,
|
||||
MAX_CONTROLLERTYPES,
|
||||
};
|
||||
|
||||
enum e_ControllerAction
|
||||
{
|
||||
PED_FIREWEAPON = 0,
|
||||
PED_CYCLE_WEAPON_RIGHT,
|
||||
PED_CYCLE_WEAPON_LEFT,
|
||||
GO_FORWARD,
|
||||
GO_BACK,
|
||||
GO_LEFT,
|
||||
GO_RIGHT,
|
||||
PED_SNIPER_ZOOM_IN,
|
||||
PED_SNIPER_ZOOM_OUT,
|
||||
VEHICLE_ENTER_EXIT,
|
||||
CAMERA_CHANGE_VIEW_ALL_SITUATIONS,
|
||||
PED_JUMPING,
|
||||
PED_SPRINT,
|
||||
PED_LOOKBEHIND,
|
||||
#ifdef BIND_VEHICLE_FIREWEAPON
|
||||
VEHICLE_FIREWEAPON,
|
||||
#endif
|
||||
VEHICLE_ACCELERATE,
|
||||
VEHICLE_BRAKE,
|
||||
VEHICLE_CHANGE_RADIO_STATION,
|
||||
VEHICLE_HORN,
|
||||
TOGGLE_SUBMISSIONS,
|
||||
VEHICLE_HANDBRAKE,
|
||||
PED_1RST_PERSON_LOOK_LEFT,
|
||||
PED_1RST_PERSON_LOOK_RIGHT,
|
||||
VEHICLE_LOOKLEFT,
|
||||
VEHICLE_LOOKRIGHT,
|
||||
VEHICLE_LOOKBEHIND,
|
||||
VEHICLE_TURRETLEFT,
|
||||
VEHICLE_TURRETRIGHT,
|
||||
VEHICLE_TURRETUP,
|
||||
VEHICLE_TURRETDOWN,
|
||||
PED_CYCLE_TARGET_LEFT,
|
||||
PED_CYCLE_TARGET_RIGHT,
|
||||
PED_CENTER_CAMERA_BEHIND_PLAYER,
|
||||
PED_LOCK_TARGET,
|
||||
NETWORK_TALK,
|
||||
PED_1RST_PERSON_LOOK_UP,
|
||||
PED_1RST_PERSON_LOOK_DOWN,
|
||||
_CONTROLLERACTION_36, // Unused
|
||||
TOGGLE_DPAD,
|
||||
SWITCH_DEBUG_CAM_ON,
|
||||
TAKE_SCREEN_SHOT,
|
||||
SHOW_MOUSE_POINTER_TOGGLE,
|
||||
MAX_CONTROLLERACTIONS,
|
||||
};
|
||||
|
||||
enum e_ControllerActionType
|
||||
{
|
||||
ACTIONTYPE_1RSTPERSON = 0,
|
||||
ACTIONTYPE_3RDPERSON,
|
||||
ACTIONTYPE_VEHICLE,
|
||||
ACTIONTYPE_VEHICLE_3RDPERSON,
|
||||
ACTIONTYPE_COMMON,
|
||||
ACTIONTYPE_1RST3RDPERSON,
|
||||
ACTIONTYPE_NONE,
|
||||
};
|
||||
|
||||
enum eContSetOrder
|
||||
{
|
||||
SETORDER_NONE = 0,
|
||||
SETORDER_1,
|
||||
SETORDER_2,
|
||||
SETORDER_3,
|
||||
SETORDER_4,
|
||||
MAX_SETORDERS,
|
||||
};
|
||||
|
||||
enum eSimCheckers
|
||||
{
|
||||
SIM_X1 = 0, SIM_Y1, // DPad
|
||||
SIM_X2, SIM_Y2, // LeftStick
|
||||
|
||||
MAX_SIMS
|
||||
};
|
||||
|
||||
class CMouseControllerState;
|
||||
class CControllerState;
|
||||
|
||||
|
||||
#define JOY_BUTTONS 16
|
||||
#define MAX_BUTTONS (JOY_BUTTONS+1)
|
||||
|
||||
#define ACTIONNAME_LENGTH 40
|
||||
|
||||
#ifdef RW_GL3
|
||||
struct GlfwJoyState {
|
||||
int8 id;
|
||||
bool isGamepad;
|
||||
uint8 numButtons;
|
||||
uint8* buttons;
|
||||
bool mappedButtons[17];
|
||||
};
|
||||
#endif
|
||||
|
||||
class CControllerConfigManager
|
||||
{
|
||||
public:
|
||||
struct tControllerConfigBind
|
||||
{
|
||||
int32 m_Key;
|
||||
int32 m_ContSetOrder;
|
||||
|
||||
tControllerConfigBind()
|
||||
{
|
||||
m_Key = 0;
|
||||
m_ContSetOrder = 0;
|
||||
}
|
||||
};
|
||||
|
||||
bool m_bFirstCapture;
|
||||
#if defined RW_GL3
|
||||
GlfwJoyState m_OldState;
|
||||
GlfwJoyState m_NewState;
|
||||
#else
|
||||
DIJOYSTATE2 m_OldState;
|
||||
DIJOYSTATE2 m_NewState;
|
||||
#endif
|
||||
wchar m_aActionNames[MAX_CONTROLLERACTIONS][ACTIONNAME_LENGTH];
|
||||
bool m_aButtonStates[MAX_BUTTONS];
|
||||
tControllerConfigBind m_aSettings[MAX_CONTROLLERACTIONS][MAX_CONTROLLERTYPES];
|
||||
bool m_aSimCheckers[MAX_SIMS][MAX_CONTROLLERTYPES];
|
||||
bool m_bMouseAssociated;
|
||||
|
||||
#ifdef LOAD_INI_SETTINGS
|
||||
static uint32 ms_padButtonsInited;
|
||||
#endif
|
||||
|
||||
CControllerConfigManager();
|
||||
|
||||
void MakeControllerActionsBlank();
|
||||
|
||||
int32 GetJoyButtonJustDown();
|
||||
|
||||
void SaveSettings(int32 file);
|
||||
void LoadSettings(int32 file);
|
||||
|
||||
void InitDefaultControlConfiguration();
|
||||
void InitDefaultControlConfigMouse(CMouseControllerState const &availableButtons);
|
||||
void InitDefaultControlConfigJoyPad(uint32 buttons);
|
||||
void InitialiseControllerActionNameArray();
|
||||
|
||||
void UpdateJoyInConfigMenus_ButtonDown (int32 button, int32 padnumber);
|
||||
void AffectControllerStateOn_ButtonDown (int32 button, eControllerType type);
|
||||
void AffectControllerStateOn_ButtonDown_Driving (int32 button, eControllerType type, CControllerState &state);
|
||||
void AffectControllerStateOn_ButtonDown_FirstPersonOnly (int32 button, eControllerType type, CControllerState &state);
|
||||
void AffectControllerStateOn_ButtonDown_ThirdPersonOnly (int32 button, eControllerType type, CControllerState &state);
|
||||
void AffectControllerStateOn_ButtonDown_FirstAndThirdPersonOnly (int32 button, eControllerType type, CControllerState &state);
|
||||
void AffectControllerStateOn_ButtonDown_AllStates (int32 button, eControllerType type, CControllerState &state);
|
||||
void AffectControllerStateOn_ButtonDown_VehicleAndThirdPersonOnly(int32 button, eControllerType type, CControllerState &state);
|
||||
|
||||
void UpdateJoyInConfigMenus_ButtonUp(int32 button, int32 padnumber);
|
||||
void AffectControllerStateOn_ButtonUp(int32 button, eControllerType type);
|
||||
void AffectControllerStateOn_ButtonUp_All_Player_States(int32 button, eControllerType type, CControllerState &state);
|
||||
|
||||
void AffectPadFromKeyBoard();
|
||||
void AffectPadFromMouse();
|
||||
|
||||
void ClearSimButtonPressCheckers();
|
||||
|
||||
bool GetIsKeyboardKeyDown (RsKeyCodes keycode);
|
||||
bool GetIsKeyboardKeyJustDown(RsKeyCodes keycode);
|
||||
bool GetIsMouseButtonDown (RsKeyCodes keycode);
|
||||
bool GetIsMouseButtonUp (RsKeyCodes keycode);
|
||||
|
||||
|
||||
void DeleteMatchingCommonControls (e_ControllerAction action, int32 key, eControllerType type);
|
||||
void DeleteMatching3rdPersonControls (e_ControllerAction action, int32 key, eControllerType type);
|
||||
void DeleteMatching1rst3rdPersonControls (e_ControllerAction action, int32 key, eControllerType type);
|
||||
void DeleteMatchingVehicleControls (e_ControllerAction action, int32 key, eControllerType type);
|
||||
void DeleteMatchingVehicle_3rdPersonControls(e_ControllerAction action, int32 key, eControllerType type);
|
||||
void DeleteMatching1rstPersonControls (e_ControllerAction action, int32 key, eControllerType type);
|
||||
void DeleteMatchingActionInitiators (e_ControllerAction action, int32 key, eControllerType type);
|
||||
|
||||
#ifdef RADIO_SCROLL_TO_PREV_STATION
|
||||
bool IsAnyVehicleActionAssignedToMouseKey(int32 key);
|
||||
#endif
|
||||
|
||||
bool GetIsKeyBlank(int32 key, eControllerType type);
|
||||
e_ControllerActionType GetActionType(e_ControllerAction action);
|
||||
|
||||
void ClearSettingsAssociatedWithAction (e_ControllerAction action, eControllerType type);
|
||||
wchar *GetControllerSettingTextWithOrderNumber(e_ControllerAction action, eContSetOrder setorder);
|
||||
wchar *GetControllerSettingTextKeyBoard (e_ControllerAction action, eControllerType type);
|
||||
wchar *GetControllerSettingTextMouse (e_ControllerAction action);
|
||||
wchar *GetControllerSettingTextJoystick (e_ControllerAction action);
|
||||
|
||||
int32 GetNumOfSettingsForAction(e_ControllerAction action);
|
||||
void GetWideStringOfCommandKeys(uint16 action, wchar *text, uint16 leight);
|
||||
int32 GetControllerKeyAssociatedWithAction(e_ControllerAction action, eControllerType type);
|
||||
|
||||
void UpdateJoyButtonState(int32 padnumber);
|
||||
|
||||
bool GetIsActionAButtonCombo (e_ControllerAction action);
|
||||
wchar *GetButtonComboText (e_ControllerAction action);
|
||||
void SetControllerKeyAssociatedWithAction(e_ControllerAction action, int32 key, eControllerType type);
|
||||
int32 GetMouseButtonAssociatedWithAction (e_ControllerAction action);
|
||||
void SetMouseButtonAssociatedWithAction (e_ControllerAction action, int32 button);
|
||||
void ResetSettingOrder (e_ControllerAction action);
|
||||
};
|
||||
|
||||
#ifndef RW_GL3
|
||||
VALIDATE_SIZE(CControllerConfigManager, 0x143C);
|
||||
#endif
|
||||
|
||||
extern CControllerConfigManager ControlsManager;
|
||||
36
src/core/Crime.h
Normal file
36
src/core/Crime.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
enum eCrimeType {
|
||||
CRIME_NONE,
|
||||
CRIME_POSSESSION_GUN,
|
||||
CRIME_HIT_PED,
|
||||
CRIME_HIT_COP,
|
||||
CRIME_SHOOT_PED,
|
||||
CRIME_SHOOT_COP,
|
||||
CRIME_STEAL_CAR,
|
||||
CRIME_RUN_REDLIGHT,
|
||||
CRIME_RECKLESS_DRIVING,
|
||||
CRIME_SPEEDING,
|
||||
CRIME_RUNOVER_PED,
|
||||
CRIME_RUNOVER_COP,
|
||||
CRIME_SHOOT_HELI,
|
||||
CRIME_PED_BURNED,
|
||||
CRIME_COP_BURNED,
|
||||
CRIME_VEHICLE_BURNED,
|
||||
CRIME_DESTROYED_CESSNA,
|
||||
NUM_CRIME_TYPES
|
||||
};
|
||||
|
||||
class CCrimeBeingQd
|
||||
{
|
||||
public:
|
||||
eCrimeType m_nType;
|
||||
int32 m_nId;
|
||||
uint32 m_nTime;
|
||||
CVector m_vecPosn;
|
||||
bool m_bReported;
|
||||
bool m_bPoliceDoesntCare;
|
||||
|
||||
CCrimeBeingQd() { };
|
||||
~CCrimeBeingQd() { };
|
||||
};
|
||||
170
src/core/Debug.cpp
Normal file
170
src/core/Debug.cpp
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#include "common.h"
|
||||
#include "RwHelper.h"
|
||||
#include "Debug.h"
|
||||
#include "Lines.h"
|
||||
#include "Font.h"
|
||||
#include "main.h"
|
||||
#include "Text.h"
|
||||
|
||||
bool gbDebugStuffInRelease = false;
|
||||
|
||||
#define DEBUG_X_POS (300)
|
||||
#define DEBUG_Y_POS (41)
|
||||
#define DEBUG_LINE_HEIGHT (22)
|
||||
|
||||
int16 CDebug::ms_nCurrentTextLine;
|
||||
char CDebug::ms_aTextBuffer[MAX_LINES][MAX_STR_LEN];
|
||||
|
||||
void
|
||||
CDebug::DebugInitTextBuffer()
|
||||
{
|
||||
ms_nCurrentTextLine = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CDebug::DebugAddText(const char *str)
|
||||
{
|
||||
int32 i = 0;
|
||||
if (*str != '\0') {
|
||||
while (i < MAX_STR_LEN - 1) {
|
||||
ms_aTextBuffer[ms_nCurrentTextLine][i++] = *(str++);
|
||||
if (*str == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ms_aTextBuffer[ms_nCurrentTextLine++][i] = '\0';
|
||||
if (ms_nCurrentTextLine >= MAX_LINES)
|
||||
ms_nCurrentTextLine = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CDebug::DebugDisplayTextBuffer()
|
||||
{
|
||||
#ifndef MASTER
|
||||
if (gbDebugStuffInRelease)
|
||||
{
|
||||
int32 i = 0;
|
||||
int32 y = DEBUG_Y_POS;
|
||||
#ifdef FIX_BUGS
|
||||
CFont::SetPropOn();
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetScale(1.0f, 1.0f);
|
||||
CFont::SetCentreOff();
|
||||
CFont::SetRightJustifyOff();
|
||||
CFont::SetJustifyOn();
|
||||
CFont::SetRightJustifyWrap(0.0f);
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
#else
|
||||
// this is not even readable
|
||||
CFont::SetPropOff();
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetScale(1.0f, 1.0f);
|
||||
CFont::SetCentreOff();
|
||||
CFont::SetRightJustifyOn();
|
||||
CFont::SetRightJustifyWrap(0.0f);
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
CFont::SetPropOff();
|
||||
#endif
|
||||
do {
|
||||
char *line;
|
||||
while (true) {
|
||||
line = ms_aTextBuffer[(ms_nCurrentTextLine + i++) % MAX_LINES];
|
||||
if (*line != '\0')
|
||||
break;
|
||||
y += DEBUG_LINE_HEIGHT;
|
||||
if (i == MAX_LINES) {
|
||||
CFont::DrawFonts();
|
||||
return;
|
||||
}
|
||||
}
|
||||
AsciiToUnicode(line, gUString);
|
||||
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
||||
CFont::PrintString(DEBUG_X_POS, y-1, gUString);
|
||||
CFont::SetColor(CRGBA(255, 128, 128, 255));
|
||||
CFont::PrintString(DEBUG_X_POS+1, y, gUString);
|
||||
y += DEBUG_LINE_HEIGHT;
|
||||
} while (i != MAX_LINES);
|
||||
CFont::DrawFonts();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// custom
|
||||
|
||||
CDebug::ScreenStr CDebug::ms_aScreenStrs[MAX_SCREEN_STRS];
|
||||
int CDebug::ms_nScreenStrs;
|
||||
|
||||
void
|
||||
CDebug::DisplayScreenStrings()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
CFont::SetPropOn();
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetScale(1.0f, 1.0f);
|
||||
CFont::SetCentreOff();
|
||||
CFont::SetRightJustifyOff();
|
||||
CFont::SetJustifyOff();
|
||||
CFont::SetRightJustifyWrap(0.0f);
|
||||
CFont::SetWrapx(9999.0f);
|
||||
CFont::SetBackGroundOnlyTextOff();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
|
||||
for(i = 0; i < ms_nScreenStrs; i++){
|
||||
/*
|
||||
AsciiToUnicode(ms_aScreenStrs[i].str, gUString);
|
||||
CFont::SetColor(CRGBA(0, 0, 0, 255));
|
||||
CFont::PrintString(ms_aScreenStrs[i].x, ms_aScreenStrs[i].y, gUString);
|
||||
CFont::SetColor(CRGBA(255, 255, 255, 255));
|
||||
CFont::PrintString(ms_aScreenStrs[i].x+1, ms_aScreenStrs[i].y+1, gUString);
|
||||
*/
|
||||
ObrsPrintfString(ms_aScreenStrs[i].str, ms_aScreenStrs[i].x, ms_aScreenStrs[i].y);
|
||||
}
|
||||
CFont::DrawFonts();
|
||||
|
||||
ms_nScreenStrs = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CDebug::PrintAt(const char *str, int x, int y)
|
||||
{
|
||||
if(ms_nScreenStrs >= MAX_SCREEN_STRS)
|
||||
return;
|
||||
strncpy(ms_aScreenStrs[ms_nScreenStrs].str, str, 256);
|
||||
ms_aScreenStrs[ms_nScreenStrs].x = x;//*12;
|
||||
ms_aScreenStrs[ms_nScreenStrs].y = y;//*22;
|
||||
ms_nScreenStrs++;
|
||||
}
|
||||
|
||||
CDebug::Line CDebug::ms_aLines[MAX_DEBUG_LINES];
|
||||
int CDebug::ms_nLines;
|
||||
|
||||
void
|
||||
CDebug::AddLine(CVector p1, CVector p2, uint32 c1, uint32 c2)
|
||||
{
|
||||
if(ms_nLines >= MAX_DEBUG_LINES)
|
||||
return;
|
||||
ms_aLines[ms_nLines].p1 = p1;
|
||||
ms_aLines[ms_nLines].p2 = p2;
|
||||
ms_aLines[ms_nLines].c1 = c1;
|
||||
ms_aLines[ms_nLines].c2 = c2;
|
||||
ms_nLines++;
|
||||
}
|
||||
|
||||
void
|
||||
CDebug::DrawLines(void)
|
||||
{
|
||||
int i;
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
|
||||
for(i = 0; i < ms_nLines; i++){
|
||||
Line *l = &ms_aLines[i];
|
||||
CLines::RenderLineWithClipping(l->p1.x, l->p1.y, l->p1.z, l->p2.x, l->p2.y, l->p2.z, l->c1, l->c2);
|
||||
}
|
||||
ms_nLines = 0;
|
||||
}
|
||||
45
src/core/Debug.h
Normal file
45
src/core/Debug.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
class CDebug
|
||||
{
|
||||
enum
|
||||
{
|
||||
MAX_LINES = 15,
|
||||
MAX_STR_LEN = 80,
|
||||
|
||||
MAX_SCREEN_STRS = 100,
|
||||
MAX_DEBUG_LINES = 100,
|
||||
};
|
||||
|
||||
static int16 ms_nCurrentTextLine;
|
||||
static char ms_aTextBuffer[MAX_LINES][MAX_STR_LEN];
|
||||
|
||||
// custom
|
||||
struct ScreenStr {
|
||||
int x, y;
|
||||
char str[256];
|
||||
};
|
||||
static ScreenStr ms_aScreenStrs[MAX_SCREEN_STRS];
|
||||
static int ms_nScreenStrs;
|
||||
|
||||
struct Line {
|
||||
CVector p1, p2;
|
||||
uint32 c1, c2;
|
||||
};
|
||||
static Line ms_aLines[MAX_DEBUG_LINES];
|
||||
static int ms_nLines;
|
||||
|
||||
public:
|
||||
static void DebugInitTextBuffer();
|
||||
static void DebugDisplayTextBuffer();
|
||||
static void DebugAddText(const char *str);
|
||||
|
||||
// custom
|
||||
static void PrintAt(const char *str, int x, int y);
|
||||
static void DisplayScreenStrings();
|
||||
|
||||
static void AddLine(CVector p1, CVector p2, uint32 c1, uint32 c2);
|
||||
static void DrawLines(void);
|
||||
};
|
||||
|
||||
extern bool gbDebugStuffInRelease;
|
||||
74
src/core/Directory.cpp
Normal file
74
src/core/Directory.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "General.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Directory.h"
|
||||
|
||||
CDirectory::CDirectory(int32 maxEntries)
|
||||
: numEntries(0), maxEntries(maxEntries)
|
||||
{
|
||||
entries = new DirectoryInfo[maxEntries];
|
||||
}
|
||||
|
||||
CDirectory::~CDirectory(void)
|
||||
{
|
||||
delete[] entries;
|
||||
}
|
||||
|
||||
void
|
||||
CDirectory::ReadDirFile(const char *filename)
|
||||
{
|
||||
int fd;
|
||||
DirectoryInfo dirinfo;
|
||||
|
||||
fd = CFileMgr::OpenFile(filename, "rb");
|
||||
while(CFileMgr::Read(fd, (char*)&dirinfo, sizeof(dirinfo)))
|
||||
AddItem(dirinfo);
|
||||
CFileMgr::CloseFile(fd);
|
||||
}
|
||||
|
||||
bool
|
||||
CDirectory::WriteDirFile(const char *filename)
|
||||
{
|
||||
int fd;
|
||||
size_t n;
|
||||
fd = CFileMgr::OpenFileForWriting(filename);
|
||||
n = CFileMgr::Write(fd, (char*)entries, numEntries*sizeof(DirectoryInfo));
|
||||
CFileMgr::CloseFile(fd);
|
||||
return n == numEntries*sizeof(DirectoryInfo);
|
||||
}
|
||||
|
||||
void
|
||||
CDirectory::AddItem(const DirectoryInfo &dirinfo)
|
||||
{
|
||||
assert(numEntries < maxEntries);
|
||||
#ifdef FIX_BUGS
|
||||
// don't add if already exists
|
||||
uint32 offset, size;
|
||||
if(FindItem(dirinfo.name, offset, size))
|
||||
return;
|
||||
#endif
|
||||
entries[numEntries++] = dirinfo;
|
||||
}
|
||||
|
||||
void
|
||||
CDirectory::AddItem(const DirectoryInfo &dirinfo, int32 imgId)
|
||||
{
|
||||
DirectoryInfo di = dirinfo;
|
||||
di.offset |= imgId<<24;
|
||||
AddItem(di);
|
||||
}
|
||||
|
||||
bool
|
||||
CDirectory::FindItem(const char *name, uint32 &offset, uint32 &size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < numEntries; i++)
|
||||
if(!CGeneral::faststricmp(entries[i].name, name)){
|
||||
offset = entries[i].offset;
|
||||
size = entries[i].size;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
23
src/core/Directory.h
Normal file
23
src/core/Directory.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
class CDirectory
|
||||
{
|
||||
public:
|
||||
struct DirectoryInfo {
|
||||
uint32 offset;
|
||||
uint32 size;
|
||||
char name[24];
|
||||
};
|
||||
DirectoryInfo *entries;
|
||||
int32 maxEntries;
|
||||
int32 numEntries;
|
||||
|
||||
CDirectory(int32 maxEntries);
|
||||
~CDirectory(void);
|
||||
|
||||
void ReadDirFile(const char *filename);
|
||||
bool WriteDirFile(const char *filename);
|
||||
void AddItem(const DirectoryInfo &dirinfo);
|
||||
void AddItem(const DirectoryInfo &dirinfo, int32 imgId);
|
||||
bool FindItem(const char *name, uint32 &offset, uint32 &size);
|
||||
};
|
||||
237
src/core/EventList.cpp
Normal file
237
src/core/EventList.cpp
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Pools.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "World.h"
|
||||
#include "Wanted.h"
|
||||
#include "EventList.h"
|
||||
#include "Messages.h"
|
||||
#include "Text.h"
|
||||
#include "main.h"
|
||||
#include "Accident.h"
|
||||
|
||||
int32 CEventList::ms_nFirstFreeSlotIndex;
|
||||
CEvent gaEvent[NUMEVENTS];
|
||||
|
||||
enum
|
||||
{
|
||||
EVENT_STATE_0,
|
||||
EVENT_STATE_CANDELETE,
|
||||
EVENT_STATE_CLEAR,
|
||||
};
|
||||
|
||||
void
|
||||
CEventList::Initialise(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
debug("Initialising CEventList...");
|
||||
for(i = 0; i < NUMEVENTS; i++){
|
||||
gaEvent[i].type = EVENT_NULL;
|
||||
gaEvent[i].entityType = EVENT_ENTITY_NONE;
|
||||
gaEvent[i].entityRef = 0;
|
||||
gaEvent[i].posn.x = 0.0f;
|
||||
gaEvent[i].posn.y = 0.0f;
|
||||
gaEvent[i].posn.z = 0.0f;
|
||||
gaEvent[i].timeout = 0;
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
ms_nFirstFreeSlotIndex = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::Update(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
ms_nFirstFreeSlotIndex = 0;
|
||||
for(i = 0; i < NUMEVENTS; i++){
|
||||
if(gaEvent[i].type == EVENT_NULL)
|
||||
continue;
|
||||
if(CTimer::GetTimeInMilliseconds() > gaEvent[i].timeout || gaEvent[i].state == EVENT_STATE_CANDELETE){
|
||||
gaEvent[i].type = EVENT_NULL;
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
if(gaEvent[i].state == EVENT_STATE_CLEAR)
|
||||
gaEvent[i].state = EVENT_STATE_CANDELETE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout)
|
||||
{
|
||||
int i;
|
||||
int ref;
|
||||
bool copsDontCare;
|
||||
|
||||
#ifdef SQUEEZE_PERFORMANCE
|
||||
if (type == EVENT_INJURED_PED) {
|
||||
gAccidentManager.ReportAccident((CPed*)ent);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
copsDontCare = false;
|
||||
switch(entityType){
|
||||
case EVENT_ENTITY_PED:
|
||||
ref = CPools::GetPedRef((CPed*)ent);
|
||||
if(ent->GetModelIndex() >= MI_GANG01 && ent->GetModelIndex() <= MI_CRIMINAL02)
|
||||
copsDontCare = true;
|
||||
break;
|
||||
case EVENT_ENTITY_VEHICLE:
|
||||
ref = CPools::GetVehicleRef((CVehicle*)ent);
|
||||
break;
|
||||
case EVENT_ENTITY_OBJECT:
|
||||
ref = CPools::GetObjectRef((CObject*)ent);
|
||||
break;
|
||||
default:
|
||||
Error("Undefined entity type, RegisterEvent, EventList.cpp");
|
||||
ref = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// only update time if event exists already
|
||||
for(i = 0; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == type &&
|
||||
gaEvent[i].entityType == entityType &&
|
||||
gaEvent[i].entityRef == ref){
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = ms_nFirstFreeSlotIndex; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == EVENT_NULL){
|
||||
ms_nFirstFreeSlotIndex = i;
|
||||
break;
|
||||
}
|
||||
if(i < NUMEVENTS){
|
||||
gaEvent[i].type = type;
|
||||
gaEvent[i].entityType = entityType;
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
gaEvent[i].entityRef = ref;
|
||||
gaEvent[i].posn = ent->GetPosition();
|
||||
gaEvent[i].criminal = criminal;
|
||||
if(gaEvent[i].criminal)
|
||||
gaEvent[i].criminal->RegisterReference((CEntity**)&gaEvent[i].criminal);
|
||||
if(type == EVENT_GUNSHOT)
|
||||
gaEvent[i].state = EVENT_STATE_CLEAR;
|
||||
else
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
|
||||
if(criminal == FindPlayerPed())
|
||||
ReportCrimeForEvent(type, (intptr)ent, copsDontCare);
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::RegisterEvent(eEventType type, CVector posn, int32 timeout)
|
||||
{
|
||||
int i;
|
||||
|
||||
// only update time if event exists already
|
||||
for(i = 0; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == type &&
|
||||
gaEvent[i].posn.x == posn.x &&
|
||||
gaEvent[i].posn.y == posn.y &&
|
||||
gaEvent[i].posn.z == posn.z &&
|
||||
gaEvent[i].entityType == EVENT_ENTITY_NONE){
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = ms_nFirstFreeSlotIndex; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == EVENT_NULL){
|
||||
ms_nFirstFreeSlotIndex = i;
|
||||
break;
|
||||
}
|
||||
if(i < NUMEVENTS){
|
||||
gaEvent[i].type = type;
|
||||
gaEvent[i].entityType = EVENT_ENTITY_NONE;
|
||||
gaEvent[i].timeout = CTimer::GetTimeInMilliseconds() + timeout;
|
||||
gaEvent[i].posn = posn;
|
||||
gaEvent[i].entityRef = 0;
|
||||
if(type == EVENT_GUNSHOT)
|
||||
gaEvent[i].state = EVENT_STATE_CLEAR;
|
||||
else
|
||||
gaEvent[i].state = EVENT_STATE_0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CEventList::GetEvent(eEventType type, int32 *event)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMEVENTS; i++)
|
||||
if(gaEvent[i].type == type){
|
||||
*event = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::ClearEvent(int32 event)
|
||||
{
|
||||
if(gaEvent[event].state != EVENT_STATE_CANDELETE)
|
||||
gaEvent[event].state = EVENT_STATE_CLEAR;
|
||||
}
|
||||
|
||||
bool
|
||||
CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event)
|
||||
{
|
||||
int i;
|
||||
float dist;
|
||||
bool found = false;
|
||||
float mindist = 60.0f;
|
||||
|
||||
for(i = 0; i < NUMEVENTS; i++){
|
||||
if(gaEvent[i].type != type)
|
||||
continue;
|
||||
dist = (posn - gaEvent[i].posn).Magnitude();
|
||||
if(dist < mindist){
|
||||
mindist = dist;
|
||||
found = true;
|
||||
*event = i;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void
|
||||
CEventList::ReportCrimeForEvent(eEventType type, intptr crimeId, bool copsDontCare)
|
||||
{
|
||||
eCrimeType crime;
|
||||
switch(type){
|
||||
case EVENT_ASSAULT: crime = CRIME_HIT_PED; break;
|
||||
case EVENT_RUN_REDLIGHT: crime = CRIME_RUN_REDLIGHT; break;
|
||||
case EVENT_ASSAULT_POLICE: crime = CRIME_HIT_COP; break;
|
||||
case EVENT_GUNSHOT: crime = CRIME_POSSESSION_GUN; break;
|
||||
case EVENT_STEAL_CAR: crime = CRIME_STEAL_CAR; break;
|
||||
case EVENT_HIT_AND_RUN: crime = CRIME_RUNOVER_PED; break;
|
||||
case EVENT_HIT_AND_RUN_COP: crime = CRIME_RUNOVER_COP; break;
|
||||
case EVENT_SHOOT_PED: crime = CRIME_SHOOT_PED; break;
|
||||
case EVENT_SHOOT_COP: crime = CRIME_SHOOT_COP; break;
|
||||
case EVENT_PED_SET_ON_FIRE: crime = CRIME_PED_BURNED; break;
|
||||
case EVENT_COP_SET_ON_FIRE: crime = CRIME_COP_BURNED; break;
|
||||
case EVENT_CAR_SET_ON_FIRE: crime = CRIME_VEHICLE_BURNED; break;
|
||||
default: crime = CRIME_NONE; break;
|
||||
}
|
||||
|
||||
if(crime == CRIME_NONE)
|
||||
return;
|
||||
|
||||
CVector playerPedCoors = FindPlayerPed()->GetPosition();
|
||||
CVector playerCoors = FindPlayerCoors();
|
||||
|
||||
if(CWanted::WorkOutPolicePresence(playerCoors, 14.0f) != 0){
|
||||
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(crime, playerPedCoors, crimeId, copsDontCare);
|
||||
FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
|
||||
}else
|
||||
FindPlayerPed()->m_pWanted->RegisterCrime(crime, playerPedCoors, crimeId, copsDontCare);
|
||||
|
||||
if(type == EVENT_ASSAULT_POLICE)
|
||||
FindPlayerPed()->SetWantedLevelNoDrop(1);
|
||||
if(type == EVENT_SHOOT_COP)
|
||||
FindPlayerPed()->SetWantedLevelNoDrop(2);
|
||||
|
||||
}
|
||||
65
src/core/EventList.h
Normal file
65
src/core/EventList.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
class CPed;
|
||||
|
||||
enum eEventType
|
||||
{
|
||||
EVENT_NULL,
|
||||
EVENT_ASSAULT,
|
||||
EVENT_RUN_REDLIGHT,
|
||||
EVENT_ASSAULT_POLICE,
|
||||
EVENT_GUNSHOT,
|
||||
EVENT_INJURED_PED,
|
||||
EVENT_DEAD_PED,
|
||||
EVENT_FIRE,
|
||||
EVENT_STEAL_CAR,
|
||||
EVENT_HIT_AND_RUN,
|
||||
EVENT_HIT_AND_RUN_COP,
|
||||
EVENT_SHOOT_PED,
|
||||
EVENT_SHOOT_COP,
|
||||
EVENT_EXPLOSION,
|
||||
EVENT_PED_SET_ON_FIRE,
|
||||
EVENT_COP_SET_ON_FIRE,
|
||||
EVENT_CAR_SET_ON_FIRE,
|
||||
EVENT_ASSAULT_NASTYWEAPON, // not sure
|
||||
EVENT_ICECREAM,
|
||||
EVENT_ATM,
|
||||
EVENT_SHOPSTALL, // used on graffitis
|
||||
EVENT_LAST_EVENT
|
||||
};
|
||||
|
||||
enum eEventEntity
|
||||
{
|
||||
EVENT_ENTITY_NONE,
|
||||
EVENT_ENTITY_PED,
|
||||
EVENT_ENTITY_VEHICLE,
|
||||
EVENT_ENTITY_OBJECT
|
||||
};
|
||||
|
||||
struct CEvent
|
||||
{
|
||||
eEventType type;
|
||||
eEventEntity entityType;
|
||||
int32 entityRef;
|
||||
CPed *criminal;
|
||||
CVector posn;
|
||||
uint32 timeout;
|
||||
int32 state;
|
||||
};
|
||||
|
||||
class CEventList
|
||||
{
|
||||
static int32 ms_nFirstFreeSlotIndex;
|
||||
public:
|
||||
static void Initialise(void);
|
||||
static void Update(void);
|
||||
static void RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout);
|
||||
static void RegisterEvent(eEventType type, CVector posn, int32 timeout);
|
||||
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, intptr, bool);
|
||||
};
|
||||
|
||||
extern CEvent gaEvent[NUMEVENTS];
|
||||
1852
src/core/FileLoader.cpp
Normal file
1852
src/core/FileLoader.cpp
Normal file
File diff suppressed because it is too large
Load diff
49
src/core/FileLoader.h
Normal file
49
src/core/FileLoader.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
class CFileLoader
|
||||
{
|
||||
static char ms_line[256];
|
||||
public:
|
||||
static void LoadLevel(const char *filename);
|
||||
static void LoadCollisionFromDatFile(int currlevel);
|
||||
static char *LoadLine(int fd);
|
||||
static RwTexDictionary *LoadTexDictionary(const char *filename);
|
||||
static void LoadCollisionFile(const char *filename);
|
||||
static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name);
|
||||
static void LoadModelFile(const char *filename);
|
||||
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
|
||||
static void LoadClumpFile(const char *filename);
|
||||
static bool LoadClumpFile(RwStream *stream, uint32 id);
|
||||
static bool StartLoadClumpFile(RwStream *stream, uint32 id);
|
||||
static bool FinishLoadClumpFile(RwStream *stream, uint32 id);
|
||||
static bool LoadAtomicFile(RwStream *stream, uint32 id);
|
||||
static RpAtomic *SetRelatedModelInfoCB(RpAtomic *atomic, void *data);
|
||||
static RpClump *LoadAtomicFile2Return(const char *filename);
|
||||
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
|
||||
|
||||
static void LoadObjectTypes(const char *filename);
|
||||
static void LoadObject(const char *line);
|
||||
static int LoadMLO(const char *line);
|
||||
static void LoadMLOInstance(int id, const char *line);
|
||||
static void LoadTimeObject(const char *line);
|
||||
static void LoadClumpObject(const char *line);
|
||||
static void LoadVehicleObject(const char *line);
|
||||
static void LoadPedObject(const char *line);
|
||||
static int LoadPathHeader(const char *line, char *type);
|
||||
static void LoadPedPathNode(const char *line, int id, int node);
|
||||
static void LoadCarPathNode(const char *line, int id, int node);
|
||||
static void Load2dEffect(const char *line);
|
||||
|
||||
static void LoadScene(const char *filename);
|
||||
static void LoadObjectInstance(const char *line);
|
||||
static void LoadZone(const char *line);
|
||||
static void LoadCullZone(const char *line);
|
||||
static void LoadPickup(const char *line);
|
||||
|
||||
static void LoadMapZones(const char *filename);
|
||||
|
||||
static void ReloadPaths(const char *filename);
|
||||
static void ReloadObjectTypes(const char *filename);
|
||||
static void ReloadObject(const char *line);
|
||||
static void ReLoadScene(const char *filename); // unused mobile function
|
||||
};
|
||||
313
src/core/FileMgr.cpp
Normal file
313
src/core/FileMgr.cpp
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "crossplatform.h"
|
||||
|
||||
#include "FileMgr.h"
|
||||
|
||||
const char *_psGetUserFilesFolder();
|
||||
|
||||
/*
|
||||
* Windows FILE is BROKEN for GTA.
|
||||
*
|
||||
* We need to support mapping between LF and CRLF for text files
|
||||
* but we do NOT want to end the file at the first sight of a SUB character.
|
||||
* So here is a simple implementation of a FILE interface that works like GTA expects.
|
||||
*/
|
||||
|
||||
struct myFILE
|
||||
{
|
||||
bool isText;
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
#define NUMFILES 20
|
||||
static myFILE myfiles[NUMFILES];
|
||||
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#define _getcwd getcwd
|
||||
|
||||
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
|
||||
void mychdir(char const *path)
|
||||
{
|
||||
char* r = casepath(path, false);
|
||||
if (r) {
|
||||
chdir(r);
|
||||
free(r);
|
||||
} else {
|
||||
errno = ENOENT;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define mychdir chdir
|
||||
#endif
|
||||
|
||||
/* Force file to open as binary but remember if it was text mode */
|
||||
static int
|
||||
myfopen(const char *filename, const char *mode)
|
||||
{
|
||||
int fd;
|
||||
char realmode[10], *p;
|
||||
|
||||
for(fd = 1; fd < NUMFILES; fd++)
|
||||
if(myfiles[fd].file == nil)
|
||||
goto found;
|
||||
return 0; // no free fd
|
||||
found:
|
||||
myfiles[fd].isText = strchr(mode, 'b') == nil;
|
||||
p = realmode;
|
||||
while(*mode)
|
||||
if(*mode != 't' && *mode != 'b')
|
||||
*p++ = *mode++;
|
||||
else
|
||||
mode++;
|
||||
*p++ = 'b';
|
||||
*p = '\0';
|
||||
|
||||
myfiles[fd].file = fcaseopen(filename, realmode);
|
||||
if(myfiles[fd].file == nil)
|
||||
return 0;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int
|
||||
myfclose(int fd)
|
||||
{
|
||||
int ret;
|
||||
assert(fd < NUMFILES);
|
||||
if(myfiles[fd].file){
|
||||
ret = fclose(myfiles[fd].file);
|
||||
myfiles[fd].file = nil;
|
||||
return ret;
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static int
|
||||
myfgetc(int fd)
|
||||
{
|
||||
int c;
|
||||
c = fgetc(myfiles[fd].file);
|
||||
if(myfiles[fd].isText && c == 015){
|
||||
/* translate CRLF to LF */
|
||||
c = fgetc(myfiles[fd].file);
|
||||
if(c == 012)
|
||||
return c;
|
||||
ungetc(c, myfiles[fd].file);
|
||||
return 015;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static int
|
||||
myfputc(int c, int fd)
|
||||
{
|
||||
/* translate LF to CRLF */
|
||||
if(myfiles[fd].isText && c == 012)
|
||||
fputc(015, myfiles[fd].file);
|
||||
return fputc(c, myfiles[fd].file);
|
||||
}
|
||||
|
||||
static char*
|
||||
myfgets(char *buf, int len, int fd)
|
||||
{
|
||||
int c;
|
||||
char *p;
|
||||
|
||||
p = buf;
|
||||
len--; // NUL byte
|
||||
while(len--){
|
||||
c = myfgetc(fd);
|
||||
if(c == EOF){
|
||||
if(p == buf)
|
||||
return nil;
|
||||
break;
|
||||
}
|
||||
*p++ = c;
|
||||
if(c == '\n')
|
||||
break;
|
||||
}
|
||||
*p = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
static size_t
|
||||
myfread(void *buf, size_t elt, size_t n, int fd)
|
||||
{
|
||||
if(myfiles[fd].isText){
|
||||
unsigned char *p;
|
||||
size_t i;
|
||||
int c;
|
||||
|
||||
n *= elt;
|
||||
p = (unsigned char*)buf;
|
||||
for(i = 0; i < n; i++){
|
||||
c = myfgetc(fd);
|
||||
if(c == EOF)
|
||||
break;
|
||||
*p++ = (unsigned char)c;
|
||||
}
|
||||
return i / elt;
|
||||
}
|
||||
return fread(buf, elt, n, myfiles[fd].file);
|
||||
}
|
||||
|
||||
static size_t
|
||||
myfwrite(void *buf, size_t elt, size_t n, int fd)
|
||||
{
|
||||
if(myfiles[fd].isText){
|
||||
unsigned char *p;
|
||||
size_t i;
|
||||
int c;
|
||||
|
||||
n *= elt;
|
||||
p = (unsigned char*)buf;
|
||||
for(i = 0; i < n; i++){
|
||||
c = *p++;
|
||||
myfputc(c, fd);
|
||||
if(feof(myfiles[fd].file)) // is this right?
|
||||
break;
|
||||
}
|
||||
return i / elt;
|
||||
}
|
||||
return fwrite(buf, elt, n, myfiles[fd].file);
|
||||
}
|
||||
|
||||
static int
|
||||
myfseek(int fd, long offset, int whence)
|
||||
{
|
||||
return fseek(myfiles[fd].file, offset, whence);
|
||||
}
|
||||
|
||||
static int
|
||||
myfeof(int fd)
|
||||
{
|
||||
return feof(myfiles[fd].file);
|
||||
// return ferror(myfiles[fd].file);
|
||||
}
|
||||
|
||||
|
||||
char CFileMgr::ms_rootDirName[128] = {'\0'};
|
||||
char CFileMgr::ms_dirName[128];
|
||||
|
||||
void
|
||||
CFileMgr::Initialise(void)
|
||||
{
|
||||
_getcwd(ms_rootDirName, 128);
|
||||
strcat(ms_rootDirName, "\\");
|
||||
}
|
||||
|
||||
void
|
||||
CFileMgr::ChangeDir(const char *dir)
|
||||
{
|
||||
if(*dir == '\\'){
|
||||
strcpy(ms_dirName, ms_rootDirName);
|
||||
dir++;
|
||||
}
|
||||
if(*dir != '\0'){
|
||||
strcat(ms_dirName, dir);
|
||||
// BUG in the game it seems, it's off by one
|
||||
if(dir[strlen(dir)-1] != '\\')
|
||||
strcat(ms_dirName, "\\");
|
||||
}
|
||||
mychdir(ms_dirName);
|
||||
}
|
||||
|
||||
void
|
||||
CFileMgr::SetDir(const char *dir)
|
||||
{
|
||||
strcpy(ms_dirName, ms_rootDirName);
|
||||
if(*dir != '\0'){
|
||||
strcat(ms_dirName, dir);
|
||||
// BUG in the game it seems, it's off by one
|
||||
if(dir[strlen(dir)-1] != '\\')
|
||||
strcat(ms_dirName, "\\");
|
||||
}
|
||||
mychdir(ms_dirName);
|
||||
}
|
||||
|
||||
void
|
||||
CFileMgr::SetDirMyDocuments(void)
|
||||
{
|
||||
SetDir(""); // better start at the root if user directory is relative
|
||||
mychdir(_psGetUserFilesFolder());
|
||||
}
|
||||
|
||||
ssize_t
|
||||
CFileMgr::LoadFile(const char *file, uint8 *buf, int maxlen, const char *mode)
|
||||
{
|
||||
int fd;
|
||||
ssize_t n, len;
|
||||
|
||||
fd = myfopen(file, mode);
|
||||
if(fd == 0)
|
||||
return -1;
|
||||
len = 0;
|
||||
do{
|
||||
n = myfread(buf + len, 1, 0x4000, fd);
|
||||
#ifndef FIX_BUGS
|
||||
if (n < 0)
|
||||
return -1;
|
||||
#endif
|
||||
len += n;
|
||||
assert(len < maxlen);
|
||||
}while(n == 0x4000);
|
||||
buf[len] = 0;
|
||||
myfclose(fd);
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
CFileMgr::OpenFile(const char *file, const char *mode)
|
||||
{
|
||||
return myfopen(file, mode);
|
||||
}
|
||||
|
||||
int
|
||||
CFileMgr::OpenFileForWriting(const char *file)
|
||||
{
|
||||
return OpenFile(file, "wb");
|
||||
}
|
||||
|
||||
size_t
|
||||
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, ssize_t len)
|
||||
{
|
||||
return myfwrite((void*)buf, 1, len, fd);
|
||||
}
|
||||
|
||||
bool
|
||||
CFileMgr::Seek(int fd, int offset, int whence)
|
||||
{
|
||||
return !!myfseek(fd, offset, whence);
|
||||
}
|
||||
|
||||
bool
|
||||
CFileMgr::ReadLine(int fd, char *buf, int len)
|
||||
{
|
||||
return myfgets(buf, len, fd) != nil;
|
||||
}
|
||||
|
||||
int
|
||||
CFileMgr::CloseFile(int fd)
|
||||
{
|
||||
return myfclose(fd);
|
||||
}
|
||||
|
||||
int
|
||||
CFileMgr::GetErrorReadWrite(int fd)
|
||||
{
|
||||
return myfeof(fd);
|
||||
}
|
||||
23
src/core/FileMgr.h
Normal file
23
src/core/FileMgr.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
class CFileMgr
|
||||
{
|
||||
static char ms_rootDirName[128];
|
||||
static char ms_dirName[128];
|
||||
public:
|
||||
static void Initialise(void);
|
||||
static void ChangeDir(const char *dir);
|
||||
static void SetDir(const char *dir);
|
||||
static void SetDirMyDocuments(void);
|
||||
static ssize_t LoadFile(const char *file, uint8 *buf, int maxlen, const char *mode);
|
||||
static int OpenFile(const char *file, const char *mode);
|
||||
static int OpenFile(const char *file) { return OpenFile(file, "rb"); }
|
||||
static int OpenFileForWriting(const char *file);
|
||||
static size_t Read(int fd, const char *buf, 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);
|
||||
static int GetErrorReadWrite(int fd);
|
||||
static char *GetRootDirName() { return ms_rootDirName; }
|
||||
};
|
||||
440
src/core/Fire.cpp
Normal file
440
src/core/Fire.cpp
Normal file
|
|
@ -0,0 +1,440 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Vector.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Entity.h"
|
||||
#include "PointLights.h"
|
||||
#include "Particle.h"
|
||||
#include "Timer.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Shadows.h"
|
||||
#include "Automobile.h"
|
||||
#include "World.h"
|
||||
#include "General.h"
|
||||
#include "EventList.h"
|
||||
#include "DamageManager.h"
|
||||
#include "Ped.h"
|
||||
#include "Fire.h"
|
||||
|
||||
CFireManager gFireManager;
|
||||
|
||||
CFire::CFire()
|
||||
{
|
||||
m_bIsOngoing = false;
|
||||
m_bIsScriptFire = false;
|
||||
m_bPropagationFlag = true;
|
||||
m_bAudioSet = true;
|
||||
m_vecPos = CVector(0.0f, 0.0f, 0.0f);
|
||||
m_pEntity = nil;
|
||||
m_pSource = nil;
|
||||
m_nFiremenPuttingOut = 0;
|
||||
m_nExtinguishTime = 0;
|
||||
m_nStartTime = 0;
|
||||
field_20 = 1;
|
||||
m_nNextTimeToAddFlames = 0;
|
||||
m_fStrength = 0.8f;
|
||||
}
|
||||
|
||||
CFire::~CFire() {}
|
||||
|
||||
void
|
||||
CFire::ProcessFire(void)
|
||||
{
|
||||
float fDamagePlayer;
|
||||
float fDamagePeds;
|
||||
float fDamageVehicle;
|
||||
int16 nRandNumber;
|
||||
float fGreen;
|
||||
float fRed;
|
||||
CVector lightpos;
|
||||
CVector firePos;
|
||||
CPed *ped = (CPed *)m_pEntity;
|
||||
CVehicle *veh = (CVehicle*)m_pEntity;
|
||||
|
||||
if (m_pEntity) {
|
||||
m_vecPos = m_pEntity->GetPosition();
|
||||
|
||||
if (((CPed *)m_pEntity)->IsPed()) {
|
||||
if (ped->m_pFire != this) {
|
||||
Extinguish();
|
||||
return;
|
||||
}
|
||||
if (ped->m_nMoveState != PEDMOVE_RUN)
|
||||
m_vecPos.z -= 1.0f;
|
||||
if (ped->bInVehicle && ped->m_pMyVehicle) {
|
||||
if (ped->m_pMyVehicle->IsCar())
|
||||
ped->m_pMyVehicle->m_fHealth = 75.0f;
|
||||
} else if (m_pEntity == (CPed *)FindPlayerPed()) {
|
||||
fDamagePlayer = 1.2f * CTimer::GetTimeStep();
|
||||
|
||||
((CPlayerPed *)m_pEntity)->InflictDamage(
|
||||
(CPlayerPed *)m_pSource, WEAPONTYPE_FLAMETHROWER,
|
||||
fDamagePlayer, PEDPIECE_TORSO, 0);
|
||||
} else {
|
||||
fDamagePeds = 1.2f * CTimer::GetTimeStep();
|
||||
|
||||
if (((CPlayerPed *)m_pEntity)->InflictDamage(
|
||||
(CPlayerPed *)m_pSource, WEAPONTYPE_FLAMETHROWER,
|
||||
fDamagePeds, PEDPIECE_TORSO, 0)) {
|
||||
m_pEntity->bRenderScorched = true;
|
||||
}
|
||||
}
|
||||
} else if (m_pEntity->IsVehicle()) {
|
||||
if (veh->m_pCarFire != this) {
|
||||
Extinguish();
|
||||
return;
|
||||
}
|
||||
if (!m_bIsScriptFire) {
|
||||
fDamageVehicle = 1.2f * CTimer::GetTimeStep();
|
||||
veh->InflictDamage((CVehicle *)m_pSource, WEAPONTYPE_FLAMETHROWER, fDamageVehicle);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() > m_nNextTimeToAddFlames) {
|
||||
m_nNextTimeToAddFlames = CTimer::GetTimeInMilliseconds() + 80;
|
||||
firePos = m_vecPos;
|
||||
|
||||
if (veh && veh->IsVehicle() && veh->IsCar()) {
|
||||
CVehicleModelInfo *mi = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(veh->GetModelIndex()));
|
||||
CVector ModelInfo = mi->m_positions[CAR_POS_HEADLIGHTS];
|
||||
ModelInfo = m_pEntity->GetMatrix() * ModelInfo;
|
||||
|
||||
firePos.x = ModelInfo.x;
|
||||
firePos.y = ModelInfo.y;
|
||||
firePos.z = ModelInfo.z + 0.15f;
|
||||
}
|
||||
|
||||
CParticle::AddParticle(PARTICLE_CARFLAME, firePos,
|
||||
CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.0125f, 0.1f) * m_fStrength),
|
||||
0, m_fStrength, 0, 0, 0, 0);
|
||||
|
||||
CGeneral::GetRandomNumber(); CGeneral::GetRandomNumber(); CGeneral::GetRandomNumber(); /* unsure why these three rands are called */
|
||||
|
||||
CParticle::AddParticle(PARTICLE_CARFLAME_SMOKE, firePos,
|
||||
CVector(0.0f, 0.0f, 0.0f), 0, 0.0f, 0, 0, 0, 0);
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() < m_nExtinguishTime || m_bIsScriptFire) {
|
||||
if (CTimer::GetTimeInMilliseconds() > m_nStartTime)
|
||||
m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
|
||||
|
||||
nRandNumber = CGeneral::GetRandomNumber() & 127;
|
||||
lightpos.x = m_vecPos.x;
|
||||
lightpos.y = m_vecPos.y;
|
||||
lightpos.z = m_vecPos.z + 5.0f;
|
||||
|
||||
if (!m_pEntity) {
|
||||
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.f;
|
||||
fRed = nRandNumber / 128.f;
|
||||
|
||||
CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0, 0, 0);
|
||||
} else {
|
||||
Extinguish();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CFire::ReportThisFire(void)
|
||||
{
|
||||
gFireManager.m_nTotalFires++;
|
||||
CEventList::RegisterEvent(EVENT_FIRE, m_vecPos, 1000);
|
||||
}
|
||||
|
||||
void
|
||||
CFire::Extinguish(void)
|
||||
{
|
||||
if (m_bIsOngoing) {
|
||||
if (!m_bIsScriptFire)
|
||||
gFireManager.m_nTotalFires--;
|
||||
|
||||
m_nExtinguishTime = 0;
|
||||
m_bIsOngoing = false;
|
||||
|
||||
if (m_pEntity) {
|
||||
if (m_pEntity->IsPed()) {
|
||||
((CPed *)m_pEntity)->RestorePreviousState();
|
||||
((CPed *)m_pEntity)->m_pFire = nil;
|
||||
} else if (m_pEntity->IsVehicle()) {
|
||||
((CVehicle *)m_pEntity)->m_pCarFire = nil;
|
||||
}
|
||||
m_pEntity = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CFireManager::StartFire(CVector pos, float size, bool propagation)
|
||||
{
|
||||
CFire *fire = GetNextFreeFire();
|
||||
|
||||
if (fire) {
|
||||
fire->m_bIsOngoing = true;
|
||||
fire->m_bIsScriptFire = false;
|
||||
fire->m_bPropagationFlag = propagation;
|
||||
fire->m_bAudioSet = true;
|
||||
fire->m_vecPos = pos;
|
||||
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + 10000;
|
||||
fire->m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
|
||||
fire->m_pEntity = nil;
|
||||
fire->m_pSource = nil;
|
||||
fire->m_nNextTimeToAddFlames = 0;
|
||||
fire->ReportThisFire();
|
||||
fire->m_fStrength = size;
|
||||
}
|
||||
}
|
||||
|
||||
CFire *
|
||||
CFireManager::StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, bool propagation)
|
||||
{
|
||||
CPed *ped = (CPed *)entityOnFire;
|
||||
CVehicle *veh = (CVehicle *)entityOnFire;
|
||||
|
||||
if (entityOnFire->IsPed()) {
|
||||
if (ped->m_pFire)
|
||||
return nil;
|
||||
if (!ped->IsPedInControl())
|
||||
return nil;
|
||||
} else if (entityOnFire->IsVehicle()) {
|
||||
if (veh->m_pCarFire)
|
||||
return nil;
|
||||
if (veh->IsCar() && ((CAutomobile *)veh)->Damage.GetEngineStatus() >= 225)
|
||||
return nil;
|
||||
}
|
||||
CFire *fire = GetNextFreeFire();
|
||||
|
||||
if (fire) {
|
||||
if (entityOnFire->IsPed()) {
|
||||
ped->m_pFire = fire;
|
||||
if (ped != FindPlayerPed()) {
|
||||
if (fleeFrom) {
|
||||
ped->SetFlee(fleeFrom, 10000);
|
||||
} else {
|
||||
CVector2D pos = entityOnFire->GetPosition();
|
||||
ped->SetFlee(pos, 10000);
|
||||
ped->m_fleeFrom = nil;
|
||||
}
|
||||
ped->bDrawLast = false;
|
||||
ped->SetMoveState(PEDMOVE_SPRINT);
|
||||
ped->SetMoveAnim();
|
||||
ped->SetPedState(PED_ON_FIRE);
|
||||
}
|
||||
if (fleeFrom) {
|
||||
if (ped->m_nPedType == PEDTYPE_COP) {
|
||||
CEventList::RegisterEvent(EVENT_COP_SET_ON_FIRE, EVENT_ENTITY_PED,
|
||||
entityOnFire, (CPed *)fleeFrom, 10000);
|
||||
} else {
|
||||
CEventList::RegisterEvent(EVENT_PED_SET_ON_FIRE, EVENT_ENTITY_PED,
|
||||
entityOnFire, (CPed *)fleeFrom, 10000);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (entityOnFire->IsVehicle()) {
|
||||
veh->m_pCarFire = fire;
|
||||
if (fleeFrom) {
|
||||
CEventList::RegisterEvent(EVENT_CAR_SET_ON_FIRE, EVENT_ENTITY_VEHICLE,
|
||||
entityOnFire, (CPed *)fleeFrom, 10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fire->m_bIsOngoing = true;
|
||||
fire->m_bIsScriptFire = false;
|
||||
fire->m_vecPos = entityOnFire->GetPosition();
|
||||
|
||||
if (entityOnFire && entityOnFire->IsPed() && ped->IsPlayer()) {
|
||||
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + 3333;
|
||||
} else if (entityOnFire->IsVehicle()) {
|
||||
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(4000, 5000);
|
||||
} else {
|
||||
fire->m_nExtinguishTime = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(10000, 11000);
|
||||
}
|
||||
fire->m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
|
||||
fire->m_pEntity = entityOnFire;
|
||||
|
||||
entityOnFire->RegisterReference(&fire->m_pEntity);
|
||||
fire->m_pSource = fleeFrom;
|
||||
|
||||
if (fleeFrom)
|
||||
fleeFrom->RegisterReference(&fire->m_pSource);
|
||||
fire->ReportThisFire();
|
||||
fire->m_nNextTimeToAddFlames = 0;
|
||||
fire->m_fStrength = strength;
|
||||
fire->m_bPropagationFlag = propagation;
|
||||
fire->m_bAudioSet = true;
|
||||
}
|
||||
return fire;
|
||||
}
|
||||
|
||||
void
|
||||
CFireManager::Update(void)
|
||||
{
|
||||
for (int i = 0; i < NUM_FIRES; i++) {
|
||||
if (m_aFires[i].m_bIsOngoing)
|
||||
m_aFires[i].ProcessFire();
|
||||
}
|
||||
}
|
||||
|
||||
CFire* CFireManager::FindNearestFire(CVector vecPos, float *pDistance)
|
||||
{
|
||||
for (int i = 0; i < MAX_FIREMEN_ATTENDING; i++) {
|
||||
int fireId = -1;
|
||||
float minDistance = 999999;
|
||||
for (int j = 0; j < NUM_FIRES; j++) {
|
||||
if (!m_aFires[j].m_bIsOngoing)
|
||||
continue;
|
||||
if (m_aFires[j].m_bIsScriptFire)
|
||||
continue;
|
||||
if (m_aFires[j].m_nFiremenPuttingOut != i)
|
||||
continue;
|
||||
float distance = (m_aFires[j].m_vecPos - vecPos).Magnitude2D();
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
fireId = j;
|
||||
}
|
||||
}
|
||||
*pDistance = minDistance;
|
||||
if (fireId != -1)
|
||||
return &m_aFires[fireId];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
CFire *
|
||||
CFireManager::FindFurthestFire_NeverMindFireMen(CVector coords, float minRange, float maxRange)
|
||||
{
|
||||
int furthestFire = -1;
|
||||
float lastFireDist = 0.0f;
|
||||
float fireDist;
|
||||
|
||||
for (int i = 0; i < NUM_FIRES; i++) {
|
||||
if (m_aFires[i].m_bIsOngoing && !m_aFires[i].m_bIsScriptFire) {
|
||||
fireDist = (m_aFires[i].m_vecPos - coords).Magnitude2D();
|
||||
if (fireDist > minRange && fireDist < maxRange && fireDist > lastFireDist) {
|
||||
lastFireDist = fireDist;
|
||||
furthestFire = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (furthestFire == -1)
|
||||
return nil;
|
||||
else
|
||||
return &m_aFires[furthestFire];
|
||||
}
|
||||
|
||||
CFire *
|
||||
CFireManager::GetNextFreeFire(void)
|
||||
{
|
||||
for (int i = 0; i < NUM_FIRES; i++) {
|
||||
if (!m_aFires[i].m_bIsOngoing && !m_aFires[i].m_bIsScriptFire)
|
||||
return &m_aFires[i];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
uint32
|
||||
CFireManager::GetTotalActiveFires(void) const
|
||||
{
|
||||
return m_nTotalFires;
|
||||
}
|
||||
|
||||
void
|
||||
CFireManager::ExtinguishPoint(CVector point, float range)
|
||||
{
|
||||
for (int i = 0; i < NUM_FIRES; i++) {
|
||||
if (m_aFires[i].m_bIsOngoing) {
|
||||
if ((point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range))
|
||||
m_aFires[i].Extinguish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32
|
||||
CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strength, bool propagation)
|
||||
{
|
||||
CFire *fire;
|
||||
CPed *ped = (CPed *)target;
|
||||
CVehicle *veh = (CVehicle *)target;
|
||||
|
||||
if (target) {
|
||||
if (target->IsPed()) {
|
||||
if (ped->m_pFire)
|
||||
ped->m_pFire->Extinguish();
|
||||
} else if (target->IsVehicle()) {
|
||||
if (veh->m_pCarFire)
|
||||
veh->m_pCarFire->Extinguish();
|
||||
if (veh->IsCar() && ((CAutomobile *)veh)->Damage.GetEngineStatus() >= 225) {
|
||||
((CAutomobile *)veh)->Damage.SetEngineStatus(215);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fire = GetNextFreeFire();
|
||||
fire->m_bIsOngoing = true;
|
||||
fire->m_bIsScriptFire = true;
|
||||
fire->m_bPropagationFlag = propagation;
|
||||
fire->m_bAudioSet = true;
|
||||
fire->m_vecPos = pos;
|
||||
fire->m_nStartTime = CTimer::GetTimeInMilliseconds() + 400;
|
||||
fire->m_pEntity = target;
|
||||
|
||||
if (target)
|
||||
target->RegisterReference(&fire->m_pEntity);
|
||||
fire->m_pSource = nil;
|
||||
fire->m_nNextTimeToAddFlames = 0;
|
||||
fire->m_fStrength = strength;
|
||||
if (target) {
|
||||
if (target->IsPed()) {
|
||||
ped->m_pFire = fire;
|
||||
if (target != FindPlayerPed()) {
|
||||
CVector2D pos = target->GetPosition();
|
||||
ped->SetFlee(pos, 10000);
|
||||
ped->SetMoveAnim();
|
||||
ped->SetPedState(PED_ON_FIRE);
|
||||
}
|
||||
} else if (target->IsVehicle()) {
|
||||
veh->m_pCarFire = fire;
|
||||
}
|
||||
}
|
||||
return fire - m_aFires;
|
||||
}
|
||||
|
||||
bool
|
||||
CFireManager::IsScriptFireExtinguish(int16 index)
|
||||
{
|
||||
return !m_aFires[index].m_bIsOngoing;
|
||||
}
|
||||
|
||||
void
|
||||
CFireManager::RemoveAllScriptFires(void)
|
||||
{
|
||||
for (int i = 0; i < NUM_FIRES; i++) {
|
||||
if (m_aFires[i].m_bIsScriptFire) {
|
||||
m_aFires[i].Extinguish();
|
||||
m_aFires[i].m_bIsScriptFire = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CFireManager::RemoveScriptFire(int16 index)
|
||||
{
|
||||
m_aFires[index].Extinguish();
|
||||
m_aFires[index].m_bIsScriptFire = false;
|
||||
}
|
||||
|
||||
void
|
||||
CFireManager::SetScriptFireAudio(int16 index, bool state)
|
||||
{
|
||||
m_aFires[index].m_bAudioSet = state;
|
||||
}
|
||||
51
src/core/Fire.h
Normal file
51
src/core/Fire.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
|
||||
class CFire
|
||||
{
|
||||
public:
|
||||
bool m_bIsOngoing;
|
||||
bool m_bIsScriptFire;
|
||||
bool m_bPropagationFlag;
|
||||
bool m_bAudioSet;
|
||||
CVector m_vecPos;
|
||||
CEntity *m_pEntity;
|
||||
CEntity *m_pSource;
|
||||
uint32 m_nExtinguishTime;
|
||||
uint32 m_nStartTime;
|
||||
int32 field_20;
|
||||
uint32 m_nNextTimeToAddFlames;
|
||||
uint32 m_nFiremenPuttingOut;
|
||||
float m_fStrength;
|
||||
|
||||
CFire();
|
||||
~CFire();
|
||||
void ProcessFire(void);
|
||||
void ReportThisFire(void);
|
||||
void Extinguish(void);
|
||||
};
|
||||
|
||||
class CFireManager
|
||||
{
|
||||
enum {
|
||||
MAX_FIREMEN_ATTENDING = 2,
|
||||
};
|
||||
public:
|
||||
uint32 m_nTotalFires;
|
||||
CFire m_aFires[NUM_FIRES];
|
||||
void StartFire(CVector pos, float size, bool propagation);
|
||||
CFire *StartFire(CEntity *entityOnFire, CEntity *fleeFrom, float strength, bool propagation);
|
||||
void Update(void);
|
||||
CFire *FindFurthestFire_NeverMindFireMen(CVector coords, float minRange, float maxRange);
|
||||
CFire *FindNearestFire(CVector vecPos, float *pDistance);
|
||||
CFire *GetNextFreeFire(void);
|
||||
uint32 GetTotalActiveFires() const;
|
||||
void ExtinguishPoint(CVector point, float range);
|
||||
int32 StartScriptFire(const CVector &pos, CEntity *target, float strength, bool propagation);
|
||||
bool IsScriptFireExtinguish(int16 index);
|
||||
void RemoveAllScriptFires(void);
|
||||
void RemoveScriptFire(int16 index);
|
||||
void SetScriptFireAudio(int16 index, bool state);
|
||||
};
|
||||
extern CFireManager gFireManager;
|
||||
1887
src/core/FrontEndControls.cpp
Normal file
1887
src/core/FrontEndControls.cpp
Normal file
File diff suppressed because it is too large
Load diff
750
src/core/FrontEndControls.h
Normal file
750
src/core/FrontEndControls.h
Normal file
|
|
@ -0,0 +1,750 @@
|
|||
#pragma once
|
||||
|
||||
enum {
|
||||
NUM_MULTICHOICE_OPTIONS = 16,
|
||||
// 50 actual lines and 15 for spacing
|
||||
NUM_LINELISTER_LINES = 50,
|
||||
NUM_LINELISTER_LINES_TOTAL = NUM_LINELISTER_LINES + 15,
|
||||
NUM_PAGE_WIDGETS = 10,
|
||||
};
|
||||
|
||||
class CTriggerCaller
|
||||
{
|
||||
bool bHasTrigger;
|
||||
void *pTrigger;
|
||||
void (*pFunc)(void *);
|
||||
int field_C;
|
||||
public:
|
||||
|
||||
CTriggerCaller() : bHasTrigger(false), pFunc(nil)
|
||||
{}
|
||||
|
||||
void SetTrigger(void *func, void *trigger)
|
||||
{
|
||||
if ( !bHasTrigger )
|
||||
{
|
||||
pFunc = (void (*)(void *))func;
|
||||
pTrigger = trigger;
|
||||
bHasTrigger = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CallTrigger(void)
|
||||
{
|
||||
if ( bHasTrigger && pFunc != nil )
|
||||
pFunc(pTrigger);
|
||||
|
||||
bHasTrigger = false;
|
||||
pFunc = nil;
|
||||
}
|
||||
|
||||
bool CanCall()
|
||||
{
|
||||
return bHasTrigger;
|
||||
}
|
||||
};
|
||||
|
||||
class CPlaceableText
|
||||
{
|
||||
public:
|
||||
CVector2D m_position;
|
||||
CRGBA m_color;
|
||||
wchar *m_text;
|
||||
|
||||
CPlaceableText(void)
|
||||
: m_position(0.0f, 0.0f), m_color(255, 255, 255, 255), m_text(nil) {}
|
||||
void SetPosition(float x, float y) { m_position.x = x; m_position.y = y; }
|
||||
void SetColor(const CRGBA &color) { m_color = color; }
|
||||
CRGBA GetColor(void) { return m_color; }
|
||||
void SetAlpha(uint8 alpha) { m_color.alpha = alpha; }
|
||||
};
|
||||
|
||||
// No trace of this in the game but it makes the other classes simpler
|
||||
class CPlaceableTextTwoLines
|
||||
{
|
||||
public:
|
||||
CPlaceableText m_line1;
|
||||
CPlaceableText m_line2;
|
||||
|
||||
void SetColor(const CRGBA &color) { m_line1.SetColor(color); m_line2.SetColor(color); }
|
||||
void SetAlpha(uint8 alpha) { m_line1.SetAlpha(alpha); m_line2.SetAlpha(alpha); }
|
||||
};
|
||||
|
||||
// No trace of this in the game but it makes the other classes simpler
|
||||
class CShadowInfo
|
||||
{
|
||||
public:
|
||||
bool m_bRightJustify;
|
||||
bool m_bDropShadow;
|
||||
CRGBA m_shadowColor;
|
||||
CVector2D m_shadowOffset;
|
||||
|
||||
CShadowInfo(void)
|
||||
: m_bRightJustify(false), m_bDropShadow(false),
|
||||
m_shadowColor(255, 255, 255, 255),
|
||||
m_shadowOffset(-1.0f, -1.0f) {}
|
||||
CRGBA GetShadowColor(void) { return m_shadowColor; }
|
||||
void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset){
|
||||
m_bDropShadow = bDropShadows;
|
||||
m_shadowColor = shadowColor;
|
||||
m_shadowOffset = shadowOffset;
|
||||
}
|
||||
};
|
||||
|
||||
// No trace of this in the game but it makes the other classes simpler
|
||||
class CSelectable
|
||||
{
|
||||
public:
|
||||
bool m_bSelected;
|
||||
CRGBA m_selectedColor;
|
||||
|
||||
CSelectable(void) : m_bSelected(false) {}
|
||||
CRGBA GetSelectedColor(void) { return m_selectedColor; }
|
||||
};
|
||||
|
||||
class CPlaceableShText : public CPlaceableText, public CShadowInfo
|
||||
{
|
||||
public:
|
||||
using CPlaceableText::SetPosition;
|
||||
void SetPosition(float x, float y, bool bRightJustify) { SetPosition(x, y); m_bRightJustify = bRightJustify; }
|
||||
void SetAlpha(uint8 alpha) { m_shadowColor.alpha = alpha; CPlaceableText::SetAlpha(alpha); }
|
||||
|
||||
void Draw(float x, float y);
|
||||
void Draw(const CRGBA &color, float x, float y);
|
||||
// unused arguments it seems
|
||||
void DrawShWrap(float x, float y, float wrapX, float wrapY) { Draw(x, y); }
|
||||
};
|
||||
|
||||
class CPlaceableShTextTwoLines : public CPlaceableTextTwoLines, public CShadowInfo
|
||||
{
|
||||
public:
|
||||
void SetAlpha(uint8 alpha) { m_shadowColor.alpha = alpha; CPlaceableTextTwoLines::SetAlpha(alpha); }
|
||||
|
||||
void Draw(float x, float y);
|
||||
void Draw(const CRGBA &color, float x, float y);
|
||||
};
|
||||
|
||||
class CPlaceableShOption : public CPlaceableShText, public CSelectable
|
||||
{
|
||||
public:
|
||||
void SetColors(const CRGBA &normal, const CRGBA &selection) { CPlaceableShText::SetColor(normal); m_selectedColor = selection; }
|
||||
void SetAlpha(uint8 alpha) { m_selectedColor.alpha = alpha; CPlaceableShText::SetAlpha(alpha); }
|
||||
|
||||
using CPlaceableShText::Draw;
|
||||
void Draw(const CRGBA &highlightColor, float x, float y, bool bHighlight);
|
||||
};
|
||||
|
||||
class CPlaceableShOptionTwoLines : public CPlaceableShTextTwoLines, public CSelectable
|
||||
{
|
||||
public:
|
||||
void SetColors(const CRGBA &normal, const CRGBA &selection) { CPlaceableShTextTwoLines::SetColor(normal); m_selectedColor = selection; }
|
||||
void SetAlpha(uint8 alpha) { m_selectedColor.alpha = alpha; CPlaceableShTextTwoLines::SetAlpha(alpha); }
|
||||
|
||||
using CPlaceableShTextTwoLines::Draw;
|
||||
void Draw(const CRGBA &highlightColor, float x, float y, bool bHighlight);
|
||||
};
|
||||
|
||||
class CPlaceableSprite
|
||||
{
|
||||
public:
|
||||
CSprite2d *m_pSprite;
|
||||
CVector2D m_position;
|
||||
CVector2D m_size;
|
||||
CRGBA m_color;
|
||||
|
||||
CPlaceableSprite(void)
|
||||
: m_pSprite(nil), m_position(0.0f, 0.0f),
|
||||
m_size(0.0f, 0.0f), m_color(255, 255, 255, 255) {}
|
||||
|
||||
void SetPosition(float x, float y) { m_position.x = x; m_position.y = y; }
|
||||
void SetAlpha(uint8 alpha) { m_color.alpha = alpha; }
|
||||
|
||||
void Draw(float x, float y);
|
||||
void Draw(const CRGBA &color, float x, float y);
|
||||
};
|
||||
|
||||
class CPlaceableShSprite
|
||||
{
|
||||
public:
|
||||
CPlaceableSprite m_sprite;
|
||||
CPlaceableSprite m_shadow;
|
||||
bool m_bDropShadow;
|
||||
|
||||
CPlaceableShSprite(void) : m_bDropShadow(false) {}
|
||||
|
||||
void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset){
|
||||
m_bDropShadow = bDropShadows;
|
||||
m_shadow.m_color = shadowColor;
|
||||
m_shadow.m_position = shadowOffset;
|
||||
}
|
||||
void SetAlpha(uint8 alpha) { m_sprite.SetAlpha(alpha); m_shadow.SetAlpha(alpha); }
|
||||
|
||||
void Draw(float x, float y);
|
||||
};
|
||||
|
||||
|
||||
class CMenuBase
|
||||
{
|
||||
public:
|
||||
CVector2D m_position;
|
||||
bool m_bTwoState;
|
||||
|
||||
CMenuBase(void)
|
||||
: m_position(0.0f, 0.0f), m_bTwoState(false) {}
|
||||
void SetPosition(float x, float y) { m_position.x = x; m_position.y = y; }
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y) = 0;
|
||||
virtual void DrawNormal(float x, float y) = 0;
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y) = 0;
|
||||
virtual void SetAlpha(uint8 alpha) = 0;
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset) = 0;
|
||||
virtual bool GoNext(void) = 0;
|
||||
virtual bool GoPrev(void) = 0;
|
||||
virtual bool GoDown(void) = 0;
|
||||
virtual bool GoUp(void) = 0;
|
||||
virtual bool GoDownStill(void) = 0;
|
||||
virtual bool GoUpStill(void) = 0;
|
||||
virtual bool GoLeft(void) = 0;
|
||||
virtual bool GoRight(void) = 0;
|
||||
virtual bool GoLeftStill(void) = 0;
|
||||
virtual bool GoRightStill(void) = 0;
|
||||
virtual bool GoFirst(void) = 0;
|
||||
virtual bool GoLast(void) = 0;
|
||||
virtual void SelectCurrentOptionUnderCursor(void) = 0;
|
||||
virtual void SelectDefaultCancelAction(void) = 0;
|
||||
virtual void ActivateMenu(bool first) = 0;
|
||||
virtual void DeactivateMenu(void) = 0;
|
||||
virtual int GetMenuSelection(void) = 0;
|
||||
virtual void SetMenuSelection(int selection) = 0;
|
||||
};
|
||||
|
||||
class CMenuDummy : public CMenuBase
|
||||
{
|
||||
public:
|
||||
bool m_bActive;
|
||||
|
||||
virtual void Draw(const CRGBA &, const CRGBA &, float x, float y) {}
|
||||
virtual void DrawNormal(float x, float y) {}
|
||||
virtual void DrawHighlighted(const CRGBA &, float x, float y) {}
|
||||
virtual void SetAlpha(uint8 alpha) {}
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset) {}
|
||||
virtual bool GoNext(void) { DeactivateMenu(); return false; }
|
||||
virtual bool GoPrev(void) { DeactivateMenu(); return false; }
|
||||
virtual bool GoDown(void) { return GoNext(); }
|
||||
virtual bool GoUp(void) { return GoPrev(); }
|
||||
virtual bool GoDownStill(void) { return false; }
|
||||
virtual bool GoUpStill(void) { return false; }
|
||||
virtual bool GoLeft(void) { return true; }
|
||||
virtual bool GoRight(void) { return true; }
|
||||
virtual bool GoLeftStill(void) { return true; }
|
||||
virtual bool GoRightStill(void) { return true; }
|
||||
virtual bool GoFirst(void) { ActivateMenu(true); return true; }
|
||||
virtual bool GoLast(void) { ActivateMenu(true); return true; }
|
||||
virtual void SelectCurrentOptionUnderCursor(void) {}
|
||||
virtual void SelectDefaultCancelAction(void) {}
|
||||
virtual void ActivateMenu(bool first) { m_bActive = true; }
|
||||
virtual void DeactivateMenu(void) { m_bActive = false; }
|
||||
virtual int GetMenuSelection(void) { return -1; }
|
||||
virtual void SetMenuSelection(int) {}
|
||||
};
|
||||
|
||||
class CMenuPictureAndText : public CMenuBase
|
||||
{
|
||||
public:
|
||||
int m_numSprites;
|
||||
CPlaceableShSprite m_sprites[5];
|
||||
int m_numTexts;
|
||||
CPlaceableShText m_texts[20];
|
||||
|
||||
CVector2D m_oldTextScale;
|
||||
CVector2D m_textScale;
|
||||
bool m_bSetTextScale;
|
||||
|
||||
float m_wrapX;
|
||||
float m_oldWrapx;
|
||||
bool m_bWrap;
|
||||
// missing some?
|
||||
|
||||
|
||||
CMenuPictureAndText(void)
|
||||
: m_numSprites(0), m_numTexts(0),
|
||||
m_bSetTextScale(false), m_bWrap(false) {}
|
||||
|
||||
void SetNewOldShadowWrapX(bool bWrapX, float newWrapX, float oldWrapX);
|
||||
void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale);
|
||||
void SetTextsColor(const CRGBA &color);
|
||||
void AddText(wchar *text, float positionX, float positionY, const CRGBA &color, bool bRightJustify);
|
||||
void AddPicture(CSprite2d *sprite, CSprite2d *shadow, float positionX, float positionY, float width, float height, const CRGBA &color);
|
||||
void AddPicture(CSprite2d *sprite, float positionX, float positionY, float width, float height, const CRGBA &color);
|
||||
|
||||
virtual void Draw(const CRGBA &, const CRGBA &, float x, float y);
|
||||
virtual void DrawNormal(float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
|
||||
virtual void DrawHighlighted(const CRGBA &, float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
|
||||
virtual void SetAlpha(uint8 alpha);
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
|
||||
virtual bool GoNext(void) { return false; }
|
||||
virtual bool GoPrev(void) { return false; }
|
||||
virtual bool GoDown(void) { return GoNext(); }
|
||||
virtual bool GoUp(void) { return GoPrev(); }
|
||||
virtual bool GoDownStill(void) { return false; }
|
||||
virtual bool GoUpStill(void) { return false; }
|
||||
virtual bool GoLeft(void) { return true; }
|
||||
virtual bool GoRight(void) { return true; }
|
||||
virtual bool GoLeftStill(void) { return true; }
|
||||
virtual bool GoRightStill(void) { return true; }
|
||||
virtual bool GoFirst(void) { return false; }
|
||||
virtual bool GoLast(void) { return false; }
|
||||
virtual void SelectCurrentOptionUnderCursor(void) {}
|
||||
virtual void SelectDefaultCancelAction(void) {}
|
||||
virtual void ActivateMenu(bool first) {}
|
||||
virtual void DeactivateMenu(void) {}
|
||||
virtual int GetMenuSelection(void) { return -1; }
|
||||
virtual void SetMenuSelection(int) {}
|
||||
};
|
||||
|
||||
class CMenuMultiChoice : public CMenuBase
|
||||
{
|
||||
public:
|
||||
int m_numOptions;
|
||||
CPlaceableShText m_title;
|
||||
CPlaceableShOption m_options[NUM_MULTICHOICE_OPTIONS];
|
||||
int m_cursor;
|
||||
CVector2D m_oldTextScale;
|
||||
CVector2D m_textScale;
|
||||
bool m_bSetTextScale;
|
||||
bool m_bSetTitleTextScale;
|
||||
|
||||
CMenuMultiChoice(void)
|
||||
: m_numOptions(0), m_cursor(-1),
|
||||
m_bSetTextScale(false), m_bSetTitleTextScale(false) {}
|
||||
|
||||
void AddTitle(wchar *text, float positionX, float positionY, bool bRightJustify);
|
||||
CPlaceableShOption *AddOption(wchar *text, float positionX, float positionY, bool bSelected, bool bRightJustify);
|
||||
void SetColors(const CRGBA &title, const CRGBA &normal, const CRGBA &selected);
|
||||
void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale);
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void DrawNormal(float x, float y);
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void SetAlpha(uint8 alpha);
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
|
||||
virtual bool GoNext(void);
|
||||
virtual bool GoPrev(void);
|
||||
virtual bool GoDown(void) { return GoNext(); }
|
||||
virtual bool GoUp(void) { return GoPrev(); }
|
||||
virtual bool GoDownStill(void) { return false; }
|
||||
virtual bool GoUpStill(void) { return false; }
|
||||
virtual bool GoLeft(void) { return GoPrev(); }
|
||||
virtual bool GoRight(void) { return GoNext(); }
|
||||
virtual bool GoLeftStill(void) { return true; }
|
||||
virtual bool GoRightStill(void) { return true; }
|
||||
virtual bool GoFirst(void) { m_cursor = 0; return true; }
|
||||
virtual bool GoLast(void) { m_cursor = m_numOptions-1; return true; }
|
||||
virtual void SelectCurrentOptionUnderCursor(void);
|
||||
virtual void SelectDefaultCancelAction(void) {}
|
||||
virtual void ActivateMenu(bool first) { m_cursor = first ? 0 : m_numOptions-1; }
|
||||
virtual void DeactivateMenu(void) { m_cursor = -1; }
|
||||
virtual int GetMenuSelection(void);
|
||||
virtual void SetMenuSelection(int selection);
|
||||
};
|
||||
|
||||
class CMenuMultiChoiceTriggered : public CMenuMultiChoice
|
||||
{
|
||||
public:
|
||||
typedef void (*Trigger)(CMenuMultiChoiceTriggered *);
|
||||
|
||||
Trigger m_triggers[NUM_MULTICHOICE_OPTIONS];
|
||||
Trigger m_defaultCancel;
|
||||
|
||||
CMenuMultiChoiceTriggered(void) { Initialise(); }
|
||||
|
||||
void Initialise(void);
|
||||
CPlaceableShOption *AddOption(wchar *text, float positionX, float positionY, Trigger trigger, bool bSelected, bool bRightJustify);
|
||||
|
||||
virtual void SelectCurrentOptionUnderCursor(void);
|
||||
virtual void SelectDefaultCancelAction(void);
|
||||
};
|
||||
|
||||
class CMenuMultiChoiceTriggeredAlways : public CMenuMultiChoiceTriggered
|
||||
{
|
||||
public:
|
||||
Trigger m_alwaysNormalTrigger;
|
||||
Trigger m_alwaysHighlightTrigger;
|
||||
Trigger m_alwaysTrigger;
|
||||
|
||||
CMenuMultiChoiceTriggeredAlways(void)
|
||||
: m_alwaysNormalTrigger(nil), m_alwaysHighlightTrigger(nil), m_alwaysTrigger(nil) {}
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void DrawNormal(float x, float y);
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
|
||||
};
|
||||
|
||||
class CMenuMultiChoicePictured : public CMenuMultiChoice
|
||||
{
|
||||
public:
|
||||
CPlaceableSprite m_sprites[NUM_MULTICHOICE_OPTIONS];
|
||||
bool m_bHasSprite[NUM_MULTICHOICE_OPTIONS];
|
||||
|
||||
CMenuMultiChoicePictured(void) { Initialise(); }
|
||||
void Initialise(void);
|
||||
using CMenuMultiChoice::AddOption;
|
||||
CPlaceableShOption *AddOption(CSprite2d *sprite, float positionX, float positionY, const CVector2D &size, bool bSelected);
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void DrawNormal(float x, float y);
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void SetAlpha(uint8 alpha);
|
||||
// unnecessary - same as base class
|
||||
// virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
|
||||
};
|
||||
|
||||
class CMenuMultiChoicePicturedTriggered : public CMenuMultiChoicePictured
|
||||
{
|
||||
public:
|
||||
typedef void (*Trigger)(CMenuMultiChoicePicturedTriggered *);
|
||||
|
||||
Trigger m_triggers[NUM_MULTICHOICE_OPTIONS];
|
||||
Trigger m_defaultCancel;
|
||||
|
||||
CMenuMultiChoicePicturedTriggered(void) { Initialise(); }
|
||||
|
||||
void Initialise(void);
|
||||
using CMenuMultiChoicePictured::AddOption;
|
||||
CPlaceableShOption *AddOption(CSprite2d *sprite, float positionX, float positionY, const CVector2D &size, Trigger trigger, bool bSelected);
|
||||
|
||||
virtual void SelectCurrentOptionUnderCursor(void);
|
||||
virtual void SelectDefaultCancelAction(void);
|
||||
};
|
||||
|
||||
struct FEC_MOVETAB
|
||||
{
|
||||
int8 right;
|
||||
int8 left;
|
||||
int8 down;
|
||||
int8 up;
|
||||
};
|
||||
|
||||
class CMenuMultiChoicePicturedTriggeredAnyMove : public CMenuMultiChoicePicturedTriggered
|
||||
{
|
||||
public:
|
||||
FEC_MOVETAB m_moveTab[NUM_MULTICHOICE_OPTIONS];
|
||||
|
||||
CMenuMultiChoicePicturedTriggeredAnyMove(void) { Initialise(); }
|
||||
|
||||
void Initialise(void);
|
||||
using CMenuMultiChoicePicturedTriggered::AddOption;
|
||||
CPlaceableShOption *AddOption(CSprite2d *sprite, FEC_MOVETAB *moveTab, float positionX, float positionY, const CVector2D &size, Trigger trigger, bool bSelected);
|
||||
|
||||
virtual bool GoDown(void);
|
||||
virtual bool GoUp(void);
|
||||
virtual bool GoLeft(void);
|
||||
virtual bool GoRight(void);
|
||||
};
|
||||
|
||||
// copy of CMenuMultiChoice pretty much except for m_options type
|
||||
class CMenuMultiChoiceTwoLines : public CMenuBase
|
||||
{
|
||||
public:
|
||||
int m_numOptions;
|
||||
CPlaceableShText m_title;
|
||||
CPlaceableShOptionTwoLines m_options[NUM_MULTICHOICE_OPTIONS];
|
||||
int m_cursor;
|
||||
CVector2D m_oldTextScale;
|
||||
CVector2D m_textScale;
|
||||
bool m_bSetTextScale;
|
||||
bool m_bSetTitleTextScale;
|
||||
|
||||
CMenuMultiChoiceTwoLines(void)
|
||||
: m_numOptions(0), m_cursor(-1),
|
||||
m_bSetTextScale(false), m_bSetTitleTextScale(false) {}
|
||||
|
||||
void AddTitle(wchar *text, float positionX, float positionY, bool bRightJustify);
|
||||
CPlaceableShOptionTwoLines *AddOption(wchar *text, float positionX, float positionY, bool bSelected, bool bRightJustify);
|
||||
CPlaceableShOptionTwoLines *AddOption(wchar *text1, float positionX1, float positionY1, wchar *text2, float positionX2, float positionY2, bool bSelected, bool bRightJustify);
|
||||
void SetColors(const CRGBA &title, const CRGBA &normal, const CRGBA &selected);
|
||||
void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale);
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void DrawNormal(float x, float y);
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void SetAlpha(uint8 alpha);
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
|
||||
virtual bool GoNext(void);
|
||||
virtual bool GoPrev(void);
|
||||
virtual bool GoDown(void) { return GoNext(); }
|
||||
virtual bool GoUp(void) { return GoPrev(); }
|
||||
virtual bool GoDownStill(void) { return true; }
|
||||
virtual bool GoUpStill(void) { return true; }
|
||||
virtual bool GoLeft(void) { return GoPrev(); }
|
||||
virtual bool GoRight(void) { return GoNext(); }
|
||||
virtual bool GoLeftStill(void) { return true; }
|
||||
virtual bool GoRightStill(void) { return true; }
|
||||
virtual bool GoFirst(void) { m_cursor = 0; return true; }
|
||||
virtual bool GoLast(void) { m_cursor = m_numOptions-1; return true; }
|
||||
virtual void SelectCurrentOptionUnderCursor(void);
|
||||
virtual void SelectDefaultCancelAction(void) {}
|
||||
virtual void ActivateMenu(bool first) { m_cursor = first ? 0 : m_numOptions-1; }
|
||||
virtual void DeactivateMenu(void) { m_cursor = -1; }
|
||||
virtual int GetMenuSelection(void);
|
||||
virtual void SetMenuSelection(int selection);
|
||||
};
|
||||
|
||||
// copy of CMenuMultiChoiceTriggered except for m_options
|
||||
class CMenuMultiChoiceTwoLinesTriggered : public CMenuMultiChoiceTwoLines
|
||||
{
|
||||
public:
|
||||
typedef void (*Trigger)(CMenuMultiChoiceTwoLinesTriggered *);
|
||||
|
||||
Trigger m_triggers[NUM_MULTICHOICE_OPTIONS];
|
||||
Trigger m_defaultCancel;
|
||||
|
||||
CMenuMultiChoiceTwoLinesTriggered(void) { Initialise(); }
|
||||
|
||||
void Initialise(void);
|
||||
CPlaceableShOptionTwoLines *AddOption(wchar *text, float positionX, float positionY, Trigger trigger, bool bSelected, bool bRightJustify);
|
||||
CPlaceableShOptionTwoLines *AddOption(wchar *text1, float positionX1, float positionY1, wchar *text2, float positionX2, float positionY2, Trigger trigger, bool bSelected, bool bRightJustify);
|
||||
|
||||
virtual void SelectCurrentOptionUnderCursor(void);
|
||||
virtual void SelectDefaultCancelAction(void);
|
||||
};
|
||||
|
||||
|
||||
class CMenuOnOff : public CMenuBase
|
||||
{
|
||||
public:
|
||||
CPlaceableShOption m_title;
|
||||
CPlaceableShText m_options[2];
|
||||
bool m_bActive;
|
||||
bool m_bSetTextScale;
|
||||
bool m_bSetTitleTextScale;
|
||||
CVector2D m_textScale;
|
||||
CVector2D m_oldTextScale;
|
||||
int m_type; // 0: on/off 1: yes/no
|
||||
|
||||
void SetColors(const CRGBA &title, const CRGBA &options);
|
||||
void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale);
|
||||
void SetOptionPosition(float x, float y, bool bRightJustify);
|
||||
void AddTitle(wchar *text, bool bSelected, float positionX, float positionY, bool bRightJustify);
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void DrawNormal(float x, float y);
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void SetAlpha(uint8 alpha);
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
|
||||
virtual bool GoNext(void) { DeactivateMenu(); return false; }
|
||||
virtual bool GoPrev(void) { DeactivateMenu(); return false; }
|
||||
virtual bool GoDown(void) { return GoNext(); }
|
||||
virtual bool GoUp(void) { return GoPrev(); }
|
||||
virtual bool GoDownStill(void) { return false; }
|
||||
virtual bool GoUpStill(void) { return false; }
|
||||
virtual bool GoLeft(void) { SelectCurrentOptionUnderCursor(); return true; }
|
||||
virtual bool GoRight(void) { SelectCurrentOptionUnderCursor(); return true; }
|
||||
virtual bool GoLeftStill(void) { return true; }
|
||||
virtual bool GoRightStill(void) { return true; }
|
||||
virtual bool GoFirst(void) { ActivateMenu(true); return true; }
|
||||
virtual bool GoLast(void) { ActivateMenu(true); return true; }
|
||||
virtual void SelectCurrentOptionUnderCursor(void) { m_title.m_bSelected ^= 1; }
|
||||
virtual void SelectDefaultCancelAction(void) {}
|
||||
virtual void ActivateMenu(bool first) { m_bActive = true; }
|
||||
virtual void DeactivateMenu(void) { m_bActive = false; }
|
||||
virtual int GetMenuSelection(void) { return m_title.m_bSelected; }
|
||||
virtual void SetMenuSelection(int selection) { m_title.m_bSelected = selection; }
|
||||
};
|
||||
|
||||
class CMenuOnOffTriggered : public CMenuOnOff
|
||||
{
|
||||
public:
|
||||
typedef void (*Trigger)(CMenuOnOffTriggered *);
|
||||
|
||||
Trigger m_trigger;
|
||||
|
||||
void SetOptionPosition(float x, float y, Trigger trigger, bool bRightJustify);
|
||||
|
||||
virtual void SelectCurrentOptionUnderCursor(void);
|
||||
};
|
||||
|
||||
class CMenuSlider : public CMenuBase
|
||||
{
|
||||
public:
|
||||
CPlaceableShText m_title;
|
||||
CPlaceableShText m_box; // not really a text
|
||||
CRGBA m_colors[2]; // left and right
|
||||
CVector2D m_size[2]; // left and right
|
||||
int m_value;
|
||||
CPlaceableShText m_percentageText;
|
||||
bool m_bDrawPercentage;
|
||||
// char field_8D;
|
||||
// char field_8E;
|
||||
// char field_8F;
|
||||
uint8 m_someAlpha;
|
||||
// char field_91;
|
||||
// char field_92;
|
||||
// char field_93;
|
||||
bool m_bActive;
|
||||
int m_style;
|
||||
|
||||
static char Buf8[8];
|
||||
static wchar Buf16[8];
|
||||
|
||||
CMenuSlider(void)
|
||||
: m_value(0), m_bDrawPercentage(false), m_bActive(false), m_style(0)
|
||||
{
|
||||
AddTickBox(0.0f, 0.0f, 100.0f, 10.0f, 10.0f); //todo
|
||||
}
|
||||
|
||||
void SetColors(const CRGBA &title, const CRGBA &percentage, const CRGBA &left, const CRGBA &right);
|
||||
void DrawTicks(const CVector2D &position, const CVector2D &size, float heightRight, float level, const CRGBA &leftCol, const CRGBA &selCol, const CRGBA &rightCol, bool bShadow, const CVector2D &shadowOffset, const CRGBA &shadowColor);
|
||||
void DrawTicks(const CVector2D &position, const CVector2D &size, float heightRight, float level, const CRGBA &leftCol, const CRGBA &rightCol, bool bShadow, const CVector2D &shadowOffset, const CRGBA &shadowColor);
|
||||
void AddTickBox(float positionX, float positionY, float width, float heigthLeft, float heightRight);
|
||||
void AddTitle(wchar *text, float positionX, float positionY);
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void DrawNormal(float x, float y);
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void SetAlpha(uint8 alpha);
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
|
||||
virtual bool GoNext(void) { DeactivateMenu(); return false; }
|
||||
virtual bool GoPrev(void) { DeactivateMenu(); return false; }
|
||||
virtual bool GoDown(void) { return GoNext(); }
|
||||
virtual bool GoUp(void) { return GoPrev(); }
|
||||
virtual bool GoDownStill(void) { return false; }
|
||||
virtual bool GoUpStill(void) { return false; }
|
||||
virtual bool GoLeft(void) { if(m_value < 0) m_value = 0; return true; }
|
||||
virtual bool GoRight(void) { if(m_value > 1000) m_value = 1000; return true; }
|
||||
virtual bool GoLeftStill(void) { m_value -= 8; if(m_value < 0) m_value = 0; return true; }
|
||||
virtual bool GoRightStill(void) { m_value += 8; if(m_value > 1000) m_value = 1000; return true; }
|
||||
virtual bool GoFirst(void) { ActivateMenu(true); return true; }
|
||||
virtual bool GoLast(void) { ActivateMenu(true); return true; }
|
||||
virtual void SelectCurrentOptionUnderCursor(void) {}
|
||||
virtual void SelectDefaultCancelAction(void) {}
|
||||
virtual void ActivateMenu(bool first) { m_bActive = true; }
|
||||
virtual void DeactivateMenu(void) { m_bActive = false; }
|
||||
virtual int GetMenuSelection(void) { return m_value/10; }
|
||||
virtual void SetMenuSelection(int selection) { m_value = selection*10; }
|
||||
};
|
||||
|
||||
class CMenuSliderTriggered : public CMenuSlider
|
||||
{
|
||||
public:
|
||||
typedef void (*Trigger)(CMenuSliderTriggered *);
|
||||
|
||||
Trigger m_trigger;
|
||||
Trigger m_alwaysTrigger;
|
||||
|
||||
CMenuSliderTriggered(void)
|
||||
: m_trigger(nil), m_alwaysTrigger(nil) {}
|
||||
|
||||
void AddTickBox(float positionX, float positionY, float width, float heigthLeft, float heightRight, Trigger trigger, Trigger alwaysTrigger);
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual bool GoLeft(void);
|
||||
virtual bool GoRight(void);
|
||||
virtual bool GoLeftStill(void);
|
||||
virtual bool GoRightStill(void);
|
||||
};
|
||||
|
||||
|
||||
class CMenuLineLister : public CMenuBase
|
||||
{
|
||||
public:
|
||||
float m_width;
|
||||
float m_height;
|
||||
int m_numLines;
|
||||
CPlaceableShText m_linesLeft[NUM_LINELISTER_LINES_TOTAL];
|
||||
CPlaceableShText m_linesRight[NUM_LINELISTER_LINES_TOTAL];
|
||||
uint8 m_lineAlphas[NUM_LINELISTER_LINES_TOTAL];
|
||||
int8 m_lineFade[NUM_LINELISTER_LINES_TOTAL];
|
||||
float m_scrollPosition;
|
||||
float m_scrollSpeed;
|
||||
int field_10E8;
|
||||
float m_lineSpacing;
|
||||
|
||||
CMenuLineLister(void);
|
||||
|
||||
void SetLinesColor(const CRGBA &color);
|
||||
void ResetNumberOfTextLines(void);
|
||||
bool AddTextLine(wchar *left, wchar *right);
|
||||
|
||||
CPlaceableShText *GetLeftLine(int i) { return &m_linesLeft[(i%NUM_LINELISTER_LINES) + 15]; };
|
||||
CPlaceableShText *GetRightLine(int i) { return &m_linesRight[(i%NUM_LINELISTER_LINES) + 15]; };
|
||||
|
||||
virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
|
||||
virtual void DrawNormal(float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
|
||||
virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
|
||||
virtual void SetAlpha(uint8 alpha);
|
||||
virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
|
||||
virtual bool GoNext(void) { return false; }
|
||||
virtual bool GoPrev(void) { return false; }
|
||||
virtual bool GoDown(void) { return GoNext(); }
|
||||
virtual bool GoUp(void) { return GoPrev(); }
|
||||
virtual bool GoDownStill(void) { m_scrollSpeed = 0.0f; return true; }
|
||||
virtual bool GoUpStill(void) { m_scrollSpeed *= 6.0f; return true; }
|
||||
virtual bool GoLeft(void) { return true; }
|
||||
virtual bool GoRight(void) { return true; }
|
||||
virtual bool GoLeftStill(void) { return true; }
|
||||
virtual bool GoRightStill(void) { return true; }
|
||||
virtual bool GoFirst(void) { return true; }
|
||||
virtual bool GoLast(void) { return true; }
|
||||
virtual void SelectCurrentOptionUnderCursor(void) {}
|
||||
virtual void SelectDefaultCancelAction(void) {}
|
||||
virtual void ActivateMenu(bool first) {}
|
||||
virtual void DeactivateMenu(void) {}
|
||||
virtual int GetMenuSelection(void) { return -1; }
|
||||
virtual void SetMenuSelection(int selection) {}
|
||||
};
|
||||
|
||||
class CMenuPage
|
||||
{
|
||||
public:
|
||||
CMenuBase *m_controls[NUM_PAGE_WIDGETS];
|
||||
int m_numControls;
|
||||
CMenuBase *m_pCurrentControl;
|
||||
int m_cursor;
|
||||
|
||||
CMenuPage(void) { Initialise(); }
|
||||
void Initialise(void);
|
||||
bool AddMenu(CMenuBase *widget);
|
||||
|
||||
bool IsActiveMenuTwoState(void);
|
||||
void ActiveMenuTwoState_SelectNextPosition(void);
|
||||
void Draw(const CRGBA &,const CRGBA &, float, float);
|
||||
void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
|
||||
void DrawNormal(float x, float y);
|
||||
void ActivatePage(void);
|
||||
void SetAlpha(uint8 alpha);
|
||||
void SetShadows(bool, const CRGBA &, const CVector2D &);
|
||||
void GoPrev(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoPrev()) m_pCurrentControl->GoLast(); } }
|
||||
void GoNext(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoNext()) m_pCurrentControl->GoFirst(); } }
|
||||
void GoLeft(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoLeft()) m_pCurrentControl->GoLast(); } }
|
||||
void GoRight(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoRight()) m_pCurrentControl->GoFirst(); } }
|
||||
void GoUp(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoUp()) m_pCurrentControl->GoLast(); } }
|
||||
void GoDown(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoDown()) m_pCurrentControl->GoFirst(); } }
|
||||
void GoLeftStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoLeftStill(); }
|
||||
void GoRightStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoRightStill(); }
|
||||
void GoUpStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoUpStill(); }
|
||||
void GoDownStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoDownStill(); }
|
||||
void SelectDefaultCancelAction(void) { if(m_pCurrentControl) m_pCurrentControl->SelectDefaultCancelAction(); }
|
||||
void SelectCurrentOptionUnderCursor(void) { if(m_pCurrentControl) m_pCurrentControl->SelectCurrentOptionUnderCursor(); }
|
||||
|
||||
virtual void GoUpMenuOnPage(void);
|
||||
virtual void GoDownMenuOnPage(void);
|
||||
virtual void GoLeftMenuOnPage(void);
|
||||
virtual void GoRightMenuOnPage(void);
|
||||
};
|
||||
|
||||
class CMenuPageAnyMove : public CMenuPage
|
||||
{
|
||||
public:
|
||||
FEC_MOVETAB m_moveTab[NUM_PAGE_WIDGETS];
|
||||
|
||||
CMenuPageAnyMove(void) { Initialise(); }
|
||||
void Initialise(void);
|
||||
using CMenuPage::AddMenu;
|
||||
bool AddMenu(CMenuBase *widget, FEC_MOVETAB *moveTab);
|
||||
|
||||
virtual void GoUpMenuOnPage(void);
|
||||
virtual void GoDownMenuOnPage(void);
|
||||
virtual void GoLeftMenuOnPage(void);
|
||||
virtual void GoRightMenuOnPage(void);
|
||||
};
|
||||
6802
src/core/Frontend.cpp
Normal file
6802
src/core/Frontend.cpp
Normal file
File diff suppressed because it is too large
Load diff
839
src/core/Frontend.h
Normal file
839
src/core/Frontend.h
Normal file
|
|
@ -0,0 +1,839 @@
|
|||
#pragma once
|
||||
#ifdef PS2_MENU
|
||||
#include "Frontend_PS2.h"
|
||||
#else
|
||||
|
||||
#include "Sprite2d.h"
|
||||
|
||||
#ifdef PS2_LIKE_MENU
|
||||
#define MENUHEADER_POS_X 50.0f
|
||||
#define MENUHEADER_POS_Y 75.0f
|
||||
#define MENUHEADER_HEIGHT 1.3f
|
||||
#else
|
||||
#define MENUHEADER_POS_X 35.0f
|
||||
#define MENUHEADER_POS_Y 93.0f
|
||||
#define MENUHEADER_HEIGHT 1.6f
|
||||
#endif
|
||||
#define MENUHEADER_WIDTH 0.84f
|
||||
|
||||
#define MENU_X_MARGIN 40.0f
|
||||
#define MENUACTION_POS_Y 60.0f
|
||||
#define MENUACTION_SCALE_MULT 0.9f
|
||||
|
||||
#define MENURADIO_ICON_SCALE 60.0f
|
||||
|
||||
#define MENUSLIDER_X 256.0f
|
||||
#define MENUSLIDER_UNK 256.0f
|
||||
|
||||
#define MENUSLIDER_BARS 16
|
||||
#define MENUSLIDER_LOGICAL_BARS MENUSLIDER_BARS
|
||||
|
||||
#define BIGTEXT_X_SCALE 0.75f // For FONT_HEADING
|
||||
#define BIGTEXT_Y_SCALE 0.9f
|
||||
#define MEDIUMTEXT_X_SCALE 0.55f // For FONT_HEADING
|
||||
#define MEDIUMTEXT_Y_SCALE 0.8f
|
||||
#define SMALLTEXT_X_SCALE 0.45f // used for FONT_HEADING and FONT_BANK, but looks off for HEADING
|
||||
#define SMALLTEXT_Y_SCALE 0.7f
|
||||
#define SMALLESTTEXT_X_SCALE 0.4f // used for both FONT_HEADING and FONT_BANK
|
||||
#define SMALLESTTEXT_Y_SCALE 0.6f
|
||||
|
||||
#define HELPER_TEXT_LEFT_MARGIN 320.0f
|
||||
#define HELPER_TEXT_BOTTOM_MARGIN 120.0f
|
||||
|
||||
#define PLAYERSETUP_LIST_TOP 28.0f
|
||||
#define PLAYERSETUP_LIST_BOTTOM 125.0f
|
||||
#define PLAYERSETUP_LIST_LEFT 200.0f
|
||||
#define PLAYERSETUP_LIST_RIGHT 36.0f
|
||||
#ifdef FIX_BUGS // See the scrollbar button drawing code
|
||||
#define PLAYERSETUP_SCROLLBAR_WIDTH 19.0f
|
||||
#else
|
||||
#define PLAYERSETUP_SCROLLBAR_WIDTH 16.0f
|
||||
#endif
|
||||
#define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f
|
||||
#define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64
|
||||
#define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f
|
||||
#define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f
|
||||
#define PLAYERSETUP_LIST_BODY_TOP 47
|
||||
#define PLAYERSETUP_ROW_HEIGHT 9
|
||||
|
||||
#define STATS_SLIDE_Y_PER_SECOND 30.0f
|
||||
#define STATS_ROW_HEIGHT 20.0f
|
||||
#define STATS_ROW_X_MARGIN 50.0f
|
||||
#define STATS_BOTTOM_MARGIN 135.0f
|
||||
#define STATS_TOP_MARGIN 40.0f
|
||||
#define STATS_TOP_DIMMING_AREA_LENGTH (93.0f - STATS_TOP_MARGIN)
|
||||
#define STATS_BOTTOM_DIMMING_AREA_LENGTH 55.0f
|
||||
#define STATS_PUT_BACK_TO_BOTTOM_Y 50.0f
|
||||
#define STATS_RATING_X 24.0f
|
||||
#define STATS_RATING_Y 20.0f
|
||||
|
||||
#define BRIEFS_TOP_MARGIN 40.0f
|
||||
#define BRIEFS_LINE_X 50.0f
|
||||
#define BRIEFS_LINE_HEIGHT 60.0f
|
||||
|
||||
#define CONTSETUP_STANDARD_ROW_HEIGHT 10.7f
|
||||
#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_RIGHT 18.0f
|
||||
#define CONTSETUP_LIST_BOTTOM 120.0f
|
||||
#define CONTSETUP_LIST_LEFT 18.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_HEIGHT 25.0f
|
||||
|
||||
enum eFrontendSprites
|
||||
{
|
||||
FE2_MAINPANEL_UL,
|
||||
FE2_MAINPANEL_UR,
|
||||
FE2_MAINPANEL_DL,
|
||||
FE2_MAINPANEL_DR,
|
||||
FE2_MAINPANEL_DR2,
|
||||
FE2_TABACTIVE,
|
||||
FE_ICONBRIEF,
|
||||
FE_ICONSTATS,
|
||||
FE_ICONCONTROLS,
|
||||
FE_ICONSAVE,
|
||||
FE_ICONAUDIO,
|
||||
FE_ICONDISPLAY,
|
||||
FE_ICONLANGUAGE,
|
||||
FE_CONTROLLER,
|
||||
FE_CONTROLLERSH,
|
||||
FE_ARROWS1,
|
||||
FE_ARROWS2,
|
||||
FE_ARROWS3,
|
||||
FE_ARROWS4,
|
||||
FE_RADIO1,
|
||||
FE_RADIO2,
|
||||
FE_RADIO3,
|
||||
FE_RADIO4,
|
||||
FE_RADIO5,
|
||||
FE_RADIO6,
|
||||
FE_RADIO7,
|
||||
FE_RADIO8,
|
||||
FE_RADIO9,
|
||||
|
||||
NUM_FE_SPRITES
|
||||
};
|
||||
|
||||
enum eMenuSprites
|
||||
{
|
||||
MENUSPRITE_CONNECTION,
|
||||
MENUSPRITE_FINDGAME,
|
||||
MENUSPRITE_HOSTGAME,
|
||||
MENUSPRITE_MAINMENU,
|
||||
MENUSPRITE_PLAYERSET,
|
||||
MENUSPRITE_SINGLEPLAYER,
|
||||
MENUSPRITE_MULTIPLAYER,
|
||||
MENUSPRITE_DMALOGO,
|
||||
MENUSPRITE_GTALOGO,
|
||||
MENUSPRITE_RSTARLOGO,
|
||||
MENUSPRITE_GAMESPY,
|
||||
MENUSPRITE_MOUSE,
|
||||
MENUSPRITE_MOUSET,
|
||||
MENUSPRITE_MP3LOGO,
|
||||
MENUSPRITE_DOWNOFF,
|
||||
MENUSPRITE_DOWNON,
|
||||
MENUSPRITE_UPOFF,
|
||||
MENUSPRITE_UPON,
|
||||
MENUSPRITE_GTA3LOGO,
|
||||
MENUSPRITE_UNUSED,
|
||||
NUM_MENU_SPRITES
|
||||
};
|
||||
|
||||
enum eSaveSlot
|
||||
{
|
||||
SAVESLOT_NONE,
|
||||
SAVESLOT_0,
|
||||
SAVESLOT_1,
|
||||
SAVESLOT_2,
|
||||
SAVESLOT_3,
|
||||
SAVESLOT_4,
|
||||
SAVESLOT_5,
|
||||
SAVESLOT_6,
|
||||
SAVESLOT_7,
|
||||
SAVESLOT_8,
|
||||
SAVESLOT_LABEL = 36,
|
||||
};
|
||||
|
||||
#ifdef MENU_MAP
|
||||
enum MapSprites
|
||||
{
|
||||
MAPMID1,
|
||||
MAPMID2,
|
||||
MAPMID3,
|
||||
MAPBOT1,
|
||||
MAPBOT2,
|
||||
MAPBOT3,
|
||||
MAPTOP1,
|
||||
MAPTOP2,
|
||||
MAPTOP3,
|
||||
NUM_MAP_SPRITES
|
||||
};
|
||||
#endif
|
||||
|
||||
enum eMenuScreen
|
||||
{
|
||||
MENUPAGE_DISABLED = -1,
|
||||
MENUPAGE_NONE = 0,
|
||||
MENUPAGE_STATS = 1,
|
||||
MENUPAGE_NEW_GAME = 2,
|
||||
MENUPAGE_BRIEFS = 3,
|
||||
MENUPAGE_CONTROLLER_SETTINGS = 4,
|
||||
MENUPAGE_SOUND_SETTINGS = 5,
|
||||
MENUPAGE_DISPLAY_SETTINGS = 6,
|
||||
MENUPAGE_LANGUAGE_SETTINGS = 7,
|
||||
MENUPAGE_CHOOSE_LOAD_SLOT = 8,
|
||||
MENUPAGE_CHOOSE_DELETE_SLOT = 9,
|
||||
MENUPAGE_NEW_GAME_RELOAD = 10,
|
||||
MENUPAGE_LOAD_SLOT_CONFIRM = 11,
|
||||
MENUPAGE_DELETE_SLOT_CONFIRM = 12,
|
||||
MENUPAGE_NO_MEMORY_CARD = 13, // hud adjustment page in mobile
|
||||
MENUPAGE_LOADING_IN_PROGRESS = 14,
|
||||
MENUPAGE_DELETING_IN_PROGRESS = 15,
|
||||
MENUPAGE_PS2_LOAD_FAILED = 16,
|
||||
MENUPAGE_DELETE_FAILED = 17,
|
||||
MENUPAGE_DEBUG_MENU = 18,
|
||||
MENUPAGE_MEMORY_CARD_DEBUG = 19,
|
||||
MENUPAGE_MEMORY_CARD_TEST = 20,
|
||||
MENUPAGE_MULTIPLAYER_MAIN = 21,
|
||||
MENUPAGE_PS2_SAVE_FAILED = 22,
|
||||
MENUPAGE_PS2_SAVE_FAILED_2 = 23,
|
||||
MENUPAGE_SAVE = 24,
|
||||
MENUPAGE_NO_MEMORY_CARD_2 = 25,
|
||||
MENUPAGE_CHOOSE_SAVE_SLOT = 26,
|
||||
MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27,
|
||||
MENUPAGE_MULTIPLAYER_MAP = 28,
|
||||
MENUPAGE_MULTIPLAYER_CONNECTION = 29,
|
||||
MENUPAGE_MULTIPLAYER_FIND_GAME = 30,
|
||||
MENUPAGE_MULTIPLAYER_MODE = 31,
|
||||
MENUPAGE_MULTIPLAYER_CREATE = 32,
|
||||
MENUPAGE_MULTIPLAYER_START = 33,
|
||||
MENUPAGE_SKIN_SELECT_OLD = 34,
|
||||
MENUPAGE_CONTROLLER_PC = 35,
|
||||
MENUPAGE_CONTROLLER_PC_OLD1 = 36,
|
||||
MENUPAGE_CONTROLLER_PC_OLD2 = 37,
|
||||
MENUPAGE_CONTROLLER_PC_OLD3 = 38,
|
||||
MENUPAGE_CONTROLLER_PC_OLD4 = 39,
|
||||
MENUPAGE_CONTROLLER_DEBUG = 40,
|
||||
MENUPAGE_OPTIONS = 41,
|
||||
MENUPAGE_EXIT = 42,
|
||||
MENUPAGE_SAVING_IN_PROGRESS = 43,
|
||||
MENUPAGE_SAVE_SUCCESSFUL = 44,
|
||||
MENUPAGE_DELETING = 45,
|
||||
MENUPAGE_DELETE_SUCCESS = 46,
|
||||
MENUPAGE_SAVE_FAILED = 47,
|
||||
MENUPAGE_LOAD_FAILED = 48,
|
||||
MENUPAGE_LOAD_FAILED_2 = 49,
|
||||
MENUPAGE_FILTER_GAME = 50,
|
||||
MENUPAGE_START_MENU = 51,
|
||||
MENUPAGE_PAUSE_MENU = 52,
|
||||
MENUPAGE_CHOOSE_MODE = 53,
|
||||
MENUPAGE_SKIN_SELECT = 54,
|
||||
MENUPAGE_KEYBOARD_CONTROLS = 55,
|
||||
MENUPAGE_MOUSE_CONTROLS = 56,
|
||||
MENUPAGE_MISSION_RETRY = 57,
|
||||
#ifdef CUSTOM_FRONTEND_OPTIONS
|
||||
|
||||
#ifdef MENU_MAP
|
||||
MENUPAGE_MAP = 58,
|
||||
#endif
|
||||
#ifdef GRAPHICS_MENU_OPTIONS
|
||||
MENUPAGE_GRAPHICS_SETTINGS,
|
||||
#endif
|
||||
#ifdef DETECT_JOYSTICK_MENU
|
||||
MENUPAGE_DETECT_JOYSTICK,
|
||||
#endif
|
||||
|
||||
#endif
|
||||
MENUPAGE_UNK, // originally 58. Custom screens are inserted above, because last screen in CMenuScreens should always be empty to make CFO work
|
||||
MENUPAGES
|
||||
|
||||
};
|
||||
|
||||
enum eMenuAction
|
||||
{
|
||||
#ifdef CUSTOM_FRONTEND_OPTIONS
|
||||
MENUACTION_CFO_SLIDER = -3,
|
||||
MENUACTION_CFO_SELECT = -2,
|
||||
MENUACTION_CFO_DYNAMIC = -1,
|
||||
#endif
|
||||
MENUACTION_NOTHING,
|
||||
MENUACTION_LABEL,
|
||||
MENUACTION_CHANGEMENU,
|
||||
MENUACTION_CTRLVIBRATION,
|
||||
MENUACTION_CTRLCONFIG,
|
||||
MENUACTION_CTRLDISPLAY,
|
||||
MENUACTION_FRAMESYNC,
|
||||
MENUACTION_FRAMELIMIT,
|
||||
MENUACTION_TRAILS,
|
||||
MENUACTION_SUBTITLES,
|
||||
MENUACTION_WIDESCREEN,
|
||||
MENUACTION_BRIGHTNESS,
|
||||
MENUACTION_DRAWDIST,
|
||||
MENUACTION_MUSICVOLUME,
|
||||
MENUACTION_SFXVOLUME,
|
||||
MENUACTION_UNK15,
|
||||
MENUACTION_RADIO,
|
||||
MENUACTION_LANG_ENG,
|
||||
MENUACTION_LANG_FRE,
|
||||
MENUACTION_LANG_GER,
|
||||
MENUACTION_LANG_ITA,
|
||||
MENUACTION_LANG_SPA,
|
||||
MENUACTION_POPULATESLOTS_CHANGEMENU,
|
||||
MENUACTION_CHECKSAVE,
|
||||
MENUACTION_UNK24,
|
||||
MENUACTION_NEWGAME,
|
||||
MENUACTION_RELOADIDE,
|
||||
MENUACTION_RELOADIPL,
|
||||
MENUACTION_SETDBGFLAG,
|
||||
MENUACTION_SWITCHBIGWHITEDEBUGLIGHT,
|
||||
MENUACTION_PEDROADGROUPS,
|
||||
MENUACTION_CARROADGROUPS,
|
||||
MENUACTION_COLLISIONPOLYS,
|
||||
MENUACTION_REGMEMCARD1,
|
||||
MENUACTION_TESTFORMATMEMCARD1,
|
||||
MENUACTION_TESTUNFORMATMEMCARD1,
|
||||
MENUACTION_CREATEROOTDIR,
|
||||
MENUACTION_CREATELOADICONS,
|
||||
MENUACTION_FILLWITHGUFF,
|
||||
MENUACTION_SAVEONLYTHEGAME,
|
||||
MENUACTION_SAVEGAME,
|
||||
MENUACTION_SAVEGAMEUNDERGTA,
|
||||
MENUACTION_CREATECOPYPROTECTED,
|
||||
MENUACTION_TESTSAVE,
|
||||
MENUACTION_TESTLOAD,
|
||||
MENUACTION_TESTDELETE,
|
||||
MENUACTION_PARSEHEAP,
|
||||
MENUACTION_SHOWCULL,
|
||||
MENUACTION_MEMCARDSAVECONFIRM,
|
||||
MENUACTION_RESUME_FROM_SAVEZONE,
|
||||
MENUACTION_UNK50,
|
||||
MENUACTION_DEBUGSTREAM,
|
||||
MENUACTION_MPMAP_LIBERTY,
|
||||
MENUACTION_MPMAP_REDLIGHT,
|
||||
MENUACTION_MPMAP_CHINATOWN,
|
||||
MENUACTION_MPMAP_TOWER,
|
||||
MENUACTION_MPMAP_SEWER,
|
||||
MENUACTION_MPMAP_INDUSTPARK,
|
||||
MENUACTION_MPMAP_DOCKS,
|
||||
MENUACTION_MPMAP_STAUNTON,
|
||||
MENUACTION_MPMAP_DEATHMATCH1,
|
||||
MENUACTION_MPMAP_DEATHMATCH2,
|
||||
MENUACTION_MPMAP_TEAMDEATH1,
|
||||
MENUACTION_MPMAP_TEAMDEATH2,
|
||||
MENUACTION_MPMAP_STASH,
|
||||
MENUACTION_MPMAP_CAPTURE,
|
||||
MENUACTION_MPMAP_RATRACE,
|
||||
MENUACTION_MPMAP_DOMINATION,
|
||||
MENUACTION_STARTMP,
|
||||
MENUACTION_UNK69,
|
||||
MENUACTION_UNK70,
|
||||
MENUACTION_FINDMP,
|
||||
MENUACTION_KEYBOARDCTRLS,
|
||||
MENUACTION_UNK73,
|
||||
MENUACTION_INITMP,
|
||||
MENUACTION_MP_PLAYERCOLOR,
|
||||
MENUACTION_MP_PLAYERNAME,
|
||||
MENUACTION_MP_GAMENAME,
|
||||
MENUACTION_GETKEY,
|
||||
MENUACTION_SHOWHEADBOB,
|
||||
MENUACTION_UNK80,
|
||||
MENUACTION_INVVERT,
|
||||
MENUACTION_CANCELGAME,
|
||||
MENUACTION_MP_PLAYERNUMBER,
|
||||
MENUACTION_MOUSESENS,
|
||||
MENUACTION_CHECKMPGAMES,
|
||||
MENUACTION_CHECKMPPING,
|
||||
MENUACTION_MP_SERVER,
|
||||
MENUACTION_MP_MAP,
|
||||
MENUACTION_MP_GAMETYPE,
|
||||
MENUACTION_MP_LAN,
|
||||
MENUACTION_MP_INTERNET,
|
||||
MENUACTION_RESUME,
|
||||
MENUACTION_DONTCANCEL,
|
||||
MENUACTION_SCREENRES,
|
||||
MENUACTION_AUDIOHW,
|
||||
MENUACTION_SPEAKERCONF,
|
||||
MENUACTION_PLAYERSETUP,
|
||||
MENUACTION_RESTOREDEF,
|
||||
MENUACTION_CTRLMETHOD,
|
||||
MENUACTION_DYNAMICACOUSTIC,
|
||||
MENUACTION_LOADRADIO,
|
||||
MENUACTION_MOUSESTEER,
|
||||
MENUACTION_UNK103,
|
||||
MENUACTION_UNK104,
|
||||
MENUACTION_UNK105,
|
||||
MENUACTION_UNK106,
|
||||
MENUACTION_UNK107,
|
||||
MENUACTION_UNK108,
|
||||
MENUACTION_UNK109,
|
||||
MENUACTION_UNK110,
|
||||
MENUACTION_UNK111,
|
||||
MENUACTION_UNK112,
|
||||
MENUACTION_REJECT_RETRY,
|
||||
MENUACTION_UNK114,
|
||||
//#ifdef ANISOTROPIC_FILTERING
|
||||
// MENUACTION_MIPMAPS,
|
||||
// MENUACTION_TEXTURE_FILTERING,
|
||||
//#endif
|
||||
};
|
||||
|
||||
enum eCheckHover
|
||||
{
|
||||
HOVEROPTION_0,
|
||||
HOVEROPTION_1,
|
||||
HOVEROPTION_RANDOM_ITEM,
|
||||
HOVEROPTION_3,
|
||||
HOVEROPTION_4,
|
||||
HOVEROPTION_5,
|
||||
HOVEROPTION_6,
|
||||
HOVEROPTION_7,
|
||||
HOVEROPTION_8,
|
||||
HOVEROPTION_BACK, // also layer in controller setup and skin menu
|
||||
HOVEROPTION_10,
|
||||
HOVEROPTION_11,
|
||||
HOVEROPTION_OVER_SCROLL_UP,
|
||||
HOVEROPTION_OVER_SCROLL_DOWN,
|
||||
HOVEROPTION_CLICKED_SCROLL_UP,
|
||||
HOVEROPTION_CLICKED_SCROLL_DOWN,
|
||||
HOVEROPTION_HOLDING_SCROLLBAR,
|
||||
HOVEROPTION_PAGEUP,
|
||||
HOVEROPTION_PAGEDOWN,
|
||||
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_INCREASE_BRIGHTNESS,
|
||||
HOVEROPTION_DECREASE_BRIGHTNESS,
|
||||
HOVEROPTION_INCREASE_DRAWDIST,
|
||||
HOVEROPTION_DECREASE_DRAWDIST,
|
||||
HOVEROPTION_INCREASE_MUSICVOLUME,
|
||||
HOVEROPTION_DECREASE_MUSICVOLUME,
|
||||
HOVEROPTION_INCREASE_SFXVOLUME,
|
||||
HOVEROPTION_DECREASE_SFXVOLUME,
|
||||
HOVEROPTION_INCREASE_MOUSESENS,
|
||||
HOVEROPTION_DECREASE_MOUSESENS,
|
||||
#ifdef CUSTOM_FRONTEND_OPTIONS
|
||||
HOVEROPTION_INCREASE_CFO_SLIDER,
|
||||
HOVEROPTION_DECREASE_CFO_SLIDER,
|
||||
#endif
|
||||
HOVEROPTION_NOT_HOVERING,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_MENUROWS = 18,
|
||||
};
|
||||
|
||||
enum eControlMethod
|
||||
{
|
||||
CONTROL_STANDARD = 0,
|
||||
CONTROL_CLASSIC,
|
||||
};
|
||||
|
||||
// Why??
|
||||
enum ControllerSetupColumn
|
||||
{
|
||||
CONTSETUP_PED_COLUMN = 0,
|
||||
CONTSETUP_VEHICLE_COLUMN = 14,
|
||||
};
|
||||
|
||||
struct tSkinInfo
|
||||
{
|
||||
int32 skinId;
|
||||
char skinNameDisplayed[256];
|
||||
char skinNameOriginal[256];
|
||||
char date[256];
|
||||
tSkinInfo *nextSkin;
|
||||
};
|
||||
|
||||
struct BottomBarOption
|
||||
{
|
||||
char name[8];
|
||||
int32 screenId;
|
||||
};
|
||||
|
||||
#ifndef CUSTOM_FRONTEND_OPTIONS
|
||||
struct CMenuScreen
|
||||
{
|
||||
char m_ScreenName[8];
|
||||
int32 unk; // 2 on MENUPAGE_MULTIPLAYER_START, 1 on everywhere else, 0 on unused.
|
||||
int32 m_PreviousPage[2]; // eMenuScreen
|
||||
int32 m_ParentEntry[2]; // row
|
||||
|
||||
struct CMenuEntry
|
||||
{
|
||||
int32 m_Action; // eMenuAction
|
||||
char m_EntryName[8];
|
||||
int32 m_SaveSlot; // eSaveSlot
|
||||
int32 m_TargetMenu; // eMenuScreen
|
||||
} m_aEntries[NUM_MENUROWS];
|
||||
};
|
||||
extern CMenuScreen aScreens[MENUPAGES];
|
||||
#else
|
||||
#include "frontendoption.h"
|
||||
struct CCustomScreenLayout {
|
||||
eMenuSprites sprite;
|
||||
int columnWidth;
|
||||
int headerHeight;
|
||||
int lineHeight;
|
||||
int8 font;
|
||||
int8 alignment;
|
||||
bool showLeftRightHelper;
|
||||
float fontScaleX;
|
||||
float fontScaleY;
|
||||
};
|
||||
|
||||
struct CCFO
|
||||
{
|
||||
void *value;
|
||||
const char *saveCat;
|
||||
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;
|
||||
bool disableIfGameLoaded;
|
||||
|
||||
CCFOSelect() {};
|
||||
CCFOSelect(int8* value, const char* saveCat, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc = nil, bool disableIfGameLoaded = false){
|
||||
this->value = value;
|
||||
if (value)
|
||||
this->lastSavedValue = this->displayedValue = *value;
|
||||
|
||||
this->saveCat = saveCat;
|
||||
this->save = save;
|
||||
this->rightTexts = (char**)rightTexts;
|
||||
this->numRightTexts = numRightTexts;
|
||||
this->onlyApplyOnEnter = onlyApplyOnEnter;
|
||||
this->changeFunc = changeFunc;
|
||||
this->disableIfGameLoaded = disableIfGameLoaded;
|
||||
}
|
||||
};
|
||||
|
||||
// Value is float in here
|
||||
struct CCFOSlider : CCFO
|
||||
{
|
||||
ChangeFuncFloat changeFunc;
|
||||
float min;
|
||||
float max;
|
||||
|
||||
CCFOSlider() {};
|
||||
CCFOSlider(float* value, const char* saveCat, const char* save, float min, float max, ChangeFuncFloat changeFunc = nil){
|
||||
this->value = value;
|
||||
this->saveCat = saveCat;
|
||||
this->save = save;
|
||||
this->changeFunc = changeFunc;
|
||||
this->min = min;
|
||||
this->max = max;
|
||||
}
|
||||
};
|
||||
|
||||
struct CCFODynamic : CCFO
|
||||
{
|
||||
DrawFunc drawFunc;
|
||||
ButtonPressFunc buttonPressFunc;
|
||||
|
||||
CCFODynamic() {};
|
||||
CCFODynamic(int8* value, const char* saveCat, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){
|
||||
this->value = value;
|
||||
this->saveCat = saveCat;
|
||||
this->save = save;
|
||||
this->drawFunc = drawFunc;
|
||||
this->buttonPressFunc = buttonPressFunc;
|
||||
}
|
||||
};
|
||||
|
||||
struct CMenuScreenCustom
|
||||
{
|
||||
char m_ScreenName[8];
|
||||
int32 m_PreviousPage[2]; // 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;
|
||||
CCFOSlider *m_CFOSlider;
|
||||
};
|
||||
int32 m_SaveSlot; // eSaveSlot
|
||||
int32 m_TargetMenu; // eMenuScreen
|
||||
};
|
||||
} m_aEntries[NUM_MENUROWS];
|
||||
};
|
||||
extern CMenuScreenCustom aScreens[MENUPAGES];
|
||||
#endif
|
||||
|
||||
class CMenuManager
|
||||
{
|
||||
public:
|
||||
int32 m_nPrefsVideoMode;
|
||||
int32 m_nDisplayVideoMode;
|
||||
int8 m_nPrefsAudio3DProviderIndex;
|
||||
bool m_bKeyChangeNotProcessed;
|
||||
char m_aSkinName[256];
|
||||
int32 m_nHelperTextMsgId;
|
||||
bool m_bLanguageLoaded;
|
||||
bool m_bMenuActive;
|
||||
bool m_bMenuStateChanged;
|
||||
bool m_bWaitingForNewKeyBind;
|
||||
bool m_bWantToRestart;
|
||||
bool m_bFirstTime;
|
||||
bool m_bGameNotLoaded;
|
||||
int32 m_nMousePosX;
|
||||
int32 m_nMousePosY;
|
||||
int32 m_nMouseTempPosX;
|
||||
int32 m_nMouseTempPosY;
|
||||
bool m_bShowMouse;
|
||||
tSkinInfo m_pSkinListHead;
|
||||
tSkinInfo *m_pSelectedSkin;
|
||||
int32 m_nFirstVisibleRowOnList;
|
||||
float m_nScrollbarTopMargin;
|
||||
int32 m_nTotalListRow;
|
||||
int32 m_nSkinsTotal;
|
||||
char _unk0[4];
|
||||
int32 m_nSelectedListRow;
|
||||
bool m_bSkinsEnumerated;
|
||||
bool m_bQuitGameNoCD;
|
||||
bool m_bRenderGameInMenu;
|
||||
bool m_bSaveMenuActive;
|
||||
bool m_bWantToLoad;
|
||||
char field_455;
|
||||
bool m_bStartWaitingForKeyBind;
|
||||
bool m_bSpritesLoaded;
|
||||
CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES];
|
||||
CSprite2d m_aMenuSprites[NUM_MENU_SPRITES];
|
||||
int32 field_518;
|
||||
int32 m_nMenuFadeAlpha;
|
||||
bool m_bPressedPgUpOnList;
|
||||
bool m_bPressedPgDnOnList;
|
||||
bool m_bPressedUpOnList;
|
||||
bool m_bPressedDownOnList;
|
||||
bool m_bPressedScrollButton;
|
||||
int32 m_CurrCntrlAction;
|
||||
char _unk1[4];
|
||||
int32 m_nSelectedContSetupColumn;
|
||||
bool m_bKeyIsOK;
|
||||
bool field_535;
|
||||
int8 m_nCurrExLayer;
|
||||
int32 m_nHelperTextAlpha;
|
||||
int32 m_nMouseOldPosX;
|
||||
int32 m_nMouseOldPosY;
|
||||
int32 m_nHoverOption;
|
||||
int32 m_nCurrScreen;
|
||||
int32 m_nCurrOption;
|
||||
int32 m_nOptionMouseHovering;
|
||||
int32 m_nPrevScreen;
|
||||
uint32 field_558;
|
||||
int32 m_nCurrSaveSlot;
|
||||
int32 m_nScreenChangeDelayTimer;
|
||||
|
||||
#ifdef IMPROVED_VIDEOMODE
|
||||
int32 m_nPrefsWidth;
|
||||
int32 m_nPrefsHeight;
|
||||
int32 m_nPrefsDepth;
|
||||
int32 m_nPrefsWindowed;
|
||||
int32 m_nPrefsSubsystem;
|
||||
int32 m_nSelectedScreenMode;
|
||||
#endif
|
||||
#ifdef MULTISAMPLING
|
||||
static int8 m_nPrefsMSAALevel;
|
||||
static int8 m_nDisplayMSAALevel;
|
||||
#endif
|
||||
|
||||
enum LANGUAGE
|
||||
{
|
||||
LANGUAGE_AMERICAN,
|
||||
LANGUAGE_FRENCH,
|
||||
LANGUAGE_GERMAN,
|
||||
LANGUAGE_ITALIAN,
|
||||
LANGUAGE_SPANISH,
|
||||
#ifdef MORE_LANGUAGES
|
||||
LANGUAGE_POLISH,
|
||||
LANGUAGE_RUSSIAN,
|
||||
LANGUAGE_JAPANESE,
|
||||
#endif
|
||||
};
|
||||
public:
|
||||
bool GetIsMenuActive() {return !!m_bMenuActive;}
|
||||
|
||||
public:
|
||||
static int32 OS_Language;
|
||||
static int8 m_PrefsUseVibration;
|
||||
static int8 m_DisplayControllerOnFoot;
|
||||
static int8 m_PrefsUseWideScreen;
|
||||
static int8 m_PrefsRadioStation;
|
||||
static int8 m_PrefsVsync;
|
||||
static int8 m_PrefsVsyncDisp;
|
||||
static int8 m_PrefsFrameLimiter;
|
||||
static int8 m_PrefsShowSubtitles;
|
||||
static int8 m_PrefsSpeakers;
|
||||
static int32 m_ControlMethod;
|
||||
static int8 m_PrefsDMA;
|
||||
static int32 m_PrefsLanguage;
|
||||
static int32 m_PrefsBrightness;
|
||||
static float m_PrefsLOD;
|
||||
static int8 m_bFrontEnd_ReloadObrTxtGxt;
|
||||
static int32 m_PrefsMusicVolume;
|
||||
static int32 m_PrefsSfxVolume;
|
||||
static char m_PrefsSkinFile[256];
|
||||
static int32 m_KeyPressedCode;
|
||||
|
||||
static bool m_bStartUpFrontEndRequested;
|
||||
static bool m_bShutDownFrontEndRequested;
|
||||
static bool m_PrefsAllowNastyGame;
|
||||
|
||||
static uint8 m_PrefsStereoMono;
|
||||
static int32 m_SelectedMap;
|
||||
static int32 m_SelectedGameType;
|
||||
static uint8 m_PrefsPlayerRed;
|
||||
static uint8 m_PrefsPlayerGreen;
|
||||
static uint8 m_PrefsPlayerBlue;
|
||||
|
||||
#ifdef CUTSCENE_BORDERS_SWITCH
|
||||
static bool m_PrefsCutsceneBorders;
|
||||
#endif
|
||||
|
||||
#ifndef MASTER
|
||||
static bool m_PrefsMarketing;
|
||||
static bool m_PrefsDisableTutorials;
|
||||
#endif // !MASTER
|
||||
|
||||
#ifdef MENU_MAP
|
||||
static bool bMenuMapActive;
|
||||
static float fMapSize;
|
||||
static float fMapCenterY;
|
||||
static float fMapCenterX;
|
||||
static CSprite2d m_aMapSprites[NUM_MAP_SPRITES];
|
||||
void PrintMap();
|
||||
#endif
|
||||
|
||||
#ifdef NO_ISLAND_LOADING
|
||||
enum
|
||||
{
|
||||
ISLAND_LOADING_LOW = 0,
|
||||
ISLAND_LOADING_MEDIUM,
|
||||
ISLAND_LOADING_HIGH
|
||||
};
|
||||
|
||||
static 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)
|
||||
#else
|
||||
#define ISLAND_LOADING_IS(p)
|
||||
#define ISLAND_LOADING_ISNT(p)
|
||||
#endif
|
||||
|
||||
#ifdef GAMEPAD_MENU
|
||||
enum
|
||||
{
|
||||
CONTROLLER_DUALSHOCK2 = 0,
|
||||
CONTROLLER_DUALSHOCK3,
|
||||
CONTROLLER_DUALSHOCK4,
|
||||
CONTROLLER_XBOX360,
|
||||
CONTROLLER_XBOXONE,
|
||||
CONTROLLER_NINTENDO_SWITCH,
|
||||
};
|
||||
|
||||
static int8 m_PrefsControllerType;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2);
|
||||
static void CentreMousePointer();
|
||||
void CheckCodesForControls(int);
|
||||
bool CheckHover(int x1, int x2, int y1, int y2);
|
||||
void CheckSliderMovement(int);
|
||||
int CostructStatLine(int);
|
||||
void DisplayHelperText();
|
||||
int DisplaySlider(float, float, float, float, float, float);
|
||||
void DoSettingsBeforeStartingAGame();
|
||||
void Draw();
|
||||
void DrawControllerBound(int32, int32, int32, int8);
|
||||
void DrawControllerScreenExtraText(int, int, int);
|
||||
void DrawControllerSetupScreen();
|
||||
void DrawFrontEnd();
|
||||
void DrawFrontEndNormal();
|
||||
#ifdef PS2_SAVE_DIALOG
|
||||
void DrawFrontEndSaveZone();
|
||||
#endif
|
||||
void DrawPlayerSetupScreen();
|
||||
int FadeIn(int alpha);
|
||||
void FilterOutColorMarkersFromString(wchar*, CRGBA &);
|
||||
int GetStartOptionsCntrlConfigScreens();
|
||||
static void InitialiseChangedLanguageSettings();
|
||||
void LoadAllTextures();
|
||||
void LoadSettings();
|
||||
void MessageScreen(const char *);
|
||||
void PickNewPlayerColour();
|
||||
void PrintBriefs();
|
||||
static void PrintErrorMessage();
|
||||
void PrintStats();
|
||||
void Process();
|
||||
void ProcessButtonPresses();
|
||||
void ProcessOnOffMenuOptions();
|
||||
static void RequestFrontEndShutDown();
|
||||
static void RequestFrontEndStartUp();
|
||||
void ResetHelperText();
|
||||
void SaveLoadFileError_SetUpErrorScreen();
|
||||
void SaveSettings();
|
||||
void SetHelperText(int text);
|
||||
void ShutdownJustMenu();
|
||||
float StretchX(float);
|
||||
float StretchY(float);
|
||||
void SwitchMenuOnAndOff();
|
||||
void UnloadTextures();
|
||||
void WaitForUserCD();
|
||||
void PrintController();
|
||||
int GetNumOptionsCntrlConfigScreens();
|
||||
int ConstructStatLine(int);
|
||||
|
||||
// Those are either inlined in game, not in function yet, or I can't believe that they're not inlined.
|
||||
// Names were made up by me.
|
||||
void ThingsToDoBeforeGoingBack();
|
||||
void ScrollUpListByOne();
|
||||
void ScrollDownListByOne();
|
||||
void PageUpList(bool);
|
||||
void PageDownList(bool);
|
||||
int8 GetPreviousPageOption();
|
||||
void ProcessList(bool &goBack, bool &optionSelected);
|
||||
#ifdef GAMEPAD_MENU
|
||||
void LoadController(int8 type);
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef IMPROVED_VIDEOMODE
|
||||
VALIDATE_SIZE(CMenuManager, 0x564);
|
||||
#endif
|
||||
|
||||
extern CMenuManager FrontEndMenuManager;
|
||||
|
||||
#endif
|
||||
1393
src/core/FrontendTriggers.h
Normal file
1393
src/core/FrontendTriggers.h
Normal file
File diff suppressed because it is too large
Load diff
3033
src/core/Frontend_PS2.cpp
Normal file
3033
src/core/Frontend_PS2.cpp
Normal file
File diff suppressed because it is too large
Load diff
245
src/core/Frontend_PS2.h
Normal file
245
src/core/Frontend_PS2.h
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
#pragma once
|
||||
#include "Sprite2d.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PAGE_STATS,
|
||||
PAGE_LOAD,
|
||||
PAGE_BRIEFS,
|
||||
PAGE_CONTROLS,
|
||||
PAGE_AUDIO,
|
||||
PAGE_DISPLAY,
|
||||
PAGE_LANGUAGE,
|
||||
|
||||
NUM_PAGES,
|
||||
PAGE_FIRST = PAGE_STATS,
|
||||
PAGE_LAST = PAGE_LANGUAGE,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PAGESTATE_NORMAL = 0,
|
||||
PAGESTATE_HIGHLIGHTED,
|
||||
PAGESTATE_SELECTED
|
||||
};
|
||||
|
||||
|
||||
enum eFrontendSprites
|
||||
{
|
||||
FE2_MAINPANEL_UL,
|
||||
FE2_MAINPANEL_UR,
|
||||
FE2_MAINPANEL_DL,
|
||||
FE2_MAINPANEL_DR,
|
||||
FE2_MAINPANEL_DR2,
|
||||
FE2_TABACTIVE,
|
||||
FE_ICONBRIEF,
|
||||
FE_ICONSTATS,
|
||||
FE_ICONCONTROLS,
|
||||
FE_ICONSAVE,
|
||||
FE_ICONAUDIO,
|
||||
FE_ICONDISPLAY,
|
||||
FE_ICONLANGUAGE,
|
||||
FE_CONTROLLER,
|
||||
FE_CONTROLLERSH,
|
||||
FE_ARROWS1,
|
||||
FE_ARROWS2,
|
||||
FE_ARROWS3,
|
||||
FE_ARROWS4,
|
||||
FE_RADIO1,
|
||||
FE_RADIO2,
|
||||
FE_RADIO3,
|
||||
FE_RADIO4,
|
||||
FE_RADIO5,
|
||||
FE_RADIO6,
|
||||
FE_RADIO7,
|
||||
FE_RADIO8,
|
||||
FE_RADIO9,
|
||||
|
||||
NUM_FE_SPRITES
|
||||
};
|
||||
|
||||
|
||||
class CSprite2d;
|
||||
class CVector2D;
|
||||
|
||||
#ifdef GTA_PC
|
||||
enum eControlMethod
|
||||
{
|
||||
CONTROL_STANDARD = 0,
|
||||
CONTROL_CLASSIC,
|
||||
};
|
||||
#endif
|
||||
|
||||
class CMenuManager
|
||||
{
|
||||
public:
|
||||
enum LANGUAGE
|
||||
{
|
||||
LANGUAGE_AMERICAN,
|
||||
LANGUAGE_FRENCH,
|
||||
LANGUAGE_GERMAN,
|
||||
LANGUAGE_ITALIAN,
|
||||
LANGUAGE_SPANISH,
|
||||
#ifdef MORE_LANGUAGES
|
||||
LANGUAGE_POLISH,
|
||||
LANGUAGE_RUSSIAN,
|
||||
LANGUAGE_JAPANESE,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum CONTRCONFIG
|
||||
{
|
||||
CONFIG_1 = 0,
|
||||
CONFIG_2,
|
||||
CONFIG_3,
|
||||
CONFIG_4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_SPRIRES = 28,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PAGESTATE_NORMAL = 0,
|
||||
PAGESTATE_HIGHLIGHTED = 1,
|
||||
PAGESTATE_SELELECTED = 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SLIDE_TO_BOTTOM = 0,
|
||||
SLIDE_TO_RIGHT,
|
||||
SLIDE_TO_TOP,
|
||||
SLIDE_TO_LEFT,
|
||||
SLIDE_MAX
|
||||
};
|
||||
|
||||
int32 m_currentPage;
|
||||
int32 m_newPage;
|
||||
int32 m_pageState;
|
||||
uint32 m_nPageLeftTimer;
|
||||
uint32 m_nPageRightTimer;
|
||||
uint32 m_nChangePageTimer;
|
||||
int field_18;
|
||||
uint8 m_fade;
|
||||
uint8 m_someAlpha;
|
||||
//char field_1E; // unused ?
|
||||
//char field_1F; // unused ?
|
||||
uint32 m_nStartPauseTimer;
|
||||
uint32 m_nEndPauseTimer;
|
||||
CVector2D m_position;
|
||||
uint8 m_nSlidingDir;
|
||||
//char field_31; // unused ?
|
||||
//char field_32; // unused ?
|
||||
//char field_33; // unused ?
|
||||
bool m_bInitialised;
|
||||
bool m_bWantToUpdateContent;
|
||||
bool m_bMenuActive;
|
||||
bool m_bWantToRestart;
|
||||
//char field_38; //unused ?
|
||||
bool m_bRenderGameInMenu;
|
||||
bool m_bSaveMenuActive;
|
||||
bool m_bInSaveZone;
|
||||
char field_3C;
|
||||
bool m_bTexturesLoaded;
|
||||
//char field_3E; //unused ?
|
||||
//char field_3F; //unused ?
|
||||
CSprite2d m_sprites[NUM_SPRIRES];
|
||||
|
||||
static int32 m_PrefsSfxVolume;
|
||||
static int32 m_PrefsMusicVolume;
|
||||
static int32 m_PrefsBrightness;
|
||||
static bool m_PrefsShowTrails;
|
||||
static bool m_PrefsShowSubtitles;
|
||||
static bool m_PrefsAllowNastyGame;
|
||||
static int32 m_PrefsRadioStation;
|
||||
static int32 m_PrefsStereoMono;
|
||||
static int8 m_PrefsUseWideScreen;
|
||||
static int32 m_PrefsLanguage;
|
||||
static CONTRCONFIG m_PrefsControllerConfig;
|
||||
static bool m_PrefsUseVibration;
|
||||
|
||||
#define ISLAND_LOADING_IS(p)
|
||||
#define ISLAND_LOADING_ISNT(p)
|
||||
#ifdef GTA_PC
|
||||
bool m_bQuitGameNoCD;
|
||||
|
||||
int32 m_nMouseTempPosX;
|
||||
int32 m_nMouseTempPosY;
|
||||
int32 m_nPrefsVideoMode;
|
||||
int32 m_nDisplayVideoMode;
|
||||
int8 m_nPrefsAudio3DProviderIndex;
|
||||
|
||||
static int32 OS_Language;
|
||||
static int8 m_PrefsVsync;
|
||||
static int8 m_PrefsVsyncDisp;
|
||||
static int8 m_PrefsFrameLimiter;
|
||||
static int8 m_PrefsSpeakers;
|
||||
static int32 m_ControlMethod;
|
||||
static int8 m_PrefsDMA;
|
||||
static float m_PrefsLOD;
|
||||
static char m_PrefsSkinFile[256];
|
||||
|
||||
#ifndef MASTER
|
||||
static bool m_PrefsMarketing;
|
||||
static bool m_PrefsDisableTutorials;
|
||||
#endif // !MASTER
|
||||
|
||||
#ifdef MENU_MAP
|
||||
static bool bMenuMapActive;
|
||||
static float fMapSize;
|
||||
static float fMapCenterY;
|
||||
static float fMapCenterX;
|
||||
#endif
|
||||
|
||||
#ifdef IMPROVED_VIDEOMODE
|
||||
int32 m_nPrefsWidth = 640;
|
||||
int32 m_nPrefsHeight = 480;
|
||||
int32 m_nPrefsDepth = 32;
|
||||
int32 m_nPrefsWindowed = 1;
|
||||
int32 m_nPrefsSubsystem;
|
||||
int32 m_nSelectedScreenMode;
|
||||
#endif
|
||||
|
||||
void WaitForUserCD() { }
|
||||
#endif
|
||||
|
||||
bool GetIsMenuActive() {return !!m_bMenuActive;}
|
||||
|
||||
CMenuManager(void);
|
||||
#ifdef FIX_BUGS
|
||||
~CMenuManager(void)
|
||||
{
|
||||
UnloadTextures();
|
||||
}
|
||||
#endif
|
||||
|
||||
void LoadAllTextures(void);
|
||||
void UnloadTextures(void);
|
||||
|
||||
void InitialiseMenusOnce(void);
|
||||
void InitialiseChangedLanguageSettings(void);
|
||||
void InitialiseMenuContents(void);
|
||||
void AnaliseMenuContents(void);
|
||||
void InitialiseMenuContentsAfterLoadingGame(void);
|
||||
void DrawFrontEnd(void);
|
||||
void DrawFrontEndNormal(void);
|
||||
void DrawFrontEndSaveZone(void);
|
||||
void DrawMemoryCardStartUpMenus(void);
|
||||
void Process(void);
|
||||
void WorkOutMenuState(uint8 bExit);
|
||||
void ProcessControllerInput(void);
|
||||
void ProcessDPadLeftJustDown(void);
|
||||
void ProcessDPadRightJustDown(void);
|
||||
void ProcessDPadUpJustDown(void);
|
||||
void ProcessDPadDownJustDown(void);
|
||||
void ProcessDPadTriangleJustDown(void);
|
||||
void ProcessDPadCrossJustDown(void);
|
||||
void DoHackingMenusAtPageBrowse(void);
|
||||
void SetSoundLevelsForMusicMenu(void);
|
||||
void FilterOutColorMarkersFromString(wchar *string, CRGBA &color);
|
||||
};
|
||||
|
||||
extern CMenuManager FrontEndMenuManager;
|
||||
1464
src/core/Game.cpp
Normal file
1464
src/core/Game.cpp
Normal file
File diff suppressed because it is too large
Load diff
49
src/core/Game.h
Normal file
49
src/core/Game.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
enum eLevelName {
|
||||
LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
|
||||
LEVEL_GENERIC = 0,
|
||||
LEVEL_INDUSTRIAL,
|
||||
LEVEL_COMMERCIAL,
|
||||
LEVEL_SUBURBAN,
|
||||
NUM_LEVELS
|
||||
};
|
||||
|
||||
class CGame
|
||||
{
|
||||
public:
|
||||
static eLevelName currLevel;
|
||||
static bool bDemoMode;
|
||||
static bool nastyGame;
|
||||
static bool frenchGame;
|
||||
static bool germanGame;
|
||||
#ifdef MORE_LANGUAGES
|
||||
static bool russianGame;
|
||||
static bool japaneseGame;
|
||||
#endif
|
||||
static bool noProstitutes;
|
||||
static bool playingIntro;
|
||||
static char aDatFile[32];
|
||||
|
||||
static bool InitialiseOnceBeforeRW(void);
|
||||
static bool InitialiseRenderWare(void);
|
||||
static void ShutdownRenderWare(void);
|
||||
static bool InitialiseOnceAfterRW(void);
|
||||
static void FinalShutdown(void);
|
||||
#if GTA_VERSION <= GTA3_PS2_160
|
||||
static bool Initialise(void);
|
||||
#else
|
||||
static bool Initialise(const char *datFile);
|
||||
#endif
|
||||
static bool ShutDown(void);
|
||||
static void ReInitGameObjectVariables(void);
|
||||
static void ReloadIPLs(void);
|
||||
static void ShutDownForRestart(void);
|
||||
static void InitialiseWhenRestarting(void);
|
||||
static void Process(void);
|
||||
|
||||
// NB: these do something on PS2
|
||||
static void TidyUpMemory(bool, bool);
|
||||
static void DrasticTidyUpMemory(bool);
|
||||
static void ProcessTidyUpMemory(void);
|
||||
};
|
||||
157
src/core/General.h
Normal file
157
src/core/General.h
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#pragma once
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
class CGeneral
|
||||
{
|
||||
public:
|
||||
static float GetATanOfXY(float x, float y){
|
||||
if(x == 0.0f && y == 0.0f)
|
||||
return 0.0f;
|
||||
float xabs = Abs(x);
|
||||
float yabs = Abs(y);
|
||||
|
||||
if(xabs < yabs){
|
||||
if(y > 0.0f){
|
||||
if(x > 0.0f)
|
||||
return 0.5f*PI - Atan2(x / y, 1.0f);
|
||||
else
|
||||
return 0.5f*PI + Atan2(-x / y, 1.0f);
|
||||
}else{
|
||||
if(x > 0.0f)
|
||||
return 1.5f*PI + Atan2(x / -y, 1.0f);
|
||||
else
|
||||
return 1.5f*PI - Atan2(-x / -y, 1.0f);
|
||||
}
|
||||
}else{
|
||||
if(y > 0.0f){
|
||||
if(x > 0.0f)
|
||||
return Atan2(y / x, 1.0f);
|
||||
else
|
||||
return PI - Atan2(y / -x, 1.0f);
|
||||
}else{
|
||||
if(x > 0.0f)
|
||||
return 2.0f*PI - Atan2(-y / x, 1.0f);
|
||||
else
|
||||
return PI + Atan2(-y / -x, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float LimitAngle(float angle)
|
||||
{
|
||||
float result = angle;
|
||||
|
||||
while (result >= 180.0f) {
|
||||
result -= 2 * 180.0f;
|
||||
}
|
||||
|
||||
while (result < -180.0f) {
|
||||
result += 2 * 180.0f;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static float LimitRadianAngle(float angle)
|
||||
{
|
||||
float result = Clamp(angle, -25.0f, 25.0f);
|
||||
|
||||
while (result >= PI) {
|
||||
result -= 2 * PI;
|
||||
}
|
||||
|
||||
while (result < -PI) {
|
||||
result += 2 * PI;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns an angle such that x2/y2 looks at x1/y1 with its forward vector if rotated by that angle
|
||||
static float GetRadianAngleBetweenPoints(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
float x = x2 - x1;
|
||||
float y = y2 - y1;
|
||||
|
||||
if (y == 0.0f)
|
||||
y = 0.0001f;
|
||||
|
||||
if (x > 0.0f) {
|
||||
if (y > 0.0f)
|
||||
return PI - Atan2(x / y, 1.0f);
|
||||
else
|
||||
return -Atan2(x / y, 1.0f);
|
||||
} else {
|
||||
if (y > 0.0f)
|
||||
return -(PI + Atan2(x / y, 1.0f));
|
||||
else
|
||||
return -Atan2(x / y, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static float GetAngleBetweenPoints(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
return RADTODEG(GetRadianAngleBetweenPoints(x1, y1, x2, y2));
|
||||
}
|
||||
|
||||
// should return direction in 0-8 range. fits perfectly to peds' path directions.
|
||||
static int GetNodeHeadingFromVector(float x, float y)
|
||||
{
|
||||
float angle = CGeneral::GetRadianAngleBetweenPoints(x, y, 0.0f, 0.0f);
|
||||
if (angle < 0.0f)
|
||||
angle += TWOPI;
|
||||
|
||||
angle = DEGTORAD(22.5f) + TWOPI - angle;
|
||||
|
||||
if (angle >= TWOPI)
|
||||
angle -= TWOPI;
|
||||
|
||||
return (int)Floor(angle / DEGTORAD(45.0f));
|
||||
}
|
||||
|
||||
// Unlike usual string comparison functions, these don't care about greater or lesser
|
||||
static bool faststrcmp(const char *str1, const char *str2)
|
||||
{
|
||||
for (; *str1; str1++, str2++) {
|
||||
if (*str1 != *str2)
|
||||
return true;
|
||||
}
|
||||
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++) {
|
||||
#ifndef ASCII_STRCMP
|
||||
if (toupper(*str1) != toupper(*str2))
|
||||
#else
|
||||
if (__ascii_toupper(*str1) != __ascii_toupper(*str2))
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return *str2 != '\0';
|
||||
}
|
||||
|
||||
// not too sure about all these...
|
||||
static uint16 GetRandomNumber(void)
|
||||
{ return myrand() & MYRAND_MAX; }
|
||||
static bool GetRandomTrueFalse(void)
|
||||
{ return GetRandomNumber() < MYRAND_MAX / 2; }
|
||||
// Probably don't want to ever reach high
|
||||
static float GetRandomNumberInRange(float low, float high)
|
||||
{ return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); }
|
||||
|
||||
static int32 GetRandomNumberInRange(int32 low, int32 high)
|
||||
{ return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); }
|
||||
};
|
||||
28
src/core/IniFile.cpp
Normal file
28
src/core/IniFile.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "IniFile.h"
|
||||
|
||||
#include "CarCtrl.h"
|
||||
#include "FileMgr.h"
|
||||
#include "main.h"
|
||||
#include "Population.h"
|
||||
|
||||
float CIniFile::PedNumberMultiplier = 1.0f;
|
||||
float CIniFile::CarNumberMultiplier = 1.0f;
|
||||
|
||||
void CIniFile::LoadIniFile()
|
||||
{
|
||||
CFileMgr::SetDir("");
|
||||
int f = CFileMgr::OpenFile("gta3.ini", "r");
|
||||
if (f){
|
||||
CFileMgr::ReadLine(f, gString, 200);
|
||||
sscanf(gString, "%f", &PedNumberMultiplier);
|
||||
PedNumberMultiplier = Min(3.0f, Max(0.5f, PedNumberMultiplier));
|
||||
CFileMgr::ReadLine(f, gString, 200);
|
||||
sscanf(gString, "%f", &CarNumberMultiplier);
|
||||
CarNumberMultiplier = Min(3.0f, Max(0.5f, CarNumberMultiplier));
|
||||
CFileMgr::CloseFile(f);
|
||||
}
|
||||
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * PedNumberMultiplier;
|
||||
CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * CarNumberMultiplier;
|
||||
}
|
||||
13
src/core/IniFile.h
Normal file
13
src/core/IniFile.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#define DEFAULT_MAX_NUMBER_OF_PEDS 25.0f
|
||||
#define DEFAULT_MAX_NUMBER_OF_CARS 12.0f
|
||||
|
||||
class CIniFile
|
||||
{
|
||||
public:
|
||||
static void LoadIniFile();
|
||||
|
||||
static float PedNumberMultiplier;
|
||||
static float CarNumberMultiplier;
|
||||
};
|
||||
26
src/core/Lists.cpp
Normal file
26
src/core/Lists.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "common.h"
|
||||
#include "Pools.h"
|
||||
#include "Lists.h"
|
||||
|
||||
void*
|
||||
CPtrNode::operator new(size_t){
|
||||
CPtrNode *node = CPools::GetPtrNodePool()->New();
|
||||
assert(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
CPtrNode::operator delete(void *p, size_t){
|
||||
CPools::GetPtrNodePool()->Delete((CPtrNode*)p);
|
||||
}
|
||||
|
||||
void*
|
||||
CEntryInfoNode::operator new(size_t){
|
||||
CEntryInfoNode *node = CPools::GetEntryInfoNodePool()->New();
|
||||
assert(node);
|
||||
return node;
|
||||
}
|
||||
void
|
||||
CEntryInfoNode::operator delete(void *p, size_t){
|
||||
CPools::GetEntryInfoNodePool()->Delete((CEntryInfoNode*)p);
|
||||
}
|
||||
130
src/core/Lists.h
Normal file
130
src/core/Lists.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#pragma once
|
||||
|
||||
class CPtrNode
|
||||
{
|
||||
public:
|
||||
void *item;
|
||||
CPtrNode *prev;
|
||||
CPtrNode *next;
|
||||
|
||||
void *operator new(size_t);
|
||||
void operator delete(void *p, size_t);
|
||||
};
|
||||
|
||||
class CPtrList
|
||||
{
|
||||
public:
|
||||
CPtrNode *first;
|
||||
|
||||
CPtrList(void) { first = nil; }
|
||||
~CPtrList(void) { Flush(); }
|
||||
CPtrNode *FindItem(void *item){
|
||||
CPtrNode *node;
|
||||
for(node = first; node; node = node->next)
|
||||
if(node->item == item)
|
||||
return node;
|
||||
return nil;
|
||||
}
|
||||
CPtrNode *InsertNode(CPtrNode *node){
|
||||
node->prev = nil;
|
||||
node->next = first;
|
||||
if(first)
|
||||
first->prev = node;
|
||||
first = node;
|
||||
return node;
|
||||
}
|
||||
CPtrNode *InsertItem(void *item){
|
||||
CPtrNode *node = new CPtrNode;
|
||||
node->item = item;
|
||||
InsertNode(node);
|
||||
return node;
|
||||
}
|
||||
void RemoveNode(CPtrNode *node){
|
||||
if(node == first)
|
||||
first = node->next;
|
||||
if(node->prev)
|
||||
node->prev->next = node->next;
|
||||
if(node->next)
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
void DeleteNode(CPtrNode *node){
|
||||
RemoveNode(node);
|
||||
delete node;
|
||||
}
|
||||
void RemoveItem(void *item){
|
||||
CPtrNode *node, *next;
|
||||
for(node = first; node; node = next){
|
||||
next = node->next;
|
||||
if(node->item == item)
|
||||
DeleteNode(node);
|
||||
}
|
||||
}
|
||||
void Flush(void){
|
||||
CPtrNode *node, *next;
|
||||
for(node = first; node; node = next){
|
||||
next = node->next;
|
||||
DeleteNode(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CSector;
|
||||
|
||||
// This records in which sector list a Physical is
|
||||
class CEntryInfoNode
|
||||
{
|
||||
public:
|
||||
CPtrList *list; // list in sector
|
||||
CPtrNode *listnode; // node in list
|
||||
CSector *sector;
|
||||
|
||||
CEntryInfoNode *prev;
|
||||
CEntryInfoNode *next;
|
||||
|
||||
void *operator new(size_t);
|
||||
void operator delete(void *p, size_t);
|
||||
};
|
||||
|
||||
class CEntryInfoList
|
||||
{
|
||||
public:
|
||||
CEntryInfoNode *first;
|
||||
|
||||
CEntryInfoList(void) { first = nil; }
|
||||
~CEntryInfoList(void) { Flush(); }
|
||||
CEntryInfoNode *InsertNode(CEntryInfoNode *node){
|
||||
node->prev = nil;
|
||||
node->next = first;
|
||||
if(first)
|
||||
first->prev = node;
|
||||
first = node;
|
||||
return node;
|
||||
}
|
||||
CEntryInfoNode *InsertItem(CPtrList *list, CPtrNode *listnode, CSector *sect){
|
||||
CEntryInfoNode *node = new CEntryInfoNode;
|
||||
node->list = list;
|
||||
node->listnode = listnode;
|
||||
node->sector = sect;
|
||||
InsertNode(node);
|
||||
return node;
|
||||
}
|
||||
void RemoveNode(CEntryInfoNode *node){
|
||||
if(node == first)
|
||||
first = node->next;
|
||||
if(node->prev)
|
||||
node->prev->next = node->next;
|
||||
if(node->next)
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
void DeleteNode(CEntryInfoNode *node){
|
||||
RemoveNode(node);
|
||||
delete node;
|
||||
}
|
||||
void Flush(void){
|
||||
CEntryInfoNode *node, *next;
|
||||
for(node = first; node; node = next){
|
||||
next = node->next;
|
||||
DeleteNode(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
453
src/core/MenuScreens.cpp
Normal file
453
src/core/MenuScreens.cpp
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
#include "common.h"
|
||||
#include "Frontend.h"
|
||||
#ifdef PC_MENU
|
||||
|
||||
// Please don't touch this file, except for bug fixing or ports.
|
||||
// Check MenuScreensCustom.cpp
|
||||
|
||||
#ifndef CUSTOM_FRONTEND_OPTIONS
|
||||
CMenuScreen aScreens[MENUPAGES] = {
|
||||
// MENUPAGE_NONE = 0
|
||||
{ "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, },
|
||||
|
||||
// MENUPAGE_STATS = 1
|
||||
{ "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_NEW_GAME = 2
|
||||
{ "FET_SGA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1,
|
||||
MENUACTION_CHANGEMENU, "FES_SNG", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD,
|
||||
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMLOAD", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
|
||||
MENUACTION_POPULATESLOTS_CHANGEMENU, "FES_DGA", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_BRIEFS = 3
|
||||
{ "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_SETTINGS = 4
|
||||
{ "FET_CON", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
|
||||
MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
|
||||
MENUACTION_CTRLDISPLAY, "FEC_CDP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
|
||||
MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_SOUND_SETTINGS = 5
|
||||
{ "FET_AUD", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 1, 1,
|
||||
MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
MENUACTION_SFXVOLUME, "FEA_SFX", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
#ifdef EXTERNAL_3D_SOUND
|
||||
MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
MENUACTION_SPEAKERCONF, "FEA_SPK", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
#endif
|
||||
#ifdef AUDIO_REFLECTIONS
|
||||
MENUACTION_DYNAMICACOUSTIC, "FET_DAM", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
#endif
|
||||
MENUACTION_RADIO, "FEA_RSS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_DISPLAY_SETTINGS = 6
|
||||
{ "FET_DIS", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2,
|
||||
MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_FRAMELIMIT, "FEM_FRM", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_TRAILS, "FED_TRA", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_SUBTITLES, "FED_SUB", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_WIDESCREEN, "FED_WIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_LANGUAGE_SETTINGS = 7
|
||||
{ "FET_LAN", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 3, 3,
|
||||
MENUACTION_LANG_ENG, "FEL_ENG", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
|
||||
MENUACTION_LANG_FRE, "FEL_FRE", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
|
||||
MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
|
||||
MENUACTION_LANG_ITA, "FEL_ITA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
|
||||
MENUACTION_LANG_SPA, "FEL_SPA", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_LOAD_SLOT = 8
|
||||
{ "FET_LG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 1, 1,
|
||||
MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL0", SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_3, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL3", SAVESLOT_4, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL4", SAVESLOT_5, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL5", SAVESLOT_6, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL6", SAVESLOT_7, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
MENUACTION_CHECKSAVE, "FEM_SL7", SAVESLOT_8, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_DELETE_SLOT = 9
|
||||
{ "FET_DG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 2, 2,
|
||||
MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL0", SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL1", SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL2", SAVESLOT_3, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL3", SAVESLOT_4, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL4", SAVESLOT_5, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL5", SAVESLOT_6, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL6", SAVESLOT_7, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL7", SAVESLOT_8, MENUPAGE_DELETE_SLOT_CONFIRM,
|
||||
},
|
||||
|
||||
// MENUPAGE_NEW_GAME_RELOAD = 10
|
||||
{ "FET_NG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 0, 0,
|
||||
MENUACTION_LABEL, "FESZ_QR", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
||||
MENUACTION_NEWGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD,
|
||||
},
|
||||
|
||||
// MENUPAGE_LOAD_SLOT_CONFIRM = 11
|
||||
{ "FET_LG", 1, MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FESZ_QL", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS,
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETE_SLOT_CONFIRM = 12
|
||||
{ "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FESZ_QD", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_DELETING,
|
||||
},
|
||||
|
||||
// MENUPAGE_NO_MEMORY_CARD = 13
|
||||
{ "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
// hud adjustment page in mobile
|
||||
},
|
||||
|
||||
// MENUPAGE_LOADING_IN_PROGRESS = 14
|
||||
{ "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_LABEL, "FED_LDW", SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM,
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETING_IN_PROGRESS = 15
|
||||
{ "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_LABEL, "FEDL_WR", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_PS2_LOAD_FAILED = 16
|
||||
{ "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_LABEL, "FES_LOE", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETE_FAILED = 17
|
||||
{ "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_LABEL, "FES_DEE", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
|
||||
},
|
||||
|
||||
// MENUPAGE_DEBUG_MENU = 18
|
||||
{ "FED_DBG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 4, 0,
|
||||
MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_RELOADIPL, "FED_RIP", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_PEDROADGROUPS, "FED_SPR", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CARROADGROUPS, "FED_SCR", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_COLLISIONPOLYS, "FED_SCP", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_PARSEHEAP, "FED_PAH", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_SHOWCULL, "FED_SCZ", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_DEBUGSTREAM, "FED_DSR", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_MEMORY_CARD_DEBUG = 19
|
||||
{ "FEM_MCM", 1, MENUPAGE_NONE, MENUPAGE_NONE, 7, 0,
|
||||
MENUACTION_REGMEMCARD1, "FEM_RMC", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_TESTFORMATMEMCARD1, "FEM_TFM", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_TESTUNFORMATMEMCARD1, "FEM_TUM", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CREATEROOTDIR, "FEM_CRD", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CREATELOADICONS, "FEM_CLI", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_FILLWITHGUFF, "FEM_FFF", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_SAVEONLYTHEGAME, "FEM_SOG", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_SAVEGAME, "FEM_STG", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_SAVEGAMEUNDERGTA, "FEM_STS", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CREATECOPYPROTECTED, "FEM_CPD", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_MEMORY_CARD_TEST = 20
|
||||
{ "FEM_MC2", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_MAIN = 21
|
||||
{ "FET_MP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_PS2_SAVE_FAILED = 22
|
||||
{ "MCDNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_PS2_SAVE_FAILED_2 = 23
|
||||
{ "MCGNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// Unused in PC but anyway
|
||||
// MENUPAGE_SAVE = 24
|
||||
#ifdef PS2_SAVE_DIALOG
|
||||
{ "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_CHANGEMENU, "FESZ_SA", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
#else
|
||||
{ "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_LABEL, "FES_SCG", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
#endif
|
||||
|
||||
// MENUPAGE_NO_MEMORY_CARD_2 = 25
|
||||
{ "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_SAVE_SLOT = 26
|
||||
{ "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL1", SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL2", SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL3", SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL4", SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL5", SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL6", SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL7", SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
MENUACTION_CHANGEMENU, "FEM_SL8", SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27
|
||||
{ "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FESZ_QO", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS,
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_MAP = 28
|
||||
{ "FET_MAP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_CONNECTION = 29
|
||||
{ "FET_CON", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_FIND_GAME = 30
|
||||
{ "FET_FG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_MODE = 31
|
||||
{ "FET_GT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_CREATE = 32
|
||||
{ "FET_HG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_START = 33
|
||||
{ "FEN_STA", 2, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_SKIN_SELECT_OLD = 34
|
||||
{ "FET_PS", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC = 35
|
||||
{ "FET_CTL", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
|
||||
#ifdef PC_PLAYER_CONTROLS
|
||||
MENUACTION_CTRLMETHOD, "FET_CME", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
|
||||
#endif
|
||||
MENUACTION_KEYBOARDCTRLS,"FET_RDK", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS,
|
||||
MENUACTION_CHANGEMENU, "FET_AMS", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
|
||||
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD1 = 36
|
||||
{ "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 0, 0,
|
||||
MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_CWR", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_LKT", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_PJP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_PSP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_TLF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_TRG", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_GETKEY, "FEC_CCM", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD2 = 37
|
||||
{ "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD3 = 38
|
||||
{ "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
|
||||
MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
|
||||
MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
|
||||
MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
|
||||
MENUACTION_SHOWHEADBOB, "FEC_GSL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD4 = 39
|
||||
{ "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_DEBUG = 40
|
||||
{ "FEC_DBG", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
|
||||
MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
|
||||
MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
|
||||
MENUACTION_GETKEY, "FEC_TSS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
|
||||
MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_OPTIONS = 41
|
||||
{ "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4,
|
||||
MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
|
||||
MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
|
||||
MENUACTION_CHANGEMENU, "FET_LAN", SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS,
|
||||
MENUACTION_PLAYERSETUP, "FET_PSU", SAVESLOT_NONE, MENUPAGE_SKIN_SELECT,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_EXIT = 42
|
||||
{ "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5,
|
||||
MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVING_IN_PROGRESS = 43
|
||||
{ "", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FES_WAR", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVE_SUCCESSFUL = 44
|
||||
{ "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FES_SSC", SAVESLOT_LABEL, MENUPAGE_NONE,
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETING = 45
|
||||
{ "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FED_DLW", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETE_SUCCESS = 46
|
||||
{ "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "DEL_FNM", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVE_FAILED = 47
|
||||
{ "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
|
||||
},
|
||||
|
||||
// MENUPAGE_LOAD_FAILED = 48
|
||||
{ "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_LOAD_FAILED_2 = 49
|
||||
{ "FET_LG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
|
||||
MENUACTION_LABEL, "FEC_LUN", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
|
||||
},
|
||||
|
||||
// MENUPAGE_FILTER_GAME = 50
|
||||
{ "FIL_FLT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_START_MENU = 51
|
||||
{ "FEM_MM", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
||||
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
|
||||
MENUACTION_CHANGEMENU, "FEM_QT", SAVESLOT_NONE, MENUPAGE_EXIT,
|
||||
},
|
||||
|
||||
// MENUPAGE_PAUSE_MENU = 52
|
||||
{ "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
||||
MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS,
|
||||
MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
|
||||
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
|
||||
MENUACTION_CHANGEMENU, "FEM_QT", SAVESLOT_NONE, MENUPAGE_EXIT,
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_MODE = 53
|
||||
{ "FEN_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1,
|
||||
MENUACTION_CHANGEMENU, "FET_SP", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
|
||||
MENUACTION_INITMP, "FET_MP", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
|
||||
// MENUPAGE_SKIN_SELECT = 54
|
||||
{ "FET_PSU", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 4, 4,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN,
|
||||
},
|
||||
|
||||
// MENUPAGE_KEYBOARD_CONTROLS = 55
|
||||
{ "FET_STI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
|
||||
},
|
||||
|
||||
// MENUPAGE_MOUSE_CONTROLS = 56
|
||||
{ "FET_MTI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
|
||||
MENUACTION_MOUSESENS, "FEC_MSH", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
|
||||
MENUACTION_INVVERT, "FEC_IVV", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
|
||||
MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
},
|
||||
// MENUPAGE_MISSION_RETRY = 57
|
||||
#ifdef MISSION_REPLAY
|
||||
|
||||
{ "M_FAIL", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
|
||||
MENUACTION_LABEL, "FESZ_RM", SAVESLOT_NONE, MENUPAGE_NONE,
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS,
|
||||
MENUACTION_REJECT_RETRY, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE
|
||||
},
|
||||
#else
|
||||
{ "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
|
||||
// mission failed, wanna restart page in mobile
|
||||
},
|
||||
#endif
|
||||
|
||||
// MENUPAGE_UNK
|
||||
{ "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
936
src/core/MenuScreensCustom.cpp
Normal file
936
src/core/MenuScreensCustom.cpp
Normal file
|
|
@ -0,0 +1,936 @@
|
|||
#include "common.h"
|
||||
#if defined DETECT_JOYSTICK_MENU && defined XINPUT
|
||||
#include <windows.h>
|
||||
#include <xinput.h>
|
||||
#if !defined(PSAPI_VERSION) || (PSAPI_VERSION > 1)
|
||||
#pragma comment( lib, "Xinput9_1_0.lib" )
|
||||
#else
|
||||
#pragma comment( lib, "Xinput.lib" )
|
||||
#endif
|
||||
#endif
|
||||
#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"
|
||||
#include "ControllerConfig.h"
|
||||
#include "IniFile.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "Population.h"
|
||||
|
||||
// Menu screens array is at the bottom of the file.
|
||||
|
||||
#ifdef PC_MENU
|
||||
|
||||
#ifdef CUSTOM_FRONTEND_OPTIONS
|
||||
|
||||
#if defined(IMPROVED_VIDEOMODE) && !defined(GTA_HANDHELD)
|
||||
#define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) },
|
||||
#else
|
||||
#define VIDEOMODE_SELECTOR
|
||||
#endif
|
||||
|
||||
#ifdef MULTISAMPLING
|
||||
#define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "Graphics", "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) },
|
||||
#else
|
||||
#define MULTISAMPLING_SELECTOR
|
||||
#endif
|
||||
|
||||
#ifdef CUTSCENE_BORDERS_SWITCH
|
||||
#define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&CMenuManager::m_PrefsCutsceneBorders, "Display", "CutsceneBorders", off_on, 2, false) },
|
||||
#else
|
||||
#define CUTSCENE_BORDERS_TOGGLE
|
||||
#endif
|
||||
|
||||
#ifdef FREE_CAM
|
||||
#define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "Display", "FreeCam", off_on, 2, false) },
|
||||
#else
|
||||
#define FREE_CAM_TOGGLE
|
||||
#endif
|
||||
|
||||
#ifdef PS2_ALPHA_TEST
|
||||
#define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) },
|
||||
#else
|
||||
#define DUALPASS_SELECTOR
|
||||
#endif
|
||||
|
||||
#ifdef PED_CAR_DENSITY_SLIDERS
|
||||
// 0.2f - 3.4f makes it possible to have 1.0f somewhere inbetween
|
||||
#define DENSITY_SLIDERS \
|
||||
MENUACTION_CFO_SLIDER, "FEM_PED", { new CCFOSlider(&CIniFile::PedNumberMultiplier, "Display", "PedDensity", 0.2f, 3.4f, PedDensityChange) }, \
|
||||
MENUACTION_CFO_SLIDER, "FEM_CAR", { new CCFOSlider(&CIniFile::CarNumberMultiplier, "Display", "CarDensity", 0.2f, 3.4f, CarDensityChange) },
|
||||
#else
|
||||
#define DENSITY_SLIDERS
|
||||
#endif
|
||||
|
||||
#ifdef NO_ISLAND_LOADING
|
||||
#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
|
||||
#else
|
||||
#define ISLAND_LOADING_SELECTOR
|
||||
#endif
|
||||
|
||||
#ifdef EXTENDED_COLOURFILTER
|
||||
#define POSTFX_SELECTORS \
|
||||
MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "Graphics", "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, \
|
||||
MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "Graphics", "MotionBlur", off_on, 2, false) },
|
||||
#else
|
||||
#define POSTFX_SELECTORS
|
||||
#endif
|
||||
|
||||
#ifdef INVERT_LOOK_FOR_PAD
|
||||
#define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "Controller", "InvertPad", off_on, 2, false) },
|
||||
#else
|
||||
#define INVERT_PAD_SELECTOR
|
||||
#endif
|
||||
|
||||
#ifdef GAMEPAD_MENU
|
||||
#define SELECT_CONTROLLER_TYPE MENUACTION_CFO_SELECT, "FEC_TYP", { new CCFOSelect((int8*)&CMenuManager::m_PrefsControllerType, "Controller", "Type", controllerTypes, ARRAY_SIZE(controllerTypes), false, ControllerTypeAfterChange) },
|
||||
#else
|
||||
#define SELECT_CONTROLLER_TYPE
|
||||
#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;
|
||||
CCollision::bAlreadyLoaded = false;
|
||||
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
|
||||
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
|
||||
CMenuManager::m_PrefsFrameLimiter = true;
|
||||
CMenuManager::m_PrefsVsyncDisp = true;
|
||||
CMenuManager::m_PrefsVsync = true;
|
||||
CMenuManager::m_PrefsUseWideScreen = false;
|
||||
FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode;
|
||||
#if GTA_VERSION >= GTA3_PC_11
|
||||
if (_dwOperatingSystemVersion == OS_WIN98) {
|
||||
CMBlur::BlurOn = false;
|
||||
CMBlur::MotionBlurClose();
|
||||
} else {
|
||||
CMBlur::BlurOn = true;
|
||||
CMBlur::MotionBlurOpen(Scene.camera);
|
||||
}
|
||||
#else
|
||||
CMBlur::BlurOn = true;
|
||||
#endif
|
||||
FrontEndMenuManager.SaveSettings();
|
||||
#endif
|
||||
}
|
||||
|
||||
void RestoreDefDisplay(int8 action) {
|
||||
if (action != FEOPTION_ACTION_SELECT)
|
||||
return;
|
||||
|
||||
#ifdef CUTSCENE_BORDERS_SWITCH
|
||||
CMenuManager::m_PrefsCutsceneBorders = true;
|
||||
#endif
|
||||
#ifdef FREE_CAM
|
||||
TheCamera.bFreeCam = false;
|
||||
#endif
|
||||
#ifdef PED_CAR_DENSITY_SLIDERS
|
||||
CIniFile::LoadIniFile();
|
||||
#endif
|
||||
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
|
||||
CMenuManager::m_PrefsBrightness = 256;
|
||||
CMenuManager::m_PrefsLOD = 1.2f;
|
||||
CRenderer::ms_lodDistScale = 1.2f;
|
||||
CMenuManager::m_PrefsShowSubtitles = 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_GENERIC);
|
||||
if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) {
|
||||
if (CGame::currLevel != LEVEL_INDUSTRIAL)
|
||||
CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL);
|
||||
if (CGame::currLevel != LEVEL_COMMERCIAL)
|
||||
CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL);
|
||||
if (CGame::currLevel != LEVEL_SUBURBAN)
|
||||
CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN);
|
||||
CCollision::bAlreadyLoaded = true;
|
||||
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
|
||||
CCollision::bAlreadyLoaded = false;
|
||||
CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
|
||||
CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
|
||||
CStreaming::RemoveUnusedBuildings(CGame::currLevel);
|
||||
CStreaming::RequestIslands(CGame::currLevel);
|
||||
}
|
||||
|
||||
CStreaming::LoadAllRequestedModels(true);
|
||||
}
|
||||
|
||||
FrontEndMenuManager.SetHelperText(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PED_CAR_DENSITY_SLIDERS
|
||||
void PedDensityChange(float before, float after) {
|
||||
CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * after;
|
||||
}
|
||||
|
||||
void CarDensityChange(float before, float after) {
|
||||
CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * after;
|
||||
}
|
||||
#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 DETECT_JOYSTICK_MENU
|
||||
wchar selectedJoystickUnicode[128];
|
||||
int cachedButtonNum = -1;
|
||||
|
||||
wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
|
||||
|
||||
#if defined RW_GL3 && !defined LIBRW_SDL2
|
||||
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;
|
||||
cachedButtonNum = numButtons;
|
||||
}
|
||||
}
|
||||
if (PSGLOBAL(joy1id) == -1)
|
||||
#elif defined XINPUT
|
||||
int found = -1;
|
||||
XINPUT_STATE xstate;
|
||||
memset(&xstate, 0, sizeof(XINPUT_STATE));
|
||||
if (userHovering) {
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
if (XInputGetState(i, &xstate) == ERROR_SUCCESS) {
|
||||
if (xstate.Gamepad.bLeftTrigger || xstate.Gamepad.bRightTrigger) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
for (int j = XINPUT_GAMEPAD_DPAD_UP; j != XINPUT_GAMEPAD_Y << 1; j = (j << 1)) {
|
||||
if (xstate.Gamepad.wButtons & j) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found != -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found != -1 && CPad::XInputJoy1 != found) {
|
||||
// We should never leave pads -1, so we can process them when they're connected and kinda support hotplug.
|
||||
CPad::XInputJoy2 = (CPad::XInputJoy1 == -1 ? (found + 1) % 4 : CPad::XInputJoy1);
|
||||
CPad::XInputJoy1 = found;
|
||||
cachedButtonNum = 0; // fake too, because xinput bypass CControllerConfig
|
||||
}
|
||||
}
|
||||
sprintf(gSelectedJoystickName, "%d", CPad::XInputJoy1); // fake, on xinput we only store gamepad ids(thanks MS) so this is a temp variable to be used below
|
||||
if (CPad::XInputJoy1 == -1)
|
||||
#endif
|
||||
AsciiToUnicode("Not found", selectedJoystickUnicode);
|
||||
else
|
||||
AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode);
|
||||
|
||||
return selectedJoystickUnicode;
|
||||
}
|
||||
|
||||
void DetectJoystickGoBack() {
|
||||
if (cachedButtonNum != -1) {
|
||||
#ifdef LOAD_INI_SETTINGS
|
||||
ControlsManager.InitDefaultControlConfigJoyPad(cachedButtonNum);
|
||||
SaveINIControllerSettings();
|
||||
#else
|
||||
// Otherwise no way to save gSelectedJoystickName or ms_padButtonsInited anyway :shrug: Why do you even use this config.??
|
||||
#endif
|
||||
cachedButtonNum = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GAMEPAD_MENU
|
||||
const char* controllerTypes[] = { "FEC_DS2", "FEC_DS3", "FEC_DS4", "FEC_360", "FEC_ONE", "FEC_NSW" };
|
||||
void ControllerTypeAfterChange(int8 before, int8 after)
|
||||
{
|
||||
FrontEndMenuManager.LoadController(after);
|
||||
}
|
||||
#endif
|
||||
|
||||
CMenuScreenCustom aScreens[MENUPAGES] = {
|
||||
// MENUPAGE_NONE = 0
|
||||
{ "", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil, },
|
||||
|
||||
// MENUPAGE_STATS = 1
|
||||
{ "FET_STA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_NEW_GAME = 2
|
||||
{ "FET_SGA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FES_SNG", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD },
|
||||
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMLOAD", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
|
||||
MENUACTION_POPULATESLOTS_CHANGEMENU, "FES_DGA", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_BRIEFS = 3
|
||||
{ "FET_BRE", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_SETTINGS = 4
|
||||
#if defined(GAMEPAD_MENU) && !defined(GTA_HANDHELD)
|
||||
{ "FET_AGS", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
#else
|
||||
{ "FET_AGS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
|
||||
#endif
|
||||
MENUACTION_CTRLCONFIG, "FEC_CCF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
|
||||
MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
|
||||
INVERT_PAD_SELECTOR
|
||||
MENUACTION_CTRLVIBRATION, "FEC_VIB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
|
||||
SELECT_CONTROLLER_TYPE
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_SOUND_SETTINGS = 5
|
||||
{ "FET_AUD", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
|
||||
MENUACTION_MUSICVOLUME, "FEA_MUS", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
MENUACTION_SFXVOLUME, "FEA_SFX", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
#ifdef EXTERNAL_3D_SOUND
|
||||
MENUACTION_AUDIOHW, "FEA_3DH", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
MENUACTION_SPEAKERCONF, "FEA_SPK", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
#endif
|
||||
#ifdef AUDIO_REFLECTIONS
|
||||
MENUACTION_DYNAMICACOUSTIC, "FET_DAM", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
#endif
|
||||
MENUACTION_RADIO, "FEA_RSS", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
#ifndef GRAPHICS_MENU_OPTIONS
|
||||
// MENUPAGE_DISPLAY_SETTINGS = 6
|
||||
{ "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
|
||||
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
DENSITY_SLIDERS
|
||||
MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
#ifndef EXTENDED_COLOURFILTER
|
||||
MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
#endif
|
||||
MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
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 },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#else
|
||||
// MENUPAGE_DISPLAY_SETTINGS = 6
|
||||
{ "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
|
||||
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
DENSITY_SLIDERS
|
||||
CUTSCENE_BORDERS_TOGGLE
|
||||
FREE_CAM_TOGGLE
|
||||
MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefDisplay) },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#endif
|
||||
|
||||
// MENUPAGE_LANGUAGE_SETTINGS = 7
|
||||
{ "FET_LAN", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
|
||||
MENUACTION_LANG_ENG, "FEL_ENG", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
|
||||
MENUACTION_LANG_FRE, "FEL_FRE", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
|
||||
MENUACTION_LANG_GER, "FEL_GER", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
|
||||
MENUACTION_LANG_ITA, "FEL_ITA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
|
||||
MENUACTION_LANG_SPA, "FEL_SPA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
|
||||
// CustomFrontendOptionsPopulate will add languages here, if files are found
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_LOAD_SLOT = 8
|
||||
{ "FET_LG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
MENUACTION_CHECKSAVE, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_DELETE_SLOT = 9
|
||||
{ "FET_DG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_DELETE_SLOT_CONFIRM },
|
||||
},
|
||||
|
||||
// MENUPAGE_NEW_GAME_RELOAD = 10
|
||||
{ "FET_NG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
|
||||
MENUACTION_LABEL, "FESZ_QR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
|
||||
MENUACTION_NEWGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD },
|
||||
},
|
||||
|
||||
// MENUPAGE_LOAD_SLOT_CONFIRM = 11
|
||||
{ "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FESZ_QL", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS },
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETE_SLOT_CONFIRM = 12
|
||||
{ "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FESZ_QD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_DELETING },
|
||||
},
|
||||
|
||||
// MENUPAGE_NO_MEMORY_CARD = 13
|
||||
{ "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
// hud adjustment page in mobile
|
||||
},
|
||||
|
||||
// MENUPAGE_LOADING_IN_PROGRESS = 14
|
||||
{ "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_LABEL, "FED_LDW", { nil, SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM },
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETING_IN_PROGRESS = 15
|
||||
{ "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_LABEL, "FEDL_WR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_PS2_LOAD_FAILED = 16
|
||||
{ "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_LABEL, "FES_LOE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETE_FAILED = 17
|
||||
{ "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_LABEL, "FES_DEE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
|
||||
},
|
||||
|
||||
// MENUPAGE_DEBUG_MENU = 18
|
||||
{ "FED_DBG", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_RELOADIDE, "FED_RID", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_RELOADIPL, "FED_RIP", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_SETDBGFLAG, "FED_DFL", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_PEDROADGROUPS, "FED_SPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CARROADGROUPS, "FED_SCR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_COLLISIONPOLYS, "FED_SCP", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_PARSEHEAP, "FED_PAH", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_SHOWCULL, "FED_SCZ", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_DEBUGSTREAM, "FED_DSR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_MEMORY_CARD_DEBUG = 19
|
||||
{ "FEM_MCM", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_REGMEMCARD1, "FEM_RMC", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_TESTFORMATMEMCARD1, "FEM_TFM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_TESTUNFORMATMEMCARD1, "FEM_TUM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CREATEROOTDIR, "FEM_CRD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CREATELOADICONS, "FEM_CLI", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_FILLWITHGUFF, "FEM_FFF", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_SAVEONLYTHEGAME, "FEM_SOG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_SAVEGAME, "FEM_STG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_SAVEGAMEUNDERGTA, "FEM_STS", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CREATECOPYPROTECTED, "FEM_CPD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_MEMORY_CARD_TEST = 20
|
||||
{ "FEM_MC2", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_MAIN = 21
|
||||
{ "FET_MP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_PS2_SAVE_FAILED = 22
|
||||
{ "MCDNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_PS2_SAVE_FAILED_2 = 23
|
||||
{ "MCGNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// Unused in PC but anyway
|
||||
// MENUPAGE_SAVE = 24
|
||||
#ifdef PS2_SAVE_DIALOG
|
||||
{ "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FESZ_SA", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#else
|
||||
{ "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_LABEL, "FES_SCG", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#endif
|
||||
|
||||
// MENUPAGE_NO_MEMORY_CARD_2 = 25
|
||||
{ "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_SAVE_SLOT = 26
|
||||
{ "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL1", { nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL2", { nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL3", { nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL4", { nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL5", { nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL6", { nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL7", { nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
MENUACTION_CHANGEMENU, "FEM_SL8", { nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM },
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27
|
||||
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FESZ_QO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS },
|
||||
MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_MAP = 28
|
||||
{ "FET_MAP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_CONNECTION = 29
|
||||
{ "FET_CON", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_FIND_GAME = 30
|
||||
{ "FET_FG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_MODE = 31
|
||||
{ "FET_GT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_CREATE = 32
|
||||
{ "FET_HG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_MULTIPLAYER_START = 33
|
||||
{ "FEN_STA", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_SKIN_SELECT_OLD = 34
|
||||
{ "FET_PS", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC = 35
|
||||
{ "FET_CTL", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
|
||||
#ifdef PC_PLAYER_CONTROLS
|
||||
MENUACTION_CTRLMETHOD, "FET_CME", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
|
||||
#endif
|
||||
MENUACTION_KEYBOARDCTRLS,"FET_RDK", { nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS },
|
||||
#ifdef GAMEPAD_MENU
|
||||
MENUACTION_CHANGEMENU, "FET_AGS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
|
||||
#endif
|
||||
#ifdef DETECT_JOYSTICK_MENU
|
||||
MENUACTION_CHANGEMENU, "FEC_JOD", { nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK },
|
||||
#endif
|
||||
MENUACTION_CHANGEMENU, "FET_AMS", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
|
||||
MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD1 = 36
|
||||
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
MENUACTION_GETKEY, "FEC_PLB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_CWL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_CWR", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_LKT", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_PJP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_PSP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_TLF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_TRG", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_GETKEY, "FEC_CCM", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD2 = 37
|
||||
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD3 = 38
|
||||
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
MENUACTION_GETKEY, "FEC_LUP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
|
||||
MENUACTION_GETKEY, "FEC_LDN", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
|
||||
MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
|
||||
MENUACTION_SHOWHEADBOB, "FEC_GSL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_PC_OLD4 = 39
|
||||
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_CONTROLLER_DEBUG = 40
|
||||
{ "FEC_DBG", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
MENUACTION_GETKEY, "FEC_TGD", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
|
||||
MENUACTION_GETKEY, "FEC_TDO", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
|
||||
MENUACTION_GETKEY, "FEC_TSS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
|
||||
MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_OPTIONS = 41
|
||||
{ "FET_OPT", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
#ifdef GTA_HANDHELD
|
||||
MENUACTION_CHANGEMENU, "FET_CTL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
|
||||
#else
|
||||
MENUACTION_CHANGEMENU, "FET_CTL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
|
||||
#endif
|
||||
MENUACTION_LOADRADIO, "FET_AUD", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
|
||||
MENUACTION_CHANGEMENU, "FET_DIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
#ifdef GRAPHICS_MENU_OPTIONS
|
||||
MENUACTION_CHANGEMENU, "FET_GFX", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
|
||||
#endif
|
||||
MENUACTION_CHANGEMENU, "FET_LAN", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
|
||||
MENUACTION_PLAYERSETUP, "FET_PSU", { nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_EXIT = 42
|
||||
{ "FET_QG", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_LABEL, "FEQ_SRE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_DONTCANCEL, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CANCELGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVING_IN_PROGRESS = 43
|
||||
{ "", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FES_WAR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVE_SUCCESSFUL = 44
|
||||
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FES_SSC", { nil, SAVESLOT_LABEL, MENUPAGE_NONE },
|
||||
MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETING = 45
|
||||
{ "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FED_DLW", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_DELETE_SUCCESS = 46
|
||||
{ "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "DEL_FNM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
|
||||
},
|
||||
|
||||
// MENUPAGE_SAVE_FAILED = 47
|
||||
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FEC_SVU", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
|
||||
},
|
||||
|
||||
// MENUPAGE_LOAD_FAILED = 48
|
||||
{ "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FEC_SVU", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_LOAD_FAILED_2 = 49
|
||||
{ "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
|
||||
MENUACTION_LABEL, "FEC_LUN", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
|
||||
},
|
||||
|
||||
// MENUPAGE_FILTER_GAME = 50
|
||||
{ "FIL_FLT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
// MENUPAGE_START_MENU = 51
|
||||
{ "FEM_MM", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FEN_STA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
|
||||
MENUACTION_CHANGEMENU, "FET_OPT", { nil, SAVESLOT_NONE, MENUPAGE_OPTIONS },
|
||||
MENUACTION_CHANGEMENU, "FEM_QT", { nil, SAVESLOT_NONE, MENUPAGE_EXIT },
|
||||
},
|
||||
|
||||
// MENUPAGE_PAUSE_MENU = 52
|
||||
{ "FET_PAU", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_RESUME, "FEM_RES", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEN_STA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
|
||||
// CMenuManager::LoadAllTextures will add map here, if MENU_MAP enabled and map textures are found
|
||||
MENUACTION_CHANGEMENU, "FEP_STA", { nil, SAVESLOT_NONE, MENUPAGE_STATS },
|
||||
MENUACTION_CHANGEMENU, "FEP_BRI", { nil, SAVESLOT_NONE, MENUPAGE_BRIEFS },
|
||||
MENUACTION_CHANGEMENU, "FET_OPT", { nil, SAVESLOT_NONE, MENUPAGE_OPTIONS },
|
||||
MENUACTION_CHANGEMENU, "FEM_QT", { nil, SAVESLOT_NONE, MENUPAGE_EXIT },
|
||||
},
|
||||
|
||||
// MENUPAGE_CHOOSE_MODE = 53
|
||||
{ "FEN_STA", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FET_SP", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
|
||||
MENUACTION_INITMP, "FET_MP", { nil, SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
|
||||
// MENUPAGE_SKIN_SELECT = 54
|
||||
{ "FET_PSU", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN },
|
||||
},
|
||||
|
||||
// MENUPAGE_KEYBOARD_CONTROLS = 55
|
||||
{ "FET_STI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
|
||||
},
|
||||
|
||||
// MENUPAGE_MOUSE_CONTROLS = 56
|
||||
{ "FET_MTI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
|
||||
MENUACTION_MOUSESENS, "FEC_MSH", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
|
||||
MENUACTION_INVVERT, "FEC_IVV", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
|
||||
#ifndef GAMEPAD_MENU
|
||||
INVERT_PAD_SELECTOR
|
||||
#endif
|
||||
MENUACTION_MOUSESTEER, "FET_MST", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
// MENUPAGE_MISSION_RETRY = 57
|
||||
#ifdef MISSION_REPLAY
|
||||
|
||||
{ "M_FAIL", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
|
||||
MENUACTION_LABEL, "FESZ_RM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS },
|
||||
MENUACTION_REJECT_RETRY, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#else
|
||||
{ "", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
// mission failed, wanna restart page in mobile
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef MENU_MAP
|
||||
// MENUPAGE_MAP
|
||||
{ "FEG_MAP", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
MENUACTION_UNK110, "", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, // to prevent cross/enter to go back
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef GRAPHICS_MENU_OPTIONS
|
||||
// MENUPAGE_GRAPHICS_SETTINGS
|
||||
{ "FET_GFX", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS,
|
||||
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 50, 0, 20, FONT_HEADING, FESCREEN_LEFT_ALIGN, true, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), GraphicsGoBack,
|
||||
|
||||
#ifndef GTA_HANDHELD
|
||||
MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
|
||||
#endif
|
||||
MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
|
||||
VIDEOMODE_SELECTOR
|
||||
MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
MULTISAMPLING_SELECTOR
|
||||
ISLAND_LOADING_SELECTOR
|
||||
DUALPASS_SELECTOR
|
||||
#ifdef EXTENDED_COLOURFILTER
|
||||
POSTFX_SELECTORS
|
||||
#else
|
||||
MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
|
||||
#endif
|
||||
// re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
|
||||
MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefGraphics) },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef DETECT_JOYSTICK_MENU
|
||||
// MENUPAGE_DETECT_JOYSTICK
|
||||
{ "FEC_JOD", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC,
|
||||
new CCustomScreenLayout({MENUSPRITE_MAINMENU, 40, 60, 20, FONT_BANK, FESCREEN_LEFT_ALIGN, false, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), DetectJoystickGoBack,
|
||||
|
||||
MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, nil, DetectJoystickDraw, nil) },
|
||||
MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
|
||||
},
|
||||
#endif
|
||||
|
||||
// MENUPAGE_UNK
|
||||
{ "", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
3025
src/core/Pad.cpp
Normal file
3025
src/core/Pad.cpp
Normal file
File diff suppressed because it is too large
Load diff
474
src/core/Pad.h
Normal file
474
src/core/Pad.h
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
#pragma once
|
||||
|
||||
enum {
|
||||
PLAYERCONTROL_ENABLED = 0,
|
||||
PLAYERCONTROL_CAMERA = 1,
|
||||
PLAYERCONTROL_UNK2 = 2,
|
||||
PLAYERCONTROL_GARAGE = 4,
|
||||
PLAYERCONTROL_UNK8 = 8,
|
||||
PLAYERCONTROL_UNK10 = 16,
|
||||
PLAYERCONTROL_PLAYERINFO = 32,
|
||||
PLAYERCONTROL_PHONE = 64,
|
||||
PLAYERCONTROL_CUTSCENE = 128,
|
||||
};
|
||||
|
||||
class CControllerState
|
||||
{
|
||||
public:
|
||||
int16 LeftStickX, LeftStickY;
|
||||
int16 RightStickX, RightStickY;
|
||||
int16 LeftShoulder1, LeftShoulder2;
|
||||
int16 RightShoulder1, RightShoulder2;
|
||||
int16 DPadUp, DPadDown, DPadLeft, DPadRight;
|
||||
int16 Start, Select;
|
||||
int16 Square, Triangle, Cross, Circle;
|
||||
int16 LeftShock, RightShock;
|
||||
int16 NetworkTalk;
|
||||
float GetLeftStickX(void) { return LeftStickX/32767.0f; };
|
||||
float GetLeftStickY(void) { return LeftStickY/32767.0f; };
|
||||
float GetRightStickX(void) { return RightStickX/32767.0f; };
|
||||
float GetRightStickY(void) { return RightStickY/32767.0f; };
|
||||
|
||||
bool CheckForInput();
|
||||
void Clear(void);
|
||||
};
|
||||
VALIDATE_SIZE(CControllerState, 0x2A);
|
||||
|
||||
class CMouseControllerState
|
||||
{
|
||||
public:
|
||||
//uint32 btns; // bit 0-2 button 1-3
|
||||
|
||||
bool LMB;
|
||||
bool RMB;
|
||||
bool MMB;
|
||||
bool WHEELUP;
|
||||
bool WHEELDN;
|
||||
bool MXB1;
|
||||
bool MXB2;
|
||||
char _pad0;
|
||||
|
||||
float x, y;
|
||||
|
||||
CMouseControllerState();
|
||||
void Clear();
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CMouseControllerState, 0x10);
|
||||
|
||||
class CMousePointerStateHelper
|
||||
{
|
||||
public:
|
||||
bool bInvertHorizontally;
|
||||
bool bInvertVertically;
|
||||
|
||||
CMouseControllerState GetMouseSetUp();
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CMousePointerStateHelper, 0x2);
|
||||
|
||||
extern CMousePointerStateHelper MousePointerStateHelper;
|
||||
|
||||
|
||||
class CKeyboardState
|
||||
{
|
||||
public:
|
||||
int16 F[12];
|
||||
int16 VK_KEYS[256];
|
||||
int16 ESC;
|
||||
int16 INS;
|
||||
int16 DEL;
|
||||
int16 HOME;
|
||||
int16 END;
|
||||
int16 PGUP;
|
||||
int16 PGDN;
|
||||
int16 UP;
|
||||
int16 DOWN;
|
||||
int16 LEFT;
|
||||
int16 RIGHT;
|
||||
int16 SCROLLLOCK;
|
||||
int16 PAUSE;
|
||||
int16 NUMLOCK;
|
||||
int16 DIV;
|
||||
int16 MUL;
|
||||
int16 SUB;
|
||||
int16 ADD;
|
||||
int16 ENTER;
|
||||
int16 DECIMAL;
|
||||
int16 NUM1;
|
||||
int16 NUM2;
|
||||
int16 NUM3;
|
||||
int16 NUM4;
|
||||
int16 NUM5;
|
||||
int16 NUM6;
|
||||
int16 NUM7;
|
||||
int16 NUM8;
|
||||
int16 NUM9;
|
||||
int16 NUM0;
|
||||
int16 BACKSP;
|
||||
int16 TAB;
|
||||
int16 CAPSLOCK;
|
||||
int16 EXTENTER;
|
||||
int16 LSHIFT;
|
||||
int16 RSHIFT;
|
||||
int16 SHIFT;
|
||||
int16 LCTRL;
|
||||
int16 RCTRL;
|
||||
int16 LALT;
|
||||
int16 RALT;
|
||||
int16 LWIN;
|
||||
int16 RWIN;
|
||||
int16 APPS;
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CKeyboardState, 0x270);
|
||||
|
||||
enum
|
||||
{
|
||||
// taken from miss2
|
||||
PAD1 = 0,
|
||||
PAD2,
|
||||
|
||||
MAX_PADS
|
||||
};
|
||||
|
||||
class CPad
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
HORNHISTORY_SIZE = 5,
|
||||
};
|
||||
CControllerState NewState;
|
||||
CControllerState OldState;
|
||||
CControllerState PCTempKeyState;
|
||||
CControllerState PCTempJoyState;
|
||||
CControllerState PCTempMouseState;
|
||||
// straight out of my IDB
|
||||
int16 Phase;
|
||||
int16 Mode;
|
||||
int16 ShakeDur;
|
||||
uint8 ShakeFreq;
|
||||
bool bHornHistory[HORNHISTORY_SIZE];
|
||||
uint8 iCurrHornHistory;
|
||||
uint8 DisablePlayerControls;
|
||||
int8 bApplyBrakes;
|
||||
char CheatString[12];
|
||||
int32 LastTimeTouched;
|
||||
int32 AverageWeapon;
|
||||
int32 AverageEntries;
|
||||
|
||||
#ifdef DETECT_PAD_INPUT_SWITCH
|
||||
static bool IsAffectedByController;
|
||||
#endif
|
||||
CPad() { }
|
||||
~CPad() { }
|
||||
|
||||
static bool bDisplayNoControllerMessage;
|
||||
static bool bObsoleteControllerMessage;
|
||||
static bool bOldDisplayNoControllerMessage;
|
||||
static bool m_bMapPadOneToPadTwo;
|
||||
#ifdef INVERT_LOOK_FOR_PAD
|
||||
static bool bInvertLook4Pad;
|
||||
#endif
|
||||
|
||||
static CKeyboardState OldKeyState;
|
||||
static CKeyboardState NewKeyState;
|
||||
static CKeyboardState TempKeyState;
|
||||
static char KeyBoardCheatString[20];
|
||||
static CMouseControllerState OldMouseControllerState;
|
||||
static CMouseControllerState NewMouseControllerState;
|
||||
static CMouseControllerState PCTempMouseControllerState;
|
||||
|
||||
|
||||
#ifdef GTA_PS2_STUFF
|
||||
static void Initialise(void);
|
||||
#endif
|
||||
void Clear(bool bResetPlayerControls);
|
||||
void ClearMouseHistory();
|
||||
void UpdateMouse();
|
||||
CControllerState ReconcileTwoControllersInput(CControllerState const &State1, CControllerState const &State2);
|
||||
void StartShake(int16 nDur, uint8 nFreq);
|
||||
void StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fz);
|
||||
void StartShake_Train(float fX, float fY);
|
||||
#ifdef GTA_PS2_STUFF
|
||||
void AddToCheatString(char c);
|
||||
#endif
|
||||
void AddToPCCheatString(char c);
|
||||
|
||||
static void UpdatePads(void);
|
||||
void ProcessPCSpecificStuff(void);
|
||||
void Update(int16 pad);
|
||||
|
||||
static void DoCheats(void);
|
||||
void DoCheats(int16 unk);
|
||||
|
||||
static void StopPadsShaking(void);
|
||||
void StopShaking(int16 pad);
|
||||
|
||||
static CPad *GetPad(int32 pad);
|
||||
|
||||
int16 GetSteeringLeftRight(void);
|
||||
int16 GetSteeringUpDown(void);
|
||||
int16 GetCarGunUpDown(void);
|
||||
int16 GetCarGunLeftRight(void);
|
||||
int16 GetPedWalkLeftRight(void);
|
||||
int16 GetPedWalkUpDown(void);
|
||||
int16 GetAnalogueUpDown(void);
|
||||
bool GetLookLeft(void);
|
||||
bool GetLookRight(void);
|
||||
bool GetLookBehindForCar(void);
|
||||
bool GetLookBehindForPed(void);
|
||||
bool GetHorn(void);
|
||||
bool HornJustDown(void);
|
||||
bool GetCarGunFired(void);
|
||||
bool CarGunJustDown(void);
|
||||
int16 GetHandBrake(void);
|
||||
int16 GetBrake(void);
|
||||
bool GetExitVehicle(void);
|
||||
bool ExitVehicleJustDown(void);
|
||||
int32 GetWeapon(void);
|
||||
bool WeaponJustDown(void);
|
||||
int16 GetAccelerate(void);
|
||||
bool CycleCameraModeUpJustDown(void);
|
||||
bool CycleCameraModeDownJustDown(void);
|
||||
bool ChangeStationJustDown(void);
|
||||
bool CycleWeaponLeftJustDown(void);
|
||||
bool CycleWeaponRightJustDown(void);
|
||||
bool GetTarget(void);
|
||||
bool TargetJustDown(void);
|
||||
bool JumpJustDown(void);
|
||||
bool GetSprint(void);
|
||||
bool ShiftTargetLeftJustDown(void);
|
||||
bool ShiftTargetRightJustDown(void);
|
||||
bool GetAnaloguePadUp(void);
|
||||
bool GetAnaloguePadDown(void);
|
||||
bool GetAnaloguePadLeft(void);
|
||||
bool GetAnaloguePadRight(void);
|
||||
bool GetAnaloguePadLeftJustUp(void);
|
||||
bool GetAnaloguePadRightJustUp(void);
|
||||
bool ForceCameraBehindPlayer(void);
|
||||
bool SniperZoomIn(void);
|
||||
bool SniperZoomOut(void);
|
||||
int16 SniperModeLookLeftRight(void);
|
||||
int16 SniperModeLookUpDown(void);
|
||||
int16 LookAroundLeftRight(void);
|
||||
int16 LookAroundUpDown(void);
|
||||
void ResetAverageWeapon(void);
|
||||
static void PrintErrorMessage(void);
|
||||
static void ResetCheats(void);
|
||||
static char *EditString(char *pStr, int32 nSize);
|
||||
static int32 *EditCodesForControls(int32 *pRsKeys, int32 nSize);
|
||||
|
||||
#ifdef XINPUT
|
||||
static int XInputJoy1;
|
||||
static int XInputJoy2;
|
||||
void AffectFromXinput(uint32 pad);
|
||||
#endif
|
||||
|
||||
// mouse
|
||||
bool GetLeftMouseJustDown() { return !!(NewMouseControllerState.LMB && !OldMouseControllerState.LMB); }
|
||||
bool GetRightMouseJustDown() { return !!(NewMouseControllerState.RMB && !OldMouseControllerState.RMB); }
|
||||
bool GetMiddleMouseJustDown() { return !!(NewMouseControllerState.MMB && !OldMouseControllerState.MMB); }
|
||||
bool GetMouseWheelUpJustDown() { return !!(NewMouseControllerState.WHEELUP && !OldMouseControllerState.WHEELUP); }
|
||||
bool GetMouseWheelDownJustDown() { return !!(NewMouseControllerState.WHEELDN && !OldMouseControllerState.WHEELDN);}
|
||||
bool GetMouseX1JustDown() { return !!(NewMouseControllerState.MXB1 && !OldMouseControllerState.MXB1); }
|
||||
bool GetMouseX2JustDown() { return !!(NewMouseControllerState.MXB2 && !OldMouseControllerState.MXB2); }
|
||||
|
||||
bool GetLeftMouseJustUp() { return !!(!NewMouseControllerState.LMB && OldMouseControllerState.LMB); }
|
||||
bool GetRightMouseJustUp() { return !!(!NewMouseControllerState.RMB && OldMouseControllerState.RMB); }
|
||||
bool GetMiddleMouseJustUp() { return !!(!NewMouseControllerState.MMB && OldMouseControllerState.MMB); }
|
||||
bool GetMouseWheelUpJustUp() { return !!(!NewMouseControllerState.WHEELUP && OldMouseControllerState.WHEELUP); }
|
||||
bool GetMouseWheelDownJustUp() { return !!(!NewMouseControllerState.WHEELDN && OldMouseControllerState.WHEELDN); }
|
||||
bool GetMouseX1JustUp() { return !!(!NewMouseControllerState.MXB1 && OldMouseControllerState.MXB1); }
|
||||
bool GetMouseX2JustUp() { return !!(!NewMouseControllerState.MXB2 && OldMouseControllerState.MXB2); }
|
||||
|
||||
bool GetLeftMouse() { return NewMouseControllerState.LMB; }
|
||||
bool GetRightMouse() { return NewMouseControllerState.RMB; }
|
||||
bool GetMiddleMouse() { return NewMouseControllerState.MMB; }
|
||||
bool GetMouseWheelUp() { return NewMouseControllerState.WHEELUP; }
|
||||
bool GetMouseWheelDown() { return NewMouseControllerState.WHEELDN; }
|
||||
bool GetMouseX1() { return NewMouseControllerState.MXB1; }
|
||||
bool GetMouseX2() { return NewMouseControllerState.MXB2; }
|
||||
|
||||
bool GetLeftMouseUp() { return !OldMouseControllerState.LMB; }
|
||||
bool GetRightMouseUp() { return !OldMouseControllerState.RMB; }
|
||||
bool GetMiddleMouseUp() { return !OldMouseControllerState.MMB; }
|
||||
bool GetMouseWheelUpUp() { return !OldMouseControllerState.WHEELUP; }
|
||||
bool GetMouseWheelDownUp() { return !OldMouseControllerState.WHEELDN; }
|
||||
bool GetMouseX1Up() { return !OldMouseControllerState.MXB1; }
|
||||
bool GetMouseX2Up() { return !OldMouseControllerState.MXB2; }
|
||||
|
||||
|
||||
float GetMouseX() { return NewMouseControllerState.x; }
|
||||
float GetMouseY() { return NewMouseControllerState.y; }
|
||||
|
||||
// keyboard
|
||||
|
||||
bool GetCharJustDown(int32 c) { return !!(NewKeyState.VK_KEYS[c] && !OldKeyState.VK_KEYS[c]); }
|
||||
bool GetFJustDown(int32 n) { return !!(NewKeyState.F[n] && !OldKeyState.F[n]); }
|
||||
bool GetEscapeJustDown() { return !!(NewKeyState.ESC && !OldKeyState.ESC); }
|
||||
bool GetInsertJustDown() { return !!(NewKeyState.INS && !OldKeyState.INS); }
|
||||
bool GetDeleteJustDown() { return !!(NewKeyState.DEL && !OldKeyState.DEL); }
|
||||
bool GetHomeJustDown() { return !!(NewKeyState.HOME && !OldKeyState.HOME); }
|
||||
bool GetEndJustDown() { return !!(NewKeyState.END && !OldKeyState.END); }
|
||||
bool GetPageUpJustDown() { return !!(NewKeyState.PGUP && !OldKeyState.PGUP); }
|
||||
bool GetPageDownJustDown() { return !!(NewKeyState.PGDN && !OldKeyState.PGDN); }
|
||||
bool GetUpJustDown() { return !!(NewKeyState.UP && !OldKeyState.UP); }
|
||||
bool GetDownJustDown() { return !!(NewKeyState.DOWN && !OldKeyState.DOWN); }
|
||||
bool GetLeftJustDown() { return !!(NewKeyState.LEFT && !OldKeyState.LEFT); }
|
||||
bool GetRightJustDown() { return !!(NewKeyState.RIGHT && !OldKeyState.RIGHT); }
|
||||
bool GetScrollLockJustDown() { return !!(NewKeyState.SCROLLLOCK && !OldKeyState.SCROLLLOCK); }
|
||||
bool GetPauseJustDown() { return !!(NewKeyState.PAUSE && !OldKeyState.PAUSE); }
|
||||
bool GetNumLockJustDown() { return !!(NewKeyState.NUMLOCK && !OldKeyState.NUMLOCK); }
|
||||
bool GetDivideJustDown() { return !!(NewKeyState.DIV && !OldKeyState.DIV); }
|
||||
bool GetTimesJustDown() { return !!(NewKeyState.MUL && !OldKeyState.MUL); }
|
||||
bool GetMinusJustDown() { return !!(NewKeyState.SUB && !OldKeyState.SUB); }
|
||||
bool GetPlusJustDown() { return !!(NewKeyState.ADD && !OldKeyState.ADD); }
|
||||
bool GetPadEnterJustDown() { return !!(NewKeyState.ENTER && !OldKeyState.ENTER); }
|
||||
bool GetPadDelJustDown() { return !!(NewKeyState.DECIMAL && !OldKeyState.DECIMAL); }
|
||||
bool GetPad1JustDown() { return !!(NewKeyState.NUM1 && !OldKeyState.NUM1); }
|
||||
bool GetPad2JustDown() { return !!(NewKeyState.NUM2 && !OldKeyState.NUM2); }
|
||||
bool GetPad3JustDown() { return !!(NewKeyState.NUM3 && !OldKeyState.NUM3); }
|
||||
bool GetPad4JustDown() { return !!(NewKeyState.NUM4 && !OldKeyState.NUM4); }
|
||||
bool GetPad5JustDown() { return !!(NewKeyState.NUM5 && !OldKeyState.NUM5); }
|
||||
bool GetPad6JustDown() { return !!(NewKeyState.NUM6 && !OldKeyState.NUM6); }
|
||||
bool GetPad7JustDown() { return !!(NewKeyState.NUM7 && !OldKeyState.NUM7); }
|
||||
bool GetPad8JustDown() { return !!(NewKeyState.NUM8 && !OldKeyState.NUM8); }
|
||||
bool GetPad9JustDown() { return !!(NewKeyState.NUM9 && !OldKeyState.NUM9); }
|
||||
bool GetPad0JustDown() { return !!(NewKeyState.NUM0 && !OldKeyState.NUM0); }
|
||||
bool GetBackspaceJustDown() { return !!(NewKeyState.BACKSP && !OldKeyState.BACKSP); }
|
||||
bool GetTabJustDown() { return !!(NewKeyState.TAB && !OldKeyState.TAB); }
|
||||
bool GetCapsLockJustDown() { return !!(NewKeyState.CAPSLOCK && !OldKeyState.CAPSLOCK); }
|
||||
bool GetReturnJustDown() { return !!(NewKeyState.EXTENTER && !OldKeyState.EXTENTER); }
|
||||
bool GetLeftShiftJustDown() { return !!(NewKeyState.LSHIFT && !OldKeyState.LSHIFT); }
|
||||
bool GetShiftJustDown() { return !!(NewKeyState.SHIFT && !OldKeyState.SHIFT); }
|
||||
bool GetRightShiftJustDown() { return !!(NewKeyState.RSHIFT && !OldKeyState.RSHIFT); }
|
||||
bool GetLeftCtrlJustDown() { return !!(NewKeyState.LCTRL && !OldKeyState.LCTRL); }
|
||||
bool GetRightCtrlJustDown() { return !!(NewKeyState.RCTRL && !OldKeyState.RCTRL); }
|
||||
bool GetLeftAltJustDown() { return !!(NewKeyState.LALT && !OldKeyState.LALT); }
|
||||
bool GetRightAltJustDown() { return !!(NewKeyState.RALT && !OldKeyState.RALT); }
|
||||
bool GetLeftWinJustDown() { return !!(NewKeyState.LWIN && !OldKeyState.LWIN); }
|
||||
bool GetRightWinJustDown() { return !!(NewKeyState.RWIN && !OldKeyState.RWIN); }
|
||||
bool GetAppsJustDown() { return !!(NewKeyState.APPS && !OldKeyState.APPS); }
|
||||
bool GetEnterJustDown() { return GetPadEnterJustDown() || GetReturnJustDown(); }
|
||||
bool GetAltJustDown() { return GetLeftAltJustDown() || GetRightAltJustDown(); }
|
||||
|
||||
bool GetLeftJustUp() { return !!(!NewKeyState.LEFT && OldKeyState.LEFT); }
|
||||
bool GetRightJustUp() { return !!(!NewKeyState.RIGHT && OldKeyState.RIGHT); }
|
||||
bool GetEnterJustUp() { return GetPadEnterJustUp() || GetReturnJustUp(); }
|
||||
bool GetReturnJustUp() { return !!(!NewKeyState.EXTENTER && OldKeyState.EXTENTER); }
|
||||
bool GetPadEnterJustUp() { return !!(!NewKeyState.ENTER && OldKeyState.ENTER); }
|
||||
|
||||
bool GetChar(int32 c) { return NewKeyState.VK_KEYS[c]; }
|
||||
bool GetF(int32 n) { return NewKeyState.F[n]; }
|
||||
bool GetEscape() { return NewKeyState.ESC; }
|
||||
bool GetInsert() { return NewKeyState.INS; }
|
||||
bool GetDelete() { return NewKeyState.DEL; }
|
||||
bool GetHome() { return NewKeyState.HOME; }
|
||||
bool GetEnd() { return NewKeyState.END; }
|
||||
bool GetPageUp() { return NewKeyState.PGUP; }
|
||||
bool GetPageDown() { return NewKeyState.PGDN; }
|
||||
bool GetUp() { return NewKeyState.UP; }
|
||||
bool GetDown() { return NewKeyState.DOWN; }
|
||||
bool GetLeft() { return NewKeyState.LEFT; }
|
||||
bool GetRight() { return NewKeyState.RIGHT; }
|
||||
bool GetScrollLock() { return NewKeyState.SCROLLLOCK; }
|
||||
bool GetPause() { return NewKeyState.PAUSE; }
|
||||
bool GetNumLock() { return NewKeyState.NUMLOCK; }
|
||||
bool GetDivide() { return NewKeyState.DIV; }
|
||||
bool GetTimes() { return NewKeyState.MUL; }
|
||||
bool GetMinus() { return NewKeyState.SUB; }
|
||||
bool GetPlus() { return NewKeyState.ADD; }
|
||||
bool GetPadEnter() { return NewKeyState.ENTER; } // GetEnterJustDown
|
||||
bool GetPadDel() { return NewKeyState.DECIMAL; }
|
||||
bool GetPad1() { return NewKeyState.NUM1; }
|
||||
bool GetPad2() { return NewKeyState.NUM2; }
|
||||
bool GetPad3() { return NewKeyState.NUM3; }
|
||||
bool GetPad4() { return NewKeyState.NUM4; }
|
||||
bool GetPad5() { return NewKeyState.NUM5; }
|
||||
bool GetPad6() { return NewKeyState.NUM6; }
|
||||
bool GetPad7() { return NewKeyState.NUM7; }
|
||||
bool GetPad8() { return NewKeyState.NUM8; }
|
||||
bool GetPad9() { return NewKeyState.NUM9; }
|
||||
bool GetPad0() { return NewKeyState.NUM0; }
|
||||
bool GetBackspace() { return NewKeyState.BACKSP; }
|
||||
bool GetTab() { return NewKeyState.TAB; }
|
||||
bool GetCapsLock() { return NewKeyState.CAPSLOCK; }
|
||||
bool GetEnter() { return NewKeyState.EXTENTER; }
|
||||
bool GetLeftShift() { return NewKeyState.LSHIFT; }
|
||||
bool GetShift() { return NewKeyState.SHIFT; }
|
||||
bool GetRightShift() { return NewKeyState.RSHIFT; }
|
||||
bool GetLeftCtrl() { return NewKeyState.LCTRL; }
|
||||
bool GetRightCtrl() { return NewKeyState.RCTRL; }
|
||||
bool GetLeftAlt() { return NewKeyState.LALT; }
|
||||
bool GetRightAlt() { return NewKeyState.RALT; }
|
||||
bool GetLeftWin() { return NewKeyState.LWIN; }
|
||||
bool GetRightWin() { return NewKeyState.RWIN; }
|
||||
bool GetApps() { return NewKeyState.APPS; }
|
||||
// pad
|
||||
|
||||
bool GetTriangleJustDown() { return !!(NewState.Triangle && !OldState.Triangle); }
|
||||
bool GetCircleJustDown() { return !!(NewState.Circle && !OldState.Circle); }
|
||||
bool GetCrossJustDown() { return !!(NewState.Cross && !OldState.Cross); }
|
||||
bool GetSquareJustDown() { return !!(NewState.Square && !OldState.Square); }
|
||||
bool GetDPadUpJustDown() { return !!(NewState.DPadUp && !OldState.DPadUp); }
|
||||
bool GetDPadDownJustDown() { return !!(NewState.DPadDown && !OldState.DPadDown); }
|
||||
bool GetDPadLeftJustDown() { return !!(NewState.DPadLeft && !OldState.DPadLeft); }
|
||||
bool GetDPadRightJustDown() { return !!(NewState.DPadRight && !OldState.DPadRight); }
|
||||
bool GetLeftShoulder1JustDown() { return !!(NewState.LeftShoulder1 && !OldState.LeftShoulder1); }
|
||||
bool GetLeftShoulder2JustDown() { return !!(NewState.LeftShoulder2 && !OldState.LeftShoulder2); }
|
||||
bool GetRightShoulder1JustDown() { return !!(NewState.RightShoulder1 && !OldState.RightShoulder1); }
|
||||
bool GetRightShoulder2JustDown() { return !!(NewState.RightShoulder2 && !OldState.RightShoulder2); }
|
||||
bool GetLeftShockJustDown() { return !!(NewState.LeftShock && !OldState.LeftShock); }
|
||||
bool GetRightShockJustDown() { return !!(NewState.RightShock && !OldState.RightShock); }
|
||||
bool GetStartJustDown() { return !!(NewState.Start && !OldState.Start); }
|
||||
bool GetLeftStickXJustDown() { return !!(NewState.LeftStickX && !OldState.LeftStickX); }
|
||||
bool GetLeftStickYJustDown() { return !!(NewState.LeftStickY && !OldState.LeftStickY); }
|
||||
|
||||
bool GetTriangleJustUp() { return !!(!NewState.Triangle && OldState.Triangle); }
|
||||
bool GetCircleJustUp() { return !!(!NewState.Circle && OldState.Circle); }
|
||||
bool GetCrossJustUp() { return !!(!NewState.Cross && OldState.Cross); }
|
||||
bool GetSquareJustUp() { return !!(!NewState.Square && OldState.Square); }
|
||||
bool GetDPadUpJustUp() { return !!(!NewState.DPadUp && OldState.DPadUp); }
|
||||
bool GetDPadDownJustUp() { return !!(!NewState.DPadDown && OldState.DPadDown); }
|
||||
bool GetDPadLeftJustUp() { return !!(!NewState.DPadLeft && OldState.DPadLeft); }
|
||||
bool GetDPadRightJustUp() { return !!(!NewState.DPadRight && OldState.DPadRight); }
|
||||
|
||||
bool GetTriangle() { return !!NewState.Triangle; }
|
||||
bool GetCircle() { return !!NewState.Circle; }
|
||||
bool GetCross() { return !!NewState.Cross; }
|
||||
bool GetSquare() { return !!NewState.Square; }
|
||||
bool GetDPadUp() { return !!NewState.DPadUp; }
|
||||
bool GetDPadDown() { return !!NewState.DPadDown; }
|
||||
bool GetDPadLeft() { return !!NewState.DPadLeft; }
|
||||
bool GetDPadRight() { return !!NewState.DPadRight; }
|
||||
bool GetLeftShoulder1(void) { return !!NewState.LeftShoulder1; }
|
||||
bool GetLeftShoulder2(void) { return !!NewState.LeftShoulder2; }
|
||||
bool GetRightShoulder1(void) { return !!NewState.RightShoulder1; }
|
||||
bool GetRightShoulder2(void) { return !!NewState.RightShoulder2; }
|
||||
bool GetStart() { return !!NewState.Start; }
|
||||
int16 GetLeftStickX(void) { return NewState.LeftStickX; }
|
||||
int16 GetLeftStickY(void) { return NewState.LeftStickY; }
|
||||
int16 GetRightStickX(void) { return NewState.RightStickX; }
|
||||
int16 GetRightStickY(void) { return NewState.RightStickY; }
|
||||
|
||||
bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; }
|
||||
void SetDisablePlayerControls(uint8 who) { DisablePlayerControls |= who; }
|
||||
void SetEnablePlayerControls(uint8 who) { DisablePlayerControls &= ~who; }
|
||||
bool IsPlayerControlsDisabledBy(uint8 who) { return DisablePlayerControls & who; }
|
||||
|
||||
int16 GetMode() { return Mode; }
|
||||
void SetMode(int16 mode) { Mode = mode; }
|
||||
|
||||
static bool IsNoOrObsolete() { return bDisplayNoControllerMessage || bObsoleteControllerMessage; }
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CPad, 0xFC);
|
||||
extern CPad Pads[MAX_PADS];
|
||||
|
||||
#ifdef ALLCARSHELI_CHEAT
|
||||
extern bool bAllCarCheat;
|
||||
#endif
|
||||
66
src/core/Placeable.cpp
Normal file
66
src/core/Placeable.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include "common.h"
|
||||
#include "Placeable.h"
|
||||
|
||||
|
||||
CPlaceable::CPlaceable(void)
|
||||
{
|
||||
m_matrix.SetScale(1.0f);
|
||||
}
|
||||
|
||||
CPlaceable::~CPlaceable(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CPlaceable::SetHeading(float angle)
|
||||
{
|
||||
CVector pos = GetMatrix().GetPosition();
|
||||
m_matrix.SetRotateZ(angle);
|
||||
GetMatrix().Translate(pos);
|
||||
}
|
||||
|
||||
bool
|
||||
CPlaceable::IsWithinArea(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
float tmp;
|
||||
|
||||
if(x1 > x2){
|
||||
tmp = x1;
|
||||
x1 = x2;
|
||||
x2 = tmp;
|
||||
}
|
||||
if(y1 > y2){
|
||||
tmp = y1;
|
||||
y1 = y2;
|
||||
y2 = tmp;
|
||||
}
|
||||
|
||||
return x1 <= GetPosition().x && GetPosition().x <= x2 &&
|
||||
y1 <= GetPosition().y && GetPosition().y <= y2;
|
||||
}
|
||||
|
||||
bool
|
||||
CPlaceable::IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
{
|
||||
float tmp;
|
||||
|
||||
if(x1 > x2){
|
||||
tmp = x1;
|
||||
x1 = x2;
|
||||
x2 = tmp;
|
||||
}
|
||||
if(y1 > y2){
|
||||
tmp = y1;
|
||||
y1 = y2;
|
||||
y2 = tmp;
|
||||
}
|
||||
if(z1 > z2){
|
||||
tmp = z1;
|
||||
z1 = z2;
|
||||
z2 = tmp;
|
||||
}
|
||||
|
||||
return x1 <= GetPosition().x && GetPosition().x <= x2 &&
|
||||
y1 <= GetPosition().y && GetPosition().y <= y2 &&
|
||||
z1 <= GetPosition().z && GetPosition().z <= z2;
|
||||
}
|
||||
37
src/core/Placeable.h
Normal file
37
src/core/Placeable.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
class CPlaceable
|
||||
{
|
||||
protected:
|
||||
CMatrix m_matrix;
|
||||
|
||||
public:
|
||||
// disable allocation
|
||||
static void *operator new(size_t) throw();
|
||||
|
||||
CPlaceable(void);
|
||||
virtual ~CPlaceable(void);
|
||||
const CVector &GetPosition(void) { return m_matrix.GetPosition(); }
|
||||
void SetPosition(float x, float y, float z) {
|
||||
m_matrix.GetPosition().x = x;
|
||||
m_matrix.GetPosition().y = y;
|
||||
m_matrix.GetPosition().z = z;
|
||||
}
|
||||
void SetPosition(const CVector &pos) { m_matrix.GetPosition() = pos; }
|
||||
CVector &GetRight(void) { return m_matrix.GetRight(); }
|
||||
CVector &GetForward(void) { return m_matrix.GetForward(); }
|
||||
CVector &GetUp(void) { return m_matrix.GetUp(); }
|
||||
CMatrix &GetMatrix(void) { return m_matrix; }
|
||||
void SetMatrix(CMatrix &newMatrix) { m_matrix = newMatrix; }
|
||||
void SetTransform(RwMatrix *m) { m_matrix = CMatrix(m, false); }
|
||||
void SetHeading(float angle);
|
||||
void SetOrientation(float x, float y, float z){
|
||||
CVector pos = m_matrix.GetPosition();
|
||||
m_matrix.SetRotate(x, y, z);
|
||||
m_matrix.Translate(pos);
|
||||
}
|
||||
bool IsWithinArea(float x1, float y1, float x2, float y2);
|
||||
bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2);
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CPlaceable, 0x4C);
|
||||
662
src/core/PlayerInfo.cpp
Normal file
662
src/core/PlayerInfo.cpp
Normal file
|
|
@ -0,0 +1,662 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Automobile.h"
|
||||
#include "Bridge.h"
|
||||
#include "Camera.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "Cranes.h"
|
||||
#include "Darkel.h"
|
||||
#include "Explosion.h"
|
||||
#include "Fire.h"
|
||||
#include "Frontend.h"
|
||||
#include "General.h"
|
||||
#include "HandlingMgr.h"
|
||||
#include "Messages.h"
|
||||
#include "Pad.h"
|
||||
#include "PathFind.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "PlayerSkin.h"
|
||||
#include "ProjectileInfo.h"
|
||||
#include "Remote.h"
|
||||
#include "Renderer.h"
|
||||
#include "Replay.h"
|
||||
#include "Script.h"
|
||||
#include "SpecialFX.h"
|
||||
#include "Stats.h"
|
||||
#include "Streaming.h"
|
||||
#include "Text.h"
|
||||
#include "Wanted.h"
|
||||
#include "WaterLevel.h"
|
||||
#include "World.h"
|
||||
#include "ZoneCull.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
void
|
||||
CPlayerInfo::Clear(void)
|
||||
{
|
||||
m_pPed = nil;
|
||||
m_pRemoteVehicle = nil;
|
||||
if (m_pVehicleEx) {
|
||||
m_pVehicleEx->bUsingSpecialColModel = false;
|
||||
m_pVehicleEx = nil;
|
||||
}
|
||||
m_nVisibleMoney = 0;
|
||||
m_nMoney = m_nVisibleMoney;
|
||||
m_WBState = WBSTATE_PLAYING;
|
||||
m_nWBTime = 0;
|
||||
m_nTrafficMultiplier = 0;
|
||||
m_fRoadDensity = 1.0f;
|
||||
m_bInRemoteMode = false;
|
||||
m_bUnusedTaxiThing = false;
|
||||
m_nUnusedTaxiTimer = 0;
|
||||
m_nCollectedPackages = 0;
|
||||
m_nTotalPackages = 3;
|
||||
m_nTimeLastHealthLoss = 0;
|
||||
m_nTimeLastArmourLoss = 0;
|
||||
m_nNextSexFrequencyUpdateTime = 0;
|
||||
m_nNextSexMoneyUpdateTime = 0;
|
||||
m_nSexFrequency = 0;
|
||||
m_pHooker = nil;
|
||||
m_nTimeTankShotGun = 0;
|
||||
field_248 = 0;
|
||||
m_nUpsideDownCounter = 0;
|
||||
m_bInfiniteSprint = false;
|
||||
m_bFastReload = false;
|
||||
m_bGetOutOfJailFree = false;
|
||||
m_bGetOutOfHospitalFree = false;
|
||||
m_nPreviousTimeRewardedForExplosion = 0;
|
||||
m_nExplosionsSinceLastReward = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::Process(void)
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
if (CReplay::IsPlayingBack())
|
||||
return;
|
||||
#endif
|
||||
// Unused taxi feature. Gives you a dollar for every second with a passenger. Can be toggled via 0x29A opcode.
|
||||
bool startTaxiTimer = true;
|
||||
if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
|
||||
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||
if ((veh->GetModelIndex() == MI_TAXI || veh->GetModelIndex() == MI_CABBIE || veh->GetModelIndex() == MI_BORGNINE)
|
||||
&& veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
|
||||
for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
|
||||
timePassed -= 1000;
|
||||
++m_nMoney;
|
||||
}
|
||||
startTaxiTimer = false;
|
||||
}
|
||||
}
|
||||
if (startTaxiTimer)
|
||||
m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
|
||||
|
||||
// The effect that makes money counter does while earning/losing money
|
||||
if (m_nVisibleMoney != m_nMoney) {
|
||||
int diff = m_nMoney - m_nVisibleMoney;
|
||||
int diffAbs = Abs(diff);
|
||||
int changeBy;
|
||||
|
||||
if (diffAbs > 100000)
|
||||
changeBy = 12345;
|
||||
else if (diffAbs > 10000)
|
||||
changeBy = 1234;
|
||||
else if (diffAbs > 1000)
|
||||
changeBy = 123;
|
||||
else if (diffAbs > 50)
|
||||
changeBy = 42;
|
||||
else
|
||||
changeBy = 1;
|
||||
|
||||
if (diff < 0)
|
||||
m_nVisibleMoney -= changeBy;
|
||||
else
|
||||
m_nVisibleMoney += changeBy;
|
||||
}
|
||||
|
||||
if (!(CTimer::GetFrameCounter() & 15)) {
|
||||
CVector2D playerPos = m_pPed->bInVehicle ? m_pPed->m_pMyVehicle->GetPosition() : m_pPed->GetPosition();
|
||||
m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
|
||||
}
|
||||
|
||||
m_fRoadDensity = Clamp(m_fRoadDensity, 0.4f, 1.45f);
|
||||
|
||||
// Because vehicle enter/exit use same key binding.
|
||||
bool enterOrExitVeh;
|
||||
if (m_pPed->bVehExitWillBeInstant && m_pPed->bInVehicle)
|
||||
enterOrExitVeh = CPad::GetPad(0)->ExitVehicleJustDown();
|
||||
else
|
||||
enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
|
||||
|
||||
if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_MODE) {
|
||||
if (m_pPed->bInVehicle) {
|
||||
if (!m_pRemoteVehicle) {
|
||||
CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
|
||||
if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->GetModelIndex())) {
|
||||
CVehicle *veh = m_pPed->m_pMyVehicle;
|
||||
if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
|
||||
// This condition will always return true, else block was probably WIP Miami code.
|
||||
if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
if (veh->GetStatus() != STATUS_WRECKED && veh->GetStatus() != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
|
||||
if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
|
||||
m_pPed->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
|
||||
bool found = false;
|
||||
float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
|
||||
|
||||
if (found)
|
||||
sth.z = 1.0f + groundZ;
|
||||
m_pPed->SetPedState(PED_IDLE);
|
||||
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||
CPed::PedSetOutCarCB(0, m_pPed);
|
||||
CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_STD_IDLE, 100.0f);
|
||||
CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_STD_FALL_LAND, 100.0f);
|
||||
m_pPed->SetPosition(sth);
|
||||
m_pPed->SetMoveState(PEDMOVE_STILL);
|
||||
m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
|
||||
}
|
||||
} else {
|
||||
// The code in here was under CPed::SetExitBoat in VC, did the same for here.
|
||||
m_pPed->SetExitBoat(veh);
|
||||
m_pPed->bTryingToReachDryLand = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Enter vehicle
|
||||
if (CPad::GetPad(0)->ExitVehicleJustDown()) {
|
||||
bool weAreOnBoat = false;
|
||||
float lastCloseness = 0.0f;
|
||||
CVehicle *carBelow = nil;
|
||||
CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
|
||||
if (surfaceBelow && surfaceBelow->IsVehicle()) {
|
||||
carBelow = (CVehicle*)surfaceBelow;
|
||||
if (carBelow->IsBoat()) {
|
||||
weAreOnBoat = true;
|
||||
m_pPed->bOnBoat = true;
|
||||
#ifdef VC_PED_PORTS
|
||||
if (carBelow->GetStatus() != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
|
||||
#else
|
||||
if (carBelow->GetStatus() != STATUS_WRECKED)
|
||||
#endif
|
||||
m_pPed->SetSeekBoatPosition(carBelow);
|
||||
}
|
||||
}
|
||||
// Find closest car
|
||||
if (!weAreOnBoat) {
|
||||
float minX = m_pPed->GetPosition().x - 10.0f;
|
||||
float maxX = 10.0f + m_pPed->GetPosition().x;
|
||||
float minY = m_pPed->GetPosition().y - 10.0f;
|
||||
float maxY = 10.0f + m_pPed->GetPosition().y;
|
||||
|
||||
int minXSector = CWorld::GetSectorIndexX(minX);
|
||||
if (minXSector < 0) minXSector = 0;
|
||||
int minYSector = CWorld::GetSectorIndexY(minY);
|
||||
if (minYSector < 0) minYSector = 0;
|
||||
int maxXSector = CWorld::GetSectorIndexX(maxX);
|
||||
if (maxXSector > NUMSECTORS_X - 1) maxXSector = NUMSECTORS_X - 1;
|
||||
int maxYSector = CWorld::GetSectorIndexY(maxY);
|
||||
if (maxYSector > NUMSECTORS_Y - 1) maxYSector = NUMSECTORS_Y - 1;
|
||||
|
||||
CWorld::AdvanceCurrentScanCode();
|
||||
|
||||
for (int curY = minYSector; curY <= maxYSector; curY++) {
|
||||
for (int curX = minXSector; curX <= maxXSector; curX++) {
|
||||
CSector *sector = CWorld::GetSector(curX, curY);
|
||||
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES], m_pPed,
|
||||
minX, minY, maxX, maxY, &lastCloseness, &carBelow);
|
||||
FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], m_pPed,
|
||||
minX, minY, maxX, maxY, &lastCloseness, &carBelow);
|
||||
}
|
||||
}
|
||||
}
|
||||
// carBelow is now closest vehicle
|
||||
if (carBelow && !weAreOnBoat) {
|
||||
if (carBelow->GetStatus() == STATUS_TRAIN_NOT_MOVING) {
|
||||
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow);
|
||||
} else if (carBelow->IsBoat()) {
|
||||
if (!carBelow->pDriver) {
|
||||
m_pPed->m_vehDoor = 0;
|
||||
m_pPed->SetEnterCar(carBelow, m_pPed->m_vehDoor);
|
||||
}
|
||||
} else {
|
||||
m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_bInRemoteMode) {
|
||||
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
|
||||
if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(1.0f, FADE_OUT);
|
||||
}
|
||||
if (timeWithoutRemoteCar > 2000) {
|
||||
if (m_WBState == WBSTATE_PLAYING) {
|
||||
TheCamera.RestoreWithJumpCut();
|
||||
TheCamera.SetFadeColour(0, 0, 0);
|
||||
TheCamera.Fade(1.0f, FADE_IN);
|
||||
TheCamera.Process();
|
||||
CTimer::Stop();
|
||||
CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
|
||||
CRenderer::RequestObjectsInFrustum();
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
CTimer::Update();
|
||||
}
|
||||
m_bInRemoteMode = false;
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
|
||||
if (FindPlayerVehicle()) {
|
||||
FindPlayerVehicle()->SetStatus(STATUS_PLAYER);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(CTimer::GetFrameCounter() & 31)) {
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
|
||||
&& veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
|
||||
|
||||
if (veh->GetUp().z < -0.5f) {
|
||||
m_nUpsideDownCounter += 2;
|
||||
|
||||
} else {
|
||||
m_nUpsideDownCounter++;
|
||||
}
|
||||
} else {
|
||||
m_nUpsideDownCounter = 0;
|
||||
}
|
||||
|
||||
if (m_nUpsideDownCounter > 6 && veh->bCanBeDamaged) {
|
||||
veh->m_fHealth = 249.0f < veh->m_fHealth ? 249.0f : veh->m_fHealth;
|
||||
if (veh->IsCar()) {
|
||||
CAutomobile* car = (CAutomobile*)veh;
|
||||
car->Damage.SetEngineStatus(225);
|
||||
car->m_pSetOnFireEntity = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FindPlayerVehicle()) {
|
||||
CVehicle *veh = FindPlayerVehicle();
|
||||
veh->m_nZoneLevel = LEVEL_IGNORE;
|
||||
for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
|
||||
if (veh->pPassengers[i])
|
||||
veh->pPassengers[i]->m_nZoneLevel = LEVEL_GENERIC;
|
||||
}
|
||||
CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
|
||||
} else {
|
||||
CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CPlayerInfo::IsPlayerInRemoteMode()
|
||||
{
|
||||
return m_pRemoteVehicle || m_bInRemoteMode;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
|
||||
{
|
||||
// Interesting
|
||||
*size = sizeof(CPlayerInfo);
|
||||
|
||||
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
|
||||
CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName);
|
||||
#undef CopyToBuf
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
|
||||
{
|
||||
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
|
||||
CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName)
|
||||
#undef CopyFromBuf
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
|
||||
{
|
||||
for (CPtrNode* node = carList.first; node; node = node->next) {
|
||||
CVehicle *car = (CVehicle*)node->item;
|
||||
if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
|
||||
if (!car->bUsesCollision || !car->IsVehicle())
|
||||
continue;
|
||||
|
||||
car->m_scanCode = CWorld::GetCurrentScanCode();
|
||||
if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING
|
||||
&& (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
|
||||
CVector carCentre = car->GetBoundCentre();
|
||||
|
||||
if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
|
||||
float dist = (ped->GetPosition() - carCentre).Magnitude2D();
|
||||
if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
|
||||
EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// lastCloseness is passed to other calls of this function
|
||||
void
|
||||
CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
|
||||
{
|
||||
// This dist used for determining the angle to face
|
||||
CVector2D dist(carToTest->GetPosition() - player->GetPosition());
|
||||
float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
|
||||
while (neededTurn >= PI) {
|
||||
neededTurn -= 2 * PI;
|
||||
}
|
||||
|
||||
while (neededTurn < -PI) {
|
||||
neededTurn += 2 * PI;
|
||||
}
|
||||
|
||||
// This dist used for evaluating cars' distances, weird...
|
||||
// Accounts inverted needed turn (or needed turn in long way) and car dist.
|
||||
float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
|
||||
if (closeness > *lastCloseness) {
|
||||
*lastCloseness = closeness;
|
||||
*closestCarOutput = (CVehicle*)carToTest;
|
||||
}
|
||||
}
|
||||
|
||||
const CVector &
|
||||
CPlayerInfo::GetPos()
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
if (!m_pPed)
|
||||
return TheCamera.GetPosition();
|
||||
#endif
|
||||
if (m_pPed->InVehicle())
|
||||
return m_pPed->m_pMyVehicle->GetPosition();
|
||||
return m_pPed->GetPosition();
|
||||
}
|
||||
|
||||
CVector
|
||||
FindPlayerCoors(void)
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
if (CReplay::IsPlayingBack())
|
||||
return TheCamera.GetPosition();
|
||||
#endif
|
||||
CPlayerPed *ped = FindPlayerPed();
|
||||
if(ped->InVehicle())
|
||||
return ped->m_pMyVehicle->GetPosition();
|
||||
else
|
||||
return ped->GetPosition();
|
||||
}
|
||||
|
||||
const CVector &
|
||||
FindPlayerSpeed(void)
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
static CVector vecTmpVector(0.0f, 0.0f, 0.0f);
|
||||
if (CReplay::IsPlayingBack())
|
||||
return vecTmpVector;
|
||||
#endif
|
||||
CPlayerPed *ped = FindPlayerPed();
|
||||
if(ped->InVehicle())
|
||||
return ped->m_pMyVehicle->m_vecMoveSpeed;
|
||||
else
|
||||
return ped->m_vecMoveSpeed;
|
||||
}
|
||||
|
||||
CVehicle *
|
||||
FindPlayerVehicle(void)
|
||||
{
|
||||
CPlayerPed *ped = FindPlayerPed();
|
||||
if(ped && ped->InVehicle()) return ped->m_pMyVehicle;
|
||||
return nil;
|
||||
}
|
||||
|
||||
CEntity *
|
||||
FindPlayerEntity(void)
|
||||
{
|
||||
CPlayerPed *ped = FindPlayerPed();
|
||||
if(ped->InVehicle())
|
||||
return ped->m_pMyVehicle;
|
||||
else
|
||||
return ped;
|
||||
}
|
||||
|
||||
CVehicle *
|
||||
FindPlayerTrain(void)
|
||||
{
|
||||
if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain())
|
||||
return FindPlayerVehicle();
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
CPlayerPed *
|
||||
FindPlayerPed(void)
|
||||
{
|
||||
return CWorld::Players[CWorld::PlayerInFocus].m_pPed;
|
||||
}
|
||||
|
||||
const CVector &
|
||||
FindPlayerCentreOfWorld(int32 player)
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
if(CReplay::IsPlayingBack()) return TheCamera.GetPosition();
|
||||
#endif
|
||||
if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
|
||||
if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition();
|
||||
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
|
||||
return CWorld::Players[player].m_pPed->GetPosition();
|
||||
}
|
||||
|
||||
const CVector &
|
||||
FindPlayerCentreOfWorld_NoSniperShift(void)
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
if (CReplay::IsPlayingBack()) return TheCamera.GetPosition();
|
||||
#endif
|
||||
if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
|
||||
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
|
||||
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
|
||||
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
|
||||
return FindPlayerPed()->GetPosition();
|
||||
}
|
||||
|
||||
float
|
||||
FindPlayerHeading(void)
|
||||
{
|
||||
if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
|
||||
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
|
||||
if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading();
|
||||
return FindPlayerPed()->GetForward().Heading();
|
||||
}
|
||||
|
||||
bool
|
||||
CPlayerInfo::IsRestartingAfterDeath()
|
||||
{
|
||||
return m_WBState == WBSTATE_WASTED;
|
||||
}
|
||||
|
||||
bool
|
||||
CPlayerInfo::IsRestartingAfterArrest()
|
||||
{
|
||||
return m_WBState == WBSTATE_BUSTED;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::KillPlayer()
|
||||
{
|
||||
if (m_WBState != WBSTATE_PLAYING) return;
|
||||
|
||||
m_WBState = WBSTATE_WASTED;
|
||||
m_nWBTime = CTimer::GetTimeInMilliseconds();
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
|
||||
CStats::TimesDied++;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::ArrestPlayer()
|
||||
{
|
||||
if (m_WBState != WBSTATE_PLAYING) return;
|
||||
|
||||
m_WBState = WBSTATE_BUSTED;
|
||||
m_nWBTime = CTimer::GetTimeInMilliseconds();
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
|
||||
CStats::TimesArrested++;
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::PlayerFailedCriticalMission()
|
||||
{
|
||||
if (m_WBState != WBSTATE_PLAYING)
|
||||
return;
|
||||
m_WBState = WBSTATE_FAILED_CRITICAL_MISSION;
|
||||
m_nWBTime = CTimer::GetTimeInMilliseconds();
|
||||
CDarkel::ResetOnPlayerDeath();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
|
||||
{
|
||||
if (!car || car == m_pPed->m_pMyVehicle) {
|
||||
if (m_pPed->EnteringCar())
|
||||
m_pPed->QuitEnteringCar();
|
||||
}
|
||||
if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
||||
m_pPed->ClearObjective();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::MakePlayerSafe(bool toggle)
|
||||
{
|
||||
if (toggle) {
|
||||
CTheScripts::ResetCountdownToMakePlayerUnsafe();
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
|
||||
CWorld::StopAllLawEnforcersInTheirTracks();
|
||||
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO);
|
||||
CPad::StopPadsShaking();
|
||||
m_pPed->bBulletProof = true;
|
||||
m_pPed->bFireProof = true;
|
||||
m_pPed->bCollisionProof = true;
|
||||
m_pPed->bMeleeProof = true;
|
||||
m_pPed->bOnlyDamagedByPlayer = true;
|
||||
m_pPed->bExplosionProof = true;
|
||||
m_pPed->m_bCanBeDamaged = false;
|
||||
((CPlayerPed*)m_pPed)->ClearAdrenaline();
|
||||
CancelPlayerEnteringCars(nil);
|
||||
gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
|
||||
CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
|
||||
CProjectileInfo::RemoveAllProjectiles();
|
||||
CWorld::SetAllCarsCanBeDamaged(false);
|
||||
CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
|
||||
CReplay::DisableReplays();
|
||||
|
||||
} else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) {
|
||||
m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
|
||||
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO);
|
||||
m_pPed->bBulletProof = false;
|
||||
m_pPed->bFireProof = false;
|
||||
m_pPed->bCollisionProof = false;
|
||||
m_pPed->bMeleeProof = false;
|
||||
m_pPed->bOnlyDamagedByPlayer = false;
|
||||
m_pPed->bExplosionProof = false;
|
||||
m_pPed->m_bCanBeDamaged = true;
|
||||
CWorld::SetAllCarsCanBeDamaged(true);
|
||||
CReplay::EnableReplays();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::BlowUpRCBuggy(void)
|
||||
{
|
||||
if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
|
||||
return;
|
||||
|
||||
CRemote::TakeRemoteControlledCarFromPlayer();
|
||||
m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
|
||||
}
|
||||
|
||||
// There is something unfinished in here... Sadly all IDBs we have have it unfinished.
|
||||
void
|
||||
CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
|
||||
{
|
||||
if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
|
||||
++m_nExplosionsSinceLastReward;
|
||||
else
|
||||
m_nExplosionsSinceLastReward = 1;
|
||||
|
||||
m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
|
||||
int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
|
||||
sprintf(gString, "$%d", award);
|
||||
#ifdef MONEY_MESSAGES
|
||||
// This line is a leftover from PS2, I don't know what it was meant to be.
|
||||
// CVector sth(TheCamera.GetPosition() * 4.0f);
|
||||
|
||||
CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
|
||||
#endif
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||
|
||||
for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
|
||||
CGeneral::GetRandomNumber();
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GTA_PC
|
||||
void
|
||||
CPlayerInfo::SetPlayerSkin(const char *skin)
|
||||
{
|
||||
strncpy(m_aSkinName, skin, 32);
|
||||
LoadPlayerSkin();
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::LoadPlayerSkin()
|
||||
{
|
||||
DeletePlayerSkin();
|
||||
|
||||
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
|
||||
if (!m_pSkinTexture)
|
||||
m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
|
||||
}
|
||||
|
||||
void
|
||||
CPlayerInfo::DeletePlayerSkin()
|
||||
{
|
||||
if (m_pSkinTexture) {
|
||||
RwTextureDestroy(m_pSkinTexture);
|
||||
m_pSkinTexture = nil;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
97
src/core/PlayerInfo.h
Normal file
97
src/core/PlayerInfo.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#pragma once
|
||||
|
||||
#include "ColModel.h"
|
||||
|
||||
enum eWastedBustedState
|
||||
{
|
||||
WBSTATE_PLAYING,
|
||||
WBSTATE_WASTED,
|
||||
WBSTATE_BUSTED,
|
||||
WBSTATE_FAILED_CRITICAL_MISSION,
|
||||
};
|
||||
|
||||
class CEntity;
|
||||
class CPed;
|
||||
class CVehicle;
|
||||
class CPlayerPed;
|
||||
class CCivilianPed;
|
||||
|
||||
class CPlayerInfo
|
||||
{
|
||||
public:
|
||||
CPlayerPed *m_pPed;
|
||||
CVehicle *m_pRemoteVehicle;
|
||||
CColModel m_ColModel;
|
||||
CVehicle *m_pVehicleEx; // vehicle using the col model above
|
||||
char m_aPlayerName[70];
|
||||
int32 m_nMoney;
|
||||
int32 m_nVisibleMoney;
|
||||
int32 m_nCollectedPackages;
|
||||
int32 m_nTotalPackages;
|
||||
uint32 m_nLastBumpPlayerCarTimer;
|
||||
uint32 m_nUnusedTaxiTimer;
|
||||
bool m_bUnusedTaxiThing;
|
||||
uint32 m_nNextSexFrequencyUpdateTime;
|
||||
uint32 m_nNextSexMoneyUpdateTime;
|
||||
int32 m_nSexFrequency;
|
||||
CCivilianPed *m_pHooker;
|
||||
int8 m_WBState; // eWastedBustedState
|
||||
uint32 m_nWBTime;
|
||||
bool m_bInRemoteMode;
|
||||
uint32 m_nTimeLostRemoteCar;
|
||||
uint32 m_nTimeLastHealthLoss;
|
||||
uint32 m_nTimeLastArmourLoss;
|
||||
uint32 m_nTimeTankShotGun;
|
||||
int32 m_nUpsideDownCounter;
|
||||
int32 field_248;
|
||||
int16 m_nTrafficMultiplier;
|
||||
float m_fRoadDensity;
|
||||
uint32 m_nPreviousTimeRewardedForExplosion;
|
||||
int32 m_nExplosionsSinceLastReward;
|
||||
int32 field_268;
|
||||
int32 field_272;
|
||||
bool m_bInfiniteSprint;
|
||||
bool m_bFastReload;
|
||||
bool m_bGetOutOfJailFree;
|
||||
bool m_bGetOutOfHospitalFree;
|
||||
#ifdef GTA_PC
|
||||
char m_aSkinName[32];
|
||||
RwTexture *m_pSkinTexture;
|
||||
#endif
|
||||
|
||||
void MakePlayerSafe(bool);
|
||||
void AwardMoneyForExplosion(CVehicle *vehicle);
|
||||
const CVector &GetPos();
|
||||
void Process(void);
|
||||
void KillPlayer(void);
|
||||
void ArrestPlayer(void);
|
||||
bool IsPlayerInRemoteMode(void);
|
||||
void PlayerFailedCriticalMission(void);
|
||||
void Clear(void);
|
||||
void BlowUpRCBuggy(void);
|
||||
void CancelPlayerEnteringCars(CVehicle*);
|
||||
bool IsRestartingAfterDeath(void);
|
||||
bool IsRestartingAfterArrest(void);
|
||||
void EvaluateCarPosition(CEntity*, CPed*, float, float*, CVehicle**);
|
||||
void LoadPlayerInfo(uint8 *buf, uint32 size);
|
||||
void SavePlayerInfo(uint8 *buf, uint32* size);
|
||||
void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**);
|
||||
|
||||
#ifdef GTA_PC
|
||||
void LoadPlayerSkin();
|
||||
void SetPlayerSkin(const char *skin);
|
||||
void DeletePlayerSkin();
|
||||
#endif
|
||||
};
|
||||
|
||||
CPlayerPed *FindPlayerPed(void);
|
||||
CVehicle *FindPlayerVehicle(void);
|
||||
CVehicle *FindPlayerTrain(void);
|
||||
CEntity *FindPlayerEntity(void);
|
||||
CVector FindPlayerCoors(void);
|
||||
const CVector &FindPlayerSpeed(void);
|
||||
const CVector &FindPlayerCentreOfWorld(int32 player);
|
||||
const CVector &FindPlayerCentreOfWorld_NoSniperShift(void);
|
||||
float FindPlayerHeading(void);
|
||||
|
||||
VALIDATE_SIZE(CPlayerInfo, 0x13C);
|
||||
585
src/core/Pools.cpp
Normal file
585
src/core/Pools.cpp
Normal file
|
|
@ -0,0 +1,585 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Pools.h"
|
||||
|
||||
#include "Boat.h"
|
||||
#include "CarCtrl.h"
|
||||
#ifdef MISSION_REPLAY
|
||||
#include "GenericGameStorage.h"
|
||||
#endif
|
||||
#include "Population.h"
|
||||
#include "ProjectileInfo.h"
|
||||
#include "SaveBuf.h"
|
||||
#include "Streaming.h"
|
||||
#include "Wanted.h"
|
||||
#include "World.h"
|
||||
#include "MemoryHeap.h"
|
||||
|
||||
CCPtrNodePool *CPools::ms_pPtrNodePool;
|
||||
CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool;
|
||||
CPedPool *CPools::ms_pPedPool;
|
||||
CVehiclePool *CPools::ms_pVehiclePool;
|
||||
CBuildingPool *CPools::ms_pBuildingPool;
|
||||
CTreadablePool *CPools::ms_pTreadablePool;
|
||||
CObjectPool *CPools::ms_pObjectPool;
|
||||
CDummyPool *CPools::ms_pDummyPool;
|
||||
CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool;
|
||||
|
||||
#ifdef GTA_PS2 // or USE_CUSTOM_ALLOCATOR
|
||||
#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);
|
||||
CHECKMEM("after CPtrNodePool");
|
||||
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
|
||||
CHECKMEM("after CEntryInfoNodePool");
|
||||
ms_pPedPool = new CPedPool(NUMPEDS);
|
||||
CHECKMEM("after CPedPool");
|
||||
ms_pVehiclePool = new CVehiclePool(NUMVEHICLES);
|
||||
CHECKMEM("after CVehiclePool");
|
||||
ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS);
|
||||
CHECKMEM("after CBuildingPool");
|
||||
ms_pTreadablePool = new CTreadablePool(NUMTREADABLES);
|
||||
CHECKMEM("after CTreadablePool");
|
||||
ms_pObjectPool = new CObjectPool(NUMOBJECTS);
|
||||
CHECKMEM("after CObjectPool");
|
||||
ms_pDummyPool = new CDummyPool(NUMDUMMIES);
|
||||
CHECKMEM("after CDummyPool");
|
||||
ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS);
|
||||
CHECKMEM("after pools");
|
||||
POP_MEMID();
|
||||
}
|
||||
|
||||
void
|
||||
CPools::ShutDown(void)
|
||||
{
|
||||
debug("PtrNodes left %d\n", ms_pPtrNodePool->GetNoOfUsedSpaces());
|
||||
debug("EntryInfoNodes left %d\n", ms_pEntryInfoNodePool->GetNoOfUsedSpaces());
|
||||
debug("Peds left %d\n", ms_pPedPool->GetNoOfUsedSpaces());
|
||||
debug("Vehicles left %d\n", ms_pVehiclePool->GetNoOfUsedSpaces());
|
||||
debug("Buildings left %d\n", ms_pBuildingPool->GetNoOfUsedSpaces());
|
||||
debug("Treadables left %d\n", ms_pTreadablePool->GetNoOfUsedSpaces());
|
||||
debug("Objects left %d\n", ms_pObjectPool->GetNoOfUsedSpaces());
|
||||
debug("Dummys left %d\n", ms_pDummyPool->GetNoOfUsedSpaces());
|
||||
debug("AudioScriptObjects left %d\n", ms_pAudioScriptObjectPool->GetNoOfUsedSpaces());
|
||||
printf("Shutdown pool started\n");
|
||||
|
||||
delete ms_pPtrNodePool;
|
||||
delete ms_pEntryInfoNodePool;
|
||||
delete ms_pPedPool;
|
||||
delete ms_pVehiclePool;
|
||||
delete ms_pBuildingPool;
|
||||
delete ms_pTreadablePool;
|
||||
delete ms_pObjectPool;
|
||||
delete ms_pDummyPool;
|
||||
delete ms_pAudioScriptObjectPool;
|
||||
|
||||
printf("Shutdown pool done\n");
|
||||
}
|
||||
|
||||
int32 CPools::GetPedRef(CPed *ped) { return ms_pPedPool->GetIndex(ped); }
|
||||
CPed *CPools::GetPed(int32 handle) { return ms_pPedPool->GetAt(handle); }
|
||||
int32 CPools::GetVehicleRef(CVehicle *vehicle) { return ms_pVehiclePool->GetIndex(vehicle); }
|
||||
CVehicle *CPools::GetVehicle(int32 handle) { return ms_pVehiclePool->GetAt(handle); }
|
||||
int32 CPools::GetObjectRef(CObject *object) { return ms_pObjectPool->GetIndex(object); }
|
||||
CObject *CPools::GetObject(int32 handle) { return ms_pObjectPool->GetAt(handle); }
|
||||
|
||||
void
|
||||
CPools::CheckPoolsEmpty()
|
||||
{
|
||||
assert(ms_pPedPool->GetNoOfUsedSpaces() == 0);
|
||||
assert(ms_pVehiclePool->GetNoOfUsedSpaces() == 0);
|
||||
printf("pools have been cleared\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
|
||||
{
|
||||
if (ms_pObjectPool->GetIsFree(slot)) return;
|
||||
|
||||
CObject *object = ms_pObjectPool->GetSlot(slot);
|
||||
if (object->ObjectCreatedBy == TEMP_OBJECT) {
|
||||
CWorld::Remove(object);
|
||||
delete object;
|
||||
} else if (!CProjectileInfo::RemoveIfThisIsAProjectile(object)) {
|
||||
// relocate to another slot??
|
||||
CObject *newObject = new CObject(object->GetModelIndex(), false);
|
||||
CWorld::Remove(object);
|
||||
#if 0 // todo better
|
||||
*newObject = *object;
|
||||
#else
|
||||
memcpy(newObject, object, ms_pObjectPool->GetMaxEntrySize());
|
||||
#endif
|
||||
CWorld::Add(newObject);
|
||||
object->m_rwObject = nil;
|
||||
delete object;
|
||||
newObject->m_pFirstReference = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
|
||||
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
|
||||
|
||||
void CPools::LoadVehiclePool(uint8* buf, uint32 size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
int nNumCars, nNumBoats;
|
||||
ReadSaveBuf(&nNumCars, buf);
|
||||
ReadSaveBuf(&nNumBoats, buf);
|
||||
for (int i = 0; i < nNumCars + nNumBoats; i++) {
|
||||
uint32 type;
|
||||
int16 model;
|
||||
int32 slot;
|
||||
|
||||
ReadSaveBuf(&type, buf);
|
||||
ReadSaveBuf(&model, buf);
|
||||
CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
ReadSaveBuf(&slot, buf);
|
||||
CVehicle* pVehicle;
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
if (type == VEHICLE_TYPE_BOAT)
|
||||
pVehicle = new(slot) CBoat(model, RANDOM_VEHICLE);
|
||||
else if (type == VEHICLE_TYPE_CAR)
|
||||
pVehicle = new(slot) CAutomobile(model, RANDOM_VEHICLE);
|
||||
else
|
||||
assert(0);
|
||||
--CCarCtrl::NumRandomCars;
|
||||
pVehicle->Load(buf);
|
||||
CWorld::Add(pVehicle);
|
||||
#else
|
||||
char* vbuf = new char[Max(CAutomobile::nSaveStructSize, CBoat::nSaveStructSize)];
|
||||
if (type == VEHICLE_TYPE_BOAT) {
|
||||
memcpy(vbuf, buf, sizeof(CBoat));
|
||||
SkipSaveBuf(buf, sizeof(CBoat));
|
||||
CBoat* pBoat = new(slot) CBoat(model, RANDOM_VEHICLE);
|
||||
pVehicle = pBoat;
|
||||
--CCarCtrl::NumRandomCars;
|
||||
}
|
||||
else if (type == VEHICLE_TYPE_CAR) {
|
||||
memcpy(vbuf, buf, sizeof(CAutomobile));
|
||||
SkipSaveBuf(buf, sizeof(CAutomobile));
|
||||
CStreaming::RequestModel(model, 0); // is it needed?
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
CAutomobile* pAutomobile = new(slot) CAutomobile(model, RANDOM_VEHICLE);
|
||||
pVehicle = pAutomobile;
|
||||
CCarCtrl::NumRandomCars--; // why?
|
||||
pAutomobile->Damage = ((CAutomobile*)vbuf)->Damage;
|
||||
pAutomobile->SetupDamageAfterLoad();
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
CVehicle* pBufferVehicle = (CVehicle*)vbuf;
|
||||
pVehicle->GetMatrix() = pBufferVehicle->GetMatrix();
|
||||
pVehicle->VehicleCreatedBy = pBufferVehicle->VehicleCreatedBy;
|
||||
pVehicle->m_currentColour1 = pBufferVehicle->m_currentColour1;
|
||||
pVehicle->m_currentColour2 = pBufferVehicle->m_currentColour2;
|
||||
pVehicle->m_nAlarmState = pBufferVehicle->m_nAlarmState;
|
||||
pVehicle->m_nNumMaxPassengers = pBufferVehicle->m_nNumMaxPassengers;
|
||||
pVehicle->field_1D0[0] = pBufferVehicle->field_1D0[0];
|
||||
pVehicle->field_1D0[1] = pBufferVehicle->field_1D0[1];
|
||||
pVehicle->field_1D0[2] = pBufferVehicle->field_1D0[2];
|
||||
pVehicle->field_1D0[3] = pBufferVehicle->field_1D0[3];
|
||||
pVehicle->m_fSteerAngle = pBufferVehicle->m_fSteerAngle;
|
||||
pVehicle->m_fGasPedal = pBufferVehicle->m_fGasPedal;
|
||||
pVehicle->m_fBrakePedal = pBufferVehicle->m_fBrakePedal;
|
||||
pVehicle->bIsLawEnforcer = pBufferVehicle->bIsLawEnforcer;
|
||||
pVehicle->bIsLocked = pBufferVehicle->bIsLocked;
|
||||
pVehicle->bEngineOn = pBufferVehicle->bEngineOn;
|
||||
pVehicle->bIsHandbrakeOn = pBufferVehicle->bIsHandbrakeOn;
|
||||
pVehicle->bLightsOn = pBufferVehicle->bLightsOn;
|
||||
pVehicle->bFreebies = pBufferVehicle->bFreebies;
|
||||
pVehicle->m_fHealth = pBufferVehicle->m_fHealth;
|
||||
pVehicle->m_nCurrentGear = pBufferVehicle->m_nCurrentGear;
|
||||
pVehicle->m_fChangeGearTime = pBufferVehicle->m_fChangeGearTime;
|
||||
pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath;
|
||||
#ifdef FIX_BUGS //must be copypaste
|
||||
pVehicle->m_nBombTimer = pBufferVehicle->m_nBombTimer;
|
||||
#else
|
||||
pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath;
|
||||
#endif
|
||||
pVehicle->m_nDoorLock = pBufferVehicle->m_nDoorLock;
|
||||
pVehicle->SetStatus(pBufferVehicle->GetStatus());
|
||||
pVehicle->SetType(pBufferVehicle->GetType());
|
||||
(pVehicle->GetAddressOfEntityProperties())[0] = (pBufferVehicle->GetAddressOfEntityProperties())[0];
|
||||
(pVehicle->GetAddressOfEntityProperties())[1] = (pBufferVehicle->GetAddressOfEntityProperties())[1];
|
||||
pVehicle->AutoPilot = pBufferVehicle->AutoPilot;
|
||||
CWorld::Add(pVehicle);
|
||||
delete[] vbuf;
|
||||
#endif
|
||||
}
|
||||
VALIDATESAVEBUF(size)
|
||||
}
|
||||
|
||||
void CPools::SaveVehiclePool(uint8* buf, uint32* size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
int nNumCars = 0;
|
||||
int nNumBoats = 0;
|
||||
int nPoolSize = GetVehiclePool()->GetSize();
|
||||
for (int i = 0; i < nPoolSize; i++) {
|
||||
CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
|
||||
if (!pVehicle)
|
||||
continue;
|
||||
bool bHasPassenger = false;
|
||||
for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) {
|
||||
if (pVehicle->pPassengers[j])
|
||||
bHasPassenger = true;
|
||||
}
|
||||
#ifdef MISSION_REPLAY
|
||||
bool bForceSaving = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle == pVehicle && IsQuickSave;
|
||||
#ifdef FIX_BUGS
|
||||
if ((!pVehicle->pDriver && !bHasPassenger) || bForceSaving) {
|
||||
#else
|
||||
if (!pVehicle->pDriver && !bHasPassenger) {
|
||||
#endif
|
||||
if (pVehicle->IsCar() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
|
||||
++nNumCars;
|
||||
if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
|
||||
++nNumBoats;
|
||||
#else
|
||||
if (!pVehicle->pDriver && !bHasPassenger) {
|
||||
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
|
||||
++nNumCars;
|
||||
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
|
||||
++nNumBoats;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
*size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) +
|
||||
nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CBoat::nSaveStructSize) + sizeof(int);
|
||||
WriteSaveBuf(buf, nNumCars);
|
||||
WriteSaveBuf(buf, nNumBoats);
|
||||
for (int i = 0; i < nPoolSize; i++) {
|
||||
CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
|
||||
if (!pVehicle)
|
||||
continue;
|
||||
bool bHasPassenger = false;
|
||||
for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) {
|
||||
if (pVehicle->pPassengers[j])
|
||||
bHasPassenger = true;
|
||||
}
|
||||
#ifdef MISSION_REPLAY
|
||||
bool bForceSaving = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle == pVehicle && IsQuickSave;
|
||||
#endif
|
||||
#if defined FIX_BUGS && defined MISSION_REPLAY
|
||||
if ((!pVehicle->pDriver && !bHasPassenger) || bForceSaving) {
|
||||
#else
|
||||
if (!pVehicle->pDriver && !bHasPassenger) {
|
||||
#endif
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
#ifdef MISSION_REPLAY
|
||||
if ((pVehicle->IsCar() || pVehicle->IsBoat()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
|
||||
#else
|
||||
if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
|
||||
#endif
|
||||
WriteSaveBuf(buf, pVehicle->m_vehType);
|
||||
WriteSaveBuf(buf, pVehicle->GetModelIndex());
|
||||
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
|
||||
pVehicle->Save(buf);
|
||||
}
|
||||
#else
|
||||
#ifdef MISSION_REPLAY
|
||||
if (pVehicle->IsCar() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
|
||||
#else
|
||||
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
|
||||
#endif
|
||||
WriteSaveBuf(buf, pVehicle->m_vehType);
|
||||
WriteSaveBuf(buf, pVehicle->GetModelIndex());
|
||||
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
|
||||
memcpy(buf, pVehicle, sizeof(CAutomobile));
|
||||
SkipSaveBuf(buf, sizeof(CAutomobile));
|
||||
}
|
||||
#ifdef MISSION_REPLAY
|
||||
if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
|
||||
#else
|
||||
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
|
||||
#endif
|
||||
WriteSaveBuf(buf, pVehicle->m_vehType);
|
||||
WriteSaveBuf(buf, pVehicle->GetModelIndex());
|
||||
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
|
||||
memcpy(buf, pVehicle, sizeof(CBoat));
|
||||
SkipSaveBuf(buf, sizeof(CBoat));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
VALIDATESAVEBUF(*size)
|
||||
}
|
||||
|
||||
void CPools::SaveObjectPool(uint8* buf, uint32* size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
CProjectileInfo::RemoveAllProjectiles();
|
||||
CObject::DeleteAllTempObjects();
|
||||
int nObjects = 0;
|
||||
int nPoolSize = GetObjectPool()->GetSize();
|
||||
for (int i = 0; i < nPoolSize; i++) {
|
||||
CObject* pObject = GetObjectPool()->GetSlot(i);
|
||||
if (!pObject)
|
||||
continue;
|
||||
if (pObject->ObjectCreatedBy == MISSION_OBJECT)
|
||||
++nObjects;
|
||||
}
|
||||
*size = nObjects * (sizeof(int16) + sizeof(int) + sizeof(CCompressedMatrix) +
|
||||
sizeof(float) + sizeof(CCompressedMatrix) + sizeof(int8) + 7 * sizeof(bool) + sizeof(float) +
|
||||
sizeof(int8) + sizeof(int8) + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int);
|
||||
CopyToBuf(buf, nObjects);
|
||||
for (int i = 0; i < nPoolSize; i++) {
|
||||
CObject* pObject = GetObjectPool()->GetSlot(i);
|
||||
if (!pObject)
|
||||
continue;
|
||||
if (pObject->ObjectCreatedBy == MISSION_OBJECT) {
|
||||
bool bIsPickup = pObject->bIsPickup;
|
||||
bool bPickupObjWithMessage = pObject->bPickupObjWithMessage;
|
||||
bool bOutOfStock = pObject->bOutOfStock;
|
||||
bool bGlassCracked = pObject->bGlassCracked;
|
||||
bool bGlassBroken = pObject->bGlassBroken;
|
||||
bool bHasBeenDamaged = pObject->bHasBeenDamaged;
|
||||
bool bUseVehicleColours = pObject->bUseVehicleColours;
|
||||
CCompressedMatrix tmp;
|
||||
CopyToBuf(buf, pObject->m_modelIndex);
|
||||
int32 ref = GetObjectRef(pObject);
|
||||
CopyToBuf(buf, ref);
|
||||
tmp.CompressFromFullMatrix(pObject->GetMatrix());
|
||||
CopyToBuf(buf, tmp);
|
||||
CopyToBuf(buf, pObject->m_fUprootLimit);
|
||||
tmp.CompressFromFullMatrix(pObject->m_objectMatrix);
|
||||
CopyToBuf(buf, tmp);
|
||||
CopyToBuf(buf, pObject->ObjectCreatedBy);
|
||||
CopyToBuf(buf, bIsPickup);
|
||||
CopyToBuf(buf, bPickupObjWithMessage);
|
||||
CopyToBuf(buf, bOutOfStock);
|
||||
CopyToBuf(buf, bGlassCracked);
|
||||
CopyToBuf(buf, bGlassBroken);
|
||||
CopyToBuf(buf, bHasBeenDamaged);
|
||||
CopyToBuf(buf, bUseVehicleColours);
|
||||
CopyToBuf(buf, pObject->m_fCollisionDamageMultiplier);
|
||||
CopyToBuf(buf, pObject->m_nCollisionDamageEffect);
|
||||
CopyToBuf(buf, pObject->m_nSpecialCollisionResponseCases);
|
||||
CopyToBuf(buf, pObject->m_nEndOfLifeTime);
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
pObject->SaveEntityFlags(buf);
|
||||
#else
|
||||
CopyToBuf(buf, (pObject->GetAddressOfEntityProperties())[0]);
|
||||
CopyToBuf(buf, (pObject->GetAddressOfEntityProperties())[1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
VALIDATESAVEBUF(*size)
|
||||
}
|
||||
|
||||
void CPools::LoadObjectPool(uint8* buf, uint32 size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
int nObjects;
|
||||
CopyFromBuf(buf, nObjects);
|
||||
for (int i = 0; i < nObjects; i++) {
|
||||
int16 mi;
|
||||
CopyFromBuf(buf, mi);
|
||||
int ref;
|
||||
CopyFromBuf(buf, ref);
|
||||
char* obuf = new char[sizeof(CObject)];
|
||||
CObject* pBufferObject = (CObject*)obuf;
|
||||
CCompressedMatrix tmp;
|
||||
CopyFromBuf(buf, tmp);
|
||||
tmp.DecompressIntoFullMatrix(pBufferObject->GetMatrix());
|
||||
CopyFromBuf(buf, pBufferObject->m_fUprootLimit);
|
||||
CopyFromBuf(buf, tmp);
|
||||
tmp.DecompressIntoFullMatrix(pBufferObject->m_objectMatrix);
|
||||
CopyFromBuf(buf, pBufferObject->ObjectCreatedBy);
|
||||
int8 bitFlag;
|
||||
CopyFromBuf(buf, bitFlag);
|
||||
pBufferObject->bIsPickup = bitFlag;
|
||||
CopyFromBuf(buf, bitFlag);
|
||||
pBufferObject->bPickupObjWithMessage = bitFlag;
|
||||
CopyFromBuf(buf, bitFlag);
|
||||
pBufferObject->bOutOfStock = bitFlag;
|
||||
CopyFromBuf(buf, bitFlag);
|
||||
pBufferObject->bGlassCracked = bitFlag;
|
||||
CopyFromBuf(buf, bitFlag);
|
||||
pBufferObject->bGlassBroken = bitFlag;
|
||||
CopyFromBuf(buf, bitFlag);
|
||||
pBufferObject->bHasBeenDamaged = bitFlag;
|
||||
CopyFromBuf(buf, bitFlag);
|
||||
pBufferObject->bUseVehicleColours = bitFlag;
|
||||
CopyFromBuf(buf, pBufferObject->m_fCollisionDamageMultiplier);
|
||||
CopyFromBuf(buf, pBufferObject->m_nCollisionDamageEffect);
|
||||
CopyFromBuf(buf, pBufferObject->m_nSpecialCollisionResponseCases);
|
||||
CopyFromBuf(buf, pBufferObject->m_nEndOfLifeTime);
|
||||
#ifndef COMPATIBLE_SAVES
|
||||
CopyFromBuf(buf, (pBufferObject->GetAddressOfEntityProperties())[0]);
|
||||
CopyFromBuf(buf, (pBufferObject->GetAddressOfEntityProperties())[1]);
|
||||
#endif
|
||||
if (GetObjectPool()->GetSlot(ref >> 8))
|
||||
CPopulation::ConvertToDummyObject(GetObjectPool()->GetSlot(ref >> 8));
|
||||
CObject* pObject = new(ref) CObject(mi, false);
|
||||
pObject->GetMatrix() = pBufferObject->GetMatrix();
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
pObject->LoadEntityFlags(buf);
|
||||
#endif
|
||||
pObject->m_fUprootLimit = pBufferObject->m_fUprootLimit;
|
||||
pObject->m_objectMatrix = pBufferObject->m_objectMatrix;
|
||||
pObject->ObjectCreatedBy = pBufferObject->ObjectCreatedBy;
|
||||
pObject->bIsPickup = pBufferObject->bIsPickup;
|
||||
pObject->bPickupObjWithMessage = pBufferObject->bPickupObjWithMessage;
|
||||
pObject->bOutOfStock = pBufferObject->bOutOfStock;
|
||||
pObject->bGlassCracked = pBufferObject->bGlassCracked;
|
||||
pObject->bGlassBroken = pBufferObject->bGlassBroken;
|
||||
pObject->bHasBeenDamaged = pBufferObject->bHasBeenDamaged;
|
||||
pObject->bUseVehicleColours = pBufferObject->bUseVehicleColours;
|
||||
pObject->m_fCollisionDamageMultiplier = pBufferObject->m_fCollisionDamageMultiplier;
|
||||
pObject->m_nCollisionDamageEffect = pBufferObject->m_nCollisionDamageEffect;
|
||||
pObject->m_nSpecialCollisionResponseCases = pBufferObject->m_nSpecialCollisionResponseCases;
|
||||
pObject->m_nEndOfLifeTime = pBufferObject->m_nEndOfLifeTime;
|
||||
#ifndef COMPATIBLE_SAVES
|
||||
(pObject->GetAddressOfEntityProperties())[0] = (pBufferObject->GetAddressOfEntityProperties())[0];
|
||||
(pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1];
|
||||
#endif
|
||||
pObject->bHasCollided = false;
|
||||
CWorld::Add(pObject);
|
||||
delete[] obuf;
|
||||
}
|
||||
VALIDATESAVEBUF(size)
|
||||
}
|
||||
|
||||
void CPools::SavePedPool(uint8* buf, uint32* size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
int nNumPeds = 0;
|
||||
int nPoolSize = GetPedPool()->GetSize();
|
||||
for (int i = 0; i < nPoolSize; i++) {
|
||||
CPed* pPed = GetPedPool()->GetSlot(i);
|
||||
if (!pPed)
|
||||
continue;
|
||||
#ifdef MISSION_REPLAY
|
||||
if ((!pPed->bInVehicle || (pPed == CWorld::Players[CWorld::PlayerInFocus].m_pPed && IsQuickSave)) && pPed->m_nPedType == PEDTYPE_PLAYER1)
|
||||
#else
|
||||
if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1)
|
||||
#endif
|
||||
nNumPeds++;
|
||||
}
|
||||
*size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + CPlayerPed::nSaveStructSize +
|
||||
sizeof(CWanted::MaximumWantedLevel) + sizeof(CWanted::nMaximumWantedLevel) + MAX_MODEL_NAME);
|
||||
CopyToBuf(buf, nNumPeds);
|
||||
for (int i = 0; i < nPoolSize; i++) {
|
||||
CPed* pPed = GetPedPool()->GetSlot(i);
|
||||
if (!pPed)
|
||||
continue;
|
||||
#ifdef MISSION_REPLAY
|
||||
if ((!pPed->bInVehicle || (pPed == CWorld::Players[CWorld::PlayerInFocus].m_pPed && IsQuickSave)) && pPed->m_nPedType == PEDTYPE_PLAYER1) {
|
||||
#else
|
||||
if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) {
|
||||
#endif
|
||||
CopyToBuf(buf, pPed->m_nPedType);
|
||||
CopyToBuf(buf, pPed->m_modelIndex);
|
||||
int32 ref = GetPedRef(pPed);
|
||||
CopyToBuf(buf, ref);
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
pPed->Save(buf);
|
||||
#else
|
||||
memcpy(buf, pPed, sizeof(CPlayerPed));
|
||||
SkipSaveBuf(buf, sizeof(CPlayerPed));
|
||||
#endif
|
||||
CopyToBuf(buf, CWanted::MaximumWantedLevel);
|
||||
CopyToBuf(buf, CWanted::nMaximumWantedLevel);
|
||||
memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetModelName(), MAX_MODEL_NAME);
|
||||
SkipSaveBuf(buf, MAX_MODEL_NAME);
|
||||
}
|
||||
}
|
||||
VALIDATESAVEBUF(*size);
|
||||
#undef CopyToBuf
|
||||
}
|
||||
|
||||
void CPools::LoadPedPool(uint8* buf, uint32 size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
int nPeds;
|
||||
CopyFromBuf(buf, nPeds);
|
||||
for (int i = 0; i < nPeds; i++) {
|
||||
uint32 pedtype;
|
||||
int16 model;
|
||||
int ref;
|
||||
|
||||
CopyFromBuf(buf, pedtype);
|
||||
CopyFromBuf(buf, model);
|
||||
CopyFromBuf(buf, ref);
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
CPed* pPed;
|
||||
|
||||
char name[MAX_MODEL_NAME];
|
||||
// Unfortunate hack: player model is stored after ped structure.
|
||||
// It could be avoided by just using "player" because in practice it is always true.
|
||||
memcpy(name, buf + CPlayerPed::nSaveStructSize + 2 * sizeof(int32), MAX_MODEL_NAME);
|
||||
CStreaming::RequestSpecialModel(model, name, STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
|
||||
if (pedtype == PEDTYPE_PLAYER1)
|
||||
pPed = new(ref) CPlayerPed();
|
||||
else
|
||||
assert(0);
|
||||
|
||||
pPed->Load(buf);
|
||||
if (pedtype == PEDTYPE_PLAYER1) {
|
||||
CopyFromBuf(buf, CWanted::MaximumWantedLevel);
|
||||
CopyFromBuf(buf, CWanted::nMaximumWantedLevel);
|
||||
SkipSaveBuf(buf, MAX_MODEL_NAME);
|
||||
}
|
||||
|
||||
if (pedtype == PEDTYPE_PLAYER1) {
|
||||
pPed->m_wepAccuracy = 100;
|
||||
CWorld::Players[0].m_pPed = (CPlayerPed*)pPed;
|
||||
}
|
||||
CWorld::Add(pPed);
|
||||
#else
|
||||
char* pbuf = new char[sizeof(CPlayerPed)];
|
||||
CPlayerPed* pBufferPlayer = (CPlayerPed*)pbuf;
|
||||
CPed* pPed;
|
||||
char name[MAX_MODEL_NAME];
|
||||
// the code implies that there was idea to load non-player ped
|
||||
if (pedtype == PEDTYPE_PLAYER1) { // always true
|
||||
memcpy(pbuf, buf, sizeof(CPlayerPed));
|
||||
SkipSaveBuf(buf, sizeof(CPlayerPed));
|
||||
CopyFromBuf(buf, CWanted::MaximumWantedLevel);
|
||||
CopyFromBuf(buf, CWanted::nMaximumWantedLevel);
|
||||
CopyFromBuf(buf, name);
|
||||
}
|
||||
CStreaming::RequestSpecialModel(model, name, STREAMFLAGS_DONT_REMOVE);
|
||||
CStreaming::LoadAllRequestedModels(false);
|
||||
if (pedtype == PEDTYPE_PLAYER1) {
|
||||
CPlayerPed* pPlayerPed = new(ref) CPlayerPed();
|
||||
for (int i = 0; i < ARRAY_SIZE(pPlayerPed->m_nTargettableObjects); i++)
|
||||
pPlayerPed->m_nTargettableObjects[i] = pBufferPlayer->m_nTargettableObjects[i];
|
||||
pPlayerPed->m_fMaxStamina = pBufferPlayer->m_fMaxStamina;
|
||||
pPed = pPlayerPed;
|
||||
}
|
||||
pPed->SetPosition(pBufferPlayer->GetPosition());
|
||||
pPed->m_fHealth = pBufferPlayer->m_fHealth;
|
||||
pPed->m_fArmour = pBufferPlayer->m_fArmour;
|
||||
pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy;
|
||||
pPed->m_currentWeapon = 0;
|
||||
pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed;
|
||||
for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++)
|
||||
pPed->m_weapons[i] = pBufferPlayer->m_weapons[i];
|
||||
|
||||
if (pedtype == PEDTYPE_PLAYER1) {
|
||||
pPed->m_wepAccuracy = 100;
|
||||
CWorld::Players[0].m_pPed = (CPlayerPed*)pPed;
|
||||
}
|
||||
CWorld::Add(pPed);
|
||||
delete[] pbuf;
|
||||
#endif
|
||||
}
|
||||
VALIDATESAVEBUF(size)
|
||||
}
|
||||
|
||||
#undef CopyFromBuf
|
||||
#undef CopyToBuf
|
||||
61
src/core/Pools.h
Normal file
61
src/core/Pools.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
|
||||
#include "templates.h"
|
||||
#include "Lists.h"
|
||||
#include "Treadable.h"
|
||||
#include "Object.h"
|
||||
#include "CutsceneHead.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Automobile.h"
|
||||
#include "DummyPed.h"
|
||||
#include "AudioScriptObject.h"
|
||||
|
||||
typedef CPool<CPtrNode> CCPtrNodePool;
|
||||
typedef CPool<CEntryInfoNode> CEntryInfoNodePool;
|
||||
typedef CPool<CPed,CPlayerPed> CPedPool;
|
||||
typedef CPool<CVehicle,CAutomobile> CVehiclePool;
|
||||
typedef CPool<CBuilding> CBuildingPool;
|
||||
typedef CPool<CTreadable> CTreadablePool;
|
||||
typedef CPool<CObject, CCutsceneHead> CObjectPool;
|
||||
typedef CPool<CDummy, CDummyPed> CDummyPool;
|
||||
typedef CPool<cAudioScriptObject> CAudioScriptObjectPool;
|
||||
|
||||
class CPools
|
||||
{
|
||||
static CCPtrNodePool *ms_pPtrNodePool;
|
||||
static CEntryInfoNodePool *ms_pEntryInfoNodePool;
|
||||
static CPedPool *ms_pPedPool;
|
||||
static CVehiclePool *ms_pVehiclePool;
|
||||
static CBuildingPool *ms_pBuildingPool;
|
||||
static CTreadablePool *ms_pTreadablePool;
|
||||
static CObjectPool *ms_pObjectPool;
|
||||
static CDummyPool *ms_pDummyPool;
|
||||
static CAudioScriptObjectPool *ms_pAudioScriptObjectPool;
|
||||
public:
|
||||
static CCPtrNodePool *GetPtrNodePool(void) { return ms_pPtrNodePool; }
|
||||
static CEntryInfoNodePool *GetEntryInfoNodePool(void) { return ms_pEntryInfoNodePool; }
|
||||
static CPedPool *GetPedPool(void) { return ms_pPedPool; }
|
||||
static CVehiclePool *GetVehiclePool(void) { return ms_pVehiclePool; }
|
||||
static CBuildingPool *GetBuildingPool(void) { return ms_pBuildingPool; }
|
||||
static CTreadablePool *GetTreadablePool(void) { return ms_pTreadablePool; }
|
||||
static CObjectPool *GetObjectPool(void) { return ms_pObjectPool; }
|
||||
static CDummyPool *GetDummyPool(void) { return ms_pDummyPool; }
|
||||
static CAudioScriptObjectPool *GetAudioScriptObjectPool(void) { return ms_pAudioScriptObjectPool; }
|
||||
|
||||
static void Initialise(void);
|
||||
static void ShutDown(void);
|
||||
static int32 GetPedRef(CPed *ped);
|
||||
static CPed *GetPed(int32 handle);
|
||||
static int32 GetVehicleRef(CVehicle *vehicle);
|
||||
static CVehicle *GetVehicle(int32 handle);
|
||||
static int32 GetObjectRef(CObject *object);
|
||||
static CObject *GetObject(int32 handle);
|
||||
static void CheckPoolsEmpty();
|
||||
static void MakeSureSlotInObjectPoolIsEmpty(int32 slot);
|
||||
static void LoadObjectPool(uint8 *buf, uint32 size);
|
||||
static void LoadPedPool(uint8 *buf, uint32 size);
|
||||
static void LoadVehiclePool(uint8 *buf, uint32 size);
|
||||
static void SaveObjectPool(uint8 *buf, uint32 *size);
|
||||
static void SavePedPool(uint8 *buf, uint32 *size);
|
||||
static void SaveVehiclePool(uint8 *buf, uint32 *size);
|
||||
};
|
||||
71
src/core/Profile.cpp
Normal file
71
src/core/Profile.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#include "common.h"
|
||||
#include "Profile.h"
|
||||
|
||||
#ifndef MASTER
|
||||
float CProfile::ms_afStartTime[NUM_PROFILES];
|
||||
float CProfile::ms_afCumulativeTime[NUM_PROFILES];
|
||||
float CProfile::ms_afEndTime[NUM_PROFILES];
|
||||
float CProfile::ms_afMaxEndTime[NUM_PROFILES];
|
||||
float CProfile::ms_afMaxCumulativeTime[NUM_PROFILES];
|
||||
Const char *CProfile::ms_pProfileString[NUM_PROFILES];
|
||||
RwRGBA CProfile::ms_aBarColours[NUM_PROFILES];
|
||||
|
||||
void CProfile::Initialise()
|
||||
{
|
||||
ms_afMaxEndTime[PROFILE_FRAME_RATE] = 0.0f;
|
||||
ms_afMaxEndTime[PROFILE_PHYSICS] = 0.0f;
|
||||
ms_afMaxEndTime[PROFILE_COLLISION] = 0.0f;
|
||||
ms_afMaxEndTime[PROFILE_PED_AI] = 0.0f;
|
||||
ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = 0.0f;
|
||||
ms_afMaxEndTime[PROFILE_RENDERING_TIME] = 0.0f;
|
||||
ms_afMaxEndTime[PROFILE_TOTAL] = 0.0f;
|
||||
|
||||
ms_pProfileString[PROFILE_FRAME_RATE] = "Frame rate";
|
||||
ms_pProfileString[PROFILE_PHYSICS] = "Physics";
|
||||
ms_pProfileString[PROFILE_COLLISION] = "Collision";
|
||||
ms_pProfileString[PROFILE_PED_AI] = "Ped AI";
|
||||
ms_pProfileString[PROFILE_PROCESSING_TIME] = "Processing time";
|
||||
ms_pProfileString[PROFILE_RENDERING_TIME] = "Rendering time";
|
||||
ms_pProfileString[PROFILE_TOTAL] = "Total";
|
||||
|
||||
ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = 0.0f;
|
||||
ms_afMaxCumulativeTime[PROFILE_PHYSICS] = 0.0f;
|
||||
ms_afMaxCumulativeTime[PROFILE_COLLISION] = 0.0f;
|
||||
ms_afMaxCumulativeTime[PROFILE_PED_AI] = 0.0f;
|
||||
ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = 0.0f;
|
||||
ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = 0.0f;
|
||||
ms_afMaxCumulativeTime[PROFILE_TOTAL] = 0.0f;
|
||||
|
||||
ms_aBarColours[PROFILE_PHYSICS] = { 0, 127, 255, 255 };
|
||||
ms_aBarColours[PROFILE_COLLISION] = { 0, 255, 255, 255 };
|
||||
ms_aBarColours[PROFILE_PED_AI] = { 255, 0, 0, 255 };
|
||||
ms_aBarColours[PROFILE_PROCESSING_TIME] = { 0, 255, 0, 255 };
|
||||
ms_aBarColours[PROFILE_RENDERING_TIME] = { 0, 0, 255, 255 };
|
||||
ms_aBarColours[PROFILE_TOTAL] = { 255, 255, 255, 255 };
|
||||
}
|
||||
|
||||
void CProfile::SuspendProfile(eProfile profile)
|
||||
{
|
||||
ms_afEndTime[profile] = -ms_afStartTime[profile];
|
||||
ms_afCumulativeTime[profile] -= ms_afStartTime[profile];
|
||||
}
|
||||
|
||||
void CProfile::ShowResults()
|
||||
{
|
||||
ms_afMaxEndTime[PROFILE_FRAME_RATE] = Max(ms_afMaxEndTime[PROFILE_FRAME_RATE], ms_afEndTime[PROFILE_FRAME_RATE]);
|
||||
ms_afMaxEndTime[PROFILE_PHYSICS] = Max(ms_afMaxEndTime[PROFILE_PHYSICS], ms_afEndTime[PROFILE_PHYSICS]);
|
||||
ms_afMaxEndTime[PROFILE_COLLISION] = Max(ms_afMaxEndTime[PROFILE_COLLISION], ms_afEndTime[PROFILE_COLLISION]);
|
||||
ms_afMaxEndTime[PROFILE_PED_AI] = Max(ms_afMaxEndTime[PROFILE_PED_AI], ms_afEndTime[PROFILE_PED_AI]);
|
||||
ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = Max(ms_afMaxEndTime[PROFILE_PROCESSING_TIME], ms_afEndTime[PROFILE_PROCESSING_TIME]);
|
||||
ms_afMaxEndTime[PROFILE_RENDERING_TIME] = Max(ms_afMaxEndTime[PROFILE_RENDERING_TIME], ms_afEndTime[PROFILE_RENDERING_TIME]);
|
||||
ms_afMaxEndTime[PROFILE_TOTAL] = Max(ms_afMaxEndTime[PROFILE_TOTAL], ms_afEndTime[PROFILE_TOTAL]);
|
||||
|
||||
ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = Max(ms_afMaxCumulativeTime[PROFILE_FRAME_RATE], ms_afCumulativeTime[PROFILE_FRAME_RATE]);
|
||||
ms_afMaxCumulativeTime[PROFILE_PHYSICS] = Max(ms_afMaxCumulativeTime[PROFILE_PHYSICS], ms_afCumulativeTime[PROFILE_PHYSICS]);
|
||||
ms_afMaxCumulativeTime[PROFILE_COLLISION] = Max(ms_afMaxCumulativeTime[PROFILE_COLLISION], ms_afCumulativeTime[PROFILE_COLLISION]);
|
||||
ms_afMaxCumulativeTime[PROFILE_PED_AI] = Max(ms_afMaxCumulativeTime[PROFILE_PED_AI], ms_afCumulativeTime[PROFILE_PED_AI]);
|
||||
ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = Max(ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME], ms_afCumulativeTime[PROFILE_PROCESSING_TIME]);
|
||||
ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = Max(ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME], ms_afCumulativeTime[PROFILE_RENDERING_TIME]);
|
||||
ms_afMaxCumulativeTime[PROFILE_TOTAL] = Max(ms_afMaxCumulativeTime[PROFILE_TOTAL], ms_afCumulativeTime[PROFILE_TOTAL]);
|
||||
}
|
||||
#endif
|
||||
28
src/core/Profile.h
Normal file
28
src/core/Profile.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
enum eProfile
|
||||
{
|
||||
PROFILE_FRAME_RATE,
|
||||
PROFILE_PHYSICS,
|
||||
PROFILE_COLLISION,
|
||||
PROFILE_PED_AI,
|
||||
PROFILE_PROCESSING_TIME,
|
||||
PROFILE_RENDERING_TIME,
|
||||
PROFILE_TOTAL,
|
||||
NUM_PROFILES,
|
||||
};
|
||||
|
||||
class CProfile
|
||||
{
|
||||
static float ms_afStartTime[NUM_PROFILES];
|
||||
static float ms_afCumulativeTime[NUM_PROFILES];
|
||||
static float ms_afEndTime[NUM_PROFILES];
|
||||
static float ms_afMaxEndTime[NUM_PROFILES];
|
||||
static float ms_afMaxCumulativeTime[NUM_PROFILES];
|
||||
static Const char *ms_pProfileString[NUM_PROFILES];
|
||||
static RwRGBA ms_aBarColours[NUM_PROFILES];
|
||||
public:
|
||||
static void Initialise();
|
||||
static void SuspendProfile(eProfile profile);
|
||||
static void ShowResults();
|
||||
};
|
||||
1568
src/core/Radar.cpp
Normal file
1568
src/core/Radar.cpp
Normal file
File diff suppressed because it is too large
Load diff
201
src/core/Radar.h
Normal file
201
src/core/Radar.h
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
#pragma once
|
||||
#include "Sprite2d.h"
|
||||
#include "Draw.h"
|
||||
|
||||
enum eBlipType
|
||||
{
|
||||
BLIP_NONE,
|
||||
BLIP_CAR,
|
||||
BLIP_CHAR,
|
||||
BLIP_OBJECT,
|
||||
BLIP_COORD,
|
||||
BLIP_CONTACT_POINT
|
||||
};
|
||||
|
||||
enum eBlipDisplay
|
||||
{
|
||||
BLIP_DISPLAY_NEITHER = 0,
|
||||
BLIP_DISPLAY_MARKER_ONLY = 1,
|
||||
BLIP_DISPLAY_BLIP_ONLY = 2,
|
||||
BLIP_DISPLAY_BOTH = 3,
|
||||
};
|
||||
|
||||
enum eRadarSprite
|
||||
{
|
||||
#ifdef MENU_MAP
|
||||
RADAR_SPRITE_ENTITY_BLIP = -2,
|
||||
RADAR_SPRITE_COORD_BLIP = -1,
|
||||
#endif
|
||||
RADAR_SPRITE_NONE = 0,
|
||||
RADAR_SPRITE_ASUKA,
|
||||
RADAR_SPRITE_BOMB,
|
||||
RADAR_SPRITE_CAT,
|
||||
RADAR_SPRITE_CENTRE,
|
||||
RADAR_SPRITE_COPCAR,
|
||||
RADAR_SPRITE_DON,
|
||||
RADAR_SPRITE_EIGHT,
|
||||
RADAR_SPRITE_EL,
|
||||
RADAR_SPRITE_ICE,
|
||||
RADAR_SPRITE_JOEY,
|
||||
RADAR_SPRITE_KENJI,
|
||||
RADAR_SPRITE_LIZ,
|
||||
RADAR_SPRITE_LUIGI,
|
||||
RADAR_SPRITE_NORTH,
|
||||
RADAR_SPRITE_RAY,
|
||||
RADAR_SPRITE_SAL,
|
||||
RADAR_SPRITE_SAVE,
|
||||
RADAR_SPRITE_SPRAY,
|
||||
RADAR_SPRITE_TONY,
|
||||
RADAR_SPRITE_WEAPON,
|
||||
#ifdef MENU_MAP
|
||||
RADAR_SPRITE_WAYPOINT,
|
||||
#endif
|
||||
RADAR_SPRITE_COUNT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RADAR_TRACE_RED,
|
||||
RADAR_TRACE_GREEN,
|
||||
RADAR_TRACE_LIGHT_BLUE,
|
||||
RADAR_TRACE_GRAY,
|
||||
RADAR_TRACE_YELLOW,
|
||||
RADAR_TRACE_MAGENTA,
|
||||
RADAR_TRACE_CYAN
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BLIP_MODE_TRIANGULAR_UP = 0,
|
||||
BLIP_MODE_TRIANGULAR_DOWN,
|
||||
BLIP_MODE_SQUARE,
|
||||
};
|
||||
|
||||
struct sRadarTrace
|
||||
{
|
||||
uint32 m_nColor;
|
||||
uint32 m_eBlipType; // eBlipType
|
||||
int32 m_nEntityHandle;
|
||||
CVector2D m_vec2DPos;
|
||||
CVector m_vecPos;
|
||||
uint16 m_BlipIndex;
|
||||
bool m_bDim;
|
||||
bool m_bInUse;
|
||||
float m_Radius;
|
||||
int16 m_wScale;
|
||||
uint16 m_eBlipDisplay; // eBlipDisplay
|
||||
uint16 m_eRadarSprite; // eRadarSprite
|
||||
};
|
||||
VALIDATE_SIZE(sRadarTrace, 0x30);
|
||||
|
||||
// Values for screen space
|
||||
#define RADAR_LEFT (40.0f)
|
||||
#ifdef PS2_HUD
|
||||
#define RADAR_BOTTOM (44.0f)
|
||||
#else
|
||||
#define RADAR_BOTTOM (47.0f)
|
||||
#endif
|
||||
|
||||
#ifdef FIX_RADAR
|
||||
/*
|
||||
The values are from an early screenshot taken before R* broke radar
|
||||
#define RADAR_WIDTH (82.0f)
|
||||
#define RADAR_HEIGHT (82.0f)
|
||||
*/
|
||||
#define RADAR_WIDTH ((CDraw::ms_bFixRadar) ? (82.0f) : (94.0f))
|
||||
#define RADAR_HEIGHT ((CDraw::ms_bFixRadar) ? (82.0f) : (76.0f))
|
||||
#else
|
||||
/*
|
||||
broken since forever, someone tried to fix size for 640x512(PAL)
|
||||
http://aap.rockstarvision.com/pics/gta3/ps2screens/gta3_interface.jpg
|
||||
but failed:
|
||||
http://aap.rockstarvision.com/pics/gta3/artwork/gta3_artwork_16.jpg
|
||||
most likely the guy used something like this:
|
||||
int y = 82 * (640.0/512.0)/(640.0/480.0);
|
||||
int x = y * (640.0/512.0);
|
||||
*/
|
||||
#define RADAR_WIDTH (94.0f)
|
||||
#define RADAR_HEIGHT (76.0f)
|
||||
#endif
|
||||
|
||||
class CRadar
|
||||
{
|
||||
public:
|
||||
static float m_radarRange;
|
||||
static sRadarTrace ms_RadarTrace[NUMRADARBLIPS];
|
||||
static CSprite2d AsukaSprite;
|
||||
static CSprite2d BombSprite;
|
||||
static CSprite2d CatSprite;
|
||||
static CSprite2d CentreSprite;
|
||||
static CSprite2d CopcarSprite;
|
||||
static CSprite2d DonSprite;
|
||||
static CSprite2d EightSprite;
|
||||
static CSprite2d ElSprite;
|
||||
static CSprite2d IceSprite;
|
||||
static CSprite2d JoeySprite;
|
||||
static CSprite2d KenjiSprite;
|
||||
static CSprite2d LizSprite;
|
||||
static CSprite2d LuigiSprite;
|
||||
static CSprite2d NorthSprite;
|
||||
static CSprite2d RaySprite;
|
||||
static CSprite2d SalSprite;
|
||||
static CSprite2d SaveSprite;
|
||||
static CSprite2d SpraySprite;
|
||||
static CSprite2d TonySprite;
|
||||
static CSprite2d WeaponSprite;
|
||||
static CSprite2d *RadarSprites[RADAR_SPRITE_COUNT];
|
||||
static float cachedCos;
|
||||
static float cachedSin;
|
||||
#ifdef MENU_MAP
|
||||
static CSprite2d WaypointSprite;
|
||||
static int TargetMarkerId;
|
||||
static CVector TargetMarkerPos;
|
||||
|
||||
static void InitFrontEndMap();
|
||||
static void DrawYouAreHereSprite(float, float);
|
||||
static void ToggleTargetMarker(float, float);
|
||||
#endif
|
||||
static uint8 CalculateBlipAlpha(float dist);
|
||||
static void ChangeBlipBrightness(int32 i, int32 bright);
|
||||
static void ChangeBlipColour(int32 i, int32);
|
||||
static void ChangeBlipDisplay(int32 i, eBlipDisplay display);
|
||||
static void ChangeBlipScale(int32 i, int32 scale);
|
||||
static void ClearBlip(int32 i);
|
||||
static void ClearBlipForEntity(eBlipType type, int32 id);
|
||||
static int ClipRadarPoly(CVector2D *out, const CVector2D *in);
|
||||
static bool DisplayThisBlip(int32 i);
|
||||
static void Draw3dMarkers();
|
||||
static void DrawBlips();
|
||||
static void DrawMap();
|
||||
static void DrawRadarMap();
|
||||
static void DrawRadarMask();
|
||||
static void DrawRadarSection(int32 x, int32 y);
|
||||
static void DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha);
|
||||
static void DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha);
|
||||
static int32 GetActualBlipArrayIndex(int32 i);
|
||||
static int32 GetNewUniqueBlipIndex(int32 i);
|
||||
static uint32 GetRadarTraceColour(uint32 color, bool bright);
|
||||
static void Initialise();
|
||||
static float LimitRadarPoint(CVector2D &point);
|
||||
static void LoadAllRadarBlips(uint8 *buf, uint32 size);
|
||||
static void LoadTextures();
|
||||
static void RemoveRadarSections();
|
||||
static void SaveAllRadarBlips(uint8*, uint32*);
|
||||
static void SetBlipSprite(int32 i, int32 icon);
|
||||
static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
|
||||
static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay);
|
||||
static void SetRadarMarkerState(int32 i, bool flag);
|
||||
static void ShowRadarMarker(CVector pos, uint32 color, float radius);
|
||||
static void ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha);
|
||||
static void ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha, uint8 mode);
|
||||
static void Shutdown();
|
||||
static void StreamRadarSections(const CVector &posn);
|
||||
static void StreamRadarSections(int32 x, int32 y);
|
||||
static void TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y);
|
||||
static void TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in);
|
||||
static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in);
|
||||
static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
|
||||
|
||||
// no in CRadar in the game:
|
||||
static void CalculateCachedSinCos();
|
||||
};
|
||||
28
src/core/Range2D.cpp
Normal file
28
src/core/Range2D.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include "common.h"
|
||||
#include "Range2D.h"
|
||||
#include "General.h"
|
||||
|
||||
CRange2D::CRange2D(CVector2D _min, CVector2D _max) : min(_min), max(_max) {}
|
||||
|
||||
bool
|
||||
CRange2D::IsInRange(CVector2D vec)
|
||||
{
|
||||
return min.x < vec.x && max.x > vec.x && min.y < vec.y && max.y > vec.y;
|
||||
}
|
||||
|
||||
void
|
||||
CRange2D::DebugShowRange(float, int)
|
||||
{
|
||||
}
|
||||
|
||||
CVector2D
|
||||
CRange2D::GetRandomPointInRange()
|
||||
{
|
||||
int distX = Abs(max.x - min.x);
|
||||
int distY = Abs(max.y - min.y);
|
||||
|
||||
float outX = CGeneral::GetRandomNumber() % distX + min.x;
|
||||
float outY = CGeneral::GetRandomNumber() % distY + min.y;
|
||||
|
||||
return CVector2D(outX, outY);
|
||||
}
|
||||
11
src/core/Range2D.h
Normal file
11
src/core/Range2D.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
class CRange2D
|
||||
{
|
||||
CVector2D min, max;
|
||||
public:
|
||||
CRange2D(CVector2D _min, CVector2D _max);
|
||||
bool IsInRange(CVector2D vec);
|
||||
void DebugShowRange(float, int);
|
||||
CVector2D GetRandomPointInRange();
|
||||
};
|
||||
30
src/core/Range3D.cpp
Normal file
30
src/core/Range3D.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "common.h"
|
||||
#include "Range3D.h"
|
||||
#include "General.h"
|
||||
|
||||
CRange3D::CRange3D(CVector _min, CVector _max) : min(_min), max(_max) {}
|
||||
|
||||
bool
|
||||
CRange3D::IsInRange(CVector vec)
|
||||
{
|
||||
return min.x < vec.x && max.x > vec.x && min.y < vec.y && max.y > vec.y && min.z < vec.z && max.z > vec.z;
|
||||
}
|
||||
|
||||
void
|
||||
CRange3D::DebugShowRange(float, int)
|
||||
{
|
||||
}
|
||||
|
||||
CVector
|
||||
CRange3D::GetRandomPointInRange()
|
||||
{
|
||||
int distX = Abs(max.x - min.x);
|
||||
int distY = Abs(max.y - min.y);
|
||||
int distZ = Abs(max.z - min.z);
|
||||
|
||||
float outX = CGeneral::GetRandomNumber() % distX + min.x;
|
||||
float outY = CGeneral::GetRandomNumber() % distY + min.y;
|
||||
float outZ = CGeneral::GetRandomNumber() % distZ + min.z;
|
||||
|
||||
return CVector(outX, outY, outZ);
|
||||
}
|
||||
11
src/core/Range3D.h
Normal file
11
src/core/Range3D.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
class CRange3D
|
||||
{
|
||||
CVector min, max;
|
||||
public:
|
||||
CRange3D(CVector _min, CVector _max);
|
||||
bool IsInRange(CVector vec);
|
||||
void DebugShowRange(float, int);
|
||||
CVector GetRandomPointInRange();
|
||||
};
|
||||
126
src/core/References.cpp
Normal file
126
src/core/References.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "World.h"
|
||||
#include "Vehicle.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Pools.h"
|
||||
#include "References.h"
|
||||
|
||||
CReference CReferences::aRefs[NUMREFERENCES];
|
||||
CReference *CReferences::pEmptyList;
|
||||
|
||||
void
|
||||
CReferences::Init(void)
|
||||
{
|
||||
int i;
|
||||
pEmptyList = &aRefs[0];
|
||||
for(i = 0; i < NUMREFERENCES; i++){
|
||||
aRefs[i].pentity = nil;
|
||||
aRefs[i].next = &aRefs[i+1];
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all references to this entity
|
||||
void
|
||||
CEntity::ResolveReferences(void)
|
||||
{
|
||||
CReference *ref;
|
||||
// clear pointers to this entity
|
||||
for(ref = m_pFirstReference; ref; ref = ref->next)
|
||||
if(*ref->pentity == this)
|
||||
*ref->pentity = nil;
|
||||
// free list
|
||||
if(m_pFirstReference){
|
||||
for(ref = m_pFirstReference; ref->next; ref = ref->next)
|
||||
;
|
||||
ref->next = CReferences::pEmptyList;
|
||||
CReferences::pEmptyList = m_pFirstReference;
|
||||
m_pFirstReference = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// Free all references that no longer point to this entity
|
||||
void
|
||||
CEntity::PruneReferences(void)
|
||||
{
|
||||
CReference *ref, *next, **lastnextp;
|
||||
lastnextp = &m_pFirstReference;
|
||||
for(ref = m_pFirstReference; ref; ref = next){
|
||||
next = ref->next;
|
||||
if(*ref->pentity == this)
|
||||
lastnextp = &ref->next;
|
||||
else{
|
||||
*lastnextp = ref->next;
|
||||
ref->next = CReferences::pEmptyList;
|
||||
CReferences::pEmptyList = ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CReferences::RemoveReferencesToPlayer(void)
|
||||
{
|
||||
if(FindPlayerVehicle())
|
||||
FindPlayerVehicle()->ResolveReferences();
|
||||
#ifdef FIX_BUGS
|
||||
if (FindPlayerPed()) {
|
||||
CPlayerPed* pPlayerPed = FindPlayerPed();
|
||||
FindPlayerPed()->ResolveReferences();
|
||||
CWorld::Players[CWorld::PlayerInFocus].m_pPed = pPlayerPed;
|
||||
pPlayerPed->RegisterReference((CEntity**)&CWorld::Players[CWorld::PlayerInFocus].m_pPed);
|
||||
}
|
||||
#else
|
||||
if(FindPlayerPed())
|
||||
FindPlayerPed()->ResolveReferences();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CReferences::PruneAllReferencesInWorld(void)
|
||||
{
|
||||
int i;
|
||||
CEntity *e;
|
||||
|
||||
i = CPools::GetPedPool()->GetSize();
|
||||
while(--i >= 0){
|
||||
e = CPools::GetPedPool()->GetSlot(i);
|
||||
if(e)
|
||||
e->PruneReferences();
|
||||
}
|
||||
|
||||
i = CPools::GetVehiclePool()->GetSize();
|
||||
while(--i >= 0){
|
||||
e = CPools::GetVehiclePool()->GetSlot(i);
|
||||
if(e)
|
||||
e->PruneReferences();
|
||||
}
|
||||
|
||||
i = CPools::GetObjectPool()->GetSize();
|
||||
while(--i >= 0){
|
||||
e = CPools::GetObjectPool()->GetSlot(i);
|
||||
if(e)
|
||||
e->PruneReferences();
|
||||
}
|
||||
}
|
||||
20
src/core/References.h
Normal file
20
src/core/References.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
class CEntity;
|
||||
|
||||
struct CReference
|
||||
{
|
||||
CReference *next;
|
||||
CEntity **pentity;
|
||||
};
|
||||
|
||||
class CReferences
|
||||
{
|
||||
public:
|
||||
static CReference aRefs[NUMREFERENCES];
|
||||
static CReference *pEmptyList;
|
||||
|
||||
static void Init(void);
|
||||
static void RemoveReferencesToPlayer(void);
|
||||
static void PruneAllReferencesInWorld(void);
|
||||
};
|
||||
420
src/core/Stats.cpp
Normal file
420
src/core/Stats.cpp
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Stats.h"
|
||||
#include "Text.h"
|
||||
#include "World.h"
|
||||
|
||||
int32 CStats::DaysPassed;
|
||||
int32 CStats::HeadsPopped;
|
||||
int32 CStats::CommercialPassed;
|
||||
int32 CStats::IndustrialPassed;
|
||||
int32 CStats::SuburbanPassed;
|
||||
int32 CStats::NumberKillFrenziesPassed;
|
||||
int32 CStats::PeopleKilledByOthers;
|
||||
int32 CStats::HelisDestroyed;
|
||||
int32 CStats::PedsKilledOfThisType[NUM_PEDTYPES];
|
||||
int32 CStats::TimesDied;
|
||||
int32 CStats::TimesArrested;
|
||||
int32 CStats::KillsSinceLastCheckpoint;
|
||||
float CStats::DistanceTravelledInVehicle;
|
||||
float CStats::DistanceTravelledOnFoot;
|
||||
int32 CStats::ProgressMade;
|
||||
int32 CStats::TotalProgressInGame;
|
||||
int32 CStats::CarsExploded;
|
||||
int32 CStats::PeopleKilledByPlayer;
|
||||
float CStats::MaximumJumpDistance;
|
||||
float CStats::MaximumJumpHeight;
|
||||
int32 CStats::MaximumJumpFlips;
|
||||
int32 CStats::MaximumJumpSpins;
|
||||
int32 CStats::BestStuntJump;
|
||||
int32 CStats::NumberOfUniqueJumpsFound;
|
||||
int32 CStats::TotalNumberOfUniqueJumps;
|
||||
int32 CStats::PassengersDroppedOffWithTaxi;
|
||||
int32 CStats::MoneyMadeWithTaxi;
|
||||
int32 CStats::MissionsGiven;
|
||||
int32 CStats::MissionsPassed;
|
||||
char CStats::LastMissionPassedName[8];
|
||||
int32 CStats::TotalLegitimateKills;
|
||||
int32 CStats::ElBurroTime;
|
||||
int32 CStats::Record4x4One;
|
||||
int32 CStats::Record4x4Two;
|
||||
int32 CStats::Record4x4Three;
|
||||
int32 CStats::Record4x4Mayhem;
|
||||
int32 CStats::LivesSavedWithAmbulance;
|
||||
int32 CStats::CriminalsCaught;
|
||||
int32 CStats::HighestLevelAmbulanceMission;
|
||||
int32 CStats::FiresExtinguished;
|
||||
int32 CStats::LongestFlightInDodo;
|
||||
int32 CStats::TimeTakenDefuseMission;
|
||||
int32 CStats::TotalNumberKillFrenzies;
|
||||
int32 CStats::TotalNumberMissions;
|
||||
int32 CStats::RoundsFiredByPlayer;
|
||||
int32 CStats::KgsOfExplosivesUsed;
|
||||
int32 CStats::InstantHitsFiredByPlayer;
|
||||
int32 CStats::InstantHitsHitByPlayer;
|
||||
int32 CStats::BestTimeBombDefusal;
|
||||
int32 CStats::mmRain;
|
||||
int32 CStats::CarsCrushed;
|
||||
int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES];
|
||||
int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
|
||||
|
||||
void CStats::Init()
|
||||
{
|
||||
PeopleKilledByOthers = 0;
|
||||
PeopleKilledByPlayer = 0;
|
||||
RoundsFiredByPlayer = 0;
|
||||
CarsExploded = 0;
|
||||
HelisDestroyed = 0;
|
||||
ProgressMade = 0;
|
||||
KgsOfExplosivesUsed = 0;
|
||||
InstantHitsFiredByPlayer = 0;
|
||||
InstantHitsHitByPlayer = 0;
|
||||
CarsCrushed = 0;
|
||||
HeadsPopped = 0;
|
||||
TimesArrested = 0;
|
||||
TimesDied = 0;
|
||||
DaysPassed = 0;
|
||||
NumberOfUniqueJumpsFound = 0;
|
||||
mmRain = 0;
|
||||
MaximumJumpFlips = 0;
|
||||
MaximumJumpSpins = 0;
|
||||
MaximumJumpDistance = 0;
|
||||
MaximumJumpHeight = 0;
|
||||
BestStuntJump = 0;
|
||||
TotalNumberOfUniqueJumps = 0;
|
||||
Record4x4One = 0;
|
||||
LongestFlightInDodo = 0;
|
||||
Record4x4Two = 0;
|
||||
PassengersDroppedOffWithTaxi = 0;
|
||||
Record4x4Three = 0;
|
||||
MoneyMadeWithTaxi = 0;
|
||||
Record4x4Mayhem = 0;
|
||||
LivesSavedWithAmbulance = 0;
|
||||
ElBurroTime = 0;
|
||||
CriminalsCaught = 0;
|
||||
MissionsGiven = 0;
|
||||
HighestLevelAmbulanceMission = 0;
|
||||
MissionsPassed = 0;
|
||||
FiresExtinguished = 0;
|
||||
DistanceTravelledOnFoot = 0;
|
||||
TimeTakenDefuseMission = 0;
|
||||
NumberKillFrenziesPassed = 0;
|
||||
DistanceTravelledInVehicle = 0;
|
||||
TotalNumberKillFrenzies = 0;
|
||||
TotalNumberMissions = 0;
|
||||
KillsSinceLastCheckpoint = 0;
|
||||
TotalLegitimateKills = 0;
|
||||
for (int i = 0; i < TOTAL_FASTEST_TIMES; i++)
|
||||
FastestTimes[i] = 0;
|
||||
for (int i = 0; i < TOTAL_HIGHEST_SCORES; i++)
|
||||
HighestScores[i] = 0;
|
||||
for (int i = 0; i < NUM_PEDTYPES; i++)
|
||||
PedsKilledOfThisType[i] = 0;
|
||||
IndustrialPassed = 0;
|
||||
CommercialPassed = 0;
|
||||
SuburbanPassed = 0;
|
||||
}
|
||||
|
||||
void CStats::RegisterFastestTime(int32 index, int32 time)
|
||||
{
|
||||
assert(index >= 0 && index < TOTAL_FASTEST_TIMES);
|
||||
if (FastestTimes[index] == 0)
|
||||
FastestTimes[index] = time;
|
||||
else
|
||||
FastestTimes[index] = Min(FastestTimes[index], time);
|
||||
}
|
||||
|
||||
void CStats::RegisterHighestScore(int32 index, int32 score)
|
||||
{
|
||||
assert(index >= 0 && index < TOTAL_HIGHEST_SCORES);
|
||||
HighestScores[index] = Max(HighestScores[index], score);
|
||||
}
|
||||
|
||||
void CStats::RegisterElBurroTime(int32 time)
|
||||
{
|
||||
ElBurroTime = (ElBurroTime && ElBurroTime < time) ? ElBurroTime : time;
|
||||
}
|
||||
|
||||
void CStats::Register4x4OneTime(int32 time)
|
||||
{
|
||||
Record4x4One = (Record4x4One && Record4x4One < time) ? Record4x4One : time;
|
||||
}
|
||||
|
||||
void CStats::Register4x4TwoTime(int32 time)
|
||||
{
|
||||
Record4x4Two = (Record4x4Two && Record4x4Two < time) ? Record4x4Two : time;
|
||||
}
|
||||
|
||||
void CStats::Register4x4ThreeTime(int32 time)
|
||||
{
|
||||
Record4x4Three = (Record4x4Three && Record4x4Three < time) ? Record4x4Three : time;
|
||||
}
|
||||
|
||||
void CStats::Register4x4MayhemTime(int32 time)
|
||||
{
|
||||
Record4x4Mayhem = (Record4x4Mayhem && Record4x4Mayhem < time) ? Record4x4Mayhem : time;
|
||||
}
|
||||
|
||||
void CStats::AnotherLifeSavedWithAmbulance()
|
||||
{
|
||||
++LivesSavedWithAmbulance;
|
||||
}
|
||||
|
||||
void CStats::AnotherCriminalCaught()
|
||||
{
|
||||
++CriminalsCaught;
|
||||
}
|
||||
|
||||
void CStats::RegisterLevelAmbulanceMission(int32 level)
|
||||
{
|
||||
HighestLevelAmbulanceMission = Max(HighestLevelAmbulanceMission, level);
|
||||
}
|
||||
|
||||
void CStats::AnotherFireExtinguished()
|
||||
{
|
||||
++FiresExtinguished;
|
||||
}
|
||||
|
||||
void CStats::RegisterLongestFlightInDodo(int32 time)
|
||||
{
|
||||
LongestFlightInDodo = Max(LongestFlightInDodo, time);
|
||||
}
|
||||
|
||||
void CStats::RegisterTimeTakenDefuseMission(int32 time)
|
||||
{
|
||||
TimeTakenDefuseMission = (TimeTakenDefuseMission && TimeTakenDefuseMission < time) ? TimeTakenDefuseMission : time;
|
||||
}
|
||||
|
||||
void CStats::AnotherKillFrenzyPassed()
|
||||
{
|
||||
++NumberKillFrenziesPassed;
|
||||
}
|
||||
|
||||
void CStats::SetTotalNumberKillFrenzies(int32 total)
|
||||
{
|
||||
TotalNumberKillFrenzies = total;
|
||||
}
|
||||
|
||||
void CStats::SetTotalNumberMissions(int32 total)
|
||||
{
|
||||
TotalNumberMissions = total;
|
||||
}
|
||||
|
||||
wchar *CStats::FindCriminalRatingString()
|
||||
{
|
||||
int rating = FindCriminalRatingNumber();
|
||||
|
||||
if (rating < 10) return TheText.Get("RATNG1");
|
||||
if (rating < 25) return TheText.Get("RATNG2");
|
||||
if (rating < 70) return TheText.Get("RATNG3");
|
||||
if (rating < 150) return TheText.Get("RATNG4");
|
||||
if (rating < 250) return TheText.Get("RATNG5");
|
||||
if (rating < 450) return TheText.Get("RATNG6");
|
||||
if (rating < 700) return TheText.Get("RATNG7");
|
||||
if (rating < 1000) return TheText.Get("RATNG8");
|
||||
if (rating < 1400) return TheText.Get("RATNG9");
|
||||
if (rating < 1900) return TheText.Get("RATNG10");
|
||||
if (rating < 2500) return TheText.Get("RATNG11");
|
||||
if (rating < 3200) return TheText.Get("RATNG12");
|
||||
if (rating < 4000) return TheText.Get("RATNG13");
|
||||
if (rating < 5000) return TheText.Get("RATNG14");
|
||||
return TheText.Get("RATNG15");
|
||||
}
|
||||
|
||||
int32 CStats::FindCriminalRatingNumber()
|
||||
{
|
||||
int32 rating;
|
||||
|
||||
rating = FiresExtinguished + 10 * HighestLevelAmbulanceMission + CriminalsCaught + LivesSavedWithAmbulance
|
||||
+ 30 * HelisDestroyed + TotalLegitimateKills - 3 * TimesArrested - 3 * TimesDied
|
||||
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney / 5000;
|
||||
if (rating <= 0) rating = 0;
|
||||
|
||||
if (InstantHitsFiredByPlayer > 100)
|
||||
rating += (float)CStats::InstantHitsHitByPlayer / (float)CStats::InstantHitsFiredByPlayer * 500.0f;
|
||||
if (TotalProgressInGame)
|
||||
rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
|
||||
if (!IndustrialPassed && rating >= 3521)
|
||||
rating = 3521;
|
||||
if (!CommercialPassed && rating >= 4552)
|
||||
rating = 4552;
|
||||
return rating;
|
||||
}
|
||||
|
||||
void CStats::SaveStats(uint8 *buf, uint32 *size)
|
||||
{
|
||||
CheckPointReachedSuccessfully();
|
||||
uint8 *buf_start = buf;
|
||||
*size = sizeof(PeopleKilledByPlayer) +
|
||||
sizeof(PeopleKilledByOthers) +
|
||||
sizeof(CarsExploded) +
|
||||
sizeof(RoundsFiredByPlayer) +
|
||||
sizeof(PedsKilledOfThisType) +
|
||||
sizeof(HelisDestroyed) +
|
||||
sizeof(ProgressMade) +
|
||||
sizeof(TotalProgressInGame) +
|
||||
sizeof(KgsOfExplosivesUsed) +
|
||||
sizeof(InstantHitsFiredByPlayer) +
|
||||
sizeof(InstantHitsHitByPlayer) +
|
||||
sizeof(CarsCrushed) +
|
||||
sizeof(HeadsPopped) +
|
||||
sizeof(TimesArrested) +
|
||||
sizeof(TimesDied) +
|
||||
sizeof(DaysPassed) +
|
||||
sizeof(mmRain) +
|
||||
sizeof(MaximumJumpDistance) +
|
||||
sizeof(MaximumJumpHeight) +
|
||||
sizeof(MaximumJumpFlips) +
|
||||
sizeof(MaximumJumpSpins) +
|
||||
sizeof(BestStuntJump) +
|
||||
sizeof(NumberOfUniqueJumpsFound) +
|
||||
sizeof(TotalNumberOfUniqueJumps) +
|
||||
sizeof(MissionsGiven) +
|
||||
sizeof(MissionsPassed) +
|
||||
sizeof(PassengersDroppedOffWithTaxi) +
|
||||
sizeof(MoneyMadeWithTaxi) +
|
||||
sizeof(IndustrialPassed) +
|
||||
sizeof(CommercialPassed) +
|
||||
sizeof(SuburbanPassed) +
|
||||
sizeof(ElBurroTime) +
|
||||
sizeof(DistanceTravelledOnFoot) +
|
||||
sizeof(DistanceTravelledInVehicle) +
|
||||
sizeof(Record4x4One) +
|
||||
sizeof(Record4x4Two) +
|
||||
sizeof(Record4x4Three) +
|
||||
sizeof(Record4x4Mayhem) +
|
||||
sizeof(LivesSavedWithAmbulance) +
|
||||
sizeof(CriminalsCaught) +
|
||||
sizeof(HighestLevelAmbulanceMission) +
|
||||
sizeof(FiresExtinguished) +
|
||||
sizeof(LongestFlightInDodo) +
|
||||
sizeof(TimeTakenDefuseMission) +
|
||||
sizeof(NumberKillFrenziesPassed) +
|
||||
sizeof(TotalNumberKillFrenzies) +
|
||||
sizeof(TotalNumberMissions) +
|
||||
sizeof(FastestTimes) +
|
||||
sizeof(HighestScores) +
|
||||
sizeof(KillsSinceLastCheckpoint) +
|
||||
sizeof(TotalLegitimateKills) +
|
||||
sizeof(LastMissionPassedName);
|
||||
|
||||
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
|
||||
CopyToBuf(buf, PeopleKilledByPlayer);
|
||||
CopyToBuf(buf, PeopleKilledByOthers);
|
||||
CopyToBuf(buf, CarsExploded);
|
||||
CopyToBuf(buf, RoundsFiredByPlayer);
|
||||
CopyToBuf(buf, PedsKilledOfThisType);
|
||||
CopyToBuf(buf, HelisDestroyed);
|
||||
CopyToBuf(buf, ProgressMade);
|
||||
CopyToBuf(buf, TotalProgressInGame);
|
||||
CopyToBuf(buf, KgsOfExplosivesUsed);
|
||||
CopyToBuf(buf, InstantHitsFiredByPlayer);
|
||||
CopyToBuf(buf, InstantHitsHitByPlayer);
|
||||
CopyToBuf(buf, CarsCrushed);
|
||||
CopyToBuf(buf, HeadsPopped);
|
||||
CopyToBuf(buf, TimesArrested);
|
||||
CopyToBuf(buf, TimesDied);
|
||||
CopyToBuf(buf, DaysPassed);
|
||||
CopyToBuf(buf, mmRain);
|
||||
CopyToBuf(buf, MaximumJumpDistance);
|
||||
CopyToBuf(buf, MaximumJumpHeight);
|
||||
CopyToBuf(buf, MaximumJumpFlips);
|
||||
CopyToBuf(buf, MaximumJumpSpins);
|
||||
CopyToBuf(buf, BestStuntJump);
|
||||
CopyToBuf(buf, NumberOfUniqueJumpsFound);
|
||||
CopyToBuf(buf, TotalNumberOfUniqueJumps);
|
||||
CopyToBuf(buf, MissionsGiven);
|
||||
CopyToBuf(buf, MissionsPassed);
|
||||
CopyToBuf(buf, PassengersDroppedOffWithTaxi);
|
||||
CopyToBuf(buf, MoneyMadeWithTaxi);
|
||||
CopyToBuf(buf, IndustrialPassed);
|
||||
CopyToBuf(buf, CommercialPassed);
|
||||
CopyToBuf(buf, SuburbanPassed);
|
||||
CopyToBuf(buf, ElBurroTime);
|
||||
CopyToBuf(buf, DistanceTravelledOnFoot);
|
||||
CopyToBuf(buf, DistanceTravelledInVehicle);
|
||||
CopyToBuf(buf, Record4x4One);
|
||||
CopyToBuf(buf, Record4x4Two);
|
||||
CopyToBuf(buf, Record4x4Three);
|
||||
CopyToBuf(buf, Record4x4Mayhem);
|
||||
CopyToBuf(buf, LivesSavedWithAmbulance);
|
||||
CopyToBuf(buf, CriminalsCaught);
|
||||
CopyToBuf(buf, HighestLevelAmbulanceMission);
|
||||
CopyToBuf(buf, FiresExtinguished);
|
||||
CopyToBuf(buf, LongestFlightInDodo);
|
||||
CopyToBuf(buf, TimeTakenDefuseMission);
|
||||
CopyToBuf(buf, NumberKillFrenziesPassed);
|
||||
CopyToBuf(buf, TotalNumberKillFrenzies);
|
||||
CopyToBuf(buf, TotalNumberMissions);
|
||||
CopyToBuf(buf, FastestTimes);
|
||||
CopyToBuf(buf, HighestScores);
|
||||
CopyToBuf(buf, KillsSinceLastCheckpoint);
|
||||
CopyToBuf(buf, TotalLegitimateKills);
|
||||
CopyToBuf(buf, LastMissionPassedName);
|
||||
|
||||
assert(buf - buf_start == *size);
|
||||
#undef CopyToBuf
|
||||
}
|
||||
|
||||
void CStats::LoadStats(uint8 *buf, uint32 size)
|
||||
{
|
||||
uint8* buf_start = buf;
|
||||
|
||||
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
|
||||
|
||||
CopyFromBuf(buf, PeopleKilledByPlayer);
|
||||
CopyFromBuf(buf, PeopleKilledByOthers);
|
||||
CopyFromBuf(buf, CarsExploded);
|
||||
CopyFromBuf(buf, RoundsFiredByPlayer);
|
||||
CopyFromBuf(buf, PedsKilledOfThisType);
|
||||
CopyFromBuf(buf, HelisDestroyed);
|
||||
CopyFromBuf(buf, ProgressMade);
|
||||
CopyFromBuf(buf, TotalProgressInGame);
|
||||
CopyFromBuf(buf, KgsOfExplosivesUsed);
|
||||
CopyFromBuf(buf, InstantHitsFiredByPlayer);
|
||||
CopyFromBuf(buf, InstantHitsHitByPlayer);
|
||||
CopyFromBuf(buf, CarsCrushed);
|
||||
CopyFromBuf(buf, HeadsPopped);
|
||||
CopyFromBuf(buf, TimesArrested);
|
||||
CopyFromBuf(buf, TimesDied);
|
||||
CopyFromBuf(buf, DaysPassed);
|
||||
CopyFromBuf(buf, mmRain);
|
||||
CopyFromBuf(buf, MaximumJumpDistance);
|
||||
CopyFromBuf(buf, MaximumJumpHeight);
|
||||
CopyFromBuf(buf, MaximumJumpFlips);
|
||||
CopyFromBuf(buf, MaximumJumpSpins);
|
||||
CopyFromBuf(buf, BestStuntJump);
|
||||
CopyFromBuf(buf, NumberOfUniqueJumpsFound);
|
||||
CopyFromBuf(buf, TotalNumberOfUniqueJumps);
|
||||
CopyFromBuf(buf, MissionsGiven);
|
||||
CopyFromBuf(buf, MissionsPassed);
|
||||
CopyFromBuf(buf, PassengersDroppedOffWithTaxi);
|
||||
CopyFromBuf(buf, MoneyMadeWithTaxi);
|
||||
CopyFromBuf(buf, IndustrialPassed);
|
||||
CopyFromBuf(buf, CommercialPassed);
|
||||
CopyFromBuf(buf, SuburbanPassed);
|
||||
CopyFromBuf(buf, ElBurroTime);
|
||||
CopyFromBuf(buf, DistanceTravelledOnFoot);
|
||||
CopyFromBuf(buf, DistanceTravelledInVehicle);
|
||||
CopyFromBuf(buf, Record4x4One);
|
||||
CopyFromBuf(buf, Record4x4Two);
|
||||
CopyFromBuf(buf, Record4x4Three);
|
||||
CopyFromBuf(buf, Record4x4Mayhem);
|
||||
CopyFromBuf(buf, LivesSavedWithAmbulance);
|
||||
CopyFromBuf(buf, CriminalsCaught);
|
||||
CopyFromBuf(buf, HighestLevelAmbulanceMission);
|
||||
CopyFromBuf(buf, FiresExtinguished);
|
||||
CopyFromBuf(buf, LongestFlightInDodo);
|
||||
CopyFromBuf(buf, TimeTakenDefuseMission);
|
||||
CopyFromBuf(buf, NumberKillFrenziesPassed);
|
||||
CopyFromBuf(buf, TotalNumberKillFrenzies);
|
||||
CopyFromBuf(buf, TotalNumberMissions);
|
||||
CopyFromBuf(buf, FastestTimes);
|
||||
CopyFromBuf(buf, HighestScores);
|
||||
CopyFromBuf(buf, KillsSinceLastCheckpoint);
|
||||
CopyFromBuf(buf, TotalLegitimateKills);
|
||||
CopyFromBuf(buf, LastMissionPassedName);
|
||||
|
||||
assert(buf - buf_start == size);
|
||||
#undef CopyFromBuf
|
||||
}
|
||||
90
src/core/Stats.h
Normal file
90
src/core/Stats.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
#include "PedType.h"
|
||||
|
||||
class CStats
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
TOTAL_FASTEST_TIMES = 16,
|
||||
TOTAL_HIGHEST_SCORES = 16
|
||||
};
|
||||
static int32 DaysPassed;
|
||||
static int32 HeadsPopped;
|
||||
static int32 CommercialPassed;
|
||||
static int32 IndustrialPassed;
|
||||
static int32 SuburbanPassed;
|
||||
static int32 NumberKillFrenziesPassed;
|
||||
static int32 PeopleKilledByOthers;
|
||||
static int32 HelisDestroyed;
|
||||
static int32 PedsKilledOfThisType[NUM_PEDTYPES];
|
||||
static int32 TimesDied;
|
||||
static int32 TimesArrested;
|
||||
static int32 KillsSinceLastCheckpoint;
|
||||
static float DistanceTravelledInVehicle;
|
||||
static float DistanceTravelledOnFoot;
|
||||
static int32 CarsExploded;
|
||||
static int32 PeopleKilledByPlayer;
|
||||
static int32 ProgressMade;
|
||||
static int32 TotalProgressInGame;
|
||||
static float MaximumJumpDistance;
|
||||
static float MaximumJumpHeight;
|
||||
static int32 MaximumJumpFlips;
|
||||
static int32 MaximumJumpSpins;
|
||||
static int32 BestStuntJump;
|
||||
static int32 NumberOfUniqueJumpsFound;
|
||||
static int32 TotalNumberOfUniqueJumps;
|
||||
static int32 PassengersDroppedOffWithTaxi;
|
||||
static int32 MoneyMadeWithTaxi;
|
||||
static int32 MissionsGiven;
|
||||
static int32 MissionsPassed;
|
||||
static char LastMissionPassedName[8];
|
||||
static int32 TotalLegitimateKills;
|
||||
static int32 ElBurroTime;
|
||||
static int32 Record4x4One;
|
||||
static int32 Record4x4Two;
|
||||
static int32 Record4x4Three;
|
||||
static int32 Record4x4Mayhem;
|
||||
static int32 LivesSavedWithAmbulance;
|
||||
static int32 CriminalsCaught;
|
||||
static int32 HighestLevelAmbulanceMission;
|
||||
static int32 FiresExtinguished;
|
||||
static int32 LongestFlightInDodo;
|
||||
static int32 TimeTakenDefuseMission;
|
||||
static int32 TotalNumberKillFrenzies;
|
||||
static int32 TotalNumberMissions;
|
||||
static int32 RoundsFiredByPlayer;
|
||||
static int32 KgsOfExplosivesUsed;
|
||||
static int32 InstantHitsFiredByPlayer;
|
||||
static int32 InstantHitsHitByPlayer;
|
||||
static int32 BestTimeBombDefusal;
|
||||
static int32 mmRain;
|
||||
static int32 CarsCrushed;
|
||||
static int32 FastestTimes[TOTAL_FASTEST_TIMES];
|
||||
static int32 HighestScores[TOTAL_HIGHEST_SCORES];
|
||||
|
||||
public:
|
||||
static void Init(void);
|
||||
static void RegisterFastestTime(int32, int32);
|
||||
static void RegisterHighestScore(int32, int32);
|
||||
static void RegisterElBurroTime(int32);
|
||||
static void Register4x4OneTime(int32);
|
||||
static void Register4x4TwoTime(int32);
|
||||
static void Register4x4ThreeTime(int32);
|
||||
static void Register4x4MayhemTime(int32);
|
||||
static void AnotherLifeSavedWithAmbulance();
|
||||
static void AnotherCriminalCaught();
|
||||
static void RegisterLevelAmbulanceMission(int32);
|
||||
static void AnotherFireExtinguished();
|
||||
static wchar *FindCriminalRatingString();
|
||||
static void RegisterLongestFlightInDodo(int32);
|
||||
static void RegisterTimeTakenDefuseMission(int32);
|
||||
static void AnotherKillFrenzyPassed();
|
||||
static void SetTotalNumberKillFrenzies(int32);
|
||||
static void SetTotalNumberMissions(int32);
|
||||
static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; };
|
||||
static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
|
||||
static int32 FindCriminalRatingNumber();
|
||||
static void SaveStats(uint8 *buf, uint32 *size);
|
||||
static void LoadStats(uint8 *buf, uint32 size);
|
||||
};
|
||||
2831
src/core/Streaming.cpp
Normal file
2831
src/core/Streaming.cpp
Normal file
File diff suppressed because it is too large
Load diff
197
src/core/Streaming.h
Normal file
197
src/core/Streaming.h
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
#pragma once
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
enum {
|
||||
STREAM_OFFSET_TXD = MODELINFOSIZE,
|
||||
NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE
|
||||
};
|
||||
|
||||
enum StreamFlags
|
||||
{
|
||||
STREAMFLAGS_DONT_REMOVE = 0x01,
|
||||
STREAMFLAGS_SCRIPTOWNED = 0x02,
|
||||
STREAMFLAGS_DEPENDENCY = 0x04, // Is this right?
|
||||
STREAMFLAGS_PRIORITY = 0x08,
|
||||
STREAMFLAGS_NOFADE = 0x10,
|
||||
|
||||
STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED,
|
||||
STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY,
|
||||
};
|
||||
|
||||
enum StreamLoadState
|
||||
{
|
||||
STREAMSTATE_NOTLOADED = 0,
|
||||
STREAMSTATE_LOADED = 1,
|
||||
STREAMSTATE_INQUEUE = 2,
|
||||
STREAMSTATE_READING = 3, // channel is reading
|
||||
STREAMSTATE_STARTED = 4, // first part loaded
|
||||
};
|
||||
|
||||
enum ChannelState
|
||||
{
|
||||
CHANNELSTATE_IDLE = 0,
|
||||
CHANNELSTATE_READING = 1,
|
||||
CHANNELSTATE_STARTED = 2,
|
||||
CHANNELSTATE_ERROR = 3,
|
||||
};
|
||||
|
||||
class CStreamingInfo
|
||||
{
|
||||
public:
|
||||
CStreamingInfo *m_next;
|
||||
CStreamingInfo *m_prev;
|
||||
uint8 m_loadState;
|
||||
uint8 m_flags;
|
||||
|
||||
int16 m_nextID;
|
||||
uint32 m_position;
|
||||
uint32 m_size;
|
||||
|
||||
bool GetCdPosnAndSize(uint32 &posn, uint32 &size);
|
||||
void SetCdPosnAndSize(uint32 posn, uint32 size);
|
||||
void AddToList(CStreamingInfo *link);
|
||||
void RemoveFromList(void);
|
||||
uint32 GetCdSize(void) { return m_size; }
|
||||
bool IsPriority(void) { return !!(m_flags & STREAMFLAGS_PRIORITY); }
|
||||
};
|
||||
|
||||
struct CStreamingChannel
|
||||
{
|
||||
int32 streamIds[4];
|
||||
int32 offsets[4];
|
||||
int32 state;
|
||||
int32 field24;
|
||||
int32 position;
|
||||
int32 size;
|
||||
int32 numTries;
|
||||
int32 status; // from CdStream
|
||||
};
|
||||
|
||||
class CDirectory;
|
||||
class CPtrList;
|
||||
|
||||
class CStreaming
|
||||
{
|
||||
public:
|
||||
static bool ms_disableStreaming;
|
||||
static bool ms_bLoadingBigModel;
|
||||
static int32 ms_numModelsRequested;
|
||||
static CStreamingInfo ms_aInfoForModel[NUMSTREAMINFO];
|
||||
static CStreamingInfo ms_startLoadedList;
|
||||
static CStreamingInfo ms_endLoadedList;
|
||||
static CStreamingInfo ms_startRequestedList;
|
||||
static CStreamingInfo ms_endRequestedList;
|
||||
static int32 ms_oldSectorX;
|
||||
static int32 ms_oldSectorY;
|
||||
static int32 ms_streamingBufferSize;
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
static int8 *ms_pStreamingBuffer[2];
|
||||
#else
|
||||
static int8 *ms_pStreamingBuffer[4];
|
||||
#endif
|
||||
static size_t ms_memoryUsed;
|
||||
static CStreamingChannel ms_channel[2];
|
||||
static int32 ms_channelError;
|
||||
static int32 ms_numVehiclesLoaded;
|
||||
static int32 ms_vehiclesLoaded[MAXVEHICLESLOADED];
|
||||
static int32 ms_lastVehicleDeleted;
|
||||
static CDirectory *ms_pExtraObjectsDir;
|
||||
static int32 ms_numPriorityRequests;
|
||||
static bool ms_hasLoadedLODs;
|
||||
static int32 ms_currentPedGrp;
|
||||
static int32 ms_lastCullZone;
|
||||
static uint16 ms_loadedGangs;
|
||||
static uint16 ms_loadedGangCars;
|
||||
static int32 ms_currentPedLoading;
|
||||
static int32 ms_imageOffsets[NUMCDIMAGES];
|
||||
static int32 ms_lastImageRead;
|
||||
static int32 ms_imageSize;
|
||||
static size_t ms_memoryAvailable;
|
||||
|
||||
static void Init(void);
|
||||
static void Init2(void);
|
||||
static void Shutdown(void);
|
||||
static void Update(void);
|
||||
static void LoadCdDirectory(void);
|
||||
static void LoadCdDirectory(const char *dirname, int32 n);
|
||||
static bool ConvertBufferToObject(int8 *buf, int32 streamId);
|
||||
static bool FinishLoadingLargeFile(int8 *buf, int32 streamId);
|
||||
static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; }
|
||||
static bool HasTxdLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_TXD); }
|
||||
static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; }
|
||||
static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); }
|
||||
static void RequestModel(int32 model, int32 flags);
|
||||
static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); }
|
||||
static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); }
|
||||
static void ReRequestTxd(int32 txd) { ReRequestModel(txd + STREAM_OFFSET_TXD); }
|
||||
static void RequestSubway(void);
|
||||
static void RequestBigBuildings(eLevelName level);
|
||||
static void RequestIslands(eLevelName level);
|
||||
static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags);
|
||||
static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags);
|
||||
static bool HasSpecialCharLoaded(int32 id);
|
||||
static void SetMissionDoesntRequireSpecialChar(int32 id);
|
||||
static void DecrementRef(int32 id);
|
||||
static void RemoveModel(int32 id);
|
||||
static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); }
|
||||
static void RemoveUnusedBuildings(eLevelName level);
|
||||
static void RemoveBuildings(eLevelName level);
|
||||
static void RemoveUnusedBigBuildings(eLevelName level);
|
||||
static void RemoveIslandsNotUsed(eLevelName level);
|
||||
static void RemoveBigBuildings(eLevelName level);
|
||||
static bool RemoveLoadedVehicle(void);
|
||||
static bool RemoveLeastUsedModel(void);
|
||||
static void RemoveAllUnusedModels(void);
|
||||
static void RemoveUnusedModelsInLoadedList(void);
|
||||
static bool RemoveReferencedTxds(size_t mem); // originally signed
|
||||
static int32 GetAvailableVehicleSlot(void);
|
||||
static bool IsTxdUsedByRequestedModels(int32 txdId);
|
||||
static bool AddToLoadedVehiclesList(int32 modelId);
|
||||
static bool IsObjectInCdImage(int32 id);
|
||||
static void HaveAllBigBuildingsLoaded(eLevelName level);
|
||||
static void SetModelIsDeletable(int32 id);
|
||||
static void SetModelTxdIsDeletable(int32 id);
|
||||
static void SetMissionDoesntRequireModel(int32 id);
|
||||
static void LoadInitialPeds(void);
|
||||
static void LoadInitialVehicles(void);
|
||||
static void StreamVehiclesAndPeds(void);
|
||||
static void StreamZoneModels(const CVector &pos);
|
||||
static void RemoveCurrentZonesModels(void);
|
||||
|
||||
static int32 GetCdImageOffset(int32 lastPosn);
|
||||
static int32 GetNextFileOnCd(int32 position, bool priority);
|
||||
static void RequestModelStream(int32 ch);
|
||||
static bool ProcessLoadingChannel(int32 ch);
|
||||
static void RetryLoadFile(int32 ch);
|
||||
static void LoadRequestedModels(void);
|
||||
static void LoadAllRequestedModels(bool priority);
|
||||
static void FlushChannels(void);
|
||||
static void FlushRequestList(void);
|
||||
|
||||
static void MakeSpaceFor(int32 size);
|
||||
static void ImGonnaUseStreamingMemory(void);
|
||||
static void IHaveUsedStreamingMemory(void);
|
||||
static void UpdateMemoryUsed(void);
|
||||
|
||||
static void AddModelsToRequestList(const CVector &pos);
|
||||
static void ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float xmin, float ymin, float xmax, float ymax);
|
||||
static void ProcessEntitiesInSectorList(CPtrList &list);
|
||||
static void DeleteFarAwayRwObjects(const CVector &pos);
|
||||
static void DeleteAllRwObjects(void);
|
||||
static void DeleteRwObjectsAfterDeath(const CVector &pos);
|
||||
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); // originally signed
|
||||
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); // originally signed
|
||||
|
||||
static void LoadScene(const CVector &pos);
|
||||
|
||||
static void MemoryCardSave(uint8 *buffer, uint32 *length);
|
||||
static void MemoryCardLoad(uint8 *buffer, uint32 length);
|
||||
|
||||
static void UpdateForAnimViewer(void);
|
||||
|
||||
static void PrintStreamingBufferState();
|
||||
};
|
||||
143
src/core/SurfaceTable.cpp
Normal file
143
src/core/SurfaceTable.cpp
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "FileMgr.h"
|
||||
#include "Weather.h"
|
||||
#include "Collision.h"
|
||||
#include "SurfaceTable.h"
|
||||
|
||||
float CSurfaceTable::ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
|
||||
|
||||
void
|
||||
CSurfaceTable::Initialise(Const char *filename)
|
||||
{
|
||||
int lineno, fieldno;
|
||||
char *line;
|
||||
char surfname[256];
|
||||
float adhesiveLimit;
|
||||
|
||||
CFileMgr::SetDir("");
|
||||
CFileMgr::LoadFile(filename, work_buff, sizeof(work_buff), "r");
|
||||
|
||||
line = (char*)work_buff;
|
||||
for(lineno = 0; lineno < NUMADHESIVEGROUPS; lineno++){
|
||||
// skip white space and comments
|
||||
while(*line == ' ' || *line == '\t' || *line == '\n' || *line == '\r' || *line == ';'){
|
||||
if(*line == ';'){
|
||||
while(*line != '\n' && *line != '\r')
|
||||
line++;
|
||||
}else
|
||||
line++;
|
||||
}
|
||||
|
||||
sscanf(line, "%s", surfname);
|
||||
// skip what we just read
|
||||
while(!(*line == ' ' || *line == '\t' || *line == ','))
|
||||
line++;
|
||||
|
||||
for(fieldno = 0; fieldno <= lineno; fieldno++){
|
||||
// skip white space
|
||||
while(*line == ' ' || *line == '\t' || *line == ',')
|
||||
line++;
|
||||
adhesiveLimit = 0.0f;
|
||||
if(*line != '-')
|
||||
sscanf(line, "%f", &adhesiveLimit);
|
||||
// skip what we just read
|
||||
while(!(*line == ' ' || *line == '\t' || *line == ',' || *line == '\n'))
|
||||
line++;
|
||||
|
||||
ms_aAdhesiveLimitTable[lineno][fieldno] = adhesiveLimit;
|
||||
ms_aAdhesiveLimitTable[fieldno][lineno] = adhesiveLimit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
CSurfaceTable::GetAdhesionGroup(uint8 surfaceType)
|
||||
{
|
||||
switch(surfaceType){
|
||||
case SURFACE_DEFAULT: return ADHESIVE_ROAD;
|
||||
case SURFACE_TARMAC: return ADHESIVE_ROAD;
|
||||
case SURFACE_GRASS: return ADHESIVE_LOOSE;
|
||||
case SURFACE_GRAVEL: return ADHESIVE_LOOSE;
|
||||
case SURFACE_MUD_DRY: return ADHESIVE_HARD;
|
||||
case SURFACE_PAVEMENT: return ADHESIVE_ROAD;
|
||||
case SURFACE_CAR: return ADHESIVE_HARD;
|
||||
case SURFACE_GLASS: return ADHESIVE_HARD;
|
||||
case SURFACE_TRANSPARENT_CLOTH: return ADHESIVE_HARD;
|
||||
case SURFACE_GARAGE_DOOR: return ADHESIVE_HARD;
|
||||
case SURFACE_CAR_PANEL: return ADHESIVE_HARD;
|
||||
case SURFACE_THICK_METAL_PLATE: return ADHESIVE_HARD;
|
||||
case SURFACE_SCAFFOLD_POLE: return ADHESIVE_HARD;
|
||||
case SURFACE_LAMP_POST: return ADHESIVE_HARD;
|
||||
case SURFACE_FIRE_HYDRANT: return ADHESIVE_HARD;
|
||||
case SURFACE_GIRDER: return ADHESIVE_HARD;
|
||||
case SURFACE_METAL_CHAIN_FENCE: return ADHESIVE_HARD;
|
||||
case SURFACE_PED: return ADHESIVE_RUBBER;
|
||||
case SURFACE_SAND: return ADHESIVE_LOOSE;
|
||||
case SURFACE_WATER: return ADHESIVE_WET;
|
||||
case SURFACE_WOOD_CRATES: return ADHESIVE_ROAD;
|
||||
case SURFACE_WOOD_BENCH: return ADHESIVE_ROAD;
|
||||
case SURFACE_WOOD_SOLID: return ADHESIVE_ROAD;
|
||||
case SURFACE_RUBBER: return ADHESIVE_RUBBER;
|
||||
case SURFACE_PLASTIC: return ADHESIVE_HARD;
|
||||
case SURFACE_HEDGE: return ADHESIVE_LOOSE;
|
||||
case SURFACE_STEEP_CLIFF: return ADHESIVE_LOOSE;
|
||||
case SURFACE_CONTAINER: return ADHESIVE_HARD;
|
||||
case SURFACE_NEWS_VENDOR: return ADHESIVE_HARD;
|
||||
case SURFACE_WHEELBASE: return ADHESIVE_RUBBER;
|
||||
case SURFACE_CARDBOARDBOX: return ADHESIVE_LOOSE;
|
||||
case SURFACE_TRANSPARENT_STONE: return ADHESIVE_HARD;
|
||||
case SURFACE_METAL_GATE: return ADHESIVE_HARD;
|
||||
default: return ADHESIVE_ROAD;
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
CSurfaceTable::GetWetMultiplier(uint8 surfaceType)
|
||||
{
|
||||
switch(surfaceType){
|
||||
case SURFACE_DEFAULT:
|
||||
case SURFACE_TARMAC:
|
||||
case SURFACE_MUD_DRY:
|
||||
case SURFACE_PAVEMENT:
|
||||
case SURFACE_TRANSPARENT_CLOTH:
|
||||
case SURFACE_WOOD_CRATES:
|
||||
case SURFACE_WOOD_BENCH:
|
||||
case SURFACE_WOOD_SOLID:
|
||||
case SURFACE_HEDGE:
|
||||
case SURFACE_CARDBOARDBOX:
|
||||
case SURFACE_TRANSPARENT_STONE:
|
||||
return 1.0f - CWeather::WetRoads*0.25f;
|
||||
|
||||
case SURFACE_GRASS:
|
||||
case SURFACE_CAR:
|
||||
case SURFACE_GLASS:
|
||||
case SURFACE_GARAGE_DOOR:
|
||||
case SURFACE_CAR_PANEL:
|
||||
case SURFACE_THICK_METAL_PLATE:
|
||||
case SURFACE_SCAFFOLD_POLE:
|
||||
case SURFACE_LAMP_POST:
|
||||
case SURFACE_FIRE_HYDRANT:
|
||||
case SURFACE_GIRDER:
|
||||
case SURFACE_METAL_CHAIN_FENCE:
|
||||
case SURFACE_PED:
|
||||
case SURFACE_RUBBER:
|
||||
case SURFACE_PLASTIC:
|
||||
case SURFACE_STEEP_CLIFF:
|
||||
case SURFACE_CONTAINER:
|
||||
case SURFACE_NEWS_VENDOR:
|
||||
case SURFACE_WHEELBASE:
|
||||
case SURFACE_METAL_GATE:
|
||||
return 1.0f - CWeather::WetRoads*0.4f;
|
||||
|
||||
default:
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
CSurfaceTable::GetAdhesiveLimit(CColPoint &colpoint)
|
||||
{
|
||||
return ms_aAdhesiveLimitTable[GetAdhesionGroup(colpoint.surfaceB)][GetAdhesionGroup(colpoint.surfaceA)];
|
||||
}
|
||||
80
src/core/SurfaceTable.h
Normal file
80
src/core/SurfaceTable.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#pragma once
|
||||
|
||||
enum eSurfaceType
|
||||
{
|
||||
SURFACE_DEFAULT,
|
||||
SURFACE_TARMAC,
|
||||
SURFACE_GRASS,
|
||||
SURFACE_GRAVEL,
|
||||
SURFACE_MUD_DRY,
|
||||
SURFACE_PAVEMENT,
|
||||
SURFACE_CAR,
|
||||
SURFACE_GLASS,
|
||||
SURFACE_TRANSPARENT_CLOTH,
|
||||
SURFACE_GARAGE_DOOR,
|
||||
SURFACE_CAR_PANEL,
|
||||
SURFACE_THICK_METAL_PLATE,
|
||||
SURFACE_SCAFFOLD_POLE,
|
||||
SURFACE_LAMP_POST,
|
||||
SURFACE_FIRE_HYDRANT,
|
||||
SURFACE_GIRDER,
|
||||
SURFACE_METAL_CHAIN_FENCE,
|
||||
SURFACE_PED,
|
||||
SURFACE_SAND,
|
||||
SURFACE_WATER,
|
||||
SURFACE_WOOD_CRATES,
|
||||
SURFACE_WOOD_BENCH,
|
||||
SURFACE_WOOD_SOLID,
|
||||
SURFACE_RUBBER,
|
||||
SURFACE_PLASTIC,
|
||||
SURFACE_HEDGE,
|
||||
SURFACE_STEEP_CLIFF,
|
||||
SURFACE_CONTAINER,
|
||||
SURFACE_NEWS_VENDOR,
|
||||
SURFACE_WHEELBASE,
|
||||
SURFACE_CARDBOARDBOX,
|
||||
SURFACE_TRANSPARENT_STONE,
|
||||
SURFACE_METAL_GATE,
|
||||
|
||||
// These are illegal
|
||||
SURFACE_SAND_BEACH,
|
||||
SURFACE_CONCRETE_BEACH,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ADHESIVE_RUBBER,
|
||||
ADHESIVE_HARD,
|
||||
ADHESIVE_ROAD,
|
||||
ADHESIVE_LOOSE,
|
||||
ADHESIVE_WET,
|
||||
|
||||
NUMADHESIVEGROUPS
|
||||
};
|
||||
|
||||
struct CColPoint;
|
||||
|
||||
inline bool
|
||||
IsSeeThrough(uint8 surfType)
|
||||
{
|
||||
switch(surfType)
|
||||
case SURFACE_GLASS:
|
||||
case SURFACE_TRANSPARENT_CLOTH:
|
||||
#if defined(FIX_BUGS) || defined(GTA_PS2)
|
||||
case SURFACE_METAL_CHAIN_FENCE:
|
||||
case SURFACE_TRANSPARENT_STONE:
|
||||
case SURFACE_SCAFFOLD_POLE:
|
||||
#endif
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
class CSurfaceTable
|
||||
{
|
||||
static float ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
|
||||
public:
|
||||
static void Initialise(Const char *filename);
|
||||
static int GetAdhesionGroup(uint8 surfaceType);
|
||||
static float GetWetMultiplier(uint8 surfaceType);
|
||||
static float GetAdhesiveLimit(CColPoint &colpoint);
|
||||
};
|
||||
5
src/core/TimeStep.cpp
Normal file
5
src/core/TimeStep.cpp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "TimeStep.h"
|
||||
|
||||
float CTimeStep::ms_fTimeScale = 1.0f;
|
||||
float CTimeStep::ms_fFramesPerUpdate = 1.0f;
|
||||
float CTimeStep::ms_fTimeStep = 1.0f;
|
||||
10
src/core/TimeStep.h
Normal file
10
src/core/TimeStep.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
// Pretty sure this class is not used by the game
|
||||
class CTimeStep
|
||||
{
|
||||
public:
|
||||
static float ms_fTimeScale;
|
||||
static float ms_fFramesPerUpdate;
|
||||
static float ms_fTimeStep;
|
||||
};
|
||||
329
src/core/Timer.cpp
Normal file
329
src/core/Timer.cpp
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
#define WITHWINDOWS
|
||||
#include "common.h"
|
||||
#include "crossplatform.h"
|
||||
|
||||
#include "DMAudio.h"
|
||||
#include "Record.h"
|
||||
#include "Timer.h"
|
||||
|
||||
uint32 CTimer::m_snTimeInMilliseconds;
|
||||
uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1;
|
||||
uint32 CTimer::m_snTimeInMillisecondsNonClipped;
|
||||
uint32 CTimer::m_snPreviousTimeInMilliseconds;
|
||||
uint32 CTimer::m_FrameCounter;
|
||||
float CTimer::ms_fTimeScale;
|
||||
float CTimer::ms_fTimeStep;
|
||||
float CTimer::ms_fTimeStepNonClipped;
|
||||
bool CTimer::m_UserPause;
|
||||
bool CTimer::m_CodePause;
|
||||
#ifdef FIX_BUGS
|
||||
uint32 CTimer::m_LogicalFrameCounter;
|
||||
uint32 CTimer::m_LogicalFramesPassed;
|
||||
#endif
|
||||
|
||||
uint32 _nCyclesPerMS = 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER _oldPerfCounter;
|
||||
LARGE_INTEGER perfSuspendCounter;
|
||||
#define RsTimerType uint32
|
||||
#else
|
||||
#define RsTimerType double
|
||||
#endif
|
||||
|
||||
RsTimerType oldPcTimer;
|
||||
|
||||
RsTimerType suspendPcTimer;
|
||||
|
||||
uint32 suspendDepth;
|
||||
|
||||
void CTimer::Initialise(void)
|
||||
{
|
||||
debug("Initialising CTimer...\n");
|
||||
|
||||
ms_fTimeScale = 1.0f;
|
||||
ms_fTimeStep = 1.0f;
|
||||
suspendDepth = 0;
|
||||
m_UserPause = false;
|
||||
m_CodePause = false;
|
||||
m_snTimeInMillisecondsNonClipped = 0;
|
||||
m_snPreviousTimeInMilliseconds = 0;
|
||||
m_snTimeInMilliseconds = 1;
|
||||
#ifdef FIX_BUGS
|
||||
m_LogicalFrameCounter = 0;
|
||||
m_LogicalFramesPassed = 0;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER perfFreq;
|
||||
if ( QueryPerformanceFrequency(&perfFreq) )
|
||||
{
|
||||
OutputDebugString("Performance counter available\n");
|
||||
_nCyclesPerMS = uint32(perfFreq.QuadPart / 1000);
|
||||
QueryPerformanceCounter(&_oldPerfCounter);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
OutputDebugString("Performance counter not available, using millesecond timer\n");
|
||||
_nCyclesPerMS = 0;
|
||||
oldPcTimer = RsTimer();
|
||||
}
|
||||
|
||||
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds;
|
||||
|
||||
m_FrameCounter = 0;
|
||||
|
||||
DMAudio.ResetTimers(m_snPreviousTimeInMilliseconds);
|
||||
|
||||
debug("CTimer ready\n");
|
||||
}
|
||||
|
||||
void CTimer::Shutdown(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
#ifdef FIX_BUGS
|
||||
void CTimer::Update(void)
|
||||
{
|
||||
static double frameTimeLogical = 0.0;
|
||||
static double frameTimeFraction = 0.0;
|
||||
static double frameTimeFractionScaled = 0.0;
|
||||
double frameTime;
|
||||
double dblUpdInMs;
|
||||
|
||||
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( (double)_nCyclesPerMS != 0.0 )
|
||||
{
|
||||
LARGE_INTEGER pc;
|
||||
QueryPerformanceCounter(&pc);
|
||||
|
||||
int32 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
|
||||
|
||||
_oldPerfCounter = pc;
|
||||
|
||||
// bugfix from VC
|
||||
double updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
|
||||
|
||||
frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
|
||||
|
||||
dblUpdInMs = (double)updInCycles / (double)_nCyclesPerMS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RsTimerType timer = RsTimer();
|
||||
|
||||
RsTimerType updInMs = timer - oldPcTimer;
|
||||
|
||||
// bugfix from VC
|
||||
frameTime = GetIsPaused() ? (double)updInMs : (double)updInMs * ms_fTimeScale;
|
||||
|
||||
oldPcTimer = timer;
|
||||
|
||||
dblUpdInMs = (double)updInMs;
|
||||
}
|
||||
|
||||
// count frames as if we're running at 30 fps
|
||||
m_LogicalFramesPassed = 0;
|
||||
frameTimeLogical += dblUpdInMs;
|
||||
while(frameTimeLogical >= 1000.0 / 30.0) {
|
||||
frameTimeLogical -= 1000.0 / 30.0;
|
||||
m_LogicalFramesPassed++;
|
||||
}
|
||||
m_LogicalFrameCounter += m_LogicalFramesPassed;
|
||||
|
||||
frameTimeFraction += dblUpdInMs;
|
||||
frameTimeFractionScaled += frameTime;
|
||||
|
||||
m_snTimeInMillisecondsPauseMode += uint32(frameTimeFraction);
|
||||
|
||||
if ( GetIsPaused() )
|
||||
ms_fTimeStep = 0.0f;
|
||||
else
|
||||
{
|
||||
m_snTimeInMilliseconds += uint32(frameTimeFractionScaled);
|
||||
m_snTimeInMillisecondsNonClipped += uint32(frameTimeFractionScaled);
|
||||
ms_fTimeStep = frameTime / 1000.0f * 50.0f;
|
||||
}
|
||||
frameTimeFraction -= uint32(frameTimeFraction);
|
||||
frameTimeFractionScaled -= uint32(frameTimeFractionScaled);
|
||||
|
||||
if ( ms_fTimeStep < 0.01f && !GetIsPaused() )
|
||||
ms_fTimeStep = 0.01f;
|
||||
|
||||
ms_fTimeStepNonClipped = ms_fTimeStep;
|
||||
|
||||
if ( !CRecordDataForGame::IsPlayingBack() )
|
||||
{
|
||||
ms_fTimeStep = Min(3.0f, ms_fTimeStep);
|
||||
|
||||
if ( (m_snTimeInMilliseconds - m_snPreviousTimeInMilliseconds) > 60 )
|
||||
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
|
||||
}
|
||||
|
||||
if ( CRecordDataForChase::IsRecording() )
|
||||
{
|
||||
ms_fTimeStep = 1.0f;
|
||||
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
|
||||
}
|
||||
|
||||
m_FrameCounter++;
|
||||
}
|
||||
#else
|
||||
void CTimer::Update(void)
|
||||
{
|
||||
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( (double)_nCyclesPerMS != 0.0 )
|
||||
{
|
||||
LARGE_INTEGER pc;
|
||||
QueryPerformanceCounter(&pc);
|
||||
|
||||
int32 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
|
||||
|
||||
_oldPerfCounter = pc;
|
||||
|
||||
float updInCyclesScaled = updInCycles * ms_fTimeScale;
|
||||
|
||||
double frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
|
||||
m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
|
||||
|
||||
if ( GetIsPaused() )
|
||||
ms_fTimeStep = 0.0f;
|
||||
else
|
||||
{
|
||||
m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime;
|
||||
m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime;
|
||||
ms_fTimeStep = frameTime / 1000.0f * 50.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RsTimerType timer = RsTimer();
|
||||
|
||||
RsTimerType updInMs = timer - oldPcTimer;
|
||||
|
||||
double frameTime = (double)updInMs * ms_fTimeScale;
|
||||
|
||||
oldPcTimer = timer;
|
||||
|
||||
m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
|
||||
|
||||
if ( GetIsPaused() )
|
||||
ms_fTimeStep = 0.0f;
|
||||
else
|
||||
{
|
||||
m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime;
|
||||
m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime;
|
||||
ms_fTimeStep = frameTime / 1000.0f * 50.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ms_fTimeStep < 0.01f && !GetIsPaused() )
|
||||
ms_fTimeStep = 0.01f;
|
||||
|
||||
ms_fTimeStepNonClipped = ms_fTimeStep;
|
||||
|
||||
if ( !CRecordDataForGame::IsPlayingBack() )
|
||||
{
|
||||
ms_fTimeStep = Min(3.0f, ms_fTimeStep);
|
||||
|
||||
if ( (m_snTimeInMilliseconds - m_snPreviousTimeInMilliseconds) > 60 )
|
||||
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
|
||||
}
|
||||
|
||||
if ( CRecordDataForChase::IsRecording() )
|
||||
{
|
||||
ms_fTimeStep = 1.0f;
|
||||
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
|
||||
}
|
||||
|
||||
m_FrameCounter++;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CTimer::Suspend(void)
|
||||
{
|
||||
if ( ++suspendDepth > 1 )
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( (double)_nCyclesPerMS != 0.0 )
|
||||
QueryPerformanceCounter(&perfSuspendCounter);
|
||||
else
|
||||
#endif
|
||||
suspendPcTimer = RsTimer();
|
||||
}
|
||||
|
||||
void CTimer::Resume(void)
|
||||
{
|
||||
if ( --suspendDepth != 0 )
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( (double)_nCyclesPerMS != 0.0 )
|
||||
{
|
||||
LARGE_INTEGER pc;
|
||||
QueryPerformanceCounter(&pc);
|
||||
|
||||
_oldPerfCounter.LowPart += pc.LowPart - perfSuspendCounter.LowPart;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
oldPcTimer += RsTimer() - suspendPcTimer;
|
||||
}
|
||||
|
||||
uint32 CTimer::GetCyclesPerMillisecond(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (_nCyclesPerMS != 0)
|
||||
return _nCyclesPerMS;
|
||||
else
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32 CTimer::GetCurrentTimeInCycles(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if ( _nCyclesPerMS != 0 )
|
||||
{
|
||||
LARGE_INTEGER pc;
|
||||
QueryPerformanceCounter(&pc);
|
||||
return (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return RsTimer() - oldPcTimer;
|
||||
}
|
||||
|
||||
bool CTimer::GetIsSlowMotionActive(void)
|
||||
{
|
||||
return ms_fTimeScale < 1.0f;
|
||||
}
|
||||
|
||||
void CTimer::Stop(void)
|
||||
{
|
||||
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
|
||||
}
|
||||
|
||||
void CTimer::StartUserPause(void)
|
||||
{
|
||||
m_UserPause = true;
|
||||
}
|
||||
|
||||
void CTimer::EndUserPause(void)
|
||||
{
|
||||
m_UserPause = false;
|
||||
}
|
||||
|
||||
uint32 CTimer::GetCyclesPerFrame()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
71
src/core/Timer.h
Normal file
71
src/core/Timer.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
|
||||
class CTimer
|
||||
{
|
||||
|
||||
static uint32 m_snTimeInMilliseconds;
|
||||
static uint32 m_snTimeInMillisecondsPauseMode;
|
||||
static uint32 m_snTimeInMillisecondsNonClipped;
|
||||
static uint32 m_snPreviousTimeInMilliseconds;
|
||||
static uint32 m_FrameCounter;
|
||||
static float ms_fTimeScale;
|
||||
static float ms_fTimeStep;
|
||||
static float ms_fTimeStepNonClipped;
|
||||
#ifdef FIX_BUGS
|
||||
static uint32 m_LogicalFrameCounter;
|
||||
static uint32 m_LogicalFramesPassed;
|
||||
#endif
|
||||
public:
|
||||
static bool m_UserPause;
|
||||
static bool m_CodePause;
|
||||
|
||||
static const float &GetTimeStep(void) { return ms_fTimeStep; }
|
||||
static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
|
||||
static float GetTimeStepInSeconds() { return ms_fTimeStep / 50.0f; }
|
||||
static uint32 GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; }
|
||||
static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
|
||||
static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
|
||||
static float GetTimeStepNonClippedInMilliseconds(void) { return ms_fTimeStepNonClipped / 50.0f * 1000.0f; }
|
||||
static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; }
|
||||
static const uint32 &GetFrameCounter(void) { return m_FrameCounter; }
|
||||
static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; }
|
||||
static const uint32 &GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
|
||||
static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
|
||||
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
|
||||
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
|
||||
static uint32 GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; }
|
||||
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
|
||||
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
|
||||
static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; }
|
||||
static const float &GetTimeScale(void) { return ms_fTimeScale; }
|
||||
static void SetTimeScale(float ts) { ms_fTimeScale = ts; }
|
||||
static uint32 GetCyclesPerFrame();
|
||||
|
||||
static bool GetIsPaused() { return m_UserPause || m_CodePause; }
|
||||
static bool GetIsUserPaused() { return m_UserPause; }
|
||||
static bool GetIsCodePaused() { return m_CodePause; }
|
||||
static void SetCodePause(bool pause) { m_CodePause = pause; }
|
||||
|
||||
static void Initialise(void);
|
||||
static void Shutdown(void);
|
||||
static void Update(void);
|
||||
static void Suspend(void);
|
||||
static void Resume(void);
|
||||
static uint32 GetCyclesPerMillisecond(void);
|
||||
static uint32 GetCurrentTimeInCycles(void);
|
||||
static bool GetIsSlowMotionActive(void);
|
||||
static void Stop(void);
|
||||
static void StartUserPause(void);
|
||||
static void EndUserPause(void);
|
||||
|
||||
friend bool GenericLoad(void);
|
||||
friend bool GenericSave(int file);
|
||||
friend class CMemoryCard;
|
||||
|
||||
#ifdef FIX_BUGS
|
||||
static float GetDefaultTimeStep(void) { return 50.0f / 30.0f; }
|
||||
static float GetTimeStepFix(void) { return GetTimeStep() / GetDefaultTimeStep(); }
|
||||
static uint32 GetLogicalFrameCounter(void) { return m_LogicalFrameCounter; }
|
||||
static uint32 GetLogicalFramesPassed(void) { return m_LogicalFramesPassed; }
|
||||
#endif
|
||||
};
|
||||
127
src/core/User.cpp
Normal file
127
src/core/User.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#include "common.h"
|
||||
|
||||
|
||||
#include "Hud.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "Replay.h"
|
||||
#include "Text.h"
|
||||
#include "User.h"
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
#include "Zones.h"
|
||||
|
||||
CPlaceName CUserDisplay::PlaceName;
|
||||
COnscreenTimer CUserDisplay::OnscnTimer;
|
||||
CPager CUserDisplay::Pager;
|
||||
CCurrentVehicle CUserDisplay::CurrentVehicle;
|
||||
|
||||
CPlaceName::CPlaceName()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void
|
||||
CPlaceName::Init()
|
||||
{
|
||||
m_pZone = nil;
|
||||
m_pZone2 = nil;
|
||||
m_nAdditionalTimer = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CPlaceName::Process()
|
||||
{
|
||||
CVector pos = CWorld::Players[CWorld::PlayerInFocus].GetPos();
|
||||
CZone *navigZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_NAVIG);
|
||||
CZone *defaultZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_DEFAULT);
|
||||
|
||||
if (navigZone == nil) m_pZone = nil;
|
||||
if (defaultZone == nil) m_pZone2 = nil;
|
||||
|
||||
if (navigZone == m_pZone) {
|
||||
if (defaultZone == m_pZone2 || m_pZone != nil) {
|
||||
if (navigZone != nil || defaultZone != nil) {
|
||||
if (m_nAdditionalTimer != 0)
|
||||
m_nAdditionalTimer--;
|
||||
} else {
|
||||
m_nAdditionalTimer = 0;
|
||||
m_pZone = nil;
|
||||
m_pZone2 = nil;
|
||||
}
|
||||
} else {
|
||||
m_pZone2 = defaultZone;
|
||||
m_nAdditionalTimer = 250;
|
||||
}
|
||||
} else {
|
||||
m_pZone = navigZone;
|
||||
m_nAdditionalTimer = 250;
|
||||
}
|
||||
Display();
|
||||
}
|
||||
|
||||
void
|
||||
CPlaceName::Display()
|
||||
{
|
||||
wchar *text;
|
||||
if (m_pZone != nil)
|
||||
text = m_pZone->GetTranslatedName();
|
||||
else if (m_pZone2 != nil)
|
||||
text = m_pZone2->GetTranslatedName();
|
||||
#ifdef FIX_BUGS
|
||||
else
|
||||
text = nil;
|
||||
#endif
|
||||
CHud::SetZoneName(text);
|
||||
}
|
||||
|
||||
CCurrentVehicle::CCurrentVehicle()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void
|
||||
CCurrentVehicle::Init()
|
||||
{
|
||||
m_pCurrentVehicle = nil;
|
||||
}
|
||||
|
||||
void
|
||||
CCurrentVehicle::Process()
|
||||
{
|
||||
if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->InVehicle())
|
||||
m_pCurrentVehicle = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle;
|
||||
else
|
||||
m_pCurrentVehicle = nil;
|
||||
Display();
|
||||
}
|
||||
|
||||
void
|
||||
CCurrentVehicle::Display()
|
||||
{
|
||||
wchar *text = nil;
|
||||
if (m_pCurrentVehicle != nil)
|
||||
text = TheText.Get(((CVehicleModelInfo*)CModelInfo::GetModelInfo(m_pCurrentVehicle->GetModelIndex()))->m_gameName);
|
||||
CHud::SetVehicleName(text);
|
||||
}
|
||||
|
||||
void
|
||||
CUserDisplay::Init()
|
||||
{
|
||||
PlaceName.Init();
|
||||
OnscnTimer.Init();
|
||||
Pager.Init();
|
||||
CurrentVehicle.Init();
|
||||
}
|
||||
|
||||
void
|
||||
CUserDisplay::Process()
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
if (CReplay::IsPlayingBack())
|
||||
return;
|
||||
#endif
|
||||
PlaceName.Process();
|
||||
OnscnTimer.Process();
|
||||
Pager.Process();
|
||||
CurrentVehicle.Process();
|
||||
}
|
||||
41
src/core/User.h
Normal file
41
src/core/User.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include "Pager.h"
|
||||
#include "OnscreenTimer.h"
|
||||
|
||||
class CZone;
|
||||
class CVehicle;
|
||||
|
||||
class CPlaceName
|
||||
{
|
||||
CZone *m_pZone;
|
||||
CZone *m_pZone2;
|
||||
int16 m_nAdditionalTimer;
|
||||
public:
|
||||
CPlaceName();
|
||||
void Init();
|
||||
void Process();
|
||||
void Display();
|
||||
};
|
||||
|
||||
class CCurrentVehicle
|
||||
{
|
||||
CVehicle *m_pCurrentVehicle;
|
||||
public:
|
||||
CCurrentVehicle();
|
||||
void Init();
|
||||
void Process();
|
||||
void Display();
|
||||
};
|
||||
|
||||
class CUserDisplay
|
||||
{
|
||||
public:
|
||||
static CPlaceName PlaceName;
|
||||
static COnscreenTimer OnscnTimer;
|
||||
static CPager Pager;
|
||||
static CCurrentVehicle CurrentVehicle;
|
||||
|
||||
static void Init();
|
||||
static void Process();
|
||||
};
|
||||
492
src/core/Wanted.cpp
Normal file
492
src/core/Wanted.cpp
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "Pools.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "Timer.h"
|
||||
#include "World.h"
|
||||
#include "ZoneCull.h"
|
||||
#include "Darkel.h"
|
||||
#include "DMAudio.h"
|
||||
#include "CopPed.h"
|
||||
#include "Wanted.h"
|
||||
#include "General.h"
|
||||
|
||||
int32 CWanted::MaximumWantedLevel = 6;
|
||||
int32 CWanted::nMaximumWantedLevel = 6400;
|
||||
|
||||
void
|
||||
CWanted::Initialise()
|
||||
{
|
||||
m_nChaos = 0;
|
||||
m_nLastUpdateTime = 0;
|
||||
m_nLastWantedLevelChange = 0;
|
||||
m_CurrentCops = 0;
|
||||
m_MaxCops = 0;
|
||||
m_MaximumLawEnforcerVehicles = 0;
|
||||
m_RoadblockDensity = 0;
|
||||
m_bIgnoredByCops = false;
|
||||
m_bIgnoredByEveryone = false;
|
||||
m_bSwatRequired = false;
|
||||
m_bFbiRequired = false;
|
||||
m_bArmyRequired = false;
|
||||
m_fCrimeSensitivity = 1.0f;
|
||||
m_nWantedLevel = 0;
|
||||
m_CopsBeatingSuspect = 0;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++)
|
||||
m_pCops[i] = nil;
|
||||
|
||||
ClearQdCrimes();
|
||||
}
|
||||
|
||||
bool
|
||||
CWanted::AreSwatRequired()
|
||||
{
|
||||
return m_nWantedLevel == 4 || m_bSwatRequired;
|
||||
}
|
||||
|
||||
bool
|
||||
CWanted::AreFbiRequired()
|
||||
{
|
||||
return m_nWantedLevel == 5 || m_bFbiRequired;
|
||||
}
|
||||
|
||||
bool
|
||||
CWanted::AreArmyRequired()
|
||||
{
|
||||
return m_nWantedLevel == 6 || m_bArmyRequired;
|
||||
}
|
||||
|
||||
int32
|
||||
CWanted::NumOfHelisRequired()
|
||||
{
|
||||
if (m_bIgnoredByCops || m_bIgnoredByEveryone)
|
||||
return 0;
|
||||
|
||||
switch (m_nWantedLevel) {
|
||||
case 3:
|
||||
case 4:
|
||||
return 1;
|
||||
case 5:
|
||||
case 6:
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::SetWantedLevel(int32 level)
|
||||
{
|
||||
if (level > MaximumWantedLevel)
|
||||
level = MaximumWantedLevel;
|
||||
|
||||
ClearQdCrimes();
|
||||
switch (level) {
|
||||
case 0:
|
||||
m_nChaos = 0;
|
||||
break;
|
||||
case 1:
|
||||
m_nChaos = 60;
|
||||
break;
|
||||
case 2:
|
||||
m_nChaos = 220;
|
||||
break;
|
||||
case 3:
|
||||
m_nChaos = 420;
|
||||
break;
|
||||
case 4:
|
||||
m_nChaos = 820;
|
||||
break;
|
||||
case 5:
|
||||
m_nChaos = 1620;
|
||||
break;
|
||||
case 6:
|
||||
m_nChaos = 3220;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
UpdateWantedLevel();
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::SetWantedLevelNoDrop(int32 level)
|
||||
{
|
||||
if (level > m_nWantedLevel)
|
||||
SetWantedLevel(level);
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::SetMaximumWantedLevel(int32 level)
|
||||
{
|
||||
switch(level){
|
||||
case 0:
|
||||
nMaximumWantedLevel = 0;
|
||||
MaximumWantedLevel = 0;
|
||||
break;
|
||||
case 1:
|
||||
nMaximumWantedLevel = 120;
|
||||
MaximumWantedLevel = 1;
|
||||
break;
|
||||
case 2:
|
||||
nMaximumWantedLevel = 300;
|
||||
MaximumWantedLevel = 2;
|
||||
break;
|
||||
case 3:
|
||||
nMaximumWantedLevel = 600;
|
||||
MaximumWantedLevel = 3;
|
||||
break;
|
||||
case 4:
|
||||
nMaximumWantedLevel = 1200;
|
||||
MaximumWantedLevel = 4;
|
||||
break;
|
||||
case 5:
|
||||
nMaximumWantedLevel = 2400;
|
||||
MaximumWantedLevel = 5;
|
||||
break;
|
||||
case 6:
|
||||
nMaximumWantedLevel = 4800;
|
||||
MaximumWantedLevel = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare)
|
||||
{
|
||||
AddCrimeToQ(type, id, coors, false, policeDoesntCare);
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare)
|
||||
{
|
||||
#if defined FIX_SIGNIFICANT_BUGS || defined PEDS_REPORT_CRIMES_ON_PHONE
|
||||
if (!AddCrimeToQ(type, id, coors, true, policeDoesntCare))
|
||||
#else
|
||||
if (!AddCrimeToQ(type, id, coors, false, policeDoesntCare))
|
||||
#endif
|
||||
ReportCrimeNow(type, coors, policeDoesntCare);
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::ClearQdCrimes()
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
m_aCrimes[i].m_nType = CRIME_NONE;
|
||||
}
|
||||
|
||||
// returns whether the crime had been reported already
|
||||
bool
|
||||
CWanted::AddCrimeToQ(eCrimeType type, int32 id, const CVector &coors, bool reported, bool policeDoesntCare)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
if(m_aCrimes[i].m_nType == type && m_aCrimes[i].m_nId == id){
|
||||
if(m_aCrimes[i].m_bReported)
|
||||
return true;
|
||||
if(reported)
|
||||
m_aCrimes[i].m_bReported = reported;
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
if(m_aCrimes[i].m_nType == CRIME_NONE)
|
||||
break;
|
||||
if(i < 16){
|
||||
m_aCrimes[i].m_nType = type;
|
||||
m_aCrimes[i].m_nId = id;
|
||||
m_aCrimes[i].m_vecPosn = coors;
|
||||
m_aCrimes[i].m_nTime = CTimer::GetTimeInMilliseconds();
|
||||
m_aCrimes[i].m_bReported = reported;
|
||||
m_aCrimes[i].m_bPoliceDoesntCare = policeDoesntCare;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare)
|
||||
{
|
||||
float sensitivity, chaos;
|
||||
int wantedLevelDrop;
|
||||
|
||||
if(CDarkel::FrenzyOnGoing())
|
||||
sensitivity = m_fCrimeSensitivity*0.3f;
|
||||
else
|
||||
sensitivity = m_fCrimeSensitivity;
|
||||
|
||||
wantedLevelDrop = Min(CCullZones::GetWantedLevelDrop(), 100);
|
||||
|
||||
chaos = (1.0f - wantedLevelDrop/100.0f) * sensitivity;
|
||||
if (policeDoesntCare)
|
||||
chaos *= 0.333f;
|
||||
switch(type){
|
||||
case CRIME_POSSESSION_GUN:
|
||||
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
|
||||
m_nChaos += 5.0f*chaos;
|
||||
#endif
|
||||
break;
|
||||
case CRIME_HIT_PED:
|
||||
m_nChaos += 5.0f*chaos;
|
||||
break;
|
||||
case CRIME_HIT_COP:
|
||||
m_nChaos += 45.0f*chaos;
|
||||
break;
|
||||
case CRIME_SHOOT_PED:
|
||||
m_nChaos += 30.0f*chaos;
|
||||
break;
|
||||
case CRIME_SHOOT_COP:
|
||||
m_nChaos += 80.0f*chaos;
|
||||
break;
|
||||
case CRIME_STEAL_CAR:
|
||||
m_nChaos += 15.0f*chaos;
|
||||
break;
|
||||
case CRIME_RUN_REDLIGHT:
|
||||
m_nChaos += 10.0f*chaos;
|
||||
break;
|
||||
case CRIME_RECKLESS_DRIVING:
|
||||
m_nChaos += 5.0f*chaos;
|
||||
break;
|
||||
case CRIME_SPEEDING:
|
||||
m_nChaos += 5.0f*chaos;
|
||||
break;
|
||||
case CRIME_RUNOVER_PED:
|
||||
m_nChaos += 18.0f*chaos;
|
||||
break;
|
||||
case CRIME_RUNOVER_COP:
|
||||
m_nChaos += 80.0f*chaos;
|
||||
break;
|
||||
case CRIME_SHOOT_HELI:
|
||||
m_nChaos += 400.0f*chaos;
|
||||
break;
|
||||
case CRIME_PED_BURNED:
|
||||
m_nChaos += 20.0f*chaos;
|
||||
break;
|
||||
case CRIME_COP_BURNED:
|
||||
m_nChaos += 80.0f*chaos;
|
||||
break;
|
||||
case CRIME_VEHICLE_BURNED:
|
||||
m_nChaos += 20.0f*chaos;
|
||||
break;
|
||||
case CRIME_DESTROYED_CESSNA:
|
||||
m_nChaos += 500.0f*chaos;
|
||||
break;
|
||||
default:
|
||||
// Error("Undefined crime type, RegisterCrime, Crime.cpp"); // different file for some reason
|
||||
Error("Undefined crime type, RegisterCrime, Wanted.cpp");
|
||||
}
|
||||
DMAudio.ReportCrime(type, coors);
|
||||
UpdateWantedLevel();
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::UpdateWantedLevel()
|
||||
{
|
||||
int32 CurrWantedLevel = m_nWantedLevel;
|
||||
|
||||
if (m_nChaos > nMaximumWantedLevel)
|
||||
m_nChaos = nMaximumWantedLevel;
|
||||
|
||||
if (m_nChaos >= 0 && m_nChaos < 40) {
|
||||
m_nWantedLevel = 0;
|
||||
m_MaximumLawEnforcerVehicles = 0;
|
||||
m_MaxCops = 0;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 40 && m_nChaos < 200) {
|
||||
m_nWantedLevel = 1;
|
||||
m_MaximumLawEnforcerVehicles = 1;
|
||||
m_MaxCops = 1;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 200 && m_nChaos < 400) {
|
||||
m_nWantedLevel = 2;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 3;
|
||||
m_RoadblockDensity = 0;
|
||||
}
|
||||
else if (m_nChaos >= 400 && m_nChaos < 800) {
|
||||
m_nWantedLevel = 3;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 4;
|
||||
m_RoadblockDensity = 4;
|
||||
}
|
||||
else if (m_nChaos >= 800 && m_nChaos < 1600) {
|
||||
m_nWantedLevel = 4;
|
||||
m_MaximumLawEnforcerVehicles = 2;
|
||||
m_MaxCops = 6;
|
||||
m_RoadblockDensity = 8;
|
||||
}
|
||||
else if (m_nChaos >= 1600 && m_nChaos < 3200) {
|
||||
m_nWantedLevel = 5;
|
||||
m_MaximumLawEnforcerVehicles = 3;
|
||||
m_MaxCops = 8;
|
||||
m_RoadblockDensity = 10;
|
||||
}
|
||||
else if (m_nChaos >= 3200) {
|
||||
m_nWantedLevel = 6;
|
||||
m_MaximumLawEnforcerVehicles = 3;
|
||||
m_MaxCops = 10;
|
||||
m_RoadblockDensity = 12;
|
||||
}
|
||||
|
||||
if (CurrWantedLevel != m_nWantedLevel)
|
||||
m_nLastWantedLevelChange = CTimer::GetTimeInMilliseconds();
|
||||
}
|
||||
|
||||
int32
|
||||
CWanted::WorkOutPolicePresence(CVector posn, float radius)
|
||||
{
|
||||
int i;
|
||||
CPed *ped;
|
||||
CVehicle *vehicle;
|
||||
int numPolice = 0;
|
||||
|
||||
i = CPools::GetPedPool()->GetSize();
|
||||
while(--i >= 0){
|
||||
ped = CPools::GetPedPool()->GetSlot(i);
|
||||
if(ped &&
|
||||
IsPolicePedModel(ped->GetModelIndex()) &&
|
||||
(posn - ped->GetPosition()).Magnitude() < radius)
|
||||
numPolice++;
|
||||
}
|
||||
|
||||
i = CPools::GetVehiclePool()->GetSize();
|
||||
while(--i >= 0){
|
||||
vehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||
if(vehicle &&
|
||||
vehicle->bIsLawEnforcer &&
|
||||
IsPoliceVehicleModel(vehicle->GetModelIndex()) &&
|
||||
vehicle != FindPlayerVehicle() &&
|
||||
vehicle->GetStatus() != STATUS_ABANDONED && vehicle->GetStatus() != STATUS_WRECKED &&
|
||||
(posn - vehicle->GetPosition()).Magnitude() < radius)
|
||||
numPolice++;
|
||||
}
|
||||
|
||||
return numPolice;
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::Update(void)
|
||||
{
|
||||
if (CTimer::GetTimeInMilliseconds() - m_nLastUpdateTime > 1000) {
|
||||
if (m_nWantedLevel > 1) {
|
||||
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
|
||||
} else {
|
||||
float radius = 18.0f;
|
||||
CVector playerPos = FindPlayerCoors();
|
||||
if (WorkOutPolicePresence(playerPos, radius) == 0) {
|
||||
m_nLastUpdateTime = CTimer::GetTimeInMilliseconds();
|
||||
m_nChaos = Max(0, m_nChaos - 1);
|
||||
UpdateWantedLevel();
|
||||
}
|
||||
}
|
||||
UpdateCrimesQ();
|
||||
bool orderMessedUp = false;
|
||||
int currCopNum = 0;
|
||||
bool foundEmptySlot = false;
|
||||
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
|
||||
if (m_pCops[i]) {
|
||||
++currCopNum;
|
||||
if (foundEmptySlot)
|
||||
orderMessedUp = true;
|
||||
} else {
|
||||
foundEmptySlot = true;
|
||||
}
|
||||
}
|
||||
if (currCopNum != m_CurrentCops) {
|
||||
printf("CopPursuit total messed up: re-setting\n");
|
||||
m_CurrentCops = currCopNum;
|
||||
}
|
||||
if (orderMessedUp) {
|
||||
printf("CopPursuit pointer list messed up: re-sorting\n");
|
||||
bool fixed = true;
|
||||
for (int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
|
||||
if (!m_pCops[i]) {
|
||||
for (int j = i; j < ARRAY_SIZE(m_pCops); j++) {
|
||||
if (m_pCops[j]) {
|
||||
m_pCops[i] = m_pCops[j];
|
||||
m_pCops[j] = nil;
|
||||
fixed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fixed)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::ResetPolicePursuit(void)
|
||||
{
|
||||
for(int i = 0; i < ARRAY_SIZE(m_pCops); i++) {
|
||||
CCopPed *cop = m_pCops[i];
|
||||
if (!cop)
|
||||
continue;
|
||||
|
||||
cop->m_bIsInPursuit = false;
|
||||
cop->m_objective = OBJECTIVE_NONE;
|
||||
cop->m_prevObjective = OBJECTIVE_NONE;
|
||||
cop->m_nLastPedState = PED_NONE;
|
||||
if (!cop->DyingOrDead()) {
|
||||
cop->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
|
||||
}
|
||||
m_pCops[i] = nil;
|
||||
}
|
||||
m_CurrentCops = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CWanted::Reset(void)
|
||||
{
|
||||
ResetPolicePursuit();
|
||||
Initialise();
|
||||
}
|
||||
|
||||
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
|
||||
bool
|
||||
CrimeShouldBeReportedOnPhone(eCrimeType crime)
|
||||
{
|
||||
switch (crime) {
|
||||
case CRIME_POSSESSION_GUN:
|
||||
case CRIME_HIT_PED:
|
||||
case CRIME_HIT_COP:
|
||||
case CRIME_SHOOT_PED:
|
||||
case CRIME_SHOOT_COP:
|
||||
case CRIME_STEAL_CAR:
|
||||
case CRIME_RECKLESS_DRIVING:
|
||||
case CRIME_RUNOVER_PED:
|
||||
case CRIME_RUNOVER_COP:
|
||||
case CRIME_PED_BURNED:
|
||||
case CRIME_COP_BURNED:
|
||||
case CRIME_VEHICLE_BURNED:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
CWanted::UpdateCrimesQ(void)
|
||||
{
|
||||
for(int i = 0; i < ARRAY_SIZE(m_aCrimes); i++) {
|
||||
|
||||
CCrimeBeingQd &crime = m_aCrimes[i];
|
||||
if (crime.m_nType != CRIME_NONE) {
|
||||
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
|
||||
if (!CrimeShouldBeReportedOnPhone(crime.m_nType))
|
||||
#endif
|
||||
if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 500 && !crime.m_bReported) {
|
||||
ReportCrimeNow(crime.m_nType, crime.m_vecPosn, crime.m_bPoliceDoesntCare);
|
||||
crime.m_bReported = true;
|
||||
}
|
||||
if (CTimer::GetTimeInMilliseconds() > crime.m_nTime + 10000)
|
||||
crime.m_nType = CRIME_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/core/Wanted.h
Normal file
58
src/core/Wanted.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
|
||||
#include "Crime.h"
|
||||
|
||||
class CEntity;
|
||||
class CCopPed;
|
||||
|
||||
class CWanted
|
||||
{
|
||||
public:
|
||||
int32 m_nChaos;
|
||||
int32 m_nLastUpdateTime;
|
||||
uint32 m_nLastWantedLevelChange;
|
||||
float m_fCrimeSensitivity;
|
||||
uint8 m_CurrentCops;
|
||||
uint8 m_MaxCops;
|
||||
uint8 m_MaximumLawEnforcerVehicles;
|
||||
uint8 m_CopsBeatingSuspect;
|
||||
int16 m_RoadblockDensity;
|
||||
uint8 m_bIgnoredByCops : 1;
|
||||
uint8 m_bIgnoredByEveryone : 1;
|
||||
uint8 m_bSwatRequired : 1;
|
||||
uint8 m_bFbiRequired : 1;
|
||||
uint8 m_bArmyRequired : 1;
|
||||
int32 m_nWantedLevel;
|
||||
CCrimeBeingQd m_aCrimes[16];
|
||||
CCopPed *m_pCops[10];
|
||||
|
||||
static int32 MaximumWantedLevel;
|
||||
static int32 nMaximumWantedLevel;
|
||||
|
||||
public:
|
||||
void Initialise();
|
||||
bool AreSwatRequired();
|
||||
bool AreFbiRequired();
|
||||
bool AreArmyRequired();
|
||||
int32 NumOfHelisRequired();
|
||||
void SetWantedLevel(int32);
|
||||
void SetWantedLevelNoDrop(int32 level);
|
||||
int32 GetWantedLevel() { return m_nWantedLevel; }
|
||||
void RegisterCrime(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare);
|
||||
void RegisterCrime_Immediately(eCrimeType type, const CVector &coors, uint32 id, bool policeDoesntCare);
|
||||
void ClearQdCrimes();
|
||||
bool AddCrimeToQ(eCrimeType type, int32 id, const CVector &pos, bool reported, bool policeDoesntCare);
|
||||
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
|
||||
void UpdateWantedLevel();
|
||||
void Reset();
|
||||
void ResetPolicePursuit();
|
||||
void UpdateCrimesQ();
|
||||
void Update();
|
||||
|
||||
bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }
|
||||
|
||||
static int32 WorkOutPolicePresence(CVector posn, float radius);
|
||||
static void SetMaximumWantedLevel(int32 level);
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CWanted, 0x204);
|
||||
2162
src/core/World.cpp
Normal file
2162
src/core/World.cpp
Normal file
File diff suppressed because it is too large
Load diff
155
src/core/World.h
Normal file
155
src/core/World.h
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#pragma once
|
||||
|
||||
#include "Game.h"
|
||||
#include "Lists.h"
|
||||
#include "PlayerInfo.h"
|
||||
#include "Collision.h"
|
||||
|
||||
/* Sectors span from -2000 to 2000 in x and y.
|
||||
* With 100x100 sectors, each is 40x40 units. */
|
||||
|
||||
#define SECTOR_SIZE_X (40.0f)
|
||||
#define SECTOR_SIZE_Y (40.0f)
|
||||
|
||||
#define NUMSECTORS_X (100)
|
||||
#define NUMSECTORS_Y (100)
|
||||
|
||||
#define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X)
|
||||
#define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y)
|
||||
|
||||
#define WORLD_MIN_X (-2000.0f)
|
||||
#define WORLD_MIN_Y (-2000.0f)
|
||||
|
||||
#define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X)
|
||||
#define WORLD_MAX_Y (WORLD_MIN_Y + WORLD_SIZE_Y)
|
||||
|
||||
#define MAP_Z_LOW_LIMIT -100.0f
|
||||
|
||||
enum
|
||||
{
|
||||
ENTITYLIST_BUILDINGS,
|
||||
ENTITYLIST_BUILDINGS_OVERLAP,
|
||||
ENTITYLIST_OBJECTS,
|
||||
ENTITYLIST_OBJECTS_OVERLAP,
|
||||
ENTITYLIST_VEHICLES,
|
||||
ENTITYLIST_VEHICLES_OVERLAP,
|
||||
ENTITYLIST_PEDS,
|
||||
ENTITYLIST_PEDS_OVERLAP,
|
||||
ENTITYLIST_DUMMIES,
|
||||
ENTITYLIST_DUMMIES_OVERLAP,
|
||||
|
||||
NUMSECTORENTITYLISTS
|
||||
};
|
||||
|
||||
class CSector
|
||||
{
|
||||
public:
|
||||
CPtrList m_lists[NUMSECTORENTITYLISTS];
|
||||
};
|
||||
|
||||
VALIDATE_SIZE(CSector, 0x28);
|
||||
|
||||
class CWorld
|
||||
{
|
||||
static CPtrList ms_bigBuildingsList[NUM_LEVELS];
|
||||
static CPtrList ms_listMovingEntityPtrs;
|
||||
static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];
|
||||
static uint16 ms_nCurrentScanCode;
|
||||
|
||||
public:
|
||||
static uint8 PlayerInFocus;
|
||||
static CPlayerInfo Players[NUMPLAYERS];
|
||||
static CEntity *pIgnoreEntity;
|
||||
static bool bIncludeDeadPeds;
|
||||
static bool bNoMoreCollisionTorque;
|
||||
static bool bSecondShift;
|
||||
static bool bForceProcessControl;
|
||||
static bool bProcessCutsceneOnly;
|
||||
static bool bDoingCarCollisions;
|
||||
static bool bIncludeCarTyres;
|
||||
|
||||
static void Remove(CEntity *entity);
|
||||
static void Add(CEntity *entity);
|
||||
|
||||
static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
|
||||
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
|
||||
static CPtrList &GetMovingEntityList(void) { return ms_listMovingEntityPtrs; }
|
||||
static uint16 GetCurrentScanCode(void) { return ms_nCurrentScanCode; }
|
||||
static void AdvanceCurrentScanCode(void){
|
||||
if(++CWorld::ms_nCurrentScanCode == 0){
|
||||
CWorld::ClearScanCodes();
|
||||
CWorld::ms_nCurrentScanCode = 1;
|
||||
}
|
||||
}
|
||||
static void ClearScanCodes(void);
|
||||
static void ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemoveProjectilesAndTidyUpShadows);
|
||||
|
||||
static bool CameraToIgnoreThisObject(CEntity *ent);
|
||||
|
||||
static bool ProcessLineOfSight(const CVector &point1, const CVector &point2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
static bool ProcessLineOfSightSector(CSector §or, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
static bool ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
static bool ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly);
|
||||
static bool ProcessVerticalLineSector(CSector §or, const CColLine &line, CColPoint &point, CEntity *&entity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, CStoredCollPoly *poly);
|
||||
static bool ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CColPoint &point, float &dist, CEntity *&entity, bool ignoreSeeThrough, CStoredCollPoly *poly);
|
||||
static bool GetIsLineOfSightClear(const CVector &point1, const CVector &point2, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
static bool GetIsLineOfSightSectorClear(CSector §or, const CColLine &line, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
static bool GetIsLineOfSightSectorListClear(CPtrList &list, const CColLine &line, bool ignoreSeeThrough, bool ignoreSomeObjects = false);
|
||||
|
||||
static CEntity *TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects);
|
||||
static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
|
||||
static void FindObjectsInRangeSectorList(CPtrList &list, Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects);
|
||||
static void FindObjectsInRange(Const CVector ¢re, float radius, bool ignoreZ, int16 *numObjects, int16 lastObject, CEntity **objects, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies);
|
||||
static void FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
|
||||
static void FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
|
||||
static float FindGroundZForCoord(float x, float y);
|
||||
static float FindGroundZFor3DCoord(float x, float y, float z, bool *found);
|
||||
static float FindRoofZFor3DCoord(float x, float y, float z, bool *found);
|
||||
static void RemoveReferencesToDeletedObject(CEntity*);
|
||||
static void FindObjectsKindaColliding(const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
|
||||
static void FindObjectsKindaCollidingSectorList(CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities);
|
||||
static void FindObjectsIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
|
||||
static void FindObjectsIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities);
|
||||
static void FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
|
||||
static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
|
||||
static void FindMissionEntitiesIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bVehicles, bool bPeds, bool bObjects);
|
||||
static void FindMissionEntitiesIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bIsVehicleList, bool bIsPedList);
|
||||
|
||||
static void ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2);
|
||||
static void ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, float z2);
|
||||
static void CallOffChaseForArea(float x1, float y1, float x2, float y2);
|
||||
static void CallOffChaseForAreaSectorListVehicles(CPtrList& list, float x1, float y1, float x2, float y2, float fStartX, float fStartY, float fEndX, float fEndY);
|
||||
static void CallOffChaseForAreaSectorListPeds(CPtrList& list, float x1, float y1, float x2, float y2);
|
||||
|
||||
static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
|
||||
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }
|
||||
static int GetSectorIndexX(float f) { return (int)GetSectorX(f); }
|
||||
static int GetSectorIndexY(float f) { return (int)GetSectorY(f); }
|
||||
static float GetWorldX(int x) { return x*SECTOR_SIZE_X + WORLD_MIN_X; }
|
||||
static float GetWorldY(int y) { return y*SECTOR_SIZE_Y + WORLD_MIN_Y; }
|
||||
|
||||
static void RemoveEntityInsteadOfProcessingIt(CEntity* ent);
|
||||
static void RemoveFallenPeds();
|
||||
static void RemoveFallenCars();
|
||||
|
||||
static void StopAllLawEnforcersInTheirTracks();
|
||||
static void SetAllCarsCanBeDamaged(bool);
|
||||
static void ExtinguishAllCarFiresInArea(CVector, float);
|
||||
static void SetCarsOnFire(float x, float y, float z, float radius, CEntity* reason);
|
||||
static void SetPedsOnFire(float x, float y, float z, float radius, CEntity* reason);
|
||||
|
||||
static void Initialise();
|
||||
static void AddParticles();
|
||||
static void ShutDown();
|
||||
static void ClearForRestart(void);
|
||||
static void RepositionCertainDynamicObjects();
|
||||
static void RepositionOneObject(CEntity* pEntity);
|
||||
static void RemoveStaticObjects();
|
||||
static void Process();
|
||||
static void TriggerExplosion(const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
|
||||
static void TriggerExplosionSectorList(CPtrList& list, const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
|
||||
static void UseDetonator(CEntity *pEntity);
|
||||
};
|
||||
|
||||
extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
|
||||
|
||||
1589
src/core/ZoneCull.cpp
Normal file
1589
src/core/ZoneCull.cpp
Normal file
File diff suppressed because it is too large
Load diff
137
src/core/ZoneCull.h
Normal file
137
src/core/ZoneCull.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
class CEntity;
|
||||
|
||||
class CCullZone
|
||||
{
|
||||
public:
|
||||
CVector position;
|
||||
float minx;
|
||||
float maxx;
|
||||
float miny;
|
||||
float maxy;
|
||||
float minz;
|
||||
float maxz;
|
||||
|
||||
int32 m_indexStart;
|
||||
int16 m_groupIndexCount[3]; // only useful during resolution stage
|
||||
int16 m_numBuildings;
|
||||
int16 m_numTreadablesPlus10m;
|
||||
int16 m_numTreadables;
|
||||
|
||||
void DoStuffLeavingZone(void);
|
||||
static void DoStuffLeavingZone_OneBuilding(uint16 i);
|
||||
static void DoStuffLeavingZone_OneTreadableBoth(uint16 i);
|
||||
void DoStuffEnteringZone(void);
|
||||
static void DoStuffEnteringZone_OneBuilding(uint16 i);
|
||||
static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i);
|
||||
static void DoStuffEnteringZone_OneTreadable(uint16 i);
|
||||
|
||||
|
||||
static bool TestLine(CVector vec1, CVector vec2);
|
||||
static bool DoThoroughLineTest(CVector vec1, CVector vec2, CEntity *testEntity);
|
||||
float CalcDistToCullZoneSquared(float x, float y);
|
||||
float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); };
|
||||
bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel);
|
||||
bool PointFallsWithinZone(CVector pos, float radius);
|
||||
bool TestEntityVisibilityFromCullZone(CEntity *entity, float extraDist, CEntity *LODentity);
|
||||
void FindTestPoints();
|
||||
|
||||
void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) {
|
||||
switch (groupid) {
|
||||
case 0:
|
||||
default:
|
||||
// buildings
|
||||
start = m_indexStart;
|
||||
size = m_groupIndexCount[0];
|
||||
break;
|
||||
case 1:
|
||||
// treadables + 10m
|
||||
start = m_groupIndexCount[0] + m_indexStart;
|
||||
size = m_groupIndexCount[1];
|
||||
break;
|
||||
case 2:
|
||||
// treadables
|
||||
start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart;
|
||||
size = m_groupIndexCount[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
enum eZoneAttribs
|
||||
{
|
||||
ATTRZONE_CAMCLOSEIN = 1,
|
||||
ATTRZONE_STAIRS = 2,
|
||||
ATTRZONE_1STPERSON = 4,
|
||||
ATTRZONE_NORAIN = 8,
|
||||
ATTRZONE_NOPOLICE = 0x10,
|
||||
ATTRZONE_NOTCULLZONE = 0x20,
|
||||
ATTRZONE_DOINEEDCOLLISION = 0x40,
|
||||
ATTRZONE_SUBWAYVISIBLE = 0x80,
|
||||
};
|
||||
|
||||
struct CAttributeZone
|
||||
{
|
||||
float minx;
|
||||
float maxx;
|
||||
float miny;
|
||||
float maxy;
|
||||
float minz;
|
||||
float maxz;
|
||||
int16 attributes;
|
||||
int16 wantedLevel;
|
||||
};
|
||||
|
||||
class CCullZones
|
||||
{
|
||||
public:
|
||||
static int32 NumCullZones;
|
||||
static CCullZone aZones[NUMCULLZONES];
|
||||
static int32 NumAttributeZones;
|
||||
static CAttributeZone aAttributeZones[NUMATTRIBZONES];
|
||||
static uint16 aIndices[NUMZONEINDICES];
|
||||
static int16 aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
|
||||
static int16 aPointersToBigBuildingsForTreadables[NUMTREADABLES];
|
||||
|
||||
static int32 CurrentWantedLevelDrop_Player;
|
||||
static int32 CurrentFlags_Camera;
|
||||
static int32 CurrentFlags_Player;
|
||||
static int32 OldCullZone;
|
||||
static int32 EntityIndicesUsed;
|
||||
static bool bCurrentSubwayIsInvisible;
|
||||
static bool bCullZonesDisabled;
|
||||
|
||||
static void Init(void);
|
||||
static void ResolveVisibilities(void);
|
||||
static void Update(void);
|
||||
static void ForceCullZoneCoors(CVector coors);
|
||||
static int32 FindCullZoneForCoors(CVector coors);
|
||||
static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel);
|
||||
static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void);
|
||||
static void MarkSubwayAsInvisible(bool visible);
|
||||
static void AddCullZone(CVector const &position,
|
||||
float minx, float maxx,
|
||||
float miny, float maxy,
|
||||
float minz, float maxz,
|
||||
uint16 flag, int16 wantedLevel);
|
||||
static bool CamCloseInForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_CAMCLOSEIN) != 0; }
|
||||
static bool CamStairsForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_STAIRS) != 0; }
|
||||
static bool Cam1stPersonForPlayer(void) { return (CurrentFlags_Player & ATTRZONE_1STPERSON) != 0; }
|
||||
static bool NoPolice(void) { return (CurrentFlags_Player & ATTRZONE_NOPOLICE) != 0; }
|
||||
static bool DoINeedToLoadCollision(void) { return (CurrentFlags_Player & ATTRZONE_DOINEEDCOLLISION) != 0; }
|
||||
static bool PlayerNoRain(void) { return (CurrentFlags_Player & ATTRZONE_NORAIN) != 0; }
|
||||
static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; }
|
||||
static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; }
|
||||
|
||||
static void BuildListForBigBuildings();
|
||||
static void DoVisibilityTestCullZone(int zoneId, bool doIt);
|
||||
static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set);
|
||||
|
||||
static void CompressIndicesArray();
|
||||
static bool PickRandomSetForGroup(int32 zone, int32 group, uint16 *set);
|
||||
static void ReplaceSetForAllGroups(uint16 *set, uint16 setid);
|
||||
static void TidyUpAndMergeLists(uint16 *extraIndices, int32 numExtraIndices);
|
||||
|
||||
// debug
|
||||
static bool LoadTempFile(void);
|
||||
static void SaveTempFile(void);
|
||||
};
|
||||
821
src/core/Zones.cpp
Normal file
821
src/core/Zones.cpp
Normal file
|
|
@ -0,0 +1,821 @@
|
|||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Zones.h"
|
||||
|
||||
#include "Clock.h"
|
||||
#include "Text.h"
|
||||
#include "World.h"
|
||||
#include "Timer.h"
|
||||
#include "SaveBuf.h"
|
||||
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
#define ZONEARRAY_SAVE_SIZE 0xAF0
|
||||
#define MAPZONEARRAY_SAVE_SIZE 0x578
|
||||
#else
|
||||
#define ZONEARRAY_SAVE_SIZE sizeof(ZoneArray)
|
||||
#define MAPZONEARRAY_SAVE_SIZE sizeof(MapZoneArray)
|
||||
#endif
|
||||
|
||||
eLevelName CTheZones::m_CurrLevel;
|
||||
CZone *CTheZones::m_pPlayersZone;
|
||||
int16 CTheZones::FindIndex;
|
||||
|
||||
uint16 CTheZones::NumberOfAudioZones;
|
||||
int16 CTheZones::AudioZoneArray[NUMAUDIOZONES];
|
||||
uint16 CTheZones::TotalNumberOfMapZones;
|
||||
uint16 CTheZones::TotalNumberOfZones;
|
||||
CZone CTheZones::ZoneArray[NUMZONES];
|
||||
CZone CTheZones::MapZoneArray[NUMMAPZONES];
|
||||
uint16 CTheZones::TotalNumberOfZoneInfos;
|
||||
CZoneInfo CTheZones::ZoneInfoArray[2*NUMZONES];
|
||||
|
||||
#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
|
||||
|
||||
inline bool IsNormalZone(int type) { return type == ZONE_DEFAULT || type == ZONE_NAVIG || type == ZONE_INFO; }
|
||||
|
||||
static void
|
||||
CheckZoneInfo(CZoneInfo *info)
|
||||
{
|
||||
assert(info->carThreshold[0] >= 0);
|
||||
assert(info->carThreshold[0] <= info->carThreshold[1]);
|
||||
assert(info->carThreshold[1] <= info->carThreshold[2]);
|
||||
assert(info->carThreshold[2] <= info->carThreshold[3]);
|
||||
assert(info->carThreshold[3] <= info->carThreshold[4]);
|
||||
assert(info->carThreshold[4] <= info->carThreshold[5]);
|
||||
assert(info->carThreshold[5] <= info->copThreshold);
|
||||
assert(info->copThreshold <= info->gangThreshold[0]);
|
||||
assert(info->gangThreshold[0] <= info->gangThreshold[1]);
|
||||
assert(info->gangThreshold[1] <= info->gangThreshold[2]);
|
||||
assert(info->gangThreshold[2] <= info->gangThreshold[3]);
|
||||
assert(info->gangThreshold[3] <= info->gangThreshold[4]);
|
||||
assert(info->gangThreshold[4] <= info->gangThreshold[5]);
|
||||
assert(info->gangThreshold[5] <= info->gangThreshold[6]);
|
||||
assert(info->gangThreshold[6] <= info->gangThreshold[7]);
|
||||
assert(info->gangThreshold[7] <= info->gangThreshold[8]);
|
||||
}
|
||||
|
||||
wchar*
|
||||
CZone::GetTranslatedName(void)
|
||||
{
|
||||
return TheText.Get(name);
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::Init(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < NUMAUDIOZONES; i++)
|
||||
AudioZoneArray[i] = -1;
|
||||
NumberOfAudioZones = 0;
|
||||
|
||||
for(i = 0; i < NUMZONES; i++)
|
||||
memset(&ZoneArray[i], 0, sizeof(CZone));
|
||||
|
||||
CZoneInfo *zonei;
|
||||
int x = 1000/6;
|
||||
for(i = 0; i < 2*NUMZONES; i++){
|
||||
zonei = &ZoneInfoArray[i];
|
||||
zonei->carDensity = 10;
|
||||
zonei->carThreshold[0] = x;
|
||||
zonei->carThreshold[1] = zonei->carThreshold[0] + x;
|
||||
zonei->carThreshold[2] = zonei->carThreshold[1] + x;
|
||||
zonei->carThreshold[3] = zonei->carThreshold[2] + x;
|
||||
zonei->carThreshold[4] = zonei->carThreshold[3];
|
||||
zonei->carThreshold[5] = zonei->carThreshold[4];
|
||||
zonei->copThreshold = zonei->carThreshold[5] + x;
|
||||
zonei->gangThreshold[0] = zonei->copThreshold;
|
||||
zonei->gangThreshold[1] = zonei->gangThreshold[0];
|
||||
zonei->gangThreshold[2] = zonei->gangThreshold[1];
|
||||
zonei->gangThreshold[3] = zonei->gangThreshold[2];
|
||||
zonei->gangThreshold[4] = zonei->gangThreshold[3];
|
||||
zonei->gangThreshold[5] = zonei->gangThreshold[4];
|
||||
zonei->gangThreshold[6] = zonei->gangThreshold[5];
|
||||
zonei->gangThreshold[7] = zonei->gangThreshold[6];
|
||||
zonei->gangThreshold[8] = zonei->gangThreshold[7];
|
||||
CheckZoneInfo(zonei);
|
||||
}
|
||||
|
||||
TotalNumberOfZoneInfos = 1; // why 1?
|
||||
TotalNumberOfZones = 1;
|
||||
|
||||
m_CurrLevel = LEVEL_GENERIC;
|
||||
m_pPlayersZone = &ZoneArray[0];
|
||||
|
||||
strcpy(ZoneArray[0].name, "CITYZON");
|
||||
ZoneArray[0].minx = -4000.0f;
|
||||
ZoneArray[0].miny = -4000.0f;
|
||||
ZoneArray[0].minz = -500.0f;
|
||||
ZoneArray[0].maxx = 4000.0f;
|
||||
ZoneArray[0].maxy = 4000.0f;
|
||||
ZoneArray[0].maxz = 500.0f;
|
||||
ZoneArray[0].level = LEVEL_GENERIC;
|
||||
|
||||
for(i = 0; i < NUMMAPZONES; i++){
|
||||
memset(&MapZoneArray[i], 0, sizeof(CZone));
|
||||
MapZoneArray[i].type = ZONE_MAPZONE;
|
||||
}
|
||||
|
||||
TotalNumberOfMapZones = 1;
|
||||
|
||||
strcpy(MapZoneArray[0].name, "THEMAP");
|
||||
MapZoneArray[0].minx = -4000.0f;
|
||||
MapZoneArray[0].miny = -4000.0f;
|
||||
MapZoneArray[0].minz = -500.0f;
|
||||
MapZoneArray[0].maxx = 4000.0f;
|
||||
MapZoneArray[0].maxy = 4000.0f;
|
||||
MapZoneArray[0].maxz = 500.0f;
|
||||
MapZoneArray[0].level = LEVEL_GENERIC;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::Update(void)
|
||||
{
|
||||
#ifdef SQUEEZE_PERFORMANCE
|
||||
if (CTimer::GetFrameCounter() % 5 != 0)
|
||||
return;
|
||||
#endif
|
||||
CVector pos;
|
||||
pos = FindPlayerCoors();
|
||||
m_pPlayersZone = FindSmallestZonePosition(&pos);
|
||||
m_CurrLevel = GetLevelFromPosition(&pos);
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::CreateZone(char *name, eZoneType type,
|
||||
float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz,
|
||||
eLevelName level)
|
||||
{
|
||||
char *p;
|
||||
char tmpname[8];
|
||||
|
||||
if(minx > maxx) SWAPF(minx, maxx);
|
||||
if(miny > maxy) SWAPF(miny, maxy);
|
||||
if(minz > maxz) SWAPF(minz, maxz);
|
||||
|
||||
// make upper case
|
||||
for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
|
||||
|
||||
// add zone
|
||||
strncpy(tmpname, name, 7);
|
||||
tmpname[7] = '\0';
|
||||
strcpy(ZoneArray[TotalNumberOfZones].name, tmpname);
|
||||
ZoneArray[TotalNumberOfZones].type = type;
|
||||
ZoneArray[TotalNumberOfZones].minx = minx;
|
||||
ZoneArray[TotalNumberOfZones].miny = miny;
|
||||
ZoneArray[TotalNumberOfZones].minz = minz;
|
||||
ZoneArray[TotalNumberOfZones].maxx = maxx;
|
||||
ZoneArray[TotalNumberOfZones].maxy = maxy;
|
||||
ZoneArray[TotalNumberOfZones].maxz = maxz;
|
||||
ZoneArray[TotalNumberOfZones].level = level;
|
||||
if(IsNormalZone(type)){
|
||||
ZoneArray[TotalNumberOfZones].zoneinfoDay = TotalNumberOfZoneInfos++;
|
||||
ZoneArray[TotalNumberOfZones].zoneinfoNight = TotalNumberOfZoneInfos++;
|
||||
}
|
||||
TotalNumberOfZones++;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::CreateMapZone(char *name, eZoneType type,
|
||||
float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz,
|
||||
eLevelName level)
|
||||
{
|
||||
CZone *zone;
|
||||
char *p;
|
||||
|
||||
if(minx > maxx) SWAPF(minx, maxx);
|
||||
if(miny > maxy) SWAPF(miny, maxy);
|
||||
if(minz > maxz) SWAPF(minz, maxz);
|
||||
|
||||
// make upper case
|
||||
for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
|
||||
|
||||
// add zone
|
||||
zone = &MapZoneArray[TotalNumberOfMapZones++];
|
||||
strncpy(zone->name, name, 7);
|
||||
zone->name[7] = '\0';
|
||||
zone->type = type;
|
||||
zone->minx = minx;
|
||||
zone->miny = miny;
|
||||
zone->minz = minz;
|
||||
zone->maxx = maxx;
|
||||
zone->maxy = maxy;
|
||||
zone->maxz = maxz;
|
||||
zone->level = level;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::PostZoneCreation(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 1; i < TotalNumberOfZones; i++)
|
||||
InsertZoneIntoZoneHierarchy(&ZoneArray[i]);
|
||||
InitialiseAudioZoneArray();
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone)
|
||||
{
|
||||
zone->child = nil;
|
||||
zone->parent = nil;
|
||||
zone->next = nil;
|
||||
InsertZoneIntoZoneHierRecursive(zone, &ZoneArray[0]);
|
||||
}
|
||||
|
||||
bool
|
||||
CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer)
|
||||
{
|
||||
int n;
|
||||
CZone *child, *next, *insert;
|
||||
|
||||
// return false if inner was not inserted into outer
|
||||
if(outer == nil ||
|
||||
!ZoneIsEntirelyContainedWithinOtherZone(inner, outer))
|
||||
return false;
|
||||
|
||||
// try to insert inner into children of outer
|
||||
for(child = outer->child; child; child = child->next)
|
||||
if(InsertZoneIntoZoneHierRecursive(inner, child))
|
||||
return true;
|
||||
|
||||
// insert inner as child of outer
|
||||
// count number of outer's children contained within inner
|
||||
n = 0;
|
||||
for(child = outer->child; child; child = child->next)
|
||||
if(ZoneIsEntirelyContainedWithinOtherZone(child, inner))
|
||||
n++;
|
||||
inner->next = outer->child;
|
||||
inner->parent = outer;
|
||||
outer->child = inner;
|
||||
// move children from outer to inner
|
||||
if(n){
|
||||
insert = inner;
|
||||
for(child = inner->next; child; child = next){
|
||||
next = child->next;
|
||||
if(ZoneIsEntirelyContainedWithinOtherZone(child,inner)){
|
||||
insert->next = child->next;
|
||||
child->parent = inner;
|
||||
child->next = inner->child;
|
||||
inner->child = child;
|
||||
}else
|
||||
insert = child;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer)
|
||||
{
|
||||
char tmp[100];
|
||||
|
||||
if(inner->minx < outer->minx ||
|
||||
inner->maxx > outer->maxx ||
|
||||
inner->miny < outer->miny ||
|
||||
inner->maxy > outer->maxy ||
|
||||
inner->minz < outer->minz ||
|
||||
inner->maxz > outer->maxz){
|
||||
CVector vmin(inner->minx, inner->miny, inner->minz);
|
||||
if(PointLiesWithinZone(&vmin, outer))
|
||||
sprintf(tmp, "Overlapping zones %s and %s\n",
|
||||
inner->name, outer->name);
|
||||
CVector vmax(inner->maxx, inner->maxy, inner->maxz);
|
||||
if(PointLiesWithinZone(&vmax, outer))
|
||||
sprintf(tmp, "Overlapping zones %s and %s\n",
|
||||
inner->name, outer->name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone)
|
||||
{
|
||||
return zone->minx <= v->x && v->x <= zone->maxx &&
|
||||
zone->miny <= v->y && v->y <= zone->maxy &&
|
||||
zone->minz <= v->z && v->z <= zone->maxz;
|
||||
}
|
||||
|
||||
eLevelName
|
||||
CTheZones::GetLevelFromPosition(CVector const *v)
|
||||
{
|
||||
int i;
|
||||
// char tmp[116];
|
||||
// if(!PointLiesWithinZone(v, &MapZoneArray[0]))
|
||||
// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z);
|
||||
for(i = 1; i < TotalNumberOfMapZones; i++)
|
||||
if(PointLiesWithinZone(v, &MapZoneArray[i]))
|
||||
return MapZoneArray[i].level;
|
||||
return MapZoneArray[0].level;
|
||||
}
|
||||
|
||||
CZone*
|
||||
CTheZones::FindSmallestZonePosition(const CVector *v)
|
||||
{
|
||||
CZone *best = &ZoneArray[0];
|
||||
// zone to test next
|
||||
CZone *zone = ZoneArray[0].child;
|
||||
while(zone)
|
||||
// if in zone, descent into children
|
||||
if(PointLiesWithinZone(v, zone)){
|
||||
best = zone;
|
||||
zone = zone->child;
|
||||
// otherwise try next zone
|
||||
}else
|
||||
zone = zone->next;
|
||||
return best;
|
||||
}
|
||||
|
||||
CZone*
|
||||
CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type)
|
||||
{
|
||||
CZone *best = nil;
|
||||
if(ZoneArray[0].type == type)
|
||||
best = &ZoneArray[0];
|
||||
// zone to test next
|
||||
CZone *zone = ZoneArray[0].child;
|
||||
while(zone)
|
||||
// if in zone, descent into children
|
||||
if(PointLiesWithinZone(v, zone)){
|
||||
if(zone->type == type)
|
||||
best = zone;
|
||||
zone = zone->child;
|
||||
// otherwise try next zone
|
||||
}else
|
||||
zone = zone->next;
|
||||
return best;
|
||||
}
|
||||
|
||||
CZone*
|
||||
CTheZones::FindSmallestZonePositionILN(const CVector *v)
|
||||
{
|
||||
CZone *best = nil;
|
||||
if(IsNormalZone(ZoneArray[0].type))
|
||||
best = &ZoneArray[0];
|
||||
// zone to test next
|
||||
CZone *zone = ZoneArray[0].child;
|
||||
while(zone)
|
||||
// if in zone, descent into children
|
||||
if(PointLiesWithinZone(v, zone)){
|
||||
if(IsNormalZone(zone->type))
|
||||
best = zone;
|
||||
zone = zone->child;
|
||||
// otherwise try next zone
|
||||
}else
|
||||
zone = zone->next;
|
||||
return best;
|
||||
}
|
||||
|
||||
int16
|
||||
CTheZones::FindZoneByLabelAndReturnIndex(Const char *name)
|
||||
{
|
||||
char str[8];
|
||||
memset(str, 0, 8);
|
||||
strncpy(str, name, 8);
|
||||
for(FindIndex = 0; FindIndex < TotalNumberOfZones; FindIndex++)
|
||||
if(strcmp(GetZone(FindIndex)->name, name) == 0)
|
||||
return FindIndex;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CZoneInfo*
|
||||
CTheZones::GetZoneInfo(const CVector *v, uint8 day)
|
||||
{
|
||||
CZone *zone;
|
||||
zone = FindSmallestZonePositionILN(v);
|
||||
if(zone == nil)
|
||||
return &ZoneInfoArray[0];
|
||||
return &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
|
||||
{
|
||||
CZoneInfo *day, *night;
|
||||
float d, n;
|
||||
|
||||
day = GetZoneInfo(pos, 1);
|
||||
night = GetZoneInfo(pos, 0);
|
||||
|
||||
if(CClock::GetIsTimeInRange(8, 19))
|
||||
*info = *day;
|
||||
else if(CClock::GetIsTimeInRange(22, 5))
|
||||
*info = *night;
|
||||
else{
|
||||
if(CClock::GetIsTimeInRange(19, 22)){
|
||||
n = (CClock::GetHours() - 19) / 3.0f;
|
||||
assert(n >= 0.0f && n <= 1.0f);
|
||||
d = 1.0f - n;
|
||||
}else{
|
||||
d = (CClock::GetHours() - 5) / 3.0f;
|
||||
assert(d >= 0.0f && d <= 1.0f);
|
||||
n = 1.0f - d;
|
||||
}
|
||||
info->carDensity = day->carDensity * d + night->carDensity * n;
|
||||
info->carThreshold[0] = day->carThreshold[0] * d + night->carThreshold[0] * n;
|
||||
info->carThreshold[1] = day->carThreshold[1] * d + night->carThreshold[1] * n;
|
||||
info->carThreshold[2] = day->carThreshold[2] * d + night->carThreshold[2] * n;
|
||||
info->carThreshold[3] = day->carThreshold[3] * d + night->carThreshold[3] * n;
|
||||
info->carThreshold[4] = day->carThreshold[4] * d + night->carThreshold[4] * n;
|
||||
info->carThreshold[5] = day->carThreshold[5] * d + night->carThreshold[5] * n;
|
||||
info->copThreshold = day->copThreshold * d + night->copThreshold * n;
|
||||
info->gangThreshold[0] = day->gangThreshold[0] * d + night->gangThreshold[0] * n;
|
||||
info->gangThreshold[1] = day->gangThreshold[1] * d + night->gangThreshold[1] * n;
|
||||
info->gangThreshold[2] = day->gangThreshold[2] * d + night->gangThreshold[2] * n;
|
||||
info->gangThreshold[3] = day->gangThreshold[3] * d + night->gangThreshold[3] * n;
|
||||
info->gangThreshold[4] = day->gangThreshold[4] * d + night->gangThreshold[4] * n;
|
||||
info->gangThreshold[5] = day->gangThreshold[5] * d + night->gangThreshold[5] * n;
|
||||
info->gangThreshold[6] = day->gangThreshold[6] * d + night->gangThreshold[6] * n;
|
||||
info->gangThreshold[7] = day->gangThreshold[7] * d + night->gangThreshold[7] * n;
|
||||
info->gangThreshold[8] = day->gangThreshold[8] * d + night->gangThreshold[8] * n;
|
||||
|
||||
info->pedDensity = day->pedDensity * d + night->pedDensity * n;
|
||||
info->copDensity = day->copDensity * d + night->copDensity * n;
|
||||
info->gangDensity[0] = day->gangDensity[0] * d + night->gangDensity[0] * n;
|
||||
info->gangDensity[1] = day->gangDensity[1] * d + night->gangDensity[1] * n;
|
||||
info->gangDensity[2] = day->gangDensity[2] * d + night->gangDensity[2] * n;
|
||||
info->gangDensity[3] = day->gangDensity[3] * d + night->gangDensity[3] * n;
|
||||
info->gangDensity[4] = day->gangDensity[4] * d + night->gangDensity[4] * n;
|
||||
info->gangDensity[5] = day->gangDensity[5] * d + night->gangDensity[5] * n;
|
||||
info->gangDensity[6] = day->gangDensity[6] * d + night->gangDensity[6] * n;
|
||||
info->gangDensity[7] = day->gangDensity[7] * d + night->gangDensity[7] * n;
|
||||
info->gangDensity[8] = day->gangDensity[8] * d + night->gangDensity[8] * n;
|
||||
}
|
||||
if(CClock::GetIsTimeInRange(5, 19))
|
||||
info->pedGroup = day->pedGroup;
|
||||
else
|
||||
info->pedGroup = night->pedGroup;
|
||||
|
||||
CheckZoneInfo(info);
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
|
||||
int16 gang0Num, int16 gang1Num, int16 gang2Num,
|
||||
int16 gang3Num, int16 gang4Num, int16 gang5Num,
|
||||
int16 gang6Num, int16 gang7Num, int16 gang8Num,
|
||||
int16 copNum,
|
||||
int16 car0Num, int16 car1Num, int16 car2Num,
|
||||
int16 car3Num, int16 car4Num, int16 car5Num)
|
||||
{
|
||||
CZone *zone;
|
||||
CZoneInfo *info;
|
||||
zone = GetZone(zoneid);
|
||||
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
|
||||
|
||||
CheckZoneInfo(info);
|
||||
|
||||
if(carDensity != -1) info->carDensity = carDensity;
|
||||
int16 oldCar1Num = info->carThreshold[1] - info->carThreshold[0];
|
||||
int16 oldCar2Num = info->carThreshold[2] - info->carThreshold[1];
|
||||
int16 oldCar3Num = info->carThreshold[3] - info->carThreshold[2];
|
||||
int16 oldCar4Num = info->carThreshold[4] - info->carThreshold[3];
|
||||
int16 oldCar5Num = info->carThreshold[5] - info->carThreshold[4];
|
||||
int16 oldCopNum = info->copThreshold - info->carThreshold[5];
|
||||
int16 oldGang0Num = info->gangThreshold[0] - info->copThreshold;
|
||||
int16 oldGang1Num = info->gangThreshold[1] - info->gangThreshold[0];
|
||||
int16 oldGang2Num = info->gangThreshold[2] - info->gangThreshold[1];
|
||||
int16 oldGang3Num = info->gangThreshold[3] - info->gangThreshold[2];
|
||||
int16 oldGang4Num = info->gangThreshold[4] - info->gangThreshold[3];
|
||||
int16 oldGang5Num = info->gangThreshold[5] - info->gangThreshold[4];
|
||||
int16 oldGang6Num = info->gangThreshold[6] - info->gangThreshold[5];
|
||||
int16 oldGang7Num = info->gangThreshold[7] - info->gangThreshold[6];
|
||||
int16 oldGang8Num = info->gangThreshold[8] - info->gangThreshold[7];
|
||||
|
||||
if(car0Num != -1) info->carThreshold[0] = car0Num;
|
||||
if(car1Num != -1) info->carThreshold[1] = info->carThreshold[0] + car1Num;
|
||||
else info->carThreshold[1] = info->carThreshold[0] + oldCar1Num;
|
||||
if(car2Num != -1) info->carThreshold[2] = info->carThreshold[1] + car2Num;
|
||||
else info->carThreshold[2] = info->carThreshold[1] + oldCar2Num;
|
||||
if(car3Num != -1) info->carThreshold[3] = info->carThreshold[2] + car3Num;
|
||||
else info->carThreshold[3] = info->carThreshold[2] + oldCar3Num;
|
||||
if(car4Num != -1) info->carThreshold[4] = info->carThreshold[3] + car4Num;
|
||||
else info->carThreshold[4] = info->carThreshold[3] + oldCar4Num;
|
||||
if(car5Num != -1) info->carThreshold[5] = info->carThreshold[4] + car5Num;
|
||||
else info->carThreshold[5] = info->carThreshold[4] + oldCar5Num;
|
||||
if(copNum != -1) info->copThreshold = info->carThreshold[5] + copNum;
|
||||
else info->copThreshold = info->carThreshold[5] + oldCopNum;
|
||||
if(gang0Num != -1) info->gangThreshold[0] = info->copThreshold + gang0Num;
|
||||
else info->gangThreshold[0] = info->copThreshold + oldGang0Num;
|
||||
if(gang1Num != -1) info->gangThreshold[1] = info->gangThreshold[0] + gang1Num;
|
||||
else info->gangThreshold[1] = info->gangThreshold[0] + oldGang1Num;
|
||||
if(gang2Num != -1) info->gangThreshold[2] = info->gangThreshold[1] + gang2Num;
|
||||
else info->gangThreshold[2] = info->gangThreshold[1] + oldGang2Num;
|
||||
if(gang3Num != -1) info->gangThreshold[3] = info->gangThreshold[2] + gang3Num;
|
||||
else info->gangThreshold[3] = info->gangThreshold[2] + oldGang3Num;
|
||||
if(gang4Num != -1) info->gangThreshold[4] = info->gangThreshold[3] + gang4Num;
|
||||
else info->gangThreshold[4] = info->gangThreshold[3] + oldGang4Num;
|
||||
if(gang5Num != -1) info->gangThreshold[5] = info->gangThreshold[4] + gang5Num;
|
||||
else info->gangThreshold[5] = info->gangThreshold[4] + oldGang5Num;
|
||||
if(gang6Num != -1) info->gangThreshold[6] = info->gangThreshold[5] + gang6Num;
|
||||
else info->gangThreshold[6] = info->gangThreshold[5] + oldGang6Num;
|
||||
if(gang7Num != -1) info->gangThreshold[7] = info->gangThreshold[6] + gang7Num;
|
||||
else info->gangThreshold[7] = info->gangThreshold[6] + oldGang7Num;
|
||||
if(gang8Num != -1) info->gangThreshold[8] = info->gangThreshold[7] + gang8Num;
|
||||
else info->gangThreshold[8] = info->gangThreshold[7] + oldGang8Num;
|
||||
|
||||
CheckZoneInfo(info);
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
|
||||
int16 gang0Density, int16 gang1Density, int16 gang2Density, int16 gang3Density,
|
||||
int16 gang4Density, int16 gang5Density, int16 gang6Density, int16 gang7Density,
|
||||
int16 gang8Density, int16 copDensity)
|
||||
{
|
||||
CZone *zone;
|
||||
CZoneInfo *info;
|
||||
zone = GetZone(zoneid);
|
||||
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
|
||||
if(pedDensity != -1) info->pedDensity = pedDensity;
|
||||
if(copDensity != -1) info->copDensity = copDensity;
|
||||
if(gang0Density != -1) info->gangDensity[0] = gang0Density;
|
||||
if(gang1Density != -1) info->gangDensity[1] = gang1Density;
|
||||
if(gang2Density != -1) info->gangDensity[2] = gang2Density;
|
||||
if(gang3Density != -1) info->gangDensity[3] = gang3Density;
|
||||
if(gang4Density != -1) info->gangDensity[4] = gang4Density;
|
||||
if(gang5Density != -1) info->gangDensity[5] = gang5Density;
|
||||
if(gang6Density != -1) info->gangDensity[6] = gang6Density;
|
||||
if(gang7Density != -1) info->gangDensity[7] = gang7Density;
|
||||
if(gang8Density != -1) info->gangDensity[8] = gang8Density;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity)
|
||||
{
|
||||
CZone *zone;
|
||||
zone = GetZone(zoneid);
|
||||
if(IsNormalZone(zone->type))
|
||||
ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity)
|
||||
{
|
||||
CZone *zone;
|
||||
zone = GetZone(zoneid);
|
||||
if(IsNormalZone(zone->type))
|
||||
ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup)
|
||||
{
|
||||
CZone *zone;
|
||||
zone = GetZone(zoneid);
|
||||
if(IsNormalZone(zone->type))
|
||||
ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
|
||||
}
|
||||
|
||||
int16
|
||||
CTheZones::FindAudioZone(CVector *pos)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NumberOfAudioZones; i++)
|
||||
if(PointLiesWithinZone(pos, GetAudioZone(i)))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
eLevelName
|
||||
CTheZones::FindZoneForPoint(const CVector &pos)
|
||||
{
|
||||
if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("IND_ZON"))))
|
||||
return LEVEL_INDUSTRIAL;
|
||||
if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("COM_ZON"))))
|
||||
return LEVEL_COMMERCIAL;
|
||||
if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("SUB_ZON"))))
|
||||
return LEVEL_SUBURBAN;
|
||||
return LEVEL_GENERIC;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::AddZoneToAudioZoneArray(CZone *zone)
|
||||
{
|
||||
int i, z;
|
||||
|
||||
if(zone->type != ZONE_DEFAULT)
|
||||
return;
|
||||
|
||||
/* This is a bit stupid */
|
||||
z = -1;
|
||||
for(i = 0; i < NUMZONES; i++)
|
||||
if(&ZoneArray[i] == zone)
|
||||
z = i;
|
||||
AudioZoneArray[NumberOfAudioZones++] = z;
|
||||
}
|
||||
|
||||
void
|
||||
CTheZones::InitialiseAudioZoneArray(void)
|
||||
{
|
||||
bool gonext;
|
||||
CZone *zone;
|
||||
|
||||
gonext = false;
|
||||
zone = &ZoneArray[0];
|
||||
// Go deep first,
|
||||
// set gonext when backing up a level to visit the next child
|
||||
while(zone)
|
||||
if(gonext){
|
||||
AddZoneToAudioZoneArray(zone);
|
||||
if(zone->next){
|
||||
gonext = false;
|
||||
zone = zone->next;
|
||||
}else
|
||||
zone = zone->parent;
|
||||
}else if(zone->child)
|
||||
zone = zone->child;
|
||||
else{
|
||||
AddZoneToAudioZoneArray(zone);
|
||||
if(zone->next)
|
||||
zone = zone->next;
|
||||
else{
|
||||
gonext = true;
|
||||
zone = zone->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
static inline void
|
||||
SaveOneZone(CZone &zone, uint8 *&buffer)
|
||||
{
|
||||
memcpy(buffer, zone.name, sizeof(zone.name));
|
||||
SkipSaveBuf(buffer, sizeof(zone.name));
|
||||
WriteSaveBuf(buffer, zone.minx);
|
||||
WriteSaveBuf(buffer, zone.miny);
|
||||
WriteSaveBuf(buffer, zone.minz);
|
||||
WriteSaveBuf(buffer, zone.maxx);
|
||||
WriteSaveBuf(buffer, zone.maxy);
|
||||
WriteSaveBuf(buffer, zone.maxz);
|
||||
WriteSaveBuf(buffer, zone.type);
|
||||
WriteSaveBuf(buffer, zone.level);
|
||||
WriteSaveBuf(buffer, zone.zoneinfoDay);
|
||||
WriteSaveBuf(buffer, zone.zoneinfoNight);
|
||||
WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.child));
|
||||
WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.parent));
|
||||
WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.next));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
int i;
|
||||
|
||||
*size = SAVE_HEADER_SIZE
|
||||
+ sizeof(int32) // GetIndexForZonePointer
|
||||
+ sizeof(m_CurrLevel) + sizeof(FindIndex)
|
||||
+ sizeof(int16) // padding
|
||||
+ ZONEARRAY_SAVE_SIZE + sizeof(ZoneInfoArray)
|
||||
+ sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
|
||||
+ MAPZONEARRAY_SAVE_SIZE + sizeof(AudioZoneArray)
|
||||
+ sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
|
||||
|
||||
WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
|
||||
|
||||
WriteSaveBuf(buffer, (int32)GetIndexForZonePointer(m_pPlayersZone));
|
||||
WriteSaveBuf(buffer, m_CurrLevel);
|
||||
WriteSaveBuf(buffer, FindIndex);
|
||||
WriteSaveBuf(buffer, (int16)0); // padding
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
SaveOneZone(ZoneArray[i], buffer);
|
||||
#else
|
||||
CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]);
|
||||
zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child);
|
||||
zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent);
|
||||
zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next);
|
||||
#endif
|
||||
}
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
|
||||
WriteSaveBuf(buffer, ZoneInfoArray[i]);
|
||||
|
||||
WriteSaveBuf(buffer, TotalNumberOfZones);
|
||||
WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
|
||||
#ifndef COMPATIBLE_SAVES
|
||||
CZone* zone = WriteSaveBuf(buffer, MapZoneArray[i]);
|
||||
#endif
|
||||
|
||||
/*
|
||||
The call of GetIndexForZonePointer is wrong, as it is
|
||||
meant for a different array, but the game doesn't brake
|
||||
if those fields are nil. Let's make sure they are.
|
||||
*/
|
||||
assert(MapZoneArray[i].child == nil);
|
||||
assert(MapZoneArray[i].parent == nil);
|
||||
assert(MapZoneArray[i].next == nil);
|
||||
#ifndef COMPATIBLE_SAVES
|
||||
zone->child = (CZone*)GetIndexForZonePointer(MapZoneArray[i].child);
|
||||
zone->parent = (CZone*)GetIndexForZonePointer(MapZoneArray[i].parent);
|
||||
zone->next = (CZone*)GetIndexForZonePointer(MapZoneArray[i].next);
|
||||
#else
|
||||
SaveOneZone(MapZoneArray[i], buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
|
||||
WriteSaveBuf(buffer, AudioZoneArray[i]);
|
||||
|
||||
WriteSaveBuf(buffer, TotalNumberOfMapZones);
|
||||
WriteSaveBuf(buffer, NumberOfAudioZones);
|
||||
|
||||
VALIDATESAVEBUF(*size)
|
||||
}
|
||||
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
static inline void
|
||||
LoadOneZone(CZone &zone, uint8 *&buffer)
|
||||
{
|
||||
memcpy(zone.name, buffer, sizeof(zone.name));
|
||||
SkipSaveBuf(buffer, sizeof(zone.name));
|
||||
ReadSaveBuf(&zone.minx, buffer);
|
||||
ReadSaveBuf(&zone.miny, buffer);
|
||||
ReadSaveBuf(&zone.minz, buffer);
|
||||
ReadSaveBuf(&zone.maxx, buffer);
|
||||
ReadSaveBuf(&zone.maxy, buffer);
|
||||
ReadSaveBuf(&zone.maxz, buffer);
|
||||
ReadSaveBuf(&zone.type, buffer);
|
||||
ReadSaveBuf(&zone.level, buffer);
|
||||
ReadSaveBuf(&zone.zoneinfoDay, buffer);
|
||||
ReadSaveBuf(&zone.zoneinfoNight, buffer);
|
||||
int32 tmp;
|
||||
ReadSaveBuf(&tmp, buffer);
|
||||
zone.child = CTheZones::GetPointerForZoneIndex(tmp);
|
||||
ReadSaveBuf(&tmp, buffer);
|
||||
zone.parent = CTheZones::GetPointerForZoneIndex(tmp);
|
||||
ReadSaveBuf(&tmp, buffer);
|
||||
zone.next = CTheZones::GetPointerForZoneIndex(tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
|
||||
{
|
||||
INITSAVEBUF
|
||||
int32 i;
|
||||
|
||||
CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
|
||||
|
||||
ReadSaveBuf(&i, buffer);
|
||||
m_pPlayersZone = GetPointerForZoneIndex(i);
|
||||
ReadSaveBuf(&m_CurrLevel, buffer);
|
||||
ReadSaveBuf(&FindIndex, buffer);
|
||||
SkipSaveBuf(buffer, 2);
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
LoadOneZone(ZoneArray[i], buffer);
|
||||
#else
|
||||
ReadSaveBuf(&ZoneArray[i], buffer);
|
||||
|
||||
ZoneArray[i].child = GetPointerForZoneIndex((uintptr)ZoneArray[i].child);
|
||||
ZoneArray[i].parent = GetPointerForZoneIndex((uintptr)ZoneArray[i].parent);
|
||||
ZoneArray[i].next = GetPointerForZoneIndex((uintptr)ZoneArray[i].next);
|
||||
#endif
|
||||
}
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
|
||||
ReadSaveBuf(&ZoneInfoArray[i], buffer);
|
||||
|
||||
ReadSaveBuf(&TotalNumberOfZones, buffer);
|
||||
ReadSaveBuf(&TotalNumberOfZoneInfos, buffer);
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
|
||||
#ifdef COMPATIBLE_SAVES
|
||||
LoadOneZone(MapZoneArray[i], buffer);
|
||||
#else
|
||||
ReadSaveBuf(&MapZoneArray[i], buffer);
|
||||
|
||||
/*
|
||||
The call of GetPointerForZoneIndex is wrong, as it is
|
||||
meant for a different array, but the game doesn't brake
|
||||
if save data stored is -1.
|
||||
*/
|
||||
MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
|
||||
MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
|
||||
MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
|
||||
#endif
|
||||
assert(MapZoneArray[i].child == nil);
|
||||
assert(MapZoneArray[i].parent == nil);
|
||||
assert(MapZoneArray[i].next == nil);
|
||||
}
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
|
||||
ReadSaveBuf(&AudioZoneArray[i], buffer);
|
||||
|
||||
ReadSaveBuf(&TotalNumberOfMapZones, buffer);
|
||||
ReadSaveBuf(&NumberOfAudioZones, buffer);
|
||||
|
||||
VALIDATESAVEBUF(size)
|
||||
}
|
||||
114
src/core/Zones.h
Normal file
114
src/core/Zones.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#pragma once
|
||||
|
||||
#include "Game.h"
|
||||
#include "Gangs.h"
|
||||
|
||||
enum eZoneType
|
||||
{
|
||||
ZONE_DEFAULT,
|
||||
ZONE_NAVIG,
|
||||
ZONE_INFO,
|
||||
ZONE_MAPZONE,
|
||||
};
|
||||
|
||||
class CZone
|
||||
{
|
||||
public:
|
||||
char name[8];
|
||||
float minx;
|
||||
float miny;
|
||||
float minz;
|
||||
float maxx;
|
||||
float maxy;
|
||||
float maxz;
|
||||
eZoneType type;
|
||||
eLevelName level;
|
||||
int16 zoneinfoDay;
|
||||
int16 zoneinfoNight;
|
||||
CZone *child;
|
||||
CZone *parent;
|
||||
CZone *next;
|
||||
|
||||
wchar *GetTranslatedName(void);
|
||||
};
|
||||
|
||||
class CZoneInfo
|
||||
{
|
||||
public:
|
||||
// Car data
|
||||
int16 carDensity;
|
||||
int16 carThreshold[6];
|
||||
int16 copThreshold;
|
||||
int16 gangThreshold[NUM_GANGS];
|
||||
|
||||
// Ped data
|
||||
uint16 pedDensity;
|
||||
uint16 copDensity;
|
||||
uint16 gangDensity[NUM_GANGS];
|
||||
uint16 pedGroup;
|
||||
};
|
||||
|
||||
|
||||
class CTheZones
|
||||
{
|
||||
static CZone *m_pPlayersZone;
|
||||
static int16 FindIndex;
|
||||
|
||||
static uint16 NumberOfAudioZones;
|
||||
static int16 AudioZoneArray[NUMAUDIOZONES];
|
||||
static uint16 TotalNumberOfMapZones;
|
||||
static uint16 TotalNumberOfZones;
|
||||
static CZone ZoneArray[NUMZONES];
|
||||
static CZone MapZoneArray[NUMMAPZONES];
|
||||
static uint16 TotalNumberOfZoneInfos;
|
||||
static CZoneInfo ZoneInfoArray[2*NUMZONES];
|
||||
public:
|
||||
static eLevelName m_CurrLevel;
|
||||
|
||||
static void Init(void);
|
||||
static void Update(void);
|
||||
static void CreateZone(char *name, eZoneType type,
|
||||
float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz,
|
||||
eLevelName level);
|
||||
static void CreateMapZone(char *name, eZoneType type,
|
||||
float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz,
|
||||
eLevelName level);
|
||||
static CZone *GetZone(uint16 i) { return &ZoneArray[i]; }
|
||||
static CZone *GetAudioZone(uint16 i) { return &ZoneArray[AudioZoneArray[i]]; }
|
||||
static void PostZoneCreation(void);
|
||||
static void InsertZoneIntoZoneHierarchy(CZone *zone);
|
||||
static bool InsertZoneIntoZoneHierRecursive(CZone *z1, CZone *z2);
|
||||
static bool ZoneIsEntirelyContainedWithinOtherZone(CZone *z1, CZone *z2);
|
||||
static bool PointLiesWithinZone(const CVector *v, CZone *zone);
|
||||
static eLevelName GetLevelFromPosition(const CVector *v);
|
||||
static CZone *FindSmallestZonePosition(const CVector *v);
|
||||
static CZone *FindSmallestZonePositionType(const CVector *v, eZoneType type);
|
||||
static CZone *FindSmallestZonePositionILN(const CVector *v);
|
||||
static int16 FindZoneByLabelAndReturnIndex(Const char *name);
|
||||
static CZoneInfo *GetZoneInfo(const CVector *v, uint8 day);
|
||||
static void GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info);
|
||||
static void SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
|
||||
int16 gang0Num, int16 gang1Num, int16 gang2Num,
|
||||
int16 gang3Num, int16 gang4Num, int16 gang5Num,
|
||||
int16 gang6Num, int16 gang7Num, int16 gang8Num,
|
||||
int16 copNum,
|
||||
int16 car0Num, int16 car1Num, int16 car2Num,
|
||||
int16 car3Num, int16 car4Num, int16 car5Num);
|
||||
static void SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
|
||||
int16 gang0Density, int16 gang1Density, int16 gang2Density, int16 gang3Density,
|
||||
int16 gang4Density, int16 gang5Density, int16 gang6Density, int16 gang7Density,
|
||||
int16 gang8Density, int16 copDensity);
|
||||
static void SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity);
|
||||
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
|
||||
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
|
||||
static int16 FindAudioZone(CVector *pos);
|
||||
static eLevelName FindZoneForPoint(const CVector &pos);
|
||||
static CZone *GetPointerForZoneIndex(ssize_t i) { return i == -1 ? nil : &ZoneArray[i]; }
|
||||
static ssize_t GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
|
||||
static void AddZoneToAudioZoneArray(CZone *zone);
|
||||
static void InitialiseAudioZoneArray(void);
|
||||
static void SaveAllZones(uint8 *buffer, uint32 *length);
|
||||
static void LoadAllZones(uint8 *buffer, uint32 length);
|
||||
};
|
||||
401
src/core/common.h
Normal file
401
src/core/common.h
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
#pragma once
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define _USE_MATH_DEFINES
|
||||
#pragma warning(disable: 4244) // int to float
|
||||
#pragma warning(disable: 4800) // int to bool
|
||||
#pragma warning(disable: 4838) // narrowing conversion
|
||||
#pragma warning(disable: 4996) // POSIX names
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#define __STDC_LIMIT_MACROS // so we get UINT32_MAX etc
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#define AUDIO_MSS
|
||||
#define RWLIBS // codewarrior doesn't support project level defines - so not even this is enough, but still catches most ifdefs
|
||||
#endif
|
||||
|
||||
#if !defined RW_D3D9 && defined LIBRW
|
||||
#undef WITHD3D
|
||||
#undef WITHDINPUT
|
||||
#endif
|
||||
|
||||
#if (defined WITHD3D && !defined LIBRW)
|
||||
#define WITHWINDOWS
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 && defined WITHWINDOWS && !defined _INC_WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITHD3D
|
||||
#ifdef LIBRW
|
||||
#define WITH_D3D // librw includes d3d9 itself via this right now
|
||||
#else
|
||||
#ifndef USE_D3D9
|
||||
#include <d3d8.h>
|
||||
#else
|
||||
#include <d3d9.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITHDINPUT
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
#endif
|
||||
|
||||
#include <rwcore.h>
|
||||
#include <rpworld.h>
|
||||
|
||||
// gotta put this somewhere
|
||||
#ifdef LIBRW
|
||||
#define STREAMPOS(str) ((str)->tell())
|
||||
#define STREAMFILE(str) (((rw::StreamFile*)(str))->file)
|
||||
#define HIERNODEINFO(hier) ((hier)->nodeInfo)
|
||||
#define HIERNODEID(hier, i) ((hier)->nodeInfo[i].id)
|
||||
#define HANIMFRAME(anim, i) ((RwUInt8*)(anim)->keyframes + (i)*(anim)->interpInfo->animKeyFrameSize)
|
||||
#else
|
||||
#define RWHALFPIXEL // always d3d
|
||||
#define STREAMPOS(str) ((str)->Type.memory.position)
|
||||
#define STREAMFILE(str) ((str)->Type.file.fpFile)
|
||||
#define HIERNODEINFO(hier) ((hier)->pNodeInfo)
|
||||
#define HIERNODEID(hier, i) ((hier)->pNodeInfo[i].nodeID)
|
||||
#define HANIMFRAME(anim, i) ((RwUInt8*)(anim)->pFrames + (i)*(anim)->interpInfo->keyFrameSize)
|
||||
#define RpHAnimStdInterpFrame RpHAnimStdKeyFrame
|
||||
#endif
|
||||
|
||||
#ifdef RWHALFPIXEL
|
||||
#define HALFPX (0.5f)
|
||||
#else
|
||||
#define HALFPX (0.0f)
|
||||
#endif
|
||||
|
||||
#define rwVENDORID_ROCKSTAR 0x0253F2
|
||||
|
||||
#define Max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define Min(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
// Use this to add const that wasn't there in the original code
|
||||
#define Const const
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef int8_t int8;
|
||||
typedef uint16_t uint16;
|
||||
typedef int16_t int16;
|
||||
#ifndef __MWERKS__
|
||||
typedef uint32_t uint32;
|
||||
typedef int32_t int32;
|
||||
#else
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
#endif
|
||||
typedef uintptr_t uintptr;
|
||||
typedef intptr_t intptr;
|
||||
typedef uint64_t uint64;
|
||||
typedef int64_t int64;
|
||||
// hardcode ucs-2
|
||||
typedef uint16_t wchar;
|
||||
|
||||
typedef uint8 bool8;
|
||||
typedef uint16 bool16;
|
||||
typedef uint32 bool32;
|
||||
|
||||
#if defined(_MSC_VER) || defined (__MWERKS__)
|
||||
typedef ptrdiff_t ssize_t;
|
||||
#endif
|
||||
|
||||
#ifndef nil
|
||||
#define nil NULL
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef PED_SKIN
|
||||
#include <rphanim.h>
|
||||
#include <rpskin.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define TYPEALIGN(n) __attribute__ ((aligned (n)))
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#define TYPEALIGN(n) __declspec(align(n))
|
||||
#else
|
||||
#define TYPEALIGN(n) // unknown compiler...ignore
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ALIGNPTR(p) (void*)((((uintptr)(void*)p) + sizeof(void*)-1) & ~(sizeof(void*)-1))
|
||||
|
||||
// PDP-10 like byte functions
|
||||
#define MASK(p, s) (((1<<(s))-1) << (p))
|
||||
inline uint32 dpb(uint32 b, uint32 p, uint32 s, uint32 w)
|
||||
{
|
||||
uint32 m = MASK(p,s);
|
||||
return (w & ~m) | ((b<<p) & m);
|
||||
}
|
||||
inline uint32 ldb(uint32 p, uint32 s, uint32 w)
|
||||
{
|
||||
return w>>p & (1<<s)-1;
|
||||
}
|
||||
|
||||
#include "skeleton.h"
|
||||
#include "Draw.h"
|
||||
|
||||
#if defined(PROPER_SCALING) || defined(PS2_HUD)
|
||||
#ifdef FORCE_PC_SCALING
|
||||
#define DEFAULT_SCREEN_WIDTH (640)
|
||||
#define DEFAULT_SCREEN_HEIGHT (448)
|
||||
#else
|
||||
#define DEFAULT_SCREEN_WIDTH (640)
|
||||
#define DEFAULT_SCREEN_HEIGHT (480)
|
||||
#endif
|
||||
#elif defined(GTA_PS2)
|
||||
#define DEFAULT_SCREEN_WIDTH (640)
|
||||
#define DEFAULT_SCREEN_HEIGHT (480)
|
||||
#else //elif defined(GTA_PC)
|
||||
#define DEFAULT_SCREEN_WIDTH (640)
|
||||
#define DEFAULT_SCREEN_HEIGHT (448)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_ASPECT_RATIO (4.0f/3.0f)
|
||||
#define DEFAULT_VIEWWINDOW (0.7f)
|
||||
|
||||
// game uses maximumWidth/Height, but this probably won't work
|
||||
// with RW windowed mode
|
||||
#ifdef GTA_PS2
|
||||
#ifdef GTA_PAL
|
||||
#define SCREEN_WIDTH ((float)640)
|
||||
#define SCREEN_HEIGHT ((float)512)
|
||||
#else
|
||||
#define SCREEN_WIDTH ((float)640)
|
||||
#define SCREEN_HEIGHT ((float)448)
|
||||
#endif
|
||||
#else
|
||||
#define SCREEN_WIDTH ((float)RsGlobal.width)
|
||||
#define SCREEN_HEIGHT ((float)RsGlobal.height)
|
||||
#endif
|
||||
|
||||
#define SCREEN_HEIGHT_PAL ((float)512)
|
||||
#define SCREEN_HEIGHT_NTSC ((float)448)
|
||||
|
||||
#define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio())
|
||||
#define SCREEN_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetScaledFOV() * 0.5f)))
|
||||
|
||||
// This scales from PS2 pixel coordinates to the real resolution
|
||||
#define SCREEN_STRETCH_X(a) ((a) * (float) SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH)
|
||||
#define SCREEN_STRETCH_Y(a) ((a) * (float) SCREEN_HEIGHT / DEFAULT_SCREEN_HEIGHT)
|
||||
#define SCREEN_STRETCH_FROM_RIGHT(a) (SCREEN_WIDTH - SCREEN_STRETCH_X(a))
|
||||
#define SCREEN_STRETCH_FROM_BOTTOM(a) (SCREEN_HEIGHT - SCREEN_STRETCH_Y(a))
|
||||
|
||||
// This scales from PS2 pixel coordinates while optionally maintaining the aspect ratio
|
||||
#define SCREEN_SCALE_X(a) SCREEN_SCALE_AR(SCREEN_STRETCH_X(a))
|
||||
#define SCREEN_SCALE_Y(a) SCREEN_STRETCH_Y(a)
|
||||
#define SCREEN_SCALE_FROM_RIGHT(a) (SCREEN_WIDTH - SCREEN_SCALE_X(a))
|
||||
#define SCREEN_SCALE_FROM_BOTTOM(a) (SCREEN_HEIGHT - SCREEN_SCALE_Y(a))
|
||||
|
||||
#ifdef ASPECT_RATIO_SCALE
|
||||
#define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO)
|
||||
#define SCALE_AND_CENTER_X(x) ((SCREEN_WIDTH == DEFAULT_SCREEN_WIDTH) ? (x) : (SCREEN_WIDTH - SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)) / 2 + SCREEN_SCALE_X((x)))
|
||||
#ifdef PROPER_SCALING
|
||||
#ifndef FORCE_PC_SCALING
|
||||
#undef SCREEN_SCALE_Y
|
||||
#define SCREEN_SCALE_Y(a) CDraw::ScaleY(SCREEN_STRETCH_Y(a))
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define SCREEN_SCALE_AR(a) (a)
|
||||
#define SCALE_AND_CENTER_X(x) SCREEN_STRETCH_X(x)
|
||||
#endif
|
||||
|
||||
#include "maths.h"
|
||||
#include "Vector.h"
|
||||
#ifdef GTA_PS2
|
||||
#include "VuVector.h"
|
||||
#define CVUVECTOR CVuVector
|
||||
#else
|
||||
#define CVUVECTOR CVector
|
||||
#endif
|
||||
#include "Vector2D.h"
|
||||
#include "Matrix.h"
|
||||
#include "Rect.h"
|
||||
|
||||
class CRGBA
|
||||
{
|
||||
public:
|
||||
union
|
||||
{
|
||||
uint32 color32;
|
||||
struct { uint8 r, g, b, a; };
|
||||
struct { uint8 red, green, blue, alpha; };
|
||||
#ifdef RWCORE_H
|
||||
struct { RwRGBA rwRGBA; };
|
||||
#endif
|
||||
};
|
||||
|
||||
CRGBA(void) { }
|
||||
CRGBA(uint8 r, uint8 g, uint8 b, uint8 a) : r(r), g(g), b(b), a(a) { }
|
||||
|
||||
bool operator ==(const CRGBA &right)
|
||||
{
|
||||
return this->r == right.r && this->g == right.g && this->b == right.b && this->a == right.a;
|
||||
}
|
||||
|
||||
bool operator !=(const CRGBA &right)
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
CRGBA &operator =(const CRGBA &right)
|
||||
{
|
||||
this->r = right.r;
|
||||
this->g = right.g;
|
||||
this->b = right.b;
|
||||
this->a = right.a;
|
||||
return *this;
|
||||
}
|
||||
#ifdef RWCORE_H
|
||||
operator RwRGBA &(void) {
|
||||
return rwRGBA;
|
||||
}
|
||||
|
||||
operator RwRGBA *(void) {
|
||||
return &rwRGBA;
|
||||
}
|
||||
|
||||
operator RwRGBA (void) const {
|
||||
return rwRGBA;
|
||||
}
|
||||
|
||||
CRGBA &operator =(const RwRGBA &right)
|
||||
{
|
||||
this->r = right.red;
|
||||
this->g = right.green;
|
||||
this->b = right.blue;
|
||||
this->a = right.alpha;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#if (defined(_MSC_VER))
|
||||
extern int strcasecmp(const char *str1, const char *str2);
|
||||
#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) ? Min(v, center + radius) : Max(v, center - radius))
|
||||
|
||||
inline float sq(float x) { return x*x; }
|
||||
#define SQR(x) ((x) * (x))
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#define M_E 2.71828182845904523536 // e
|
||||
#define M_LOG2E 1.44269504088896340736 // log2(e)
|
||||
#define M_LOG10E 0.434294481903251827651 // log10(e)
|
||||
#define M_LN2 0.693147180559945309417 // ln(2)
|
||||
#define M_LN10 2.30258509299404568402 // ln(10)
|
||||
#define M_PI 3.14159265358979323846 // pi
|
||||
#define M_PI_2 1.57079632679489661923 // pi/2
|
||||
#define M_PI_4 0.785398163397448309616 // pi/4
|
||||
#define M_1_PI 0.318309886183790671538 // 1/pi
|
||||
#define M_2_PI 0.636619772367581343076 // 2/pi
|
||||
#define M_2_SQRTPI 1.12837916709551257390 // 2/sqrt(pi)
|
||||
#define M_SQRT2 1.41421356237309504880 // sqrt(2)
|
||||
#define M_SQRT1_2 0.707106781186547524401 // 1/sqrt(2)
|
||||
#endif
|
||||
|
||||
#define PI (float)M_PI
|
||||
#define TWOPI (PI*2)
|
||||
#define HALFPI (PI/2)
|
||||
#define DEGTORAD(x) ((x) * PI / 180.0f)
|
||||
#define RADTODEG(x) ((x) * 180.0f / PI)
|
||||
|
||||
#ifdef USE_PS2_RAND
|
||||
#define MYRAND_MAX 65535
|
||||
#else
|
||||
#define MYRAND_MAX 32767
|
||||
#endif
|
||||
|
||||
int myrand(void);
|
||||
void mysrand(unsigned int seed);
|
||||
|
||||
void re3_debug(const char *format, ...);
|
||||
void re3_trace(const char *filename, unsigned int lineno, const char *func, const char *format, ...);
|
||||
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func);
|
||||
void re3_usererror(const char *format, ...);
|
||||
|
||||
#define DEBUGBREAK() __debugbreak();
|
||||
|
||||
// Switch to enable development messages.
|
||||
#if 1
|
||||
#define DEV(f, ...)
|
||||
#else
|
||||
#define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
void debug(char *f, ...);
|
||||
void Error(char *f, ...);
|
||||
__inline__ void TRACE(char *f, ...) { } // this is re3 only, and so the function needs to be inline - this way no call actually gets placed
|
||||
// USERERROR only gets used in oal builds ... once
|
||||
#else
|
||||
#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__)
|
||||
#define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__)
|
||||
#ifndef MASTER
|
||||
#define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__)
|
||||
#define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__)
|
||||
#else
|
||||
#define TRACE(f, ...)
|
||||
#define USERERROR(f, ...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MASTER
|
||||
#define assert(_Expression) (void)( (!!(_Expression)) || (re3_assert(#_Expression, __FILE__, __LINE__, __FUNCTION__), 0) )
|
||||
#else
|
||||
#define assert(_Expression) (_Expression)
|
||||
#endif
|
||||
#define ASSERT assert
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#define static_assert(bool_constexpr, message)
|
||||
#endif
|
||||
|
||||
#define _TODO(x)
|
||||
#define _TODOCONST(x) (x)
|
||||
|
||||
#ifdef CHECK_STRUCT_SIZES
|
||||
template<int s, int t> struct check_size {
|
||||
static_assert(s == t, "Invalid structure size");
|
||||
};
|
||||
#define VALIDATE_SIZE(struc, size) check_size<sizeof(struc), size> struc ## Check
|
||||
#else
|
||||
#define VALIDATE_SIZE(struc, size)
|
||||
#endif
|
||||
#define VALIDATE_OFFSET(struc, member, offset) static_assert(offsetof(struc, member) == offset, "The offset of " #member " in " #struc " is not " #offset "...")
|
||||
|
||||
#define PERCENT(x, p) ((float(x) * (float(p) / 100.0f)))
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||
#define BIT(num) (1<<(num))
|
||||
|
||||
#define ABS(a) (((a) < 0) ? (-(a)) : (a))
|
||||
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min)))))
|
||||
#define lerp(norm, min, max) ( (norm) * ((max) - (min)) + (min) )
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define STR(x) STRINGIFY(x)
|
||||
#define CONCAT_(x,y) x##y
|
||||
#define CONCAT(x,y) CONCAT_(x,y)
|
||||
498
src/core/config.h
Normal file
498
src/core/config.h
Normal file
|
|
@ -0,0 +1,498 @@
|
|||
#pragma once
|
||||
|
||||
// disables (most) stuff that wasn't in original gta3.exe
|
||||
#ifdef __MWERKS__
|
||||
#define VANILLA_DEFINES
|
||||
#endif
|
||||
|
||||
enum Config {
|
||||
NUMPLAYERS = 1, // 4 on PS2
|
||||
|
||||
NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC)
|
||||
MAX_CDIMAGES = 8, // additional cdimages
|
||||
MAX_CDCHANNELS = 5,
|
||||
|
||||
MODELINFOSIZE = 5500, // 3150 on PS2
|
||||
#ifdef VANILLA_DEFINES
|
||||
TXDSTORESIZE = 850,
|
||||
#else
|
||||
TXDSTORESIZE = 1024, // for Xbox map
|
||||
#endif
|
||||
EXTRADIRSIZE = 128,
|
||||
CUTSCENEDIRSIZE = 512,
|
||||
|
||||
SIMPLEMODELSIZE = 5000, // 2910 on PS2
|
||||
MLOMODELSIZE = 1,
|
||||
MLOINSTANCESIZE = 1,
|
||||
TIMEMODELSIZE = 30,
|
||||
CLUMPMODELSIZE = 5,
|
||||
PEDMODELSIZE = 90,
|
||||
VEHICLEMODELSIZE = 120, // 70 on PS2
|
||||
XTRACOMPSMODELSIZE = 2,
|
||||
TWODFXSIZE = 2000, // 1210 on PS2
|
||||
|
||||
MAXVEHICLESLOADED = 50, // 70 on mobile
|
||||
|
||||
NUMOBJECTINFO = 168, // object.dat
|
||||
|
||||
// Pool sizes
|
||||
NUMPTRNODES = 30000, // 26000 on PS2
|
||||
NUMENTRYINFOS = 5400, // 3200 on PS2
|
||||
NUMPEDS = 140, // 90 on PS2
|
||||
NUMVEHICLES = 110, // 70 on PS2
|
||||
NUMBUILDINGS = 5500, // 4915 on PS2
|
||||
NUMTREADABLES = 1214,
|
||||
NUMOBJECTS = 450,
|
||||
NUMDUMMIES = 2802, // 2368 on PS2
|
||||
NUMAUDIOSCRIPTOBJECTS = 256,
|
||||
NUMCUTSCENEOBJECTS = 50,
|
||||
|
||||
NUMANIMBLOCKS = 2,
|
||||
NUMANIMATIONS = 250,
|
||||
|
||||
NUMTEMPOBJECTS = 30,
|
||||
|
||||
// Path data
|
||||
NUM_PATHNODES = 4930,
|
||||
NUM_CARPATHLINKS = 2076,
|
||||
NUM_MAPOBJECTS = 1250,
|
||||
NUM_PATHCONNECTIONS = 10260,
|
||||
|
||||
// Link list lengths
|
||||
NUMALPHALIST = 20,
|
||||
NUMALPHAENTITYLIST = 150,
|
||||
NUMCOLCACHELINKS = 200,
|
||||
NUMREFERENCES = 800,
|
||||
|
||||
// Zones
|
||||
NUMAUDIOZONES = 36,
|
||||
NUMZONES = 50,
|
||||
NUMMAPZONES = 25,
|
||||
|
||||
// Cull zones
|
||||
NUMCULLZONES = 512,
|
||||
NUMATTRIBZONES = 288,
|
||||
NUMZONEINDICES = 55000,
|
||||
|
||||
PATHNODESIZE = 4500,
|
||||
|
||||
NUMWEATHERS = 4,
|
||||
NUMHOURS = 24,
|
||||
|
||||
NUMEXTRADIRECTIONALS = 4,
|
||||
NUMANTENNAS = 8,
|
||||
NUMCORONAS = 56,
|
||||
NUMPOINTLIGHTS = 32,
|
||||
NUM3DMARKERS = 32,
|
||||
NUMBRIGHTLIGHTS = 32,
|
||||
NUMSHINYTEXTS = 32,
|
||||
NUMMONEYMESSAGES = 16,
|
||||
NUMPICKUPMESSAGES = 16,
|
||||
NUMBULLETTRACES = 16,
|
||||
NUMMBLURSTREAKS = 4,
|
||||
NUMSKIDMARKS = 32,
|
||||
|
||||
NUMONSCREENTIMERENTRIES = 1,
|
||||
NUMRADARBLIPS = 32,
|
||||
NUMGENERALPICKUPS = 320,
|
||||
NUMSCRIPTEDPICKUPS = 16,
|
||||
NUMPICKUPS = NUMGENERALPICKUPS + NUMSCRIPTEDPICKUPS,
|
||||
NUMCOLLECTEDPICKUPS = 20,
|
||||
NUMPACMANPICKUPS = 256,
|
||||
NUMEVENTS = 64,
|
||||
|
||||
NUM_CARGENS = 160,
|
||||
|
||||
NUM_PATH_NODES_IN_AUTOPILOT = 8,
|
||||
|
||||
NUM_ACCIDENTS = 20,
|
||||
NUM_FIRES = 40,
|
||||
NUM_GARAGES = 32,
|
||||
NUM_PROJECTILES = 32,
|
||||
|
||||
NUM_GLASSPANES = 45,
|
||||
NUM_GLASSENTITIES = 32,
|
||||
NUM_WATERCANNONS = 3,
|
||||
|
||||
NUMPEDROUTES = 200,
|
||||
NUMPHONES = 50,
|
||||
NUMPEDGROUPS = 31,
|
||||
NUMMODELSPERPEDGROUP = 8,
|
||||
NUMSHOTINFOS = 100,
|
||||
|
||||
NUMROADBLOCKS = 600,
|
||||
|
||||
NUMVISIBLEENTITIES = 2000,
|
||||
NUMINVISIBLEENTITIES = 150,
|
||||
|
||||
NUM_AUDIOENTITY_EVENTS = 4,
|
||||
NUM_PED_COMMENTS_SLOTS = 20,
|
||||
|
||||
NUM_SOUND_QUEUES = 2,
|
||||
NUM_AUDIOENTITIES = 200,
|
||||
|
||||
NUM_SCRIPT_MAX_ENTITIES = 40,
|
||||
|
||||
NUM_GARAGE_STORED_CARS = 6,
|
||||
|
||||
NUM_CRANES = 8,
|
||||
|
||||
NUM_EXPLOSIONS = 48,
|
||||
};
|
||||
|
||||
// We don't expect to compile for PS2 or Xbox
|
||||
// but it might be interesting for documentation purposes
|
||||
#define GTA_PC
|
||||
//#define GTA_PS2
|
||||
//#define GTA_XBOX
|
||||
|
||||
// Version defines
|
||||
#define GTA3_PS2_140 300
|
||||
#define GTA3_PS2_160 301
|
||||
#define GTA3_PC_10 310
|
||||
#define GTA3_PC_11 311
|
||||
#define GTA3_PC_STEAM 312
|
||||
// TODO? maybe something for xbox or android?
|
||||
|
||||
#define GTA_VERSION GTA3_PC_11
|
||||
|
||||
// Enable configuration for handheld console ports
|
||||
#if defined(__SWITCH__) || defined(PSP2)
|
||||
#define GTA_HANDHELD
|
||||
#endif
|
||||
|
||||
#if defined GTA_PS2
|
||||
# define GTA_PS2_STUFF
|
||||
# define RANDOMSPLASH
|
||||
# define USE_CUSTOM_ALLOCATOR
|
||||
# define VU_COLLISION
|
||||
# define ANIM_COMPRESSION
|
||||
# define PS2_MENU
|
||||
#elif defined GTA_PC
|
||||
# define EXTERNAL_3D_SOUND
|
||||
# define AUDIO_REFLECTIONS
|
||||
# ifndef GTA_HANDHELD
|
||||
# define PC_PLAYER_CONTROLS // mouse player/cam mode
|
||||
# endif
|
||||
# define GTA_REPLAY
|
||||
# define GTA_SCENE_EDIT
|
||||
# define PC_MENU
|
||||
#elif defined GTA_XBOX
|
||||
#endif
|
||||
|
||||
// This is enabled for all released games.
|
||||
// any debug stuff that isn't left in any game is not in FINAL
|
||||
//#define FINAL
|
||||
|
||||
// This is enabled for all released games except mobile
|
||||
// any debug stuff that is only left in mobile, is not in MASTER
|
||||
//#define MASTER
|
||||
|
||||
// once and for all:
|
||||
// pc: FINAL & MASTER
|
||||
// mobile: FINAL
|
||||
|
||||
// MASTER builds must be FINAL
|
||||
#ifdef MASTER
|
||||
#define FINAL
|
||||
#endif
|
||||
|
||||
// these are placed here to work with VANILLA_DEFINES for compatibility
|
||||
#define NO_CDCHECK // skip audio CD check
|
||||
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
|
||||
|
||||
#ifdef VANILLA_DEFINES
|
||||
#if !defined(_WIN32) || defined(__LP64__) || defined(_WIN64)
|
||||
#error Vanilla can only be built for win-x86
|
||||
#endif
|
||||
|
||||
#define FINAL
|
||||
#define MASTER
|
||||
//#define USE_MY_DOCUMENTS
|
||||
#define THIS_IS_STUPID
|
||||
#define PC_PARTICLE
|
||||
#define DONT_FIX_REPLAY_BUGS
|
||||
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
|
||||
//#define USE_TEXTURE_POOL // not possible because R* used custom RW33
|
||||
#else
|
||||
// This enables things from the PS2 version on PC
|
||||
#define GTA_PS2_STUFF
|
||||
|
||||
// quality of life fixes that should also be in FINAL
|
||||
#define NASTY_GAME // nasty game for all languages
|
||||
|
||||
// those infamous texts
|
||||
#define DRAW_GAME_VERSION_TEXT
|
||||
#ifdef DRAW_GAME_VERSION_TEXT
|
||||
// unlike R* development builds, ours has runtime switch on debug menu & .ini, and disabled as default.
|
||||
// If you disable this then game will fetch version from peds.col, as R* did while in development.
|
||||
//#define USE_OUR_VERSIONING // enabled from buildfiles by default
|
||||
#endif
|
||||
//#define DRAW_MENU_VERSION_TEXT
|
||||
|
||||
// Memory allocation and compression
|
||||
// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet
|
||||
//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
|
||||
//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
|
||||
|
||||
#if defined GTA_PC && defined GTA_PS2_STUFF
|
||||
# define USE_PS2_RAND
|
||||
# define RANDOMSPLASH // use random splash as on PS2
|
||||
# define PS2_MATFX
|
||||
#endif
|
||||
|
||||
#ifdef VU_COLLISION
|
||||
#define COMPRESSED_COL_VECTORS // currently need compressed vectors in this code
|
||||
#endif
|
||||
|
||||
#ifdef MASTER
|
||||
// only in master builds
|
||||
#undef DRAW_GAME_VERSION_TEXT
|
||||
#else
|
||||
// not in master builds
|
||||
#define VALIDATE_SAVE_SIZE
|
||||
|
||||
#define DEBUGMENU
|
||||
#endif
|
||||
|
||||
#ifdef FINAL
|
||||
// in all games
|
||||
# define USE_MY_DOCUMENTS // use my documents directory for user files
|
||||
#else
|
||||
// not in any game
|
||||
# define CHATTYSPLASH // print what the game is loading
|
||||
# define TIMEBARS // print debug timers
|
||||
#endif
|
||||
|
||||
#define FIX_BUGS // fixes bugs that we've came across during reversing. You can undefine this only on release builds.
|
||||
#define MORE_LANGUAGES // Add more translations to the game
|
||||
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible, and keeps saves compatible between platforms, needs to be enabled on 64bit builds!
|
||||
#define FIX_INCOMPATIBLE_SAVES // try to fix incompatible saves, requires COMPATIBLE_SAVES
|
||||
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
|
||||
|
||||
#define NO_MOVIES // add option to disable intro videos
|
||||
|
||||
#define EXTENDED_OFFSCREEN_DESPAWN_RANGE // Use onscreen despawn range for offscreen peds and vehicles to avoid them despawning in the distance when you look
|
||||
// away
|
||||
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build
|
||||
#endif
|
||||
|
||||
#define ASCII_STRCMP // use faster ascii str comparisons
|
||||
|
||||
#if !defined _WIN32 || defined __MINGW32__
|
||||
#undef ASCII_STRCMP
|
||||
#endif
|
||||
|
||||
// Just debug menu entries
|
||||
#ifdef DEBUGMENU
|
||||
#define MISSION_SWITCHER // from debug menu
|
||||
#endif
|
||||
|
||||
// Rendering/display
|
||||
//#define EXTRA_MODEL_FLAGS // from mobile to optimize rendering
|
||||
//# define HARDCODED_MODEL_FLAGS // sets the flags enabled above from hardcoded model names.
|
||||
// NB: keep this enabled unless your map IDEs have these flags baked in
|
||||
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios
|
||||
#define PROPER_SCALING // use original DEFAULT_SCREEN_WIDTH/DEFAULT_SCREEN_HEIGHT from PS2 instead of PC(R* changed HEIGHT here to make radar look better, but broke other hud elements aspect ratio).
|
||||
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
|
||||
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
|
||||
#define PS2_ALPHA_TEST // emulate ps2 alpha test
|
||||
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
|
||||
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
|
||||
#ifdef DISABLE_LOADING_SCREEN
|
||||
// enable the PC splash
|
||||
#undef RANDOMSPLASH
|
||||
#endif
|
||||
#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync
|
||||
#define ANISOTROPIC_FILTERING // set all textures to max anisotropic filtering
|
||||
//#define USE_TEXTURE_POOL
|
||||
#ifdef LIBRW
|
||||
#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
|
||||
#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
|
||||
#define SCREEN_DROPLETS // neo water droplets
|
||||
#define NEW_RENDERER // leeds-like world rendering, needs librw
|
||||
#endif
|
||||
|
||||
#define FIX_SPRITES // fix sprites aspect ratio(moon, coronas, particle etc)
|
||||
|
||||
#ifndef EXTENDED_COLOURFILTER
|
||||
#undef SCREEN_DROPLETS // we need the backbuffer for this effect
|
||||
#endif
|
||||
|
||||
// Particle
|
||||
//#define PC_PARTICLE
|
||||
//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
|
||||
|
||||
// Pad
|
||||
#if !defined(RW_GL3) && defined(_WIN32)
|
||||
#define XINPUT
|
||||
#endif
|
||||
#if defined XINPUT || (defined RW_GL3 && !defined LIBRW_SDL2 && !defined GTA_HANDHELD)
|
||||
#define DETECT_JOYSTICK_MENU // Then we'll expect user to enter Controller->Detect joysticks if his joystick isn't detected at the start.
|
||||
#endif
|
||||
#define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m
|
||||
#define KANGAROO_CHEAT
|
||||
#define ALLCARSHELI_CHEAT
|
||||
#define ALT_DODO_CHEAT
|
||||
#define REGISTER_START_BUTTON
|
||||
#define BIND_VEHICLE_FIREWEAPON // Adds ability to rebind fire key for 'in vehicle' controls
|
||||
#define BUTTON_ICONS // use textures to show controller buttons
|
||||
|
||||
// Hud, frontend and radar
|
||||
//#define PS2_HUD
|
||||
#define HUD_ENHANCEMENTS // Adjusts some aspects to make the HUD look/behave a little bit better.
|
||||
// #define BETA_SLIDING_TEXT
|
||||
#define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC
|
||||
#define FIX_RADAR // use radar size from early version before R* broke it
|
||||
// #define XBOX_SUBTITLES // the infamous outlines
|
||||
#define RADIO_OFF_TEXT
|
||||
#define PC_MENU
|
||||
|
||||
#ifndef PC_MENU
|
||||
# define PS2_MENU
|
||||
//# define PS2_MENU_USEALLPAGEICONS
|
||||
#else
|
||||
|
||||
# if defined(XINPUT) || defined(GTA_HANDHELD)
|
||||
# define GAMEPAD_MENU // Add gamepad menu
|
||||
# endif
|
||||
|
||||
# define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
|
||||
# define TRIANGLE_BACK_BUTTON
|
||||
//# define CIRCLE_BACK_BUTTON
|
||||
//# define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
|
||||
//# define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box
|
||||
# define CUSTOM_FRONTEND_OPTIONS
|
||||
|
||||
# ifdef CUSTOM_FRONTEND_OPTIONS
|
||||
# define MENU_MAP // VC-like menu map. Won't appear if you don't have our menu.txd
|
||||
# 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 // add bInvertLook4Pad from VC
|
||||
# define PED_CAR_DENSITY_SLIDERS
|
||||
# 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
|
||||
#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 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
|
||||
|
||||
#if SCRIPT_LOG_FILE_LEVEL == 0
|
||||
#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
|
||||
#endif
|
||||
|
||||
#ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
|
||||
#define USE_BASIC_SCRIPT_DEBUG_OUTPUT
|
||||
#endif
|
||||
|
||||
#ifdef MASTER
|
||||
#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
|
||||
#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
|
||||
#endif
|
||||
|
||||
// Replay
|
||||
//#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool!
|
||||
//#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!)
|
||||
|
||||
// Vehicles
|
||||
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
|
||||
//#define REMOVE_TREADABLE_PATHFIND
|
||||
|
||||
// Pickups
|
||||
//#define MONEY_MESSAGES
|
||||
#define CAMERA_PICKUP
|
||||
|
||||
// Peds
|
||||
#define PED_SKIN // support for skinned geometry on peds, requires COMPATIBLE_SAVES
|
||||
#define ANIMATE_PED_COL_MODEL
|
||||
// #define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
|
||||
// #define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
|
||||
#define CANCELLABLE_CAR_ENTER
|
||||
//#define PEDS_REPORT_CRIMES_ON_PHONE // requires COMPATIBLE_SAVES
|
||||
|
||||
// Camera
|
||||
//#define PS2_CAM_TRANSITION // old way of transitioning between cam modes
|
||||
#define IMPROVED_CAMERA // Better Debug cam, and maybe more in the future
|
||||
#define FREE_CAM // Rotating cam
|
||||
|
||||
// Audio
|
||||
#define EXTERNAL_3D_SOUND // use external engine to simulate 3d audio spatialization. OpenAL would not work without it (because it works in a 3d space
|
||||
// originally and making it work in 2d only requires more resource). Will not work on PS2
|
||||
#define AUDIO_REFLECTIONS // Enable audio reflections. Disabled on mobile, didn't exist yet on PS2.
|
||||
#define RADIO_SCROLL_TO_PREV_STATION
|
||||
#define AUDIO_CACHE
|
||||
#define PS2_AUDIO_CHANNELS // increases the maximum number of audio channels to PS2 value of 44 (PC has 28 originally)
|
||||
#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
|
||||
//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
|
||||
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files
|
||||
#define PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused
|
||||
#define ATTACH_RELEASING_SOUNDS_TO_ENTITIES // sounds would follow ped and vehicles coordinates if not being queued otherwise
|
||||
#define USE_TIME_SCALE_FOR_AUDIO // slow down/speed up sounds according to the speed of the game
|
||||
#define MULTITHREADED_AUDIO // for streams. requires C++11 or later
|
||||
|
||||
#ifdef AUDIO_OPUS
|
||||
#define AUDIO_OAL_USE_OPUS // enable support of opus files
|
||||
#define OPUS_AUDIO_PATHS // changes audio paths to opus paths (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
|
||||
#define OPUS_SFX // enable if your sfx.raw is encoded with opus (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
|
||||
|
||||
#ifndef AUDIO_OAL_USE_OPUS
|
||||
#undef OPUS_AUDIO_PATHS
|
||||
#undef OPUS_SFX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Streaming
|
||||
#if !defined(_WIN32) && !defined(__SWITCH__)
|
||||
//#define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash - also not utilized too much right now(see commented LoadAllRequestedModels in Streaming.cpp)
|
||||
#define FLUSHABLE_STREAMING // Make it possible to interrupt reading when processing file isn't needed anymore.
|
||||
#endif
|
||||
#define BIG_IMG // Not complete - allows to read larger img files
|
||||
|
||||
//#define SQUEEZE_PERFORMANCE
|
||||
#ifdef SQUEEZE_PERFORMANCE
|
||||
#undef PS2_ALPHA_TEST
|
||||
#undef NO_ISLAND_LOADING
|
||||
#undef PS2_AUDIO_CHANNELS
|
||||
#undef EXTENDED_OFFSCREEN_DESPAWN_RANGE
|
||||
#define PC_PARTICLE
|
||||
#define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
|
||||
#define VC_RAIN_NERF // Reduces number of rain particles
|
||||
#endif
|
||||
|
||||
// if these defines are enabled saves are not vanilla compatible without COMPATIBLE_SAVES
|
||||
#ifndef COMPATIBLE_SAVES
|
||||
#undef PED_SKIN
|
||||
#undef PEDS_REPORT_CRIMES_ON_PHONE
|
||||
#endif
|
||||
|
||||
#ifdef GTA_HANDHELD
|
||||
#define IGNORE_MOUSE_KEYBOARD // ignore mouse & keyboard input
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#define USE_UNNAMED_SEM // named semaphores are unsupported on the switch
|
||||
#endif
|
||||
|
||||
#endif // VANILLA_DEFINES
|
||||
|
||||
#if defined(AUDIO_OAL) && !defined(EXTERNAL_3D_SOUND)
|
||||
#error AUDIO_OAL cannot work without EXTERNAL_3D_SOUND
|
||||
#endif
|
||||
#if defined(GTA_PS2) && defined(EXTERNAL_3D_SOUND)
|
||||
#error EXTERNAL_3D_SOUND cannot work on PS2
|
||||
#endif
|
||||
#if defined(AUDIO_REFLECTIONS) && GTA_VERSION < GTA3_PC_10
|
||||
#error AUDIO_REFLECTIONS cannot work with versions below GTA3_PC_10
|
||||
#endif
|
||||
2493
src/core/main.cpp
Normal file
2493
src/core/main.cpp
Normal file
File diff suppressed because it is too large
Load diff
76
src/core/main.h
Normal file
76
src/core/main.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef FINAL
|
||||
// defined in RwHelpder.cpp
|
||||
void PushRendergroup(const char *name);
|
||||
void PopRendergroup(void);
|
||||
#define PUSH_RENDERGROUP(str) PushRendergroup(str)
|
||||
#define POP_RENDERGROUP() PopRendergroup()
|
||||
#else
|
||||
#define PUSH_RENDERGROUP(str)
|
||||
#define POP_RENDERGROUP()
|
||||
#endif
|
||||
|
||||
struct GlobalScene
|
||||
{
|
||||
RpWorld *world;
|
||||
RwCamera *camera;
|
||||
};
|
||||
extern GlobalScene Scene;
|
||||
|
||||
extern uint8 work_buff[55000];
|
||||
extern char gString[256];
|
||||
extern char gString2[512];
|
||||
extern wchar gUString[256];
|
||||
extern wchar gUString2[256];
|
||||
extern bool gbPrintShite;
|
||||
extern bool gbModelViewer;
|
||||
#ifdef TIMEBARS
|
||||
extern bool gbShowTimebars;
|
||||
#else
|
||||
#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);
|
||||
CSprite2d *LoadSplash(const char *name);
|
||||
void DestroySplashScreen(void);
|
||||
Const char *GetLevelSplashScreen(int level);
|
||||
Const char *GetRandomSplashScreen(void);
|
||||
void LittleTest(void);
|
||||
void ValidateVersion();
|
||||
void ResetLoadingScreenBar(void);
|
||||
#ifndef MASTER
|
||||
void TheModelViewer(void);
|
||||
#endif
|
||||
|
||||
#ifdef LOAD_INI_SETTINGS
|
||||
bool LoadINISettings();
|
||||
void SaveINISettings();
|
||||
void LoadINIControllerSettings();
|
||||
void SaveINIControllerSettings();
|
||||
#endif
|
||||
|
||||
#ifdef NEW_RENDERER
|
||||
extern bool gbNewRenderer;
|
||||
bool FredIsInFirstPersonCam(void);
|
||||
#endif
|
||||
|
||||
#ifdef DRAW_GAME_VERSION_TEXT
|
||||
extern bool gbDrawVersionText;
|
||||
#endif
|
||||
|
||||
#ifdef NO_MOVIES
|
||||
extern bool gbNoMovies;
|
||||
#endif
|
||||
119
src/core/obrstr.cpp
Normal file
119
src/core/obrstr.cpp
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#include "common.h"
|
||||
#include "Debug.h"
|
||||
#include "obrstr.h"
|
||||
|
||||
char obrstr[128];
|
||||
char obrstr2[128];
|
||||
|
||||
void ObrInt(int32 n1)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt2(int32 n1, int32 n2)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt3(int32 n1, int32 n2, int32 n3)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n5, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
|
||||
{
|
||||
IntToStr(n1, obrstr);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n2, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n3, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n4, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n5, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
strcat(obrstr, " ");
|
||||
IntToStr(n6, obrstr2);
|
||||
strcat(obrstr, obrstr2);
|
||||
CDebug::DebugAddText(obrstr);
|
||||
}
|
||||
|
||||
void IntToStr(int32 inNum, char *outStr)
|
||||
{
|
||||
bool isNeg = inNum < 0;
|
||||
|
||||
if (isNeg) {
|
||||
inNum = -inNum;
|
||||
*outStr = '-';
|
||||
}
|
||||
|
||||
int16 digits = 1;
|
||||
|
||||
if (inNum > 9) {
|
||||
int32 _inNum = inNum;
|
||||
do {
|
||||
digits++;
|
||||
_inNum /= 10;
|
||||
} while (_inNum > 9);
|
||||
}
|
||||
|
||||
int32 strSize = digits;
|
||||
if (isNeg)
|
||||
strSize++;
|
||||
|
||||
char *pStr = &outStr[strSize];
|
||||
int32 i = 0;
|
||||
do {
|
||||
*(pStr-- - 1) = (inNum % 10) + '0';
|
||||
inNum /= 10;
|
||||
} while (++i < strSize);
|
||||
outStr[strSize] = '\0';
|
||||
}
|
||||
9
src/core/obrstr.h
Normal file
9
src/core/obrstr.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
void ObrInt(int32 n1);
|
||||
void ObrInt2(int32 n1, int32 n2);
|
||||
void ObrInt3(int32 n1, int32 n2, int32 n3);
|
||||
void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4);
|
||||
void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5);
|
||||
void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
|
||||
void IntToStr(int32 inNum, char *outStr);
|
||||
1233
src/core/re3.cpp
Normal file
1233
src/core/re3.cpp
Normal file
File diff suppressed because it is too large
Load diff
269
src/core/templates.h
Normal file
269
src/core/templates.h
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
#pragma once
|
||||
|
||||
template<typename T, int32 n>
|
||||
class CStore
|
||||
{
|
||||
public:
|
||||
int32 allocPtr;
|
||||
T store[n];
|
||||
|
||||
T *Alloc(void){
|
||||
if(allocPtr >= n){
|
||||
printf("Size of this thing:%d needs increasing\n", n);
|
||||
assert(0);
|
||||
}
|
||||
return &store[allocPtr++];
|
||||
}
|
||||
void Clear(void){
|
||||
allocPtr = 0;
|
||||
}
|
||||
int32 GetIndex(T *item){
|
||||
assert(item >= &store[0]);
|
||||
assert(item < &store[n]);
|
||||
return item - store;
|
||||
}
|
||||
T *GetItem(int32 index){
|
||||
assert(index >= 0);
|
||||
assert(index < n);
|
||||
return &store[index];
|
||||
}
|
||||
};
|
||||
|
||||
#define POOLFLAG_ID 0x7f
|
||||
#define POOLFLAG_ISFREE 0x80
|
||||
|
||||
template<typename T, typename U = T>
|
||||
class CPool
|
||||
{
|
||||
U *m_entries;
|
||||
uint8 *m_flags;
|
||||
int32 m_size;
|
||||
int32 m_allocPtr;
|
||||
|
||||
public:
|
||||
CPool(int32 size){
|
||||
m_entries = (U*)new uint8[sizeof(U)*size];
|
||||
m_flags = new uint8[size];
|
||||
m_size = size;
|
||||
m_allocPtr = 0;
|
||||
for(int i = 0; i < size; i++){
|
||||
SetId(i, 0);
|
||||
SetIsFree(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
int GetId(int i) const
|
||||
{
|
||||
return m_flags[i] & POOLFLAG_ID;
|
||||
}
|
||||
|
||||
bool GetIsFree(int i) const
|
||||
{
|
||||
return !!(m_flags[i] & POOLFLAG_ISFREE);
|
||||
}
|
||||
|
||||
void SetId(int i, int id)
|
||||
{
|
||||
m_flags[i] = (m_flags[i] & POOLFLAG_ISFREE) | (id & POOLFLAG_ID);
|
||||
}
|
||||
|
||||
void SetIsFree(int i, bool isFree)
|
||||
{
|
||||
if (isFree)
|
||||
m_flags[i] |= POOLFLAG_ISFREE;
|
||||
else
|
||||
m_flags[i] &= ~POOLFLAG_ISFREE;
|
||||
}
|
||||
|
||||
~CPool() {
|
||||
Flush();
|
||||
}
|
||||
void Flush() {
|
||||
if (m_size > 0) {
|
||||
delete[] (uint8*)m_entries;
|
||||
delete[] m_flags;
|
||||
m_entries = nil;
|
||||
m_flags = nil;
|
||||
m_size = 0;
|
||||
m_allocPtr = 0;
|
||||
}
|
||||
}
|
||||
int32 GetSize(void) const { return m_size; }
|
||||
T *New(void){
|
||||
bool wrapped = false;
|
||||
do
|
||||
#ifdef FIX_BUGS
|
||||
if (++m_allocPtr >= m_size) {
|
||||
m_allocPtr = 0;
|
||||
if (wrapped)
|
||||
return nil;
|
||||
wrapped = true;
|
||||
}
|
||||
#else
|
||||
if(++m_allocPtr == m_size){
|
||||
if(wrapped)
|
||||
return nil;
|
||||
wrapped = true;
|
||||
m_allocPtr = 0;
|
||||
}
|
||||
#endif
|
||||
while(!GetIsFree(m_allocPtr));
|
||||
SetIsFree(m_allocPtr, false);
|
||||
SetId(m_allocPtr, GetId(m_allocPtr)+1);
|
||||
return (T*)&m_entries[m_allocPtr];
|
||||
}
|
||||
T *New(int32 handle){
|
||||
T *entry = (T*)&m_entries[handle>>8];
|
||||
SetNotFreeAt(handle);
|
||||
return entry;
|
||||
}
|
||||
void SetNotFreeAt(int32 handle){
|
||||
int idx = handle>>8;
|
||||
SetIsFree(idx, false);
|
||||
SetId(idx, handle & POOLFLAG_ID);
|
||||
for(m_allocPtr = 0; m_allocPtr < m_size; m_allocPtr++)
|
||||
if(GetIsFree(m_allocPtr))
|
||||
return;
|
||||
}
|
||||
void Delete(T *entry){
|
||||
int i = GetJustIndex(entry);
|
||||
SetIsFree(i, true);
|
||||
if(i < m_allocPtr)
|
||||
m_allocPtr = i;
|
||||
}
|
||||
T *GetSlot(int i){
|
||||
return GetIsFree(i) ? nil : (T*)&m_entries[i];
|
||||
}
|
||||
T *GetAt(int handle){
|
||||
#ifdef FIX_BUGS
|
||||
if (handle == -1)
|
||||
return nil;
|
||||
#endif
|
||||
return m_flags[handle>>8] == (handle & 0xFF) ?
|
||||
(T*)&m_entries[handle >> 8] : nil;
|
||||
}
|
||||
int32 GetIndex(T *entry){
|
||||
int i = GetJustIndex_NoFreeAssert(entry);
|
||||
return m_flags[i] + (i<<8);
|
||||
}
|
||||
int32 GetJustIndex(T *entry){
|
||||
int index = GetJustIndex_NoFreeAssert(entry);
|
||||
assert(!GetIsFree(index));
|
||||
return index;
|
||||
}
|
||||
int32 GetJustIndex_NoFreeAssert(T* entry){
|
||||
int index = ((U*)entry - m_entries);
|
||||
assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required
|
||||
return index;
|
||||
}
|
||||
int32 GetNoOfUsedSpaces(void) const{
|
||||
int i;
|
||||
int n = 0;
|
||||
for(i = 0; i < m_size; i++)
|
||||
if(!GetIsFree(i))
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
void ClearStorage(uint8 *&flags, U *&entries){
|
||||
delete[] flags;
|
||||
delete[] (uint8*)entries;
|
||||
flags = nil;
|
||||
entries = nil;
|
||||
}
|
||||
uint32 GetMaxEntrySize() const { return sizeof(U); }
|
||||
void CopyBack(uint8 *&flags, U *&entries){
|
||||
memcpy(m_flags, flags, sizeof(uint8)*m_size);
|
||||
memcpy(m_entries, entries, sizeof(U)*m_size);
|
||||
debug("Size copied:%d (%d)\n", sizeof(U)*m_size, m_size);
|
||||
m_allocPtr = 0;
|
||||
ClearStorage(flags, entries);
|
||||
debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
|
||||
}
|
||||
void Store(uint8 *&flags, U *&entries){
|
||||
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 */
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CLink
|
||||
{
|
||||
public:
|
||||
T item;
|
||||
CLink<T> *prev;
|
||||
CLink<T> *next;
|
||||
|
||||
void Insert(CLink<T> *link){
|
||||
link->next = this->next;
|
||||
this->next->prev = link;
|
||||
link->prev = this;
|
||||
this->next = link;
|
||||
}
|
||||
void Remove(void){
|
||||
this->prev->next = this->next;
|
||||
this->next->prev = this->prev;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CLinkList
|
||||
{
|
||||
public:
|
||||
CLink<T> head, tail;
|
||||
CLink<T> freeHead, freeTail;
|
||||
CLink<T> *links;
|
||||
|
||||
void Init(int n){
|
||||
links = new CLink<T>[n];
|
||||
head.next = &tail;
|
||||
tail.prev = &head;
|
||||
freeHead.next = &freeTail;
|
||||
freeTail.prev = &freeHead;
|
||||
while(n--)
|
||||
freeHead.Insert(&links[n]);
|
||||
}
|
||||
void Shutdown(void){
|
||||
delete[] links;
|
||||
links = nil;
|
||||
}
|
||||
void Clear(void){
|
||||
while(head.next != &tail)
|
||||
Remove(head.next);
|
||||
}
|
||||
CLink<T> *Insert(T const &item){
|
||||
CLink<T> *node = freeHead.next;
|
||||
if(node == &freeTail)
|
||||
return nil;
|
||||
node->item = item;
|
||||
node->Remove(); // remove from free list
|
||||
head.Insert(node);
|
||||
return node;
|
||||
}
|
||||
CLink<T> *InsertSorted(T const &item){
|
||||
CLink<T> *sort;
|
||||
for(sort = head.next; sort != &tail; sort = sort->next)
|
||||
if(sort->item.sort >= item.sort)
|
||||
break;
|
||||
CLink<T> *node = freeHead.next;
|
||||
if(node == &freeTail)
|
||||
return nil;
|
||||
node->item = item;
|
||||
node->Remove(); // remove from free list
|
||||
sort->prev->Insert(node);
|
||||
return node;
|
||||
}
|
||||
void Remove(CLink<T> *link){
|
||||
link->Remove(); // remove from list
|
||||
freeHead.Insert(link); // insert into free list
|
||||
}
|
||||
int32 Count(void){
|
||||
int n = 0;
|
||||
CLink<T> *lnk;
|
||||
for(lnk = head.next; lnk != &tail; lnk = lnk->next)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
121
src/core/timebars.cpp
Normal file
121
src/core/timebars.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
#include "common.h"
|
||||
#ifndef MASTER
|
||||
#include "Font.h"
|
||||
#include "Frontend.h"
|
||||
#include "Timer.h"
|
||||
#include "Text.h"
|
||||
|
||||
#define MAX_TIMERS (50)
|
||||
#define MAX_MS_COLLECTED (40)
|
||||
|
||||
// enables frame time output
|
||||
#define FRAMETIME
|
||||
|
||||
struct sTimeBar
|
||||
{
|
||||
char name[20];
|
||||
float startTime;
|
||||
float endTime;
|
||||
int32 unk;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
sTimeBar Timers[MAX_TIMERS];
|
||||
uint32 count;
|
||||
} TimerBar;
|
||||
float MaxTimes[MAX_TIMERS];
|
||||
float MaxFrameTime;
|
||||
|
||||
uint32 curMS;
|
||||
uint32 msCollected[MAX_MS_COLLECTED];
|
||||
#ifdef FRAMETIME
|
||||
float FrameInitTime;
|
||||
#endif
|
||||
|
||||
void tbInit()
|
||||
{
|
||||
TimerBar.count = 0;
|
||||
uint32 i = CTimer::GetFrameCounter() & 0x7F;
|
||||
if (i == 0) {
|
||||
do
|
||||
MaxTimes[i++] = 0.0f;
|
||||
while (i != MAX_TIMERS);
|
||||
#ifdef FRAMETIME
|
||||
MaxFrameTime = 0.0f;
|
||||
#endif
|
||||
}
|
||||
#ifdef FRAMETIME
|
||||
FrameInitTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tbStartTimer(int32 unk, Const char *name)
|
||||
{
|
||||
strcpy(TimerBar.Timers[TimerBar.count].name, name);
|
||||
TimerBar.Timers[TimerBar.count].unk = unk;
|
||||
TimerBar.Timers[TimerBar.count].startTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
TimerBar.count++;
|
||||
}
|
||||
|
||||
void tbEndTimer(Const char* name)
|
||||
{
|
||||
uint32 n = 1500;
|
||||
for (uint32 i = 0; i < TimerBar.count; i++) {
|
||||
if (strcmp(name, TimerBar.Timers[i].name) == 0)
|
||||
n = i;
|
||||
}
|
||||
assert(n != 1500);
|
||||
TimerBar.Timers[n].endTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
}
|
||||
|
||||
float Diag_GetFPS()
|
||||
{
|
||||
return 39000.0f / (msCollected[(curMS - 1) % MAX_MS_COLLECTED] - msCollected[curMS % MAX_MS_COLLECTED]);
|
||||
}
|
||||
|
||||
void tbDisplay()
|
||||
{
|
||||
char temp[200];
|
||||
wchar wtemp[200];
|
||||
|
||||
#ifdef FRAMETIME
|
||||
float FrameEndTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
|
||||
#endif
|
||||
|
||||
msCollected[(curMS++) % MAX_MS_COLLECTED] = RsTimer();
|
||||
CFont::SetBackgroundOff();
|
||||
CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
|
||||
CFont::SetScale(0.48f, 1.12f);
|
||||
CFont::SetCentreOff();
|
||||
CFont::SetJustifyOff();
|
||||
CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
|
||||
CFont::SetRightJustifyOff();
|
||||
CFont::SetPropOn();
|
||||
CFont::SetFontStyle(FONT_BANK);
|
||||
sprintf(temp, "FPS: %.2f", Diag_GetFPS());
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
CFont::SetColor(CRGBA(255, 255, 255, 255));
|
||||
if (!CMenuManager::m_PrefsMarketing || !CMenuManager::m_PrefsDisableTutorials) {
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * (4.0f / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
|
||||
#ifndef FINAL
|
||||
// Timers output (my own implementation)
|
||||
for (uint32 i = 0; i < TimerBar.count; i++) {
|
||||
MaxTimes[i] = Max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
|
||||
sprintf(temp, "%s: %.2f", &TimerBar.Timers[i].name[0], MaxTimes[i]);
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (i + 2)) / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
}
|
||||
|
||||
#ifdef FRAMETIME
|
||||
MaxFrameTime = Max(MaxFrameTime, FrameEndTime - FrameInitTime);
|
||||
sprintf(temp, "Frame Time: %.2f", MaxFrameTime);
|
||||
AsciiToUnicode(temp, wtemp);
|
||||
|
||||
CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (TimerBar.count + 4)) / DEFAULT_SCREEN_HEIGHT), wtemp);
|
||||
#endif // FRAMETIME
|
||||
#endif // !FINAL
|
||||
}
|
||||
}
|
||||
#endif // !MASTER
|
||||
13
src/core/timebars.h
Normal file
13
src/core/timebars.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef TIMEBARS
|
||||
void tbInit();
|
||||
void tbStartTimer(int32, Const char*);
|
||||
void tbEndTimer(Const char*);
|
||||
void tbDisplay();
|
||||
#else
|
||||
#define tbInit()
|
||||
#define tbStartTimer(a, b)
|
||||
#define tbEndTimer(a)
|
||||
#define tbDisplay()
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue