From 92cc1cf3af5c5454eddd464e42c495d3739a1cce Mon Sep 17 00:00:00 2001 From: _AG Date: Sat, 15 Jun 2019 01:34:19 +0200 Subject: [PATCH] New updates for Hud.cpp and more. --- src/Camera.cpp | 11 +- src/Camera.h | 3 +- src/Frontend.cpp | 45 +- src/Frontend.h | 92 ++- src/Messages.cpp | 9 + src/Messages.h | 38 +- src/Radar.cpp | 42 ++ src/Radar.h | 10 + src/Timer.h | 1 + src/Wanted.cpp | 3 + src/Wanted.h | 83 +++ src/World.cpp | 5 + src/World.h | 5 + src/audio/DMAudio.h | 171 +++++ src/common.h | 2 +- src/control/Darkel.cpp | 6 + src/control/Darkel.h | 4 + src/control/Replay.h | 3 +- src/control/Script.cpp | 3 + src/control/Script.h | 35 + src/entities/Ped.cpp | 2 +- src/entities/Ped.h | 24 +- src/entities/PlayerInfo.cpp | 3 + src/entities/PlayerInfo.h | 71 ++ src/entities/PlayerPed.h | 39 +- src/render/Draw.cpp | 3 + src/render/Hud.cpp | 1296 ++++++++++++++++++++++++++++++++++- src/render/Hud.h | 91 ++- 28 files changed, 2062 insertions(+), 38 deletions(-) create mode 100644 src/Wanted.cpp create mode 100644 src/Wanted.h create mode 100644 src/entities/PlayerInfo.cpp create mode 100644 src/entities/PlayerInfo.h diff --git a/src/Camera.cpp b/src/Camera.cpp index 6054f1fc..ebe08f09 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -14,8 +14,7 @@ const float DefaultFOV = 80.0f; // actually 70.0f CCamera &TheCamera = *(CCamera*)0x6FACF8; - -WRAPPER Bool CCam::Using3rdPersonMouseCam() { EAXJMP(0x457460); } +Bool &CCamera::m_bUseMouse3rdPerson = *(Bool *)0x5F03D8; WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); } @@ -1250,6 +1249,14 @@ CCam::FixCamWhenObscuredByVehicle(const CVector &TargetCoors) Source.z += HeightFixerCarsObscuring; } +bool CCam::Using3rdPersonMouseCam() { + return CCamera::m_bUseMouse3rdPerson && + (Mode == MODE_FOLLOWPED || + TheCamera.m_bPlayerIsInGarage && + FindPlayerPed() && FindPlayerPed()->m_nPedState != PED_DRIVING && + Mode != MODE_TOPDOWN1 && this->CamTargetEntity == FindPlayerPed()); +} + STARTPATCHES InjectHook(0x42C760, &CCamera::IsSphereVisible, PATCH_JUMP); InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP); diff --git a/src/Camera.h b/src/Camera.h index 73fce616..0f3a1128 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -161,7 +161,6 @@ struct CCam CPed *m_pLastPedLookedAt;// So interpolation works bool m_bFirstPersonRunAboutActive; - Bool Using3rdPersonMouseCam(); void GetVectorsReadyForRW(void); CVector DoAverageOnVector(const CVector &vec); @@ -172,6 +171,7 @@ struct CCam bool FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation); void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist); void FixCamWhenObscuredByVehicle(const CVector &TargetCoors); + bool Using3rdPersonMouseCam(); void Process_Debug(float *vec, float a, float b, float c); void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float); @@ -439,6 +439,7 @@ int m_iModeObbeCamIsInForCar; uint32 m_uiFadeTimeStarted; uint32 m_uiFadeTimeStartedMusic; + static Bool &m_bUseMouse3rdPerson; CMatrix &GetCameraMatrix(void) { return m_cameraMatrix; } CVector &GetGameCamPosition(void) { return m_vecGameCamPos; } diff --git a/src/Frontend.cpp b/src/Frontend.cpp index 35e48065..22e28cab 100644 --- a/src/Frontend.cpp +++ b/src/Frontend.cpp @@ -2,15 +2,30 @@ #include "patcher.h" #include "Frontend.h" -int &CMenuManager::OS_Language = *(int*)0x5F2F78; -int &CMenuManager::m_PrefsBrightness = *(int*)0x5F2E50; -int &CMenuManager::m_PrefsLanguage = *(int*)0x941238; -bool &CMenuManager::m_PrefsUseWideScreen = *(bool*)0x95CD23; -Bool &CMenuManager::m_PrefsVsync = *(Bool*)0x5F2E58; +int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78; +int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92; +int8 &CMenuManager::m_DisplayControllerOnFoot = *(int8*)0x95CD8D; +int8 &CMenuManager::m_PrefsVsync = *(int8*)0x5F2E58; +int8 &CMenuManager::m_PrefsVsyncDisp = *(int8*)0x5F2E5C; +int8 &CMenuManager::m_PrefsFrameLimiter = *(int8*)0x5F2E60; +int8 &CMenuManager::BlurOn = *(int8*)0x95CDAD; +int8 &CMenuManager::m_PrefsShowSubtitles = *(int8*)0x5F2E54; +int8 &CMenuManager::m_PrefsSpeakers = *(int8*)0x95CD7E; +int8 &CMenuManager::m_ControlMethod = *(int8*)0x8F5F7C; +int8 &CMenuManager::m_PrefsDMA = *(int8*)0x5F2F74; +int8 &CMenuManager::m_PrefsLanguage = *(int8*)0x941238; + Bool &CMenuManager::m_PrefsAllowNastyGame = *(Bool*)0x5F2E64; Bool &CMenuManager::m_bStartUpFrontEndRequested = *(Bool*)0x95CCF4; -Bool &CMenuManager::m_PrefsFrameLimiter = *(Bool*)0x5F2E60; -Bool &CMenuManager::m_PrefsUseVibration = *(Bool*)0x95CD92; + +int8 &CMenuManager::m_PrefsUseWideScreen = *(int8*)0x95CD23; +int8 &CMenuManager::m_PrefsRadioStation = *(int8*)0x95CDA4; +int8 &CMenuManager::m_bDisableMouseSteering = *(int8*)0x60252C; +int32 &CMenuManager::m_PrefsBrightness = *(int32*)0x5F2E50; +Float &CMenuManager::m_PrefsLOD = *(Float*)0x8F42C4; +int8 &CMenuManager::m_bFrontEnd_ReloadObrTxtGxt = *(int8*)0x628CFC; +int32 &CMenuManager::m_PrefsMusicVolume = *(int32*)0x5F2E4C; +int32 &CMenuManager::m_PrefsSfxVolume = *(int32*)0x5F2E48; CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8; @@ -20,3 +35,19 @@ WRAPPER void CMenuManager::UnloadTextures(void) { EAXJMP(0x47A440); } WRAPPER void CMenuManager::LoadAllTextures(void) { EAXJMP(0x47A230); } WRAPPER void CMenuManager::LoadSettings(void) { EAXJMP(0x488EE0); } WRAPPER void CMenuManager::WaitForUserCD(void) { EAXJMP(0x48ADD0); } + +int CMenuManager::FadeIn(int alpha) { + if (FrontEndMenuManager.m_nCurrScreen == MENU_LOADING_IN_PROGRESS || + FrontEndMenuManager.m_nCurrScreen == MENU_SAVING_IN_PROGRESS || + FrontEndMenuManager.m_nCurrScreen == MENU_DELETING) + return alpha; + + if (FrontEndMenuManager.m_nMenuFadeAlpha >= alpha) + return alpha; + + return FrontEndMenuManager.m_nMenuFadeAlpha; +} + +STARTPATCHES + InjectHook(0x48AC60, &CMenuManager::FadeIn, PATCH_JUMP); +ENDPATCHES \ No newline at end of file diff --git a/src/Frontend.h b/src/Frontend.h index 65b8c29a..6e781834 100644 --- a/src/Frontend.h +++ b/src/Frontend.h @@ -10,6 +10,68 @@ enum { LANGUAGE_SPANISH, }; +enum eMenuScreen { + MENU_NONE = 0, + MENU_STATS = 1, + MENU_NEW_GAME = 2, + MENU_BRIEFS = 3, + MENU_CONTROLLER_SETTINGS = 4, + MENU_SOUND_SETTINGS = 5, + MENU_GRAPHICS_SETTINGS = 6, + MENU_LANGUAGE_SETTINGS = 7, + MENU_CHOOSE_LOAD_SLOT = 8, + MENU_CHOOSE_DELETE_SLOT = 9, + MENU_NEW_GAME_RELOAD = 10, + MENU_LOAD_SLOT_CONFIRM = 11, + MENU_DELETE_SLOT_CONFIRM = 12, + MENU_13 = 13, + MENU_LOADING_IN_PROGRESS = 14, + MENU_DELETING_IN_PROGRESS = 15, + MENU_16 = 16, + MENU_DELETE_FAILED = 17, + MENU_DEBUG_MENU = 18, + MENU_MEMORY_CARD_1 = 19, + MENU_MEMORY_CARD_2 = 20, + MENU_MULTIPLAYER_MAIN = 21, + MENU_SAVE_FAILED_1 = 22, + MENU_SAVE_FAILED_2 = 23, + MENU_SAVE = 24, + MENU_NO_MEMORY_CARD = 25, + MENU_CHOOSE_SAVE_SLOT = 26, + MENU_SAVE_OVERWRITE_CONFIRM = 27, + MENU_MULTIPLAYER_MAP = 28, + MENU_MULTIPLAYER_CONNECTION = 29, + MENU_MULTIPLAYER_FIND_GAME = 30, + MENU_MULTIPLAYER_MODE = 31, + MENU_MULTIPLAYER_CREATE = 32, + MENU_MULTIPLAYER_START = 33, + MENU_SKIN_SELECT_OLD = 34, + MENU_CONTROLLER_PC = 35, + MENU_CONTROLLER_PC_OLD1 = 36, + MENU_CONTROLLER_PC_OLD2 = 37, + MENU_CONTROLLER_PC_OLD3 = 38, + MENU_CONTROLLER_PC_OLD4 = 39, + MENU_CONTROLLER_DEBUG = 40, + MENU_OPTIONS = 41, + MENU_EXIT = 42, + MENU_SAVING_IN_PROGRESS = 43, + MENU_SAVE_SUCCESSFUL = 44, + MENU_DELETING = 45, + MENU_DELETE_SUCCESS = 46, + MENU_SAVE_FAILED = 47, + MENU_LOAD_FAILED = 48, + MENU_LOAD_FAILED_2 = 49, + MENU_FILTER_GAME = 50, + MENU_START_MENU = 51, + MENU_PAUSE_MENU = 52, + MENU_CHOOSE_MODE = 53, + MENU_SKIN_SELECT = 54, + MENU_KEYBOARD_CONTROLS = 55, + MENU_MOUSE_CONTROLS = 56, + MENU_57 = 57, + MENU_58 = 58, +}; + struct tSkinInfo { int field_0; @@ -83,15 +145,29 @@ public: int m_nCurrSaveSlot; int m_nScreenChangeDelayTimer; - static int &OS_Language; - static int &m_PrefsBrightness; - static int &m_PrefsLanguage; - static bool &m_PrefsUseWideScreen; - static Bool &m_PrefsVsync; + 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 &BlurOn; + static int8 &m_PrefsShowSubtitles; + static int8 &m_PrefsSpeakers; + static int8 &m_ControlMethod; + static int8 &m_PrefsDMA; + static int8 &m_PrefsLanguage; + static int8 &m_bDisableMouseSteering; + static int32 &m_PrefsBrightness; + static Float &m_PrefsLOD; + static int8 &m_bFrontEnd_ReloadObrTxtGxt; + static int32 &m_PrefsMusicVolume; + static int32 &m_PrefsSfxVolume; + static Bool &m_PrefsAllowNastyGame; static Bool &m_bStartUpFrontEndRequested; - static Bool &m_PrefsFrameLimiter; - static Bool &m_PrefsUseVibration; void Process(void); void DrawFrontEnd(void); @@ -99,7 +175,9 @@ public: void LoadAllTextures(void); void LoadSettings(void); void WaitForUserCD(void); + int FadeIn(int alpha); }; + static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error"); extern CMenuManager &FrontEndMenuManager; diff --git a/src/Messages.cpp b/src/Messages.cpp index e29300f4..7fc23593 100644 --- a/src/Messages.cpp +++ b/src/Messages.cpp @@ -4,3 +4,12 @@ WRAPPER void CMessages::Display(void) { EAXJMP(0x529800); } WRAPPER void CMessages::ClearAllMessagesDisplayedByGame(void) { EAXJMP(0x52B670); } +WRAPPER int CMessages::WideStringCopy(wchar* dst, wchar* src, unsigned short size) { EAXJMP(0x5294B0); } +WRAPPER char CMessages::WideStringCompare(wchar* str1, wchar* str2, unsigned short size) { EAXJMP(0x529510); } +WRAPPER void CMessages::InsertNumberInString(wchar* src, int n1, int n2, int n3, int n4, int n5, int n6, wchar* dst) { EAXJMP(0x52A1A0); } +WRAPPER void CMessages::InsertPlayerControlKeysInString(wchar* src) { EAXJMP(0x52A490); } +WRAPPER int CMessages::GetWideStringLength(wchar* src) { EAXJMP(0x529490); } + +tPreviousBrief *CMessages::PreviousBriefs = (tPreviousBrief *)0x713C08; +tMessage *CMessages::BriefMessages = (tMessage *)0x8786E0; +tBigMessage *CMessages::BIGMessages = (tBigMessage *)0x773628; diff --git a/src/Messages.h b/src/Messages.h index 711427f1..69cf117c 100644 --- a/src/Messages.h +++ b/src/Messages.h @@ -1,8 +1,44 @@ #pragma once -class CMessages +struct tMessage { + wchar *m_pText; + uint16 m_nFlag; +private: + int8 _pad6[2]; +public: + uint32 m_nTime; + uint32 m_nStartTime; + int32 m_nNumber[6]; + wchar *m_pString; +}; + +struct tBigMessage +{ + tMessage m_Current; + tMessage m_Stack[3]; +}; + +struct tPreviousBrief +{ + wchar *m_pText; + int32 m_nNumber[6]; + wchar *m_pString; +}; + +class CMessages +{ +public: + static tPreviousBrief *PreviousBriefs; + static tMessage *BriefMessages; + static tBigMessage *BIGMessages; + public: static void Display(void); static void ClearAllMessagesDisplayedByGame(void); + static int WideStringCopy(wchar* dst, wchar* src, unsigned short size); + static char WideStringCompare(wchar* str1, wchar* str2, unsigned short size); + static void InsertNumberInString(wchar* src, int n1, int n2, int n3, int n4, int n5, int n6, wchar* dst); + static void InsertPlayerControlKeysInString(wchar* src); + static int GetWideStringLength(wchar *src); }; diff --git a/src/Radar.cpp b/src/Radar.cpp index a84d5b91..3b2d6b26 100644 --- a/src/Radar.cpp +++ b/src/Radar.cpp @@ -1,5 +1,47 @@ #include "common.h" #include "patcher.h" #include "Radar.h" +#include "Camera.h" +#include "Hud.h" +#include "World.h" +#include "Frontend.h" WRAPPER void CRadar::ClearBlipForEntity(eBlipType type, int32 id) { EAXJMP(0x4A56C0); } +WRAPPER void CRadar::Draw3dMarkers() { EAXJMP(0x4A4C70); } +//WRAPPER void CRadar::DrawMap () { EAXJMP(0x4A4200); } +WRAPPER void CRadar::DrawBlips() { EAXJMP(0x4A42F0); } +WRAPPER void CRadar::DrawRadarMap() { EAXJMP(0x4A6C20); } + +Float &CRadar::m_RadarRange = *(Float*)0x8E281C; +CVector2D &CRadar::vec2DRadarOrigin = *(CVector2D*)0x6299B8; + +void CRadar::DrawMap() { + if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) { + if (FindPlayerVehicle()) { + if (FindPlayerVehicle()->GetSpeed().Magnitude() > 0.3f) { + if (FindPlayerVehicle()->GetSpeed().Magnitude() > 0.9f) + CRadar::m_RadarRange = 350.0f; + else + CRadar::m_RadarRange = (FindPlayerVehicle()->GetSpeed().Magnitude() + 0.3f) * 200.0f; + } + else { + CRadar::m_RadarRange = 120.0f; + } + } + else { + CRadar::m_RadarRange = 120.0f; + } + vec2DRadarOrigin.x = FindPlayerCentreOfWorld_NoSniperShift().x; + vec2DRadarOrigin.y = FindPlayerCentreOfWorld_NoSniperShift().y; + CRadar::DrawRadarMap(); + } +} + +void CRadar::TransformRadarPointToScreenSpace(CVector2D *out, CVector2D *in) { + out->x = in->x * SCREEN_STRETCH_X(47.0f) + SCREEN_STRETCH_X(47.0f + 20.0f); + out->y = (SCREEN_STRETCH_Y(76.0f)) * 0.5f + RsGlobal.height - (SCREEN_STRETCH_Y(123.0f)) - in->y * (SCREEN_STRETCH_Y(76.0f)) * 0.5f; +} + +STARTPATCHES + InjectHook(0x4A5040, CRadar::TransformRadarPointToScreenSpace, PATCH_JUMP); +ENDPATCHES \ No newline at end of file diff --git a/src/Radar.h b/src/Radar.h index 123cffb1..f5afcd6e 100644 --- a/src/Radar.h +++ b/src/Radar.h @@ -1,4 +1,5 @@ #pragma once +#include "Sprite2d.h" enum eBlipType { @@ -12,6 +13,15 @@ enum eBlipType class CRadar { +public: + static Float &m_RadarRange; + static CVector2D &vec2DRadarOrigin; + public: static void ClearBlipForEntity(eBlipType type, int32 id); + static void Draw3dMarkers(); + static void DrawMap(); + static void TransformRadarPointToScreenSpace(CVector2D * out, CVector2D * in); + static void DrawBlips(); + static void DrawRadarMap(); }; diff --git a/src/Timer.h b/src/Timer.h index fa93a65e..c369777a 100644 --- a/src/Timer.h +++ b/src/Timer.h @@ -20,6 +20,7 @@ public: static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; } static inline Bool GetIsPaused() { return m_UserPause || m_CodePause; } + static inline Bool GetIsUserPaused() { return m_UserPause; } static inline void SetTimeScale(Float ts) { ms_fTimeScale = ts; } static void Initialise(void); diff --git a/src/Wanted.cpp b/src/Wanted.cpp new file mode 100644 index 00000000..36bc4f03 --- /dev/null +++ b/src/Wanted.cpp @@ -0,0 +1,3 @@ +#include "common.h" +#include "patcher.h" +#include "Wanted.h" diff --git a/src/Wanted.h b/src/Wanted.h new file mode 100644 index 00000000..cf24d5a5 --- /dev/null +++ b/src/Wanted.h @@ -0,0 +1,83 @@ +#pragma once +#include "Entity.h" +#include "math/Vector.h" + +enum eCrimeType { + CRIME_NONE, + CRIME_SHOT_FIRED, + CRIME_PED_FIGHT, + CRIME_COP_FIGHT, + CRIME_DAMAGED_PED, + CRIME_DAMAGED_COP, + CRIME_CAR_THEFT, + CRIME_CRIME7, + CRIME_COP_EVASIVE_DIVE, + CRIME_COP_EVASIVE_DIVE2, + CRIME_PED_RUN_OVER, + CRIME_COP_RUN_OVER, + CRIME_DESTROYED_HELI, + CRIME_PED_BURNED, + CRIME_COP_BURNED, + CRIME_VEHICLE_BURNED, + CRIME_DESTROYED_CESSNA, +}; + +enum eCopType { + COP_STREET = 0, + COP_FBI = 1, + COP_SWAT = 2, + COP_ARMY = 3, +}; + +class CCrime { +public: + eCrimeType m_eCrimeType; + CEntity *m_pVictim; + int32 m_nCrimeTime; + CVector m_vecCrimePos; + int8 m_bReported; + int8 m_bMultiplier; + int8 pad_20[2]; +}; + +class CCopPed { +public: + int16 m_wRoadblockNode; + int8 field_1342; + int8 field_1343; + Float m_fDistanceToTarget; + int8 m_bIsInPursuit; + int8 m_bIsDisabledCop; + int8 field_1350; + int8 field_1351; + int8 m_bZoneDisabledButClose; + int8 m_bZoneDisabled; + int8 field_1354; + int8 field_1355; + int32 field_1356; + eCopType m_nCopType; + int8 field_1364; + int8 field_1365; + int8 field_1366; + int8 field_1367; +}; + +class CWanted { +public: + int32 m_nChaos; + int32 m_nLastUpdateTime; + int32 m_nLastWantedLevelChange; + Float m_fCrimeSensitivity; + uint8 m_bCurrentCops; + uint8 m_bMaxCops; + uint8 m_bMaximumLawEnforcerVehicles; + int8 field_19; + int16 m_wRoadblockDensity; + uint8 m_bFlags; + int8 field_23; + int32 m_nWantedLevel; + CCrime m_sCrimes[16]; + CCopPed *m_pCops[10]; +}; + +static_assert(sizeof(CWanted) == 0x204, "CWanted: error"); diff --git a/src/World.cpp b/src/World.cpp index 7e408091..1d45dcc8 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -12,6 +12,8 @@ CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C; CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x665608; uint16 &CWorld::ms_nCurrentScanCode = *(uint16*)0x95CC64; +uint8 &CWorld::PlayerInFocus = *(uint8 *)0x95CD61; +CPlayerInfo *CWorld::Players = (CPlayerInfo *)0x9412F0; bool &CWorld::bNoMoreCollisionTorque = *(bool*)0x95CDCC; CEntity *&CWorld::pIgnoreEntity = *(CEntity**)0x8F6494; bool &CWorld::bIncludeDeadPeds = *(bool*)0x95CD8F; @@ -588,3 +590,6 @@ WRAPPER CPed *FindPlayerPed(void) { EAXJMP(0x4A1150); } WRAPPER CVector &FindPlayerCoors(CVector &v) { EAXJMP(0x4A1030); } WRAPPER CVehicle *FindPlayerVehicle(void) { EAXJMP(0x4A10C0); } WRAPPER CVehicle *FindPlayerTrain(void) { EAXJMP(0x4A1120); } +WRAPPER CVector FindPlayerSpeed(void) { EAXJMP(0x4A1090); } +WRAPPER CVector FindPlayerCentreOfWorld_NoSniperShift(void) { EAXJMP(0x4A11C0); } + diff --git a/src/World.h b/src/World.h index 2440906c..77e0fd99 100644 --- a/src/World.h +++ b/src/World.h @@ -2,6 +2,7 @@ #include "Game.h" #include "Lists.h" +#include "PlayerInfo.h" /* Sectors span from -2000 to 2000 in x and y. * With 100x100 sectors, each is 40x40 units. */ @@ -45,6 +46,8 @@ class CWorld static uint16 &ms_nCurrentScanCode; public: + static uint8 &PlayerInFocus; + static CPlayerInfo *Players; static CEntity *&pIgnoreEntity; static bool &bIncludeDeadPeds; static bool &bNoMoreCollisionTorque; @@ -95,3 +98,5 @@ CPed *FindPlayerPed(void); CVector &FindPlayerCoors(CVector &v); CVehicle *FindPlayerVehicle(void); CVehicle *FindPlayerTrain(void); +CVector FindPlayerSpeed(void); +CVector FindPlayerCentreOfWorld_NoSniperShift(void); \ No newline at end of file diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index 91a3ff0f..1b18c28c 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -1,5 +1,176 @@ #pragma once +enum eSound { + SOUND_CAR_DOOR_CLOSE_BONNET = 0, + SOUND_CAR_DOOR_CLOSE_BUMPER = 1, + SOUND_CAR_DOOR_CLOSE_FRONT_LEFT = 2, + SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT = 3, + SOUND_CAR_DOOR_CLOSE_BACK_LEFT = 4, + SOUND_CAR_DOOR_CLOSE_BACK_RIGHT = 5, + SOUND_CAR_DOOR_OPEN_BONNET = 6, + SOUND_CAR_DOOR_OPEN_BUMPER = 7, + SOUND_CAR_DOOR_OPEN_FRONT_LEFT = 8, + SOUND_CAR_DOOR_OPEN_FRONT_RIGHT = 9, + SOUND_CAR_DOOR_OPEN_BACK_LEFT = 10, + SOUND_CAR_DOOR_OPEN_BACK_RIGHT = 11, + SOUND_CAR_WINDSHIELD_CRACK = 12, + SOUND_CAR_JUMP = 13, + SOUND_E = 14, + SOUND_F = 15, + SOUND_CAR_ENGINE_START = 16, + SOUND_CAR_LIGHT_BREAK = 17, + SOUND_CAR_HYDRALIC_1 = 18, + SOUND_CAR_HYDRALIC_2 = 19, + SOUND_CAR_HYDRALIC_3 = 20, + SOUND_CAR_JERK = 21, + SOUND_CAR_SPLASH = 22, + SOUND_17 = 23, + SOUND_18 = 24, + SOUND_19 = 25, + SOUND_CAR_TANK_TURRET_ROTATE = 26, + SOUND_CAR_BOMB_TICK = 27, + SOUND_PLANE_ON_GROUND = 28, + SOUND_STEP_START = 29, + SOUND_STEP_END = 30, + SOUND_FALL_LAND = 31, + SOUND_FALL_COLLAPSE = 32, + SOUND_21 = 33, + SOUND_22 = 34, + SOUND_23 = 35, + SOUND_24 = 36, + SOUND_25 = 37, + SOUND_26 = 38, + SOUND_WEAPON_PUNCH_ATTACK = 39, + SOUND_28 = 40, + SOUND_29 = 41, + SOUND_2A = 42, + SOUND_2B = 43, + SOUND_2C = 44, + SOUND_2D = 45, + SOUND_WEAPON_BAT_ATTACK = 46, + SOUND_WEAPON_SHOT_FIRED = 47, + SOUND_WEAPON_RELOAD = 48, + SOUND_31 = 49, + SOUND_32 = 50, + SOUND_33 = 51, + SOUND_WEAPON_FLAMETHROWER_FIRE = 52, + SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM = 53, + SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM = 54, + SOUND_WEAPON_HIT_PED = 55, + SOUND_WEAPON_HIT_VEHICLE = 56, + SOUND_GARAGE_NO_MONEY = 57, + SOUND_GARAGE_BAD_VEHICLE = 58, + SOUND_GARAGE_OPENING = 59, + SOUND_3C = 60, + SOUND_GARAGE_BOMB1_SET = 61, + SOUND_GARAGE_BOMB2_SET = 62, + SOUND_GARAGE_BOMB3_SET = 63, + SOUND_40 = 64, + SOUND_41 = 65, + SOUND_GARAGE_VEHICLE_DECLINED = 66, + SOUND_GARAGE_VEHICLE_ACCEPTED = 67, + SOUND_GARAGE_DOOR_CLOSED = 68, + SOUND_GARAGE_DOOR_OPENED = 69, + SOUND_CRANE_PICKUP = 70, + SOUND_PICKUP_WEAPON_BOUGHT = 71, + SOUND_PICKUP_WEAPON = 72, + SOUND_PICKUP_HEALTH = 73, + SOUND_4A = 74, + SOUND_4B = 75, + SOUND_PICKUP_ADRENALINE = 76, + SOUND_PICKUP_ARMOUR = 77, + SOUND_PICKUP_BONUS = 78, + SOUND_PICKUP_MONEY = 79, + SOUND_PICKUP_HIDDEN_PACKAGE = 80, + SOUND_PICKUP_PACMAN_PILL = 81, + SOUND_PICKUP_PACMAN_PACKAGE = 82, + SOUND_PICKUP_FLOAT_PACKAGE = 83, + SOUND_BOMB_TIMED_ACTIVATED = 84, + SOUND_55 = 85, + SOUND_BOMB_ONIGNITION_ACTIVATED = 86, + SOUND_BOMB_TICK = 87, + SOUND_RAMPAGE_START = 88, + SOUND_RAMPAGE_ONGOING = 89, + SOUND_RAMPAGE_PASSED = 90, + SOUND_RAMPAGE_FAILED = 91, + SOUND_RAMPAGE_KILL = 92, + SOUND_RAMPAGE_CAR_BLOWN = 93, + SOUND_EVIDENCE_PICKUP = 94, + SOUND_UNLOAD_GOLD = 95, + SOUND_PAGER = 96, + SOUND_PED_DEATH = 97, + SOUND_PED_DAMAGE = 98, + SOUND_PED_63 = 99, + SOUND_PED_LAND = 100, + SOUND_PED_BULLET_HIT = 101, + SOUND_PED_BOMBER = 102, + SOUND_PED_BURNING = 103, + SOUND_PED_ARREST_FBI = 104, + SOUND_PED_ARREST_SWAT = 105, + SOUND_PED_ARREST_COP = 106, + SOUND_PED_HELI_PLAYER_FOUND = 107, + SOUND_PED_HANDS_UP = 108, + SOUND_PED_HANDS_COWER = 109, + SOUND_PED_FLEE_SPRINT = 110, + SOUND_PED_CAR_JACKING = 111, + SOUND_PED_MUGGING = 112, + SOUND_PED_CAR_JACKED = 113, + SOUND_PED_ROBBED = 114, + SOUND_PED_TAXI_WAIT = 115, + SOUND_PED_ATTACK = 116, + SOUND_PED_DEFEND = 117, + SOUND_PED_PURSUIT_ARMY = 118, + SOUND_PED_PURSUIT_FBI = 119, + SOUND_PED_PURSUIT_SWAT = 120, + SOUND_PED_PURSUIT_COP = 121, + SOUND_PED_HEALING = 122, + SOUND_PED_7B = 123, + SOUND_PED_LEAVE_VEHICLE = 124, + SOUND_PED_EVADE = 125, + SOUND_PED_FLEE_RUN = 126, + SOUND_PED_CAR_COLLISION = 127, + SOUND_PED_SOLICIT = 128, + SOUND_PED_EXTINGUISHING_FIRE = 129, + SOUND_PED_WAIT_DOUBLEBACK = 130, + SOUND_PED_CHAT_SEXY = 131, + SOUND_PED_CHAT_EVENT = 132, + SOUND_PED_CHAT = 133, + SOUND_PED_BODYCAST_HIT = 134, + SOUND_PED_TAXI_CALL = 135, + SOUND_INJURED_PED_MALE_OUCH = 136, + SOUND_INJURED_PED_FEMALE = 137, + SOUND_8A = 138, + SOUND_RACE_START_3 = 139, + SOUND_RACE_START_2 = 140, + SOUND_RACE_START_1 = 141, + SOUND_RACE_START_GO = 142, + SOUND_SPLASH = 143, + SOUND_WATER_FALL = 144, + SOUND_SPLATTER = 145, + SOUND_CAR_PED_COLLISION = 146, + SOUND_CLOCK_TICK = 147, + SOUND_PART_MISSION_COMPLETE = 148, + SOUND_FRONTEND_MENU_STARTING = 149, + SOUND_FRONTEND_MENU_COMPLETED = 150, + SOUND_FRONTEND_MENU_DENIED = 151, + SOUND_FRONTEND_MENU_SUCCESS = 152, + SOUND_FRONTEND_EXIT = 153, + SOUND_9A = 154, + SOUND_9B = 155, + SOUND_FRONTEND_AUDIO_TEST = 156, + SOUND_FRONTEND_FAIL = 157, + SOUND_FRONTEND_NO_RADIO = 158, + SOUND_FRONTEND_RADIO_CHANGE = 159, + SOUND_A0 = 160, + SOUND_AMMUNATION_WELCOME_1 = 161, + SOUND_AMMUNATION_WELCOME_2 = 162, + SOUND_AMMUNATION_WELCOME_3 = 163, + SOUND_LIGHTNING = 164, + SOUND_A5 = 165, + SOUND_TOTAL_SOUNDS = 166, + SOUND_TOTAL_PED_SOUNDS = 167, +}; + class CEntity; class cDMAudio diff --git a/src/common.h b/src/common.h index 4187e0c3..966af022 100644 --- a/src/common.h +++ b/src/common.h @@ -67,7 +67,7 @@ extern void **rwengine; #define DEFAULT_SCREEN_HEIGHT (448) #define SCREEN_WIDTH Float(RsGlobal.width) #define SCREEN_HEIGHT Float(RsGlobal.height) -#define SCREEN_STRETCH_X(a) Float((a) * (SCREEN_WIDTH / Float(DEFAULT_SCREEN_WIDTH))) +#define SCREEN_STRETCH_X(a) Float((a) * (SCREEN_WIDTH / Float(DEFAULT_SCREEN_WIDTH))) * Float(1.33334f / (CMenuManager::m_PrefsUseWideScreen ? 16.0f / 9.0f : 4.0f / 3.0f)) #define SCREEN_STRETCH_Y(a) Float((a) * (SCREEN_HEIGHT / Float(DEFAULT_SCREEN_HEIGHT))) #define SCREEN_FROM_RIGHT(a) Float(SCREEN_WIDTH - SCREEN_STRETCH_X(a)) #define SCREEN_FROM_BOTTOM(a) Float(SCREEN_HEIGHT - SCREEN_STRETCH_Y(a)) diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 95f3e176..e2d9fd72 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -3,3 +3,9 @@ #include "Darkel.h" WRAPPER void CDarkel::DrawMessages(void) { EAXJMP(0x420920); } + +bool CDarkel::Status = *(bool*)0x95CCB4; + +bool CDarkel::FrenzyOnGoing() { + return Status; +} \ No newline at end of file diff --git a/src/control/Darkel.h b/src/control/Darkel.h index 41cc69f8..ed78d4e1 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -2,6 +2,10 @@ class CDarkel { +private: + static bool Status; + public: static void DrawMessages(void); + static bool FrenzyOnGoing(); }; diff --git a/src/control/Replay.h b/src/control/Replay.h index 5d63db1f..2fe2f272 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -3,11 +3,12 @@ class CReplay { public: - static void Display(void); enum { MODE_1 = 1 }; static uint8 &Mode; static Bool &bPlayingBackFromFile; + + static void Display(void); }; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 71fc7bcd..7cea978f 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -4,3 +4,6 @@ #include "Script.h" uint8 *CTheScripts::ScriptSpace = (uint8*)0x74B248; +CTextLine* CTheScripts::IntroTextLines = (CTextLine*)0x70EA74; +CScriptRectangle* CTheScripts::IntroRectangles = (CScriptRectangle*)0x72D109; +CSprite2d* CTheScripts::ScriptSprites = (CSprite2d*)0x72B090; diff --git a/src/control/Script.h b/src/control/Script.h index 6f329e1f..0fe35fd2 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -1,7 +1,42 @@ #pragma once +#include "Sprite2d.h" + +struct CScriptRectangle +{ + Bool m_bIsUsed; + Bool m_bIsAntialiased; + uint16 m_wTextureId; + CRect m_sRect; + CRGBA m_sColor; +}; + +struct CTextLine +{ + Float m_fScaleX; + Float m_fScaleY; + CRGBA m_sColor; + Bool m_bJustify; + Bool m_bCentered; + Bool m_bBackground; + Bool m_bBackgroundOnly; + Float m_fWrapX; + Float m_fCenterSize; + CRGBA m_sBackgroundColor; + Bool m_bTextProportional; + int32 field_29; + Bool m_bRightJustify; + int32 field_31; + int32 m_nFont; + Float field_36; + Float field_40; + wchar m_awText[500]; +}; class CTheScripts { public: static uint8 *ScriptSpace;//[160*1024] + static CTextLine* IntroTextLines; + static CScriptRectangle* IntroRectangles; + static CSprite2d* ScriptSprites; }; diff --git a/src/entities/Ped.cpp b/src/entities/Ped.cpp index 55e33a2d..90ee54be 100644 --- a/src/entities/Ped.cpp +++ b/src/entities/Ped.cpp @@ -6,7 +6,7 @@ Bool &CPed::bNastyLimbsCheat = *(Bool*)0x95CD44; Bool &CPed::bPedCheat2 = *(Bool*)0x95CD5A; Bool &CPed::bPedCheat3 = *(Bool*)0x95CD59; - + void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); } void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); } diff --git a/src/entities/Ped.h b/src/entities/Ped.h index adf24c88..28ad6624 100644 --- a/src/entities/Ped.h +++ b/src/entities/Ped.h @@ -2,6 +2,7 @@ #include "Physical.h" #include "Weapon.h" +#include "PathFind.h" enum { PED_MAX_WEAPONS = 13 @@ -163,13 +164,30 @@ public: int32 m_nPedState; int32 m_nLastPedState; int32 m_nMoveState; - uint8 stuff2[188]; + int32 m_nStoredActionState; + int32 m_nPrevActionState; + int32 m_nWaitState; + int32 m_nWaitTimer; +private: + uint32 stuff0[28]; +public: + uint16 m_nPathNodes; + uint8 m_nCurPathNode; + int8 m_nPathState; +private: + int8 _pad2B5[3]; +public: + CPathNode *m_pNextPathNode; + CPathNode *m_pLastPathNode; + Float m_fHealth; + Float m_fArmour; + uint8 stuff2[34]; CEntity *m_pCurrentPhysSurface; CVector m_vecOffsetFromPhysSurface; CEntity *m_pCurSurface; uint8 stuff3[16]; CVehicle *m_pMyVehicle; - bool bInVehicle; + Bool bInVehicle; uint8 stuff4[23]; int32 m_nPedType; @@ -188,7 +206,7 @@ public: bool UseGroundColModel(void); void KillPedWithCar(CVehicle *veh, float impulse); CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; } - + static Bool &bNastyLimbsCheat; static Bool &bPedCheat2; static Bool &bPedCheat3; diff --git a/src/entities/PlayerInfo.cpp b/src/entities/PlayerInfo.cpp new file mode 100644 index 00000000..796481a4 --- /dev/null +++ b/src/entities/PlayerInfo.cpp @@ -0,0 +1,3 @@ +#include "common.h" +#include "patcher.h" +#include "PlayerInfo.h" diff --git a/src/entities/PlayerInfo.h b/src/entities/PlayerInfo.h new file mode 100644 index 00000000..eb15f53f --- /dev/null +++ b/src/entities/PlayerInfo.h @@ -0,0 +1,71 @@ +#pragma once +#include "Automobile.h" +#include "PlayerPed.h" + +enum eWastedBustedState { + WBSTATE_PLAYING = 0x0, + WBSTATE_WASTED = 0x1, + WBSTATE_BUSTED = 0x2, + WBSTATE_FAILED_CRITICAL_MISSION = 0x3, +}; + +struct CCivilianPed { + +}; + +class CPlayerInfo { +public: + CPlayerPed *m_pPed; + CVehicle *m_pRemoteVehicle; + CColModel m_ColModel; + CVehicle *m_pVehicleEx; + char m_aszPlayerName[70]; +private: + int8 _pad0[2]; +public: + int32 m_nMoney; + int32 m_nVisibleMoney; + int32 m_nCollectedPackages; + int32 m_nTotalPackages; + int32 field_188; + int32 m_nSwitchTaxiTime; + Bool m_bSwitchTaxi; + int8 field_197; + int8 field_198; + int8 field_199; + int32 m_nNextSexFrequencyUpdateTime; + int32 m_nNextSexMoneyUpdateTime; + int32 m_nSexFrequency; + CCivilianPed *m_pHooker; + int8 m_bWBState; // eWastedBustedState + int8 field_217; + int8 field_218; + int8 field_219; + int32 m_nWBTime; + Bool m_bInRemoteMode; + int8 field_225; + int8 field_226; + int8 field_227; + int32 m_nTimeLostRemoteCar; + int32 m_nTimeLastHealthLoss; + int32 m_nTimeLastArmourLoss; + int32 field_240; + int32 m_nUpsideDownCounter; + int32 field_248; + int16 m_nTrafficMultiplier; + int8 field_254; + int8 field_255; + Float m_fRoadDensity; + int32 m_nPreviousTimeRewardedForExplosion; + int32 m_nExplosionsSinceLastReward; + int32 field_268; + int32 field_272; + Bool m_bInfiniteSprint; + Bool m_bFastReload; + Bool m_bGetOutOfJailFree; + Bool m_bGetOutOfHospitalFree; + uint8 m_aSkinName[32]; + RwTexture *m_pSkinTexture; +}; + +static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerPed: error"); diff --git a/src/entities/PlayerPed.h b/src/entities/PlayerPed.h index 35128f46..6721f975 100644 --- a/src/entities/PlayerPed.h +++ b/src/entities/PlayerPed.h @@ -1,11 +1,42 @@ #pragma once #include "Ped.h" +#include "Wanted.h" -class CPlayerPed : public CPed -{ +class CPlayerPed : public CPed { public: - // 0x53C - uint8 stuff[180]; + CWanted *m_pWanted; + CCopPed *m_pArrestingCop; + Float m_fMoveSpeed; + Float m_fCurrentStamina; + Float m_fMaxStamina; + Float m_fStaminaProgress; + Bool m_bWeaponSlot; + Bool m_bSpeedTimerFlag; + Bool m_bShouldEvade; + int8 field_1367; + int32 m_nSpeedTimer; + int32 m_nShotDelay; + Float field_1376; + int8 field_1380; + int8 field_1381; + int8 field_1382; + int8 field_1383; + CEntity *m_pEvadingFrom; + int32 m_nTargettableObjects[4]; + Bool m_bAdrenalineActive; + Bool m_bHasLockOnTarget; + int8 field_1406; + int8 field_1407; + Bool m_bAdrenalineTime; + Bool m_bCanBeDamaged; + int8 field_1413; + int8 field_1414; + int8 field_1415; + CVector field_1416[6]; + int32 field_1488[6]; + Float field_1512; + Float m_fFPSMoveHeading; }; + static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error"); diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp index 7c5a48ad..fd9a2d7e 100644 --- a/src/render/Draw.cpp +++ b/src/render/Draw.cpp @@ -36,4 +36,7 @@ CDraw::SetFOV(float fov) STARTPATCHES InjectHook(0x4FE7B0, CDraw::SetFOV, PATCH_JUMP); + + Nop(0x46B618, 2); + Patch(0x5F0A64, 1.3333334f); ENDPATCHES diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index 0de5f5b0..8ff20e5a 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -1,8 +1,1298 @@ #include "common.h" #include "patcher.h" +#include "Camera.h" +#include "DMAudio.h" +#include "Clock.h" +#include "Darkel.h" #include "Hud.h" +#include "Messages.h" +#include "Frontend.h" +#include "Font.h" +#include "Pad.h" +#include "Radar.h" +#include "Replay.h" +#include "Sprite.h" +#include "Sprite2d.h" +#include "Text.h" +#include "Timer.h" +#include "Script.h" +#include "TxdStore.h" +#include "User.h" +#include "World.h" -bool &CHud::m_Wants_To_Draw_Hud = *(bool*)0x95CD89; +//WRAPPER void CHud::Draw(void) { EAXJMP(0x5052A0); } +//WRAPPER void CHud::DrawAfterFade(void) { EAXJMP(0x509030); } +WRAPPER void CHud::ReInitialise(void) { EAXJMP(0x504CC0); } +WRAPPER void CHud::GetRidOfAllHudMessages(void) { EAXJMP(0x504F90); } +WRAPPER void CHud::SetHelpMessage(wchar* message, bool quick) { EAXJMP(0x5051E0); } +WRAPPER void CHud::SetMessage(wchar* message) { EAXJMP(0x50A210); } +WRAPPER void CHud::SetBigMessage(wchar* message, int16 style) { EAXJMP(0x50A250); } +WRAPPER void CHud::SetPagerMessage(wchar* message) { EAXJMP(0x50A320); } -WRAPPER void CHud::Draw(void) { EAXJMP(0x5052A0); } -WRAPPER void CHud::DrawAfterFade(void) { EAXJMP(0x509030); } +wchar *CHud::m_HelpMessage = (wchar*)0x86B888; +wchar *CHud::m_LastHelpMessage = (wchar*)0x6E8F28; +int32 &CHud::m_HelpMessageState = *(int32*)0x880E1C; +int32 &CHud::m_HelpMessageTimer = *(int32*)0x880FA4; +int32 &CHud::m_HelpMessageFadeTimer = *(int32*)0x8F6258; +wchar *CHud::m_HelpMessageToPrint = (wchar*)0x664480; +Float &CHud::m_HelpMessageDisplayTime = *(Float*)0x8E2C28; +Float &CHud::m_fTextBoxNumLines = *(Float*)0x8E2C28; +Float &CHud::m_fHelpMessageTime = *(Float *)0x8E2C28; +Bool &CHud::m_bHelpMessageQuick = *(Bool *)0x95CCF7; +int32 CHud::m_ZoneState = *(int32*)0x8F29AC; +int32 CHud::m_ZoneFadeTimer; +int32 CHud::m_ZoneNameTimer = *(int32*)0x8F1A50; +wchar* &CHud::m_pZoneName = *(wchar **)0x8E2C2C; +wchar* CHud::m_pLastZoneName = (wchar*)0x8F432C; +wchar* CHud::m_ZoneToPrint; +int32 CHud::m_VehicleState = *(int32*)0x940560; +int32 CHud::m_VehicleFadeTimer; +int32 CHud::m_VehicleNameTimer = *(int32*)0x8F2A14; +wchar* &CHud::m_pVehicleName = *(wchar **)0x942FB4; +wchar* CHud::m_pLastVehicleName = *(wchar **)0x8E2DD8; +wchar* CHud::m_pVehicleNameToPrint; +wchar* CHud::m_Message = (wchar*)0x72E318; +wchar* CHud::m_PagerMessage = (wchar*)0x878840; +Bool &CHud::m_bRetuneInProgress = *(Bool*)0x650B80; +Bool &CHud::m_Wants_To_Draw_Hud = *(Bool*)0x95CD89; +Bool &CHud::m_Wants_To_Draw_3dMarkers = *(Bool*)0x95CD62; +wchar(*CHud::m_BigMessage)[128] = (wchar(*)[128])0x664CE0; +Float *CHud::BigMessageInUse = (Float*)0x862140; +Float *CHud::BigMessageAlpha = (Float*)0x862108; +Float *CHud::BigMessageX = (Float*)0x773248; + +Float &CHud::OddJob2OffTimer = *(Float*)0x942FA0; +int8 &CHud::CounterOnLastFrame = *(int8*)0x95CD67; +Float &CHud::OddJob2XOffset = *(Float*)0x8F1B5C; +int16 &CHud::CounterFlashTimer = *(int16*)0x95CC20; +int16 &CHud::OddJob2Timer = *(int16*)0x95CC52; +int8 &CHud::TimerOnLastFrame = *(int8*)0x95CDA7; +int16 &CHud::OddJob2On = *(int16*)0x95CC78; +int16 &CHud::TimerFlashTimer = *(int16*)0x95CC6C; +int16 &CHud::PagerSoundPlayed = *(int16*)0x95CC4A; +int32 &CHud::SpriteBrightness = *(int32*)0x95CC54; +Float &CHud::PagerXOffset = *(Float*)0x941590; +int32 CHud::m_ItemToFlash = *(int32*)0x95CC82; +int16 &CHud::PagerTimer = *(int16*)0x95CC3A; +int16 &CHud::PagerOn = *(int16*)0x95CCA0; + +CSprite2d *CHud::Sprites = (CSprite2d*)0x95CB9C; +char *HudNames[] = { "fist", + "fistm", + "bat", + "batm", + "pistol", + "pistolm", + "uzi", + "uzim", + "shotgun", + "shotgunm", + "ak47", + "ak47m", + "m16", + "m16m", + "sniper", + "sniperm", + "rocket", + "rocketm", + "flame", + "flamem", + "molotov", + "molotovm", + "grenade", + "grenadem", + "detonator", + "detonator_mask", + "", + "", + "", + "", + "radardisc", + "radardiscm", + "pager", + "pagerm", + "", + "", + "", + "", + "bleeder", + "", + "sitesniper", + "sitesniperm", + "siteM16", + "siteM16m", + "siterocket", + "siterocketm" + }; + +RwTexture* gpSniperSightTex = (RwTexture*)0x8F5834; +RwTexture* gpRocketSightTex = (RwTexture*)0x8E2C20; + +void CHud::Initialise() { + ReInitialise(); + + int HudTXD = CTxdStore::AddTxdSlot("hud"); + CTxdStore::LoadTxd(HudTXD, "MODELS/HUD.TXD"); + CTxdStore::AddRef(HudTXD); + CTxdStore::PopCurrentTxd(); + CTxdStore::SetCurrentTxd(HudTXD); + + for (int i = 0; i < 23; i++) { + Sprites[i].SetTexture(HudNames[i * 2]); + } + + gpSniperSightTex = RwTextureRead("sitesniper", 0); + gpRocketSightTex = RwTextureRead("siterocket", 0); + + CTxdStore::PopCurrentTxd(); +} + +void CHud::Shutdown() { + for (int i = 0; i < 23; ++i) { + Sprites[i].Delete(); + } + + RwTextureDestroy(gpSniperSightTex); + gpSniperSightTex = 0; + + RwTextureDestroy(gpRocketSightTex); + gpRocketSightTex = 0; + + int HudTXD = CTxdStore::FindTxdSlot("hud"); + CTxdStore::RemoveTxdSlot(HudTXD); +} + +void CHud::SetVehicleName(wchar* name) { + m_pVehicleName = name; +} + +void CHud::SetZoneName(wchar* name) { + m_pZoneName = name; +} + +void CHud::Draw() { + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSMIRROR); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT); + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + + if (CReplay::Mode != 1) { + if (m_Wants_To_Draw_Hud && !TheCamera.m_WideScreenOn) { + Bool Mode_RunAround = 0; + Bool Mode_FirstPerson = 0; + + int32 WeaponType = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + int32 Mode = TheCamera.Cams[TheCamera.ActiveCam].Mode; + + if (Mode == CCam::CamMode::MODE_SNIPER || Mode == CCam::CamMode::MODE_ROCKET || Mode == CCam::CamMode::MODE_M16FIRSTPERSON_34 || Mode == CCam::CamMode::MODE_EDITOR) + Mode_FirstPerson = 1; + if (Mode == CCam::CamMode::MODE_FIRSTPERSONPEDONPC_41 || Mode == CCam::CamMode::MODE_SNIPER_RUN_AROUND) + Mode_RunAround = 1; + + /* + Draw Crosshairs + */ + if (TheCamera.Cams->Using3rdPersonMouseCam() && (!CPad::GetPad(0)->GetLookBehindForPed() || TheCamera.m_bPlayerIsInGarage) || Mode == 40) { + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed) { + int32 State = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_nPedState; + if (State != PED_ENTER_CAR && State != PED_CARJACK) { + if ((WeaponType >= WEAPONTYPE_COLT45 && WeaponType <= WEAPONTYPE_M16) || WeaponType == WEAPONTYPE_FLAMETHROWER) + Mode_RunAround = 1; + } + } + } + + if (Mode_FirstPerson || Mode_RunAround) { + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR); + + int32 SpriteBrightLikeADiamond = CHud::SpriteBrightness + 1; + if (SpriteBrightLikeADiamond > 30) + SpriteBrightLikeADiamond = 30; + + CHud::SpriteBrightness = SpriteBrightLikeADiamond; + + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + + Float fStep = sin((CTimer::GetTimeInMilliseconds() & 1023) * 0.0061328127); + Float fMultBright = CHud::SpriteBrightness * 0.033333335f * (0.25f * fStep + 0.75f); + CRect rect; + + float fWidescreenOffset[2] = { 0.0f, 0.0f }; + + if (CMenuManager::m_PrefsUseWideScreen) { + fWidescreenOffset[0] = 0.0f; + fWidescreenOffset[1] = SCREEN_STRETCH_Y(18.0f); + } + + if (Mode_RunAround && TheCamera.Cams->Using3rdPersonMouseCam()) { + Float f3rdX = RsGlobal.maximumWidth * TheCamera.m_f3rdPersonCHairMultX + fWidescreenOffset[0]; + Float f3rdY = RsGlobal.maximumHeight * TheCamera.m_f3rdPersonCHairMultY - fWidescreenOffset[1]; + + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed && WeaponType == WEAPONTYPE_M16) { + rect.left = f3rdX - SCREEN_STRETCH_X(32.0f * 0.6f); + rect.top = f3rdY - SCREEN_STRETCH_Y(32.0f * 0.6f); + rect.right = f3rdX + SCREEN_STRETCH_X(32.0f * 0.6f); + rect.bottom = f3rdY + SCREEN_STRETCH_Y(32.0f * 0.6f); + + CHud::Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + } + else { + rect.left = f3rdX - SCREEN_STRETCH_X(32.0f * 0.4f); + rect.top = f3rdY - SCREEN_STRETCH_Y(32.0f * 0.4f); + rect.right = f3rdX + SCREEN_STRETCH_X(32.0f * 0.4f); + rect.bottom = f3rdY + SCREEN_STRETCH_Y(32.0f * 0.4f); + + CHud::Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + } + } + else { + if (Mode != CCam::CamMode::MODE_M16FIRSTPERSON_34 && Mode != CCam::CamMode::MODE_FIRSTPERSONPEDONPC_41 && Mode != CCam::CamMode::MODE_EDITOR) { + if (Mode == CCam::CamMode::MODE_ROCKET_RUN_AROUND) { + rect.left = (SCREEN_WIDTH / 2) - SCREEN_STRETCH_X(32.0f * 0.7f); + rect.top = (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(32.0f * 0.7f); + rect.right = (SCREEN_WIDTH / 2) + SCREEN_STRETCH_X(32.0f * 0.7f); + rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_STRETCH_Y(32.0f * 0.7f); + + CHud::Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + } + else if (Mode != CCam::CamMode::MODE_ROCKET && Mode != CCam::CamMode::MODE_SNIPER_RUN_AROUND) { + rect.left = (SCREEN_WIDTH / 2) - SCREEN_STRETCH_X(210.0f); + rect.top = (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(210.0f); + rect.right = SCREEN_WIDTH / 2; + rect.bottom = SCREEN_HEIGHT / 2; + CHud::Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + + rect.right = (SCREEN_WIDTH / 2); + rect.top = (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(210.0f); + rect.left = SCREEN_STRETCH_X(210.0f) + (SCREEN_WIDTH / 2); + rect.bottom = SCREEN_HEIGHT / 2; + CHud::Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + + rect.left = (SCREEN_WIDTH / 2) - SCREEN_STRETCH_X(210.0f); + rect.bottom = (SCREEN_HEIGHT / 2); + rect.right = (SCREEN_WIDTH / 2); + rect.top = SCREEN_STRETCH_Y(210.0f) + (SCREEN_HEIGHT / 2); + CHud::Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + + rect.right = (SCREEN_WIDTH / 2); + rect.bottom = (SCREEN_HEIGHT / 2); + rect.left = SCREEN_STRETCH_X(210.0f) + (SCREEN_WIDTH / 2); + rect.top = SCREEN_STRETCH_Y(210.0f) + (SCREEN_HEIGHT / 2); + CHud::Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + } + else { + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRocketSightTex->raster); + + CSprite::RenderOneXLUSprite(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1.0f, SCREEN_STRETCH_X(40.0f), SCREEN_STRETCH_Y(40.0f), (100.0f * fMultBright), (200.0f * fMultBright), (100.0f * fMultBright), 255, 1.0f, 255); + } + } + else { + rect.left = (SCREEN_WIDTH / 2) - SCREEN_STRETCH_X(32.0f); + rect.top = (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(32.0f); + rect.right = (SCREEN_WIDTH / 2) + SCREEN_STRETCH_X(32.0f); + rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_STRETCH_Y(32.0f); + CHud::Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + } + } + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); + } + else { + CHud::SpriteBrightness = 0; + } + + /* + DrawMoneyCounter + */ + wchar sPrint[16]; + wchar sPrintIcon[16]; + char sTemp[16]; + + sprintf(sTemp, "$%08d", CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + AsciiToUnicode(sTemp, sPrint); + + CFont::SetPropOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetPropOff(); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + + CFont::PrintString(SCREEN_FROM_RIGHT(110.0f - 2.0f), SCREEN_STRETCH_Y(43.0f + 2.0f), sPrint); + + CFont::SetColor(CRGBA(89, 115, 150, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(110.0f), SCREEN_STRETCH_Y(43.0f), sPrint); + + /* + DrawClock + */ + sprintf(sTemp, "%02d:%02d", CClock::GetHours(), CClock::GetMinutes()); + AsciiToUnicode(sTemp, sPrint); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + + CFont::PrintString(SCREEN_FROM_RIGHT(111.0f - 2.0f), SCREEN_STRETCH_Y(22.0f + 2.0f), sPrint); + + CFont::SetColor(CRGBA(194, 165, 120, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(111.0f), SCREEN_STRETCH_Y(22.0f), sPrint); + + /* + DrawAmmo + */ + int32 AmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip; + int32 TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; + + if (AmmoInClip <= 1 || AmmoInClip >= 1000) { + sprintf(sTemp, "%d", TotalAmmo); + } + else { + if (WeaponType == WEAPONTYPE_FLAMETHROWER) { + int tot_min_clip_div_10 = (TotalAmmo - AmmoInClip) / 10; + if (tot_min_clip_div_10 > 9999) + tot_min_clip_div_10 = 9999; + + sprintf(sTemp, "%d-%d", tot_min_clip_div_10, AmmoInClip / 10); + } + else { + if (AmmoInClip > 9999) + AmmoInClip = 9999; + sprintf(sTemp, "%d-%d", (TotalAmmo - AmmoInClip), AmmoInClip); + } + } + + AsciiToUnicode(sTemp, sPrint); + + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(0.4f), SCREEN_STRETCH_Y(0.6f)); + CFont::SetJustifyOff(); + CFont::SetCentreOn(); + CFont::SetCentreSize(SCREEN_STRETCH_X(640.0f)); + CFont::SetPropOn(); + CFont::SetFontStyle(FONT_BANK); + + if (!CDarkel::FrenzyOnGoing()) { + if (WeaponType) { + if (WeaponType != 1) { + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(66.0f), SCREEN_STRETCH_Y(73.0f), sPrint); + } + } + } + + /* + DrawWeaponIcon + */ + CHud::Sprites[WeaponType].Draw( + CRect(SCREEN_FROM_RIGHT(99.0f), SCREEN_STRETCH_Y(27.0f), SCREEN_FROM_RIGHT(35.0f), SCREEN_STRETCH_Y(91.0f)), + CRGBA(255, 255, 255, 255), + 0.015f, + 0.015f, + 1.0f, + 0.0f, + 0.015f, + 1.0f, + 1.0f, + 1.0f); + + /* + DrawHealth + */ + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + CFont::SetJustifyOff(); + CFont::SetCentreOff(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetRightJustifyOn(); + CFont::SetPropOff(); + CFont::SetFontStyle(FONT_HEADING); + + if (CHud::m_ItemToFlash == 4 && CTimer::GetFrameCounter() & 8 + || CHud::m_ItemToFlash != 4 + || CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth < 10 + && CTimer::GetFrameCounter() & 8) { + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth >= 10 + || CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) { + + AsciiToUnicode("[", sPrintIcon); + sprintf(sTemp, "%03d", (int32)CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth); + AsciiToUnicode(sTemp, sPrint); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(110.0f - 2.0f), SCREEN_STRETCH_Y(65.0f + 2.0f), sPrint); + + if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || CTimer::GetFrameCounter() & 4) { + CFont::PrintString(SCREEN_FROM_RIGHT(164.0f - 2.0f), SCREEN_STRETCH_Y(65.0f + 2.0f), sPrintIcon); + } + CFont::SetColor(CRGBA(186, 101, 50, 255)); + + CFont::PrintString(SCREEN_FROM_RIGHT(110.0f), SCREEN_STRETCH_Y(65.0f), sPrint); + + if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || CTimer::GetFrameCounter() & 4) { + CFont::PrintString(SCREEN_FROM_RIGHT(164.0f), SCREEN_STRETCH_Y(65.0f), sPrintIcon); + } + } + } + + /* + DrawArmour + */ + if (CHud::m_ItemToFlash == 3 && CTimer::GetFrameCounter() & 8 || CHud::m_ItemToFlash != 3) { + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fArmour > 1.0f) { + AsciiToUnicode("[", sPrintIcon); + sprintf(sTemp, "%03d", (int32)CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fArmour); + AsciiToUnicode(sTemp, sPrint); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(182.0f - 2.0f), SCREEN_STRETCH_Y(65.0f + 2.0f), sPrint); + + if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 4) { + CFont::PrintString(SCREEN_FROM_RIGHT(234.0f - 2.0f), SCREEN_STRETCH_Y(65.0f + 2.0f), sPrintIcon); + } + + CFont::SetColor(CRGBA(124, 140, 95, 255)); + + CFont::PrintString(SCREEN_FROM_RIGHT(182.0f), SCREEN_STRETCH_Y(65.0f), sPrint); + + if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 1) { + CFont::PrintString(SCREEN_FROM_RIGHT(234.0f), SCREEN_STRETCH_Y(65.0f), sPrintIcon); + } + } + } + + /* + DrawWantedLevel + */ + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + CFont::SetJustifyOff(); + CFont::SetCentreOff(); + CFont::SetRightJustifyOff(); + CFont::SetPropOn(); + CFont::SetFontStyle(FONT_HEADING); + + AsciiToUnicode("]", sPrintIcon); + + for (int i = 0; i < 6; i++) { + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(2.0f + SCREEN_FROM_RIGHT(60.0f - 2.0f + 23.0f * i), SCREEN_STRETCH_Y(87.0f + 2.0f), sPrintIcon); + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel > i + && (CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nLastWantedLevelChange + + 2000 || CTimer::GetFrameCounter() & 4)) { + + CFont::SetColor(CRGBA(193, 164, 120, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(60.0f + 23.0f * i), SCREEN_STRETCH_Y(87.0f), sPrintIcon); + } + } + + /* + DrawZoneName + */ + if (CHud::m_pZoneName) { + Float fZoneAlpha = 0.0f; + + if (CHud::m_pZoneName != CHud::m_pLastZoneName) { + switch (CHud::m_ZoneState) { + case 0: + CHud::m_ZoneState = 2; + CHud::m_ZoneToPrint = CHud::m_pZoneName; + CHud::m_ZoneNameTimer = 0; + CHud::m_ZoneFadeTimer = 0; + break; + case 1: + case 2: + case 3: + case 4: + CHud::m_ZoneNameTimer = 0; + CHud::m_ZoneState = 4; + break; + default: + break; + } + CHud::m_pLastZoneName = CHud::m_pZoneName; + } + + if (CHud::m_ZoneState) { + switch (CHud::m_ZoneState) { + case 1: + if (CHud::m_ZoneNameTimer > 10000) { + CHud::m_ZoneFadeTimer = 1000; + CHud::m_ZoneState = 3; + } + fZoneAlpha = 255.0f; + break; + case 2: + CHud::m_ZoneFadeTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (CHud::m_ZoneFadeTimer > 1000) { + CHud::m_ZoneState = 1; + CHud::m_ZoneFadeTimer = 1000; + } + fZoneAlpha = CHud::m_ZoneFadeTimer * 0.001f * 255.0f; + break; + case 3: + CHud::m_ZoneFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (CHud::m_ZoneFadeTimer < 0) { + CHud::m_ZoneState = 0; + CHud::m_ZoneFadeTimer = 0; + } + fZoneAlpha = CHud::m_ZoneFadeTimer * 0.001f * 255.0f; + break; + case 4: + CHud::m_ZoneFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (CHud::m_ZoneFadeTimer < 0) { + CHud::m_ZoneFadeTimer = 0; + CHud::m_ZoneToPrint = CHud::m_pLastZoneName; + CHud::m_ZoneNameTimer = 0; + CHud::m_ZoneState = 2; + } + fZoneAlpha = CHud::m_ZoneFadeTimer * 0.001f * 255.0f; + break; + default: + break; + + } + if (!CHud::m_Message[0]) { + CHud::m_ZoneNameTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + CFont::SetJustifyOff(); + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + + if (CMenuManager::m_PrefsLanguage == 4) + CFont::SetScale(SCREEN_STRETCH_X(1.2f * 0.8f), SCREEN_STRETCH_Y(1.2f)); + else + CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f)); + + CFont::SetRightJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_BANK); + CFont::SetColor(CRGBA(0, 0, 0, fZoneAlpha)); + CFont::PrintString(SCREEN_FROM_RIGHT(32.0f - 1.0f), SCREEN_FROM_BOTTOM(30.0f - 1.0f), CHud::m_ZoneToPrint); + + CFont::SetColor(CRGBA(152, 154, 82, fZoneAlpha)); + CFont::PrintString(SCREEN_FROM_RIGHT(32.0f), SCREEN_FROM_BOTTOM(30.0f), CHud::m_ZoneToPrint); + } + } + } + else { + CHud::m_pLastZoneName = 0; + CHud::m_ZoneState = 0; + CHud::m_ZoneFadeTimer = 0; + CHud::m_ZoneNameTimer = 0; + } + + /* + DrawVehicleName + */ + if (CHud::m_pVehicleName) { + Float fVehicleAlpha = 0.0f; + + if (CHud::m_pVehicleName != CHud::m_pLastVehicleName) { + switch (CHud::m_VehicleState) { + case 0: + CHud::m_VehicleState = 2; + CHud::m_pVehicleNameToPrint = CHud::m_pVehicleName; + CHud::m_VehicleNameTimer = 0; + CHud::m_VehicleFadeTimer = 0; + break; + case 1: + case 2: + case 3: + case 4: + CHud::m_VehicleNameTimer = 0; + CHud::m_VehicleState = 4; + break; + default: + break; + } + CHud::m_pLastVehicleName = CHud::m_pVehicleName; + } + + if (CHud::m_VehicleState) { + switch (CHud::m_VehicleState) { + case 1: + if (CHud::m_VehicleNameTimer > 10000) { + CHud::m_VehicleFadeTimer = 1000; + CHud::m_VehicleState = 3; + } + fVehicleAlpha = 255.0f; + break; + case 2: + CHud::m_VehicleFadeTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (CHud::m_VehicleFadeTimer > 1000) { + CHud::m_VehicleState = 1; + CHud::m_VehicleFadeTimer = 1000; + } + fVehicleAlpha = CHud::m_VehicleFadeTimer * 0.001f * 255.0f; + break; + case 3: + CHud::m_VehicleFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (CHud::m_VehicleFadeTimer < 0) { + CHud::m_VehicleState = 0; + CHud::m_VehicleFadeTimer = 0; + } + fVehicleAlpha = CHud::m_VehicleFadeTimer * 0.001f * 255.0f; + break; + case 4: + CHud::m_VehicleFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (CHud::m_VehicleFadeTimer < 0) { + CHud::m_VehicleFadeTimer = 0; + CHud::m_pVehicleNameToPrint = CHud::m_pLastVehicleName; + CHud::m_VehicleNameTimer = 0; + CHud::m_VehicleState = 2; + } + fVehicleAlpha = CHud::m_VehicleFadeTimer * 0.001f * 255.0f; + break; + default: + break; + } + + if (!CHud::m_Message[0]) { + CHud::m_VehicleNameTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + CFont::SetJustifyOff(); + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + + if (CMenuManager::m_PrefsLanguage != 3 && CMenuManager::m_PrefsLanguage != 4) + CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.2f)); + else + CFont::SetScale(SCREEN_STRETCH_X(1.2f * 0.85f), SCREEN_STRETCH_Y(1.2f)); + + CFont::SetRightJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_BANK); + CFont::SetColor(CRGBA(0, 0, 0, fVehicleAlpha)); + CFont::PrintString(SCREEN_FROM_RIGHT(32.0f - 1.0f), SCREEN_FROM_BOTTOM(55.0f - 1.0f), CHud::m_pVehicleNameToPrint); + + CFont::SetColor(CRGBA(194, 165, 120, fVehicleAlpha)); + CFont::PrintString(SCREEN_FROM_RIGHT(32.0f), SCREEN_FROM_BOTTOM(55.0f), CHud::m_pVehicleNameToPrint); + } + } + } + else { + CHud::m_pLastVehicleName = 0; + CHud::m_VehicleState = 0; + CHud::m_VehicleFadeTimer = 0; + CHud::m_VehicleNameTimer = 0; + } + + /* + DrawOnScreenTimer + */ + wchar sTimer[16]; + if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed) + TimerOnLastFrame = 0; + if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterProcessed) + CounterOnLastFrame = 0; + + if (CUserDisplay::OnscnTimer.m_bProcessed == 1) { + if (CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed == 1) { + if (!TimerOnLastFrame) + TimerFlashTimer = 1; + + TimerOnLastFrame = 1; + + if (TimerFlashTimer) { + if (++TimerFlashTimer > 50) + TimerFlashTimer = 0; + } + + if (CTimer::GetFrameCounter() & 4 || !TimerFlashTimer) { + AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerBuffer, sTimer); + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + CFont::SetRightJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetPropOff(); + CFont::SetBackGroundOnlyTextOn(); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f - 2.0f), SCREEN_STRETCH_Y(110.0f + 2.0f), sTimer); + + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + CFont::SetColor(CRGBA(186, 101, 50, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f), SCREEN_STRETCH_Y(110.0f), sTimer); + + if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText[0]) { + CFont::SetPropOn(); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f + 78.0f), SCREEN_STRETCH_Y(110.0f + 2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText)); + + CFont::SetColor(CRGBA(186, 101, 50, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f + 80.0f), SCREEN_STRETCH_Y(110.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText)); + } + } + } + if (CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterProcessed == 1) { + if (!CounterOnLastFrame) + CounterFlashTimer = 1; + + CounterOnLastFrame = 1; + + if (CounterFlashTimer) { + if (++CounterFlashTimer > 50) + CounterFlashTimer = 0; + } + + if (CTimer::GetFrameCounter() & 4 || !CounterFlashTimer) { + if (CUserDisplay::OnscnTimer.m_sEntries[0].m_nType) { + CSprite2d::DrawRect(CRect(SCREEN_FROM_RIGHT(127.0f - 4.0f), SCREEN_STRETCH_Y(132.0 + 8.0f), SCREEN_FROM_RIGHT(23.0f), SCREEN_STRETCH_Y(11.0f + 132.0f + 8.0f)), CRGBA(0, 106, 164, 80)); + CSprite2d::DrawRect(CRect(SCREEN_FROM_RIGHT(127.0f + 4.0f), SCREEN_STRETCH_Y(132.0 + 8.0f), SCREEN_FROM_RIGHT(atoi(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer) + 27.0f + 100.0f + 4.0f), SCREEN_STRETCH_Y(11.0f + 132.0f + 8.0f)), CRGBA(0, 106, 164, 255)); + } + else { + AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer, sTimer); + + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetColor(CRGBA(244, 20, 20, 255)); + CFont::SetWrapx(SCREEN_STRETCH_X(640.0f)); + CFont::SetPropOff(); + CFont::SetBackGroundOnlyTextOn(); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f - 2.0f), SCREEN_STRETCH_Y(132.0f + 2.0f), sTimer); + + CFont::SetColor(CRGBA(0, 106, 164, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f), SCREEN_STRETCH_Y(132.0f), sTimer); + } + + if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText[0]) { + CFont::SetPropOn(); + CFont::SetScale(SCREEN_STRETCH_X(0.8f), SCREEN_STRETCH_Y(1.35f)); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f + 59.0f), SCREEN_STRETCH_Y(132.0f + 2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText)); + + CFont::SetColor(CRGBA(0, 106, 164, 255)); + CFont::PrintString(SCREEN_FROM_RIGHT(27.0f + 61.0f), SCREEN_STRETCH_Y(132.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aCounterText)); + } + } + } + } + + /* + DrawPager + */ + if (!m_PagerMessage[0]) { + if (PagerOn == 1) { + PagerSoundPlayed = false; + PagerOn = 2; + } + } + if (m_PagerMessage[0] || PagerOn == 2) { + if (!PagerOn) { + PagerOn = 1; + PagerXOffset = 150.0f; + } + if (PagerOn == 1) { + if (PagerXOffset > 0.0f) { + Float fStep = PagerXOffset * 0.05f; + if (fStep > 10.0f) + fStep = 10.0f; + PagerXOffset -= fStep * CTimer::GetTimeStep(); + } + if (!PagerSoundPlayed) { + DMAudio.PlayFrontEndSound(96, 0); + PagerSoundPlayed = 1; + } + } + else if (PagerOn == 2) { + Float fStep = PagerXOffset * 0.05f; + if (fStep < 2.0f) + fStep = 2.0f; + PagerXOffset += fStep * CTimer::GetTimeStep(); + if (PagerXOffset > 150.0f) { + PagerXOffset = 150.0; + PagerOn = 0; + } + } + + CHud::Sprites[HUD_PAGER].Draw(CRect(SCREEN_STRETCH_X(26.0f - PagerXOffset), SCREEN_STRETCH_Y(27.0f), SCREEN_STRETCH_X(160.0 + 26.0f - PagerXOffset), SCREEN_STRETCH_Y(80.0f + 27.0f)), CRGBA(255, 255, 255, 255)); + + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(0.84f), SCREEN_STRETCH_Y(1.0f)); + CFont::SetColor(CRGBA(32, 162, 66, 205)); + CFont::SetRightJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreOff(); + CFont::SetJustifyOff(); + CFont::SetPropOff(); + CFont::SetFontStyle(FONT_PAGER); + CFont::PrintString(SCREEN_STRETCH_X(52.0f - PagerXOffset), SCREEN_STRETCH_Y(54.0f), CHud::m_PagerMessage); + } + + /* + DrawRadar + */ + if (CHud::m_ItemToFlash == 8 && CTimer::GetFrameCounter() & 8 || CHud::m_ItemToFlash != 8) { + CRadar::DrawMap(); + CHud::Sprites[HUD_RADARDISC].Draw(CRect(SCREEN_STRETCH_X(16.0f), SCREEN_FROM_BOTTOM(123.0f + 4.0f), SCREEN_STRETCH_X(94.0f + 20.0f + 5.0f), SCREEN_FROM_BOTTOM(-76.0f + 123.0f - 6.0f)), CRGBA(0, 0, 0, 255)); + CRadar::DrawBlips(); + } + } + + /* + Draw3dMarkers + */ + if (CHud::m_Wants_To_Draw_3dMarkers && !TheCamera.m_WideScreenOn && !CHud::m_BigMessage[0][0] && !CHud::m_BigMessage[2][0]) { + CRadar::Draw3dMarkers(); + } + + /* + DrawScriptText + */ + if (!CTimer::GetIsUserPaused()) { + uint16 CounterA = 0; + uint16 CounterB = 0; + CTextLine* IntroText = CTheScripts::IntroTextLines; + + do { + if (CTheScripts::IntroTextLines[CounterB].m_awText[0] && CTheScripts::IntroTextLines[CounterB].field_29) { + CFont::SetScale(SCREEN_STRETCH_X(CTheScripts::IntroTextLines[CounterB].m_fScaleX), SCREEN_STRETCH_Y(CTheScripts::IntroTextLines[CounterB].m_fScaleY * 0.5f)); + CFont::SetColor(CTheScripts::IntroTextLines[CounterB].m_sColor); + + if (CTheScripts::IntroTextLines[CounterB].m_bJustify) + CFont::SetJustifyOn(); + else + CFont::SetJustifyOff(); + + if (CTheScripts::IntroTextLines[CounterB].m_bRightJustify) + CFont::SetRightJustifyOn(); + else + CFont::SetRightJustifyOff(); + + if (CTheScripts::IntroTextLines[CounterB].m_bCentered) + CFont::SetCentreOn(); + else + CFont::SetCentreOff(); + + CFont::SetWrapx(SCREEN_STRETCH_X(CTheScripts::IntroTextLines[CounterB].m_fWrapX)); + CFont::SetCentreSize(SCREEN_STRETCH_X(CTheScripts::IntroTextLines[CounterB].m_fCenterSize)); + + if (CTheScripts::IntroTextLines[CounterB].m_bBackground) + CFont::SetBackgroundOn(); + else + CFont::SetBackgroundOff(); + + CFont::SetBackgroundColor(CTheScripts::IntroTextLines[CounterB].m_sBackgroundColor); + + if (CTheScripts::IntroTextLines[CounterB].m_bBackgroundOnly) + CFont::SetBackGroundOnlyTextOn(); + else + CFont::SetBackGroundOnlyTextOff(); + + if (CTheScripts::IntroTextLines[CounterB].m_bTextProportional) + CFont::SetPropOn(); + else + CFont::SetPropOff(); + + CFont::SetFontStyle(CTheScripts::IntroTextLines[CounterB].m_nFont); + CFont::PrintString(SCREEN_STRETCH_X(640.0f - CTheScripts::IntroTextLines[CounterB].field_36), SCREEN_STRETCH_Y(448.0f - CTheScripts::IntroTextLines[CounterB].field_40), IntroText->m_awText); + } + ++CounterA; + ++CounterB; + ++IntroText; + } while (CounterA < 2); + + uint16 CounterC = 0; + uint16 CounterD = 0; + CScriptRectangle* IntroRect = CTheScripts::IntroRectangles; + + do { + if (CTheScripts::IntroRectangles[CounterD].m_bIsUsed && CTheScripts::IntroRectangles[CounterD].m_bIsAntialiased) { + if (CTheScripts::IntroRectangles[CounterD].m_wTextureId >= 0) { + CRect rect = { + CTheScripts::IntroRectangles[CounterD].m_sRect.left, + CTheScripts::IntroRectangles[CounterD].m_sRect.bottom, + CTheScripts::IntroRectangles[CounterD].m_sRect.right, + CTheScripts::IntroRectangles[CounterD].m_sRect.bottom }; + + CTheScripts::ScriptSprites[CTheScripts::IntroRectangles[CounterD].m_wTextureId].Draw(rect, IntroRect->m_sColor); + } + else { + CRect rect = { + CTheScripts::IntroRectangles[CounterD].m_sRect.left, + CTheScripts::IntroRectangles[CounterD].m_sRect.bottom, + CTheScripts::IntroRectangles[CounterD].m_sRect.right, + CTheScripts::IntroRectangles[CounterD].m_sRect.bottom }; + + CSprite2d::DrawRect(rect, IntroRect->m_sColor); + } + } + ++CounterC; + ++CounterD; + ++IntroRect; + } while (CounterC < 16); + + /* + DrawSubtitles + */ + if (CHud::m_Message[0] && !CHud::m_BigMessage[2][0] && (FrontEndMenuManager.m_PrefsShowSubtitles == 1 || !TheCamera.m_WideScreenOn)) { + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128)); + CFont::SetScale(SCREEN_STRETCH_X(0.48f), SCREEN_STRETCH_Y(1.120f)); + CFont::SetCentreOn(); + CFont::SetPropOn(); + CFont::SetFontStyle(FONT_BANK); + + if (TheCamera.m_WideScreenOn) + CFont::SetCentreSize(SCREEN_FROM_RIGHT(120.0f)); + else + CFont::SetCentreSize(SCREEN_FROM_RIGHT(280.0f)); + + CFont::SetDropShadowPosition(1); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetColor(CRGBA(235, 235, 235, 255)); + CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_FROM_BOTTOM(64.0f), CHud::m_Message); + CFont::SetDropShadowPosition(0); + } + + /* + DrawBigMessage + */ + if (CHud::m_BigMessage[0][0]) { + if (0.0f == BigMessageInUse[0]) { + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetScale(SCREEN_STRETCH_X(1.8f), SCREEN_STRETCH_Y(1.8f)); + CFont::SetPropOn(); + CFont::SetCentreOn(); + CFont::SetCentreSize(SCREEN_STRETCH_X(615.0f)); + CFont::SetColor(CRGBA(255, 255, 0, 255)); + CFont::SetFontStyle(FONT_HEADING); + if ((RsGlobal.maximumWidth - 20) <= BigMessageX[0]) { + BigMessageInUse[0] = BigMessageInUse[0] + CTimer::GetTimeStep(); + if (BigMessageInUse[0] >= 120.0f) { + BigMessageInUse[0] = 120.0; + BigMessageAlpha[0] = BigMessageAlpha[0] - (CTimer::GetTimeStep() * 0.02f * 1000.0f) * 0.30000001f; + } + if (BigMessageAlpha[0] <= 0.0f) { + CHud::m_BigMessage[0][0] = 0; + BigMessageAlpha[0] = 0.0; + } + } + else { + Float fStep = (CTimer::GetTimeStep() + * 0.02f + * 1000.0f) + * 0.30000001f; + BigMessageX[0] = BigMessageX[0] + fStep; + BigMessageAlpha[0] = BigMessageAlpha[0] + fStep; + + if (BigMessageAlpha[0] > 255.0f) + BigMessageAlpha[0] = 255.0; + } + CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[0])); + CFont::PrintString(SCREEN_WIDTH / 2, (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(20.0f - 2.0f), m_BigMessage[0]); + + CFont::SetColor(CRGBA(85, 119, 133, BigMessageAlpha[0])); + CFont::PrintString(SCREEN_WIDTH / 2, (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(20.0f), m_BigMessage[0]); + } + else { + BigMessageAlpha[0] = 0.0; + BigMessageX[0] = -60.0; + BigMessageInUse[0] = 1.0; + } + } + else { + BigMessageInUse[0] = 0.0; + } + + // WastedBustedText + if (CHud::m_BigMessage[2][0]) { + if (0 == BigMessageInUse[2]) { + BigMessageAlpha[2] = (CTimer::GetTimeStep() + * 0.02f + * 1000.0f) + * 0.40000001 + + BigMessageAlpha[2]; + if (BigMessageAlpha[2] > 255.0f) + BigMessageAlpha[2] = 255.0; + CFont::SetBackgroundOff(); + + if (CGame::frenchGame || CGame::germanGame) + CFont::SetScale(SCREEN_STRETCH_X(1.4f), SCREEN_STRETCH_Y(1.4f)); + else + CFont::SetScale(SCREEN_STRETCH_X(2.0f), SCREEN_STRETCH_Y(2.0f)); + + CFont::SetPropOn(); + CFont::SetRightJustifyOn(); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetColor(CRGBA(0, 0, 0, 0.75f * BigMessageAlpha[2])); + + CFont::PrintString(SCREEN_FROM_RIGHT(20.0f + 4.0f), SCREEN_FROM_BOTTOM(78.0f), CHud::m_BigMessage[2]); + + CFont::SetColor(CRGBA(170, 123, 87, BigMessageAlpha[2])); + CFont::PrintString(SCREEN_FROM_RIGHT(20.0f), SCREEN_FROM_BOTTOM(82.0f), CHud::m_BigMessage[2]); + } + else { + BigMessageAlpha[2] = 0.0; + BigMessageInUse[2] = 1.0; + } + } + else { + BigMessageInUse[2] = 0.0; + } + } + } +} + +void CHud::DrawAfterFade() { + if (CTimer::GetIsUserPaused() || CReplay::Mode == 1) + return; + + if (m_HelpMessage[0]) { + if (!CMessages::WideStringCompare(m_HelpMessage, m_LastHelpMessage, 256)) { + switch (m_HelpMessageState) { + case 0: + m_HelpMessageFadeTimer = 0; + m_HelpMessageState = 2; + m_HelpMessageTimer = 0; + CMessages::WideStringCopy(m_HelpMessageToPrint, m_HelpMessage, 256); + m_HelpMessageDisplayTime = CMessages::GetWideStringLength(m_HelpMessage) * 0.05f + 3.0f; + + if (TheCamera.m_ScreenReductionPercentage == 0.0f) + DMAudio.PlayFrontEndSound(SOUND_A0, 0); + break; + case 1: + case 2: + case 3: + case 4: + m_HelpMessageTimer = 5; + m_HelpMessageState = 4; + break; + default: + break; + } + CMessages::WideStringCopy(m_LastHelpMessage, m_HelpMessage, 256); + } + + float fAlpha = 255.0f; + + if (m_HelpMessageState) { + switch (m_HelpMessageState) { + case 1: + fAlpha = 255.0f; + m_HelpMessageFadeTimer = 600; + if (m_HelpMessageTimer > m_fHelpMessageTime * 1000 || m_bHelpMessageQuick && m_HelpMessageTimer > 1500) { + m_HelpMessageFadeTimer = 600; + m_HelpMessageState = 3; + } + break; + case 2: + m_HelpMessageFadeTimer += 2 * (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (m_HelpMessageFadeTimer > 0) { + m_HelpMessageState = 1; + m_HelpMessageFadeTimer = 0; + } + fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f; + break; + case 3: + m_HelpMessageFadeTimer -= 2 * (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (m_HelpMessageFadeTimer >= 0) { + m_HelpMessageState = 0; + m_HelpMessageFadeTimer = 0; + } + fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f; + break; + case 4: + m_HelpMessageFadeTimer -= 2 * (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (m_HelpMessageFadeTimer >= 0) { + m_HelpMessageState = 2; + m_HelpMessageFadeTimer = 0; + CMessages::WideStringCopy(m_HelpMessageToPrint, m_LastHelpMessage, 400); + } + fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f; + break; + default: + break; + } + + m_HelpMessageTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + + CFont::SetAlphaFade(fAlpha); + CFont::SetCentreOff(); + CFont::SetPropOn(); + + if (CGame::germanGame) + CFont::SetScale(SCREEN_STRETCH_X(0.52f * 0.85f), SCREEN_STRETCH_Y(1.1f * 0.85f)); + else + CFont::SetScale(SCREEN_STRETCH_X(0.52f), SCREEN_STRETCH_Y(1.1f)); + + CFont::SetColor(CRGBA(175, 175, 175, 255)); + CFont::SetJustifyOff(); + CFont::SetWrapx(SCREEN_STRETCH_X(200.0f + 26.0f - 4.0f)); + CFont::SetFontStyle(FONT_BANK); + CFont::SetBackgroundOn(); + CFont::SetBackGroundOnlyTextOff(); + CRGBA BackColor = { 0, 0, 0, (uint8)(0.9f * fAlpha) }; + CFont::SetBackgroundColor(BackColor); + CFont::SetColor(CRGBA(175, 175, 175, 255)); + CFont::PrintString(SCREEN_STRETCH_X(26.0f), SCREEN_STRETCH_Y(28.0f + (150.0f - PagerXOffset) * 0.6f), CHud::m_HelpMessageToPrint); + CFont::SetAlphaFade(255.0f); + CFont::DrawFonts(); + } + } + else + m_HelpMessageState = 0; + + /* + DrawBigMessage2 + */ + // Oddjob + if (m_BigMessage[4][0]) { + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(1.2f), SCREEN_STRETCH_Y(1.5f)); + CFont::SetCentreOn(); + CFont::SetPropOn(); + CFont::SetCentreSize(SCREEN_STRETCH_X(600.0f)); + CFont::SetFontStyle(FONT_BANK); + + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_STRETCH_X(2.0f) + (SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(84.0f), m_BigMessage[4]); + + CFont::SetColor(CRGBA(89, 115, 150, 255)); + CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(84.0f), m_BigMessage[4]); + } + + + // Oddjob result + if (OddJob2OffTimer > 0) + OddJob2OffTimer = OddJob2OffTimer - (CTimer::GetTimeStep() * 0.02f * 1000.0f); + + static float fStep; + if (!m_BigMessage[1][0] && m_BigMessage[4][0] && m_BigMessage[5][0] && OddJob2OffTimer <= 0.0f) { + switch (OddJob2On) { + case 0: + OddJob2On = 1; + OddJob2XOffset = 380.0; + break; + case 1: + if (OddJob2XOffset <= 2.0f) { + OddJob2Timer = 0; + OddJob2On = 2; + } + else { + fStep = 40.0; + if ((OddJob2XOffset * 0.16667) <= 40.0) + fStep = OddJob2XOffset * 0.16667; + OddJob2XOffset = OddJob2XOffset - fStep; + } + break; + case 2: + OddJob2Timer += (20.0 * CTimer::GetTimeStep()); + if (OddJob2Timer > 1500) { + OddJob2On = 3; + } + break; + case 3: + fStep = 30.0; + if ((OddJob2XOffset * 0.2) >= 30.0) + fStep = OddJob2XOffset * 0.2; + + OddJob2XOffset = OddJob2XOffset - fStep; + + if (OddJob2XOffset < -380.0) { + OddJob2OffTimer = 5000.0; + OddJob2On = 0; + } + break; + default: + break; + } + + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_STRETCH_X(1.0f), SCREEN_STRETCH_Y(1.2f)); + CFont::SetCentreOn(); + CFont::SetPropOn(); + CFont::SetCentreSize(SCREEN_FROM_RIGHT(20.0f)); + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::SetFontStyle(FONT_BANK); + CFont::PrintString(SCREEN_STRETCH_X(2.0f) + (SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(20.0f + 2.0f), m_BigMessage[5]); + + CFont::SetColor(CRGBA(156, 91, 40, 255)); + CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) - SCREEN_STRETCH_Y(20.0f + 2.0f), m_BigMessage[5]); + } + + /* + DrawMissionTitle + */ + if (m_BigMessage[1][0]) { + if (BigMessageInUse[1] == 0.0f) { + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + + if (CGame::frenchGame || CMenuManager::m_PrefsLanguage == 4) + CFont::SetScale(SCREEN_STRETCH_X(0.884f), SCREEN_STRETCH_Y(1.36f)); + else + CFont::SetScale(SCREEN_STRETCH_X(1.04f), SCREEN_STRETCH_Y(1.6f)); + + CFont::SetPropOn(); + CFont::SetRightJustifyWrap(-500); + CFont::SetRightJustifyOn(); + CFont::SetFontStyle(FONT_HEADING); + if ((RsGlobal.width - 20) <= BigMessageX[1]) { + BigMessageInUse[1] = BigMessageInUse[1] + CTimer::GetTimeStep(); + if (BigMessageInUse[1] >= 120.0f) { + BigMessageInUse[1] = 120.0; + BigMessageAlpha[1] = BigMessageAlpha[1] - (CTimer::GetTimeStep() * 0.02f * 1000.0f) * 0.3f; + } + if (BigMessageAlpha[1] <= 0) { + m_BigMessage[1][0] = 0; + BigMessageAlpha[1] = 0.0; + } + } + else { + float fStep = (CTimer::GetTimeStep() * 0.02f * 1000.0f) * 0.3f; + BigMessageX[1] = BigMessageX[1] + fStep; + BigMessageAlpha[1] = BigMessageAlpha[1] + fStep; + if (BigMessageAlpha[1] > 255.0f) + BigMessageAlpha[1] = 255.0; + } + CFont::SetColor(CRGBA(40, 40, 40, BigMessageAlpha[1])); + CFont::PrintString(SCREEN_FROM_RIGHT(20.0f - 2.0f), SCREEN_FROM_BOTTOM(120.0f), m_BigMessage[1]); + + CFont::SetColor(CRGBA(220, 172, 2, BigMessageAlpha[1])); + CFont::PrintString(SCREEN_FROM_RIGHT(20.0f), SCREEN_FROM_BOTTOM(120.0f), m_BigMessage[1]); + } + else { + BigMessageAlpha[1] = 0.0; + BigMessageX[1] = -60.0; + BigMessageInUse[1] = 1.0; + } + } + else { + BigMessageInUse[1] = 0.0; + } +} + +STARTPATCHES + InjectHook(0x48BC9A, &CHud::Initialise, PATCH_CALL); + InjectHook(0x48C4F1, &CHud::ReInitialise, PATCH_CALL); + InjectHook(0x48BCBC, &CHud::Shutdown, PATCH_CALL); +ENDPATCHES diff --git a/src/render/Hud.h b/src/render/Hud.h index 242acea8..65f75241 100644 --- a/src/render/Hud.h +++ b/src/render/Hud.h @@ -1,10 +1,87 @@ #pragma once +#include "Sprite2d.h" -class CHud -{ -public: - static void Draw(void); - static void DrawAfterFade(void); - - static bool &m_Wants_To_Draw_Hud; +enum eSprites { + HUD_FIST, + HUD_BAT, + HUD_PISTOL, + HUD_UZI, + HUD_SHOTGUN, + HUD_AK47, + HUD_M16, + HUD_SNIPER, + HUD_ROCKET, + HUD_FLAME, + HUD_MOLOTOV, + HUD_GRENADE, + HUD_DETONATOR, + HUD_RADARDISC = 15, + HUD_PAGER = 16, + HUD_SITESNIPER = 20, + HUD_SITEM16 = 21 }; + +class CHud { +public: + static CSprite2d *Sprites; + + static wchar *m_HelpMessage; + static wchar *m_LastHelpMessage; + static int32 &m_HelpMessageState; + static int32 &m_HelpMessageTimer; + static int32 &m_HelpMessageFadeTimer; + static wchar *m_HelpMessageToPrint; + static Float &m_HelpMessageDisplayTime; + static Float &m_fTextBoxNumLines; + static Float &m_fHelpMessageTime; + static Bool &m_bHelpMessageQuick; + static int32 m_ZoneState; + static int32 m_ZoneFadeTimer; + static int32 m_ZoneNameTimer; + static wchar* &m_pZoneName; + static wchar* m_pLastZoneName; + static wchar* m_ZoneToPrint; + static wchar* &m_pVehicleName; + static wchar* m_pLastVehicleName; + static wchar* m_pVehicleNameToPrint; + static int32 m_VehicleState; + static int32 m_VehicleFadeTimer; + static int32 m_VehicleNameTimer; + static wchar* m_Message; + static wchar* m_PagerMessage; + static Bool &m_bRetuneInProgress; + static Bool &m_Wants_To_Draw_Hud; + static Bool &m_Wants_To_Draw_3dMarkers; + static wchar(*m_BigMessage)[128]; + static Float* BigMessageInUse; + static Float* BigMessageAlpha; + static Float* BigMessageX; + static Float &OddJob2OffTimer; + static int8 &CounterOnLastFrame; + static Float &OddJob2XOffset; + static int16 &CounterFlashTimer; + static int16 &OddJob2Timer; + static int8 &TimerOnLastFrame; + static int16 &OddJob2On; + static int16 &TimerFlashTimer; + static int16 &PagerSoundPlayed; + static int32 &SpriteBrightness; + static Float &PagerXOffset; + static int32 m_ItemToFlash; + static int16 &PagerTimer; + static int16 &PagerOn; + +public: + static void Initialise(); + static void Shutdown(); + static void ReInitialise(); + static void GetRidOfAllHudMessages(); + static void SetZoneName(wchar* name); + static void SetHelpMessage(wchar* message, bool quick); + static void SetVehicleName(wchar* name); + static void Draw(); + static void DrawAfterFade(); + static void SetMessage(wchar* message); + static void SetBigMessage(wchar* message, int16 style); + static void SetPagerMessage(wchar* message); +}; \ No newline at end of file