summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorNikolay Korolev <nickvnuk@gmail.com>2020-01-01 00:42:00 +0100
committerNikolay Korolev <nickvnuk@gmail.com>2020-01-01 00:42:00 +0100
commit5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5 (patch)
tree2e2bca559ef34473733d63a022c74a711c894830 /src/core
parentsome not fully tested stuff (diff)
parentmaking particleobject compile on vs2015 (diff)
downloadre3-5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5.tar
re3-5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5.tar.gz
re3-5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5.tar.bz2
re3-5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5.tar.lz
re3-5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5.tar.xz
re3-5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5.tar.zst
re3-5b0cf80a76e49cee88e796bb8c4b53fd3ca8f3c5.zip
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ControllerConfig.cpp105
-rw-r--r--src/core/CutsceneMgr.cpp15
-rw-r--r--src/core/Directory.cpp3
-rw-r--r--src/core/Explosion.cpp1
-rw-r--r--src/core/Explosion.h1
-rw-r--r--src/core/Fire.cpp21
-rw-r--r--src/core/Fire.h3
-rw-r--r--src/core/Frontend.cpp758
-rw-r--r--src/core/Frontend.h12
-rw-r--r--src/core/General.h23
-rw-r--r--src/core/Pad.cpp4
-rw-r--r--src/core/Pad.h4
-rw-r--r--src/core/PlayerInfo.cpp500
-rw-r--r--src/core/PlayerInfo.h26
-rw-r--r--src/core/PlayerSkin.cpp4
-rw-r--r--src/core/Radar.cpp4
-rw-r--r--src/core/Stats.cpp2
-rw-r--r--src/core/Stats.h2
-rw-r--r--src/core/Streaming.cpp27
-rw-r--r--src/core/TempColModels.cpp276
-rw-r--r--src/core/TxdStore.cpp3
-rw-r--r--src/core/User.cpp12
-rw-r--r--src/core/User.h4
-rw-r--r--src/core/World.cpp48
-rw-r--r--src/core/World.h2
-rw-r--r--src/core/common.h4
-rw-r--r--src/core/config.h2
-rw-r--r--src/core/re3.cpp13
28 files changed, 1442 insertions, 437 deletions
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index f0492b0f..26db4e5e 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -1443,39 +1443,36 @@ bool CControllerConfigManager::GetIsMouseButtonDown(RsKeyCodes keycode)
bool CControllerConfigManager::GetIsMouseButtonUp(RsKeyCodes keycode)
{
- if (keycode > rsMOUSEX2BUTTON)
+ switch (keycode)
{
- switch (keycode)
- {
- case rsMOUSELEFTBUTTON:
- if (CPad::GetPad(PAD1)->GetLeftMouseUp())
- return true;
- break;
- case rsMOUSMIDDLEBUTTON:
- if (CPad::GetPad(PAD1)->GetMiddleMouseUp())
- return true;
- break;
- case rsMOUSERIGHTBUTTON:
- if (CPad::GetPad(PAD1)->GetRightMouseUp())
- return true;
- break;
- case rsMOUSEWHEELUPBUTTON:
- if (CPad::GetPad(PAD1)->GetMouseWheelUpUp())
- return true;
- break;
- case rsMOUSEWHEELDOWNBUTTON:
- if (CPad::GetPad(PAD1)->GetMouseWheelDownUp())
- return true;
- break;
- case rsMOUSEX1BUTTON:
- if (CPad::GetPad(PAD1)->GetMouseX1Up())
- return true;
- break;
- case rsMOUSEX2BUTTON:
- if (CPad::GetPad(PAD1)->GetMouseX2Up())
- return true;
- break;
- }
+ case rsMOUSELEFTBUTTON:
+ if (CPad::GetPad(PAD1)->GetLeftMouseUp())
+ return true;
+ break;
+ case rsMOUSMIDDLEBUTTON:
+ if (CPad::GetPad(PAD1)->GetMiddleMouseUp())
+ return true;
+ break;
+ case rsMOUSERIGHTBUTTON:
+ if (CPad::GetPad(PAD1)->GetRightMouseUp())
+ return true;
+ break;
+ case rsMOUSEWHEELUPBUTTON:
+ if (CPad::GetPad(PAD1)->GetMouseWheelUpUp())
+ return true;
+ break;
+ case rsMOUSEWHEELDOWNBUTTON:
+ if (CPad::GetPad(PAD1)->GetMouseWheelDownUp())
+ return true;
+ break;
+ case rsMOUSEX1BUTTON:
+ if (CPad::GetPad(PAD1)->GetMouseX1Up())
+ return true;
+ break;
+ case rsMOUSEX2BUTTON:
+ if (CPad::GetPad(PAD1)->GetMouseX2Up())
+ return true;
+ break;
}
return false;
@@ -1662,9 +1659,6 @@ void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction
bool CControllerConfigManager::GetIsKeyBlank(int32 key, eControllerType type)
{
- if (type > JOYSTICK)
- return true;
-
switch (type)
{
case KEYBOARD:
@@ -1755,27 +1749,24 @@ e_ControllerActionType CControllerConfigManager::GetActionType(e_ControllerActio
void CControllerConfigManager::ClearSettingsAssociatedWithAction(e_ControllerAction action, eControllerType type)
{
- if (type <= JOYSTICK)
+ switch (type)
{
- switch (type)
- {
- case KEYBOARD:
- m_aSettings[action][type].m_Key = rsNULL;
- m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
- break;
- case OPTIONAL_EXTRA:
- m_aSettings[action][type].m_Key = rsNULL;
- m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
- break;
- case MOUSE:
- m_aSettings[action][type].m_Key = 0;
- m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
- break;
- case JOYSTICK:
- m_aSettings[action][type].m_Key = 0;
- m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
- break;
- }
+ case KEYBOARD:
+ m_aSettings[action][type].m_Key = rsNULL;
+ m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
+ break;
+ case OPTIONAL_EXTRA:
+ m_aSettings[action][type].m_Key = rsNULL;
+ m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
+ break;
+ case MOUSE:
+ m_aSettings[action][type].m_Key = 0;
+ m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
+ break;
+ case JOYSTICK:
+ m_aSettings[action][type].m_Key = 0;
+ m_aSettings[action][type].m_ContSetOrder = SETORDER_NONE;
+ break;
}
ResetSettingOrder(action);
@@ -2257,6 +2248,7 @@ void CControllerConfigManager::UpdateJoyButtonState(int32 padnumber)
for (int32 i = 0; i < MAX_BUTTONS; i++)
m_aButtonStates[i] = false;
+#ifdef __DINPUT_INCLUDED__
for (int32 i = 0; i < MAX_BUTTONS; i++)
{
if (m_NewState.rgbButtons[i] & 0x80)
@@ -2264,6 +2256,7 @@ void CControllerConfigManager::UpdateJoyButtonState(int32 padnumber)
else
m_aButtonStates[i] = false;
}
+#endif
}
bool CControllerConfigManager::GetIsActionAButtonCombo(e_ControllerAction action)
@@ -2412,4 +2405,4 @@ STARTPATCHES
InjectHook(0x58F740, &CControllerConfigManager::GetMouseButtonAssociatedWithAction, PATCH_JUMP);
InjectHook(0x58F760, &CControllerConfigManager::SetMouseButtonAssociatedWithAction, PATCH_JUMP);
InjectHook(0x58F790, &CControllerConfigManager::ResetSettingOrder, PATCH_JUMP);
-ENDPATCHES \ No newline at end of file
+ENDPATCHES
diff --git a/src/core/CutsceneMgr.cpp b/src/core/CutsceneMgr.cpp
index fa322242..2fbc5186 100644
--- a/src/core/CutsceneMgr.cpp
+++ b/src/core/CutsceneMgr.cpp
@@ -1,5 +1,6 @@
#include "common.h"
#include "patcher.h"
+#include "General.h"
#include "CutsceneMgr.h"
#include "Directory.h"
#include "Camera.h"
@@ -107,7 +108,7 @@ int
FindCutsceneAudioTrackId(const char *szCutsceneName)
{
for (int i = 0; musicNameIdAssoc[i].szTrackName; i++) {
- if (!strcmpi(musicNameIdAssoc[i].szTrackName, szCutsceneName))
+ if (!CGeneral::faststricmp(musicNameIdAssoc[i].szTrackName, szCutsceneName))
return musicNameIdAssoc[i].iTrackId;
}
return -1;
@@ -171,7 +172,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CPlayerPed *pPlayerPed;
ms_cutsceneProcessing = true;
- if (!strcmpi(szCutsceneName, "jb"))
+ if (!strcasecmp(szCutsceneName, "jb"))
ms_useLodMultiplier = true;
CTimer::Stop();
@@ -207,7 +208,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CFileMgr::CloseFile(file);
- if (strcmpi(ms_cutsceneName, "end")) {
+ if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
int trackId = FindCutsceneAudioTrackId(szCutsceneName);
if (trackId != -1) {
@@ -364,9 +365,9 @@ CCutsceneMgr::DeleteCutsceneData(void)
CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_80;
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
- if (strcmpi(ms_cutsceneName, "end")) {
+ if (CGeneral::faststricmp(ms_cutsceneName, "end")) {
DMAudio.StopCutSceneMusic();
- if (strcmpi(ms_cutsceneName, "bet"))
+ if (CGeneral::faststricmp(ms_cutsceneName, "bet"))
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
CTimer::Stop();
@@ -389,7 +390,7 @@ CCutsceneMgr::Update(void)
switch (ms_cutsceneLoadStatus) {
case CUTSCENE_LOADING_AUDIO:
SetupCutsceneToStart();
- if (strcmpi(ms_cutsceneName, "end"))
+ if (CGeneral::faststricmp(ms_cutsceneName, "end"))
DMAudio.PlayPreloadedCutSceneMusic();
ms_cutsceneLoadStatus++;
break;
@@ -407,7 +408,7 @@ CCutsceneMgr::Update(void)
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 (CGeneral::faststricmp(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()
diff --git a/src/core/Directory.cpp b/src/core/Directory.cpp
index 3e0d5382..d4b4279d 100644
--- a/src/core/Directory.cpp
+++ b/src/core/Directory.cpp
@@ -1,5 +1,6 @@
#include "common.h"
#include "patcher.h"
+#include "General.h"
#include "FileMgr.h"
#include "Directory.h"
@@ -49,7 +50,7 @@ CDirectory::FindItem(const char *name, uint32 &offset, uint32 &size)
int i;
for(i = 0; i < numEntries; i++)
- if(strcmpi(entries[i].name, name) == 0){
+ if(!CGeneral::faststricmp(entries[i].name, name)){
offset = entries[i].offset;
size = entries[i].size;
return true;
diff --git a/src/core/Explosion.cpp b/src/core/Explosion.cpp
index 9ccd6e81..30809dc9 100644
--- a/src/core/Explosion.cpp
+++ b/src/core/Explosion.cpp
@@ -3,6 +3,7 @@
#include "Explosion.h"
WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); }
+WRAPPER void CExplosion::RemoveAllExplosionsInArea(CVector, float) { EAXJMP(0x55AD40); }
WRAPPER
int8 CExplosion::GetExplosionActiveCounter(uint8 id)
diff --git a/src/core/Explosion.h b/src/core/Explosion.h
index fde4ad7f..0768bbe4 100644
--- a/src/core/Explosion.h
+++ b/src/core/Explosion.h
@@ -27,4 +27,5 @@ public:
static CVector *GetExplosionPosition(uint8 id);
static uint8 GetExplosionType(uint8 id);
static void ResetExplosionActiveCounter(uint8 id);
+ static void RemoveAllExplosionsInArea(CVector, float);
};
diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp
index 274c06a5..5c777eab 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -5,6 +5,9 @@
CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
+WRAPPER void CFireManager::StartFire(CEntity* entityOnFire, CEntity* culprit, float, uint32) { EAXJMP(0x479590); }
+WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); }
+WRAPPER CFire* CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
uint32 CFireManager::GetTotalActiveFires() const
{
@@ -38,12 +41,28 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance)
return nil;
}
+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();
+ }
+ }
+}
+
WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
WRAPPER void CFireManager::StartFire(CVector, float, uint8) { EAXJMP(0x479500); }
-WRAPPER void CFireManager::ExtinguishPoint(CVector, float) { EAXJMP(0x479DB0); }
WRAPPER int32 CFireManager::StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8) { EAXJMP(0x479E60); }
WRAPPER bool CFireManager::IsScriptFireExtinguish(int16) { EAXJMP(0x479FC0); }
WRAPPER void CFireManager::RemoveScriptFire(int16) { EAXJMP(0x479FE0); }
WRAPPER void CFireManager::RemoveAllScriptFires(void) { EAXJMP(0x47A000); }
WRAPPER void CFireManager::SetScriptFireAudio(int16, bool) { EAXJMP(0x47A040); }
+
+STARTPATCHES
+ InjectHook(0x479DB0, &CFireManager::ExtinguishPoint, PATCH_JUMP);
+ InjectHook(0x479340, &CFireManager::FindNearestFire, PATCH_JUMP);
+ENDPATCHES
+
diff --git a/src/core/Fire.h b/src/core/Fire.h
index 9d72179e..cd6de90c 100644
--- a/src/core/Fire.h
+++ b/src/core/Fire.h
@@ -35,12 +35,13 @@ public:
void Update(void);
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
CFire *FindNearestFire(CVector, float*);
- uint32 GetTotalActiveFires() const;
+ uint32 GetTotalActiveFires() const { return m_nTotalFires; }
void ExtinguishPoint(CVector, float);
int32 StartScriptFire(const CVector& pos, CEntity* culprit, float, uint8);
bool IsScriptFireExtinguish(int16);
void RemoveScriptFire(int16);
void RemoveAllScriptFires(void);
void SetScriptFireAudio(int16, bool);
+ void ExtinguishPoint(CVector, float);
};
extern CFireManager &gFireManager;
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 5911433c..05c6b6e8 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -26,6 +26,7 @@
#include "PlayerInfo.h"
#include "World.h"
#include "Renderer.h"
+#include "CdStream.h"
#define ALL_ORIGINAL_FRONTEND 1
@@ -58,13 +59,17 @@ char *CMenuManager::m_PrefsSkinFile = (char*)0x5F2E74; //[256] "$$\"\""
int32 &CMenuManager::m_KeyPressedCode = *(int32*)0x5F2E70; // -1
+float &CMenuManager::headingYStart = *(float*)0x5F355C; // don't know the original name
+float &CMenuManager::unkX = *(float*)0x5F2E40;
+float &CMenuManager::unkY = *(float*)0x5F2E44;
+
CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8;
// Move this somewhere else.
float &CRenderer::ms_lodDistScale = *(float*)0x5F726C; // 1.2
// Stuff not in CMenuManager:
-uint32 &VibrationTime = *(uint32*)0x628CF8;
+uint32 &TimeToStopPadShaking = *(uint32*)0x628CF8;
char *&pEditString = *(char**)0x628D00;
int32 *&pControlEdit = *(int32**)0x628D08;
bool &DisplayComboButtonErrMsg = *(bool*)0x628D14;
@@ -94,87 +99,108 @@ bool GetMouseMoveRight();
bool GetPadInput();
bool GetMouseInput();
-const char *FrontendFilenames[] = {
- "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", // HEAD_RADIO
- "fe_radio2", // DOUBLE_CLEF
- "fe_radio5", // JAH_RADIO
- "fe_radio7", // RISE_FM
- "fe_radio8", // LIPS_106
- "fe_radio3", // GAME_FM
- "fe_radio4", // MSX_FM
- "fe_radio6", // FLASHBACK
- "fe_radio9", // CHATTERBOX
+// 0x5F311C
+const char* FrontendFilenames[][2] = {
+ {"fe2_mainpanel_ul", "" },
+ {"fe2_mainpanel_ur", "" },
+ {"fe2_mainpanel_dl", "" },
+ {"fe2_mainpanel_dr", "" },
+ {"fe2_mainpanel_dr2", "" },
+ {"fe2_tabactive", "" },
+ {"fe_iconbrief", "" },
+ {"fe_iconstats", "" },
+ {"fe_iconcontrols", "" },
+ {"fe_iconsave", "" },
+ {"fe_iconaudio", "" },
+ {"fe_icondisplay", "" },
+ {"fe_iconlanguage", "" },
+ {"fe_controller", "" },
+ {"fe_controllersh", "" },
+ {"fe_arrows1", "" },
+ {"fe_arrows2", "" },
+ {"fe_arrows3", "" },
+ {"fe_arrows4", "" },
+ {"fe_radio1", "" }, // HEAD_RADIO
+ {"fe_radio2", "" }, // DOUBLE_CLEF
+ {"fe_radio3", "" }, // JAH_RADIO
+ {"fe_radio4", "" }, // RISE_FM
+ {"fe_radio5", "" }, // LIPS_106
+ {"fe_radio6", "" }, // GAME_FM
+ {"fe_radio7", "" }, // MSX_FM
+ {"fe_radio8", "" }, // FLASHBACK
+ {"fe_radio9", "" }, // CHATTERBOX
};
-const char *MenuFilenames[] = {
- "connection24", "",
- "findgame24", "",
- "hostgame24", "",
- "mainmenu24", "",
- "Playersetup24", "",
- "singleplayer24", "",
- "multiplayer24", "",
- "dmalogo128", "dmalogo128m",
- "gtaLogo128", "gtaLogo128",
- "rockstarLogo128", "rockstarlogo128m",
- "gamespy256", "gamespy256a",
- "mouse", "mousetimera",
- "mousetimer", "mousetimera",
- "mp3logo", "mp3logoA",
- "downOFF", "buttonA",
- "downON", "buttonA",
- "upOFF", "buttonA",
- "upON", "buttonA",
- "gta3logo256", "gta3logo256m",
- nil, nil
+// 0x5F3344
+const char* MenuFilenames[][2] = {
+ {"connection24", ""},
+ {"findgame24", ""},
+ {"hostgame24", ""},
+ {"mainmenu24", ""},
+ {"Playersetup24", ""},
+ {"singleplayer24", ""},
+ {"multiplayer24", ""},
+ {"dmalogo128", "dmalogo128m"},
+ {"gtaLogo128", "gtaLogo128"},
+ {"rockstarLogo128", "rockstarlogo128m"},
+ {"gamespy256", "gamespy256a"},
+ {"mouse", "mousetimera"},
+ {"mousetimer", "mousetimera"},
+ {"mp3logo", "mp3logoA"},
+ {"downOFF", "buttonA"},
+ {"downON", "buttonA"},
+ {"upOff", "buttonA"},
+ {"upON", "buttonA"},
+ {"gta3logo256", "gta3logo256m"},
+ { nil, nil }
};
-#if 0
-WRAPPER void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2) { EAXJMP(0x483870); }
+#ifdef ASPECT_RATIO_SCALE
+// All of these defines replaces the StretchX function. Otherwise use SCREEN_SCALE_X.
+#define MENU_X_LEFT_ALIGNED(x) ScaleAndCenterX(x)
+#define MENU_X(x) SCREEN_SCALE_X(x)
+#define MENU_Y(y) SCREEN_SCALE_Y(y)
+float
+ScaleAndCenterX(float x)
+{
+ if (SCREEN_WIDTH == DEFAULT_SCREEN_WIDTH)
+ return x;
+ else {
+ if (x > DEFAULT_SCREEN_WIDTH / 2) {
+ return SCREEN_WIDTH / 2 + SCREEN_SCALE_X(x - DEFAULT_SCREEN_WIDTH / 2);
+ } else {
+ return SCREEN_WIDTH / 2 - SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH / 2 - x);
+ }
+ }
+}
#else
-void CMenuManager::BuildStatLine(char *text, float *stat, bool aFloat, float* stat2)
+#define MENU_X_LEFT_ALIGNED(x) StretchX(x)
+#define MENU_X(x) StretchX(x)
+#define MENU_Y(y) StretchY(y)
+#endif
+
+void
+CMenuManager::BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2)
{
if (!text)
return;
if (stat2) {
if (aFloat)
- sprintf(gString2, " %.2f %s %.2f", *stat, UnicodeToAscii(TheText.Get("FEST_OO")), *stat2);
+ sprintf(gString2, " %.2f %s %.2f", *(float*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(float*)stat2);
else
sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2);
- }
- else if (stat) {
+ } else if (stat) {
if (aFloat)
- sprintf(gString2, " %.2f", *stat);
+ sprintf(gString2, " %.2f", *(float*)stat);
else
sprintf(gString2, " %d", *(int*)stat);
- }
- else
+ } else
gString2[0] = '\0';
UnicodeStrcpy(gUString, TheText.Get(text));
AsciiToUnicode(gString2, gUString2);
}
-#endif
#if 0
WRAPPER void CMenuManager::CentreMousePointer() { EAXJMP(0x48ACE0); }
@@ -359,6 +385,7 @@ void CMenuManager::DoSettingsBeforeStartingAGame()
}
#endif
+// WIP - has broken, duplicate and missing codes
#if ALL_ORIGINAL_FRONTEND
WRAPPER void CMenuManager::Draw() { EAXJMP(0x47AE00); }
#else
@@ -370,29 +397,27 @@ void CMenuManager::Draw()
CFont::SetJustifyOn();
CFont::SetBackGroundOnlyTextOn();
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f));
- CFont::SetRightJustifyWrap(0.0f);
- CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A)));
+ CFont::SetRightJustifyWrap(SCREEN_SCALE_X(38.0f));
+// CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A)));
switch (m_nCurrScreen) {
- case MENUPAGE_STATS:
- PrintStats();
- break;
- case MENUPAGE_BRIEFS:
- PrintBriefs();
- break;
- case MENUPAGE_CONTROLLER_DEBUG:
- DrawControllerScreenExtraText(0, 350, 20);
- break;
+ case MENUPAGE_STATS:
+ PrintStats();
+ break;
+ case MENUPAGE_BRIEFS:
+ PrintBriefs();
+ break;
}
// Header.
+ headingYStart = 40.0f;
if (aScreens[m_nCurrScreen].m_ScreenName[0]) {
- CFont::SetDropShadowPosition(0);
CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
CFont::SetRightJustifyOn();
CFont::SetFontStyle(FONT_HEADING);
- CFont::SetScale(SCREEN_SCALE_X(MENUHEADER_WIDTH), SCREEN_SCALE_Y(MENUHEADER_HEIGHT));
+ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
+ headingYStart += 24.0f + 10.0f;
}
// Action text.
@@ -422,13 +447,109 @@ void CMenuManager::Draw()
break;
}
- CFont::SetDropShadowPosition(MENUDROP_COLOR_SIZE);
- CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A)));
+// CFont::SetDropShadowPosition(MENUDROP_COLOR_SIZE);
+// CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(MENUDROP_COLOR_A)));
CFont::SetFontStyle(FONT_BANK);
- CFont::SetScale(SCREEN_SCALE_X(MENUACTION_WIDTH), SCREEN_SCALE_Y(MENUACTION_HEIGHT));
- CFont::SetAlignment(ALIGN_LEFT);
+ CFont::SetScale(MENU_X(MENUACTION_WIDTH), MENU_Y(MENUACTION_HEIGHT));
+ CFont::SetAlignment(ALIGN_LEFT); // AG's extra. III uses SetRightJustifyOff.
CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
- CFont::PrintString(SCREEN_SCALE_X(MENUACTION_POS_X), SCREEN_SCALE_Y(MENUACTION_POS_Y), str);
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(MENUACTION_POS_X), MENU_Y(headingYStart), str);
+ }
+
+ CFont::SetCentreSize(SCREEN_WIDTH);
+
+ bool v360 = false;
+ int v361;
+ int v362;
+ int v20;
+ switch (m_nCurrScreen) {
+ case MENUPAGE_STATS:
+ case MENUPAGE_BRIEFS:
+ v20 = 320;
+ v362 = 240;
+ v361 = 24;
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(StretchX(unkX = 0.75f), StretchY(unkY = 0.9f));
+ CFont::SetCentreOn();
+ break;
+ case MENUPAGE_SOUND_SETTINGS:
+ case MENUPAGE_GRAPHICS_SETTINGS:
+ case MENUPAGE_MULTIPLAYER_CREATE:
+ case MENUPAGE_SKIN_SELECT_OLD:
+ case MENUPAGE_CONTROLLER_PC_OLD1:
+ case MENUPAGE_CONTROLLER_PC_OLD2:
+ case MENUPAGE_CONTROLLER_PC_OLD3:
+ case MENUPAGE_CONTROLLER_PC_OLD4:
+ case MENUPAGE_CONTROLLER_DEBUG:
+ case MENUPAGE_MOUSE_CONTROLS:
+ v20 = 50;
+ v362 = 0;
+ v361 = 20;
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(StretchX(unkX = 0.8f), StretchY(unkY = 0.55f));
+ CFont::SetRightJustifyOff();
+ break;
+ case MENUPAGE_CHOOSE_LOAD_SLOT:
+ case MENUPAGE_CHOOSE_DELETE_SLOT:
+ case MENUPAGE_CHOOSE_SAVE_SLOT:
+ v20 = 120;
+ v362 = 38;
+ v361 = 20;
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetScale(StretchX(unkX = 0.7f), StretchY(unkY = 0.45f));
+ CFont::SetRightJustifyOff();
+ break;
+ case MENUPAGE_NEW_GAME_RELOAD:
+ case MENUPAGE_LOAD_SLOT_CONFIRM:
+ case MENUPAGE_DELETE_SLOT_CONFIRM:
+ case MENUPAGE_SAVE_OVERWRITE_CONFIRM:
+ case MENUPAGE_EXIT:
+ v20 = 320;
+ v362 = 60;
+ v361 = 24;
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(StretchX(unkX = 0.75f), StretchY(unkY = 0.9f));
+ CFont::SetCentreOn();
+ break;
+ case MENUPAGE_START_MENU:
+ v20 = 320;
+ v362 = 140;
+ v361 = 24;
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(StretchX(unkX = 0.75f), StretchY(unkY = 0.9f));
+ CFont::SetCentreOn();
+ break;
+ case MENUPAGE_PAUSE_MENU:
+ v20 = 320;
+ v362 = 117;
+ v361 = 24;
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(StretchX(unkX = 0.75f), StretchY(unkY = 0.9f));
+ CFont::SetCentreOn();
+ break;
+ default:
+ v20 = 320;
+ v362 = 40;
+ v361 = 24;
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(StretchX(unkX = 0.75f), StretchY(unkY = 0.9f));
+ CFont::SetCentreOn();
+ break;
+ }
+
+ switch (m_nCurrScreen) {
+ case MENUPAGE_CONTROLLER_PC_OLD1:
+ case MENUPAGE_CONTROLLER_PC_OLD2:
+ case MENUPAGE_CONTROLLER_PC_OLD3:
+ case MENUPAGE_CONTROLLER_PC_OLD4:
+ case MENUPAGE_CONTROLLER_DEBUG:
+ if (field_113)
+ v360 = 0;
+
+ CMenuManager::DrawControllerScreenExtraText(headingYStart - 8.0f, 350, v361);
+ break;
+ default:
+ break;
}
for (int i = 0; i < NUM_MENUROWS; ++i) {
@@ -437,27 +558,38 @@ void CMenuManager::Draw()
bool Locked = false;
if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) {
+ CFont::SetRightJustifyOff();
textToPrint[MENUCOLUMN_LEFT] = GetNameOfSavedGame(i - 1);
- textToPrint[MENUCOLUMN_RIGHT] = GetSavedGameDateAndTime(i - 1);
- if (!textToPrint[MENUCOLUMN_LEFT][0]) {
+ if (Slots[i-1] != 1)
+ textToPrint[MENUCOLUMN_RIGHT] = GetSavedGameDateAndTime(i - 1);
+
+ if (!textToPrint[MENUCOLUMN_LEFT]) {
sprintf(gString, "FEM_SL%d", i);
textToPrint[MENUCOLUMN_LEFT] = TheText.Get(gString);
}
}
else {
textToPrint[MENUCOLUMN_LEFT] = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName);
-
+ /*
if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_SCREENRES) {
if (m_bGameNotLoaded)
Locked = false;
else
Locked = true;
}
+ */
}
switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
+ case MENUACTION_CHANGEMENU:
+ assert(0 && "Not implemented");
+ break;
case MENUACTION_CTRLVIBRATION:
+ if (CMenuManager::m_PrefsUseVibration)
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEM_ON");
+ else
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEM_OFF");
break;
case MENUACTION_CTRLCONFIG:
switch (CPad::GetPad(0)->Mode) {
@@ -476,6 +608,10 @@ void CMenuManager::Draw()
}
break;
case MENUACTION_CTRLDISPLAY:
+ if (m_DisplayControllerOnFoot)
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEC_ONF");
+ else
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEC_INC");
break;
case MENUACTION_FRAMESYNC:
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(m_PrefsVsyncDisp ? "FEM_ON" : "FEM_OFF");
@@ -507,6 +643,9 @@ void CMenuManager::Draw()
#endif
break;
case MENUACTION_RADIO:
+ if (m_PrefsRadioStation > 9)
+ break;
+
sprintf(gString, "FEA_FM%d", m_PrefsRadioStation);
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gString);
break;
@@ -514,29 +653,42 @@ void CMenuManager::Draw()
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(CTheScripts::DbgFlag ? "FEM_ON" : "FEM_OFF");
break;
case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT:
- textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(CTheScripts::DbgFlag ? "FEM_ON" : "FEM_OFF");
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_PEDROADGROUPS:
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gbShowPedRoadGroups ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_CARROADGROUPS:
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gbShowCarRoadGroups ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_COLLISIONPOLYS:
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_SHOWCULL:
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(gbShowCullZoneDebugStuff ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_SHOWHEADBOB:
+ textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(TheCamera.m_bHeadBob ? "FEM_ON" : "FEM_OFF");
break;
case MENUACTION_INVVERT:
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get(MousePointerStateHelper.bInvertVertically ? "FEM_ON" : "FEM_OFF");
break;
case MENUACTION_SCREENRES:
- {
char *res = _psGetVideoModeList()[m_nDisplayVideoMode];
-
- if (!res)
- res = "";
-
- AsciiToUnicode(res, gUString);
- textToPrint[MENUCOLUMN_RIGHT] = gUString;
- }
- break;
+ AsciiToUnicode(res, textToPrint[MENUCOLUMN_RIGHT]);
+ break;
case MENUACTION_AUDIOHW:
if (m_nPrefsAudio3DProviderIndex == -1)
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEA_NAH");
else {
char *provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex);
- AsciiToUnicode(provider, gUString);
- textToPrint[MENUCOLUMN_RIGHT] = gUString;
+
+ if (!strcmp(strupr(provider), "DIRECTSOUND3D HARDWARE SUPPORT")) {
+ strcpy(provider, "DSOUND3D HARDWARE SUPPORT");
+ } else if (!strcmp(strupr(provider), "DIRECTSOUND3D SOFTWARE EMULATION")) {
+ strcpy(provider, "DSOUND3D SOFTWARE EMULATION");
+ }
+ AsciiToUnicode(provider, textToPrint[MENUCOLUMN_RIGHT]);
}
break;
case MENUACTION_SPEAKERCONF:
@@ -580,6 +732,7 @@ void CMenuManager::Draw()
CFont::SetWrapx(SCREEN_WIDTH);
CFont::SetRightJustifyWrap(-SCREEN_WIDTH);
+ // !! Most of these are now duplicate(see before the loop) and needs to be deleted.
// Set alignment.
CVector2D vecPositions = { 0.0f, 0.0f };
float fVerticalSpacing;
@@ -768,19 +921,27 @@ void CMenuManager::Draw()
SetHelperText(3);
}
}
-
- switch (m_nCurrScreen) {
- case MENUPAGE_CONTROLLER_SETTINGS:
- case MENUPAGE_SOUND_SETTINGS:
- case MENUPAGE_GRAPHICS_SETTINGS:
- case MENUPAGE_SKIN_SELECT:
- case MENUPAGE_CONTROLLER_PC:
- case MENUPAGE_MOUSE_CONTROLS:
- DisplayHelperText();
- break;
- }
}
}
+
+ switch (m_nCurrScreen) {
+ case MENUPAGE_CONTROLLER_SETTINGS:
+ case MENUPAGE_SOUND_SETTINGS:
+ case MENUPAGE_GRAPHICS_SETTINGS:
+ case MENUPAGE_SKIN_SELECT:
+ case MENUPAGE_CONTROLLER_PC:
+ case MENUPAGE_MOUSE_CONTROLS:
+ DisplayHelperText();
+ break;
+ }
+/*
+ if (m_nCurrScreen == MENUPAGE_CONTROLLER_SETTINGS) {
+ PrintController();
+ } else if (m_nCurrScreen == MENUPAGE_SKIN_SELECT_OLD) {
+ CSprite2d::DrawRect(CRect(StretchX(180), StretchY(98), StretchX(230), StretchY(123)), CRGBA(255, 255, 255, FadeIn(255)));
+ CSprite2d::DrawRect(CRect(StretchX(181), StretchY(99), StretchX(229), StretchY(233)), CRGBA(Player color from PickNewPlayerColour, FadeIn(255)));
+ }
+*/
}
#endif
@@ -811,9 +972,6 @@ void CMenuManager::DrawControllerSetupScreen()
}
#endif
-#if 0
-WRAPPER void CMenuManager::DrawFrontEnd(void) { EAXJMP(0x47A540); }
-#else
void CMenuManager::DrawFrontEnd()
{
CFont::SetAlphaFade(255.0f);
@@ -833,27 +991,73 @@ void CMenuManager::DrawFrontEnd()
CMenuManager::DrawFrontEndNormal();
CMenuManager::PrintErrorMessage();
}
-#endif
-#if 0
-WRAPPER void CMenuManager::DrawFrontEndNormal(void) { EAXJMP(0x47A5B0); }
-#else
void CMenuManager::DrawFrontEndNormal()
{
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
-
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
LoadSplash(nil);
- eMenuSprites previousSprite = MENUSPRITE_MAINMENU; // actually uninitialized
+ eMenuSprites previousSprite;
if (m_nMenuFadeAlpha < 255) {
switch (m_nPrevScreen) {
+ case MENUPAGE_STATS:
+ case MENUPAGE_START_MENU:
+ case MENUPAGE_PAUSE_MENU:
+ previousSprite = MENUSPRITE_MAINMENU;
+ break;
+ case MENUPAGE_NEW_GAME:
+ case MENUPAGE_CHOOSE_LOAD_SLOT:
+ case MENUPAGE_CHOOSE_DELETE_SLOT:
+ case MENUPAGE_NEW_GAME_RELOAD:
+ case MENUPAGE_LOAD_SLOT_CONFIRM:
+ case MENUPAGE_DELETE_SLOT_CONFIRM:
+ case MENUPAGE_EXIT:
+ previousSprite = MENUSPRITE_SINGLEPLAYER;
+ break;
+ case MENUPAGE_MULTIPLAYER_MAIN:
+ previousSprite = MENUSPRITE_MULTIPLAYER;
+ break;
+ case MENUPAGE_MULTIPLAYER_MAP:
+ case MENUPAGE_MULTIPLAYER_FIND_GAME:
+ case MENUPAGE_SKIN_SELECT:
+ case MENUPAGE_KEYBOARD_CONTROLS:
+ case MENUPAGE_MOUSE_CONTROLS:
+ previousSprite = MENUSPRITE_FINDGAME;
+ break;
+ case MENUPAGE_MULTIPLAYER_CONNECTION:
+ case MENUPAGE_MULTIPLAYER_MODE:
+ previousSprite = MENUSPRITE_CONNECTION;
+ break;
+ case MENUPAGE_MULTIPLAYER_CREATE:
+ previousSprite = MENUSPRITE_HOSTGAME;
+ break;
+ case MENUPAGE_SKIN_SELECT_OLD:
+ case MENUPAGE_OPTIONS:
+ previousSprite = MENUSPRITE_PLAYERSET;
+ break;
+ default:
+ previousSprite = MENUSPRITE_MAINMENU;
+ break;
+ }
+
+ if (m_nPrevScreen == m_nCurrScreen)
+ CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255-m_nMenuFadeAlpha));
+ else
+ m_aMenuSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255-m_nMenuFadeAlpha));
+ }
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+
+ eMenuSprites currentSprite = MENUSPRITE_MAINMENU; // actually uninitialized
+ switch (m_nCurrScreen) {
case MENUPAGE_STATS:
case MENUPAGE_START_MENU:
case MENUPAGE_PAUSE_MENU:
- previousSprite = MENUSPRITE_MAINMENU;
+ currentSprite = MENUSPRITE_MAINMENU;
break;
case MENUPAGE_NEW_GAME:
case MENUPAGE_CHOOSE_LOAD_SLOT:
@@ -862,77 +1066,29 @@ void CMenuManager::DrawFrontEndNormal()
case MENUPAGE_LOAD_SLOT_CONFIRM:
case MENUPAGE_DELETE_SLOT_CONFIRM:
case MENUPAGE_EXIT:
- previousSprite = MENUSPRITE_SINGLEPLAYER;
+ currentSprite = MENUSPRITE_SINGLEPLAYER;
break;
case MENUPAGE_MULTIPLAYER_MAIN:
- previousSprite = MENUSPRITE_MULTIPLAYER;
+ currentSprite = MENUSPRITE_MULTIPLAYER;
break;
case MENUPAGE_MULTIPLAYER_MAP:
case MENUPAGE_MULTIPLAYER_FIND_GAME:
case MENUPAGE_SKIN_SELECT:
case MENUPAGE_KEYBOARD_CONTROLS:
case MENUPAGE_MOUSE_CONTROLS:
- previousSprite = MENUSPRITE_FINDGAME;
+ currentSprite = MENUSPRITE_FINDGAME;
break;
case MENUPAGE_MULTIPLAYER_CONNECTION:
case MENUPAGE_MULTIPLAYER_MODE:
- previousSprite = MENUSPRITE_CONNECTION;
+ currentSprite = MENUSPRITE_CONNECTION;
break;
case MENUPAGE_MULTIPLAYER_CREATE:
- previousSprite = MENUSPRITE_HOSTGAME;
+ currentSprite = MENUSPRITE_HOSTGAME;
break;
case MENUPAGE_SKIN_SELECT_OLD:
case MENUPAGE_OPTIONS:
- previousSprite = MENUSPRITE_PLAYERSET;
+ currentSprite = MENUSPRITE_PLAYERSET;
break;
- }
-
- if (m_nPrevScreen == m_nCurrScreen)
- CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255-m_nMenuFadeAlpha));
- else
- m_aMenuSprites[previousSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255-m_nMenuFadeAlpha));
- }
-
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
-
- eMenuSprites currentSprite = MENUSPRITE_MAINMENU; // actually uninitialized
- switch (m_nCurrScreen) {
- case MENUPAGE_STATS:
- case MENUPAGE_START_MENU:
- case MENUPAGE_PAUSE_MENU:
- currentSprite = MENUSPRITE_MAINMENU;
- break;
- case MENUPAGE_NEW_GAME:
- case MENUPAGE_CHOOSE_LOAD_SLOT:
- case MENUPAGE_CHOOSE_DELETE_SLOT:
- case MENUPAGE_NEW_GAME_RELOAD:
- case MENUPAGE_LOAD_SLOT_CONFIRM:
- case MENUPAGE_DELETE_SLOT_CONFIRM:
- case MENUPAGE_EXIT:
- currentSprite = MENUSPRITE_SINGLEPLAYER;
- break;
- case MENUPAGE_MULTIPLAYER_MAIN:
- currentSprite = MENUSPRITE_MULTIPLAYER;
- break;
- case MENUPAGE_MULTIPLAYER_MAP:
- case MENUPAGE_MULTIPLAYER_FIND_GAME:
- case MENUPAGE_SKIN_SELECT:
- case MENUPAGE_KEYBOARD_CONTROLS:
- case MENUPAGE_MOUSE_CONTROLS:
- currentSprite = MENUSPRITE_FINDGAME;
- break;
- case MENUPAGE_MULTIPLAYER_CONNECTION:
- case MENUPAGE_MULTIPLAYER_MODE:
- currentSprite = MENUSPRITE_CONNECTION;
- break;
- case MENUPAGE_MULTIPLAYER_CREATE:
- currentSprite = MENUSPRITE_HOSTGAME;
- break;
- case MENUPAGE_SKIN_SELECT_OLD:
- case MENUPAGE_OPTIONS:
- currentSprite = MENUSPRITE_PLAYERSET;
- break;
}
if (m_nMenuFadeAlpha < 255) {
@@ -954,7 +1110,9 @@ void CMenuManager::DrawFrontEndNormal()
m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
// TODO: what is this? waiting mouse?
if(field_518 == 4){
- if(m_nHoverOption == 3 || m_nHoverOption == 4 || m_nHoverOption == 5 || m_nHoverOption == 6 || m_nHoverOption == 7)
+ if(m_nHoverOption == HOVEROPTION_3 || m_nHoverOption == HOVEROPTION_4 ||
+ m_nHoverOption == HOVEROPTION_5 || m_nHoverOption == HOVEROPTION_6 || m_nHoverOption == HOVEROPTION_7)
+
field_518 = 2;
else
field_518 = 1;
@@ -966,24 +1124,24 @@ void CMenuManager::DrawFrontEndNormal()
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
- m_aMenuSprites[MENUSPRITE_GTA3LOGO].Draw(CRect((SCREEN_WIDTH / 2) - SCREEN_SCALE_X(115.0f), SCREEN_SCALE_Y(70.0f), (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(115.0f), SCREEN_SCALE_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255)));
+ m_aMenuSprites[MENUSPRITE_GTA3LOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), StretchY(70.0f), MENU_X_LEFT_ALIGNED(435.0f), StretchY(180.0f)), CRGBA(255, 255, 255, FadeIn(255)));
else
- m_aMenuSprites[MENUSPRITE_GTALOGO].Draw(CRect((SCREEN_WIDTH / 2) - SCREEN_SCALE_X(95.0f), SCREEN_SCALE_Y(40.0f), (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(95.0f), SCREEN_SCALE_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255)));
+ m_aMenuSprites[MENUSPRITE_GTALOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), StretchY(40.0f), MENU_X_LEFT_ALIGNED(415.0f), StretchY(210.0f)), CRGBA(255, 255, 255, FadeIn(255)));
}
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
switch (m_nCurrScreen) {
- case MENUPAGE_SKIN_SELECT:
- CMenuManager::DrawPlayerSetupScreen();
- break;
- case MENUPAGE_KEYBOARD_CONTROLS:
- CMenuManager::DrawControllerSetupScreen();
- break;
- default:
- CMenuManager::Draw();
- break;
+ case MENUPAGE_SKIN_SELECT:
+ CMenuManager::DrawPlayerSetupScreen();
+ break;
+ case MENUPAGE_KEYBOARD_CONTROLS:
+ CMenuManager::DrawControllerSetupScreen();
+ break;
+ default:
+ CMenuManager::Draw();
+ break;
}
CFont::DrawFonts();
@@ -996,20 +1154,22 @@ void CMenuManager::DrawFrontEndNormal()
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- CRect mouse(0.0f, 0.0f, SCREEN_SCALE_X(75.0f), SCREEN_SCALE_Y(75.0f));
+ CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f));
+ CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f));
+
mouse.Translate(m_nMousePosX, m_nMousePosY);
- CRect shad = mouse;
- shad.Translate(SCREEN_SCALE_X(10.0f), SCREEN_SCALE_Y(3.0f));
+ shad.Translate(m_nMousePosX, m_nMousePosY);
if(field_518 == 4){
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50));
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255));
}else{
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
}
}
}
-#endif
#if 1
WRAPPER void CMenuManager::DrawPlayerSetupScreen() { EAXJMP(0x47F2B0); }
@@ -1078,78 +1238,80 @@ void CMenuManager::InitialiseChangedLanguageSettings()
}
#endif
-#if ALL_ORIGINAL_FRONTEND
-WRAPPER void CMenuManager::LoadAllTextures() { EAXJMP(0x47A230); }
-#else
void CMenuManager::LoadAllTextures()
{
- if (!m_bSpritesLoaded) {
- CMenuManager::CentreMousePointer();
- DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
- m_nCurrOption = 0;
- m_PrefsRadioStation = DMAudio.GetRadioInCar();
+ if (m_bSpritesLoaded)
+ return;
- if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (CMenuManager::m_PrefsRadioStation > USERTRACK)
- CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
- }
- else if (CMenuManager::m_PrefsRadioStation > CHATTERBOX)
- CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
+ CMenuManager::CentreMousePointer();
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
+ m_nCurrOption = 0;
+ m_PrefsRadioStation = DMAudio.GetRadioInCar();
+
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ if (CMenuManager::m_PrefsRadioStation > USERTRACK)
+ CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
+ } else if (CMenuManager::m_PrefsRadioStation > CHATTERBOX)
+ CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
- CFileMgr::SetDir("");
- CTimer::Stop();
- CStreaming::MakeSpaceFor(700 * 1024);
- CStreaming::ImGonnaUseStreamingMemory();
- CTxdStore::PushCurrentTxd();
-
- int frontend = CTxdStore::AddTxdSlot("frontend");
- CTxdStore::LoadTxd(frontend, "MODELS/FRONTEND.TXD");
- CTxdStore::AddRef(frontend);
- CTxdStore::SetCurrentTxd(frontend);
- CStreaming::IHaveUsedStreamingMemory();
- CTimer::Update();
-
- debug("LOAD frontend\n");
- for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) {
- m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i]);
- m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
- }
-
- CTxdStore::PopCurrentTxd();
+ CFileMgr::SetDir("");
+ //CFileMgr::SetDir("");
+ CTimer::Stop();
+ CStreaming::MakeSpaceFor(350 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile
+ CStreaming::ImGonnaUseStreamingMemory();
+ CGame::TidyUpMemory(false, true);
+ CTxdStore::PushCurrentTxd();
+ int frontendTxdSlot = CTxdStore::FindTxdSlot("frontend");
+
+ if(frontendTxdSlot == -1)
+ frontendTxdSlot = CTxdStore::AddTxdSlot("frontend");
+
+ printf("LOAD frontend\n");
+ CTxdStore::LoadTxd(frontendTxdSlot, "MODELS/FRONTEND.TXD");
+ CTxdStore::AddRef(frontendTxdSlot);
+ CTxdStore::SetCurrentTxd(frontendTxdSlot);
+ CStreaming::IHaveUsedStreamingMemory();
+ CTimer::Update();
+
+ for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) {
+ m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]);
+ m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
+ }
- int menu = CTxdStore::AddTxdSlot("menu");
- CTxdStore::LoadTxd(menu, "MODELS/MENU.TXD");
- CTxdStore::AddRef(menu);
- CTxdStore::SetCurrentTxd(menu);
+ int menuTxdSlot = CTxdStore::FindTxdSlot("menu");
- debug("LOAD sprite\n");
- for (int i = 0; i < ARRAY_SIZE(MenuFilenames)/2; i++) {
- m_aMenuSprites[i].SetTexture(MenuFilenames[i*2], MenuFilenames[i*2+1]);
- m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
- }
+ if (menuTxdSlot == -1)
+ menuTxdSlot = CTxdStore::AddTxdSlot("menu");
- CTxdStore::PopCurrentTxd();
+ printf("LOAD sprite\n");
+ CTxdStore::LoadTxd(menuTxdSlot, "MODELS/MENU.TXD");
+ CTxdStore::AddRef(menuTxdSlot);
+ CTxdStore::SetCurrentTxd(menuTxdSlot);
- m_bSpritesLoaded = true;
+ for (int i = 0; i < ARRAY_SIZE(MenuFilenames); i++) {
+ m_aMenuSprites[i].SetTexture(MenuFilenames[i][0], MenuFilenames[i][1]);
+ m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
}
-}
-#endif
+ m_bSpritesLoaded = true;
+ CTxdStore::PopCurrentTxd();
+}
#if 0
WRAPPER void CMenuManager::LoadSettings() { EAXJMP(0x488EE0); }
#else
void CMenuManager::LoadSettings()
{
-
CFileMgr::SetDirMyDocuments();
+ int fileHandle = CFileMgr::OpenFile("gta3.set", "r");
int32 prevLang = m_PrefsLanguage;
CMBlur::BlurOn = true;
MousePointerStateHelper.bInvertVertically = true;
+ // 50 is silly
char Ver[50];
- int fileHandle = CFileMgr::OpenFile("gta3.set", "r");
+
if (fileHandle) {
CFileMgr::Read(fileHandle, Ver, 29);
@@ -1206,14 +1368,14 @@ void CMenuManager::LoadSettings()
m_bFrontEnd_ReloadObrTxtGxt = true;
InitialiseChangedLanguageSettings();
- debug("The previously saved language is now in use");
+ OutputDebugString("The previously saved language is now in use");
}
- struct _WIN32_FIND_DATAA FindFileData;
- char skinfile[256+16]; // ?? + 16?
+ WIN32_FIND_DATA FindFileData;
+ char skinfile[256+16]; // Stack analysis shows 16 bits gap, but I don't trust it. It may very well be MAX_PATH(260).
bool SkinFound = false;
- HANDLE handle = FindFirstFileA("skins\\*.bmp", &FindFileData);
- for (int i = 1; handle != (HANDLE)-1 && i; i = FindNextFileA(handle, &FindFileData)) {
+ HANDLE handle = FindFirstFile("skins\\*.bmp", &FindFileData);
+ for (int i = 1; handle != INVALID_HANDLE_VALUE && i; i = FindNextFile(handle, &FindFileData)) {
strcpy(skinfile, m_PrefsSkinFile);
strcat(skinfile, ".bmp");
if (strcmp(FindFileData.cFileName, skinfile) == 0)
@@ -1222,7 +1384,7 @@ void CMenuManager::LoadSettings()
FindClose(handle);
if (!SkinFound) {
- debug("Default skin set as no other skins are available OR saved skin not found!");
+ OutputDebugString("Default skin set as no other skins are available OR saved skin not found!");
strcpy(m_PrefsSkinFile, "$$\"\"");
strcpy(m_aSkinName, "$$\"\"");
}
@@ -1238,9 +1400,8 @@ void CMenuManager::SaveSettings()
CFileMgr::SetDirMyDocuments();
- int fileHandle = CFileMgr::OpenFile("gta3.set", "w");
+ int fileHandle = CFileMgr::OpenFile("gta3.set", "w+");
if (fileHandle) {
-
ControlsManager.SaveSettings(fileHandle);
CFileMgr::Write(fileHandle, RubbishString, 20);
CFileMgr::Write(fileHandle, RubbishString, 20);
@@ -1266,7 +1427,7 @@ void CMenuManager::SaveSettings()
CFileMgr::Write(fileHandle, (char*)&m_PrefsUseWideScreen, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsFrameLimiter, 1);
- CFileMgr::Write(fileHandle, (char*)&m_nDisplayVideoMode, 1);
+ CFileMgr::Write(fileHandle, (char*)&m_nPrefsVideoMode, 1);
CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1);
CFileMgr::Write(fileHandle, m_PrefsSkinFile, 256);
CFileMgr::Write(fileHandle, (char*)&m_ControlMethod, 1);
@@ -1398,10 +1559,10 @@ void CMenuManager::Process(void)
if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service();
- m_bStartGameLoading = 1;
+ m_bStartGameLoading = true;
RequestFrontEndShutdown();
- m_bLoadingSavedGame = 1;
- b_FoundRecentSavedGameWantToLoad = 1;
+ m_bLoadingSavedGame = true;
+ b_FoundRecentSavedGameWantToLoad = true;
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
@@ -1483,9 +1644,9 @@ void CMenuManager::Process(void)
}
// Reset pad shaking.
- if (VibrationTime && CTimer::GetTimeInMillisecondsPauseMode() > VibrationTime) {
+ if (TimeToStopPadShaking && TimeToStopPadShaking < CTimer::GetTimeInMillisecondsPauseMode()) {
CPad::StopPadsShaking();
- VibrationTime = 0;
+ TimeToStopPadShaking = 0;
}
} else {
@@ -1780,7 +1941,7 @@ void CMenuManager::ProcessOnOffMenuOptions()
if (m_PrefsUseVibration) {
CPad::GetPad(0)->StartShake(350, 150);
- VibrationTime = CTimer::GetTimeInMillisecondsPauseMode() + 500;
+ TimeToStopPadShaking = CTimer::GetTimeInMillisecondsPauseMode() + 500;
}
SaveSettings();
break;
@@ -2155,40 +2316,44 @@ void CMenuManager::ResetHelperText()
}
#endif
-#if ALL_ORIGINAL_FRONTEND
-WRAPPER void CMenuManager::SaveLoadFileError_SetUpErrorScreen() { EAXJMP(0x488930); }
-#else
void CMenuManager::SaveLoadFileError_SetUpErrorScreen()
{
+ // TO-DO: Enum
switch (PcSaveHelper.m_nHelper) {
- case 1:
- case 2:
- case 3:
- SwitchToNewScreen(MENUPAGE_SAVE_FAILED);
- m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
- break;
- break;
- case 4:
- case 5:
- case 6:
- SwitchToNewScreen(MENUPAGE_LOAD_FAILED);
- m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
- break;
- case 7:
- SwitchToNewScreen(MENUPAGE_LOAD_FAILED_2);
- m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
- break;
- case 8:
- case 9:
- case 10:
- SwitchToNewScreen(MENUPAGE_DELETE_FAILED);
- m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
- break;
- default:
- return;
+ case 1:
+ case 2:
+ case 3:
+ m_nPrevScreen = m_nCurrScreen;
+ m_nCurrScreen = MENUPAGE_SAVE_FAILED;
+ m_nCurrOption = 0;
+ m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ break;
+ case 4:
+ case 5:
+ case 6:
+ m_nPrevScreen = m_nCurrScreen;
+ m_nCurrScreen = MENUPAGE_LOAD_FAILED;
+ m_nCurrOption = 0;
+ m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ break;
+ case 7:
+ m_nPrevScreen = m_nCurrScreen;
+ m_nCurrScreen = MENUPAGE_LOAD_FAILED_2;
+ m_nCurrOption = 0;
+ m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ break;
+ case 8:
+ case 9:
+ case 10:
+ m_nPrevScreen = m_nCurrScreen;
+ m_nCurrScreen = MENUPAGE_DELETE_FAILED;
+ m_nCurrOption = 0;
+ m_nScreenChangeDelayTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ break;
+ default:
+ return;
}
}
-#endif
#if ALL_ORIGINAL_FRONTEND
WRAPPER void CMenuManager::SetHelperText(int text) { EAXJMP(0x48B450); }
@@ -2210,33 +2375,23 @@ void CMenuManager::ShutdownJustMenu()
}
#endif
-#if ALL_ORIGINAL_FRONTEND
-WRAPPER float CMenuManager::StretchX(float) { EAXJMP(0x48ABE0); }
-#else
float CMenuManager::StretchX(float x)
{
- if (SCREEN_WIDTH == 640)
+ if (SCREEN_WIDTH == DEFAULT_SCREEN_WIDTH)
return x;
else
-#ifndef ASPECT_RATIO_SCALE
- return SCREEN_WIDTH * x * 0.0015625f;
-#else
- return SCREEN_SCALE_X(x);
-#endif
+ // We won't make this SCREEN_SCALE, because many cases relies on stretching and we want the code to be portable.
+ // Instead we will use MENU_X_LEFT_ALIGNED or SCREEN_SCALE_X when needed.
+ return SCREEN_STRETCH_X(x);
}
-#endif
-#if ALL_ORIGINAL_FRONTEND
-WRAPPER float CMenuManager::StretchY(float) { EAXJMP(0x48AC20); }
-#else
float CMenuManager::StretchY(float y)
{
- if (SCREEN_HEIGHT == 448)
+ if (SCREEN_HEIGHT == DEFAULT_SCREEN_HEIGHT)
return y;
else
- return SCREEN_HEIGHT * y * 0.002232143f;
+ return SCREEN_STRETCH_Y(y);
}
-#endif
#if ALL_ORIGINAL_FRONTEND
WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); }
@@ -2580,20 +2735,19 @@ bool GetMouseInput()
STARTPATCHES
#if ALL_ORIGINAL_FRONTEND
#else
- InjectHook(0x47A230, &CMenuManager::LoadAllTextures, PATCH_JUMP);
InjectHook(0x47A440, &CMenuManager::UnloadTextures, PATCH_JUMP);
- InjectHook(0x485100, &CMenuManager::Process, PATCH_JUMP);
InjectHook(0x4856F0, &CMenuManager::ProcessButtonPresses, PATCH_JUMP);
InjectHook(0x48AE60, &CMenuManager::ProcessOnOffMenuOptions, PATCH_JUMP);
- InjectHook(0x488EE0, &CMenuManager::LoadSettings, PATCH_JUMP);
- InjectHook(0x488CC0, &CMenuManager::SaveSettings, PATCH_JUMP);
- InjectHook(0x48ABE0, &CMenuManager::StretchX, PATCH_JUMP);
- InjectHook(0x48AC20, &CMenuManager::StretchY, PATCH_JUMP);
for (int i = 1; i < ARRAY_SIZE(aScreens); i++)
Patch(0x611930 + sizeof(CMenuScreen) * i, aScreens[i]);
#endif
+ InjectHook(0x485100, &CMenuManager::Process, PATCH_JUMP);
+ InjectHook(0x47A230, &CMenuManager::LoadAllTextures, PATCH_JUMP);
+ InjectHook(0x47A540, &CMenuManager::DrawFrontEnd, PATCH_JUMP);
+ InjectHook(0x48ABE0, &CMenuManager::StretchX, PATCH_JUMP);
+ InjectHook(0x48AC20, &CMenuManager::StretchY, PATCH_JUMP);
InjectHook(0x488EE0, &CMenuManager::LoadSettings, PATCH_JUMP);
InjectHook(0x488CC0, &CMenuManager::SaveSettings, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index e1ee5b31..ed7cd2c3 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -7,10 +7,10 @@
#define MENUHEADER_WIDTH 0.84f
#define MENUHEADER_HEIGHT 1.6f
-#define MENUACTION_POS_X 20.0f
+#define MENUACTION_POS_X 40.0f
#define MENUACTION_POS_Y 37.5f
-#define MENUACTION_WIDTH 0.675f
-#define MENUACTION_HEIGHT 0.81f
+#define MENUACTION_WIDTH 0.405f
+#define MENUACTION_HEIGHT 0.63f
#define MENUCOLUMN_POS_X MENUHEADER_POS_X + 16.0f
#define MENUCOLUMN_MAX_Y 149.0f
@@ -466,9 +466,13 @@ public:
static bool &m_bStartUpFrontEndRequested;
static bool &m_bShutDownFrontEndRequested;
static bool &m_PrefsAllowNastyGame;
+
+ static float &headingYStart;
+ static float &unkX;
+ static float &unkY;
public:
- void BuildStatLine(char *text, float *stat, bool aFloat, float* stat2);
+ static void BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2);
static void CentreMousePointer();
int CheckCodesForControls(int32);
bool CheckHover(int x1, int x2, int y1, int y2);
diff --git a/src/core/General.h b/src/core/General.h
index d73cf36f..a7b240c2 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -104,6 +104,29 @@ public:
return (int)floorf(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 faststricmp(const char *str1, const char *str2)
+ {
+ for (; *str1; str1++, str2++) {
+#if MUCH_SLOWER
+ 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; }
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index e5178ef3..51102c7b 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -36,7 +36,7 @@ CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
CKeyboardState &CPad::NewKeyState = *(CKeyboardState*)0x6E60D0;
CKeyboardState &CPad::TempKeyState = *(CKeyboardState*)0x774DE8;
-char CPad::KeyBoardCheatString[18];
+char CPad::KeyBoardCheatString[20];
CMouseControllerState &CPad::OldMouseControllerState = *(CMouseControllerState*)0x8472A0;
CMouseControllerState &CPad::NewMouseControllerState = *(CMouseControllerState*)0x8809F0;
@@ -427,7 +427,7 @@ void CPad::StartShake_Train(float fX, float fY)
void CPad::AddToPCCheatString(char c)
{
- for ( int32 i = ARRAY_SIZE(KeyBoardCheatString); i >= 0; i-- )
+ for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
KeyBoardCheatString[i + 1] = KeyBoardCheatString[i];
KeyBoardCheatString[0] = c;
diff --git a/src/core/Pad.h b/src/core/Pad.h
index 89ec4aa2..03b734cb 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -7,7 +7,7 @@ enum {
PLAYERCONTROL_DISABLED_4 = 4,
PLAYERCONTROL_DISABLED_8 = 8,
PLAYERCONTROL_DISABLED_10 = 16,
- PLAYERCONTROL_DISABLED_20 = 32,
+ PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe
PLAYERCONTROL_DISABLED_40 = 64, // used on phone calls
PLAYERCONTROL_DISABLED_80 = 128,
};
@@ -166,7 +166,7 @@ public:
static CKeyboardState &OldKeyState;
static CKeyboardState &NewKeyState;
static CKeyboardState &TempKeyState;
- static char KeyBoardCheatString[18];
+ static char KeyBoardCheatString[20];
static CMouseControllerState &OldMouseControllerState;
static CMouseControllerState &NewMouseControllerState;
static CMouseControllerState &PCTempMouseControllerState;
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index f0b7d444..fcdd60da 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -1,18 +1,32 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
#include "PlayerPed.h"
#include "PlayerInfo.h"
#include "Frontend.h"
-#include "Vehicle.h"
#include "PlayerSkin.h"
#include "Darkel.h"
#include "Messages.h"
#include "Text.h"
#include "Stats.h"
-
-WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); }
-WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); }
-WRAPPER void CPlayerInfo::Process(void) { EAXJMP(0x49FD30); }
+#include "Remote.h"
+#include "World.h"
+#include "Replay.h"
+#include "Pad.h"
+#include "ProjectileInfo.h"
+#include "Explosion.h"
+#include "Script.h"
+#include "Automobile.h"
+#include "HandlingMgr.h"
+#include "General.h"
+#include "SpecialFX.h"
+#include "Cranes.h"
+#include "Bridge.h"
+#include "WaterLevel.h"
+#include "PathFind.h"
+#include "ZoneCull.h"
+#include "Renderer.h"
+#include "Streaming.h"
void
CPlayerInfo::SetPlayerSkin(char *skin)
@@ -24,7 +38,7 @@ CPlayerInfo::SetPlayerSkin(char *skin)
CVector&
CPlayerInfo::GetPos()
{
- if (m_pPed->bInVehicle && m_pPed->m_pMyVehicle)
+ if (m_pPed->InVehicle())
return m_pPed->m_pMyVehicle->GetPosition();
return m_pPed->GetPosition();
}
@@ -44,7 +58,7 @@ CPlayerInfo::DeletePlayerSkin()
{
if (m_pSkinTexture) {
RwTextureDestroy(m_pSkinTexture);
- m_pSkinTexture = NULL;
+ m_pSkinTexture = nil;
}
}
@@ -88,9 +102,473 @@ CPlayerInfo::PlayerFailedCriticalMission()
CDarkel::ResetOnPlayerDeath();
}
+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::BlowUpRCBuggy(void)
+{
+ if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
+ return;
+
+ CRemote::TakeRemoteControlledCarFromPlayer();
+ m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
+}
+
+void
+CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
+{
+ if (!car || car == m_pPed->m_pMyVehicle) {
+ if (m_pPed->m_nPedState == PED_CARJACK || m_pPed->m_nPedState == PED_ENTER_CAR)
+ 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::CountdownToMakePlayerUnsafe = 0;
+ m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
+ CWorld::StopAllLawEnforcersInTheirTracks();
+ CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
+ 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(false);
+ 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::CountdownToMakePlayerUnsafe) {
+ m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
+ CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
+ m_pPed->bBulletProof = false;
+ m_pPed->bFireProof = false;
+ m_pPed->bCollisionProof = false;
+ m_pPed->bMeleeProof = false;
+ m_pPed->bOnlyDamagedByPlayer = false;
+ m_pPed->bExplosionProof = false;
+ m_pPed->m_bCanBeDamaged = true;
+ CWorld::SetAllCarsCanBeDamaged(true);
+ CReplay::EnableReplays();
+ }
+}
+
+bool
+CPlayerInfo::IsRestartingAfterDeath()
+{
+ return m_WBState == WBSTATE_WASTED;
+}
+
+bool
+CPlayerInfo::IsRestartingAfterArrest()
+{
+ return m_WBState == WBSTATE_BUSTED;
+}
+
+// lastClosestness is passed to other calls of this function
+void
+CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastClosestness, 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 closestness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
+ if (closestness > *lastClosestness) {
+ *lastClosestness = closestness;
+ *closestCarOutput = (CVehicle*)carToTest;
+ }
+}
+
+// There is something unfinished in here... Sadly all IDBs we have have it unfinished.
+void
+CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
+{
+ if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
+ ++m_nExplosionsSinceLastReward;
+ else
+ m_nExplosionsSinceLastReward = 1;
+
+ m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
+ int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
+ sprintf(gString, "$%d", award);
+#ifdef MONEY_MESSAGES
+ // This line is a leftover from PS2, I don't know what it was meant to be.
+ // CVector sth(TheCamera.GetPosition() * 4.0f);
+
+ CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
+#endif
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
+
+ for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
+ CGeneral::GetRandomNumber();
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
+ }
+}
+
+void
+CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
+{
+ // Interesting
+ *size = sizeof(CPlayerInfo);
+
+INITSAVEBUF
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
+ for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i]);
+ }
+// Save struct is different
+// VALIDATESAVEBUF(*size)
+}
+
+void
+CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
+{
+INITSAVEBUF
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = ReadSaveBuf<uint32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_WBState = ReadSaveBuf<int8>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nWBTime = ReadSaveBuf<uint32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier = ReadSaveBuf<int16>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity = ReadSaveBuf<float>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney = ReadSaveBuf<int32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages = ReadSaveBuf<int32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ReadSaveBuf<int32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint = ReadSaveBuf<bool>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bFastReload = ReadSaveBuf<bool>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree = ReadSaveBuf<bool>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree = ReadSaveBuf<bool>(buf);
+ for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
+ CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i] = ReadSaveBuf<char>(buf);
+ }
+// Save struct is different
+// VALIDATESAVEBUF(size)
+}
+
+void
+CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastClosestness, 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->m_status != STATUS_WRECKED && car->m_status != 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, lastClosestness, closestCarOutput);
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CPlayerInfo::Process(void)
+{
+ // 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->m_modelIndex == MI_TAXI || veh->m_modelIndex == MI_CABBIE || veh->m_modelIndex == 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->m_ped_flagI4 && 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_ODE) {
+ if (m_pPed->bInVehicle) {
+ if (!m_pRemoteVehicle) {
+ CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
+ if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->m_modelIndex)) {
+ 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->m_status != STATUS_WRECKED && veh->m_status != 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_VEHICLE, 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->m_nPedState = PED_IDLE;
+ m_pPed->SetMoveState(PEDMOVE_STILL);
+ CPed::PedSetOutCarCB(0, m_pPed);
+ CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
+ CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f);
+ m_pPed->GetPosition() = 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 lastClosestness = 0.0f;
+ CVehicle *carBelow;
+ 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->m_status != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
+#else
+ if (carBelow->m_status != 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, &lastClosestness, &carBelow);
+ FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], m_pPed,
+ minX, minY, maxX, maxY, &lastClosestness, &carBelow);
+ }
+ }
+ }
+ // carBelow is now closest vehicle
+ if (carBelow && !weAreOnBoat) {
+ if (carBelow->m_status == STATUS_TRAIN_NOT_MOVING) {
+ m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow);
+ } else if (carBelow->IsBoat()) {
+ if (!carBelow->pDriver) {
+ m_pPed->m_vehEnterType = 0;
+ m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType);
+ }
+ } 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, 0);
+ }
+ if (timeWithoutRemoteCar > 2000) {
+ if (m_WBState == WBSTATE_PLAYING) {
+ TheCamera.RestoreWithJumpCut();
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(1.0f, 1);
+ 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()->m_status = 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 = -1;
+ for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
+ if (veh->pPassengers[i])
+ veh->pPassengers[i]->m_nZoneLevel = 0;
+ }
+ CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
+ } else {
+ CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
+ }
+}
+
STARTPATCHES
-InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP);
-InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP);
-InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP);
-InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP);
+ InjectHook(0x4B5DC0, &CPlayerInfo::dtor, PATCH_JUMP);
+ InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP);
+ InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP);
+ InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP);
+ InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP);
+ InjectHook(0x49FC10, &CPlayerInfo::Clear, PATCH_JUMP);
+ InjectHook(0x4A15C0, &CPlayerInfo::BlowUpRCBuggy, PATCH_JUMP);
+ InjectHook(0x4A13B0, &CPlayerInfo::CancelPlayerEnteringCars, PATCH_JUMP);
+ InjectHook(0x4A1400, &CPlayerInfo::MakePlayerSafe, PATCH_JUMP);
+ InjectHook(0x4A0EC0, &CPlayerInfo::EvaluateCarPosition, PATCH_JUMP);
+ InjectHook(0x4A15F0, &CPlayerInfo::AwardMoneyForExplosion, PATCH_JUMP);
+ InjectHook(0x4A0B20, &CPlayerInfo::LoadPlayerInfo, PATCH_JUMP);
+ InjectHook(0x4A0960, &CPlayerInfo::SavePlayerInfo, PATCH_JUMP);
+ InjectHook(0x49FD30, &CPlayerInfo::Process, PATCH_JUMP);
ENDPATCHES
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index ef21fb52..19c5ce23 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -10,6 +10,8 @@ enum eWastedBustedState
WBSTATE_FAILED_CRITICAL_MISSION,
};
+class CEntity;
+class CPed;
class CVehicle;
class CPlayerPed;
class CCivilianPed;
@@ -27,20 +29,20 @@ public:
int32 m_nCollectedPackages;
int32 m_nTotalPackages;
uint32 m_nLastBumpPlayerCarTimer;
- int32 m_nSwitchTaxiTime;
- bool m_bSwitchTaxi;
+ uint32 m_nUnusedTaxiTimer;
+ bool m_bUnusedTaxiThing;
int8 field_197;
int8 field_198;
int8 field_199;
- int32 m_nNextSexFrequencyUpdateTime;
- int32 m_nNextSexMoneyUpdateTime;
+ uint32 m_nNextSexFrequencyUpdateTime;
+ uint32 m_nNextSexMoneyUpdateTime;
int32 m_nSexFrequency;
CCivilianPed *m_pHooker;
int8 m_WBState; // eWastedBustedState
int8 field_217;
int8 field_218;
int8 field_219;
- int32 m_nWBTime;
+ uint32 m_nWBTime;
bool m_bInRemoteMode;
int8 field_225;
int8 field_226;
@@ -55,7 +57,7 @@ public:
int8 field_254;
int8 field_255;
float m_fRoadDensity;
- int32 m_nPreviousTimeRewardedForExplosion;
+ uint32 m_nPreviousTimeRewardedForExplosion;
int32 m_nExplosionsSinceLastReward;
int32 field_268;
int32 field_272;
@@ -77,6 +79,18 @@ public:
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**);
+
+ ~CPlayerInfo() { };
+ void dtor(void) { this->CPlayerInfo::~CPlayerInfo(); }
};
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
diff --git a/src/core/PlayerSkin.cpp b/src/core/PlayerSkin.cpp
index 82427491..4d2c31df 100644
--- a/src/core/PlayerSkin.cpp
+++ b/src/core/PlayerSkin.cpp
@@ -28,7 +28,7 @@ FindPlayerDff(uint32 &offset, uint32 &size)
do {
if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
return;
- } while (strcmpi("player.dff", info.name));
+ } while (strcasecmp("player.dff", info.name) != 0);
offset = info.offset;
size = info.size;
@@ -94,7 +94,7 @@ CPlayerSkin::GetSkinTexture(const char *texName)
CTxdStore::PopCurrentTxd();
if (tex) return tex;
- if (!strcmp(DEFAULT_SKIN_NAME, texName))
+ if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
sprintf(gString, "models\\generic\\player.bmp");
else
sprintf(gString, "skins\\%s.bmp", texName);
diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp
index f06e5317..ab7de13e 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -312,7 +312,7 @@ void CRadar::DrawBlips()
break;
case BLIP_CHAR:
blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) {
+ if (blipEntity && ((CPed*)blipEntity)->InVehicle()) {
blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
}
break;
@@ -415,7 +415,7 @@ void CRadar::DrawBlips()
break;
case BLIP_CHAR:
blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) {
+ if (blipEntity && ((CPed*)blipEntity)->InVehicle()) {
blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
}
break;
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index 5d2401ed..17c3d9d7 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -12,6 +12,8 @@ int32 *CStats::PedsKilledOfThisType = (int32*)0x880DBC;
int32 &CStats::TimesDied = *(int32*)0x8E2BDC;
int32 &CStats::TimesArrested = *(int32*)0x8E2BEC;
int32 &CStats::KillsSinceLastCheckpoint = *(int32*)0x8F2C8C;
+int32& CStats::DistanceTravelledInVehicle = *(int32*)0x940574;
+int32& CStats::DistanceTravelledOnFoot = *(int32*)0x941518;
int32 &CStats::ProgressMade = *(int32*)0x8F6224;
int32 &CStats::TotalProgressInGame = *(int32*)0x885B2C;
float &CStats::MaximumJumpDistance = *(float*)0x8F2BDC;
diff --git a/src/core/Stats.h b/src/core/Stats.h
index 22f0c68a..add4320b 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -14,6 +14,8 @@ public:
static int32 &TimesDied;
static int32 &TimesArrested;
static int32 &KillsSinceLastCheckpoint;
+ static int32 &DistanceTravelledInVehicle;
+ static int32 &DistanceTravelledOnFoot;
static int32 &ProgressMade;
static int32 &TotalProgressInGame;
static float &MaximumJumpDistance;
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index 69e14869..b0933063 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -1,5 +1,6 @@
#include "common.h"
#include "patcher.h"
+#include "General.h"
#include "Pad.h"
#include "Hud.h"
#include "Text.h"
@@ -347,7 +348,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
if(direntry.size > (uint32)ms_streamingBufferSize)
ms_streamingBufferSize = direntry.size;
- if(strcmp(dot+1, "DFF") == 0 || strcmp(dot+1, "dff") == 0){
+ if(!CGeneral::faststrcmp(dot+1, "DFF") || !CGeneral::faststrcmp(dot+1, "dff")){
if(CModelInfo::GetModelInfo(direntry.name, &modelId)){
if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){
debug("%s appears more than once in %s\n", direntry.name, dirname);
@@ -364,20 +365,20 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
ms_pExtraObjectsDir->AddItem(direntry);
lastID = -1;
}
- }else if(strcmp(dot+1, "TXD") == 0 || strcmp(dot+1, "txd") == 0){
+ }else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){
txdId = CTxdStore::FindTxdSlot(direntry.name);
if(txdId == -1)
txdId = CTxdStore::AddTxdSlot(direntry.name);
- if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){
- debug("%s appears more than once in %s\n", direntry.name, dirname);
- lastID = -1;
- }else{
- direntry.offset |= imgSelector;
- ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size);
- if(lastID != -1)
- ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD;
- lastID = txdId + STREAM_OFFSET_TXD;
- }
+ if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){
+ debug("%s appears more than once in %s\n", direntry.name, dirname);
+ lastID = -1;
+ }else{
+ direntry.offset |= imgSelector;
+ ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size);
+ if(lastID != -1)
+ ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD;
+ lastID = txdId + STREAM_OFFSET_TXD;
+ }
}else
lastID = -1;
}
@@ -720,7 +721,7 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag
uint32 pos, size;
mi = CModelInfo::GetModelInfo(modelId);
- if(strcmp(mi->GetName(), modelName) == 0){
+ if(!CGeneral::faststrcmp(mi->GetName(), modelName)){
// Already have the correct name, just request it
RequestModel(modelId, flags);
return;
diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp
index d2d3f5fb..f7cf035e 100644
--- a/src/core/TempColModels.cpp
+++ b/src/core/TempColModels.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "TempColModels.h"
+#include "SurfaceTable.h"
CColModel &CTempColModels::ms_colModelPed1 = *(CColModel*)0x726CB0;
CColModel &CTempColModels::ms_colModelPed2 = *(CColModel*)0x726D08;
@@ -16,4 +17,277 @@ CColModel &CTempColModels::ms_colModelBoot1 = *(CColModel*)0x880670;
CColModel &CTempColModels::ms_colModelDoor1 = *(CColModel*)0x880850;
CColModel &CTempColModels::ms_colModelBonnet1 = *(CColModel*)0x8808A8;
-WRAPPER void CTempColModels::Initialise(void) { EAXJMP(0x412160); }
+
+CColSphere s_aPedSpheres[3];
+CColSphere s_aPed2Spheres[3];
+CColSphere s_aPedGSpheres[4];
+CColSphere s_aDoorSpheres[4];
+CColSphere s_aBumperSpheres[4];
+CColSphere s_aPanelSpheres[4];
+CColSphere s_aBonnetSpheres[4];
+CColSphere s_aBootSpheres[4];
+CColSphere s_aWheelSpheres[2];
+CColSphere s_aBodyPartSpheres1[2];
+CColSphere s_aBodyPartSpheres2[2];
+
+void
+CTempColModels::Initialise(void)
+{
+#define SET_COLMODEL_SPHERES(colmodel, sphrs)\
+ colmodel.numSpheres = ARRAYSIZE(sphrs);\
+ colmodel.spheres = sphrs;\
+ colmodel.level = LEVEL_NONE;\
+ colmodel.ownsCollisionVolumes = false;\
+
+ int i;
+
+ ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBBox.level = LEVEL_NONE;
+
+ for (i = 0; i < ARRAYSIZE(ms_colModelCutObj); i++) {
+ ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
+ ms_colModelCutObj[i].level = LEVEL_NONE;
+ }
+
+ // Ped Spheres
+
+ for (i = 0; i < ARRAYSIZE(s_aPedSpheres); i++)
+ s_aPedSpheres[i].radius = 0.35f;
+
+ s_aPedSpheres[0].center = CVector(0.0f, 0.0f, -0.25f);
+ s_aPedSpheres[1].center = CVector(0.0f, 0.0f, 0.15f);
+ s_aPedSpheres[2].center = CVector(0.0f, 0.0f, 0.55f);
+
+#ifdef FIX_BUGS
+ for (i = 0; i < ARRAYSIZE(s_aPedSpheres); i++) {
+#else
+ for (i = 0; i < ARRAYSIZE(s_aPedGSpheres); i++) {
+#endif
+ s_aPedSpheres[i].surface = SURFACE_FLESH;
+ s_aPedSpheres[i].piece = 0;
+ }
+
+ ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0);
+ SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
+
+ // Ped 2 Spheres
+
+ s_aPed2Spheres[0].radius = 0.3f;
+ s_aPed2Spheres[1].radius = 0.4f;
+ s_aPed2Spheres[2].radius = 0.3f;
+
+ s_aPed2Spheres[0].center = CVector(0.0f, 0.35f, -0.9f);
+ s_aPed2Spheres[1].center = CVector(0.0f, 0.0f, -0.9f);
+ s_aPed2Spheres[2].center = CVector(0.0f, -0.35f, -0.9f);
+
+ for (i = 0; i < ARRAYSIZE(s_aPed2Spheres); i++) {
+ s_aPed2Spheres[i].surface = SURFACE_FLESH;
+ s_aPed2Spheres[i].piece = 0;
+ }
+
+ ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres);
+
+ // Ped ground collision
+
+ s_aPedGSpheres[0].radius = 0.35f;
+ s_aPedGSpheres[1].radius = 0.35f;
+ s_aPedGSpheres[2].radius = 0.35f;
+ s_aPedGSpheres[3].radius = 0.3f;
+
+ s_aPedGSpheres[0].center = CVector(0.0f, -0.4f, -0.9f);
+ s_aPedGSpheres[1].center = CVector(0.0f, -0.1f, -0.9f);
+ s_aPedGSpheres[2].center = CVector(0.0f, 0.25f, -0.9f);
+ s_aPedGSpheres[3].center = CVector(0.0f, 0.65f, -0.9f);
+
+ s_aPedGSpheres[0].surface = SURFACE_FLESH;
+ s_aPedGSpheres[1].surface = SURFACE_FLESH;
+ s_aPedGSpheres[2].surface = SURFACE_FLESH;
+ s_aPedGSpheres[3].surface = SURFACE_FLESH;
+ s_aPedGSpheres[0].piece = 4;
+ s_aPedGSpheres[1].piece = 1;
+ s_aPedGSpheres[2].piece = 0;
+ s_aPedGSpheres[3].piece = 6;
+
+ ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres);
+
+ // Door Spheres
+
+ s_aDoorSpheres[0].radius = 0.15f;
+ s_aDoorSpheres[1].radius = 0.15f;
+ s_aDoorSpheres[2].radius = 0.25f;
+
+ s_aDoorSpheres[0].center = CVector(0.0f, -0.25f, -0.35f);
+ s_aDoorSpheres[1].center = CVector(0.0f, -0.95f, -0.35f);
+ s_aDoorSpheres[2].center = CVector(0.0f, -0.6f, 0.25f);
+
+ for (i = 0; i < ARRAYSIZE(s_aDoorSpheres); i++) {
+ s_aDoorSpheres[i].surface = SURFACE_BILLBOARD;
+ s_aDoorSpheres[i].piece = 0;
+ }
+
+ ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres);
+
+ // Bumper Spheres
+
+ for (i = 0; i < ARRAYSIZE(s_aBumperSpheres); i++)
+ s_aBumperSpheres[i].radius = 0.15f;
+
+ s_aBumperSpheres[0].center = CVector(0.85f, -0.05f, 0.0f);
+ s_aBumperSpheres[1].center = CVector(0.4f, 0.05f, 0.0f);
+ s_aBumperSpheres[2].center = CVector(-0.4f, 0.05f, 0.0f);
+ s_aBumperSpheres[3].center = CVector(-0.85f, -0.05f, 0.0f);
+
+ for (i = 0; i < ARRAYSIZE(s_aBumperSpheres); i++) {
+ s_aBumperSpheres[i].surface = SURFACE_BILLBOARD;
+ s_aBumperSpheres[i].piece = 0;
+ }
+
+ ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, -0.2f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres);
+
+ // Panel Spheres
+
+ for (i = 0; i < ARRAYSIZE(s_aPanelSpheres); i++)
+ s_aPanelSpheres[i].radius = 0.15f;
+
+ s_aPanelSpheres[0].center = CVector(0.15f, 0.45f, 0.0f);
+ s_aPanelSpheres[1].center = CVector(0.15f, -0.45f, 0.0f);
+ s_aPanelSpheres[2].center = CVector(-0.15f, -0.45f, 0.0f);
+ s_aPanelSpheres[3].center = CVector(-0.15f, 0.45f, 0.0f);
+
+ for (i = 0; i < ARRAYSIZE(s_aPanelSpheres); i++) {
+ s_aPanelSpheres[i].surface = SURFACE_BILLBOARD;
+ s_aPanelSpheres[i].piece = 0;
+ }
+
+ ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres);
+
+ // Bonnet Spheres
+
+ for (i = 0; i < ARRAYSIZE(s_aBonnetSpheres); i++)
+ s_aBonnetSpheres[i].radius = 0.2f;
+
+ s_aBonnetSpheres[0].center = CVector(-0.4f, 0.1f, 0.0f);
+ s_aBonnetSpheres[1].center = CVector(-0.4f, 0.9f, 0.0f);
+ s_aBonnetSpheres[2].center = CVector(0.4f, 0.1f, 0.0f);
+ s_aBonnetSpheres[3].center = CVector(0.4f, 0.9f, 0.0f);
+
+ for (i = 0; i < ARRAYSIZE(s_aBonnetSpheres); i++) {
+ s_aBonnetSpheres[i].surface = SURFACE_BILLBOARD;
+ s_aBonnetSpheres[i].piece = 0;
+ }
+
+ ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres);
+
+ // Boot Spheres
+
+ for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++)
+ s_aBootSpheres[i].radius = 0.2f;
+
+ s_aBootSpheres[0].center = CVector(-0.4f, -0.1f, 0.0f);
+ s_aBootSpheres[1].center = CVector(-0.4f, -0.6f, 0.0f);
+ s_aBootSpheres[2].center = CVector(0.4f, -0.1f, 0.0f);
+ s_aBootSpheres[3].center = CVector(0.4f, -0.6f, 0.0f);
+
+ for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+ s_aBootSpheres[i].surface = SURFACE_BILLBOARD;
+ s_aBootSpheres[i].piece = 0;
+ }
+
+ ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres);
+
+ // Wheel Spheres
+
+ s_aWheelSpheres[0].radius = 0.35f;
+ s_aWheelSpheres[1].radius = 0.35f;
+
+ s_aWheelSpheres[0].center = CVector(-0.3f, 0.0f, 0.0f);
+ s_aWheelSpheres[1].center = CVector(0.3f, 0.0f, 0.0f);
+
+#ifdef FIX_BUGS
+ for (i = 0; i < ARRAYSIZE(s_aWheelSpheres); i++) {
+#else
+ for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+#endif
+ s_aWheelSpheres[i].surface = SURFACE_RUBBER29;
+ s_aWheelSpheres[i].piece = 0;
+ }
+
+ ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres);
+
+ // Body Part Spheres 1
+
+ s_aBodyPartSpheres1[0].radius = 0.2f;
+ s_aBodyPartSpheres1[1].radius = 0.2f;
+
+ s_aBodyPartSpheres1[0].center = CVector(0.0f, 0.0f, 0.0f);
+ s_aBodyPartSpheres1[1].center = CVector(0.8f, 0.0f, 0.0f);
+
+#ifdef FIX_BUGS
+ for (i = 0; i < ARRAYSIZE(s_aBodyPartSpheres1); i++) {
+#else
+ for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+#endif
+ s_aBodyPartSpheres1[i].surface = SURFACE_FLESH;
+ s_aBodyPartSpheres1[i].piece = 0;
+ }
+
+ ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1);
+
+ // Body Part Spheres 2
+
+ s_aBodyPartSpheres2[0].radius = 0.15f;
+ s_aBodyPartSpheres2[1].radius = 0.15f;
+
+ s_aBodyPartSpheres2[0].center = CVector(0.0f, 0.0f, 0.0f);
+ s_aBodyPartSpheres2[1].center = CVector(0.5f, 0.0f, 0.0f);
+
+#ifdef FIX_BUGS
+ for (i = 0; i < ARRAYSIZE(s_aBodyPartSpheres2); i++) {
+#else
+ for (i = 0; i < ARRAYSIZE(s_aBootSpheres); i++) {
+#endif
+ s_aBodyPartSpheres2[i].surface = SURFACE_FLESH;
+ s_aBodyPartSpheres2[i].piece = 0;
+ }
+
+ ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0);
+
+ SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
+
+#undef SET_COLMODEL_SPHERES
+}
+
+STARTPATCHES
+ InjectHook(0x412160, CTempColModels::Initialise, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/core/TxdStore.cpp b/src/core/TxdStore.cpp
index 5085c7e4..ab970b99 100644
--- a/src/core/TxdStore.cpp
+++ b/src/core/TxdStore.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "templates.h"
+#include "General.h"
#include "Streaming.h"
#include "RwHelper.h"
#include "TxdStore.h"
@@ -61,7 +62,7 @@ CTxdStore::FindTxdSlot(const char *name)
int size = ms_pTxdPool->GetSize();
for(int i = 0; i < size; i++){
defname = GetTxdName(i);
- if(defname && _strcmpi(defname, name) == 0)
+ if(defname && !CGeneral::faststricmp(defname, name))
return i;
}
return -1;
diff --git a/src/core/User.cpp b/src/core/User.cpp
index 600fa443..488d64be 100644
--- a/src/core/User.cpp
+++ b/src/core/User.cpp
@@ -140,7 +140,7 @@ bool COnscreenTimerEntry::ProcessForDisplay() {
if(m_nTimerOffset != 0) {
m_bTimerProcessed = true;
- ProcessForDisplayTimer();
+ ProcessForDisplayClock();
}
if(m_nCounterOffset != 0) {
@@ -150,21 +150,21 @@ bool COnscreenTimerEntry::ProcessForDisplay() {
return true;
}
-int COnscreenTimerEntry::ProcessForDisplayTimer() {
+void COnscreenTimerEntry::ProcessForDisplayClock() {
uint32 time = *(uint32*)&CTheScripts::ScriptSpace[m_nTimerOffset];
- return sprintf(m_bTimerBuffer, "%02d:%02d", time / 1000 / 60,
+ sprintf(m_bTimerBuffer, "%02d:%02d", time / 1000 / 60,
time / 1000 % 60);
}
-int COnscreenTimerEntry::ProcessForDisplayCounter() {
+void COnscreenTimerEntry::ProcessForDisplayCounter() {
uint32 counter = *(uint32*)&CTheScripts::ScriptSpace[m_nCounterOffset];
- return sprintf(m_bCounterBuffer, "%d", counter);
+ sprintf(m_bCounterBuffer, "%d", counter);
}
STARTPATCHES
InjectHook(0x429160, &COnscreenTimerEntry::Process, PATCH_JUMP);
InjectHook(0x429110, &COnscreenTimerEntry::ProcessForDisplay, PATCH_JUMP);
- InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayTimer, PATCH_JUMP);
+ InjectHook(0x429080, &COnscreenTimerEntry::ProcessForDisplayClock, PATCH_JUMP);
InjectHook(0x4290F0, &COnscreenTimerEntry::ProcessForDisplayCounter, PATCH_JUMP);
InjectHook(0x429220, &COnscreenTimer::Init, PATCH_JUMP);
diff --git a/src/core/User.h b/src/core/User.h
index 90b2da55..03ba1bab 100644
--- a/src/core/User.h
+++ b/src/core/User.h
@@ -18,8 +18,8 @@ public:
void Process();
bool ProcessForDisplay();
- int ProcessForDisplayTimer();
- int ProcessForDisplayCounter();
+ void ProcessForDisplayClock();
+ void ProcessForDisplayCounter();
};
static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
diff --git a/src/core/World.cpp b/src/core/World.cpp
index ae0d67cc..dac64970 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -859,8 +859,8 @@ FindPlayerPed(void)
CVehicle*
FindPlayerVehicle(void)
{
- CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
- if(ped->bInVehicle && ped->m_pMyVehicle)
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped->InVehicle())
return ped->m_pMyVehicle;
else
return nil;
@@ -878,8 +878,8 @@ FindPlayerTrain(void)
CEntity*
FindPlayerEntity(void)
{
- CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
- if(ped->bInVehicle && ped->m_pMyVehicle)
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped->InVehicle())
return ped->m_pMyVehicle;
else
return ped;
@@ -888,8 +888,8 @@ FindPlayerEntity(void)
CVector
FindPlayerCoors(void)
{
- CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
- if(ped->bInVehicle && ped->m_pMyVehicle)
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped->InVehicle())
return ped->m_pMyVehicle->GetPosition();
else
return ped->GetPosition();
@@ -898,8 +898,8 @@ FindPlayerCoors(void)
CVector&
FindPlayerSpeed(void)
{
- CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
- if(ped->bInVehicle && ped->m_pMyVehicle)
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped->InVehicle())
return ped->m_pMyVehicle->m_vecMoveSpeed;
else
return ped->m_vecMoveSpeed;
@@ -926,7 +926,7 @@ FindPlayerCentreOfWorld_NoSniperShift(void)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
if(FindPlayerVehicle())
return FindPlayerVehicle()->GetPosition();
- return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetPosition();
+ return FindPlayerPed()->GetPosition();
}
float
@@ -936,7 +936,7 @@ FindPlayerHeading(void)
return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
if(FindPlayerVehicle())
return FindPlayerVehicle()->GetForward().Heading();
- return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetForward().Heading();
+ return FindPlayerPed()->GetForward().Heading();
}
void
@@ -1012,6 +1012,30 @@ CWorld::StopAllLawEnforcersInTheirTracks(void)
}
void
+CWorld::SetAllCarsCanBeDamaged(bool toggle)
+{
+ int poolSize = CPools::GetVehiclePool()->GetSize();
+ for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
+ CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
+ if (veh)
+ veh->bCanBeDamaged = toggle;
+ }
+}
+
+void
+CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
+{
+ int poolSize = CPools::GetVehiclePool()->GetSize();
+ for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) {
+ CVehicle* veh = CPools::GetVehiclePool()->GetSlot(poolIndex);
+ if (veh) {
+ if ((point - veh->GetPosition()).MagnitudeSqr() < sq(range))
+ veh->ExtinguishCarFire();
+ }
+ }
+}
+
+void
CWorld::Process(void)
{
if (!(CTimer::GetFrameCounter() & 63))
@@ -1212,5 +1236,9 @@ STARTPATCHES
InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP);
InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP);
+ InjectHook(0x4B5BC0, CWorld::StopAllLawEnforcersInTheirTracks, PATCH_JUMP);
+ InjectHook(0x4B53F0, CWorld::SetAllCarsCanBeDamaged, PATCH_JUMP);
+ InjectHook(0x4B5460, CWorld::ExtinguishAllCarFiresInArea, PATCH_JUMP);
+
InjectHook(0x4B1A60, CWorld::Process, PATCH_JUMP);
ENDPATCHES
diff --git a/src/core/World.h b/src/core/World.h
index 3b04403e..119c6324 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -121,6 +121,8 @@ public:
static void RemoveFallenCars();
static void StopAllLawEnforcersInTheirTracks();
+ static void SetAllCarsCanBeDamaged(bool);
+ static void ExtinguishAllCarFiresInArea(CVector, float);
static void Initialise();
static void ShutDown();
diff --git a/src/core/common.h b/src/core/common.h
index fd5f35b0..cadcac1d 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -153,6 +153,10 @@ public:
#endif
};
+#if (defined(_MSC_VER))
+extern int strcasecmp(const char *str1, const char *str2);
+#endif
+
#define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
inline float sq(float x) { return x*x; }
diff --git a/src/core/config.h b/src/core/config.h
index 175a5f61..166c2a68 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -87,6 +87,7 @@ enum Config {
NUM_FIRES = 40,
NUMPEDROUTES = 200,
+ NUMPHONES = 50,
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
@@ -145,6 +146,7 @@ enum Config {
#endif
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
+#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. doesn't have too many things
// Pad
#define KANGAROO_CHEAT
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index d6bc8148..d3b8200d 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -29,12 +29,10 @@ void **rwengine = *(void***)0x5A10E1;
DebugMenuAPI gDebugMenuAPI;
-WRAPPER void *gtanew(uint32 sz) { EAXJMP(0x5A0690); }
-WRAPPER void gtadelete(void *p) { EAXJMP(0x5A07E0); }
-
-// overload our own new/delete with GTA's functions
-void *operator new(size_t sz) { return gtanew(sz); }
-void operator delete(void *ptr) noexcept { gtadelete(ptr); }
+STARTPATCHES
+ InjectHook(0x5A07E0, (void (*)(void*)) &operator delete, PATCH_JUMP);
+ InjectHook(0x5A0690, (void* (*)(size_t)) &operator new, PATCH_JUMP);
+ENDPATCHES
#ifdef USE_PS2_RAND
unsigned __int64 myrand_seed = 1;
@@ -351,10 +349,11 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
DebugMenuAddCmd("Debug", "Make peds follow you in formation", LetThemFollowYou);
-#ifndef MASTER
+#ifdef TOGGLEABLE_BETA_FEATURES
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
+ DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", (int8*)&CPed::bMakePedsRunToPhonesToReportCrimes, nil);
#endif
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);