This commit is contained in:
Nikolay Korolev 2019-10-26 17:20:31 +03:00
commit 3dee880c29
99 changed files with 6011 additions and 2727 deletions

View File

@ -29,12 +29,10 @@ after_build:
$url = "$releases/download/$latestVersion/$name"
Start-FileDownload $url -FileName 'C:\Ultimate-ASI-Loader.zip'
7z e c:\Ultimate-ASI-Loader.zip -oc:\Projects\re3\bin\${env:CONFIGURATION}
cd "bin\${env:CONFIGURATION}"
copy re3.dll re3.asi
@ -44,4 +42,4 @@ after_build:
Get-ChildItem .\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
artifacts:
- path: bin/%CONFIGURATION%/re3.dll
name: re3.dll
name: re3.dll

View File

@ -15,6 +15,7 @@ workspace "re3"
files { "src/render/*.*" }
files { "src/skel/*.*" }
files { "src/skel/win/*.*" }
files { "src/text/*.*" }
files { "src/vehicles/*.*" }
files { "src/weapons/*.*" }
files { "eax/*.*" }
@ -32,6 +33,7 @@ workspace "re3"
includedirs { "src/render" }
includedirs { "src/skel/" }
includedirs { "src/skel/win" }
includedirs { "src/text" }
includedirs { "src/vehicles" }
includedirs { "src/weapons" }
includedirs { "eax" }

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,136 @@
#pragma once
#include "AudioSamples.h"
#include "DMAudio.h"
#include "common.h"
enum eScriptSounds : int16
{
SCRIPT_SOUND_0 = 0,
SCRIPT_SOUND_1 = 1,
SCRIPT_SOUND_2 = 2,
SCRIPT_SOUND_3 = 3,
SCRIPT_SOUND_PARTY_1_LOOP_S = 4,
SCRIPT_SOUND_PARTY_1_LOOP_L = 5,
SCRIPT_SOUND_PARTY_2_LOOP_S = 6,
SCRIPT_SOUND_PARTY_2_LOOP_L = 7,
SCRIPT_SOUND_PARTY_3_LOOP_S = 8,
SCRIPT_SOUND_PARTY_3_LOOP_L = 9,
SCRIPT_SOUND_PARTY_4_LOOP_S = 10,
SCRIPT_SOUND_PARTY_4_LOOP_L = 11,
SCRIPT_SOUND_PARTY_5_LOOP_S = 12,
SCRIPT_SOUND_PARTY_5_LOOP_L = 13,
SCRIPT_SOUND_PARTY_6_LOOP_S = 14,
SCRIPT_SOUND_PARTY_6_LOOP_L = 15,
SCRIPT_SOUND_PARTY_7_LOOP_S = 16,
SCRIPT_SOUND_PARTY_7_LOOP_L = 17,
SCRIPT_SOUND_PARTY_8_LOOP_S = 18,
SCRIPT_SOUND_PARTY_8_LOOP_L = 19,
SCRIPT_SOUND_PARTY_9_LOOP_S = 20,
SCRIPT_SOUND_PARTY_9_LOOP_L = 21,
SCRIPT_SOUND_PARTY_10_LOOP_S = 22,
SCRIPT_SOUND_PARTY_10_LOOP_L = 23,
SCRIPT_SOUND_PARTY_11_LOOP_S = 24,
SCRIPT_SOUND_PARTY_11_LOOP_L = 25,
SCRIPT_SOUND_PARTY_12_LOOP_S = 26,
SCRIPT_SOUND_PARTY_12_LOOP_L = 27,
SCRIPT_SOUND_PARTY_13_LOOP_S = 28,
SCRIPT_SOUND_PARTY_13_LOOP_L = 29,
SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S = 30,
SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L = 31,
SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S = 32,
SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L = 33,
SCRIPT_SOUND_WORK_SHOP_LOOP_S = 34,
SCRIPT_SOUND_WORK_SHOP_LOOP_L = 35,
SCRIPT_SOUND_SAWMILL_LOOP_S = 36,
SCRIPT_SOUND_SAWMILL_LOOP_L = 37,
SCRIPT_SOUND_38 = 38,
SCRIPT_SOUND_39 = 39,
SCRIPT_SOUND_LAUNDERETTE_LOOP_S = 40,
SCRIPT_SOUND_LAUNDERETTE_LOOP_L = 41,
SCRIPT_SOUND_CHINATOWN_RESTAURANT_S = 42,
SCRIPT_SOUND_CHINATOWN_RESTAURANT_L = 43,
SCRIPT_SOUND_CIPRIANI_RESAURANT_S = 44,
SCRIPT_SOUND_CIPRIANI_RESAURANT_L = 45,
SCRIPT_SOUND_46 = 46,
SCRIPT_SOUND_47 = 47,
SCRIPT_SOUND_MARCO_BISTRO_S = 48,
SCRIPT_SOUND_MARCO_BISTRO_L = 49,
SCRIPT_SOUND_AIRPORT_LOOP_S = 50,
SCRIPT_SOUND_AIRPORT_LOOP_L = 51,
SCRIPT_SOUND_SHOP_LOOP_S = 52,
SCRIPT_SOUND_SHOP_LOOP_L = 53,
SCRIPT_SOUND_CINEMA_LOOP_S = 54,
SCRIPT_SOUND_CINEMA_LOOP_L = 55,
SCRIPT_SOUND_DOCKS_LOOP_S = 56,
SCRIPT_SOUND_DOCKS_LOOP_L = 57,
SCRIPT_SOUND_HOME_LOOP_S = 58,
SCRIPT_SOUND_HOME_LOOP_L = 59,
SCRIPT_SOUND_FRANKIE_PIANO = 60,
SCRIPT_SOUND_PARTY_1_LOOP = 61,
SCRIPT_SOUND_PORN_CINEMA_1_S = 62,
SCRIPT_SOUND_PORN_CINEMA_1_L = 63,
SCRIPT_SOUND_PORN_CINEMA_2_S = 64,
SCRIPT_SOUND_PORN_CINEMA_2_L = 65,
SCRIPT_SOUND_PORN_CINEMA_3_S = 66,
SCRIPT_SOUND_PORN_CINEMA_3_L = 67,
SCRIPT_SOUND_BANK_ALARM_LOOP_S = 68,
SCRIPT_SOUND_BANK_ALARM_LOOP_L = 69,
SCRIPT_SOUND_POLICE_BALL_LOOP_S = 70,
SCRIPT_SOUND_POLICE_BALL_LOOP_L = 71,
SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S = 72,
SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L = 73,
SCRIPT_SOUND_74 = 74,
SCRIPT_SOUND_75 = 75,
SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S = 76,
SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L = 77,
SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S = 78,
SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L = 79,
SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S = 80,
SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L = 81,
SCRIPT_SOUND_EVIDENCE_PICKUP = 82,
SCRIPT_SOUND_UNLOAD_GOLD = 83,
SCRIPT_SOUND_RAVE_1_LOOP_S = 84,
SCRIPT_SOUND_RAVE_1_LOOP_L = 85,
SCRIPT_SOUND_RAVE_2_LOOP_S = 86,
SCRIPT_SOUND_RAVE_2_LOOP_L = 87,
SCRIPT_SOUND_RAVE_3_LOOP_S = 88,
SCRIPT_SOUND_RAVE_3_LOOP_L = 89,
SCRIPT_SOUND_MISTY_SEX_S = 90,
SCRIPT_SOUND_MISTY_SEX_L = 91,
SCRIPT_SOUND_GATE_START_CLUNK = 92,
SCRIPT_SOUND_GATE_STOP_CLUNK = 93,
SCRIPT_SOUND_PART_MISSION_COMPLETE = 94,
SCRIPT_SOUND_CHUNKY_RUN_SHOUT = 95,
SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT = 96,
SCRIPT_SOUND_RACE_START_3 = 97,
SCRIPT_SOUND_RACE_START_2 = 98,
SCRIPT_SOUND_RACE_START_1 = 99,
SCRIPT_SOUND_RACE_START_GO = 100,
SCRIPT_SOUND_SWAT_PED_SHOUT = 101,
SCRIPT_SOUND_PRETEND_FIRE_LOOP = 102,
SCRIPT_SOUND_AMMUNATION_CHAT_1 = 103,
SCRIPT_SOUND_AMMUNATION_CHAT_2 = 104,
SCRIPT_SOUND_AMMUNATION_CHAT_3 = 105,
SCRIPT_SOUND_BULLET_HIT_GROUND_1 = 106,
SCRIPT_SOUND_BULLET_HIT_GROUND_2 = 107,
SCRIPT_SOUND_BULLET_HIT_GROUND_3 = 108,
SCRIPT_SOUND_109 = 109,
SCRIPT_SOUND_110 = 110,
SCRIPT_SOUND_111 = 111,
SCRIPT_SOUND_PAYPHONE_RINGING = 112,
SCRIPT_SOUND_113 = 113,
SCRIPT_SOUND_GLASS_BREAK_L = 114,
SCRIPT_SOUND_GLASS_BREAK_S = 115,
SCRIPT_SOUND_GLASS_CRACK = 116,
SCRIPT_SOUND_GLASS_LIGHT_BREAK = 117,
SCRIPT_SOUND_BOX_DESTROYED_1 = 118,
SCRIPT_SOUND_BOX_DESTROYED_2 = 119,
SCRIPT_SOUND_METAL_COLLISION = 120,
SCRIPT_SOUND_TIRE_COLLISION = 121,
SCRIPT_SOUND_GUNSHELL_DROP = 122,
SCRIPT_SOUND_GUNSHELL_DROP_SOFT = 123,
};
class tActiveSample
{
public:
@ -45,7 +172,7 @@ public:
uint8 field_82;
uint8 field_83;
int32 calculatedVolume;
uint8 field_88;
int8 field_88;
uint8 field_89;
uint8 field_90;
uint8 field_91;
@ -55,7 +182,8 @@ public:
static_assert(sizeof(tActiveSample) == 92, "tActiveSample: error");
enum eAudioType : int32 {
enum eAudioType : int32
{
AUDIOTYPE_PHYSICAL = 0,
AUDIOTYPE_EXPLOSION = 1,
AUDIOTYPE_FIRE = 2,
@ -158,7 +286,8 @@ public:
uint8 gap_811;
cAudioCollision m_sQueue;
void AddCollisionToRequestedQueue(); // todo
// reversed all methods
void AddCollisionToRequestedQueue(); /// ok
};
static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error");
@ -199,6 +328,8 @@ public:
CVector Posn;
int32 AudioEntity;
void Reset(); /// ok
static void *operator new(size_t);
static void *operator new(size_t, int);
static void operator delete(void *, size_t);
@ -232,6 +363,15 @@ enum AudioEntityHandle {
AEHANDLE_ERROR_BADAUDIOTYPE = -1,
};
struct Crime {
int32 type;
CVector position;
uint16 timer;
uint16 gap;
};
static_assert(sizeof(Crime) == 20, "Crime: error ");
class cAudioManager
{
public:
@ -250,7 +390,7 @@ public:
uint8 field_15;
int32 m_nTimer;
tActiveSample m_sQueueSample;
uint8 m_bActiveSampleQueue;
bool m_bActiveSampleQueue;
uint8 gap_109[3];
tActiveSample m_asSamples[2][27];
uint8 m_abSampleQueueIndexTable[2][27];
@ -267,7 +407,12 @@ public:
int32 m_nFireAudioEntity;
int32 m_nWaterCannonEntity;
int32 m_nPoliceChannelEntity;
uint8 gap45B8[444];
int32 crimesSamples[60];
uint8 policeChannelTimer;
uint8 policeChannelTimerSeconds;
uint8 policeChannelCounterSeconds;
uint8 gap30;
Crime crimes[10];
int32 m_nFrontEndEntity;
int32 m_nCollisionEntity;
cAudioCollisionManager m_sCollisionManager;
@ -279,30 +424,31 @@ public:
uint8 m_bUserPause;
uint8 m_bPreviousUserPause;
uint8 field_19195; // time?
uint32 m_FrameCounter;
uint32 m_nTimeOfRecentCrime;
// getters
uint32 GetFrameCounter() const { return m_FrameCounter; }
uint32 GetFrameCounter() const { return m_nTimeOfRecentCrime; }
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; }
// "Should" be in alphabetic order, except "getXTalkSfx"
void AddDetailsToRequestedOrderList(uint8 sample); /// ok
void AddDetailsToRequestedOrderList(uint8 sample); /// ok (check once more)
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 unk1,
uint8 counter, bool notLooping); /// ok
void AddReflectionsToRequestedQueue(); /// ok (check value)
void AddReleasingSounds(); // todo (difficult)
void AddReleasingSounds(); /// ok (check)
void AddSampleToRequestedQueue(); /// ok
void AgeCrimes(); // todo
void AgeCrimes(); /// ok
void CalculateDistance(bool *ptr, float dist); /// ok
bool CheckForAnAudioFileOnCD() const; /// ok
void ClearActiveSamples(); /// ok
void ClearMissionAudio(); /// ok
void ClearRequestedQueue(); /// ok
int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
float speedMultiplier) const; /// ok
int32 ComputePan(float, CVector *); // todo
uint32 ComputeVolume(int emittingVolume, float soundIntensity, float distance) const; /// ok
float speedMultiplier) const; /// ok
int32 ComputePan(float, CVector *); /// ok
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; /// ok
int32 CreateEntity(int32 type, CPhysical *entity); /// ok
void DestroyAllGameCreatedEntities(); /// ok
@ -395,7 +541,7 @@ public:
uint8 GetCDAudioDriveLetter() const;
int8 GetCurrent3DProviderIndex() const; /// ok
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(uint32 a, float b) const; /// ok
float GetCollisionOneShotRatio(int32 a, float b) const; /// ok
float GetCollisionRatio(float a, float b, float c, float d) const; /// ok
float GetDistanceSquared(CVector *v) const; /// ok
int32 GetJumboTaxiFreq() const; /// ok
@ -404,15 +550,18 @@ public:
uint8 GetNum3DProvidersAvailable() const;
int32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const;
float GetVehicleDriveWheelSkidValue(uint8 a1, CAutomobile *a2, cTransmission *a3,
float a4); // todo
int32 GetVehicleNonDriveWheelSkidValue(float a1, int a2, int a3, int a4, float a5); // todo
float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
cTransmission *transmission,
float velocityChange); /// ok
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
cTransmission *transmission,
float velocityChange); /// ok
bool HasAirBrakes(int32 model) const; /// ok
void Initialise(); /// ok
void InitialisePoliceRadio(); // todo
void InitialisePoliceRadioZones(); // todo
void InitialisePoliceRadio(); /// ok
void InitialisePoliceRadioZones(); /// ok
void InterrogateAudioEntities(); /// ok
bool IsAudioInitialised() const; /// ok
bool IsMissionAudioSampleFinished(); /// ok
@ -421,15 +570,15 @@ public:
bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; /// ok
void PlayLoadedMissionAudio(); /// ok
void PlayOneShot(int32 index, int16 sound, float vol); // todo
uint32 PlaySuspectLastSeen(float x, float y, float z); // todo
void PlayOneShot(int32 index, int16 sound, float vol); /// ok
void PlaySuspectLastSeen(float x, float y, float z); /// ok
void PlayerJustGotInCar() const; /// ok
void PlayerJustLeftCar() const; /// ok
void PostInitialiseGameSpecificSetup(); /// ok
void PostTerminateGameSpecificShutdown(); /// ok
void PreInitialiseGameSpecificSetup() const;
void PreloadMissionAudio(char *); // todo
void PreTerminateGameSpecificShutdown(); /// ok
void PreInitialiseGameSpecificSetup() const; // ok
void PreloadMissionAudio(char *); // todo
void PreTerminateGameSpecificShutdown(); /// ok
/// processX - main logic of adding new sounds
void ProcessActiveQueues(); // todo
bool ProcessAirBrakes(cVehicleParams *params); /// ok
@ -464,7 +613,7 @@ public:
void ProcessLaunderetteScriptObject(uint8 sound); /// ok
void ProcessLoopingScriptObject(uint8 sound); /// ok
void ProcessMissionAudio(); /// ok
void ProcessModelCarEngine(cVehicleParams *params); /// ok (check float comparisons)
void ProcessModelCarEngine(cVehicleParams *params); /// ok
void ProcessOneShotScriptObject(uint8 sound); /// ok
void ProcessPed(CPhysical *ped); /// ok
void ProcessPedHeadphones(cPedParams *params); /// ok
@ -472,10 +621,10 @@ public:
void ProcessPhysical(int32 id); /// ok
void ProcessPlane(cVehicleParams *params); /// ok
void ProcessPlayersVehicleEngine(cVehicleParams *params,
CAutomobile *automobile); /// ok (check float comparisons)
void ProcessPoliceCellBeatingScriptObject(uint8 sound); // todo
CAutomobile *automobile); /// ok
void ProcessPoliceCellBeatingScriptObject(uint8 sound); /// ok
void ProcessPornCinema(uint8 sound); /// ok
void ProcessProjectiles(); // todo requires CProjectileInfo
void ProcessProjectiles(); /// ok
void ProcessRainOnVehicle(cVehicleParams *params); /// ok
void ProcessReverb() const; /// ok
bool ProcessReverseGear(cVehicleParams *a2); /// ok
@ -484,65 +633,71 @@ public:
void ProcessShopScriptObject(uint8 sound); /// ok
void ProcessSpecial(); /// ok
bool ProcessTrainNoise(cVehicleParams *params); /// ok
void ProcessVehicle(CVehicle *); // todo
void ProcessVehicle(CVehicle *vehicle); /// ok
bool ProcessVehicleDoors(cVehicleParams *params); /// ok
// bool ProcessVehicleEngine(void *);
// void ProcessVehicleHorn(cVehicleParams *params);
// void ProcessVehicleOneShots(void *);
bool ProcessVehicleEngine(cVehicleParams *params); // todo
void ProcessVehicleHorn(cVehicleParams *params); /// ok
void ProcessVehicleOneShots(void *); // todo
bool ProcessVehicleReverseWarning(cVehicleParams *params); /// ok
bool ProcessVehicleRoadNoise(cVehicleParams *params); /// ok
// void ProcessVehicleSirenOrAlarm(void *);
// void ProcessVehicleSkidding(void *);
void ProcessWaterCannon(int32); // todo
void ProcessWeather(int32 id); /// ok
bool ProcessWetRoadNoise(cVehicleParams *params); /// ok
void ProcessWorkShopScriptObject(uint8 sound); /// ok
void ProcessVehicleSirenOrAlarm(void *); // todo
void ProcessVehicleSkidding(cVehicleParams *params); /// ok
void ProcessWaterCannon(int32); /// ok
void ProcessWeather(int32 id); /// ok
bool ProcessWetRoadNoise(cVehicleParams *params); /// ok
void ProcessWorkShopScriptObject(uint8 sound); /// ok
int32 RandomDisplacement(uint32 seed) const;
void ReacquireDigitalHandle() const;
void ReleaseDigitalHandle() const;
int32 ReportCollision(CEntity *a2, CEntity *a3, uint8 a4, uint8 a5, float a6,
float a7); // todo
int32 ReportCrime(eCrimeType crime, const CVector *pos); // todo
void ResetAudioLogicTimers(int32 timer); /// ok
void ResetPoliceRadio(); /// ok
void ResetTimers(uint32 a2); // todo
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2,
float collisionPower, float intensity2); /// ok
void ReportCrime(int32 crime, const CVector *pos); /// ok
void ResetAudioLogicTimers(int32 timer); /// ok
void ResetPoliceRadio(); /// ok
void ResetTimers(uint32 time); /// ok
void Service(); // todo
void ServiceCollisions(); // todo
void ServicePoliceRadio(); // todo
void ServicePoliceRadioChannel(int a2); // todo
void ServiceSoundEffects(); // todo
int8 SetCurrent3DProvider(uint8); // todo
void Service(); /// ok
void ServiceCollisions(); // todo
void ServicePoliceRadio(); /// ok
void ServicePoliceRadioChannel(int32 wantedLevel); /// ok
void ServiceSoundEffects(); /// ok
int8 SetCurrent3DProvider(uint8 which); /// ok
void SetDynamicAcousticModelingStatus(bool status);
void SetEffectsFadeVolume(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
void SetEntityStatus(int32 id, bool status);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(int32); // todo
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(cAudioCollision *audioCollision); /// ok
void SetMissionAudioLocation(float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const;
void SetMonoMode(uint8); // todo
void SetMonoMode(uint8); // todo (mobile)
void SetMusicFadeVolume(uint8 volume) const;
void SetMusicMasterVolume(uint8 volume) const;
void SetSpeakerConfig(int32 conf) const;
void SetUpLoopingCollisionSound(int a2, int a3); // todo
void SetUpOneShotCollisionSound(int a2); // todo
void SetupCrimeReport(); // todo
bool SetupJumboEngineSound(uint8, int32); // todo
bool SetupJumboFlySound(uint8 emittingVol); /// ok
bool SetupJumboRumbleSound(uint8 emittingVol); /// ok
bool SetupJumboTaxiSound(uint8 vol); /// ok
bool SetupJumboWhineSound(uint8 emittingVol, int32 freq); /// ok
void SetupPedComments(cPedParams *params, uint32 sound); /// ok
void SetupSuspectLastSeenReport(); // todo
void SetUpLoopingCollisionSound(cAudioCollision *col, uint8 counter); /// ok
void SetUpOneShotCollisionSound(cAudioCollision *col); /// ok
bool SetupCrimeReport(); /// ok
bool SetupJumboEngineSound(uint8 a2, int32 a3); // todo
bool SetupJumboFlySound(uint8 emittingVol); /// ok
bool SetupJumboRumbleSound(uint8 emittingVol); /// ok
bool SetupJumboTaxiSound(uint8 vol); /// ok
bool SetupJumboWhineSound(uint8 emittingVol, int32 freq); /// ok
void SetupPedComments(cPedParams *params, uint32 sound); /// ok
void SetupSuspectLastSeenReport(); /// ok
void Terminate();
void TranslateEntity(CVector *v1, CVector *v2) const; /// ok
void TranslateEntity(CVector *v1, CVector *v2) const;
void UpdateGasPedalAudio(CAutomobile *automobile); // todo hook
void UpdateGasPedalAudio(CAutomobile *automobile);
void UpdateReflections(); // todo
bool UsesReverseWarning(int32 model) const;
bool UsesSiren(int32 model) const;
bool UsesSirenSwitching(int32 model) const;
// only used in pc
void AdjustSamplesVolume(); /// ok
int32 ComputeEmittingVolume(uint8 emittingVolume, float intensity,
float dist); /// ok
};
static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");

View File

@ -3047,130 +3047,3 @@ enum eAudioSamples : uint32 {
SAMPLEBANK_PED_MAX = AUDIO_SAMPLE_AMMUNATION_WELCOME_3+1,
};
enum eScriptSounds : int16
{
SCRIPT_SOUND_0 = 0,
SCRIPT_SOUND_1 = 1,
SCRIPT_SOUND_2 = 2,
SCRIPT_SOUND_3 = 3,
SCRIPT_SOUND_PARTY_1_LOOP_S = 4,
SCRIPT_SOUND_PARTY_1_LOOP_L = 5,
SCRIPT_SOUND_PARTY_2_LOOP_S = 6,
SCRIPT_SOUND_PARTY_2_LOOP_L = 7,
SCRIPT_SOUND_PARTY_3_LOOP_S = 8,
SCRIPT_SOUND_PARTY_3_LOOP_L = 9,
SCRIPT_SOUND_PARTY_4_LOOP_S = 10,
SCRIPT_SOUND_PARTY_4_LOOP_L = 11,
SCRIPT_SOUND_PARTY_5_LOOP_S = 12,
SCRIPT_SOUND_PARTY_5_LOOP_L = 13,
SCRIPT_SOUND_PARTY_6_LOOP_S = 14,
SCRIPT_SOUND_PARTY_6_LOOP_L = 15,
SCRIPT_SOUND_PARTY_7_LOOP_S = 16,
SCRIPT_SOUND_PARTY_7_LOOP_L = 17,
SCRIPT_SOUND_PARTY_8_LOOP_S = 18,
SCRIPT_SOUND_PARTY_8_LOOP_L = 19,
SCRIPT_SOUND_PARTY_9_LOOP_S = 20,
SCRIPT_SOUND_PARTY_9_LOOP_L = 21,
SCRIPT_SOUND_PARTY_10_LOOP_S = 22,
SCRIPT_SOUND_PARTY_10_LOOP_L = 23,
SCRIPT_SOUND_PARTY_11_LOOP_S = 24,
SCRIPT_SOUND_PARTY_11_LOOP_L = 25,
SCRIPT_SOUND_PARTY_12_LOOP_S = 26,
SCRIPT_SOUND_PARTY_12_LOOP_L = 27,
SCRIPT_SOUND_PARTY_13_LOOP_S = 28,
SCRIPT_SOUND_PARTY_13_LOOP_L = 29,
SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S = 30,
SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L = 31,
SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S = 32,
SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L = 33,
SCRIPT_SOUND_WORK_SHOP_LOOP_S = 34,
SCRIPT_SOUND_WORK_SHOP_LOOP_L = 35,
SCRIPT_SOUND_SAWMILL_LOOP_S = 36,
SCRIPT_SOUND_SAWMILL_LOOP_L = 37,
SCRIPT_SOUND_38 = 38,
SCRIPT_SOUND_39 = 39,
SCRIPT_SOUND_LAUNDERETTE_LOOP_S = 40,
SCRIPT_SOUND_LAUNDERETTE_LOOP_L = 41,
SCRIPT_SOUND_CHINATOWN_RESTAURANT_S = 42,
SCRIPT_SOUND_CHINATOWN_RESTAURANT_L = 43,
SCRIPT_SOUND_CIPRIANI_RESAURANT_S = 44,
SCRIPT_SOUND_CIPRIANI_RESAURANT_L = 45,
SCRIPT_SOUND_46 = 46,
SCRIPT_SOUND_47 = 47,
SCRIPT_SOUND_MARCO_BISTRO_S = 48,
SCRIPT_SOUND_MARCO_BISTRO_L = 49,
SCRIPT_SOUND_AIRPORT_LOOP_S = 50,
SCRIPT_SOUND_AIRPORT_LOOP_L = 51,
SCRIPT_SOUND_SHOP_LOOP_S = 52,
SCRIPT_SOUND_SHOP_LOOP_L = 53,
SCRIPT_SOUND_CINEMA_LOOP_S = 54,
SCRIPT_SOUND_CINEMA_LOOP_L = 55,
SCRIPT_SOUND_DOCKS_LOOP_S = 56,
SCRIPT_SOUND_DOCKS_LOOP_L = 57,
SCRIPT_SOUND_HOME_LOOP_S = 58,
SCRIPT_SOUND_HOME_LOOP_L = 59,
SCRIPT_SOUND_FRANKIE_PIANO = 60,
SCRIPT_SOUND_PARTY_1_LOOP = 61,
SCRIPT_SOUND_PORN_CINEMA_1_S = 62,
SCRIPT_SOUND_PORN_CINEMA_1_L = 63,
SCRIPT_SOUND_PORN_CINEMA_2_S = 64,
SCRIPT_SOUND_PORN_CINEMA_2_L = 65,
SCRIPT_SOUND_PORN_CINEMA_3_S = 66,
SCRIPT_SOUND_PORN_CINEMA_3_L = 67,
SCRIPT_SOUND_BANK_ALARM_LOOP_S = 68,
SCRIPT_SOUND_BANK_ALARM_LOOP_L = 69,
SCRIPT_SOUND_POLICE_BALL_LOOP_S = 70,
SCRIPT_SOUND_POLICE_BALL_LOOP_L = 71,
SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S = 72,
SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L = 73,
SCRIPT_SOUND_74 = 74,
SCRIPT_SOUND_75 = 75,
SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S = 76,
SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L = 77,
SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S = 78,
SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L = 79,
SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S = 80,
SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L = 81,
SCRIPT_SOUND_EVIDENCE_PICKUP = 82,
SCRIPT_SOUND_UNLOAD_GOLD = 83,
SCRIPT_SOUND_RAVE_1_LOOP_S = 84,
SCRIPT_SOUND_RAVE_1_LOOP_L = 85,
SCRIPT_SOUND_RAVE_2_LOOP_S = 86,
SCRIPT_SOUND_RAVE_2_LOOP_L = 87,
SCRIPT_SOUND_RAVE_3_LOOP_S = 88,
SCRIPT_SOUND_RAVE_3_LOOP_L = 89,
SCRIPT_SOUND_MISTY_SEX_S = 90,
SCRIPT_SOUND_MISTY_SEX_L = 91,
SCRIPT_SOUND_GATE_START_CLUNK = 92,
SCRIPT_SOUND_GATE_STOP_CLUNK = 93,
SCRIPT_SOUND_PART_MISSION_COMPLETE = 94,
SCRIPT_SOUND_CHUNKY_RUN_SHOUT = 95,
SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT = 96,
SCRIPT_SOUND_RACE_START_3 = 97,
SCRIPT_SOUND_RACE_START_2 = 98,
SCRIPT_SOUND_RACE_START_1 = 99,
SCRIPT_SOUND_RACE_START_GO = 100,
SCRIPT_SOUND_SWAT_PED_SHOUT = 101,
SCRIPT_SOUND_PRETEND_FIRE_LOOP = 102,
SCRIPT_SOUND_AMMUNATION_CHAT_1 = 103,
SCRIPT_SOUND_AMMUNATION_CHAT_2 = 104,
SCRIPT_SOUND_AMMUNATION_CHAT_3 = 105,
SCRIPT_SOUND_BULLET_HIT_GROUND_1 = 106,
SCRIPT_SOUND_BULLET_HIT_GROUND_2 = 107,
SCRIPT_SOUND_BULLET_HIT_GROUND_3 = 108,
SCRIPT_SOUND_109 = 109,
SCRIPT_SOUND_110 = 110,
SCRIPT_SOUND_111 = 111,
SCRIPT_SOUND_PAYPHONE_RINGING = 112,
SCRIPT_SOUND_113 = 113,
SCRIPT_SOUND_GLASS_BREAK_L = 114,
SCRIPT_SOUND_GLASS_BREAK_S = 115,
SCRIPT_SOUND_GLASS_CRACK = 116,
SCRIPT_SOUND_GLASS_LIGHT_BREAK = 117,
SCRIPT_SOUND_BOX_DESTROYED_1 = 118,
SCRIPT_SOUND_BOX_DESTROYED_2 = 119,
SCRIPT_SOUND_METAL_COLLISION = 120,
SCRIPT_SOUND_TIRE_COLLISION = 121,
SCRIPT_SOUND_GUNSHELL_DROP = 122,
SCRIPT_SOUND_GUNSHELL_DROP_SOFT = 123,
};

View File

@ -26,7 +26,7 @@ cDMAudio::Service(void)
}
int32
cDMAudio::CreateEntity(eAudioType type, void *UID)
cDMAudio::CreateEntity(int32 type, void *UID)
{
return AudioManager.CreateEntity(type, (CPhysical *)UID);
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "audio_enums.h"
#include "Wanted.h"
enum eSound : int16
@ -180,7 +181,6 @@ enum eSound : int16
class cAudioScriptObject;
class CEntity;
enum eCrimeType;
enum eAudioType;
class cDMAudio
{
@ -192,7 +192,7 @@ public:
void Terminate(void);
void Service(void);
int32 CreateEntity(eAudioType type, void *UID);
int32 CreateEntity(int32 type, void *UID);
void DestroyEntity(int32 audioEntity);
void SetEntityStatus(int32 audioEntity, uint8 status);
void PlayOneShot(int32 audioEntity, uint16 oneShot, float volume);

View File

@ -1,34 +1,33 @@
#include "common.h"
#include "patcher.h"
#include "MusicManager.h"
#include "Camera.h"
#include "Font.h"
#include "Hud.h"
#include "ModelIndices.h"
#include "Replay.h"
#include "Text.h"
#include "Timer.h"
#include "Camera.h"
#include "World.h"
#include "ModelIndices.h"
#include "sampman.h"
#include "Replay.h"
#include "patcher.h"
cMusicManager &MusicManager = *(cMusicManager*)0x8F3964;
int32 &gNumRetunePresses = *(int32*)0x650B80;
wchar *pCurrentStation = (wchar*)0x650B9C;
uint8 &cDisplay = *(uint8*)0x650BA1;
cMusicManager &MusicManager = *(cMusicManager *)0x8F3964;
int32 &gNumRetunePresses = *(int32 *)0x650B80;
wchar *pCurrentStation = (wchar *)0x650B9C;
uint8 &cDisplay = *(uint8 *)0x650BA1;
WRAPPER char* cMusicManager::Get3DProviderName(char) { EAXJMP(0x57A8C0); }
bool cMusicManager::PlayerInCar()
bool
cMusicManager::PlayerInCar()
{
if (!FindPlayerVehicle())
if(!FindPlayerVehicle())
return false;
else {
int32 State = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_nPedState;
if (State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
return false;
switch (FindPlayerVehicle()->m_modelIndex) {
switch(FindPlayerVehicle()->m_modelIndex) {
case MI_FIRETRUCK:
case MI_AMBULAN:
case MI_MRWHOOP:
@ -36,10 +35,8 @@ bool cMusicManager::PlayerInCar()
case MI_TRAIN:
case MI_SPEEDER:
case MI_REEFER:
case MI_GHOST:
return false;
default:
return true;
case MI_GHOST: return false;
default: return true;
}
}
}
@ -47,56 +44,56 @@ bool cMusicManager::PlayerInCar()
#if 0
WRAPPER void cMusicManager::DisplayRadioStationName(void) { EAXJMP(0x57E6D0); }
#else
void cMusicManager::DisplayRadioStationName()
void
cMusicManager::DisplayRadioStationName()
{
int8 pRetune;
int8 gStreamedSound;
int8 gRetuneCounter;
if (!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && cMusicManager::PlayerInCar() && !CReplay::IsPlayingBack()) {
if (MusicManager.m_bPlayerInCar && !MusicManager.m_bPreviousPlayerInCar)
if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && cMusicManager::PlayerInCar() &&
!CReplay::IsPlayingBack()) {
if(MusicManager.m_bPlayerInCar && !MusicManager.m_bPreviousPlayerInCar)
pCurrentStation = nil;
if (SampleManager.IsMP3RadioChannelAvailable()) {
if(SampleManager.IsMP3RadioChannelAvailable()) {
gStreamedSound = MusicManager.m_nCurrentStreamedSound;
if (gStreamedSound != STREAMED_SOUND_CITY_AMBIENT && gStreamedSound != STREAMED_SOUND_WATER_AMBIENT) {
if (gStreamedSound > STREAMED_SOUND_RADIO_MP3_PLAYER)
if(gStreamedSound == STREAMED_SOUND_CITY_AMBIENT ||
gStreamedSound == STREAMED_SOUND_WATER_AMBIENT) {
gStreamedSound = STREAMED_SOUND_RADIO_POLICE;
} else {
if(gStreamedSound >
STREAMED_SOUND_RADIO_MP3_PLAYER)
return;
}
else {
gStreamedSound = STREAMED_SOUND_RADIO_POLICE;
}
pRetune = gNumRetunePresses + gStreamedSound;
if (pRetune == POLICE_RADIO) {
if(pRetune == POLICE_RADIO) {
pRetune = RADIO_OFF;
}
else if (pRetune > POLICE_RADIO) {
} else if(pRetune > POLICE_RADIO) {
pRetune = pRetune - 11;
}
}
else {
} else {
gStreamedSound = MusicManager.m_nCurrentStreamedSound;
pRetune = gNumRetunePresses + gStreamedSound;
if (pRetune >= USERTRACK) {
if(pRetune >= USERTRACK) {
gRetuneCounter = gNumRetunePresses;
pRetune = MusicManager.m_nCurrentStreamedSound;
if (gStreamedSound == STREAMED_SOUND_WATER_AMBIENT)
if(gStreamedSound == STREAMED_SOUND_WATER_AMBIENT)
pRetune = RADIO_OFF;
while (gRetuneCounter) {
if (pRetune == RADIO_OFF) {
while(gRetuneCounter) {
if(pRetune == RADIO_OFF) {
pRetune = HEAD_RADIO;
}
else if (pRetune < USERTRACK) {
} else if(pRetune < USERTRACK) {
pRetune = pRetune + 1;
}
if (pRetune == USERTRACK)
pRetune = RADIO_OFF;
if(pRetune == USERTRACK) pRetune = RADIO_OFF;
--gRetuneCounter;
}
@ -105,52 +102,29 @@ void cMusicManager::DisplayRadioStationName()
wchar *string = nil;
switch (pRetune) {
case HEAD_RADIO:
string = TheText.Get("FEA_FM0");
break;
case DOUBLE_CLEF:
string = TheText.Get("FEA_FM1");
break;
case JAH_RADIO:
string = TheText.Get("FEA_FM2");
break;
case RISE_FM:
string = TheText.Get("FEA_FM3");
break;
case LIPS_106:
string = TheText.Get("FEA_FM4");
break;
case GAME_FM:
string = TheText.Get("FEA_FM5");
break;
case MSX_FM:
string = TheText.Get("FEA_FM6");
break;
case FLASHBACK:
string = TheText.Get("FEA_FM7");
break;
case CHATTERBOX:
string = TheText.Get("FEA_FM8");
break;
case USERTRACK:
string = TheText.Get("FEA_FM9");
break;
default:
return;
switch(pRetune) {
case HEAD_RADIO: string = TheText.Get("FEA_FM0"); break;
case DOUBLE_CLEF: string = TheText.Get("FEA_FM1"); break;
case JAH_RADIO: string = TheText.Get("FEA_FM2"); break;
case RISE_FM: string = TheText.Get("FEA_FM3"); break;
case LIPS_106: string = TheText.Get("FEA_FM4"); break;
case GAME_FM: string = TheText.Get("FEA_FM5"); break;
case MSX_FM: string = TheText.Get("FEA_FM6"); break;
case FLASHBACK: string = TheText.Get("FEA_FM7"); break;
case CHATTERBOX: string = TheText.Get("FEA_FM8"); break;
case USERTRACK: string = TheText.Get("FEA_FM9"); break;
default: return;
};
if (pRetune > CHATTERBOX && !SampleManager.IsMP3RadioChannelAvailable()) {
return;
}
if(pRetune > CHATTERBOX && !SampleManager.IsMP3RadioChannelAvailable()) { return; }
if (string && pCurrentStation != string || MusicManager.m_nCurrentStreamedSound == STREAMED_SOUND_RADIO_MP3_PLAYER && MusicManager.m_nPreviousStreamedSound != STREAMED_SOUND_RADIO_MP3_PLAYER) {
if(string && pCurrentStation != string ||
MusicManager.m_nCurrentStreamedSound == STREAMED_SOUND_RADIO_MP3_PLAYER &&
MusicManager.m_nPreviousStreamedSound != STREAMED_SOUND_RADIO_MP3_PLAYER) {
pCurrentStation = string;
cDisplay = 60;
}
else {
if (!cDisplay)
return;
} else {
if(!cDisplay) return;
--cDisplay;
}
@ -164,7 +138,7 @@ void cMusicManager::DisplayRadioStationName()
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), pCurrentStation);
if (gNumRetunePresses)
if(gNumRetunePresses)
CFont::SetColor(CRGBA(102, 133, 143, 255));
else
CFont::SetColor(CRGBA(147, 196, 211, 255));
@ -203,43 +177,67 @@ cMusicManager::StopFrontEndTrack()
EAXJMP(0x57E3D0);
}
WRAPPER void cMusicManager::PlayAnnouncement(unsigned char)
WRAPPER void
cMusicManager::PlayAnnouncement(uint8)
{
EAXJMP(0x57E430);
}
WRAPPER void cMusicManager::PlayFrontEndTrack(unsigned char, unsigned char)
WRAPPER void
cMusicManager::PlayFrontEndTrack(uint8, uint8)
{
EAXJMP(0x57E2E0);
}
WRAPPER void cMusicManager::PreloadCutSceneMusic(unsigned char)
WRAPPER void
cMusicManager::PreloadCutSceneMusic(uint8)
{
EAXJMP(0x57E210);
}
WRAPPER void cMusicManager::PlayPreloadedCutSceneMusic(void)
WRAPPER void
cMusicManager::PlayPreloadedCutSceneMusic(void)
{
EAXJMP(0x57E290);
}
WRAPPER void cMusicManager::StopCutSceneMusic(void)
WRAPPER void
cMusicManager::StopCutSceneMusic(void)
{
EAXJMP(0x57E2B0);
}
WRAPPER int32 cMusicManager::GetRadioInCar(void)
WRAPPER int32
cMusicManager::GetRadioInCar(void)
{
EAXJMP(0x57D1D0);
}
WRAPPER void cMusicManager::SetRadioInCar(unsigned int)
WRAPPER void
cMusicManager::SetRadioInCar(uint32)
{
EAXJMP(0x57D2C0);
}
WRAPPER void cMusicManager::SetRadioChannelByScript(unsigned char, int)
WRAPPER void
cMusicManager::SetRadioChannelByScript(uint8, int32)
{
EAXJMP(0x57D180);
}
}
WRAPPER
void
cMusicManager::ResetMusicAfterReload()
{
EAXJMP(0x57CF30);
}
WRAPPER
void cMusicManager::ResetTimers(int32) { EAXJMP(0x57D420); }
WRAPPER
void
cMusicManager::Service()
{
EAXJMP(0x57D440);
}

View File

@ -1,231 +1,6 @@
#pragma once
enum eRadioStation
{
HEAD_RADIO,
DOUBLE_CLEF,
JAH_RADIO,
RISE_FM,
LIPS_106,
GAME_FM,
MSX_FM,
FLASHBACK,
CHATTERBOX,
USERTRACK,
POLICE_RADIO,
RADIO_OFF,
};
enum eMusicMode
{
MUSICMODE_FRONTEND = 0,
MUSICMODE_GAME,
MUSICMODE_CUTSCENE,
MUSICMODE_OFF,
MUSICMODE_4,
};
enum eStreamedSounds
{
STREAMED_SOUND_RADIO_HEAD = 0,
STREAMED_SOUND_RADIO_CLASSIC = 1,
STREAMED_SOUND_RADIO_KJAH = 2,
STREAMED_SOUND_RADIO_RISE = 3,
STREAMED_SOUND_RADIO_LIPS = 4,
STREAMED_SOUND_RADIO_GAME = 5,
STREAMED_SOUND_RADIO_MSX = 6,
STREAMED_SOUND_RADIO_FLASH = 7,
STREAMED_SOUND_RADIO_CHAT = 8,
STREAMED_SOUND_RADIO_MP3_PLAYER = 9,
STREAMED_SOUND_RADIO_POLICE = 10,
STREAMED_SOUND_CITY_AMBIENT = 11,
STREAMED_SOUND_WATER_AMBIENT = 12,
STREAMED_SOUND_ANNOUNCE_COMMERCIAL_OPEN = 13,
STREAMED_SOUND_ANNOUNCE_SUBURBAN_OPEN = 14,
STREAMED_SOUND_NEWS_INTRO = 15,
STREAMED_SOUND_BANK_INTRO = 16,
STREAMED_SOUND_CUTSCENE_LUIGI1_LG = 17,
STREAMED_SOUND_CUTSCENE_LUIGI2_DSB = 18,
STREAMED_SOUND_CUTSCENE_LUIGI3_DM = 19,
STREAMED_SOUND_CUTSCENE_LUIGI4_PAP = 20,
STREAMED_SOUND_CUTSCENE_LUIGI5_TFB = 21,
STREAMED_SOUND_CUTSCENE_JOEY0_DM2 = 22,
STREAMED_SOUND_CUTSCENE_JOEY1_LFL = 23,
STREAMED_SOUND_CUTSCENE_JOEY2_KCL = 24,
STREAMED_SOUND_CUTSCENE_JOEY3_VH = 25,
STREAMED_SOUND_CUTSCENE_JOEY4_ETH = 26,
STREAMED_SOUND_CUTSCENE_JOEY5_DST = 27,
STREAMED_SOUND_CUTSCENE_JOEY6_TBJ = 28,
STREAMED_SOUND_CUTSCENE_TONI1_TOL = 29,
STREAMED_SOUND_CUTSCENE_TONI2_TPU = 30,
STREAMED_SOUND_CUTSCENE_TONI3_MAS = 31,
STREAMED_SOUND_CUTSCENE_TONI4_TAT = 32,
STREAMED_SOUND_CUTSCENE_TONI5_BF = 33,
STREAMED_SOUND_CUTSCENE_SAL0_MAS = 34,
STREAMED_SOUND_CUTSCENE_SAL1_PF = 35,
STREAMED_SOUND_CUTSCENE_SAL2_CTG = 36,
STREAMED_SOUND_CUTSCENE_SAL3_RTC = 37,
STREAMED_SOUND_CUTSCENE_SAL5_LRQ = 38,
STREAMED_SOUND_CUTSCENE_SAL4_BDBA = 39,
STREAMED_SOUND_CUTSCENE_SAL4_BDBB = 40,
STREAMED_SOUND_CUTSCENE_SAL2_CTG2 = 41,
STREAMED_SOUND_CUTSCENE_SAL4_BDBD = 42,
STREAMED_SOUND_CUTSCENE_SAL5_LRQB = 43,
STREAMED_SOUND_CUTSCENE_SAL5_LRQC = 44,
STREAMED_SOUND_CUTSCENE_ASUKA_1_SSO = 45,
STREAMED_SOUND_CUTSCENE_ASUKA_2_PP = 46,
STREAMED_SOUND_CUTSCENE_ASUKA_3_SS = 47,
STREAMED_SOUND_CUTSCENE_ASUKA_4_PDR = 48,
STREAMED_SOUND_CUTSCENE_ASUKA_5_K2FT = 49,
STREAMED_SOUND_CUTSCENE_KENJI1_KBO = 50,
STREAMED_SOUND_CUTSCENE_KENJI2_GIS = 51,
STREAMED_SOUND_CUTSCENE_KENJI3_DS = 52,
STREAMED_SOUND_CUTSCENE_KENJI4_SHI = 53,
STREAMED_SOUND_CUTSCENE_KENJI5_SD = 54,
STREAMED_SOUND_CUTSCENE_RAY0_PDR2 = 55,
STREAMED_SOUND_CUTSCENE_RAY1_SW = 56,
STREAMED_SOUND_CUTSCENE_RAY2_AP = 57,
STREAMED_SOUND_CUTSCENE_RAY3_ED = 58,
STREAMED_SOUND_CUTSCENE_RAY4_GF = 59,
STREAMED_SOUND_CUTSCENE_RAY5_PB = 60,
STREAMED_SOUND_CUTSCENE_RAY6_MM = 61,
STREAMED_SOUND_CUTSCENE_DONALD1_STOG = 62,
STREAMED_SOUND_CUTSCENE_DONALD2_KK = 63,
STREAMED_SOUND_CUTSCENE_DONALD3_ADO = 64,
STREAMED_SOUND_CUTSCENE_DONALD5_ES = 65,
STREAMED_SOUND_CUTSCENE_DONALD7_MLD = 66,
STREAMED_SOUND_CUTSCENE_DONALD4_GTA = 67,
STREAMED_SOUND_CUTSCENE_DONALD4_GTA2 = 68,
STREAMED_SOUND_CUTSCENE_DONALD6_STS = 69,
STREAMED_SOUND_CUTSCENE_ASUKA6_BAIT = 70,
STREAMED_SOUND_CUTSCENE_ASUKA7_ETG = 71,
STREAMED_SOUND_CUTSCENE_ASUKA8_PS = 72,
STREAMED_SOUND_CUTSCENE_ASUKA9_ASD = 73,
STREAMED_SOUND_CUTSCENE_KENJI4_SHI2 = 74,
STREAMED_SOUND_CUTSCENE_CATALINA1_TEX = 75,
STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 = 76,
STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 = 77,
STREAMED_SOUND_CUTSCENE_ELBURRO3_PH3 = 78,
STREAMED_SOUND_CUTSCENE_ELBURRO4_PH4 = 79,
STREAMED_SOUND_CUTSCENE_YARDIE_PH1 = 80,
STREAMED_SOUND_CUTSCENE_YARDIE_PH2 = 81,
STREAMED_SOUND_CUTSCENE_YARDIE_PH3 = 82,
STREAMED_SOUND_CUTSCENE_YARDIE_PH4 = 83,
STREAMED_SOUND_CUTSCENE_HOODS_PH1 = 84,
STREAMED_SOUND_CUTSCENE_HOODS_PH2 = 85,
STREAMED_SOUND_CUTSCENE_HOODS_PH3 = 86,
STREAMED_SOUND_CUTSCENE_HOODS_PH4 = 87,
STREAMED_SOUND_CUTSCENE_HOODS_PH5 = 88,
STREAMED_SOUND_CUTSCENE_MARTY_PH1 = 89,
STREAMED_SOUND_CUTSCENE_MARTY_PH2 = 90,
STREAMED_SOUND_CUTSCENE_MARTY_PH3 = 91,
STREAMED_SOUND_CUTSCENE_MARTY_PH4 = 92,
STREAMED_SOUND_MISSION_COMPLETED = 93,
STREAMED_SOUND_GAME_COMPLETED = 94,
STREAMED_SOUND_MISSION_LIB_A1 = 95,
STREAMED_SOUND_MISSION_LIB_A2 = 96,
STREAMED_SOUND_MISSION_LIB_A = 97,
STREAMED_SOUND_MISSION_LIB_B = 98,
STREAMED_SOUND_MISSION_LIB_C = 99,
STREAMED_SOUND_MISSION_LIB_D = 100,
STREAMED_SOUND_MISSION_L2_A = 101,
STREAMED_SOUND_MISSION_J4T_1 = 102,
STREAMED_SOUND_MISSION_J4T_2 = 103,
STREAMED_SOUND_MISSION_J4T_3 = 104,
STREAMED_SOUND_MISSION_J4T_4 = 105,
STREAMED_SOUND_MISSION_J4_A = 106,
STREAMED_SOUND_MISSION_J4_B = 107,
STREAMED_SOUND_MISSION_J4_C = 108,
STREAMED_SOUND_MISSION_J4_D = 109,
STREAMED_SOUND_MISSION_J4_E = 110,
STREAMED_SOUND_MISSION_J4_F = 111,
STREAMED_SOUND_MISSION_J6_1 = 112,
STREAMED_SOUND_MISSION_J6_A = 113,
STREAMED_SOUND_MISSION_J6_B = 114,
STREAMED_SOUND_MISSION_J6_C = 115,
STREAMED_SOUND_MISSION_J6_D = 116,
STREAMED_SOUND_MISSION_T4_A = 117,
STREAMED_SOUND_MISSION_S1_A = 118,
STREAMED_SOUND_MISSION_S1_A1 = 119,
STREAMED_SOUND_MISSION_S1_B = 120,
STREAMED_SOUND_MISSION_S1_C = 121,
STREAMED_SOUND_MISSION_S1_C1 = 122,
STREAMED_SOUND_MISSION_S1_D = 123,
STREAMED_SOUND_MISSION_S1_E = 124,
STREAMED_SOUND_MISSION_S1_F = 125,
STREAMED_SOUND_MISSION_S1_G = 126,
STREAMED_SOUND_MISSION_S1_H = 127,
STREAMED_SOUND_MISSION_S1_I = 128,
STREAMED_SOUND_MISSION_S1_J = 129,
STREAMED_SOUND_MISSION_S1_K = 130,
STREAMED_SOUND_MISSION_S1_L = 131,
STREAMED_SOUND_MISSION_S3_A = 132,
STREAMED_SOUND_MISSION_S3_B = 133,
STREAMED_SOUND_MISSION_EL3_A = 134,
STREAMED_SOUND_MISSION_MF1_A = 135,
STREAMED_SOUND_MISSION_MF2_A = 136,
STREAMED_SOUND_MISSION_MF3_A = 137,
STREAMED_SOUND_MISSION_MF3_B = 138,
STREAMED_SOUND_MISSION_MF3_B1 = 139,
STREAMED_SOUND_MISSION_MF3_C = 140,
STREAMED_SOUND_MISSION_MF4_A = 141,
STREAMED_SOUND_MISSION_MF4_B = 142,
STREAMED_SOUND_MISSION_MF4_C = 143,
STREAMED_SOUND_MISSION_A1_A = 144,
STREAMED_SOUND_MISSION_A3_A = 145,
STREAMED_SOUND_MISSION_A5_A = 146,
STREAMED_SOUND_MISSION_A4_A = 147,
STREAMED_SOUND_MISSION_A4_B = 148,
STREAMED_SOUND_MISSION_A4_C = 149,
STREAMED_SOUND_MISSION_A4_D = 150,
STREAMED_SOUND_MISSION_K1_A = 151,
STREAMED_SOUND_MISSION_K3_A = 152,
STREAMED_SOUND_MISSION_R1_A = 153,
STREAMED_SOUND_MISSION_R2_A = 154,
STREAMED_SOUND_MISSION_R2_B = 155,
STREAMED_SOUND_MISSION_R2_C = 156,
STREAMED_SOUND_MISSION_R2_D = 157,
STREAMED_SOUND_MISSION_R2_E = 158,
STREAMED_SOUND_MISSION_R2_F = 159,
STREAMED_SOUND_MISSION_R2_G = 160,
STREAMED_SOUND_MISSION_R2_H = 161,
STREAMED_SOUND_MISSION_R5_A = 162,
STREAMED_SOUND_MISSION_R6_A = 163,
STREAMED_SOUND_MISSION_R6_A1 = 164,
STREAMED_SOUND_MISSION_R6_B = 165,
STREAMED_SOUND_MISSION_LO2_A = 166,
STREAMED_SOUND_MISSION_LO6_A = 167,
STREAMED_SOUND_MISSION_YD2_A = 168,
STREAMED_SOUND_MISSION_YD2_B = 169,
STREAMED_SOUND_MISSION_YD2_C = 170,
STREAMED_SOUND_MISSION_YD2_C1 = 171,
STREAMED_SOUND_MISSION_YD2_D = 172,
STREAMED_SOUND_MISSION_YD2_E = 173,
STREAMED_SOUND_MISSION_YD2_F = 174,
STREAMED_SOUND_MISSION_YD2_G = 175,
STREAMED_SOUND_MISSION_YD2_H = 176,
STREAMED_SOUND_MISSION_YD2_ASS = 177,
STREAMED_SOUND_MISSION_YD2_OK = 178,
STREAMED_SOUND_MISSION_H5_A = 179,
STREAMED_SOUND_MISSION_H5_B = 180,
STREAMED_SOUND_MISSION_H5_C = 181,
STREAMED_SOUND_MISSION_AMMU_A = 182,
STREAMED_SOUND_MISSION_AMMU_B = 183,
STREAMED_SOUND_MISSION_AMMU_C = 184,
STREAMED_SOUND_MISSION_DOOR_1 = 185,
STREAMED_SOUND_MISSION_DOOR_2 = 186,
STREAMED_SOUND_MISSION_DOOR_3 = 187,
STREAMED_SOUND_MISSION_DOOR_4 = 188,
STREAMED_SOUND_MISSION_DOOR_5 = 189,
STREAMED_SOUND_MISSION_DOOR_6 = 190,
STREAMED_SOUND_MISSION_T3_A = 191,
STREAMED_SOUND_MISSION_T3_B = 192,
STREAMED_SOUND_MISSION_T3_C = 193,
STREAMED_SOUND_MISSION_K1_B = 194,
STREAMED_SOUND_MISSION_CAT1 = 195,
TOTAL_STREAMED_SOUNDS = 196,
NO_STREAMED_SOUND = 197,
};
#include "audio_enums.h"
class tMP3Sample
{
@ -250,7 +25,7 @@ public:
bool m_bPreviousPlayerInCar;
bool m_bPlayerInCar;
bool m_bAnnouncementInProgress;
tMP3Sample m_asMP3Samples[196];
tMP3Sample m_asMP3Samples[TOTAL_STREAMED_SOUNDS];
uint8 field_2364;
uint8 field_2365;
uint8 field_2366;
@ -283,18 +58,22 @@ public:
void ChangeMusicMode(int32 mode);
void StopFrontEndTrack();
char *Get3DProviderName(char);
bool PlayerInCar();
void DisplayRadioStationName();
void PlayAnnouncement(unsigned char);
void PlayFrontEndTrack(unsigned char, unsigned char);
void PreloadCutSceneMusic(unsigned char);
void PlayAnnouncement(uint8);
void PlayFrontEndTrack(uint8, uint8);
void PreloadCutSceneMusic(uint8);
void PlayPreloadedCutSceneMusic(void);
void StopCutSceneMusic(void);
int32 GetRadioInCar(void);
void SetRadioInCar(unsigned int);
void SetRadioChannelByScript(unsigned char, int);
void SetRadioInCar(uint32);
void SetRadioChannelByScript(uint8, int32);
void ResetMusicAfterReload();
void ResetTimers(int32);
void Service();
};
static_assert(sizeof(cMusicManager) == 0x95C, "cMusicManager: error");

228
src/audio/audio_enums.h Normal file
View File

@ -0,0 +1,228 @@
#pragma once
enum eRadioStation
{
HEAD_RADIO,
DOUBLE_CLEF,
JAH_RADIO,
RISE_FM,
LIPS_106,
GAME_FM,
MSX_FM,
FLASHBACK,
CHATTERBOX,
USERTRACK,
POLICE_RADIO,
RADIO_OFF,
};
enum eMusicMode
{
MUSICMODE_FRONTEND = 0,
MUSICMODE_GAME,
MUSICMODE_CUTSCENE,
MUSICMODE_OFF,
MUSICMODE_4,
};
enum eStreamedSounds
{
STREAMED_SOUND_RADIO_HEAD = 0,
STREAMED_SOUND_RADIO_CLASSIC = 1,
STREAMED_SOUND_RADIO_KJAH = 2,
STREAMED_SOUND_RADIO_RISE = 3,
STREAMED_SOUND_RADIO_LIPS = 4,
STREAMED_SOUND_RADIO_GAME = 5,
STREAMED_SOUND_RADIO_MSX = 6,
STREAMED_SOUND_RADIO_FLASH = 7,
STREAMED_SOUND_RADIO_CHAT = 8,
STREAMED_SOUND_RADIO_MP3_PLAYER = 9,
STREAMED_SOUND_RADIO_POLICE = 10,
STREAMED_SOUND_CITY_AMBIENT = 11,
STREAMED_SOUND_WATER_AMBIENT = 12,
STREAMED_SOUND_ANNOUNCE_COMMERCIAL_OPEN = 13,
STREAMED_SOUND_ANNOUNCE_SUBURBAN_OPEN = 14,
STREAMED_SOUND_NEWS_INTRO = 15,
STREAMED_SOUND_BANK_INTRO = 16,
STREAMED_SOUND_CUTSCENE_LUIGI1_LG = 17,
STREAMED_SOUND_CUTSCENE_LUIGI2_DSB = 18,
STREAMED_SOUND_CUTSCENE_LUIGI3_DM = 19,
STREAMED_SOUND_CUTSCENE_LUIGI4_PAP = 20,
STREAMED_SOUND_CUTSCENE_LUIGI5_TFB = 21,
STREAMED_SOUND_CUTSCENE_JOEY0_DM2 = 22,
STREAMED_SOUND_CUTSCENE_JOEY1_LFL = 23,
STREAMED_SOUND_CUTSCENE_JOEY2_KCL = 24,
STREAMED_SOUND_CUTSCENE_JOEY3_VH = 25,
STREAMED_SOUND_CUTSCENE_JOEY4_ETH = 26,
STREAMED_SOUND_CUTSCENE_JOEY5_DST = 27,
STREAMED_SOUND_CUTSCENE_JOEY6_TBJ = 28,
STREAMED_SOUND_CUTSCENE_TONI1_TOL = 29,
STREAMED_SOUND_CUTSCENE_TONI2_TPU = 30,
STREAMED_SOUND_CUTSCENE_TONI3_MAS = 31,
STREAMED_SOUND_CUTSCENE_TONI4_TAT = 32,
STREAMED_SOUND_CUTSCENE_TONI5_BF = 33,
STREAMED_SOUND_CUTSCENE_SAL0_MAS = 34,
STREAMED_SOUND_CUTSCENE_SAL1_PF = 35,
STREAMED_SOUND_CUTSCENE_SAL2_CTG = 36,
STREAMED_SOUND_CUTSCENE_SAL3_RTC = 37,
STREAMED_SOUND_CUTSCENE_SAL5_LRQ = 38,
STREAMED_SOUND_CUTSCENE_SAL4_BDBA = 39,
STREAMED_SOUND_CUTSCENE_SAL4_BDBB = 40,
STREAMED_SOUND_CUTSCENE_SAL2_CTG2 = 41,
STREAMED_SOUND_CUTSCENE_SAL4_BDBD = 42,
STREAMED_SOUND_CUTSCENE_SAL5_LRQB = 43,
STREAMED_SOUND_CUTSCENE_SAL5_LRQC = 44,
STREAMED_SOUND_CUTSCENE_ASUKA_1_SSO = 45,
STREAMED_SOUND_CUTSCENE_ASUKA_2_PP = 46,
STREAMED_SOUND_CUTSCENE_ASUKA_3_SS = 47,
STREAMED_SOUND_CUTSCENE_ASUKA_4_PDR = 48,
STREAMED_SOUND_CUTSCENE_ASUKA_5_K2FT = 49,
STREAMED_SOUND_CUTSCENE_KENJI1_KBO = 50,
STREAMED_SOUND_CUTSCENE_KENJI2_GIS = 51,
STREAMED_SOUND_CUTSCENE_KENJI3_DS = 52,
STREAMED_SOUND_CUTSCENE_KENJI4_SHI = 53,
STREAMED_SOUND_CUTSCENE_KENJI5_SD = 54,
STREAMED_SOUND_CUTSCENE_RAY0_PDR2 = 55,
STREAMED_SOUND_CUTSCENE_RAY1_SW = 56,
STREAMED_SOUND_CUTSCENE_RAY2_AP = 57,
STREAMED_SOUND_CUTSCENE_RAY3_ED = 58,
STREAMED_SOUND_CUTSCENE_RAY4_GF = 59,
STREAMED_SOUND_CUTSCENE_RAY5_PB = 60,
STREAMED_SOUND_CUTSCENE_RAY6_MM = 61,
STREAMED_SOUND_CUTSCENE_DONALD1_STOG = 62,
STREAMED_SOUND_CUTSCENE_DONALD2_KK = 63,
STREAMED_SOUND_CUTSCENE_DONALD3_ADO = 64,
STREAMED_SOUND_CUTSCENE_DONALD5_ES = 65,
STREAMED_SOUND_CUTSCENE_DONALD7_MLD = 66,
STREAMED_SOUND_CUTSCENE_DONALD4_GTA = 67,
STREAMED_SOUND_CUTSCENE_DONALD4_GTA2 = 68,
STREAMED_SOUND_CUTSCENE_DONALD6_STS = 69,
STREAMED_SOUND_CUTSCENE_ASUKA6_BAIT = 70,
STREAMED_SOUND_CUTSCENE_ASUKA7_ETG = 71,
STREAMED_SOUND_CUTSCENE_ASUKA8_PS = 72,
STREAMED_SOUND_CUTSCENE_ASUKA9_ASD = 73,
STREAMED_SOUND_CUTSCENE_KENJI4_SHI2 = 74,
STREAMED_SOUND_CUTSCENE_CATALINA1_TEX = 75,
STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 = 76,
STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 = 77,
STREAMED_SOUND_CUTSCENE_ELBURRO3_PH3 = 78,
STREAMED_SOUND_CUTSCENE_ELBURRO4_PH4 = 79,
STREAMED_SOUND_CUTSCENE_YARDIE_PH1 = 80,
STREAMED_SOUND_CUTSCENE_YARDIE_PH2 = 81,
STREAMED_SOUND_CUTSCENE_YARDIE_PH3 = 82,
STREAMED_SOUND_CUTSCENE_YARDIE_PH4 = 83,
STREAMED_SOUND_CUTSCENE_HOODS_PH1 = 84,
STREAMED_SOUND_CUTSCENE_HOODS_PH2 = 85,
STREAMED_SOUND_CUTSCENE_HOODS_PH3 = 86,
STREAMED_SOUND_CUTSCENE_HOODS_PH4 = 87,
STREAMED_SOUND_CUTSCENE_HOODS_PH5 = 88,
STREAMED_SOUND_CUTSCENE_MARTY_PH1 = 89,
STREAMED_SOUND_CUTSCENE_MARTY_PH2 = 90,
STREAMED_SOUND_CUTSCENE_MARTY_PH3 = 91,
STREAMED_SOUND_CUTSCENE_MARTY_PH4 = 92,
STREAMED_SOUND_MISSION_COMPLETED = 93,
STREAMED_SOUND_GAME_COMPLETED = 94,
STREAMED_SOUND_MISSION_LIB_A1 = 95,
STREAMED_SOUND_MISSION_LIB_A2 = 96,
STREAMED_SOUND_MISSION_LIB_A = 97,
STREAMED_SOUND_MISSION_LIB_B = 98,
STREAMED_SOUND_MISSION_LIB_C = 99,
STREAMED_SOUND_MISSION_LIB_D = 100,
STREAMED_SOUND_MISSION_L2_A = 101,
STREAMED_SOUND_MISSION_J4T_1 = 102,
STREAMED_SOUND_MISSION_J4T_2 = 103,
STREAMED_SOUND_MISSION_J4T_3 = 104,
STREAMED_SOUND_MISSION_J4T_4 = 105,
STREAMED_SOUND_MISSION_J4_A = 106,
STREAMED_SOUND_MISSION_J4_B = 107,
STREAMED_SOUND_MISSION_J4_C = 108,
STREAMED_SOUND_MISSION_J4_D = 109,
STREAMED_SOUND_MISSION_J4_E = 110,
STREAMED_SOUND_MISSION_J4_F = 111,
STREAMED_SOUND_MISSION_J6_1 = 112,
STREAMED_SOUND_MISSION_J6_A = 113,
STREAMED_SOUND_MISSION_J6_B = 114,
STREAMED_SOUND_MISSION_J6_C = 115,
STREAMED_SOUND_MISSION_J6_D = 116,
STREAMED_SOUND_MISSION_T4_A = 117,
STREAMED_SOUND_MISSION_S1_A = 118,
STREAMED_SOUND_MISSION_S1_A1 = 119,
STREAMED_SOUND_MISSION_S1_B = 120,
STREAMED_SOUND_MISSION_S1_C = 121,
STREAMED_SOUND_MISSION_S1_C1 = 122,
STREAMED_SOUND_MISSION_S1_D = 123,
STREAMED_SOUND_MISSION_S1_E = 124,
STREAMED_SOUND_MISSION_S1_F = 125,
STREAMED_SOUND_MISSION_S1_G = 126,
STREAMED_SOUND_MISSION_S1_H = 127,
STREAMED_SOUND_MISSION_S1_I = 128,
STREAMED_SOUND_MISSION_S1_J = 129,
STREAMED_SOUND_MISSION_S1_K = 130,
STREAMED_SOUND_MISSION_S1_L = 131,
STREAMED_SOUND_MISSION_S3_A = 132,
STREAMED_SOUND_MISSION_S3_B = 133,
STREAMED_SOUND_MISSION_EL3_A = 134,
STREAMED_SOUND_MISSION_MF1_A = 135,
STREAMED_SOUND_MISSION_MF2_A = 136,
STREAMED_SOUND_MISSION_MF3_A = 137,
STREAMED_SOUND_MISSION_MF3_B = 138,
STREAMED_SOUND_MISSION_MF3_B1 = 139,
STREAMED_SOUND_MISSION_MF3_C = 140,
STREAMED_SOUND_MISSION_MF4_A = 141,
STREAMED_SOUND_MISSION_MF4_B = 142,
STREAMED_SOUND_MISSION_MF4_C = 143,
STREAMED_SOUND_MISSION_A1_A = 144,
STREAMED_SOUND_MISSION_A3_A = 145,
STREAMED_SOUND_MISSION_A5_A = 146,
STREAMED_SOUND_MISSION_A4_A = 147,
STREAMED_SOUND_MISSION_A4_B = 148,
STREAMED_SOUND_MISSION_A4_C = 149,
STREAMED_SOUND_MISSION_A4_D = 150,
STREAMED_SOUND_MISSION_K1_A = 151,
STREAMED_SOUND_MISSION_K3_A = 152,
STREAMED_SOUND_MISSION_R1_A = 153,
STREAMED_SOUND_MISSION_R2_A = 154,
STREAMED_SOUND_MISSION_R2_B = 155,
STREAMED_SOUND_MISSION_R2_C = 156,
STREAMED_SOUND_MISSION_R2_D = 157,
STREAMED_SOUND_MISSION_R2_E = 158,
STREAMED_SOUND_MISSION_R2_F = 159,
STREAMED_SOUND_MISSION_R2_G = 160,
STREAMED_SOUND_MISSION_R2_H = 161,
STREAMED_SOUND_MISSION_R5_A = 162,
STREAMED_SOUND_MISSION_R6_A = 163,
STREAMED_SOUND_MISSION_R6_A1 = 164,
STREAMED_SOUND_MISSION_R6_B = 165,
STREAMED_SOUND_MISSION_LO2_A = 166,
STREAMED_SOUND_MISSION_LO6_A = 167,
STREAMED_SOUND_MISSION_YD2_A = 168,
STREAMED_SOUND_MISSION_YD2_B = 169,
STREAMED_SOUND_MISSION_YD2_C = 170,
STREAMED_SOUND_MISSION_YD2_C1 = 171,
STREAMED_SOUND_MISSION_YD2_D = 172,
STREAMED_SOUND_MISSION_YD2_E = 173,
STREAMED_SOUND_MISSION_YD2_F = 174,
STREAMED_SOUND_MISSION_YD2_G = 175,
STREAMED_SOUND_MISSION_YD2_H = 176,
STREAMED_SOUND_MISSION_YD2_ASS = 177,
STREAMED_SOUND_MISSION_YD2_OK = 178,
STREAMED_SOUND_MISSION_H5_A = 179,
STREAMED_SOUND_MISSION_H5_B = 180,
STREAMED_SOUND_MISSION_H5_C = 181,
STREAMED_SOUND_MISSION_AMMU_A = 182,
STREAMED_SOUND_MISSION_AMMU_B = 183,
STREAMED_SOUND_MISSION_AMMU_C = 184,
STREAMED_SOUND_MISSION_DOOR_1 = 185,
STREAMED_SOUND_MISSION_DOOR_2 = 186,
STREAMED_SOUND_MISSION_DOOR_3 = 187,
STREAMED_SOUND_MISSION_DOOR_4 = 188,
STREAMED_SOUND_MISSION_DOOR_5 = 189,
STREAMED_SOUND_MISSION_DOOR_6 = 190,
STREAMED_SOUND_MISSION_T3_A = 191,
STREAMED_SOUND_MISSION_T3_B = 192,
STREAMED_SOUND_MISSION_T3_C = 193,
STREAMED_SOUND_MISSION_K1_B = 194,
STREAMED_SOUND_MISSION_CAT1 = 195,
TOTAL_STREAMED_SOUNDS = 196,
NO_STREAMED_SOUND = 197,
};

View File

@ -6,6 +6,8 @@
CAccidentManager& gAccidentManager = *(CAccidentManager*)0x87FD10;
WRAPPER void CAccidentManager::Update(void) { EAXJMP(0x456710); }
uint16 CAccidentManager::CountActiveAccidents()
{
uint16 accidents = 0;

View File

@ -22,6 +22,7 @@ class CAccidentManager
public:
uint16 CountActiveAccidents();
CAccident* FindNearestAccident(CVector, float*);
void Update(void);
};
extern CAccidentManager& gAccidentManager;

View File

@ -123,8 +123,7 @@ void CBridge::FindBridgeEntities()
pLiftRoad = nil;
pLiftPart = nil;
for (int i = 1; i < CPools::GetBuildingPool()->GetSize(); ++i)
{
for (int i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--) {
CBuilding* entry = CPools::GetBuildingPool()->GetSlot(i);
if (entry)
{

View File

@ -588,7 +588,7 @@ void CCarAI::MakeWayForCarWithSiren(CVehicle *pVehicle)
CVector2D forward = pVehicle->GetMoveSpeed() / flatSpeed;
float projection = flatSpeed * 45 + 20;
int i = CPools::GetVehiclePool()->GetSize();
while (i--) {
while (--i >= 0) {
CVehicle* vehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!vehicle)
continue;

View File

@ -648,8 +648,7 @@ CCarCtrl::AddToCarArray(int32 id, int32 vehclass)
void
CCarCtrl::RemoveDistantCars()
{
uint32 i = CPools::GetVehiclePool()->GetSize();
while (--i){
for (int i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle)
continue;
@ -733,8 +732,7 @@ int32
CCarCtrl::CountCarsOfType(int32 mi)
{
int32 total = 0;
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--){
for (int i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle)
continue;

View File

@ -5,4 +5,6 @@
WRAPPER bool CCranes::IsThisCarBeingTargettedByAnyCrane(CVehicle*) { EAXJMP(0x5451E0); }
WRAPPER bool CCranes::IsThisCarBeingCarriedByAnyCrane(CVehicle*) { EAXJMP(0x545190); }
WRAPPER void CCranes::ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float) { EAXJMP(0x543650); }
WRAPPER void CCranes::DeActivateCrane(float, float) { EAXJMP(0x543890); }
WRAPPER void CCranes::DeActivateCrane(float, float) { EAXJMP(0x543890); }
WRAPPER void CCranes::InitCranes(void) { EAXJMP(0x543360); }
WRAPPER void CCranes::UpdateCranes(void) { EAXJMP(0x5439E0); }

View File

@ -10,4 +10,6 @@ public:
static bool IsThisCarBeingCarriedByAnyCrane(CVehicle*);
static void ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float);
static void DeActivateCrane(float, float);
static void InitCranes(void);
static void UpdateCranes(void);
};

View File

@ -30,7 +30,7 @@ CGameLogic::InitAtStartOfGame()
void
CGameLogic::PassTime(uint32 time)
{
uint8 minutes, hours, days;
int32 minutes, hours, days;
minutes = time + CClock::GetMinutes();
hours = CClock::GetHours();

View File

@ -25,6 +25,9 @@ bool &CGarages::PlayerInGarage = *(bool *)0x95CD83;
int32 &CGarages::PoliceCarsCollected = *(int32 *)0x941444;
uint32 &CGarages::GarageToBeTidied = *(uint32 *)0x623570;
WRAPPER void CGarages::Init(void) { EAXJMP(0x421C60); }
WRAPPER void CGarages::Update(void) { EAXJMP(0x421E40); }
bool
CGarages::IsModelIndexADoor(uint32 id)
{
@ -119,4 +122,4 @@ void CGarages::PrintMessages()
}
}
}
#endif
#endif

View File

@ -30,6 +30,8 @@ public:
static bool IsPointWithinHideOutGarage(CVector&);
static bool IsPointWithinAnyGarage(CVector&);
static void PlayerArrestedOrDied();
static void Init(void);
static void Update(void);
static int16 AddOne(float, float, float, float, float, float, uint8, uint32);
static void SetTargetCarForMissonGarage(int16, CVehicle*);
static bool HasCarBeenDroppedOffYet(int16);

View File

@ -15,6 +15,8 @@ CPhone *&CPhoneInfo::pickedUpPhone = *(CPhone**)0x6283B0;
bool &CPhoneInfo::isPhoneBeingPickedUp = *(bool*)0x6283B4;
CPed *&CPhoneInfo::pedWhoPickingUpPhone = *(CPed**)0x6283B8;
WRAPPER void CPhoneInfo::Update(void) { EAXJMP(0x42F7A0); }
int
CPhoneInfo::FindNearestFreePhone(CVector *pos)
{
@ -151,8 +153,8 @@ CPhoneInfo::Initialise(void)
pickedUpPhone = nil;
m_nMax = 0;
m_nNum = 0;
for (int v5 = pool->GetSize() - 1; v5 >= 0; v5--) {
CBuilding *building = pool->GetSlot(v5);
for (int i = pool->GetSize() - 1; i >= 0; i--) {
CBuilding *building = pool->GetSlot(i);
if (building) {
if (building->m_modelIndex == MI_PHONEBOOTH1) {
CPhone *maxPhone = &m_aPhones[m_nMax];

View File

@ -56,6 +56,7 @@ public:
int GrabPhone(float, float);
void Initialise(void);
void Shutdown(void);
void Update(void);
};
extern CPhoneInfo &gPhoneInfo;

View File

@ -47,6 +47,7 @@ uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 25
float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f };
WRAPPER void CPacManPickups::Render(void) { EAXJMP(0x432F60); }
WRAPPER void CPacManPickups::Update(void) { EAXJMP(0x432800); }
void
@ -296,7 +297,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
m_pObject->UpdateRwFrame();
bool touched = false;
for (int32 i = CPools::GetVehiclePool()->GetSize(); i > 0; i--) { // TODO: check if i > 0 is not a R* mistake
for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i);
if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
touched = true;
@ -323,7 +324,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
if (CTimer::GetTimeInMilliseconds() > m_nTimer)
explode = true;
else {// added else here since vehicle lookup is useless
for (int32 i = CPools::GetVehiclePool()->GetSize(); i > 0; i--) { // TODO: check if i > 0 is not a R* mistake
for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i);
if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
explode = true;

View File

@ -106,4 +106,5 @@ class CPacManPickups
{
public:
static void Render(void);
static void Update(void);
};

View File

@ -11,15 +11,74 @@ int32 &CPopulation::m_AllRandomPedsThisType = *(int32*)0x5FA570;
float &CPopulation::PedDensityMultiplier = *(float*)0x5FA56C;
uint32 &CPopulation::ms_nTotalMissionPeds = *(uint32*)0x8F5F70;
int32 &CPopulation::MaxNumberOfPedsInUse = *(int32*)0x5FA574;
uint32& CPopulation::ms_nNumCivMale = *(uint32*)0x8F2548;
uint32& CPopulation::ms_nNumCivFemale = *(uint32*)0x8F5F44;
uint32& CPopulation::ms_nNumCop = *(uint32*)0x885AFC;
bool& CPopulation::bZoneChangeHasHappened = *(bool*)0x95CD79;
uint32& CPopulation::ms_nNumEmergency = *(uint32*)0x94071C;
uint32& CPopulation::m_CountDownToPedsAtStart = *(uint32*)0x95CD4F;
uint32& CPopulation::ms_nNumGang1 = *(uint32*)0x8F1B1C;
uint32& CPopulation::ms_nNumGang2 = *(uint32*)0x8F1B14;
uint32& CPopulation::ms_nTotalPeds = *(uint32*)0x95CB50;
uint32& CPopulation::ms_nNumGang3 = *(uint32*)0x8F2548;
uint32& CPopulation::ms_nTotalGangPeds = *(uint32*)0x885AF0;
uint32& CPopulation::ms_nNumGang4 = *(uint32*)0x8F1B2C;
uint32& CPopulation::ms_nTotalCivPeds = *(uint32*)0x8F2C3C;
uint32& CPopulation::ms_nNumGang5 = *(uint32*)0x8F1B30;
uint32& CPopulation::ms_nNumDummy = *(uint32*)0x8F1A98;
uint32& CPopulation::ms_nNumGang6 = *(uint32*)0x8F1B20;
uint32& CPopulation::ms_nNumGang9 = *(uint32*)0x8F1B10;
uint32& CPopulation::ms_nNumGang7 = *(uint32*)0x8F1B28;
uint32& CPopulation::ms_nNumGang8 = *(uint32*)0x8F1B0C;
WRAPPER void CPopulation::Update(void) { EAXJMP(0x4F39A0); }
WRAPPER void CPopulation::LoadPedGroups() { EAXJMP(0x4F3870); }
WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); }
WRAPPER void CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool) { EAXJMP(0x4F6200); }
WRAPPER CPed *CPopulation::AddPedInCar(CVehicle *vehicle) { EAXJMP(0x4F5800); }
WRAPPER bool CPopulation::IsPointInSafeZone(CVector *coors) { EAXJMP(0x4F60C0); }
void
CPopulation::Initialise()
{
debug("Initialising CPopulation...\n");
ms_nNumCivMale = 0;
m_AllRandomPedsThisType = -1;
ms_nNumCivFemale = 0;
PedDensityMultiplier = 1.0;
ms_nNumCop = 0;
bZoneChangeHasHappened = 0;
ms_nNumEmergency = 0;
m_CountDownToPedsAtStart = 2;
ms_nNumGang1 = 0;
ms_nTotalMissionPeds = 0;
ms_nNumGang2 = 0;
ms_nTotalPeds = 0;
ms_nNumGang3 = 0;
ms_nTotalGangPeds = 0;
ms_nNumGang4 = 0;
ms_nTotalCivPeds = 0;
ms_nNumGang5 = 0;
ms_nNumDummy = 0;
ms_nNumGang6 = 0;
ms_nNumGang9 = 0;
ms_nNumGang7 = 0;
ms_nNumGang8 = 0;
LoadPedGroups();
DealWithZoneChange(LEVEL_COMMERCIAL, LEVEL_INDUSTRIAL, true);
debug("CPopulation ready\n");
}
void
CPopulation::RemovePed(CEntity* ent)
{
CWorld::Remove(ent);
delete ent;
}
STARTPATCHES
InjectHook(0x4F3770, CPopulation::Initialise, PATCH_JUMP);
ENDPATCHES

View File

@ -19,7 +19,29 @@ public:
static float &PedDensityMultiplier;
static uint32 &ms_nTotalMissionPeds;
static int32 &MaxNumberOfPedsInUse;
static uint32& ms_nNumCivMale;
static uint32 &ms_nNumCivFemale;
static uint32 &ms_nNumCop;
static bool &bZoneChangeHasHappened;
static uint32 &ms_nNumEmergency;
static uint32& m_CountDownToPedsAtStart;
static uint32& ms_nNumGang1;
static uint32& ms_nNumGang2;
static uint32& ms_nTotalPeds;
static uint32& ms_nNumGang3;
static uint32& ms_nTotalGangPeds;
static uint32& ms_nNumGang4;
static uint32& ms_nTotalCivPeds;
static uint32& ms_nNumGang5;
static uint32& ms_nNumDummy;
static uint32& ms_nNumGang6;
static uint32& ms_nNumGang9;
static uint32& ms_nNumGang7;
static uint32& ms_nNumGang8;
static void Initialise();
static void Update(void);
static void LoadPedGroups();
static void UpdatePedCount(uint32, bool);
static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
static CPed *AddPedInCar(CVehicle *vehicle);

View File

@ -6,5 +6,8 @@ uint16 &CRecordDataForGame::RecordingState = *(uint16*)0x95CC24;
uint8 &CRecordDataForChase::Status = *(uint8*)0x95CDCE;
WRAPPER void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void) { EAXJMP(0x4341F0); }
WRAPPER void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void) { EAXJMP(0x4347F0); }
WRAPPER void CRecordDataForChase::ProcessControlCars(void) { EAXJMP(0x435540); }
WRAPPER void CRecordDataForChase::SaveOrRetrieveCarPositions(void) { EAXJMP(0x434B20); }

View File

@ -11,6 +11,7 @@ class CRecordDataForChase
public:
static uint8 &Status;
static void SaveOrRetrieveDataForThisFrame(void);
static void ProcessControlCars(void);
static void SaveOrRetrieveCarPositions(void);
};
@ -20,4 +21,6 @@ class CRecordDataForGame
{
public:
static uint16 &RecordingState;
static void SaveOrRetrieveDataForThisFrame(void);
};

View File

@ -1036,7 +1036,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
bAllowLookAroundCam = true;
bPlayingBackFromFile = false;
OldRadioStation = DMAudio.GetRadioInCar();
DMAudio.ChangeMusicMode(0);
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
int current;
@ -1156,7 +1156,7 @@ void CReplay::RestoreStuffFromMem(void)
FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted); /* Nice memory leak */
CWorld::Players[0] = PlayerInfo;
int i = CPools::GetPedPool()->GetSize();
while (i--){
while (--i >= 0) {
CPed* ped = CPools::GetPedPool()->GetSlot(i);
if (!ped)
continue;
@ -1174,7 +1174,7 @@ void CReplay::RestoreStuffFromMem(void)
ped->AddWeaponModel(ped->m_wepModelID);
}
i = CPools::GetVehiclePool()->GetSize();
while (i--){
while (--i >= 0) {
CVehicle* vehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!vehicle)
continue;
@ -1233,7 +1233,7 @@ void CReplay::RestoreStuffFromMem(void)
}
PrintElementsInPtrList();
i = CPools::GetObjectPool()->GetSize();
while (i--){
while (--i >= 0) {
CObject* object = CPools::GetObjectPool()->GetSlot(i);
if (!object)
continue;
@ -1248,7 +1248,7 @@ void CReplay::RestoreStuffFromMem(void)
object->GetMatrix().AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(object->m_rwObject)), false);
}
i = CPools::GetDummyPool()->GetSize();
while (i--){
while (--i >= 0) {
CDummy* dummy = CPools::GetDummyPool()->GetSlot(i);
if (!dummy)
continue;
@ -1282,9 +1282,9 @@ void CReplay::RestoreStuffFromMem(void)
}
delete[] pPedAnims;
pPedAnims = nil;
DMAudio.ChangeMusicMode(0);
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetRadioInCar(OldRadioStation);
DMAudio.ChangeMusicMode(1);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
#endif
@ -1294,7 +1294,7 @@ WRAPPER void CReplay::EmptyPedsAndVehiclePools(void) { EAXJMP(0x5970E0); }
void CReplay::EmptyPedsAndVehiclePools(void)
{
int i = CPools::GetVehiclePool()->GetSize();
while (i--) {
while (--i >= 0) {
CVehicle* v = CPools::GetVehiclePool()->GetSlot(i);
if (!v)
continue;
@ -1302,7 +1302,7 @@ void CReplay::EmptyPedsAndVehiclePools(void)
delete v;
}
i = CPools::GetPedPool()->GetSize();
while (i--) {
while (--i >= 0) {
CPed* p = CPools::GetPedPool()->GetSlot(i);
if (!p)
continue;
@ -1319,7 +1319,7 @@ void CReplay::EmptyAllPools(void)
{
EmptyPedsAndVehiclePools();
int i = CPools::GetObjectPool()->GetSize();
while (i--) {
while (--i >= 0) {
CObject* o = CPools::GetObjectPool()->GetSlot(i);
if (!o)
continue;
@ -1327,7 +1327,7 @@ void CReplay::EmptyAllPools(void)
delete o;
}
i = CPools::GetDummyPool()->GetSize();
while (i--) {
while (--i >= 0) {
CDummy* d = CPools::GetDummyPool()->GetSlot(i);
if (!d)
continue;
@ -1343,14 +1343,14 @@ WRAPPER void CReplay::MarkEverythingAsNew(void) { EAXJMP(0x597280); }
void CReplay::MarkEverythingAsNew(void)
{
int i = CPools::GetVehiclePool()->GetSize();
while (i--) {
while (--i >= 0) {
CVehicle* v = CPools::GetVehiclePool()->GetSlot(i);
if (!v)
continue;
v->bHasAlreadyBeenRecorded = false;
}
i = CPools::GetPedPool()->GetSize();
while (i--) {
while (--i >= 0) {
CPed* p = CPools::GetPedPool()->GetSlot(i);
if (!p)
continue;

View File

@ -2,4 +2,6 @@
#include "patcher.h"
#include "RoadBlocks.h"
WRAPPER void CRoadBlocks::Init(void) { EAXJMP(0x436F50); }
WRAPPER void CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle*, int32, int16) { EAXJMP(0x4376A0); }
WRAPPER void CRoadBlocks::GenerateRoadBlocks(void) { EAXJMP(0x436FA0); }

View File

@ -6,5 +6,7 @@ class CVehicle;
class CRoadBlocks
{
public:
static void Init(void);
static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
static void GenerateRoadBlocks(void);
};

View File

@ -0,0 +1,5 @@
#include "common.h"
#include "patcher.h"
#include "SceneEdit.h"
WRAPPER void CSceneEdit::Update(void) { EAXJMP(0x585570); }

7
src/control/SceneEdit.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
class CSceneEdit
{
public:
static void Update(void);
};

View File

@ -670,12 +670,12 @@ void CRunningScript::Process()
if (!CPad::GetPad(0)->GetCrossJustDown())
return;
m_nWakeTime = 0;
for (int i = 0; i < 6; i++){ /* TODO: add constant for number of messages */
if (CMessages::BIGMessages[i].m_Current.m_pText)
CMessages::BIGMessages[i].m_Current.m_nStartTime = 0;
if (CMessages::BriefMessages[0].m_pText)
CMessages::BriefMessages[0].m_nStartTime = 0;
for (int i = 0; i < NUMBIGMESSAGES; i++){
if (CMessages::BIGMessages[i].m_Stack[0].m_pText != nil)
CMessages::BIGMessages[i].m_Stack[0].m_nStartTime = 0;
}
if (CMessages::BriefMessages[0].m_pText != nil)
CMessages::BriefMessages[0].m_nStartTime = 0;
}
int8 CRunningScript::ProcessOneCommand()
@ -2191,7 +2191,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]);
m_nIp += 8;
CollectParameters(&m_nIp, 2);
CMessages::AddMessage(key, ScriptParams[0], ScriptParams[1]);
CMessages::AddMessageSoon(key, ScriptParams[0], ScriptParams[1]);
return 0;
}
case COMMAND_CLEAR_PRINTS:

View File

@ -5,6 +5,7 @@
#include "Vehicle.h"
WRAPPER void CTrafficLights::DisplayActualLight(CEntity *ent) { EAXJMP(0x455800); }
WRAPPER void CTrafficLights::ScanForLightsOnMap(void) { EAXJMP(0x454F40); }
WRAPPER bool CTrafficLights::ShouldCarStopForLight(CVehicle*, bool) { EAXJMP(0x455350); }
WRAPPER bool CTrafficLights::ShouldCarStopForBridge(CVehicle*) { EAXJMP(0x456460); }

View File

@ -13,6 +13,7 @@ class CTrafficLights
{
public:
static void DisplayActualLight(CEntity *ent);
static void ScanForLightsOnMap(void);
static uint8 LightForPeds(void);
static bool ShouldCarStopForLight(CVehicle*, bool);
static bool ShouldCarStopForBridge(CVehicle*);

View File

@ -22,6 +22,7 @@ WRAPPER void CControllerConfigManager::ClearSimButtonPressCheckers() { EAXJMP(0x
WRAPPER void CControllerConfigManager::AffectPadFromKeyBoard() { EAXJMP(0x58D0C0); }
WRAPPER void CControllerConfigManager::AffectPadFromMouse() { EAXJMP(0x58D1A0); }
WRAPPER void CControllerConfigManager::ClearSettingsAssociatedWithAction(int, int) { EAXJMP(0x58EB40); }
WRAPPER void CControllerConfigManager::GetWideStringOfCommandKeys(uint16, wchar*, uint16) { EAXJMP(0x58F460); }
void CControllerConfigManager::LoadSettings(int32 file)
{

View File

@ -9,10 +9,64 @@ enum eControllerType
OPTIONAL_EXTRA,
MOUSE,
JOYSTICK,
TOTAL_CONTROLLER_TYPES
};
enum e_ControllerAction
{
PED_FIREWEAPON = 0,
PED_CYCLE_WEAPON_RIGHT,
PED_CYCLE_WEAPON_LEFT,
GO_FORWARD,
GO_BACK,
GO_LEFT,
GO_RIGHT,
PED_SNIPER_ZOOM_IN,
PED_SNIPER_ZOOM_OUT,
VEHICLE_ENTER_EXIT,
CAMERA_CHANGE_VIEW_ALL_SITUATIONS,
PED_JUMPING,
PED_SPRINT,
PED_LOOKBEHIND,
//PED_DUCK, // VC
//PED_ANSWER_PHONE, // VC
VEHICLE_ACCELERATE,
VEHICLE_BRAKE,
VEHICLE_CHANGE_RADIO_STATION,
VEHICLE_HORN,
TOGGLE_SUBMISSIONS,
VEHICLE_HANDBRAKE,
PED_1RST_PERSON_LOOK_LEFT,
PED_1RST_PERSON_LOOK_RIGHT,
VEHICLE_LOOKLEFT,
VEHICLE_LOOKRIGHT,
VEHICLE_LOOKBEHIND,
VEHICLE_TURRETLEFT,
VEHICLE_TURRETRIGHT,
VEHICLE_TURRETUP,
VEHICLE_TURRETDOWN,
PED_CYCLE_TARGET_LEFT,
PED_CYCLE_TARGET_RIGHT,
PED_CENTER_CAMERA_BEHIND_PLAYER,
PED_LOCK_TARGET,
NETWORK_TALK,
PED_1RST_PERSON_LOOK_UP,
PED_1RST_PERSON_LOOK_DOWN,
CONTROLLERACTION_36, // unk, unused?
TOGGLE_DPAD,
SWITCH_DEBUG_CAM_ON,
TAKE_SCREEN_SHOT,
SHOW_MOUSE_POINTER_TOGGLE,
TOTAL_CONTROL_ACTIONS
};
class CMouseControllerState;
#define ACTIONNAME_LENGTH 40
class CControllerConfigManager
{
public:
@ -23,16 +77,13 @@ public:
};
bool firstCapture;
char _pad0[3];
DIJOYSTATE2 m_OldState;
DIJOYSTATE2 m_NewState;
wchar m_aActionNames[41][40];
wchar m_aActionNames[TOTAL_CONTROL_ACTIONS][ACTIONNAME_LENGTH];
bool m_aButtonStates[17];
char _pad1[3];
tControllerConfigBind m_aSettings[41][4];
tControllerConfigBind m_aSettings[TOTAL_CONTROL_ACTIONS][TOTAL_CONTROLLER_TYPES];
uint8 m_aSimCheckers[4][4];
bool m_bMouseAssociated;
char _pad2[3];
void UpdateJoyButtonState(int padnumber);
void UpdateJoyInConfigMenus_ButtonDown(int button, int padnumber);
@ -52,6 +103,7 @@ public:
void AffectPadFromMouse();
void ClearSettingsAssociatedWithAction(int, int);
void GetWideStringOfCommandKeys(uint16, wchar*, uint16);
};
VALIDATE_SIZE(CControllerConfigManager, 0x143C);

View File

@ -17,7 +17,6 @@
#include "RpAnimBlend.h"
#include "ModelIndices.h"
#include "TempColModels.h"
#include "MusicManager.h"
const struct {
const char *szTrackName;
@ -209,7 +208,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CFileMgr::CloseFile(file);
if (strcmpi(ms_cutsceneName, "end")) {
DMAudio.ChangeMusicMode(2);
DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
int trackId = FindCutsceneAudioTrackId(szCutsceneName);
if (trackId != -1) {
printf("Start preload audio %s\n", szCutsceneName);
@ -368,7 +367,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
if (strcmpi(ms_cutsceneName, "end")) {
DMAudio.StopCutSceneMusic();
if (strcmpi(ms_cutsceneName, "bet"))
DMAudio.ChangeMusicMode(1);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
CTimer::Stop();
//TheCamera.GetScreenFadeStatus() == 2; // what for??

View File

@ -25,6 +25,8 @@
#include "CdStream.h"
#include "FileLoader.h"
WRAPPER void CFileLoader::ReloadPaths(const char *filename) { EAXJMP(0x476DB0); }
char CFileLoader::ms_line[256];
const char*

View File

@ -9,7 +9,7 @@ public:
static char *LoadLine(int fd);
static RwTexDictionary *LoadTexDictionary(const char *filename);
static void LoadCollisionFile(const char *filename);
static void LoadCollisionModel(uint8 *buf, CColModel &model, char *name);
static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name);
static void LoadModelFile(const char *filename);
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
static void LoadClumpFile(const char *filename);
@ -39,4 +39,6 @@ public:
static void LoadPickup(const char *line);
static void LoadMapZones(const char *filename);
static void ReloadPaths(const char *filename);
};

View File

@ -32,4 +32,5 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance)
}
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); }
WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }

View File

@ -31,6 +31,7 @@ class CFireManager
CFire m_aFires[NUM_FIRES];
public:
void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32);
void Update(void);
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
CFire *FindNearestFire(CVector, float*);
uint32 GetTotalActiveFires() const { return m_nTotalFires; }

View File

@ -11,7 +11,6 @@
#include "Timer.h"
#include "Game.h"
#include "DMAudio.h"
#include "MusicManager.h"
#include "FileMgr.h"
#include "Streaming.h"
#include "TxdStore.h"
@ -535,7 +534,7 @@ void CMenuManager::Draw()
if (m_nPrefsAudio3DProviderIndex == -1)
textToPrint[MENUCOLUMN_RIGHT] = TheText.Get("FEA_NAH");
else {
char *provider = MusicManager.Get3DProviderName(m_nPrefsAudio3DProviderIndex);
char *provider = DMAudio.Get3DProviderName(m_nPrefsAudio3DProviderIndex);
AsciiToUnicode(provider, gUString);
textToPrint[MENUCOLUMN_RIGHT] = gUString;
}
@ -1086,7 +1085,7 @@ void CMenuManager::LoadAllTextures()
{
if (!m_bSpritesLoaded) {
CMenuManager::CentreMousePointer();
DMAudio.ChangeMusicMode(0);
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
m_nCurrOption = 0;
m_PrefsRadioStation = DMAudio.GetRadioInCar();
@ -2133,7 +2132,7 @@ WRAPPER void CMenuManager::RequestFrontEndShutdown() { EAXJMP(0x488750); }
void CMenuManager::RequestFrontEndShutdown()
{
m_bShutDownFrontEndRequested = true;
DMAudio.ChangeMusicMode(1);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
#endif

View File

@ -2,8 +2,60 @@
#include "patcher.h"
#include "Game.h"
#include "main.h"
#include "AccidentManager.h"
#include "Antennas.h"
#include "Bridge.h"
#include "Camera.h"
#include "CarCtrl.h"
#include "CarGen.h"
#include "CdStream.h"
#include "Clock.h"
#include "Clouds.h"
#include "Collision.h"
#include "Coronas.h"
#include "Cranes.h"
#include "CutsceneMgr.h"
#include "Darkel.h"
#include "EventList.h"
#include "FileLoader.h"
#include "FileMgr.h"
#include "Fire.h"
#include "Fluff.h"
#include "Font.h"
#include "Frontend.h"
#include "GameLogic.h"
#include "Garages.h"
#include "Glass.h"
#include "Heli.h"
#include "Pad.h"
#include "Particle.h"
#include "Phones.h"
#include "Pickups.h"
#include "Plane.h"
#include "Population.h"
#include "Record.h"
#include "Renderer.h"
#include "Replay.h"
#include "RoadBlocks.h"
#include "Rubbish.h"
#include "SceneEdit.h"
#include "Script.h"
#include "Shadows.h"
#include "Skidmarks.h"
#include "SpecialFX.h"
#include "Sprite2d.h"
#include "Streaming.h"
#include "TimeCycle.h"
#include "TrafficLights.h"
#include "Train.h"
#include "TxdStore.h"
#include "User.h"
#include "WaterCannon.h"
#include "Weapon.h"
#include "Weather.h"
#include "World.h"
#include "ZoneCull.h"
#include "Zones.h"
eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
@ -25,14 +77,128 @@ CGame::InitialiseOnceBeforeRW(void)
}
WRAPPER void CGame::Initialise(const char *datFile) { EAXJMP(0x48BED0); }
#if 0
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
#else
extern void (*DebugMenuProcess)(void);
void CGame::Process(void)
{
CPad::UpdatePads();
TheCamera.SetMotionBlurAlpha(0);
if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
DebugMenuProcess();
CCutsceneMgr::Update();
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process();
CStreaming::Update();
if (!CTimer::GetIsPaused())
{
CTheZones::Update();
CSprite2d::SetRecipNearClip();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
CRecordDataForGame::SaveOrRetrieveDataForThisFrame();
CRecordDataForChase::SaveOrRetrieveDataForThisFrame();
CPad::DoCheats();
CClock::Update();
CWeather::Update();
CTheScripts::Process();
CCollision::Update();
CTrain::UpdateTrains();
CPlane::UpdatePlanes();
CHeli::UpdateHelis();
CDarkel::Update();
CSkidmarks::Update();
CAntennas::Update();
CGlass::Update();
CSceneEdit::Update();
CEventList::Update();
CParticle::Update();
gFireManager.Update();
CPopulation::Update();
CWeapon::UpdateWeapons();
if (!CCutsceneMgr::IsRunning())
CTheCarGenerators::Process();
if (!CReplay::IsPlayingBack())
CCranes::UpdateCranes();
CClouds::Update();
CMovingThings::Update();
CWaterCannons::Update();
CUserDisplay::Process();
CReplay::Update();
CWorld::Process();
gAccidentManager.Update();
CPacManPickups::Update();
CPickups::Update();
CGarages::Update();
CRubbish::Update();
CSpecialFX::Update();
CTimeCycle::Update();
if (CReplay::ShouldStandardCameraBeProcessed())
TheCamera.Process();
CCullZones::Update();
if (!CReplay::IsPlayingBack())
CGameLogic::Update();
CBridge::Update();
CCoronas::DoSunAndMoon();
CCoronas::Update();
CShadows::UpdateStaticShadows();
CShadows::UpdatePermanentShadows();
gPhoneInfo.Update();
if (!CReplay::IsPlayingBack())
{
CCarCtrl::GenerateRandomCars();
CRoadBlocks::GenerateRoadBlocks();
CCarCtrl::RemoveDistantCars();
}
}
}
#endif
void CGame::ReloadIPLs(void)
{
CTimer::Stop();
CWorld::RemoveStaticObjects();
ThePaths.Init();
CCullZones::Init();
CFileLoader::ReloadPaths("GTA3.IDE");
CFileLoader::LoadScene("INDUST.IPL");
CFileLoader::LoadScene("COMMER.IPL");
CFileLoader::LoadScene("SUBURBAN.IPL");
CFileLoader::LoadScene("CULL.IPL");
ThePaths.PreparePathData();
CTrafficLights::ScanForLightsOnMap();
CRoadBlocks::Init();
CCranes::InitCranes();
CGarages::Init();
CWorld::RepositionCertainDynamicObjects();
CCullZones::ResolveVisibilities();
CRenderer::SortBIGBuildings();
CTimer::Update();
}
#if 0
WRAPPER void CGame::FinalShutdown(void) { EAXJMP(0x48BEC0); }
#else
void
CGame::FinalShutdown(void)
{
CTxdStore::Shutdown();
CPedStats::Shutdown();
CdStreamShutdown();
}
#endif
WRAPPER bool CGame::InitialiseRenderWare(void) { EAXJMP(0x48BBA0); }
WRAPPER void CGame::ShutdownRenderWare(void) { EAXJMP(0x48BCB0); }
WRAPPER void CGame::FinalShutdown(void) { EAXJMP(0x48BEC0); }
WRAPPER void CGame::ShutDown(void) { EAXJMP(0x48C3A0); }
WRAPPER void CGame::ShutDownForRestart(void) { EAXJMP(0x48C6B0); }
WRAPPER void CGame::InitialiseWhenRestarting(void) { EAXJMP(0x48C740); }
WRAPPER bool CGame::InitialiseOnceAfterRW(void) { EAXJMP(0x48BD50); }
STARTPATCHES
InjectHook(0x48C850, CGame::Process, PATCH_JUMP);
InjectHook(0x48BEC0, CGame::FinalShutdown, PATCH_JUMP);
ENDPATCHES

View File

@ -30,6 +30,7 @@ public:
static void FinalShutdown(void);
static void ShutDownForRestart(void);
static void Process(void);
static void ReloadIPLs(void);
// NB: these do something on PS2
static void TidyUpMemory(bool, bool) {}

View File

@ -1,5 +1,7 @@
#pragma once
#include "common.h"
class CPtrNode
{
public:

View File

@ -1,27 +0,0 @@
#include "common.h"
#include "patcher.h"
#include "Messages.h"
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); }
WRAPPER void CMessages::AddBigMessage(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529EB0); }
WRAPPER void CMessages::AddBigMessageQ(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529F60); }
WRAPPER void CMessages::AddBigMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52AD10); }
WRAPPER void CMessages::AddBigMessageWithNumberQ(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52AE00); }
WRAPPER void CMessages::AddMessage(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529900); }
WRAPPER void CMessages::AddMessageJumpQ(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529A10); }
WRAPPER void CMessages::AddMessageSoon(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529AF0); }
WRAPPER void CMessages::AddMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52A850); }
WRAPPER void CMessages::AddMessageJumpQWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52A9A0); }
WRAPPER void CMessages::AddMessageSoonWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52AAC0); }
WRAPPER void CMessages::ClearMessages() { EAXJMP(0x529CE0); }
WRAPPER void CMessages::Init() { EAXJMP(0x529310); }
WRAPPER void CMessages::Process() { EAXJMP(0x529580); }
tPreviousBrief *CMessages::PreviousBriefs = (tPreviousBrief *)0x713C08;
tMessage *CMessages::BriefMessages = (tMessage *)0x8786E0;
tBigMessage *CMessages::BIGMessages = (tBigMessage *)0x773628;

View File

@ -1,57 +0,0 @@
#pragma once
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);
static void AddBigMessage(wchar* key, uint32 time, uint16 pos);
static void AddBigMessageQ(wchar* key, uint32 time, uint16 pos);
static void AddBigMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
static void AddBigMessageWithNumberQ(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
static void AddMessage(wchar* key, uint32 time, uint16 pos);
static void AddMessageJumpQ(wchar* key, uint32 time, uint16 pos);
static void AddMessageSoon(wchar* key, uint32 time, uint16 pos);
static void AddMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
static void AddMessageJumpQWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
static void AddMessageSoonWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
static void ClearMessages();
static void Init();
static void Process();
};

View File

@ -1,6 +1,8 @@
#include "common.h"
#include "patcher.h"
#include "Pools.h"
#include "World.h"
#include "ProjectileInfo.h"
CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044;
CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448;
@ -12,15 +14,9 @@ CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28;
CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18;
CAudioScriptObjectPool *&CPools::ms_pAudioScriptObjectPool = *(CAudioScriptObjectPool**)0x8F1B6C;
WRAPPER void CPools::Initialise(void) { EAXJMP(0x4A1770); }
WRAPPER void CPools::MakeSureSlotInObjectPoolIsEmpty(int32 handle) { EAXJMP(0x4A2DB0); }
#if 0
void
CPools::Initialise(void)
{
// TODO: unused right now
assert(0);
ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES);
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
ms_pPedPool = new CPedPool(NUMPEDS);
@ -31,7 +27,33 @@ CPools::Initialise(void)
ms_pDummyPool = new CDummyPool(NUMDUMMIES);
ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS);
}
#endif
void
CPools::ShutDown(void)
{
debug("PtrNodes left %d\n", ms_pPtrNodePool->GetNoOfUsedSpaces());
debug("EntryInfoNodes left %d\n", ms_pEntryInfoNodePool->GetNoOfUsedSpaces());
debug("Peds left %d\n", ms_pPedPool->GetNoOfUsedSpaces());
debug("Vehicles left %d\n", ms_pVehiclePool->GetNoOfUsedSpaces());
debug("Buildings left %d\n", ms_pBuildingPool->GetNoOfUsedSpaces());
debug("Treadables left %d\n", ms_pTreadablePool->GetNoOfUsedSpaces());
debug("Objects left %d\n", ms_pObjectPool->GetNoOfUsedSpaces());
debug("Dummys left %d\n", ms_pDummyPool->GetNoOfUsedSpaces());
debug("AudioScriptObjects left %d\n", ms_pAudioScriptObjectPool->GetNoOfUsedSpaces());
printf("Shutdown pool started\n");
delete ms_pPtrNodePool;
delete ms_pEntryInfoNodePool;
delete ms_pPedPool;
delete ms_pVehiclePool;
delete ms_pBuildingPool;
delete ms_pTreadablePool;
delete ms_pObjectPool;
delete ms_pDummyPool;
delete ms_pAudioScriptObjectPool;
printf("Shutdown pool done\n");
}
int32 CPools::GetPedRef(CPed *ped) { return ms_pPedPool->GetIndex(ped); }
CPed *CPools::GetPed(int32 handle) { return ms_pPedPool->GetAt(handle); }
@ -39,3 +61,47 @@ int32 CPools::GetVehicleRef(CVehicle *vehicle) { return ms_pVehiclePool->GetInde
CVehicle *CPools::GetVehicle(int32 handle) { return ms_pVehiclePool->GetAt(handle); }
int32 CPools::GetObjectRef(CObject *object) { return ms_pObjectPool->GetIndex(object); }
CObject *CPools::GetObject(int32 handle) { return ms_pObjectPool->GetAt(handle); }
void
CPools::CheckPoolsEmpty()
{
assert(ms_pPedPool->GetNoOfUsedSpaces() == 0);
assert(ms_pVehiclePool->GetNoOfUsedSpaces() == 0);
printf("pools have beem cleared \n");
}
void
CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
{
if (ms_pObjectPool->IsFreeSlot(slot)) return;
CObject *object = ms_pObjectPool->GetSlot(slot);
if (object->ObjectCreatedBy == TEMP_OBJECT) {
CWorld::Remove(object);
delete object;
} else if (!CProjectileInfo::RemoveIfThisIsAProjectile(object)) {
// relocate to another slot??
CObject *newObject = new CObject();
CWorld::Remove(object);
memcpy(newObject, object, ms_pObjectPool->GetMaxEntrySize());
CWorld::Add(newObject);
object->m_rwObject = nil;
delete object;
newObject->m_pFirstReference = nil;
}
}
STARTPATCHES
InjectHook(0x4A1770, CPools::Initialise, PATCH_JUMP);
InjectHook(0x4A1880, CPools::ShutDown, PATCH_JUMP);
InjectHook(0x4A1A50, CPools::CheckPoolsEmpty, PATCH_JUMP);
InjectHook(0x4A1A80, CPools::GetPedRef, PATCH_JUMP);
InjectHook(0x4A1AA0, CPools::GetPed, PATCH_JUMP);
InjectHook(0x4A1AC0, CPools::GetVehicleRef, PATCH_JUMP);
InjectHook(0x4A1AE0, CPools::GetVehicle, PATCH_JUMP);
InjectHook(0x4A1B00, CPools::GetObjectRef, PATCH_JUMP);
InjectHook(0x4A1B20, CPools::GetObject, PATCH_JUMP);
InjectHook(0x4A2DB0, CPools::MakeSureSlotInObjectPoolIsEmpty, PATCH_JUMP);
ENDPATCHES

View File

@ -43,11 +43,13 @@ public:
static CAudioScriptObjectPool *GetAudioScriptObjectPool(void) { return ms_pAudioScriptObjectPool; }
static void Initialise(void);
static void ShutDown(void);
static int32 GetPedRef(CPed *ped);
static CPed *GetPed(int32 handle);
static int32 GetVehicleRef(CVehicle *vehicle);
static CVehicle *GetVehicle(int32 handle);
static int32 GetObjectRef(CObject *object);
static CObject *GetObject(int32 handle);
static void MakeSureSlotInObjectPoolIsEmpty(int32 handle);
static void CheckPoolsEmpty();
static void MakeSureSlotInObjectPoolIsEmpty(int32 slot);
};

View File

@ -1,5 +1,15 @@
#pragma warning( push )
#pragma warning( disable : 4005)
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma warning( pop )
#include "common.h"
#include "win.h"
#include "patcher.h"
#include "Timer.h"
float &texLoadTime = *(float*)0x8F1B50;
int32 &texNumLoaded = *(int32*)0x8F252C;
RwTexture*
RwTextureGtaStreamRead(RwStream *stream)
@ -10,11 +20,15 @@ RwTextureGtaStreamRead(RwStream *stream)
if(!RwStreamFindChunk(stream, rwID_TEXTURENATIVE, &size, &version))
return nil;
// TODO: unused timing
float preloadTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
if(!RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, &tex, size)))
return nil;
if (gGameState == GS_INIT_PLAYING_GAME) {
texLoadTime = (texNumLoaded * texLoadTime + (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond() - preloadTime) / (float)(texNumLoaded+1);
texNumLoaded++;
}
return tex;
}

View File

@ -226,7 +226,7 @@ CStreaming::Init(void)
CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd);
CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom);
for(i = 0; i < CPools::GetBuildingPool()->GetSize(); i++){
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
if(building == nil)
continue;
@ -682,8 +682,8 @@ CStreaming::RequestBigBuildings(eLevelName level)
int i, n;
CBuilding *b;
n = CPools::GetBuildingPool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
RequestModel(b->GetModelIndex(), STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY);
@ -837,8 +837,8 @@ CStreaming::RemoveBuildings(eLevelName level)
CEntity *e;
CBaseModelInfo *mi;
n = CPools::GetBuildingPool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@ -850,8 +850,8 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
n = CPools::GetTreadablePool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetTreadablePool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetTreadablePool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@ -863,8 +863,8 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
n = CPools::GetObjectPool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetObjectPool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetObjectPool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@ -876,8 +876,8 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
n = CPools::GetDummyPool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetDummyPool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetDummyPool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@ -951,8 +951,8 @@ CStreaming::RemoveBigBuildings(eLevelName level)
CEntity *e;
CBaseModelInfo *mi;
n = CPools::GetBuildingPool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->bIsBIGBuilding && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@ -1172,8 +1172,8 @@ CStreaming::HaveAllBigBuildingsLoaded(eLevelName level)
return;
}
n = CPools::GetBuildingPool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->bIsBIGBuilding && e->m_level == level &&
ms_aInfoForModel[e->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)

View File

@ -13,8 +13,7 @@ COnscreenTimer& CUserDisplay::OnscnTimer = *(COnscreenTimer*)0x862238;
CPager& CUserDisplay::Pager = *(CPager*)0x8F2744;
CCurrentVehicle& CUserDisplay::CurrentVehicle = *(CCurrentVehicle*)0x8F5FE8;
WRAPPER void CPager::AddMessage(wchar*, uint16, uint16, uint16) { EAXJMP(0x52B940); }
WRAPPER void CPager::AddMessageWithNumber(wchar*, int, int, int, int, int, uint16, uint16, uint16) { EAXJMP(0x52BB50); }
WRAPPER void CUserDisplay::Process(void) { EAXJMP(0x4AD690); }
void COnscreenTimer::Init() {
m_bDisabled = false;

View File

@ -1,5 +1,7 @@
#pragma once
#include "Pager.h"
class COnscreenTimerEntry
{
public:
@ -50,13 +52,6 @@ class CCurrentVehicle
{
};
class CPager
{
public:
void AddMessage(wchar*, uint16, uint16, uint16);
void AddMessageWithNumber(wchar*, int, int, int, int, int, uint16, uint16, uint16);
};
class CUserDisplay
{
public:
@ -64,4 +59,6 @@ public:
static COnscreenTimer &OnscnTimer;
static CPager &Pager;
static CCurrentVehicle &CurrentVehicle;
static void Process(void);
};

View File

@ -39,6 +39,8 @@ bool &CWorld::bDoingCarCollisions = *(bool*)0x95CD8C;
bool &CWorld::bIncludeCarTyres = *(bool*)0x95CDAA;
WRAPPER void CWorld::ShutDown(void) { EAXJMP(0x4AE450); }
WRAPPER void CWorld::RepositionCertainDynamicObjects() { EAXJMP(0x4B42B0); }
WRAPPER void CWorld::RemoveStaticObjects() { EAXJMP(0x4B4D50); }
WRAPPER void CWorld::RemoveReferencesToDeletedObject(CEntity*) { EAXJMP(0x4B3BF0); }
WRAPPER void CWorld::FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool){ EAXJMP(0x4B2A30); }
WRAPPER void CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8) { EAXJMP(0x4B4E70) };

View File

@ -124,6 +124,8 @@ public:
static void Initialise();
static void ShutDown();
static void RepositionCertainDynamicObjects();
static void RemoveStaticObjects();
static void Process();
};

View File

@ -169,22 +169,22 @@ CCullZones::MarkSubwayAsInvisible(bool visible)
CEntity *e;
CVehicle *v;
n = CPools::GetBuildingPool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetBuildingPool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->bIsSubway)
e->bIsVisible = visible;
}
n = CPools::GetTreadablePool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetTreadablePool()->GetSize()-1;
for(i = n; i >= 0; i--){
e = CPools::GetTreadablePool()->GetSlot(i);
if(e && e->bIsSubway)
e->bIsVisible = visible;
}
n = CPools::GetVehiclePool()->GetSize();
for(i = 0; i < n; i++){
n = CPools::GetVehiclePool()->GetSize()-1;
for(i = n; i >= 0; i--){
v = CPools::GetVehiclePool()->GetSlot(i);
if(v && v->IsTrain() && ((CTrain*)v)->m_nTrackId != TRACK_ELTRAIN)
v->bIsVisible = visible;

View File

@ -121,7 +121,7 @@ public:
CRGBA(void) { }
CRGBA(uint8 r, uint8 g, uint8 b, uint8 a) : r(r), g(g), b(b), a(a) { }
CRGBA &CRGBA::operator =(const CRGBA &right)
CRGBA &operator =(const CRGBA &right)
{
this->r = right.r;
this->g = right.g;
@ -142,7 +142,7 @@ public:
return rwRGBA;
}
CRGBA &CRGBA::operator =(const RwRGBA &right)
CRGBA &operator =(const RwRGBA &right)
{
this->r = right.red;
this->g = right.green;
@ -197,8 +197,6 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#define BIT(num) (1<<(num))
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define ABS(a) (((a) < 0) ? (-(a)) : (a))
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min)))))
@ -337,7 +335,7 @@ inline void SkipSaveBuf(uint8 *&buf, int32 skip)
template<typename T>
inline const T ReadSaveBuf(uint8 *&buf)
{
{
T &value = *(T*)buf;
SkipSaveBuf(buf, sizeof(T));
return value;
@ -345,8 +343,8 @@ inline const T ReadSaveBuf(uint8 *&buf)
template<typename T>
inline T *WriteSaveBuf(uint8 *&buf, const T &value)
{
T *p = (T*)buf;
{
T *p = (T*)buf;
*p = value;
SkipSaveBuf(buf, sizeof(T));
return p;
@ -355,11 +353,11 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
#define SAVE_HEADER_SIZE (4*sizeof(char)+sizeof(uint32))
#define WriteSaveHeader(buf,a,b,c,d,size) \
WriteSaveBuf(buf, a);\
WriteSaveBuf(buf, b);\
WriteSaveBuf(buf, c);\
WriteSaveBuf(buf, d);\
#define WriteSaveHeader(buf,a,b,c,d,size) \
WriteSaveBuf(buf, a);\
WriteSaveBuf(buf, b);\
WriteSaveBuf(buf, c);\
WriteSaveBuf(buf, d);\
WriteSaveBuf(buf, size);
#define CheckSaveHeader(buf,a,b,c,d,size)\

View File

@ -67,6 +67,7 @@ enum Config {
NUMANTENNAS = 8,
NUMCORONAS = 56,
NUMPOINTLIGHTS = 32,
NUM3DMARKERS = 32,
NUMMONEYMESSAGES = 16,
NUMPICKUPMESSAGES = 16,

View File

@ -18,6 +18,7 @@
#include "Automobile.h"
#include "Ped.h"
#include "debugmenu_public.h"
#include "Particle.h"
#include <vector>
#include <list>
@ -352,6 +353,7 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Debug", "Make peds follow you in formation", LetThemFollowYou);
#ifndef MASTER
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
#endif
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);

View File

@ -44,7 +44,20 @@ public:
m_flags[i].free = 1;
}
}
int GetSize(void) { return m_size; }
~CPool() {
Flush();
}
void Flush() {
if (m_size > 0) {
free(m_entries);
free(m_flags);
m_entries = nil;
m_flags = nil;
m_size = 0;
m_allocPtr = 0;
}
}
int GetSize(void) const { return m_size; }
T *New(void){
bool wrapped = false;
do
@ -101,12 +114,14 @@ public:
n++;
return n;
}
bool IsFreeSlot(int i) { return !!m_flags[i].free; }
void ClearStorage(uint8 *&flags, U *&entries){
free(flags);
free(entries);
flags = nil;
entries = nil;
}
uint32 GetMaxEntrySize() const { return sizeof(U); }
void CopyBack(uint8 *&flags, U *&entries){
memcpy(m_flags, flags, sizeof(uint8)*m_size);
memcpy(m_entries, entries, sizeof(U)*m_size);

View File

@ -127,20 +127,14 @@ public:
}
void Scale(float scale)
{
// GTA treats this as 4x4 floats
m_matrix.right.x *= scale;
m_matrix.right.y *= scale;
m_matrix.right.z *= scale;
m_matrix.up.x *= scale;
m_matrix.up.y *= scale;
m_matrix.up.z *= scale;
m_matrix.at.x *= scale;
m_matrix.at.y *= scale;
m_matrix.at.z *= scale;
m_matrix.pos.x *= scale;
m_matrix.pos.y *= scale;
m_matrix.pos.z *= scale;
m_matrix.flags = 0;
float *pFloatMatrix = (float*)&m_matrix;
for (int i = 0; i < 3; i++)
#ifdef FIX_BUGS // BUGFIX from VC
for (int j = 0; j < 3; j++)
#else
for (int j = 0; j < 4; j++)
#endif
pFloatMatrix[i * 4 + j] *= scale;
}

View File

@ -45,7 +45,6 @@
#include "CarAI.h"
#include "Zones.h"
#include "Cranes.h"
#include "MusicManager.h"
#include "Timecycle.h"
#include "ParticleObject.h"
#include "Floater.h"
@ -59,7 +58,6 @@ WRAPPER void CPed::UpdatePosition(void) { EAXJMP(0x4C7A00); }
WRAPPER void CPed::WanderPath(void) { EAXJMP(0x4D28D0); }
WRAPPER void CPed::SeekCar(void) { EAXJMP(0x4D3F90); }
WRAPPER void CPed::UpdateFromLeader(void) { EAXJMP(0x4D8F30); }
WRAPPER int CPed::ScanForThreats(void) { EAXJMP(0x4C5FE0); }
WRAPPER void CPed::SetEnterCar_AllClear(CVehicle*, uint32, uint32) { EAXJMP(0x4E0A40); }
WRAPPER bool CPed::WarpPedToNearEntityOffScreen(CEntity*) { EAXJMP(0x4E5570); }
WRAPPER void CPed::SetObjective(eObjective, CVector) { EAXJMP(0x4D8A90); }
@ -3245,7 +3243,7 @@ CPed::CheckForGunShots(void)
int event;
if (CEventList::FindClosestEvent(EVENT_GUNSHOT, GetPosition(), &event)) {
if (gaEvent[event].entityType == EVENT_ENTITY_PED) {
// Is that a bug?!? (same on VC)
// Probably due to we don't want peds to go gunshot area? (same on VC)
m_ped_flagD2 = false;
return CPools::GetPed(gaEvent[event].entityRef);
}
@ -12357,7 +12355,7 @@ CPed::ProcessObjective(void)
SetLookTimer(CGeneral::GetRandomNumberInRange(500, 1500));
// Second condition is pointless and isn't there in Mobile.
if (threatType == 0x100000 || (threatType == 0x800000 && m_threatEntity) || m_threatEntity) {
if (threatType == PED_FLAG_GUN || (threatType == PED_FLAG_EXPLOSION && m_threatEntity) || m_threatEntity) {
if (m_threatEntity->IsPed())
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
}
@ -15236,6 +15234,346 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
}
}
void
CPed::ScanForInterestingStuff(void)
{
if (!IsPedInControl())
return;
if (m_objective != OBJECTIVE_NONE)
return;
if (CharCreatedBy == MISSION_CHAR)
return;
LookForSexyPeds();
LookForSexyCars();
if (LookForInterestingNodes())
return;
if (m_nPedType == PEDTYPE_CRIMINAL && m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) {
if (CGeneral::GetRandomNumber() % 100 >= 10) {
if (m_objective != OBJECTIVE_MUG_CHAR && !(CGeneral::GetRandomNumber() & 7)) {
CPed *charToMug = nil;
for (int i = 0; i < m_numNearPeds; ++i) {
CPed *nearPed = m_nearPeds[i];
if ((nearPed->GetPosition() - GetPosition()).MagnitudeSqr() > 49.0f)
break;
if ((nearPed->m_nPedType == PEDTYPE_CIVFEMALE || nearPed->m_nPedType == PEDTYPE_CIVMALE
|| nearPed->m_nPedType == PEDTYPE_CRIMINAL || nearPed->m_nPedType == PEDTYPE_UNUSED1
|| nearPed->m_nPedType == PEDTYPE_PROSTITUTE)
&& nearPed->CharCreatedBy != MISSION_CHAR
&& nearPed->IsPedShootable()
&& nearPed->m_objective != OBJECTIVE_MUG_CHAR) {
charToMug = nearPed;
break;
}
}
if (charToMug)
SetObjective(OBJECTIVE_MUG_CHAR, charToMug);
m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
}
} else {
int mostExpensiveVehAround = -1;
int bestMonetaryValue = 0;
CVector pos = GetPosition();
int16 lastVehicle;
CEntity *vehicles[8];
CWorld::FindObjectsInRange(pos, 10.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
for (int i = 0; i < lastVehicle; i++) {
CVehicle* veh = (CVehicle*)vehicles[i];
if (veh->VehicleCreatedBy != MISSION_VEHICLE) {
if (veh->m_vecMoveSpeed.Magnitude() <= 0.1f && veh->IsVehicleNormal()
&& veh->IsCar() && bestMonetaryValue < veh->pHandling->nMonetaryValue) {
mostExpensiveVehAround = i;
bestMonetaryValue = veh->pHandling->nMonetaryValue;
}
}
}
if (bestMonetaryValue > 2000 && mostExpensiveVehAround != -1 && vehicles[mostExpensiveVehAround]) {
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, vehicles[mostExpensiveVehAround]);
m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
return;
}
m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
}
}
if (m_nPedState == PEDTYPE_CIVFEMALE) {
#ifndef VC_PED_PORTS
if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
// += 2 is weird
for (int i = 0; i < m_numNearPeds; i += 2) {
if (m_nearPeds[i]->m_nPedState == PED_WANDER_PATH && WillChat(m_nearPeds[i])) {
if (CGeneral::GetRandomNumberInRange(0, 100) >= 100)
m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000;
else {
if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() >= 1.8f) {
m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000;
} else if (CanSeeEntity(m_nearPeds[i], DEGTORAD(60.0f))) {
int time = CGeneral::GetRandomNumber() % 4000 + 10000;
SetChat(m_nearPeds[i], time);
m_nearPeds[i]->SetChat(this, time);
return;
}
}
}
}
}
#else
if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) >= 0.5f) {
m_standardTimer = CTimer::GetTimeInMilliseconds() + 200;
} else {
if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
for (int i = 0; i < m_numNearPeds; i ++) {
if (m_nearPeds[i]->m_nPedState == PED_WANDER_PATH) {
if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 1.8f
&& CanSeeEntity(m_nearPeds[i], DEGTORAD(60.0f)
&& m_nearPeds[i]->CanSeeEntity(this, DEGTORAD(60.0f)))
&& WillChat(m_nearPeds[i])) {
int time = CGeneral::GetRandomNumber() % 4000 + 10000;
SetChat(m_nearPeds[i], time);
m_nearPeds[i]->SetChat(this, time);
return;
}
}
}
}
}
#endif
}
// Parts below aren't there in VC, they're in somewhere else.
if (!CGame::noProstitutes && m_nPedType == PEDTYPE_PROSTITUTE && CharCreatedBy != MISSION_CHAR
&& m_objectiveTimer < CTimer::GetTimeInMilliseconds() && !CTheScripts::IsPlayerOnAMission()) {
CVector pos = GetPosition();
int16 lastVehicle;
CEntity* vehicles[8];
CWorld::FindObjectsInRange(pos, 15.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
for (int i = 0; i < lastVehicle; i++) {
CVehicle* veh = (CVehicle*)vehicles[i];
if (veh->IsVehicleNormal()) {
if (veh->IsCar()) {
if ((GetPosition() - veh->GetPosition()).Magnitude() < 5.0f && veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil)) {
SetObjective(OBJECTIVE_SOLICIT, veh);
Say(SOUND_PED_SOLICIT);
return;
}
}
}
}
}
if (m_nPedType == PEDTYPE_CIVMALE || m_nPedType == PEDTYPE_CIVFEMALE) {
CVector pos = GetPosition();
int16 lastVehicle;
CEntity* vehicles[8];
CWorld::FindObjectsInRange(pos, 15.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
for (int i = 0; i < lastVehicle; i++) {
CVehicle* veh = (CVehicle*)vehicles[i];
if (veh->m_modelIndex == MI_MRWHOOP) {
if (veh->m_status != STATUS_ABANDONED && veh->m_status != STATUS_WRECKED) {
if ((GetPosition() - veh->GetPosition()).Magnitude() < 5.0f) {
SetObjective(OBJECTIVE_BUY_ICE_CREAM, veh);
return;
}
}
}
}
}
}
uint32
CPed::ScanForThreats(void)
{
int fearFlags = m_fearFlags;
CVector ourPos = GetPosition();
float closestPedDist = 60.0f;
CVector2D explosionPos = GetPosition();
if (fearFlags & PED_FLAG_EXPLOSION && CheckForExplosions(explosionPos)) {
m_eventOrThreat = explosionPos;
return PED_FLAG_EXPLOSION;
}
CPed *shooter = nil;
if ((fearFlags & PED_FLAG_GUN) && (shooter = CheckForGunShots()) && (m_nPedType != shooter->m_nPedType || m_nPedType == PEDTYPE_CIVMALE || m_nPedType == PEDTYPE_CIVFEMALE)) {
if (!IsGangMember()) {
m_threatEntity = shooter;
m_threatEntity->RegisterReference((CEntity **) &m_threatEntity);
return PED_FLAG_GUN;
}
if (CPedType::GetFlag(shooter->m_nPedType) & fearFlags) {
m_threatEntity = shooter;
m_threatEntity->RegisterReference((CEntity **) &m_threatEntity);
return CPedType::GetFlag(shooter->m_nPedType);
}
}
CPed *deadPed = nil;
if (fearFlags & PED_FLAG_DEADPEDS && CharCreatedBy != MISSION_CHAR
&& (deadPed = CheckForDeadPeds()) != nil && (deadPed->GetPosition() - ourPos).MagnitudeSqr() < 400.0f) {
m_pEventEntity = deadPed;
m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity);
return PED_FLAG_DEADPEDS;
} else {
uint32 flagsOfSomePed = 0;
CPed *pedToFearFrom = nil;
#ifndef VC_PED_PORTS
for (int i = 0; i < m_numNearPeds; i++) {
if (CharCreatedBy != RANDOM_CHAR || m_nearPeds[i]->CharCreatedBy != MISSION_CHAR || m_nearPeds[i]->IsPlayer()) {
CPed *nearPed = m_nearPeds[i];
// BUG: WTF Rockstar?! Putting this here will result in returning the flags of farthest ped to us, since m_nearPeds is sorted by distance.
// Fixed at the bottom of the function.
flagsOfSomePed = CPedType::GetFlag(nearPed->m_nPedType);
if (CPedType::GetFlag(nearPed->m_nPedType) & fearFlags) {
if (nearPed->m_fHealth > 0.0f && OurPedCanSeeThisOne(m_nearPeds[i])) {
// FIX: Taken from VC
#ifdef FIX_BUGS
float nearPedDistSqr = (nearPed->GetPosition() - ourPos).MagnitudeSqr2D();
#else
float nearPedDistSqr = (CVector2D(ourPos) - explosionPos).MagnitudeSqr();
#endif
if (sq(closestPedDist) > nearPedDistSqr) {
closestPedDist = Sqrt(nearPedDistSqr);
pedToFearFrom = m_nearPeds[i];
}
}
}
}
}
#else
bool weSawOurEnemy = false;
bool weMaySeeOurEnemy = false;
float closestEnemyDist = 60.0f;
if ((CTimer::GetFrameCounter() + (uint8)m_randomSeed + 16) & 4) {
for (int i = 0; i < m_numNearPeds; ++i) {
if (CharCreatedBy == RANDOM_CHAR && m_nearPeds[i]->CharCreatedBy == MISSION_CHAR && !m_nearPeds[i]->IsPlayer()) {
continue;
}
// BUG: Explained at the same occurence of this bug above. Fixed at the bottom of the function.
flagsOfSomePed = CPedType::GetFlag(m_nearPeds[i]->m_nPedType);
if (flagsOfSomePed & fearFlags) {
if (m_nearPeds[i]->m_fHealth > 0.0f) {
// VC also has ability to include objects to line of sight check here (via last bit of flagsL)
if (OurPedCanSeeThisOne(m_nearPeds[i])) {
if (m_nearPeds[i]->m_nPedState == PED_ATTACK) {
if (m_nearPeds[i]->m_pedInObjective == this) {
float enemyDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
if (sq(closestEnemyDist) > enemyDistSqr) {
float enemyDist = Sqrt(enemyDistSqr);
weSawOurEnemy = true;
closestPedDist = enemyDist;
closestEnemyDist = enemyDist;
pedToFearFrom = m_nearPeds[i];
}
}
} else {
float nearPedDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
if (sq(closestPedDist) > nearPedDistSqr && !weSawOurEnemy) {
closestPedDist = Sqrt(nearPedDistSqr);
pedToFearFrom = m_nearPeds[i];
}
}
} else if (!weSawOurEnemy) {
CPed *nearPed = m_nearPeds[i];
if (nearPed->m_nPedState == PED_ATTACK) {
CColPoint foundCol;
CEntity *foundEnt;
// We don't see him yet but he's behind a ped, vehicle or object
// VC also has ability to include objects to line of sight check here (via last bit of flagsL)
if (!CWorld::ProcessLineOfSight(ourPos, nearPed->GetPosition(), foundCol, foundEnt,
true, false, false, false, false, false, false)) {
if (nearPed->m_pedInObjective == this) {
float enemyDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
if (sq(closestEnemyDist) > enemyDistSqr) {
float enemyDist = Sqrt(enemyDistSqr);
weMaySeeOurEnemy = true;
closestPedDist = enemyDist;
closestEnemyDist = enemyDist;
pedToFearFrom = m_nearPeds[i];
}
} else if (!nearPed->GetWeapon()->IsTypeMelee() && !weMaySeeOurEnemy) {
float nearPedDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
if (sq(closestPedDist) > nearPedDistSqr) {
weMaySeeOurEnemy = true;
closestPedDist = Sqrt(nearPedDistSqr);
pedToFearFrom = m_nearPeds[i];
}
}
}
}
}
}
}
}
}
#endif
int16 lastVehicle;
CEntity* vehicles[8];
CWorld::FindObjectsInRange(ourPos, 20.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
CVehicle* foundVeh = nil;
for (int i = 0; i < lastVehicle; i++) {
CVehicle* nearVeh = (CVehicle*)vehicles[i];
CPed *driver = nearVeh->pDriver;
if (driver) {
// BUG: Same bug as above. Fixed at the bottom of function.
flagsOfSomePed = CPedType::GetFlag(driver->m_nPedType);
if (CPedType::GetFlag(driver->m_nPedType) & fearFlags) {
if (driver->m_fHealth > 0.0f && OurPedCanSeeThisOne(nearVeh->pDriver)) {
// FIX: Taken from VC
#ifdef FIX_BUGS
float driverDistSqr = (driver->GetPosition() - ourPos).MagnitudeSqr2D();
#else
float driverDistSqr = (CVector2D(ourPos) - explosionPos).MagnitudeSqr();
#endif
if (sq(closestPedDist) > driverDistSqr) {
closestPedDist = Sqrt(driverDistSqr);
pedToFearFrom = nearVeh->pDriver;
}
}
}
}
}
m_threatEntity = pedToFearFrom;
if (m_threatEntity)
m_threatEntity->RegisterReference((CEntity **) &m_threatEntity);
#ifdef FIX_BUGS
if (pedToFearFrom)
flagsOfSomePed = CPedType::GetFlag(((CPed*)m_threatEntity)->m_nPedType);
else
flagsOfSomePed = 0;
#endif
return flagsOfSomePed;
}
}
class CPed_ : public CPed
{
public:
@ -15451,4 +15789,6 @@ STARTPATCHES
InjectHook(0x4D6620, &CPed::SetSolicit, PATCH_JUMP);
InjectHook(0x4D2EA0, &CPed::SetFollowPath, PATCH_JUMP);
InjectHook(0x4E1010, &CPed::SetExitCar, PATCH_JUMP);
InjectHook(0x4C5FE0, &CPed::ScanForThreats, PATCH_JUMP);
InjectHook(0x4C6C10, &CPed::ScanForInterestingStuff, PATCH_JUMP);
ENDPATCHES

View File

@ -669,7 +669,7 @@ public:
bool PlacePedOnDryLand(void);
bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*);
void UpdateFromLeader(void);
int ScanForThreats(void);
uint32 ScanForThreats(void);
void SetEnterCar(CVehicle*, uint32);
bool WarpPedToNearEntityOffScreen(CEntity*);
void SetExitCar(CVehicle*, uint32);
@ -678,6 +678,7 @@ public:
void SetEnterTrain(CVehicle*, uint32);
void SetEnterCar_AllClear(CVehicle*, uint32, uint32);
void SetSolicit(uint32 time);
void ScanForInterestingStuff(void);
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);

View File

@ -10,11 +10,11 @@ WRAPPER void CPedIK::ExtractYawAndPitchLocal(RwMatrixTag*, float*, float*) { EAX
WRAPPER void CPedIK::ExtractYawAndPitchWorld(RwMatrixTag*, float*, float*) { EAXJMP(0x4ED140); }
WRAPPER bool CPedIK::RestoreLookAt(void) { EAXJMP(0x4ED810); }
// TODO: These are hardcoded into exe, reverse it.
LimbMovementInfo &CPedIK::ms_torsoInfo = *(LimbMovementInfo*)0x5F9F8C;
LimbMovementInfo &CPedIK::ms_headInfo = *(LimbMovementInfo*)0x5F9F5C;
LimbMovementInfo &CPedIK::ms_upperArmInfo = *(LimbMovementInfo*)0x5F9FA4;
LimbMovementInfo &CPedIK::ms_lowerArmInfo = *(LimbMovementInfo*)0x5F9FBC;
LimbMovementInfo CPedIK::ms_torsoInfo = { DEGTORAD(50.0f), DEGTORAD(-50.0f), DEGTORAD(15.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(7.0f) };
LimbMovementInfo CPedIK::ms_headInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
LimbMovementInfo CPedIK::ms_headRestoreInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(10.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
LimbMovementInfo CPedIK::ms_upperArmInfo = { DEGTORAD(20.0f), DEGTORAD(-100.0f), DEGTORAD(20.0f), DEGTORAD(70.0f), DEGTORAD(-70.0f), DEGTORAD(10.0f) };
LimbMovementInfo CPedIK::ms_lowerArmInfo = { DEGTORAD(80.0f), DEGTORAD(0.0f), DEGTORAD(20.0f), DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(5.0f) };
CPedIK::CPedIK(CPed *ped)
{

View File

@ -42,10 +42,11 @@ public:
LimbOrientation m_lowerArmOrient;
int32 m_flags;
static LimbMovementInfo &ms_torsoInfo;
static LimbMovementInfo &ms_headInfo;
static LimbMovementInfo &ms_upperArmInfo;
static LimbMovementInfo &ms_lowerArmInfo;
static LimbMovementInfo ms_torsoInfo;
static LimbMovementInfo ms_headInfo;
static LimbMovementInfo ms_headRestoreInfo;
static LimbMovementInfo ms_upperArmInfo;
static LimbMovementInfo ms_lowerArmInfo;
CPedIK(CPed *ped);
bool PointGunInDirection(float phi, float theta);

View File

@ -17,3 +17,4 @@ CGlass::WindowRespondsToSoftCollision(CEntity *ent, float amount)
}
WRAPPER void CGlass::Render(void) { EAXJMP(0x502350); }
WRAPPER void CGlass::Update(void) { EAXJMP(0x502050); }

View File

@ -9,4 +9,5 @@ public:
static void WindowRespondsToCollision(CEntity *ent, float amount, CVector speed, CVector point, bool foo);
static void WindowRespondsToSoftCollision(CEntity *ent, float amount);
static void Render(void);
static void Update(void);
};

View File

@ -637,6 +637,7 @@ void CHud::Draw()
/*
DrawOnScreenTimer
*/
wchar sTimer[16];
if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed)
@ -697,7 +698,7 @@ void CHud::Draw()
if (CTimer::GetFrameCounter() & 4 || !CounterFlashTimer) {
if (CUserDisplay::OnscnTimer.m_sEntries[0].m_nType) {
CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_FROM_RIGHT(27.0f) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 80));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_X(atoi(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer)) / 2 + SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_FROM_RIGHT(27.0f) - SCREEN_SCALE_X(100.0f) / 2 + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_X(atoi(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer)) / 2 + SCREEN_SCALE_FROM_RIGHT(27.0f + 50.0f) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(11.0f) + SCREEN_SCALE_Y(8.0f)), CRGBA(0, 106, 164, 255));
} else {
AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer, sTimer);
CFont::SetPropOn();

View File

@ -12,6 +12,10 @@
#include "ParticleObject.h"
#include "Particle.h"
#ifndef MASTER
bool CParticle::bEnableBannedParticles = false;
#endif
#define MAX_PARTICLES_ON_SCREEN (1000)
@ -768,7 +772,9 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
{
if ( CTimer::GetIsPaused() )
return NULL;
#ifndef MASTER
if(!bEnableBannedParticles)
#endif
if ( ( type == PARTICLE_ENGINE_SMOKE
|| type == PARTICLE_ENGINE_SMOKE2
|| type == PARTICLE_ENGINE_STEAM
@ -781,7 +787,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
{
return nil;
}
CParticle *pParticle = m_pUnusedListHead;
if ( pParticle == nil )
@ -1455,7 +1461,10 @@ void CParticle::Render()
RwRaster **frames = psystem->m_ppRaster;
tParticleType type = psystem->m_Type;
#ifndef MASTER
if (!bEnableBannedParticles)
#endif
if ( type == PARTICLE_ENGINE_SMOKE
|| type == PARTICLE_ENGINE_SMOKE2
|| type == PARTICLE_ENGINE_STEAM

View File

@ -97,6 +97,9 @@ public:
static void AddJetExplosion(CVector const &vecPos, float fPower, float fSize);
static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix);
#ifndef MASTER
static bool bEnableBannedParticles;
#endif
};
VALIDATE_SIZE(CParticle, 0x68);

View File

@ -4,3 +4,4 @@
WRAPPER void CRubbish::Render(void) { EAXJMP(0x512190); }
WRAPPER void CRubbish::StirUp(CVehicle *veh) { EAXJMP(0x512690); }
WRAPPER void CRubbish::Update(void) { EAXJMP(0x511B90); }

View File

@ -7,4 +7,5 @@ class CRubbish
public:
static void Render(void);
static void StirUp(CVehicle *veh); // CAutomobile on PS2
static void Update(void);
};

View File

@ -3,6 +3,7 @@
#include "Skidmarks.h"
WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); }
WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); }
WRAPPER void CSkidmarks::Render(void) { EAXJMP(0x5182E0); }
WRAPPER void CSkidmarks::RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy) { EAXJMP(0x5185C0); }

View File

@ -4,6 +4,7 @@ class CSkidmarks
{
public:
static void Clear(void);
static void Update(void);
static void Render(void);
static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy);
};

View File

@ -5,8 +5,15 @@
#include "Sprite.h"
#include "Font.h"
#include "Text.h"
#include "TxdStore.h"
#include "FileMgr.h"
#include "FileLoader.h"
#include "Lights.h"
#include "VisibilityPlugins.h"
#include "World.h"
WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); }
WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); }
WRAPPER void CMotionBlurStreaks::RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { EAXJMP(0x519460); }
@ -17,9 +24,290 @@ WRAPPER void CBulletTraces::Init(void) { EAXJMP(0x518DE0); }
WRAPPER void CBrightLights::RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1, uint8 unk2, uint8 unk3) { EAXJMP(0x51A410); }
WRAPPER void C3dMarkers::PlaceMarkerSet(uint32 id, uint16 type, CVector& pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate) { EAXJMP(0x51BB80); }
RpAtomic *
MarkerAtomicCB(RpAtomic *atomic, void *data)
{
*(RpAtomic**)data = atomic;
return atomic;
}
bool
C3dMarker::AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
{
m_nIdentifier = identifier;
m_Matrix.SetUnity();
RpAtomic *origAtomic;
origAtomic = nil;
RpClumpForAllAtomics(C3dMarkers::m_pRpClumpArray[type], MarkerAtomicCB, &origAtomic);
RpAtomic *atomic = RpAtomicClone(origAtomic);
RwFrame *frame = RwFrameCreate();
RpAtomicSetFrame(atomic, frame);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
RpGeometry *geometry = RpAtomicGetGeometry(atomic);
RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
m_pAtomic = atomic;
m_Matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
m_pMaterial = RpGeometryGetMaterial(geometry, 0);
m_fSize = fSize;
m_fStdSize = m_fSize;
m_Color.red = r;
m_Color.green = g;
m_Color.blue = b;
m_Color.alpha = a;
m_nPulsePeriod = pulsePeriod;
m_fPulseFraction = pulseFraction;
m_nRotateRate = rotateRate;
m_nStartTime = CTimer::GetTimeInMilliseconds();
m_nType = type;
return m_pAtomic != nil;
}
void
C3dMarker::DeleteMarkerObject()
{
RwFrame *frame;
m_nIdentifier = 0;
m_nStartTime = 0;
m_bIsUsed = false;
m_nType = MARKERTYPE_INVALID;
frame = RpAtomicGetFrame(m_pAtomic);
RpAtomicDestroy(m_pAtomic);
RwFrameDestroy(frame);
m_pAtomic = nil;
}
void
C3dMarker::Render()
{
if (m_pAtomic == nil) return;
RwRGBA *color = RpMaterialGetColor(m_pMaterial);
*color = m_Color;
m_Matrix.UpdateRW();
CMatrix matrix;
matrix.Attach(m_Matrix.m_attachment);
matrix.Scale(m_fSize);
matrix.UpdateRW();
RwFrameUpdateObjects(RpAtomicGetFrame(m_pAtomic));
SetBrightMarkerColours(m_fBrightness);
if (m_nType != MARKERTYPE_ARROW)
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RpAtomicRender(m_pAtomic);
if (m_nType != MARKERTYPE_ARROW)
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
ReSetAmbientAndDirectionalColours();
}
C3dMarker(&C3dMarkers::m_aMarkerArray)[NUM3DMARKERS] = *(C3dMarker(*)[NUM3DMARKERS])*(uintptr*)0x72D408;
int32 &C3dMarkers::NumActiveMarkers = *(int32*)0x8F2A08;
RpClump* (&C3dMarkers::m_pRpClumpArray)[NUMMARKERTYPES] = *(RpClump*(*)[NUMMARKERTYPES])*(uintptr*)0x8E2888;
void
C3dMarkers::Init()
{
for (int i = 0; i < NUM3DMARKERS; i++) {
m_aMarkerArray[i].m_pAtomic = nil;
m_aMarkerArray[i].m_nType = MARKERTYPE_INVALID;
m_aMarkerArray[i].m_bIsUsed = false;
m_aMarkerArray[i].m_nIdentifier = 0;
m_aMarkerArray[i].m_Color.red = 255;
m_aMarkerArray[i].m_Color.green = 255;
m_aMarkerArray[i].m_Color.blue = 255;
m_aMarkerArray[i].m_Color.alpha = 255;
m_aMarkerArray[i].m_nPulsePeriod = 1024;
m_aMarkerArray[i].m_nRotateRate = 5;
m_aMarkerArray[i].m_nStartTime = 0;
m_aMarkerArray[i].m_fPulseFraction = 0.25f;
m_aMarkerArray[i].m_fStdSize = 1.0f;
m_aMarkerArray[i].m_fSize = 1.0f;
m_aMarkerArray[i].m_fBrightness = 1.0f;
m_aMarkerArray[i].m_fCameraRange = 0.0f;
}
NumActiveMarkers = 0;
int txdSlot = CTxdStore::FindTxdSlot("particle");
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(txdSlot);
CFileMgr::ChangeDir("\\");
m_pRpClumpArray[MARKERTYPE_ARROW] = CFileLoader::LoadAtomicFile2Return("models/generic/arrow.dff");
m_pRpClumpArray[MARKERTYPE_CYLINDER] = CFileLoader::LoadAtomicFile2Return("models/generic/zonecylb.dff");
CTxdStore::PopCurrentTxd();
}
void
C3dMarkers::Shutdown()
{
for (int i = 0; i < NUM3DMARKERS; i++) {
if (m_aMarkerArray[i].m_pAtomic != nil)
m_aMarkerArray[i].DeleteMarkerObject();
}
for (int i = 0; i < NUMMARKERTYPES; i++) {
if (m_pRpClumpArray[i] != nil)
RpClumpDestroy(m_pRpClumpArray[i]);
}
}
void
C3dMarkers::Render()
{
NumActiveMarkers = 0;
ActivateDirectional();
for (int i = 0; i < NUM3DMARKERS; i++) {
if (m_aMarkerArray[i].m_bIsUsed) {
if (m_aMarkerArray[i].m_fCameraRange < 120.0f)
m_aMarkerArray[i].Render();
NumActiveMarkers++;
m_aMarkerArray[i].m_bIsUsed = false;
} else if (m_aMarkerArray[i].m_pAtomic != nil) {
m_aMarkerArray[i].DeleteMarkerObject();
}
}
}
C3dMarker *
C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
{
C3dMarker *pMarker;
pMarker = nil;
float dist = Sqrt((pos.x - FindPlayerCentreOfWorld(0).x) * (pos.x - FindPlayerCentreOfWorld(0).x) + (pos.y - FindPlayerCentreOfWorld(0).y) * (pos.y - FindPlayerCentreOfWorld(0).y));
if (type != MARKERTYPE_ARROW && type != MARKERTYPE_CYLINDER) return nil;
for (int i = 0; i < NUM3DMARKERS; i++) {
if (!m_aMarkerArray[i].m_bIsUsed && m_aMarkerArray[i].m_nIdentifier == identifier) {
pMarker = &m_aMarkerArray[i];
break;
}
}
if (pMarker == nil) {
for (int i = 0; i < NUM3DMARKERS; i++) {
if (m_aMarkerArray[i].m_nType == MARKERTYPE_INVALID) {
pMarker = &m_aMarkerArray[i];
break;
}
}
}
if (pMarker == nil && type == MARKERTYPE_ARROW) {
for (int i = 0; i < NUM3DMARKERS; i++) {
if (dist < m_aMarkerArray[i].m_fCameraRange && m_aMarkerArray[i].m_nType == MARKERTYPE_ARROW && (pMarker == nil || m_aMarkerArray[i].m_fCameraRange > pMarker->m_fCameraRange)) {
pMarker = &m_aMarkerArray[i];
break;
}
}
if (pMarker != nil)
pMarker->m_nType = MARKERTYPE_INVALID;
}
if (pMarker == nil) return pMarker;
pMarker->m_fCameraRange = dist;
if (pMarker->m_nIdentifier == identifier && pMarker->m_nType == type) {
if (type == MARKERTYPE_ARROW) {
if (dist < 25.0f) {
if (dist > 5.0f)
pMarker->m_fStdSize = size - (25.0f - dist) * (0.3f * size) / 20.0f;
else
pMarker->m_fStdSize = size - 0.3f * size;
} else {
pMarker->m_fStdSize = size;
}
} else if (type == MARKERTYPE_CYLINDER) {
if (dist < size + 12.0f) {
if (dist > size + 1.0f)
pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a;
else
pMarker->m_Color.alpha = (float)a * 0.3f;
} else {
pMarker->m_Color.alpha = a;
}
}
float someSin = Sin(TWOPI * (float)((pMarker->m_nPulsePeriod - 1) & (CTimer::GetTimeInMilliseconds() - pMarker->m_nStartTime)) / (float)pMarker->m_nPulsePeriod);
pMarker->m_fSize = pMarker->m_fStdSize - pulseFraction * pMarker->m_fStdSize * someSin;
if (type == MARKERTYPE_ARROW) {
pos.z += 0.25f * pMarker->m_fStdSize * someSin;
} else if (type == MARKERTYPE_0) {
if (someSin > 0.0f)
pMarker->m_Color.alpha = (float)a * 0.7f * someSin + a;
else
pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a;
}
if (pMarker->m_nRotateRate) {
RwV3d pos = pMarker->m_Matrix.m_matrix.pos;
pMarker->m_Matrix.RotateZ(DEGTORAD(pMarker->m_nRotateRate * CTimer::GetTimeStep()));
pMarker->m_Matrix.GetPosition() = pos;
}
if (type == MARKERTYPE_ARROW)
pMarker->m_Matrix.GetPosition() = pos;
pMarker->m_bIsUsed = true;
return pMarker;
}
if (pMarker->m_nIdentifier != 0)
pMarker->DeleteMarkerObject();
pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate);
if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) {
float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil);
if (z != 0.0f)
pos.z = z - 0.05f * size;
}
pMarker->m_Matrix.SetTranslate(pos.x, pos.y, pos.z);
if (type == MARKERTYPE_2) {
pMarker->m_Matrix.RotateX(PI);
pMarker->m_Matrix.GetPosition() = pos;
}
pMarker->m_Matrix.UpdateRW();
if (type == MARKERTYPE_ARROW) {
if (dist < 25.0f) {
if (dist > 5.0f)
pMarker->m_fStdSize = size - (25.0f - dist) * (0.3f * size) / 20.0f;
else
pMarker->m_fStdSize = size - 0.3f * size;
} else {
pMarker->m_fStdSize = size;
}
} else if (type == MARKERTYPE_CYLINDER) {
if (dist < size + 12.0f) {
if (dist > size + 1.0f)
pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a;
else
pMarker->m_Color.alpha = (float)a * 0.3f;
} else {
pMarker->m_Color.alpha = a;
}
}
pMarker->m_bIsUsed = true;
return pMarker;
}
void
C3dMarkers::PlaceMarkerSet(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
{
PlaceMarker(id, type, pos, size, r, g, b, a, pulsePeriod, pulseFraction, 1);
PlaceMarker(id, type, pos, size * 0.93f, r, g, b, a, pulsePeriod, pulseFraction, 2);
PlaceMarker(id, type, pos, size * 0.86f, r, g, b, a, pulsePeriod, pulseFraction, -1);
}
void
C3dMarkers::Update()
{
}
#define MONEY_MESSAGE_LIFETIME_MS 2000
@ -96,6 +384,15 @@ CMoneyMessages::RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8
}
STARTPATCHES
InjectHook(0x51B070, &C3dMarker::AddMarker, PATCH_JUMP);
InjectHook(0x51B170, &C3dMarker::DeleteMarkerObject, PATCH_JUMP);
InjectHook(0x51B1B0, &C3dMarker::Render, PATCH_JUMP);
InjectHook(0x51B2B0, C3dMarkers::Init, PATCH_JUMP);
InjectHook(0x51B480, C3dMarkers::PlaceMarker, PATCH_JUMP);
InjectHook(0x51BB80, C3dMarkers::PlaceMarkerSet, PATCH_JUMP);
InjectHook(0x51B400, C3dMarkers::Render, PATCH_JUMP);
InjectHook(0x51B3B0, C3dMarkers::Shutdown, PATCH_JUMP);
InjectHook(0x51AF70, CMoneyMessages::Init, PATCH_JUMP);
InjectHook(0x51B030, CMoneyMessages::Render, PATCH_JUMP);
ENDPATCHES

View File

@ -4,6 +4,7 @@ class CSpecialFX
{
public:
static void Render(void);
static void Update(void);
};
class CMotionBlurStreaks
@ -35,10 +36,56 @@ public:
static void RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1 = 0, uint8 unk2 = 0, uint8 unk3 = 0);
};
enum
{
MARKERTYPE_0 = 0,
MARKERTYPE_ARROW,
MARKERTYPE_2,
MARKERTYPE_3,
MARKERTYPE_CYLINDER,
NUMMARKERTYPES,
MARKERTYPE_INVALID = 0x101
};
class C3dMarker
{
public:
CMatrix m_Matrix;
RpAtomic *m_pAtomic;
RpMaterial *m_pMaterial;
uint16 m_nType;
bool m_bIsUsed;
uint32 m_nIdentifier;
RwRGBA m_Color;
uint16 m_nPulsePeriod;
int16 m_nRotateRate;
uint32 m_nStartTime;
float m_fPulseFraction;
float m_fStdSize;
float m_fSize;
float m_fBrightness;
float m_fCameraRange;
bool AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
void DeleteMarkerObject();
void Render();
};
class C3dMarkers
{
public:
static void PlaceMarkerSet(uint32 id, uint16 type, CVector& pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
static void Init();
static void Shutdown();
static C3dMarker *PlaceMarker(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
static void PlaceMarkerSet(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
static void Render();
static void Update();
static C3dMarker(&m_aMarkerArray)[NUM3DMARKERS];
static int32 &NumActiveMarkers;
static RpClump* (&m_pRpClumpArray)[NUMMARKERTYPES];
};
class CMoneyMessage

View File

@ -7,6 +7,7 @@
#include "Renderer.h"
#include "Camera.h"
#include "VisibilityPlugins.h"
#include "World.h"
#define FADE_DISTANCE 20.0f
@ -43,7 +44,7 @@ CVisibilityPlugins::Initialise(void)
m_alphaList.Init(20);
m_alphaList.head.item.sort = 0.0f;
m_alphaList.tail.item.sort = 100000000.0f;
m_alphaEntityList.Init(350); // TODO: set back to 150 when things are fixed
m_alphaEntityList.Init(150);
m_alphaEntityList.head.item.sort = 0.0f;
m_alphaEntityList.tail.item.sort = 100000000.0f;
}
@ -498,14 +499,11 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
return atomic;
}
// TODO: this is part of a struct
static RwTexture *&playerskin = *(RwTexture**)0x941428;
RpAtomic*
CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
{
if(playerskin)
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, playerskin);
if(CWorld::Players[0].m_pSkinTexture)
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
AtomicDefaultRenderCallBack(atomic);
return atomic;
}
@ -607,22 +605,30 @@ CVisibilityPlugins::DefaultVisibilityCB(RpClump *clump)
bool
CVisibilityPlugins::FrustumSphereCB(RpClump *clump)
{
// TODO, but unused
return true;
RwSphere sphere;
RwFrame *frame = RpClumpGetFrame(clump);
CClumpModelInfo *modelInfo = (CClumpModelInfo*)GetFrameHierarchyId(frame);
sphere.radius = modelInfo->GetColModel()->boundingSphere.radius;
sphere.center.x = modelInfo->GetColModel()->boundingSphere.center.x;
sphere.center.y = modelInfo->GetColModel()->boundingSphere.center.y;
sphere.center.z = modelInfo->GetColModel()->boundingSphere.center.z;
RwV3dTransformPoints(&sphere.center, &sphere.center, 1, RwFrameGetLTM(frame));
return RwCameraFrustumTestSphere(ms_pCamera, &sphere) != rwSPHEREOUTSIDE;
}
bool
CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump)
{
// TODO, but unused
return true;
if (GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)) <= ms_vehicleLod1Dist)
return FrustumSphereCB(clump);
return false;
}
bool
CVisibilityPlugins::VehicleVisibilityCB_BigVehicle(RpClump *clump)
{
// TODO, but unused
return true;
return FrustumSphereCB(clump);
}

View File

@ -2,5 +2,8 @@
#include "patcher.h"
#include "WaterCannon.h"
CWaterCannon* aCannons = (CWaterCannon*)0x8F2CA8;
WRAPPER void CWaterCannons::Update(void) { EAXJMP(0x522510); }
WRAPPER void CWaterCannons::UpdateOne(uint32 id, CVector *pos, CVector *dir) { EAXJMP(0x522470); }
WRAPPER void CWaterCannons::Render(void) { EAXJMP(0x522550); }

View File

@ -1,8 +1,25 @@
#pragma once
class CWaterCannon
{
public:
int32 m_nId;
int16 m_wIndex;
char gap_6[2];
int32 m_nTimeCreated;
CVector m_avecPos[16];
CVector m_avecVelocity[16];
char m_abUsed[16];
};
static_assert(sizeof(CWaterCannon) == 412, "CWaterCannon: error");
class CWaterCannons
{
public:
static void Update();
static void UpdateOne(uint32 id, CVector *pos, CVector *dir);
static void Render(void);
};
extern CWaterCannon *aCannons;

View File

@ -33,6 +33,7 @@ int16 &CWeather::Stored_NewWeatherType = *(int16*)0x95CCAE;
float &CWeather::Stored_Rain = *(float*)0x885B4C;
WRAPPER void CWeather::RenderRainStreaks(void) { EAXJMP(0x524550); }
WRAPPER void CWeather::Update(void) { EAXJMP(0x522C10); }
void CWeather::ReleaseWeather()
{

View File

@ -38,6 +38,7 @@ public:
static float &Stored_Rain;
static void RenderRainStreaks(void);
static void Update(void);
static void ReleaseWeather();
static void ForceWeather(int16);

View File

@ -2162,7 +2162,7 @@ _WinMain(HINSTANCE instance,
CPad::ResetCheats();
CPad::StopPadsShaking();
DMAudio.ChangeMusicMode(_TODOCONST(3));
DMAudio.ChangeMusicMode(MUSICMODE_OFF);
CTimer::Stop();
@ -2170,7 +2170,7 @@ _WinMain(HINSTANCE instance,
{
CGame::ShutDownForRestart();
CGame::InitialiseWhenRestarting();
DMAudio.ChangeMusicMode(_TODOCONST(1));
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
FrontEndMenuManager.m_bLoadingSavedGame = false;
}

View File

@ -90,4 +90,5 @@ void HandleExit();
#endif /* __cplusplus */
extern DWORD &_dwOperatingSystemVersion;
#endif /* (!defined(_PLATFORM_WIN_H)) */

835
src/text/Messages.cpp Normal file
View File

@ -0,0 +1,835 @@
#define DIRECTINPUT_VERSION 0x0800
#include "dinput.h"
#include "common.h"
#include "patcher.h"
#include "Messages.h"
#include "RwHelper.h"
#include "Hud.h"
#include "User.h"
#include "Timer.h"
#include "Text.h"
#include "ControllerConfig.h"
tMessage(&CMessages::BriefMessages)[NUMBRIEFMESSAGES] = *(tMessage(*)[NUMBRIEFMESSAGES])*(uintptr*)0x8786E0;
tPreviousBrief(&CMessages::PreviousBriefs)[NUMPREVIOUSBRIEFS] = *(tPreviousBrief(*)[NUMPREVIOUSBRIEFS])*(uintptr*)0x713C08;
tBigMessage(&CMessages::BIGMessages)[NUMBIGMESSAGES] = *(tBigMessage(*)[NUMBIGMESSAGES])*(uintptr*)0x773628;
char CMessages::PreviousMissionTitle[16]; // unused
void
CMessages::Init()
{
ClearMessages();
for (int32 i = 0; i < NUMPREVIOUSBRIEFS; i++) {
PreviousBriefs[i].m_pText = nil;
PreviousBriefs[i].m_pString = nil;
}
}
uint16
CMessages::GetWideStringLength(wchar *src)
{
uint16 length = 0;
while (*(src++)) length++;
return length;
}
void
CMessages::WideStringCopy(wchar *dst, wchar *src, uint16 size)
{
int32 i = 0;
if (src) {
while (i < size - 1) {
if (!src[i]) break;
dst[i] = src[i];
i++;
}
} else {
while (i < size - 1)
dst[i++] = '\0';
}
dst[i] = '\0';
}
bool
CMessages::WideStringCompare(wchar *str1, wchar *str2, uint16 size)
{
uint16 len1 = GetWideStringLength(str1);
uint16 len2 = GetWideStringLength(str2);
if (len1 != len2 && (len1 < size || len2 < size))
return false;
for (int32 i = 0; i < size; i++) {
if (!str1[i])
break;
if (str1[i] != str2[i])
return false;
}
return true;
}
void
CMessages::Process()
{
for (int32 style = 0; style < 6; style++) {
if (BIGMessages[style].m_Stack[0].m_pText != nil && CTimer::GetTimeInMilliseconds() > BIGMessages[style].m_Stack[0].m_nTime + BIGMessages[style].m_Stack[0].m_nStartTime) {
BIGMessages[style].m_Stack[0].m_pText = nil;
int32 i = 0;
while (i < 3) {
if (BIGMessages[style].m_Stack[i + 1].m_pText == nil) break;
BIGMessages[style].m_Stack[i] = BIGMessages[style].m_Stack[i + 1];
i++;
}
BIGMessages[style].m_Stack[i].m_pText = nil;
BIGMessages[style].m_Stack[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
}
}
if (BriefMessages[0].m_pText != nil && CTimer::GetTimeInMilliseconds() > BriefMessages[0].m_nTime + BriefMessages[0].m_nStartTime) {
BriefMessages[0].m_pText = nil;
int32 i = 0;
while (i < NUMBRIEFMESSAGES-1) {
if (BriefMessages[i + 1].m_pText == nil)
break;
BriefMessages[i] = BriefMessages[i + 1];
i++;
}
CMessages::BriefMessages[i].m_pText = nil;
CMessages::BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
if (BriefMessages[0].m_pText != nil)
AddToPreviousBriefArray(
BriefMessages[0].m_pText,
BriefMessages[0].m_nNumber[0],
BriefMessages[0].m_nNumber[1],
BriefMessages[0].m_nNumber[2],
BriefMessages[0].m_nNumber[3],
BriefMessages[0].m_nNumber[4],
BriefMessages[0].m_nNumber[5],
BriefMessages[0].m_pString);
}
}
void
CMessages::Display()
{
wchar outstr[256];
DefinedState();
for (int32 i = 0; i < NUMBIGMESSAGES; i++) {
InsertNumberInString(
BIGMessages[i].m_Stack[0].m_pText,
BIGMessages[i].m_Stack[0].m_nNumber[0],
BIGMessages[i].m_Stack[0].m_nNumber[1],
BIGMessages[i].m_Stack[0].m_nNumber[2],
BIGMessages[i].m_Stack[0].m_nNumber[3],
BIGMessages[i].m_Stack[0].m_nNumber[4],
BIGMessages[i].m_Stack[0].m_nNumber[5],
outstr);
InsertStringInString(outstr, BIGMessages[i].m_Stack[0].m_pString);
InsertPlayerControlKeysInString(outstr);
CHud::SetBigMessage(outstr, i);
}
InsertNumberInString(
BriefMessages[0].m_pText,
BriefMessages[0].m_nNumber[0],
BriefMessages[0].m_nNumber[1],
BriefMessages[0].m_nNumber[2],
BriefMessages[0].m_nNumber[3],
BriefMessages[0].m_nNumber[4],
BriefMessages[0].m_nNumber[5],
outstr);
InsertStringInString(outstr, BriefMessages[0].m_pString);
InsertPlayerControlKeysInString(outstr);
CHud::SetMessage(outstr);
}
void
CMessages::AddMessage(wchar *msg, uint32 time, uint16 flag)
{
wchar outstr[512]; // unused
WideStringCopy(outstr, msg, 256);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
int32 i = 0;
while (i < NUMBRIEFMESSAGES && BriefMessages[i].m_pText != nil)
i++;
if (i >= NUMBRIEFMESSAGES) return;
BriefMessages[i].m_pText = msg;
BriefMessages[i].m_nFlag = flag;
BriefMessages[i].m_nTime = time;
BriefMessages[i].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[i].m_nNumber[0] = -1;
BriefMessages[i].m_nNumber[1] = -1;
BriefMessages[i].m_nNumber[2] = -1;
BriefMessages[i].m_nNumber[3] = -1;
BriefMessages[i].m_nNumber[4] = -1;
BriefMessages[i].m_nNumber[5] = -1;
BriefMessages[i].m_pString = nil;
if (i == 0)
AddToPreviousBriefArray(
BriefMessages[0].m_pText,
BriefMessages[0].m_nNumber[0],
BriefMessages[0].m_nNumber[1],
BriefMessages[0].m_nNumber[2],
BriefMessages[0].m_nNumber[3],
BriefMessages[0].m_nNumber[4],
BriefMessages[0].m_nNumber[5],
BriefMessages[0].m_pString);
}
void
CMessages::AddMessageJumpQ(wchar *msg, uint32 time, uint16 flag)
{
wchar outstr[512]; // unused
WideStringCopy(outstr, msg, 256);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
BriefMessages[0].m_pText = msg;
BriefMessages[0].m_nFlag = flag;
BriefMessages[0].m_nTime = time;
BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[0].m_nNumber[0] = -1;
BriefMessages[0].m_nNumber[1] = -1;
BriefMessages[0].m_nNumber[2] = -1;
BriefMessages[0].m_nNumber[3] = -1;
BriefMessages[0].m_nNumber[4] = -1;
BriefMessages[0].m_nNumber[5] = -1;
BriefMessages[0].m_pString = nil;
AddToPreviousBriefArray(msg, -1, -1, -1, -1, -1, -1, 0);
}
void
CMessages::AddMessageSoon(wchar *msg, uint32 time, uint16 flag)
{
wchar outstr[512]; // unused
WideStringCopy(outstr, msg, 256);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
if (BriefMessages[0].m_pText != nil) {
for (int i = NUMBRIEFMESSAGES-1; i > 1; i--)
BriefMessages[i] = BriefMessages[i-1];
BriefMessages[1].m_pText = msg;
BriefMessages[1].m_nFlag = flag;
BriefMessages[1].m_nTime = time;
BriefMessages[1].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[1].m_nNumber[0] = -1;
BriefMessages[1].m_nNumber[1] = -1;
BriefMessages[1].m_nNumber[2] = -1;
BriefMessages[1].m_nNumber[3] = -1;
BriefMessages[1].m_nNumber[4] = -1;
BriefMessages[1].m_nNumber[5] = -1;
BriefMessages[1].m_pString = nil;
}else{
BriefMessages[0].m_pText = msg;
BriefMessages[0].m_nFlag = flag;
BriefMessages[0].m_nTime = time;
BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[0].m_nNumber[0] = -1;
BriefMessages[0].m_nNumber[1] = -1;
BriefMessages[0].m_nNumber[2] = -1;
BriefMessages[0].m_nNumber[3] = -1;
BriefMessages[0].m_nNumber[4] = -1;
BriefMessages[0].m_nNumber[5] = -1;
BriefMessages[0].m_pString = nil;
AddToPreviousBriefArray(msg, -1, -1, -1, -1, -1, -1, nil);
}
}
void
CMessages::ClearMessages()
{
for (int32 i = 0; i < NUMBIGMESSAGES; i++) {
for (int32 j = 0; j < 4; j++) {
BIGMessages[i].m_Stack[j].m_pText = nil;
BIGMessages[i].m_Stack[j].m_pString = nil;
}
}
ClearSmallMessagesOnly();
}
void
CMessages::ClearSmallMessagesOnly()
{
for (int32 i = 0; i < NUMBRIEFMESSAGES; i++) {
BriefMessages[i].m_pText = nil;
BriefMessages[i].m_pString = nil;
}
}
void
CMessages::AddBigMessage(wchar *msg, uint32 time, uint16 style)
{
wchar outstr[512]; // unused
WideStringCopy(outstr, msg, 256);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
BIGMessages[style].m_Stack[0].m_pText = msg;
BIGMessages[style].m_Stack[0].m_nFlag = 0;
BIGMessages[style].m_Stack[0].m_nTime = time;
BIGMessages[style].m_Stack[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
BIGMessages[style].m_Stack[0].m_nNumber[0] = -1;
BIGMessages[style].m_Stack[0].m_nNumber[1] = -1;
BIGMessages[style].m_Stack[0].m_nNumber[2] = -1;
BIGMessages[style].m_Stack[0].m_nNumber[3] = -1;
BIGMessages[style].m_Stack[0].m_nNumber[4] = -1;
BIGMessages[style].m_Stack[0].m_nNumber[5] = -1;
BIGMessages[style].m_Stack[0].m_pString = nil;
}
void
CMessages::AddBigMessageQ(wchar *msg, uint32 time, uint16 style)
{
wchar outstr[512]; // unused
WideStringCopy(outstr, msg, 256);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
int32 i = 0;
while (i < 4 && BIGMessages[style].m_Stack[i].m_pText != nil)
i++;
if (i >= 4) return;
BIGMessages[style].m_Stack[i].m_pText = msg;
BIGMessages[style].m_Stack[i].m_nFlag = 0;
BIGMessages[style].m_Stack[i].m_nTime = time;
BIGMessages[style].m_Stack[i].m_nStartTime = CTimer::GetTimeInMilliseconds();
BIGMessages[style].m_Stack[i].m_nNumber[0] = -1;
BIGMessages[style].m_Stack[i].m_nNumber[1] = -1;
BIGMessages[style].m_Stack[i].m_nNumber[2] = -1;
BIGMessages[style].m_Stack[i].m_nNumber[3] = -1;
BIGMessages[style].m_Stack[i].m_nNumber[4] = -1;
BIGMessages[style].m_Stack[i].m_nNumber[5] = -1;
BIGMessages[style].m_Stack[i].m_pString = nil;
}
void
CMessages::AddToPreviousBriefArray(wchar *text, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, wchar *string)
{
int32 i = 0;
while (i < NUMPREVIOUSBRIEFS) {
if (PreviousBriefs[i].m_pText == nil)
break;
if (PreviousBriefs[i].m_nNumber[0] == n1
&& PreviousBriefs[i].m_nNumber[1] == n2
&& PreviousBriefs[i].m_nNumber[2] == n3
&& PreviousBriefs[i].m_nNumber[3] == n4
&& PreviousBriefs[i].m_nNumber[4] == n5
&& PreviousBriefs[i].m_nNumber[5] == n6
&& PreviousBriefs[i].m_pText == text
&& PreviousBriefs[i].m_pString == string)
return;
i++;
}
if (i != 0) {
if (i == NUMPREVIOUSBRIEFS) i -= 2;
else i--;
while (i >= 0) {
PreviousBriefs[i + 1] = PreviousBriefs[i];
i--;
}
}
PreviousBriefs[0].m_pText = text;
PreviousBriefs[0].m_nNumber[0] = n1;
PreviousBriefs[0].m_nNumber[1] = n2;
PreviousBriefs[0].m_nNumber[2] = n3;
PreviousBriefs[0].m_nNumber[3] = n4;
PreviousBriefs[0].m_nNumber[4] = n5;
PreviousBriefs[0].m_nNumber[5] = n6;
PreviousBriefs[0].m_pString = string;
}
void
CMessages::InsertNumberInString(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, wchar *outstr)
{
char numStr[10];
wchar wNumStr[10];
if (str == nil) {
*outstr = '\0';
return;
}
int32 size = GetWideStringLength(str);
int32 i = 0;
for (int32 c = 0; c < size;) {
if (str[c] == '~' && str[c + 1] == '1' && str[c + 2] == '~') {
switch (i) {
case 0: sprintf(numStr, "%d", n1); break;
case 1: sprintf(numStr, "%d", n2); break;
case 2: sprintf(numStr, "%d", n3); break;
case 3: sprintf(numStr, "%d", n4); break;
case 4: sprintf(numStr, "%d", n5); break;
case 5: sprintf(numStr, "%d", n6); break;
}
i++;
AsciiToUnicode(numStr, wNumStr);
int j = 0;
while (wNumStr[j] != '\0')
*(outstr++) = wNumStr[j++];
c += 3;
} else {
*(outstr++) = str[c++];
}
}
*outstr = '\0';
}
void
CMessages::InsertStringInString(wchar *str1, wchar *str2)
{
wchar tempstr[256];
if (!str1 || !str2) return;
int32 str1_size = GetWideStringLength(str1);
int32 str2_size = GetWideStringLength(str2);
int32 total_size = str1_size + str2_size;
wchar *_str1 = str1;
uint16 i;
for (i = 0; i < total_size; ) {
if (*_str1 == '~' && *(_str1 + 1) == 'a' && *(_str1 + 2) == '~') {
_str1 += 3;
for (int j = 0; j < str2_size; j++) {
tempstr[i++] = str2[j];
}
} else {
tempstr[i++] = *(_str1++);
}
}
tempstr[i] = '\0';
for (i = 0; i < total_size; i++)
str1[i] = tempstr[i];
while (i < 256)
str1[i++] = '\0';
}
void
CMessages::InsertPlayerControlKeysInString(wchar *str)
{
uint16 i;
wchar outstr[256];
wchar keybuf[256];
if (!str) return;
uint16 strSize = GetWideStringLength(str);
memset(keybuf, 0, 256*sizeof(wchar));
wchar *_outstr = outstr;
for (i = 0; i < strSize;) {
if (str[i] == '~' && str[i + 1] == 'k' && str[i + 2] == '~') {
i += 4;
for (int32 cont = 0; cont < TOTAL_CONTROL_ACTIONS; cont++) {
uint16 contSize = GetWideStringLength(ControlsManager.m_aActionNames[cont]);
if (contSize != 0) {
if (WideStringCompare(&str[i], ControlsManager.m_aActionNames[cont], contSize)) {
ControlsManager.GetWideStringOfCommandKeys(cont, keybuf, 256);
uint16 keybuf_size = GetWideStringLength(keybuf);
for (uint16 j = 0; j < keybuf_size; j++) {
*(_outstr++) = keybuf[j];
keybuf[j] = '\0';
}
i += contSize + 1;
}
}
}
} else {
*(_outstr++) = str[i++];
}
}
*_outstr = '\0';
for (i = 0; i < GetWideStringLength(outstr); i++)
str[i] = outstr[i];
while (i < 256)
str[i++] = '\0';
}
void
CMessages::AddMessageWithNumber(wchar *str, uint32 time, uint16 flag, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
{
wchar outstr[512]; // unused
InsertNumberInString(str, n1, n2, n3, n4, n5, n6, outstr);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
uint16 i = 0;
while (i < NUMBRIEFMESSAGES && BriefMessages[i].m_pText)
i++;
if (i >= NUMBRIEFMESSAGES) return;
BriefMessages[i].m_pText = str;
BriefMessages[i].m_nFlag = flag;
BriefMessages[i].m_nTime = time;
BriefMessages[i].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[i].m_nNumber[0] = n1;
BriefMessages[i].m_nNumber[1] = n2;
BriefMessages[i].m_nNumber[2] = n3;
BriefMessages[i].m_nNumber[3] = n4;
BriefMessages[i].m_nNumber[4] = n5;
BriefMessages[i].m_nNumber[5] = n6;
BriefMessages[i].m_pString = nil;
if (i == 0)
AddToPreviousBriefArray(
BriefMessages[0].m_pText,
BriefMessages[0].m_nNumber[0],
BriefMessages[0].m_nNumber[1],
BriefMessages[0].m_nNumber[2],
BriefMessages[0].m_nNumber[3],
BriefMessages[0].m_nNumber[4],
BriefMessages[0].m_nNumber[5],
BriefMessages[0].m_pString);
}
void
CMessages::AddMessageJumpQWithNumber(wchar *str, uint32 time, uint16 flag, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
{
wchar outstr[512]; // unused
InsertNumberInString(str, n1, n2, n3, n4, n5, n6, outstr);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
BriefMessages[0].m_pText = str;
BriefMessages[0].m_nFlag = flag;
BriefMessages[0].m_nTime = time;
BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[0].m_nNumber[0] = n1;
BriefMessages[0].m_nNumber[1] = n2;
BriefMessages[0].m_nNumber[2] = n3;
BriefMessages[0].m_nNumber[3] = n4;
BriefMessages[0].m_nNumber[4] = n5;
BriefMessages[0].m_nNumber[5] = n6;
BriefMessages[0].m_pString = nil;
AddToPreviousBriefArray(str, n1, n2, n3, n4, n5, n6, nil);
}
void
CMessages::AddMessageSoonWithNumber(wchar *str, uint32 time, uint16 flag, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
{
wchar outstr[512]; // unused
InsertNumberInString(str, n1, n2, n3, n4, n5, n6, outstr);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
if (BriefMessages[0].m_pText != nil) {
for (int32 i = NUMBRIEFMESSAGES-1; i > 1; i--)
BriefMessages[i] = BriefMessages[i-1];
BriefMessages[1].m_pText = str;
BriefMessages[1].m_nFlag = flag;
BriefMessages[1].m_nTime = time;
BriefMessages[1].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[1].m_nNumber[0] = n1;
BriefMessages[1].m_nNumber[1] = n2;
BriefMessages[1].m_nNumber[2] = n3;
BriefMessages[1].m_nNumber[3] = n4;
BriefMessages[1].m_nNumber[4] = n5;
BriefMessages[1].m_nNumber[5] = n6;
BriefMessages[1].m_pString = nil;
} else {
BriefMessages[0].m_pText = str;
BriefMessages[0].m_nFlag = flag;
BriefMessages[0].m_nTime = time;
BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[0].m_nNumber[0] = n1;
BriefMessages[0].m_nNumber[1] = n2;
BriefMessages[0].m_nNumber[2] = n3;
BriefMessages[0].m_nNumber[3] = n4;
BriefMessages[0].m_nNumber[4] = n5;
BriefMessages[0].m_nNumber[5] = n6;
BriefMessages[0].m_pString = nil;
AddToPreviousBriefArray(str, n1, n2, n3, n4, n5, n6, nil);
}
}
void
CMessages::AddBigMessageWithNumber(wchar *str, uint32 time, uint16 style, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
{
wchar outstr[512]; // unused
InsertNumberInString(str, n1, n2, n3, n4, n5, n6, outstr);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
BIGMessages[style].m_Stack[0].m_pText = str;
BIGMessages[style].m_Stack[0].m_nFlag = 0;
BIGMessages[style].m_Stack[0].m_nTime = time;
BIGMessages[style].m_Stack[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
BIGMessages[style].m_Stack[0].m_nNumber[0] = n1;
BIGMessages[style].m_Stack[0].m_nNumber[1] = n2;
BIGMessages[style].m_Stack[0].m_nNumber[2] = n3;
BIGMessages[style].m_Stack[0].m_nNumber[3] = n4;
BIGMessages[style].m_Stack[0].m_nNumber[4] = n5;
BIGMessages[style].m_Stack[0].m_nNumber[5] = n6;
BIGMessages[style].m_Stack[0].m_pString = nil;
}
void
CMessages::AddBigMessageWithNumberQ(wchar *str, uint32 time, uint16 style, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
{
wchar outstr[512]; // unused
InsertNumberInString(str, n1, n2, n3, n4, n5, n6, outstr);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
int32 i = 0;
while (i < 4 && BIGMessages[style].m_Stack[i].m_pText != nil)
i++;
if (i >= 4) return;
BIGMessages[style].m_Stack[i].m_pText = str;
BIGMessages[style].m_Stack[i].m_nFlag = 0;
BIGMessages[style].m_Stack[i].m_nTime = time;
BIGMessages[style].m_Stack[i].m_nStartTime = CTimer::GetTimeInMilliseconds();
BIGMessages[style].m_Stack[i].m_nNumber[0] = n1;
BIGMessages[style].m_Stack[i].m_nNumber[1] = n2;
BIGMessages[style].m_Stack[i].m_nNumber[2] = n3;
BIGMessages[style].m_Stack[i].m_nNumber[3] = n4;
BIGMessages[style].m_Stack[i].m_nNumber[4] = n5;
BIGMessages[style].m_Stack[i].m_nNumber[5] = n6;
BIGMessages[style].m_Stack[i].m_pString = nil;
}
void
CMessages::AddMessageWithString(wchar *text, uint32 time, uint16 flag, wchar *str)
{
wchar outstr[512]; // unused
WideStringCopy(outstr, text, 256);
InsertStringInString(outstr, str);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
int32 i = 0;
while (i < NUMBRIEFMESSAGES && BriefMessages[i].m_pText != nil)
i++;
if (i >= NUMBRIEFMESSAGES) return;
BriefMessages[i].m_pText = text;
BriefMessages[i].m_nFlag = flag;
BriefMessages[i].m_nTime = time;
BriefMessages[i].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[i].m_nNumber[0] = -1;
BriefMessages[i].m_nNumber[1] = -1;
BriefMessages[i].m_nNumber[2] = -1;
BriefMessages[i].m_nNumber[3] = -1;
BriefMessages[i].m_nNumber[4] = -1;
BriefMessages[i].m_nNumber[5] = -1;
BriefMessages[i].m_pString = str;
if (i == 0)
AddToPreviousBriefArray(
BriefMessages[0].m_pText,
BriefMessages[0].m_nNumber[0],
BriefMessages[0].m_nNumber[1],
BriefMessages[0].m_nNumber[2],
BriefMessages[0].m_nNumber[3],
BriefMessages[0].m_nNumber[4],
BriefMessages[0].m_nNumber[5],
BriefMessages[0].m_pString);
}
void
CMessages::AddMessageJumpQWithString(wchar *text, uint32 time, uint16 flag, wchar *str)
{
wchar outstr[512]; // unused
WideStringCopy(outstr, text, 256);
InsertStringInString(outstr, str);
InsertPlayerControlKeysInString(outstr);
GetWideStringLength(outstr);
BriefMessages[0].m_pText = text;
BriefMessages[0].m_nFlag = flag;
BriefMessages[0].m_nTime = time;
BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
BriefMessages[0].m_nNumber[0] = -1;
BriefMessages[0].m_nNumber[1] = -1;
BriefMessages[0].m_nNumber[2] = -1;
BriefMessages[0].m_nNumber[3] = -1;
BriefMessages[0].m_nNumber[4] = -1;
BriefMessages[0].m_nNumber[5] = -1;
BriefMessages[0].m_pString = str;
AddToPreviousBriefArray(text, -1, -1, -1, -1, -1, -1, str);
}
inline bool
FastWideStringComparison(wchar *str1, wchar *str2)
{
while (*str1 == *str2) {
++str1;
++str2;
if (!*str1 && !*str2) return true;
}
return false;
}
void
CMessages::ClearThisPrint(wchar *str)
{
bool equal;
do {
equal = false;
uint16 i = 0;
while (i < NUMBRIEFMESSAGES) {
if (BriefMessages[i].m_pText == nil)
break;
equal = FastWideStringComparison(str, BriefMessages[i].m_pText);
if (equal) break;
i++;
}
if (equal) {
if (i != 0) {
BriefMessages[i].m_pText = nil;
while (i < NUMBRIEFMESSAGES-1) {
if (BriefMessages[i + 1].m_pText == nil)
break;
BriefMessages[i] = BriefMessages[i + 1];
i++;
}
BriefMessages[i].m_pText = nil;
} else {
BriefMessages[0].m_pText = nil;
while (i < NUMBRIEFMESSAGES-1) {
if (BriefMessages[i + 1].m_pText == nil)
break;
BriefMessages[i] = BriefMessages[i + 1];
i++;
}
BriefMessages[i].m_pText = nil;
BriefMessages[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
if (BriefMessages[0].m_pText == nil)
AddToPreviousBriefArray(
BriefMessages[0].m_pText,
BriefMessages[0].m_nNumber[0],
BriefMessages[0].m_nNumber[1],
BriefMessages[0].m_nNumber[2],
BriefMessages[0].m_nNumber[3],
BriefMessages[0].m_nNumber[4],
BriefMessages[0].m_nNumber[5],
BriefMessages[0].m_pString);
}
}
} while (equal);
}
void
CMessages::ClearThisBigPrint(wchar *str)
{
bool equal;
do {
uint16 i = 0;
equal = false;
uint16 style = 0;
while (style < NUMBIGMESSAGES)
{
if (i >= 4)
break;
if (CMessages::BIGMessages[style].m_Stack[i].m_pText == nil || equal)
break;
equal = FastWideStringComparison(str, BIGMessages[style].m_Stack[i].m_pText);
if (!equal && ++i == 4) {
i = 0;
style++;
}
}
if (equal) {
if (i != 0) {
BIGMessages[style].m_Stack[i].m_pText = nil;
while (i < 3) {
if (BIGMessages[style].m_Stack[i + 1].m_pText == nil)
break;
BIGMessages[style].m_Stack[i] = BIGMessages[style].m_Stack[i + 1];
i++;
}
BIGMessages[style].m_Stack[i].m_pText = nil;
} else {
BIGMessages[style].m_Stack[0].m_pText = 0;
i = 0;
while (i < 3) {
if (BIGMessages[style].m_Stack[i + 1].m_pText == nil)
break;
BIGMessages[style].m_Stack[i] = BIGMessages[style].m_Stack[i + 1];
i++;
}
BIGMessages[style].m_Stack[i].m_pText = nil;
BIGMessages[style].m_Stack[0].m_nStartTime = CTimer::GetTimeInMilliseconds();
}
}
} while (equal);
}
void
CMessages::ClearAllMessagesDisplayedByGame()
{
ClearMessages();
for (int32 i = 0; i < NUMPREVIOUSBRIEFS; i++) {
PreviousBriefs[i].m_pText = nil;
PreviousBriefs[i].m_pString = nil;
}
CHud::GetRidOfAllHudMessages();
CUserDisplay::Pager.ClearMessages();
}
STARTPATCHES
InjectHook(0x529310, CMessages::Init, PATCH_JUMP);
InjectHook(0x529490, CMessages::GetWideStringLength, PATCH_JUMP);
InjectHook(0x5294B0, CMessages::WideStringCopy, PATCH_JUMP);
InjectHook(0x529510, CMessages::WideStringCompare, PATCH_JUMP);
InjectHook(0x529580, CMessages::Process, PATCH_JUMP);
InjectHook(0x529800, CMessages::Display, PATCH_JUMP);
InjectHook(0x529900, CMessages::AddMessage, PATCH_JUMP);
InjectHook(0x529A10, CMessages::AddMessageJumpQ, PATCH_JUMP);
InjectHook(0x529AF0, CMessages::AddMessageSoon, PATCH_JUMP);
InjectHook(0x529CE0, CMessages::ClearMessages, PATCH_JUMP);
InjectHook(0x529E00, CMessages::ClearSmallMessagesOnly, PATCH_JUMP);
InjectHook(0x529EB0, CMessages::AddBigMessage, PATCH_JUMP);
InjectHook(0x529F60, CMessages::AddBigMessageQ, PATCH_JUMP);
InjectHook(0x52A040, CMessages::AddToPreviousBriefArray, PATCH_JUMP);
InjectHook(0x52A1A0, CMessages::InsertNumberInString, PATCH_JUMP);
InjectHook(0x52A300, CMessages::InsertStringInString, PATCH_JUMP);
InjectHook(0x52A490, CMessages::InsertPlayerControlKeysInString, PATCH_JUMP);
InjectHook(0x52A850, CMessages::AddMessageWithNumber, PATCH_JUMP);
InjectHook(0x52A9A0, CMessages::AddMessageJumpQWithNumber, PATCH_JUMP);
InjectHook(0x52AAC0, CMessages::AddMessageSoonWithNumber, PATCH_JUMP);
InjectHook(0x52AD10, CMessages::AddBigMessageWithNumber, PATCH_JUMP);
InjectHook(0x52AE00, CMessages::AddBigMessageWithNumberQ, PATCH_JUMP);
InjectHook(0x52AF30, CMessages::AddMessageWithString, PATCH_JUMP);
InjectHook(0x52B050, CMessages::AddMessageJumpQWithString, PATCH_JUMP);
InjectHook(0x52B140, CMessages::ClearThisPrint, PATCH_JUMP);
InjectHook(0x52B3C0, CMessages::ClearThisBigPrint, PATCH_JUMP);
InjectHook(0x52B670, CMessages::ClearAllMessagesDisplayedByGame, PATCH_JUMP);
ENDPATCHES

69
src/text/Messages.h Normal file
View File

@ -0,0 +1,69 @@
#pragma once
struct tMessage
{
wchar *m_pText;
uint16 m_nFlag;
uint32 m_nTime;
uint32 m_nStartTime;
int32 m_nNumber[6];
wchar *m_pString;
};
struct tBigMessage
{
tMessage m_Stack[4];
};
struct tPreviousBrief
{
wchar *m_pText;
int32 m_nNumber[6];
wchar *m_pString;
};
#define NUMBRIEFMESSAGES 8
#define NUMBIGMESSAGES 6
#define NUMPREVIOUSBRIEFS 5
class CMessages
{
public:
static tMessage(&BriefMessages)[NUMBRIEFMESSAGES];
static tBigMessage(&BIGMessages)[NUMBIGMESSAGES];
static tPreviousBrief(&PreviousBriefs)[NUMPREVIOUSBRIEFS];
static char PreviousMissionTitle[16]; // unused
public:
static void Init(void);
static uint16 GetWideStringLength(wchar *src);
static void WideStringCopy(wchar *dst, wchar *src, uint16 size);
static bool WideStringCompare(wchar *str1, wchar *str2, uint16 size);
static void Process(void);
static void Display(void);
static void AddMessage(wchar *key, uint32 time, uint16 pos);
static void AddMessageJumpQ(wchar *key, uint32 time, uint16 pos);
static void AddMessageSoon(wchar *key, uint32 time, uint16 pos);
static void ClearMessages(void);
static void ClearSmallMessagesOnly(void);
static void AddBigMessage(wchar *key, uint32 time, uint16 pos);
static void AddBigMessageQ(wchar *key, uint32 time, uint16 pos);
static void AddToPreviousBriefArray(wchar *text, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, wchar *string);
static void InsertNumberInString(wchar *src, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, wchar *dst);
static void InsertStringInString(wchar *str1, wchar *str2);
static void InsertPlayerControlKeysInString(wchar *src);
static void AddMessageWithNumber(wchar *key, uint32 time, uint16 pos, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
static void AddMessageJumpQWithNumber(wchar *key, uint32 time, uint16 pos, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
static void AddMessageSoonWithNumber(wchar *key, uint32 time, uint16 pos, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
static void AddBigMessageWithNumber(wchar *key, uint32 time, uint16 pos, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
static void AddBigMessageWithNumberQ(wchar *key, uint32 time, uint16 pos, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
static void AddMessageWithString(wchar *text, uint32 time, uint16 flag, wchar *str);
static void AddMessageJumpQWithString(wchar *text, uint32 time, uint16 flag, wchar *str);
static void ClearThisPrint(wchar *str);
static void ClearThisBigPrint(wchar *str);
static void ClearAllMessagesDisplayedByGame(void);
// unused or cut
//static void AddMessageSoonWithString(wchar*, uint32, uint16, wchar*);
//static void CutString(int16, char*, char**);
//static void PrintString(char*, int16, int16, int16);
};

194
src/text/Pager.cpp Normal file
View File

@ -0,0 +1,194 @@
#include "common.h"
#include "patcher.h"
#include "Pager.h"
#include "Timer.h"
#include "Messages.h"
#include "Hud.h"
#include "Camera.h"
void
CPager::Init()
{
ClearMessages();
m_nNumDisplayLetters = 8;
}
void
CPager::Process()
{
if (m_messages[0].m_pText != nil && m_messages[0].m_nCurrentPosition >= (int32)m_messages[0].m_nStringLength) {
m_messages[0].m_pText = nil;
uint16 i = 0;
while (i < NUMPAGERMESSAGES-1) {
if (m_messages[i + 1].m_pText == nil) break;
m_messages[i] = m_messages[i + 1];
i++;
}
m_messages[i].m_pText = nil;
if (m_messages[0].m_pText != nil)
CMessages::AddToPreviousBriefArray(
m_messages[0].m_pText,
m_messages[0].m_nNumber[0],
m_messages[0].m_nNumber[1],
m_messages[0].m_nNumber[2],
m_messages[0].m_nNumber[3],
m_messages[0].m_nNumber[4],
m_messages[0].m_nNumber[5],
0);
}
Display();
if (m_messages[0].m_pText != nil) {
if (TheCamera.m_WideScreenOn || !CHud::m_Wants_To_Draw_Hud || CHud::m_BigMessage[0][0] || CHud::m_BigMessage[2][0]) {
RestartCurrentMessage();
} else {
if (CTimer::GetTimeInMilliseconds() > m_messages[0].m_nTimeToChangePosition) {
m_messages[0].m_nCurrentPosition++;
m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
}
}
}
}
void
CPager::Display()
{
wchar outstr1[256];
wchar outstr2[260];
wchar *pText = m_messages[0].m_pText;
uint16 i = 0;
if (pText != nil) {
CMessages::InsertNumberInString(
pText,
m_messages[0].m_nNumber[0],
m_messages[0].m_nNumber[1],
m_messages[0].m_nNumber[2],
m_messages[0].m_nNumber[3],
m_messages[0].m_nNumber[4],
m_messages[0].m_nNumber[5],
outstr1);
for (; i < m_nNumDisplayLetters; i++) {
int pos = m_messages[0].m_nCurrentPosition + i;
if (pos >= 0) {
if (!outstr1[pos]) break;
outstr2[i] = outstr1[pos];
} else {
outstr2[i] = ' ';
}
}
}
outstr2[i] = '\0';
CHud::SetPagerMessage(outstr2);
}
void
CPager::AddMessage(wchar *str, uint16 speed, uint16 priority, uint16 a5)
{
uint16 size = CMessages::GetWideStringLength(str);
for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
if (m_messages[i].m_pText) {
if (m_messages[i].m_nPriority >= priority)
continue;
for (int j = NUMPAGERMESSAGES-1; j > i; j--)
m_messages[j] = m_messages[j-1];
}
m_messages[i].m_pText = str;
m_messages[i].m_nSpeedMs = speed;
m_messages[i].m_nPriority = priority;
m_messages[i].field_10 = a5;
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
m_messages[i].m_nStringLength = size;
m_messages[i].m_nNumber[0] = -1;
m_messages[i].m_nNumber[1] = -1;
m_messages[i].m_nNumber[2] = -1;
m_messages[i].m_nNumber[3] = -1;
m_messages[i].m_nNumber[4] = -1;
m_messages[i].m_nNumber[5] = -1;
if (i == 0)
CMessages::AddToPreviousBriefArray(
m_messages[0].m_pText,
m_messages[0].m_nNumber[0],
m_messages[0].m_nNumber[1],
m_messages[0].m_nNumber[2],
m_messages[0].m_nNumber[3],
m_messages[0].m_nNumber[4],
m_messages[0].m_nNumber[5],
nil);
return;
}
}
void
CPager::AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11)
{
wchar nstr[520];
CMessages::InsertNumberInString(str, n1, n2, n3, n4, n5, n6, nstr);
uint16 size = CMessages::GetWideStringLength(nstr);
for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
if (m_messages[i].m_pText) {
if (m_messages[i].m_nPriority >= priority)
continue;
for (int j = NUMPAGERMESSAGES-1; j > i; j--)
m_messages[j] = m_messages[j - 1];
}
m_messages[i].m_pText = str;
m_messages[i].m_nSpeedMs = speed;
m_messages[i].m_nPriority = priority;
m_messages[i].field_10 = a11;
m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
m_messages[i].m_nStringLength = size;
m_messages[i].m_nNumber[0] = n1;
m_messages[i].m_nNumber[1] = n2;
m_messages[i].m_nNumber[2] = n3;
m_messages[i].m_nNumber[3] = n4;
m_messages[i].m_nNumber[4] = n5;
m_messages[i].m_nNumber[5] = n6;
if (i == 0)
CMessages::AddToPreviousBriefArray(
m_messages[0].m_pText,
m_messages[0].m_nNumber[0],
m_messages[0].m_nNumber[1],
m_messages[0].m_nNumber[2],
m_messages[0].m_nNumber[3],
m_messages[0].m_nNumber[4],
m_messages[0].m_nNumber[5],
nil);
return;
}
}
void
CPager::ClearMessages()
{
for (int32 i = 0; i < NUMPAGERMESSAGES; i++)
m_messages[i].m_pText = nil;
}
void
CPager::RestartCurrentMessage()
{
if (m_messages[0].m_pText != nil) {
m_messages[0].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
}
}
STARTPATCHES
InjectHook(0x52B6F0, &CPager::Init, PATCH_JUMP);
InjectHook(0x52B740, &CPager::Process, PATCH_JUMP);
InjectHook(0x52B890, &CPager::Display, PATCH_JUMP);
InjectHook(0x52B940, &CPager::AddMessage, PATCH_JUMP);
InjectHook(0x52BB50, &CPager::AddMessageWithNumber, PATCH_JUMP);
InjectHook(0x52BE50, &CPager::RestartCurrentMessage, PATCH_JUMP);
InjectHook(0x52BE00, &CPager::ClearMessages, PATCH_JUMP);
ENDPATCHES

28
src/text/Pager.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
struct PagerMessage {
wchar *m_pText;
uint16 m_nSpeedMs;
int16 m_nCurrentPosition;
uint16 m_nStringLength;
uint16 m_nPriority;
uint32 m_nTimeToChangePosition;
int16 field_10;
int32 m_nNumber[6];
};
#define NUMPAGERMESSAGES 8
class CPager
{
int16 m_nNumDisplayLetters;
PagerMessage m_messages[NUMPAGERMESSAGES];
public:
void Init();
void Process();
void Display();
void AddMessage(wchar*, uint16, uint16, uint16);
void AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11);
void ClearMessages();
void RestartCurrentMessage();
};

View File

@ -11,20 +11,10 @@ CText &TheText = *(CText*)0x941520;
CText::CText(void)
{
keyArray.entries = nil;
keyArray.numEntries = 0;
data.chars = nil;
data.numChars = 0;
encoding = 101;
encoding = 'e';
memset(WideErrorString, 0, sizeof(WideErrorString));
}
CText::~CText(void)
{
data.Unload();
keyArray.Unload();
}
void
CText::Load(void)
{
@ -96,12 +86,64 @@ CText::Get(const char *key)
return keyArray.Search(key);
}
wchar UpperCaseTable[128] = {
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
150, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
149, 173, 173, 175, 176, 177, 178, 179, 180, 181, 182,
183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193,
194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,
249, 250, 251, 252, 253, 254, 255
};
wchar FrenchUpperCaseTable[128] = {
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
150, 65, 65, 65, 65, 132, 133, 69, 69, 69, 69, 73, 73,
73, 73, 79, 79, 79, 79, 85, 85, 85, 85, 173, 173, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186,
187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230,
231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
253, 254, 255
};
wchar
CText::GetUpperCase(wchar c)
{
// TODO: do this depending on encoding
if(islower(c))
return toupper(c);
{
switch (encoding)
{
case 'e':
if (c >= 'a' && c <= 'z')
return c - 32;
break;
case 'f':
if (c >= 'a' && c <= 'z')
return c - 32;
if (c >= 128 && c <= 255)
return FrenchUpperCaseTable[c-128];
break;
case 'g':
case 'i':
case 's':
if (c >= 'a' && c <= 'z')
return c - 32;
if (c >= 128 && c <= 255)
return UpperCaseTable[c-128];
break;
default:
break;
}
return c;
}
@ -205,7 +247,7 @@ CData::Unload(void)
}
void
AsciiToUnicode(const char *src, uint16 *dst)
AsciiToUnicode(const char *src, wchar *dst)
{
while((*dst++ = *src++) != '\0');
}
@ -215,8 +257,8 @@ UnicodeToAscii(wchar *src)
{
static char aStr[256];
int len;
for(len = 0; src && *src != 0 && len < 256-1; len++, src++)
if(*src < 256)
for(len = 0; *src != '\0' && len < 256-1; len++, src++)
if(*src < 128)
aStr[len] = *src;
else
aStr[len] = '#';
@ -227,10 +269,9 @@ UnicodeToAscii(wchar *src)
char*
UnicodeToAsciiForSaveLoad(wchar *src)
{
// exact same code as above
static char aStr[256];
int len;
for(len = 0; src && *src != 0 && len < 256-1; len++, src++)
for(len = 0; *src != '\0' && len < 256-1; len++, src++)
if(*src < 256)
aStr[len] = *src;
else
@ -249,7 +290,7 @@ int
UnicodeStrlen(const wchar *str)
{
int len;
for(len = 0; *str != 0; len++, str++);
for(len = 0; *str != '\0'; len++, str++);
return len;
}
@ -264,6 +305,8 @@ STARTPATCHES
InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP);
InjectHook(0x52C580, &CText::Unload, PATCH_JUMP);
InjectHook(0x52C5A0, &CText::Get, PATCH_JUMP);
InjectHook(0x52C220, &CText::GetUpperCase, PATCH_JUMP);
InjectHook(0x52C2C0, &CText::UpperCase, PATCH_JUMP);
InjectHook(0x52BE70, &CKeyArray::Load, PATCH_JUMP);
InjectHook(0x52BF60, &CKeyArray::Unload, PATCH_JUMP);

View File

@ -21,6 +21,8 @@ public:
CKeyEntry *entries;
int numEntries;
CKeyArray(void) : entries(nil), numEntries(0) {}
~CKeyArray(void) { Unload(); }
void Load(uint32 length, uint8 *data, int *offset);
void Unload(void);
void Update(wchar *chars);
@ -34,6 +36,8 @@ public:
wchar *chars;
int numChars;
CData(void) : chars(nil), numChars(0) {}
~CData(void) { Unload(); }
void Load(uint32 length, uint8 *data, int *offset);
void Unload(void);
};
@ -42,10 +46,9 @@ class CText
{
CKeyArray keyArray;
CData data;
int8 encoding;
char encoding;
public:
CText(void);
~CText(void);
void Load(void);
void Unload(void);
wchar *Get(const char *key);

View File

@ -15,7 +15,6 @@
#include "PointLights.h"
#include "Renderer.h"
#include "DMAudio.h"
#include "MusicManager.h"
#include "Radar.h"
bool &CVehicle::bWheelsOnlyCheat = *(bool *)0x95CD78;

View File

@ -191,7 +191,7 @@ public:
uint8 m_bRainAudioCounter;
uint8 m_bRainSamplesCounter;
uint8 m_nCarHornTimer;
int8 field_22D;
int8 field_22D; // last horn?
bool m_bSirenOrAlarm;
int8 m_comedyControlState;
CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car
@ -286,7 +286,7 @@ class cTransmission;
class cVehicleParams
{
public:
char m_bDistanceCalculated;
uint8 m_bDistancECalculated;
char gap_1[3];
float m_fDistance;
CVehicle *m_pVehicle;

View File

@ -0,0 +1,10 @@
#include "CProjectileInfo.h"
CProjectileInfo *gaProjectileInfo = (CProjectileInfo *)0x64ED50;
CProjectileInfo *CProjectileInfo::ms_apProjectile = (CProjectileInfo *)0x87C748;
CProjectileInfo *
CProjectileInfo::GetProjectileInfo(int32 id)
{
return &gaProjectileInfo[id];
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "Object.h"
#include "Weapon.h"
struct CProjectileInfo : public CObject {
eWeaponType m_eWeaponType;
CEntity *m_pSource;
int m_nExplosionTime;
char m_bInUse;
char field_13;
char field_14;
char field_15;
CVector m_vecPos;
static CProjectileInfo *GetProjectileInfo(int32 id);
static CProjectileInfo *ms_apProjectile;
};
extern CProjectileInfo *gaProjectileInfo;

View File

@ -0,0 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "ProjectileInfo.h"
#include "Projectile.h"
WRAPPER bool CProjectileInfo::RemoveIfThisIsAProjectile(CObject *pObject) { EAXJMP(0x55BBD0); }

View File

@ -0,0 +1,9 @@
#pragma once
class CObject;
class CProjectileInfo
{
public:
static bool RemoveIfThisIsAProjectile(CObject *pObject);
};

View File

@ -6,6 +6,7 @@
#include "Ped.h"
#include "World.h"
WRAPPER void CWeapon::UpdateWeapons(void) { EAXJMP(0x55C310); }
WRAPPER bool CWeapon::Fire(CEntity*, CVector*) { EAXJMP(0x55C380); }
WRAPPER void CWeapon::FireFromCar(CAutomobile *car, bool left) { EAXJMP(0x55C940); }
WRAPPER void CWeapon::AddGunshell(CEntity*, CVector const&, CVector2D const&, float) { EAXJMP(0x55F770); }

View File

@ -73,5 +73,6 @@ public:
static void DoTankDoomAiming(CEntity *playerVehicle, CEntity *playerPed, CVector *start, CVector *end);
bool HitsGround(CEntity* holder, CVector* firePos, CEntity* aimingTo);
static void InitialiseWeapons(void);
static void UpdateWeapons(void);
};
static_assert(sizeof(CWeapon) == 0x18, "CWeapon: error");