summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Collision.cpp5
-rw-r--r--src/core/Collision.h11
-rw-r--r--src/core/Frontend.cpp132
-rw-r--r--src/core/Frontend.h56
-rw-r--r--src/core/Pools.cpp345
-rw-r--r--src/core/Profile.cpp71
-rw-r--r--src/core/Profile.h28
-rw-r--r--src/core/World.cpp4
-rw-r--r--src/core/World.h4
-rw-r--r--src/core/main.cpp5
10 files changed, 552 insertions, 109 deletions
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index c884f751..85145e86 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -31,8 +31,8 @@ enum Direction
DIR_Z_NEG,
};
-eLevelName &CCollision::ms_collisionInMemory = *(eLevelName*)0x8F6250;
-CLinkList<CColModel*> &CCollision::ms_colModelCache = *(CLinkList<CColModel*>*)0x95CB58;
+eLevelName CCollision::ms_collisionInMemory;
+CLinkList<CColModel*> CCollision::ms_colModelCache;
void
CCollision::Init(void)
@@ -1355,6 +1355,7 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
modelB.triangles[aTriangleIndicesB[j]],
modelB.trianglePlanes[aTriangleIndicesB[j]],
spherepoints[numCollisions], coldist);
+
if(hasCollided)
numCollisions++;
}
diff --git a/src/core/Collision.h b/src/core/Collision.h
index 1cbd1690..bdf51eb8 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -3,6 +3,13 @@
#include "templates.h"
#include "Game.h" // for eLevelName
+// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
+#ifdef FIX_BUGS
+#define MAX_COLLISION_POINTS 64
+#else
+#define MAX_COLLISION_POINTS 32
+#endif
+
struct CColSphere
{
CVector center;
@@ -110,8 +117,8 @@ struct CColModel
class CCollision
{
public:
- static eLevelName &ms_collisionInMemory;
- static CLinkList<CColModel*> &ms_colModelCache;
+ static eLevelName ms_collisionInMemory;
+ static CLinkList<CColModel*> ms_colModelCache;
static void Init(void);
static void Shutdown(void);
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 643c450f..166ecb35 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -82,34 +82,34 @@ int curBottomBarOption = -1;
int hoveredBottomBarOption = -1;
#endif
-int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78; // 9
-int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92;
-int8 &CMenuManager::m_DisplayControllerOnFoot = *(int8*)0x95CD8D;
-int8 &CMenuManager::m_PrefsVsync = *(int8*)0x5F2E58; // 1
-int8 &CMenuManager::m_PrefsVsyncDisp = *(int8*)0x5F2E5C; // 1
-int8 &CMenuManager::m_PrefsFrameLimiter = *(int8*)0x5F2E60; // 1
-int8 &CMenuManager::m_PrefsShowSubtitles = *(int8*)0x5F2E54; // 1
-int8 &CMenuManager::m_PrefsSpeakers = *(int8*)0x95CD7E;
-int32 &CMenuManager::m_ControlMethod = *(int32*)0x8F5F7C;
-int8 &CMenuManager::m_PrefsDMA = *(int8*)0x5F2F74; // 1
-int32 &CMenuManager::m_PrefsLanguage = *(int32*)0x941238;
+int32 CMenuManager::OS_Language = LANG_ENGLISH;
+int8 CMenuManager::m_PrefsUseVibration;
+int8 CMenuManager::m_DisplayControllerOnFoot;
+int8 CMenuManager::m_PrefsVsync = 1;
+int8 CMenuManager::m_PrefsVsyncDisp = 1;
+int8 CMenuManager::m_PrefsFrameLimiter = 1;
+int8 CMenuManager::m_PrefsShowSubtitles = 1;
+int8 CMenuManager::m_PrefsSpeakers;
+int32 CMenuManager::m_ControlMethod;
+int8 CMenuManager::m_PrefsDMA = 1;
+int32 CMenuManager::m_PrefsLanguage;
uint8 CMenuManager::m_PrefsStereoMono; // *(bool*)0x95CDB5; // unused except restore settings
-bool &CMenuManager::m_PrefsAllowNastyGame = *(bool*)0x5F2E64; // true
-bool &CMenuManager::m_bStartUpFrontEndRequested = *(bool*)0x95CCF4;
-bool &CMenuManager::m_bShutDownFrontEndRequested = *(bool*)0x95CD6A;
+bool CMenuManager::m_PrefsAllowNastyGame = true;
+bool CMenuManager::m_bStartUpFrontEndRequested;
+bool CMenuManager::m_bShutDownFrontEndRequested;
-int8 &CMenuManager::m_PrefsUseWideScreen = *(int8*)0x95CD23;
-int8 &CMenuManager::m_PrefsRadioStation = *(int8*)0x95CDA4;
-int32 &CMenuManager::m_PrefsBrightness = *(int32*)0x5F2E50; // 256
-float &CMenuManager::m_PrefsLOD = *(float*)0x8F42C4;
-int8 &CMenuManager::m_bFrontEnd_ReloadObrTxtGxt = *(int8*)0x628CFC;
-int32 &CMenuManager::m_PrefsMusicVolume = *(int32*)0x5F2E4C; // 102
-int32 &CMenuManager::m_PrefsSfxVolume = *(int32*)0x5F2E48; // 102
+int8 CMenuManager::m_PrefsUseWideScreen;
+int8 CMenuManager::m_PrefsRadioStation;
+int32 CMenuManager::m_PrefsBrightness = 256;
+float CMenuManager::m_PrefsLOD = CRenderer::ms_lodDistScale;
+int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt;
+int32 CMenuManager::m_PrefsMusicVolume = 102;
+int32 CMenuManager::m_PrefsSfxVolume = 102;
-char *CMenuManager::m_PrefsSkinFile = (char*)0x5F2E74; //[256] "$$\"\""
+char CMenuManager::m_PrefsSkinFile[256] = "$$\"\"";
-int32 &CMenuManager::m_KeyPressedCode = *(int32*)0x5F2E70; // -1
+int32 CMenuManager::m_KeyPressedCode = -1;
// Originally that was PS2 option color, they forget it here and used in PrintBriefs once(but didn't use the output anyway)
#ifdef PS2_LIKE_MENU
@@ -119,29 +119,26 @@ const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color
#endif
const float menuXYpadding = MENUACTION_POS_Y; // *(float*)0x5F355C; // not original name
-float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; //*(float*)0x5F2E40;
-float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; //*(float*)0x5F2E44;
+float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE;
+float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE;
bool holdingScrollBar; // *(bool*)0x628D59; // not original name
-int32 CMenuManager::m_SelectedMap; // *(int32*)0x8E2880;
-int32 CMenuManager::m_SelectedGameType; // *(int32*)0x942F88;
+int32 CMenuManager::m_SelectedMap;
+int32 CMenuManager::m_SelectedGameType;
// Used in a hidden menu
uint8 CMenuManager::m_PrefsPlayerRed = 255;
uint8 CMenuManager::m_PrefsPlayerGreen = 128;
uint8 CMenuManager::m_PrefsPlayerBlue; // why??
-CMenuManager FrontEndMenuManager; // = *(CMenuManager*)0x8F59D8;
+CMenuManager FrontEndMenuManager;
-// Move this somewhere else.
-float CRenderer::ms_lodDistScale = 1.2f; // *(float*)0x5F726C;
-
-uint32 TimeToStopPadShaking; // = *(uint32*)0x628CF8;
-char *pEditString; // = *(char**)0x628D00;
-int32 *pControlEdit; // = *(int32**)0x628D08;
-bool DisplayComboButtonErrMsg; // = *(bool*)0x628D14;
-int32 MouseButtonJustClicked; // = *(int32*)0x628D0C;
-int32 JoyButtonJustClicked; // = *(int32*)0x628D10;
+uint32 TimeToStopPadShaking;
+char *pEditString;
+int32 *pControlEdit;
+bool DisplayComboButtonErrMsg;
+int32 MouseButtonJustClicked;
+int32 JoyButtonJustClicked;
//int32 *pControlTemp = 0;
#ifndef MASTER
@@ -283,6 +280,12 @@ ScaleAndCenterX(float x)
} while(0)
#endif
+#define PREPARE_MENU_HEADER \
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); \
+ CFont::SetRightJustifyOn(); \
+ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \
+ CFont::SetFontStyle(FONT_HEADING);
+
#define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \
do { \
lastActiveBarX = DisplaySlider(SCREEN_STRETCH_FROM_RIGHT(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
@@ -447,8 +450,8 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
if (typeOfControl == KEYBOARD) {
if (*pControlEdit == rsESC) {
escPressed = true;
- } else if (*pControlEdit > rsF3 && *pControlEdit != rsF9 && *pControlEdit != rsLWIN &&
- *pControlEdit != rsRWIN && *pControlEdit != rsRALT) {
+ } else if (*pControlEdit != rsF1 && *pControlEdit != rsF2 && *pControlEdit != rsF3 && *pControlEdit != rsF9 &&
+ *pControlEdit != rsLWIN && *pControlEdit != rsRWIN && *pControlEdit != rsRALT) {
typeToSave = KEYBOARD;
if (ControlsManager.GetControllerKeyAssociatedWithAction(action, KEYBOARD) != rsNULL &&
*pControlEdit != ControlsManager.GetControllerKeyAssociatedWithAction(action, KEYBOARD)) {
@@ -465,7 +468,10 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
DisplayComboButtonErrMsg = true;
}
- ControlsManager.ClearSettingsAssociatedWithAction(action, typeToSave);
+#ifdef FIX_BUGS
+ if(!escPressed && !invalidKey)
+#endif
+ ControlsManager.ClearSettingsAssociatedWithAction(action, typeToSave);
if (!DisplayComboButtonErrMsg && !escPressed && !invalidKey) {
if (typeOfControl == KEYBOARD) {
ControlsManager.DeleteMatchingActionInitiators(action, *pControlEdit, KEYBOARD);
@@ -670,6 +676,17 @@ CMenuManager::Draw()
CFont::SetCentreOff();
CFont::SetJustifyOn();
CFont::SetBackGroundOnlyTextOn();
+#ifdef GTA3_1_1_PATCH
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ CFont::SetRightJustifyOn();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(MENU_X(0.7f), MENU_Y(0.5f));
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::SetRightJustifyWrap(0.0f);
+ strcpy(gString, "V1.1");
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 45, gUString);
+#endif
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
@@ -696,17 +713,9 @@ CMenuManager::Draw()
#endif
if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') {
- CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONT_HEADING);
-#ifdef PS2_LIKE_MENU
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(1.3f));
- CFont::PrintString(MENU_X_RIGHT_ALIGNED(50.0f), SCREEN_SCALE_FROM_BOTTOM(75.0f), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
-#else
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
+ PREPARE_MENU_HEADER
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
-#endif
+
// Weird place to put that.
nextYToUse += 24.0f + 10.0f;
}
@@ -1655,7 +1664,6 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
}
}
-// TODO: Complete aScreens and test that
void
CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeight)
{
@@ -1736,11 +1744,8 @@ CMenuManager::DrawControllerSetupScreen()
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
- // Page header
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetRightJustifyOn();
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
- CFont::SetFontStyle(FONT_HEADING);
+ PREPARE_MENU_HEADER
+
switch (m_ControlMethod) {
case CONTROL_STANDARD:
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
@@ -2418,10 +2423,8 @@ CMenuManager::DrawPlayerSetupScreen()
CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
- CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONT_HEADING);
+ PREPARE_MENU_HEADER
+
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS"));
// lstrcpy's changed with strcpy
@@ -2463,7 +2466,7 @@ CMenuManager::DrawPlayerSetupScreen()
m_pSelectedSkin->skinNameDisplayed[oldLength - 4] = '\0';
m_pSelectedSkin->skinNameOriginal[oldLength - 4] = '\0';
- // Truncate to 40 bytes-39 chars, idk why. This is done in sepearate function in game.
+ // Fill to 40 bytes-39 chars, idk why. This is done in sepearate function in game.
strncpy(nameTemp, m_pSelectedSkin->skinNameDisplayed, 39); // game doesn't do that, but in our day strncpy to same string is forbidden
strncpy(m_pSelectedSkin->skinNameDisplayed, nameTemp, 39);
if (oldLength - 4 > 39)
@@ -3315,10 +3318,7 @@ CMenuManager::PrintStats()
// ::Draw already does that.
/*
- CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONT_HEADING);
- CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
+ PREPARE_MENU_HEADER
CFont::PrintString(MENU_X_RIGHT_ALIGNED(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
*/
CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y));
@@ -4875,7 +4875,7 @@ float CMenuManager::StretchY(float y)
void
CMenuManager::SwitchMenuOnAndOff()
{
- bool menuWasActive = !!m_bMenuActive;
+ bool menuWasActive = GetIsMenuActive();
// Reminder: You need REGISTER_START_BUTTON defined to make it work.
if (CPad::GetPad(0)->GetStartJustDown()
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 81765af9..8fe61a36 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -2,10 +2,16 @@
#include "Sprite2d.h"
+#ifdef PS2_LIKE_MENU
+#define MENUHEADER_POS_X 50.0f
+#define MENUHEADER_POS_Y 75.0f
+#define MENUHEADER_HEIGHT 1.3f
+#else
#define MENUHEADER_POS_X 35.0f
#define MENUHEADER_POS_Y 93.0f
-#define MENUHEADER_WIDTH 0.84f
#define MENUHEADER_HEIGHT 1.6f
+#endif
+#define MENUHEADER_WIDTH 0.84f
#define MENU_X_MARGIN 40.0f
#define MENUACTION_POS_Y 60.0f
@@ -530,30 +536,30 @@ public:
bool GetIsMenuActive() {return !!m_bMenuActive;}
public:
- static int32 &OS_Language;
- static int8 &m_PrefsUseVibration;
- static int8 &m_DisplayControllerOnFoot;
- static int8 &m_PrefsUseWideScreen;
- static int8 &m_PrefsRadioStation;
- static int8 &m_PrefsVsync;
- static int8 &m_PrefsVsyncDisp;
- static int8 &m_PrefsFrameLimiter;
- static int8 &m_PrefsShowSubtitles;
- static int8 &m_PrefsSpeakers;
- static int32 &m_ControlMethod;
- static int8 &m_PrefsDMA;
- static int32 &m_PrefsLanguage;
- static int32 &m_PrefsBrightness;
- static float &m_PrefsLOD;
- static int8 &m_bFrontEnd_ReloadObrTxtGxt;
- static int32 &m_PrefsMusicVolume;
- static int32 &m_PrefsSfxVolume;
- static char *m_PrefsSkinFile;
- static int32 &m_KeyPressedCode;
-
- static bool &m_bStartUpFrontEndRequested;
- static bool &m_bShutDownFrontEndRequested;
- static bool &m_PrefsAllowNastyGame;
+ static int32 OS_Language;
+ static int8 m_PrefsUseVibration;
+ static int8 m_DisplayControllerOnFoot;
+ static int8 m_PrefsUseWideScreen;
+ static int8 m_PrefsRadioStation;
+ static int8 m_PrefsVsync;
+ static int8 m_PrefsVsyncDisp;
+ static int8 m_PrefsFrameLimiter;
+ static int8 m_PrefsShowSubtitles;
+ static int8 m_PrefsSpeakers;
+ static int32 m_ControlMethod;
+ static int8 m_PrefsDMA;
+ static int32 m_PrefsLanguage;
+ static int32 m_PrefsBrightness;
+ static float m_PrefsLOD;
+ static int8 m_bFrontEnd_ReloadObrTxtGxt;
+ static int32 m_PrefsMusicVolume;
+ static int32 m_PrefsSfxVolume;
+ static char m_PrefsSkinFile[256];
+ static int32 m_KeyPressedCode;
+
+ static bool m_bStartUpFrontEndRequested;
+ static bool m_bShutDownFrontEndRequested;
+ static bool m_PrefsAllowNastyGame;
static uint8 m_PrefsStereoMono;
static int32 m_SelectedMap;
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index 75536b88..6add9e0c 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -1,8 +1,14 @@
#include "common.h"
#include "patcher.h"
#include "Pools.h"
-#include "World.h"
+
+#include "Boat.h"
+#include "CarCtrl.h"
+#include "Population.h"
#include "ProjectileInfo.h"
+#include "Streaming.h"
+#include "Wanted.h"
+#include "World.h"
CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044;
CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448;
@@ -14,13 +20,6 @@ CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28;
CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18;
CAudioScriptObjectPool *&CPools::ms_pAudioScriptObjectPool = *(CAudioScriptObjectPool**)0x8F1B6C;
-WRAPPER void CPools::LoadObjectPool(uint8* buf, uint32 size) { EAXJMP(0x4a2550); }
-WRAPPER void CPools::LoadPedPool(uint8* buf, uint32 size) { EAXJMP(0x4a2b50); }
-WRAPPER void CPools::LoadVehiclePool(uint8* buf, uint32 size) { EAXJMP(0x4a1b40); }
-WRAPPER void CPools::SaveObjectPool(uint8* buf, uint32 *size) { EAXJMP(0x4a22d0); }
-WRAPPER void CPools::SavePedPool(uint8* buf, uint32 *size) { EAXJMP(0x4a29b0); }
-WRAPPER void CPools::SaveVehiclePool(uint8* buf, uint32 *size) { EAXJMP(0x4a2080); }
-
void
CPools::Initialise(void)
{
@@ -99,6 +98,333 @@ CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
}
}
+void CPools::LoadVehiclePool(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ int nNumCars = ReadSaveBuf<int>(buf);
+ int nNumBoats = ReadSaveBuf<int>(buf);
+ for (int i = 0; i < nNumCars + nNumBoats; i++) {
+ uint32 type = ReadSaveBuf<uint32>(buf);
+ int16 model = ReadSaveBuf<int16>(buf);
+ CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ int32 slot = ReadSaveBuf<int32>(buf);
+ CVehicle* pVehicle;
+ char* vbuf = new char[max(sizeof(CAutomobile), sizeof(CBoat))];
+ if (type == VEHICLE_TYPE_BOAT) {
+ memcpy(vbuf, buf, sizeof(CBoat));
+ SkipSaveBuf(buf, sizeof(CBoat));
+ CBoat* pBoat = new(slot) CBoat(model, RANDOM_VEHICLE);
+ pVehicle = pBoat;
+ --CCarCtrl::NumRandomCars; // why?
+ }
+ else if (type == VEHICLE_TYPE_CAR) {
+ memcpy(vbuf, buf, sizeof(CAutomobile));
+ SkipSaveBuf(buf, sizeof(CAutomobile));
+ CStreaming::RequestModel(model, 0); // is it needed?
+ CStreaming::LoadAllRequestedModels(false);
+ CAutomobile* pAutomobile = new(slot) CAutomobile(model, RANDOM_VEHICLE);
+ pVehicle = pAutomobile;
+ CCarCtrl::NumRandomCars--; // why?
+ pAutomobile->Damage = ((CAutomobile*)vbuf)->Damage;
+ pAutomobile->SetupDamageAfterLoad();
+ }
+ else
+ assert(0);
+ CVehicle* pBufferVehicle = (CVehicle*)vbuf;
+ pVehicle->GetMatrix() = pBufferVehicle->GetMatrix();
+ pVehicle->VehicleCreatedBy = pBufferVehicle->VehicleCreatedBy;
+ pVehicle->m_currentColour1 = pBufferVehicle->m_currentColour1;
+ pVehicle->m_currentColour2 = pBufferVehicle->m_currentColour2;
+ pVehicle->m_nAlarmState = pBufferVehicle->m_nAlarmState;
+ pVehicle->m_nNumMaxPassengers = pBufferVehicle->m_nNumMaxPassengers;
+ pVehicle->field_1D0[0] = pBufferVehicle->field_1D0[0];
+ pVehicle->field_1D0[1] = pBufferVehicle->field_1D0[1];
+ pVehicle->field_1D0[2] = pBufferVehicle->field_1D0[2];
+ pVehicle->field_1D0[3] = pBufferVehicle->field_1D0[3];
+ pVehicle->m_fSteerAngle = pBufferVehicle->m_fSteerAngle;
+ pVehicle->m_fGasPedal = pBufferVehicle->m_fGasPedal;
+ pVehicle->m_fBrakePedal = pBufferVehicle->m_fBrakePedal;
+ pVehicle->bIsLawEnforcer = pBufferVehicle->bIsLawEnforcer;
+ pVehicle->bIsLocked = pBufferVehicle->bIsLocked;
+ pVehicle->bEngineOn = pBufferVehicle->bEngineOn;
+ pVehicle->bIsHandbrakeOn = pBufferVehicle->bIsHandbrakeOn;
+ pVehicle->bLightsOn = pBufferVehicle->bLightsOn;
+ pVehicle->bFreebies = pBufferVehicle->bFreebies;
+ pVehicle->m_fHealth = pBufferVehicle->m_fHealth;
+ pVehicle->m_nCurrentGear = pBufferVehicle->m_nCurrentGear;
+ pVehicle->m_fChangeGearTime = pBufferVehicle->m_fChangeGearTime;
+ pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath;
+#ifdef FIX_BUGS //must be copypaste
+ pVehicle->m_nBombTimer = pBufferVehicle->m_nBombTimer;
+#else
+ pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath;
+#endif
+ pVehicle->m_nDoorLock = pBufferVehicle->m_nDoorLock;
+ pVehicle->m_status = pBufferVehicle->m_status;
+ pVehicle->m_type = pBufferVehicle->m_type;
+ (pVehicle->GetAddressOfEntityProperties())[0] = (pBufferVehicle->GetAddressOfEntityProperties())[0];
+ (pVehicle->GetAddressOfEntityProperties())[1] = (pBufferVehicle->GetAddressOfEntityProperties())[1];
+ pVehicle->AutoPilot = pBufferVehicle->AutoPilot;
+ CWorld::Add(pVehicle);
+ delete[] vbuf;
+ }
+VALIDATESAVEBUF(size)
+}
+
+void CPools::SaveVehiclePool(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ int nNumCars = 0;
+ int nNumBoats = 0;
+ int nPoolSize = GetVehiclePool()->GetSize();
+ for (int i = 0; i < nPoolSize; i++) {
+ CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ bool bHasPassenger = false;
+ for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) {
+ if (pVehicle->pPassengers[i])
+ bHasPassenger = true;
+ }
+ if (!pVehicle->pDriver && !bHasPassenger) {
+ if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
+ ++nNumCars;
+ if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
+ ++nNumBoats;
+ }
+ }
+ *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CAutomobile)) + sizeof(int) +
+ nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CBoat)) + sizeof(int);
+ WriteSaveBuf(buf, nNumCars);
+ WriteSaveBuf(buf, nNumBoats);
+ for (int i = 0; i < nPoolSize; i++) {
+ CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ bool bHasPassenger = false;
+ for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) {
+ if (pVehicle->pPassengers[j])
+ bHasPassenger = true;
+ }
+ if (!pVehicle->pDriver && !bHasPassenger) {
+ if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+ WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
+ WriteSaveBuf(buf, pVehicle->m_modelIndex);
+ WriteSaveBuf(buf, GetVehicleRef(pVehicle));
+ memcpy(buf, pVehicle, sizeof(CAutomobile));
+ SkipSaveBuf(buf, sizeof(CAutomobile));
+ }
+ if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+ WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
+ WriteSaveBuf(buf, pVehicle->m_modelIndex);
+ WriteSaveBuf(buf, GetVehicleRef(pVehicle));
+ memcpy(buf, pVehicle, sizeof(CBoat));
+ SkipSaveBuf(buf, sizeof(CBoat));
+ }
+ }
+ }
+VALIDATESAVEBUF(*size)
+}
+
+void CPools::SaveObjectPool(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ CProjectileInfo::RemoveAllProjectiles();
+ CObject::DeleteAllTempObjects();
+ int nObjects = 0;
+ int nPoolSize = GetObjectPool()->GetSize();
+ for (int i = 0; i < nPoolSize; i++) {
+ CObject* pObject = GetObjectPool()->GetSlot(i);
+ if (!pObject)
+ continue;
+ if (pObject->ObjectCreatedBy == MISSION_OBJECT)
+ ++nObjects;
+ }
+ *size = nObjects * (sizeof(int16) + sizeof(int) + sizeof(CCompressedMatrixNotAligned) + sizeof(uint32) +
+ sizeof(float) + sizeof(CCompressedMatrixNotAligned) + sizeof(uint32) + sizeof(int8) + 7 * sizeof(bool) + sizeof(float) +
+ sizeof(int8) + sizeof(int8) + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int);
+ WriteSaveBuf(buf, nObjects);
+ for (int i = 0; i < nPoolSize; i++) {
+ CObject* pObject = GetObjectPool()->GetSlot(i);
+ if (!pObject)
+ continue;
+ if (pObject->ObjectCreatedBy == MISSION_OBJECT) {
+ bool bIsPickup = pObject->bIsPickup;
+ bool bFlag2 = pObject->m_obj_flag2;
+ bool bOutOfStock = pObject->bOutOfStock;
+ bool bGlassCracked = pObject->bGlassCracked;
+ bool bGlassBroken = pObject->bGlassBroken;
+ bool bHasBeenDamaged = pObject->bHasBeenDamaged;
+ bool bUseVehicleColours = pObject->bUseVehicleColours;
+ CCompressedMatrixNotAligned tmp;
+ WriteSaveBuf(buf, pObject->m_modelIndex);
+ WriteSaveBuf(buf, GetObjectRef(pObject));
+ tmp.CompressFromFullMatrix(pObject->GetMatrix());
+ WriteSaveBuf(buf, tmp);
+ WriteSaveBuf(buf, (uint32)0); // game writes ununitialized data here
+ WriteSaveBuf(buf, pObject->m_fUprootLimit);
+ tmp.CompressFromFullMatrix(pObject->m_objectMatrix);
+ WriteSaveBuf(buf, tmp);
+ WriteSaveBuf(buf, (uint32)0); // same
+ WriteSaveBuf(buf, pObject->ObjectCreatedBy);
+ WriteSaveBuf(buf, bIsPickup);
+ WriteSaveBuf(buf, bFlag2);
+ WriteSaveBuf(buf, bOutOfStock);
+ WriteSaveBuf(buf, bGlassCracked);
+ WriteSaveBuf(buf, bGlassBroken);
+ WriteSaveBuf(buf, bHasBeenDamaged);
+ WriteSaveBuf(buf, bUseVehicleColours);
+ WriteSaveBuf(buf, pObject->m_fCollisionDamageMultiplier);
+ WriteSaveBuf(buf, pObject->m_nCollisionDamageEffect);
+ WriteSaveBuf(buf, pObject->m_nSpecialCollisionResponseCases);
+ WriteSaveBuf(buf, pObject->m_nEndOfLifeTime);
+ WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[0]);
+ WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[1]);
+ }
+ }
+VALIDATESAVEBUF(*size)
+}
+
+void CPools::LoadObjectPool(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ int nObjects = ReadSaveBuf<int>(buf);
+ for (int i = 0; i < nObjects; i++) {
+ int16 mi = ReadSaveBuf<int16>(buf);
+ int ref = ReadSaveBuf<int>(buf);
+ char* obuf = new char[sizeof(CObject)];
+ CObject* pBufferObject = (CObject*)obuf;
+ CCompressedMatrixNotAligned tmp;
+ tmp = ReadSaveBuf<CCompressedMatrixNotAligned>(buf);
+ tmp.DecompressIntoFullMatrix(pBufferObject->GetMatrix());
+ ReadSaveBuf<uint32>(buf);
+ pBufferObject->m_fUprootLimit = ReadSaveBuf<float>(buf);
+ tmp = ReadSaveBuf<CCompressedMatrixNotAligned>(buf);
+ tmp.DecompressIntoFullMatrix(pBufferObject->m_objectMatrix);
+ ReadSaveBuf<uint32>(buf);
+ pBufferObject->ObjectCreatedBy = ReadSaveBuf<int8>(buf);
+ pBufferObject->bIsPickup = ReadSaveBuf<bool>(buf);
+ pBufferObject->m_flagE2 = ReadSaveBuf<bool>(buf);
+ pBufferObject->bOutOfStock = ReadSaveBuf<bool>(buf);
+ pBufferObject->bGlassCracked = ReadSaveBuf<bool>(buf);
+ pBufferObject->bGlassBroken = ReadSaveBuf<bool>(buf);
+ pBufferObject->bHasBeenDamaged = ReadSaveBuf<bool>(buf);
+ pBufferObject->bUseVehicleColours = ReadSaveBuf<bool>(buf);
+ pBufferObject->m_fCollisionDamageMultiplier = ReadSaveBuf<float>(buf);
+ pBufferObject->m_nCollisionDamageEffect = ReadSaveBuf<uint8>(buf);
+ pBufferObject->m_nSpecialCollisionResponseCases = ReadSaveBuf<uint8>(buf);
+ pBufferObject->m_nEndOfLifeTime = ReadSaveBuf<uint32>(buf);
+ (pBufferObject->GetAddressOfEntityProperties())[0] = ReadSaveBuf<uint32>(buf);
+ (pBufferObject->GetAddressOfEntityProperties())[1] = ReadSaveBuf<uint32>(buf);
+ if (GetObjectPool()->GetSlot(ref >> 8))
+ CPopulation::ConvertToDummyObject(GetObjectPool()->GetSlot(ref >> 8));
+ CObject* pObject = new(ref) CObject(mi, false);
+ pObject->GetMatrix() = pBufferObject->GetMatrix();
+ pObject->m_fUprootLimit = pBufferObject->m_fUprootLimit;
+ pObject->m_objectMatrix = pBufferObject->m_objectMatrix;
+ pObject->ObjectCreatedBy = pBufferObject->ObjectCreatedBy;
+ pObject->bIsPickup = pBufferObject->bIsPickup;
+ pObject->m_flagE2 = pBufferObject->m_flagE2;
+ pObject->bOutOfStock = pBufferObject->bOutOfStock;
+ pObject->bGlassCracked = pBufferObject->bGlassCracked;
+ pObject->bGlassBroken = pBufferObject->bGlassBroken;
+ pObject->bHasBeenDamaged = pBufferObject->bHasBeenDamaged;
+ pObject->bUseVehicleColours = pBufferObject->bUseVehicleColours;
+ pObject->m_fCollisionDamageMultiplier = pBufferObject->m_fCollisionDamageMultiplier;
+ pObject->m_nCollisionDamageEffect = pBufferObject->m_nCollisionDamageEffect;
+ pObject->m_nSpecialCollisionResponseCases = pBufferObject->m_nSpecialCollisionResponseCases;
+ pObject->m_nEndOfLifeTime = pBufferObject->m_nEndOfLifeTime;
+ (pObject->GetAddressOfEntityProperties())[0] = (pBufferObject->GetAddressOfEntityProperties())[0];
+ (pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1];
+ pObject->bHasCollided = false;
+ CWorld::Add(pObject);
+ delete[] obuf;
+ }
+VALIDATESAVEBUF(size)
+}
+
+void CPools::SavePedPool(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ int nNumPeds = 0;
+ int nPoolSize = GetPedPool()->GetSize();
+ for (int i = 0; i < nPoolSize; i++) {
+ CPed* pPed = GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1)
+ nNumPeds++;
+ }
+ *size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + sizeof(CPlayerPed) +
+ sizeof(CWanted::MaximumWantedLevel) + sizeof(CWanted::nMaximumWantedLevel) + MAX_MODEL_NAME);
+ WriteSaveBuf(buf, nNumPeds);
+ for (int i = 0; i < nPoolSize; i++) {
+ CPed* pPed = GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) {
+ WriteSaveBuf(buf, pPed->m_nPedType);
+ WriteSaveBuf(buf, pPed->m_modelIndex);
+ WriteSaveBuf(buf, GetPedRef(pPed));
+ memcpy(buf, pPed, sizeof(CPlayerPed));
+ SkipSaveBuf(buf, sizeof(CPlayerPed));
+ WriteSaveBuf(buf, CWanted::MaximumWantedLevel);
+ WriteSaveBuf(buf, CWanted::nMaximumWantedLevel);
+ memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName(), MAX_MODEL_NAME);
+ SkipSaveBuf(buf, MAX_MODEL_NAME);
+ }
+ }
+VALIDATESAVEBUF(*size);
+}
+
+void CPools::LoadPedPool(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ int nPeds = ReadSaveBuf<int>(buf);
+ for (int i = 0; i < nPeds; i++) {
+ uint32 pedtype = ReadSaveBuf<uint32>(buf);
+ int16 model = ReadSaveBuf<int16>(buf);
+ int ref = ReadSaveBuf<int>(buf);
+ char* pbuf = new char[sizeof(CPlayerPed)];
+ CPlayerPed* pBufferPlayer = (CPlayerPed*)pbuf;
+ CPed* pPed;
+ char name[MAX_MODEL_NAME];
+ // the code implies that there was idea to load non-player ped
+ if (pedtype == PEDTYPE_PLAYER1) { // always true
+ memcpy(pbuf, buf, sizeof(CPlayerPed));
+ SkipSaveBuf(buf, sizeof(CPlayerPed));
+ CWanted::MaximumWantedLevel = ReadSaveBuf<int32>(buf);
+ CWanted::nMaximumWantedLevel = ReadSaveBuf<int32>(buf);
+ memcpy(name, buf, MAX_MODEL_NAME);
+ SkipSaveBuf(buf, MAX_MODEL_NAME);
+ }
+ CStreaming::RequestSpecialModel(model, name, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+ if (pedtype == PEDTYPE_PLAYER1) {
+ CPlayerPed* pPlayerPed = new(ref) CPlayerPed();
+ for (int i = 0; i < ARRAY_SIZE(pPlayerPed->m_nTargettableObjects); i++)
+ pPlayerPed->m_nTargettableObjects[i] = pBufferPlayer->m_nTargettableObjects[i];
+ pPlayerPed->m_fMaxStamina = pBufferPlayer->m_fMaxStamina;
+ pPed = pPlayerPed;
+ }
+ pPed->GetPosition() = pBufferPlayer->GetPosition();
+ pPed->m_fHealth = pBufferPlayer->m_fHealth;
+ pPed->m_fArmour = pBufferPlayer->m_fArmour;
+ pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy;
+ pPed->m_currentWeapon = 0;
+ pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed;
+ for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++)
+ pPed->m_weapons[i] = pBufferPlayer->m_weapons[i];
+ if (pedtype == PEDTYPE_PLAYER1) {
+ pPed->m_wepAccuracy = 100;
+ CWorld::Players[0].m_pPed = (CPlayerPed*)pPed;
+ }
+ CWorld::Add(pPed);
+ delete[] pbuf;
+ }
+VALIDATESAVEBUF(size)
+}
STARTPATCHES
InjectHook(0x4A1770, CPools::Initialise, PATCH_JUMP);
@@ -111,4 +437,7 @@ STARTPATCHES
InjectHook(0x4A1B00, CPools::GetObjectRef, PATCH_JUMP);
InjectHook(0x4A1B20, CPools::GetObject, PATCH_JUMP);
InjectHook(0x4A2DB0, CPools::MakeSureSlotInObjectPoolIsEmpty, PATCH_JUMP);
+ InjectHook(0x4A1B40, CPools::LoadVehiclePool, PATCH_JUMP);
+ InjectHook(0x4A2550, CPools::LoadObjectPool, PATCH_JUMP);
+ InjectHook(0x4A2B50, CPools::LoadPedPool, PATCH_JUMP);
ENDPATCHES
diff --git a/src/core/Profile.cpp b/src/core/Profile.cpp
new file mode 100644
index 00000000..56584d12
--- /dev/null
+++ b/src/core/Profile.cpp
@@ -0,0 +1,71 @@
+#include "common.h"
+#include "Profile.h"
+
+#ifndef MASTER
+float CProfile::ms_afStartTime[NUM_PROFILES];
+float CProfile::ms_afCumulativeTime[NUM_PROFILES];
+float CProfile::ms_afEndTime[NUM_PROFILES];
+float CProfile::ms_afMaxEndTime[NUM_PROFILES];
+float CProfile::ms_afMaxCumulativeTime[NUM_PROFILES];
+char *CProfile::ms_pProfileString[NUM_PROFILES];
+RwRGBA CProfile::ms_aBarColours[NUM_PROFILES];
+
+void CProfile::Initialise()
+{
+ ms_afMaxEndTime[PROFILE_FRAME_RATE] = 0.0f;
+ ms_afMaxEndTime[PROFILE_PHYSICS] = 0.0f;
+ ms_afMaxEndTime[PROFILE_COLLISION] = 0.0f;
+ ms_afMaxEndTime[PROFILE_PED_AI] = 0.0f;
+ ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = 0.0f;
+ ms_afMaxEndTime[PROFILE_RENDERING_TIME] = 0.0f;
+ ms_afMaxEndTime[PROFILE_TOTAL] = 0.0f;
+
+ ms_pProfileString[PROFILE_FRAME_RATE] = "Frame rate";
+ ms_pProfileString[PROFILE_PHYSICS] = "Physics";
+ ms_pProfileString[PROFILE_COLLISION] = "Collision";
+ ms_pProfileString[PROFILE_PED_AI] = "Ped AI";
+ ms_pProfileString[PROFILE_PROCESSING_TIME] = "Processing time";
+ ms_pProfileString[PROFILE_RENDERING_TIME] = "Rendering time";
+ ms_pProfileString[PROFILE_TOTAL] = "Total";
+
+ ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_PHYSICS] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_COLLISION] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_PED_AI] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_TOTAL] = 0.0f;
+
+ ms_aBarColours[PROFILE_PHYSICS] = { 0, 127, 255, 255 };
+ ms_aBarColours[PROFILE_COLLISION] = { 0, 255, 255, 255 };
+ ms_aBarColours[PROFILE_PED_AI] = { 255, 0, 0, 255 };
+ ms_aBarColours[PROFILE_PROCESSING_TIME] = { 0, 255, 0, 255 };
+ ms_aBarColours[PROFILE_RENDERING_TIME] = { 0, 0, 255, 255 };
+ ms_aBarColours[PROFILE_TOTAL] = { 255, 255, 255, 255 };
+}
+
+void CProfile::SuspendProfile(eProfile profile)
+{
+ ms_afEndTime[profile] = -ms_afStartTime[profile];
+ ms_afCumulativeTime[profile] -= ms_afStartTime[profile];
+}
+
+void CProfile::ShowResults()
+{
+ ms_afMaxEndTime[PROFILE_FRAME_RATE] = max(ms_afMaxEndTime[PROFILE_FRAME_RATE], ms_afEndTime[PROFILE_FRAME_RATE]);
+ ms_afMaxEndTime[PROFILE_PHYSICS] = max(ms_afMaxEndTime[PROFILE_PHYSICS], ms_afEndTime[PROFILE_PHYSICS]);
+ ms_afMaxEndTime[PROFILE_COLLISION] = max(ms_afMaxEndTime[PROFILE_COLLISION], ms_afEndTime[PROFILE_COLLISION]);
+ ms_afMaxEndTime[PROFILE_PED_AI] = max(ms_afMaxEndTime[PROFILE_PED_AI], ms_afEndTime[PROFILE_PED_AI]);
+ ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxEndTime[PROFILE_PROCESSING_TIME], ms_afEndTime[PROFILE_PROCESSING_TIME]);
+ ms_afMaxEndTime[PROFILE_RENDERING_TIME] = max(ms_afMaxEndTime[PROFILE_RENDERING_TIME], ms_afEndTime[PROFILE_RENDERING_TIME]);
+ ms_afMaxEndTime[PROFILE_TOTAL] = max(ms_afMaxEndTime[PROFILE_TOTAL], ms_afEndTime[PROFILE_TOTAL]);
+
+ ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = max(ms_afMaxCumulativeTime[PROFILE_FRAME_RATE], ms_afCumulativeTime[PROFILE_FRAME_RATE]);
+ ms_afMaxCumulativeTime[PROFILE_PHYSICS] = max(ms_afMaxCumulativeTime[PROFILE_PHYSICS], ms_afCumulativeTime[PROFILE_PHYSICS]);
+ ms_afMaxCumulativeTime[PROFILE_COLLISION] = max(ms_afMaxCumulativeTime[PROFILE_COLLISION], ms_afCumulativeTime[PROFILE_COLLISION]);
+ ms_afMaxCumulativeTime[PROFILE_PED_AI] = max(ms_afMaxCumulativeTime[PROFILE_PED_AI], ms_afCumulativeTime[PROFILE_PED_AI]);
+ ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME], ms_afCumulativeTime[PROFILE_PROCESSING_TIME]);
+ ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME], ms_afCumulativeTime[PROFILE_RENDERING_TIME]);
+ ms_afMaxCumulativeTime[PROFILE_TOTAL] = max(ms_afMaxCumulativeTime[PROFILE_TOTAL], ms_afCumulativeTime[PROFILE_TOTAL]);
+}
+#endif \ No newline at end of file
diff --git a/src/core/Profile.h b/src/core/Profile.h
new file mode 100644
index 00000000..d2e8054b
--- /dev/null
+++ b/src/core/Profile.h
@@ -0,0 +1,28 @@
+#pragma once
+
+enum eProfile
+{
+ PROFILE_FRAME_RATE,
+ PROFILE_PHYSICS,
+ PROFILE_COLLISION,
+ PROFILE_PED_AI,
+ PROFILE_PROCESSING_TIME,
+ PROFILE_RENDERING_TIME,
+ PROFILE_TOTAL,
+ NUM_PROFILES,
+};
+
+class CProfile
+{
+ static float ms_afStartTime[NUM_PROFILES];
+ static float ms_afCumulativeTime[NUM_PROFILES];
+ static float ms_afEndTime[NUM_PROFILES];
+ static float ms_afMaxEndTime[NUM_PROFILES];
+ static float ms_afMaxCumulativeTime[NUM_PROFILES];
+ static char *ms_pProfileString[NUM_PROFILES];
+ static RwRGBA ms_aBarColours[NUM_PROFILES];
+public:
+ static void Initialise();
+ static void SuspendProfile(eProfile profile);
+ static void ShowResults();
+}; \ No newline at end of file
diff --git a/src/core/World.cpp b/src/core/World.cpp
index d64569b3..289be256 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -21,7 +21,7 @@
#include "Population.h"
#include "Fire.h"
-CColPoint *gaTempSphereColPoints = (CColPoint*)0x6E64C0; // [32]
+CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C;
@@ -29,7 +29,7 @@ CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x6656
uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64;
uint8 &CWorld::PlayerInFocus = *(uint8 *)0x95CD61;
-CPlayerInfo (&CWorld::Players)[NUMPLAYERS] = *(CPlayerInfo (*)[NUMPLAYERS])*(uintptr*)0x9412F0;
+CPlayerInfo CWorld::Players[NUMPLAYERS];
bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC;
CEntity *&CWorld::pIgnoreEntity = *(CEntity**)0x8F6494;
bool &CWorld::bIncludeDeadPeds = *(bool*)0x95CD8F;
diff --git a/src/core/World.h b/src/core/World.h
index 07e7889f..62fdc3b3 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -61,7 +61,7 @@ class CWorld
public:
static uint8 &PlayerInFocus;
- static CPlayerInfo (&Players)[NUMPLAYERS];
+ static CPlayerInfo Players[NUMPLAYERS];
static CEntity *&pIgnoreEntity;
static bool &bIncludeDeadPeds;
static bool &bNoMoreCollisionTorque;
@@ -144,7 +144,7 @@ public:
static void TriggerExplosion(const CVector &, float, float, CEntity*, bool);
};
-extern CColPoint *gaTempSphereColPoints;
+extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
class CPlayerPed;
class CVehicle;
diff --git a/src/core/main.cpp b/src/core/main.cpp
index f09c2e0a..2d452f9c 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -690,14 +690,14 @@ DisplayGameDebugText()
CFont::SetPropOn();
CFont::SetBackgroundOff();
CFont::SetFontStyle(FONT_BANK);
- CFont::SetScale(SCREEN_STRETCH_X(0.5f), SCREEN_STRETCH_Y(0.5f));
+ CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.5f));
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetWrapx(SCREEN_WIDTH);
CFont::SetJustifyOff();
CFont::SetBackGroundOnlyTextOff();
CFont::SetColor(CRGBA(255, 108, 0, 255));
- CFont::PrintString(10.0f, 10.0f, ver);
+ CFont::PrintString(SCREEN_SCALE_X(10.0f), SCREEN_SCALE_Y(10.0f), ver);
FrameSamples++;
FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
@@ -748,6 +748,7 @@ DisplayGameDebugText()
AsciiToUnicode(str, ustr);
+ // Let's not scale those numbers, they look better that way :eyes:
CFont::SetPropOff();
CFont::SetBackgroundOff();
CFont::SetScale(0.7f, 1.5f);