summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/Camera.cpp24
-rw-r--r--src/core/Camera.h23
-rw-r--r--src/core/CutsceneMgr.cpp417
-rw-r--r--src/core/CutsceneMgr.h29
-rw-r--r--src/core/Frontend.cpp2
-rw-r--r--src/core/General.h9
-rw-r--r--src/core/Pad.h1
-rw-r--r--src/core/PlayerInfo.cpp24
-rw-r--r--src/core/PlayerInfo.h1
-rw-r--r--src/core/PlayerSkin.cpp166
-rw-r--r--src/core/PlayerSkin.h16
-rw-r--r--src/core/Pools.cpp1
-rw-r--r--src/core/Pools.h1
-rw-r--r--src/core/Radar.cpp424
-rw-r--r--src/core/Radar.h38
-rw-r--r--src/core/Streaming.cpp17
-rw-r--r--src/core/TempColModels.cpp2
-rw-r--r--src/core/TempColModels.h2
-rw-r--r--src/core/World.h3
-rw-r--r--src/core/common.h4
-rw-r--r--src/core/config.h27
21 files changed, 1074 insertions, 157 deletions
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index cb16c3ad..775ab46a 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -22,7 +22,6 @@ WRAPPER void CCamera::CamShake(float strength, float x, float y, float z) { EAXJ
WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); }
WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); }
WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); }
-WRAPPER void CCamera::SetWidescreenOff(void) { EAXJMP(0x46FF10); }
WRAPPER void CamShakeNoPos(CCamera*, float) { EAXJMP(0x46B100); }
WRAPPER void CCamera::TakeControl(CEntity*, int16, int16, int32) { EAXJMP(0x471500); }
WRAPPER void CCamera::TakeControlNoEntity(const CVector&, int16, int32) { EAXJMP(0x4715B0); }
@@ -30,6 +29,10 @@ WRAPPER void CCamera::SetCamPositionForFixedMode(const CVector&, const CVector&)
WRAPPER void CCamera::Init(void) { EAXJMP(0x46BAD0); }
WRAPPER void CCamera::SetRwCamera(RwCamera*) { EAXJMP(0x46FEC0); }
WRAPPER void CCamera::Process(void) { EAXJMP(0x46D3F0); }
+WRAPPER void CCamera::LoadPathSplines(int file) { EAXJMP(0x46D1D0); }
+WRAPPER uint32 CCamera::GetCutSceneFinishTime(void) { EAXJMP(0x46B920); }
+WRAPPER void CCamera::FinishCutscene(void) { EAXJMP(0x46B560); }
+WRAPPER void CCamera::RestoreWithJumpCut(void) { EAXJMP(0x46FAE0); };
bool
CCamera::GetFading()
@@ -1327,6 +1330,25 @@ CCamera::Find3rdPersonQuickAimPitch(void)
return -(DEGTORAD(((0.5f - m_f3rdPersonCHairMultY) * 1.8f * 0.5f * Cams[ActiveCam].FOV)) + rot);
}
+void
+CCamera::SetCamCutSceneOffSet(const CVector &pos)
+{
+ m_vecCutSceneOffset = pos;
+};
+
+void
+CCamera::TakeControlWithSpline(short nSwitch)
+{
+ m_iModeToGoTo = CCam::MODE_FLYBY;
+ m_bLookingAtPlayer = false;
+ m_bLookingAtVector = false;
+ m_bcutsceneFinished = false;
+ m_iTypeOfSwitch = nSwitch;
+ m_bStartInterScript = true;
+
+ //FindPlayerPed(); // unused
+};
+
STARTPATCHES
InjectHook(0x42C760, (bool (CCamera::*)(const CVector &center, float radius, const CMatrix *mat))&CCamera::IsSphereVisible, PATCH_JUMP);
InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP);
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 1f38963b..0fd372c3 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -380,11 +380,11 @@ uint32 unknown;
CVector m_RealPreviousCameraPosition;
CVector m_cvecAimingTargetCoors;
CVector m_vecFixedModeVector;
+ CVector m_vecFixedModeSource;
+ CVector m_vecFixedModeUpOffSet;
+ CVector m_vecCutSceneOffset;
- // one of those has to go
- CVector m_vecFixedModeSource;
- CVector m_vecFixedModeUpOffSet;
-// CVector m_vecCutSceneOffset;
+ // one of those has to go
CVector m_cvecStartingSourceForInterPol;
CVector m_cvecStartingTargetForInterPol;
CVector m_cvecStartingUpForInterPol;
@@ -394,7 +394,7 @@ uint32 unknown;
CVector m_vecSourceWhenInterPol;
CVector m_vecTargetWhenInterPol;
CVector m_vecUpWhenInterPol;
- CVector m_vecClearGeometryVec;
+ //CVector m_vecClearGeometryVec;
CVector m_vecGameCamPos;
CVector SourceDuringInter;
@@ -444,6 +444,7 @@ int m_iModeObbeCamIsInForCar;
bool Get_Just_Switched_Status() { return m_bJust_Switched; }
inline const CMatrix& GetCameraMatrix(void) { return m_cameraMatrix; }
CVector &GetGameCamPosition(void) { return m_vecGameCamPos; }
+ float GetPositionAlongSpline(void) { return m_fPositionAlongSpline; }
bool IsPointVisible(const CVector &center, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius);
@@ -467,7 +468,8 @@ int m_iModeObbeCamIsInForCar;
void DrawBordersForWideScreen(void);
void Restore(void);
- void SetWidescreenOff(void);
+ void SetWideScreenOn(void) { m_WideScreenOn = true; }
+ void SetWideScreenOff(void) { m_WideScreenOn = false; }
float Find3rdPersonQuickAimPitch(void);
@@ -480,6 +482,14 @@ int m_iModeObbeCamIsInForCar;
void SetRwCamera(RwCamera*);
void Process();
+ void LoadPathSplines(int file);
+ uint32 GetCutSceneFinishTime(void);
+ void FinishCutscene(void);
+
+ void SetCamCutSceneOffSet(const CVector&);
+ void TakeControlWithSpline(short);
+ void RestoreWithJumpCut(void);
+
void dtor(void) { this->CCamera::~CCamera(); }
};
static_assert(offsetof(CCamera, m_WideScreenOn) == 0x70, "CCamera: error");
@@ -489,6 +499,7 @@ static_assert(offsetof(CCamera, m_uiTransitionState) == 0x89, "CCamera: error");
static_assert(offsetof(CCamera, m_uiTimeTransitionStart) == 0x94, "CCamera: error");
static_assert(offsetof(CCamera, m_BlurBlue) == 0x9C, "CCamera: error");
static_assert(offsetof(CCamera, Cams) == 0x1A4, "CCamera: error");
+static_assert(offsetof(CCamera, m_vecCutSceneOffset) == 0x6F8, "CCamera: error");
static_assert(sizeof(CCamera) == 0xE9D8, "CCamera: wrong size");
extern CCamera &TheCamera;
diff --git a/src/core/CutsceneMgr.cpp b/src/core/CutsceneMgr.cpp
index a54e8ff6..1461c858 100644
--- a/src/core/CutsceneMgr.cpp
+++ b/src/core/CutsceneMgr.cpp
@@ -1,8 +1,425 @@
#include "common.h"
#include "patcher.h"
#include "CutsceneMgr.h"
+#include "Directory.h"
+#include "Camera.h"
+#include "Streaming.h"
+#include "FileMgr.h"
+#include "main.h"
+#include "AnimManager.h"
+#include "AnimBlendAssocGroup.h"
+#include "AnimBlendClumpData.h"
+#include "Pad.h"
+#include "DMAudio.h"
+#include "World.h"
+#include "PlayerPed.h"
+#include "CutsceneHead.h"
+#include "RpAnimBlend.h"
+#include "ModelIndices.h"
+#include "TempColModels.h"
+#include "MusicManager.h"
+
+const struct {
+ const char *szTrackName;
+ int iTrackId;
+} musicNameIdAssoc[] = {
+ { "JB", STREAMED_SOUND_NEWS_INTRO },
+ { "BET", STREAMED_SOUND_BANK_INTRO },
+ { "L1_LG", STREAMED_SOUND_CUTSCENE_LUIGI1_LG },
+ { "L2_DSB", STREAMED_SOUND_CUTSCENE_LUIGI2_DSB },
+ { "L3_DM", STREAMED_SOUND_CUTSCENE_LUIGI3_DM },
+ { "L4_PAP", STREAMED_SOUND_CUTSCENE_LUIGI4_PAP },
+ { "L5_TFB", STREAMED_SOUND_CUTSCENE_LUIGI5_TFB },
+ { "J0_DM2", STREAMED_SOUND_CUTSCENE_JOEY0_DM2 },
+ { "J1_LFL", STREAMED_SOUND_CUTSCENE_JOEY1_LFL },
+ { "J2_KCL", STREAMED_SOUND_CUTSCENE_JOEY2_KCL },
+ { "J3_VH", STREAMED_SOUND_CUTSCENE_JOEY3_VH },
+ { "J4_ETH", STREAMED_SOUND_CUTSCENE_JOEY4_ETH },
+ { "J5_DST", STREAMED_SOUND_CUTSCENE_JOEY5_DST },
+ { "J6_TBJ", STREAMED_SOUND_CUTSCENE_JOEY6_TBJ },
+ { "T1_TOL", STREAMED_SOUND_CUTSCENE_TONI1_TOL },
+ { "T2_TPU", STREAMED_SOUND_CUTSCENE_TONI2_TPU },
+ { "T3_MAS", STREAMED_SOUND_CUTSCENE_TONI3_MAS },
+ { "T4_TAT", STREAMED_SOUND_CUTSCENE_TONI4_TAT },
+ { "T5_BF", STREAMED_SOUND_CUTSCENE_TONI5_BF },
+ { "S0_MAS", STREAMED_SOUND_CUTSCENE_SAL0_MAS },
+ { "S1_PF", STREAMED_SOUND_CUTSCENE_SAL1_PF },
+ { "S2_CTG", STREAMED_SOUND_CUTSCENE_SAL2_CTG },
+ { "S3_RTC", STREAMED_SOUND_CUTSCENE_SAL3_RTC },
+ { "S5_LRQ", STREAMED_SOUND_CUTSCENE_SAL5_LRQ },
+ { "S4_BDBA", STREAMED_SOUND_CUTSCENE_SAL4_BDBA },
+ { "S4_BDBB", STREAMED_SOUND_CUTSCENE_SAL4_BDBB },
+ { "S2_CTG2", STREAMED_SOUND_CUTSCENE_SAL2_CTG2 },
+ { "S4_BDBD", STREAMED_SOUND_CUTSCENE_SAL4_BDBD },
+ { "S5_LRQB", STREAMED_SOUND_CUTSCENE_SAL5_LRQB },
+ { "S5_LRQC", STREAMED_SOUND_CUTSCENE_SAL5_LRQC },
+ { "A1_SS0", STREAMED_SOUND_CUTSCENE_ASUKA_1_SSO },
+ { "A2_PP", STREAMED_SOUND_CUTSCENE_ASUKA_2_PP },
+ { "A3_SS", STREAMED_SOUND_CUTSCENE_ASUKA_3_SS },
+ { "A4_PDR", STREAMED_SOUND_CUTSCENE_ASUKA_4_PDR },
+ { "A5_K2FT", STREAMED_SOUND_CUTSCENE_ASUKA_5_K2FT},
+ { "K1_KBO", STREAMED_SOUND_CUTSCENE_KENJI1_KBO },
+ { "K2_GIS", STREAMED_SOUND_CUTSCENE_KENJI2_GIS },
+ { "K3_DS", STREAMED_SOUND_CUTSCENE_KENJI3_DS },
+ { "K4_SHI", STREAMED_SOUND_CUTSCENE_KENJI4_SHI },
+ { "K5_SD", STREAMED_SOUND_CUTSCENE_KENJI5_SD },
+ { "R0_PDR2", STREAMED_SOUND_CUTSCENE_RAY0_PDR2 },
+ { "R1_SW", STREAMED_SOUND_CUTSCENE_RAY1_SW },
+ { "R2_AP", STREAMED_SOUND_CUTSCENE_RAY2_AP },
+ { "R3_ED", STREAMED_SOUND_CUTSCENE_RAY3_ED },
+ { "R4_GF", STREAMED_SOUND_CUTSCENE_RAY4_GF },
+ { "R5_PB", STREAMED_SOUND_CUTSCENE_RAY5_PB },
+ { "R6_MM", STREAMED_SOUND_CUTSCENE_RAY6_MM },
+ { "D1_STOG", STREAMED_SOUND_CUTSCENE_DONALD1_STOG },
+ { "D2_KK", STREAMED_SOUND_CUTSCENE_DONALD2_KK },
+ { "D3_ADO", STREAMED_SOUND_CUTSCENE_DONALD3_ADO },
+ { "D5_ES", STREAMED_SOUND_CUTSCENE_DONALD5_ES },
+ { "D7_MLD", STREAMED_SOUND_CUTSCENE_DONALD7_MLD },
+ { "D4_GTA", STREAMED_SOUND_CUTSCENE_DONALD4_GTA },
+ { "D4_GTA2", STREAMED_SOUND_CUTSCENE_DONALD4_GTA2 },
+ { "D6_STS", STREAMED_SOUND_CUTSCENE_DONALD6_STS },
+ { "A6_BAIT", STREAMED_SOUND_CUTSCENE_ASUKA6_BAIT },
+ { "A7_ETG", STREAMED_SOUND_CUTSCENE_ASUKA7_ETG },
+ { "A8_PS", STREAMED_SOUND_CUTSCENE_ASUKA8_PS },
+ { "A9_ASD", STREAMED_SOUND_CUTSCENE_ASUKA9_ASD },
+ { "K4_SHI2", STREAMED_SOUND_CUTSCENE_KENJI4_SHI2 },
+ { "C1_TEX", STREAMED_SOUND_CUTSCENE_CATALINA1_TEX },
+ { "EL_PH1", STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 },
+ { "EL_PH2", STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 },
+ { "EL_PH3", STREAMED_SOUND_CUTSCENE_ELBURRO3_PH3 },
+ { "EL_PH4", STREAMED_SOUND_CUTSCENE_ELBURRO4_PH4 },
+ { "YD_PH1", STREAMED_SOUND_CUTSCENE_YARDIE_PH1 },
+ { "YD_PH2", STREAMED_SOUND_CUTSCENE_YARDIE_PH2 },
+ { "YD_PH3", STREAMED_SOUND_CUTSCENE_YARDIE_PH3 },
+ { "YD_PH4", STREAMED_SOUND_CUTSCENE_YARDIE_PH4 },
+ { "HD_PH1", STREAMED_SOUND_CUTSCENE_HOODS_PH1 },
+ { "HD_PH2", STREAMED_SOUND_CUTSCENE_HOODS_PH2 },
+ { "HD_PH3", STREAMED_SOUND_CUTSCENE_HOODS_PH3 },
+ { "HD_PH4", STREAMED_SOUND_CUTSCENE_HOODS_PH4 },
+ { "HD_PH5", STREAMED_SOUND_CUTSCENE_HOODS_PH5 },
+ { "MT_PH1", STREAMED_SOUND_CUTSCENE_MARTY_PH1 },
+ { "MT_PH2", STREAMED_SOUND_CUTSCENE_MARTY_PH2 },
+ { "MT_PH3", STREAMED_SOUND_CUTSCENE_MARTY_PH3 },
+ { "MT_PH4", STREAMED_SOUND_CUTSCENE_MARTY_PH4 },
+ { NULL, NULL }
+};
+
+int
+FindCutsceneAudioTrackId(const char *szCutsceneName)
+{
+ for (int i = 0; musicNameIdAssoc[i].szTrackName; i++)
+ {
+ if (!strcmpi(musicNameIdAssoc[i].szTrackName, szCutsceneName))
+ return musicNameIdAssoc[i].iTrackId;
+ }
+ return -1;
+}
bool &CCutsceneMgr::ms_running = *(bool*)0x95CCF5;
bool &CCutsceneMgr::ms_cutsceneProcessing = *(bool*)0x95CD9F;
CDirectory *&CCutsceneMgr::ms_pCutsceneDir = *(CDirectory**)0x8F5F88;
CCutsceneObject *(&CCutsceneMgr::ms_pCutsceneObjects)[NUMCUTSCENEOBJECTS] = *(CCutsceneObject*(*)[NUMCUTSCENEOBJECTS]) *(uintptr*) 0x862170;
+int32 &CCutsceneMgr::ms_numCutsceneObjs = *(int32*)0x942FA4;
+bool &CCutsceneMgr::ms_loaded = *(bool*)0x95CD95;
+bool &CCutsceneMgr::ms_animLoaded = *(bool*)0x95CDA0;
+bool &CCutsceneMgr::ms_useLodMultiplier = *(bool*)0x95CD74;
+char(&CCutsceneMgr::ms_cutsceneName)[CUTSCENENAMESIZE] = *(char(*)[CUTSCENENAMESIZE]) *(uintptr*)0x70D9D0;
+CAnimBlendAssocGroup &CCutsceneMgr::ms_cutsceneAssociations = *(CAnimBlendAssocGroup*)0x709C58;
+CVector &CCutsceneMgr::ms_cutsceneOffset = *(CVector*)0x8F2C0C;
+float &CCutsceneMgr::ms_cutsceneTimer = *(float*)0x941548;
+uint32 &CCutsceneMgr::ms_cutsceneLoadStatus = *(uint32*)0x95CB40;
+
+WRAPPER RpAtomic* CalculateBoundingSphereRadiusCB(RpAtomic * atomic, void *data) { EAXJMP(0x404B40); }
+
+void
+CCutsceneMgr::Initialise(void)
+{
+ ms_numCutsceneObjs = 0;
+ ms_loaded = false;
+ ms_running = false;
+ ms_animLoaded = false;
+ ms_cutsceneProcessing = false;
+ ms_useLodMultiplier = false;
+
+ ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE);
+ ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
+}
+
+void
+CCutsceneMgr::Shutdown(void)
+{
+ delete ms_pCutsceneDir;
+}
+
+void
+CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
+{
+ int file;
+ uint32 size;
+ uint32 offset;
+ CPlayerPed *pPlayerPed;
+
+ ms_cutsceneProcessing = true;
+ if (!strcmpi(szCutsceneName, "jb"))
+ ms_useLodMultiplier = true;
+ CTimer::Stop();
+
+ ms_pCutsceneDir->numEntries = 0;
+ ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
+
+ CStreaming::RemoveUnusedModelsInLoadedList();
+ CGame::DrasticTidyUpMemory();
+
+ strcpy(ms_cutsceneName, szCutsceneName);
+ file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb");
+
+ // Load animations
+ sprintf(gString, "%s.IFP", szCutsceneName);
+ if (ms_pCutsceneDir->FindItem(gString, offset, size)) {
+ CStreaming::MakeSpaceFor(size << 11);
+ CStreaming::ImGonnaUseStreamingMemory();
+ CFileMgr::Seek(file, offset << 11, SEEK_SET);
+ CAnimManager::LoadAnimFile(file, false);
+ ms_cutsceneAssociations.CreateAssociations(szCutsceneName);
+ CStreaming::IHaveUsedStreamingMemory();
+ ms_animLoaded = true;
+ } else {
+ ms_animLoaded = false;
+ }
+
+ // Load camera data
+ sprintf(gString, "%s.DAT", szCutsceneName);
+ if (ms_pCutsceneDir->FindItem(gString, offset, size)) {
+ CFileMgr::Seek(file, offset << 11, SEEK_SET);
+ TheCamera.LoadPathSplines(file);
+ }
+
+ CFileMgr::CloseFile(file);
+
+ if (strcmpi(ms_cutsceneName, "end")) {
+ DMAudio.ChangeMusicMode(2);
+ int trackId = FindCutsceneAudioTrackId(szCutsceneName);
+ if (trackId != -1) {
+ printf("Start preload audio %s\n", szCutsceneName);
+ DMAudio.PreloadCutSceneMusic(trackId);
+ printf("End preload audio %s\n", szCutsceneName);
+ }
+ }
+
+ ms_cutsceneTimer = 0.0f;
+ ms_loaded = true;
+ ms_cutsceneOffset = CVector(0.0f, 0.0f, 0.0f);
+
+ pPlayerPed = FindPlayerPed();
+ CTimer::Update();
+
+ pPlayerPed->m_pWanted->ClearQdCrimes();
+ pPlayerPed->bIsVisible = false;
+ pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
+ CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
+ CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(true);
+}
+
+void
+CCutsceneMgr::SetHeadAnim(const char *animName, CObject *pObject)
+{
+ CCutsceneHead *pCutsceneHead = (CCutsceneHead*)pObject;
+ char szAnim[CUTSCENENAMESIZE * 2];
+
+ sprintf(szAnim, "%s_%s", ms_cutsceneName, animName);
+ pCutsceneHead->PlayAnimation(szAnim);
+}
+
+void
+CCutsceneMgr::FinishCutscene()
+{
+ CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
+ TheCamera.FinishCutscene();
+
+ FindPlayerPed()->bIsVisible = true;
+ CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
+}
+
+void
+CCutsceneMgr::SetupCutsceneToStart(void)
+{
+ TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset);
+ TheCamera.TakeControlWithSpline(2);
+ TheCamera.SetWideScreenOn();
+
+ ms_cutsceneOffset.z++;
+
+ for (int i = ms_numCutsceneObjs - 1; i >= 0; i--) {
+ assert(RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP);
+ if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) {
+ assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation());
+ ms_pCutsceneObjects[i]->GetPosition() = ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation;
+ CWorld::Add(ms_pCutsceneObjects[i]);
+ pAnimBlendAssoc->SetRun();
+ } else {
+ ms_pCutsceneObjects[i]->GetPosition() = ms_cutsceneOffset;
+ }
+ }
+
+ CTimer::Update();
+ CTimer::Update();
+ ms_running = true;
+ ms_cutsceneTimer = 0.0f;
+}
+
+void
+CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
+{
+ CAnimBlendAssociation *pNewAnim;
+ CAnimBlendClumpData *pAnimBlendClumpData;
+
+ assert(RwObjectGetType(pObject->m_rwObject) == rpCLUMP);
+ RpAnimBlendClumpRemoveAllAssociations((RpClump*)pObject->m_rwObject);
+
+ pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
+ pNewAnim->SetCurrentTime(0.0f);
+ pNewAnim->flags |= ASSOC_HAS_TRANSLATION;
+ pNewAnim->flags &= ~ASSOC_RUNNING;
+
+ pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
+ pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
+}
+
+CCutsceneHead *
+CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId)
+{
+ CCutsceneHead *pHead = new CCutsceneHead(pObject);
+ pHead->SetModelIndex(modelId);
+ CWorld::Add(pHead);
+ ms_pCutsceneObjects[ms_numCutsceneObjs++] = pHead;
+ return pHead;
+}
+
+CCutsceneObject *
+CCutsceneMgr::CreateCutsceneObject(int modelId)
+{
+ CBaseModelInfo *pModelInfo;
+ CColModel *pColModel;
+ float radius;
+ RpClump *clump;
+ CCutsceneObject *pCutsceneObject;
+
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
+ pModelInfo = CModelInfo::GetModelInfo(modelId);
+ pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
+ radius = 0.0f;
+
+ pModelInfo->SetColModel(pColModel);
+ clump = (RpClump*)pModelInfo->GetRwObject();
+ assert(RwObjectGetType(clump) == rpCLUMP);
+ RpClumpForAllAtomics(clump, (RpAtomicCallBack)CalculateBoundingSphereRadiusCB, &radius);
+
+ pColModel->boundingSphere.radius = radius;
+ pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
+ pColModel->boundingBox.max = CVector(radius, radius, radius);
+ }
+
+ pCutsceneObject = new CCutsceneObject();
+ pCutsceneObject->SetModelIndex(modelId);
+ ms_pCutsceneObjects[ms_numCutsceneObjs++] = pCutsceneObject;
+ return pCutsceneObject;
+}
+
+void
+CCutsceneMgr::DeleteCutsceneData(void)
+{
+ if (!ms_loaded) return;
+
+ ms_cutsceneProcessing = false;
+ ms_useLodMultiplier = false;
+
+ for (--ms_numCutsceneObjs; ms_numCutsceneObjs >= 0; ms_numCutsceneObjs--) {
+ CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
+ ms_pCutsceneObjects[ms_numCutsceneObjs]->DeleteRwObject();
+ delete ms_pCutsceneObjects[ms_numCutsceneObjs];
+ }
+ ms_numCutsceneObjs = 0;
+
+ if (ms_animLoaded)
+ CAnimManager::RemoveLastAnimFile();
+
+ ms_animLoaded = false;
+ TheCamera.RestoreWithJumpCut();
+ TheCamera.SetWideScreenOff();
+ ms_running = false;
+ ms_loaded = false;
+
+ FindPlayerPed()->bIsVisible = true;
+ CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_80;
+ CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
+
+ if (strcmpi(ms_cutsceneName, "end")) {
+ DMAudio.StopCutSceneMusic();
+ if (strcmpi(ms_cutsceneName, "bet"))
+ DMAudio.ChangeMusicMode(1);
+ }
+ CTimer::Stop();
+ //TheCamera.GetScreenFadeStatus() == 2; // what for??
+ CGame::DrasticTidyUpMemory();
+ CTimer::Update();
+}
+
+void
+CCutsceneMgr::Update(void)
+{
+ enum {
+ CUTSCENE_LOADING_0 = 0,
+ CUTSCENE_LOADING_AUDIO,
+ CUTSCENE_LOADING_2,
+ CUTSCENE_LOADING_3,
+ CUTSCENE_LOADING_4
+ };
+
+ switch (ms_cutsceneLoadStatus) {
+ case CUTSCENE_LOADING_AUDIO:
+ SetupCutsceneToStart();
+ if (strcmpi(ms_cutsceneName, "end"))
+ DMAudio.PlayPreloadedCutSceneMusic();
+ ms_cutsceneLoadStatus++;
+ break;
+ case CUTSCENE_LOADING_2:
+ case CUTSCENE_LOADING_3:
+ ms_cutsceneLoadStatus++;
+ break;
+ case CUTSCENE_LOADING_4:
+ ms_cutsceneLoadStatus = CUTSCENE_LOADING_0;
+ break;
+ default:
+ break;
+ }
+
+ if (!ms_running) return;
+
+ ms_cutsceneTimer += CTimer::GetTimeStepNonClipped() * 0.02f;
+ if (strcmpi(ms_cutsceneName, "end") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
+ if (CPad::GetPad(0)->GetCrossJustDown()
+ || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
+ || CPad::GetPad(0)->GetLeftMouseJustDown()
+ || CPad::GetPad(0)->GetPadEnterJustDown() || CPad::GetPad(0)->GetEnterJustDown() // NOTE: In original code it's a single CPad method
+ || CPad::GetPad(0)->GetCharJustDown(VK_SPACE))
+ FinishCutscene();
+ }
+}
+
+bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; }
+
+STARTPATCHES
+InjectHook(0x4045D0, &CCutsceneMgr::Initialise, PATCH_JUMP);
+InjectHook(0x404630, &CCutsceneMgr::Shutdown, PATCH_JUMP);
+InjectHook(0x404650, &CCutsceneMgr::LoadCutsceneData, PATCH_JUMP);
+InjectHook(0x405140, &CCutsceneMgr::FinishCutscene, PATCH_JUMP);
+InjectHook(0x404D80, &CCutsceneMgr::SetHeadAnim, PATCH_JUMP);
+InjectHook(0x404DC0, &CCutsceneMgr::SetupCutsceneToStart, PATCH_JUMP);
+InjectHook(0x404D20, &CCutsceneMgr::SetCutsceneAnim, PATCH_JUMP);
+InjectHook(0x404CD0, &CCutsceneMgr::AddCutsceneHead, PATCH_JUMP);
+InjectHook(0x404BE0, &CCutsceneMgr::CreateCutsceneObject, PATCH_JUMP);
+InjectHook(0x4048E0, &CCutsceneMgr::DeleteCutsceneData, PATCH_JUMP);
+InjectHook(0x404EE0, &CCutsceneMgr::Update, PATCH_JUMP);
+InjectHook(0x4051B0, &CCutsceneMgr::GetCutsceneTimeInMilleseconds, PATCH_JUMP);
+InjectHook(0x4051F0, &CCutsceneMgr::HasCutsceneFinished, PATCH_JUMP);
+ENDPATCHES \ No newline at end of file
diff --git a/src/core/CutsceneMgr.h b/src/core/CutsceneMgr.h
index aa5a2eb2..9b942030 100644
--- a/src/core/CutsceneMgr.h
+++ b/src/core/CutsceneMgr.h
@@ -1,7 +1,11 @@
#pragma once
#include "CutsceneObject.h"
+#define CUTSCENENAMESIZE 8
+
class CDirectory;
+class CAnimBlendAssocGroup;
+class CCutsceneHead;
class CCutsceneMgr
{
@@ -9,10 +13,35 @@ class CCutsceneMgr
static bool &ms_cutsceneProcessing;
static CCutsceneObject *(&ms_pCutsceneObjects)[NUMCUTSCENEOBJECTS];
+ static int32 &ms_numCutsceneObjs;
+ static bool &ms_loaded;
+ static bool &ms_animLoaded;
+ static bool &ms_useLodMultiplier;
+
+ static char(&ms_cutsceneName)[CUTSCENENAMESIZE];
+ static CAnimBlendAssocGroup &ms_cutsceneAssociations;
+ static CVector &ms_cutsceneOffset;
+ static float &ms_cutsceneTimer;
public:
static CDirectory *&ms_pCutsceneDir;
+ static uint32 &ms_cutsceneLoadStatus;
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
+ static int GetCutsceneTimeInMilleseconds(void) { return 1000.0f * ms_cutsceneTimer; }
+ static char *GetCutsceneName(void) { return ms_cutsceneName; }
+ static bool HasCutsceneFinished(void);
+
+ static void Initialise(void);
+ static void Shutdown(void);
+ static void LoadCutsceneData(const char *szCutsceneName);
+ static void FinishCutscene(void);
+ static void SetHeadAnim(const char *animName, CObject *pObject);
+ static void SetupCutsceneToStart(void);
+ static void SetCutsceneAnim(const char *animName, CObject *pObject);
+ static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId);
+ static CCutsceneObject *CreateCutsceneObject(int modelId);
+ static void DeleteCutsceneData(void);
+ static void Update(void);
};
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index effcb0b4..30b80634 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -2383,7 +2383,7 @@ void CMenuManager::SwitchToNewScreen(int32 screen)
// Set player skin.
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
- CPlayerSkin::BeginFrontEndSkinEdit();
+ CPlayerSkin::BeginFrontendSkinEdit();
m_bSkinsFound = false;
}
diff --git a/src/core/General.h b/src/core/General.h
index 366c571c..d73cf36f 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -54,14 +54,7 @@ public:
static float LimitRadianAngle(float angle)
{
- float result;
-
- if (angle < -25.0f)
- result = -25.0f;
- else if (angle > 25.0f)
- result = 25.0f;
- else
- result = angle;
+ float result = clamp(angle, -25.0f, 25.0f);
while (result >= PI) {
result -= 2 * PI;
diff --git a/src/core/Pad.h b/src/core/Pad.h
index 4f129e85..eca334ee 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -368,6 +368,7 @@ public:
bool GetLeftShoulder2JustDown() { return !!(NewState.LeftShoulder2 && !OldState.LeftShoulder2); }
bool GetRightShoulder1JustDown() { return !!(NewState.RightShoulder1 && !OldState.RightShoulder1); }
bool GetRightShoulder2JustDown() { return !!(NewState.RightShoulder2 && !OldState.RightShoulder2); }
+ bool GetStartJustDown() { return !!(NewState.Start && !OldState.Start); }
/*
int32 GetLeftShoulder1(void) { return NewState.LeftShoulder1; }
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index 8c505eb4..dc72848d 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -4,9 +4,9 @@
#include "PlayerInfo.h"
#include "Frontend.h"
#include "Vehicle.h"
+#include "PlayerSkin.h"
WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); }
-WRAPPER void CPlayerInfo::LoadPlayerSkin() { EAXJMP(0x4A1700); }
WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); }
WRAPPER void CPlayerInfo::Process(void) { EAXJMP(0x49FD30); }
@@ -22,3 +22,25 @@ CVector& CPlayerInfo::GetPos()
return m_pPed->m_pMyVehicle->GetPosition();
return m_pPed->GetPosition();
}
+
+void CPlayerInfo::LoadPlayerSkin()
+{
+ DeletePlayerSkin();
+
+ m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
+ if (!m_pSkinTexture)
+ m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
+}
+
+void CPlayerInfo::DeletePlayerSkin()
+{
+ if (m_pSkinTexture) {
+ RwTextureDestroy(m_pSkinTexture);
+ m_pSkinTexture = NULL;
+ }
+}
+
+STARTPATCHES
+InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP);
+InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index 29290f6e..f0b879ee 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -68,6 +68,7 @@ public:
void MakePlayerSafe(bool);
void LoadPlayerSkin();
+ void DeletePlayerSkin();
void AwardMoneyForExplosion(CVehicle *vehicle);
void SetPlayerSkin(char* skin);
CVector& GetPos();
diff --git a/src/core/PlayerSkin.cpp b/src/core/PlayerSkin.cpp
index 1c9ca2c6..111333ec 100644
--- a/src/core/PlayerSkin.cpp
+++ b/src/core/PlayerSkin.cpp
@@ -1,5 +1,169 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
#include "PlayerSkin.h"
+#include "TxdStore.h"
+#include "rtbmp.h"
+#include "ClumpModelInfo.h"
+#include "VisibilityPlugins.h"
+#include "World.h"
+#include "PlayerInfo.h"
+#include "CdStream.h"
+#include "FileMgr.h"
+#include "Directory.h"
+#include "RwHelper.h"
+#include "Timer.h"
+#include "Lights.h"
-WRAPPER void CPlayerSkin::BeginFrontEndSkinEdit() { EAXJMP(0x59BC70); }
+int CPlayerSkin::m_txdSlot;
+
+void
+FindPlayerDff(uint32 &offset, uint32 &size)
+{
+ int file;
+ CDirectory::DirectoryInfo info;
+
+ file = CFileMgr::OpenFile("models\\gta3.dir", "rb");
+
+ do {
+ if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
+ return;
+ } while (strcmpi("player.dff", info.name));
+
+ offset = info.offset;
+ size = info.size;
+}
+
+void
+LoadPlayerDff(void)
+{
+ RwStream *stream;
+ RwMemory mem;
+ uint32 offset, size;
+ uint8 *buffer;
+ bool streamWasAdded = false;
+
+ if (CdStreamGetNumImages() == 0) {
+ CdStreamAddImage("models\\gta3.img");
+ streamWasAdded = true;
+ }
+
+ FindPlayerDff(offset, size);
+ buffer = (uint8*)RwMallocAlign(size << 11, 2048);
+ CdStreamRead(0, buffer, offset, size);
+ CdStreamSync(0);
+
+ mem.start = buffer;
+ mem.length = size << 11;
+ stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
+
+ if (RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
+ gpPlayerClump = RpClumpStreamRead(stream);
+
+ RwStreamClose(stream, &mem);
+ RwFreeAlign(buffer);
+
+ if (streamWasAdded)
+ CdStreamRemoveImages();
+}
+
+void
+CPlayerSkin::Initialise(void)
+{
+ m_txdSlot = CTxdStore::AddTxdSlot("skin");
+ CTxdStore::Create(m_txdSlot);
+ CTxdStore::AddRef(m_txdSlot);
+}
+
+void
+CPlayerSkin::Shutdown(void)
+{
+ CTxdStore::RemoveTxdSlot(m_txdSlot);
+}
+
+RwTexture *
+CPlayerSkin::GetSkinTexture(const char *texName)
+{
+ RwTexture *tex;
+ RwRaster *raster;
+ int32 width, height, depth, format;
+
+ CTxdStore::PushCurrentTxd();
+ CTxdStore::SetCurrentTxd(m_txdSlot);
+ tex = RwTextureRead(texName, NULL);
+ CTxdStore::PopCurrentTxd();
+ if (tex) return tex;
+
+ if (!strcmp(DEFAULT_SKIN_NAME, texName))
+ sprintf(gString, "models\\generic\\player.bmp");
+ else
+ sprintf(gString, "skins\\%s.bmp", texName);
+
+ if (RwImage *image = RtBMPImageRead(gString)) {
+ RwImageFindRasterFormat(image, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
+ raster = RwRasterCreate(width, height, depth, format);
+ RwRasterSetFromImage(raster, image);
+
+ tex = RwTextureCreate(raster);
+ RwTextureSetName(tex, texName);
+ RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
+ RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
+
+ RwImageDestroy(image);
+ }
+ return tex;
+}
+
+void
+CPlayerSkin::BeginFrontendSkinEdit(void)
+{
+ LoadPlayerDff();
+ RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, CVisibilityPlugins::RenderPlayerCB);
+ CWorld::Players[0].LoadPlayerSkin();
+ gOldFov = CDraw::GetFOV();
+ CDraw::SetFOV(30.0f);
+}
+
+void
+CPlayerSkin::EndFrontendSkinEdit(void)
+{
+ RpClumpDestroy(gpPlayerClump);
+ gpPlayerClump = NULL;
+ CDraw::SetFOV(gOldFov);
+}
+
+void
+CPlayerSkin::RenderFrontendSkinEdit(void)
+{
+ static float rotation = 0.0f;
+ RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
+ const RwV3d pos = { 1.35f, 0.35f, 7.725f };
+ const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
+ const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
+ static uint32 LastFlash = 0;
+
+ RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
+
+ if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 7) {
+ rotation += 2.0f;
+ if (rotation > 360.0f)
+ rotation -= 360.0f;
+ LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
+ RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
+ RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
+ RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
+ RwFrameUpdateObjects(frame);
+ SetAmbientColours(&AmbientColor);
+ RpClumpRender(gpPlayerClump);
+}
+
+STARTPATCHES
+InjectHook(0x59B9B0, &CPlayerSkin::Initialise, PATCH_JUMP);
+InjectHook(0x59B9E0, &CPlayerSkin::Shutdown, PATCH_JUMP);
+InjectHook(0x59B9F0, &CPlayerSkin::GetSkinTexture, PATCH_JUMP);
+InjectHook(0x59BC70, &CPlayerSkin::BeginFrontendSkinEdit, PATCH_JUMP);
+InjectHook(0x59BCB0, &CPlayerSkin::EndFrontendSkinEdit, PATCH_JUMP);
+InjectHook(0x59BCE0, &CPlayerSkin::RenderFrontendSkinEdit, PATCH_JUMP);
+ENDPATCHES \ No newline at end of file
diff --git a/src/core/PlayerSkin.h b/src/core/PlayerSkin.h
index 61e09cdf..2d82ec12 100644
--- a/src/core/PlayerSkin.h
+++ b/src/core/PlayerSkin.h
@@ -1,7 +1,21 @@
#pragma once
+#define DEFAULT_SKIN_NAME "$$\"\""
+
+static RpClump *gpPlayerClump;// = *(RpClump**)0x660FF8;
+static float gOldFov;// = *(float*)0x660FFC;
+
+void LoadPlayerDff(void);
+void FindPlayerDff(uint32 &offset, uint32 &size);
+
class CPlayerSkin
{
+ static int m_txdSlot;
public:
- static void BeginFrontEndSkinEdit();
+ static void Initialise();
+ static void Shutdown();
+ static RwTexture *GetSkinTexture(const char *texName);
+ static void BeginFrontendSkinEdit();
+ static void EndFrontendSkinEdit();
+ static void RenderFrontendSkinEdit();
}; \ No newline at end of file
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index a76bbb6d..847fa753 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -13,6 +13,7 @@ CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18;
CAudioScriptObjectPool *&CPools::ms_pAudioScriptObjectPool = *(CAudioScriptObjectPool**)0x8F1B6C;
WRAPPER void CPools::Initialise(void) { EAXJMP(0x4A1770); }
+WRAPPER void CPools::MakeSureSlotInObjectPoolIsEmpty(int32 handle) { EAXJMP(0x4A2DB0); }
#if 0
void
diff --git a/src/core/Pools.h b/src/core/Pools.h
index bdf668c2..4e6bd547 100644
--- a/src/core/Pools.h
+++ b/src/core/Pools.h
@@ -49,4 +49,5 @@ public:
static CVehicle *GetVehicle(int32 handle);
static int32 GetObjectRef(CObject *object);
static CObject *GetObject(int32 handle);
+ static void MakeSureSlotInObjectPoolIsEmpty(int32 handle);
};
diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp
index f04e14d1..0d6cbc82 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -16,8 +16,7 @@
#include "Streaming.h"
float &CRadar::m_RadarRange = *(float*)0x8E281C;
-CBlip *CRadar::ms_RadarTrace = (CBlip*)0x6ED5E0;
-
+CBlip (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(CBlip(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
int *gRadarTxdIds = (int*)0x6299C0;
@@ -78,13 +77,13 @@ static_assert(RADAR_TILE_SIZE == (WORLD_SIZE_Y / RADAR_NUM_TILES), "CRadar: not
#if 0
WRAPPER void CRadar::CalculateBlipAlpha(float) { EAXJMP(0x4A4F90); }
#else
-int CRadar::CalculateBlipAlpha(float dist)
+uint8 CRadar::CalculateBlipAlpha(float dist)
{
if (dist <= 1.0f)
return 255;
if (dist <= 5.0f)
- return (((1.0f - ((dist * 0.25f) - 0.25f)) * 255.0f) + (((dist * 0.25f) - 0.25f) * 128.0f));
+ return (128.0f * ((dist - 1.0f) / 4.0f)) + ((1.0f - (dist - 1.0f) / 4.0f) * 255.0f);
return 128;
}
@@ -109,18 +108,18 @@ void CRadar::ChangeBlipColour(int32 i, int32)
#endif
#if 1
-WRAPPER void CRadar::ChangeBlipDisplay(int32, int16) { EAXJMP(0x4A5810); }
+WRAPPER void CRadar::ChangeBlipDisplay(int32, eBlipDisplay) { EAXJMP(0x4A5810); }
#else
-void CRadar::ChangeBlipDisplay(int32 i, int16 flag)
+void CRadar::ChangeBlipDisplay(int32 i, eBlipDisplay display)
{
}
#endif
#if 1
-WRAPPER void CRadar::ChangeBlipScale(int32, int16) { EAXJMP(0x4A57E0); }
+WRAPPER void CRadar::ChangeBlipScale(int32, int32) { EAXJMP(0x4A57E0); }
#else
-void CRadar::ChangeBlipScale(int32 i, int16 scale)
+void CRadar::ChangeBlipScale(int32 i, int32 scale)
{
}
@@ -136,17 +135,17 @@ void CRadar::ClearBlip(int32 i)
#endif
#if 0
-WRAPPER void CRadar::ClearBlipForEntity(int16, int32) { EAXJMP(0x4A56C0); }
+WRAPPER void CRadar::ClearBlipForEntity(eBlipType, int32) { EAXJMP(0x4A56C0); }
#else
-void CRadar::ClearBlipForEntity(int16 type, int32 id)
+void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
{
for (int i = 0; i < NUMRADARBLIPS; i++) {
if (type == ms_RadarTrace[i].m_eBlipType && id == ms_RadarTrace[i].m_nEntityHandle) {
- SetRadarMarkerState(i, 0);
- ms_RadarTrace[i].m_bInUse = 0;
- ms_RadarTrace[i].m_eBlipType = 0;
- ms_RadarTrace[i].m_eBlipDisplay = 0;
- ms_RadarTrace[i].m_IconID = 0;
+ SetRadarMarkerState(i, false);
+ ms_RadarTrace[i].m_bInUse = false;
+ ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
+ ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
+ ms_RadarTrace[i].m_IconID = RADAR_SPRITE_NONE;
}
};
}
@@ -278,6 +277,10 @@ void CRadar::DrawBlips()
float angle;
if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1)
angle = PI + FindPlayerHeading();
+#ifdef FIX_BUGS
+ else if (TheCamera.GetLookDirection() != LOOKING_FORWARD)
+ angle = FindPlayerHeading() - (PI + (TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind).Heading());
+#endif
else
angle = FindPlayerHeading() - (PI + TheCamera.GetForward().Heading());
@@ -291,82 +294,224 @@ void CRadar::DrawBlips()
TransformRadarPointToScreenSpace(out, in);
DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255);
- /*
- DrawEntityBlip
- */
- for (int i = 0; i < NUMRADARBLIPS; i++) {
- if (ms_RadarTrace[i].m_bInUse) {
- if (ms_RadarTrace[i].m_eBlipType <= BLIP_OBJECT) {
- CEntity *e = nil;
- switch (ms_RadarTrace[i].m_eBlipType) {
- case BLIP_CAR:
- e = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
- break;
- case BLIP_CHAR:
- e = CPools::GetPedPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
- break;
- case BLIP_OBJECT:
- e = CPools::GetObjectPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
- break;
- };
-
- if (e) {
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ CEntity *blipEntity = nil;
+ for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
+ if (!ms_RadarTrace[blipId].m_bInUse)
+ continue;
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ case BLIP_CHAR:
+ case BLIP_OBJECT:
+ if (ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SAVE
+ || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_WEAPON) {
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ case BLIP_CHAR:
+ blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) {
+ blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
+ }
+ break;
+ case BLIP_OBJECT:
+ blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ default:
+ break;
+ }
+ if (blipEntity) {
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::DbgFlag) {
+ ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE) {
+ DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
+ } else {
+#ifdef TRIANGULAR_BLIPS
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = blipEntity->GetPosition();
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
+ }
+ }
+ }
+ }
+ break;
+ case BLIP_COORD:
+ case BLIP_CONTACT_POINT:
+ if ((ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SAVE
+ || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_WEAPON)
+ && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
+
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
if (CTheScripts::DbgFlag) {
- ShowRadarMarker(e->GetPosition(), GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim), ms_RadarTrace->m_Radius);
-
- ms_RadarTrace[i].m_Radius = ms_RadarTrace[i].m_Radius - 0.1f;
- if (ms_RadarTrace[i].m_Radius >= 1.0f)
- ms_RadarTrace[i].m_Radius = 5.0;
+ ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
}
}
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- vec2d = e->GetPosition();
- TransformRealWorldPointToRadarSpace(in, vec2d);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
float dist = LimitRadarPoint(in);
- int a = CalculateBlipAlpha(dist);
TransformRadarPointToScreenSpace(out, in);
-
- int32 col = GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim);
-
- if (ms_RadarTrace[i].m_IconID)
- DrawRadarSprite(ms_RadarTrace[i].m_IconID, out.x, out.y, a);
- else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, ((col >> 24)), ((col >> 16) & 0xFF), ((col >> 8)), 255);
+ if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE) {
+ DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
+ } else {
+#ifdef TRIANGULAR_BLIPS
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
+ }
}
}
- }
+ break;
+ default:
+ break;
+ }
+ }
+ for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
+ if (!ms_RadarTrace[blipId].m_bInUse)
+ continue;
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ case BLIP_CHAR:
+ case BLIP_OBJECT:
+ if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SAVE
+ && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_WEAPON) {
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ case BLIP_CHAR:
+ blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) {
+ blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
+ }
+ break;
+ case BLIP_OBJECT:
+ blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ default:
+ break;
+ }
- /*
- DrawCoordBlip
- */
- if (ms_RadarTrace[i].m_eBlipType >= BLIP_COORD) {
- if (ms_RadarTrace[i].m_eBlipType != BLIP_CONTACT_POINT || ms_RadarTrace[i].m_eBlipType == BLIP_CONTACT_POINT && DisplayThisBlip(i) || !CTheScripts::IsPlayerOnAMission()) {
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (blipEntity) {
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::DbgFlag) {
+ ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE)
+ DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
+ else
+#ifdef TRIANGULAR_BLIPS
+ {
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = blipEntity->GetPosition();
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+ }
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ for (int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
+ if (!ms_RadarTrace[blipId].m_bInUse)
+ continue;
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_COORD:
+ case BLIP_CONTACT_POINT:
+ if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SAVE
+ && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_WEAPON
+ && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
+
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
if (CTheScripts::DbgFlag) {
- ShowRadarMarker(ms_RadarTrace[i].m_vecPos, GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim), ms_RadarTrace->m_Radius);
- ms_RadarTrace[i].m_Radius = ms_RadarTrace[i].m_Radius - 0.1f;
- if (ms_RadarTrace[i].m_Radius >= 1.0f)
- ms_RadarTrace[i].m_Radius = 5.0f;
+ ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
}
}
-
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[i].m_vec2DPos);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
float dist = LimitRadarPoint(in);
- int a = CalculateBlipAlpha(dist);
TransformRadarPointToScreenSpace(out, in);
-
- int32 col = GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim);
-
- if (ms_RadarTrace[i].m_IconID)
- DrawRadarSprite(ms_RadarTrace[i].m_IconID, out.x, out.y, a);
+ if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE)
+ DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, ((col >> 24)), ((col >> 16) & 0xFF), ((col >> 8)), 255);
+#ifdef TRIANGULAR_BLIPS
+ {
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+ }
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
}
}
- }
- };
+ break;
+ default:
+ break;
+ }
}
}
}
@@ -531,9 +676,9 @@ void CRadar::DrawRadarSection(int32 x, int32 y)
#endif
#if 0
-WRAPPER void CRadar::DrawRadarSprite(int32 sprite, float x, float y, int32 alpha) { EAXJMP(0x4A5EF0); }
+WRAPPER void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha) { EAXJMP(0x4A5EF0); }
#else
-void CRadar::DrawRadarSprite(int32 sprite, float x, float y, int32 alpha)
+void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
{
RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
}
@@ -570,12 +715,17 @@ void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float
}
#endif
-#if 1
+#if 0
WRAPPER int32 CRadar::GetActualBlipArrayIndex(int32) { EAXJMP(0x4A41C0); }
#else
int32 CRadar::GetActualBlipArrayIndex(int32 i)
{
- return int32();
+ if (i == -1)
+ return -1;
+ else if ((i & 0xFFFF0000) >> 16 != ms_RadarTrace[(uint16)i].m_BlipIndex)
+ return -1;
+ else
+ return (uint16)i;
}
#endif
@@ -589,9 +739,9 @@ int32 CRadar::GetNewUniqueBlipIndex(int32 i)
#endif
#if 0
-WRAPPER int32 CRadar::GetRadarTraceColour(int32 color, bool bright) { EAXJMP(0x4A5BB0); }
+WRAPPER uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright) { EAXJMP(0x4A5BB0); }
#else
-int32 CRadar::GetRadarTraceColour(int32 color, bool bright)
+uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
{
int32 c;
switch (color) {
@@ -605,13 +755,13 @@ int32 CRadar::GetRadarTraceColour(int32 color, bool bright)
if (bright)
c = 0x5FA06AFF;
else
- c = 0x7F00FF;
+ c = 0x007F00FF;
break;
case 2:
if (bright)
c = 0x80A7F3FF;
else
- c = 0x007FFF;
+ c = 0x00007FFF;
break;
case 3:
if (bright)
@@ -633,9 +783,9 @@ int32 CRadar::GetRadarTraceColour(int32 color, bool bright)
break;
case 6:
if (bright)
- c = 0xFFFFFF;
+ c = 0x00FFFFFF;
else
- c = 0x7F7FFF;
+ c = 0x007F7FFF;
break;
default:
c = color;
@@ -727,37 +877,70 @@ void CRadar::SaveAllRadarBlips(int32)
}
#endif
-#if 1
+#if 0
WRAPPER void CRadar::SetBlipSprite(int32, int32) { EAXJMP(0x4A5840); }
#else
void CRadar::SetBlipSprite(int32 i, int32 icon)
{
-
+ int index = CRadar::GetActualBlipArrayIndex(i);
+ if (index != -1) {
+ ms_RadarTrace[index].m_IconID = icon;
+ }
}
#endif
-#if 1
-WRAPPER int32 CRadar::SetCoordBlip(eBlipType, CVector, int32, eBlipDisplay) { EAXJMP(0x4A5590); }
+#if 0
+WRAPPER int32 CRadar::SetCoordBlip(eBlipType, CVector, int32, eBlipDisplay display) { EAXJMP(0x4A5590); }
#else
-int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 flag, eBlipDisplay)
+int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display)
{
- return 0;
+ int nextBlip;
+ for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
+ if (!ms_RadarTrace[nextBlip].m_bInUse)
+ break;
+ }
+ ms_RadarTrace[nextBlip].m_eBlipType = type;
+ ms_RadarTrace[nextBlip].m_nColor = color;
+ ms_RadarTrace[nextBlip].m_bDim = 1;
+ ms_RadarTrace[nextBlip].m_bInUse = 1;
+ ms_RadarTrace[nextBlip].m_Radius = 1.0f;
+ ms_RadarTrace[nextBlip].m_vec2DPos = pos;
+ ms_RadarTrace[nextBlip].m_vecPos = pos;
+ ms_RadarTrace[nextBlip].m_nEntityHandle = 0;
+ ms_RadarTrace[nextBlip].m_wScale = 1;
+ ms_RadarTrace[nextBlip].m_eBlipDisplay = display;
+ ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
+ return CRadar::GetNewUniqueBlipIndex(nextBlip);
}
#endif
-#if 1
+#if 0
WRAPPER int CRadar::SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay) { EAXJMP(0x4A5640); }
#else
-int CRadar::SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay)
+int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display)
{
- return 0;
+ int nextBlip;
+ for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
+ if (!ms_RadarTrace[nextBlip].m_bInUse)
+ break;
+ }
+ ms_RadarTrace[nextBlip].m_eBlipType = type;
+ ms_RadarTrace[nextBlip].m_nColor = color;
+ ms_RadarTrace[nextBlip].m_bDim = 1;
+ ms_RadarTrace[nextBlip].m_bInUse = 1;
+ ms_RadarTrace[nextBlip].m_Radius = 1.0f;
+ ms_RadarTrace[nextBlip].m_nEntityHandle = handle;
+ ms_RadarTrace[nextBlip].m_wScale = 1;
+ ms_RadarTrace[nextBlip].m_eBlipDisplay = display;
+ ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
+ return CRadar::GetNewUniqueBlipIndex(nextBlip);
}
#endif
#if 0
-WRAPPER void CRadar::SetRadarMarkerState(int32, int32) { EAXJMP(0x4A5C60); }
+WRAPPER void CRadar::SetRadarMarkerState(int32, bool) { EAXJMP(0x4A5C60); }
#else
-void CRadar::SetRadarMarkerState(int32 counter, int32 flag)
+void CRadar::SetRadarMarkerState(int32 counter, bool flag)
{
CEntity *e;
switch (ms_RadarTrace[counter].m_eBlipType) {
@@ -780,11 +963,11 @@ void CRadar::SetRadarMarkerState(int32 counter, int32 flag)
#endif
#if 0
-WRAPPER void CRadar::ShowRadarMarker(CVector pos, int16 color, float radius) { EAXJMP(0x4A59C0); }
+WRAPPER void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) { EAXJMP(0x4A59C0); }
#else
-void CRadar::ShowRadarMarker(CVector pos, int16 color, float radius) {
- float f1 = radius * 0.5f;
- float f2 = radius * 1.4f;
+void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
+ float f1 = radius * 1.4f;
+ float f2 = radius * 0.5f;
CVector p1, p2;
p1 = pos + TheCamera.GetUp()*f1;
@@ -806,15 +989,42 @@ void CRadar::ShowRadarMarker(CVector pos, int16 color, float radius) {
#endif
#if 0
-WRAPPER void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha) { EAXJMP(0x4A5870); }
+WRAPPER void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha) { EAXJMP(0x4A5870); }
#else
-void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha)
+void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha)
{
+ if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
+ return;
+
CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
}
#endif
+void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha, uint8 mode)
+{
+ if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
+ return;
+
+ switch (mode)
+ {
+ case BLIP_MODE_TRIANGULAR_UP:
+ // size++; // VC does size + 1 for triangles
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 3.0f), y + SCREEN_SCALE_Y(size + 2.0f), x - (SCREEN_SCALE_X(size + 3.0f)), y + SCREEN_SCALE_Y(size + 2.0f), x, y - (SCREEN_SCALE_Y(size + 3.0f)), x, y - (SCREEN_SCALE_Y(size + 3.0f)), CRGBA(0, 0, 0, alpha));
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 1.0f), y + SCREEN_SCALE_Y(size + 1.0f), x - (SCREEN_SCALE_X(size + 1.0f)), y + SCREEN_SCALE_Y(size + 1.0f), x, y - (SCREEN_SCALE_Y(size + 1.0f)), x, y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
+ break;
+ case BLIP_MODE_TRIANGULAR_DOWN:
+ // size++; // VC does size + 1 for triangles
+ CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 2.0f), x, y + SCREEN_SCALE_Y(size + 3.0f), x + SCREEN_SCALE_X(size + 3.0f), y - (SCREEN_SCALE_Y(size + 2.0f)), x - (SCREEN_SCALE_X(size + 3.0f)), y - (SCREEN_SCALE_Y(size + 2.0f)), CRGBA(0, 0, 0, alpha));
+ CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 1.0f), x, y + SCREEN_SCALE_Y(size + 1.0f), x + SCREEN_SCALE_X(size + 1.0f), y - (SCREEN_SCALE_Y(size + 1.0f)), x - (SCREEN_SCALE_X(size + 1.0f)), y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
+ break;
+ case BLIP_MODE_SQUARE:
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
+ break;
+ }
+}
+
#if 1
WRAPPER void CRadar::Shutdown() { EAXJMP(0x4A3F60); }
#else
@@ -1076,7 +1286,7 @@ STARTPATCHES
// InjectHook(0x4A3F60, CRadar::Shutdown, PATCH_JUMP);
// InjectHook(0x4A4030, CRadar::LoadTextures, PATCH_JUMP);
// InjectHook(0x4A4180, CRadar::GetNewUniqueBlipIndex, PATCH_JUMP);
-// InjectHook(0x4A41C0, CRadar::GetActualBlipArrayIndex, PATCH_JUMP);
+ InjectHook(0x4A41C0, CRadar::GetActualBlipArrayIndex, PATCH_JUMP);
InjectHook(0x4A4200, CRadar::DrawMap, PATCH_JUMP);
InjectHook(0x4A42F0, CRadar::DrawBlips, PATCH_JUMP);
// InjectHook(0x4A4C70, CRadar::Draw3dMarkers, PATCH_JUMP);
@@ -1086,18 +1296,18 @@ STARTPATCHES
InjectHook(0x4A50D0, CRadar::TransformRealWorldPointToRadarSpace, PATCH_JUMP);
InjectHook(0x4A5300, CRadar::TransformRadarPointToRealWorldSpace, PATCH_JUMP);
InjectHook(0x4A5530, CRadar::TransformRealWorldToTexCoordSpace, PATCH_JUMP);
-// InjectHook(0x4A5590, CRadar::SetCoordBlip, PATCH_JUMP);
-// InjectHook(0x4A5640, CRadar::SetEntityBlip, PATCH_JUMP);
+ InjectHook(0x4A5590, CRadar::SetCoordBlip, PATCH_JUMP);
+ InjectHook(0x4A5640, CRadar::SetEntityBlip, PATCH_JUMP);
InjectHook(0x4A56C0, CRadar::ClearBlipForEntity, PATCH_JUMP);
// InjectHook(0x4A5720, CRadar::ClearBlip, PATCH_JUMP);
// InjectHook(0x4A5770, CRadar::ChangeBlipColour, PATCH_JUMP);
// InjectHook(0x4A57A0, CRadar::ChangeBlipBrightness, PATCH_JUMP);
// InjectHook(0x4A57E0, CRadar::ChangeBlipScale, PATCH_JUMP);
// InjectHook(0x4A5810, CRadar::ChangeBlipDisplay, PATCH_JUMP);
-// InjectHook(0x4A5840, CRadar::SetBlipSprite, PATCH_JUMP);
+ InjectHook(0x4A5840, CRadar::SetBlipSprite, PATCH_JUMP);
InjectHook(0x4A5870, CRadar::ShowRadarTrace, PATCH_JUMP);
InjectHook(0x4A59C0, CRadar::ShowRadarMarker, PATCH_JUMP);
- //InjectHook(0x4A5BB0, CRadar::GetRadarTraceColour, PATCH_JUMP);
+ InjectHook(0x4A5BB0, CRadar::GetRadarTraceColour, PATCH_JUMP);
InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, PATCH_JUMP);
diff --git a/src/core/Radar.h b/src/core/Radar.h
index 1ec28070..d6b249db 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -45,10 +45,17 @@ enum eRadarSprite
RADAR_SPRITE_COUNT = 21,
};
+enum
+{
+ BLIP_MODE_TRIANGULAR_UP = 0,
+ BLIP_MODE_TRIANGULAR_DOWN,
+ BLIP_MODE_SQUARE,
+};
+
struct CBlip
{
- int32 m_nColor;
- int16 m_eBlipType; // eBlipType
+ uint32 m_nColor;
+ uint16 m_eBlipType; // eBlipType
int32 m_nEntityHandle;
CVector2D m_vec2DPos;
CVector m_vecPos;
@@ -57,8 +64,8 @@ struct CBlip
bool m_bInUse;
float m_Radius;
int16 m_wScale;
- int16 m_eBlipDisplay; // eBlipDisplay
- int16 m_IconID; // eRadarSprite
+ uint16 m_eBlipDisplay; // eBlipDisplay
+ uint16 m_IconID; // eRadarSprite
};
static_assert(sizeof(CBlip) == 0x30, "CBlip: error");
@@ -72,7 +79,7 @@ class CRadar
{
public:
static float &m_RadarRange;
- static CBlip *ms_RadarTrace; //[NUMRADARBLIPS]
+ static CBlip (&ms_RadarTrace)[NUMRADARBLIPS];
static CSprite2d *AsukaSprite;
static CSprite2d *BombSprite;
static CSprite2d *CatSprite;
@@ -96,13 +103,13 @@ public:
static CSprite2d *RadarSprites[21];
public:
- static int CalculateBlipAlpha(float dist);
+ static uint8 CalculateBlipAlpha(float dist);
static void ChangeBlipBrightness(int32 i, int32 bright);
static void ChangeBlipColour(int32 i, int32);
- static void ChangeBlipDisplay(int32 i, int16 flag);
- static void ChangeBlipScale(int32 i, int16 scale);
+ static void ChangeBlipDisplay(int32 i, eBlipDisplay display);
+ static void ChangeBlipScale(int32 i, int32 scale);
static void ClearBlip(int32 i);
- static void ClearBlipForEntity(int16 type, int32 id);
+ static void ClearBlipForEntity(eBlipType type, int32 id);
static int ClipRadarPoly(CVector2D *out, const CVector2D *in);
static bool DisplayThisBlip(int32 i);
static void Draw3dMarkers();
@@ -111,11 +118,11 @@ public:
static void DrawRadarMap();
static void DrawRadarMask();
static void DrawRadarSection(int32 x, int32 y);
- static void DrawRadarSprite(int32 sprite, float x, float y, int32 alpha);
+ 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 int32 GetRadarTraceColour(int32 color, bool bright);
+ static uint32 GetRadarTraceColour(uint32 color, bool bright);
static void Initialise();
static float LimitRadarPoint(CVector2D &point);
static void LoadAllRadarBlips(int32);
@@ -125,11 +132,12 @@ public:
static void RequestMapSection(int32 x, int32 y);
static void SaveAllRadarBlips(int32);
static void SetBlipSprite(int32 i, int32 icon);
- static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay flag);
+ static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
static int32 SetEntityBlip(eBlipType type, int32, int32, eBlipDisplay);
- static void SetRadarMarkerState(int32 i, int32 flag);
- static void ShowRadarMarker(CVector pos, int16 color, float radius);
- static void ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha);
+ 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);
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index a7bde91e..227a4a9f 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -1021,7 +1021,7 @@ CStreaming::RemoveAllUnusedModels(void)
for(i = 0; i < MAXVEHICLESLOADED; i++)
RemoveLoadedVehicle();
- for(i = NUM_DEFAULT_MODELS; i < MODELINFOSIZE; i++){
+ for(i = NUMDEFAULTMODELS; i < MODELINFOSIZE; i++){
if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED &&
ms_aInfoForModel[i].m_flags & STREAMFLAGS_DONT_REMOVE &&
CModelInfo::GetModelInfo(i)->m_refCount == 0){
@@ -1719,8 +1719,10 @@ CStreaming::RetryLoadFile(int32 ch)
}
switch(ms_channel[ch].state){
+ case CHANNELSTATE_ERROR:
+ ms_channel[ch].numTries++;
+ if (CdStreamGetStatus(ch) == STREAM_READING || CdStreamGetStatus(ch) == STREAM_WAITING) break;
case CHANNELSTATE_IDLE:
-streamread:
CdStreamRead(ch, ms_pStreamingBuffer[ch], ms_channel[ch].position, ms_channel[ch].size);
ms_channel[ch].state = CHANNELSTATE_READING;
ms_channel[ch].field24 = -600;
@@ -1731,11 +1733,6 @@ streamread:
CTimer::SetCodePause(false);
}
break;
- case CHANNELSTATE_ERROR:
- ms_channel[ch].numTries++;
- if(CdStreamGetStatus(ch) != STREAM_READING && CdStreamGetStatus(ch) != STREAM_WAITING)
- goto streamread;
- break;
}
}
@@ -2408,8 +2405,8 @@ CStreaming::MemoryCardSave(uint8 *buffer, uint32 *length)
{
int i;
- *length = NUM_DEFAULT_MODELS;
- for(i = 0; i < NUM_DEFAULT_MODELS; i++)
+ *length = NUMDEFAULTMODELS;
+ for(i = 0; i < NUMDEFAULTMODELS; i++)
if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED)
buffer[i] = ms_aInfoForModel[i].m_flags;
else
@@ -2421,7 +2418,7 @@ CStreaming::MemoryCardLoad(uint8 *buffer, uint32 length)
{
uint32 i;
- assert(length == NUM_DEFAULT_MODELS);
+ assert(length == NUMDEFAULTMODELS);
for(i = 0; i < length; i++)
if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED)
if(buffer[i] != 0xFF)
diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp
index 07ac7989..d2d3f5fb 100644
--- a/src/core/TempColModels.cpp
+++ b/src/core/TempColModels.cpp
@@ -10,7 +10,7 @@ CColModel &CTempColModels::ms_colModelWheel1 = *(CColModel*)0x878C40;
CColModel &CTempColModels::ms_colModelPanel1 = *(CColModel*)0x87BDD8;
CColModel &CTempColModels::ms_colModelBodyPart2 = *(CColModel*)0x87BE30;
CColModel &CTempColModels::ms_colModelBodyPart1 = *(CColModel*)0x87BE88;
-CColModel &CTempColModels::ms_colModelCutObj = *(CColModel*)0x87C960;
+CColModel (&CTempColModels::ms_colModelCutObj)[5] = *(CColModel(*)[5]) *(uintptr*)0x87C960;
CColModel &CTempColModels::ms_colModelPedGroundHit = *(CColModel*)0x880480;
CColModel &CTempColModels::ms_colModelBoot1 = *(CColModel*)0x880670;
CColModel &CTempColModels::ms_colModelDoor1 = *(CColModel*)0x880850;
diff --git a/src/core/TempColModels.h b/src/core/TempColModels.h
index f91ac77e..263904d3 100644
--- a/src/core/TempColModels.h
+++ b/src/core/TempColModels.h
@@ -13,7 +13,7 @@ public:
static CColModel &ms_colModelPanel1;
static CColModel &ms_colModelBodyPart2;
static CColModel &ms_colModelBodyPart1;
- static CColModel &ms_colModelCutObj;
+ static CColModel (&ms_colModelCutObj)[5];
static CColModel &ms_colModelPedGroundHit;
static CColModel &ms_colModelBoot1;
static CColModel &ms_colModelDoor1;
diff --git a/src/core/World.h b/src/core/World.h
index b24e66f0..523585e7 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -56,9 +56,10 @@ class CWorld
static CPtrList &ms_listMovingEntityPtrs;
static CSector (*ms_aSectors)[NUMSECTORS_X]; // [NUMSECTORS_Y][NUMSECTORS_X];
static uint16 &ms_nCurrentScanCode;
- static CColPoint &ms_testSpherePoint;
public:
+ static CColPoint& ms_testSpherePoint;
+
static uint8 &PlayerInFocus;
static CPlayerInfo *Players;
static CEntity *&pIgnoreEntity;
diff --git a/src/core/common.h b/src/core/common.h
index b3a271c6..caa305d6 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -92,9 +92,11 @@ extern void **rwengine;
#define SCREEN_SCALE_FROM_BOTTOM(a) (SCREEN_HEIGHT - SCREEN_SCALE_Y(a))
#ifdef ASPECT_RATIO_SCALE
-#define SCREEN_SCALE_AR(a) ((a) * (4.0f / 3.0f) / SCREEN_ASPECT_RATIO)
+#define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO)
+#define SCREEN_SCALE_AR2(a) ((a) / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO))
#else
#define SCREEN_SCALE_AR(a) (a)
+#define SCREEN_SCALE_AR2(a) (a)
#endif
#include "maths.h"
diff --git a/src/core/config.h b/src/core/config.h
index 81e2f2fb..cfad6d85 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -8,6 +8,7 @@ enum Config {
MODELINFOSIZE = 5500,
TXDSTORESIZE = 850,
EXTRADIRSIZE = 128,
+ CUTSCENEDIRSIZE = 512,
SIMPLEMODELSIZE = 5000,
TIMEMODELSIZE = 30,
@@ -31,6 +32,7 @@ enum Config {
NUMDUMMIES = 2802, // 2368 on PS2
NUMAUDIOSCRIPTOBJECTS = 256,
NUMCUTSCENEOBJECTS = 50,
+ NUMDEFAULTMODELS = 200,
NUMTEMPOBJECTS = 30,
@@ -66,10 +68,15 @@ enum Config {
NUMANTENNAS = 8,
NUMCORONAS = 56,
NUMPOINTLIGHTS = 32,
+ NUMMONEYMESSAGES = 16,
+ NUMPICKUPMESSAGES = 16,
NUMONSCREENTIMERENTRIES = 1,
NUMRADARBLIPS = 32,
- NUMPICKUPS = 336,
+ NUMGENERALPICKUPS = 320,
+ NUMSCRIPTEDPICKUPS = 16,
+ NUMPICKUPS = NUMGENERALPICKUPS + NUMSCRIPTEDPICKUPS,
+ NUMCOLLECTEDPICKUPS = 20,
NUMEVENTS = 64,
NUM_CARGENS = 160,
@@ -132,10 +139,26 @@ enum Config {
#endif
#define FIX_BUGS // fix bugs in the game, TODO: use this more
+
+// Pad
#define KANGAROO_CHEAT
+
+// Hud & radar
#define ASPECT_RATIO_SCALE
+#define TRIANGULAR_BLIPS
+
+// Script
#define USE_DEBUG_SCRIPT_LOADER
+
+// Vehicles
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
+//#define REMOVE_TREADABLE_PATHFIND
+
+// Pickups
+//#define MONEY_MESSAGES
+
+// Peds
#define ANIMATE_PED_COL_MODEL
+#define VC_PED_PORTS
+#define NEW_WALK_AROUND_ALGORITHM
#define CANCELLABLE_CAR_ENTER
-//#define REMOVE_TREADABLE_PATHFIND