summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/animation/AnimBlendAssociation.h2
-rw-r--r--src/animation/AnimBlendClumpData.cpp1
-rw-r--r--src/audio/AudioCollision.cpp409
-rw-r--r--src/audio/AudioCollision.h23
-rw-r--r--src/audio/AudioLogic.cpp663
-rw-r--r--src/audio/AudioManager.cpp66
-rw-r--r--src/audio/AudioManager.h507
-rw-r--r--src/audio/MusicManager.cpp20
-rw-r--r--src/audio/PolRadio.cpp6
-rw-r--r--src/audio/oal/stream.cpp3
-rw-r--r--src/audio/sampman.h110
-rw-r--r--src/audio/sampman_miles.cpp146
-rw-r--r--src/audio/sampman_oal.cpp53
-rw-r--r--src/control/AutoPilot.cpp58
-rw-r--r--src/control/CarCtrl.cpp2
-rw-r--r--src/control/Garages.cpp118
-rw-r--r--src/control/Garages.h22
-rw-r--r--src/control/Phones.cpp45
-rw-r--r--src/control/Pickups.cpp33
-rw-r--r--src/control/Script.cpp28
-rw-r--r--src/control/Script.h1
-rw-r--r--src/control/Script5.cpp36
-rw-r--r--src/control/Script6.cpp4
-rw-r--r--src/core/Fire.cpp2
-rw-r--r--src/core/Frontend.cpp98
-rw-r--r--src/core/Frontend.h29
-rw-r--r--src/core/Game.cpp6
-rw-r--r--src/core/IniFile.cpp4
-rw-r--r--src/core/IniFile.h3
-rw-r--r--src/core/MenuScreensCustom.cpp27
-rw-r--r--src/core/Pools.cpp10
-rw-r--r--src/core/Zones.cpp78
-rw-r--r--src/core/config.h191
-rw-r--r--src/core/re3.cpp135
-rw-r--r--src/entities/Entity.cpp4
-rw-r--r--src/extras/frontendoption.h2
-rw-r--r--src/extras/ini.h761
-rw-r--r--src/extras/ini_parser.hpp333
-rw-r--r--src/objects/ParticleObject.cpp109
-rw-r--r--src/peds/Ped.cpp28
-rw-r--r--src/peds/PedFight.cpp8
-rw-r--r--src/peds/PedIK.h2
-rw-r--r--src/peds/PlayerPed.cpp17
-rw-r--r--src/peds/Population.cpp8
-rw-r--r--src/renderer/2dEffect.h (renamed from src/render/2dEffect.h)0
-rw-r--r--src/renderer/Antennas.cpp (renamed from src/render/Antennas.cpp)0
-rw-r--r--src/renderer/Antennas.h (renamed from src/render/Antennas.h)0
-rw-r--r--src/renderer/Clouds.cpp (renamed from src/render/Clouds.cpp)0
-rw-r--r--src/renderer/Clouds.h (renamed from src/render/Clouds.h)0
-rw-r--r--src/renderer/Console.cpp (renamed from src/render/Console.cpp)0
-rw-r--r--src/renderer/Console.h (renamed from src/render/Console.h)0
-rw-r--r--src/renderer/Coronas.cpp (renamed from src/render/Coronas.cpp)0
-rw-r--r--src/renderer/Coronas.h (renamed from src/render/Coronas.h)0
-rw-r--r--src/renderer/Credits.cpp (renamed from src/render/Credits.cpp)0
-rw-r--r--src/renderer/Credits.h (renamed from src/render/Credits.h)0
-rw-r--r--src/renderer/Draw.cpp (renamed from src/render/Draw.cpp)0
-rw-r--r--src/renderer/Draw.h (renamed from src/render/Draw.h)0
-rw-r--r--src/renderer/Fluff.cpp (renamed from src/render/Fluff.cpp)0
-rw-r--r--src/renderer/Fluff.h (renamed from src/render/Fluff.h)0
-rw-r--r--src/renderer/Font.cpp (renamed from src/render/Font.cpp)0
-rw-r--r--src/renderer/Font.h (renamed from src/render/Font.h)0
-rw-r--r--src/renderer/Glass.cpp (renamed from src/render/Glass.cpp)0
-rw-r--r--src/renderer/Glass.h (renamed from src/render/Glass.h)0
-rw-r--r--src/renderer/Hud.cpp (renamed from src/render/Hud.cpp)0
-rw-r--r--src/renderer/Hud.h (renamed from src/render/Hud.h)0
-rw-r--r--src/renderer/Instance.cpp (renamed from src/render/Instance.cpp)0
-rw-r--r--src/renderer/Instance.h (renamed from src/render/Instance.h)0
-rw-r--r--src/renderer/Lines.cpp (renamed from src/render/Lines.cpp)0
-rw-r--r--src/renderer/Lines.h (renamed from src/render/Lines.h)0
-rw-r--r--src/renderer/MBlur.cpp (renamed from src/render/MBlur.cpp)0
-rw-r--r--src/renderer/MBlur.h (renamed from src/render/MBlur.h)0
-rw-r--r--src/renderer/Particle.cpp (renamed from src/render/Particle.cpp)0
-rw-r--r--src/renderer/Particle.h (renamed from src/render/Particle.h)0
-rw-r--r--src/renderer/ParticleMgr.cpp (renamed from src/render/ParticleMgr.cpp)0
-rw-r--r--src/renderer/ParticleMgr.h (renamed from src/render/ParticleMgr.h)0
-rw-r--r--src/renderer/ParticleType.h (renamed from src/render/ParticleType.h)0
-rw-r--r--src/renderer/PlayerSkin.cpp (renamed from src/render/PlayerSkin.cpp)0
-rw-r--r--src/renderer/PlayerSkin.h (renamed from src/render/PlayerSkin.h)0
-rw-r--r--src/renderer/PointLights.cpp (renamed from src/render/PointLights.cpp)0
-rw-r--r--src/renderer/PointLights.h (renamed from src/render/PointLights.h)0
-rw-r--r--src/renderer/RenderBuffer.cpp (renamed from src/render/RenderBuffer.cpp)0
-rw-r--r--src/renderer/RenderBuffer.h (renamed from src/render/RenderBuffer.h)0
-rw-r--r--src/renderer/Renderer.cpp (renamed from src/render/Renderer.cpp)0
-rw-r--r--src/renderer/Renderer.h (renamed from src/render/Renderer.h)0
-rw-r--r--src/renderer/Rubbish.cpp (renamed from src/render/Rubbish.cpp)0
-rw-r--r--src/renderer/Rubbish.h (renamed from src/render/Rubbish.h)0
-rw-r--r--src/renderer/Shadows.cpp (renamed from src/render/Shadows.cpp)0
-rw-r--r--src/renderer/Shadows.h (renamed from src/render/Shadows.h)0
-rw-r--r--src/renderer/Skidmarks.cpp (renamed from src/render/Skidmarks.cpp)0
-rw-r--r--src/renderer/Skidmarks.h (renamed from src/render/Skidmarks.h)0
-rw-r--r--src/renderer/SpecialFX.cpp (renamed from src/render/SpecialFX.cpp)0
-rw-r--r--src/renderer/SpecialFX.h (renamed from src/render/SpecialFX.h)0
-rw-r--r--src/renderer/Sprite.cpp (renamed from src/render/Sprite.cpp)0
-rw-r--r--src/renderer/Sprite.h (renamed from src/render/Sprite.h)0
-rw-r--r--src/renderer/Sprite2d.cpp (renamed from src/render/Sprite2d.cpp)0
-rw-r--r--src/renderer/Sprite2d.h (renamed from src/render/Sprite2d.h)0
-rw-r--r--src/renderer/TexList.cpp (renamed from src/render/TexList.cpp)0
-rw-r--r--src/renderer/TexList.h (renamed from src/render/TexList.h)0
-rw-r--r--src/renderer/Timecycle.cpp (renamed from src/render/Timecycle.cpp)0
-rw-r--r--src/renderer/Timecycle.h (renamed from src/render/Timecycle.h)0
-rw-r--r--src/renderer/WaterCannon.cpp (renamed from src/render/WaterCannon.cpp)0
-rw-r--r--src/renderer/WaterCannon.h (renamed from src/render/WaterCannon.h)0
-rw-r--r--src/renderer/WaterLevel.cpp (renamed from src/render/WaterLevel.cpp)0
-rw-r--r--src/renderer/WaterLevel.h (renamed from src/render/WaterLevel.h)0
-rw-r--r--src/renderer/Weather.cpp (renamed from src/render/Weather.cpp)0
-rw-r--r--src/renderer/Weather.h (renamed from src/render/Weather.h)0
-rw-r--r--src/save/GenericGameStorage.cpp546
-rw-r--r--src/save/GenericGameStorage.h5
-rw-r--r--src/save/PCSave.cpp7
-rw-r--r--src/save/PCSave.h2
-rw-r--r--src/save/SaveBuf.h9
-rw-r--r--src/skel/crossplatform.cpp23
-rw-r--r--src/skel/crossplatform.h3
-rw-r--r--src/vehicles/Automobile.cpp4
-rw-r--r--src/vehicles/Boat.cpp2
-rw-r--r--src/vehicles/Cranes.cpp86
-rw-r--r--src/vehicles/Vehicle.cpp99
-rw-r--r--src/weapons/Weapon.cpp12
119 files changed, 3371 insertions, 1640 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 35b7ec11..28090d7e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -39,7 +39,7 @@ target_compile_definitions(${EXECUTABLE}
PRIVATE
$<IF:$<CONFIG:DEBUG>,DEBUG,NDEBUG>
LIBRW
- ${PROJECT}_NO_AUTOLINK
+ CMAKE_NO_AUTOLINK
)
if(LIBRW_PLATFORM_D3D9)
diff --git a/src/animation/AnimBlendAssociation.h b/src/animation/AnimBlendAssociation.h
index 80927da2..45720b6f 100644
--- a/src/animation/AnimBlendAssociation.h
+++ b/src/animation/AnimBlendAssociation.h
@@ -35,7 +35,7 @@ public:
CAnimBlendLink link;
- int numNodes; // taken from CAnimBlendClumpData::numFrames
+ int32 numNodes; // taken from CAnimBlendClumpData::numFrames
// NB: Order of these depends on order of nodes in Clump this was built from
CAnimBlendNode *nodes;
CAnimBlendHierarchy *hierarchy;
diff --git a/src/animation/AnimBlendClumpData.cpp b/src/animation/AnimBlendClumpData.cpp
index 702ee811..b333a449 100644
--- a/src/animation/AnimBlendClumpData.cpp
+++ b/src/animation/AnimBlendClumpData.cpp
@@ -3,7 +3,6 @@
#include "AnimBlendClumpData.h"
#include "MemoryMgr.h"
-
CAnimBlendClumpData::CAnimBlendClumpData(void)
{
numFrames = 0;
diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp
index fd819641..cfd13fb6 100644
--- a/src/audio/AudioCollision.cpp
+++ b/src/audio/AudioCollision.cpp
@@ -10,20 +10,39 @@
const int CollisionSoundIntensity = 60;
-cAudioCollisionManager::cAudioCollisionManager()
+void
+cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
+ float velocity)
{
- m_sQueue.m_pEntity1 = nil;
- m_sQueue.m_pEntity2 = nil;
- m_sQueue.m_bSurface1 = SURFACE_DEFAULT;
- m_sQueue.m_bSurface2 = SURFACE_DEFAULT;
- m_sQueue.m_fIntensity2 = 0.0f;
- m_sQueue.m_fIntensity1 = 0.0f;
- m_sQueue.m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
+ float distSquared;
+ CVector v1;
+ CVector v2;
- for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
- m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
+ if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause ||
+ (velocity < 0.0016f && collisionPower < 0.01f))
+ return;
- m_bCollisionsInQueue = 0;
+ if(entity1->IsBuilding()) {
+ v1 = v2 = entity2->GetPosition();
+ } else if(entity2->IsBuilding()) {
+ v1 = v2 = entity1->GetPosition();
+ } else {
+ v1 = entity1->GetPosition();
+ v2 = entity2->GetPosition();
+ }
+ CVector pos = (v1 + v2) * 0.5f;
+ distSquared = GetDistanceSquared(pos);
+ if(distSquared < SQR(CollisionSoundIntensity)) {
+ m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
+ m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
+ m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
+ m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
+ m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
+ m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
+ m_sCollisionManager.m_sQueue.m_vecPosition = pos;
+ m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
+ m_sCollisionManager.AddCollisionToRequestedQueue();
+ }
}
void
@@ -55,133 +74,71 @@ cAudioCollisionManager::AddCollisionToRequestedQueue()
m_bIndicesTable[i] = collisionsIndex;
}
-float
-cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const
-{
- return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
-}
-
-float
-cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const
+void
+cAudioManager::ServiceCollisions()
{
- float result;
-
- switch(a) {
- case SURFACE_DEFAULT:
- case SURFACE_TARMAC:
- case SURFACE_PAVEMENT:
- case SURFACE_STEEP_CLIFF:
- case SURFACE_TRANSPARENT_STONE: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
- case SURFACE_GRASS:
- case SURFACE_CARDBOARDBOX: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_GRAVEL: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_MUD_DRY: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_CAR: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break;
- case SURFACE_GLASS: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
- case SURFACE_TRANSPARENT_CLOTH:
- case SURFACE_THICK_METAL_PLATE: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
- case SURFACE_GARAGE_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
- case SURFACE_CAR_PANEL: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
- case SURFACE_SCAFFOLD_POLE:
- case SURFACE_METAL_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
- case SURFACE_LAMP_POST: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
- case SURFACE_FIRE_HYDRANT: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
- case SURFACE_GIRDER: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
- case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
- case SURFACE_PED: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break;
- case SURFACE_SAND: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
- case SURFACE_WATER: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
- case SURFACE_WOOD_CRATES: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
- case SURFACE_WOOD_BENCH: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
- case SURFACE_WOOD_SOLID: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
- case SURFACE_RUBBER:
- case SURFACE_WHEELBASE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
- case SURFACE_PLASTIC: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break;
- case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break;
- case SURFACE_CONTAINER: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
- case SURFACE_NEWS_VENDOR: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break;
- default: result = 0.f; break;
- }
+ int i, j;
+ bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS];
+ bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS];
- return result;
-}
+ m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
-float
-cAudioManager::GetCollisionRatio(float a, float b, float c, float d) const
-{
- float e;
- e = a;
- if(a <= b) return 0.0f;
- if(c <= a) e = c;
- return (e - b) / d;
-}
+ for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
+ abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
-uint32
-cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision)
-{
- uint8 surface1 = audioCollision.m_bSurface1;
- uint8 surface2 = audioCollision.m_bSurface2;
- int32 vol;
- float ratio;
+ for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
+ for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
+ int index = m_sCollisionManager.m_bIndicesTable[i];
+ if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
+ && (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
+ && (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
+ && (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
+ ) {
+ abRepeatedCollision1[index] = TRUE;
+ abRepeatedCollision2[j] = TRUE;
+ m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
+ SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
+ break;
+ }
+ }
+ }
- if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
- surface2 == SURFACE_HEDGE) {
- ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
- m_sQueueSample.m_nSampleIndex = SFX_RAIN;
- m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
- vol = 50.f * ratio;
- } else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) {
- ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
- m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
- m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
- vol = 30.f * ratio;
- } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY ||
- surface2 == SURFACE_MUD_DRY || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) {
- ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
- m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
- m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
- vol = 50.f * ratio;
- } else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) {
- return 0;
- } else {
- ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
- m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
- m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
- vol = 40.f * ratio;
+ for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
+ if (!abRepeatedCollision2[i]) {
+ m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
+ m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
+ m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
+ m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
+ m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
+ m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
+ m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
+ m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
+ }
}
- if(audioCollision.m_nBaseVolume < 2) vol = audioCollision.m_nBaseVolume * vol / 2;
- return vol;
-}
-void
-cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
-{
- if(col.m_fIntensity2 > 0.0016f) {
- uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
- if(emittingVol) {
- m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
- m_sQueueSample.m_nVolume =
- ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
- if(m_sQueueSample.m_nVolume) {
- m_sQueueSample.m_nCounter = counter;
- m_sQueueSample.m_vecPos = col.m_vecPosition;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = FALSE;
- m_sQueueSample.m_nReleasingVolumeModificator = 7;
- m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 4.0f;
- m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
- m_sQueueSample.m_bReleasingSoundFlag = FALSE;
- m_sQueueSample.m_nReleasingVolumeDivider = 5;
- m_sQueueSample.m_bReverbFlag = TRUE;
- m_sQueueSample.m_bRequireReflection = FALSE;
- AddSampleToRequestedQueue();
+ for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
+ int index = m_sCollisionManager.m_bIndicesTable[i];
+ if (!abRepeatedCollision1[index]) {
+ for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
+ if (!abRepeatedCollision2[j]) {
+ m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
+ m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
+ m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
+ m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
+ m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
+ break;
+ }
}
+ SetUpOneShotCollisionSound(m_sCollisionManager.m_asCollisions1[index]);
+ SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
}
}
+
+ for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
+ m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
+ m_sCollisionManager.m_bCollisionsInQueue = 0;
}
+
static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
SFX_COL_TARMAC_1,
SFX_COL_GRASS_1,
@@ -219,9 +176,8 @@ static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
void
cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
{
-
- int16 s1;
- int16 s2;
+ uint16 s1;
+ uint16 s2;
int32 emittingVol;
float ratio;
@@ -321,101 +277,126 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
}
void
-cAudioManager::ServiceCollisions()
+cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
{
- int i, j;
- bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS];
- bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS];
-
- m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
-
- for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
- abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
-
- for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
- for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
- int index = m_sCollisionManager.m_bIndicesTable[i];
- if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
- && (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
- && (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
- && (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
- ) {
- abRepeatedCollision1[index] = TRUE;
- abRepeatedCollision2[j] = TRUE;
- m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
- SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
- break;
+ if(col.m_fIntensity2 > 0.0016f) {
+ uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
+ if(emittingVol) {
+ m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
+ m_sQueueSample.m_nVolume =
+ ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
+ if(m_sQueueSample.m_nVolume) {
+ m_sQueueSample.m_nCounter = counter;
+ m_sQueueSample.m_vecPos = col.m_vecPosition;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = FALSE;
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
+ m_sQueueSample.m_bReleasingSoundFlag = FALSE;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = TRUE;
+ m_sQueueSample.m_bRequireReflection = FALSE;
+ AddSampleToRequestedQueue();
}
}
}
+}
- for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
- if (!abRepeatedCollision2[i]) {
- m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
- m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
- m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
- m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
- m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
- m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
- m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
- m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
- }
+uint32
+cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision)
+{
+ uint8 surface1 = audioCollision.m_bSurface1;
+ uint8 surface2 = audioCollision.m_bSurface2;
+ int32 vol;
+ float ratio;
+
+ if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
+ surface2 == SURFACE_HEDGE) {
+ ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
+ m_sQueueSample.m_nSampleIndex = SFX_RAIN;
+ m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
+ vol = 50.f * ratio;
+ } else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) {
+ ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
+ m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
+ vol = 30.f * ratio;
+ } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY ||
+ surface2 == SURFACE_MUD_DRY || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) {
+ ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
+ m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
+ m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
+ vol = 50.f * ratio;
+ } else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) {
+ return 0;
+ } else {
+ ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
+ m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
+ m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
+ vol = 40.f * ratio;
}
+ if(audioCollision.m_nBaseVolume < 2) vol = audioCollision.m_nBaseVolume * vol / 2;
+ return vol;
+}
- for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
- int index = m_sCollisionManager.m_bIndicesTable[i];
- if (!abRepeatedCollision1[index]) {
- for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
- if (!abRepeatedCollision2[j]) {
- m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
- m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
- m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
- m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
- m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
- break;
- }
- }
- SetUpOneShotCollisionSound(m_sCollisionManager.m_asCollisions1[index]);
- SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
- }
+float
+cAudioManager::GetCollisionOneShotRatio(uint32 a, float b)
+{
+ switch(a) {
+ case SURFACE_DEFAULT:
+ case SURFACE_TARMAC:
+ case SURFACE_PAVEMENT:
+ case SURFACE_STEEP_CLIFF:
+ case SURFACE_TRANSPARENT_STONE: return GetCollisionRatio(b, 10.f, 60.f, 50.f);
+ case SURFACE_GRASS:
+ case SURFACE_CARDBOARDBOX: return GetCollisionRatio(b, 0.f, 2.f, 2.f);
+ case SURFACE_GRAVEL: return GetCollisionRatio(b, 0.f, 2.f, 2.f);
+ case SURFACE_MUD_DRY: return GetCollisionRatio(b, 0.f, 2.f, 2.f);
+ case SURFACE_CAR: return GetCollisionRatio(b, 6.f, 50.f, 44.f);
+ case SURFACE_GLASS: return GetCollisionRatio(b, 0.1f, 10.f, 9.9f);
+ case SURFACE_TRANSPARENT_CLOTH:
+ case SURFACE_THICK_METAL_PLATE: return GetCollisionRatio(b, 30.f, 130.f, 100.f);
+ case SURFACE_GARAGE_DOOR: return GetCollisionRatio(b, 20.f, 100.f, 80.f);
+ case SURFACE_CAR_PANEL: return GetCollisionRatio(b, 0.f, 4.f, 4.f);
+ case SURFACE_SCAFFOLD_POLE:
+ case SURFACE_METAL_GATE: return GetCollisionRatio(b, 1.f, 10.f, 9.f);
+ case SURFACE_LAMP_POST: return GetCollisionRatio(b, 1.f, 10.f, 9.f);
+ case SURFACE_FIRE_HYDRANT: return GetCollisionRatio(b, 1.f, 15.f, 14.f);
+ case SURFACE_GIRDER: return GetCollisionRatio(b, 8.f, 50.f, 42.f);
+ case SURFACE_METAL_CHAIN_FENCE: return GetCollisionRatio(b, 0.1f, 10.f, 9.9f);
+ case SURFACE_PED: return GetCollisionRatio(b, 0.f, 20.f, 20.f);
+ case SURFACE_SAND: return GetCollisionRatio(b, 0.f, 10.f, 10.f);
+ case SURFACE_WATER: return GetCollisionRatio(b, 0.f, 10.f, 10.f);
+ case SURFACE_WOOD_CRATES: return GetCollisionRatio(b, 1.f, 4.f, 3.f);
+ case SURFACE_WOOD_BENCH: return GetCollisionRatio(b, 0.1f, 5.f, 4.9f);
+ case SURFACE_WOOD_SOLID: return GetCollisionRatio(b, 0.1f, 40.f, 39.9f);
+ case SURFACE_RUBBER:
+ case SURFACE_WHEELBASE: return GetCollisionRatio(b, 0.f, 10.f, 10.f);
+ case SURFACE_PLASTIC: return GetCollisionRatio(b, 0.1f, 4.f, 3.9f);
+ case SURFACE_HEDGE: return GetCollisionRatio(b, 0.f, 0.5f, 0.5f);
+ case SURFACE_CONTAINER: return GetCollisionRatio(b, 4.f, 40.f, 36.f);
+ case SURFACE_NEWS_VENDOR: return GetCollisionRatio(b, 0.f, 5.f, 5.f);
}
- for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
- m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
- m_sCollisionManager.m_bCollisionsInQueue = 0;
+ return 0.f;
}
-void
-cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
- float velocity)
+float
+cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c)
{
- float distSquared;
- CVector v1;
- CVector v2;
-
- if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause ||
- (velocity < 0.0016f && collisionPower < 0.01f))
- return;
+ return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
+}
- if(entity1->IsBuilding()) {
- v1 = v2 = entity2->GetPosition();
- } else if(entity2->IsBuilding()) {
- v1 = v2 = entity1->GetPosition();
- } else {
- v1 = entity1->GetPosition();
- v2 = entity2->GetPosition();
- }
- CVector pos = (v1 + v2) * 0.5f;
- distSquared = GetDistanceSquared(pos);
- if(distSquared < SQR(CollisionSoundIntensity)) {
- m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
- m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
- m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
- m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
- m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
- m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
- m_sCollisionManager.m_sQueue.m_vecPosition = pos;
- m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
- m_sCollisionManager.AddCollisionToRequestedQueue();
- }
+float
+cAudioManager::GetCollisionRatio(float a, float b, float c, float d)
+{
+ float e;
+ e = a;
+ if(a <= b) return 0.0f;
+ if(c <= a) e = c;
+ return (e - b) / d;
}
diff --git a/src/audio/AudioCollision.h b/src/audio/AudioCollision.h
index 0a058916..a201d500 100644
--- a/src/audio/AudioCollision.h
+++ b/src/audio/AudioCollision.h
@@ -17,7 +17,18 @@ public:
float m_fDistance;
int32 m_nBaseVolume;
- // no methods
+ cAudioCollision() { Reset(); }
+
+ void Reset()
+ {
+ m_pEntity1 = nil;
+ m_pEntity2 = nil;
+ m_bSurface1 = 0;
+ m_bSurface2 = 0;
+ m_fIntensity1 = m_fIntensity2 = 0.0f;
+ m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
+ m_fDistance = 0.0f;
+ }
};
VALIDATE_SIZE(cAudioCollision, 40);
@@ -31,7 +42,15 @@ public:
uint8 m_bCollisionsInQueue;
cAudioCollision m_sQueue;
- cAudioCollisionManager();
+ cAudioCollisionManager()
+ {
+ m_sQueue.Reset();
+
+ for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
+ m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
+
+ m_bCollisionsInQueue = 0;
+ }
void AddCollisionToRequestedQueue();
};
diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp
index fdc7305b..44664f8a 100644
--- a/src/audio/AudioLogic.cpp
+++ b/src/audio/AudioLogic.cpp
@@ -52,11 +52,8 @@ uint32 gHomeNextTime;
uint32 gCellNextTime;
uint32 gNextCryTime;
-enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED };
-enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED };
-
void
-cAudioManager::PreInitialiseGameSpecificSetup() const
+cAudioManager::PreInitialiseGameSpecificSetup()
{
BankStartOffset[SFX_BANK_0] = SAMPLEBANK_START;
#ifdef GTA_PS2
@@ -163,6 +160,7 @@ cAudioManager::PostInitialiseGameSpecificSetup()
m_sMissionAudio.m_nMissionAudioCounter = 0;
ResetAudioLogicTimers(CTimer::GetTimeInMilliseconds());
}
+
void
cAudioManager::PreTerminateGameSpecificShutdown()
{
@@ -228,7 +226,7 @@ cAudioManager::ResetAudioLogicTimers(uint32 timer)
}
void
-cAudioManager::ProcessReverb() const
+cAudioManager::ProcessReverb()
{
if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) {
#ifndef GTA_PS2
@@ -248,7 +246,7 @@ cAudioManager::ProcessReverb() const
}
float
-cAudioManager::GetDistanceSquared(const CVector &v) const
+cAudioManager::GetDistanceSquared(const CVector &v)
{
const CVector &c = TheCamera.GetPosition();
return sq(v.x - c.x) + sq(v.y - c.y) + sq((v.z - c.z) * 0.2f);
@@ -801,8 +799,6 @@ cAudioManager::ProcessModelCarEngine(cVehicleParams& params)
}
}
-
-
bool8
cAudioManager::ProcessVehicleRoadNoise(cVehicleParams& params)
{
@@ -1063,20 +1059,20 @@ cAudioManager::UpdateGasPedalAudio(CAutomobile *automobile)
}
void
-cAudioManager::PlayerJustGotInCar() const
+cAudioManager::PlayerJustGotInCar()
{
if (m_bIsInitialised)
bPlayerJustEnteredCar = TRUE;
}
void
-cAudioManager::PlayerJustLeftCar(void) const
+cAudioManager::PlayerJustLeftCar(void)
{
// UNUSED: This is a perfectly empty function.
}
void
-cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping)
+cAudioManager::AddPlayerCarSample(uint8 emittingVolume, uint32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping)
{
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, 50.f, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
@@ -1581,7 +1577,7 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams& params)
}
bool8
-cAudioManager::UsesSiren(int32 model) const
+cAudioManager::UsesSiren(uint32 model)
{
switch (model) {
case FIRETRUK:
@@ -1597,7 +1593,7 @@ cAudioManager::UsesSiren(int32 model) const
}
bool8
-cAudioManager::UsesSirenSwitching(int32 model) const
+cAudioManager::UsesSirenSwitching(uint32 model)
{
switch (model) {
case AMBULAN:
@@ -1663,7 +1659,7 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams& params)
}
bool8
-cAudioManager::UsesReverseWarning(int32 model) const
+cAudioManager::UsesReverseWarning(uint32 model)
{
return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH;
}
@@ -1792,7 +1788,7 @@ cAudioManager::ProcessAirBrakes(cVehicleParams& params)
}
bool8
-cAudioManager::HasAirBrakes(int32 model) const
+cAudioManager::HasAirBrakes(uint32 model)
{
return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH;
}
@@ -2631,8 +2627,8 @@ uint8 gJumboVolOffsetPercentage;
void
DoJumboVolOffset()
{
- if (!(AudioManager.GetFrameCounter() % (AudioManager.GetRandomNumber(0) % 6 + 3)))
- gJumboVolOffsetPercentage = AudioManager.GetRandomNumber(1) % 60;
+ if (!(AudioManager.m_FrameCounter % (AudioManager.m_anRandomTable[0] % 6 + 3)))
+ gJumboVolOffsetPercentage = AudioManager.m_anRandomTable[1] % 60;
}
void
@@ -2910,7 +2906,7 @@ cAudioManager::SetupJumboRumbleSound(uint8 emittingVol)
}
int32
-cAudioManager::GetJumboTaxiFreq() const
+cAudioManager::GetJumboTaxiFreq()
{
return (60.833f * m_sQueueSample.m_fDistance) + 22050;
}
@@ -3565,23 +3561,23 @@ cAudioManager::SetupPedComments(cPedParams &params, uint16 sound)
switch (sound) {
case SOUND_PED_HELI_PLAYER_FOUND:
soundIntensity = 400.0f;
- pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_POLICE_HELI_1, SFX_POLICE_HELI_29);
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 29 + SFX_POLICE_HELI_1;
break;
case SOUND_PED_BODYCAST_HIT:
if (CTimer::GetTimeInMilliseconds() <= gNextCryTime)
return;
soundIntensity = 50.0f;
gNextCryTime = CTimer::GetTimeInMilliseconds() + 500;
- pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_PLASTER_BLOKE_1, SFX_PLASTER_BLOKE_4);
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 4 + SFX_PLASTER_BLOKE_1;
break;
case SOUND_INJURED_PED_MALE_OUCH:
case SOUND_INJURED_PED_MALE_PRISON:
soundIntensity = 50.0f;
- pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_MALE_GRUNT_1, SFX_GENERIC_MALE_GRUNT_15);
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 15 + SFX_GENERIC_MALE_GRUNT_1;
break;
case SOUND_INJURED_PED_FEMALE:
soundIntensity = 50.0f;
- pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_FEMALE_GRUNT_1, SFX_GENERIC_FEMALE_GRUNT_11);
+ pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex % 4] % 11 + SFX_GENERIC_FEMALE_GRUNT_1;
break;
default:
return;
@@ -3618,7 +3614,7 @@ cAudioManager::SetupPedComments(cPedParams &params, uint16 sound)
}
int32
-cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound)
+cAudioManager::GetPedCommentSfx(CPed *ped, uint16 sound)
{
if (ped->IsPlayer())
return GetPlayerTalkSfx(sound);
@@ -3639,7 +3635,7 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound)
case MI_MALE01:
return GetNormalMaleTalkSfx(sound);
case MI_TAXI_D:
- return GetTaxiDriverTalkSfx(sound);
+ return GetAsianTaxiDriverTalkSfx(sound);
case MI_PIMP:
return GetPimpTalkSfx(sound);
case MI_GANG01:
@@ -3673,7 +3669,7 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound)
case MI_SPECIAL04:
return GetSpecialCharacterTalkSfx(ped->GetModelIndex(), sound);
case MI_MALE02:
- return GetMaleNo2TalkSfx(sound);
+ return GetCasualMaleOldTalkSfx(sound);
case MI_MALE03:
case MI_P_MAN1:
case MI_P_MAN2:
@@ -3768,14 +3764,14 @@ cAudioManager::GetPedCommentSfx(CPed *ped, int32 sound)
case MI_STUD_WOM:
return GetStudentFemaleTalkSfx(sound);
case MI_CAS_MAN:
- return GetCasualMaleOldTalkSfx(sound);
+ return GetCasualMaleYoungTalkSfx(sound);
default:
return GetGenericMaleTalkSfx(sound);
}
}
void
-cAudioManager::GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const
+cAudioManager::GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset)
{
phrase = sample + m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % maxOffset;
@@ -3789,7 +3785,7 @@ cAudioManager::GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint
#pragma region PED_COMMENTS
uint32
-cAudioManager::GetPlayerTalkSfx(int16 sound)
+cAudioManager::GetPlayerTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -3812,7 +3808,7 @@ cAudioManager::GetPlayerTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetCopTalkSfx(int16 sound)
+cAudioManager::GetCopTalkSfx(uint16 sound)
{
uint32 sfx;
PedState pedState;
@@ -3836,7 +3832,7 @@ cAudioManager::GetCopTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetSwatTalkSfx(int16 sound)
+cAudioManager::GetSwatTalkSfx(uint16 sound)
{
uint32 sfx;
PedState pedState;
@@ -3860,7 +3856,7 @@ cAudioManager::GetSwatTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetFBITalkSfx(int16 sound)
+cAudioManager::GetFBITalkSfx(uint16 sound)
{
uint32 sfx;
PedState pedState;
@@ -3884,7 +3880,7 @@ cAudioManager::GetFBITalkSfx(int16 sound)
}
uint32
-cAudioManager::GetArmyTalkSfx(int16 sound)
+cAudioManager::GetArmyTalkSfx(uint16 sound)
{
uint32 sfx;
PedState pedState;
@@ -3903,7 +3899,7 @@ cAudioManager::GetArmyTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetMedicTalkSfx(int16 sound)
+cAudioManager::GetMedicTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -3931,41 +3927,41 @@ cAudioManager::GetMedicTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetFiremanTalkSfx(int16 sound)
+cAudioManager::GetFiremanTalkSfx(uint16 sound)
{
return GetGenericMaleTalkSfx(sound);
}
uint32
-cAudioManager::GetNormalMaleTalkSfx(int16 sound)
+cAudioManager::GetBusinessMaleOldTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
switch (sound) {
case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_GUN_PANIC_1, 7);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_GUN_PANIC_1, 3);
break;
case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_CARJACKED_1, 7);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CARJACKED_1, 2);
+ break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_1, 5);
break;
case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_DODGE_1, 9);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_1, 4);
break;
case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_RUN_FROM_FIGHT_1, 5);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_1, 5);
break;
case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_DRIVER_ABUSE_1, 12);
- break;
- case SOUND_PED_CHAT_SEXY:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_EYING_1, 8);
- break;
- case SOUND_PED_CHAT_EVENT:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_SHOCKED_1, 10);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 5);
break;
case SOUND_PED_CHAT:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_CHAT_1, 25);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_1, 5);
break;
default:
return GetGenericMaleTalkSfx(sound);
@@ -3974,61 +3970,47 @@ cAudioManager::GetNormalMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetTaxiDriverTalkSfx(int16 sound)
+cAudioManager::GetBusinessMaleYoungTalkSfx(uint16 sound, uint32 model)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_1, 7);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1, 6);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
- }
-
- return (SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_1 - SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
-}
-
-uint32
-cAudioManager::GetPimpTalkSfx(int16 sound)
-{
- uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_PIMP_GUN_COOL_1, 7);
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_GUN_PANIC_1, 3);
break;
case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_PIMP_CARJACKED_1, 4);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_DEFEND:
- GetPhrase(sfx, lastSfx, SFX_PIMP_FIGHT_1, 9);
+ case SOUND_PED_ROBBED:
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_FIGHT_1, 4);
break;
case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_PIMP_DODGE_1, 6);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_DODGE_1, 4);
break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_PIMP_DRIVER_ABUSE_1, 5);
+ case SOUND_PED_FLEE_RUN:
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_1, 5);
break;
- case SOUND_PED_CHAT_EVENT:
- GetPhrase(sfx, lastSfx, SFX_PIMP_SHOCKED_1, 2);
+ case SOUND_PED_ANNOYED_DRIVER:
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1, 6);
break;
case SOUND_PED_CHAT:
- GetPhrase(sfx, lastSfx, SFX_PIMP_CHAT_1, 17);
+ GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_1, 6);
break;
default:
return GetGenericMaleTalkSfx(sound);
}
+
+ if (model == MI_B_MAN3)
+ sfx += (SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_1 - SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1);
return sfx;
}
uint32
-cAudioManager::GetMafiaTalkSfx(int16 sound)
+cAudioManager::GetMafiaTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4062,7 +4044,7 @@ cAudioManager::GetMafiaTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetTriadTalkSfx(int16 sound)
+cAudioManager::GetTriadTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4099,7 +4081,7 @@ cAudioManager::GetTriadTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetDiabloTalkSfx(int16 sound)
+cAudioManager::GetDiabloTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4140,7 +4122,7 @@ cAudioManager::GetDiabloTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetYakuzaTalkSfx(int16 sound)
+cAudioManager::GetYakuzaTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4171,7 +4153,7 @@ cAudioManager::GetYakuzaTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetYardieTalkSfx(int16 sound)
+cAudioManager::GetYardieTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4208,7 +4190,7 @@ cAudioManager::GetYardieTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetColumbianTalkSfx(int16 sound)
+cAudioManager::GetColumbianTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4242,7 +4224,7 @@ cAudioManager::GetColumbianTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetHoodTalkSfx(int16 sound)
+cAudioManager::GetHoodTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4281,7 +4263,7 @@ cAudioManager::GetHoodTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackCriminalTalkSfx(int16 sound)
+cAudioManager::GetBlackCriminalTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4313,7 +4295,7 @@ cAudioManager::GetBlackCriminalTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetWhiteCriminalTalkSfx(int16 sound)
+cAudioManager::GetWhiteCriminalTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4345,7 +4327,7 @@ cAudioManager::GetWhiteCriminalTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetMaleNo2TalkSfx(int16 sound)
+cAudioManager::GetCasualMaleOldTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4379,79 +4361,13 @@ cAudioManager::GetMaleNo2TalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackProjectMaleTalkSfx(int16 sound, int32 model)
-{
- uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch(sound) {
- case SOUND_PED_HANDS_UP: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_1, 3); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CARJACKED_1, 2); break;
- case SOUND_PED_ROBBED: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_ATTACK: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_1, 6); break;
- case SOUND_PED_EVADE: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_1, 5); break;
- case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1, 7); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_1, 3); break;
- case SOUND_PED_CHAT: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_1, 6); break;
- default: return GetGenericMaleTalkSfx(sound);
- }
-
- if (model == MI_P_MAN2)
- sfx += (SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1);
- return sfx;
-}
-
-uint32
-cAudioManager::GetWhiteFatMaleTalkSfx(int16 sound)
-{
- uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch(sound) {
- case SOUND_PED_CAR_JACKED: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_1, 3); break;
- case SOUND_PED_ROBBED: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_1, 3); break;
- case SOUND_PED_EVADE: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DODGE_1, 9); break;
- case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 9); break;
- case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_LOST_1, 2); break;
- case SOUND_PED_CHAT: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CHAT_1, 9); break;
- default: return GetGenericMaleTalkSfx(sound);
- }
- return sfx;
-}
-
-uint32
-cAudioManager::GetBlackFatMaleTalkSfx(int16 sound)
+cAudioManager::GetCasualMaleYoungTalkSfx(uint16 sound)
{
- uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_1, 4);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_MUGGED_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DODGE_1, 7);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
- break;
- case SOUND_PED_WAIT_DOUBLEBACK:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_LOST_1, 3);
- break;
- case SOUND_PED_CHAT:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_CHAT_1, 8);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
- }
- return sfx;
+ return GetGenericMaleTalkSfx(sound);
}
uint32
-cAudioManager::GetBlackCasualFemaleTalkSfx(int16 sound)
+cAudioManager::GetBlackCasualFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4488,7 +4404,7 @@ cAudioManager::GetBlackCasualFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetWhiteCasualFemaleTalkSfx(int16 sound)
+cAudioManager::GetWhiteCasualFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4525,7 +4441,7 @@ cAudioManager::GetWhiteCasualFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetFemaleNo3TalkSfx(int16 sound)
+cAudioManager::GetFemaleNo3TalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4562,7 +4478,47 @@ cAudioManager::GetFemaleNo3TalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackFatFemaleTalkSfx(int16 sound)
+cAudioManager::GetWhiteBusinessFemaleTalkSfx(uint16 sound, uint32 model)
+{
+ uint32 sfx;
+ static uint32 lastSfx = NO_SAMPLE;
+
+ switch (sound) {
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_1, 4);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CARJACKED_1, 2);
+ break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_1, 6);
+ break;
+ case SOUND_PED_FLEE_RUN:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 4);
+ break;
+ case SOUND_PED_ANNOYED_DRIVER:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5);
+ break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_SHOCKED_1, 4);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_1, 7);
+ break;
+ default:
+ return GetGenericFemaleTalkSfx(sound);
+ }
+
+ if (model == MI_B_WOM2)
+ sfx += (SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetBlackFatFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4596,7 +4552,56 @@ cAudioManager::GetBlackFatFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetWhiteFatFemaleTalkSfx(int16 sound)
+cAudioManager::GetWhiteFatMaleTalkSfx(uint16 sound)
+{
+ uint32 sfx;
+ static uint32 lastSfx = NO_SAMPLE;
+
+ switch(sound) {
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_1, 3); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_1, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DODGE_1, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_LOST_1, 2); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CHAT_1, 9); break;
+ default: return GetGenericMaleTalkSfx(sound);
+ }
+ return sfx;
+}
+
+uint32
+cAudioManager::GetBlackFatMaleTalkSfx(uint16 sound)
+{
+ uint32 sfx;
+ static uint32 lastSfx = NO_SAMPLE;
+
+ switch (sound) {
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_1, 4);
+ break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_MUGGED_1, 3);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DODGE_1, 7);
+ break;
+ case SOUND_PED_ANNOYED_DRIVER:
+ GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
+ case SOUND_PED_WAIT_DOUBLEBACK:
+ GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_LOST_1, 3);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_CHAT_1, 8);
+ break;
+ default:
+ return GetGenericMaleTalkSfx(sound);
+ }
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWhiteFatFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4630,7 +4635,7 @@ cAudioManager::GetWhiteFatFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackFemaleProstituteTalkSfx(int16 sound)
+cAudioManager::GetBlackFemaleProstituteTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4664,7 +4669,7 @@ cAudioManager::GetBlackFemaleProstituteTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetWhiteFemaleProstituteTalkSfx(int16 sound)
+cAudioManager::GetWhiteFemaleProstituteTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4695,7 +4700,30 @@ cAudioManager::GetWhiteFemaleProstituteTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackProjectFemaleOldTalkSfx(int16 sound)
+cAudioManager::GetBlackProjectMaleTalkSfx(uint16 sound, uint32 model)
+{
+ uint32 sfx;
+ static uint32 lastSfx = NO_SAMPLE;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_GUN_COOL_1, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_MUGGED_1, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_FIGHT_1, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1, 7); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_EYING_1, 3); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_CHAT_1, 6); break;
+ default: return GetGenericMaleTalkSfx(sound);
+ }
+
+ if (model == MI_P_MAN2)
+ sfx += (SFX_BLACK_PROJECT_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetBlackProjectFemaleOldTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4729,7 +4757,7 @@ cAudioManager::GetBlackProjectFemaleOldTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackProjectFemaleYoungTalkSfx(int16 sound)
+cAudioManager::GetBlackProjectFemaleYoungTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4763,7 +4791,7 @@ cAudioManager::GetBlackProjectFemaleYoungTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetChinatownMaleOldTalkSfx(int16 sound)
+cAudioManager::GetChinatownMaleOldTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4797,7 +4825,7 @@ cAudioManager::GetChinatownMaleOldTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetChinatownMaleYoungTalkSfx(int16 sound)
+cAudioManager::GetChinatownMaleYoungTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4831,7 +4859,7 @@ cAudioManager::GetChinatownMaleYoungTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetChinatownFemaleOldTalkSfx(int16 sound)
+cAudioManager::GetChinatownFemaleOldTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4862,7 +4890,7 @@ cAudioManager::GetChinatownFemaleOldTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetChinatownFemaleYoungTalkSfx(int16 sound)
+cAudioManager::GetChinatownFemaleYoungTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4893,7 +4921,7 @@ cAudioManager::GetChinatownFemaleYoungTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetLittleItalyMaleTalkSfx(int16 sound)
+cAudioManager::GetLittleItalyMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4927,7 +4955,7 @@ cAudioManager::GetLittleItalyMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetLittleItalyFemaleOldTalkSfx(int16 sound)
+cAudioManager::GetLittleItalyFemaleOldTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4958,7 +4986,7 @@ cAudioManager::GetLittleItalyFemaleOldTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetLittleItalyFemaleYoungTalkSfx(int16 sound)
+cAudioManager::GetLittleItalyFemaleYoungTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -4989,7 +5017,7 @@ cAudioManager::GetLittleItalyFemaleYoungTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetWhiteDockerMaleTalkSfx(int16 sound)
+cAudioManager::GetWhiteDockerMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5020,7 +5048,7 @@ cAudioManager::GetWhiteDockerMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackDockerMaleTalkSfx(int16 sound)
+cAudioManager::GetBlackDockerMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5051,7 +5079,7 @@ cAudioManager::GetBlackDockerMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetScumMaleTalkSfx(int16 sound)
+cAudioManager::GetScumMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5088,7 +5116,7 @@ cAudioManager::GetScumMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetScumFemaleTalkSfx(int16 sound)
+cAudioManager::GetScumFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5119,7 +5147,7 @@ cAudioManager::GetScumFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetWhiteWorkerMaleTalkSfx(int16 sound)
+cAudioManager::GetWhiteWorkerMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5150,7 +5178,7 @@ cAudioManager::GetWhiteWorkerMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackWorkerMaleTalkSfx(int16 sound)
+cAudioManager::GetBlackWorkerMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5181,124 +5209,7 @@ cAudioManager::GetBlackWorkerMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBusinessMaleYoungTalkSfx(int16 sound, int32 model)
-{
- uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_RUN_FROM_FIGHT_1, 5);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1, 6);
- break;
- case SOUND_PED_CHAT:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_YOUNG_VOICE_1_CHAT_1, 6);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
- }
-
- if (model == MI_B_MAN3)
- sfx += (SFX_BUSINESS_MALE_YOUNG_VOICE_2_DRIVER_ABUSE_1 - SFX_BUSINESS_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1);
- return sfx;
-}
-
-uint32
-cAudioManager::GetBusinessMaleOldTalkSfx(int16 sound)
-{
- uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_1, 5);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 5);
- break;
- case SOUND_PED_CHAT:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_1, 5);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
- }
- return sfx;
-}
-
-uint32
-cAudioManager::GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model)
-{
- uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 4);
- break;
- case SOUND_PED_ANNOYED_DRIVER:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5);
- break;
- case SOUND_PED_CHAT_EVENT:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_SHOCKED_1, 4);
- break;
- case SOUND_PED_CHAT:
- GetPhrase(sfx, lastSfx, SFX_WHITE_BUSINESS_FEMALE_VOICE_1_CHAT_1, 7);
- break;
- default:
- return GetGenericFemaleTalkSfx(sound);
- }
-
- if (model == MI_B_WOM2)
- sfx += (SFX_WHITE_BUSINESS_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_WHITE_BUSINESS_FEMALE_VOICE_1_DRIVER_ABUSE_1);
- return sfx;
-}
-
-uint32
-cAudioManager::GetBlackBusinessFemaleTalkSfx(int16 sound)
+cAudioManager::GetBlackBusinessFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5335,7 +5246,7 @@ cAudioManager::GetBlackBusinessFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetSupermodelMaleTalkSfx(int16 sound)
+cAudioManager::GetSupermodelMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5369,7 +5280,7 @@ cAudioManager::GetSupermodelMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetSupermodelFemaleTalkSfx(int16 sound)
+cAudioManager::GetSupermodelFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5400,7 +5311,7 @@ cAudioManager::GetSupermodelFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetStewardMaleTalkSfx(int16 sound)
+cAudioManager::GetStewardMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5428,7 +5339,7 @@ cAudioManager::GetStewardMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetStewardFemaleTalkSfx(int16 sound)
+cAudioManager::GetStewardFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5453,7 +5364,7 @@ cAudioManager::GetStewardFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetFanMaleTalkSfx(int16 sound, int32 model)
+cAudioManager::GetFanMaleTalkSfx(uint16 sound, uint32 model)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5484,7 +5395,7 @@ cAudioManager::GetFanMaleTalkSfx(int16 sound, int32 model)
}
uint32
-cAudioManager::GetFanFemaleTalkSfx(int16 sound)
+cAudioManager::GetFanFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5512,7 +5423,7 @@ cAudioManager::GetFanFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetHospitalMaleTalkSfx(int16 sound)
+cAudioManager::GetHospitalMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5540,7 +5451,7 @@ cAudioManager::GetHospitalMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetHospitalFemaleTalkSfx(int16 sound)
+cAudioManager::GetHospitalFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5562,7 +5473,7 @@ cAudioManager::GetHospitalFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetWhiteConstructionWorkerTalkSfx(int16 sound)
+cAudioManager::GetWhiteConstructionWorkerTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5596,7 +5507,7 @@ cAudioManager::GetWhiteConstructionWorkerTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetBlackConstructionWorkerTalkSfx(int16 sound)
+cAudioManager::GetBlackConstructionWorkerTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5630,7 +5541,7 @@ cAudioManager::GetBlackConstructionWorkerTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetShopperFemaleTalkSfx(int16 sound, int32 model)
+cAudioManager::GetShopperFemaleTalkSfx(uint16 sound, uint32 model)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5667,7 +5578,7 @@ cAudioManager::GetShopperFemaleTalkSfx(int16 sound, int32 model)
}
uint32
-cAudioManager::GetStudentMaleTalkSfx(int16 sound)
+cAudioManager::GetStudentMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5701,7 +5612,7 @@ cAudioManager::GetStudentMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetStudentFemaleTalkSfx(int16 sound)
+cAudioManager::GetStudentFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5735,29 +5646,23 @@ cAudioManager::GetStudentFemaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetCasualMaleOldTalkSfx(int16 sound)
-{
- return GetGenericMaleTalkSfx(sound);
-}
-
-uint32
-cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound)
+cAudioManager::GetSpecialCharacterTalkSfx(uint32 modelIndex, uint16 sound)
{
char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetModelName();
if (!CGeneral::faststricmp(modelName, "eight") || !CGeneral::faststricmp(modelName, "eight2")) {
- return GetEightTalkSfx(sound);
+ return GetEightBallTalkSfx(sound);
}
if (!CGeneral::faststricmp(modelName, "frankie")) {
- return GetFrankieTalkSfx(sound);
+ return GetSalvatoreTalkSfx(sound);
}
if (!CGeneral::faststricmp(modelName, "misty")) {
return GetMistyTalkSfx(sound);
}
if (!CGeneral::faststricmp(modelName, "ojg") || !CGeneral::faststricmp(modelName, "ojg_p")) {
- return GetOJGTalkSfx(sound);
+ return GetOldJapTalkSfx(sound);
}
if (!CGeneral::faststricmp(modelName, "cat")) {
- return GetCatatalinaTalkSfx(sound);
+ return GetCatalinaTalkSfx(sound);
}
if (!CGeneral::faststricmp(modelName, "bomber")) {
return GetBomberTalkSfx(sound);
@@ -5777,8 +5682,9 @@ cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound)
return GetGenericMaleTalkSfx(sound);
}
+
uint32
-cAudioManager::GetEightTalkSfx(int16 sound)
+cAudioManager::GetEightBallTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5803,7 +5709,7 @@ cAudioManager::GetEightTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetFrankieTalkSfx(int16 sound)
+cAudioManager::GetSalvatoreTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5828,7 +5734,7 @@ cAudioManager::GetFrankieTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetMistyTalkSfx(int16 sound)
+cAudioManager::GetMistyTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5857,19 +5763,19 @@ cAudioManager::GetMistyTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetOJGTalkSfx(int16 sound)
+cAudioManager::GetOldJapTalkSfx(uint16 sound)
{
return GetGenericMaleTalkSfx(sound);
}
uint32
-cAudioManager::GetCatatalinaTalkSfx(int16 sound)
+cAudioManager::GetCatalinaTalkSfx(uint16 sound)
{
return GetGenericFemaleTalkSfx(sound);
}
uint32
-cAudioManager::GetBomberTalkSfx(int16 sound)
+cAudioManager::GetBomberTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5886,7 +5792,7 @@ cAudioManager::GetBomberTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetSecurityGuardTalkSfx(int16 sound)
+cAudioManager::GetSecurityGuardTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5919,7 +5825,7 @@ cAudioManager::GetSecurityGuardTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetChunkyTalkSfx(int16 sound)
+cAudioManager::GetChunkyTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5939,7 +5845,98 @@ cAudioManager::GetChunkyTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetGenericMaleTalkSfx(int16 sound)
+cAudioManager::GetAsianTaxiDriverTalkSfx(uint16 sound)
+{
+ uint32 sfx;
+ static uint32 lastSfx = NO_SAMPLE;
+
+ switch (sound) {
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(sfx, lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_CARJACKED_1, 7);
+ break;
+ case SOUND_PED_ANNOYED_DRIVER:
+ GetPhrase(sfx, lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
+ default:
+ return GetGenericMaleTalkSfx(sound);
+ }
+
+ return (SFX_ASIAN_TAXI_DRIVER_VOICE_2_DRIVER_ABUSE_1 - SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+}
+
+uint32
+cAudioManager::GetPimpTalkSfx(uint16 sound)
+{
+ uint32 sfx;
+ static uint32 lastSfx = NO_SAMPLE;
+
+ switch (sound) {
+ case SOUND_PED_HANDS_UP:
+ GetPhrase(sfx, lastSfx, SFX_PIMP_GUN_COOL_1, 7);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(sfx, lastSfx, SFX_PIMP_CARJACKED_1, 4);
+ break;
+ case SOUND_PED_DEFEND:
+ GetPhrase(sfx, lastSfx, SFX_PIMP_FIGHT_1, 9);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(sfx, lastSfx, SFX_PIMP_DODGE_1, 6);
+ break;
+ case SOUND_PED_ANNOYED_DRIVER:
+ GetPhrase(sfx, lastSfx, SFX_PIMP_DRIVER_ABUSE_1, 5);
+ break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(sfx, lastSfx, SFX_PIMP_SHOCKED_1, 2);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(sfx, lastSfx, SFX_PIMP_CHAT_1, 17);
+ break;
+ default:
+ return GetGenericMaleTalkSfx(sound);
+ }
+ return sfx;
+}
+
+uint32
+cAudioManager::GetNormalMaleTalkSfx(uint16 sound)
+{
+ uint32 sfx;
+ static uint32 lastSfx = NO_SAMPLE;
+
+ switch (sound) {
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_GUN_PANIC_1, 7);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_CARJACKED_1, 7);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_DODGE_1, 9);
+ break;
+ case SOUND_PED_FLEE_RUN:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_RUN_FROM_FIGHT_1, 5);
+ break;
+ case SOUND_PED_ANNOYED_DRIVER:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_DRIVER_ABUSE_1, 12);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_EYING_1, 8);
+ break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_SHOCKED_1, 10);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_CHAT_1, 25);
+ break;
+ default:
+ return GetGenericMaleTalkSfx(sound);
+ }
+ return sfx;
+}
+
+uint32
+cAudioManager::GetGenericMaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -5965,7 +5962,7 @@ cAudioManager::GetGenericMaleTalkSfx(int16 sound)
}
uint32
-cAudioManager::GetGenericFemaleTalkSfx(int16 sound)
+cAudioManager::GetGenericFemaleTalkSfx(uint16 sound)
{
uint32 sfx;
static uint32 lastSfx = NO_SAMPLE;
@@ -8353,7 +8350,7 @@ FindMissionAudioSfx(const char *name)
}
bool8
-cAudioManager::MissionScriptAudioUsesPoliceChannel(int32 soundMission) const
+cAudioManager::MissionScriptAudioUsesPoliceChannel(uint32 soundMission)
{
switch (soundMission) {
case STREAMED_SOUND_MISSION_J6_D:
@@ -8394,7 +8391,7 @@ cAudioManager::PreloadMissionAudio(Const char *name)
}
uint8
-cAudioManager::GetMissionAudioLoadingStatus() const
+cAudioManager::GetMissionAudioLoadingStatus()
{
if (m_bIsInitialised)
return m_sMissionAudio.m_nLoadingStatus;
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index 2e391349..c3565828 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -109,7 +109,9 @@ cAudioManager::Service()
if (m_bIsInitialised) {
m_nPreviousUserPause = m_nUserPause;
m_nUserPause = CTimer::GetIsUserPaused();
+#ifdef GTA_PC
UpdateReflections();
+#endif
ServiceSoundEffects();
MusicManager.Service();
}
@@ -216,33 +218,33 @@ cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
}
void
-cAudioManager::SetEffectsMasterVolume(uint8 volume) const
+cAudioManager::SetEffectsMasterVolume(uint8 volume)
{
SampleManager.SetEffectsMasterVolume(volume);
}
void
-cAudioManager::SetMusicMasterVolume(uint8 volume) const
+cAudioManager::SetMusicMasterVolume(uint8 volume)
{
SampleManager.SetMusicMasterVolume(volume);
}
void
-cAudioManager::SetEffectsFadeVol(uint8 volume) const
+cAudioManager::SetEffectsFadeVol(uint8 volume)
{
SampleManager.SetEffectsFadeVolume(volume);
}
void
-cAudioManager::SetMonoMode(bool8 mono)
+cAudioManager::SetMusicFadeVol(uint8 volume)
{
- SampleManager.SetMonoMode(mono);
+ SampleManager.SetMusicFadeVolume(volume);
}
void
-cAudioManager::SetMusicFadeVol(uint8 volume) const
+cAudioManager::SetMonoMode(bool8 mono)
{
- SampleManager.SetMusicFadeVolume(volume);
+ SampleManager.SetMonoMode(mono);
}
void
@@ -307,8 +309,10 @@ cAudioManager::DestroyAllGameCreatedEntities()
}
}
+#ifdef GTA_PC
+
uint8
-cAudioManager::GetNum3DProvidersAvailable() const
+cAudioManager::GetNum3DProvidersAvailable()
{
if (m_bIsInitialised)
return SampleManager.GetNum3DProvidersAvailable();
@@ -316,7 +320,7 @@ cAudioManager::GetNum3DProvidersAvailable() const
}
char *
-cAudioManager::Get3DProviderName(uint8 id) const
+cAudioManager::Get3DProviderName(uint8 id)
{
if (!m_bIsInitialised)
return nil;
@@ -331,7 +335,7 @@ cAudioManager::Get3DProviderName(uint8 id) const
}
int8
-cAudioManager::GetCurrent3DProviderIndex() const
+cAudioManager::GetCurrent3DProviderIndex()
{
if (m_bIsInitialised)
return SampleManager.GetCurrent3DProviderIndex();
@@ -363,13 +367,13 @@ cAudioManager::SetCurrent3DProvider(uint8 which)
}
void
-cAudioManager::SetSpeakerConfig(int32 conf) const
+cAudioManager::SetSpeakerConfig(int32 conf)
{
SampleManager.SetSpeakerConfig(conf);
}
bool8
-cAudioManager::IsMP3RadioChannelAvailable() const
+cAudioManager::IsMP3RadioChannelAvailable()
{
if (m_bIsInitialised)
return SampleManager.IsMP3RadioChannelAvailable();
@@ -378,7 +382,7 @@ cAudioManager::IsMP3RadioChannelAvailable() const
}
void
-cAudioManager::ReleaseDigitalHandle() const
+cAudioManager::ReleaseDigitalHandle()
{
if (m_bIsInitialised) {
SampleManager.ReleaseDigitalHandle();
@@ -386,7 +390,7 @@ cAudioManager::ReleaseDigitalHandle() const
}
void
-cAudioManager::ReacquireDigitalHandle() const
+cAudioManager::ReacquireDigitalHandle()
{
if (m_bIsInitialised) {
SampleManager.ReacquireDigitalHandle();
@@ -400,13 +404,13 @@ cAudioManager::SetDynamicAcousticModelingStatus(bool8 status)
}
bool8
-cAudioManager::CheckForAnAudioFileOnCD() const
+cAudioManager::CheckForAnAudioFileOnCD()
{
return SampleManager.CheckForAnAudioFileOnCD();
}
char
-cAudioManager::GetCDAudioDriveLetter() const
+cAudioManager::GetCDAudioDriveLetter()
{
if (m_bIsInitialised)
return SampleManager.GetCDAudioDriveLetter();
@@ -415,11 +419,13 @@ cAudioManager::GetCDAudioDriveLetter() const
}
bool8
-cAudioManager::IsAudioInitialised() const
+cAudioManager::IsAudioInitialised()
{
return m_bIsInitialised;
}
+#endif // GTA_PC
+
void
cAudioManager::ServiceSoundEffects()
{
@@ -469,8 +475,14 @@ cAudioManager::ServiceSoundEffects()
m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
}
+uint32
+cAudioManager::FL(float f)
+{
+ return SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) * f;
+}
+
uint8
-cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const
+cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance)
{
float newSoundIntensity;
if (soundIntensity <= 0.0f)
@@ -482,7 +494,7 @@ cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float d
}
void
-cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const
+cAudioManager::TranslateEntity(Const CVector *in, CVector *out)
{
*out = MultiplyInverse(TheCamera.GetMatrix(), *in);
}
@@ -501,7 +513,7 @@ cAudioManager::ComputePan(float dist, CVector *vec)
}
int32
-cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const
+cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier)
{
uint32 newFreq = oldFreq;
if (!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) {
@@ -522,7 +534,7 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
}
int32
-cAudioManager::RandomDisplacement(uint32 seed) const
+cAudioManager::RandomDisplacement(uint32 seed)
{
int32 value;
@@ -593,6 +605,7 @@ cAudioManager::AddSampleToRequestedQueue()
AddReflectionsToRequestedQueue();
}
}
+
void
cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
{
@@ -610,6 +623,7 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] = sample;
}
+#ifdef GTA_PC
void
cAudioManager::AddReflectionsToRequestedQueue()
{
@@ -687,6 +701,7 @@ cAudioManager::UpdateReflections()
m_afReflectionsDistances[4] = 50.0f;
}
}
+#endif // GTA_PC
void
cAudioManager::AddReleasingSounds()
@@ -965,6 +980,13 @@ cAudioManager::ClearActiveSamples()
}
void
+cAudioManager::LoadBankIfNecessary(uint8 bank)
+{
+ if(!SampleManager.IsSampleBankLoaded(bank))
+ SampleManager.LoadSampleBank(bank);
+}
+
+void
cAudioManager::GenerateIntegerRandomNumberTable()
{
for (int32 i = 0; i < ARRAY_SIZE(m_anRandomTable); i++) {
@@ -993,4 +1015,4 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa
return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume / quatIntensity;
return emittingVolume;
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 70302745..7c591a1e 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -20,8 +20,8 @@ public:
#ifndef GTA_PS2
int32 m_nLoopStart;
int32 m_nLoopEnd;
-#endif
uint8 m_nEmittingVolume;
+#endif
float m_fSpeedMultiplier;
float m_fSoundIntensity;
bool8 m_bReleasingSoundFlag;
@@ -183,6 +183,9 @@ enum {
MAX_REFLECTIONS,
};
+enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED };
+enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED };
+
class cAudioManager
{
public:
@@ -204,8 +207,10 @@ public:
tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES];
int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES];
int32 m_nAudioEntitiesTotal;
+#ifdef GTA_PC
CVector m_avecReflectionsPos[NUM_AUDIO_REFLECTIONS];
float m_afReflectionsDistances[NUM_AUDIO_REFLECTIONS];
+#endif
cAudioScriptObjectManager m_sAudioScriptObjectManager;
cPedComments m_sPedComments;
int32 m_nFireAudioEntity;
@@ -227,277 +232,279 @@ public:
cAudioManager();
~cAudioManager();
- // getters
- 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 ShouldDuckMissionAudio() const { return m_sMissionAudio.m_nPlayStatus == 1; }
-
- // "Should" be in alphabetic order, except "getXTalkSfx"
- void AddDetailsToRequestedOrderList(uint8 sample);
- void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank,
- uint8 counter, bool8 notLooping);
- void AddReflectionsToRequestedQueue();
- void AddReleasingSounds();
- void AddSampleToRequestedQueue();
- void AgeCrimes();
-
- void CalculateDistance(bool8 &condition, float dist);
- bool8 CheckForAnAudioFileOnCD() const;
- void ClearActiveSamples();
- void ClearMissionAudio();
- void ClearRequestedQueue();
- int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
- float speedMultiplier) const;
- int32 ComputePan(float, CVector *);
- uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const;
+ void Initialise();
+ void Terminate();
+ void Service();
int32 CreateEntity(eAudioType type, void *entity);
-
- void DestroyAllGameCreatedEntities();
void DestroyEntity(int32 id);
- void DoPoliceRadioCrackle();
+ void SetEntityStatus(int32 id, bool8 status);
+ void PlayOneShot(int32 index, uint16 sound, float vol);
+ void SetEffectsMasterVolume(uint8 volume);
+ void SetMusicMasterVolume(uint8 volume);
+ void SetEffectsFadeVol(uint8 volume);
+ void SetMusicFadeVol(uint8 volume);
+ void SetMonoMode(bool8 mono);
+ void ResetTimers(uint32 time);
+ void DestroyAllGameCreatedEntities();
- // functions returning talk sfx,
- // order from GetPedCommentSfx
- uint32 GetPlayerTalkSfx(int16 sound);
- uint32 GetCopTalkSfx(int16 sound);
- uint32 GetSwatTalkSfx(int16 sound);
- uint32 GetFBITalkSfx(int16 sound);
- uint32 GetArmyTalkSfx(int16 sound);
- uint32 GetMedicTalkSfx(int16 sound);
- uint32 GetFiremanTalkSfx(int16 sound);
- uint32 GetNormalMaleTalkSfx(int16 sound);
- uint32 GetTaxiDriverTalkSfx(int16 sound);
- uint32 GetPimpTalkSfx(int16 sound);
- uint32 GetMafiaTalkSfx(int16 sound);
- uint32 GetTriadTalkSfx(int16 sound);
- uint32 GetDiabloTalkSfx(int16 sound);
- uint32 GetYakuzaTalkSfx(int16 sound);
- uint32 GetYardieTalkSfx(int16 sound);
- uint32 GetColumbianTalkSfx(int16 sound);
- uint32 GetHoodTalkSfx(int16 sound);
- uint32 GetBlackCriminalTalkSfx(int16 sound);
- uint32 GetWhiteCriminalTalkSfx(int16 sound);
- uint32 GetMaleNo2TalkSfx(int16 sound);
- uint32 GetBlackProjectMaleTalkSfx(int16 sound, int32 model);
- uint32 GetWhiteFatMaleTalkSfx(int16 sound);
- uint32 GetBlackFatMaleTalkSfx(int16 sound);
- uint32 GetBlackCasualFemaleTalkSfx(int16 sound);
- uint32 GetWhiteCasualFemaleTalkSfx(int16 sound);
- uint32 GetFemaleNo3TalkSfx(int16 sound);
- uint32 GetBlackFatFemaleTalkSfx(int16 sound);
- uint32 GetWhiteFatFemaleTalkSfx(int16 sound);
- uint32 GetBlackFemaleProstituteTalkSfx(int16 sound);
- uint32 GetWhiteFemaleProstituteTalkSfx(int16 sound);
- uint32 GetBlackProjectFemaleOldTalkSfx(int16 sound);
- uint32 GetBlackProjectFemaleYoungTalkSfx(int16 sound);
- uint32 GetChinatownMaleOldTalkSfx(int16 sound);
- uint32 GetChinatownMaleYoungTalkSfx(int16 sound);
- uint32 GetChinatownFemaleOldTalkSfx(int16 sound);
- uint32 GetChinatownFemaleYoungTalkSfx(int16 sound);
- uint32 GetLittleItalyMaleTalkSfx(int16 sound);
- uint32 GetLittleItalyFemaleOldTalkSfx(int16 sound);
- uint32 GetLittleItalyFemaleYoungTalkSfx(int16 sound);
- uint32 GetWhiteDockerMaleTalkSfx(int16 sound);
- uint32 GetBlackDockerMaleTalkSfx(int16 sound);
- uint32 GetScumMaleTalkSfx(int16 sound);
- uint32 GetScumFemaleTalkSfx(int16 sound);
- uint32 GetWhiteWorkerMaleTalkSfx(int16 sound);
- uint32 GetBlackWorkerMaleTalkSfx(int16 sound);
- uint32 GetBusinessMaleYoungTalkSfx(int16 sound, int32 model);
- uint32 GetBusinessMaleOldTalkSfx(int16 sound);
- uint32 GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model);
- uint32 GetBlackBusinessFemaleTalkSfx(int16 sound);
- uint32 GetSupermodelMaleTalkSfx(int16 sound);
- uint32 GetSupermodelFemaleTalkSfx(int16 sound);
- uint32 GetStewardMaleTalkSfx(int16 sound);
- uint32 GetStewardFemaleTalkSfx(int16 sound);
- uint32 GetFanMaleTalkSfx(int16 sound, int32 model);
- uint32 GetFanFemaleTalkSfx(int16 sound);
- uint32 GetHospitalMaleTalkSfx(int16 sound);
- uint32 GetHospitalFemaleTalkSfx(int16 sound);
- uint32 GetWhiteConstructionWorkerTalkSfx(int16 sound);
- uint32 GetBlackConstructionWorkerTalkSfx(int16 sound);
- uint32 GetShopperFemaleTalkSfx(int16 sound, int32 model);
- uint32 GetStudentMaleTalkSfx(int16 sound);
- uint32 GetStudentFemaleTalkSfx(int16 sound);
- uint32 GetCasualMaleOldTalkSfx(int16 sound);
-
- uint32 GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound);
- uint32 GetEightTalkSfx(int16 sound);
- uint32 GetFrankieTalkSfx(int16 sound);
- uint32 GetMistyTalkSfx(int16 sound);
- uint32 GetOJGTalkSfx(int16 sound);
- uint32 GetCatatalinaTalkSfx(int16 sound);
- uint32 GetBomberTalkSfx(int16 sound);
- uint32 GetSecurityGuardTalkSfx(int16 sound);
- uint32 GetChunkyTalkSfx(int16 sound);
-
- uint32 GetGenericMaleTalkSfx(int16 sound);
- uint32 GetGenericFemaleTalkSfx(int16 sound);
- // end of functions returning talk sfx
-
- void GenerateIntegerRandomNumberTable();
- char *Get3DProviderName(uint8 id) const;
- char GetCDAudioDriveLetter() const;
- int8 GetCurrent3DProviderIndex() 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;
- float GetDistanceSquared(const CVector &v) const;
- int32 GetJumboTaxiFreq() const;
- uint8 GetMissionAudioLoadingStatus() const;
- int8 GetMissionScriptPoliceAudioPlayingStatus() const;
- uint8 GetNum3DProvidersAvailable() const;
- int32 GetPedCommentSfx(CPed *ped, int32 sound);
- void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
- float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
- cTransmission *transmission, float velocityChange);
- float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
- cTransmission *transmission, float velocityChange);
-
- bool8 HasAirBrakes(int32 model) const;
+#ifdef GTA_PC
+ uint8 GetNum3DProvidersAvailable();
+ char *Get3DProviderName(uint8 id);
+ int8 GetCurrent3DProviderIndex();
+ int8 SetCurrent3DProvider(uint8 which);
+ void SetSpeakerConfig(int32 conf);
+ bool8 IsMP3RadioChannelAvailable();
+ void ReleaseDigitalHandle();
+ void ReacquireDigitalHandle();
+ void SetDynamicAcousticModelingStatus(bool8 status);
+ bool8 CheckForAnAudioFileOnCD();
+ char GetCDAudioDriveLetter();
+ bool8 IsAudioInitialised();
+#endif
- void Initialise();
- void InitialisePoliceRadio();
- void InitialisePoliceRadioZones();
- void InterrogateAudioEntities();
- bool8 IsAudioInitialised() const;
- bool8 IsMissionAudioSampleFinished();
- bool8 IsMP3RadioChannelAvailable() const;
+ void ServiceSoundEffects();
+ uint32 FL(float f); // not used
+ uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance);
+ void TranslateEntity(Const CVector *v1, CVector *v2);
+ int32 ComputePan(float, CVector *);
+ int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier); // inlined on PS2
+ int32 RandomDisplacement(uint32 seed);
+ void InterrogateAudioEntities(); // inlined on PS2
+ void AddSampleToRequestedQueue();
+ void AddDetailsToRequestedOrderList(uint8 sample); // inlined on PS2
+#ifdef GTA_PC
+ void AddReflectionsToRequestedQueue();
+ void UpdateReflections();
+#endif
+ void AddReleasingSounds();
+ void ProcessActiveQueues();
+ void ClearRequestedQueue(); // inlined on PS2
+ void ClearActiveSamples();
+ void GenerateIntegerRandomNumberTable(); // inlined on PS2
+ void LoadBankIfNecessary(uint8 bank); // this is used only on PS2 but technically not a platform code
- bool8 MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
+#ifdef GTA_PC
+ void AdjustSamplesVolume();
+ uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
+#endif
- void PlayLoadedMissionAudio();
- void PlayOneShot(int32 index, uint16 sound, float vol);
- void PlaySuspectLastSeen(float x, float y, float z);
- void PlayerJustGotInCar() const;
- void PlayerJustLeftCar() const;
+ // audio logic
+ void PreInitialiseGameSpecificSetup();
void PostInitialiseGameSpecificSetup();
- void PostTerminateGameSpecificShutdown();
- void PreInitialiseGameSpecificSetup() const;
- void PreloadMissionAudio(Const char *name);
void PreTerminateGameSpecificShutdown();
- /// processX - main logic of adding new sounds
- void ProcessActiveQueues();
- bool8 ProcessAirBrakes(cVehicleParams& params);
- void ProcessAirportScriptObject(uint8 sound);
- bool8 ProcessBoatEngine(cVehicleParams& params);
- bool8 ProcessBoatMovingOverWater(cVehicleParams& params);
- void ProcessBridge();
- void ProcessBridgeMotor();
- void ProcessBridgeOneShots();
- void ProcessBridgeWarning();
- bool8 ProcessCarBombTick(cVehicleParams& params);
- void ProcessCesna(cVehicleParams& params);
- void ProcessCinemaScriptObject(uint8 sound);
- void ProcessCrane();
- void ProcessDocksScriptObject(uint8 sound);
- bool8 ProcessEngineDamage(cVehicleParams& params);
+ void PostTerminateGameSpecificShutdown();
+ void ResetAudioLogicTimers(uint32 timer);
+ void ProcessReverb();
+ float GetDistanceSquared(const CVector &v);
+ void CalculateDistance(bool8 &condition, float dist);
+ void ProcessSpecial();
void ProcessEntity(int32 sound);
- void ProcessExplosions(int32 explosion);
- void ProcessFireHydrant();
- void ProcessFires(int32 entity);
- void ProcessFrontEnd();
- void ProcessGarages();
- bool8 ProcessHelicopter(cVehicleParams& params);
- void ProcessHomeScriptObject(uint8 sound);
- void ProcessJumbo(cVehicleParams& params);
+ void ProcessPhysical(int32 id);
+ void ProcessVehicle(CVehicle *vehicle);
+ void ProcessRainOnVehicle(cVehicleParams &params);
+ bool8 ProcessReverseGear(cVehicleParams &params);
+ void ProcessModelCarEngine(cVehicleParams &params);
+ bool8 ProcessVehicleRoadNoise(cVehicleParams &params);
+ bool8 ProcessWetRoadNoise(cVehicleParams &params);
+
+ // vehicles
+ void ProcessVehicleEngine(cVehicleParams &params);
+ void UpdateGasPedalAudio(CAutomobile *automobile); // inlined on PS2
+ void PlayerJustGotInCar();
+ void PlayerJustLeftCar();
+ void AddPlayerCarSample(uint8 emittingVolume, uint32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping);
+ void ProcessCesna(cVehicleParams &params);
+ void ProcessPlayersVehicleEngine(cVehicleParams &params, CAutomobile *automobile);
+ bool8 ProcessVehicleSkidding(cVehicleParams &params);
+ float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange);
+ float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange); // was in .h on PS2
+ void ProcessVehicleHorn(cVehicleParams &params);
+ bool8 UsesSiren(uint32 model); // inlined on PS2
+ bool8 UsesSirenSwitching(uint32 model); // inlined on PS2
+ bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params);
+ bool8 UsesReverseWarning(uint32 model); // inlined on PS2
+ bool8 ProcessVehicleReverseWarning(cVehicleParams &params);
+ bool8 ProcessVehicleDoors(cVehicleParams &params);
+ bool8 ProcessAirBrakes(cVehicleParams &params);
+ bool8 HasAirBrakes(uint32 model); // inlined on PS2
+ bool8 ProcessEngineDamage(cVehicleParams &params);
+ bool8 ProcessCarBombTick(cVehicleParams &params);
+ void ProcessVehicleOneShots(cVehicleParams &params);
+ bool8 ProcessTrainNoise(cVehicleParams &params);
+ bool8 ProcessBoatEngine(cVehicleParams &params);
+ bool8 ProcessBoatMovingOverWater(cVehicleParams &params);
+ bool8 ProcessHelicopter(cVehicleParams &params);
+ void ProcessPlane(cVehicleParams &params); // inlined on PS2
+ void ProcessJumbo(cVehicleParams &params);
+ void ProcessJumboTaxi(); // inlined on PS2
void ProcessJumboAccel(CPlane *plane);
- void ProcessJumboDecel(CPlane *plane);
- void ProcessJumboFlying();
- void ProcessJumboLanding(CPlane *plane);
- void ProcessJumboTakeOff(CPlane *plane);
- void ProcessJumboTaxi();
- void ProcessLaunderetteScriptObject(uint8 sound);
- void ProcessLoopingScriptObject(uint8 sound);
- void ProcessMissionAudio();
- void ProcessModelCarEngine(cVehicleParams& params);
- void ProcessOneShotScriptObject(uint8 sound);
- void ProcessPed(CPhysical *ped);
+ void ProcessJumboTakeOff(CPlane *plane); // inlined on PS2
+ void ProcessJumboFlying(); // inlined on PS2
+ void ProcessJumboLanding(CPlane *plane); // inlined on PS2
+ void ProcessJumboDecel(CPlane *plane); // inlined on PS2
+ bool8 SetupJumboTaxiSound(uint8 vol);
+ bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
+ bool8 SetupJumboEngineSound(uint8 vol, uint32 freq);
+ bool8 SetupJumboFlySound(uint8 emittingVol);
+ bool8 SetupJumboRumbleSound(uint8 emittingVol);
+ int32 GetJumboTaxiFreq(); // inlined on PS2
+
+ // peds
+ void ProcessPed(CPhysical *ped); // inlined on PS2
void ProcessPedHeadphones(cPedParams &params);
void ProcessPedOneShots(cPedParams &params);
- void ProcessPhysical(int32 id);
- void ProcessPlane(cVehicleParams& params);
- void ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *automobile);
- void ProcessPoliceCellBeatingScriptObject(uint8 sound);
+
+ // ped comments
+ void SetupPedComments(cPedParams &params, uint16 sound);
+ int32 GetPedCommentSfx(CPed *ped, uint16 sound);
+ void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset); // inlined on PS2
+ uint32 GetPlayerTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetCopTalkSfx(uint16 sound);
+ uint32 GetSwatTalkSfx(uint16 sound);
+ uint32 GetFBITalkSfx(uint16 sound);
+ uint32 GetArmyTalkSfx(uint16 sound);
+ uint32 GetMedicTalkSfx(uint16 sound);
+ uint32 GetFiremanTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetBusinessMaleOldTalkSfx(uint16 sound);
+ uint32 GetBusinessMaleYoungTalkSfx(uint16 sound, uint32 model);
+ uint32 GetMafiaTalkSfx(uint16 sound);
+ uint32 GetTriadTalkSfx(uint16 sound);
+ uint32 GetDiabloTalkSfx(uint16 sound);
+ uint32 GetYakuzaTalkSfx(uint16 sound);
+ uint32 GetYardieTalkSfx(uint16 sound);
+ uint32 GetColumbianTalkSfx(uint16 sound);
+ uint32 GetHoodTalkSfx(uint16 sound);
+ uint32 GetBlackCriminalTalkSfx(uint16 sound);
+ uint32 GetWhiteCriminalTalkSfx(uint16 sound);
+ uint32 GetCasualMaleOldTalkSfx(uint16 sound);
+ uint32 GetCasualMaleYoungTalkSfx(uint16 sound);
+ uint32 GetBlackCasualFemaleTalkSfx(uint16 sound);
+ uint32 GetWhiteCasualFemaleTalkSfx(uint16 sound);
+ uint32 GetFemaleNo3TalkSfx(uint16 sound);
+ uint32 GetWhiteBusinessFemaleTalkSfx(uint16 sound, uint32 model);
+ uint32 GetBlackFatFemaleTalkSfx(uint16 sound);
+ uint32 GetWhiteFatMaleTalkSfx(uint16 sound);
+ uint32 GetBlackFatMaleTalkSfx(uint16 sound);
+ uint32 GetWhiteFatFemaleTalkSfx(uint16 sound);
+ uint32 GetBlackFemaleProstituteTalkSfx(uint16 sound);
+ uint32 GetWhiteFemaleProstituteTalkSfx(uint16 sound);
+ uint32 GetBlackProjectMaleTalkSfx(uint16 sound, uint32 model);
+ uint32 GetBlackProjectFemaleOldTalkSfx(uint16 sound);
+ uint32 GetBlackProjectFemaleYoungTalkSfx(uint16 sound);
+ uint32 GetChinatownMaleOldTalkSfx(uint16 sound);
+ uint32 GetChinatownMaleYoungTalkSfx(uint16 sound);
+ uint32 GetChinatownFemaleOldTalkSfx(uint16 sound);
+ uint32 GetChinatownFemaleYoungTalkSfx(uint16 sound);
+ uint32 GetLittleItalyMaleTalkSfx(uint16 sound);
+ uint32 GetLittleItalyFemaleOldTalkSfx(uint16 sound);
+ uint32 GetLittleItalyFemaleYoungTalkSfx(uint16 sound);
+ uint32 GetWhiteDockerMaleTalkSfx(uint16 sound);
+ uint32 GetBlackDockerMaleTalkSfx(uint16 sound);
+ uint32 GetScumMaleTalkSfx(uint16 sound);
+ uint32 GetScumFemaleTalkSfx(uint16 sound);
+ uint32 GetWhiteWorkerMaleTalkSfx(uint16 sound);
+ uint32 GetBlackWorkerMaleTalkSfx(uint16 sound);
+ uint32 GetBlackBusinessFemaleTalkSfx(uint16 sound);
+ uint32 GetSupermodelMaleTalkSfx(uint16 sound);
+ uint32 GetSupermodelFemaleTalkSfx(uint16 sound);
+ uint32 GetStewardMaleTalkSfx(uint16 sound);
+ uint32 GetStewardFemaleTalkSfx(uint16 sound);
+ uint32 GetFanMaleTalkSfx(uint16 sound, uint32 model);
+ uint32 GetFanFemaleTalkSfx(uint16 sound);
+ uint32 GetHospitalMaleTalkSfx(uint16 sound);
+ uint32 GetHospitalFemaleTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetWhiteConstructionWorkerTalkSfx(uint16 sound);
+ uint32 GetBlackConstructionWorkerTalkSfx(uint16 sound);
+ uint32 GetShopperFemaleTalkSfx(uint16 sound, uint32 model);
+ uint32 GetStudentMaleTalkSfx(uint16 sound);
+ uint32 GetStudentFemaleTalkSfx(uint16 sound);
+
+ uint32 GetSpecialCharacterTalkSfx(uint32 modelIndex, uint16 sound);
+ uint32 GetEightBallTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetSalvatoreTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetMistyTalkSfx(uint16 sound);
+ uint32 GetOldJapTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetCatalinaTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetBomberTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetSecurityGuardTalkSfx(uint16 sound);
+ uint32 GetChunkyTalkSfx(uint16 sound); // inlined on PS2
+
+ uint32 GetAsianTaxiDriverTalkSfx(uint16 sound); // inlined on PS2
+ uint32 GetPimpTalkSfx(uint16 sound);
+ uint32 GetNormalMaleTalkSfx(uint16 sound);
+ uint32 GetGenericMaleTalkSfx(uint16 sound);
+ uint32 GetGenericFemaleTalkSfx(uint16 sound);
+
+ // particles
+ void ProcessExplosions(int32 explosion);
+ void ProcessFires(int32 entity);
+ void ProcessWaterCannon(int32);
+
+ // script objects
+ void ProcessScriptObject(int32 id); // inlined on PS2
+ void ProcessOneShotScriptObject(uint8 sound);
+ void ProcessLoopingScriptObject(uint8 sound);
void ProcessPornCinema(uint8 sound);
- void ProcessProjectiles();
- void ProcessRainOnVehicle(cVehicleParams& params);
- void ProcessReverb() const;
- bool8 ProcessReverseGear(cVehicleParams& params);
+ void ProcessWorkShopScriptObject(uint8 sound);
void ProcessSawMillScriptObject(uint8 sound);
- void ProcessScriptObject(int32 id);
+ void ProcessLaunderetteScriptObject(uint8 sound);
void ProcessShopScriptObject(uint8 sound);
- void ProcessSpecial();
- bool8 ProcessTrainNoise(cVehicleParams& params);
- void ProcessVehicle(CVehicle *vehicle);
- bool8 ProcessVehicleDoors(cVehicleParams& params);
- void ProcessVehicleEngine(cVehicleParams& params);
- void 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 ProcessAirportScriptObject(uint8 sound);
+ void ProcessCinemaScriptObject(uint8 sound);
+ void ProcessDocksScriptObject(uint8 sound);
+ void ProcessHomeScriptObject(uint8 sound);
+ void ProcessPoliceCellBeatingScriptObject(uint8 sound);
+
+ // misc
void ProcessWeather(int32 id);
- bool8 ProcessWetRoadNoise(cVehicleParams& params);
- void ProcessWorkShopScriptObject(uint8 sound);
+ void ProcessFrontEnd();
+ void ProcessCrane();
+ void ProcessProjectiles();
+ void ProcessGarages();
+ void ProcessFireHydrant();
- 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);
+ // bridge
+ void ProcessBridge(); // inlined on PS2
+ void ProcessBridgeWarning();
+ void ProcessBridgeMotor();
+ void ProcessBridgeOneShots();
- void Service();
- void ServiceCollisions();
+ // mission audio
+ bool8 MissionScriptAudioUsesPoliceChannel(uint32 soundMission);
+ void PreloadMissionAudio(Const char *name);
+ uint8 GetMissionAudioLoadingStatus();
+ void SetMissionAudioLocation(float x, float y, float z);
+ void PlayLoadedMissionAudio();
+ bool8 IsMissionAudioSampleFinished();
+ bool8 IsMissionAudioSamplePlaying() { return m_sMissionAudio.m_nPlayStatus == PLAY_STATUS_PLAYING; }
+ bool8 ShouldDuckMissionAudio() { return IsMissionAudioSamplePlaying(); }
+ void ClearMissionAudio();
+ void ProcessMissionAudio();
+
+ // police radio
+ void InitialisePoliceRadioZones();
+ void InitialisePoliceRadio();
+ void ResetPoliceRadio();
+ void SetMissionScriptPoliceAudio(int32 sfx);
+ int8 GetMissionScriptPoliceAudioPlayingStatus();
+ void DoPoliceRadioCrackle();
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 SetEntityStatus(int32 id, bool8 status);
- uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
- void SetMissionAudioLocation(float x, float y, float z);
- void SetMissionScriptPoliceAudio(int32 sfx) const;
- 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();
- void TranslateEntity(Const CVector *v1, CVector *v2) const;
-
- void UpdateGasPedalAudio(CAutomobile *automobile);
- void UpdateReflections();
- bool8 UsesReverseWarning(int32 model) const;
- bool8 UsesSiren(int32 model) const;
- bool8 UsesSirenSwitching(int32 model) const;
-
-#ifdef GTA_PC
- // only used in pc
- void AdjustSamplesVolume();
- uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
-#endif
+ void ReportCrime(eCrimeType crime, const CVector &pos);
+ void PlaySuspectLastSeen(float x, float y, float z);
+ void AgeCrimes(); // inlined on PS2
+
+ // collision stuff
+ void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2);
+ void ServiceCollisions();
+ void SetUpOneShotCollisionSound(const cAudioCollision &col);
+ void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
+ uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
+ float GetCollisionOneShotRatio(uint32 a, float b);
+ float GetCollisionLoopingRatio(uint32 a, uint32 b, float c); // not used
+ float GetCollisionRatio(float a, float b, float c, float d); // inlined on PS2
};
/*
diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index cb441622..815e55f2 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -236,23 +236,23 @@ cMusicManager::Initialise()
if (!IsInitialised()) {
time_t timevalue = time(0);
if (timevalue == -1) {
- pos = AudioManager.GetRandomNumber(0);
+ pos = AudioManager.m_anRandomTable[0];
} else {
tm *pTm = localtime(&timevalue);
if (pTm->tm_sec == 0)
- pTm->tm_sec = AudioManager.GetRandomNumber(0);
+ pTm->tm_sec = AudioManager.m_anRandomTable[0];
if (pTm->tm_min == 0)
- pTm->tm_min = AudioManager.GetRandomNumber(1);
+ pTm->tm_min = AudioManager.m_anRandomTable[1];
if (pTm->tm_hour == 0)
- pTm->tm_hour = AudioManager.GetRandomNumber(2);
+ pTm->tm_hour = AudioManager.m_anRandomTable[2];
if (pTm->tm_mday == 0)
- pTm->tm_mday = AudioManager.GetRandomNumber(3);
+ pTm->tm_mday = AudioManager.m_anRandomTable[3];
if (pTm->tm_mon == 0)
- pTm->tm_mon = AudioManager.GetRandomNumber(4);
+ pTm->tm_mon = AudioManager.m_anRandomTable[4];
if (pTm->tm_year == 0)
- pTm->tm_year = AudioManager.GetRandomNumber(3);
+ pTm->tm_year = AudioManager.m_anRandomTable[3];
if (pTm->tm_wday == 0)
- pTm->tm_wday = AudioManager.GetRandomNumber(2);
+ pTm->tm_wday = AudioManager.m_anRandomTable[2];
pos = pTm->tm_yday
* pTm->tm_wday
* pTm->tm_year
@@ -265,7 +265,7 @@ cMusicManager::Initialise()
for (int i = 0; i < TOTAL_STREAMED_SOUNDS; i++) {
m_aTracks[i].m_nLength = SampleManager.GetStreamedFileLength(i);
- m_aTracks[i].m_nPosition = pos * AudioManager.GetRandomNumber(i % 5) % m_aTracks[i].m_nLength;
+ m_aTracks[i].m_nPosition = pos * AudioManager.m_anRandomTable[i % 5] % m_aTracks[i].m_nLength;
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
@@ -949,7 +949,7 @@ cMusicManager::GetCarTuning()
if (veh == nil) return RADIO_OFF;
if (UsesPoliceRadio(veh)) return POLICE_RADIO;
if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable())
- veh->m_nRadioStation = AudioManager.GetRandomNumber(2) % USERTRACK;
+ veh->m_nRadioStation = AudioManager.m_anRandomTable[2] % USERTRACK;
return veh->m_nRadioStation;
}
diff --git a/src/audio/PolRadio.cpp b/src/audio/PolRadio.cpp
index 235a53d3..9a98de35 100644
--- a/src/audio/PolRadio.cpp
+++ b/src/audio/PolRadio.cpp
@@ -106,7 +106,7 @@ cAudioManager::ResetPoliceRadio()
}
void
-cAudioManager::SetMissionScriptPoliceAudio(int32 sfx) const
+cAudioManager::SetMissionScriptPoliceAudio(int32 sfx)
{
if (!m_bIsInitialised) return;
if (g_nMissionAudioPlayingStatus != 1) {
@@ -116,7 +116,7 @@ cAudioManager::SetMissionScriptPoliceAudio(int32 sfx) const
}
int8
-cAudioManager::GetMissionScriptPoliceAudioPlayingStatus() const
+cAudioManager::GetMissionScriptPoliceAudioPlayingStatus()
{
return g_nMissionAudioPlayingStatus;
}
@@ -677,8 +677,6 @@ cAudioManager::SetupSuspectLastSeenReport()
}
}
-
-
void
cAudioManager::ReportCrime(eCrimeType type, const CVector &pos)
{
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index 0209202a..6afe8e30 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -2,7 +2,7 @@
#ifdef AUDIO_OAL
-#if defined _MSC_VER && !defined RE3_NO_AUTOLINK
+#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK
#ifdef AUDIO_OAL_USE_SNDFILE
#pragma comment( lib, "libsndfile-1.lib" )
#endif
@@ -504,6 +504,7 @@ public:
class CMP3File : public IDecoder
{
+protected:
mpg123_handle *m_pMH;
bool m_bOpened;
uint32 m_nRate;
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index d1ad9a26..dc95622b 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -259,8 +259,8 @@ static char StreamedNameTable[][25] = {
"AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS",
"AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"};
#else
-#if defined(PS2_AUDIO_PATHS)
-static char StreamedNameTable[][25]=
+#ifdef PS2_AUDIO_PATHS
+static char PS2StreamedNameTable[][25]=
{
"AUDIO\\MUSIC\\HEAD.VB",
"AUDIO\\MUSIC\\CLASS.VB",
@@ -357,7 +357,110 @@ static char StreamedNameTable[][25]=
"AUDIO\\PHONE\\MT_PH4.VB",
"AUDIO\\MUSIC\\MISCOM.VB",
"AUDIO\\MUSIC\\END.VB",
-#else
+ "AUDIO\\lib_a1.WAV",
+ "AUDIO\\lib_a2.WAV",
+ "AUDIO\\lib_a.WAV",
+ "AUDIO\\lib_b.WAV",
+ "AUDIO\\lib_c.WAV",
+ "AUDIO\\lib_d.WAV",
+ "AUDIO\\l2_a.WAV",
+ "AUDIO\\j4t_1.WAV",
+ "AUDIO\\j4t_2.WAV",
+ "AUDIO\\j4t_3.WAV",
+ "AUDIO\\j4t_4.WAV",
+ "AUDIO\\j4_a.WAV",
+ "AUDIO\\j4_b.WAV",
+ "AUDIO\\j4_c.WAV",
+ "AUDIO\\j4_d.WAV",
+ "AUDIO\\j4_e.WAV",
+ "AUDIO\\j4_f.WAV",
+ "AUDIO\\j6_1.WAV",
+ "AUDIO\\j6_a.WAV",
+ "AUDIO\\j6_b.WAV",
+ "AUDIO\\j6_c.WAV",
+ "AUDIO\\j6_d.WAV",
+ "AUDIO\\t4_a.WAV",
+ "AUDIO\\s1_a.WAV",
+ "AUDIO\\s1_a1.WAV",
+ "AUDIO\\s1_b.WAV",
+ "AUDIO\\s1_c.WAV",
+ "AUDIO\\s1_c1.WAV",
+ "AUDIO\\s1_d.WAV",
+ "AUDIO\\s1_e.WAV",
+ "AUDIO\\s1_f.WAV",
+ "AUDIO\\s1_g.WAV",
+ "AUDIO\\s1_h.WAV",
+ "AUDIO\\s1_i.WAV",
+ "AUDIO\\s1_j.WAV",
+ "AUDIO\\s1_k.WAV",
+ "AUDIO\\s1_l.WAV",
+ "AUDIO\\s3_a.WAV",
+ "AUDIO\\s3_b.WAV",
+ "AUDIO\\el3_a.WAV",
+ "AUDIO\\mf1_a.WAV",
+ "AUDIO\\mf2_a.WAV",
+ "AUDIO\\mf3_a.WAV",
+ "AUDIO\\mf3_b.WAV",
+ "AUDIO\\mf3_b1.WAV",
+ "AUDIO\\mf3_c.WAV",
+ "AUDIO\\mf4_a.WAV",
+ "AUDIO\\mf4_b.WAV",
+ "AUDIO\\mf4_c.WAV",
+ "AUDIO\\a1_a.WAV",
+ "AUDIO\\a3_a.WAV",
+ "AUDIO\\a5_a.WAV",
+ "AUDIO\\a4_a.WAV",
+ "AUDIO\\a4_b.WAV",
+ "AUDIO\\a4_c.WAV",
+ "AUDIO\\a4_d.WAV",
+ "AUDIO\\k1_a.WAV",
+ "AUDIO\\k3_a.WAV",
+ "AUDIO\\r1_a.WAV",
+ "AUDIO\\r2_a.WAV",
+ "AUDIO\\r2_b.WAV",
+ "AUDIO\\r2_c.WAV",
+ "AUDIO\\r2_d.WAV",
+ "AUDIO\\r2_e.WAV",
+ "AUDIO\\r2_f.WAV",
+ "AUDIO\\r2_g.WAV",
+ "AUDIO\\r2_h.WAV",
+ "AUDIO\\r5_a.WAV",
+ "AUDIO\\r6_a.WAV",
+ "AUDIO\\r6_a1.WAV",
+ "AUDIO\\r6_b.WAV",
+ "AUDIO\\lo2_a.WAV",
+ "AUDIO\\lo6_a.WAV",
+ "AUDIO\\yd2_a.WAV",
+ "AUDIO\\yd2_b.WAV",
+ "AUDIO\\yd2_c.WAV",
+ "AUDIO\\yd2_c1.WAV",
+ "AUDIO\\yd2_d.WAV",
+ "AUDIO\\yd2_e.WAV",
+ "AUDIO\\yd2_f.WAV",
+ "AUDIO\\yd2_g.WAV",
+ "AUDIO\\yd2_h.WAV",
+ "AUDIO\\yd2_ass.WAV",
+ "AUDIO\\yd2_ok.WAV",
+ "AUDIO\\h5_a.WAV",
+ "AUDIO\\h5_b.WAV",
+ "AUDIO\\h5_c.WAV",
+ "AUDIO\\ammu_a.WAV",
+ "AUDIO\\ammu_b.WAV",
+ "AUDIO\\ammu_c.WAV",
+ "AUDIO\\door_1.WAV",
+ "AUDIO\\door_2.WAV",
+ "AUDIO\\door_3.WAV",
+ "AUDIO\\door_4.WAV",
+ "AUDIO\\door_5.WAV",
+ "AUDIO\\door_6.WAV",
+ "AUDIO\\t3_a.WAV",
+ "AUDIO\\t3_b.WAV",
+ "AUDIO\\t3_c.WAV",
+ "AUDIO\\k1_b.WAV",
+ "AUDIO\\cat1.WAV"
+};
+#endif
+
static char StreamedNameTable[][25] =
{
"AUDIO\\HEAD.WAV",
@@ -455,7 +558,6 @@ static char StreamedNameTable[][25] =
"AUDIO\\MT_PH4.MP3",
"AUDIO\\MISCOM.WAV",
"AUDIO\\END.MP3",
-#endif
"AUDIO\\lib_a1.WAV",
"AUDIO\\lib_a2.WAV",
"AUDIO\\lib_a.WAV",
diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp
index e820864c..7c40d15d 100644
--- a/src/audio/sampman_miles.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -992,11 +992,20 @@ cSampleManager::Initialise(void)
if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM )
{
+ FILE *f;
+#ifdef PS2_AUDIO_PATHS
strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[0]);
-
- FILE *f = fopen(filepath, "rb");
+ strcat(filepath, PS2StreamedNameTable[0]);
+ f = fopen(filepath, "rb");
+
+ if ( !f )
+#endif
+ {
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[0]);
+ f = fopen(filepath, "rb");
+ }
if ( f )
{
fclose(f);
@@ -1005,11 +1014,20 @@ cSampleManager::Initialise(void)
for ( int32 i = 0; 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] )
{
AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
@@ -1078,7 +1096,14 @@ cSampleManager::Initialise(void)
strcpy(_aHDDPath, m_szCDRomRootPath);
rootpath[0] = '\0';
- FILE *f = fopen(StreamedNameTable[0], "rb");
+ FILE *f;
+
+#ifdef PS2_AUDIO_PATHS
+ f = fopen(PS2StreamedNameTable[0], "rb");
+ if (!f)
+#endif
+
+ f = fopen(StreamedNameTable[0], "rb");
if ( f )
{
@@ -1086,11 +1111,20 @@ cSampleManager::Initialise(void)
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
{
+#ifdef PS2_AUDIO_PATHS
strcpy(filepath, rootpath);
- strcat(filepath, StreamedNameTable[i]);
-
+ strcat(filepath, PS2StreamedNameTable[i]);
+
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
-
+ if ( !mp3Stream[0] )
+#endif
+ {
+ strcpy(filepath, rootpath);
+ strcat(filepath, StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ }
+
if ( mp3Stream[0] )
{
AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
@@ -1211,7 +1245,7 @@ cSampleManager::Initialise(void)
int32 randval;
if ( bUseRandomTable )
- randval = AudioManager.GetRandomNumber(1);
+ randval = AudioManager.m_anRandomTable[1];
else
randval = localtm->tm_sec * localtm->tm_min;
@@ -1222,7 +1256,7 @@ cSampleManager::Initialise(void)
randmp3 = randmp3->pNext;
if ( bUseRandomTable )
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ _CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
else
{
if ( localtm->tm_sec > 0 )
@@ -1231,7 +1265,7 @@ cSampleManager::Initialise(void)
_CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
}
else
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ _CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
}
}
else
@@ -1299,9 +1333,11 @@ cSampleManager::CheckForAnAudioFileOnCD(void)
{
#if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
char filepath[MAX_PATH];
+ FILE *f;
+#ifdef PS2_AUDIO_PATHS
#if GTA_VERSION >= GTA3_PC_11
- if (_bUseHDDAudio)
+ if(_bUseHDDAudio)
strcpy(filepath, _aHDDPath);
else
strcpy(filepath, m_szCDRomRootPath);
@@ -1309,10 +1345,25 @@ cSampleManager::CheckForAnAudioFileOnCD(void)
strcpy(filepath, m_szCDRomRootPath);
#endif // #if GTA_VERSION >= GTA3_PC_11
- strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
-
- FILE *f = fopen(filepath, "rb");
+ strcat(filepath, PS2StreamedNameTable[AudioManager.m_anRandomTable[1] % TOTAL_STREAMED_SOUNDS]);
+
+ f = fopen(filepath, "rb");
+ if ( !f )
+#endif // PS2_AUDIO_PATHS
+ {
+#if GTA_VERSION >= GTA3_PC_11
+ if (_bUseHDDAudio)
+ strcpy(filepath, _aHDDPath);
+ else
+ strcpy(filepath, m_szCDRomRootPath);
+#else
+ strcpy(filepath, m_szCDRomRootPath);
+#endif // #if GTA_VERSION >= GTA3_PC_11
+
+ strcat(filepath, StreamedNameTable[AudioManager.m_anRandomTable[1] % TOTAL_STREAMED_SOUNDS]);
+ f = fopen(filepath, "rb");
+ }
if ( f )
{
fclose(f);
@@ -1580,12 +1631,12 @@ cSampleManager::UpdateReverb(void)
if ( !usingEAX )
return FALSE;
- if ( AudioManager.GetFrameCounter() & 15 )
+ if ( AudioManager.m_FrameCounter & 15 )
return FALSE;
- float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
- float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
- float z = AudioManager.GetReflectionsDistance(REFLECTION_UP);
+ float y = AudioManager.m_afReflectionsDistances[REFLECTION_TOP] + AudioManager.m_afReflectionsDistances[REFLECTION_BOTTOM];
+ float x = AudioManager.m_afReflectionsDistances[REFLECTION_LEFT] + AudioManager.m_afReflectionsDistances[REFLECTION_RIGHT];
+ float z = AudioManager.m_afReflectionsDistances[REFLECTION_UP];
float normy = norm(y, 5.0f, 40.0f);
float normx = norm(x, 5.0f, 40.0f);
@@ -2007,11 +2058,19 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
}
char filepath[MAX_PATH];
-
+#ifdef PS2_AUDIO_PATHS
strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[nFile]);
-
+ strcat(filepath, PS2StreamedNameTable[nFile]);
+
mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
+ if ( !mp3Stream[nStream] )
+#endif
+ {
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
+ }
if ( mp3Stream[nStream] )
{
@@ -2073,10 +2132,19 @@ cSampleManager::StartStreamedFile(uint8 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_szCDRomRootPath);
- strcat(filename, StreamedNameTable[nFile]);
-
+ strcat(filename, PS2StreamedNameTable[nFile]);
+
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ if ( !mp3Stream[nStream] )
+#endif
+ {
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ }
if ( mp3Stream[nStream] )
{
AIL_set_stream_loop_count(mp3Stream[nStream], 1);
@@ -2120,10 +2188,19 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
{
nFile = 0;
_bIsMp3Active = 0;
+#ifdef PS2_AUDIO_PATHS
strcpy(filename, m_szCDRomRootPath);
- strcat(filename, StreamedNameTable[nFile]);
-
+ strcat(filename, PS2StreamedNameTable[nFile]);
+
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ if ( !mp3Stream[nStream] )
+#endif
+ {
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ }
if ( mp3Stream[nStream] )
{
AIL_set_stream_loop_count(mp3Stream[nStream], 1);
@@ -2161,10 +2238,19 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
position = 0;
nFile = 0;
}
+#ifdef PS2_AUDIO_PATHS
strcpy(filename, m_szCDRomRootPath);
- strcat(filename, StreamedNameTable[nFile]);
-
+ strcat(filename, PS2StreamedNameTable[nFile]);
+
mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ if ( !mp3Stream[nStream] )
+#endif
+ {
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ }
if ( mp3Stream[nStream] )
{
AIL_set_stream_loop_count(mp3Stream[nStream], 1);
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
index fdd449f7..17776347 100644
--- a/src/audio/sampman_oal.cpp
+++ b/src/audio/sampman_oal.cpp
@@ -894,7 +894,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();
@@ -991,7 +995,7 @@ cSampleManager::Initialise(void)
int32 randval;
if ( bUseRandomTable )
- randval = AudioManager.GetRandomNumber(1);
+ randval = AudioManager.m_anRandomTable[1];
else
randval = localtm->tm_sec * localtm->tm_min;
@@ -1002,7 +1006,7 @@ cSampleManager::Initialise(void)
randmp3 = randmp3->pNext;
if ( bUseRandomTable )
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ _CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
else
{
if ( localtm->tm_sec > 0 )
@@ -1011,7 +1015,7 @@ cSampleManager::Initialise(void)
_CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
}
else
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ _CurMP3Pos = AudioManager.m_anRandomTable[0] % randmp3->nTrackLength;
}
}
else
@@ -1356,12 +1360,12 @@ bool8 cSampleManager::UpdateReverb(void)
if ( !usingEAX && !_usingEFX )
return FALSE;
- if ( AudioManager.GetFrameCounter() & 15 )
+ if ( AudioManager.m_FrameCounter & 15 )
return FALSE;
- float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
- float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
- float z = AudioManager.GetReflectionsDistance(REFLECTION_UP);
+ float y = AudioManager.m_afReflectionsDistances[REFLECTION_TOP] + AudioManager.m_afReflectionsDistances[REFLECTION_BOTTOM];
+ float x = AudioManager.m_afReflectionsDistances[REFLECTION_LEFT] + AudioManager.m_afReflectionsDistances[REFLECTION_RIGHT];
+ float z = AudioManager.m_afReflectionsDistances[REFLECTION_UP];
float normy = norm(y, 5.0f, 40.0f);
float normx = norm(x, 5.0f, 40.0f);
@@ -1601,8 +1605,6 @@ cSampleManager::StopChannel(uint32 nChannel)
void
cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
{
- char filename[MAX_PATH];
-
ASSERT( nStream < MAX_STREAMS );
if ( nFile < TOTAL_STREAMED_SOUNDS )
@@ -1611,9 +1613,10 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 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();
@@ -1673,10 +1676,11 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
// Try to continue from previous song, if already started
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() ) {
if (position != 0)
stream->SetPosMS(position);
@@ -1725,10 +1729,11 @@ cSampleManager::StartStreamedFile(uint8 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()) {
if (position != 0)
@@ -1768,11 +1773,11 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
position = 0;
nFile = 0;
}
- strcpy(filename, StreamedNameTable[nFile]);
-
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() ) {
if (position != 0)
diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp
index 22a73179..5af4071a 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -50,41 +50,41 @@ 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(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);
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);
- 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);
+ 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)
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index 0516e214..35580053 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -77,7 +77,7 @@ int32 CCarCtrl::NumRandomCars;
int32 CCarCtrl::NumParkedCars;
int32 CCarCtrl::NumPermanentCars;
int8 CCarCtrl::CountDownToCarsAtStart;
-int32 CCarCtrl::MaxNumberOfCarsInUse = 12;
+int32 CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS;
uint32 CCarCtrl::LastTimeLawEnforcerCreated;
uint32 CCarCtrl::LastTimeFireTruckCreated;
uint32 CCarCtrl::LastTimeAmbulanceCreated;
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 3410c881..245e961d 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -26,13 +26,6 @@
#include "World.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)
@@ -1883,11 +1876,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())
m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType;
}
@@ -1936,11 +1930,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;
}
@@ -2312,6 +2306,9 @@ void CGarages::Save(uint8 * buf, uint32 * size)
#else
* size = 5484;
#endif
+#if !defined THIS_IS_STUPID && !defined FIX_GARAGE_SIZE && defined COMPATIBLE_SAVES
+ memset(buf + 5240, 0, *size - 5240); // garbage data is written otherwise
+#endif
CloseHideOutGaragesBeforeSave();
WriteSaveBuf(buf, NumGarages);
WriteSaveBuf(buf, (uint32)BombsAreFree);
@@ -2327,8 +2324,47 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, aCarsInSafeHouse2[i]);
WriteSaveBuf(buf, aCarsInSafeHouse3[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].field_2);
+ WriteSaveBuf(buf, aGarages[i].m_bClosingWithoutTargetCar);
+ WriteSaveBuf(buf, aGarages[i].m_bDeactivated);
+ WriteSaveBuf(buf, aGarages[i].m_bResprayHappened);
+ ZeroSaveBuf(buf, 2);
+ 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_fX1);
+ WriteSaveBuf(buf, aGarages[i].m_fX2);
+ WriteSaveBuf(buf, aGarages[i].m_fY1);
+ WriteSaveBuf(buf, aGarages[i].m_fY2);
+ WriteSaveBuf(buf, aGarages[i].m_fZ1);
+ WriteSaveBuf(buf, aGarages[i].m_fZ2);
+ 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 + 4);
+ ZeroSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
+#else
WriteSaveBuf(buf, aGarages[i]);
+#endif
+ }
#ifdef FIX_GARAGE_SIZE
VALIDATESAVEBUF(*size);
#endif
@@ -2339,11 +2375,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;
@@ -2357,7 +2389,7 @@ void CGarages::Load(uint8* buf, uint32 size)
{
#ifdef FIX_GARAGE_SIZE
INITSAVEBUF
- assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
+ assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)));
#else
assert(size == 5484);
#endif
@@ -2380,7 +2412,45 @@ void CGarages::Load(uint8* buf, uint32 size)
ReadSaveBuf(&aCarsInSafeHouse3[i], buf);
}
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].field_2, buf);
+ ReadSaveBuf(&aGarages[i].m_bClosingWithoutTargetCar, buf);
+ ReadSaveBuf(&aGarages[i].m_bDeactivated, buf);
+ ReadSaveBuf(&aGarages[i].m_bResprayHappened, buf);
+ SkipSaveBuf(buf, 2);
+ 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_fX1, buf);
+ ReadSaveBuf(&aGarages[i].m_fX2, buf);
+ ReadSaveBuf(&aGarages[i].m_fY1, buf);
+ ReadSaveBuf(&aGarages[i].m_fY2, buf);
+ ReadSaveBuf(&aGarages[i].m_fZ1, buf);
+ ReadSaveBuf(&aGarages[i].m_fZ2, 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 + 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;
diff --git a/src/control/Garages.h b/src/control/Garages.h
index a7dfa462..8a9fd1b6 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -51,14 +51,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;
@@ -78,6 +81,13 @@ VALIDATE_SIZE(CStoredCar, 0x28);
#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
+#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)
+
class CGarage
{
public:
@@ -87,7 +97,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;
diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp
index f9cb1421..7632cfa3 100644
--- a/src/control/Phones.cpp
+++ b/src/control/Phones.cpp
@@ -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
@@ -209,6 +215,22 @@ CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
return pPhoneDisplayingMessages == &m_aPhones[phoneId];
}
+#ifdef COMPATIBLE_SAVES
+static inline void
+LoadPhone(CPhone &phone, uint8 *&buf)
+{
+ ReadSaveBuf(&phone.m_vecPos, buf);
+ SkipSaveBuf(buf, 6 * 4);
+ ReadSaveBuf<uint32>(&phone.m_repeatedMessagePickupStart, buf);
+ uint32 tmp;
+ ReadSaveBuf(&tmp, buf);
+ phone.m_pEntity = (CEntity*)(uintptr)tmp;
+ ReadSaveBuf<PhoneState>(&phone.m_nState, buf);
+ ReadSaveBuf<bool>(&phone.m_visibleToCam, buf);
+ SkipSaveBuf(buf, 3);
+}
+#endif
+
void
CPhoneInfo::Load(uint8 *buf, uint32 size)
{
@@ -226,7 +248,12 @@ INITSAVEBUF
// We can do it without touching saves. We'll only load script phones, others are already loaded in Initialise
for (int i = 0; i < 50; i++) {
CPhone phoneToLoad;
+#ifdef COMPATIBLE_SAVES
+ phoneToLoad.m_apMessages[0]=phoneToLoad.m_apMessages[1]=phoneToLoad.m_apMessages[2]=phoneToLoad.m_apMessages[3]=phoneToLoad.m_apMessages[4]=phoneToLoad.m_apMessages[5] = nil;
+ LoadPhone(phoneToLoad, buf);
+#else
ReadSaveBuf(&phoneToLoad, buf);
+#endif
if (ignoreOtherPhones)
continue;
@@ -252,7 +279,11 @@ INITSAVEBUF
m_nScriptPhonesMax = scriptPhonesMax;
for (int i = 0; i < NUMPHONES; i++) {
+#ifdef COMPATIBLE_SAVES
+ LoadPhone(m_aPhones[i], buf);
+#else
ReadSaveBuf(&m_aPhones[i], buf);
+#endif
// 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);
@@ -376,7 +407,7 @@ 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);
@@ -385,12 +416,24 @@ INITSAVEBUF
#else
for (int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
#endif
+#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)
}
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index 10175fba..8d3472ea 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -32,6 +32,12 @@
#include "WaterLevel.h"
#include "World.h"
+#ifdef COMPATIBLE_SAVES
+#define PICKUPS_SAVE_SIZE 0x24C0
+#else
+#define PICKUPS_SAVE_SIZE sizeof(aPickUps)
+#endif
+
CPickup CPickups::aPickUps[NUMPICKUPS];
int16 CPickups::NumMessages;
int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
@@ -1000,10 +1006,23 @@ CPickups::Load(uint8 *buf, uint32 size)
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
+#ifdef COMPATIBLE_SAVES
+ ReadSaveBuf(&aPickUps[i].m_eType, buf);
+ ReadSaveBuf(&aPickUps[i].m_bRemoved, buf);
+ ReadSaveBuf(&aPickUps[i].m_nQuantity, buf);
+ int32 tmp;
+ ReadSaveBuf(&tmp, buf);
+ aPickUps[i].m_pObject = aPickUps[i].m_eType != PICKUP_NONE && tmp != 0 ? CPools::GetObjectPool()->GetSlot(tmp - 1) : nil;
+ ReadSaveBuf(&aPickUps[i].m_nTimer, buf);
+ ReadSaveBuf(&aPickUps[i].m_eModelIndex, buf);
+ ReadSaveBuf(&aPickUps[i].m_nIndex, buf);
+ ReadSaveBuf(&aPickUps[i].m_vecPos, buf);
+#else
ReadSaveBuf(&aPickUps[i], buf);
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1);
+#endif
}
ReadSaveBuf(&CollectedPickUpIndex, buf);
@@ -1019,14 +1038,26 @@ VALIDATESAVEBUF(size)
void
CPickups::Save(uint8 *buf, uint32 *size)
{
- *size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
+ *size = PICKUPS_SAVE_SIZE + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
+#ifdef COMPATIBLE_SAVES
+ WriteSaveBuf(buf, aPickUps[i].m_eType);
+ WriteSaveBuf(buf, aPickUps[i].m_bRemoved);
+ WriteSaveBuf(buf, aPickUps[i].m_nQuantity);
+ 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);
+ WriteSaveBuf(buf, aPickUps[i].m_nTimer);
+ WriteSaveBuf(buf, aPickUps[i].m_eModelIndex);
+ WriteSaveBuf(buf, aPickUps[i].m_nIndex);
+ WriteSaveBuf(buf, aPickUps[i].m_vecPos);
+#else
CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil)
buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pObject) + 1);
+#endif
}
WriteSaveBuf(buf, CollectedPickUpIndex);
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index e06acdc3..b07c0701 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -1771,20 +1771,12 @@ int scriptToLoad = 0;
int open_script()
{
- // glfwGetKey doesn't work because of CGame::Initialise is blocking
- CPad::UpdatePads();
- if (CPad::GetPad(0)->GetChar('G'))
- scriptToLoad = 0;
- if (CPad::GetPad(0)->GetChar('R'))
- scriptToLoad = 1;
- if (CPad::GetPad(0)->GetChar('D'))
- scriptToLoad = 2;
switch (scriptToLoad) {
- case 0: return CFileMgr::OpenFile("main.scm", "rb");
- case 1: return CFileMgr::OpenFile("main_freeroam.scm", "rb");
- case 2: return CFileMgr::OpenFile("main_d.scm", "rb");
+ case 0: return CFileMgr::OpenFile("data\\main.scm", "rb");
+ case 1: return CFileMgr::OpenFile("data\\main_freeroam.scm", "rb");
+ case 2: return CFileMgr::OpenFile("data\\main_d.scm", "rb");
}
- return CFileMgr::OpenFile("main.scm", "rb");
+ return CFileMgr::OpenFile("data\\main.scm", "rb");
}
#endif
@@ -1800,10 +1792,16 @@ void CTheScripts::Init()
MissionCleanUp.Init();
UpsideDownCars.Init();
StuckCars.Init();
- CFileMgr::SetDir("data");
#ifdef USE_DEBUG_SCRIPT_LOADER
+ // glfwGetKey doesn't work because of CGame::Initialise is blocking
+ CPad::UpdatePads();
+ if(CPad::GetPad(0)->GetChar('G')) scriptToLoad = 0;
+ if(CPad::GetPad(0)->GetChar('R')) scriptToLoad = 1;
+ if(CPad::GetPad(0)->GetChar('D')) scriptToLoad = 2;
+
int mainf = open_script();
#else
+ CFileMgr::SetDir("data");
int mainf = CFileMgr::OpenFile("main.scm", "rb");
#endif
CFileMgr::Read(mainf, (char*)ScriptSpace, SIZE_MAIN_SCRIPT);
@@ -4392,7 +4390,11 @@ CTheScripts::SwitchToMission(int32 mission)
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[mission];
CFileMgr::ChangeDir("\\");
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ int handle = open_script();
+#else
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
+#endif
CFileMgr::Seek(handle, offset, 0);
CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT);
CFileMgr::CloseFile(handle);
diff --git a/src/control/Script.h b/src/control/Script.h
index 5682024b..cefd6747 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -591,5 +591,6 @@ void RetryMission(int, int);
#endif
#ifdef USE_DEBUG_SCRIPT_LOADER
+int open_script();
extern int scriptToLoad;
#endif \ No newline at end of file
diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp
index a9aec18e..953a1f50 100644
--- a/src/control/Script5.cpp
+++ b/src/control/Script5.cpp
@@ -2089,33 +2089,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_bCondResult);
- WriteSaveBuf<bool>(buf, m_bIsMissionScript);
- WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
- SkipSaveBuf(buf, 1);
- 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_bCondResult);
+ WriteSaveBuf(buf, m_bIsMissionScript);
+ WriteSaveBuf(buf, m_bSkipWakeTime);
+ ZeroSaveBuf(buf, 1);
+ 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
diff --git a/src/control/Script6.cpp b/src/control/Script6.cpp
index 31be6987..c9b2b070 100644
--- a/src/control/Script6.cpp
+++ b/src/control/Script6.cpp
@@ -305,7 +305,11 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
CFileMgr::ChangeDir("\\");
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ int handle = open_script();
+#else
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
+#endif
CFileMgr::Seek(handle, offset, 0);
CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT);
CFileMgr::CloseFile(handle);
diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp
index 984b21bb..8b184622 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -396,7 +396,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();
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 7ff80697..ecb893b4 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -336,6 +336,7 @@ const char* MenuFilenames[][2] = {
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \
CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+// value must be between 0.0-1.0
#define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \
do { \
lastActiveBarX = DisplaySlider(MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
@@ -489,7 +490,7 @@ CMenuManager::ThingsToDoBeforeGoingBack()
option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
if (option.m_Action == MENUACTION_CFO_SELECT && option.m_CFOSelect->onlyApplyOnEnter && option.m_CFOSelect->lastSavedValue != option.m_CFOSelect->displayedValue)
- option.m_CFOSelect->displayedValue = *option.m_CFO->value = option.m_CFOSelect->lastSavedValue;
+ option.m_CFOSelect->displayedValue = *(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue;
if (aScreens[m_nCurrScreen].returnPrevPageFunc) {
aScreens[m_nCurrScreen].returnPrevPageFunc();
@@ -898,29 +899,29 @@ CMenuManager::CheckSliderMovement(int value)
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_BRIGHTNESS:
- m_PrefsBrightness += value * (512/16);
+ m_PrefsBrightness += value * (512/MENUSLIDER_LOGICAL_BARS);
m_PrefsBrightness = Clamp(m_PrefsBrightness, 0, 511);
break;
case MENUACTION_DRAWDIST:
if(value > 0)
- m_PrefsLOD += ((1.8f - 0.8f) / 16.0f);
+ m_PrefsLOD += ((1.8f - 0.8f) / MENUSLIDER_LOGICAL_BARS);
else
- m_PrefsLOD -= ((1.8f - 0.8f) / 16.0f);
+ m_PrefsLOD -= ((1.8f - 0.8f) / MENUSLIDER_LOGICAL_BARS);
m_PrefsLOD = Clamp(m_PrefsLOD, 0.8f, 1.8f);
CRenderer::ms_lodDistScale = m_PrefsLOD;
break;
case MENUACTION_MUSICVOLUME:
- m_PrefsMusicVolume += value * (128/16);
+ m_PrefsMusicVolume += value * (128/MENUSLIDER_LOGICAL_BARS);
m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 127);
DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
break;
case MENUACTION_SFXVOLUME:
- m_PrefsSfxVolume += value * (128/16);
+ m_PrefsSfxVolume += value * (128/MENUSLIDER_LOGICAL_BARS);
m_PrefsSfxVolume = Clamp(m_PrefsSfxVolume, 0, 127);
DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
break;
case MENUACTION_MOUSESENS:
- TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ???
+ TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
@@ -928,6 +929,20 @@ CMenuManager::CheckSliderMovement(int value)
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
#endif
break;
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case MENUACTION_CFO_SLIDER:
+ {
+ CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
+ float oldValue = *(float*)option.m_CFOSlider->value;
+ *(float*)option.m_CFOSlider->value += value * ((option.m_CFOSlider->max - option.m_CFOSlider->min) / MENUSLIDER_LOGICAL_BARS);
+ *(float*)option.m_CFOSlider->value = Clamp(*(float*)option.m_CFOSlider->value, option.m_CFOSlider->min, option.m_CFOSlider->max);
+
+ if (*(float*)option.m_CFOSlider->value != oldValue && option.m_CFOSlider->changeFunc)
+ option.m_CFOSlider->changeFunc(oldValue, *(float*)option.m_CFOSlider->value);
+
+ break;
+ }
+#endif
default:
return;
}
@@ -1001,10 +1016,10 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
int lastActiveBarX = 0;
float curBarX = 0.0f;
float spacing = SCREEN_SCALE_X(10.0f);
- for (int i = 0; i < 16; i++) {
- curBarX = i * rectSize/16.0f + x;
+ for (int i = 0; i < MENUSLIDER_BARS; i++) {
+ curBarX = i * rectSize/MENUSLIDER_BARS + x;
- if (i / 16.0f + 1 / 32.0f < progress) {
+ if (i / (float)MENUSLIDER_BARS + 1 / (MENUSLIDER_BARS * 2.f) < progress) {
color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255));
lastActiveBarX = curBarX;
} else
@@ -1012,7 +1027,7 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
maxBarHeight = Max(mostLeftBarSize, mostRightBarSize);
- float curBarFreeSpace = ((16 - i) * mostLeftBarSize + i * mostRightBarSize) / 16.0f;
+ float curBarFreeSpace = ((MENUSLIDER_BARS - i) * mostLeftBarSize + i * mostRightBarSize) / (float)MENUSLIDER_BARS;
float left = curBarX;
float top = y + maxBarHeight - curBarFreeSpace;
float right = spacing + curBarX;
@@ -1595,10 +1610,10 @@ CMenuManager::Draw()
// If that was previously selected option, restore it to default value.
// if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i)
- option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value;
+ option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
} else {
- if (option.m_CFOSelect->displayedValue != *option.m_CFO->value)
+ if (option.m_CFOSelect->displayedValue != *(int8*)option.m_CFO->value)
SetHelperText(1); // Enter to apply
else if (m_nHelperTextMsgId == 1)
ResetHelperText(); // Applied
@@ -1606,8 +1621,8 @@ CMenuManager::Draw()
}
// To whom manipulate option.m_CFO->value of select options externally (like RestoreDef functions)
- if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
- option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value;
+ if (*(int8*)option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
+ option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
option.m_CFOSelect->displayedValue = 0;
@@ -1799,6 +1814,12 @@ CMenuManager::Draw()
case MENUACTION_MOUSESENS:
ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, MENU_X_LEFT_ALIGNED(200.0f), SCREEN_WIDTH);
break;
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case MENUACTION_CFO_SLIDER:
+ CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i];
+ ProcessSlider((*(float*)option.m_CFOSlider->value - option.m_CFOSlider->min) / (option.m_CFOSlider->max - option.m_CFOSlider->min), HOVEROPTION_INCREASE_CFO_SLIDER, HOVEROPTION_DECREASE_CFO_SLIDER, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
+ break;
+#endif
}
// Needed after the bug fix in Font.cpp
@@ -4477,7 +4498,7 @@ CMenuManager::ProcessButtonPresses(void)
#ifndef TIDY_UP_PBP
switch (m_nHoverOption) {
case HOVEROPTION_INCREASE_BRIGHTNESS:
- m_PrefsBrightness = m_PrefsBrightness + 32;
+ m_PrefsBrightness = m_PrefsBrightness + (512 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsBrightness < 0) {
m_PrefsBrightness = 0;
}
@@ -4487,7 +4508,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_DECREASE_BRIGHTNESS:
- m_PrefsBrightness = m_PrefsBrightness - 32;
+ m_PrefsBrightness = m_PrefsBrightness - (512 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsBrightness < 0) {
m_PrefsBrightness = 0;
}
@@ -4497,25 +4518,25 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_INCREASE_DRAWDIST:
- m_PrefsLOD = m_PrefsLOD + (1.0f / 16);
+ m_PrefsLOD = m_PrefsLOD + (1.0f / MENUSLIDER_LOGICAL_BARS);
m_PrefsLOD = min(1.8f, m_PrefsLOD);
CRenderer::ms_lodDistScale = m_PrefsLOD;
SaveSettings();
break;
case HOVEROPTION_DECREASE_DRAWDIST:
- m_PrefsLOD = m_PrefsLOD - (1.0f / 16);
+ m_PrefsLOD = m_PrefsLOD - (1.0f / MENUSLIDER_LOGICAL_BARS);
m_PrefsLOD = max(0.8f, m_PrefsLOD);
CRenderer::ms_lodDistScale = m_PrefsLOD;
SaveSettings();
break;
case HOVEROPTION_INCREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume + 8;
+ m_PrefsMusicVolume = m_PrefsMusicVolume + (128 / MENUSLIDER_LOGICAL_BARS);
m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 127);
DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
SaveSettings();
break;
case HOVEROPTION_DECREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume - 8;
+ m_PrefsMusicVolume = m_PrefsMusicVolume - (128 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsMusicVolume < 0) {
m_PrefsMusicVolume = 0;
}
@@ -4526,7 +4547,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_INCREASE_SFXVOLUME:
- m_PrefsSFXVolume = m_PrefsSFXVolume + 8;
+ m_PrefsSFXVolume = m_PrefsSFXVolume + (128 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsSFXVolume < 0) {
m_PrefsSFXVolume = 0;
}
@@ -4537,7 +4558,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_DECREASE_SFXVOLUME:
- m_PrefsSFXVolume = m_PrefsSFXVolume - 8;
+ m_PrefsSFXVolume = m_PrefsSFXVolume - (128 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsSFXVolume < 0) {
m_PrefsSFXVolume = 0;
}
@@ -4548,7 +4569,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_INCREASE_MOUSESENS:
- TheCamera.m_fMouseAccelHorzntl += (1.0f / 3000);
+ TheCamera.m_fMouseAccelHorzntl += 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
@@ -4558,7 +4579,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_DECREASE_MOUSESENS:
- TheCamera.m_fMouseAccelHorzntl -= (1.0f / 3000);
+ TheCamera.m_fMouseAccelHorzntl -= 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
@@ -4575,6 +4596,9 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_INCREASE_MUSICVOLUME:
case HOVEROPTION_INCREASE_SFXVOLUME:
case HOVEROPTION_INCREASE_MOUSESENS:
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case HOVEROPTION_INCREASE_CFO_SLIDER:
+#endif
CheckSliderMovement(1);
break;
case HOVEROPTION_DECREASE_BRIGHTNESS:
@@ -4582,6 +4606,9 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_DECREASE_MUSICVOLUME:
case HOVEROPTION_DECREASE_SFXVOLUME:
case HOVEROPTION_DECREASE_MOUSESENS:
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case HOVEROPTION_DECREASE_CFO_SLIDER:
+#endif
CheckSliderMovement(-1);
break;
}
@@ -4612,7 +4639,11 @@ CMenuManager::ProcessButtonPresses(void)
|| CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp()
|| CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
- if (option == MENUACTION_BRIGHTNESS || option == MENUACTION_DRAWDIST)
+ if (option == MENUACTION_BRIGHTNESS || option == MENUACTION_DRAWDIST
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ || option == MENUACTION_CFO_SLIDER
+#endif
+ )
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
else if (option == MENUACTION_SFXVOLUME)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0);
@@ -4775,7 +4806,12 @@ CMenuManager::ProcessButtonPresses(void)
} else if (option != MENUACTION_CHANGEMENU && option != MENUACTION_BRIGHTNESS && option != MENUACTION_DRAWDIST
&& option != MENUACTION_MUSICVOLUME && option != MENUACTION_SFXVOLUME
&& option != MENUACTION_CHECKSAVE && option != MENUACTION_UNK24
- && option != MENUACTION_MOUSESENS && option != MENUACTION_SCREENRES) {
+ && option != MENUACTION_MOUSESENS && option != MENUACTION_SCREENRES
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ && option != MENUACTION_CFO_SLIDER
+#endif
+ )
+ {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
}
@@ -5166,9 +5202,9 @@ CMenuManager::ProcessButtonPresses(void)
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
option.m_CFOSelect->displayedValue = 0;
}
- int8 oldValue = *option.m_CFO->value;
+ int8 oldValue = *(int8*)option.m_CFO->value;
- *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
+ *(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
// if (option.m_CFOSelect->save)
@@ -5412,9 +5448,9 @@ CMenuManager::ProcessButtonPresses(void)
option.m_CFOSelect->displayedValue = option.m_CFOSelect->numRightTexts - 1;
}
if (!option.m_CFOSelect->onlyApplyOnEnter) {
- int8 oldValue = *option.m_CFO->value;
+ int8 oldValue = *(int8*)option.m_CFO->value;
- *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
+ *(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
// if (option.m_CFOSelect->save)
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 5c3523ab..32e5ef9d 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -25,6 +25,9 @@
#define MENUSLIDER_X 256.0f
#define MENUSLIDER_UNK 256.0f
+#define MENUSLIDER_BARS 16
+#define MENUSLIDER_LOGICAL_BARS MENUSLIDER_BARS
+
#define BIGTEXT_X_SCALE 0.75f // For FONT_HEADING
#define BIGTEXT_Y_SCALE 0.9f
#define MEDIUMTEXT_X_SCALE 0.55f // For FONT_HEADING
@@ -256,6 +259,7 @@ enum eMenuScreen
enum eMenuAction
{
#ifdef CUSTOM_FRONTEND_OPTIONS
+ MENUACTION_CFO_SLIDER = -3,
MENUACTION_CFO_SELECT = -2,
MENUACTION_CFO_DYNAMIC = -1,
#endif
@@ -424,6 +428,10 @@ enum eCheckHover
HOVEROPTION_DECREASE_SFXVOLUME,
HOVEROPTION_INCREASE_MOUSESENS,
HOVEROPTION_DECREASE_MOUSESENS,
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ HOVEROPTION_INCREASE_CFO_SLIDER,
+ HOVEROPTION_DECREASE_CFO_SLIDER,
+#endif
HOVEROPTION_NOT_HOVERING,
};
@@ -493,7 +501,7 @@ struct CCustomScreenLayout {
struct CCFO
{
- int8 *value;
+ void *value;
const char *saveCat;
const char *save;
};
@@ -524,6 +532,24 @@ struct CCFOSelect : CCFO
}
};
+// Value is float in here
+struct CCFOSlider : CCFO
+{
+ ChangeFuncFloat changeFunc;
+ float min;
+ float max;
+
+ CCFOSlider() {};
+ CCFOSlider(float* value, const char* saveCat, const char* save, float min, float max, ChangeFuncFloat changeFunc = nil){
+ this->value = value;
+ this->saveCat = saveCat;
+ this->save = save;
+ this->changeFunc = changeFunc;
+ this->min = min;
+ this->max = max;
+ }
+};
+
struct CCFODynamic : CCFO
{
DrawFunc drawFunc;
@@ -555,6 +581,7 @@ struct CMenuScreenCustom
CCFO *m_CFO; // for initializing
CCFOSelect *m_CFOSelect;
CCFODynamic *m_CFODynamic;
+ CCFOSlider *m_CFOSlider;
};
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index f6156a4c..b3dd1eda 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -409,7 +409,11 @@ bool CGame::Initialise(const char* datFile)
#endif
#ifndef GTA_PS2
- CIniFile::LoadIniFile();
+#ifdef PED_CAR_DENSITY_SLIDERS
+ // Load density values from gta3.ini only if our re3.ini have them 1.f
+ if (CIniFile::PedNumberMultiplier == 1.f && CIniFile::CarNumberMultiplier == 1.f)
+#endif
+ CIniFile::LoadIniFile();
#endif
currLevel = LEVEL_INDUSTRIAL;
diff --git a/src/core/IniFile.cpp b/src/core/IniFile.cpp
index df01b440..524632fe 100644
--- a/src/core/IniFile.cpp
+++ b/src/core/IniFile.cpp
@@ -23,6 +23,6 @@ void CIniFile::LoadIniFile()
CarNumberMultiplier = Min(3.0f, Max(0.5f, CarNumberMultiplier));
CFileMgr::CloseFile(f);
}
- CPopulation::MaxNumberOfPedsInUse = 25.0f * PedNumberMultiplier;
- CCarCtrl::MaxNumberOfCarsInUse = 12.0f * CarNumberMultiplier;
+ CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * PedNumberMultiplier;
+ CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * CarNumberMultiplier;
} \ No newline at end of file
diff --git a/src/core/IniFile.h b/src/core/IniFile.h
index 1e30c4de..30dc8c21 100644
--- a/src/core/IniFile.h
+++ b/src/core/IniFile.h
@@ -1,5 +1,8 @@
#pragma once
+#define DEFAULT_MAX_NUMBER_OF_PEDS 25.0f
+#define DEFAULT_MAX_NUMBER_OF_CARS 12.0f
+
class CIniFile
{
public:
diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp
index 6e23f76a..033ed9b9 100644
--- a/src/core/MenuScreensCustom.cpp
+++ b/src/core/MenuScreensCustom.cpp
@@ -26,6 +26,9 @@
#include "ModelInfo.h"
#include "Pad.h"
#include "ControllerConfig.h"
+#include "IniFile.h"
+#include "CarCtrl.h"
+#include "Population.h"
// Menu screens array is at the bottom of the file.
@@ -63,6 +66,15 @@
#define DUALPASS_SELECTOR
#endif
+#ifdef PED_CAR_DENSITY_SLIDERS
+ // 0.2f - 3.4f makes it possible to have 1.0f somewhere inbetween
+ #define DENSITY_SLIDERS \
+ MENUACTION_CFO_SLIDER, "FEM_PED", { new CCFOSlider(&CIniFile::PedNumberMultiplier, "Display", "PedDensity", 0.2f, 3.4f, PedDensityChange) }, \
+ MENUACTION_CFO_SLIDER, "FEM_CAR", { new CCFOSlider(&CIniFile::CarNumberMultiplier, "Display", "CarDensity", 0.2f, 3.4f, CarDensityChange) },
+#else
+ #define DENSITY_SLIDERS
+#endif
+
#ifdef NO_ISLAND_LOADING
#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
#else
@@ -145,6 +157,9 @@ void RestoreDefDisplay(int8 action) {
#ifdef FREE_CAM
TheCamera.bFreeCam = false;
#endif
+ #ifdef PED_CAR_DENSITY_SLIDERS
+ CIniFile::LoadIniFile();
+ #endif
#ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
CMenuManager::m_PrefsBrightness = 256;
CMenuManager::m_PrefsLOD = 1.2f;
@@ -195,6 +210,16 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
}
#endif
+#ifdef PED_CAR_DENSITY_SLIDERS
+void PedDensityChange(float before, float after) {
+ CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * after;
+}
+
+void CarDensityChange(float before, float after) {
+ CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * after;
+}
+#endif
+
#ifndef MULTISAMPLING
void GraphicsGoBack() {
}
@@ -423,6 +448,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
{ "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ DENSITY_SLIDERS
MENUACTION_FRAMESYNC, "FEM_VSC", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
#ifndef EXTENDED_COLOURFILTER
@@ -447,6 +473,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
{ "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ DENSITY_SLIDERS
CUTSCENE_BORDERS_TOGGLE
FREE_CAM_TOGGLE
MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index 5cffe9e4..b0248664 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -281,9 +281,9 @@ INITSAVEBUF
#else
if ((pVehicle->IsCar() || pVehicle->IsBoat()) && 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
@@ -292,7 +292,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));
@@ -303,7 +303,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));
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 107b1db8..82fbc047 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -10,6 +10,14 @@
#include "Timer.h"
#include "SaveBuf.h"
+#ifdef COMPATIBLE_SAVES
+#define ZONEARRAY_SAVE_SIZE 0xAF0
+#define MAPZONEARRAY_SAVE_SIZE 0x578
+#else
+#define ZONEARRAY_SAVE_SIZE sizeof(ZoneArray)
+#define MAPZONEARRAY_SAVE_SIZE sizeof(MapZoneArray)
+#endif
+
eLevelName CTheZones::m_CurrLevel;
CZone *CTheZones::m_pPlayersZone;
int16 CTheZones::FindIndex;
@@ -633,6 +641,28 @@ CTheZones::InitialiseAudioZoneArray(void)
}
}
+#ifdef COMPATIBLE_SAVES
+static inline void
+SaveOneZone(CZone &zone, uint8 *&buffer)
+{
+ memcpy(buffer, zone.name, sizeof(zone.name));
+ SkipSaveBuf(buffer, sizeof(zone.name));
+ WriteSaveBuf(buffer, zone.minx);
+ WriteSaveBuf(buffer, zone.miny);
+ WriteSaveBuf(buffer, zone.minz);
+ WriteSaveBuf(buffer, zone.maxx);
+ WriteSaveBuf(buffer, zone.maxy);
+ WriteSaveBuf(buffer, zone.maxz);
+ WriteSaveBuf(buffer, zone.type);
+ WriteSaveBuf(buffer, zone.level);
+ WriteSaveBuf(buffer, zone.zoneinfoDay);
+ WriteSaveBuf(buffer, zone.zoneinfoNight);
+ WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.child));
+ WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.parent));
+ WriteSaveBuf(buffer, (int32)CTheZones::GetIndexForZonePointer(zone.next));
+}
+#endif
+
void
CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
{
@@ -643,9 +673,9 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
+ sizeof(int32) // GetIndexForZonePointer
+ sizeof(m_CurrLevel) + sizeof(FindIndex)
+ sizeof(int16) // padding
- + sizeof(ZoneArray) + sizeof(ZoneInfoArray)
+ + ZONEARRAY_SAVE_SIZE + sizeof(ZoneInfoArray)
+ sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
- + sizeof(MapZoneArray) + sizeof(AudioZoneArray)
+ + MAPZONEARRAY_SAVE_SIZE + sizeof(AudioZoneArray)
+ sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
@@ -656,10 +686,14 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
WriteSaveBuf(buffer, (int16)0); // padding
for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
+#ifdef COMPATIBLE_SAVES
+ SaveOneZone(ZoneArray[i], buffer);
+#else
CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]);
zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child);
zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent);
zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next);
+#endif
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
@@ -669,7 +703,9 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
+#ifndef COMPATIBLE_SAVES
CZone* zone = WriteSaveBuf(buffer, MapZoneArray[i]);
+#endif
/*
The call of GetIndexForZonePointer is wrong, as it is
@@ -679,9 +715,13 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
assert(MapZoneArray[i].child == nil);
assert(MapZoneArray[i].parent == nil);
assert(MapZoneArray[i].next == nil);
+#ifndef COMPATIBLE_SAVES
zone->child = (CZone*)GetIndexForZonePointer(MapZoneArray[i].child);
zone->parent = (CZone*)GetIndexForZonePointer(MapZoneArray[i].parent);
zone->next = (CZone*)GetIndexForZonePointer(MapZoneArray[i].next);
+#else
+ SaveOneZone(MapZoneArray[i], buffer);
+#endif
}
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
@@ -693,6 +733,32 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
VALIDATESAVEBUF(*size)
}
+#ifdef COMPATIBLE_SAVES
+static inline void
+LoadOneZone(CZone &zone, uint8 *&buffer)
+{
+ memcpy(zone.name, buffer, sizeof(zone.name));
+ SkipSaveBuf(buffer, sizeof(zone.name));
+ ReadSaveBuf(&zone.minx, buffer);
+ ReadSaveBuf(&zone.miny, buffer);
+ ReadSaveBuf(&zone.minz, buffer);
+ ReadSaveBuf(&zone.maxx, buffer);
+ ReadSaveBuf(&zone.maxy, buffer);
+ ReadSaveBuf(&zone.maxz, buffer);
+ ReadSaveBuf(&zone.type, buffer);
+ ReadSaveBuf(&zone.level, buffer);
+ ReadSaveBuf(&zone.zoneinfoDay, buffer);
+ ReadSaveBuf(&zone.zoneinfoNight, buffer);
+ int32 tmp;
+ ReadSaveBuf(&tmp, buffer);
+ zone.child = CTheZones::GetPointerForZoneIndex(tmp);
+ ReadSaveBuf(&tmp, buffer);
+ zone.parent = CTheZones::GetPointerForZoneIndex(tmp);
+ ReadSaveBuf(&tmp, buffer);
+ zone.next = CTheZones::GetPointerForZoneIndex(tmp);
+}
+#endif
+
void
CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{
@@ -708,11 +774,15 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
SkipSaveBuf(buffer, 2);
for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
+#ifdef COMPATIBLE_SAVES
+ LoadOneZone(ZoneArray[i], buffer);
+#else
ReadSaveBuf(&ZoneArray[i], buffer);
ZoneArray[i].child = GetPointerForZoneIndex((uintptr)ZoneArray[i].child);
ZoneArray[i].parent = GetPointerForZoneIndex((uintptr)ZoneArray[i].parent);
ZoneArray[i].next = GetPointerForZoneIndex((uintptr)ZoneArray[i].next);
+#endif
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
@@ -722,6 +792,9 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
ReadSaveBuf(&TotalNumberOfZoneInfos, buffer);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
+#ifdef COMPATIBLE_SAVES
+ LoadOneZone(MapZoneArray[i], buffer);
+#else
ReadSaveBuf(&MapZoneArray[i], buffer);
/*
@@ -732,6 +805,7 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
MapZoneArray[i].child = GetPointerForZoneIndex((uintptr)MapZoneArray[i].child);
MapZoneArray[i].parent = GetPointerForZoneIndex((uintptr)MapZoneArray[i].parent);
MapZoneArray[i].next = GetPointerForZoneIndex((uintptr)MapZoneArray[i].next);
+#endif
assert(MapZoneArray[i].child == nil);
assert(MapZoneArray[i].parent == nil);
assert(MapZoneArray[i].next == nil);
diff --git a/src/core/config.h b/src/core/config.h
index 298b2a1a..2abaec13 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -1,7 +1,9 @@
#pragma once
-// disables (most) stuff that wasn't in original gta3.exe - check section at the bottom of this file
-//#define VANILLA_DEFINES
+// disables (most) stuff that wasn't in original gta3.exe
+#ifdef __MWERKS__
+#define VANILLA_DEFINES
+#endif
enum Config {
NUMPLAYERS = 1, // 4 on PS2
@@ -11,7 +13,7 @@ enum Config {
MAX_CDCHANNELS = 5,
MODELINFOSIZE = 5500, // 3150 on PS2
-#if defined __MWERKS__ || defined VANILLA_DEFINES
+#ifdef VANILLA_DEFINES
TXDSTORESIZE = 850,
#else
TXDSTORESIZE = 1024, // for Xbox map
@@ -146,8 +148,30 @@ enum Config {
//#define GTA_PS2
//#define GTA_XBOX
-// This enables things from the PS2 version on PC
-#define GTA_PS2_STUFF
+// Version defines
+#define GTA3_PS2_140 300
+#define GTA3_PS2_160 301
+#define GTA3_PC_10 310
+#define GTA3_PC_11 311
+#define GTA3_PC_STEAM 312
+// TODO? maybe something for xbox or android?
+
+#define GTA_VERSION GTA3_PC_11
+
+#if defined GTA_PS2
+# define GTA_PS2_STUFF
+# define RANDOMSPLASH
+# define USE_CUSTOM_ALLOCATOR
+# define VU_COLLISION
+# define ANIM_COMPRESSION
+# 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
+#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
@@ -166,19 +190,29 @@ enum Config {
#define FINAL
#endif
-// Version defines
-#define GTA3_PS2_140 300
-#define GTA3_PS2_160 301
-#define GTA3_PC_10 310
-#define GTA3_PC_11 311
-#define GTA3_PC_STEAM 312
-// 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 GTA3_PC_11
+#ifdef VANILLA_DEFINES
+#if !defined(_WIN32) || defined(__LP64__) || defined(_WIN64)
+#error Vanilla can only be built for win-x86
+#endif
+
+#define FINAL
+#define MASTER
+//#define USE_MY_DOCUMENTS
+#define THIS_IS_STUPID
+#define PC_PARTICLE
+#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
@@ -194,22 +228,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
-# define ANIM_COMPRESSION
-#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
@@ -237,7 +259,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, needs to be enabled on 64bit builds!
+#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
@@ -248,7 +271,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
@@ -340,6 +363,7 @@ enum Config {
# define CUTSCENE_BORDERS_SWITCH
# define MULTISAMPLING // adds MSAA option
# define INVERT_LOOK_FOR_PAD // add bInvertLook4Pad from VC
+# define PED_CAR_DENSITY_SLIDERS
# endif
#endif
@@ -385,7 +409,7 @@ enum Config {
// #define VC_PED_PORTS // various ports from VC's CPed, mostly subtle
// #define NEW_WALK_AROUND_ALGORITHM // to make walking around vehicles/objects less awkward
#define CANCELLABLE_CAR_ENTER
-//#define PEDS_REPORT_CRIMES_ON_PHONE, requires COMPATIBLE_SAVES
+//#define PEDS_REPORT_CRIMES_ON_PHONE // requires COMPATIBLE_SAVES
// Camera
//#define PS2_CAM_TRANSITION // old way of transitioning between cam modes
@@ -396,7 +420,7 @@ enum Config {
#define RADIO_SCROLL_TO_PREV_STATION
#define AUDIO_CACHE
#define PS2_AUDIO_CHANNELS // increases the maximum number of audio channels to PS2 value of 44 (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 PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused
@@ -437,101 +461,4 @@ enum Config {
#undef PEDS_REPORT_CRIMES_ON_PHONE
#endif
-// -------
-
-#if defined __MWERKS__ || defined VANILLA_DEFINES
-#define FINAL
-#undef CHATTYSPLASH
-#undef TIMEBARS
-//#define USE_MY_DOCUMENTS
-
-#define MASTER
-#undef VALIDATE_SAVE_SIZE
-#undef NO_MOVIES
-#undef DEBUGMENU
-
-//#undef NASTY_GAME
-//#undef NO_CDCHECK
-
-#undef DRAW_GAME_VERSION_TEXT
-#undef DRAW_MENU_VERSION_TEXT
-
-#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 ANISOTROPIC_FILTERING
-//#define USE_TEXTURE_POOL // not possible because R* used custom RW33
-
-#undef EXTENDED_COLOURFILTER
-#undef EXTENDED_PIPELINES
-#undef SCREEN_DROPLETS
-#undef NEW_RENDERER
-
-#undef FIX_SPRITES
-
-#define PC_PARTICLE
-
-#undef XINPUT
-#undef DETECT_PAD_INPUT_SWITCH
-#undef KANGAROO_CHEAT
-#undef ALLCARSHELI_CHEAT
-#undef ALT_DODO_CHEAT
-#undef REGISTER_START_BUTTON
-#undef BIND_VEHICLE_FIREWEAPON
-#undef BUTTON_ICONS
-
-#undef HUD_ENHANCEMENTS
-#undef TRIANGULAR_BLIPS
-#undef FIX_RADAR
-#undef RADIO_OFF_TEXT
-
-#undef MENU_MAP
-#undef GAMEPAD_MENU
-#undef SCROLLABLE_STATS_PAGE
-#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 MISSION_REPLAY
-#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
-#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
-
-#define DONT_FIX_REPLAY_BUGS
-
-#undef EXPLODING_AIRTRAIN
-#undef CAMERA_PICKUP
-#undef PED_SKIN
-#undef ANIMATE_PED_COL_MODEL
-#undef CANCELLABLE_CAR_ENTER
-#undef IMPROVED_CAMERA
-#undef FREE_CAM
-
-#undef RADIO_SCROLL_TO_PREV_STATION
-#undef AUDIO_CACHE
-#undef PS2_AUDIO_CHANNELS
-#undef PAUSE_RADIO_IN_FRONTEND
-#undef MULTITHREADED_AUDIO
-#undef BIG_IMG
-#endif
+#endif // VANILLA_DEFINES
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index fe0347d9..b7d89363 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -41,6 +41,9 @@
#include "Camera.h"
#include "MBlur.h"
#include "ControllerConfig.h"
+#include "CarCtrl.h"
+#include "Population.h"
+#include "IniFile.h"
#ifdef DETECT_JOYSTICK_MENU
#include "crossplatform.h"
@@ -179,16 +182,29 @@ CustomFrontendOptionsPopulate(void)
#endif
#ifdef LOAD_INI_SETTINGS
-#include "ini_parser.hpp"
+#define MINI_CASE_SENSITIVE
+#include "ini.h"
+
+mINI::INIFile ini("re3.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;
@@ -196,11 +212,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;
@@ -208,11 +223,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;
@@ -220,11 +234,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;
@@ -232,10 +245,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;
@@ -243,10 +256,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;
@@ -254,42 +267,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];
+ char temp[11];
sprintf(temp, "%u", val);
- cfg.set(cat, key, temp);
+ 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",
@@ -351,7 +364,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++) {
@@ -453,12 +466,13 @@ void SaveINIControllerSettings()
#endif
#endif
StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited);
- cfg.write_file("re3.ini");
+
+ ini.write(cfg);
}
bool LoadINISettings()
{
- if (!cfg.load_file("re3.ini"))
+ if (!ini.read(cfg))
return false;
#ifdef IMPROVED_VIDEOMODE
@@ -524,7 +538,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];
@@ -533,22 +547,29 @@ bool LoadINISettings()
// CFO check
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
- // CFO only supports saving uint8 right now
-
// 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);
+ // Old values can only be int8, new ones can contain float if it is slider
+ if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, (int8*)option.m_CFO->value))
+ cfg["FrontendOptions"].remove(option.m_CFO->save);
+ else if (option.m_Action == MENUACTION_CFO_SLIDER)
+ ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, (float*)option.m_CFO->value);
else
- ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value);
+ ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, (int8*)option.m_CFO->value);
if (option.m_Action == MENUACTION_CFO_SELECT) {
- option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value;
+ option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *(int8*)option.m_CFO->value;
}
}
}
}
#endif
+ // Fetched in above block, but needs evaluation
+#ifdef PED_CAR_DENSITY_SLIDERS
+ CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS * CIniFile::PedNumberMultiplier;
+ CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS * CIniFile::CarNumberMultiplier;
+#endif
+
return true;
}
@@ -623,14 +644,16 @@ void SaveINISettings()
break;
if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
- // Beware: CFO only supports saving uint8 right now
- StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *option.m_CFO->value);
+ if (option.m_Action == MENUACTION_CFO_SLIDER)
+ StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *(float*)option.m_CFO->value);
+ else
+ StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *(int8*)option.m_CFO->value);
}
}
}
#endif
- cfg.write_file("re3.ini");
+ ini.write(cfg);
}
#endif
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index a7f4bd45..c38f12c7 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -732,7 +732,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
if (bZoneCulled) tmp |= BIT(30);
if (bZoneCulled2) tmp |= BIT(31);
- WriteSaveBuf<uint32>(buf, tmp);
+ WriteSaveBuf(buf, tmp);
tmp = 0;
@@ -748,7 +748,7 @@ CEntity::SaveEntityFlags(uint8*& buf)
if (bDistanceFade) tmp |= BIT(8);
if (m_flagE2) tmp |= BIT(9);
- WriteSaveBuf<uint32>(buf, tmp);
+ WriteSaveBuf(buf, tmp);
}
void
diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h
index 8b64335a..a571170f 100644
--- a/src/extras/frontendoption.h
+++ b/src/extras/frontendoption.h
@@ -40,6 +40,8 @@ typedef void (*ReturnPrevPageFunc)();
typedef void (*ChangeFunc)(int8 before, int8 after); // called after updating the value.
// only called on enter if onlyApplyOnEnter set, otherwise called on every value change
+typedef void (*ChangeFuncFloat)(float before, float after); // called after updating the value.
+
// for dynamic options
typedef wchar* (*DrawFunc)(bool* disabled, bool userHovering); // you must return a pointer for right text.
// you can also set *disabled if you want to gray it out.
diff --git a/src/extras/ini.h b/src/extras/ini.h
new file mode 100644
index 00000000..44dd3d57
--- /dev/null
+++ b/src/extras/ini.h
@@ -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_
diff --git a/src/extras/ini_parser.hpp b/src/extras/ini_parser.hpp
deleted file mode 100644
index 7bea024c..00000000
--- a/src/extras/ini_parser.hpp
+++ /dev/null
@@ -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
-
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index 211a568c..5d480ecc 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -10,6 +10,12 @@
#include "DMAudio.h"
#include "screendroplets.h"
+#ifdef COMPATIBLE_SAVES
+#define PARTICLE_OBJECT_SIZEOF 0x88
+#else
+#define PARTICLE_OBJECT_SIZEOF sizeof(CParticleObject)
+#endif
+
CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
@@ -1111,6 +1117,49 @@ 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
+ {
+ ZeroBuf(buffer, 4);
+ 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)
{
@@ -1128,27 +1177,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 != NULL; 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 != NULL; 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;
@@ -1166,7 +1223,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 )
@@ -1177,14 +1234,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 == NULL )
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;
@@ -1200,6 +1260,47 @@ 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
+ {
+ SkipBuf(buffer, 4);
+ 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++;
}
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 5a72f288..3ccae5d0 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -326,6 +326,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++;
@@ -1359,6 +1360,9 @@ CPed::CalculateNewVelocity(void)
limitedRotDest -= 2 * PI;
}
+#ifdef FREE_CAM
+ if (!TheCamera.Cams[0].Using3rdPersonMouseCam())
+#endif
if (IsPlayer() && m_nPedState == PED_ATTACK)
headAmount /= 4.0f;
@@ -2485,12 +2489,12 @@ CPed::ProcessControl(void)
obstacleForFlyingOtherDirZ = 501.0f;
}
#ifdef VC_PED_PORTS
- uint8 flyDir = 0;
+ int16 flyDir = 0;
float feetZ = GetPosition().z - FEET_OFFSET;
#ifdef FIX_BUGS
- if (obstacleForFlyingZ > feetZ && obstacleForFlyingOtherDirZ < 501.0f)
+ if (obstacleForFlyingZ > feetZ && obstacleForFlyingZ < 500.0f)
flyDir = 1;
- else if (obstacleForFlyingOtherDirZ > feetZ && obstacleForFlyingZ < 500.0f)
+ else if (obstacleForFlyingOtherDirZ > feetZ && obstacleForFlyingOtherDirZ < 501.0f)
flyDir = 2;
#else
if ((obstacleForFlyingZ > feetZ && obstacleForFlyingOtherDirZ < 500.0f) || (obstacleForFlyingZ > feetZ && obstacleForFlyingOtherDirZ > feetZ))
@@ -2499,8 +2503,8 @@ CPed::ProcessControl(void)
flyDir = 2;
#endif
- if (flyDir != 0 && !bSomeVCflag1) {
- SetPosition((flyDir == 2 ? obstacleForFlyingOtherDir.point : obstacleForFlying.point));
+ if (flyDir > 0 && !bSomeVCflag1) {
+ GetMatrix().SetTranslateOnly((flyDir == 2 ? obstacleForFlyingOtherDir.point : obstacleForFlying.point));
GetMatrix().GetPosition().z += FEET_OFFSET;
GetMatrix().UpdateRW();
SetLanding();
@@ -3199,7 +3203,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
lowerSpeedLimit *= 1.5f;
}
CAnimBlendAssociation *fallAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_STD_FALL);
- if (!bWasStanding && speed > upperSpeedLimit && (/*!bPushedAlongByCar ||*/ m_vecMoveSpeed.z < lowerSpeedLimit)
+ if (!bWasStanding && ((speed > upperSpeedLimit /* ||!bPushedAlongByCar*/) || (m_vecMoveSpeed.z < lowerSpeedLimit))
&& m_pCollidingEntity != collidingEnt) {
float damage = 100.0f * Max(speed - 0.25f, 0.0f);
@@ -8508,21 +8512,21 @@ CPed::renderLimb(int node)
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, 351);
+ ZeroSaveBuf(buf, 351);
CopyToBuf(buf, m_fHealth);
CopyToBuf(buf, m_fArmour);
- SkipSaveBuf(buf, 148);
+ ZeroSaveBuf(buf, 148);
for (int i = 0; i < 13; i++) // has to be hardcoded
m_weapons[i].Save(buf);
- SkipSaveBuf(buf, 5);
+ ZeroSaveBuf(buf, 5);
CopyToBuf(buf, m_maxWeaponTypeAllowed);
- SkipSaveBuf(buf, 162);
+ ZeroSaveBuf(buf, 162);
}
void
diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp
index 46ac369c..13d3930c 100644
--- a/src/peds/PedFight.cpp
+++ b/src/peds/PedFight.cpp
@@ -320,6 +320,14 @@ CPed::SetAttack(CEntity *victim)
((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
}
}
+#ifdef FIX_BUGS
+ // fix aiming for flamethrower while using PC controls
+ else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER && TheCamera.Cams[0].Using3rdPersonMouseCam() && this == FindPlayerPed())
+ {
+ SetAimFlag(m_fRotationCur);
+ ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
+ }
+#endif
if (m_nPedState == PED_ATTACK) {
bIsAttacking = true;
return;
diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h
index 9077fbea..1543fa34 100644
--- a/src/peds/PedIK.h
+++ b/src/peds/PedIK.h
@@ -29,7 +29,7 @@ class CPedIK
{
public:
enum {
- GUN_POINTED_SUCCESSFULLY = 1, // set but unused
+ GUN_POINTED_SUCCESSFULLY = 1,
LOOKAROUND_HEAD_ONLY = 2,
AIMS_WITH_ARM = 4,
};
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 93a403bd..416fb949 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -503,6 +503,10 @@ CPlayerPed::DoWeaponSmoothSpray(void)
{
if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
eWeaponType weapon = GetWeapon()->m_eWeaponType;
+#ifdef FREE_CAM
+ if(TheCamera.Cams[0].Using3rdPersonMouseCam() && (weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI))
+ return false;
+#endif
if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN ||
weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
return true;
@@ -1183,6 +1187,13 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
padMoveInGameUnit = CVector2D(leftRight, upDown).Magnitude() / PAD_MOVE_TO_GAME_WORLD_MOVE;
}
+#ifdef FREE_CAM
+ if(TheCamera.Cams[0].Using3rdPersonMouseCam() && doSmoothSpray) {
+ padMoveInGameUnit = 0.0f;
+ smoothSprayWithoutMove = false;
+ }
+#endif
+
if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
@@ -1492,14 +1503,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, 116);
+ ZeroSaveBuf(buf, 116);
}
void
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index ace6d37c..1d2a5798 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -55,7 +55,7 @@ bool CPopulation::ms_bGivePedsWeapons;
int32 CPopulation::m_AllRandomPedsThisType = -1;
float CPopulation::PedDensityMultiplier = 1.0f;
uint32 CPopulation::ms_nTotalMissionPeds;
-int32 CPopulation::MaxNumberOfPedsInUse = 25;
+int32 CPopulation::MaxNumberOfPedsInUse = DEFAULT_MAX_NUMBER_OF_PEDS;
uint32 CPopulation::ms_nNumCivMale;
uint32 CPopulation::ms_nNumCivFemale;
uint32 CPopulation::ms_nNumCop;
@@ -1122,12 +1122,6 @@ CPopulation::ManagePopulation(void)
}
float dist = (ped->GetPosition() - playerPos).Magnitude2D();
-#ifdef SQUEEZE_PERFORMANCE
- if (dist > 50.f)
- ped->bUsesCollision = false;
- else
- ped->bUsesCollision = true;
-#endif
bool pedIsFarAway = false;
if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist
diff --git a/src/render/2dEffect.h b/src/renderer/2dEffect.h
index a8013b34..a8013b34 100644
--- a/src/render/2dEffect.h
+++ b/src/renderer/2dEffect.h
diff --git a/src/render/Antennas.cpp b/src/renderer/Antennas.cpp
index 5e30aca2..5e30aca2 100644
--- a/src/render/Antennas.cpp
+++ b/src/renderer/Antennas.cpp
diff --git a/src/render/Antennas.h b/src/renderer/Antennas.h
index 47cb1dad..47cb1dad 100644
--- a/src/render/Antennas.h
+++ b/src/renderer/Antennas.h
diff --git a/src/render/Clouds.cpp b/src/renderer/Clouds.cpp
index 957844a5..957844a5 100644
--- a/src/render/Clouds.cpp
+++ b/src/renderer/Clouds.cpp
diff --git a/src/render/Clouds.h b/src/renderer/Clouds.h
index 4d8cd2c8..4d8cd2c8 100644
--- a/src/render/Clouds.h
+++ b/src/renderer/Clouds.h
diff --git a/src/render/Console.cpp b/src/renderer/Console.cpp
index 8ea5b7a3..8ea5b7a3 100644
--- a/src/render/Console.cpp
+++ b/src/renderer/Console.cpp
diff --git a/src/render/Console.h b/src/renderer/Console.h
index 9f22236f..9f22236f 100644
--- a/src/render/Console.h
+++ b/src/renderer/Console.h
diff --git a/src/render/Coronas.cpp b/src/renderer/Coronas.cpp
index e9f9e662..e9f9e662 100644
--- a/src/render/Coronas.cpp
+++ b/src/renderer/Coronas.cpp
diff --git a/src/render/Coronas.h b/src/renderer/Coronas.h
index 46eb4315..46eb4315 100644
--- a/src/render/Coronas.h
+++ b/src/renderer/Coronas.h
diff --git a/src/render/Credits.cpp b/src/renderer/Credits.cpp
index 60581793..60581793 100644
--- a/src/render/Credits.cpp
+++ b/src/renderer/Credits.cpp
diff --git a/src/render/Credits.h b/src/renderer/Credits.h
index e049ce76..e049ce76 100644
--- a/src/render/Credits.h
+++ b/src/renderer/Credits.h
diff --git a/src/render/Draw.cpp b/src/renderer/Draw.cpp
index f702f188..f702f188 100644
--- a/src/render/Draw.cpp
+++ b/src/renderer/Draw.cpp
diff --git a/src/render/Draw.h b/src/renderer/Draw.h
index 8727e0e0..8727e0e0 100644
--- a/src/render/Draw.h
+++ b/src/renderer/Draw.h
diff --git a/src/render/Fluff.cpp b/src/renderer/Fluff.cpp
index c4cfe7f7..c4cfe7f7 100644
--- a/src/render/Fluff.cpp
+++ b/src/renderer/Fluff.cpp
diff --git a/src/render/Fluff.h b/src/renderer/Fluff.h
index fe3ab256..fe3ab256 100644
--- a/src/render/Fluff.h
+++ b/src/renderer/Fluff.h
diff --git a/src/render/Font.cpp b/src/renderer/Font.cpp
index 6a9944e1..6a9944e1 100644
--- a/src/render/Font.cpp
+++ b/src/renderer/Font.cpp
diff --git a/src/render/Font.h b/src/renderer/Font.h
index 9316ed34..9316ed34 100644
--- a/src/render/Font.h
+++ b/src/renderer/Font.h
diff --git a/src/render/Glass.cpp b/src/renderer/Glass.cpp
index cc45648c..cc45648c 100644
--- a/src/render/Glass.cpp
+++ b/src/renderer/Glass.cpp
diff --git a/src/render/Glass.h b/src/renderer/Glass.h
index 51c5aae9..51c5aae9 100644
--- a/src/render/Glass.h
+++ b/src/renderer/Glass.h
diff --git a/src/render/Hud.cpp b/src/renderer/Hud.cpp
index bba8c525..bba8c525 100644
--- a/src/render/Hud.cpp
+++ b/src/renderer/Hud.cpp
diff --git a/src/render/Hud.h b/src/renderer/Hud.h
index adfdf1fc..adfdf1fc 100644
--- a/src/render/Hud.h
+++ b/src/renderer/Hud.h
diff --git a/src/render/Instance.cpp b/src/renderer/Instance.cpp
index be6d73d6..be6d73d6 100644
--- a/src/render/Instance.cpp
+++ b/src/renderer/Instance.cpp
diff --git a/src/render/Instance.h b/src/renderer/Instance.h
index 693cfdf1..693cfdf1 100644
--- a/src/render/Instance.h
+++ b/src/renderer/Instance.h
diff --git a/src/render/Lines.cpp b/src/renderer/Lines.cpp
index b5c85149..b5c85149 100644
--- a/src/render/Lines.cpp
+++ b/src/renderer/Lines.cpp
diff --git a/src/render/Lines.h b/src/renderer/Lines.h
index f2694fc0..f2694fc0 100644
--- a/src/render/Lines.h
+++ b/src/renderer/Lines.h
diff --git a/src/render/MBlur.cpp b/src/renderer/MBlur.cpp
index 8e5fba2a..8e5fba2a 100644
--- a/src/render/MBlur.cpp
+++ b/src/renderer/MBlur.cpp
diff --git a/src/render/MBlur.h b/src/renderer/MBlur.h
index e2e5d38c..e2e5d38c 100644
--- a/src/render/MBlur.h
+++ b/src/renderer/MBlur.h
diff --git a/src/render/Particle.cpp b/src/renderer/Particle.cpp
index 76ddde50..76ddde50 100644
--- a/src/render/Particle.cpp
+++ b/src/renderer/Particle.cpp
diff --git a/src/render/Particle.h b/src/renderer/Particle.h
index 7f02e318..7f02e318 100644
--- a/src/render/Particle.h
+++ b/src/renderer/Particle.h
diff --git a/src/render/ParticleMgr.cpp b/src/renderer/ParticleMgr.cpp
index 3387d471..3387d471 100644
--- a/src/render/ParticleMgr.cpp
+++ b/src/renderer/ParticleMgr.cpp
diff --git a/src/render/ParticleMgr.h b/src/renderer/ParticleMgr.h
index 0100bb65..0100bb65 100644
--- a/src/render/ParticleMgr.h
+++ b/src/renderer/ParticleMgr.h
diff --git a/src/render/ParticleType.h b/src/renderer/ParticleType.h
index 8d352c44..8d352c44 100644
--- a/src/render/ParticleType.h
+++ b/src/renderer/ParticleType.h
diff --git a/src/render/PlayerSkin.cpp b/src/renderer/PlayerSkin.cpp
index f0fae45a..f0fae45a 100644
--- a/src/render/PlayerSkin.cpp
+++ b/src/renderer/PlayerSkin.cpp
diff --git a/src/render/PlayerSkin.h b/src/renderer/PlayerSkin.h
index e0214ce0..e0214ce0 100644
--- a/src/render/PlayerSkin.h
+++ b/src/renderer/PlayerSkin.h
diff --git a/src/render/PointLights.cpp b/src/renderer/PointLights.cpp
index 84ac4ab2..84ac4ab2 100644
--- a/src/render/PointLights.cpp
+++ b/src/renderer/PointLights.cpp
diff --git a/src/render/PointLights.h b/src/renderer/PointLights.h
index 9e94328f..9e94328f 100644
--- a/src/render/PointLights.h
+++ b/src/renderer/PointLights.h
diff --git a/src/render/RenderBuffer.cpp b/src/renderer/RenderBuffer.cpp
index 6120dfe2..6120dfe2 100644
--- a/src/render/RenderBuffer.cpp
+++ b/src/renderer/RenderBuffer.cpp
diff --git a/src/render/RenderBuffer.h b/src/renderer/RenderBuffer.h
index 485d24e3..485d24e3 100644
--- a/src/render/RenderBuffer.h
+++ b/src/renderer/RenderBuffer.h
diff --git a/src/render/Renderer.cpp b/src/renderer/Renderer.cpp
index 1c0bd445..1c0bd445 100644
--- a/src/render/Renderer.cpp
+++ b/src/renderer/Renderer.cpp
diff --git a/src/render/Renderer.h b/src/renderer/Renderer.h
index 0322939c..0322939c 100644
--- a/src/render/Renderer.h
+++ b/src/renderer/Renderer.h
diff --git a/src/render/Rubbish.cpp b/src/renderer/Rubbish.cpp
index 8da6b025..8da6b025 100644
--- a/src/render/Rubbish.cpp
+++ b/src/renderer/Rubbish.cpp
diff --git a/src/render/Rubbish.h b/src/renderer/Rubbish.h
index 37f895f3..37f895f3 100644
--- a/src/render/Rubbish.h
+++ b/src/renderer/Rubbish.h
diff --git a/src/render/Shadows.cpp b/src/renderer/Shadows.cpp
index 3884d3bb..3884d3bb 100644
--- a/src/render/Shadows.cpp
+++ b/src/renderer/Shadows.cpp
diff --git a/src/render/Shadows.h b/src/renderer/Shadows.h
index 8c909df3..8c909df3 100644
--- a/src/render/Shadows.h
+++ b/src/renderer/Shadows.h
diff --git a/src/render/Skidmarks.cpp b/src/renderer/Skidmarks.cpp
index 4c662a79..4c662a79 100644
--- a/src/render/Skidmarks.cpp
+++ b/src/renderer/Skidmarks.cpp
diff --git a/src/render/Skidmarks.h b/src/renderer/Skidmarks.h
index c061782d..c061782d 100644
--- a/src/render/Skidmarks.h
+++ b/src/renderer/Skidmarks.h
diff --git a/src/render/SpecialFX.cpp b/src/renderer/SpecialFX.cpp
index 6d96d21a..6d96d21a 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/renderer/SpecialFX.cpp
diff --git a/src/render/SpecialFX.h b/src/renderer/SpecialFX.h
index 2d9f18b1..2d9f18b1 100644
--- a/src/render/SpecialFX.h
+++ b/src/renderer/SpecialFX.h
diff --git a/src/render/Sprite.cpp b/src/renderer/Sprite.cpp
index 3fef0733..3fef0733 100644
--- a/src/render/Sprite.cpp
+++ b/src/renderer/Sprite.cpp
diff --git a/src/render/Sprite.h b/src/renderer/Sprite.h
index ec4c1d1b..ec4c1d1b 100644
--- a/src/render/Sprite.h
+++ b/src/renderer/Sprite.h
diff --git a/src/render/Sprite2d.cpp b/src/renderer/Sprite2d.cpp
index 59622516..59622516 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/renderer/Sprite2d.cpp
diff --git a/src/render/Sprite2d.h b/src/renderer/Sprite2d.h
index 0e12d441..0e12d441 100644
--- a/src/render/Sprite2d.h
+++ b/src/renderer/Sprite2d.h
diff --git a/src/render/TexList.cpp b/src/renderer/TexList.cpp
index 1689837f..1689837f 100644
--- a/src/render/TexList.cpp
+++ b/src/renderer/TexList.cpp
diff --git a/src/render/TexList.h b/src/renderer/TexList.h
index 7e042211..7e042211 100644
--- a/src/render/TexList.h
+++ b/src/renderer/TexList.h
diff --git a/src/render/Timecycle.cpp b/src/renderer/Timecycle.cpp
index 0d94dbd6..0d94dbd6 100644
--- a/src/render/Timecycle.cpp
+++ b/src/renderer/Timecycle.cpp
diff --git a/src/render/Timecycle.h b/src/renderer/Timecycle.h
index d5d7b67a..d5d7b67a 100644
--- a/src/render/Timecycle.h
+++ b/src/renderer/Timecycle.h
diff --git a/src/render/WaterCannon.cpp b/src/renderer/WaterCannon.cpp
index 08898be8..08898be8 100644
--- a/src/render/WaterCannon.cpp
+++ b/src/renderer/WaterCannon.cpp
diff --git a/src/render/WaterCannon.h b/src/renderer/WaterCannon.h
index a37bdd12..a37bdd12 100644
--- a/src/render/WaterCannon.h
+++ b/src/renderer/WaterCannon.h
diff --git a/src/render/WaterLevel.cpp b/src/renderer/WaterLevel.cpp
index 7001c0cf..7001c0cf 100644
--- a/src/render/WaterLevel.cpp
+++ b/src/renderer/WaterLevel.cpp
diff --git a/src/render/WaterLevel.h b/src/renderer/WaterLevel.h
index b797f251..b797f251 100644
--- a/src/render/WaterLevel.h
+++ b/src/renderer/WaterLevel.h
diff --git a/src/render/Weather.cpp b/src/renderer/Weather.cpp
index e57d57d6..e57d57d6 100644
--- a/src/render/Weather.cpp
+++ b/src/renderer/Weather.cpp
diff --git a/src/render/Weather.h b/src/renderer/Weather.h
index 9c670317..9c670317 100644
--- a/src/render/Weather.h
+++ b/src/renderer/Weather.h
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index 23a8fd6a..f51f8233 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -600,6 +600,552 @@ align4bytes(int32 size)
return (size + 3) & 0xFFFFFFFC;
}
+#ifdef FIX_INCOMPATIBLE_SAVES
+#define LoadSaveDataBlockNoCheck(buf, file, size) \
+do { \
+ CFileMgr::Read(file, (const char *)&size, sizeof(size)); \
+ size = align4bytes(size); \
+ CFileMgr::Read(file, (const char *)work_buff, size); \
+ buf = work_buff; \
+} while(0)
+
+#define WriteSavaDataBlockNoFunc(buf, file, size) \
+do { \
+ if (!PcSaveHelper.PcClassSaveRoutine(file, buf, size)) \
+ goto fail; \
+ totalSize += size; \
+} while(0)
+
+#define FixSaveDataBlock(fix_func, file, size) \
+do { \
+ ReadDataFromBufferPointer(buf, size); \
+ memset(work_buff2, 0, sizeof(work_buff2)); \
+ buf2 = work_buff2; \
+ reserved = 0; \
+ MakeSpaceForSizeInBufferPointer(presize, buf2, postsize); \
+ fix_func(save_type, buf, buf2, &size); \
+ CopySizeAndPreparePointer(presize, buf2, postsize, reserved, size); \
+ if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff2, buf2 - work_buff2)) \
+ goto fail; \
+ totalSize += buf2 - work_buff2; \
+} while(0)
+
+#define ReadDataFromBufferPointerWithSize(buf, to, size) memcpy(&to, buf, size); buf += align4bytes(size)
+
+#define ReadBuf(buf, to) memcpy(&to, buf, sizeof(to)); buf += sizeof(to)
+#define WriteBuf(buf, from) memcpy(buf, &from, sizeof(from)); buf += sizeof(from)
+#define CopyBuf(from, to, size) memcpy(to, from, size); to += (size); from += (size)
+#define CopyPtr(from, to) memcpy(to, from, 4); to += 4; from += 8
+#define SkipBuf(buf, size) buf += (size)
+#define SkipBoth(from, to, size) to += (size); from += (size)
+#define SkipPtr(from, to) to += 4; from += 8
+
+// unfortunately we need a 2nd buffer of the same size to store the fixed output ...
+static uint8 work_buff2[sizeof(work_buff)];
+
+enum
+{
+ SAVE_TYPE_NONE = 0,
+ SAVE_TYPE_32_BIT = 1,
+ SAVE_TYPE_64_BIT = 2,
+ SAVE_TYPE_MSVC = 4,
+ SAVE_TYPE_GCC = 8,
+};
+
+uint8
+GetSaveType(char *savename)
+{
+ uint8 save_type = SAVE_TYPE_NONE;
+ int file = CFileMgr::OpenFile(savename, "rb");
+
+ uint32 size;
+ CFileMgr::Read(file, (const char *)&size, sizeof(size));
+
+ uint8 *buf = work_buff;
+ CFileMgr::Read(file, (const char *)work_buff, size); // simple vars + scripts
+
+ LoadSaveDataBlockNoCheck(buf, file, size); // ped pool
+
+ LoadSaveDataBlockNoCheck(buf, file, size); // garages
+ ReadDataFromBufferPointer(buf, size);
+
+ // store for later after we know how much data we need to skip
+ ReadDataFromBufferPointerWithSize(buf, work_buff2, size);
+
+ LoadSaveDataBlockNoCheck(buf, file, size); // vehicle pool
+ LoadSaveDataBlockNoCheck(buf, file, size); // object pool
+ LoadSaveDataBlockNoCheck(buf, file, size); // paths
+
+ LoadSaveDataBlockNoCheck(buf, file, size); // cranes
+
+ CFileMgr::CloseFile(file);
+
+ ReadDataFromBufferPointer(buf, size);
+
+ if (size == 1032)
+ save_type |= SAVE_TYPE_32_BIT;
+ else if (size == 1160)
+ save_type |= SAVE_TYPE_64_BIT;
+ else
+ assert(0); // this should never happen
+
+ buf = work_buff2;
+
+ buf += 760; // skip everything before the first garage
+ buf += save_type & SAVE_TYPE_32_BIT ? 28 : 40; // skip first garage up to m_fX1
+
+ // now the values we want to verify
+ float fX1, fX2, fY1, fY2, fZ1, fZ2;
+
+ ReadBuf(buf, fX1);
+ ReadBuf(buf, fX2);
+ ReadBuf(buf, fY1);
+ ReadBuf(buf, fY2);
+ ReadBuf(buf, fZ1);
+ ReadBuf(buf, fZ2);
+
+ if (fX1 == CRUSHER_GARAGE_X1 && fX2 == CRUSHER_GARAGE_X2 &&
+ fY1 == CRUSHER_GARAGE_Y1 && fY2 == CRUSHER_GARAGE_Y2 &&
+ fZ1 == CRUSHER_GARAGE_Z1 && fZ2 == CRUSHER_GARAGE_Z2)
+ save_type |= SAVE_TYPE_MSVC;
+ else
+ save_type |= SAVE_TYPE_GCC;
+
+ return save_type;
+}
+
+static void
+FixGarages(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ // hardcoded: 5484
+ // x86 msvc: 5240
+ // x86 gcc: 5040
+ // amd64 msvc: 5880
+ // amd64 gcc: 5808
+
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+ uint32 read;
+ uint32 written = 5240;
+
+ if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_GCC)
+ read = 5040;
+ else if (save_type & SAVE_TYPE_64_BIT && save_type & SAVE_TYPE_GCC)
+ read = 5808;
+ else
+ read = 5880;
+
+ uint32 ptrsize = save_type & SAVE_TYPE_32_BIT ? 4 : 8;
+
+ CopyBuf(buf, buf2, 4 * 6);
+ CopyBuf(buf, buf2, 4 * TOTAL_COLLECTCARS_GARAGES);
+ CopyBuf(buf, buf2, 4);
+
+ if (save_type & SAVE_TYPE_GCC)
+ {
+ for (int32 i = 0; i < NUM_GARAGE_STORED_CARS; i++)
+ {
+#define FixStoredCar(buf, buf2) \
+do { \
+ CopyBuf(buf, buf2, 4 + sizeof(CVector) + sizeof(CVector)); \
+ uint8 nFlags8; \
+ ReadBuf(buf, nFlags8); \
+ int32 nFlags32 = nFlags8; \
+ WriteBuf(buf2, nFlags32); \
+ CopyBuf(buf, buf2, 1 * 6); \
+ SkipBuf(buf, 1); \
+ SkipBuf(buf2, 2); \
+} while(0)
+
+ FixStoredCar(buf, buf2);
+ FixStoredCar(buf, buf2);
+ FixStoredCar(buf, buf2);
+
+#undef FixStoredCar
+ }
+ }
+ else
+ {
+ CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
+ CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
+ CopyBuf(buf, buf2, sizeof(CStoredCar) * NUM_GARAGE_STORED_CARS);
+ }
+
+ for (int32 i = 0; i < NUM_GARAGES; i++)
+ {
+ // skip the last 5 garages in 64bit builds without FIX_GARAGE_SIZE since they weren't actually saved and are unused
+ if (save_type & SAVE_TYPE_64_BIT && *size == 5484 && i >= NUM_GARAGES - 5)
+ {
+ SkipBuf(buf, 160); // sizeof(CGarage) on x64
+ SkipBuf(buf2, 140); // sizeof(CGarage) on x86
+ }
+ else
+ {
+ CopyBuf(buf, buf2, 1 * 6);
+ SkipBoth(buf, buf2, 2);
+ CopyBuf(buf, buf2, 4);
+ SkipBuf(buf, ptrsize - 4); // write 4 bytes padding if 8 byte pointer, if not, write 0
+ SkipBuf(buf, ptrsize * 2);
+ SkipBuf(buf2, 4 * 2);
+ CopyBuf(buf, buf2, 1 * 7);
+ SkipBoth(buf, buf2, 1);
+ CopyBuf(buf, buf2, 4 * 15 + 1);
+ SkipBoth(buf, buf2, 3);
+ SkipBuf(buf, ptrsize * 2);
+ SkipBuf(buf2, 4 * 2);
+
+ if (save_type & SAVE_TYPE_GCC)
+ SkipBuf(buf, save_type & SAVE_TYPE_64_BIT ? 36 + 4 : 36); // sizeof(CStoredCar) on gcc 64/32 before fix
+ else
+ SkipBuf(buf, sizeof(CStoredCar));
+
+ SkipBuf(buf2, sizeof(CStoredCar));
+ }
+ }
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+#ifdef FIX_GARAGE_SIZE
+ *size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CGarages::CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
+#else
+ *size = 5484;
+#endif
+}
+
+static void
+FixCranes(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+ uint32 read = 2 * sizeof(uint32) + 0x480; // sizeof(aCranes)
+ uint32 written = 2 * sizeof(uint32) + 0x400; // see CRANES_SAVE_SIZE
+
+ CopyBuf(buf, buf2, 4 + 4);
+
+ for (int32 i = 0; i < NUM_CRANES; i++)
+ {
+ CopyPtr(buf, buf2);
+ CopyPtr(buf, buf2);
+ CopyBuf(buf, buf2, 15 * 4 + sizeof(CVector) * 3 + sizeof(CVector2D));
+ CopyPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4 + 7 * 1);
+ SkipBuf(buf, 5);
+ SkipBuf(buf2, 1);
+ }
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+ *size = written;
+}
+
+static void
+FixPickups(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+ uint32 read = 0x3480 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // sizeof(aPickUps)
+ uint32 written = 0x24C0 + sizeof(uint16) + sizeof(uint16) + sizeof(int32) * NUMCOLLECTEDPICKUPS; // see PICKUPS_SAVE_SIZE
+
+ for (int32 i = 0; i < NUMPICKUPS; i++)
+ {
+ CopyBuf(buf, buf2, 1 + 1 + 2);
+ SkipBuf(buf, 4);
+ CopyPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4 + 2 + 2 + sizeof(CVector));
+ SkipBuf(buf, 4);
+ }
+
+ CopyBuf(buf, buf2, 2);
+ SkipBoth(buf, buf2, 2);
+
+ CopyBuf(buf, buf2, NUMCOLLECTEDPICKUPS * 4);
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+ *size = written;
+}
+
+static void
+FixPhoneInfo(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+ uint32 read = 0x1138; // sizeof(CPhoneInfo)
+ uint32 written = 0xA30; // see PHONEINFO_SAVE_SIZE
+
+ CopyBuf(buf, buf2, 4 + 4);
+
+ for (int32 i = 0; i < NUMPHONES; i++)
+ {
+ CopyBuf(buf, buf2, sizeof(CVector));
+ SkipBuf(buf, 4);
+ SkipPtr(buf, buf2);
+ SkipPtr(buf, buf2);
+ SkipPtr(buf, buf2);
+ SkipPtr(buf, buf2);
+ SkipPtr(buf, buf2);
+ SkipPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4);
+ SkipBuf(buf, 4);
+ CopyPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4 + 1);
+ SkipBoth(buf, buf2, 3);
+ }
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+ *size = written;
+}
+
+static void
+FixZones(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+ uint32 read = 11300; // see SaveAllZones
+ uint32 written = 10100; // see SaveAllZones
+
+ CopyBuf(buf, buf2, 1 * 4);
+
+ SkipBuf(buf, 4);
+ uint32 hdr_size = 10100 - (1 * 4 + 4); // see SaveAllZones
+ WriteBuf(buf2, hdr_size);
+
+ CopyBuf(buf, buf2, 4 * 2 + 2);
+ SkipBoth(buf, buf2, 2);
+
+#define FixOneZone(buf, buf2) \
+do { \
+ CopyBuf(buf, buf2, 8 + 8 * 4 + 2 * 2); \
+ SkipBuf(buf, 4); \
+ CopyPtr(buf, buf2); \
+ CopyPtr(buf, buf2); \
+ CopyPtr(buf, buf2); \
+} while(0)
+
+ for (int32 i = 0; i < NUMZONES; i++)
+ FixOneZone(buf, buf2);
+
+ CopyBuf(buf, buf2, sizeof(CZoneInfo) * NUMZONES * 2);
+ CopyBuf(buf, buf2, 2 + 2);
+
+ for (int32 i = 0; i < NUMMAPZONES; i++)
+ FixOneZone(buf, buf2);
+
+ CopyBuf(buf, buf2, 2 * NUMAUDIOZONES);
+ CopyBuf(buf, buf2, 2 + 2);
+
+#undef FixOneZone
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+ *size = written;
+}
+
+static void
+FixParticles(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size)
+{
+ uint8 *buf_start = buf;
+ uint8 *buf2_start = buf2;
+
+ int32 numObjects;
+ ReadBuf(buf, numObjects);
+ WriteBuf(buf2, numObjects);
+
+ uint32 read = 0xA0 * (numObjects + 1) + 4; // sizeof(CParticleObject)
+ uint32 written = 0x88 * (numObjects + 1) + 4; // see PARTICLE_OBJECT_SIZEOF
+
+ for (int32 i = 0; i < numObjects; i++)
+ {
+ // CPlaceable
+ SkipPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4 * 4 * 4);
+ SkipPtr(buf, buf2);
+ CopyBuf(buf, buf2, 1);
+ SkipBuf(buf, 7);
+ SkipBuf(buf2, 3);
+
+ // CParticleObject
+ SkipPtr(buf, buf2);
+ SkipPtr(buf, buf2);
+ SkipPtr(buf, buf2);
+ CopyBuf(buf, buf2, 4 * 3 + 2 * 1 + 2 * 2);
+ SkipBoth(buf, buf2, 2);
+ CopyBuf(buf, buf2, sizeof(CVector) + 2 * 4 + sizeof(CRGBA) + 2 * 1);
+ SkipBoth(buf, buf2, 2);
+ }
+
+ SkipBuf(buf, 0xA0); // sizeof(CParticleObject)
+ SkipBuf(buf2, 0x88); // see PARTICLE_OBJECT_SIZEOF
+
+ *size = 0;
+
+ assert(buf - buf_start == read);
+ assert(buf2 - buf2_start == written);
+
+ *size = written;
+}
+
+bool
+FixSave(int32 slot, uint8 save_type)
+{
+ if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC)
+ return true;
+
+ bool success = false;
+
+ uint8 *buf, *presize, *postsize, *buf2;
+ uint32 size;
+ uint32 reserved;
+
+ uint32 totalSize;
+
+ char savename[MAX_PATH];
+ char savename_bak[MAX_PATH];
+
+ sprintf(savename, "%s%i%s", DefaultPCSaveFileName, slot + 1, ".b");
+ sprintf(savename_bak, "%s%i%s.%lld.bak", DefaultPCSaveFileName, slot + 1, ".b", time(nil));
+
+ assert(caserename(savename, savename_bak) == 0);
+
+ int file_in = CFileMgr::OpenFile(savename_bak, "rb");
+ int file_out = CFileMgr::OpenFileForWriting(savename);
+
+ CheckSum = 0;
+ totalSize = 0;
+
+ CFileMgr::Read(file_in, (const char *)&size, sizeof(size));
+
+ buf = work_buff;
+ CFileMgr::Read(file_in, (const char *)work_buff, size); // simple vars + scripts
+
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // ped pool
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // garages
+ FixSaveDataBlock(FixGarages, file_out, size); // garages need to be fixed in either case
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // vehicle pool
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // object pool
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // paths
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // cranes
+ if (save_type & SAVE_TYPE_64_BIT)
+ FixSaveDataBlock(FixCranes, file_out, size);
+ else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // pickups
+ if (save_type & SAVE_TYPE_64_BIT)
+ FixSaveDataBlock(FixPickups, file_out, size);
+ else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // phoneinfo
+ if (save_type & SAVE_TYPE_64_BIT)
+ FixSaveDataBlock(FixPhoneInfo, file_out, size);
+ else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // restart
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // radar blips
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // zones
+ if (save_type & SAVE_TYPE_64_BIT)
+ FixSaveDataBlock(FixZones, file_out, size);
+ else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // gang data
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // car generators
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // particles
+ if (save_type & SAVE_TYPE_64_BIT)
+ FixSaveDataBlock(FixParticles, file_out, size);
+ else
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // audio script objects
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // player info
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // stats
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // streaming
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ LoadSaveDataBlockNoCheck(buf, file_in, size); // ped type
+ WriteSavaDataBlockNoFunc(buf, file_out, size);
+
+ memset(work_buff, 0, sizeof(work_buff));
+
+ for (int i = 0; i < 4; i++) {
+ size = align4bytes(SIZE_OF_ONE_GAME_IN_BYTES - totalSize - 4);
+ if (size > sizeof(work_buff))
+ size = sizeof(work_buff);
+ if (size > 4) {
+ if (!PcSaveHelper.PcClassSaveRoutine(file_out, work_buff, size))
+ goto fail;
+ totalSize += size;
+ }
+ }
+
+ if (!CFileMgr::Write(file_out, (const char *)&CheckSum, sizeof(CheckSum)))
+ goto fail;
+
+ success = true;
+
+fail:;
+ CFileMgr::CloseFile(file_in);
+ CFileMgr::CloseFile(file_out);
+
+ return success;
+}
+
+#undef LoadSaveDataBlockNoCheck
+#undef WriteSavaDataBlockNoFunc
+#undef FixSaveDataBlock
+#undef ReadDataFromBufferPointerWithSize
+#undef ReadBuf
+#undef WriteBuf
+#undef CopyBuf
+#undef CopyPtr
+#undef SkipBuf
+#undef SkipBoth
+#undef SkipPtr
+#endif
+
#ifdef MISSION_REPLAY
void DisplaySaveResult(int unk, char* name)
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index 069ba7cd..b291ddf9 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -22,6 +22,11 @@ bool CheckDataNotCorrupt(int32 slot, char *name);
bool RestoreForStartLoad();
int align4bytes(int32 size);
+#ifdef FIX_INCOMPATIBLE_SAVES
+uint8 GetSaveType(char *savename);
+bool FixSave(int32 slot, uint8 save_type);
+#endif
+
extern class CDate CompileDateAndTime;
extern char DefaultPCSaveFileName[260];
diff --git a/src/save/PCSave.cpp b/src/save/PCSave.cpp
index a9df00af..0c228a6d 100644
--- a/src/save/PCSave.cpp
+++ b/src/save/PCSave.cpp
@@ -122,6 +122,13 @@ C_PcSave::PopulateSlotInfo()
}
if (Slots[i + 1] == SLOT_OK) {
if (CheckDataNotCorrupt(i, savename)) {
+#ifdef FIX_INCOMPATIBLE_SAVES
+ if (!FixSave(i, GetSaveType(savename))) {
+ CMessages::InsertNumberInString(TheText.Get("FEC_SLC"), i + 1, -1, -1, -1, -1, -1, SlotFileName[i]);
+ Slots[i + 1] = SLOT_CORRUPTED;
+ continue;
+ }
+#endif
SYSTEMTIME st;
memcpy(&st, &header.SaveDateTime, sizeof(SYSTEMTIME));
const char *month;
diff --git a/src/save/PCSave.h b/src/save/PCSave.h
index 4a2d9a66..83471b5d 100644
--- a/src/save/PCSave.h
+++ b/src/save/PCSave.h
@@ -33,7 +33,7 @@ public:
void PopulateSlotInfo();
bool DeleteSlot(int32 slot);
bool SaveSlot(int32 slot);
- bool PcClassSaveRoutine(int32 a2, uint8 *data, uint32 size);
+ bool PcClassSaveRoutine(int32 file, uint8 *data, uint32 size);
static void SetSaveDirectory(const char *path);
};
diff --git a/src/save/SaveBuf.h b/src/save/SaveBuf.h
index 98fe888b..aad2e1a8 100644
--- a/src/save/SaveBuf.h
+++ b/src/save/SaveBuf.h
@@ -36,6 +36,15 @@ WriteSaveBuf(uint8 *&buf, const T &value)
return p;
}
+#ifdef COMPATIBLE_SAVES
+inline void
+ZeroSaveBuf(uint8 *&buf, uint32 length)
+{
+ memset(buf, 0, length);
+ SkipSaveBuf(buf, length);
+}
+#endif
+
#define SAVE_HEADER_SIZE (4 * sizeof(char) + sizeof(uint32))
#define WriteSaveHeader(buf, a, b, c, d, size) \
diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp
index 1d49ebd2..577983b6 100644
--- a/src/skel/crossplatform.cpp
+++ b/src/skel/crossplatform.cpp
@@ -155,6 +155,29 @@ FILE* _fcaseopen(char const* filename, char const* mode)
return result;
}
+int _caserename(const char *old_filename, const char *new_filename)
+{
+ int result;
+ char *real_old = casepath(old_filename);
+ char *real_new = casepath(new_filename);
+
+ // hack so we don't even try to rename it to new_filename if it already exists
+ if (!real_new) {
+ free(real_old);
+ return -1;
+ }
+
+ if (!real_old)
+ result = rename(old_filename, real_new);
+ else
+ result = rename(real_old, real_new);
+
+ free(real_old);
+ free(real_new);
+
+ return result;
+}
+
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
// Returned string should freed manually (if exists)
char* casepath(char const* path, bool checkPathFirst)
diff --git a/src/skel/crossplatform.h b/src/skel/crossplatform.h
index 2dd9c162..aa90ce5a 100644
--- a/src/skel/crossplatform.h
+++ b/src/skel/crossplatform.h
@@ -29,6 +29,7 @@ enum eWinVersion
#endif
extern DWORD _dwOperatingSystemVersion;
#define fcaseopen fopen
+#define caserename rename
#else
char *strupr(char *str);
char *strlwr(char *str);
@@ -51,6 +52,8 @@ extern long _dwOperatingSystemVersion;
char *casepath(char const *path, bool checkPathFirst = true);
FILE *_fcaseopen(char const *filename, char const *mode);
#define fcaseopen _fcaseopen
+int _caserename(const char *old_filename, const char *new_filename);
+#define caserename _caserename
#endif
#ifdef RW_GL3
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 3de3e12b..7d942dcd 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -4717,8 +4717,8 @@ void
CAutomobile::Save(uint8*& buf)
{
CVehicle::Save(buf);
- WriteSaveBuf<CDamageManager>(buf, Damage);
- SkipSaveBuf(buf, 800 - sizeof(CDamageManager));
+ WriteSaveBuf(buf, Damage);
+ ZeroSaveBuf(buf, 800 - sizeof(CDamageManager));
}
void
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 88444e95..65cdd8c6 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -940,7 +940,7 @@ void
CBoat::Save(uint8*& buf)
{
CVehicle::Save(buf);
- SkipSaveBuf(buf, 1156 - 648);
+ ZeroSaveBuf(buf, 1156 - 648);
}
void
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
index 0f1b8b4c..db9d2e00 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -37,6 +37,12 @@
#define MIN_VALID_POSITION (-10000.0f)
#define DEFAULT_OFFSET (20.0f)
+#ifdef COMPATIBLE_SAVES
+#define CRANES_SAVE_SIZE 0x400
+#else
+#define CRANES_SAVE_SIZE sizeof(aCranes)
+#endif
+
uint32 TimerForCamInterpolation;
uint32 CCranes::CarsCollectedMilitaryCrane;
@@ -634,10 +640,46 @@ void CCranes::Save(uint8* buf, uint32* size)
{
INITSAVEBUF
- *size = 2 * sizeof(uint32) + sizeof(aCranes);
+ *size = 2 * sizeof(uint32) + CRANES_SAVE_SIZE;
WriteSaveBuf(buf, NumCranes);
WriteSaveBuf(buf, CarsCollectedMilitaryCrane);
for (int i = 0; i < NUM_CRANES; i++) {
+#ifdef COMPATIBLE_SAVES
+ int32 tmp = aCranes[i].m_pCraneEntity != nil ? CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(aCranes[i].m_pCraneEntity) + 1 : 0;
+ WriteSaveBuf(buf, tmp);
+ tmp = aCranes[i].m_pHook != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aCranes[i].m_pHook) + 1 : 0;
+ WriteSaveBuf(buf, tmp);
+ WriteSaveBuf(buf, aCranes[i].m_nAudioEntity);
+ WriteSaveBuf(buf, aCranes[i].m_fPickupX1);
+ WriteSaveBuf(buf, aCranes[i].m_fPickupX2);
+ WriteSaveBuf(buf, aCranes[i].m_fPickupY1);
+ WriteSaveBuf(buf, aCranes[i].m_fPickupY2);
+ WriteSaveBuf(buf, aCranes[i].m_vecDropoffTarget);
+ WriteSaveBuf(buf, aCranes[i].m_fDropoffHeading);
+ WriteSaveBuf(buf, aCranes[i].m_fPickupAngle);
+ WriteSaveBuf(buf, aCranes[i].m_fDropoffAngle);
+ WriteSaveBuf(buf, aCranes[i].m_fPickupDistance);
+ WriteSaveBuf(buf, aCranes[i].m_fDropoffDistance);
+ WriteSaveBuf(buf, aCranes[i].m_fPickupHeight);
+ WriteSaveBuf(buf, aCranes[i].m_fDropoffHeight);
+ WriteSaveBuf(buf, aCranes[i].m_fHookAngle);
+ WriteSaveBuf(buf, aCranes[i].m_fHookOffset);
+ WriteSaveBuf(buf, aCranes[i].m_fHookHeight);
+ WriteSaveBuf(buf, aCranes[i].m_vecHookInitPos);
+ WriteSaveBuf(buf, aCranes[i].m_vecHookCurPos);
+ WriteSaveBuf(buf, aCranes[i].m_vecHookVelocity);
+ tmp = aCranes[i].m_pVehiclePickedUp != nil ? CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(aCranes[i].m_pVehiclePickedUp) + 1 : 0;
+ WriteSaveBuf(buf, tmp);
+ WriteSaveBuf(buf, aCranes[i].m_nTimeForNextCheck);
+ WriteSaveBuf(buf, aCranes[i].m_nCraneStatus);
+ WriteSaveBuf(buf, aCranes[i].m_nCraneState);
+ WriteSaveBuf(buf, aCranes[i].m_nVehiclesCollected);
+ WriteSaveBuf(buf, aCranes[i].m_bIsCrusher);
+ WriteSaveBuf(buf, aCranes[i].m_bIsMilitaryCrane);
+ WriteSaveBuf(buf, aCranes[i].m_bWasMilitaryCrane);
+ WriteSaveBuf(buf, aCranes[i].m_bIsTop);
+ ZeroSaveBuf(buf, 1);
+#else
CCrane *pCrane = WriteSaveBuf(buf, aCranes[i]);
if (pCrane->m_pCraneEntity != nil)
pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pCrane->m_pCraneEntity) + 1);
@@ -645,6 +687,7 @@ void CCranes::Save(uint8* buf, uint32* size)
pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pCrane->m_pHook) + 1);
if (pCrane->m_pVehiclePickedUp != nil)
pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pCrane->m_pVehiclePickedUp) + 1);
+#endif
}
VALIDATESAVEBUF(*size);
@@ -656,8 +699,46 @@ void CCranes::Load(uint8* buf, uint32 size)
ReadSaveBuf(&NumCranes, buf);
ReadSaveBuf(&CarsCollectedMilitaryCrane, buf);
- for (int i = 0; i < NUM_CRANES; i++)
+ for (int i = 0; i < NUM_CRANES; i++) {
+#ifdef COMPATIBLE_SAVES
+ int32 tmp;
+ ReadSaveBuf(&tmp, buf);
+ aCranes[i].m_pCraneEntity = tmp != 0 ? CPools::GetBuildingPool()->GetSlot(tmp - 1) : nil;
+ ReadSaveBuf(&tmp, buf);
+ aCranes[i].m_pHook = tmp != 0 ? CPools::GetObjectPool()->GetSlot(tmp - 1) : nil;
+ ReadSaveBuf(&aCranes[i].m_nAudioEntity, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupX1, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupX2, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupY1, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupY2, buf);
+ ReadSaveBuf(&aCranes[i].m_vecDropoffTarget, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffHeading, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupAngle, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffAngle, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupDistance, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffDistance, buf);
+ ReadSaveBuf(&aCranes[i].m_fPickupHeight, buf);
+ ReadSaveBuf(&aCranes[i].m_fDropoffHeight, buf);
+ ReadSaveBuf(&aCranes[i].m_fHookAngle, buf);
+ ReadSaveBuf(&aCranes[i].m_fHookOffset, buf);
+ ReadSaveBuf(&aCranes[i].m_fHookHeight, buf);
+ ReadSaveBuf(&aCranes[i].m_vecHookInitPos, buf);
+ ReadSaveBuf(&aCranes[i].m_vecHookCurPos, buf);
+ ReadSaveBuf(&aCranes[i].m_vecHookVelocity, buf);
+ ReadSaveBuf(&tmp, buf);
+ aCranes[i].m_pVehiclePickedUp = tmp != 0 ? CPools::GetVehiclePool()->GetSlot(tmp - 1) : nil;
+ ReadSaveBuf(&aCranes[i].m_nTimeForNextCheck, buf);
+ ReadSaveBuf(&aCranes[i].m_nCraneStatus, buf);
+ ReadSaveBuf(&aCranes[i].m_nCraneState, buf);
+ ReadSaveBuf(&aCranes[i].m_nVehiclesCollected, buf);
+ ReadSaveBuf(&aCranes[i].m_bIsCrusher, buf);
+ ReadSaveBuf(&aCranes[i].m_bIsMilitaryCrane, buf);
+ ReadSaveBuf(&aCranes[i].m_bWasMilitaryCrane, buf);
+ ReadSaveBuf(&aCranes[i].m_bIsTop, buf);
+ SkipSaveBuf(buf, 1);
+#else
ReadSaveBuf(&aCranes[i], buf);
+ }
for (int i = 0; i < NUM_CRANES; i++) {
CCrane *pCrane = &aCranes[i];
if (pCrane->m_pCraneEntity != nil)
@@ -666,6 +747,7 @@ void CCranes::Load(uint8* buf, uint32 size)
pCrane->m_pHook = CPools::GetObjectPool()->GetSlot((uintptr)pCrane->m_pHook - 1);
if (pCrane->m_pVehiclePickedUp != nil)
pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uintptr)pCrane->m_pVehiclePickedUp - 1);
+#endif
}
for (int i = 0; i < NUM_CRANES; i++) {
aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]);
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index 3d3ba8f2..4259f9d8 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -1262,42 +1262,42 @@ DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle)
void
CVehicle::Save(uint8*& buf)
{
- SkipSaveBuf(buf, 4);
- WriteSaveBuf<float>(buf, GetRight().x);
- WriteSaveBuf<float>(buf, GetRight().y);
- WriteSaveBuf<float>(buf, GetRight().z);
- SkipSaveBuf(buf, 4);
- WriteSaveBuf<float>(buf, GetForward().x);
- WriteSaveBuf<float>(buf, GetForward().y);
- WriteSaveBuf<float>(buf, GetForward().z);
- SkipSaveBuf(buf, 4);
- WriteSaveBuf<float>(buf, GetUp().x);
- WriteSaveBuf<float>(buf, GetUp().y);
- WriteSaveBuf<float>(buf, GetUp().z);
- SkipSaveBuf(buf, 4);
- WriteSaveBuf<float>(buf, GetPosition().x);
- WriteSaveBuf<float>(buf, GetPosition().y);
- WriteSaveBuf<float>(buf, GetPosition().z);
- SkipSaveBuf(buf, 16);
+ ZeroSaveBuf(buf, 4);
+ WriteSaveBuf(buf, GetRight().x);
+ WriteSaveBuf(buf, GetRight().y);
+ WriteSaveBuf(buf, GetRight().z);
+ ZeroSaveBuf(buf, 4);
+ WriteSaveBuf(buf, GetForward().x);
+ WriteSaveBuf(buf, GetForward().y);
+ WriteSaveBuf(buf, GetForward().z);
+ ZeroSaveBuf(buf, 4);
+ WriteSaveBuf(buf, GetUp().x);
+ WriteSaveBuf(buf, GetUp().y);
+ WriteSaveBuf(buf, GetUp().z);
+ ZeroSaveBuf(buf, 4);
+ WriteSaveBuf(buf, GetPosition().x);
+ WriteSaveBuf(buf, GetPosition().y);
+ WriteSaveBuf(buf, GetPosition().z);
+ ZeroSaveBuf(buf, 16);
SaveEntityFlags(buf);
- SkipSaveBuf(buf, 212);
+ ZeroSaveBuf(buf, 212);
AutoPilot.Save(buf);
- WriteSaveBuf<int8>(buf, m_currentColour1);
- WriteSaveBuf<int8>(buf, m_currentColour2);
- SkipSaveBuf(buf, 2);
- WriteSaveBuf<int16>(buf, m_nAlarmState);
- SkipSaveBuf(buf, 43);
- WriteSaveBuf<uint8>(buf, m_nNumMaxPassengers);
- SkipSaveBuf(buf, 2);
- WriteSaveBuf<float>(buf, field_1D0[0]);
- WriteSaveBuf<float>(buf, field_1D0[1]);
- WriteSaveBuf<float>(buf, field_1D0[2]);
- WriteSaveBuf<float>(buf, field_1D0[3]);
- SkipSaveBuf(buf, 8);
- WriteSaveBuf<float>(buf, m_fSteerAngle);
- WriteSaveBuf<float>(buf, m_fGasPedal);
- WriteSaveBuf<float>(buf, m_fBrakePedal);
- WriteSaveBuf<uint8>(buf, VehicleCreatedBy);
+ WriteSaveBuf(buf, m_currentColour1);
+ WriteSaveBuf(buf, m_currentColour2);
+ ZeroSaveBuf(buf, 2);
+ WriteSaveBuf(buf, m_nAlarmState);
+ ZeroSaveBuf(buf, 43);
+ WriteSaveBuf(buf, m_nNumMaxPassengers);
+ ZeroSaveBuf(buf, 2);
+ WriteSaveBuf(buf, field_1D0[0]);
+ WriteSaveBuf(buf, field_1D0[1]);
+ WriteSaveBuf(buf, field_1D0[2]);
+ WriteSaveBuf(buf, field_1D0[3]);
+ ZeroSaveBuf(buf, 8);
+ WriteSaveBuf(buf, m_fSteerAngle);
+ WriteSaveBuf(buf, m_fGasPedal);
+ WriteSaveBuf(buf, m_fBrakePedal);
+ WriteSaveBuf(buf, VehicleCreatedBy);
uint8 flags = 0;
if (bIsLawEnforcer) flags |= BIT(0);
if (bIsLocked) flags |= BIT(3);
@@ -1305,19 +1305,19 @@ CVehicle::Save(uint8*& buf)
if (bIsHandbrakeOn) flags |= BIT(5);
if (bLightsOn) flags |= BIT(6);
if (bFreebies) flags |= BIT(7);
- WriteSaveBuf<uint8>(buf, flags);
- SkipSaveBuf(buf, 10);
- WriteSaveBuf<float>(buf, m_fHealth);
- WriteSaveBuf<uint8>(buf, m_nCurrentGear);
- SkipSaveBuf(buf, 3);
- WriteSaveBuf<float>(buf, m_fChangeGearTime);
- SkipSaveBuf(buf, 4);
- WriteSaveBuf<uint32>(buf, m_nTimeOfDeath);
- SkipSaveBuf(buf, 2);
- WriteSaveBuf<int16>(buf, m_nBombTimer);
- SkipSaveBuf(buf, 12);
- WriteSaveBuf<int8>(buf, m_nDoorLock);
- SkipSaveBuf(buf, 99);
+ WriteSaveBuf(buf, flags);
+ ZeroSaveBuf(buf, 10);
+ WriteSaveBuf(buf, m_fHealth);
+ WriteSaveBuf(buf, m_nCurrentGear);
+ ZeroSaveBuf(buf, 3);
+ WriteSaveBuf(buf, m_fChangeGearTime);
+ ZeroSaveBuf(buf, 4);
+ WriteSaveBuf(buf, m_nTimeOfDeath);
+ ZeroSaveBuf(buf, 2);
+ WriteSaveBuf(buf, m_nBombTimer);
+ ZeroSaveBuf(buf, 12);
+ WriteSaveBuf(buf, m_nDoorLock);
+ ZeroSaveBuf(buf, 96);
}
void
@@ -1379,8 +1379,7 @@ CVehicle::Load(uint8*& buf)
SkipSaveBuf(buf, 2);
ReadSaveBuf(&m_nBombTimer, buf);
SkipSaveBuf(buf, 12);
- ReadSaveBuf(&flags, buf);
- m_nDoorLock = (eCarLock)flags;
- SkipSaveBuf(buf, 99);
+ ReadSaveBuf(&m_nDoorLock, buf);
+ SkipSaveBuf(buf, 96);
}
#endif
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 43a85db8..6eab1a65 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -592,6 +592,16 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
{
CVector src, trgt;
TheCamera.Find3rdPersonCamTargetVector(info->m_fRange, *fireSource, src, trgt);
+#ifdef FREE_CAM
+ CPed *shooterPed = (CPed *)shooter;
+ if((shooterPed->m_pedIK.m_flags & CPedIK::GUN_POINTED_SUCCESSFULLY) == 0) {
+ trgt.x = info->m_fRange;
+ trgt.y = 0.0f;
+ trgt.z = 0.0f;
+
+ shooterPed->TransformToNode(trgt, PED_HANDR);
+ }
+#endif
#ifdef FIX_BUGS
// fix muzzleflash rotation
@@ -2337,7 +2347,7 @@ CWeapon::Save(uint8*& buf)
CopyToBuf(buf, m_nAmmoTotal);
CopyToBuf(buf, m_nTimer);
CopyToBuf(buf, m_bAddRotOffset);
- SkipSaveBuf(buf, 3);
+ ZeroSaveBuf(buf, 3);
}
void