Merge pull request #1 from GTAmodding/master

upd
This commit is contained in:
Fire_Head 2019-10-27 06:39:56 +03:00 committed by GitHub
commit c39cf2d960
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 8937 additions and 5952 deletions

View File

@ -29,12 +29,10 @@ after_build:
$url = "$releases/download/$latestVersion/$name" $url = "$releases/download/$latestVersion/$name"
Start-FileDownload $url -FileName 'C:\Ultimate-ASI-Loader.zip' Start-FileDownload $url -FileName 'C:\Ultimate-ASI-Loader.zip'
7z e c:\Ultimate-ASI-Loader.zip -oc:\Projects\re3\bin\${env:CONFIGURATION} 7z e c:\Ultimate-ASI-Loader.zip -oc:\Projects\re3\bin\${env:CONFIGURATION}
cd "bin\${env:CONFIGURATION}" cd "bin\${env:CONFIGURATION}"
copy re3.dll re3.asi copy re3.dll re3.asi

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,136 @@
#pragma once #pragma once
#include "AudioSamples.h"
#include "DMAudio.h" #include "DMAudio.h"
#include "common.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 class tActiveSample
{ {
public: public:
@ -45,7 +172,7 @@ public:
uint8 field_82; uint8 field_82;
uint8 field_83; uint8 field_83;
int32 calculatedVolume; int32 calculatedVolume;
uint8 field_88; int8 field_88;
uint8 field_89; uint8 field_89;
uint8 field_90; uint8 field_90;
uint8 field_91; uint8 field_91;
@ -55,7 +182,8 @@ public:
static_assert(sizeof(tActiveSample) == 92, "tActiveSample: error"); static_assert(sizeof(tActiveSample) == 92, "tActiveSample: error");
enum eAudioType : int32 { enum eAudioType : int32
{
AUDIOTYPE_PHYSICAL = 0, AUDIOTYPE_PHYSICAL = 0,
AUDIOTYPE_EXPLOSION = 1, AUDIOTYPE_EXPLOSION = 1,
AUDIOTYPE_FIRE = 2, AUDIOTYPE_FIRE = 2,
@ -86,7 +214,7 @@ public:
int16 m_awAudioEvent[4]; int16 m_awAudioEvent[4];
uint8 gap_18[2]; uint8 gap_18[2];
float m_afVolume[4]; float m_afVolume[4];
uint8 m_Loops; uint8 m_AudioEvents;
uint8 field_25[3]; uint8 field_25[3];
// no methods // no methods
@ -158,7 +286,8 @@ public:
uint8 gap_811; uint8 gap_811;
cAudioCollision m_sQueue; cAudioCollision m_sQueue;
void AddCollisionToRequestedQueue(); // todo // reversed all methods
void AddCollisionToRequestedQueue(); /// ok
}; };
static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error"); static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error");
@ -199,6 +328,8 @@ public:
CVector Posn; CVector Posn;
int32 AudioEntity; int32 AudioEntity;
void Reset(); /// ok
static void *operator new(size_t); static void *operator new(size_t);
static void *operator new(size_t, int); static void *operator new(size_t, int);
static void operator delete(void *, size_t); static void operator delete(void *, size_t);
@ -232,6 +363,15 @@ enum AudioEntityHandle {
AEHANDLE_ERROR_BADAUDIOTYPE = -1, AEHANDLE_ERROR_BADAUDIOTYPE = -1,
}; };
struct Crime {
int32 type;
CVector position;
uint16 timer;
uint16 gap;
};
static_assert(sizeof(Crime) == 20, "Crime: error ");
class cAudioManager class cAudioManager
{ {
public: public:
@ -250,7 +390,7 @@ public:
uint8 field_15; uint8 field_15;
int32 m_nTimer; int32 m_nTimer;
tActiveSample m_sQueueSample; tActiveSample m_sQueueSample;
uint8 m_bActiveSampleQueue; bool m_bActiveSampleQueue;
uint8 gap_109[3]; uint8 gap_109[3];
tActiveSample m_asSamples[2][27]; tActiveSample m_asSamples[2][27];
uint8 m_abSampleQueueIndexTable[2][27]; uint8 m_abSampleQueueIndexTable[2][27];
@ -267,7 +407,12 @@ public:
int32 m_nFireAudioEntity; int32 m_nFireAudioEntity;
int32 m_nWaterCannonEntity; int32 m_nWaterCannonEntity;
int32 m_nPoliceChannelEntity; 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_nFrontEndEntity;
int32 m_nCollisionEntity; int32 m_nCollisionEntity;
cAudioCollisionManager m_sCollisionManager; cAudioCollisionManager m_sCollisionManager;
@ -279,30 +424,31 @@ public:
uint8 m_bUserPause; uint8 m_bUserPause;
uint8 m_bPreviousUserPause; uint8 m_bPreviousUserPause;
uint8 field_19195; // time? uint8 field_19195; // time?
uint32 m_FrameCounter; uint32 m_nTimeOfRecentCrime;
// getters // getters
uint32 GetFrameCounter() const { return m_FrameCounter; } uint32 GetFrameCounter() const { return m_nTimeOfRecentCrime; }
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; } float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; } int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; }
// "Should" be in alphabetic order, except "getXTalkSfx" // "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, void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 unk1,
uint8 counter, bool notLooping); /// ok uint8 counter, bool notLooping); /// ok
void AddReflectionsToRequestedQueue(); /// ok (check value) void AddReflectionsToRequestedQueue(); /// ok (check value)
void AddReleasingSounds(); // todo (difficult) void AddReleasingSounds(); /// ok (check)
void AddSampleToRequestedQueue(); /// ok void AddSampleToRequestedQueue(); /// ok
void AgeCrimes(); // todo void AgeCrimes(); /// ok
void CalculateDistance(bool *ptr, float dist); /// ok void CalculateDistance(bool *ptr, float dist); /// ok
bool CheckForAnAudioFileOnCD() const; /// ok bool CheckForAnAudioFileOnCD() const; /// ok
void ClearActiveSamples(); /// ok
void ClearMissionAudio(); /// ok void ClearMissionAudio(); /// ok
void ClearRequestedQueue(); /// ok void ClearRequestedQueue(); /// ok
int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
float speedMultiplier) const; /// ok float speedMultiplier) const; /// ok
int32 ComputePan(float, CVector *); // todo int32 ComputePan(float, CVector *); /// ok
uint32 ComputeVolume(int emittingVolume, float soundIntensity, float distance) const; /// ok uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; /// ok
int32 CreateEntity(int32 type, CPhysical *entity); /// ok int32 CreateEntity(int32 type, CPhysical *entity); /// ok
void DestroyAllGameCreatedEntities(); /// ok void DestroyAllGameCreatedEntities(); /// ok
@ -395,7 +541,7 @@ public:
uint8 GetCDAudioDriveLetter() const; uint8 GetCDAudioDriveLetter() const;
int8 GetCurrent3DProviderIndex() const; /// ok int8 GetCurrent3DProviderIndex() const; /// ok
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used 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 GetCollisionRatio(float a, float b, float c, float d) const; /// ok
float GetDistanceSquared(CVector *v) const; /// ok float GetDistanceSquared(CVector *v) const; /// ok
int32 GetJumboTaxiFreq() const; /// ok int32 GetJumboTaxiFreq() const; /// ok
@ -404,15 +550,18 @@ public:
uint8 GetNum3DProvidersAvailable() const; uint8 GetNum3DProvidersAvailable() const;
int32 GetPedCommentSfx(CPed *ped, int32 sound); int32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const; void GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const;
float GetVehicleDriveWheelSkidValue(uint8 a1, CAutomobile *a2, cTransmission *a3, float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
float a4); // todo cTransmission *transmission,
int32 GetVehicleNonDriveWheelSkidValue(float a1, int a2, int a3, int a4, float a5); // todo float velocityChange); /// ok
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
cTransmission *transmission,
float velocityChange); /// ok
bool HasAirBrakes(int32 model) const; /// ok bool HasAirBrakes(int32 model) const; /// ok
void Initialise(); /// ok void Initialise(); /// ok
void InitialisePoliceRadio(); // todo void InitialisePoliceRadio(); /// ok
void InitialisePoliceRadioZones(); // todo void InitialisePoliceRadioZones(); /// ok
void InterrogateAudioEntities(); /// ok void InterrogateAudioEntities(); /// ok
bool IsAudioInitialised() const; /// ok bool IsAudioInitialised() const; /// ok
bool IsMissionAudioSampleFinished(); /// ok bool IsMissionAudioSampleFinished(); /// ok
@ -421,13 +570,13 @@ public:
bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; /// ok bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; /// ok
void PlayLoadedMissionAudio(); /// ok void PlayLoadedMissionAudio(); /// ok
void PlayOneShot(int32 index, int16 sound, float vol); // todo void PlayOneShot(int32 index, int16 sound, float vol); /// ok
uint32 PlaySuspectLastSeen(float x, float y, float z); // todo void PlaySuspectLastSeen(float x, float y, float z); /// ok
void PlayerJustGotInCar() const; /// ok void PlayerJustGotInCar() const; /// ok
void PlayerJustLeftCar() const; /// ok void PlayerJustLeftCar() const; /// ok
void PostInitialiseGameSpecificSetup(); /// ok void PostInitialiseGameSpecificSetup(); /// ok
void PostTerminateGameSpecificShutdown(); /// ok void PostTerminateGameSpecificShutdown(); /// ok
void PreInitialiseGameSpecificSetup() const; void PreInitialiseGameSpecificSetup() const; // ok
void PreloadMissionAudio(char *); // todo void PreloadMissionAudio(char *); // todo
void PreTerminateGameSpecificShutdown(); /// ok void PreTerminateGameSpecificShutdown(); /// ok
/// processX - main logic of adding new sounds /// processX - main logic of adding new sounds
@ -464,7 +613,7 @@ public:
void ProcessLaunderetteScriptObject(uint8 sound); /// ok void ProcessLaunderetteScriptObject(uint8 sound); /// ok
void ProcessLoopingScriptObject(uint8 sound); /// ok void ProcessLoopingScriptObject(uint8 sound); /// ok
void ProcessMissionAudio(); /// ok void ProcessMissionAudio(); /// ok
void ProcessModelCarEngine(cVehicleParams *params); /// ok (check float comparisons) void ProcessModelCarEngine(cVehicleParams *params); /// ok
void ProcessOneShotScriptObject(uint8 sound); /// ok void ProcessOneShotScriptObject(uint8 sound); /// ok
void ProcessPed(CPhysical *ped); /// ok void ProcessPed(CPhysical *ped); /// ok
void ProcessPedHeadphones(cPedParams *params); /// ok void ProcessPedHeadphones(cPedParams *params); /// ok
@ -472,10 +621,10 @@ public:
void ProcessPhysical(int32 id); /// ok void ProcessPhysical(int32 id); /// ok
void ProcessPlane(cVehicleParams *params); /// ok void ProcessPlane(cVehicleParams *params); /// ok
void ProcessPlayersVehicleEngine(cVehicleParams *params, void ProcessPlayersVehicleEngine(cVehicleParams *params,
CAutomobile *automobile); /// ok (check float comparisons) CAutomobile *automobile); /// ok
void ProcessPoliceCellBeatingScriptObject(uint8 sound); // todo void ProcessPoliceCellBeatingScriptObject(uint8 sound); /// ok
void ProcessPornCinema(uint8 sound); /// ok void ProcessPornCinema(uint8 sound); /// ok
void ProcessProjectiles(); // todo requires CProjectileInfo void ProcessProjectiles(); /// ok
void ProcessRainOnVehicle(cVehicleParams *params); /// ok void ProcessRainOnVehicle(cVehicleParams *params); /// ok
void ProcessReverb() const; /// ok void ProcessReverb() const; /// ok
bool ProcessReverseGear(cVehicleParams *a2); /// ok bool ProcessReverseGear(cVehicleParams *a2); /// ok
@ -484,16 +633,16 @@ public:
void ProcessShopScriptObject(uint8 sound); /// ok void ProcessShopScriptObject(uint8 sound); /// ok
void ProcessSpecial(); /// ok void ProcessSpecial(); /// ok
bool ProcessTrainNoise(cVehicleParams *params); /// ok bool ProcessTrainNoise(cVehicleParams *params); /// ok
void ProcessVehicle(CVehicle *); // todo void ProcessVehicle(CVehicle *vehicle); /// ok
bool ProcessVehicleDoors(cVehicleParams *params); /// ok bool ProcessVehicleDoors(cVehicleParams *params); /// ok
// bool ProcessVehicleEngine(void *); bool ProcessVehicleEngine(cVehicleParams *params); // todo
// void ProcessVehicleHorn(cVehicleParams *params); void ProcessVehicleHorn(cVehicleParams *params); /// ok
// void ProcessVehicleOneShots(void *); void ProcessVehicleOneShots(void *); // todo
bool ProcessVehicleReverseWarning(cVehicleParams *params); /// ok bool ProcessVehicleReverseWarning(cVehicleParams *params); /// ok
bool ProcessVehicleRoadNoise(cVehicleParams *params); /// ok bool ProcessVehicleRoadNoise(cVehicleParams *params); /// ok
// void ProcessVehicleSirenOrAlarm(void *); void ProcessVehicleSirenOrAlarm(void *); // todo
// void ProcessVehicleSkidding(void *); void ProcessVehicleSkidding(cVehicleParams *params); /// ok
void ProcessWaterCannon(int32); // todo void ProcessWaterCannon(int32); /// ok
void ProcessWeather(int32 id); /// ok void ProcessWeather(int32 id); /// ok
bool ProcessWetRoadNoise(cVehicleParams *params); /// ok bool ProcessWetRoadNoise(cVehicleParams *params); /// ok
void ProcessWorkShopScriptObject(uint8 sound); /// ok void ProcessWorkShopScriptObject(uint8 sound); /// ok
@ -501,48 +650,54 @@ public:
int32 RandomDisplacement(uint32 seed) const; int32 RandomDisplacement(uint32 seed) const;
void ReacquireDigitalHandle() const; void ReacquireDigitalHandle() const;
void ReleaseDigitalHandle() const; void ReleaseDigitalHandle() const;
int32 ReportCollision(CEntity *a2, CEntity *a3, uint8 a4, uint8 a5, float a6, void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2,
float a7); // todo float collisionPower, float intensity2); /// ok
int32 ReportCrime(eCrimeType crime, const CVector *pos); // todo void ReportCrime(int32 crime, const CVector *pos); /// ok
void ResetAudioLogicTimers(int32 timer); /// ok void ResetAudioLogicTimers(int32 timer); /// ok
void ResetPoliceRadio(); /// ok void ResetPoliceRadio(); /// ok
void ResetTimers(uint32 a2); // todo void ResetTimers(uint32 time); /// ok
void Service(); // todo void Service(); /// ok
void ServiceCollisions(); // todo void ServiceCollisions(); // todo
void ServicePoliceRadio(); // todo void ServicePoliceRadio(); /// ok
void ServicePoliceRadioChannel(int a2); // todo void ServicePoliceRadioChannel(int32 wantedLevel); /// ok
void ServiceSoundEffects(); // todo void ServiceSoundEffects(); /// ok
int8 SetCurrent3DProvider(uint8); // todo int8 SetCurrent3DProvider(uint8 which); /// ok
void SetDynamicAcousticModelingStatus(bool status); void SetDynamicAcousticModelingStatus(bool status);
void SetEffectsFadeVolume(uint8 volume) const; void SetEffectsFadeVolume(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const; void SetEffectsMasterVolume(uint8 volume) const;
void SetEntityStatus(int32 id, bool status); void SetEntityStatus(int32 id, bool status);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(int32); // todo uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(cAudioCollision *audioCollision); /// ok
void SetMissionAudioLocation(float x, float y, float z); void SetMissionAudioLocation(float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const; void SetMissionScriptPoliceAudio(int32 sfx) const;
void SetMonoMode(uint8); // todo void SetMonoMode(uint8); // todo (mobile)
void SetMusicFadeVolume(uint8 volume) const; void SetMusicFadeVolume(uint8 volume) const;
void SetMusicMasterVolume(uint8 volume) const; void SetMusicMasterVolume(uint8 volume) const;
void SetSpeakerConfig(int32 conf) const; void SetSpeakerConfig(int32 conf) const;
void SetUpLoopingCollisionSound(int a2, int a3); // todo void SetUpLoopingCollisionSound(cAudioCollision *col, uint8 counter); /// ok
void SetUpOneShotCollisionSound(int a2); // todo void SetUpOneShotCollisionSound(cAudioCollision *col); /// ok
void SetupCrimeReport(); // todo bool SetupCrimeReport(); /// ok
bool SetupJumboEngineSound(uint8, int32); // todo bool SetupJumboEngineSound(uint8 a2, int32 a3); // todo
bool SetupJumboFlySound(uint8 emittingVol); /// ok bool SetupJumboFlySound(uint8 emittingVol); /// ok
bool SetupJumboRumbleSound(uint8 emittingVol); /// ok bool SetupJumboRumbleSound(uint8 emittingVol); /// ok
bool SetupJumboTaxiSound(uint8 vol); /// ok bool SetupJumboTaxiSound(uint8 vol); /// ok
bool SetupJumboWhineSound(uint8 emittingVol, int32 freq); /// ok bool SetupJumboWhineSound(uint8 emittingVol, int32 freq); /// ok
void SetupPedComments(cPedParams *params, uint32 sound); /// ok void SetupPedComments(cPedParams *params, uint32 sound); /// ok
void SetupSuspectLastSeenReport(); // todo void SetupSuspectLastSeenReport(); /// ok
void Terminate(); 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 UsesReverseWarning(int32 model) const;
bool UsesSiren(int32 model) const; bool UsesSiren(int32 model) const;
bool UsesSirenSwitching(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"); static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

@ -30,7 +30,7 @@ CGameLogic::InitAtStartOfGame()
void void
CGameLogic::PassTime(uint32 time) CGameLogic::PassTime(uint32 time)
{ {
uint8 minutes, hours, days; int32 minutes, hours, days;
minutes = time + CClock::GetMinutes(); minutes = time + CClock::GetMinutes();
hours = CClock::GetHours(); hours = CClock::GetHours();
@ -112,8 +112,8 @@ CGameLogic::Update()
CCarCtrl::ClearInterestingVehicleList(); CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = false; CRestart::OverrideHospitalLevel = LEVEL_NONE;
CRestart::OverridePoliceStationLevel = false; CRestart::OverridePoliceStationLevel = LEVEL_NONE;
PassTime(720); PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
SortOutStreamingAndMemory(pPlayerInfo.GetPos()); SortOutStreamingAndMemory(pPlayerInfo.GetPos());
@ -183,8 +183,8 @@ CGameLogic::Update()
CCarCtrl::ClearInterestingVehicleList(); CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = false; CRestart::OverrideHospitalLevel = LEVEL_NONE;
CRestart::OverridePoliceStationLevel = false; CRestart::OverridePoliceStationLevel = LEVEL_NONE;
PassTime(720); PassTime(720);
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
pPlayerInfo.m_pPed->ClearWeapons(); pPlayerInfo.m_pPed->ClearWeapons();
@ -224,8 +224,8 @@ CGameLogic::Update()
CCarCtrl::ClearInterestingVehicleList(); CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverridePoliceStationLevel = false; CRestart::OverridePoliceStationLevel = LEVEL_NONE;
CRestart::OverrideHospitalLevel = false; CRestart::OverrideHospitalLevel = LEVEL_NONE;
RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
SortOutStreamingAndMemory(pPlayerInfo.GetPos()); SortOutStreamingAndMemory(pPlayerInfo.GetPos());
TheCamera.m_fCamShakeForce = 0.0f; TheCamera.m_fCamShakeForce = 0.0f;

View File

@ -1036,7 +1036,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
bAllowLookAroundCam = true; bAllowLookAroundCam = true;
bPlayingBackFromFile = false; bPlayingBackFromFile = false;
OldRadioStation = DMAudio.GetRadioInCar(); OldRadioStation = DMAudio.GetRadioInCar();
DMAudio.ChangeMusicMode(0); DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetEffectsFadeVol(0); DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0); DMAudio.SetMusicFadeVol(0);
int current; int current;
@ -1282,9 +1282,9 @@ void CReplay::RestoreStuffFromMem(void)
} }
delete[] pPedAnims; delete[] pPedAnims;
pPedAnims = nil; pPedAnims = nil;
DMAudio.ChangeMusicMode(0); DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetRadioInCar(OldRadioStation); DMAudio.SetRadioInCar(OldRadioStation);
DMAudio.ChangeMusicMode(1); DMAudio.ChangeMusicMode(MUSICMODE_GAME);
} }
#endif #endif

View File

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

View File

@ -94,6 +94,8 @@ class CControllerState;
#define JOY_BUTTONS 16 #define JOY_BUTTONS 16
#define MAX_BUTTONS (JOY_BUTTONS+1) #define MAX_BUTTONS (JOY_BUTTONS+1)
#define ACTIONNAME_LENGTH 40
class CControllerConfigManager class CControllerConfigManager
{ {
public: public:

View File

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

View File

@ -9,7 +9,7 @@ public:
static char *LoadLine(int fd); static char *LoadLine(int fd);
static RwTexDictionary *LoadTexDictionary(const char *filename); static RwTexDictionary *LoadTexDictionary(const char *filename);
static void LoadCollisionFile(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 void LoadModelFile(const char *filename);
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data); static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
static void LoadClumpFile(const char *filename); static void LoadClumpFile(const char *filename);

View File

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

View File

@ -80,12 +80,15 @@ WRAPPER void CGame::Initialise(const char *datFile) { EAXJMP(0x48BED0); }
#if 0 #if 0
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); } WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
#else #else
extern void (*DebugMenuProcess)(void);
void CGame::Process(void) void CGame::Process(void)
{ {
CPad::UpdatePads(); CPad::UpdatePads();
TheCamera.SetMotionBlurAlpha(0); TheCamera.SetMotionBlurAlpha(0);
if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL) if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
DebugMenuProcess();
CCutsceneMgr::Update(); CCutsceneMgr::Update();
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused()) if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process(); FrontEndMenuManager.Process();

View File

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

View File

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

View File

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

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "Pager.h"
class COnscreenTimerEntry class COnscreenTimerEntry
{ {
public: public:
@ -50,12 +52,6 @@ class CCurrentVehicle
{ {
}; };
class CPager
{
public:
void AddMessage(wchar*, uint16, uint16, uint16);
};
class CUserDisplay class CUserDisplay
{ {
public: public:

View File

@ -121,7 +121,7 @@ public:
CRGBA(void) { } CRGBA(void) { }
CRGBA(uint8 r, uint8 g, uint8 b, uint8 a) : r(r), g(g), b(b), a(a) { } 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->r = right.r;
this->g = right.g; this->g = right.g;
@ -142,7 +142,7 @@ public:
return rwRGBA; return rwRGBA;
} }
CRGBA &CRGBA::operator =(const RwRGBA &right) CRGBA &operator =(const RwRGBA &right)
{ {
this->r = right.red; this->r = right.red;
this->g = right.green; 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 ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#define BIT(num) (1<<(num)) #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 ABS(a) (((a) < 0) ? (-(a)) : (a))
#define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min))))) #define norm(value, min, max) (((value) < (min)) ? 0 : (((value) > (max)) ? 1 : (((value) - (min)) / ((max) - (min)))))

View File

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

View File

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

View File

@ -127,20 +127,14 @@ public:
} }
void Scale(float scale) void Scale(float scale)
{ {
// GTA treats this as 4x4 floats float *pFloatMatrix = (float*)&m_matrix;
m_matrix.right.x *= scale; for (int i = 0; i < 3; i++)
m_matrix.right.y *= scale; #ifdef FIX_BUGS // BUGFIX from VC
m_matrix.right.z *= scale; for (int j = 0; j < 3; j++)
m_matrix.up.x *= scale; #else
m_matrix.up.y *= scale; for (int j = 0; j < 4; j++)
m_matrix.up.z *= scale; #endif
m_matrix.at.x *= scale; pFloatMatrix[i * 4 + j] *= 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;
} }
@ -255,7 +249,15 @@ public:
CMatrix &Invert(const CMatrix &src, CMatrix &dst); CMatrix &Invert(const CMatrix &src, CMatrix &dst);
CVector operator*(const CMatrix &mat, const CVector &vec); CVector operator*(const CMatrix &mat, const CVector &vec);
CMatrix operator*(const CMatrix &m1, const CMatrix &m2); CMatrix operator*(const CMatrix &m1, const CMatrix &m2);
CVector MultiplyInverse(const CMatrix &mat, const CVector &vec); inline CVector MultiplyInverse(const CMatrix &mat, const CVector &vec)
{
CVector v(vec.x - mat.m_matrix.pos.x, vec.y - mat.m_matrix.pos.y, vec.z - mat.m_matrix.pos.z);
return CVector(
mat.m_matrix.right.x * v.x + mat.m_matrix.right.y * v.y + mat.m_matrix.right.z * v.z,
mat.m_matrix.up.x * v.x + mat.m_matrix.up.y * v.y + mat.m_matrix.up.z * v.z,
mat.m_matrix.at.x * v.x + mat.m_matrix.at.y * v.y + mat.m_matrix.at.z * v.z);
}
const CVector Multiply3x3(const CMatrix &mat, const CVector &vec); const CVector Multiply3x3(const CMatrix &mat, const CVector &vec);
const CVector Multiply3x3(const CVector &vec, const CMatrix &mat); const CVector Multiply3x3(const CVector &vec, const CMatrix &mat);

View File

@ -126,16 +126,6 @@ operator*(const CMatrix &m1, const CMatrix &m2)
return out; return out;
} }
CVector
MultiplyInverse(const CMatrix &mat, const CVector &vec)
{
CVector v(vec.x - mat.m_matrix.pos.x, vec.y - mat.m_matrix.pos.y, vec.z - mat.m_matrix.pos.z);
return CVector(
mat.m_matrix.right.x * v.x + mat.m_matrix.right.y * v.y + mat.m_matrix.right.z * v.z,
mat.m_matrix.up.x * v.x + mat.m_matrix.up.y * v.y + mat.m_matrix.up.z * v.z,
mat.m_matrix.at.x * v.x + mat.m_matrix.at.y * v.y + mat.m_matrix.at.z * v.z);
}
const CVector const CVector
Multiply3x3(const CMatrix &mat, const CVector &vec) Multiply3x3(const CMatrix &mat, const CVector &vec)
{ {

View File

@ -26,6 +26,12 @@ MatchModelString(const char *modelname, int16 id)
#undef X #undef X
} }
void
TestModelIndices(void)
{
;
}
STARTPATCHES STARTPATCHES
InjectHook(0x48EB60, InitModelIndices, PATCH_JUMP); InjectHook(0x48EB60, InitModelIndices, PATCH_JUMP);
InjectHook(0x48F030, MatchModelString, PATCH_JUMP); InjectHook(0x48F030, MatchModelString, PATCH_JUMP);

View File

@ -365,6 +365,7 @@ enum{
void InitModelIndices(void); void InitModelIndices(void);
void MatchModelString(const char *name, int16 id); void MatchModelString(const char *name, int16 id);
void TestModelIndices(void);
inline bool inline bool
IsGlass(int16 id) IsGlass(int16 id)
@ -462,7 +463,6 @@ IsPickupModel(int16 id)
id == MI_UZI || id == MI_UZI ||
id == MI_M16 || id == MI_M16 ||
id == MI_FLAMETHROWER || id == MI_FLAMETHROWER ||
id >= MI_M16 && id <= MI_FLAMETHROWER ||
id == MI_PICKUP_ADRENALINE || id == MI_PICKUP_ADRENALINE ||
id == MI_PICKUP_BODYARMOUR || id == MI_PICKUP_BODYARMOUR ||
id == MI_PICKUP_INFO || id == MI_PICKUP_INFO ||

View File

@ -45,7 +45,6 @@
#include "CarAI.h" #include "CarAI.h"
#include "Zones.h" #include "Zones.h"
#include "Cranes.h" #include "Cranes.h"
#include "MusicManager.h"
#include "Timecycle.h" #include "Timecycle.h"
#include "ParticleObject.h" #include "ParticleObject.h"
#include "Floater.h" #include "Floater.h"
@ -57,13 +56,13 @@ WRAPPER void CPed::StartFightDefend(uint8, uint8, uint8) { EAXJMP(0x4E7780); }
WRAPPER void CPed::ServiceTalking(void) { EAXJMP(0x4E5870); } WRAPPER void CPed::ServiceTalking(void) { EAXJMP(0x4E5870); }
WRAPPER void CPed::UpdatePosition(void) { EAXJMP(0x4C7A00); } WRAPPER void CPed::UpdatePosition(void) { EAXJMP(0x4C7A00); }
WRAPPER void CPed::WanderPath(void) { EAXJMP(0x4D28D0); } WRAPPER void CPed::WanderPath(void) { EAXJMP(0x4D28D0); }
WRAPPER void CPed::SeekCar(void) { EAXJMP(0x4D3F90); }
WRAPPER void CPed::UpdateFromLeader(void) { EAXJMP(0x4D8F30); } 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 void CPed::SetEnterCar_AllClear(CVehicle*, uint32, uint32) { EAXJMP(0x4E0A40); }
WRAPPER bool CPed::WarpPedToNearEntityOffScreen(CEntity*) { EAXJMP(0x4E5570); } WRAPPER bool CPed::WarpPedToNearEntityOffScreen(CEntity*) { EAXJMP(0x4E5570); }
WRAPPER void CPed::SetObjective(eObjective, CVector) { EAXJMP(0x4D8A90); } WRAPPER void CPed::SetObjective(eObjective, CVector) { EAXJMP(0x4D8A90); }
WRAPPER void CPed::SetObjective(eObjective, CVector, float) { EAXJMP(0x4D8770); } WRAPPER void CPed::SetObjective(eObjective, CVector, float) { EAXJMP(0x4D8770); }
WRAPPER void CPed::WarpPedIntoCar(CVehicle*) { EAXJMP(0x4D7D20); }
WRAPPER void CPed::SetCarJack(CVehicle*) { EAXJMP(0x4E0220); }
#define FEET_OFFSET 1.04f #define FEET_OFFSET 1.04f
@ -471,9 +470,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bIsLanding = false; bIsLanding = false;
bIsRunning = false; bIsRunning = false;
bHitSomethingLastFrame = false; bHitSomethingLastFrame = false;
m_ped_flagB80 = false; bVehEnterDoorIsBlocked = false;
m_ped_flagC1 = false; bCanPedEnterSeekedCar = false;
bRespondsToThreats = true; bRespondsToThreats = true;
bRenderPedInCar = true; bRenderPedInCar = true;
bChangedSeat = false; bChangedSeat = false;
@ -3245,7 +3244,7 @@ CPed::CheckForGunShots(void)
int event; int event;
if (CEventList::FindClosestEvent(EVENT_GUNSHOT, GetPosition(), &event)) { if (CEventList::FindClosestEvent(EVENT_GUNSHOT, GetPosition(), &event)) {
if (gaEvent[event].entityType == EVENT_ENTITY_PED) { 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; m_ped_flagD2 = false;
return CPools::GetPed(gaEvent[event].entityRef); return CPools::GetPed(gaEvent[event].entityRef);
} }
@ -8571,11 +8570,15 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
Say(SOUND_PED_DEFEND); Say(SOUND_PED_DEFEND);
} }
#if defined FIX_BUGS || defined VC_PED_PORTS #ifdef VC_PED_PORTS
// Killing gang members with car wasn't triggering a fight, until now... Taken from VC. // Killing gang members with car wasn't triggering a fight, until now... Taken from VC.
if (IsGangMember()) { if (IsGangMember()) {
CPed *driver = car->pDriver; CPed *driver = car->pDriver;
if (driver && driver->IsPlayer()) { if (driver && driver->IsPlayer()
#ifdef FIX_BUGS
&& (CharCreatedBy != MISSION_CHAR || bRespondsToThreats) && (!m_leader || m_leader != driver)
#endif
) {
RegisterThreatWithGangPeds(driver); RegisterThreatWithGangPeds(driver);
} }
} }
@ -9511,7 +9514,7 @@ CPed::ProcessControl(void)
|| m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)) { || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)) {
if (collidingVeh != m_pCurrentPhysSurface || IsPlayer()) { if (collidingVeh != m_pCurrentPhysSurface || IsPlayer()) {
if (!m_ped_flagB80) { if (!bVehEnterDoorIsBlocked) {
if (collidingVeh->m_status != STATUS_PLAYER || CharCreatedBy == MISSION_CHAR) { if (collidingVeh->m_status != STATUS_PLAYER || CharCreatedBy == MISSION_CHAR) {
// VC calls SetDirectionToWalkAroundVehicle instead if ped is in PED_SEEK_CAR. // VC calls SetDirectionToWalkAroundVehicle instead if ped is in PED_SEEK_CAR.
@ -9697,7 +9700,7 @@ CPed::ProcessControl(void)
} }
} }
} else if (!m_ped_flagB80) { } else if (!bVehEnterDoorIsBlocked) {
if (collidingVeh->m_status != STATUS_PLAYER || CharCreatedBy == MISSION_CHAR) { if (collidingVeh->m_status != STATUS_PLAYER || CharCreatedBy == MISSION_CHAR) {
SetDirectionToWalkAroundObject(collidingVeh); SetDirectionToWalkAroundObject(collidingVeh);
@ -12163,7 +12166,7 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh)
// ?!? I think it's absurd to use this unless another function like SeekCar finds next pos. with it and we're trying to simulate it's behaviour. // ?!? I think it's absurd to use this unless another function like SeekCar finds next pos. with it and we're trying to simulate it's behaviour.
// On every run it returns another pos. for ped, with same distance to the veh. // On every run it returns another pos. for ped, with same distance to the veh.
// Sequence of positions are not guarenteed, it depends on global pos. (So sometimes it returns positions to make ped draw circle, sometimes don't) // Sequence of positions are not guaranteed, it depends on global pos. (So sometimes it returns positions to make ped draw circle, sometimes don't)
helperPos = veh->GetMatrix() * helperPos; helperPos = veh->GetMatrix() * helperPos;
float vehForwardHeading = veh->GetForward().Heading(); float vehForwardHeading = veh->GetForward().Heading();
@ -12357,7 +12360,7 @@ CPed::ProcessObjective(void)
SetLookTimer(CGeneral::GetRandomNumberInRange(500, 1500)); SetLookTimer(CGeneral::GetRandomNumberInRange(500, 1500));
// Second condition is pointless and isn't there in Mobile. // 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()) if (m_threatEntity->IsPed())
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity); SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
} }
@ -13029,7 +13032,7 @@ CPed::ProcessObjective(void)
} else { } else {
SetSeekBoatPosition(m_carInObjective); SetSeekBoatPosition(m_carInObjective);
} }
if (m_nMoveState == PEDMOVE_STILL && !m_ped_flagB80) if (m_nMoveState == PEDMOVE_STILL && !bVehEnterDoorIsBlocked)
SetMoveState(PEDMOVE_RUN); SetMoveState(PEDMOVE_RUN);
if (m_carInObjective && m_carInObjective->m_fHealth > 0.0f) { if (m_carInObjective && m_carInObjective->m_fHealth > 0.0f) {
@ -15236,6 +15239,505 @@ 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;
}
}
void
CPed::SeekCar(void)
{
CVehicle *vehToSeek = m_carInObjective;
CVector dest(0.0f, 0.0f, 0.0f);
if (!vehToSeek) {
RestorePreviousState();
return;
}
if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
if (m_vehEnterType && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
if (IsRoomToBeCarJacked()) {
dest = GetPositionToOpenCarDoor(vehToSeek, m_vehEnterType);
} else if (m_nPedType == PEDTYPE_COP) {
dest = GetPositionToOpenCarDoor(vehToSeek, CAR_DOOR_RF);
} else {
SetMoveState(PEDMOVE_STILL);
}
} else
GetNearestDoor(vehToSeek, dest);
} else {
if (m_hitRecoverTimer > CTimer::GetTimeInMilliseconds()) {
SetMoveState(PEDMOVE_STILL);
return;
}
if (vehToSeek->m_modelIndex == MI_COACH) {
GetNearestDoor(vehToSeek, dest);
} else {
if (vehToSeek->IsTrain()) {
if (vehToSeek->m_status != STATUS_TRAIN_NOT_MOVING) {
RestorePreviousObjective();
RestorePreviousState();
return;
}
if (!GetNearestTrainDoor(vehToSeek, dest)) {
RestorePreviousObjective();
RestorePreviousState();
return;
}
} else {
if (!GetNearestPassengerDoor(vehToSeek, dest)) {
if (vehToSeek->m_nNumPassengers == vehToSeek->m_nNumMaxPassengers) {
RestorePreviousObjective();
RestorePreviousState();
} else {
SetMoveState(PEDMOVE_STILL);
}
bVehEnterDoorIsBlocked = true;
return;
}
bVehEnterDoorIsBlocked = false;
}
}
}
if (dest.x == 0.0f && dest.y == 0.0f) {
if ((!IsPlayer() && CharCreatedBy != MISSION_CHAR) || vehToSeek->VehicleCreatedBy != MISSION_VEHICLE || vehToSeek->pDriver) {
RestorePreviousState();
if (IsPlayer()) {
ClearObjective();
} else if (CharCreatedBy == RANDOM_CHAR) {
m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000;
}
SetMoveState(PEDMOVE_STILL);
TheCamera.ClearPlayerWeaponMode();
CCarCtrl::RemoveFromInterestingVehicleList(vehToSeek);
return;
}
dest = vehToSeek->GetPosition();
if (bCollidedWithMyVehicle) {
WarpPedIntoCar(m_pMyVehicle);
return;
}
}
bool foundBetterPosToSeek = PossiblyFindBetterPosToSeekCar(&dest, vehToSeek);
m_vecSeekPos = dest;
float distToDest = (m_vecSeekPos - GetPosition()).MagnitudeSqr();
#ifndef VC_PED_PORTS
if (bIsRunning)
SetMoveState(PEDMOVE_RUN);
#else
if (bIsRunning ||
vehToSeek->pDriver && distToDest > 4.0f && (Abs(vehToSeek->m_vecMoveSpeed.x) > 0.01f || Abs(vehToSeek->m_vecMoveSpeed.y) > 0.01f))
SetMoveState(PEDMOVE_RUN);
#endif
else if (distToDest < 4.0f)
SetMoveState(PEDMOVE_WALK);
if (distToDest >= 1.0f)
bCanPedEnterSeekedCar = false;
else if (2.0f * vehToSeek->GetColModel()->boundingBox.max.x > distToDest)
bCanPedEnterSeekedCar = true;
if (vehToSeek->m_nGettingInFlags & GetCarDoorFlag(m_vehEnterType))
bVehEnterDoorIsBlocked = true;
else
bVehEnterDoorIsBlocked = false;
if (Seek()) {
if (!foundBetterPosToSeek) {
if (1.5f + GetPosition().z > dest.z && GetPosition().z - 0.5f < dest.z) {
if (vehToSeek->IsTrain()) {
SetEnterTrain(vehToSeek, m_vehEnterType);
} else {
m_fRotationCur = m_fRotationDest;
if (!bVehEnterDoorIsBlocked) {
vehToSeek->bIsStatic = false;
if (m_objective == OBJECTIVE_SOLICIT) {
SetSolicit(1000);
} else if (m_objective == OBJECTIVE_BUY_ICE_CREAM) {
SetBuyIceCream();
} else if (vehToSeek->m_nNumGettingIn < vehToSeek->m_nNumMaxPassengers + 1
&& vehToSeek->CanPedEnterCar()) {
switch (vehToSeek->m_status) {
case STATUS_PLAYER:
case STATUS_SIMPLE:
case STATUS_PHYSICS:
case STATUS_PLAYER_DISABLED:
if (!vehToSeek->bIsBus && (!m_leader || m_leader != vehToSeek->pDriver) &&
(m_vehEnterType == CAR_DOOR_LF && vehToSeek->pDriver || m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0] || m_vehEnterType == CAR_DOOR_LR && vehToSeek->pPassengers[1] || m_vehEnterType == CAR_DOOR_RR && vehToSeek->pPassengers[2])) {
SetCarJack(vehToSeek);
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && m_vehEnterType != CAR_DOOR_LF)
vehToSeek->pDriver->bFleeAfterExitingCar = true;
} else {
SetEnterCar(vehToSeek, m_vehEnterType);
}
break;
case STATUS_ABANDONED:
if (m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0]) {
if (vehToSeek->pPassengers[0]->m_ped_flagF4) {
if (IsPlayer())
CPed::SetEnterCar(vehToSeek, m_vehEnterType);
} else {
SetCarJack(vehToSeek);
}
} else {
SetEnterCar(vehToSeek, m_vehEnterType);
}
break;
case STATUS_WRECKED:
SetIdle();
break;
default:
return;
}
} else {
RestorePreviousState();
}
} else {
SetMoveState(PEDMOVE_STILL);
}
}
}
}
}
}
class CPed_ : public CPed class CPed_ : public CPed
{ {
public: public:
@ -15451,4 +15953,7 @@ STARTPATCHES
InjectHook(0x4D6620, &CPed::SetSolicit, PATCH_JUMP); InjectHook(0x4D6620, &CPed::SetSolicit, PATCH_JUMP);
InjectHook(0x4D2EA0, &CPed::SetFollowPath, PATCH_JUMP); InjectHook(0x4D2EA0, &CPed::SetFollowPath, PATCH_JUMP);
InjectHook(0x4E1010, &CPed::SetExitCar, PATCH_JUMP); InjectHook(0x4E1010, &CPed::SetExitCar, PATCH_JUMP);
InjectHook(0x4C5FE0, &CPed::ScanForThreats, PATCH_JUMP);
InjectHook(0x4C6C10, &CPed::ScanForInterestingStuff, PATCH_JUMP);
InjectHook(0x4D3F90, &CPed::SeekCar, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -294,9 +294,9 @@ public:
uint8 bIsLanding : 1; uint8 bIsLanding : 1;
uint8 bIsRunning : 1; // on some conditions uint8 bIsRunning : 1; // on some conditions
uint8 bHitSomethingLastFrame : 1; uint8 bHitSomethingLastFrame : 1;
uint8 m_ped_flagB80 : 1; // bIsNearCar? it's sure that it's related with cars and used for deciding whether we should move uint8 bVehEnterDoorIsBlocked : 1; // because someone else enters/exits from there
uint8 m_ped_flagC1 : 1; // bCanPedEnterSeekedCar? uint8 bCanPedEnterSeekedCar : 1;
uint8 bRespondsToThreats : 1; uint8 bRespondsToThreats : 1;
uint8 bRenderPedInCar : 1; uint8 bRenderPedInCar : 1;
uint8 bChangedSeat : 1; uint8 bChangedSeat : 1;
@ -669,7 +669,7 @@ public:
bool PlacePedOnDryLand(void); bool PlacePedOnDryLand(void);
bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*); bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*);
void UpdateFromLeader(void); void UpdateFromLeader(void);
int ScanForThreats(void); uint32 ScanForThreats(void);
void SetEnterCar(CVehicle*, uint32); void SetEnterCar(CVehicle*, uint32);
bool WarpPedToNearEntityOffScreen(CEntity*); bool WarpPedToNearEntityOffScreen(CEntity*);
void SetExitCar(CVehicle*, uint32); void SetExitCar(CVehicle*, uint32);
@ -678,6 +678,9 @@ public:
void SetEnterTrain(CVehicle*, uint32); void SetEnterTrain(CVehicle*, uint32);
void SetEnterCar_AllClear(CVehicle*, uint32, uint32); void SetEnterCar_AllClear(CVehicle*, uint32, uint32);
void SetSolicit(uint32 time); void SetSolicit(uint32 time);
void ScanForInterestingStuff(void);
void WarpPedIntoCar(CVehicle*);
void SetCarJack(CVehicle*);
// Static methods // Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset); 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 void CPedIK::ExtractYawAndPitchWorld(RwMatrixTag*, float*, float*) { EAXJMP(0x4ED140); }
WRAPPER bool CPedIK::RestoreLookAt(void) { EAXJMP(0x4ED810); } WRAPPER bool CPedIK::RestoreLookAt(void) { EAXJMP(0x4ED810); }
// TODO: These are hardcoded into exe, reverse it. 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_torsoInfo = *(LimbMovementInfo*)0x5F9F8C; 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_headInfo = *(LimbMovementInfo*)0x5F9F5C; 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 = *(LimbMovementInfo*)0x5F9FA4; 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 = *(LimbMovementInfo*)0x5F9FBC; 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) CPedIK::CPedIK(CPed *ped)
{ {

View File

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

View File

@ -637,6 +637,7 @@ void CHud::Draw()
/* /*
DrawOnScreenTimer DrawOnScreenTimer
*/ */
wchar sTimer[16]; wchar sTimer[16];
if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed) if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed)
@ -697,7 +698,7 @@ void CHud::Draw()
if (CTimer::GetFrameCounter() & 4 || !CounterFlashTimer) { if (CTimer::GetFrameCounter() & 4 || !CounterFlashTimer) {
if (CUserDisplay::OnscnTimer.m_sEntries[0].m_nType) { 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_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 { } else {
AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer, sTimer); AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterBuffer, sTimer);
CFont::SetPropOn(); CFont::SetPropOn();

View File

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

View File

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

View File

@ -5,6 +5,12 @@
#include "Sprite.h" #include "Sprite.h"
#include "Font.h" #include "Font.h"
#include "Text.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::Render(void) { EAXJMP(0x518DC0); }
WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); } WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); }
@ -18,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 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 #define MONEY_MESSAGE_LIFETIME_MS 2000
@ -97,6 +384,15 @@ CMoneyMessages::RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8
} }
STARTPATCHES 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(0x51AF70, CMoneyMessages::Init, PATCH_JUMP);
InjectHook(0x51B030, CMoneyMessages::Render, PATCH_JUMP); InjectHook(0x51B030, CMoneyMessages::Render, PATCH_JUMP);
ENDPATCHES ENDPATCHES

View File

@ -36,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); 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 class C3dMarkers
{ {
public: 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 class CMoneyMessage

View File

@ -7,6 +7,7 @@
#include "Renderer.h" #include "Renderer.h"
#include "Camera.h" #include "Camera.h"
#include "VisibilityPlugins.h" #include "VisibilityPlugins.h"
#include "World.h"
#define FADE_DISTANCE 20.0f #define FADE_DISTANCE 20.0f
@ -498,14 +499,11 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
return atomic; return atomic;
} }
// TODO: this is part of a struct
static RwTexture *&playerskin = *(RwTexture**)0x941428;
RpAtomic* RpAtomic*
CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic) CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
{ {
if(playerskin) if(CWorld::Players[0].m_pSkinTexture)
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, playerskin); RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
AtomicDefaultRenderCallBack(atomic); AtomicDefaultRenderCallBack(atomic);
return atomic; return atomic;
} }
@ -607,22 +605,30 @@ CVisibilityPlugins::DefaultVisibilityCB(RpClump *clump)
bool bool
CVisibilityPlugins::FrustumSphereCB(RpClump *clump) CVisibilityPlugins::FrustumSphereCB(RpClump *clump)
{ {
// TODO, but unused RwSphere sphere;
return true; 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 bool
CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump) CVisibilityPlugins::VehicleVisibilityCB(RpClump *clump)
{ {
// TODO, but unused if (GetDistanceSquaredFromCamera(RpClumpGetFrame(clump)) <= ms_vehicleLod1Dist)
return true; return FrustumSphereCB(clump);
return false;
} }
bool bool
CVisibilityPlugins::VehicleVisibilityCB_BigVehicle(RpClump *clump) CVisibilityPlugins::VehicleVisibilityCB_BigVehicle(RpClump *clump)
{ {
// TODO, but unused return FrustumSphereCB(clump);
return true;
} }

View File

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

View File

@ -1,9 +1,25 @@
#pragma once #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 class CWaterCannons
{ {
public: public:
static void Update(void); static void Update();
static void UpdateOne(uint32 id, CVector *pos, CVector *dir); static void UpdateOne(uint32 id, CVector *pos, CVector *dir);
static void Render(void); static void Render(void);
}; };
extern CWaterCannon *aCannons;

View File

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

View File

@ -127,4 +127,5 @@ void HandleExit();
#endif /* __cplusplus */ #endif /* __cplusplus */
extern DWORD &_dwOperatingSystemVersion;
#endif /* (!defined(_PLATFORM_WIN_H)) */ #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) CText::CText(void)
{ {
keyArray.entries = nil; encoding = 'e';
keyArray.numEntries = 0;
data.chars = nil;
data.numChars = 0;
encoding = 101;
memset(WideErrorString, 0, sizeof(WideErrorString)); memset(WideErrorString, 0, sizeof(WideErrorString));
} }
CText::~CText(void)
{
data.Unload();
keyArray.Unload();
}
void void
CText::Load(void) CText::Load(void)
{ {
@ -96,12 +86,64 @@ CText::Get(const char *key)
return keyArray.Search(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 wchar
CText::GetUpperCase(wchar c) CText::GetUpperCase(wchar c)
{ {
// TODO: do this depending on encoding switch (encoding)
if(islower(c)) {
return toupper(c); 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; return c;
} }
@ -205,7 +247,7 @@ CData::Unload(void)
} }
void void
AsciiToUnicode(const char *src, uint16 *dst) AsciiToUnicode(const char *src, wchar *dst)
{ {
while((*dst++ = *src++) != '\0'); while((*dst++ = *src++) != '\0');
} }
@ -215,8 +257,8 @@ UnicodeToAscii(wchar *src)
{ {
static char aStr[256]; static char aStr[256];
int len; 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) if(*src < 128)
aStr[len] = *src; aStr[len] = *src;
else else
aStr[len] = '#'; aStr[len] = '#';
@ -227,10 +269,9 @@ UnicodeToAscii(wchar *src)
char* char*
UnicodeToAsciiForSaveLoad(wchar *src) UnicodeToAsciiForSaveLoad(wchar *src)
{ {
// exact same code as above
static char aStr[256]; static char aStr[256];
int len; 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) if(*src < 256)
aStr[len] = *src; aStr[len] = *src;
else else
@ -249,7 +290,7 @@ int
UnicodeStrlen(const wchar *str) UnicodeStrlen(const wchar *str)
{ {
int len; int len;
for(len = 0; *str != 0; len++, str++); for(len = 0; *str != '\0'; len++, str++);
return len; return len;
} }
@ -264,6 +305,8 @@ STARTPATCHES
InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP); InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP);
InjectHook(0x52C580, &CText::Unload, PATCH_JUMP); InjectHook(0x52C580, &CText::Unload, PATCH_JUMP);
InjectHook(0x52C5A0, &CText::Get, 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(0x52BE70, &CKeyArray::Load, PATCH_JUMP);
InjectHook(0x52BF60, &CKeyArray::Unload, PATCH_JUMP); InjectHook(0x52BF60, &CKeyArray::Unload, PATCH_JUMP);

View File

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

View File

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

View File

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