diff --git a/src/Camera.h b/src/Camera.h index 1f9a287c..6669ff13 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -10,7 +10,7 @@ class CAutomobile; struct CCam { - enum CamMode + enum { MODE_TOPDOWN1 = 1, MODE_TOPDOWN2, diff --git a/src/Streaming.cpp b/src/Streaming.cpp index 7d633d90..f75f358a 100644 --- a/src/Streaming.cpp +++ b/src/Streaming.cpp @@ -19,6 +19,11 @@ #include "CullZones.h" #include "Radar.h" #include "Camera.h" +#include "Record.h" +#include "CarCtrl.h" +#include "Population.h" +#include "Gangs.h" +#include "CutsceneMgr.h" #include "CdStream.h" #include "Streaming.h" @@ -47,6 +52,7 @@ int32 &CStreaming::ms_currentPedGrp = *(int32*)0x8F2BBC; int32 CStreaming::ms_currentPedLoading; int32 CStreaming::ms_lastCullZone; uint16 &CStreaming::ms_loadedGangs = *(uint16*)0x95CC60; +uint16 &CStreaming::ms_loadedGangCars = *(uint16*)0x95CC2E; int32 *CStreaming::ms_imageOffsets = (int32*)0x6E60A0; int32 &CStreaming::ms_lastImageRead = *(int32*)0x880E2C; int32 &CStreaming::ms_imageSize = *(int32*)0x8F1A34; @@ -240,6 +246,53 @@ CStreaming::Shutdown(void) delete ms_pExtraObjectsDir; } +void +CStreaming::Update(void) +{ + CEntity *train; + CVector playerPos; + CStreamingInfo *si, *prev; + bool requestedSubway = false; + + UpdateMemoryUsed(); + + if(ms_channelError != -1){ + RetryLoadFile(ms_channelError); + return; + } + + if(CTimer::GetIsPaused()) + return; + + train = FindPlayerTrain(); + if(train && train->GetPosition().z < 0.0f){ + RequestSubway(); + requestedSubway = true; + }else if(!ms_disableStreaming) + AddModelsToRequestList(TheCamera.GetPosition()); + + DeleteFarAwayRwObjects(TheCamera.GetPosition()); + + if(!ms_disableStreaming && + !CCutsceneMgr::IsRunning() && + !requestedSubway && + !CGame::playingIntro && + ms_numModelsRequested < 5 && + !CRenderer::m_loadingPriority){ + StreamVehiclesAndPeds(); + FindPlayerCoors(playerPos); + StreamZoneModels(playerPos); + } + + LoadRequestedModels(); + + for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){ + prev = si->m_prev; + if((si->m_flags & (STREAMFLAGS_KEEP_IN_MEMORY|STREAMFLAGS_PRIORITY)) == 0) + RemoveModel(si - ms_aInfoForModel); + } +} + void CStreaming::LoadCdDirectory(void) { @@ -705,6 +758,18 @@ CStreaming::RequestSpecialChar(int32 charId, const char *modelName, int32 flags) RequestSpecialModel(charId + MI_SPECIAL01, modelName, flags); } +bool +CStreaming::HasSpecialCharLoaded(int32 id) +{ + return HasModelLoaded(id + MI_SPECIAL01); +} + +void +CStreaming::SetMissionDoesntRequireSpecialChar(int32 id) +{ + return SetMissionDoesntRequireModel(id + MI_SPECIAL01); +} + void CStreaming::DecrementRef(int32 id) { @@ -1176,6 +1241,181 @@ CStreaming::LoadInitialVehicles(void) RequestModel(id, STREAMFLAGS_DONT_REMOVE); } +void +CStreaming::StreamVehiclesAndPeds(void) +{ + int i, model; + static int timeBeforeNextLoad = 0; + static int modelQualityClass = 0; + + if(CRecordDataForGame::RecordingState == RECORDSTATE_1 || + CRecordDataForGame::RecordingState == RECORDSTATE_2) + return; + + if(FindPlayerPed()->m_pWanted->AreSwatRequired()){ + RequestModel(MI_ENFORCER, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_SWAT, STREAMFLAGS_DONT_REMOVE); + }else{ + SetModelIsDeletable(MI_ENFORCER); + if(!HasModelLoaded(MI_ENFORCER)) + SetModelIsDeletable(MI_SWAT); + } + + if(FindPlayerPed()->m_pWanted->AreFbiRequired()){ + RequestModel(MI_FBICAR, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_FBI, STREAMFLAGS_DONT_REMOVE); + }else{ + SetModelIsDeletable(MI_FBICAR); + if(!HasModelLoaded(MI_FBICAR)) + SetModelIsDeletable(MI_FBI); + } + + if(FindPlayerPed()->m_pWanted->AreArmyRequired()){ + RequestModel(MI_RHINO, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_BARRACKS, STREAMFLAGS_DONT_REMOVE); + RequestModel(MI_ARMY, STREAMFLAGS_DONT_REMOVE); + }else{ + SetModelIsDeletable(MI_RHINO); + SetModelIsDeletable(MI_BARRACKS); + if(!HasModelLoaded(MI_RHINO) && !HasModelLoaded(MI_BARRACKS)) + SetModelIsDeletable(MI_ARMY); + } + + if(FindPlayerPed()->m_pWanted->NumOfHelisRequired() > 0) + RequestModel(MI_CHOPPER, STREAMFLAGS_DONT_REMOVE); + else + SetModelIsDeletable(MI_CHOPPER); + + if(timeBeforeNextLoad >= 0) + timeBeforeNextLoad--; + else if(ms_numVehiclesLoaded <= desiredNumVehiclesLoaded){ + for(i = 0; i <= 10; i++){ + model = CCarCtrl::ChooseCarModel(modelQualityClass); + modelQualityClass++; + if(modelQualityClass >= NUM_VEHICLE_CLASSES) + modelQualityClass = 0; + + // check if we want to load this model + if(ms_aInfoForModel[model].m_loadState == STREAMSTATE_NOTLOADED && + ((CVehicleModelInfo*)CModelInfo::GetModelInfo(model))->m_level & (1 << (CGame::currLevel-1))) + break; + } + + if(i <= 10){ + RequestModel(model, STREAMFLAGS_DEPENDENCY); + timeBeforeNextLoad = 500; + } + } +} + +void +CStreaming::StreamZoneModels(const CVector &pos) +{ + int i; + uint16 gangsToLoad, gangCarsToLoad, bit; + CZoneInfo info; + + CTheZones::GetZoneInfoForTimeOfDay(&pos, &info); + + if(info.pedGroup != ms_currentPedGrp){ + + // unload pevious group + if(ms_currentPedGrp != -1) + for(i = 0; i < 8; i++){ + if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1) + break; + SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]); + SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]); + } + + ms_currentPedGrp = info.pedGroup; + + for(i = 0; i < 8; i++){ + if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1) + break; + RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DONT_REMOVE); + } + } + RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE); + + gangsToLoad = 0; + gangCarsToLoad = 0; + if(info.gangDensity[0] != 0) gangsToLoad |= 1<<0; + if(info.gangDensity[1] != 0) gangsToLoad |= 1<<1; + if(info.gangDensity[2] != 0) gangsToLoad |= 1<<2; + if(info.gangDensity[3] != 0) gangsToLoad |= 1<<3; + if(info.gangDensity[4] != 0) gangsToLoad |= 1<<4; + if(info.gangDensity[5] != 0) gangsToLoad |= 1<<5; + if(info.gangDensity[6] != 0) gangsToLoad |= 1<<6; + if(info.gangDensity[7] != 0) gangsToLoad |= 1<<7; + if(info.gangDensity[8] != 0) gangsToLoad |= 1<<8; + if(info.gangThreshold[0] != info.copDensity) gangCarsToLoad |= 1<<0; + if(info.gangThreshold[1] != info.gangThreshold[0]) gangCarsToLoad |= 1<<1; + if(info.gangThreshold[2] != info.gangThreshold[1]) gangCarsToLoad |= 1<<2; + if(info.gangThreshold[3] != info.gangThreshold[2]) gangCarsToLoad |= 1<<3; + if(info.gangThreshold[4] != info.gangThreshold[3]) gangCarsToLoad |= 1<<4; + if(info.gangThreshold[5] != info.gangThreshold[4]) gangCarsToLoad |= 1<<5; + if(info.gangThreshold[6] != info.gangThreshold[5]) gangCarsToLoad |= 1<<6; + if(info.gangThreshold[7] != info.gangThreshold[6]) gangCarsToLoad |= 1<<7; + if(info.gangThreshold[8] != info.gangThreshold[7]) gangCarsToLoad |= 1<<8; + + if(gangsToLoad == ms_loadedGangs && gangCarsToLoad == ms_loadedGangCars) + return; + + // This makes things simpler than the game does it + gangsToLoad |= gangCarsToLoad; + + for(i = 0; i < NUM_GANGS; i++){ + bit = 1<m_nVehicleMI, STREAMFLAGS_DONT_REMOVE); + }else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){ + SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + SetModelTxdIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + } + } + ms_loadedGangCars = gangCarsToLoad; +} + +void +CStreaming::RemoveCurrentZonesModels(void) +{ + int i; + + if(ms_currentPedGrp != -1) + for(i = 0; i < 8; i++){ + if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1) + break; + if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) + SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]); + } + + for(i = 0; i < NUM_GANGS; i++){ + SetModelIsDeletable(MI_GANG01 + i*2); + SetModelIsDeletable(MI_GANG01 + i*2 + 1); + if(CGangs::GetGangInfo(i)->m_nVehicleMI != -1) + SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI); + } + + ms_currentPedGrp = -1; + ms_loadedGangs = 0; + ms_loadedGangCars = 0; +} + + // Find starting offset of the cdimage we next want to read // Not useful at all on PC... @@ -2166,9 +2406,35 @@ CStreaming::LoadScene(const CVector &pos) debug("End load scene\n"); } +void +CStreaming::MemoryCardSave(uint8 *buffer, uint32 *length) +{ + int i; + + *length = NUM_DEFAULT_MODELS; + for(i = 0; i < NUM_DEFAULT_MODELS; i++) + if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) + buffer[i] = ms_aInfoForModel[i].m_flags; + else + buffer[i] = 0xFF; +} + +void +CStreaming::MemoryCardLoad(uint8 *buffer, uint32 length) +{ + uint32 i; + + assert(length == NUM_DEFAULT_MODELS); + for(i = 0; i < length; i++) + if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) + if(buffer[i] != 0xFF) + ms_aInfoForModel[i].m_flags = buffer[i]; +} + STARTPATCHES InjectHook(0x406430, CStreaming::Init, PATCH_JUMP); InjectHook(0x406C80, CStreaming::Shutdown, PATCH_JUMP); + InjectHook(0x4076C0, CStreaming::Update, PATCH_JUMP); InjectHook(0x406CC0, (void (*)(void))CStreaming::LoadCdDirectory, PATCH_JUMP); InjectHook(0x406DA0, (void (*)(const char*, int))CStreaming::LoadCdDirectory, PATCH_JUMP); InjectHook(0x409740, CStreaming::ConvertBufferToObject, PATCH_JUMP); @@ -2179,6 +2445,9 @@ STARTPATCHES InjectHook(0x408210, CStreaming::RequestIslands, PATCH_JUMP); InjectHook(0x40A890, CStreaming::RequestSpecialModel, PATCH_JUMP); InjectHook(0x40ADA0, CStreaming::RequestSpecialChar, PATCH_JUMP); + InjectHook(0x54A5F0, CStreaming::HasModelLoaded, PATCH_JUMP); + InjectHook(0x40ADC0, CStreaming::HasSpecialCharLoaded, PATCH_JUMP); + InjectHook(0x40ADE0, CStreaming::SetMissionDoesntRequireSpecialChar, PATCH_JUMP); InjectHook(0x408830, CStreaming::RemoveModel, PATCH_JUMP); InjectHook(0x4083A0, CStreaming::RemoveUnusedBuildings, PATCH_JUMP); @@ -2202,6 +2471,9 @@ STARTPATCHES InjectHook(0x40AA00, CStreaming::LoadInitialPeds, PATCH_JUMP); InjectHook(0x40ADF0, CStreaming::LoadInitialVehicles, PATCH_JUMP); + InjectHook(0x40AE60, CStreaming::StreamVehiclesAndPeds, PATCH_JUMP); + InjectHook(0x40AA30, CStreaming::StreamZoneModels, PATCH_JUMP); + InjectHook(0x40AD00, CStreaming::RemoveCurrentZonesModels, PATCH_JUMP); InjectHook(0x409BE0, CStreaming::ProcessLoadingChannel, PATCH_JUMP); InjectHook(0x40A610, CStreaming::FlushChannels, PATCH_JUMP); @@ -2228,6 +2500,9 @@ STARTPATCHES InjectHook(0x409B70, CStreaming::MakeSpaceFor, PATCH_JUMP); InjectHook(0x40A6D0, CStreaming::LoadScene, PATCH_JUMP); + InjectHook(0x40B210, CStreaming::MemoryCardSave, PATCH_JUMP); + InjectHook(0x40B250, CStreaming::MemoryCardLoad, PATCH_JUMP); + InjectHook(0x4063E0, &CStreamingInfo::GetCdPosnAndSize, PATCH_JUMP); InjectHook(0x406410, &CStreamingInfo::SetCdPosnAndSize, PATCH_JUMP); InjectHook(0x4063D0, &CStreamingInfo::GetCdSize, PATCH_JUMP); diff --git a/src/Streaming.h b/src/Streaming.h index 4caefb6d..d0c6fc68 100644 --- a/src/Streaming.h +++ b/src/Streaming.h @@ -10,7 +10,7 @@ enum StreamFlags { STREAMFLAGS_DONT_REMOVE = 0x01, STREAMFLAGS_SCRIPTOWNED = 0x02, - STREAMFLAGS_DEPENDENCY = 0x04, + STREAMFLAGS_DEPENDENCY = 0x04, // Is this right? STREAMFLAGS_PRIORITY = 0x08, STREAMFLAGS_NOFADE = 0x10, @@ -99,6 +99,7 @@ public: static int32 &ms_currentPedGrp; static int32 ms_lastCullZone; static uint16 &ms_loadedGangs; + static uint16 &ms_loadedGangCars; static int32 ms_currentPedLoading; static int32 *ms_imageOffsets; //[NUMCDIMAGES] static int32 &ms_lastImageRead; @@ -107,10 +108,12 @@ public: static void Init(void); static void Shutdown(void); + static void Update(void); static void LoadCdDirectory(void); static void LoadCdDirectory(const char *dirname, int32 n); static bool ConvertBufferToObject(int8 *buf, int32 streamId); static bool FinishLoadingLargeFile(int8 *buf, int32 streamId); + static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; } static void RequestModel(int32 model, int32 flags); static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); } static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); } @@ -120,6 +123,8 @@ public: static void RequestIslands(eLevelName level); static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags); static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags); + static bool HasSpecialCharLoaded(int32 id); + static void SetMissionDoesntRequireSpecialChar(int32 id); static void DecrementRef(int32 id); static void RemoveModel(int32 id); static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); } @@ -141,6 +146,11 @@ public: static void SetModelIsDeletable(int32 id); static void SetModelTxdIsDeletable(int32 id); static void SetMissionDoesntRequireModel(int32 id); + static void LoadInitialPeds(void); + static void LoadInitialVehicles(void); + static void StreamVehiclesAndPeds(void); + static void StreamZoneModels(const CVector &pos); + static void RemoveCurrentZonesModels(void); static int32 GetCdImageOffset(int32 lastPosn); static int32 GetNextFileOnCd(int32 position, bool priority); @@ -169,10 +179,8 @@ public: static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, int32 mem); static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem); - static void LoadInitialPeds(void); - static void LoadInitialVehicles(void); - static void LoadScene(const CVector &pos); - static bool IsModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; } + static void MemoryCardSave(uint8 *buffer, uint32 *length); + static void MemoryCardLoad(uint8 *buffer, uint32 length); }; diff --git a/src/Timer.cpp b/src/Timer.cpp index 62f1ed55..2f7dc38d 100644 --- a/src/Timer.cpp +++ b/src/Timer.cpp @@ -133,7 +133,7 @@ void CTimer::Update(void) ms_fTimeStepNonClipped = ms_fTimeStep; - if ( CRecordDataForGame::RecordingState != _TODOCONST(2) ) + if ( CRecordDataForGame::RecordingState != RECORDSTATE_2 ) { ms_fTimeStep = min(3.0f, ms_fTimeStep); @@ -141,7 +141,7 @@ void CTimer::Update(void) m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60; } - if ( CRecordDataForChase::Status == _TODOCONST(1) ) + if ( CRecordDataForChase::Status == RECORDSTATE_1 ) { ms_fTimeStep = 1.0f; m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16; diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 4ce856f7..fe5b6dab 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -5,5 +5,6 @@ int &CCarCtrl::NumLawEnforcerCars = *(int*)0x8F1B38; WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); } -WRAPPER void CCarCtrl::AddToCarArray(int id, int vehclass) { EAXJMP(0x4182F0); } -WRAPPER void CCarCtrl::UpdateCarCount(CVehicle*, bool) { EAXJMP(0x4202E0); } \ No newline at end of file +WRAPPER void CCarCtrl::AddToCarArray(int32 id, int32 vehclass) { EAXJMP(0x4182F0); } +WRAPPER void CCarCtrl::UpdateCarCount(CVehicle*, bool) { EAXJMP(0x4202E0); } +WRAPPER int32 CCarCtrl::ChooseCarModel(int32 vehclass) { EAXJMP(0x418110); } diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h index cc9327ee..27ea6293 100644 --- a/src/control/CarCtrl.h +++ b/src/control/CarCtrl.h @@ -6,8 +6,9 @@ class CCarCtrl { public: static void SwitchVehicleToRealPhysics(CVehicle*); - static void AddToCarArray(int id, int vehclass); + static void AddToCarArray(int32 id, int32 vehclass); static void UpdateCarCount(CVehicle*, bool); + static int32 ChooseCarModel(int32 vehclass); static int32 &NumLawEnforcerCars; }; diff --git a/src/control/Gangs.cpp b/src/control/Gangs.cpp new file mode 100644 index 00000000..fc77ad72 --- /dev/null +++ b/src/control/Gangs.cpp @@ -0,0 +1,99 @@ +#include "common.h" +#include "patcher.h" +#include "ModelIndices.h" +#include "Gangs.h" + +CGangInfo(&CGangs::Gang)[NUM_GANGS] = *(CGangInfo(*)[9])*(uintptr*)0x6EDF78; + +CGangInfo::CGangInfo() : + m_nVehicleMI(MI_BUS), + m_nPedModelOverride(-1), + m_Weapon1(WEAPONTYPE_UNARMED), + m_Weapon2(WEAPONTYPE_UNARMED) +{} + +void CGangs::Initialize(void) +{ + Gang[GANG_MAFIA].m_nVehicleMI = MI_MAFIA; + Gang[GANG_TRIAD].m_nVehicleMI = MI_BELLYUP; + Gang[GANG_DIABLOS].m_nVehicleMI = MI_DIABLOS; + Gang[GANG_YAKUZA].m_nVehicleMI = MI_YAKUZA; + Gang[GANG_YARDIE].m_nVehicleMI = MI_YARDIE; + Gang[GANG_COLUMB].m_nVehicleMI = MI_COLUMB; + Gang[GANG_HOODS].m_nVehicleMI = MI_HOODS; + Gang[GANG_7].m_nVehicleMI = -1; + Gang[GANG_8].m_nVehicleMI = -1; +} + +void CGangs::SetGangVehicleModel(int16 gang, int model) +{ + GetGangInfo(gang)->m_nVehicleMI = model; +} + +void CGangs::SetGangWeapons(int16 gang, eWeaponType weapon1, eWeaponType weapon2) +{ + CGangInfo *gi = GetGangInfo(gang); + gi->m_Weapon1 = weapon1; + gi->m_Weapon2 = weapon2; +} + +void CGangs::SetGangPedModelOverride(int16 gang, int8 ovrd) +{ + GetGangInfo(gang)->m_nPedModelOverride = ovrd; +} + +int8 CGangs::GetGangPedModelOverride(int16 gang) +{ + return GetGangInfo(gang)->m_nPedModelOverride; +} + +void CGangs::SaveAllGangData(uint8 *buffer, uint32 *size) +{ + buffer[0] = 'G'; + buffer[1] = 'N'; + buffer[2] = 'G'; + buffer[3] = '\0'; + *size = 8 + NUM_GANGS * 16; + *(uint32*)(buffer + 4) = *size - 8; + buffer += 8; + for (int i = 0; i < NUM_GANGS; i++) { + *(uint32*)(buffer) = GetGangInfo(i)->m_nVehicleMI; + *(int8*)(buffer + 4) = GetGangInfo(i)->m_nPedModelOverride; + *(int8*)(buffer + 5) = GetGangInfo(i)->field_5; + *(int16*)(buffer + 6) = GetGangInfo(i)->field_6; + *(eWeaponType*)(buffer + 8) = GetGangInfo(i)->m_Weapon1; + *(eWeaponType*)(buffer + 12) = GetGangInfo(i)->m_Weapon2; + buffer += 16; + } +} + +void CGangs::LoadAllGangData(uint8 *buffer, uint32 size) +{ + Initialize(); + assert(size == 8 + NUM_GANGS * 16); + assert(buffer[0] == 'G'); + assert(buffer[1] == 'N'); + assert(buffer[2] == 'G'); + assert(buffer[3] == '\0'); + assert(*(uint32*)(buffer + 4) == size - 8); + buffer += 8; + for (int i = 0; i < NUM_GANGS; i++){ + GetGangInfo(i)->m_nVehicleMI = *(uint32*)(buffer); + GetGangInfo(i)->m_nPedModelOverride = *(int8*)(buffer + 4); + GetGangInfo(i)->field_5 = *(int8*)(buffer + 5); + GetGangInfo(i)->field_6 = *(int16*)(buffer + 6); + GetGangInfo(i)->m_Weapon1 = *(eWeaponType*)(buffer + 8); + GetGangInfo(i)->m_Weapon2 = *(eWeaponType*)(buffer + 12); + buffer += 16; + } +} + +STARTPATCHES +InjectHook(0x4C3FB0, CGangs::Initialize, PATCH_JUMP); +InjectHook(0x4C4010, CGangs::SetGangVehicleModel, PATCH_JUMP); +InjectHook(0x4C4030, CGangs::SetGangWeapons, PATCH_JUMP); +InjectHook(0x4C4050, CGangs::SetGangPedModelOverride, PATCH_JUMP); +InjectHook(0x4C4070, CGangs::GetGangPedModelOverride, PATCH_JUMP); +InjectHook(0x4C4080, CGangs::SaveAllGangData, PATCH_JUMP); +InjectHook(0x4C4100, CGangs::LoadAllGangData, PATCH_JUMP); +ENDPATCHES diff --git a/src/control/Gangs.h b/src/control/Gangs.h new file mode 100644 index 00000000..2366614b --- /dev/null +++ b/src/control/Gangs.h @@ -0,0 +1,47 @@ +#pragma once + +#include "Weapon.h" + +struct CGangInfo +{ + int32 m_nVehicleMI; + int8 m_nPedModelOverride; + int8 field_5; + int16 field_6; + eWeaponType m_Weapon1; + eWeaponType m_Weapon2; + + CGangInfo(); +}; + +static_assert(sizeof(CGangInfo) == 0x10, "CGangInfo: error"); + +enum { + GANG_MAFIA = 0, + GANG_TRIAD, + GANG_DIABLOS, + GANG_YAKUZA, + GANG_YARDIE, + GANG_COLUMB, + GANG_HOODS, + GANG_7, + GANG_8, + NUM_GANGS +}; + +class CGangs +{ +public: + static void Initialize(void); + static void SetGangVehicleModel(int16, int); + static void SetGangWeapons(int16, eWeaponType, eWeaponType); + static void SetGangPedModelOverride(int16, int8); + static int8 GetGangPedModelOverride(int16); + static void SaveAllGangData(uint8 *, uint32 *); + static void LoadAllGangData(uint8 *, uint32); + static CGangInfo* GetGangInfo(int16 gang) { return &Gang[gang]; } + +private: + + static CGangInfo(&Gang)[NUM_GANGS]; +}; diff --git a/src/control/Population.cpp b/src/control/Population.cpp index ebb48a93..fd1a89f5 100644 --- a/src/control/Population.cpp +++ b/src/control/Population.cpp @@ -2,6 +2,7 @@ #include "patcher.h" #include "Population.h" +PedGroup *CPopulation::ms_pPedGroups = (PedGroup*)0x6E9248; bool &CPopulation::ms_bGivePedsWeapons = *(bool*)0x95CCF6; -WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); } \ No newline at end of file +WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); } diff --git a/src/control/Population.h b/src/control/Population.h index a5572cdb..76442442 100644 --- a/src/control/Population.h +++ b/src/control/Population.h @@ -2,10 +2,16 @@ #include "PedType.h" +struct PedGroup +{ + int32 models[8]; +}; + class CPopulation { public: + static PedGroup *ms_pPedGroups; //[31] static bool &ms_bGivePedsWeapons; static void UpdatePedCount(uint32, bool); -}; \ No newline at end of file +}; diff --git a/src/control/Record.h b/src/control/Record.h index 2b904d1d..2705a955 100644 --- a/src/control/Record.h +++ b/src/control/Record.h @@ -1,5 +1,11 @@ #pragma once +enum { + RECORDSTATE_0, + RECORDSTATE_1, + RECORDSTATE_2, +}; + class CRecordDataForGame { public: diff --git a/src/re3.cpp b/src/re3.cpp index 284b88de..ec4f4439 100644 --- a/src/re3.cpp +++ b/src/re3.cpp @@ -126,7 +126,7 @@ spawnCar(int id) CVector playerpos; CStreaming::RequestModel(id, 0); CStreaming::LoadAllRequestedModels(false); - if(CStreaming::IsModelLoaded(id)){ + if(CStreaming::HasModelLoaded(id)){ FindPlayerCoors(playerpos); int node = ThePaths.FindNodeClosestToCoors(playerpos, 0, 100.0f, false, false); if(node < 0) diff --git a/src/render/Draw.cpp b/src/render/Draw.cpp index 7fd2f604..90875299 100644 --- a/src/render/Draw.cpp +++ b/src/render/Draw.cpp @@ -23,8 +23,6 @@ CDraw::CalculateAspectRatio() if(FrontEndMenuManager.m_PrefsUseWideScreen) ms_fAspectRatio = 16.0f/9.0f; - else if(TheCamera.m_WideScreenOn) - ms_fAspectRatio = 1.25f; else ms_fAspectRatio = 4.0f/3.0f; } diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index c3640ebf..19501ce8 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -33,21 +33,23 @@ bool &CHud::m_HelpMessageQuick = *(bool *)0x95CCF7; int32 CHud::m_ZoneState = *(int32*)0x8F29AC; int32 CHud::m_ZoneFadeTimer; int32 CHud::m_ZoneNameTimer = *(int32*)0x8F1A50; -wchar *&CHud::m_ZoneName = *(wchar **)0x8E2C2C; -wchar *CHud::m_LastZoneName = (wchar*)0x8F432C; +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_VehicleName = *(wchar **)0x942FB4; -wchar *CHud::m_LastVehicleName = *(wchar **)0x8E2DD8; -wchar *CHud::m_VehicleNameToPrint; +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_Wants_To_Draw_Hud = *(bool*)0x95CD89; bool &CHud::m_Wants_To_Draw_3dMarkers = *(bool*)0x95CD62; wchar(*CHud::m_BigMessage)[128] = (wchar(*)[128])0x664CE0; -wchar *CHud::m_LastBigMessage = (wchar*)0x86B288; +int32 CHud::m_ItemToFlash = *(int32*)0x95CC82; + +// These aren't really in CHud float CHud::BigMessageInUse[6]; float CHud::BigMessageAlpha[6]; float CHud::BigMessageX[6]; @@ -62,7 +64,6 @@ 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; @@ -141,9 +142,9 @@ void CHud::Draw() 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) + if (Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKET || Mode == CCam::MODE_M16FIRSTPERSON_34 || Mode == CCam::MODE_EDITOR) Mode_FirstPerson = 1; - if (Mode == CCam::CamMode::MODE_FIRSTPERSONPEDONPC_41 || Mode == CCam::CamMode::MODE_SNIPER_RUN_AROUND) + if (Mode == CCam::MODE_FIRSTPERSONPEDONPC_41 || Mode == CCam::MODE_SNIPER_RUN_AROUND) Mode_RunAround = 1; /* @@ -162,16 +163,16 @@ void CHud::Draw() if (Mode_FirstPerson || Mode_RunAround) { RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR); - int32 SpriteBrightLikeADiamond = CHud::SpriteBrightness + 1; + int32 SpriteBrightLikeADiamond = SpriteBrightness + 1; if (SpriteBrightLikeADiamond > 30) SpriteBrightLikeADiamond = 30; - CHud::SpriteBrightness = SpriteBrightLikeADiamond; + SpriteBrightness = SpriteBrightLikeADiamond; RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); float fStep = sin((CTimer::GetTimeInMilliseconds() & 1023) * 0.0061328127); - float fMultBright = CHud::SpriteBrightness * 0.03f * (0.25f * fStep + 0.75f); + float fMultBright = SpriteBrightness * 0.03f * (0.25f * fStep + 0.75f); CRect rect; float fWidescreenOffset[2] = { 0.0f, 0.0f }; @@ -191,7 +192,7 @@ void CHud::Draw() rect.right = f3rdX + SCREEN_SCALE_X(32.0f * 0.6f); rect.bottom = f3rdY + SCREEN_SCALE_Y(32.0f * 0.6f); - CHud::Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); } else { rect.left = f3rdX - SCREEN_SCALE_X(32.0f * 0.4f); @@ -199,61 +200,61 @@ void CHud::Draw() rect.right = f3rdX + SCREEN_SCALE_X(32.0f * 0.4f); rect.bottom = f3rdY + SCREEN_SCALE_Y(32.0f * 0.4f); - CHud::Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + 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_SCALE_X(32.0f * 0.7f); - rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(32.0f * 0.7f); - rect.right = (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(32.0f * 0.7f); - rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_SCALE_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_SCALE_X(210.0f); - rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_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_SCALE_Y(210.0f); - rect.left = SCREEN_SCALE_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_SCALE_X(210.0f); - rect.bottom = (SCREEN_HEIGHT / 2); - rect.right = (SCREEN_WIDTH / 2); - rect.top = SCREEN_SCALE_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_SCALE_X(210.0f) + (SCREEN_WIDTH / 2); - rect.top = SCREEN_SCALE_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_SCALE_X(40.0f), SCREEN_SCALE_Y(40.0f), (100.0f * fMultBright), (200.0f * fMultBright), (100.0f * fMultBright), 255, 1.0f, 255); - } - } - else { + if (Mode == CCam::MODE_M16FIRSTPERSON_34 || + Mode == CCam::MODE_FIRSTPERSONPEDONPC_41 || + Mode != CCam::MODE_EDITOR) { rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(32.0f); rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(32.0f); rect.right = (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(32.0f); rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(32.0f); - CHud::Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + } + else if (Mode == CCam::MODE_ROCKET_RUN_AROUND) { + rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(32.0f * 0.7f); + rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(32.0f * 0.7f); + rect.right = (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(32.0f * 0.7f); + rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(32.0f * 0.7f); + + Sprites[HUD_SITEM16].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + } + else if (Mode == CCam::MODE_ROCKET || Mode == CCam::MODE_SNIPER_RUN_AROUND) { + 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_SCALE_X(40.0f), SCREEN_SCALE_Y(40.0f), (100.0f * fMultBright), (200.0f * fMultBright), (100.0f * fMultBright), 255, 1.0f, 255); + } + else { + rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(210.0f); + rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(210.0f); + rect.right = SCREEN_WIDTH / 2; + rect.bottom = SCREEN_HEIGHT / 2; + Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + + rect.right = (SCREEN_WIDTH / 2); + rect.top = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(210.0f); + rect.left = SCREEN_SCALE_X(210.0f) + (SCREEN_WIDTH / 2); + rect.bottom = SCREEN_HEIGHT / 2; + Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + + rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(210.0f); + rect.bottom = (SCREEN_HEIGHT / 2); + rect.right = (SCREEN_WIDTH / 2); + rect.top = SCREEN_SCALE_Y(210.0f) + (SCREEN_HEIGHT / 2); + Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); + + rect.right = (SCREEN_WIDTH / 2); + rect.bottom = (SCREEN_HEIGHT / 2); + rect.left = SCREEN_SCALE_X(210.0f) + (SCREEN_WIDTH / 2); + rect.top = SCREEN_SCALE_Y(210.0f) + (SCREEN_HEIGHT / 2); + Sprites[HUD_SITESNIPER].Draw(CRect(rect), CRGBA(255, 255, 255, 255)); } } RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR); @@ -261,7 +262,7 @@ void CHud::Draw() RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA); } else { - CHud::SpriteBrightness = 0; + SpriteBrightness = 0; } /* @@ -346,7 +347,7 @@ void CHud::Draw() if (!CDarkel::FrenzyOnGoing()) { if (WeaponType) { - if (WeaponType != 1) { + if (WeaponType != WEAPONTYPE_BASEBALLBAT) { CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(73.0f), sPrint); } @@ -356,7 +357,7 @@ void CHud::Draw() /* DrawWeaponIcon */ - CHud::Sprites[WeaponType].Draw( + Sprites[WeaponType].Draw( CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)), CRGBA(255, 255, 255, 255), 0.015f, @@ -380,8 +381,8 @@ void CHud::Draw() CFont::SetPropOff(); CFont::SetFontStyle(FONT_HEADING); - if (CHud::m_ItemToFlash == ITEM_HEALTH && CTimer::GetFrameCounter() & 8 - || CHud::m_ItemToFlash != ITEM_HEALTH + if (m_ItemToFlash == ITEM_HEALTH && CTimer::GetFrameCounter() & 8 + || m_ItemToFlash != ITEM_HEALTH || CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) { if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth >= 10 @@ -410,7 +411,7 @@ void CHud::Draw() /* DrawArmour */ - if (CHud::m_ItemToFlash == ITEM_ARMOUR && CTimer::GetFrameCounter() & 8 || CHud::m_ItemToFlash != ITEM_ARMOUR) { + if (m_ItemToFlash == ITEM_ARMOUR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_ARMOUR) { CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fArmour > 1.0f) { AsciiToUnicode("[", sPrintIcon); @@ -462,71 +463,71 @@ void CHud::Draw() /* DrawZoneName */ - if (CHud::m_ZoneName) { + if (m_pZoneName) { float fZoneAlpha = 0.0f; - if (CHud::m_ZoneName != CHud::m_LastZoneName) { - switch (CHud::m_ZoneState) { + if (m_pZoneName != m_pLastZoneName) { + switch (m_ZoneState) { case 0: - CHud::m_ZoneState = 2; - CHud::m_ZoneToPrint = CHud::m_ZoneName; - CHud::m_ZoneNameTimer = 0; - CHud::m_ZoneFadeTimer = 0; + m_ZoneState = 2; + m_ZoneToPrint = m_pZoneName; + m_ZoneNameTimer = 0; + m_ZoneFadeTimer = 0; break; case 1: case 2: case 3: case 4: - CHud::m_ZoneNameTimer = 0; - CHud::m_ZoneState = 4; + m_ZoneNameTimer = 0; + m_ZoneState = 4; break; default: break; } - CHud::m_LastZoneName = CHud::m_ZoneName; + m_pLastZoneName = m_pZoneName; } - if (CHud::m_ZoneState) { - switch (CHud::m_ZoneState) { + if (m_ZoneState) { + switch (m_ZoneState) { case 1: - if (CHud::m_ZoneNameTimer > 10000) { - CHud::m_ZoneFadeTimer = 1000; - CHud::m_ZoneState = 3; + if (m_ZoneNameTimer > 10000) { + m_ZoneFadeTimer = 1000; + 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; + m_ZoneFadeTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (m_ZoneFadeTimer > 1000) { + m_ZoneState = 1; + m_ZoneFadeTimer = 1000; } - fZoneAlpha = CHud::m_ZoneFadeTimer * 0.001f * 255.0f; + fZoneAlpha = 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; + m_ZoneFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (m_ZoneFadeTimer < 0) { + m_ZoneState = 0; + m_ZoneFadeTimer = 0; } - fZoneAlpha = CHud::m_ZoneFadeTimer * 0.001f * 255.0f; + fZoneAlpha = 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_LastZoneName; - CHud::m_ZoneNameTimer = 0; - CHud::m_ZoneState = 2; + m_ZoneFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (m_ZoneFadeTimer < 0) { + m_ZoneFadeTimer = 0; + m_ZoneToPrint = m_pLastZoneName; + m_ZoneNameTimer = 0; + m_ZoneState = 2; } - fZoneAlpha = CHud::m_ZoneFadeTimer * 0.001f * 255.0f; + fZoneAlpha = m_ZoneFadeTimer * 0.001f * 255.0f; break; default: break; } - if (!CHud::m_Message[0]) { - CHud::m_ZoneNameTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (!m_Message[0]) { + m_ZoneNameTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); CFont::SetJustifyOff(); CFont::SetPropOn(); CFont::SetBackgroundOff(); @@ -541,88 +542,88 @@ void CHud::Draw() CFont::SetBackGroundOnlyTextOff(); CFont::SetFontStyle(FONT_BANK); CFont::SetColor(CRGBA(0, 0, 0, fZoneAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f - 1.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f - 1.0f), CHud::m_ZoneToPrint); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f - 1.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f - 1.0f), m_ZoneToPrint); CFont::SetColor(CRGBA(152, 154, 82, fZoneAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f), CHud::m_ZoneToPrint); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f), m_ZoneToPrint); } } } else { - CHud::m_LastZoneName = 0; - CHud::m_ZoneState = 0; - CHud::m_ZoneFadeTimer = 0; - CHud::m_ZoneNameTimer = 0; + m_pLastZoneName = 0; + m_ZoneState = 0; + m_ZoneFadeTimer = 0; + m_ZoneNameTimer = 0; } /* DrawVehicleName */ - if (CHud::m_VehicleName) { + if (m_VehicleName) { float fVehicleAlpha = 0.0f; - if (CHud::m_VehicleName != CHud::m_LastVehicleName) { - switch (CHud::m_VehicleState) { + if (m_VehicleName != m_pLastVehicleName) { + switch (m_VehicleState) { case 0: - CHud::m_VehicleState = 2; - CHud::m_VehicleNameToPrint = CHud::m_VehicleName; - CHud::m_VehicleNameTimer = 0; - CHud::m_VehicleFadeTimer = 0; + m_VehicleState = 2; + m_pVehicleNameToPrint = m_VehicleName; + m_VehicleNameTimer = 0; + m_VehicleFadeTimer = 0; break; case 1: case 2: case 3: case 4: - CHud::m_VehicleNameTimer = 0; - CHud::m_VehicleState = 4; + m_VehicleNameTimer = 0; + m_VehicleState = 4; break; default: break; } - CHud::m_LastVehicleName = CHud::m_VehicleName; + m_pLastVehicleName = m_VehicleName; } - if (CHud::m_VehicleState) { - switch (CHud::m_VehicleState) { + if (m_VehicleState) { + switch (m_VehicleState) { case 1: - if (CHud::m_VehicleNameTimer > 10000) { - CHud::m_VehicleFadeTimer = 1000; - CHud::m_VehicleState = 3; + if (m_VehicleNameTimer > 10000) { + m_VehicleFadeTimer = 1000; + 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; + m_VehicleFadeTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (m_VehicleFadeTimer > 1000) { + m_VehicleState = 1; + m_VehicleFadeTimer = 1000; } - fVehicleAlpha = CHud::m_VehicleFadeTimer * 0.001f * 255.0f; + fVehicleAlpha = 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; + m_VehicleFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (m_VehicleFadeTimer < 0) { + m_VehicleState = 0; + m_VehicleFadeTimer = 0; } - fVehicleAlpha = CHud::m_VehicleFadeTimer * 0.001f * 255.0f; + fVehicleAlpha = 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_VehicleNameToPrint = CHud::m_LastVehicleName; - CHud::m_VehicleNameTimer = 0; - CHud::m_VehicleState = 2; + m_VehicleFadeTimer += (CTimer::GetTimeStep() * 0.02f * -1000.0f); + if (m_VehicleFadeTimer < 0) { + m_VehicleFadeTimer = 0; + m_pVehicleNameToPrint = m_pLastVehicleName; + m_VehicleNameTimer = 0; + m_VehicleState = 2; } - fVehicleAlpha = CHud::m_VehicleFadeTimer * 0.001f * 255.0f; + fVehicleAlpha = m_VehicleFadeTimer * 0.001f * 255.0f; break; default: break; } - if (!CHud::m_Message[0]) { - CHud::m_VehicleNameTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); + if (!m_Message[0]) { + m_VehicleNameTimer += (CTimer::GetTimeStep() * 0.02f * 1000.0f); CFont::SetJustifyOff(); CFont::SetPropOn(); CFont::SetBackgroundOff(); @@ -637,18 +638,18 @@ void CHud::Draw() CFont::SetBackGroundOnlyTextOff(); CFont::SetFontStyle(FONT_BANK); CFont::SetColor(CRGBA(0, 0, 0, fVehicleAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f - 1.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f - 1.0f), CHud::m_VehicleNameToPrint); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f - 1.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f - 1.0f), m_pVehicleNameToPrint); CFont::SetColor(CRGBA(194, 165, 120, fVehicleAlpha)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f), CHud::m_VehicleNameToPrint); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f), m_pVehicleNameToPrint); } } } else { - CHud::m_LastVehicleName = 0; - CHud::m_VehicleState = 0; - CHud::m_VehicleFadeTimer = 0; - CHud::m_VehicleNameTimer = 0; + m_pLastVehicleName = 0; + m_VehicleState = 0; + m_VehicleFadeTimer = 0; + m_VehicleNameTimer = 0; } /* @@ -788,7 +789,7 @@ void CHud::Draw() } } - CHud::Sprites[HUD_PAGER].Draw(CRect(SCREEN_SCALE_X(26.0f - PagerXOffset), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_X(160.0 + 26.0f - PagerXOffset), SCREEN_SCALE_Y(80.0f + 27.0f)), CRGBA(255, 255, 255, 255)); + Sprites[HUD_PAGER].Draw(CRect(SCREEN_SCALE_X(26.0f - PagerXOffset), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_X(160.0 + 26.0f - PagerXOffset), SCREEN_SCALE_Y(80.0f + 27.0f)), CRGBA(255, 255, 255, 255)); CFont::SetBackgroundOff(); CFont::SetScale(SCREEN_SCALE_X(0.84f), SCREEN_SCALE_Y(1.0f)); @@ -799,19 +800,19 @@ void CHud::Draw() CFont::SetJustifyOff(); CFont::SetPropOff(); CFont::SetFontStyle(FONT_PAGER); - CFont::PrintString(SCREEN_SCALE_X(52.0f - PagerXOffset), SCREEN_SCALE_Y(54.0f), CHud::m_PagerMessage); + CFont::PrintString(SCREEN_SCALE_X(52.0f - PagerXOffset), SCREEN_SCALE_Y(54.0f), m_PagerMessage); } /* DrawRadar */ - if (CHud::m_ItemToFlash == ITEM_RADAR && CTimer::GetFrameCounter() & 8 || CHud::m_ItemToFlash != ITEM_RADAR) { + if (m_ItemToFlash == ITEM_RADAR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_RADAR) { CRadar::DrawMap(); CRect rect(0.0f, 0.0f, SCREEN_SCALE_X(RADAR_WIDTH), SCREEN_SCALE_Y(RADAR_HEIGHT)); // FIX: game doesn't scale RADAR_LEFT here rect.Translate(SCREEN_SCALE_X(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT)); rect.Grow(4.0f); - CHud::Sprites[HUD_RADARDISC].Draw(rect, CRGBA(0, 0, 0, 255)); + Sprites[HUD_RADARDISC].Draw(rect, CRGBA(0, 0, 0, 255)); CRadar::DrawBlips(); } } @@ -819,7 +820,7 @@ void CHud::Draw() /* Draw3dMarkers */ - if (CHud::m_Wants_To_Draw_3dMarkers && !TheCamera.m_WideScreenOn && !CHud::m_BigMessage[0][0] && !CHud::m_BigMessage[2][0]) { + if (m_Wants_To_Draw_3dMarkers && !TheCamera.m_WideScreenOn && !m_BigMessage[0][0] && !m_BigMessage[2][0]) { CRadar::Draw3dMarkers(); } @@ -902,7 +903,7 @@ void CHud::Draw() /* DrawSubtitles */ - if (CHud::m_Message[0] && !CHud::m_BigMessage[2][0] && (FrontEndMenuManager.m_PrefsShowSubtitles == 1 || !TheCamera.m_WideScreenOn)) { + if (m_Message[0] && !m_BigMessage[2][0] && (FrontEndMenuManager.m_PrefsShowSubtitles == 1 || !TheCamera.m_WideScreenOn)) { CFont::SetJustifyOff(); CFont::SetBackgroundOff(); CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128)); @@ -919,7 +920,7 @@ void CHud::Draw() CFont::SetDropShadowPosition(1); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetColor(CRGBA(235, 235, 235, 255)); - CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_FROM_BOTTOM(64.0f), CHud::m_Message); + CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_FROM_BOTTOM(64.0f), m_Message); CFont::SetDropShadowPosition(0); } @@ -1255,7 +1256,38 @@ WRAPPER void CHud::GetRidOfAllHudMessages(void) { EAXJMP(0x504F90); } #else void CHud::GetRidOfAllHudMessages() { - ReInitialise(); + m_ZoneState = 0; + m_pLastZoneName = 0; + m_ZoneNameTimer = 0; + m_pZoneName = 0; + + for (int i = 0; i < 256; i++) { + m_HelpMessage[i] = 0; + m_LastHelpMessage[i] = 0; + m_HelpMessageToPrint[i] = 0; + } + + m_HelpMessageTimer = 0; + m_HelpMessageFadeTimer = 0; + m_HelpMessageState = 0; + m_HelpMessageQuick = 0; + m_HelpMessageDisplayTime = 1.0f; + m_VehicleName = 0; + m_pLastVehicleName = 0; + m_pVehicleNameToPrint = 0; + m_VehicleNameTimer = 0; + m_VehicleFadeTimer = 0; + m_VehicleState = 0; + + for (int i = 0; i < 256; i++) + m_Message[i] = 0; + + for (int i = 0; i < 6; i++) { + BigMessageInUse[i] = 0.0f; + + for (int j = 0; j < 128; j++) + m_BigMessage[i][j] = 0; + } } #endif @@ -1286,41 +1318,16 @@ WRAPPER void CHud::ReInitialise(void) { EAXJMP(0x504CC0); } #else void CHud::ReInitialise() { m_Wants_To_Draw_Hud = true; - m_ZoneState = 0; m_Wants_To_Draw_3dMarkers = true; - m_LastZoneName = 0; - m_ZoneNameTimer = 0; - m_ZoneName = 0; - for (int i = 0; i < 256; i++) { - m_HelpMessage[i] = 0; - m_LastHelpMessage[i] = 0; - m_HelpMessageToPrint[i] = 0; - m_Message[i] = 0; - - if (i <= 6) - BigMessageInUse[i] = 0.0f; - - if (i <= 128) - m_BigMessage[i][0] = 0; - } - - m_HelpMessageTimer = 0; - m_HelpMessageFadeTimer = 0; - m_HelpMessageState = 0; - m_HelpMessageQuick = 0; - m_VehicleName = 0; - m_LastVehicleName = 0; - m_VehicleNameToPrint = 0; - m_VehicleNameTimer = 0; - m_VehicleFadeTimer = 0; - m_VehicleState = 0; - m_HelpMessageDisplayTime = 1.0f; + GetRidOfAllHudMessages(); CounterOnLastFrame = 0; m_ItemToFlash = ITEM_NONE; OddJob2Timer = 0; OddJob2OffTimer = 0.0f; + OddJob2On = 0; + OddJob2XOffset = 0.0f; CounterFlashTimer = 0; TimerOnLastFrame = 0; TimerFlashTimer = 0; @@ -1328,28 +1335,40 @@ void CHud::ReInitialise() { PagerOn = 0; PagerTimer = 0; PagerSoundPlayed = 0; - OddJob2On = 0; PagerXOffset = 150.0f; - OddJob2XOffset = 0.0f; } #endif +wchar LastBigMessage[6][128]; #if 0 WRAPPER void CHud::SetBigMessage(wchar *message, int16 style) { EAXJMP(0x50A250); } #else void CHud::SetBigMessage(wchar *message, int16 style) { - for (int i = 0; i < 128; i++) { - if (!message[i]) - break; + int i; - if (message[i] != m_LastBigMessage[i]) { - OddJob2On = 0; - OddJob2OffTimer = 0.0f; + if (style == 5) { + for (i = 0; i < 128; i++) { + if (message[i] == 0) + break; + + if (message[i] != LastBigMessage[5][i]) { + OddJob2On = 0; + OddJob2OffTimer = 0.0f; + } + + m_BigMessage[5][i] = message[i]; + LastBigMessage[5][i] = message[i]; } - - m_BigMessage[style][i] = message[i]; - }; + } else { + for (i = 0; i < 128; i++) { + if (message[i] == 0) + break; + m_BigMessage[style][i] = message[i]; + } + } + LastBigMessage[style][i] = 0; + m_BigMessage[style][i] = 0; } #endif @@ -1364,7 +1383,7 @@ void CHud::SetHelpMessage(wchar *message, bool quick) for (int i = 0; i < 256; i++) { m_LastHelpMessage[i] = message[i]; - }; + } m_HelpMessageState = 0; m_HelpMessageQuick = quick; @@ -1377,14 +1396,14 @@ WRAPPER void CHud::SetMessage(wchar *message) { EAXJMP(0x50A210); } #else void CHud::SetMessage(wchar *message) { - int i = 0; - for (i; i < 256; i++) { - if (!message[i]) + int i; + for (i = 0; i < 256; i++) { + if (message[i] == 0) break; m_Message[i] = message[i]; - }; - m_Message[i] = message[i]; + } + m_Message[i] = 0; } #endif @@ -1393,14 +1412,13 @@ WRAPPER void CHud::SetPagerMessage(wchar *message) { EAXJMP(0x50A320); } #else void CHud::SetPagerMessage(wchar *message) { - int i = 0; - for (i; i < 256; i++) { - if (!message[i]) + int i; + for (i = 0; i < 256; i++) { + if (message[i] == 0) break; m_PagerMessage[i] = message[i]; - }; - + } m_PagerMessage[i] = 0; } #endif @@ -1419,7 +1437,7 @@ WRAPPER void CHud::SetZoneName(wchar *name) { EAXJMP(0x5051D0); } #else void CHud::SetZoneName(wchar *name) { - m_ZoneName = name; + m_pZoneName = name; } #endif diff --git a/src/render/Hud.h b/src/render/Hud.h index c4a768f4..1c82b7df 100644 --- a/src/render/Hud.h +++ b/src/render/Hud.h @@ -34,6 +34,7 @@ class CHud { public: static CSprite2d *Sprites; + static int32 &SpriteBrightness; static wchar *m_HelpMessage; static wchar *m_LastHelpMessage; static int32 &m_HelpMessageState; @@ -47,12 +48,12 @@ public: static int32 m_ZoneState; static int32 m_ZoneFadeTimer; static int32 m_ZoneNameTimer; - static wchar *&m_ZoneName; - static wchar *m_LastZoneName; + static wchar *&m_pZoneName; + static wchar *m_pLastZoneName; static wchar *m_ZoneToPrint; static wchar *&m_VehicleName; - static wchar *m_LastVehicleName; - static wchar *m_VehicleNameToPrint; + static wchar *m_pLastVehicleName; + static wchar *m_pVehicleNameToPrint; static int32 m_VehicleState; static int32 m_VehicleFadeTimer; static int32 m_VehicleNameTimer; @@ -61,7 +62,9 @@ public: static bool &m_Wants_To_Draw_Hud; static bool &m_Wants_To_Draw_3dMarkers; static wchar(*m_BigMessage)[128]; - static wchar *m_LastBigMessage; + static int32 m_ItemToFlash; + + // These aren't really in CHud static float BigMessageInUse[6]; static float BigMessageAlpha[6]; static float BigMessageX[6]; @@ -70,13 +73,11 @@ public: static float &OddJob2XOffset; static int16 &CounterFlashTimer; static int16 &OddJob2Timer; - static int8 &TimerOnLastFrame; + 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;