Merge branch 'miami' of https://github.com/GTAmodding/re3 into miami_highfps

This commit is contained in:
Veyrdite 2021-07-21 16:31:39 +10:00
commit e8e999d2cb
130 changed files with 4065 additions and 1533 deletions

View File

@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
platform: [win-amd64-librw_d3d9-oal, win-amd64-librw_gl3_glfw-oal]
buildtype: [Debug, Release, Vanilla]
buildtype: [Debug, Release]
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.2

View File

@ -13,7 +13,7 @@
"src/modelinfo",
"src/objects",
"src/peds",
"src/render",
"src/renderer",
"src/rw",
"src/save",
"src/skel",

View File

@ -130,7 +130,7 @@ Microsoft recently discontinued its downloads of the DX9 SDK. You can download a
**If you choose OpenAL on Windows** You must read [Running OpenAL build on Windows](https://github.com/GTAmodding/re3/wiki/Running-OpenAL-build-on-Windows).
</details>
> :information_source: premake has an `--lto` option if you want the project to be compiled with Link Time Optimization.
> :information_source: premake has an `--with-lto` option if you want the project to be compiled with Link Time Optimization.
> :information_source: There are various settings in [config.h](https://github.com/GTAmodding/re3/tree/miami/src/core/config.h), you may want to take a look there.

View File

@ -187,7 +187,7 @@
</SETTING>
<SETTING>
<SETTING><NAME>SearchPath</NAME>
<SETTING><NAME>Path</NAME><VALUE>..\src\render</VALUE></SETTING>
<SETTING><NAME>Path</NAME><VALUE>..\src\renderer</VALUE></SETTING>
<SETTING><NAME>PathFormat</NAME><VALUE>Windows</VALUE></SETTING>
<SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING>
</SETTING>
@ -6712,7 +6712,7 @@
</SETTING>
<SETTING>
<SETTING><NAME>SearchPath</NAME>
<SETTING><NAME>Path</NAME><VALUE>..\src\render</VALUE></SETTING>
<SETTING><NAME>Path</NAME><VALUE>..\src\renderer</VALUE></SETTING>
<SETTING><NAME>PathFormat</NAME><VALUE>Windows</VALUE></SETTING>
<SETTING><NAME>PathRoot</NAME><VALUE>Project</VALUE></SETTING>
</SETTING>
@ -14909,7 +14909,7 @@
<PATHFORMAT>Windows</PATHFORMAT>
</FILEREF>
</GROUP>
<GROUP><NAME>render</NAME>
<GROUP><NAME>renderer</NAME>
<FILEREF>
<TARGETNAME>Debug</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -68,7 +68,7 @@ end
workspace "reVC"
language "C++"
configurations { "Debug", "Release", "Vanilla" }
configurations { "Debug", "Release" }
startproject "reVC"
location "build"
symbols "Full"
@ -80,6 +80,7 @@ workspace "reVC"
end
filter { "system:windows" }
configurations { "Vanilla" }
platforms {
"win-x86-RW34_d3d8-mss",
"win-x86-librw_d3d9-mss",
@ -123,9 +124,6 @@ workspace "reVC"
flags { "LinkTimeOptimization" }
end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter { "platforms:win*" }
system "windows"
@ -266,7 +264,7 @@ project "reVC"
files { addSrcFiles("src/modelinfo") }
files { addSrcFiles("src/objects") }
files { addSrcFiles("src/peds") }
files { addSrcFiles("src/render") }
files { addSrcFiles("src/renderer") }
files { addSrcFiles("src/rw") }
files { addSrcFiles("src/save") }
files { addSrcFiles("src/skel") }
@ -295,7 +293,7 @@ project "reVC"
includedirs { "src/modelinfo" }
includedirs { "src/objects" }
includedirs { "src/peds" }
includedirs { "src/render" }
includedirs { "src/renderer" }
includedirs { "src/rw" }
includedirs { "src/save/" }
includedirs { "src/skel/" }
@ -315,6 +313,9 @@ project "reVC"
includedirs { "vendor/opusfile/include" }
end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter "platforms:*mss"
defines { "AUDIO_MSS" }
includedirs { "vendor/milessdk/include" }

View File

@ -96,8 +96,8 @@ public:
m_nCommentsInBank[i] = 0;
m_nActiveBank = 0;
}
void Add(tPedComment *com); // done
void Process(); // done
void Add(tPedComment *com);
void Process();
};
VALIDATE_SIZE(cPedComments, 0x490);
@ -251,34 +251,34 @@ public:
~cAudioManager();
// getters
uint32 GetFrameCounter() const { return m_FrameCounter; } // done
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; } // done
uint32 GetFrameCounter() const { return m_FrameCounter; }
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; }
int32 GetRandomNumberInRange(int32 idx, int32 low, int32 high) const { return (m_anRandomTable[idx] % (high - low + 1)) + low; }
bool8 IsMissionAudioSamplePlaying(uint8 slot) const; // { return m_sMissionAudio.m_nPlayStatus == 1; }
bool8 ShouldDuckMissionAudio(uint8 slot) const;
// "Should" be in alphabetic order, except "getXTalkSfx"
void AddDetailsToRequestedOrderList(uint8 sample); // done (inlined in vc)
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping); // done
void AddReflectionsToRequestedQueue(); // done
void AddReleasingSounds(); // done
void AddSampleToRequestedQueue(); // done
void AgeCrimes(); // done (inlined in vc)
void AddDetailsToRequestedOrderList(uint8 sample); // inlined in vc
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping);
void AddReflectionsToRequestedQueue();
void AddReleasingSounds();
void AddSampleToRequestedQueue();
void AgeCrimes(); // inlined in vc
void CalculateDistance(bool8 &condition, float dist); // done
bool8 CheckForAnAudioFileOnCD() const; // done
void ClearActiveSamples(); // done
void ClearMissionAudio(uint8 slot); // done (inlined in vc)
void ClearRequestedQueue(); // done (inlined in vc)
uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const; // done
int32 ComputePan(float, CVector *); // done
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; // done
int32 CreateEntity(eAudioType type, void *entity); // done
void CalculateDistance(bool8 &condition, float dist);
bool8 CheckForAnAudioFileOnCD() const;
void ClearActiveSamples();
void ClearMissionAudio(uint8 slot); // inlined in vc
void ClearRequestedQueue(); // inlined in vc
uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const;
int32 ComputePan(float, CVector *);
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const;
int32 CreateEntity(eAudioType type, void *entity);
void DestroyAllGameCreatedEntities(); // done
void DestroyEntity(int32 id); // done (inlined in vc)
void DoPoliceRadioCrackle(); // done
void DestroyAllGameCreatedEntities();
void DestroyEntity(int32 id); // inlined in vc
void DoPoliceRadioCrackle();
// functions returning talk sfx,
// order from GetPedCommentSfx
@ -295,8 +295,8 @@ public:
uint32 GetHMYSTTalkSfx(CPed *ped, int16 sound);
uint32 GetHMOSTTalkSfx(CPed *ped, int16 sound);
uint32 GetHFYRITalkSfx(CPed *ped, int16 sound);
uint32 GetHFORITalkSfx(CPed *ped, int16 sound);
uint32 GetHMYRITalkSfx(CPed *ped, int16 sound);
uint32 GetHFORITalkSfx(CPed *ped, int16 sound);
uint32 GetHMYRITalkSfx(CPed *ped, int16 sound);
uint32 GetHMORITalkSfx(CPed *ped, int16 sound);
uint32 GetHFYBETalkSfx(CPed *ped, int16 sound);
uint32 GetHFOBETalkSfx(CPed *ped, int16 sound);
@ -379,170 +379,170 @@ public:
uint32 GetGenericFemaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc)
// end of functions returning talk sfx
void GenerateIntegerRandomNumberTable(); // done
char *Get3DProviderName(uint8 id) const; // done
char GetCDAudioDriveLetter() const; // done
int8 GetCurrent3DProviderIndex() const; // done
int8 AutoDetect3DProviders() const; // done
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(int32 a, float b) const; // done
float GetCollisionRatio(float a, float b, float c, float d) const; // done (inlined in vc)
float GetDistanceSquared(const CVector &v) const; // done (inlined in vc)
int32 GetJumboTaxiFreq() const; // done (inlined in vc)
uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done
int8 GetMissionScriptPoliceAudioPlayingStatus() const; // done
uint8 GetNum3DProvidersAvailable() const; // done
uint32 GetPedCommentSfx(CPed *ped, int32 sound); // done
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const; // done
void GenerateIntegerRandomNumberTable();
char *Get3DProviderName(uint8 id) const;
char GetCDAudioDriveLetter() const;
int8 GetCurrent3DProviderIndex() const;
int8 AutoDetect3DProviders() const;
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(int32 a, float b) const;
float GetCollisionRatio(float a, float b, float c, float d) const; // inlined in vc
float GetDistanceSquared(const CVector &v) const; // inlined in vc
int32 GetJumboTaxiFreq() const; // inlined in vc
uint8 GetMissionAudioLoadingStatus(uint8 slot) const;
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
uint8 GetNum3DProvidersAvailable() const;
uint32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
float GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission,
float velocityChange); // done
float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange); // done
float velocityChange);
float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange);
bool8 HasAirBrakes(int32 model) const; // done
bool8 HasAirBrakes(int32 model) const;
void Initialise(); // done
void InitialisePoliceRadio(); // done
void InitialisePoliceRadioZones(); // done
void InterrogateAudioEntities(); // done (inlined)
bool8 IsAudioInitialised() const; // done
bool8 IsMissionAudioSampleFinished(uint8 slot); // done
bool8 IsMP3RadioChannelAvailable() const; // done
void Initialise();
void InitialisePoliceRadio();
void InitialisePoliceRadioZones();
void InterrogateAudioEntities(); // inlined
bool8 IsAudioInitialised() const;
bool8 IsMissionAudioSampleFinished(uint8 slot);
bool8 IsMP3RadioChannelAvailable() const;
bool8 MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; //done
bool8 MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
void PlayLoadedMissionAudio(uint8 slot); // done
void PlayOneShot(int32 index, uint16 sound, float vol); // done
void PlaySuspectLastSeen(float x, float y, float z); // done
void PlayerJustGotInCar() const; // done
void PlayerJustLeftCar() const; // done
void PostInitialiseGameSpecificSetup(); // done
void PostTerminateGameSpecificShutdown(); // done
void PreInitialiseGameSpecificSetup() const; // done
void PreloadMissionAudio(uint8 slot, Const char *name); // done
void PreTerminateGameSpecificShutdown(); // done
void PlayLoadedMissionAudio(uint8 slot);
void PlayOneShot(int32 index, uint16 sound, float vol);
void PlaySuspectLastSeen(float x, float y, float z);
void PlayerJustGotInCar() const;
void PlayerJustLeftCar() const;
void PostInitialiseGameSpecificSetup();
void PostTerminateGameSpecificShutdown();
void PreInitialiseGameSpecificSetup() const;
void PreloadMissionAudio(uint8 slot, Const char *name);
void PreTerminateGameSpecificShutdown();
/// processX - main logic of adding new sounds
void ProcessActiveQueues(); // done
bool8 ProcessAirBrakes(cVehicleParams& params); // done
void ProcessActiveQueues();
bool8 ProcessAirBrakes(cVehicleParams& params);
bool8 ProcessBoatEngine(cVehicleParams& params);
bool8 ProcessBoatMovingOverWater(cVehicleParams& params); //done
bool8 ProcessBoatMovingOverWater(cVehicleParams& params);
#ifdef GTA_BRIDGE
void ProcessBridge(); // done(bcs not exists in VC)
void ProcessBridgeMotor(); // done(bcs not exists in VC)
void ProcessBridgeOneShots(); // done(bcs not exists in VC)
void ProcessBridgeWarning(); // done(bcs not exists in VC)
void ProcessBridge();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
void ProcessBridgeWarning();
#endif
bool8 ProcessCarBombTick(cVehicleParams& params); // done
void ProcessCarHeli(cVehicleParams& params); // done
void ProcessCesna(cVehicleParams& params); // done
//void ProcessCrane(); // done(bcs not exists in VC)
bool8 ProcessEngineDamage(cVehicleParams& params); // done
void ProcessEntity(int32 sound); // done
void ProcessExplosions(int32 explosion); // done
void ProcessFireHydrant(); // done
void ProcessFires(int32 entity); // done
void ProcessFrontEnd(); // done
void ProcessGarages(); // done
void ProcessJumbo(cVehicleParams& params); // done
void ProcessJumboAccel(CPlane *plane); // done
void ProcessJumboDecel(CPlane *plane); // done
void ProcessJumboFlying(); // done
void ProcessJumboLanding(CPlane *plane); // done
void ProcessJumboTakeOff(CPlane *plane); // done
void ProcessJumboTaxi(); // done
void ProcessLoopingScriptObject(uint8 sound); // done
void ProcessMissionAudio(); // done
void ProcessMissionAudioSlot(uint8 slot); // done
void ProcessModelHeliVehicle(cVehicleParams& params); // done
void ProcessModelVehicle(cVehicleParams& params); // done
void ProcessOneShotScriptObject(uint8 sound); //
void ProcessPed(CPhysical *ped); // done
void ProcessPedOneShots(cPedParams &params); //
void ProcessPhysical(int32 id); // done
void ProcessPlane(cVehicleParams& params); // done
void ProcessPlayerMood(); // done
void ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh); // done
void ProcessProjectiles(); // done
void ProcessRainOnVehicle(cVehicleParams& params); // done
void ProcessReverb() const; // done
bool8 ProcessReverseGear(cVehicleParams& params); // done
void ProcessScriptObject(int32 id); // done
void ProcessSpecial(); // done
bool8 ProcessCarBombTick(cVehicleParams& params);
void ProcessCarHeli(cVehicleParams& params);
void ProcessCesna(cVehicleParams& params);
//void ProcessCrane();
bool8 ProcessEngineDamage(cVehicleParams& params);
void ProcessEntity(int32 sound);
void ProcessExplosions(int32 explosion);
void ProcessFireHydrant();
void ProcessFires(int32 entity);
void ProcessFrontEnd();
void ProcessGarages();
void ProcessJumbo(cVehicleParams& params);
void ProcessJumboAccel(CPlane *plane);
void ProcessJumboDecel(CPlane *plane);
void ProcessJumboFlying();
void ProcessJumboLanding(CPlane *plane);
void ProcessJumboTakeOff(CPlane *plane);
void ProcessJumboTaxi();
void ProcessLoopingScriptObject(uint8 sound);
void ProcessMissionAudio();
void ProcessMissionAudioSlot(uint8 slot);
void ProcessModelHeliVehicle(cVehicleParams& params);
void ProcessModelVehicle(cVehicleParams& params);
void ProcessOneShotScriptObject(uint8 sound);
void ProcessPed(CPhysical *ped);
void ProcessPedOneShots(cPedParams &params);
void ProcessPhysical(int32 id);
void ProcessPlane(cVehicleParams& params);
void ProcessPlayerMood();
void ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh);
void ProcessProjectiles();
void ProcessRainOnVehicle(cVehicleParams& params);
void ProcessReverb() const;
bool8 ProcessReverseGear(cVehicleParams& params);
void ProcessScriptObject(int32 id);
void ProcessSpecial();
#ifdef GTA_TRAIN
bool8 ProcessTrainNoise(cVehicleParams *params); //done(bcs not exists in VC)
bool8 ProcessTrainNoise(cVehicleParams *params);
#endif
void ProcessVehicle(CVehicle *vehicle); // done
bool8 ProcessVehicleDoors(cVehicleParams &params); // done
void ProcessVehicleEngine(cVehicleParams &params); // done
void ProcessVehicleFlatTyre(cVehicleParams &params); // done
bool8 ProcessVehicleHorn(cVehicleParams &params); // done
void ProcessVehicleOneShots(cVehicleParams &params); // done
bool8 ProcessVehicleReverseWarning(cVehicleParams &params); // done
bool8 ProcessVehicleRoadNoise(cVehicleParams &params); // done
bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params); // done
bool8 ProcessVehicleSkidding(cVehicleParams &params); // done
void ProcessWaterCannon(int32); // done
void ProcessWeather(int32 id); // done
bool8 ProcessWetRoadNoise(cVehicleParams& params); // done
void ProcessEscalators(); // done
void ProcessExtraSounds(); // done
void ProcessVehicle(CVehicle *vehicle);
bool8 ProcessVehicleDoors(cVehicleParams &params);
void ProcessVehicleEngine(cVehicleParams &params);
void ProcessVehicleFlatTyre(cVehicleParams &params);
bool8 ProcessVehicleHorn(cVehicleParams &params);
void ProcessVehicleOneShots(cVehicleParams &params);
bool8 ProcessVehicleReverseWarning(cVehicleParams &params);
bool8 ProcessVehicleRoadNoise(cVehicleParams &params);
bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params);
bool8 ProcessVehicleSkidding(cVehicleParams &params);
void ProcessWaterCannon(int32);
void ProcessWeather(int32 id);
bool8 ProcessWetRoadNoise(cVehicleParams& params);
void ProcessEscalators();
void ProcessExtraSounds();
int32 RandomDisplacement(uint32 seed) const; // done
void ReacquireDigitalHandle() const; // done
void ReleaseDigitalHandle() const; // done
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2); // done
void ReportCrime(eCrimeType crime, const CVector &pos); // done
void ResetAudioLogicTimers(uint32 timer); // done
void ResetPoliceRadio(); // done
void ResetTimers(uint32 time); // done
int32 RandomDisplacement(uint32 seed) const;
void ReacquireDigitalHandle() const;
void ReleaseDigitalHandle() const;
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2);
void ReportCrime(eCrimeType crime, const CVector &pos);
void ResetAudioLogicTimers(uint32 timer);
void ResetPoliceRadio();
void ResetTimers(uint32 time);
void Service(); // done
void ServiceCollisions(); // done
void ServicePoliceRadio(); // done
void ServicePoliceRadioChannel(uint8 wantedLevel); // done
void ServiceSoundEffects(); // done
int8 SetCurrent3DProvider(uint8 which); // done
void SetDynamicAcousticModelingStatus(bool8 status); // done
void SetEffectsFadeVol(uint8 volume) const; // done
void SetEffectsMasterVolume(uint8 volume) const; // done
void SetMP3BoostVolume(uint8 volume) const; // done
void SetEntityStatus(int32 id, bool8 status); // done
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); // done
void SetMissionAudioLocation(uint8 slot, float x, float y, float z); // done
void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized
void SetMonoMode(bool8 mono); // done
void SetMusicFadeVol(uint8 volume) const; // done
void SetMusicMasterVolume(uint8 volume) const; // done
void SetSpeakerConfig(int32 conf) const; // done
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter); // done
void SetUpOneShotCollisionSound(const cAudioCollision &col); // done
bool8 SetupCrimeReport(); // done
bool8 SetupJumboEngineSound(uint8 vol, uint32 freq); // done
bool8 SetupJumboFlySound(uint8 emittingVol); // done
bool8 SetupJumboRumbleSound(uint8 emittingVol); // done
bool8 SetupJumboTaxiSound(uint8 vol); // done
bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq); // done
void SetupPedComments(cPedParams &params, uint16 sound); // done
void Service();
void ServiceCollisions();
void ServicePoliceRadio();
void ServicePoliceRadioChannel(uint8 wantedLevel);
void ServiceSoundEffects();
int8 SetCurrent3DProvider(uint8 which);
void SetDynamicAcousticModelingStatus(bool8 status);
void SetEffectsFadeVol(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
void SetMP3BoostVolume(uint8 volume) const;
void SetEntityStatus(int32 id, bool8 status);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized
void SetMonoMode(bool8 mono);
void SetMusicFadeVol(uint8 volume) const;
void SetMusicMasterVolume(uint8 volume) const;
void SetSpeakerConfig(int32 conf) const;
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
void SetUpOneShotCollisionSound(const cAudioCollision &col);
bool8 SetupCrimeReport();
bool8 SetupJumboEngineSound(uint8 vol, uint32 freq);
bool8 SetupJumboFlySound(uint8 emittingVol);
bool8 SetupJumboRumbleSound(uint8 emittingVol);
bool8 SetupJumboTaxiSound(uint8 vol);
bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
void SetupPedComments(cPedParams &params, uint16 sound);
void SetupSuspectLastSeenReport();
void Terminate(); // done
void TranslateEntity(Const CVector *v1, CVector *v2) const; // done
void Terminate();
void TranslateEntity(Const CVector *v1, CVector *v2) const;
void UpdateGasPedalAudio(CVehicle *veh, int vehType); // done
void UpdateReflections(); // done
bool8 UsesReverseWarning(int32 model) const; // done
bool8 UsesSiren(cVehicleParams &params) const; // done
bool8 UsesSirenSwitching(cVehicleParams &params) const; // done
void UpdateGasPedalAudio(CVehicle *veh, int vehType);
void UpdateReflections();
bool8 UsesReverseWarning(int32 model) const;
bool8 UsesSiren(cVehicleParams &params) const;
bool8 UsesSirenSwitching(cVehicleParams &params) const;
CVehicle *FindVehicleOfPlayer(); // done
void SetPedTalkingStatus(CPed *ped, bool8 status); // done
void SetPlayersMood(uint8 mood, uint32 time); // done
CVehicle *FindVehicleOfPlayer();
void SetPedTalkingStatus(CPed *ped, bool8 status);
void SetPlayersMood(uint8 mood, uint32 time);
float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); }
#ifdef GTA_PC
// only used in pc
void AdjustSamplesVolume(); // done (inlined)
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // done (inlined)
void AdjustSamplesVolume(); // inlined
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // inlined
#endif
};

View File

@ -1648,7 +1648,7 @@ void CStream::SetPlay(bool state)
{
ALint sourceState = AL_STOPPED;
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState);
if (sourceState != AL_STOPPED )
if (sourceState != AL_STOPPED)
alSourceStop(m_pAlSources[0]);
sourceState = AL_STOPPED;

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
#define WITHWINDOWS
#include "common.h"
#ifdef AUDIO_MSS
@ -1060,10 +1061,20 @@ cSampleManager::Initialise(void)
#endif
for ( int32 i = STREAMED_SOUND_MISSION_MOBR1; i < TOTAL_STREAMED_SOUNDS; i++ )
{
#ifdef PS2_AUDIO_PATHS
strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, StreamedNameTable[i]);
strcat(filepath, PS2StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
if ( !mp3Stream[0] )
#endif
{
strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
}
if ( mp3Stream[0] )
{
@ -1101,11 +1112,21 @@ cSampleManager::Initialise(void)
for (int32 i = 0; i < STREAMED_SOUND_MISSION_MOBR1; i++)
{
#ifdef PS2_AUDIO_PATHS
strcpy(filepath, m_MP3FilesPath);
strcat(filepath, StreamedNameTable[i]);
strcat(filepath, PS2StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
if ( !mp3Stream[0] )
#endif
{
strcpy(filepath, m_MP3FilesPath);
strcat(filepath, StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
}
if (mp3Stream[0])
{
AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
@ -1146,10 +1167,20 @@ cSampleManager::Initialise(void)
#endif
for ( int32 i = STREAMED_SOUND_MISSION_COMPLETED4; i < STREAMED_SOUND_MISSION_PAGER; i++ )
{
#ifdef PS2_AUDIO_PATHS
strcpy(filepath, m_MiscomPath);
strcat(filepath, StreamedNameTable[i]);
strcat(filepath, PS2StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
if ( !mp3Stream[0] )
#endif
{
strcpy(filepath, m_MiscomPath);
strcat(filepath, StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
}
if ( mp3Stream[0] )
{
@ -2042,11 +2073,20 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
}
char filepath[MAX_PATH];
#ifdef PS2_AUDIO_PATHS
strcpy(filepath, nFile < STREAMED_SOUND_MISSION_COMPLETED4 ? m_MP3FilesPath : (nFile < STREAMED_SOUND_MISSION_MOBR1 ? m_MiscomPath : m_WavFilesPath));
strcat(filepath, StreamedNameTable[nFile]);
strcat(filepath, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
if ( !mp3Stream[nStream] )
#endif
{
strcpy(filepath, nFile < STREAMED_SOUND_MISSION_COMPLETED4 ? m_MP3FilesPath : (nFile < STREAMED_SOUND_MISSION_MOBR1 ? m_MiscomPath : m_WavFilesPath));
strcat(filepath, StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
}
if ( mp3Stream[nStream] )
{
@ -2108,10 +2148,20 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
// Try to continue from previous song, if already started
if(!_GetMP3PosFromStreamPos(&position, &e) && !e) {
nFile = 0;
#ifdef PS2_AUDIO_PATHS
strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
mp3Stream[nStream] =
AIL_open_stream(DIG, filename, 0);
strcat(filename, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
if ( !mp3Stream[nStream] )
#endif
{
strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
mp3Stream[nStream] =
AIL_open_stream(DIG, filename, 0);
}
if(mp3Stream[nStream]) {
AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1);
nStreamLoopedFlag[nStream] = TRUE;
@ -2155,11 +2205,20 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
nFile = 0;
_bIsMp3Active = 0;
#ifdef PS2_AUDIO_PATHS
strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
strcat(filename, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] =
AIL_open_stream(DIG, filename, 0);
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
if ( !mp3Stream[nStream] )
#endif
{
strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
mp3Stream[nStream] =
AIL_open_stream(DIG, filename, 0);
}
if(mp3Stream[nStream]) {
AIL_set_stream_loop_count(
mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1);
@ -2200,10 +2259,20 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
position = 0;
nFile = 0;
}
#ifdef PS2_AUDIO_PATHS
strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
strcat(filename, PS2StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
if ( !mp3Stream[nStream] )
#endif
{
strcpy(filename, m_MiscomPath);
strcat(filename, StreamedNameTable[nFile]);
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
}
if ( mp3Stream[nStream] )
{
AIL_set_stream_loop_count(mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1);

View File

@ -920,7 +920,11 @@ cSampleManager::Initialise(void)
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
{
if ( aStream[0] && aStream[0]->Open(StreamedNameTable[i], IsThisTrackAt16KHz(i) ? 16000 : 32000) )
if ( aStream[0] && (
#ifdef PS2_AUDIO_PATHS
aStream[0]->Open(PS2StreamedNameTable[i], IsThisTrackAt16KHz(i) ? 16000 : 32000) ||
#endif
aStream[0]->Open(StreamedNameTable[i], IsThisTrackAt16KHz(i) ? 16000 : 32000)) )
{
uint32 tatalms = aStream[0]->GetLengthMS();
aStream[0]->Close();
@ -1627,9 +1631,7 @@ cSampleManager::StopChannel(uint32 nChannel)
void
cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
char filename[MAX_PATH];
{
ASSERT( nStream < MAX_STREAMS );
if ( nFile < TOTAL_STREAMED_SOUNDS )
@ -1637,10 +1639,10 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
CStream *stream = aStream[nStream];
stream->Close();
strcpy(filename, StreamedNameTable[nFile]);
stream->Open(filename, IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
#endif
stream->Open(StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
if ( !stream->Setup() )
{
stream->Close();
@ -1701,10 +1703,11 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
if(!_GetMP3PosFromStreamPos(&position, &e) && !e) {
nFile = 0;
strcpy(filename, StreamedNameTable[nFile]);
CStream *stream = aStream[nStream];
stream->Open(filename, IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
#endif
stream->Open(StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
if ( stream->Setup() ) {
stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
nStreamLoopedFlag[nStream] = TRUE;
@ -1756,10 +1759,12 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
nFile = 0;
_bIsMp3Active = 0;
strcpy(filename, StreamedNameTable[nFile]);
CStream* stream = aStream[nStream];
stream->Open(filename, IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
CStream *stream = aStream[nStream];
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
#endif
stream->Open(StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
if (stream->Setup()) {
stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
@ -1806,7 +1811,10 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
CStream *stream = aStream[nStream];
aStream[nStream]->Open(filename, IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
#ifdef PS2_AUDIO_PATHS
if(!stream->Open(PS2StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000))
#endif
stream->Open(StreamedNameTable[nFile], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
if ( stream->Setup() ) {
stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);

View File

@ -50,45 +50,45 @@ void CAutoPilot::RemoveOnePathNode()
#ifdef COMPATIBLE_SAVES
void CAutoPilot::Save(uint8*& buf)
{
WriteSaveBuf<int32>(buf, m_nCurrentRouteNode);
WriteSaveBuf<int32>(buf, m_nNextRouteNode);
WriteSaveBuf<int32>(buf, m_nPrevRouteNode);
WriteSaveBuf<int32>(buf, m_nTimeEnteredCurve);
WriteSaveBuf<int32>(buf, m_nTimeToSpendOnCurrentCurve);
WriteSaveBuf<uint32>(buf, m_nCurrentPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nNextPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nPreviousPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nAntiReverseTimer);
WriteSaveBuf<uint32>(buf, m_nTimeToStartMission);
WriteSaveBuf<int8>(buf, m_nPreviousDirection);
WriteSaveBuf<int8>(buf, m_nCurrentDirection);
WriteSaveBuf<int8>(buf, m_nNextDirection);
WriteSaveBuf<int8>(buf, m_nCurrentLane);
WriteSaveBuf<int8>(buf, m_nNextLane);
WriteSaveBuf<uint8>(buf, m_nDrivingStyle);
WriteSaveBuf<uint8>(buf, m_nCarMission);
WriteSaveBuf<uint8>(buf, m_nTempAction);
WriteSaveBuf<uint32>(buf, m_nTimeTempAction);
WriteSaveBuf<float>(buf, m_fMaxTrafficSpeed);
WriteSaveBuf<uint8>(buf, m_nCruiseSpeed);
WriteSaveBuf<uint8>(buf, m_nCruiseSpeedMultiplierType);
SkipSaveBuf(buf, 2);
WriteSaveBuf<float>(buf, m_fCruiseSpeedMultiplier);
WriteSaveBuf(buf, m_nCurrentRouteNode);
WriteSaveBuf(buf, m_nNextRouteNode);
WriteSaveBuf(buf, m_nPrevRouteNode);
WriteSaveBuf(buf, m_nTimeEnteredCurve);
WriteSaveBuf(buf, m_nTimeToSpendOnCurrentCurve);
WriteSaveBuf(buf, m_nCurrentPathNodeInfo);
WriteSaveBuf(buf, m_nNextPathNodeInfo);
WriteSaveBuf(buf, m_nPreviousPathNodeInfo);
WriteSaveBuf(buf, m_nAntiReverseTimer);
WriteSaveBuf(buf, m_nTimeToStartMission);
WriteSaveBuf(buf, m_nPreviousDirection);
WriteSaveBuf(buf, m_nCurrentDirection);
WriteSaveBuf(buf, m_nNextDirection);
WriteSaveBuf(buf, m_nCurrentLane);
WriteSaveBuf(buf, m_nNextLane);
WriteSaveBuf(buf, m_nDrivingStyle);
WriteSaveBuf(buf, m_nCarMission);
WriteSaveBuf(buf, m_nTempAction);
WriteSaveBuf(buf, m_nTimeTempAction);
WriteSaveBuf(buf, m_fMaxTrafficSpeed);
WriteSaveBuf(buf, m_nCruiseSpeed);
WriteSaveBuf(buf, m_nCruiseSpeedMultiplierType);
ZeroSaveBuf(buf, 2);
WriteSaveBuf(buf, m_fCruiseSpeedMultiplier);
uint8 flags = 0;
if (m_bSlowedDownBecauseOfCars) flags |= BIT(0);
if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1);
if (m_bStayInCurrentLevel) flags |= BIT(2);
if (m_bStayInFastLane) flags |= BIT(3);
if (m_bIgnorePathfinding) flags |= BIT(4);
WriteSaveBuf<uint8>(buf, flags);
WriteSaveBuf<uint8>(buf, m_nSwitchDistance);
SkipSaveBuf(buf, 2);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.x);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.y);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.z);
SkipSaveBuf(buf, 32);
WriteSaveBuf<int16>(buf, m_nPathFindNodesCount);
SkipSaveBuf(buf, 6);
WriteSaveBuf(buf, flags);
WriteSaveBuf(buf, m_nSwitchDistance);
ZeroSaveBuf(buf, 2);
WriteSaveBuf(buf, m_vecDestinationCoors.x);
WriteSaveBuf(buf, m_vecDestinationCoors.y);
WriteSaveBuf(buf, m_vecDestinationCoors.z);
ZeroSaveBuf(buf, 32);
WriteSaveBuf(buf, m_nPathFindNodesCount);
ZeroSaveBuf(buf, 6);
}
void CAutoPilot::Load(uint8*& buf)

View File

@ -26,13 +26,6 @@
#include "VarConsole.h"
#include "SaveBuf.h"
#define CRUSHER_GARAGE_X1 (1135.5f)
#define CRUSHER_GARAGE_Y1 (57.0f)
#define CRUSHER_GARAGE_Z1 (-1.0f)
#define CRUSHER_GARAGE_X2 (1149.5f)
#define CRUSHER_GARAGE_Y2 (63.7f)
#define CRUSHER_GARAGE_Z2 (3.5f)
#define ROTATED_DOOR_OPEN_SPEED (0.015f)
#define ROTATED_DOOR_CLOSE_SPEED (0.02f)
#define DEFAULT_DOOR_OPEN_SPEED (0.035f)
@ -1844,11 +1837,12 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
m_nRadioStation = pVehicle->m_nRadioStation;
m_nVariationA = pVehicle->m_aExtras[0];
m_nVariationB = pVehicle->m_aExtras[1];
m_bBulletproof = pVehicle->bBulletProof;
m_bFireproof = pVehicle->bFireProof;
m_bExplosionproof = pVehicle->bExplosionProof;
m_bCollisionproof = pVehicle->bCollisionProof;
m_bMeleeproof = pVehicle->bMeleeProof;
m_nFlags = 0;
if (pVehicle->bBulletProof) m_nFlags |= FLAG_BULLETPROOF;
if (pVehicle->bFireProof) m_nFlags |= FLAG_FIREPROOF;
if (pVehicle->bExplosionProof) m_nFlags |= FLAG_EXPLOSIONPROOF;
if (pVehicle->bCollisionProof) m_nFlags |= FLAG_COLLISIONPROOF;
if (pVehicle->bMeleeProof) m_nFlags |= FLAG_MELEEPROOF;
if (pVehicle->IsCar() || pVehicle->IsBike())
m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour
}
@ -1897,11 +1891,11 @@ CVehicle* CStoredCar::RestoreCar()
}
pVehicle->bHasBeenOwnedByPlayer = true;
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
pVehicle->bBulletProof = m_bBulletproof;
pVehicle->bFireProof = m_bFireproof;
pVehicle->bExplosionProof = m_bExplosionproof;
pVehicle->bCollisionProof = m_bCollisionproof;
pVehicle->bMeleeProof = m_bMeleeproof;
if (m_nFlags & FLAG_BULLETPROOF) pVehicle->bBulletProof = true;
if (m_nFlags & FLAG_FIREPROOF) pVehicle->bFireProof = true;
if (m_nFlags & FLAG_EXPLOSIONPROOF) pVehicle->bExplosionProof = true;
if (m_nFlags & FLAG_COLLISIONPROOF) pVehicle->bCollisionProof = true;
if (m_nFlags & FLAG_MELEEPROOF) pVehicle->bMeleeProof = true;
return pVehicle;
}
@ -2265,6 +2259,9 @@ void CGarages::Save(uint8 * buf, uint32 * size)
//INITSAVEBUF
*size = 7876; // for some reason it's not actual size again
//*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
#if !defined THIS_IS_STUPID && defined COMPATIBLE_SAVES
memset(buf + 7340, 0, *size - 7340); // garbage data is written otherwise
#endif
CloseHideOutGaragesBeforeSave();
WriteSaveBuf(buf, NumGarages);
WriteSaveBuf(buf, (uint32)BombsAreFree);
@ -2280,8 +2277,53 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, aCarsInSafeHouses[j][i]);
}
}
for (int i = 0; i < NUM_GARAGES; i++)
for (int i = 0; i < NUM_GARAGES; i++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aGarages[i].m_eGarageType);
WriteSaveBuf(buf, aGarages[i].m_eGarageState);
WriteSaveBuf(buf, aGarages[i].m_nMaxStoredCars);
WriteSaveBuf(buf, aGarages[i].field_2);
WriteSaveBuf(buf, aGarages[i].m_bClosingWithoutTargetCar);
WriteSaveBuf(buf, aGarages[i].m_bDeactivated);
WriteSaveBuf(buf, aGarages[i].m_bResprayHappened);
ZeroSaveBuf(buf, 1);
WriteSaveBuf(buf, aGarages[i].m_nTargetModelIndex);
ZeroSaveBuf(buf, 4 + 4);
WriteSaveBuf(buf, aGarages[i].m_bDoor1PoolIndex);
WriteSaveBuf(buf, aGarages[i].m_bDoor2PoolIndex);
WriteSaveBuf(buf, aGarages[i].m_bDoor1IsDummy);
WriteSaveBuf(buf, aGarages[i].m_bDoor2IsDummy);
WriteSaveBuf(buf, aGarages[i].m_bRecreateDoorOnNextRefresh);
WriteSaveBuf(buf, aGarages[i].m_bRotatedDoor);
WriteSaveBuf(buf, aGarages[i].m_bCameraFollowsPlayer);
ZeroSaveBuf(buf, 1);
WriteSaveBuf(buf, aGarages[i].m_vecCorner1);
WriteSaveBuf(buf, aGarages[i].m_fInfZ);
WriteSaveBuf(buf, aGarages[i].m_vDir1);
WriteSaveBuf(buf, aGarages[i].m_vDir2);
WriteSaveBuf(buf, aGarages[i].m_fSupZ);
WriteSaveBuf(buf, aGarages[i].m_fDir1Len);
WriteSaveBuf(buf, aGarages[i].m_fDir2Len);
WriteSaveBuf(buf, aGarages[i].m_fInfX);
WriteSaveBuf(buf, aGarages[i].m_fSupX);
WriteSaveBuf(buf, aGarages[i].m_fInfY);
WriteSaveBuf(buf, aGarages[i].m_fSupY);
WriteSaveBuf(buf, aGarages[i].m_fDoorPos);
WriteSaveBuf(buf, aGarages[i].m_fDoorHeight);
WriteSaveBuf(buf, aGarages[i].m_fDoor1X);
WriteSaveBuf(buf, aGarages[i].m_fDoor1Y);
WriteSaveBuf(buf, aGarages[i].m_fDoor2X);
WriteSaveBuf(buf, aGarages[i].m_fDoor2Y);
WriteSaveBuf(buf, aGarages[i].m_fDoor1Z);
WriteSaveBuf(buf, aGarages[i].m_fDoor2Z);
WriteSaveBuf(buf, aGarages[i].m_nTimeToStartAction);
WriteSaveBuf(buf, aGarages[i].m_bCollectedCarsState);
ZeroSaveBuf(buf, 3 + 4);
ZeroSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
WriteSaveBuf(buf, aGarages[i]);
#endif
}
//VALIDATESAVEBUF(*size);
}
@ -2290,11 +2332,7 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
m_nModelIndex = other.m_nModelIndex;
m_vecPos = other.m_vecPos;
m_vecAngle = other.m_vecAngle;
m_bBulletproof = other.m_bBulletproof;
m_bFireproof = other.m_bFireproof;
m_bExplosionproof = other.m_bExplosionproof;
m_bCollisionproof = other.m_bCollisionproof;
m_bMeleeproof = other.m_bMeleeproof;
m_nFlags = other.m_nFlags;
m_nPrimaryColor = other.m_nPrimaryColor;
m_nSecondaryColor = other.m_nSecondaryColor;
m_nRadioStation = other.m_nRadioStation;
@ -2307,7 +2345,7 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
void CGarages::Load(uint8* buf, uint32 size)
{
//INITSAVEBUF
assert(size = 7876);
assert(size == 7876);
//assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)));
CloseHideOutGaragesBeforeSave();
ReadSaveBuf(&NumGarages, buf);
@ -2328,7 +2366,51 @@ void CGarages::Load(uint8* buf, uint32 size)
}
}
for (int i = 0; i < NUM_GARAGES; i++) {
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aGarages[i].m_eGarageType, buf);
ReadSaveBuf(&aGarages[i].m_eGarageState, buf);
ReadSaveBuf(&aGarages[i].m_nMaxStoredCars, buf);
ReadSaveBuf(&aGarages[i].field_2, buf);
ReadSaveBuf(&aGarages[i].m_bClosingWithoutTargetCar, buf);
ReadSaveBuf(&aGarages[i].m_bDeactivated, buf);
ReadSaveBuf(&aGarages[i].m_bResprayHappened, buf);
SkipSaveBuf(buf, 1);
ReadSaveBuf(&aGarages[i].m_nTargetModelIndex, buf);
SkipSaveBuf(buf, 4 + 4);
ReadSaveBuf(&aGarages[i].m_bDoor1PoolIndex, buf);
ReadSaveBuf(&aGarages[i].m_bDoor2PoolIndex, buf);
ReadSaveBuf(&aGarages[i].m_bDoor1IsDummy, buf);
ReadSaveBuf(&aGarages[i].m_bDoor2IsDummy, buf);
ReadSaveBuf(&aGarages[i].m_bRecreateDoorOnNextRefresh, buf);
ReadSaveBuf(&aGarages[i].m_bRotatedDoor, buf);
ReadSaveBuf(&aGarages[i].m_bCameraFollowsPlayer, buf);
SkipSaveBuf(buf, 1);
ReadSaveBuf(&aGarages[i].m_vecCorner1, buf);
ReadSaveBuf(&aGarages[i].m_fInfZ, buf);
ReadSaveBuf(&aGarages[i].m_vDir1, buf);
ReadSaveBuf(&aGarages[i].m_vDir2, buf);
ReadSaveBuf(&aGarages[i].m_fSupZ, buf);
ReadSaveBuf(&aGarages[i].m_fDir1Len, buf);
ReadSaveBuf(&aGarages[i].m_fDir2Len, buf);
ReadSaveBuf(&aGarages[i].m_fInfX, buf);
ReadSaveBuf(&aGarages[i].m_fSupX, buf);
ReadSaveBuf(&aGarages[i].m_fInfY, buf);
ReadSaveBuf(&aGarages[i].m_fSupY, buf);
ReadSaveBuf(&aGarages[i].m_fDoorPos, buf);
ReadSaveBuf(&aGarages[i].m_fDoorHeight, buf);
ReadSaveBuf(&aGarages[i].m_fDoor1X, buf);
ReadSaveBuf(&aGarages[i].m_fDoor1Y, buf);
ReadSaveBuf(&aGarages[i].m_fDoor2X, buf);
ReadSaveBuf(&aGarages[i].m_fDoor2Y, buf);
ReadSaveBuf(&aGarages[i].m_fDoor1Z, buf);
ReadSaveBuf(&aGarages[i].m_fDoor2Z, buf);
ReadSaveBuf(&aGarages[i].m_nTimeToStartAction, buf);
ReadSaveBuf(&aGarages[i].m_bCollectedCarsState, buf);
SkipSaveBuf(buf, 3 + 4);
SkipSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
ReadSaveBuf(&aGarages[i], buf);
#endif
aGarages[i].m_pDoor1 = nil;
aGarages[i].m_pDoor2 = nil;
aGarages[i].m_pTarget = nil;

View File

@ -63,14 +63,17 @@ enum
class CStoredCar
{
enum {
FLAG_BULLETPROOF = 0x1,
FLAG_FIREPROOF = 0x2,
FLAG_EXPLOSIONPROOF = 0x4,
FLAG_COLLISIONPROOF = 0x8,
FLAG_MELEEPROOF = 0x10,
};
int32 m_nModelIndex;
CVector m_vecPos;
CVector m_vecAngle;
int32 m_bBulletproof : 1;
int32 m_bFireproof : 1;
int32 m_bExplosionproof : 1;
int32 m_bCollisionproof : 1;
int32 m_bMeleeproof : 1;
int32 m_nFlags;
int8 m_nPrimaryColor;
int8 m_nSecondaryColor;
int8 m_nRadioStation;
@ -100,7 +103,7 @@ public:
bool m_bClosingWithoutTargetCar;
bool m_bDeactivated;
bool m_bResprayHappened;
int m_nTargetModelIndex;
int32 m_nTargetModelIndex;
CEntity *m_pDoor1;
CEntity *m_pDoor2;
uint8 m_bDoor1PoolIndex;

View File

@ -18,6 +18,12 @@
#include "Replay.h"
#endif
#ifdef COMPATIBLE_SAVES
#define PHONEINFO_SAVE_SIZE 0xA30
#else
#define PHONEINFO_SAVE_SIZE sizeof(CPhoneInfo)
#endif
CPhoneInfo gPhoneInfo;
bool CPhoneInfo::bDisplayingPhoneMessage; // is phone picked up
@ -201,11 +207,24 @@ INITSAVEBUF
ReadSaveBuf(&m_nMax, buf);
ReadSaveBuf(&m_nScriptPhonesMax, buf);
for (int i = 0; i < NUMPHONES; i++) {
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&m_aPhones[i].m_vecPos, buf);
SkipSaveBuf(buf, 6 * 4);
ReadSaveBuf(&m_aPhones[i].m_repeatedMessagePickupStart, buf);
int32 tmp;
ReadSaveBuf(&tmp, buf);
// It's saved as building pool index in save file, convert it to true entity
m_aPhones[i].m_pEntity = tmp != 0 ? CPools::GetBuildingPool()->GetSlot(tmp - 1) : nil;
ReadSaveBuf(&m_aPhones[i].m_nState, buf);
ReadSaveBuf(&m_aPhones[i].m_visibleToCam, buf);
SkipSaveBuf(buf, 3);
#else
ReadSaveBuf(&m_aPhones[i], buf);
// It's saved as building pool index in save file, convert it to true entity
if (m_aPhones[i].m_pEntity) {
m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
}
#endif
}
VALIDATESAVEBUF(size)
}
@ -299,17 +318,29 @@ CPhoneInfo::Initialise(void)
void
CPhoneInfo::Save(uint8 *buf, uint32 *size)
{
*size = sizeof(CPhoneInfo);
*size = PHONEINFO_SAVE_SIZE;
INITSAVEBUF
WriteSaveBuf(buf, m_nMax);
WriteSaveBuf(buf, m_nScriptPhonesMax);
for(int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, m_aPhones[phoneId].m_vecPos);
ZeroSaveBuf(buf, 6 * 4);
WriteSaveBuf(buf, m_aPhones[phoneId].m_repeatedMessagePickupStart);
// Convert entity pointer to building pool index while saving
int32 tmp = m_aPhones[phoneId].m_pEntity ? CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)m_aPhones[phoneId].m_pEntity) + 1 : 0;
WriteSaveBuf(buf, tmp);
WriteSaveBuf(buf, m_aPhones[phoneId].m_nState);
WriteSaveBuf(buf, m_aPhones[phoneId].m_visibleToCam);
ZeroSaveBuf(buf, 3);
#else
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
// Convert entity pointer to building pool index while saving
if (phone->m_pEntity) {
phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)phone->m_pEntity) + 1);
}
#endif
}
VALIDATESAVEBUF(*size)
}

View File

@ -35,6 +35,12 @@
#include "Streaming.h"
#include "SaveBuf.h"
#ifdef COMPATIBLE_SAVES
#define PICKUPS_SAVE_SIZE 0x4440
#else
#define PICKUPS_SAVE_SIZE sizeof(aPickUps)
#endif
CPickup CPickups::aPickUps[NUMPICKUPS];
int16 CPickups::NumMessages;
int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
@ -1442,6 +1448,31 @@ CPickups::Load(uint8 *buf, uint32 size)
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aPickUps[i].m_vecPos, buf);
ReadSaveBuf(&aPickUps[i].m_fRevenue, buf);
int32 tmp_pObject;
ReadSaveBuf(&tmp_pObject, buf);
int32 tmp_pExtraObject;
ReadSaveBuf(&tmp_pExtraObject, buf);
ReadSaveBuf(&aPickUps[i].m_nQuantity, buf);
ReadSaveBuf(&aPickUps[i].m_nTimer, buf);
ReadSaveBuf(&aPickUps[i].m_nMoneySpeed, buf);
ReadSaveBuf(&aPickUps[i].m_eModelIndex, buf);
ReadSaveBuf(&aPickUps[i].m_nIndex, buf);
memcpy(aPickUps[i].m_sTextKey, buf, sizeof(aPickUps[i].m_sTextKey));
SkipSaveBuf(buf, sizeof(aPickUps[i].m_sTextKey));
ReadSaveBuf(&aPickUps[i].m_eType, buf);
ReadSaveBuf(&aPickUps[i].m_bRemoved, buf);
uint8 flags;
ReadSaveBuf(&flags, buf);
aPickUps[i].m_bWasAmmoCollected = !!(flags & BIT(0));
aPickUps[i].m_bWasControlMessageShown = !!(flags & BIT(1));
SkipSaveBuf(buf, 3);
aPickUps[i].m_pObject = aPickUps[i].m_eType != PICKUP_NONE && tmp_pObject != 0 ? CPools::GetObjectPool()->GetSlot(tmp_pObject - 1) : nil;
aPickUps[i].m_pExtraObject = aPickUps[i].m_eType != PICKUP_NONE && tmp_pExtraObject != 0 ? CPools::GetObjectPool()->GetSlot(tmp_pExtraObject - 1) : nil;
#else
ReadSaveBuf(&aPickUps[i], buf);
if (aPickUps[i].m_eType != PICKUP_NONE) {
@ -1450,7 +1481,7 @@ INITSAVEBUF
if (aPickUps[i].m_pExtraObject != nil)
aPickUps[i].m_pExtraObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pExtraObject - 1);
}
#endif
}
ReadSaveBuf(&CollectedPickUpIndex, buf);
@ -1466,12 +1497,34 @@ VALIDATESAVEBUF(size)
void
CPickups::Save(uint8 *buf, uint32 *size)
{
*size = sizeof(aPickUps);
*size = PICKUPS_SAVE_SIZE;
*size += sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aPickUps[i].m_vecPos);
WriteSaveBuf(buf, aPickUps[i].m_fRevenue);
int32 tmp = aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aPickUps[i].m_pObject) + 1 : 0;
WriteSaveBuf(buf, tmp);
tmp = aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pExtraObject != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aPickUps[i].m_pExtraObject) + 1 : 0;
WriteSaveBuf(buf, tmp);
WriteSaveBuf(buf, aPickUps[i].m_nQuantity);
WriteSaveBuf(buf, aPickUps[i].m_nTimer);
WriteSaveBuf(buf, aPickUps[i].m_nMoneySpeed);
WriteSaveBuf(buf, aPickUps[i].m_eModelIndex);
WriteSaveBuf(buf, aPickUps[i].m_nIndex);
memcpy(buf, aPickUps[i].m_sTextKey, sizeof(aPickUps[i].m_sTextKey));
SkipSaveBuf(buf, sizeof(aPickUps[i].m_sTextKey));
WriteSaveBuf(buf, aPickUps[i].m_eType);
WriteSaveBuf(buf, aPickUps[i].m_bRemoved);
uint8 flags = 0;
if (aPickUps[i].m_bWasAmmoCollected) flags |= BIT(0);
if (aPickUps[i].m_bWasControlMessageShown) flags |= BIT(1);
WriteSaveBuf(buf, flags);
ZeroSaveBuf(buf, 3);
#else
CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
if (buf_pickup->m_eType != PICKUP_NONE) {
if (buf_pickup->m_pObject != nil)
@ -1479,6 +1532,7 @@ INITSAVEBUF
if (buf_pickup->m_pExtraObject != nil)
buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pExtraObject) + 1);
}
#endif
}
WriteSaveBuf(buf, CollectedPickUpIndex);

View File

@ -2208,20 +2208,16 @@ void CRunningScript::Init()
int scriptToLoad = 0;
const char *scriptfile = "main.scm";
#ifdef _WIN32
#include <Windows.h>
#endif
int open_script()
{
// glfwGetKey doesn't work because of CGame::Initialise is blocking
#ifdef _WIN32
if (GetAsyncKeyState('G') & 0x8000)
// glfwGetKey doesn't work because of CGame::Initialise is blocking
CPad::UpdatePads();
if (CPad::GetPad(0)->GetChar('G'))
scriptToLoad = 0;
if (GetAsyncKeyState('R') & 0x8000)
if (CPad::GetPad(0)->GetChar('R'))
scriptToLoad = 1;
if (GetAsyncKeyState('D') & 0x8000)
if (CPad::GetPad(0)->GetChar('D'))
scriptToLoad = 2;
#endif
switch (scriptToLoad) {
case 0: scriptfile = "main.scm"; break;
case 1: scriptfile = "freeroam_miami.scm"; break;

View File

@ -2267,33 +2267,33 @@ VALIDATESAVEBUF(size)
void CRunningScript::Save(uint8*& buf)
{
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
ZeroSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
WriteSaveBuf<char>(buf, m_abScriptName[i]);
WriteSaveBuf<uint32>(buf, m_nIp);
WriteSaveBuf(buf, m_abScriptName[i]);
WriteSaveBuf(buf, m_nIp);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
WriteSaveBuf<uint32>(buf, m_anStack[i]);
WriteSaveBuf<uint16>(buf, m_nStackPointer);
SkipSaveBuf(buf, 2);
WriteSaveBuf(buf, m_anStack[i]);
WriteSaveBuf(buf, m_nStackPointer);
ZeroSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
WriteSaveBuf<bool>(buf, m_bIsActive);
WriteSaveBuf<bool>(buf, m_bCondResult);
WriteSaveBuf<bool>(buf, m_bIsMissionScript);
WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
WriteSaveBuf<uint32>(buf, m_nWakeTime);
WriteSaveBuf<uint16>(buf, m_nAndOrState);
WriteSaveBuf<bool>(buf, m_bNotFlag);
WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled);
WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted);
WriteSaveBuf<bool>(buf, m_bMissionFlag);
SkipSaveBuf(buf, 2);
WriteSaveBuf(buf, m_anLocalVariables[i]);
WriteSaveBuf(buf, m_bIsActive);
WriteSaveBuf(buf, m_bCondResult);
WriteSaveBuf(buf, m_bIsMissionScript);
WriteSaveBuf(buf, m_bSkipWakeTime);
WriteSaveBuf(buf, m_nWakeTime);
WriteSaveBuf(buf, m_nAndOrState);
WriteSaveBuf(buf, m_bNotFlag);
WriteSaveBuf(buf, m_bDeatharrestEnabled);
WriteSaveBuf(buf, m_bDeatharrestExecuted);
WriteSaveBuf(buf, m_bMissionFlag);
ZeroSaveBuf(buf, 2);
#else
WriteSaveBuf(buf, *this);
#endif

View File

@ -457,7 +457,7 @@ CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strengt
if (target) {
if (target->IsPed()) {
ped->m_pFire = fire;
if (target != (CVehicle *)FindPlayerPed()) {
if (target != FindPlayerPed()) {
CVector2D pos = target->GetPosition();
ped->SetFlee(pos, 10000);
ped->SetMoveAnim();

View File

@ -4558,19 +4558,11 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
#ifdef USE_DEBUG_SCRIPT_LOADER
if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
#ifdef RW_GL3
if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
if (CPad::GetPad(0)->GetChar('R')) {
scriptToLoad = 1;
DoSettingsBeforeStartingAGame();
return;
}
#elif defined _WIN32
if (GetAsyncKeyState('R') & 0x8000) {
scriptToLoad = 1;
DoSettingsBeforeStartingAGame();
return;
}
#endif
}
#endif

View File

@ -33,4 +33,4 @@ public:
bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2);
};
VALIDATE_SIZE(CPlaceable, 0x4C);
VALIDATE_SIZE(CPlaceable, 0x48);

View File

@ -310,9 +310,9 @@ INITSAVEBUF
#else
if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf<uint32>(buf, pVehicle->m_vehType);
WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex());
WriteSaveBuf<int32>(buf, GetVehicleRef(pVehicle));
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
pVehicle->Save(buf);
}
#else
@ -321,7 +321,7 @@ INITSAVEBUF
#else
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
memcpy(buf, pVehicle, sizeof(CAutomobile));
@ -332,7 +332,7 @@ INITSAVEBUF
#else
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
memcpy(buf, pVehicle, sizeof(CBoat));
@ -343,7 +343,7 @@ INITSAVEBUF
#else
if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
memcpy(buf, pVehicle, sizeof(CBike));

View File

@ -1229,7 +1229,11 @@ CStats::ConstructStatLine(int rowIdx)
FASTEST_TIME(20, "STFT_21");
if (FastestTimes[21])
#ifdef FIX_BUGS
STAT_LINE_1(float, "STFT_22", Floor(FastestTimes[21] / 10) / 100, 1);
#else
STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1);
#endif
if (TopShootingRangeScore > 0.0f)
STAT_LINE_1(int, "TOP_SHO", TopShootingRangeScore, 0);

View File

@ -1,7 +1,9 @@
#pragma once
// disables (most) stuff that wasn't in original gta-vc.exe - check section at the bottom of this file
//#define VANILLA_DEFINES
// disables (most) stuff that wasn't in original gta-vc.exe
#ifdef __MWERKS__
#define VANILLA_DEFINES
#endif
enum Config {
NUMPLAYERS = 1,
@ -154,8 +156,33 @@ enum Config {
//#define GTA_PS2
//#define GTA_XBOX
// This enables things from the PS2 version on PC
#define GTA_PS2_STUFF
// Version defines
#define GTAVC_PS2 400
#define GTAVC_PC_10 410
#define GTAVC_PC_11 411
#define GTAVC_PC_JAP 412
// TODO? maybe something for xbox or android?
#define GTA_VERSION GTAVC_PC_11
// TODO(MIAMI): someone ought to find and check out uses of these defines:
//#define GTA3_STEAM_PATCH
//#define GTAVC_JP_PATCH
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
//# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
# define PS2_MENU
#elif defined GTA_PC
# define PC_PLAYER_CONTROLS // mouse player/cam mode
# define GTA_REPLAY
# define GTA_SCENE_EDIT
# define PC_MENU
# define PC_WATER
#elif defined GTA_XBOX
#endif
// This is enabled for all released games.
// any debug stuff that isn't left in any game is not in FINAL
@ -174,22 +201,28 @@ enum Config {
#define FINAL
#endif
// Version defines
#define GTAVC_PS2 400
#define GTAVC_PC_10 410
#define GTAVC_PC_11 411
#define GTAVC_PC_JAP 412
// TODO? maybe something for xbox or android?
// these are placed here to work with VANILLA_DEFINES for compatibility
#define NO_CDCHECK // skip audio CD check
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
#define GTA_VERSION GTAVC_PC_11
#ifdef VANILLA_DEFINES
#if !defined(_WIN32) || defined(__LP64__) || defined(_WIN64)
#error Vanilla can only be built for win-x86
#endif
// TODO(MIAMI): someone ought to find and check out uses of these defines:
//#define GTA3_STEAM_PATCH
//#define GTAVC_JP_PATCH
#define FINAL
#define MASTER
//#define USE_MY_DOCUMENTS
#define THIS_IS_STUPID
#define DONT_FIX_REPLAY_BUGS
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
//#define USE_TEXTURE_POOL // not possible because R* used custom RW33
#else
// This enables things from the PS2 version on PC
#define GTA_PS2_STUFF
// quality of life fixes that should also be in FINAL
#define NASTY_GAME // nasty game for all languages
#define NO_CDCHECK
// those infamous texts
#define DRAW_GAME_VERSION_TEXT
@ -204,21 +237,10 @@ enum Config {
//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
//# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
#elif defined GTA_PC
# ifdef GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
# endif
# define PC_PLAYER_CONTROLS // mouse player/cam mode
# define GTA_REPLAY
# define GTA_SCENE_EDIT
#elif defined GTA_XBOX
#if defined GTA_PC && defined GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
#endif
#ifdef VU_COLLISION
@ -246,7 +268,8 @@ enum Config {
#define FIX_BUGS // fixes bugs that we've came across during reversing. You can undefine this only on release builds.
#define MORE_LANGUAGES // Add more translations to the game
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible, and keeps saves compatible between platforms
#define FIX_INCOMPATIBLE_SAVES // try to fix incompatible saves, requires COMPATIBLE_SAVES
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
#define NO_MOVIES // add option to disable intro videos
@ -257,7 +280,7 @@ enum Config {
#define ASCII_STRCMP // use faster ascii str comparisons
#if !defined _WIN32 || defined __MWERKS__ || defined __MINGW32__ || defined VANILLA_DEFINES
#if !defined _WIN32 || defined __MINGW32__
#undef ASCII_STRCMP
#endif
@ -292,11 +315,11 @@ enum Config {
#endif
// Water & Particle
// #define PC_WATER
#undef PC_WATER
#define WATER_CHEATS
//#define USE_CUTSCENE_SHADOW_FOR_PED
#define DISABLE_CUTSCENE_SHADOWS
//#define USE_CUTSCENE_SHADOW_FOR_PED // requires COMPATIBLE_SAVES
//#define DISABLE_CUTSCENE_SHADOWS
// Pad
#if !defined(RW_GL3) && defined(_WIN32)
@ -396,7 +419,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#define RADIO_SCROLL_TO_PREV_STATION // Won't work without FIX_BUGS
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot
#define PS2_AUDIO_CHANNELS // increases the maximum number of audio channels to PS2 value of 43 (PC has 28 originally)
//#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files
#define MULTITHREADED_AUDIO // for streams. requires C++11 or later
@ -428,92 +451,9 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef PS2_AUDIO_CHANNELS
#endif
// -------
#if defined __MWERKS__ || defined VANILLA_DEFINES
#define FINAL
#undef CHATTYSPLASH
#undef TIMEBARS
#define MASTER
#undef VALIDATE_SAVE_SIZE
#undef NO_MOVIES
#undef DEBUGMENU
#undef DRAW_GAME_VERSION_TEXT
//#undef NASTY_GAME
//#undef NO_CDCHECK
#undef GTA_PS2_STUFF
#undef USE_PS2_RAND
#undef RANDOMSPLASH
#undef PS2_MATFX
#undef FIX_BUGS
#define THIS_IS_STUPID
#undef MORE_LANGUAGES
#undef COMPATIBLE_SAVES
#undef LOAD_INI_SETTINGS
#undef ASPECT_RATIO_SCALE
#undef PROPER_SCALING
//#undef DEFAULT_NATIVE_RESOLUTION
#undef PS2_ALPHA_TEST
#undef IMPROVED_VIDEOMODE
#undef DISABLE_LOADING_SCREEN
#undef DISABLE_VSYNC_ON_TEXTURE_CONVERSION
#undef FIX_SPRITES
#define PC_WATER
#undef WATER_CHEATS
// if these defines are enabled saves are not vanilla compatible without COMPATIBLE_SAVES
#ifndef COMPATIBLE_SAVES
#undef USE_CUTSCENE_SHADOW_FOR_PED
#undef DISABLE_CUTSCENE_SHADOWS
#undef XINPUT
#undef DETECT_PAD_INPUT_SWITCH
#undef KANGAROO_CHEAT
#undef RESTORE_ALLCARSHELI_CHEAT
#undef BETTER_ALLCARSAREDODO_CHEAT
#undef WALLCLIMB_CHEAT
#undef REGISTER_START_BUTTON
#undef BIND_VEHICLE_FIREWEAPON
#undef BUTTON_ICONS
#undef FIX_RADAR
#undef RADIO_OFF_TEXT
#undef MAP_ENHANCEMENTS
#undef GAMEPAD_MENU
#undef MUCH_SHORTER_OUTRO_SCREEN
#undef CUSTOM_FRONTEND_OPTIONS
#undef GRAPHICS_MENU_OPTIONS
#undef NO_ISLAND_LOADING
#undef CUTSCENE_BORDERS_SWITCH
#undef MULTISAMPLING
#undef INVERT_LOOK_FOR_PAD
#undef USE_DEBUG_SCRIPT_LOADER
#undef USE_MEASUREMENTS_IN_METERS
#undef USE_PRECISE_MEASUREMENT_CONVERTION
#undef SUPPORT_JAPANESE_SCRIPT
#undef MISSION_REPLAY
#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
#define DONT_FIX_REPLAY_BUGS
#undef EXPLODING_AIRTRAIN
#undef CPLANE_ROTORS
#undef CAMERA_PICKUP
#undef CANCELLABLE_CAR_ENTER
#undef IMPROVED_CAMERA
#undef FREE_CAM
#undef BIG_IMG
#undef PS2_AUDIO_CHANNELS
#undef MULTITHREADED_AUDIO
#undef RADIO_SCROLL_TO_PREV_STATION
#endif
#endif // VANILLA_DEFINES

View File

@ -189,16 +189,29 @@ CustomFrontendOptionsPopulate(void)
#endif
#ifdef LOAD_INI_SETTINGS
#include "ini_parser.hpp"
#define MINI_CASE_SENSITIVE
#include "ini.h"
mINI::INIFile ini("reVC.ini");
mINI::INIStructure cfg;
linb::ini cfg;
bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtoul(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtoul(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
}
bool ReadIniIfExists(const char *cat, const char *key, uint8 *out)
{
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtoul(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -206,11 +219,10 @@ bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
bool ReadIniIfExists(const char *cat, const char *key, bool *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtoul(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtoul(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -218,11 +230,10 @@ bool ReadIniIfExists(const char *cat, const char *key, bool *out)
bool ReadIniIfExists(const char *cat, const char *key, int32 *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtol(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtol(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -230,11 +241,10 @@ bool ReadIniIfExists(const char *cat, const char *key, int32 *out)
bool ReadIniIfExists(const char *cat, const char *key, int8 *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtol(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtol(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -242,10 +252,10 @@ bool ReadIniIfExists(const char *cat, const char *key, int8 *out)
bool ReadIniIfExists(const char *cat, const char *key, float *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
if (value && value[0] != '\xBA') {
*out = atof(value);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtof(section.get(key).c_str(), &endPtr);
return true;
}
return false;
@ -253,10 +263,10 @@ bool ReadIniIfExists(const char *cat, const char *key, float *out)
bool ReadIniIfExists(const char *cat, const char *key, char *out, int size)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
if (value && value[0] != '\xBA') {
strncpy(out, value, size);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
strncpy(out, section.get(key).c_str(), size - 1);
out[size - 1] = '\0';
return true;
}
return false;
@ -264,42 +274,42 @@ bool ReadIniIfExists(const char *cat, const char *key, char *out, int size)
void StoreIni(const char *cat, const char *key, uint32 val)
{
char temp[10];
sprintf(temp, "%u", val);
cfg.set(cat, key, temp);
char temp[11];
sprintf(temp, "%u", val);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, uint8 val)
{
char temp[10];
sprintf(temp, "%u", (uint32)val);
cfg.set(cat, key, temp);
char temp[11];
sprintf(temp, "%u", val);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, int32 val)
{
char temp[10];
char temp[11];
sprintf(temp, "%d", val);
cfg.set(cat, key, temp);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, int8 val)
{
char temp[10];
sprintf(temp, "%d", (int32)val);
cfg.set(cat, key, temp);
char temp[11];
sprintf(temp, "%d", val);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, float val)
{
char temp[10];
char temp[50];
sprintf(temp, "%f", val);
cfg.set(cat, key, temp);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, char *val, int size)
{
cfg.set(cat, key, val);
cfg[cat][key] = val;
}
const char *iniControllerActions[] = { "PED_FIREWEAPON", "PED_CYCLE_WEAPON_RIGHT", "PED_CYCLE_WEAPON_LEFT", "GO_FORWARD", "GO_BACK", "GO_LEFT", "GO_RIGHT", "PED_SNIPER_ZOOM_IN",
@ -361,7 +371,7 @@ void LoadINIControllerSettings()
#endif
// force to default GTA behaviour (never overwrite bindings on joy change/initialization) if user init'ed/set bindings before we introduced that
if (!ReadIniIfExists("Controller", "PadButtonsInited", &ControlsManager.ms_padButtonsInited)) {
ControlsManager.ms_padButtonsInited = cfg.category_size("Bindings") != 0 ? 16 : 0;
ControlsManager.ms_padButtonsInited = cfg.get("Bindings").size() != 0 ? 16 : 0;
}
for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) {
@ -463,12 +473,13 @@ void SaveINIControllerSettings()
#endif
#endif
StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited);
cfg.write_file("reVC.ini");
ini.write(cfg);
}
bool LoadINISettings()
{
if (!cfg.load_file("reVC.ini"))
if (!ini.read(cfg))
return false;
#ifdef IMPROVED_VIDEOMODE
@ -540,7 +551,7 @@ bool LoadINISettings()
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
bool migrate = cfg.category_size("FrontendOptions") != 0;
bool migrate = cfg.get("FrontendOptions").size() != 0;
for (int i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) {
CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
@ -553,7 +564,7 @@ bool LoadINISettings()
// Migrate from old .ini to new .ini
if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, option.m_CFO->value))
cfg.remove("FrontendOptions", option.m_CFO->save);
cfg["FrontendOptions"].remove(option.m_CFO->save);
else
ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value);
@ -652,7 +663,7 @@ void SaveINISettings()
}
#endif
cfg.write_file("reVC.ini");
ini.write(cfg);
}
#endif

View File

@ -824,7 +824,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
if (bStreamingDontDelete) tmp |= BIT(30);
if (bRemoveFromWorld) tmp |= BIT(31);
WriteSaveBuf<uint32>(buf, tmp);
WriteSaveBuf(buf, tmp);
tmp = 0;
@ -845,7 +845,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
if (bUnderwater) tmp |= BIT(13);
if (bHasPreRenderEffects) tmp |= BIT(14);
WriteSaveBuf<uint32>(buf, tmp);
WriteSaveBuf(buf, tmp);
}
void

View File

@ -521,6 +521,10 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin
{
float speedA = DotProduct(speed, springDir);
float speedB = DotProduct(GetSpeed(point), springDir);
#ifdef FIX_BUGS
if (speedB == 0.0f)
return true;
#endif
float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f;
if(bIsHeavy)

761
src/extras/ini.h Normal file
View File

@ -0,0 +1,761 @@
/*
* The MIT License (MIT)
* Copyright (c) 2018 Danijel Durakovic
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
///////////////////////////////////////////////////////////////////////////////
//
// /mINI/ v0.9.10
// An INI file reader and writer for the modern age.
//
///////////////////////////////////////////////////////////////////////////////
//
// A tiny utility library for manipulating INI files with a straightforward
// API and a minimal footprint. It conforms to the (somewhat) standard INI
// format - sections and keys are case insensitive and all leading and
// trailing whitespace is ignored. Comments are lines that begin with a
// semicolon. Trailing comments are allowed on section lines.
//
// Files are read on demand, upon which data is kept in memory and the file
// is closed. This utility supports lazy writing, which only writes changes
// and updates to a file and preserves custom formatting and comments. A lazy
// write invoked by a write() call will read the output file, find what
// changes have been made and update the file accordingly. If you only need to
// generate files, use generate() instead. Section and key order is preserved
// on read, write and insert.
//
///////////////////////////////////////////////////////////////////////////////
//
// /* BASIC USAGE EXAMPLE: */
//
// /* read from file */
// mINI::INIFile file("myfile.ini");
// mINI::INIStructure ini;
// file.read(ini);
//
// /* read value; gets a reference to actual value in the structure.
// if key or section don't exist, a new empty value will be created */
// std::string& value = ini["section"]["key"];
//
// /* read value safely; gets a copy of value in the structure.
// does not alter the structure */
// std::string value = ini.get("section").get("key");
//
// /* set or update values */
// ini["section"]["key"] = "value";
//
// /* set multiple values */
// ini["section2"].set({
// {"key1", "value1"},
// {"key2", "value2"}
// });
//
// /* write updates back to file, preserving comments and formatting */
// file.write(ini);
//
// /* or generate a file (overwrites the original) */
// file.generate(ini);
//
///////////////////////////////////////////////////////////////////////////////
//
// Long live the INI file!!!
//
///////////////////////////////////////////////////////////////////////////////
#ifndef MINI_INI_H_
#define MINI_INI_H_
#include <string>
#include <sstream>
#include <algorithm>
#include <utility>
#include <unordered_map>
#include <vector>
#include <memory>
#include <fstream>
#include <sys/stat.h>
#include <cctype>
namespace mINI
{
namespace INIStringUtil
{
const char* const whitespaceDelimiters = " \t\n\r\f\v";
inline void trim(std::string& str)
{
str.erase(str.find_last_not_of(whitespaceDelimiters) + 1);
str.erase(0, str.find_first_not_of(whitespaceDelimiters));
}
#ifndef MINI_CASE_SENSITIVE
inline void toLower(std::string& str)
{
std::transform(str.begin(), str.end(), str.begin(), [](const char c) {
return static_cast<const char>(std::tolower(c));
});
}
#endif
inline void replace(std::string& str, std::string const& a, std::string const& b)
{
if (!a.empty())
{
std::size_t pos = 0;
while ((pos = str.find(a, pos)) != std::string::npos)
{
str.replace(pos, a.size(), b);
pos += b.size();
}
}
}
#ifdef _WIN32
const char* const endl = "\r\n";
#else
const char* const endl = "\n";
#endif
};
template<typename T>
class INIMap
{
private:
using T_DataIndexMap = std::unordered_map<std::string, std::size_t>;
using T_DataItem = std::pair<std::string, T>;
using T_DataContainer = std::vector<T_DataItem>;
using T_MultiArgs = typename std::vector<std::pair<std::string, T>>;
T_DataIndexMap dataIndexMap;
T_DataContainer data;
inline std::size_t setEmpty(std::string& key)
{
std::size_t index = data.size();
dataIndexMap[key] = index;
data.emplace_back(key, T());
return index;
}
public:
using const_iterator = typename T_DataContainer::const_iterator;
INIMap() { }
INIMap(INIMap const& other)
{
std::size_t data_size = other.data.size();
for (std::size_t i = 0; i < data_size; ++i)
{
auto const& key = other.data[i].first;
auto const& obj = other.data[i].second;
data.emplace_back(key, obj);
}
dataIndexMap = T_DataIndexMap(other.dataIndexMap);
}
T& operator[](std::string key)
{
INIStringUtil::trim(key);
#ifndef MINI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
bool hasIt = (it != dataIndexMap.end());
std::size_t index = (hasIt) ? it->second : setEmpty(key);
return data[index].second;
}
T get(std::string key) const
{
INIStringUtil::trim(key);
#ifndef MINI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
if (it == dataIndexMap.end())
{
return T();
}
return T(data[it->second].second);
}
bool has(std::string key) const
{
INIStringUtil::trim(key);
#ifndef MINI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
return (dataIndexMap.count(key) == 1);
}
void set(std::string key, T obj)
{
INIStringUtil::trim(key);
#ifndef MINI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
if (it != dataIndexMap.end())
{
data[it->second].second = obj;
}
else
{
dataIndexMap[key] = data.size();
data.emplace_back(key, obj);
}
}
void set(T_MultiArgs const& multiArgs)
{
for (auto const& it : multiArgs)
{
auto const& key = it.first;
auto const& obj = it.second;
set(key, obj);
}
}
bool remove(std::string key)
{
INIStringUtil::trim(key);
#ifndef MINI_CASE_SENSITIVE
INIStringUtil::toLower(key);
#endif
auto it = dataIndexMap.find(key);
if (it != dataIndexMap.end())
{
std::size_t index = it->second;
data.erase(data.begin() + index);
dataIndexMap.erase(it);
for (auto& it2 : dataIndexMap)
{
auto& vi = it2.second;
if (vi > index)
{
vi--;
}
}
return true;
}
return false;
}
void clear()
{
data.clear();
dataIndexMap.clear();
}
std::size_t size() const
{
return data.size();
}
const_iterator begin() const { return data.begin(); }
const_iterator end() const { return data.end(); }
};
using INIStructure = INIMap<INIMap<std::string>>;
namespace INIParser
{
using T_ParseValues = std::pair<std::string, std::string>;
enum class PDataType : char
{
PDATA_NONE,
PDATA_COMMENT,
PDATA_SECTION,
PDATA_KEYVALUE,
PDATA_UNKNOWN
};
inline PDataType parseLine(std::string line, T_ParseValues& parseData)
{
parseData.first.clear();
parseData.second.clear();
INIStringUtil::trim(line);
if (line.empty())
{
return PDataType::PDATA_NONE;
}
char firstCharacter = line[0];
if (firstCharacter == ';')
{
return PDataType::PDATA_COMMENT;
}
if (firstCharacter == '[')
{
auto commentAt = line.find_first_of(';');
if (commentAt != std::string::npos)
{
line = line.substr(0, commentAt);
}
auto closingBracketAt = line.find_last_of(']');
if (closingBracketAt != std::string::npos)
{
auto section = line.substr(1, closingBracketAt - 1);
INIStringUtil::trim(section);
parseData.first = section;
return PDataType::PDATA_SECTION;
}
}
auto lineNorm = line;
INIStringUtil::replace(lineNorm, "\\=", " ");
auto equalsAt = lineNorm.find_first_of('=');
if (equalsAt != std::string::npos)
{
auto key = line.substr(0, equalsAt);
INIStringUtil::trim(key);
INIStringUtil::replace(key, "\\=", "=");
auto value = line.substr(equalsAt + 1);
INIStringUtil::trim(value);
parseData.first = key;
parseData.second = value;
return PDataType::PDATA_KEYVALUE;
}
return PDataType::PDATA_UNKNOWN;
}
};
class INIReader
{
public:
using T_LineData = std::vector<std::string>;
using T_LineDataPtr = std::shared_ptr<T_LineData>;
private:
std::ifstream fileReadStream;
T_LineDataPtr lineData;
T_LineData readFile()
{
std::string fileContents;
fileReadStream.seekg(0, std::ios::end);
fileContents.resize(fileReadStream.tellg());
fileReadStream.seekg(0, std::ios::beg);
std::size_t fileSize = fileContents.size();
fileReadStream.read(&fileContents[0], fileSize);
fileReadStream.close();
T_LineData output;
if (fileSize == 0)
{
return output;
}
std::string buffer;
buffer.reserve(50);
for (std::size_t i = 0; i < fileSize; ++i)
{
char& c = fileContents[i];
if (c == '\n')
{
output.emplace_back(buffer);
buffer.clear();
continue;
}
if (c != '\0' && c != '\r')
{
buffer += c;
}
}
output.emplace_back(buffer);
return output;
}
public:
INIReader(std::string const& filename, bool keepLineData = false)
{
fileReadStream.open(filename, std::ios::in | std::ios::binary);
if (keepLineData)
{
lineData = std::make_shared<T_LineData>();
}
}
~INIReader() { }
bool operator>>(INIStructure& data)
{
if (!fileReadStream.is_open())
{
return false;
}
T_LineData fileLines = readFile();
std::string section;
bool inSection = false;
INIParser::T_ParseValues parseData;
for (auto const& line : fileLines)
{
auto parseResult = INIParser::parseLine(line, parseData);
if (parseResult == INIParser::PDataType::PDATA_SECTION)
{
inSection = true;
data[section = parseData.first];
}
else if (inSection && parseResult == INIParser::PDataType::PDATA_KEYVALUE)
{
auto const& key = parseData.first;
auto const& value = parseData.second;
data[section][key] = value;
}
if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN)
{
if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection)
{
continue;
}
lineData->emplace_back(line);
}
}
return true;
}
T_LineDataPtr getLines()
{
return lineData;
}
};
class INIGenerator
{
private:
std::ofstream fileWriteStream;
public:
bool prettyPrint = false;
INIGenerator(std::string const& filename)
{
fileWriteStream.open(filename, std::ios::out | std::ios::binary);
}
~INIGenerator() { }
bool operator<<(INIStructure const& data)
{
if (!fileWriteStream.is_open())
{
return false;
}
if (!data.size())
{
return true;
}
auto it = data.begin();
for (;;)
{
auto const& section = it->first;
auto const& collection = it->second;
fileWriteStream
<< "["
<< section
<< "]";
if (collection.size())
{
fileWriteStream << INIStringUtil::endl;
auto it2 = collection.begin();
for (;;)
{
auto key = it2->first;
INIStringUtil::replace(key, "=", "\\=");
auto value = it2->second;
INIStringUtil::trim(value);
fileWriteStream
<< key
<< ((prettyPrint) ? " = " : "=")
<< value;
if (++it2 == collection.end())
{
break;
}
fileWriteStream << INIStringUtil::endl;
}
}
if (++it == data.end())
{
break;
}
fileWriteStream << INIStringUtil::endl;
if (prettyPrint)
{
fileWriteStream << INIStringUtil::endl;
}
}
return true;
}
};
class INIWriter
{
private:
using T_LineData = std::vector<std::string>;
using T_LineDataPtr = std::shared_ptr<T_LineData>;
std::string filename;
T_LineData getLazyOutput(T_LineDataPtr const& lineData, INIStructure& data, INIStructure& original)
{
T_LineData output;
INIParser::T_ParseValues parseData;
std::string sectionCurrent;
bool parsingSection = false;
bool continueToNextSection = false;
bool discardNextEmpty = false;
bool writeNewKeys = false;
std::size_t lastKeyLine = 0;
for (auto line = lineData->begin(); line != lineData->end(); ++line)
{
if (!writeNewKeys)
{
auto parseResult = INIParser::parseLine(*line, parseData);
if (parseResult == INIParser::PDataType::PDATA_SECTION)
{
if (parsingSection)
{
writeNewKeys = true;
parsingSection = false;
--line;
continue;
}
sectionCurrent = parseData.first;
if (data.has(sectionCurrent))
{
parsingSection = true;
continueToNextSection = false;
discardNextEmpty = false;
output.emplace_back(*line);
lastKeyLine = output.size();
}
else
{
continueToNextSection = true;
discardNextEmpty = true;
continue;
}
}
else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE)
{
if (continueToNextSection)
{
continue;
}
if (data.has(sectionCurrent))
{
auto& collection = data[sectionCurrent];
auto const& key = parseData.first;
auto const& value = parseData.second;
if (collection.has(key))
{
auto outputValue = collection[key];
if (value == outputValue)
{
output.emplace_back(*line);
}
else
{
INIStringUtil::trim(outputValue);
auto lineNorm = *line;
INIStringUtil::replace(lineNorm, "\\=", " ");
auto equalsAt = lineNorm.find_first_of('=');
auto valueAt = lineNorm.find_first_not_of(
INIStringUtil::whitespaceDelimiters,
equalsAt + 1
);
std::string outputLine = line->substr(0, valueAt);
if (prettyPrint && equalsAt + 1 == valueAt)
{
outputLine += " ";
}
outputLine += outputValue;
output.emplace_back(outputLine);
}
lastKeyLine = output.size();
}
}
}
else
{
if (discardNextEmpty && line->empty())
{
discardNextEmpty = false;
}
else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN)
{
output.emplace_back(*line);
}
}
}
if (writeNewKeys || std::next(line) == lineData->end())
{
T_LineData linesToAdd;
if (data.has(sectionCurrent) && original.has(sectionCurrent))
{
auto const& collection = data[sectionCurrent];
auto const& collectionOriginal = original[sectionCurrent];
for (auto const& it : collection)
{
auto key = it.first;
if (collectionOriginal.has(key))
{
continue;
}
auto value = it.second;
INIStringUtil::replace(key, "=", "\\=");
INIStringUtil::trim(value);
linesToAdd.emplace_back(
key + ((prettyPrint) ? " = " : "=") + value
);
}
}
if (!linesToAdd.empty())
{
output.insert(
output.begin() + lastKeyLine,
linesToAdd.begin(),
linesToAdd.end()
);
}
if (writeNewKeys)
{
writeNewKeys = false;
--line;
}
}
}
for (auto const& it : data)
{
auto const& section = it.first;
if (original.has(section))
{
continue;
}
if (prettyPrint && output.size() > 0 && !output.back().empty())
{
output.emplace_back();
}
output.emplace_back("[" + section + "]");
auto const& collection = it.second;
for (auto const& it2 : collection)
{
auto key = it2.first;
auto value = it2.second;
INIStringUtil::replace(key, "=", "\\=");
INIStringUtil::trim(value);
output.emplace_back(
key + ((prettyPrint) ? " = " : "=") + value
);
}
}
return output;
}
public:
bool prettyPrint = false;
INIWriter(std::string const& filename)
: filename(filename)
{
}
~INIWriter() { }
bool operator<<(INIStructure& data)
{
struct stat buf;
bool fileExists = (stat(filename.c_str(), &buf) == 0);
if (!fileExists)
{
INIGenerator generator(filename);
generator.prettyPrint = prettyPrint;
return generator << data;
}
INIStructure originalData;
T_LineDataPtr lineData;
bool readSuccess = false;
{
INIReader reader(filename, true);
if ((readSuccess = reader >> originalData))
{
lineData = reader.getLines();
}
}
if (!readSuccess)
{
return false;
}
T_LineData output = getLazyOutput(lineData, data, originalData);
std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary);
if (fileWriteStream.is_open())
{
if (output.size())
{
auto line = output.begin();
for (;;)
{
fileWriteStream << *line;
if (++line == output.end())
{
break;
}
fileWriteStream << INIStringUtil::endl;
}
}
return true;
}
return false;
}
};
class INIFile
{
private:
std::string filename;
public:
INIFile(std::string const& filename)
: filename(filename)
{ }
~INIFile() { }
bool read(INIStructure& data) const
{
if (data.size())
{
data.clear();
}
if (filename.empty())
{
return false;
}
INIReader reader(filename);
return reader >> data;
}
bool generate(INIStructure const& data, bool pretty = false) const
{
if (filename.empty())
{
return false;
}
INIGenerator generator(filename);
generator.prettyPrint = pretty;
return generator << data;
}
bool write(INIStructure& data, bool pretty = false) const
{
if (filename.empty())
{
return false;
}
INIWriter writer(filename);
writer.prettyPrint = pretty;
return writer << data;
}
};
}
#endif // MINI_INI_H_

View File

@ -1,333 +0,0 @@
/*
* Copyright (c) 2013-2015 Denilson das Mercês Amorim <dma_2012@hotmail.com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*/
#ifndef LINB_INI_PARSER_HPP
#define LINB_INI_PARSER_HPP
/*
* STL-like INI Container
*/
#include <string> // for std::string
#include <map> // for std::map
#include <cstdio> // for std::FILE
#include <algorithm> // for std::find_if
#include <functional> // for std::function
namespace linb
{
template<
class CharT = char, /* Not compatible with other type here, since we're using C streams */
class StringType = std::basic_string<CharT>,
class KeyContainer = std::map<StringType, StringType>,
class SectionContainer = std::map<StringType, KeyContainer>
> class basic_ini
{
public:
typedef CharT char_type;
typedef StringType string_type;
typedef KeyContainer key_container;
typedef SectionContainer section_container;
// Typedef container values types
typedef typename section_container::value_type value_type;
typedef typename section_container::key_type key_type;
typedef typename section_container::mapped_type mapped_type;
// Typedef common types
typedef typename section_container::size_type size_type;
typedef typename section_container::difference_type difference_type;
// Typedef iterators
typedef typename section_container::iterator iterator;
typedef typename section_container::const_iterator const_iterator;
typedef typename section_container::reverse_iterator reverse_iterator;
typedef typename section_container::const_reverse_iterator const_reverse_iterator;
// typedef References and pointers
typedef typename section_container::reference reference;
typedef typename section_container::const_reference const_reference;
typedef typename section_container::pointer pointer;
typedef typename section_container::const_pointer const_pointer;
private:
section_container data;
public:
basic_ini()
{ }
basic_ini(const char_type* filename)
{ this->read_file(filename); }
/* Iterator methods */
iterator begin()
{ return data.begin(); }
const_iterator begin() const
{ return data.begin(); }
iterator end()
{ return data.end(); }
const_iterator end() const
{ return data.end(); }
const_iterator cbegin() const
{ return data.cbegin(); }
const_iterator cend() const
{ return data.cend(); }
/* Reverse iterator methods */
reverse_iterator rbegin()
{ return data.rbegin(); }
const_reverse_iterator rbegin() const
{ return data.rbegin(); }
reverse_iterator rend()
{ return data.rend(); }
const_reverse_iterator rend() const
{ return data.rend(); }
const_reverse_iterator crbegin() const
{ return data.crbegin(); }
const_reverse_iterator crend() const
{ return data.crend(); }
/* Acessing index methods */
mapped_type& operator[](const string_type& sect)
{ return data[sect]; }
mapped_type& operator[](string_type&& sect)
{ return data[std::forward<string_type>(sect)]; }
mapped_type& at( const string_type& sect)
{ return data.at(sect); }
const mapped_type& at(const string_type& sect) const
{ return data.at(sect); }
/* Capacity information */
bool empty() const
{ return data.empty(); }
size_type size() const
{ return data.size(); }
size_type max_size() const
{ return data.max_size(); }
/* Modifiers */
void clear()
{ return data.clear(); }
/* Lookup */
size_type count(const string_type& sect)
{ return data.count(sect); }
iterator find(const string_type& sect)
{ return data.find(sect); }
/* Gets a value from the specified section & key, default_value is returned if the sect & key doesn't exist */
string_type get(const string_type& sect, const key_type& key, const string_type& default_value)
{
auto it = this->find(sect);
if(it != this->end())
{
auto itv = it->second.find(key);
if(itv != it->second.end())
return itv->second;
}
return default_value;
}
/* Sets the value of a value in the ini */
void set(const string_type& sect, const key_type& key, const string_type& value)
{
(*this)[sect][key] = value; // no emplace since overwrite!
}
/* Too lazy to continue this container... If you need more methods, just add it */
// re3
void remove(const string_type& sect, const key_type& key)
{
auto it = this->find(sect);
if(it != this->end())
{
it->second.erase(key);
}
}
int category_size(const string_type& sect)
{
auto it = this->find(sect);
if(it != this->end())
{
return it->second.size();
}
return 0;
}
#if 1
bool read_file(const char_type* filename)
{
/* Using C stream in a STL-like container, funny?
*/
if(FILE* f = fopen(filename, "r"))
{
key_container* keys = nullptr;
char_type buf[2048];
string_type line;
string_type key;
string_type value;
string_type null_string;
size_type pos;
// Trims an string
auto trim = [](string_type& s, bool trimLeft, bool trimRight) -> string_type&
{
if(s.size())
{
// Ignore UTF-8 BOM
while(s.size() >= 3 && s[0] == (char)(0xEF) && s[1] == (char)(0xBB) && s[2] == (char)(0xBF))
s.erase(s.begin(), s.begin() + 3);
if(trimLeft)
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::function<int(int)>(::isspace))));
if(trimRight)
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::function<int(int)>(::isspace))).base(), s.end());
}
return s;
};
// Start parsing
while(fgets(buf, sizeof(buf), f))
{
// What a thing, reading into a char buffer and then putting in the string...
line = buf;
// Find comment and remove anything after it from the line
if((pos = line.find_first_of(';')) != line.npos)
line.erase(pos);
// Trim the string, and if it gets empty, skip this line
if(trim(line, true, true).empty())
continue;
// Find section name
if(line.front() == '[' && line.back() == ']')
{
pos = line.length() - 1; //line.find_first_of(']');
if(pos != line.npos)
{
trim(key.assign(line, 1, pos-1), true, true);
keys = &data[std::move(key)]; // Create section
}
else
keys = nullptr;
}
else
{
// Find key and value positions
pos = line.find_first_of('=');
if(pos == line.npos)
{
// There's only the key
key = line; // No need for trim, line is already trimmed
value.clear();
}
else
{
// There's the key and the value
trim(key.assign(line, 0, pos), false, true); // trim the right
trim(value.assign(line, pos + 1, line.npos), true, false); // trim the left
}
// Put the key/value into the current keys object, or into the section "" if no section has been found
#if __cplusplus >= 201103L || _MSC_VER >= 1800
(keys ? *keys : data[null_string]).emplace(std::move(key), std::move(value));
#else
(keys ? *keys : data[null_string])[key] = value;
key.clear(); value.clear();
#endif
}
}
fclose(f);
return true;
}
return false;
}
/*
* Dumps the content of this container into an ini file
*/
bool write_file(const char_type* filename)
{
if(FILE* f = fopen(filename, "w"))
{
bool first = true;
for(auto& sec : this->data)
{
fprintf(f, first? "[%s]\n" : "\n[%s]\n", sec.first.c_str());
first = false;
for(auto& kv : sec.second)
{
if(kv.second.empty())
fprintf(f, "%s\n", kv.first.c_str());
else
fprintf(f, "%s = %s\n", kv.first.c_str(), kv.second.c_str());
}
}
fclose(f);
return true;
}
return false;
}
/*
*/
bool load_file(const char_type* filename)
{
return read_file(filename);
}
bool load_file(const StringType& filename)
{
return load_file(filename.c_str());
}
bool write_file(const StringType& filename)
{
return write_file(filename.c_str());
}
#endif
};
/* Use default basic_ini
*
* Limitations:
* * Not unicode aware
* * Case sensitive
* * Sections must have unique keys
*/
typedef basic_ini<> ini;
}
#endif

View File

@ -10,6 +10,12 @@
#include "DMAudio.h"
#include "screendroplets.h"
#ifdef COMPATIBLE_SAVES
#define PARTICLE_OBJECT_SIZEOF 0x84
#else
#define PARTICLE_OBJECT_SIZEOF sizeof(CParticleObject)
#endif
CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
@ -1057,6 +1063,48 @@ CParticleObject::UpdateFar(void)
}
}
#ifdef COMPATIBLE_SAVES
static inline void
SaveOneParticle(CParticleObject *p, uint8 *&buffer)
{
#define SkipBuf(buf, num) buf += num
#define ZeroBuf(buf, num) memset(buf, 0, num); SkipBuf(buf, num)
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipBuf(buf, sizeof(data))
// CPlaceable
{
CopyToBuf(buffer, p->GetMatrix().f);
ZeroBuf(buffer, 4);
CopyToBuf(buffer, p->GetMatrix().m_hasRwMatrix);
ZeroBuf(buffer, 3);
}
// CParticleObject
{
ZeroBuf(buffer, 4);
ZeroBuf(buffer, 4);
ZeroBuf(buffer, 4);
CopyToBuf(buffer, p->m_nRemoveTimer);
CopyToBuf(buffer, p->m_Type);
CopyToBuf(buffer, p->m_ParticleType);
CopyToBuf(buffer, p->m_nNumEffectCycles);
CopyToBuf(buffer, p->m_nSkipFrames);
CopyToBuf(buffer, p->m_nFrameCounter);
CopyToBuf(buffer, p->m_nState);
ZeroBuf(buffer, 2);
CopyToBuf(buffer, p->m_vecTarget);
CopyToBuf(buffer, p->m_fRandVal);
CopyToBuf(buffer, p->m_fSize);
CopyToBuf(buffer, p->m_Color);
CopyToBuf(buffer, p->m_bRemove);
CopyToBuf(buffer, p->m_nCreationChance);
ZeroBuf(buffer, 2);
}
#undef SkipBuf
#undef ZeroBuf
#undef CopyToBuf
}
#endif
bool
CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
{
@ -1074,27 +1122,35 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
*(int32 *)buffer = numObjects;
buffer += sizeof(int32);
int32 objectsLength = sizeof(CParticleObject) * (numObjects + 1);
int32 objectsLength = PARTICLE_OBJECT_SIZEOF * (numObjects + 1);
int32 dataLength = objectsLength + sizeof(int32);
for ( CParticleObject *p = pCloseListHead; p != nil; p = p->m_pNext )
{
#if 0 // todo better
#ifdef COMPATIBLE_SAVES
SaveOneParticle(p, buffer);
#else
#ifdef THIS_IS_STUPID
*(CParticleObject*)buffer = *p;
#else
memcpy(buffer, p, sizeof(CParticleObject));
#endif
buffer += sizeof(CParticleObject);
#endif
}
for ( CParticleObject *p = pFarListHead; p != nil; p = p->m_pNext )
{
#if 0 // todo better
#ifdef COMPATIBLE_SAVES
SaveOneParticle(p, buffer);
#else
#ifdef THIS_IS_STUPID
*(CParticleObject*)buffer = *p;
#else
memcpy(buffer, p, sizeof(CParticleObject));
#endif
buffer += sizeof(CParticleObject);
#endif
}
*length = dataLength;
@ -1112,7 +1168,7 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
int32 numObjects = *(int32 *)buffer;
buffer += sizeof(int32);
if ( length != sizeof(CParticleObject) * (numObjects + 1) + sizeof(int32) )
if ( length != PARTICLE_OBJECT_SIZEOF * (numObjects + 1) + sizeof(int32) )
return false;
if ( numObjects == 0 )
@ -1123,14 +1179,17 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
while ( i < numObjects )
{
CParticleObject *dst = pUnusedListHead;
#ifndef COMPATIBLE_SAVES
CParticleObject *src = (CParticleObject *)buffer;
buffer += sizeof(CParticleObject);
#endif
if ( dst == nil )
return false;
MoveToList(&pUnusedListHead, &pCloseListHead, dst);
#ifndef COMPATIBLE_SAVES
dst->m_nState = POBJECTSTATE_UPDATE_CLOSE;
dst->m_Type = src->m_Type;
dst->m_ParticleType = src->m_ParticleType;
@ -1146,6 +1205,46 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
dst->m_nNumEffectCycles = src->m_nNumEffectCycles;
dst->m_nSkipFrames = src->m_nSkipFrames;
dst->m_nCreationChance = src->m_nCreationChance;
#else
dst->m_nState = POBJECTSTATE_UPDATE_CLOSE;
dst->m_pParticle = NULL;
#define SkipBuf(buf, num) buf += num
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipBuf(buf, sizeof(data))
// CPlaceable
{
CMatrix matrix;
CopyFromBuf(buffer, matrix.f);
SkipBuf(buffer, 4);
CopyFromBuf(buffer, matrix.m_hasRwMatrix);
SkipBuf(buffer, 3);
dst->SetPosition(matrix.GetPosition());
}
// CParticleObject
{
SkipBuf(buffer, 4);
SkipBuf(buffer, 4);
SkipBuf(buffer, 4);
CopyFromBuf(buffer, dst->m_nRemoveTimer);
CopyFromBuf(buffer, dst->m_Type);
CopyFromBuf(buffer, dst->m_ParticleType);
CopyFromBuf(buffer, dst->m_nNumEffectCycles);
CopyFromBuf(buffer, dst->m_nSkipFrames);
CopyFromBuf(buffer, dst->m_nFrameCounter);
SkipBuf(buffer, 2);
SkipBuf(buffer, 2);
CopyFromBuf(buffer, dst->m_vecTarget);
CopyFromBuf(buffer, dst->m_fRandVal);
CopyFromBuf(buffer, dst->m_fSize);
CopyFromBuf(buffer, dst->m_Color);
CopyFromBuf(buffer, dst->m_bRemove);
CopyFromBuf(buffer, dst->m_nCreationChance);
SkipBuf(buffer, 2);
}
#undef CopyFromBuf
#undef SkipBuf
#endif
i++;
}

View File

@ -421,6 +421,7 @@ CPed::~CPed(void)
nearPed->m_nearPeds[k] = nearPed->m_nearPeds[k + 1];
nearPed->m_nearPeds[k + 1] = nil;
}
nearPed->m_nearPeds[ARRAY_SIZE(m_nearPeds) - 1] = nil;
nearPed->m_numNearPeds--;
} else
j++;
@ -9585,19 +9586,19 @@ CPed::Say(uint16 audio, int32 time)
void
CPed::Save(uint8*& buf)
{
SkipSaveBuf(buf, 52);
ZeroSaveBuf(buf, 52);
CopyToBuf(buf, GetPosition().x);
CopyToBuf(buf, GetPosition().y);
CopyToBuf(buf, GetPosition().z);
SkipSaveBuf(buf, 288);
ZeroSaveBuf(buf, 288);
CopyToBuf(buf, CharCreatedBy);
SkipSaveBuf(buf, 499);
ZeroSaveBuf(buf, 499);
CopyToBuf(buf, m_fHealth);
CopyToBuf(buf, m_fArmour);
SkipSaveBuf(buf, 172);
ZeroSaveBuf(buf, 172);
for (int i = 0; i < 10; i++) // has to be hardcoded
m_weapons[i].Save(buf);
SkipSaveBuf(buf, 252);
ZeroSaveBuf(buf, 252);
}
void

View File

@ -2188,14 +2188,14 @@ void
CPlayerPed::Save(uint8*& buf)
{
CPed::Save(buf);
SkipSaveBuf(buf, 16);
ZeroSaveBuf(buf, 16);
CopyToBuf(buf, m_fMaxStamina);
SkipSaveBuf(buf, 28);
ZeroSaveBuf(buf, 28);
CopyToBuf(buf, m_nTargettableObjects[0]);
CopyToBuf(buf, m_nTargettableObjects[1]);
CopyToBuf(buf, m_nTargettableObjects[2]);
CopyToBuf(buf, m_nTargettableObjects[3]);
SkipSaveBuf(buf, 164);
ZeroSaveBuf(buf, 164);
}
void

View File

@ -25,6 +25,12 @@
#include "Coronas.h"
#include "SaveBuf.h"
#ifdef COMPATIBLE_SAVES
#define SCRIPTPATHS_SAVE_SIZE 0x9C
#else
#define SCRIPTPATHS_SAVE_SIZE sizeof(aArray)
#endif
CPlaneTrail CPlaneTrails::aArray[6];
RwImVertexIndex TrailIndices[32] = {
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
@ -1268,14 +1274,34 @@ INITSAVEBUF
aArray[i].Clear();
for (int32 i = 0; i < 3; i++) {
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aArray[i].m_numNodes, buf);
SkipSaveBuf(buf, 4);
ReadSaveBuf(&aArray[i].m_fTotalLength, buf);
ReadSaveBuf(&aArray[i].m_fSpeed, buf);
ReadSaveBuf(&aArray[i].m_fPosition, buf);
ReadSaveBuf(&aArray[i].m_fObjectLength, buf);
ReadSaveBuf(&aArray[i].m_state, buf);
#else
ReadSaveBuf(&aArray[i], buf);
#endif
for (int32 j = 0; j < 6; j++) {
#ifdef COMPATIBLE_SAVES
aArray[i].m_pObjects[j] = nil;
int32 tmp;
ReadSaveBuf(&tmp, buf);
if (tmp != 0) {
aArray[i].m_pObjects[j] = CPools::GetObjectPool()->GetSlot(tmp - 1);
aArray[i].m_pObjects[j]->m_phy_flagA08 = false;
}
#else
CScriptPath *pPath = &aArray[i];
if (pPath->m_pObjects[j] != nil) {
pPath->m_pObjects[j] = CPools::GetObjectPool()->GetSlot((uintptr)pPath->m_pObjects[j] - 1);
pPath->m_pObjects[j]->m_phy_flagA08 = false;
}
#endif
}
aArray[i].m_pNode = new CPlaneNode[aArray[i].m_numNodes];
@ -1287,14 +1313,28 @@ VALIDATESAVEBUF(size)
}
void CScriptPaths::Save(uint8 *buf, uint32 *size) {
*size = sizeof(aArray);
*size = SCRIPTPATHS_SAVE_SIZE;
INITSAVEBUF
for (int32 i = 0; i < 3; i++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aArray[i].m_numNodes);
ZeroSaveBuf(buf, 4);
WriteSaveBuf(buf, aArray[i].m_fTotalLength);
WriteSaveBuf(buf, aArray[i].m_fSpeed);
WriteSaveBuf(buf, aArray[i].m_fPosition);
WriteSaveBuf(buf, aArray[i].m_fObjectLength);
WriteSaveBuf(buf, aArray[i].m_state);
#else
CScriptPath *pPath = WriteSaveBuf(buf, aArray[i]);
#endif
for (int32 j = 0; j < 6; j++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aArray[i].m_pObjects[j] != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aArray[i].m_pObjects[j]) + 1 : 0);
#else
if (pPath->m_pObjects[j] != nil)
pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pPath->m_pObjects[j]) + 1);
#endif
}
for (int32 j = 0; j < aArray[i].m_numNodes; j++) {

Some files were not shown because too many files have changed in this diff Show More