summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergeanur <s.anureev@yandex.ua>2020-04-14 23:10:50 +0200
committerSergeanur <s.anureev@yandex.ua>2020-04-14 23:10:50 +0200
commite373d0526ef07183cba8e89aba46f2ab416e67ba (patch)
treee6b2052e078cd2ad2ae1503262421c6858a20a0f
parentCFont (diff)
parentRwMatFX support with linked RW libs (diff)
downloadre3-e373d0526ef07183cba8e89aba46f2ab416e67ba.tar
re3-e373d0526ef07183cba8e89aba46f2ab416e67ba.tar.gz
re3-e373d0526ef07183cba8e89aba46f2ab416e67ba.tar.bz2
re3-e373d0526ef07183cba8e89aba46f2ab416e67ba.tar.lz
re3-e373d0526ef07183cba8e89aba46f2ab416e67ba.tar.xz
re3-e373d0526ef07183cba8e89aba46f2ab416e67ba.tar.zst
re3-e373d0526ef07183cba8e89aba46f2ab416e67ba.zip
-rw-r--r--README.md36
-rw-r--r--gamefiles/menu.txdbin0 -> 10244648 bytes
-rw-r--r--premake5.lua22
-rw-r--r--src/animation/CutsceneMgr.cpp (renamed from src/core/CutsceneMgr.cpp)9
-rw-r--r--src/animation/CutsceneMgr.h (renamed from src/core/CutsceneMgr.h)2
-rw-r--r--src/audio/AudioCollision.cpp822
-rw-r--r--src/audio/AudioCollision.h70
-rw-r--r--src/audio/AudioManager.cpp5750
-rw-r--r--src/audio/AudioManager.h431
-rw-r--r--src/audio/AudioScriptObject.cpp2
-rw-r--r--src/audio/PoliceRadio.cpp1581
-rw-r--r--src/audio/PoliceRadio.h90
-rw-r--r--src/control/AutoPilot.cpp16
-rw-r--r--src/control/CarCtrl.cpp146
-rw-r--r--src/control/Cranes.cpp14
-rw-r--r--src/control/Cranes.h61
-rw-r--r--src/control/GameLogic.cpp572
-rw-r--r--src/control/GameLogic.h24
-rw-r--r--src/control/Garages.cpp49
-rw-r--r--src/control/Garages.h1
-rw-r--r--src/control/OnscreenTimer.h96
-rw-r--r--src/control/PathFind.cpp167
-rw-r--r--src/control/PathFind.h12
-rw-r--r--src/control/Pickups.cpp2501
-rw-r--r--src/control/Pickups.h271
-rw-r--r--src/control/PowerPoints.cpp42
-rw-r--r--src/control/PowerPoints.h50
-rw-r--r--src/control/Record.cpp526
-rw-r--r--src/control/Record.h90
-rw-r--r--src/control/Replay.cpp8
-rw-r--r--src/control/Restart.cpp434
-rw-r--r--src/control/RoadBlocks.cpp200
-rw-r--r--src/control/RoadBlocks.h2
-rw-r--r--src/control/Script.cpp34
-rw-r--r--src/control/Script.h31
-rw-r--r--src/control/TrafficLights.cpp334
-rw-r--r--src/control/TrafficLights.h7
-rw-r--r--src/core/Cam.cpp18
-rw-r--r--src/core/Camera.cpp68
-rw-r--r--src/core/Camera.h37
-rw-r--r--src/core/Collision.cpp83
-rw-r--r--src/core/Collision.h1
-rw-r--r--src/core/Debug.cpp2
-rw-r--r--src/core/FileLoader.cpp167
-rw-r--r--src/core/FileLoader.h3
-rw-r--r--src/core/FrontEndControls.cpp1881
-rw-r--r--src/core/FrontEndControls.h712
-rw-r--r--src/core/Frontend.cpp3031
-rw-r--r--src/core/Frontend.h259
-rw-r--r--src/core/Game.cpp20
-rw-r--r--src/core/Game.h1
-rw-r--r--src/core/MenuScreens.h207
-rw-r--r--src/core/Pad.cpp407
-rw-r--r--src/core/Pad.h18
-rw-r--r--src/core/PlayerInfo.cpp900
-rw-r--r--src/core/Pools.cpp345
-rw-r--r--src/core/Profile.cpp71
-rw-r--r--src/core/Profile.h28
-rw-r--r--src/core/Radar.cpp2813
-rw-r--r--src/core/Radar.h34
-rw-r--r--src/core/RwTexRead.cpp140
-rw-r--r--src/core/Stats.cpp303
-rw-r--r--src/core/Stats.h43
-rw-r--r--src/core/Streaming.cpp4
-rw-r--r--src/core/Timer.cpp36
-rw-r--r--src/core/Timer.h8
-rw-r--r--src/core/World.cpp2
-rw-r--r--src/core/World.h2
-rw-r--r--src/core/common.h6
-rw-r--r--src/core/config.h18
-rw-r--r--src/core/main.cpp1931
-rw-r--r--src/core/obrstr.cpp236
-rw-r--r--src/core/obrstr.h16
-rw-r--r--src/core/re3.cpp27
-rw-r--r--src/core/timebars.cpp240
-rw-r--r--src/core/timebars.h10
-rw-r--r--src/entities/Entity.cpp26
-rw-r--r--src/entities/Entity.h5
-rw-r--r--src/entities/Physical.cpp2
-rw-r--r--src/entities/Physical.h2
-rw-r--r--src/entities/Solid.h22
-rw-r--r--src/math/Matrix.h11
-rw-r--r--src/math/Vector.h2
-rw-r--r--src/modelinfo/BaseModelInfo.h4
-rw-r--r--src/modelinfo/MloModelInfo.h26
-rw-r--r--src/modelinfo/ModelInfo.cpp17
-rw-r--r--src/modelinfo/ModelInfo.h3
-rw-r--r--src/modelinfo/PedModelInfo.cpp2
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp21
-rw-r--r--src/modelinfo/XtraCompsModelInfo.h22
-rw-r--r--src/objects/CutsceneHead.cpp2
-rw-r--r--src/objects/Object.cpp285
-rw-r--r--src/objects/Object.h37
-rw-r--r--src/objects/ParticleObject.cpp2
-rw-r--r--src/peds/CivilianPed.cpp12
-rw-r--r--src/peds/Gangs.cpp (renamed from src/control/Gangs.cpp)18
-rw-r--r--src/peds/Gangs.h (renamed from src/control/Gangs.h)0
-rw-r--r--src/peds/Ped.cpp9
-rw-r--r--src/peds/PedIK.cpp4
-rw-r--r--src/peds/PedIK.h4
-rw-r--r--src/peds/PedType.h1
-rw-r--r--src/peds/PlayerPed.cpp3070
-rw-r--r--src/peds/Population.cpp86
-rw-r--r--src/peds/Population.h54
-rw-r--r--src/render/Clouds.cpp14
-rw-r--r--src/render/Coronas.cpp4
-rw-r--r--src/render/Fluff.cpp4
-rw-r--r--src/render/Hud.cpp275
-rw-r--r--src/render/Hud.h69
-rw-r--r--src/render/MBlur.cpp3
-rw-r--r--src/render/PlayerSkin.cpp (renamed from src/core/PlayerSkin.cpp)345
-rw-r--r--src/render/PlayerSkin.h (renamed from src/core/PlayerSkin.h)6
-rw-r--r--src/render/Renderer.h2
-rw-r--r--src/render/Rubbish.cpp422
-rw-r--r--src/render/Rubbish.h39
-rw-r--r--src/render/Shadows.h11
-rw-r--r--src/render/Skidmarks.cpp247
-rw-r--r--src/render/Skidmarks.h26
-rw-r--r--src/render/SpecialFX.cpp657
-rw-r--r--src/render/SpecialFX.h228
-rw-r--r--src/render/Sprite.cpp12
-rw-r--r--src/render/Sprite2d.cpp30
-rw-r--r--src/render/TexList.cpp41
-rw-r--r--src/render/TexList.h14
-rw-r--r--src/render/Timecycle.h3
-rw-r--r--src/render/Weather.cpp470
-rw-r--r--src/render/Weather.h22
-rw-r--r--src/rw/ClumpRead.cpp (renamed from src/core/RwClumpRead.cpp)0
-rw-r--r--src/rw/Lights.cpp (renamed from src/render/Lights.cpp)0
-rw-r--r--src/rw/Lights.h (renamed from src/render/Lights.h)0
-rw-r--r--src/rw/NodeName.cpp (renamed from src/core/NodeName.cpp)0
-rw-r--r--src/rw/NodeName.h (renamed from src/core/NodeName.h)0
-rw-r--r--src/rw/RwHelper.cpp (renamed from src/core/RwHelper.cpp)60
-rw-r--r--src/rw/RwHelper.h (renamed from src/core/RwHelper.h)1
-rw-r--r--src/rw/RwMatFX.cpp (renamed from src/core/RwMatFX.cpp)13
-rw-r--r--src/rw/TexRead.cpp349
-rw-r--r--src/rw/TxdStore.cpp (renamed from src/core/TxdStore.cpp)0
-rw-r--r--src/rw/TxdStore.h (renamed from src/core/TxdStore.h)0
-rw-r--r--src/rw/VisibilityPlugins.cpp (renamed from src/render/VisibilityPlugins.cpp)2
-rw-r--r--src/rw/VisibilityPlugins.h (renamed from src/render/VisibilityPlugins.h)0
-rw-r--r--src/rw/rw.cpp (renamed from src/core/rw.cpp)428
-rw-r--r--src/save/Date.h34
-rw-r--r--src/save/GenericGameStorage.cpp189
-rw-r--r--src/save/GenericGameStorage.h78
-rw-r--r--src/skel/win/win.cpp14
-rw-r--r--src/text/Pager.cpp386
-rw-r--r--src/text/Pager.h54
-rw-r--r--src/vehicles/Automobile.cpp44
-rw-r--r--src/vehicles/Bike.h15
-rw-r--r--src/vehicles/Boat.cpp693
-rw-r--r--src/vehicles/Boat.h49
-rw-r--r--src/vehicles/CarGen.cpp (renamed from src/control/CarGen.cpp)88
-rw-r--r--src/vehicles/CarGen.h (renamed from src/control/CarGen.h)12
-rw-r--r--src/vehicles/Cranes.cpp671
-rw-r--r--src/vehicles/Cranes.h97
-rw-r--r--src/vehicles/Floater.cpp2
-rw-r--r--src/vehicles/Vehicle.cpp49
-rw-r--r--src/vehicles/Vehicle.h5
-rw-r--r--src/weapons/Explosion.cpp428
-rw-r--r--src/weapons/Explosion.h25
-rw-r--r--src/weapons/ProjectileInfo.h62
161 files changed, 26917 insertions, 12255 deletions
diff --git a/README.md b/README.md
index 3f98c9a5..c7d83212 100644
--- a/README.md
+++ b/README.md
@@ -16,12 +16,6 @@ such that we have a working game at all times.
- Since re3 is a DLL that works with original GTA III for now, you need Simple DLL Loader. You can get it [here](https://github.com/aap/simpledllloader).
- Build re3 or download it from one of the above links (Debug or Release).
- Make sure you included the re3 in `plugins.cfg` or `dlls.cfg`.
-- re3 starts the script `main_freeroam.scm` that comes along with it by default, so you should copy it to from `gamefiles/` to your game's `data/` directory.
-
-![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice**
-
-If you want to load original script/story, press and hold G while game is loading.
-This includes both starting new game and loading save game.
![#ffa500](https://placehold.it/15/ffa500/000000?text=+) **Notice if you will build it**
@@ -38,35 +32,19 @@ to reverse at the time, calling the original functions is acceptable.
### Unreversed / incomplete classes (at least the ones we know)
```
-cAudioManager - WIP
-CBoat
-CBrightLights
CBulletInfo
-CCrane
-CCranes
-CCullZone
-CCullZones
-CExplosion
-CFallingGlassPane
-CGlass
-CMenuManager - WIP
-CMotionBlurStreaks
-CObject
-CPacManPickups
CPedPath
-CRecordDataForChase
-CRoadBlocks
-CRubbish
-CSceneEdit
-CSkidmarks
-CSpecialFX
-CStats
-CTrafficLights
CWeapon
-CWeather
CWorld
```
+The following classes have only unused or practically unused code left:
+```
+CCullZone - only mobile stuff
+CCullZones - only mobile stuff
+CSceneEdit
+```
+
### Coding style
I started writing in [Plan 9 style](http://man.cat-v.org/plan_9/6/style),
diff --git a/gamefiles/menu.txd b/gamefiles/menu.txd
new file mode 100644
index 00000000..f617bcf8
--- /dev/null
+++ b/gamefiles/menu.txd
Binary files differ
diff --git a/premake5.lua b/premake5.lua
index 9e3609b6..4ec2eca1 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -1,5 +1,5 @@
workspace "re3"
- configurations { "Debug", "Release", "ReleaseFH" }
+ configurations { "Debug", "Release", "ReleaseFH", "DebugRW", "ReleaseRW" }
location "build"
files { "src/*.*" }
@@ -13,6 +13,7 @@ workspace "re3"
files { "src/objects/*.*" }
files { "src/peds/*.*" }
files { "src/render/*.*" }
+ files { "src/rw/*.*" }
files { "src/save/*.*" }
files { "src/skel/*.*" }
files { "src/skel/win/*.*" }
@@ -32,6 +33,7 @@ workspace "re3"
includedirs { "src/objects" }
includedirs { "src/peds" }
includedirs { "src/render" }
+ includedirs { "src/rw" }
includedirs { "src/save/" }
includedirs { "src/skel/" }
includedirs { "src/skel/win" }
@@ -47,6 +49,12 @@ workspace "re3"
libdirs { "dxsdk/lib" }
libdirs { "milessdk/lib" }
+
+ filter "configurations:DebugRW or configurations:ReleaseRW"
+ defines { "RWLIBS" }
+ libdirs { "rwsdk/lib/d3d8/release" }
+ links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp" }
+ filter {}
pbcommands = {
"setlocal EnableDelayedExpansion",
@@ -102,3 +110,15 @@ project "re3"
staticruntime "on"
targetextension ".asi"
setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "scripts/")
+
+ filter "configurations:DebugRW"
+ defines { "DEBUG" }
+ staticruntime "on"
+ symbols "On"
+ setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "plugins/")
+
+ filter "configurations:ReleaseRW"
+ defines { "NDEBUG" }
+ optimize "On"
+ staticruntime "on"
+ setpaths("$(GTA_III_RE_DIR)/", "gta3.exe", "plugins/")
diff --git a/src/core/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp
index 283f34b8..6f8e9790 100644
--- a/src/core/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -134,8 +134,8 @@ uint32 &CCutsceneMgr::ms_cutsceneLoadStatus = *(uint32*)0x95CB40;
RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
{
- float radius = RpAtomicGetBoundingSphereMacro(atomic)->radius;
- RwV3d center = RpAtomicGetBoundingSphereMacro(atomic)->center;
+ float radius = RpAtomicGetBoundingSphere(atomic)->radius;
+ RwV3d center = RpAtomicGetBoundingSphere(atomic)->center;
for (RwFrame *frame = RpAtomicGetFrame(atomic); RwFrameGetParent(frame); frame = RwFrameGetParent(frame))
RwV3dTransformPoints(&center, &center, 1, RwFrameGetMatrix(frame));
@@ -326,7 +326,7 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
pModelInfo->SetColModel(pColModel);
clump = (RpClump*)pModelInfo->GetRwObject();
- assert(RwObjectGetType(clump) == rpCLUMP);
+ assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
pColModel->boundingSphere.radius = radius;
@@ -352,6 +352,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
ms_pCutsceneObjects[ms_numCutsceneObjs]->DeleteRwObject();
delete ms_pCutsceneObjects[ms_numCutsceneObjs];
+ ms_pCutsceneObjects[ms_numCutsceneObjs] = nil;
}
ms_numCutsceneObjs = 0;
@@ -409,7 +410,7 @@ CCutsceneMgr::Update(void)
if (!ms_running) return;
- ms_cutsceneTimer += CTimer::GetTimeStepNonClipped() * 0.02f;
+ ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds();
if (CGeneral::faststricmp(ms_cutsceneName, "end") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
if (CPad::GetPad(0)->GetCrossJustDown()
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
diff --git a/src/core/CutsceneMgr.h b/src/animation/CutsceneMgr.h
index 7b809964..3c915eea 100644
--- a/src/core/CutsceneMgr.h
+++ b/src/animation/CutsceneMgr.h
@@ -26,7 +26,7 @@ public:
static CDirectory *&ms_pCutsceneDir;
static uint32 &ms_cutsceneLoadStatus;
- static void SetRunning(bool running) { ms_running = running; }
+ static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; }
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp
index 850fafda..fecd079e 100644
--- a/src/audio/AudioCollision.cpp
+++ b/src/audio/AudioCollision.cpp
@@ -1,403 +1,419 @@
-#include "common.h"
-#include "patcher.h"
-#include "DMAudio.h"
-#include "Entity.h"
-#include "AudioCollision.h"
-#include "AudioManager.h"
-#include "AudioSamples.h"
-#include "SurfaceTable.h"
-#include "sampman.h"
-
-const int CollisionSoundIntensity = 60;
-
-void
-cAudioCollisionManager::AddCollisionToRequestedQueue()
-{
- int32 collisionsIndex;
- int32 i;
-
-
- if (m_bCollisionsInQueue < NUMAUDIOCOLLISIONS)
- collisionsIndex = m_bCollisionsInQueue++;
- else {
- collisionsIndex = m_bIndicesTable[NUMAUDIOCOLLISIONS - 1];
- if (m_sQueue.m_fDistance >= m_asCollisions1[collisionsIndex].m_fDistance) return;
- }
-
- m_asCollisions1[collisionsIndex] = m_sQueue;
-
- i = 0;
- if(collisionsIndex) {
- while(m_asCollisions1[m_bIndicesTable[i]].m_fDistance <= m_asCollisions1[collisionsIndex].m_fDistance) {
- if(++i >= collisionsIndex) {
- m_bIndicesTable[i] = collisionsIndex;
- return;
- }
- }
- memmove(&m_bIndicesTable[i + 1], &m_bIndicesTable[i], NUMAUDIOCOLLISIONS - 1 - i);
- }
- 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
-{
- float result;
-
- switch(a) {
- case SURFACE_DEFAULT:
- case SURFACE_TARMAC:
- case SURFACE_PAVEMENT:
- case SURFACE_STONE:
- case SURFACE_BOLLARD: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
- case SURFACE_GRASS:
- case SURFACE_LOOSE30: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_DIRT: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_DIRTTRACK: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_METAL6: 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_SCAFFOLD:
- case SURFACE_STEEL: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
- case SURFACE_METAL_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
- case SURFACE_BILLBOARD: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
- case SURFACE_METAL_POLE:
- case SURFACE_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
- case SURFACE_STREET_LIGHT: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
- case SURFACE_METAL14: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
- case SURFACE_METAL15: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
- case SURFACE_METAL_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
- case SURFACE_FLESH: 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_PUDDLE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
- case SURFACE_WOOD: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
- case SURFACE_WOOD_BOX: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
- case SURFACE_WOOD_PLANK: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
- case SURFACE_TIRE:
- case SURFACE_RUBBER29: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
- case SURFACE_HARD24: 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_METAL27: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
- case SURFACE_METAL28: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break;
- default: result = 0.f; break;
- }
-
- return result;
-}
-
-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;
-}
-
-uint32
-cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(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_PUDDLE || surface2 == SURFACE_PUDDLE) {
- 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_DIRT || surface2 == SURFACE_DIRT || surface1 == SURFACE_DIRTTRACK ||
- surface2 == SURFACE_DIRTTRACK || 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_FLESH || surface2 == SURFACE_FLESH) { return 0; }
- 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;
-}
-
-void
-cAudioManager::SetUpLoopingCollisionSound(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_bVolume =
- ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
- if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = counter;
- m_sQueueSample.m_vecPos = col->m_vecPosition;
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 7;
- m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 4.0f;
- m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 5;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- }
- }
-}
-
-void
-cAudioManager::SetUpOneShotCollisionSound(cAudioCollision *col)
-{
- static const int32 gOneShotCol[] = {
- SFX_COL_TARMAC_1, SFX_COL_TARMAC_1, SFX_COL_GRASS_1,
- SFX_COL_GRAVEL_1, SFX_COL_MUD_1, SFX_COL_TARMAC_1,
- SFX_COL_CAR_1, SFX_COL_GRASS_1, SFX_COL_SCAFFOLD_POLE_1,
- SFX_COL_GARAGE_DOOR_1, SFX_COL_CAR_PANEL_1, SFX_COL_THICK_METAL_PLATE_1,
- SFX_COL_SCAFFOLD_POLE_1, SFX_COL_LAMP_POST_1, SFX_COL_HYDRANT_1,
- SFX_COL_HYDRANT_1, SFX_COL_METAL_CHAIN_FENCE_1, SFX_COL_PED_1,
- SFX_COL_SAND_1, SFX_SPLASH_1, SFX_COL_WOOD_CRATES_1,
- SFX_COL_WOOD_BENCH_1, SFX_COL_WOOD_SOLID_1, SFX_COL_GRASS_1,
- SFX_COL_GRASS_1, SFX_COL_VEG_1, SFX_COL_TARMAC_1,
- SFX_COL_CONTAINER_1, SFX_COL_NEWS_VENDOR_1, SFX_TYRE_BUMP,
- SFX_COL_CARDBOARD_1, SFX_COL_TARMAC_1, SFX_COL_GATE};
-
- int16 s1;
- int16 s2;
-
- int32 emittingVol;
- float ratio;
-
- static uint16 counter = 28;
-
- for(int32 i = 0; i < 2; i++) {
- if(i) {
- s1 = col->m_bSurface2;
- s2 = col->m_bSurface1;
- } else {
- s1 = col->m_bSurface1;
- s2 = col->m_bSurface2;
- }
- ratio = GetCollisionOneShotRatio(s1, col->m_fIntensity1);
- if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio = 0.25f * ratio;
- if(s1 == SURFACE_METAL6 && ratio < 0.6f) {
- s1 = SURFACE_BILLBOARD;
- ratio = min(1.f, 2.f * ratio);
- }
- emittingVol = 40.f * ratio;
- if(emittingVol) {
- m_sQueueSample.m_fDistance = Sqrt(col->m_fDistance);
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
- if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_nSampleIndex = gOneShotCol[s1];
- switch(m_sQueueSample.m_nSampleIndex) {
- case SFX_COL_TARMAC_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 5;
- break;
- case SFX_COL_CAR_PANEL_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[0] % 6;
- break;
- case SFX_COL_LAMP_POST_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 2;
- break;
- case SFX_COL_METAL_CHAIN_FENCE_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4;
- break;
- case SFX_COL_PED_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 5;
- break;
- case SFX_COL_WOOD_CRATES_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4;
- break;
- case SFX_COL_WOOD_BENCH_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 4;
- break;
- case SFX_COL_VEG_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 5;
- break;
- case SFX_COL_NEWS_VENDOR_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 3;
- break;
- case SFX_COL_CAR_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 5;
- break;
- case SFX_COL_CARDBOARD_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 2;
- break;
- default: break;
- }
- switch(s1) {
- case SURFACE_GLASS: m_sQueueSample.m_nFrequency = 13500; break;
- case SURFACE_METAL15: m_sQueueSample.m_nFrequency = 8819; break;
- case SURFACE_PUDDLE:
- m_sQueueSample.m_nFrequency =
- 2 * SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- break;
- case SURFACE_TIRE: m_sQueueSample.m_nFrequency = 6000; break;
- case SURFACE_HARD24: m_sQueueSample.m_nFrequency = 8000; break;
- default:
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- break;
- }
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
- m_sQueueSample.m_counter = counter++;
- if(counter >= 255) counter = 28;
- m_sQueueSample.m_vecPos = col->m_vecPosition;
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 11;
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.field_48 = 4.0f;
- m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- }
- }
-}
-
-void
-cAudioManager::ServiceCollisions()
-{
- int i, j;
- bool someArr1[NUMAUDIOCOLLISIONS];
- bool someArr2[NUMAUDIOCOLLISIONS];
-
- m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
-
- for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
- someArr1[i] = someArr2[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)
- ) {
- someArr1[index] = true;
- someArr2[j] = true;
- m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
- SetUpLoopingCollisionSound(&m_sCollisionManager.m_asCollisions1[index], j);
- break;
- }
- }
- }
-
- for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
- if (!someArr2[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;
- }
- }
-
- for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
- int index = m_sCollisionManager.m_bIndicesTable[i];
- if (!someArr1[index]) {
- for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
- if (someArr2[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;
-}
-
-void
-cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
- float velocity)
-{
- float distSquared;
- CVector v1;
- CVector v2;
-
- if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_bUserPause ||
- (velocity < 0.0016f && collisionPower < 0.01f))
- return;
-
- 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();
- }
-}
-
-STARTPATCHES
-InjectHook(0x5685E0, &cAudioCollisionManager::AddCollisionToRequestedQueue, PATCH_JUMP);
-InjectHook(0x569060, &cAudioManager::GetCollisionOneShotRatio, PATCH_JUMP);
-InjectHook(0x5693B0, &cAudioManager::GetCollisionRatio, PATCH_JUMP);
-InjectHook(0x568410, &cAudioManager::ReportCollision, PATCH_JUMP);
-InjectHook(0x5686D0, &cAudioManager::ServiceCollisions, PATCH_JUMP);
-InjectHook(0x568E20, &cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol, PATCH_JUMP);
-InjectHook(0x568D30, &cAudioManager::SetUpLoopingCollisionSound, PATCH_JUMP);
-InjectHook(0x5689D0, &cAudioManager::SetUpOneShotCollisionSound, PATCH_JUMP);
-ENDPATCHES
+#include "common.h"
+#include "patcher.h"
+#include "DMAudio.h"
+#include "Entity.h"
+#include "AudioCollision.h"
+#include "AudioManager.h"
+#include "AudioSamples.h"
+#include "SurfaceTable.h"
+#include "sampman.h"
+
+const int CollisionSoundIntensity = 60;
+
+cAudioCollisionManager::cAudioCollisionManager()
+{
+ 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);
+
+ for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
+ m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
+
+ m_bCollisionsInQueue = 0;
+}
+
+void
+cAudioCollisionManager::AddCollisionToRequestedQueue()
+{
+ int32 collisionsIndex;
+ int32 i;
+
+
+ if (m_bCollisionsInQueue < NUMAUDIOCOLLISIONS)
+ collisionsIndex = m_bCollisionsInQueue++;
+ else {
+ collisionsIndex = m_bIndicesTable[NUMAUDIOCOLLISIONS - 1];
+ if (m_sQueue.m_fDistance >= m_asCollisions1[collisionsIndex].m_fDistance) return;
+ }
+
+ m_asCollisions1[collisionsIndex] = m_sQueue;
+
+ i = 0;
+ if(collisionsIndex) {
+ while(m_asCollisions1[m_bIndicesTable[i]].m_fDistance <= m_asCollisions1[collisionsIndex].m_fDistance) {
+ if(++i >= collisionsIndex) {
+ m_bIndicesTable[i] = collisionsIndex;
+ return;
+ }
+ }
+ memmove(&m_bIndicesTable[i + 1], &m_bIndicesTable[i], NUMAUDIOCOLLISIONS - 1 - i);
+ }
+ 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
+{
+ float result;
+
+ switch(a) {
+ case SURFACE_DEFAULT:
+ case SURFACE_TARMAC:
+ case SURFACE_PAVEMENT:
+ case SURFACE_STONE:
+ case SURFACE_BOLLARD: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
+ case SURFACE_GRASS:
+ case SURFACE_LOOSE30: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
+ case SURFACE_DIRT: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
+ case SURFACE_DIRTTRACK: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
+ case SURFACE_METAL6: 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_SCAFFOLD:
+ case SURFACE_STEEL: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
+ case SURFACE_METAL_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
+ case SURFACE_BILLBOARD: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
+ case SURFACE_METAL_POLE:
+ case SURFACE_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
+ case SURFACE_STREET_LIGHT: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
+ case SURFACE_METAL14: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
+ case SURFACE_METAL15: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
+ case SURFACE_METAL_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
+ case SURFACE_FLESH: 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_PUDDLE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
+ case SURFACE_WOOD: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
+ case SURFACE_WOOD_BOX: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
+ case SURFACE_WOOD_PLANK: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
+ case SURFACE_TIRE:
+ case SURFACE_RUBBER29: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
+ case SURFACE_HARD24: 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_METAL27: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
+ case SURFACE_METAL28: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break;
+ default: result = 0.f; break;
+ }
+
+ return result;
+}
+
+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;
+}
+
+uint32
+cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(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_PUDDLE || surface2 == SURFACE_PUDDLE) {
+ 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_DIRT || surface2 == SURFACE_DIRT || surface1 == SURFACE_DIRTTRACK ||
+ surface2 == SURFACE_DIRTTRACK || 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_FLESH || surface2 == SURFACE_FLESH) { return 0; }
+ 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;
+}
+
+void
+cAudioManager::SetUpLoopingCollisionSound(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_bVolume =
+ ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
+ if(m_sQueueSample.m_bVolume) {
+ m_sQueueSample.m_nCounter = counter;
+ m_sQueueSample.m_vecPos = col->m_vecPosition;
+ m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_bEmittingVolume = emittingVol;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(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();
+ }
+ }
+ }
+}
+
+void
+cAudioManager::SetUpOneShotCollisionSound(cAudioCollision *col)
+{
+ static const int32 gOneShotCol[] = {
+ SFX_COL_TARMAC_1, SFX_COL_TARMAC_1, SFX_COL_GRASS_1,
+ SFX_COL_GRAVEL_1, SFX_COL_MUD_1, SFX_COL_TARMAC_1,
+ SFX_COL_CAR_1, SFX_COL_GRASS_1, SFX_COL_SCAFFOLD_POLE_1,
+ SFX_COL_GARAGE_DOOR_1, SFX_COL_CAR_PANEL_1, SFX_COL_THICK_METAL_PLATE_1,
+ SFX_COL_SCAFFOLD_POLE_1, SFX_COL_LAMP_POST_1, SFX_COL_HYDRANT_1,
+ SFX_COL_HYDRANT_1, SFX_COL_METAL_CHAIN_FENCE_1, SFX_COL_PED_1,
+ SFX_COL_SAND_1, SFX_SPLASH_1, SFX_COL_WOOD_CRATES_1,
+ SFX_COL_WOOD_BENCH_1, SFX_COL_WOOD_SOLID_1, SFX_COL_GRASS_1,
+ SFX_COL_GRASS_1, SFX_COL_VEG_1, SFX_COL_TARMAC_1,
+ SFX_COL_CONTAINER_1, SFX_COL_NEWS_VENDOR_1, SFX_TYRE_BUMP,
+ SFX_COL_CARDBOARD_1, SFX_COL_TARMAC_1, SFX_COL_GATE};
+
+ int16 s1;
+ int16 s2;
+
+ int32 emittingVol;
+ float ratio;
+
+ static uint16 counter = 28;
+
+ for(int32 i = 0; i < 2; i++) {
+ if(i) {
+ s1 = col->m_bSurface2;
+ s2 = col->m_bSurface1;
+ } else {
+ s1 = col->m_bSurface1;
+ s2 = col->m_bSurface2;
+ }
+ ratio = GetCollisionOneShotRatio(s1, col->m_fIntensity1);
+ if(s1 == SURFACE_METAL6 && s2 == SURFACE_FLESH) ratio = 0.25f * ratio;
+ if(s1 == SURFACE_METAL6 && ratio < 0.6f) {
+ s1 = SURFACE_BILLBOARD;
+ ratio = min(1.f, 2.f * ratio);
+ }
+ emittingVol = 40.f * ratio;
+ if(emittingVol) {
+ m_sQueueSample.m_fDistance = Sqrt(col->m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
+ if(m_sQueueSample.m_bVolume) {
+ m_sQueueSample.m_nSampleIndex = gOneShotCol[s1];
+ switch(m_sQueueSample.m_nSampleIndex) {
+ case SFX_COL_TARMAC_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 5;
+ break;
+ case SFX_COL_CAR_PANEL_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[0] % 6;
+ break;
+ case SFX_COL_LAMP_POST_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 2;
+ break;
+ case SFX_COL_METAL_CHAIN_FENCE_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4;
+ break;
+ case SFX_COL_PED_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 5;
+ break;
+ case SFX_COL_WOOD_CRATES_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4;
+ break;
+ case SFX_COL_WOOD_BENCH_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 4;
+ break;
+ case SFX_COL_VEG_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 5;
+ break;
+ case SFX_COL_NEWS_VENDOR_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[2] % 3;
+ break;
+ case SFX_COL_CAR_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[1] % 5;
+ break;
+ case SFX_COL_CARDBOARD_1:
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 2;
+ break;
+ default: break;
+ }
+ switch(s1) {
+ case SURFACE_GLASS: m_sQueueSample.m_nFrequency = 13500; break;
+ case SURFACE_METAL15: m_sQueueSample.m_nFrequency = 8819; break;
+ case SURFACE_PUDDLE:
+ m_sQueueSample.m_nFrequency =
+ 2 * SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ break;
+ case SURFACE_TIRE: m_sQueueSample.m_nFrequency = 6000; break;
+ case SURFACE_HARD24: m_sQueueSample.m_nFrequency = 8000; break;
+ default:
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ break;
+ }
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ m_sQueueSample.m_nCounter = counter++;
+ if(counter >= 255) counter = 28;
+ m_sQueueSample.m_vecPos = col->m_vecPosition;
+ m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 11;
+ m_sQueueSample.m_nLoopCount = 1;
+ m_sQueueSample.m_bEmittingVolume = emittingVol;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+ }
+}
+
+void
+cAudioManager::ServiceCollisions()
+{
+ int i, j;
+ bool someArr1[NUMAUDIOCOLLISIONS];
+ bool someArr2[NUMAUDIOCOLLISIONS];
+
+ m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
+
+ for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
+ someArr1[i] = someArr2[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)
+ ) {
+ someArr1[index] = true;
+ someArr2[j] = true;
+ m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
+ SetUpLoopingCollisionSound(&m_sCollisionManager.m_asCollisions1[index], j);
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
+ if (!someArr2[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;
+ }
+ }
+
+ for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
+ int index = m_sCollisionManager.m_bIndicesTable[i];
+ if (!someArr1[index]) {
+ for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
+ if (someArr2[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;
+}
+
+void
+cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
+ float velocity)
+{
+ float distSquared;
+ CVector v1;
+ CVector v2;
+
+ if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_bUserPause ||
+ (velocity < 0.0016f && collisionPower < 0.01f))
+ return;
+
+ 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();
+ }
+}
+
+STARTPATCHES
+InjectHook(0x5685E0, &cAudioCollisionManager::AddCollisionToRequestedQueue, PATCH_JUMP);
+InjectHook(0x569060, &cAudioManager::GetCollisionOneShotRatio, PATCH_JUMP);
+InjectHook(0x5693B0, &cAudioManager::GetCollisionRatio, PATCH_JUMP);
+InjectHook(0x568410, &cAudioManager::ReportCollision, PATCH_JUMP);
+InjectHook(0x5686D0, &cAudioManager::ServiceCollisions, PATCH_JUMP);
+InjectHook(0x568E20, &cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol, PATCH_JUMP);
+InjectHook(0x568D30, &cAudioManager::SetUpLoopingCollisionSound, PATCH_JUMP);
+InjectHook(0x5689D0, &cAudioManager::SetUpOneShotCollisionSound, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/audio/AudioCollision.h b/src/audio/AudioCollision.h
index cf201735..a21bbfdc 100644
--- a/src/audio/AudioCollision.h
+++ b/src/audio/AudioCollision.h
@@ -1,36 +1,36 @@
-#pragma once
-
-#define NUMAUDIOCOLLISIONS 10
-
-class cAudioCollision
-{
-public:
- CEntity *m_pEntity1;
- CEntity *m_pEntity2;
- uint8 m_bSurface1;
- uint8 m_bSurface2;
- float m_fIntensity1;
- float m_fIntensity2;
- CVector m_vecPosition;
- float m_fDistance;
- int32 m_nBaseVolume;
-
- // no methods
-};
-
-static_assert(sizeof(cAudioCollision) == 40, "cAudioCollision: error");
-
-class cAudioCollisionManager
-{
-public:
- cAudioCollision m_asCollisions1[NUMAUDIOCOLLISIONS];
- cAudioCollision m_asCollisions2[NUMAUDIOCOLLISIONS];
- uint8 m_bIndicesTable[NUMAUDIOCOLLISIONS];
- uint8 m_bCollisionsInQueue;
- cAudioCollision m_sQueue;
-
- // reversed all methods
- void AddCollisionToRequestedQueue(); /// ok
-};
-
+#pragma once
+
+#define NUMAUDIOCOLLISIONS 10
+
+class cAudioCollision
+{
+public:
+ CEntity *m_pEntity1;
+ CEntity *m_pEntity2;
+ uint8 m_bSurface1;
+ uint8 m_bSurface2;
+ float m_fIntensity1;
+ float m_fIntensity2;
+ CVector m_vecPosition;
+ float m_fDistance;
+ int32 m_nBaseVolume;
+
+ // no methods
+};
+
+static_assert(sizeof(cAudioCollision) == 40, "cAudioCollision: error");
+
+class cAudioCollisionManager
+{
+public:
+ cAudioCollision m_asCollisions1[NUMAUDIOCOLLISIONS];
+ cAudioCollision m_asCollisions2[NUMAUDIOCOLLISIONS];
+ uint8 m_bIndicesTable[NUMAUDIOCOLLISIONS];
+ uint8 m_bCollisionsInQueue;
+ cAudioCollision m_sQueue;
+
+ cAudioCollisionManager();
+ void AddCollisionToRequestedQueue();
+};
+
static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error"); \ No newline at end of file
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index 8e8d024a..1d2835cf 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -1,8 +1,7 @@
-#include "common.h"
+#include "common.h"
#include "patcher.h"
-#include "General.h"
-#include "audio_enums.h"
+#include "audio_enums.h"
#include "AudioManager.h"
#include "Automobile.h"
@@ -13,14 +12,15 @@
#include "DMAudio.h"
#include "Entity.h"
#include "Explosion.h"
+#include "Fire.h"
#include "Garages.h"
+#include "General.h"
#include "HandlingMgr.h"
#include "Heli.h"
#include "ModelIndices.h"
#include "MusicManager.h"
#include "Pad.h"
#include "Ped.h"
-#include "Fire.h"
#include "Physical.h"
#include "Placeable.h"
#include "Plane.h"
@@ -39,20 +39,19 @@
#include "ZoneCull.h"
#include "sampman.h"
-cAudioManager &AudioManager = *(cAudioManager *)0x880FC0;
-uint32 &gPornNextTime = *(uint32*)0x6508A0;
-uint32 &gSawMillNextTime = *(uint32*)0x6508A4;
-uint32 &gShopNextTime = *(uint32*)0x6508A8;
-uint32 &gAirportNextTime = *(uint32*)0x6508AC;
-uint32 &gCinemaNextTime = *(uint32*)0x6508B0;
-uint32 &gDocksNextTime = *(uint32*)0x6508B4;
-uint32 &gHomeNextTime = *(uint32*)0x6508B8;
-uint32 &gCellNextTime = *(uint32*)0x6508BC;
-uint32 &gNextCryTime = *(uint32*)0x6508C0;
-uint8 &jumboVolOffset = *(uint8 *)0x6508ED;
-uint8 &gJumboVolOffsetPercentage = *(uint8 *)0x6508ED;
-bool &bPlayerJustEnteredCar = *(bool *)0x6508C4;
-bool &g_bMissionAudioLoadFailed = *(bool *)0x95CD8E;
+cAudioManager AudioManager;
+uint32 gPornNextTime; // = *(uint32*)0x6508A0;
+uint32 gSawMillNextTime; // = *(uint32*)0x6508A4;
+uint32 gShopNextTime; // = *(uint32*)0x6508A8;
+uint32 gAirportNextTime; // = *(uint32*)0x6508AC;
+uint32 gCinemaNextTime; //= *(uint32*)0x6508B0;
+uint32 gDocksNextTime; // = *(uint32*)0x6508B4;
+uint32 gHomeNextTime; // = *(uint32*)0x6508B8;
+uint32 gCellNextTime; // = *(uint32*)0x6508BC;
+uint32 gNextCryTime; // = *(uint32*)0x6508C0;
+uint8 gJumboVolOffsetPercentage; // = *(uint8 *)0x6508ED;
+bool bPlayerJustEnteredCar; // = *(bool *)0x6508C4;
+bool g_bMissionAudioLoadFailed; // = *(bool *)0x95CD8E;
const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
const int policeChannel = channels + 1;
@@ -70,39 +69,46 @@ const int rainOnVehicleIntensity = 22;
const int reverseGearIntensity = 30;
const int engineDamageIntensity = 40;
-
const bool hornPatternsArray[8][44] = {
- {false, false, true, true, true, true, true, true, true, true, true, true, true, true, true,
- true, true, false, false, false, false, false, false, true, true, true, true, true, true, true,
- true, true, true, true, true, true, true, true, true, true, false, false, false, false},
+ {false, false, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, false, false, false, false, false,
+ false, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, false, false, false, false},
{false, false, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, false, false},
- {false, false, true, true, true, true, true, true, true, true, true, true, false, false, false,
- false, true, true, true, true, true, false, false, false, true, true, true, true, true, true,
- true, true, true, true, true, true, true, true, true, true, true, true, true, false},
- {false, false, true, true, true, true, true, false, false, true, true, true, true, true, false,
- false, false, true, true, true, true, true, true, true, true, true, true, false, false, false,
- true, true, true, true, true, true, true, true, true, true, true, true, true, false},
- {false, false, true, true, true, true, true, true, true, true, true, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false, false, false},
- {false, false, true, true, true, false, false, false, true, true, true, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false, false, false},
- {false, false, true, true, true, true, false, false, false, false, true, true, true, false, false,
- true, true, true, false, false, true, true, true, true, true, true, false, false, false, false,
- false, true, true, true, true, true, true, true, true, true, true, true, false, false},
- {false, false, true, true, true, true, false, false, true, true, true, true, true, false, false,
- false, true, true, true, true, true, true, false, false, false, false, true, true, true, true,
- true, true, true, true, true, true, true, true, true, false, false, false, false, false},
+ {false, false, true, true, true, true, true, true, true, true, true,
+ true, false, false, false, false, true, true, true, true, true, false,
+ false, false, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true, true, false},
+ {false, false, true, true, true, true, true, false, false, true, true,
+ true, true, true, false, false, false, true, true, true, true, true,
+ true, true, true, true, true, false, false, false, true, true, true,
+ true, true, true, true, true, true, true, true, true, true, false},
+ {false, false, true, true, true, true, true, true, true, true, true,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false},
+ {false, false, true, true, true, false, false, false, true, true, true,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false},
+ {false, false, true, true, true, true, false, false, false, false, true,
+ true, true, false, false, true, true, true, false, false, true, true,
+ true, true, true, true, false, false, false, false, false, true, true,
+ true, true, true, true, true, true, true, true, true, false, false},
+ {false, false, true, true, true, true, false, false, true, true, true,
+ true, true, false, false, false, true, true, true, true, true, true,
+ false, false, false, false, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, false, false, false, false, false},
};
const int totalAudioEntitiesSlots = 200;
-const uint8 panTable[64]{0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45,
- 46, 47, 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59,
- 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63};
+const uint8 panTable[64]{0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37,
+ 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53,
+ 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61,
+ 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63};
// TODO: where is this used? Is this the right file?
enum eVehicleModel {
@@ -178,37 +184,60 @@ enum eVehicleModel {
CAR159,
};
+enum PLAY_STATUS : uint8 {
+ PLAY_STATUS_STOPPED = 0,
+ PLAY_STATUS_PLAYING = 1,
+ PLAY_STATUS_FINISHED = 2
+};
+
+enum LOADING_STATUS : uint8 { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED = 1 };
+
+cPedComments::cPedComments()
+{
+ for (int i = 0; i < NUM_PED_COMMENTS_SLOTS; i++)
+ for (int j = 0; j < NUM_PED_COMMENTS_BANKS; j++) {
+ m_asPedComments[j][i].m_nProcess = -1;
+ m_nIndexMap[j][i] = NUM_PED_COMMENTS_SLOTS;
+ }
+
+ for (int i = 0; i < NUM_PED_COMMENTS_BANKS; i++)
+ m_nCommentsInBank[i] = 0;
+ m_nActiveBank = 0;
+}
+
void
cPedComments::Add(tPedComment *com)
{
uint8 index;
- if(nrOfCommentsInBank[activeBank] >= NUM_PED_COMMENTS_SLOTS) {
- index = indexMap[activeBank][NUM_PED_COMMENTS_SLOTS - 1];
- if(m_asPedComments[activeBank][index].m_bVolume > com->m_bVolume) return;
+ if(m_nCommentsInBank[m_nActiveBank] >= NUM_PED_COMMENTS_SLOTS) {
+ index = m_nIndexMap[m_nActiveBank][NUM_PED_COMMENTS_SLOTS - 1];
+ if(m_asPedComments[m_nActiveBank][index].m_bVolume > com->m_bVolume) return;
} else {
- index = nrOfCommentsInBank[activeBank]++;
+ index = m_nCommentsInBank[m_nActiveBank]++;
}
- m_asPedComments[activeBank][index].m_nSampleIndex = com->m_nSampleIndex;
- m_asPedComments[activeBank][index].m_entityIndex = com->m_entityIndex;
- m_asPedComments[activeBank][index].m_vecPos = com->m_vecPos;
- m_asPedComments[activeBank][index].m_fDistance = com->m_fDistance;
- m_asPedComments[activeBank][index].m_bVolume = com->m_bVolume;
+ m_asPedComments[m_nActiveBank][index].m_nSampleIndex = com->m_nSampleIndex;
+ m_asPedComments[m_nActiveBank][index].m_nEntityIndex = com->m_nEntityIndex;
+ m_asPedComments[m_nActiveBank][index].m_vecPos = com->m_vecPos;
+ m_asPedComments[m_nActiveBank][index].m_fDistance = com->m_fDistance;
+ m_asPedComments[m_nActiveBank][index].m_bVolume = com->m_bVolume;
uint32 i = 0;
if(index != 0) {
for(i = 0; i < index; i++) {
- if(m_asPedComments[activeBank][indexMap[activeBank][i]].m_bVolume <
- m_asPedComments[activeBank][index].m_bVolume) {
+ if(m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][i]].m_bVolume <
+ m_asPedComments[m_nActiveBank][index].m_bVolume) {
break;
}
}
- if(i < index) memmove(&indexMap[activeBank][i + 1], &indexMap[activeBank][i], NUM_PED_COMMENTS_SLOTS -1 - i);
+ if(i < index)
+ memmove(&m_nIndexMap[m_nActiveBank][i + 1], &m_nIndexMap[m_nActiveBank][i],
+ NUM_PED_COMMENTS_SLOTS - 1 - i);
}
- indexMap[activeBank][i] = index;
+ m_nIndexMap[m_nActiveBank][i] = index;
}
void
@@ -222,36 +251,42 @@ cPedComments::Process()
static const int policeHeliIntensity = 400;
if(!AudioManager.m_bUserPause) {
- if(nrOfCommentsInBank[activeBank]) {
- sampleIndex = m_asPedComments[activeBank][indexMap[activeBank][0]].m_nSampleIndex;
- if(!SampleManager.IsPedCommentLoaded(sampleIndex)) SampleManager.LoadPedComment(sampleIndex);
+ if(m_nCommentsInBank[m_nActiveBank]) {
+ sampleIndex = m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]]
+ .m_nSampleIndex;
+ if(!SampleManager.IsPedCommentLoaded(sampleIndex))
+ SampleManager.LoadPedComment(sampleIndex);
AudioManager.m_sQueueSample.m_nEntityIndex =
- m_asPedComments[activeBank][indexMap[activeBank][0]].m_entityIndex;
- AudioManager.m_sQueueSample.m_counter = 0;
+ m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]]
+ .m_nEntityIndex;
+ AudioManager.m_sQueueSample.m_nCounter = 0;
AudioManager.m_sQueueSample.m_nSampleIndex = sampleIndex;
AudioManager.m_sQueueSample.m_bBankIndex = SAMPLEBANK_PED;
- AudioManager.m_sQueueSample.field_16 = 3;
+ AudioManager.m_sQueueSample.m_nReleasingVolumeModificator = 3;
AudioManager.m_sQueueSample.m_bVolume =
- m_asPedComments[activeBank][indexMap[activeBank][0]].m_bVolume;
+ m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_bVolume;
AudioManager.m_sQueueSample.m_fDistance =
- m_asPedComments[activeBank][indexMap[activeBank][0]].m_fDistance;
+ m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]]
+ .m_fDistance;
AudioManager.m_sQueueSample.m_nLoopCount = 1;
AudioManager.m_sQueueSample.m_nLoopStart = 0;
AudioManager.m_sQueueSample.m_nLoopEnd = -1;
AudioManager.m_sQueueSample.m_bEmittingVolume = maxVolume;
- AudioManager.m_sQueueSample.field_48 = 3.0f;
+ AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f;
switch(sampleIndex) {
case SFX_POLICE_HELI_1:
case SFX_POLICE_HELI_2:
case SFX_POLICE_HELI_3:
AudioManager.m_sQueueSample.m_fSoundIntensity = policeHeliIntensity;
break;
- default: AudioManager.m_sQueueSample.m_fSoundIntensity = defaultIntensity; break;
+ default:
+ AudioManager.m_sQueueSample.m_fSoundIntensity = defaultIntensity;
+ break;
}
- AudioManager.m_sQueueSample.field_56 = 1;
+ AudioManager.m_sQueueSample.m_bReleasingSoundFlag = true;
AudioManager.m_sQueueSample.m_vecPos =
- m_asPedComments[activeBank][indexMap[activeBank][0]].m_vecPos;
+ m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_vecPos;
if(sampleIndex >= SFX_AMMU_D && sampleIndex <= SFX_AMMU_F) {
AudioManager.m_sQueueSample.m_bReverbFlag = false;
@@ -261,34 +296,73 @@ cPedComments::Process()
AudioManager.m_sQueueSample.m_bRequireReflection = true;
}
- AudioManager.m_sQueueSample.m_bIsDistant = false;
+ AudioManager.m_sQueueSample.m_bIs2D = false;
AudioManager.m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(AudioManager.m_sQueueSample.m_nSampleIndex) +
+ SampleManager.GetSampleBaseFrequency(
+ AudioManager.m_sQueueSample.m_nSampleIndex) +
AudioManager.RandomDisplacement(750);
- if(CTimer::GetIsSlowMotionActive()) AudioManager.m_sQueueSample.m_nFrequency /= 2;
- m_asPedComments[activeBank][indexMap[activeBank][0]].field_25 = -1;
+ if(CTimer::GetIsSlowMotionActive())
+ AudioManager.m_sQueueSample.m_nFrequency /= 2;
+ m_asPedComments[m_nActiveBank][m_nIndexMap[m_nActiveBank][0]].m_nProcess =
+ -1;
AudioManager.AddSampleToRequestedQueue();
}
// Switch bank
- if(activeBank) {
+ if(m_nActiveBank) {
actualUsedBank = SAMPLEBANK_PED;
- activeBank = SAMPLEBANK_MAIN;
+ m_nActiveBank = SAMPLEBANK_MAIN;
} else {
actualUsedBank = SAMPLEBANK_MAIN;
- activeBank = SAMPLEBANK_PED;
+ m_nActiveBank = SAMPLEBANK_PED;
}
comment = m_asPedComments[actualUsedBank];
- for(uint32 i = 0; i < nrOfCommentsInBank[actualUsedBank]; i++) {
- if(m_asPedComments[actualUsedBank][indexMap[actualUsedBank][i]].field_25 > 0) {
- --m_asPedComments[actualUsedBank][indexMap[actualUsedBank][i]].field_25;
- Add(&comment[indexMap[actualUsedBank][i]]);
+ for(uint32 i = 0; i < m_nCommentsInBank[actualUsedBank]; i++) {
+ if(m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]]
+ .m_nProcess > 0) {
+ --m_asPedComments[actualUsedBank][m_nIndexMap[actualUsedBank][i]]
+ .m_nProcess;
+ Add(&comment[m_nIndexMap[actualUsedBank][i]]);
}
}
- for(uint32 i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) { indexMap[actualUsedBank][i] = NUM_PED_COMMENTS_SLOTS; }
- nrOfCommentsInBank[actualUsedBank] = 0;
+ for(uint32 i = 0; i < NUM_PED_COMMENTS_SLOTS; i++) {
+ m_nIndexMap[actualUsedBank][i] = NUM_PED_COMMENTS_SLOTS;
+ }
+ m_nCommentsInBank[actualUsedBank] = 0;
+ }
+}
+
+cAudioManager::cAudioManager()
+{
+ m_bIsInitialised = false;
+ field_1 = 1;
+ m_fSpeedOfSound = 6.86f;
+ m_bTimeSpent = 50;
+ m_bActiveSamples = NUM_SOUNDS_SAMPLES_SLOTS;
+ m_bActiveSampleQueue = 1;
+ ClearRequestedQueue();
+ m_bActiveSampleQueue = 0;
+ ClearRequestedQueue();
+ ClearActiveSamples();
+ GenerateIntegerRandomNumberTable();
+ field_4 = 0;
+ m_bDynamicAcousticModelingStatus = 1;
+
+ for(int i = 0; i < NUM_AUDIOENTITIES; i++) {
+ m_asAudioEntities[i].m_bIsUsed = false;
+ m_anAudioEntityIndices[i] = NUM_AUDIOENTITIES;
}
+ m_nAudioEntitiesTotal = 0;
+ m_FrameCounter = 0;
+ m_bFifthFrameFlag = 0;
+ m_bTimerJustReset = 0;
+ m_nTimer = 0;
+}
+
+cAudioManager::~cAudioManager()
+{
+ if(m_bIsInitialised) Terminate();
}
void
@@ -297,42 +371,47 @@ cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
uint32 i = 0;
if(sample != 0) {
for(; i < sample; i++) {
- if(m_asSamples[m_bActiveSampleQueue][m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]]
- .calculatedVolume > m_asSamples[m_bActiveSampleQueue][sample].calculatedVolume)
+ if(m_asSamples[m_bActiveSampleQueue]
+ [m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]]
+ .m_nCalculatedVolume >
+ m_asSamples[m_bActiveSampleQueue][sample].m_nCalculatedVolume)
break;
}
if(i < sample) {
memmove(&m_abSampleQueueIndexTable[m_bActiveSampleQueue][i + 1],
- &m_abSampleQueueIndexTable[m_bActiveSampleQueue][i], m_bActiveSamples - i - 1);
+ &m_abSampleQueueIndexTable[m_bActiveSampleQueue][i],
+ m_bActiveSamples - i - 1);
}
}
m_abSampleQueueIndexTable[m_bActiveSampleQueue][i] = sample;
}
void
-cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 unk1, uint8 counter,
- bool notLooping)
+cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 unk1,
+ uint8 counter, bool notLooping)
{
m_sQueueSample.m_bVolume = ComputeVolume(emittingVolume, 50.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = counter;
+ m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_nSampleIndex = sample;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_nFrequency = freq;
if(notLooping) {
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_76 = 8;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
} else {
m_sQueueSample.m_nLoopCount = 1;
}
m_sQueueSample.m_bEmittingVolume = emittingVolume;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
- m_sQueueSample.field_56 = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -354,18 +433,20 @@ cAudioManager::AddReflectionsToRequestedQueue()
if(m_sQueueSample.m_bLoopsRemaining > 5) {
m_sQueueSample.m_fDistance = m_afReflectionsDistances[i];
m_sQueueSample.m_bEmittingVolume = emittingVolume;
- m_sQueueSample.m_bVolume = ComputeVolume(
- emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume > emittingVolume >> 4) {
- m_sQueueSample.m_counter += ((i + 1) << 8);
+ m_sQueueSample.m_nCounter += ((i + 1) << 8);
if(m_sQueueSample.m_nLoopCount) {
- noise = RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ noise = RandomDisplacement(
+ m_sQueueSample.m_nFrequency >> 5);
if(noise <= 0)
m_sQueueSample.m_nFrequency += noise;
else
m_sQueueSample.m_nFrequency -= noise;
}
- m_sQueueSample.field_16 += 20;
+ m_sQueueSample.m_nReleasingVolumeModificator += 20;
m_sQueueSample.m_vecPos = m_avecReflectionsPos[i];
AddSampleToRequestedQueue();
}
@@ -377,46 +458,51 @@ cAudioManager::AddReflectionsToRequestedQueue()
void
cAudioManager::AddReleasingSounds()
{
- bool toProcess[44];
+ bool toProcess[44]; // why not 27?
int8 queue = m_bActiveSampleQueue == 0;
for(int32 i = 0; i < m_bSampleRequestQueuesStatus[queue]; i++) {
tSound &sample = m_asSamples[queue][m_abSampleQueueIndexTable[queue][i]];
- if (sample.m_bLoopEnded) continue;
+ if(sample.m_bLoopEnded) continue;
toProcess[i] = false;
for(int32 j = 0; j < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; j++) {
if(sample.m_nEntityIndex ==
- m_asSamples[m_bActiveSampleQueue]
- [m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
- .m_nEntityIndex &&
- sample.m_counter == m_asSamples[m_bActiveSampleQueue]
- [m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
- .m_counter) {
+ m_asSamples[m_bActiveSampleQueue]
+ [m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
+ .m_nEntityIndex &&
+ sample.m_nCounter ==
+ m_asSamples[m_bActiveSampleQueue]
+ [m_abSampleQueueIndexTable[m_bActiveSampleQueue][j]]
+ .m_nCounter) {
toProcess[i] = true;
break;
}
}
if(!toProcess[i]) {
- if(sample.m_counter <= 255 || !sample.m_bLoopsRemaining) {
- if(!sample.field_76) continue;
+ if(sample.m_nCounter <= 255 || !sample.m_bLoopsRemaining) {
+ if(!sample.m_nReleasingVolumeDivider) continue;
if(!sample.m_nLoopCount) {
- if(sample.field_88 == -1) {
- sample.field_88 = sample.m_bVolume / sample.field_76;
- if(sample.field_88 <= 0) sample.field_88 = 1;
+ if(sample.m_nVolumeChange == -1) {
+ sample.m_nVolumeChange =
+ sample.m_bVolume /
+ sample.m_nReleasingVolumeDivider;
+ if(sample.m_nVolumeChange <= 0)
+ sample.m_nVolumeChange = 1;
}
- if(sample.m_bVolume <= sample.field_88) {
- sample.field_76 = 0;
+ if(sample.m_bVolume <= sample.m_nVolumeChange) {
+ sample.m_nReleasingVolumeDivider = 0;
continue;
}
- sample.m_bVolume -= sample.field_88;
+ sample.m_bVolume -= sample.m_nVolumeChange;
}
- --sample.field_76;
- if(field_2) {
- if(sample.field_16 < 20) ++sample.field_16;
+ --sample.m_nReleasingVolumeDivider;
+ if(m_bFifthFrameFlag) {
+ if(sample.m_nReleasingVolumeModificator < 20)
+ ++sample.m_nReleasingVolumeModificator;
}
- sample.field_56 = 0;
+ sample.m_bReleasingSoundFlag = 0;
}
memcpy(&m_sQueueSample, &sample, sizeof(tSound));
AddSampleToRequestedQueue();
@@ -432,17 +518,21 @@ cAudioManager::AddSampleToRequestedQueue()
bool bReflections;
if(m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) {
- calculatedVolume = m_sQueueSample.field_16 * (maxVolume - m_sQueueSample.m_bVolume);
+ calculatedVolume = m_sQueueSample.m_nReleasingVolumeModificator *
+ (maxVolume - m_sQueueSample.m_bVolume);
sampleIndex = m_bSampleRequestQueuesStatus[m_bActiveSampleQueue];
if(sampleIndex >= m_bActiveSamples) {
- sampleIndex = m_abSampleQueueIndexTable[m_bActiveSampleQueue][m_bActiveSamples - 1];
- if(m_asSamples[m_bActiveSampleQueue][sampleIndex].calculatedVolume <= calculatedVolume) return;
+ sampleIndex =
+ m_abSampleQueueIndexTable[m_bActiveSampleQueue][m_bActiveSamples - 1];
+ if(m_asSamples[m_bActiveSampleQueue][sampleIndex].m_nCalculatedVolume <=
+ calculatedVolume)
+ return;
} else {
++m_bSampleRequestQueuesStatus[m_bActiveSampleQueue];
}
- m_sQueueSample.calculatedVolume = calculatedVolume;
- m_sQueueSample.m_bLoopEnded = 0;
- if(m_sQueueSample.m_bIsDistant) {
+ m_sQueueSample.m_nCalculatedVolume = calculatedVolume;
+ m_sQueueSample.m_bLoopEnded = false;
+ if(m_sQueueSample.m_bIs2D) {
m_sQueueSample.m_bRequireReflection = false;
m_sQueueSample.m_bLoopsRemaining = 0;
}
@@ -483,27 +573,27 @@ cAudioManager::ClearActiveSamples()
{
for(int32 i = 0; i < m_bActiveSamples; i++) {
m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE;
- m_asActiveSamples[i].m_counter = 0;
+ m_asActiveSamples[i].m_nCounter = 0;
m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE;
m_asActiveSamples[i].m_bBankIndex = SAMPLEBANK_INVALID;
- m_asActiveSamples[i].m_bIsDistant = false;
- m_asActiveSamples[i].field_16 = 5;
+ m_asActiveSamples[i].m_bIs2D = false;
+ m_asActiveSamples[i].m_nReleasingVolumeModificator = 5;
m_asActiveSamples[i].m_nFrequency = 0;
m_asActiveSamples[i].m_bVolume = 0;
m_asActiveSamples[i].m_bEmittingVolume = 0;
m_asActiveSamples[i].m_fDistance = 0.0f;
- m_asActiveSamples[i].m_bIsProcessed = 0;
- m_asActiveSamples[i].m_bLoopEnded = 0;
+ m_asActiveSamples[i].m_bIsProcessed = false;
+ m_asActiveSamples[i].m_bLoopEnded = false;
m_asActiveSamples[i].m_nLoopCount = 1;
m_asActiveSamples[i].m_nLoopStart = 0;
m_asActiveSamples[i].m_nLoopEnd = -1;
- m_asActiveSamples[i].field_48 = 0.0f;
+ m_asActiveSamples[i].m_fSpeedMultiplier = 0.0f;
m_asActiveSamples[i].m_fSoundIntensity = 200.0f;
m_asActiveSamples[i].m_bOffset = 63;
- m_asActiveSamples[i].field_56 = 0;
- m_asActiveSamples[i].calculatedVolume = 0;
- m_asActiveSamples[i].field_76 = 0;
- m_asActiveSamples[i].field_88 = -1;
+ m_asActiveSamples[i].m_bReleasingSoundFlag = 0;
+ m_asActiveSamples[i].m_nCalculatedVolume = 0;
+ m_asActiveSamples[i].m_nReleasingVolumeDivider = 0;
+ m_asActiveSamples[i].m_nVolumeChange = -1;
m_asActiveSamples[i].m_vecPos = {0.0f, 0.0f, 0.0f};
m_asActiveSamples[i].m_bReverbFlag = false;
m_asActiveSamples[i].m_bLoopsRemaining = 0;
@@ -516,12 +606,12 @@ cAudioManager::ClearMissionAudio()
{
if(m_bIsInitialised) {
m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
- m_sMissionAudio.m_bLoadingStatus = 0;
- m_sMissionAudio.m_bPlayStatus = 0;
+ m_sMissionAudio.m_bLoadingStatus = LOADING_STATUS_NOT_LOADED;
+ m_sMissionAudio.m_bPlayStatus = PLAY_STATUS_STOPPED;
m_sMissionAudio.field_22 = 0;
m_sMissionAudio.m_bIsPlayed = false;
- m_sMissionAudio.field_12 = 1;
- m_sMissionAudio.field_24 = 0;
+ m_sMissionAudio.m_bPredefinedProperties = 1;
+ m_sMissionAudio.m_nMissionAudioCounter = 0;
}
}
@@ -542,14 +632,15 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
if(!TheCamera.Get_Just_Switched_Status() && speedMultiplier != 0.0f) {
float dist = position2 - position1;
if(dist != 0.0f) {
- float speedOfSource = (dist / field_19195) * speedMultiplier;
- if(speedOfSound > Abs(speedOfSource)) {
+ float speedOfSource = (dist / m_bTimeSpent) * speedMultiplier;
+ if(m_fSpeedOfSound > Abs(speedOfSource)) {
if(speedOfSource < 0.0f) {
speedOfSource = max(speedOfSource, -1.5f);
} else {
speedOfSource = min(speedOfSource, 1.5f);
}
- newFreq = (oldFreq * speedOfSound) / (speedOfSource + speedOfSound);
+ newFreq =
+ (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound);
}
}
}
@@ -573,7 +664,9 @@ cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float d
if((soundIntensity * 0.2f) <= distance) {
newSoundIntensity = soundIntensity * 0.2f;
emittingVolume =
- sq((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) / (soundIntensity - newSoundIntensity)) * emittingVolume;
+ sq((soundIntensity - newSoundIntensity - (distance - newSoundIntensity)) /
+ (soundIntensity - newSoundIntensity)) *
+ emittingVolume;
}
return emittingVolume;
}
@@ -618,7 +711,8 @@ cAudioManager::DestroyAllGameCreatedEntities()
case AUDIOTYPE_GARAGE:
case AUDIOTYPE_FIREHYDRANT: DestroyEntity(i); break;
case AUDIOTYPE_SCRIPTOBJECT:
- entity = (cAudioScriptObject *)m_asAudioEntities[i].m_pEntity;
+ entity =
+ (cAudioScriptObject *)m_asAudioEntities[i].m_pEntity;
if(entity) {
delete entity;
m_asAudioEntities[i].m_pEntity = nil;
@@ -629,21 +723,25 @@ cAudioManager::DestroyAllGameCreatedEntities()
}
}
}
- m_nScriptObjectEntityTotal = 0;
+ m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
}
}
void
cAudioManager::DestroyEntity(int32 id)
{
- if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots && m_asAudioEntities[id].m_bIsUsed) {
+ if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots &&
+ m_asAudioEntities[id].m_bIsUsed) {
m_asAudioEntities[id].m_bIsUsed = false;
for(int32 i = 0; i < m_nAudioEntitiesTotal; ++i) {
if(id == m_anAudioEntityIndices[i]) {
if(i < totalAudioEntitiesSlots - 1)
- memmove(&m_anAudioEntityIndices[i], &m_anAudioEntityIndices[i + 1],
- 4 * (m_nAudioEntitiesTotal - (i + 1)));
- m_anAudioEntityIndices[--m_nAudioEntitiesTotal] = totalAudioEntitiesSlots;
+ memmove(&m_anAudioEntityIndices[i],
+ &m_anAudioEntityIndices[i + 1],
+ NUM_AUDIOENTITY_EVENTS *
+ (m_nAudioEntitiesTotal - (i + 1)));
+ m_anAudioEntityIndices[--m_nAudioEntitiesTotal] =
+ totalAudioEntitiesSlots;
return;
}
}
@@ -653,7 +751,8 @@ cAudioManager::DestroyEntity(int32 id)
void
cAudioManager::DoJumboVolOffset() const
{
- if(!(m_FrameCounter % (m_anRandomTable[0] % 6 + 3))) jumboVolOffset = m_anRandomTable[1] % 60;
+ if(!(m_FrameCounter % (m_anRandomTable[0] % 6 + 3)))
+ gJumboVolOffsetPercentage = m_anRandomTable[1] % 60;
}
uint32
@@ -684,11 +783,14 @@ cAudioManager::GetCopTalkSfx(int16 sound)
if(sound != SOUND_PED_PURSUIT_COP) { return GetGenericMaleTalkSfx(sound); }
pedState = FindPlayerPed()->m_nPedState;
- if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) return NO_SAMPLE;
+ if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE)
+ return NO_SAMPLE;
GetPhrase(&sfx, &lastSfx, SFX_COP_VOICE_1_CHASE_1, 7);
}
- return (SFX_COP_VOICE_2_ARREST_1 - SFX_COP_VOICE_1_ARREST_1) * (m_sQueueSample.m_nEntityIndex % 5) + sfx;
+ return (SFX_COP_VOICE_2_ARREST_1 - SFX_COP_VOICE_1_ARREST_1) *
+ (m_sQueueSample.m_nEntityIndex % 5) +
+ sfx;
}
uint32
@@ -704,11 +806,14 @@ cAudioManager::GetSwatTalkSfx(int16 sound)
if(sound != SOUND_PED_PURSUIT_SWAT) { return GetGenericMaleTalkSfx(sound); }
pedState = FindPlayerPed()->m_nPedState;
- if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) return NO_SAMPLE;
+ if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE)
+ return NO_SAMPLE;
GetPhrase(&sfx, &lastSfx, SFX_SWAT_VOICE_1_CHASE_1, 6);
}
- return (SFX_SWAT_VOICE_2_CHASE_1 - SFX_SWAT_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+ return (SFX_SWAT_VOICE_2_CHASE_1 - SFX_SWAT_VOICE_1_CHASE_1) *
+ (m_sQueueSample.m_nEntityIndex % 4) +
+ sfx;
}
uint32
@@ -724,11 +829,14 @@ cAudioManager::GetFBITalkSfx(int16 sound)
if(sound != SOUND_PED_PURSUIT_FBI) { return GetGenericMaleTalkSfx(sound); }
pedState = FindPlayerPed()->m_nPedState;
- if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) return NO_SAMPLE;
+ if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE)
+ return NO_SAMPLE;
GetPhrase(&sfx, &lastSfx, SFX_FBI_VOICE_1_CHASE_1, 6);
}
- return (SFX_FBI_VOICE_2_CHASE_1 - SFX_FBI_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+ return (SFX_FBI_VOICE_2_CHASE_1 - SFX_FBI_VOICE_1_CHASE_1) *
+ (m_sQueueSample.m_nEntityIndex % 3) +
+ sfx;
}
uint32
@@ -741,10 +849,13 @@ cAudioManager::GetArmyTalkSfx(int16 sound)
if(sound != SOUND_PED_PURSUIT_ARMY) { return GetGenericMaleTalkSfx(sound); }
pedState = FindPlayerPed()->m_nPedState;
- if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE) return NO_SAMPLE;
+ if(pedState == PED_ARRESTED || pedState == PED_DEAD || pedState == PED_DIE)
+ return NO_SAMPLE;
GetPhrase(&sfx, &lastSfx, SFX_ARMY_VOICE_1_CHASE_1, 15);
- return (SFX_ARMY_VOICE_2_CHASE_1 - SFX_ARMY_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_ARMY_VOICE_2_CHASE_1 - SFX_ARMY_VOICE_1_CHASE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -754,14 +865,24 @@ cAudioManager::GetMedicTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_GUN_PANIC_1, 5); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_CARJACKED_1, 5); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_GUN_PANIC_1, 5);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_CARJACKED_1, 5);
+ break;
case SOUND_PED_HEALING: GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_AT_VICTIM_1, 12); break;
- case SOUND_PED_LEAVE_VEHICLE: GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1, 9); break;
- case SOUND_PED_FLEE_RUN: GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_1, 6); break;
+ case SOUND_PED_LEAVE_VEHICLE:
+ GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1, 9);
+ break;
+ case SOUND_PED_FLEE_RUN:
+ GetPhrase(&sfx, &lastSfx, SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_1, 6);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
- return (SFX_MEDIC_VOICE_2_GUN_PANIC_1 - SFX_MEDIC_VOICE_1_GUN_PANIC_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_MEDIC_VOICE_2_GUN_PANIC_1 - SFX_MEDIC_VOICE_1_GUN_PANIC_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -777,10 +898,14 @@ cAudioManager::GetNormalMaleTalkSfx(int16 sound)
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_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_FLEE_RUN:
+ GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_RUN_FROM_FIGHT_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_NORMAL_MALE_DRIVER_ABUSE_1, 12);
break;
@@ -804,7 +929,10 @@ cAudioManager::GetTaxiDriverTalkSfx(int16 sound)
if(sound != SOUND_PED_CAR_COLLISION) return GetGenericMaleTalkSfx(sound);
GetPhrase(&sfx, &lastSfx, SFX_ASIAN_TAXI_DRIVER_VOICE_1_DRIVER_ABUSE_1, 6);
}
- 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;
+ 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
@@ -833,16 +961,26 @@ cAudioManager::GetMafiaTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_CAR_JACKING: GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKING_1, 2); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_CAR_JACKING:
+ GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKING_1, 2);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKED_1, 2);
+ break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_FIGHT_1, 5); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_DODGE_1, 5); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1, 6); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_EYING_1, 3); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_EYING_1, 3);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_MAFIA_MALE_VOICE_1_CHAT_1, 7); break;
default: return GetGenericMaleTalkSfx(sound);
}
- return (SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+ return (SFX_MAFIA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_MAFIA_MALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 3) +
+ sfx;
}
uint32
@@ -852,13 +990,23 @@ cAudioManager::GetTriadTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_UP: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_GUN_COOL_1, 3); break;
- case SOUND_PED_CAR_JACKING: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKING_1, 2); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_HANDS_UP:
+ GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_GUN_COOL_1, 3);
+ break;
+ case SOUND_PED_CAR_JACKING:
+ GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKING_1, 2);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKED_1, 2);
+ break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_FIGHT_1, 5); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_DODGE_1, 4); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_1, 7); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_EYING_1, 3); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_DRIVER_ABUSE_1, 7);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_EYING_1, 3);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_TRIAD_MALE_VOICE_1_CHAT_1, 8); break;
default: return GetGenericMaleTalkSfx(sound);
}
@@ -872,21 +1020,33 @@ cAudioManager::GetDiabloTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_UP: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_GUN_COOL_1, 4); break;
+ case SOUND_PED_HANDS_UP:
+ GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_GUN_COOL_1, 4);
+ break;
case SOUND_PED_HANDS_COWER:
sound = SOUND_PED_FLEE_SPRINT;
return GetGenericMaleTalkSfx(sound);
break;
- case SOUND_PED_CAR_JACKING: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKING_1, 2); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_CAR_JACKING:
+ GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKING_1, 2);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKED_1, 2);
+ break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_FIGHT_1, 4); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_DODGE_1, 4); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_1, 5); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_EYING_1, 4); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_DRIVER_ABUSE_1, 5);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_EYING_1, 4);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_DIABLO_MALE_VOICE_1_CHAT_1, 5); break;
default: return GetGenericMaleTalkSfx(sound);
}
- return (SFX_DIABLO_MALE_VOICE_2_CHAT_1 - SFX_DIABLO_MALE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_DIABLO_MALE_VOICE_2_CHAT_1 - SFX_DIABLO_MALE_VOICE_1_CHAT_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -896,15 +1056,23 @@ cAudioManager::GetYakuzaTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_CAR_JACKING: GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKING_1, 2); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_CAR_JACKING:
+ GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKING_1, 2);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKED_1, 2);
+ break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_FIGHT_1, 5); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_DODGE_1, 4); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1, 6); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_YAKUZA_MALE_VOICE_1_CHAT_1, 5); break;
default: return GetGenericMaleTalkSfx(sound);
}
- return (SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_YAKUZA_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YAKUZA_MALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -915,16 +1083,24 @@ cAudioManager::GetYardieTalkSfx(int16 sound)
switch(sound) {
case SOUND_PED_HANDS_UP: sfx = SFX_YARDIE_MALE_VOICE_1_GUN_COOL_1; break;
- case SOUND_PED_CAR_JACKING: GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_CARJACKING_1, 2); break;
+ case SOUND_PED_CAR_JACKING:
+ GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_CARJACKING_1, 2);
+ break;
case SOUND_PED_CAR_JACKED: sfx = SFX_YARDIE_MALE_VOICE_1_CARJACKED_1; break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_FIGHT_1, 6); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_DODGE_1, 5); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1, 6); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_EYING_1, 2); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_EYING_1, 2);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_YARDIE_MALE_VOICE_1_CHAT_1, 8); break;
default: return GetGenericMaleTalkSfx(sound);
}
- return (SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_YARDIE_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_YARDIE_MALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -934,16 +1110,31 @@ cAudioManager::GetColumbianTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_CAR_JACKING: GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKING_1, 2); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKED_1, 2); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_1, 5); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_DODGE_1, 5); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1, 6); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_EYING_1, 2); break;
+ case SOUND_PED_CAR_JACKING:
+ GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKING_1, 2);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKED_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_1, 5);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_DODGE_1, 5);
+ break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_EYING_1, 2);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CHAT_1, 5); break;
default: return GetGenericMaleTalkSfx(sound);
}
- return (SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_COLUMBIAN_MALE_VOICE_2_DRIVER_ABUSE_1 -
+ SFX_COLUMBIAN_MALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -953,18 +1144,30 @@ cAudioManager::GetHoodTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_UP: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_GUN_COOL_1, 5); break;
- case SOUND_PED_CAR_JACKING: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKING_1, 2); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_HANDS_UP:
+ GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_GUN_COOL_1, 5);
+ break;
+ case SOUND_PED_CAR_JACKING:
+ GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKING_1, 2);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKED_1, 2);
+ break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_FIGHT_1, 6); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_DODGE_1, 5); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1, 7); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_EYING_1, 2); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1, 7);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_EYING_1, 2);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_HOOD_MALE_VOICE_1_CHAT_1, 6); break;
default: return GetGenericMaleTalkSfx(sound); break;
}
- return (SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_HOOD_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_HOOD_MALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -974,11 +1177,19 @@ cAudioManager::GetBlackCriminalTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_UP: GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_1, 4); break;
+ case SOUND_PED_HANDS_UP:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_1, 4);
+ break;
case SOUND_PED_CAR_JACKING: sfx = SFX_BLACK_CRIMINAL_VOICE_1_CARJACKING_1; break;
- case SOUND_PED_MUGGING: GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_MUGGING_1, 2); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_1, 5); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_DODGE_1, 6); break;
+ case SOUND_PED_MUGGING:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_MUGGING_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_1, 5);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_DODGE_1, 6);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_DRIVER_ABUSE_1, 5);
break;
@@ -994,11 +1205,19 @@ cAudioManager::GetWhiteCriminalTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_UP: GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_GUN_COOL_1, 3); break;
+ case SOUND_PED_HANDS_UP:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_GUN_COOL_1, 3);
+ break;
case SOUND_PED_CAR_JACKING: sfx = SFX_WHITE_CRIMINAL_VOICE_1_CARJACKING_1; break;
- case SOUND_PED_MUGGING: GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_MUGGING_1, 2); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_1, 4); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_MUGGING:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_MUGGING_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_1, 4);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_DRIVER_ABUSE_1, 4);
break;
@@ -1014,13 +1233,27 @@ cAudioManager::GetMaleNo2TalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_CARJACKED_1, 3); break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_1, 4); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_1, 4); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_1, 4); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 7); break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_EYING_1, 5); break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_CARJACKED_1, 3);
+ break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_1, 4);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_1, 4);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_1, 4);
+ break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 7);
+ break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_EYING_1, 5);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1033,13 +1266,21 @@ cAudioManager::GetBlackProjectMaleTalkSfx(int16 sound, int32 model)
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_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_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_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_MALE_VOICE_1_DRIVER_ABUSE_1, 7);
break;
@@ -1050,7 +1291,9 @@ cAudioManager::GetBlackProjectMaleTalkSfx(int16 sound, int32 model)
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);
+ 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;
}
@@ -1061,9 +1304,15 @@ cAudioManager::GetWhiteFatMaleTalkSfx(int16 sound)
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_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_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 9);
break;
@@ -1083,9 +1332,15 @@ cAudioManager::GetBlackFatMaleTalkSfx(int16 sound)
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_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_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
break;
@@ -1142,7 +1397,9 @@ cAudioManager::GetWhiteCasualFemaleTalkSfx(int16 sound)
GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_CARJACKED_1, 2);
break;
case SOUND_PED_ROBBED: sfx = SFX_WHITE_CASUAL_FEMALE_VOICE_1_MUGGED_1; break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_DODGE_1, 3); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_DODGE_1, 3);
+ break;
case SOUND_PED_FLEE_RUN:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 2);
break;
@@ -1152,7 +1409,9 @@ cAudioManager::GetWhiteCasualFemaleTalkSfx(int16 sound)
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_SHOCKED_1, 2);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_CHAT_1, 4); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_CHAT_1, 4);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1165,15 +1424,23 @@ cAudioManager::GetFemaleNo3TalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_GUN_PANIC_1, 5); break;
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_CARJACKED_1, 3); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_GUN_PANIC_1, 5);
+ break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_CARJACKED_1, 3);
+ break;
case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_MUGGED_1, 3); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_DODGE_1, 6); break;
- case SOUND_PED_FLEE_RUN: GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_1, 4); break;
+ case SOUND_PED_FLEE_RUN:
+ GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_1, 4);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_DRIVER_ABUSE_1, 6);
break;
- case SOUND_PED_CHAT_EVENT: GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_SHOCKED_1, 4); break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_SHOCKED_1, 4);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_FEMALE_3_VOICE_1_CHAT_1, 5); break;
default: return GetGenericFemaleTalkSfx(sound);
}
@@ -1193,15 +1460,21 @@ cAudioManager::GetBlackFatFemaleTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_1, 6);
break;
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_SHOCKED_1, 5);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1217,8 +1490,12 @@ cAudioManager::GetWhiteFatFemaleTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_1, 6); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_1, 6);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_DRIVER_ABUSE_1, 8);
break;
@@ -1228,7 +1505,9 @@ cAudioManager::GetWhiteFatFemaleTalkSfx(int16 sound)
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_SHOCKED_1, 4);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_1, 8); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_CHAT_1, 8);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1248,17 +1527,23 @@ cAudioManager::GetBlackFemaleProstituteTalkSfx(int16 sound)
case SOUND_PED_ATTACK:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_FIGHT_1, 4);
break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_DODGE_1, 3); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_DODGE_1, 3);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_DRIVER_ABUSE_1, 4);
break;
case SOUND_PED_SOLICIT:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_SOLICIT_1, 8);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1, 4); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1, 4);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
- return (SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_1 - SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_BLACK_PROSTITUTE_VOICE_2_CHAT_1 - SFX_BLACK_PROSTITUTE_VOICE_1_CHAT_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -1274,17 +1559,23 @@ cAudioManager::GetWhiteFemaleProstituteTalkSfx(int16 sound)
case SOUND_PED_ATTACK:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_FIGHT_1, 4);
break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_DODGE_1, 3); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_DODGE_1, 3);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_DRIVER_ABUSE_1, 4);
break;
case SOUND_PED_SOLICIT:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_SOLICIT_1, 8);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1, 4); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1, 4);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
- return (SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_1 - SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_WHITE_PROSTITUTE_VOICE_2_CHAT_1 - SFX_WHITE_PROSTITUTE_VOICE_1_CHAT_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -1312,7 +1603,9 @@ cAudioManager::GetBlackProjectFemaleOldTalkSfx(int16 sound)
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_SHOCKED_1, 2);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_1, 10); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CHAT_1, 10);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1341,7 +1634,9 @@ cAudioManager::GetBlackProjectFemaleYoungTalkSfx(int16 sound)
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_SHOCKED_1, 5);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1360,13 +1655,21 @@ cAudioManager::GetChinatownMaleOldTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_1, 5); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_1, 6); break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_1, 5);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_1, 6);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_DRIVER_ABUSE_1, 6);
break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_EYING_1, 3); break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_EYING_1, 3);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1385,15 +1688,21 @@ cAudioManager::GetChinatownMaleYoungTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_1, 6); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_1, 6);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DRIVER_ABUSE_1, 6);
break;
case SOUND_PED_CHAT_SEXY:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_EYING_1, 3);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_1, 6); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CHAT_1, 6);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1409,13 +1718,19 @@ cAudioManager::GetChinatownFemaleOldTalkSfx(int16 sound)
case SOUND_PED_HANDS_COWER:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_GUN_PANIC_1, 3);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5);
break;
case SOUND_PED_CHAT_EVENT: sfx = SFX_CHINATOWN_OLD_FEMALE_VOICE_1_SHOCKED_1; break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_1, 6); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_CHAT_1, 6);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1431,15 +1746,21 @@ cAudioManager::GetChinatownFemaleYoungTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_1, 6); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_1, 6);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_1, 7);
break;
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_SHOCKED_1, 4);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1458,16 +1779,27 @@ cAudioManager::GetLittleItalyMaleTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_1, 5); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_1, 5);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_1, 7);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_1, 6); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_CHAT_1, 6);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
- return (SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_LITTLE_ITALY_MALE_VOICE_2_DRIVER_ABUSE_1 -
+ SFX_LITTLE_ITALY_MALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -1480,15 +1812,21 @@ cAudioManager::GetLittleItalyFemaleOldTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CARJACKED_1, 2);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_1, 6); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_1, 6);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DRIVER_ABUSE_1, 7);
break;
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_SHOCKED_1, 4);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1507,14 +1845,18 @@ cAudioManager::GetLittleItalyFemaleYoungTalkSfx(int16 sound)
case SOUND_PED_ROBBED:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_MUGGED_1, 2);
break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_1, 7); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_1, 7);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DRIVER_ABUSE_1, 6);
break;
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_SHOCKED_1, 4);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_1, 6); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CHAT_1, 6);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1530,13 +1872,21 @@ cAudioManager::GetWhiteDockerMaleTalkSfx(int16 sound)
case SOUND_PED_HANDS_COWER:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_GUN_PANIC_1, 2);
break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_FIGHT_1, 3); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_1, 4); break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_FIGHT_1, 3);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_1, 4);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_DRIVER_ABUSE_1, 4);
break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_EYING_1, 3); break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_1, 5); break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_EYING_1, 3);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_CHAT_1, 5);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1552,12 +1902,16 @@ cAudioManager::GetBlackDockerMaleTalkSfx(int16 sound)
case SOUND_PED_HANDS_COWER:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_GUN_PANIC_1, 3);
break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_FIGHT_1, 5); break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_FIGHT_1, 5);
+ break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_DODGE_1, 5); break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_1, 6);
break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_EYING_1, 3); break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_EYING_1, 3);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_DOCKER_VOICE_1_CHAT_1, 5); break;
default: return GetGenericMaleTalkSfx(sound);
}
@@ -1571,15 +1925,21 @@ cAudioManager::GetScumMaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_GUN_PANIC_1, 5); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_GUN_PANIC_1, 5);
+ break;
case SOUND_PED_ROBBED: sfx = SFX_SCUM_MALE_VOICE_1_MUGGED_1; break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_FIGHT_1, 0xA); break;
+ case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_FIGHT_1, 10); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_DODGE_1, 5); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_1, 6); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
case SOUND_PED_WAIT_DOUBLEBACK:
GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_LOST_1, 3);
break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_EYING_1, 5); break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_EYING_1, 5);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_SCUM_MALE_VOICE_1_CHAT_1, 9); break;
default: return GetGenericMaleTalkSfx(sound);
}
@@ -1593,8 +1953,12 @@ cAudioManager::GetScumFemaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_1, 4); break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_MUGGED_1, 2); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_1, 4);
+ break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_FIGHT_1, 4); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_SCUM_FEMALE_VOICE_1_DODGE_1, 8); break;
case SOUND_PED_CAR_COLLISION:
@@ -1616,13 +1980,21 @@ cAudioManager::GetWhiteWorkerMaleTalkSfx(int16 sound)
case SOUND_PED_HANDS_COWER:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_GUN_PANIC_1, 3);
break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_FIGHT_1, 3); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_1, 4); break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_FIGHT_1, 3);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_1, 4);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_EYING_1, 2); break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_1, 6); break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_EYING_1, 2);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_CHAT_1, 6);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1638,13 +2010,21 @@ cAudioManager::GetBlackWorkerMaleTalkSfx(int16 sound)
case SOUND_PED_HANDS_COWER:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_GUN_PANIC_1, 4);
break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_FIGHT_1, 3); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_DODGE_1, 3); break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_FIGHT_1, 3);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_DODGE_1, 3);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_DRIVER_ABUSE_1, 4);
break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_EYING_1, 3); break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_CHAT_1, 4); break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_EYING_1, 3);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_CHAT_1, 4);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1663,20 +2043,30 @@ cAudioManager::GetBusinessMaleYoungTalkSfx(int16 sound, int32 model)
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_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_CAR_COLLISION:
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;
+ 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);
+ 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;
}
@@ -1693,14 +2083,24 @@ cAudioManager::GetBusinessMaleOldTalkSfx(int16 sound)
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_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_CAR_COLLISION:
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;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CHAT_1, 5);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1716,19 +2116,33 @@ cAudioManager::GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model)
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_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_CAR_COLLISION:
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;
+ 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);
+ 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;
}
@@ -1745,8 +2159,12 @@ cAudioManager::GetBlackBusinessFemaleTalkSfx(int16 sound)
case SOUND_PED_CAR_JACKED:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CARAJACKED_1, 4);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_MUGGED_1, 3); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_1, 6); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_MUGGED_1, 3);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_1, 6);
+ break;
case SOUND_PED_FLEE_RUN:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 6);
break;
@@ -1756,7 +2174,9 @@ cAudioManager::GetBlackBusinessFemaleTalkSfx(int16 sound)
case SOUND_PED_CHAT_EVENT:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_SHOCKED_1, 4);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1769,14 +2189,18 @@ cAudioManager::GetSupermodelMaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_CARJACKED_1, 2);
+ break;
case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_MUGGED_1, 2); break;
case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_FIGHT_1, 5); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_DODGE_1, 6); break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_DRIVER_ABUSE_1, 6);
break;
- case SOUND_PED_CHAT_SEXY: GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_EYING_1, 3); break;
+ case SOUND_PED_CHAT_SEXY:
+ GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_EYING_1, 3);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_MODEL_MALE_VOICE_1_CHAT_1, 6); break;
default: return GetGenericMaleTalkSfx(sound);
}
@@ -1793,7 +2217,9 @@ cAudioManager::GetSupermodelFemaleTalkSfx(int16 sound)
case SOUND_PED_HANDS_COWER:
GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_GUN_PANIC_1, 4);
break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_MUGGED_1, 3); break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_MUGGED_1, 3);
+ break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_DODGE_1, 4); break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_MODEL_FEMALE_VOICE_1_DRIVER_ABUSE_1, 7);
@@ -1814,8 +2240,12 @@ cAudioManager::GetStewardMaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_GUN_PANIC_1, 3); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_FIGHT_1, 4); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_GUN_PANIC_1, 3);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_FIGHT_1, 4);
+ break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_DODGE_1, 3); break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_STEWARD_MALE_VOICE_1_DRIVER_ABUSE_1, 5);
@@ -1836,14 +2266,19 @@ cAudioManager::GetStewardFemaleTalkSfx(int16 sound)
case SOUND_PED_HANDS_COWER:
GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_GUN_PANIC_1, 3);
break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5);
break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_STEWARD_FEMALE_VOICE_1_CHAT_1, 5); break;
default: return GetGenericFemaleTalkSfx(sound);
}
- return (SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_STEWARD_FEMALE_VOICE_2_DRIVER_ABUSE_1 -
+ SFX_STEWARD_FEMALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -1853,15 +2288,25 @@ cAudioManager::GetFanMaleTalkSfx(int16 sound, int32 model)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_FIGHT_1, 3); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_DODGE_1, 4); break;
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_1, 5); break;
- case SOUND_PED_CHAT_EVENT: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_SHOCKED_1, 2); break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_FIGHT_1, 3);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_DODGE_1, 4);
+ break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_1, 5);
+ break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_SHOCKED_1, 2);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_MALE_VOICE_1_CHAT_1, 6); break;
default: return GetGenericMaleTalkSfx(sound);
}
- if(model == MI_FAN_MAN2) sfx += (SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_1 - SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_1);
+ if(model == MI_FAN_MAN2)
+ sfx += (SFX_FOOTBALL_MALE_VOICE_2_DRIVER_ABUSE_1 -
+ SFX_FOOTBALL_MALE_VOICE_1_DRIVER_ABUSE_1);
return sfx;
}
@@ -1873,15 +2318,24 @@ cAudioManager::GetFanFemaleTalkSfx(int16 sound)
switch(sound) {
case SOUND_PED_ROBBED: sfx = SFX_FOOTBALL_FEMALE_VOICE_1_MUGGED_1; break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_1, 4); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_1, 4);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_1, 5);
break;
- case SOUND_PED_CHAT_EVENT: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_SHOCKED_1, 2); break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_1, 6); break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_SHOCKED_1, 2);
+ break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_CHAT_1, 6);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
- return (SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_1 - SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return (SFX_FOOTBALL_FEMALE_VOICE_2_DRIVER_ABUSE_1 -
+ SFX_FOOTBALL_FEMALE_VOICE_1_DRIVER_ABUSE_1) *
+ (m_sQueueSample.m_nEntityIndex % 2) +
+ sfx;
}
uint32
@@ -1891,9 +2345,15 @@ cAudioManager::GetHospitalMaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_1, 4); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_FIGHT_1, 4); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_DODGE_1, 4); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_1, 4);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_FIGHT_1, 4);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_DODGE_1, 4);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_MALE_VOICE_1_DRIVER_ABUSE_1, 5);
break;
@@ -1910,11 +2370,15 @@ cAudioManager::GetHospitalFemaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_DRIVER_ABUSE_1, 6);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_1, 6); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_CHAT_1, 6);
+ break;
default: return GetGenericFemaleTalkSfx(sound);
}
return sfx;
@@ -1934,14 +2398,18 @@ cAudioManager::GetWhiteConstructionWorkerTalkSfx(int16 sound)
case SOUND_PED_ATTACK:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_1, 5);
break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DRIVER_ABUSE_1, 4);
break;
case SOUND_PED_CHAT_SEXY:
GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_EYING_1, 3);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_1, 7); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CHAT_1, 7);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1963,14 +2431,18 @@ cAudioManager::GetBlackConstructionWorkerTalkSfx(int16 sound)
case SOUND_PED_ATTACK:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_1, 5);
break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_1, 5); break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_1, 5);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DRIVER_ABUSE_1, 5);
break;
case SOUND_PED_CHAT_SEXY:
GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_EYING_1, 4);
break;
- case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CHAT_1, 4); break;
+ case SOUND_PED_CHAT:
+ GetPhrase(&sfx, &lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CHAT_1, 4);
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -1983,13 +2455,17 @@ cAudioManager::GetShopperFemaleTalkSfx(int16 sound, int32 model)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_CAR_JACKED: GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_CARJACKED_1, 2); break;
+ case SOUND_PED_CAR_JACKED:
+ GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_CARJACKED_1, 2);
+ break;
case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_MUGGED_1, 2); break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_DODGE_1, 6); break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_DRIVER_ABUSE_1, 7);
break;
- case SOUND_PED_CHAT_EVENT: GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_SHOCKED_1, 4); break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_SHOCKED_1, 4);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_SHOPPER_VOICE_1_CHAT_1, 7); break;
default: return GetGenericFemaleTalkSfx(sound);
}
@@ -2009,14 +2485,22 @@ cAudioManager::GetStudentMaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_GUN_PANIC_1, 2); break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_FIGHT_1, 4); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_GUN_PANIC_1, 2);
+ break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_FIGHT_1, 4);
+ break;
case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_DODGE_1, 4); break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_DRIVER_ABUSE_1, 4);
break;
- case SOUND_PED_CHAT_EVENT: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_SHOCKED_1, 3); break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_SHOCKED_1, 3);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_MALE_VOICE_1_CHAT_1, 5); break;
default: return GetGenericMaleTalkSfx(sound);
}
@@ -2030,14 +2514,24 @@ cAudioManager::GetStudentFemaleTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_COWER: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_1, 4); break;
- case SOUND_PED_ROBBED: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_MUGGED_1, 2); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_FIGHT_1, 4); break;
- case SOUND_PED_EVADE: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_DODGE_1, 4); break;
+ case SOUND_PED_HANDS_COWER:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_1, 4);
+ break;
+ case SOUND_PED_ROBBED:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_MUGGED_1, 2);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_FIGHT_1, 4);
+ break;
+ case SOUND_PED_EVADE:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_DODGE_1, 4);
+ break;
case SOUND_PED_CAR_COLLISION:
GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_DRIVER_ABUSE_1, 4);
break;
- case SOUND_PED_CHAT_EVENT: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_SHOCKED_1, 2); break;
+ case SOUND_PED_CHAT_EVENT:
+ GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_SHOCKED_1, 2);
+ break;
case SOUND_PED_CHAT: GetPhrase(&sfx, &lastSfx, SFX_STUDENT_FEMALE_VOICE_1_CHAT_1, 4); break;
default: return GetGenericFemaleTalkSfx(sound);
}
@@ -2054,10 +2548,15 @@ uint32
cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound)
{
char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetName();
- if(!CGeneral::faststricmp(modelName, "eight") || !CGeneral::faststricmp(modelName, "eight2")) { return GetEightTalkSfx(sound); }
+ if(!CGeneral::faststricmp(modelName, "eight") ||
+ !CGeneral::faststricmp(modelName, "eight2")) {
+ return GetEightTalkSfx(sound);
+ }
if(!CGeneral::faststricmp(modelName, "frankie")) { return GetFrankieTalkSfx(sound); }
if(!CGeneral::faststricmp(modelName, "misty")) { return GetMistyTalkSfx(sound); }
- if(!CGeneral::faststricmp(modelName, "ojg") || !CGeneral::faststricmp(modelName, "ojg_p")) { return GetOJGTalkSfx(sound); }
+ if(!CGeneral::faststricmp(modelName, "ojg") || !CGeneral::faststricmp(modelName, "ojg_p")) {
+ return GetOJGTalkSfx(sound);
+ }
if(!CGeneral::faststricmp(modelName, "cat")) { return GetCatatalinaTalkSfx(sound); }
if(!CGeneral::faststricmp(modelName, "bomber")) { return GetBomberTalkSfx(sound); }
if(!CGeneral::faststricmp(modelName, "s_guard")) { return GetSecurityGuardTalkSfx(sound); }
@@ -2147,12 +2646,24 @@ cAudioManager::GetSecurityGuardTalkSfx(int16 sound)
static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_HANDS_UP: GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_GUN_COOL_1, 2); break;
+ case SOUND_PED_HANDS_UP:
+ GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_GUN_COOL_1, 2);
+ break;
case SOUND_PED_HANDS_COWER: sfx = SFX_SECURITY_GUARD_VOICE_1_GUN_PANIC_1; break;
case SOUND_PED_CAR_JACKED:
- case SOUND_PED_CAR_COLLISION: GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_1, 6); break;
- case SOUND_PED_ATTACK: GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_FIGHT_1, 2); break;
- case SOUND_PED_FLEE_RUN: GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_1, 12); break;
+ case SOUND_PED_CAR_COLLISION:
+ GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_1, 6);
+ break;
+ case SOUND_PED_ATTACK:
+ GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_FIGHT_1, 2);
+ break;
+ case SOUND_PED_FLEE_RUN:
+#ifdef FIX_BUGS
+ sfx = SFX_SECURITY_GUARD_VOICE_1_RUN_FROM_FIGHT_1;
+#else
+ GetPhrase(&sfx, &lastSfx, SFX_SECURITY_GUARD_VOICE_1_DRIVER_ABUSE_1, 12);
+#endif
+ break;
default: return GetGenericMaleTalkSfx(sound);
}
return sfx;
@@ -2215,8 +2726,8 @@ cAudioManager::GenerateIntegerRandomNumberTable()
char *
cAudioManager::Get3DProviderName(uint8 id) const
{
- if(!m_bIsInitialised) return 0;
- if(id >= SampleManager.GetNum3DProvidersAvailable()) return 0;
+ if(!m_bIsInitialised) return nil;
+ if(id >= SampleManager.GetNum3DProvidersAvailable()) return nil;
return SampleManager.Get3DProviderName(id);
}
@@ -2368,8 +2879,8 @@ cAudioManager::GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint
}
float
-cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission,
- float velocityChange)
+cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
+ cTransmission *transmission, float velocityChange)
{
tWheelState wheelState;
float relativeVelChange;
@@ -2407,8 +2918,8 @@ cAudioManager::GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobil
}
float
-cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission,
- float velocityChange)
+cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
+ cTransmission *transmission, float velocityChange)
{
float relativeVelChange;
@@ -2424,7 +2935,8 @@ cAudioManager::GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automo
bool
cAudioManager::HasAirBrakes(int32 model) const
{
- return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH;
+ return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS ||
+ model == COACH;
}
void
@@ -2466,7 +2978,7 @@ cAudioManager::IsAudioInitialised() const
bool
cAudioManager::IsMissionAudioSampleFinished()
{
- if(m_bIsInitialised) return m_sMissionAudio.m_bPlayStatus == 2;
+ if(m_bIsInitialised) return m_sMissionAudio.m_bPlayStatus == PLAY_STATUS_FINISHED;
static int32 cPretendFrame = 1;
@@ -2504,7 +3016,8 @@ cAudioManager::MissionScriptAudioUsesPoliceChannel(int32 soundMission) const
void
cAudioManager::PlayLoadedMissionAudio()
{
- if(m_bIsInitialised && m_sMissionAudio.m_nSampleIndex != NO_SAMPLE && m_sMissionAudio.m_bLoadingStatus == 1 &&
+ if(m_bIsInitialised && m_sMissionAudio.m_nSampleIndex != NO_SAMPLE &&
+ m_sMissionAudio.m_bLoadingStatus == LOADING_STATUS_LOADED &&
!m_sMissionAudio.m_bPlayStatus) {
m_sMissionAudio.m_bIsPlayed = true;
}
@@ -2514,11 +3027,12 @@ void
cAudioManager::PlayOneShot(int32 index, int16 sound, float vol)
{
static const uint8 OneShotPriority[] = {
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1, 1, 4, 4, 3, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 3, 2, 2, 2, 2, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3, 1, 1, 1, 9,
- 2, 2, 0, 0, 0, 0, 3, 3, 5, 1, 1, 1, 1, 3, 4, 7, 6, 6, 6, 6, 1, 3, 4, 3, 4, 2, 1, 3, 5, 4, 6, 6, 1, 3,
- 1, 1, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 3, 5, 2, 2, 1, 1, 3, 1, 3, 3, 1, 1,
+ 1, 4, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 3, 2, 2, 2, 2, 0, 0, 6,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 3, 1, 1, 1, 9, 2, 2, 0, 0, 0, 0, 3, 3, 5, 1,
+ 1, 1, 1, 3, 4, 7, 6, 6, 6, 6, 1, 3, 4, 3, 4, 2, 1, 3, 5, 4, 6, 6, 1, 3, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if(m_bIsInitialised) {
if(index >= 0 && index < totalAudioEntitiesSlots) {
@@ -2526,37 +3040,48 @@ cAudioManager::PlayOneShot(int32 index, int16 sound, float vol)
if(entity.m_bIsUsed) {
if(sound < SOUND_TOTAL_SOUNDS) {
if(entity.m_nType == AUDIOTYPE_SCRIPTOBJECT) {
- if(m_nScriptObjectEntityTotal < ARRAY_SIZE(m_anScriptObjectEntityIndices)) {
+ if(m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal <
+ ARRAY_SIZE(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices)) {
entity.m_awAudioEvent[0] = sound;
entity.m_AudioEvents = 1;
- m_anScriptObjectEntityIndices[m_nScriptObjectEntityTotal++] =
- index;
+ m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices
+ [m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal++] = index;
}
} else {
int32 i = 0;
while(true) {
if(i >= entity.m_AudioEvents) {
- if(entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) {
- entity.m_awAudioEvent[i] = sound;
+ if(entity.m_AudioEvents <
+ ARRAY_SIZE(
+ entity.m_awAudioEvent)) {
+ entity.m_awAudioEvent[i] =
+ sound;
entity.m_afVolume[i] = vol;
++entity.m_AudioEvents;
}
return;
}
- if(OneShotPriority[entity.m_awAudioEvent[i]] >
+ if(OneShotPriority[entity
+ .m_awAudioEvent[i]] >
OneShotPriority[sound])
break;
++i;
}
- if(i < 3) {
+ if(i < NUM_AUDIOENTITY_EVENTS - 1) {
memmove(&entity.m_awAudioEvent[i + 1],
- &entity.m_awAudioEvent[i], (3 - i) * 2);
- memmove(&entity.m_afVolume[i + 1], &entity.m_afVolume[i],
- (3 - i) * 4);
+ &entity.m_awAudioEvent[i],
+ (NUM_AUDIOENTITY_EVENTS - 1 - i) *
+ NUM_AUDIOENTITY_EVENTS / 2);
+ memmove(&entity.m_afVolume[i + 1],
+ &entity.m_afVolume[i],
+ (NUM_AUDIOENTITY_EVENTS - 1 - i) *
+ NUM_AUDIOENTITY_EVENTS);
}
entity.m_awAudioEvent[i] = sound;
entity.m_afVolume[i] = vol;
- if(entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) ++entity.m_AudioEvents;
+ if(entity.m_AudioEvents <
+ ARRAY_SIZE(entity.m_awAudioEvent))
+ ++entity.m_AudioEvents;
}
}
}
@@ -2582,31 +3107,31 @@ cAudioManager::PostInitialiseGameSpecificSetup()
m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE, &gFireManager);
if(m_nFireAudioEntity >= 0) SetEntityStatus(m_nFireAudioEntity, 1);
- m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void*)1);
+ m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void *)1);
if(m_nCollisionEntity >= 0) SetEntityStatus(m_nCollisionEntity, 1);
- m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void*)1);
+ m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void *)1);
if(m_nFrontEndEntity >= 0) SetEntityStatus(m_nFrontEndEntity, 1);
- m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void*)1);
+ m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void *)1);
if(m_nProjectileEntity >= 0) SetEntityStatus(m_nProjectileEntity, 1);
- m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void*)1);
+ m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void *)1);
if(m_nWaterCannonEntity >= 0) SetEntityStatus(m_nWaterCannonEntity, 1);
- m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void*)1);
+ m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1);
if(m_nPoliceChannelEntity >= 0) SetEntityStatus(m_nPoliceChannelEntity, 1);
- m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void*)1);
+ m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void *)1);
if(m_nBridgeEntity >= 0) SetEntityStatus(m_nBridgeEntity, 1);
m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
- m_sMissionAudio.m_bLoadingStatus = 0;
- m_sMissionAudio.m_bPlayStatus = 0;
+ m_sMissionAudio.m_bLoadingStatus = LOADING_STATUS_NOT_LOADED;
+ m_sMissionAudio.m_bPlayStatus = PLAY_STATUS_STOPPED;
m_sMissionAudio.field_22 = 0;
m_sMissionAudio.m_bIsPlayed = false;
- m_sMissionAudio.field_12 = 1;
- m_sMissionAudio.field_24 = 0;
+ m_sMissionAudio.m_bPredefinedProperties = 1;
+ m_sMissionAudio.m_nMissionAudioCounter = 0;
ResetAudioLogicTimers(CTimer::GetTimeInMilliseconds());
}
@@ -2685,7 +3210,8 @@ int32
FindMissionAudioSfx(const char *name)
{
for(uint32 i = 0; i < ARRAY_SIZE(MissionAudioNameSfxAssoc); ++i) {
- if(!CGeneral::faststricmp(MissionAudioNameSfxAssoc[i].m_pName, name)) return MissionAudioNameSfxAssoc[i].m_nId;
+ if(!CGeneral::faststricmp(MissionAudioNameSfxAssoc[i].m_pName, name))
+ return MissionAudioNameSfxAssoc[i].m_nId;
}
debug("Can't find mission audio %s", name);
return NO_SAMPLE;
@@ -2698,19 +3224,19 @@ cAudioManager::PreloadMissionAudio(const char *name)
int32 missionAudioSfx = FindMissionAudioSfx(name);
if(missionAudioSfx != NO_SAMPLE) {
m_sMissionAudio.m_nSampleIndex = missionAudioSfx;
- m_sMissionAudio.m_bLoadingStatus = 0;
- m_sMissionAudio.m_bPlayStatus = 0;
+ m_sMissionAudio.m_bLoadingStatus = LOADING_STATUS_NOT_LOADED;
+ m_sMissionAudio.m_bPlayStatus = PLAY_STATUS_STOPPED;
m_sMissionAudio.field_22 = 0;
- m_sMissionAudio.field_24 =
- field_19192 * SampleManager.GetStreamedFileLength(missionAudioSfx) / 1000;
- m_sMissionAudio.field_24 *= 4;
+ m_sMissionAudio.m_nMissionAudioCounter =
+ m_bTimeSpent * SampleManager.GetStreamedFileLength(missionAudioSfx) /
+ 1000;
+ m_sMissionAudio.m_nMissionAudioCounter *= 4;
m_sMissionAudio.m_bIsPlayed = false;
- m_sMissionAudio.field_12 = 1;
- g_bMissionAudioLoadFailed = 0;
+ m_sMissionAudio.m_bPredefinedProperties = 1;
+ g_bMissionAudioLoadFailed = false;
}
}
}
-
void
cAudioManager::PreTerminateGameSpecificShutdown()
{
@@ -2763,190 +3289,232 @@ cAudioManager::ProcessActiveQueues()
uint8 emittingVol;
CVector position;
- for (int32 i = 0; i < m_bActiveSamples; i++) {
- m_asSamples[m_bActiveSampleQueue][i].m_bIsProcessed = 0;
- m_asActiveSamples[i].m_bIsProcessed = 0;
- }
-
- for (int32 i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; ++i) {
- tSound& sample = m_asSamples[m_bActiveSampleQueue][m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]];
- if (sample.m_nSampleIndex != NO_SAMPLE) {
- for (int32 j = 0; j < m_bActiveSamples; ++j) {
- if (sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex &&
- sample.m_counter == m_asActiveSamples[j].m_counter &&
- sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) {
- if (sample.m_nLoopCount) {
- if (m_FrameCounter & 1) {
+ for(int32 i = 0; i < m_bActiveSamples; i++) {
+ m_asSamples[m_bActiveSampleQueue][i].m_bIsProcessed = false;
+ m_asActiveSamples[i].m_bIsProcessed = false;
+ }
+
+ for(int32 i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; ++i) {
+ tSound &sample = m_asSamples[m_bActiveSampleQueue]
+ [m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]];
+ if(sample.m_nSampleIndex != NO_SAMPLE) {
+ for(int32 j = 0; j < m_bActiveSamples; ++j) {
+ if(sample.m_nEntityIndex == m_asActiveSamples[j].m_nEntityIndex &&
+ sample.m_nCounter == m_asActiveSamples[j].m_nCounter &&
+ sample.m_nSampleIndex == m_asActiveSamples[j].m_nSampleIndex) {
+ if(sample.m_nLoopCount) {
+ if(m_FrameCounter & 1) {
flag = !!(j & 1);
- }
- else {
+ } else {
flag = !(j & 1);
}
- if (flag && !SampleManager.GetChannelUsedFlag(j)) {
- sample.m_bLoopEnded = 1;
- m_asActiveSamples[j].m_bLoopEnded = 1;
- m_asActiveSamples[j].m_nSampleIndex = NO_SAMPLE;
- m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE;
+ if(flag && !SampleManager.GetChannelUsedFlag(j)) {
+ sample.m_bLoopEnded = true;
+ m_asActiveSamples[j].m_bLoopEnded = true;
+ m_asActiveSamples[j].m_nSampleIndex =
+ NO_SAMPLE;
+ m_asActiveSamples[j].m_nEntityIndex =
+ AEHANDLE_NONE;
continue;
}
}
- sample.m_bIsProcessed = 1;
- m_asActiveSamples[j].m_bIsProcessed = 1;
- sample.field_88 = -1;
- if (!sample.field_56) {
- if (sample.m_bIsDistant) {
- if (field_4) {
- emittingVol = 2 * min(63, sample.m_bEmittingVolume);
- }
- else {
- emittingVol = sample.m_bEmittingVolume;
+ sample.m_bIsProcessed = true;
+ m_asActiveSamples[j].m_bIsProcessed = true;
+ sample.m_nVolumeChange = -1;
+ if(!sample.m_bReleasingSoundFlag) {
+ if(sample.m_bIs2D) {
+ if(field_4) {
+ emittingVol =
+ 2 *
+ min(63,
+ sample.m_bEmittingVolume);
+ } else {
+ emittingVol =
+ sample.m_bEmittingVolume;
}
- SampleManager.SetChannelFrequency(j, sample.m_nFrequency);
- SampleManager.SetChannelEmittingVolume(j, emittingVol);
- }
- else {
- m_asActiveSamples[j].m_fDistance = sample.m_fDistance;
+ SampleManager.SetChannelFrequency(
+ j, sample.m_nFrequency);
+ SampleManager.SetChannelEmittingVolume(
+ j, emittingVol);
+ } else {
+ m_asActiveSamples[j].m_fDistance =
+ sample.m_fDistance;
position2 = sample.m_fDistance;
- position1 = m_asActiveSamples[j].m_fDistance;
- sample.m_nFrequency = ComputeDopplerEffectedFrequency(
- sample.m_nFrequency, position1, position2, sample.field_48);
- if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) {
+ position1 =
+ m_asActiveSamples[j].m_fDistance;
+ sample.m_nFrequency =
+ ComputeDopplerEffectedFrequency(
+ sample.m_nFrequency, position1,
+ position2,
+ sample.m_fSpeedMultiplier);
+ if(sample.m_nFrequency !=
+ m_asActiveSamples[j].m_nFrequency) {
int32 freq;
- if (sample.m_nFrequency <=
- m_asActiveSamples[j].m_nFrequency) {
- freq = max(sample.m_nFrequency,
- m_asActiveSamples[j].m_nFrequency -
- 6000);
- }
- else {
- freq = min(sample.m_nFrequency,
- m_asActiveSamples[j].m_nFrequency +
- 6000);
+ if(sample.m_nFrequency <=
+ m_asActiveSamples[j]
+ .m_nFrequency) {
+ freq = max(
+ sample.m_nFrequency,
+ m_asActiveSamples[j]
+ .m_nFrequency -
+ 6000);
+ } else {
+ freq = min(
+ sample.m_nFrequency,
+ m_asActiveSamples[j]
+ .m_nFrequency +
+ 6000);
}
- m_asActiveSamples[j].m_nFrequency = freq;
- SampleManager.SetChannelFrequency(j, freq);
+ m_asActiveSamples[j].m_nFrequency =
+ freq;
+ SampleManager.SetChannelFrequency(
+ j, freq);
}
- if (sample.m_bEmittingVolume !=
- m_asActiveSamples[j].m_bEmittingVolume) {
- if (sample.m_bEmittingVolume <=
- m_asActiveSamples[j].m_bEmittingVolume) {
+ if(sample.m_bEmittingVolume !=
+ m_asActiveSamples[j].m_bEmittingVolume) {
+ if(sample.m_bEmittingVolume <=
+ m_asActiveSamples[j]
+ .m_bEmittingVolume) {
vol = max(
- m_asActiveSamples[j].m_bEmittingVolume - 10,
- sample.m_bEmittingVolume);
- }
- else {
+ m_asActiveSamples[j]
+ .m_bEmittingVolume -
+ 10,
+ sample
+ .m_bEmittingVolume);
+ } else {
vol = min(
- m_asActiveSamples[j].m_bEmittingVolume + 10,
- sample.m_bEmittingVolume);
+ m_asActiveSamples[j]
+ .m_bEmittingVolume +
+ 10,
+ sample
+ .m_bEmittingVolume);
}
uint8 emittingVol;
- if (field_4) {
- emittingVol = 2 * min(63, vol);
- }
- else {
+ if(field_4) {
+ emittingVol =
+ 2 * min(63, vol);
+ } else {
emittingVol = vol;
}
- SampleManager.SetChannelEmittingVolume(j, emittingVol);
- m_asActiveSamples[j].m_bEmittingVolume = vol;
+ SampleManager
+ .SetChannelEmittingVolume(
+ j, emittingVol);
+ m_asActiveSamples[j]
+ .m_bEmittingVolume = vol;
}
- TranslateEntity(&sample.m_vecPos, &position);
- SampleManager.SetChannel3DPosition(j, position.x, position.y,
- position.z);
+ TranslateEntity(&sample.m_vecPos,
+ &position);
+ SampleManager.SetChannel3DPosition(
+ j, position.x, position.y, position.z);
SampleManager.SetChannel3DDistances(
- j, sample.m_fSoundIntensity,
- 0.25f * sample.m_fSoundIntensity);
+ j, sample.m_fSoundIntensity,
+ 0.25f * sample.m_fSoundIntensity);
}
- SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag);
+ SampleManager.SetChannelReverbFlag(
+ j, sample.m_bReverbFlag);
continue;
}
- sample.m_bIsProcessed = 0;
- m_asActiveSamples[j].m_bIsProcessed = 0;
+ sample.m_bIsProcessed = false;
+ m_asActiveSamples[j].m_bIsProcessed = false;
break;
}
}
}
}
- for (int32 i = 0; i < m_bActiveSamples; i++) {
- if (m_asActiveSamples[i].m_nSampleIndex != NO_SAMPLE && !m_asActiveSamples[i].m_bIsProcessed) {
+ for(int32 i = 0; i < m_bActiveSamples; i++) {
+ if(m_asActiveSamples[i].m_nSampleIndex != NO_SAMPLE &&
+ !m_asActiveSamples[i].m_bIsProcessed) {
SampleManager.StopChannel(i);
m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE;
- m_asActiveSamples[i].m_nEntityIndex = -5;
+ m_asActiveSamples[i].m_nEntityIndex = AEHANDLE_NONE;
}
}
- for (int32 i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; ++i) {
-
- tSound& sample = m_asSamples[m_bActiveSampleQueue][m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]];
- if (!sample.m_bIsProcessed && !sample.m_bLoopEnded &&
- m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed && sample.m_nSampleIndex < NO_SAMPLE) {
- if (sample.m_counter > 255 && sample.m_nLoopCount && sample.m_bLoopsRemaining) {
+ for(int32 i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; ++i) {
+ tSound &sample = m_asSamples[m_bActiveSampleQueue]
+ [m_abSampleQueueIndexTable[m_bActiveSampleQueue][i]];
+ if(!sample.m_bIsProcessed && !sample.m_bLoopEnded &&
+ m_asAudioEntities[sample.m_nEntityIndex].m_bIsUsed &&
+ sample.m_nSampleIndex < NO_SAMPLE) {
+ if(sample.m_nCounter > 255 && sample.m_nLoopCount &&
+ sample.m_bLoopsRemaining) {
--sample.m_bLoopsRemaining;
- sample.field_76 = 1;
- }
- else {
- for (int32 j = 0; j < m_bActiveSamples; ++j) {
- if (!m_asActiveSamples[j].m_bIsProcessed) {
- if (sample.m_nLoopCount) {
- v28 = sample.m_nFrequency / field_19192;
+ sample.m_nReleasingVolumeDivider = 1;
+ } else {
+ for(int32 j = 0; j < m_bActiveSamples; ++j) {
+ if(!m_asActiveSamples[j].m_bIsProcessed) {
+ if(sample.m_nLoopCount) {
+ v28 = sample.m_nFrequency / m_bTimeSpent;
v29 = sample.m_nLoopCount *
- SampleManager.GetSampleLength(sample.m_nSampleIndex);
- if (v28 == 0) continue;
- sample.field_76 = v29 / v28 + 1;
+ SampleManager.GetSampleLength(
+ sample.m_nSampleIndex);
+ if(v28 == 0) continue;
+ sample.m_nReleasingVolumeDivider =
+ v29 / v28 + 1;
}
- memcpy(&m_asActiveSamples[j], &sample, sizeof(tSound));
- if (!m_asActiveSamples[j].m_bIsDistant)
- TranslateEntity(&m_asActiveSamples[j].m_vecPos, &position);
- if (field_4) {
+ memcpy(&m_asActiveSamples[j], &sample,
+ sizeof(tSound));
+ if(!m_asActiveSamples[j].m_bIs2D)
+ TranslateEntity(
+ &m_asActiveSamples[j].m_vecPos,
+ &position);
+ if(field_4) {
emittingVol =
- 2 * min(63, m_asActiveSamples[j].m_bEmittingVolume);
- }
- else {
- emittingVol = m_asActiveSamples[j].m_bEmittingVolume;
+ 2 * min(63, m_asActiveSamples[j]
+ .m_bEmittingVolume);
+ } else {
+ emittingVol =
+ m_asActiveSamples[j].m_bEmittingVolume;
}
- if (SampleManager.InitialiseChannel(j,
- m_asActiveSamples[j].m_nSampleIndex,
- m_asActiveSamples[j].m_bBankIndex)) {
+ if(SampleManager.InitialiseChannel(
+ j, m_asActiveSamples[j].m_nSampleIndex,
+ m_asActiveSamples[j].m_bBankIndex)) {
SampleManager.SetChannelFrequency(
- j, m_asActiveSamples[j].m_nFrequency);
- SampleManager.SetChannelEmittingVolume(j, emittingVol);
+ j, m_asActiveSamples[j].m_nFrequency);
+ SampleManager.SetChannelEmittingVolume(
+ j, emittingVol);
SampleManager.SetChannelLoopPoints(
- j, m_asActiveSamples[j].m_nLoopStart,
- m_asActiveSamples[j].m_nLoopEnd);
+ j, m_asActiveSamples[j].m_nLoopStart,
+ m_asActiveSamples[j].m_nLoopEnd);
SampleManager.SetChannelLoopCount(
- j, m_asActiveSamples[j].m_nLoopCount);
+ j, m_asActiveSamples[j].m_nLoopCount);
SampleManager.SetChannelReverbFlag(
- j, m_asActiveSamples[j].m_bReverbFlag);
- if (m_asActiveSamples[j].m_bIsDistant) {
- uint8 offset = m_asActiveSamples[j].m_bOffset;
- if (offset == 63) {
+ j, m_asActiveSamples[j].m_bReverbFlag);
+ if(m_asActiveSamples[j].m_bIs2D) {
+ uint8 offset =
+ m_asActiveSamples[j].m_bOffset;
+ if(offset == 63) {
x = 0.f;
- }
- else if (offset >= 63) {
- x = (offset - 63) * 1000.f / 63;
- }
- else {
- x = -(63 - offset) * 1000.f / 63;
+ } else if(offset >= 63) {
+ x = (offset - 63) * 1000.f /
+ 63;
+ } else {
+ x = -(63 - offset) *
+ 1000.f / 63;
}
usedX = x;
usedY = 0.f;
usedZ = 0.f;
- m_asActiveSamples[j].m_fSoundIntensity = 100000.0f;
- }
- else {
+ m_asActiveSamples[j]
+ .m_fSoundIntensity = 100000.0f;
+ } else {
usedX = position.x;
usedY = position.y;
usedZ = position.z;
}
- SampleManager.SetChannel3DPosition(j, usedX, usedY, usedZ);
+ SampleManager.SetChannel3DPosition(
+ j, usedX, usedY, usedZ);
SampleManager.SetChannel3DDistances(
- j, m_asActiveSamples[j].m_fSoundIntensity,
- 0.25f * m_asActiveSamples[j].m_fSoundIntensity);
+ j,
+ m_asActiveSamples[j].m_fSoundIntensity,
+ 0.25f * m_asActiveSamples[j]
+ .m_fSoundIntensity);
SampleManager.StartChannel(j);
}
- m_asActiveSamples[j].m_bIsProcessed = 1;
- sample.m_bIsProcessed = 1;
- sample.field_88 = -1;
+ m_asActiveSamples[j].m_bIsProcessed = true;
+ sample.m_bIsProcessed = true;
+ sample.m_nVolumeChange = -1;
break;
}
}
@@ -2965,7 +3533,8 @@ cAudioManager::ProcessAirBrakes(cVehicleParams *params)
automobile = (CAutomobile *)params->m_pVehicle;
if(!automobile->bEngineOn) return true;
- if((automobile->m_fVelocityChangeForAudio < 0.025f || params->m_fVelocityChange >= 0.025f) &&
+ if((automobile->m_fVelocityChangeForAudio < 0.025f ||
+ params->m_fVelocityChange >= 0.025f) &&
(automobile->m_fVelocityChangeForAudio > -0.025f || params->m_fVelocityChange <= 0.025f))
return true;
@@ -2973,20 +3542,20 @@ cAudioManager::ProcessAirBrakes(cVehicleParams *params)
rand = m_anRandomTable[0] % 10 + 70;
m_sQueueSample.m_bVolume = ComputeVolume(rand, 30.0f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 13;
+ m_sQueueSample.m_nCounter = 13;
m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AIR_BRAKES);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 10;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 10;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_bEmittingVolume = rand;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3014,19 +3583,20 @@ cAudioManager::ProcessAirportScriptObject(uint8 sound)
float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_bVolume =
- ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ 110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_AIRPORT_ANNOUNCEMENT_1;
+ m_sQueueSample.m_nSampleIndex =
+ (m_anRandomTable[1] & 3) + SFX_AIRPORT_ANNOUNCEMENT_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_counter = counter++;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nCounter = counter++;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = 110;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -3058,25 +3628,28 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
boat = (CBoat *)params->m_pVehicle;
if(params->m_nIndex == REEFER) {
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- m_sQueueSample.m_bVolume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 39;
+ m_sQueueSample.m_nCounter = 39;
m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
m_sQueueSample.m_nFrequency = 10386;
- m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex << 16) % 1000;
+ m_sQueueSample.m_nFrequency +=
+ (m_sQueueSample.m_nEntityIndex << 16) % 1000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = 80;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 7;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3090,7 +3663,8 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
emittingVol = (100.f * padRelativeAccerate) + 15;
m_sQueueSample.m_nFrequency = (3000.f * padRelativeAccerate) + 6000;
if(!boat->m_bIsAnchored)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nFrequency =
+ 11 * m_sQueueSample.m_nFrequency / 10;
} else {
gasPedal = Abs(boat->m_fGasPedal);
if(gasPedal > 0.0f) {
@@ -3100,26 +3674,29 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
emittingVol = (100.f * gasPedal) + 15;
m_sQueueSample.m_nFrequency = (3000.f * gasPedal) + 6000;
if(!boat->m_bIsAnchored)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nFrequency =
+ 11 * m_sQueueSample.m_nFrequency / 10;
}
}
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
if(!m_sQueueSample.m_bVolume) return 1;
- m_sQueueSample.m_counter = 40;
+ m_sQueueSample.m_nCounter = 40;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL;
m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex << 16) % 1000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 7;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
} else {
@@ -3131,18 +3708,21 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
if(padAccelerate <= 20) {
emittingVol = 45 - 45 * padAccelerate / 40;
m_sQueueSample.m_nFrequency = 100 * padAccelerate + 11025;
- m_sQueueSample.m_counter = 39;
+ m_sQueueSample.m_nCounter = 39;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_IDLE;
if(LastAccel > 20) {
oneShotVol = LastVol;
- PlayOneShot(m_sQueueSample.m_nEntityIndex, SOUND_17, oneShotVol);
+ PlayOneShot(m_sQueueSample.m_nEntityIndex, SOUND_17,
+ oneShotVol);
}
} else {
emittingVol = 105 * padAccelerate / 255 + 15;
- m_sQueueSample.m_nFrequency = 4000 * padAccelerate / 255 + 8000;
+ m_sQueueSample.m_nFrequency =
+ 4000 * padAccelerate / 255 + 8000;
if(!boat->m_bIsAnchored)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
- m_sQueueSample.m_counter = 40;
+ m_sQueueSample.m_nFrequency =
+ 11 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nCounter = 40;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL;
}
LastVol = emittingVol;
@@ -3152,33 +3732,36 @@ cAudioManager::ProcessBoatEngine(cVehicleParams *params)
if(gasPedal > 0.0f) {
m_sQueueSample.m_nFrequency = 11025;
emittingVol = 45;
- m_sQueueSample.m_counter = 39;
+ m_sQueueSample.m_nCounter = 39;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_IDLE;
} else {
emittingVol = (105.f * gasPedal) + 15;
m_sQueueSample.m_nFrequency = (4000.f * gasPedal) + 8000;
if(!boat->m_bIsAnchored)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
- m_sQueueSample.m_counter = 40;
+ m_sQueueSample.m_nFrequency =
+ 11 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nCounter = 40;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL;
}
}
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
if(!m_sQueueSample.m_bVolume) return 1;
m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex << 16) % 1000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 7;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
}
@@ -3206,20 +3789,22 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams *params)
vol = (30.f * multiplier);
m_sQueueSample.m_bVolume = ComputeVolume(vol, 50.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 38;
+ m_sQueueSample.m_nCounter = 38;
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nFrequency = (6050.f * multiplier) + 16000;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = vol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3259,23 +3844,26 @@ void
cAudioManager::ProcessBridgeMotor()
{
if(m_sQueueSample.m_fDistance < bridgeIntensity) {
- m_sQueueSample.m_bVolume = ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 1;
- m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE; // todo check sfx name
+ m_sQueueSample.m_nCounter = 1;
+ m_sQueueSample.m_nSampleIndex =
+ SFX_FISHING_BOAT_IDLE; // todo check sfx name
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency = 5500;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = maxVolume;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = bridgeIntensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = false;
AddSampleToRequestedQueue();
}
@@ -3285,10 +3873,12 @@ cAudioManager::ProcessBridgeMotor()
void
cAudioManager::ProcessBridgeOneShots()
{
- if(CBridge::State == STATE_LIFT_PART_IS_UP && CBridge::OldState == STATE_LIFT_PART_MOVING_UP) {
+ if(CBridge::State == STATE_LIFT_PART_IS_UP &&
+ CBridge::OldState == STATE_LIFT_PART_MOVING_UP) {
m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1;
} else {
- if(CBridge::State == STATE_LIFT_PART_IS_DOWN && CBridge::OldState == STATE_LIFT_PART_MOVING_DOWN) {
+ if(CBridge::State == STATE_LIFT_PART_IS_DOWN &&
+ CBridge::OldState == STATE_LIFT_PART_MOVING_DOWN) {
m_sQueueSample.m_nSampleIndex = SFX_COL_CONTAINER_1;
} else {
if(CBridge::State == STATE_LIFT_PART_MOVING_UP &&
@@ -3304,21 +3894,22 @@ cAudioManager::ProcessBridgeOneShots()
}
}
if(m_sQueueSample.m_fDistance < bridgeIntensity) {
- m_sQueueSample.m_bVolume = ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(maxVolume, bridgeIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 2;
+ m_sQueueSample.m_nCounter = 2;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_bEmittingVolume = maxVolume;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = bridgeIntensity;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = false;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3332,21 +3923,23 @@ cAudioManager::ProcessBridgeWarning()
if(CStats::CommercialPassed && m_sQueueSample.m_fDistance < 450.f) {
m_sQueueSample.m_bVolume = ComputeVolume(100, 450.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 0;
+ m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_nSampleIndex = SFX_BRIDGE_OPEN_WARNING;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BRIDGE_OPEN_WARNING);
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_BRIDGE_OPEN_WARNING);
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = 100;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = 450.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 8;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
m_sQueueSample.m_bReverbFlag = false;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3365,21 +3958,23 @@ cAudioManager::ProcessCarBombTick(cVehicleParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(60, 40.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 35;
+ m_sQueueSample.m_nCounter = 35;
m_sQueueSample.m_nSampleIndex = SFX_COUNTDOWN;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 0;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COUNTDOWN);
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_COUNTDOWN);
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = 60;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = 40.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3402,9 +3997,10 @@ cAudioManager::ProcessCesna(cVehicleParams *params)
} else if(nAccel < 60) {
++nAccel;
}
- AddPlayerCarSample(85 * (60 - nAccel) / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_IDLE, 0,
- 52, 1);
- AddPlayerCarSample(85 * nAccel / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_REV, 0, 2, 1);
+ AddPlayerCarSample(85 * (60 - nAccel) / 60 + 20, 8500 * nAccel / 60 + 17000,
+ SFX_CESNA_IDLE, 0, 52, 1);
+ AddPlayerCarSample(85 * nAccel / 60 + 20, 8500 * nAccel / 60 + 17000,
+ SFX_CESNA_REV, 0, 2, 1);
}
} else if(params->m_nIndex == DODO) {
AddPlayerCarSample(105, 17000, SFX_CESNA_IDLE, 0, 52, 1);
@@ -3412,44 +4008,47 @@ cAudioManager::ProcessCesna(cVehicleParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(80, 200.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 52;
+ m_sQueueSample.m_nCounter = 52;
m_sQueueSample.m_nSampleIndex = SFX_CESNA_IDLE;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_nFrequency = 12500;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_76 = 8;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
m_sQueueSample.m_bEmittingVolume = 80;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 8.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 8.0f;
m_sQueueSample.m_fSoundIntensity = 200.0f;
- m_sQueueSample.field_56 = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
if(params->m_fDistance < 8100.f) {
- m_sQueueSample.m_bVolume = ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 2;
+ m_sQueueSample.m_nCounter = 2;
m_sQueueSample.m_nSampleIndex = SFX_CESNA_REV;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_nFrequency = 25000;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_76 = 4;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
m_sQueueSample.m_bEmittingVolume = 80;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 8.0f;
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 8.0f;
m_sQueueSample.m_fSoundIntensity = 90.0f;
- m_sQueueSample.field_56 = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3480,20 +4079,21 @@ cAudioManager::ProcessCinemaScriptObject(uint8 sound)
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
rand = m_anRandomTable[0] % 90 + 30;
- m_sQueueSample.m_bVolume =
- ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = counter % 3 + SFX_CINEMA_BASS_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 4);
- m_sQueueSample.m_counter = counter++;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency / 4);
+ m_sQueueSample.m_nCounter = counter++;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = rand;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -3515,41 +4115,46 @@ cAudioManager::ProcessCrane()
static const int intensity = 80;
if(crane) {
- if(crane->m_bCraneActive == 1) {
- if(crane->m_bCraneStatus) {
- m_sQueueSample.m_vecPos = crane->m_pObject->GetPosition();
+ if(crane->m_nCraneStatus == CCrane::ACTIVATED) {
+ if(crane->m_nCraneState != CCrane::IDLE) {
+ m_sQueueSample.m_vecPos = crane->m_pCraneEntity->GetPosition();
distSquared = GetDistanceSquared(&this->m_sQueueSample.m_vecPos);
if(distSquared < SQR(intensity)) {
CalculateDistance(distCalculated, distSquared);
- m_sQueueSample.m_bVolume = ComputeVolume(100, 80.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(100, 80.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 0;
+ m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_nSampleIndex = SFX_CRANE_MAGNET;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 2;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
m_sQueueSample.m_nFrequency = 6000;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = 100;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(
- m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 4.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
- if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents) {
- m_sQueueSample.m_counter = 1;
+ if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex]
+ .m_AudioEvents) {
+ m_sQueueSample.m_nCounter = 1;
m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_2;
m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(SFX_COL_CAR_2);
+ SampleManager.GetSampleBaseFrequency(
+ SFX_COL_CAR_2);
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = true;
AddSampleToRequestedQueue();
@@ -3584,19 +4189,21 @@ cAudioManager::ProcessDocksScriptObject(uint8 sound)
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
rand = m_anRandomTable[0] % 60 + 40;
- m_sQueueSample.m_bVolume =
- ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_DOCKS_FOGHORN;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOCKS_FOGHORN);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 3);
- m_sQueueSample.m_counter = counter++;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_DOCKS_FOGHORN);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 3);
+ m_sQueueSample.m_nCounter = counter++;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = rand;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -3624,29 +4231,32 @@ cAudioManager::ProcessEngineDamage(cVehicleParams *params)
if(engineStatus < 225) {
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
emittingVolume = 6;
- m_sQueueSample.field_16 = 7;
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
m_sQueueSample.m_nFrequency = 40000;
} else {
emittingVolume = 60;
m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
- m_sQueueSample.field_16 = 7;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
}
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVolume, engineDamageIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(emittingVolume, engineDamageIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 28;
+ m_sQueueSample.m_nCounter = 28;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVolume;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = engineDamageIntensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3752,14 +4362,14 @@ cAudioManager::ProcessExplosions(int32 explosion)
m_sQueueSample.m_fSoundIntensity = 400.0f;
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_2;
m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
break;
case EXPLOSION_MOLOTOV:
m_sQueueSample.m_fSoundIntensity = 200.0f;
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_3;
m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 19000;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
break;
case EXPLOSION_MINE:
@@ -3767,7 +4377,7 @@ cAudioManager::ProcessExplosions(int32 explosion)
m_sQueueSample.m_fSoundIntensity = 300.0f;
m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT;
m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 12347;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
break;
default:
@@ -3775,8 +4385,9 @@ cAudioManager::ProcessExplosions(int32 explosion)
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1;
m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 38000;
if(type == EXPLOSION_HELI)
- m_sQueueSample.m_nFrequency = 8 * m_sQueueSample.m_nFrequency / 10;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_nFrequency =
+ 8 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
break;
}
@@ -3785,14 +4396,15 @@ cAudioManager::ProcessExplosions(int32 explosion)
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_bVolume = ComputeVolume(maxVolume, m_sQueueSample.m_fSoundIntensity,
- m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(maxVolume, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = i;
- m_sQueueSample.field_48 = 2.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nCounter = i;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bEmittingVolume = maxVolume;
m_sQueueSample.m_nLoopStart = 0;
@@ -3813,27 +4425,29 @@ cAudioManager::ProcessFireHydrant()
bool distCalculated = false;
static const int intensity = 35;
- m_sQueueSample.m_vecPos = ((CEntity*)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)->GetPosition();
+ m_sQueueSample.m_vecPos =
+ ((CEntity *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)->GetPosition();
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(intensity)) {
CalculateDistance(distCalculated, distSquared);
m_sQueueSample.m_bVolume = ComputeVolume(40, 35.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 0;
+ m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 4;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
m_sQueueSample.m_nFrequency = 15591;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = 40;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3857,9 +4471,12 @@ void cAudioManager::ProcessFires(int32)
m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
emittingVol = 100;
m_sQueueSample.m_nFrequency =
- 8 * SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE) / 10;
- m_sQueueSample.m_nFrequency += i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
- m_sQueueSample.field_16 = 6;
+ 8 *
+ SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE) /
+ 10;
+ m_sQueueSample.m_nFrequency +=
+ i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
break;
case ENTITY_TYPE_PED:
m_sQueueSample.m_fSoundIntensity = 25.0f;
@@ -3867,45 +4484,52 @@ void cAudioManager::ProcessFires(int32)
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE);
emittingVol = 60;
- m_sQueueSample.m_nFrequency += i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
- m_sQueueSample.field_16 = 10;
+ m_sQueueSample.m_nFrequency +=
+ i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
+ m_sQueueSample.m_nReleasingVolumeModificator = 10;
break;
default:
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
- m_sQueueSample.m_nFrequency += i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
+ m_sQueueSample.m_nFrequency +=
+ i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
emittingVol = 80;
- m_sQueueSample.field_16 = 8;
+ m_sQueueSample.m_nReleasingVolumeModificator = 8;
}
} else {
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
- m_sQueueSample.m_nFrequency += i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
+ m_sQueueSample.m_nFrequency +=
+ i * ((uint32)m_sQueueSample.m_nFrequency >> 6);
emittingVol = 80;
- m_sQueueSample.field_16 = 8;
+ m_sQueueSample.m_nReleasingVolumeModificator = 8;
}
m_sQueueSample.m_vecPos = gFireManager.m_aFires[i].m_vecPos;
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
- m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = i;
+ m_sQueueSample.m_nCounter = i;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_48 = 2.0f;
- m_sQueueSample.field_76 = 10;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 10;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3932,7 +4556,9 @@ cAudioManager::ProcessFrontEnd()
stereo = false;
processedMission = false;
switch(m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i]) {
- case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM: m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_RIFLE; break;
+ case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM:
+ m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_RIFLE;
+ break;
case SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM:
m_sQueueSample.m_nSampleIndex = SFX_ERROR_FIRE_ROCKET_LAUNCHER;
break;
@@ -3985,7 +4611,9 @@ cAudioManager::ProcessFrontEnd()
case SOUND_RACE_START_2:
case SOUND_RACE_START_1:
case SOUND_CLOCK_TICK: m_sQueueSample.m_nSampleIndex = SFX_TIMER_BEEP; break;
- case SOUND_RACE_START_GO: m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE; break;
+ case SOUND_RACE_START_GO:
+ m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE;
+ break;
case SOUND_PART_MISSION_COMPLETE:
m_sQueueSample.m_nSampleIndex = SFX_PART_MISSION_COMPLETE;
processedMission = true;
@@ -4023,7 +4651,9 @@ cAudioManager::ProcessFrontEnd()
stereo = true;
break;
case SOUND_FRONTEND_NO_RADIO:
- case SOUND_FRONTEND_RADIO_CHANGE: m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK; break;
+ case SOUND_FRONTEND_RADIO_CHANGE:
+ m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK;
+ break;
case SOUND_A0: m_sQueueSample.m_nSampleIndex = SFX_INFO; break;
default: continue;
}
@@ -4049,12 +4679,12 @@ cAudioManager::ProcessFrontEnd()
SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
}
m_sQueueSample.m_bVolume = 110;
- m_sQueueSample.m_counter = counter++;
+ m_sQueueSample.m_nCounter = counter++;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 0;
- m_sQueueSample.m_bIsDistant = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_bIs2D = true;
m_sQueueSample.m_bEmittingVolume = m_sQueueSample.m_bVolume;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -4067,7 +4697,7 @@ cAudioManager::ProcessFrontEnd()
AddSampleToRequestedQueue();
if(stereo) {
++m_sQueueSample.m_nSampleIndex;
- m_sQueueSample.m_counter = counter++;
+ m_sQueueSample.m_nCounter = counter++;
m_sQueueSample.m_bOffset = maxVolume - m_sQueueSample.m_bOffset;
AddSampleToRequestedQueue();
}
@@ -4086,48 +4716,53 @@ cAudioManager::ProcessGarages()
static uint8 iSound = 32;
-#define LOOP_HELPER \
- for(j = 0; j < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; ++j) { \
- switch(m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j]) { \
- case SOUND_GARAGE_DOOR_CLOSED: \
- case SOUND_GARAGE_DOOR_OPENED: \
- if(distSquared < 6400.f) { \
- CalculateDistance(distCalculated, distSquared); \
- m_sQueueSample.m_bVolume = ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \
- if(m_sQueueSample.m_bVolume) { \
- if(CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { \
- m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; \
- m_sQueueSample.m_nFrequency = 6735; \
- } else if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex] \
- .m_awAudioEvent[j] == 69) { \
- m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; \
- m_sQueueSample.m_nFrequency = 22000; \
- } else { \
- m_sQueueSample.m_nSampleIndex = SFX_COL_GARAGE_DOOR_1; \
- m_sQueueSample.m_nFrequency = 18000; \
- } \
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN; \
- m_sQueueSample.field_16 = 4; \
- m_sQueueSample.m_bEmittingVolume = 60; \
- m_sQueueSample.field_48 = 0.0f; \
- m_sQueueSample.m_fSoundIntensity = 80.0f; \
- /*m_sQueueSample.field_16 = 4;*/ \
- m_sQueueSample.m_bReverbFlag = true; \
- /*m_sQueueSample.m_bReverbFlag = true;*/ \
- m_sQueueSample.m_bIsDistant = false; \
- m_sQueueSample.field_56 = 1; \
- m_sQueueSample.m_nLoopCount = 1; \
- m_sQueueSample.m_nLoopStart = 0; \
- m_sQueueSample.m_nLoopEnd = -1; \
- m_sQueueSample.m_counter = iSound++; \
- if(iSound < 32) iSound = 32; \
- m_sQueueSample.m_bRequireReflection = true; \
- AddSampleToRequestedQueue(); \
- } \
- } \
- break; \
- default: continue; \
- } \
+#define LOOP_HELPER \
+ for(j = 0; j < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; ++j) { \
+ switch(m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[j]) { \
+ case SOUND_GARAGE_DOOR_CLOSED: \
+ case SOUND_GARAGE_DOOR_OPENED: \
+ if(distSquared < 6400.f) { \
+ CalculateDistance(distCalculated, distSquared); \
+ m_sQueueSample.m_bVolume = \
+ ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \
+ if(m_sQueueSample.m_bVolume) { \
+ if(CGarages::aGarages[i].m_eGarageType == \
+ GARAGE_CRUSHER) { \
+ m_sQueueSample.m_nSampleIndex = \
+ SFX_COL_CAR_PANEL_2; \
+ m_sQueueSample.m_nFrequency = 6735; \
+ } else if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex] \
+ .m_awAudioEvent[j] == 69) { \
+ m_sQueueSample.m_nSampleIndex = \
+ SFX_COL_CAR_PANEL_2; \
+ m_sQueueSample.m_nFrequency = 22000; \
+ } else { \
+ m_sQueueSample.m_nSampleIndex = \
+ SFX_COL_GARAGE_DOOR_1; \
+ m_sQueueSample.m_nFrequency = 18000; \
+ } \
+ m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN; \
+ m_sQueueSample.m_nReleasingVolumeModificator = 4; \
+ m_sQueueSample.m_bEmittingVolume = 60; \
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f; \
+ m_sQueueSample.m_fSoundIntensity = 80.0f; \
+ /*m_sQueueSample.m_nReleasingVolumeModificator = 4;*/ \
+ m_sQueueSample.m_bReverbFlag = true; \
+ /*m_sQueueSample.m_bReverbFlag = true;*/ \
+ m_sQueueSample.m_bIs2D = false; \
+ m_sQueueSample.m_bReleasingSoundFlag = true; \
+ m_sQueueSample.m_nLoopCount = 1; \
+ m_sQueueSample.m_nLoopStart = 0; \
+ m_sQueueSample.m_nLoopEnd = -1; \
+ m_sQueueSample.m_nCounter = iSound++; \
+ if(iSound < 32) iSound = 32; \
+ m_sQueueSample.m_bRequireReflection = true; \
+ AddSampleToRequestedQueue(); \
+ } \
+ } \
+ break; \
+ default: continue; \
+ } \
}
for(uint32 i = 0; i < CGarages::NumGarages; ++i) {
@@ -4141,19 +4776,24 @@ cAudioManager::ProcessGarages()
state = CGarages::aGarages[i].m_eGarageState;
if(state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) {
CalculateDistance(distCalculated, distSquared);
- m_sQueueSample.m_bVolume = ComputeVolume(90, 80.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(90, 80.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
if(CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) {
- if(CGarages::aGarages[i].m_eGarageState == GS_AFTERDROPOFF) {
+ if(CGarages::aGarages[i].m_eGarageState ==
+ GS_AFTERDROPOFF) {
if(!(m_FrameCounter & 1)) {
LOOP_HELPER
continue;
}
if(m_anRandomTable[1] & 1) {
- sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_CAR_1;
+ sampleIndex =
+ m_anRandomTable[2] % 5 +
+ SFX_COL_CAR_1;
} else {
sampleIndex =
- m_anRandomTable[2] % 6 + SFX_COL_CAR_PANEL_1;
+ m_anRandomTable[2] % 6 +
+ SFX_COL_CAR_PANEL_1;
}
m_sQueueSample.m_nSampleIndex = sampleIndex;
m_sQueueSample.m_nFrequency =
@@ -4161,14 +4801,17 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_nSampleIndex) >>
1;
m_sQueueSample.m_nFrequency +=
- RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
+ RandomDisplacement(
+ m_sQueueSample.m_nFrequency >> 4);
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nCounter = iSound++;
if(iSound < 32) iSound = 32;
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bBankIndex =
+ SAMPLEBANK_MAIN;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample
+ .m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_bEmittingVolume = 90;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(
@@ -4176,7 +4819,7 @@ cAudioManager::ProcessGarages()
m_sQueueSample.m_nLoopEnd =
SampleManager.GetSampleLoopEndOffset(
m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
@@ -4184,25 +4827,29 @@ cAudioManager::ProcessGarages()
LOOP_HELPER
continue;
}
- m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
+ m_sQueueSample.m_nSampleIndex =
+ SFX_FISHING_BOAT_IDLE;
m_sQueueSample.m_nFrequency = 6543;
} else {
- m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP;
+ m_sQueueSample.m_nSampleIndex =
+ SFX_GARAGE_DOOR_LOOP;
m_sQueueSample.m_nFrequency = 13961;
}
- m_sQueueSample.m_counter = i;
+ m_sQueueSample.m_nCounter = i;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_56 = 0;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_bEmittingVolume = 90;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 2.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
@@ -4232,7 +4879,9 @@ cAudioManager::ProcessHelicopter(cVehicleParams *params)
static const tHelicopterSampleData gHeliSfxRanges[3] = {
{400.f, 380.f, 100}, {100.f, 70.f, maxVolume}, {60.f, 30.f, maxVolume}};
- if(gHeliSfxRanges[0].m_fMaxDistance * gHeliSfxRanges[0].m_fMaxDistance <= params->m_fDistance) return false;
+ if(gHeliSfxRanges[0].m_fMaxDistance * gHeliSfxRanges[0].m_fMaxDistance <=
+ params->m_fDistance)
+ return false;
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
heli = (CHeli *)params->m_pVehicle;
@@ -4242,29 +4891,32 @@ cAudioManager::ProcessHelicopter(cVehicleParams *params)
if(dist >= MaxDist) return true;
baseDist = gHeliSfxRanges[i].m_fBaseDistance;
if(dist < baseDist)
- emittingVol = (gHeliSfxRanges[i].m_bBaseVolume * ((MaxDist - dist) / (MaxDist - baseDist)));
+ emittingVol = (gHeliSfxRanges[i].m_bBaseVolume *
+ ((MaxDist - dist) / (MaxDist - baseDist)));
else
emittingVol = gHeliSfxRanges[i].m_bBaseVolume;
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, gHeliSfxRanges[i].m_fMaxDistance, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVol, gHeliSfxRanges[i].m_fMaxDistance, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = i + 65;
+ m_sQueueSample.m_nCounter = i + 65;
m_sQueueSample.m_nSampleIndex = i + SFX_HELI_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 0;
- m_sQueueSample.m_nFrequency = 1200 * heli->m_nHeliId + SampleManager.GetSampleBaseFrequency(
- m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_nFrequency =
+ 1200 * heli->m_nHeliId +
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = gHeliSfxRanges[i].m_fMaxDistance;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -4297,20 +4949,21 @@ cAudioManager::ProcessHomeScriptObject(uint8 sound)
if(dist < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(dist);
rand = m_anRandomTable[0] % 30 + 40;
- m_sQueueSample.m_bVolume =
- ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 5 + SFX_HOME_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
- m_sQueueSample.m_counter = counter++;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ m_sQueueSample.m_nCounter = counter++;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_bEmittingVolume = rand;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -4370,7 +5023,8 @@ cAudioManager::ProcessJumboAccel(CPlane *plane)
if(SetupJumboFlySound(20)) {
modificator = (plane->m_fSpeed - 0.10334f) * 1.676f;
if(modificator > 1.0f) modificator = 1.0f;
- if(SetupJumboRumbleSound(maxVolume * modificator) && SetupJumboTaxiSound((1.0f - modificator) * 75.f)) {
+ if(SetupJumboRumbleSound(maxVolume * modificator) &&
+ SetupJumboTaxiSound((1.0f - modificator) * 75.f)) {
if(modificator < 0.2f) {
whineSoundFreq = modificator * 5.f * 14600.0f + 29500;
vol = modificator * 5.f * maxVolume;
@@ -4409,7 +5063,8 @@ cAudioManager::ProcessJumboLanding(CPlane *plane)
if(SetupJumboFlySound(107.f * modificator + 20)) {
if(SetupJumboTaxiSound(75.f * (1.f - modificator))) {
SetupJumboEngineSound(maxVolume, 22050);
- SetupJumboWhineSound(18.f * (1.f - modificator), 14600.f * modificator + 29500);
+ SetupJumboWhineSound(18.f * (1.f - modificator),
+ 14600.f * modificator + 29500);
}
}
}
@@ -4419,8 +5074,10 @@ cAudioManager::ProcessJumboTakeOff(CPlane *plane)
{
const float modificator = (PlanePathPosition[plane->m_nPlaneId] - TakeOffPoint) / 300.f;
- if(SetupJumboFlySound((107.f * modificator) + 20) && SetupJumboRumbleSound(maxVolume * (1.f - modificator))) {
- if(SetupJumboEngineSound(maxVolume, 22050)) SetupJumboWhineSound(18.f * (1.f - modificator), 44100);
+ if(SetupJumboFlySound((107.f * modificator) + 20) &&
+ SetupJumboRumbleSound(maxVolume * (1.f - modificator))) {
+ if(SetupJumboEngineSound(maxVolume, 22050))
+ SetupJumboWhineSound(18.f * (1.f - modificator), 44100);
}
}
@@ -4437,9 +5094,7 @@ cAudioManager::ProcessLaunderetteScriptObject(uint8 sound)
{
switch(sound) {
case SCRIPT_SOUND_LAUNDERETTE_LOOP_S:
- case SCRIPT_SOUND_LAUNDERETTE_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- break;
+ case SCRIPT_SOUND_LAUNDERETTE_LOOP_L: m_sQueueSample.m_fSoundIntensity = 30.0f; break;
default: return;
}
float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
@@ -4450,37 +5105,41 @@ cAudioManager::ProcessLaunderetteScriptObject(uint8 sound)
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_LOOP;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_LOOP);
- m_sQueueSample.m_counter = 0;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_LOOP);
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = 45;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
- m_sQueueSample.m_bVolume =
- ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_SONG_LOOP;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_SONG_LOOP);
- m_sQueueSample.m_counter = 1;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_LAUNDERETTE_SONG_LOOP);
+ m_sQueueSample.m_nCounter = 1;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = 110;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -4501,9 +5160,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_1_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4511,9 +5170,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_2_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4521,9 +5180,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_2_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4531,9 +5190,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_3_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4541,9 +5200,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_3_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4551,9 +5210,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_4_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4561,9 +5220,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_4_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4571,9 +5230,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_5_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4581,9 +5240,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_5_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4591,9 +5250,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_6_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4601,9 +5260,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_6);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_6_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4611,9 +5270,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_6);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_7_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4621,9 +5280,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_7);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_7_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4631,9 +5290,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_7);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_8_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4641,9 +5300,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_8);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_8_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4651,9 +5310,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_8);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_9_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4661,9 +5320,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_9);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_9_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4671,9 +5330,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_9);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_10_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4681,9 +5340,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_10);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_10_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4691,9 +5350,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_10);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_11_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4701,9 +5360,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_11);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_11_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4711,9 +5370,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_11);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_12_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4721,9 +5380,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_12);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_12_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4731,9 +5390,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_12);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_13_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4741,9 +5400,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_RAGGA);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_13_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4751,49 +5410,53 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_RAGGA);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_STRIP_CLUB_LOOP_1_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_STRIP_CLUB_LOOP_1_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_WORK_SHOP_LOOP_S:
case SCRIPT_SOUND_WORK_SHOP_LOOP_L: ProcessWorkShopScriptObject(sound); return;
@@ -4804,20 +5467,22 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY);
- m_sQueueSample.field_16 = 6;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY);
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_39:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY);
- m_sQueueSample.field_16 = 6;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_DOG_FOOD_FACTORY);
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_LAUNDERETTE_LOOP_S:
case SCRIPT_SOUND_LAUNDERETTE_LOOP_L: ProcessLaunderetteScriptObject(sound); return;
@@ -4826,80 +5491,88 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_CHINATOWN_RESTAURANT_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_CHINATOWN;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_CHINATOWN);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_CIPRIANI_RESAURANT_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_CIPRIANI_RESAURANT_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_ITALY;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_ITALY);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_46_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_47_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_MARCO_BISTRO_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_MARCO_BISTRO_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_AIRPORT_LOOP_S:
case SCRIPT_SOUND_AIRPORT_LOOP_L: ProcessAirportScriptObject(sound); return;
@@ -4917,9 +5590,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PIANO_BAR_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PARTY_1_LOOP:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -4927,9 +5600,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PORN_CINEMA_1_S:
case SCRIPT_SOUND_PORN_CINEMA_1_L:
@@ -4944,73 +5617,82 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 90;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1);
- m_sQueueSample.field_16 = 2;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_BANK_ALARM_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_BANK_ALARM_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 90;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1);
- m_sQueueSample.field_16 = 2;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_BANK_ALARM_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_POLICE_BALL_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1);
- m_sQueueSample.field_16 = 2;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_POLICE_BALL_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_BALL_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1);
- m_sQueueSample.field_16 = 2;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_POLICE_BALL_1);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S:
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L: ProcessPoliceCellBeatingScriptObject(sound); return;
+ case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L:
+ ProcessPoliceCellBeatingScriptObject(sound);
+ return;
case SCRIPT_SOUND_RAVE_1_LOOP_S:
case SCRIPT_SOUND_RAVE_2_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_RAVE_1_LOOP_L:
case SCRIPT_SOUND_RAVE_2_LOOP_L:
@@ -5018,30 +5700,33 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_RAVE_3_LOOP_S:
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_RAVE_3_LOOP_L:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
case SCRIPT_SOUND_PRETEND_FIRE_LOOP:
m_sQueueSample.m_fSoundIntensity = 50.0f;
@@ -5049,9 +5734,9 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 80;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
- m_sQueueSample.field_16 = 8;
- m_sQueueSample.field_76 = 10;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 8;
+ m_sQueueSample.m_nReleasingVolumeDivider = 10;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
break;
default: return;
}
@@ -5059,18 +5744,19 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 0;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bEmittingVolume = emittingVolume;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
@@ -5093,12 +5779,13 @@ cAudioManager::ProcessMissionAudio()
if(m_bIsInitialised) {
if(m_sMissionAudio.m_nSampleIndex != NO_SAMPLE) {
switch(m_sMissionAudio.m_bLoadingStatus) {
- case 0:
- SampleManager.PreloadStreamedFile(m_sMissionAudio.m_nSampleIndex, 1);
- m_sMissionAudio.m_bLoadingStatus = 1;
+ case LOADING_STATUS_NOT_LOADED:
+ SampleManager.PreloadStreamedFile(m_sMissionAudio.m_nSampleIndex,
+ 1);
+ m_sMissionAudio.m_bLoadingStatus = LOADING_STATUS_LOADED;
nFramesUntilFailedLoad = 0;
return;
- case 1:
+ case LOADING_STATUS_LOADED:
if(!m_sMissionAudio.m_bIsPlayed) return;
if(g_bMissionAudioLoadFailed) {
if(m_bTimerJustReset) {
@@ -5109,15 +5796,19 @@ cAudioManager::ProcessMissionAudio()
nFramesUntilFailedLoad = 0;
} else if(!m_bUserPause) {
if(++nFramesForPretendPlaying < 120) {
- m_sMissionAudio.m_bPlayStatus = 1;
+ m_sMissionAudio.m_bPlayStatus =
+ PLAY_STATUS_PLAYING;
} else {
- m_sMissionAudio.m_bPlayStatus = 2;
+ m_sMissionAudio.m_bPlayStatus =
+ PLAY_STATUS_FINISHED;
m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
}
}
} else {
if(m_sMissionAudio.m_bPlayStatus) {
- if(m_sMissionAudio.m_bPlayStatus != 1) return;
+ if(m_sMissionAudio.m_bPlayStatus !=
+ PLAY_STATUS_PLAYING)
+ return;
if(m_bTimerJustReset) {
ClearMissionAudio();
SampleManager.StopStreamedFile(1);
@@ -5128,32 +5819,49 @@ cAudioManager::ProcessMissionAudio()
if(!m_bUserPause) {
if(nCheckPlayingDelay) {
--nCheckPlayingDelay;
- } else if(GetMissionScriptPoliceAudioPlayingStatus() ==
- 2 ||
- m_sMissionAudio.field_24-- == 0) {
- m_sMissionAudio.m_bPlayStatus = 2;
- m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
- SampleManager.StopStreamedFile(1);
- m_sMissionAudio.field_24 = 0;
+ } else if(
+ GetMissionScriptPoliceAudioPlayingStatus() ==
+ PLAY_STATUS_FINISHED ||
+ m_sMissionAudio
+ .m_nMissionAudioCounter-- ==
+ 0) {
+ m_sMissionAudio
+ .m_bPlayStatus =
+ PLAY_STATUS_FINISHED;
+ m_sMissionAudio
+ .m_nSampleIndex =
+ NO_SAMPLE;
+ SampleManager
+ .StopStreamedFile(1);
+ m_sMissionAudio
+ .m_nMissionAudioCounter =
+ 0;
}
}
} else if(m_sMissionAudio.field_22) {
- if(SampleManager.IsStreamPlaying(1) || m_bUserPause ||
- m_bPreviousUserPause) {
+ if(SampleManager.IsStreamPlaying(1) ||
+ m_bUserPause || m_bPreviousUserPause) {
if(m_bUserPause)
- SampleManager.PauseStream(1, 1);
+ SampleManager.PauseStream(
+ 1, 1);
else
- SampleManager.PauseStream(0, 1);
+ SampleManager.PauseStream(
+ 0, 1);
} else {
- m_sMissionAudio.m_bPlayStatus = 2;
- m_sMissionAudio.m_nSampleIndex = NO_SAMPLE;
+ m_sMissionAudio.m_bPlayStatus =
+ PLAY_STATUS_FINISHED;
+ m_sMissionAudio.m_nSampleIndex =
+ NO_SAMPLE;
SampleManager.StopStreamedFile(1);
- m_sMissionAudio.field_24 = 0;
+ m_sMissionAudio
+ .m_nMissionAudioCounter = 0;
}
} else {
if(m_bUserPause) return;
if(nCheckPlayingDelay--) {
- if(!SampleManager.IsStreamPlaying(1)) return;
+ if(!SampleManager.IsStreamPlaying(
+ 1))
+ return;
nCheckPlayingDelay = 0;
}
m_sMissionAudio.field_22 = 1;
@@ -5161,30 +5869,40 @@ cAudioManager::ProcessMissionAudio()
} else {
if(MissionScriptAudioUsesPoliceChannel(
m_sMissionAudio.m_nSampleIndex)) {
- SetMissionScriptPoliceAudio(m_sMissionAudio.m_nSampleIndex);
+ SetMissionScriptPoliceAudio(
+ m_sMissionAudio.m_nSampleIndex);
} else {
- if(m_bUserPause) SampleManager.PauseStream(1, 1);
- if(m_sMissionAudio.field_12) {
- SampleManager.SetStreamedVolumeAndPan(80, 63, 1, 1);
+ if(m_bUserPause)
+ SampleManager.PauseStream(1, 1);
+ if(m_sMissionAudio
+ .m_bPredefinedProperties) {
+ SampleManager
+ .SetStreamedVolumeAndPan(80, 63,
+ 1, 1);
} else {
- distSquared =
- GetDistanceSquared(&m_sMissionAudio.m_vecPos);
+ distSquared = GetDistanceSquared(
+ &m_sMissionAudio.m_vecPos);
if(distSquared >= 2500.f) {
emittingVol = 0;
pan = 63;
} else {
dist = Sqrt(distSquared);
- emittingVol = ComputeVolume(80, 50.0f, dist);
- TranslateEntity(&m_sMissionAudio.m_vecPos,
- &vec);
- pan = ComputePan(50.f, &vec);
+ emittingVol = ComputeVolume(
+ 80, 50.0f, dist);
+ TranslateEntity(
+ &m_sMissionAudio
+ .m_vecPos,
+ &vec);
+ pan =
+ ComputePan(50.f, &vec);
}
- SampleManager.SetStreamedVolumeAndPan(emittingVol, pan,
- 1, 1);
+ SampleManager
+ .SetStreamedVolumeAndPan(
+ emittingVol, pan, 1, 1);
}
SampleManager.StartPreloadedStreamedFile(1);
}
- m_sMissionAudio.m_bPlayStatus = 1;
+ m_sMissionAudio.m_bPlayStatus = PLAY_STATUS_PLAYING;
nCheckPlayingDelay = 30;
}
}
@@ -5192,9 +5910,9 @@ cAudioManager::ProcessMissionAudio()
case 2:
if(++nFramesUntilFailedLoad >= 90) {
nFramesForPretendPlaying = 0;
- g_bMissionAudioLoadFailed = 1;
+ g_bMissionAudioLoadFailed = true;
nFramesUntilFailedLoad = 0;
- m_sMissionAudio.m_bLoadingStatus = 1;
+ m_sMissionAudio.m_bLoadingStatus = LOADING_STATUS_LOADED;
}
return;
default: return;
@@ -5218,8 +5936,10 @@ cAudioManager::ProcessModelCarEngine(cVehicleParams *params)
velocityChange = Abs(params->m_fVelocityChange);
} else {
if(automobile->m_nDriveWheelsOnGround)
- automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.4f;
- velocityChange = automobile->m_fGasPedalAudio * params->m_pTransmission->fMaxVelocity;
+ automobile->m_fGasPedalAudio =
+ automobile->m_fGasPedalAudio * 0.4f;
+ velocityChange = automobile->m_fGasPedalAudio *
+ params->m_pTransmission->fMaxVelocity;
}
if(velocityChange > 0.001f) {
allowedVelocity = 0.5f * params->m_pTransmission->fMaxVelocity;
@@ -5228,28 +5948,33 @@ cAudioManager::ProcessModelCarEngine(cVehicleParams *params)
else
emittingVol = 90;
if(emittingVol) {
- CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance);
+ CalculateDistance(params->m_bDistanceCalculated,
+ params->m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVol, 30.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 2;
- m_sQueueSample.m_nSampleIndex = SFX_REMOTE_CONTROLLED_CAR;
+ m_sQueueSample.m_nCounter = 2;
+ m_sQueueSample.m_nSampleIndex =
+ SFX_REMOTE_CONTROLLED_CAR;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency =
- (11025.f * velocityChange / params->m_pTransmission->fMaxVelocity +
+ (11025.f * velocityChange /
+ params->m_pTransmission->fMaxVelocity +
11025.f);
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(
- m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 3.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -5296,9 +6021,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_nFrequency = 10600;
else
m_sQueueSample.m_nFrequency = 9000;
- m_sQueueSample.field_16 = 1;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
emittingVolume = RandomDisplacement(10) + 50;
break;
@@ -5308,11 +6033,12 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.m_nSampleIndex = m_anRandomTable[iSound % 5] % 3 + SFX_BULLET_WALL_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 9;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 9;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
emittingVolume = m_anRandomTable[2] % 20 + 90;
break;
case SCRIPT_SOUND_110:
@@ -5322,10 +6048,11 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = maxVolume;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TRAIN_STATION_ANNOUNCE);
- m_sQueueSample.field_16 = 0;
- m_sQueueSample.field_48 = 2.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_TRAIN_STATION_ANNOUNCE);
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
case SCRIPT_SOUND_PAYPHONE_RINGING:
m_sQueueSample.m_fSoundIntensity = 80.0f;
@@ -5333,9 +6060,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 80;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PHONE_RING);
- m_sQueueSample.field_16 = 1;
- m_sQueueSample.field_48 = 2.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = false;
break;
case SCRIPT_SOUND_GLASS_BREAK_L:
@@ -5344,9 +6071,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 70;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
case SCRIPT_SOUND_GLASS_BREAK_S:
m_sQueueSample.m_fSoundIntensity = 60.0f;
@@ -5354,9 +6081,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 60;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_SMASH);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
case SCRIPT_SOUND_GLASS_CRACK:
m_sQueueSample.m_fSoundIntensity = 60.0f;
@@ -5364,9 +6091,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
emittingVolume = 70;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
break;
case SCRIPT_SOUND_GLASS_LIGHT_BREAK:
@@ -5374,9 +6101,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = (m_anRandomTable[4] & 3) + SFX_GLASS_SHARD_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 19000;
- m_sQueueSample.field_16 = 9;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 9;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
emittingVolume = RandomDisplacement(11) + 25;
break;
case SCRIPT_SOUND_BOX_DESTROYED_1:
@@ -5384,9 +6111,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = SFX_WOODEN_BOX_SMASH;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
emittingVolume = m_anRandomTable[2] % 20 + 80;
break;
@@ -5395,9 +6122,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = SFX_CARDBOARD_BOX_SMASH;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 18600;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
emittingVolume = m_anRandomTable[2] % 20 + 80;
break;
@@ -5405,11 +6132,12 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_fSoundIntensity = 60.0f;
m_sQueueSample.m_nSampleIndex = m_anRandomTable[3] % 5 + SFX_COL_CAR_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
emittingVolume = m_anRandomTable[2] % 30 + 70;
break;
@@ -5417,11 +6145,12 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_fSoundIntensity = 60.0f;
m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
emittingVolume = m_anRandomTable[2] % 30 + 60;
break;
@@ -5439,22 +6168,22 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
case SURFACE_HEDGE:
m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2;
m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000;
- m_sQueueSample.field_16 = 18;
+ m_sQueueSample.m_nReleasingVolumeModificator = 18;
m_sQueueSample.m_fSoundIntensity = 20.0f;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
emittingVolume = m_anRandomTable[2] % 20 + 30;
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity,
- m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVolume, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bEmittingVolume = emittingVolume;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -5469,21 +6198,21 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
}
m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1;
m_sQueueSample.m_nFrequency = RandomDisplacement(750) + 18000;
- m_sQueueSample.field_16 = 15;
+ m_sQueueSample.m_nReleasingVolumeModificator = 15;
m_sQueueSample.m_fSoundIntensity = 20.0f;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
emittingVolume = m_anRandomTable[2] % 20 + 30;
break;
case SCRIPT_SOUND_GUNSHELL_DROP_SOFT:
m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2;
m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000;
- m_sQueueSample.field_16 = 18;
+ m_sQueueSample.m_nReleasingVolumeModificator = 18;
m_sQueueSample.m_fSoundIntensity = 20.0f;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
emittingVolume = m_anRandomTable[2] % 20 + 30;
break;
default: return;
@@ -5492,12 +6221,12 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bEmittingVolume = emittingVolume;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -5518,7 +6247,7 @@ cAudioManager::ProcessPed(CPhysical *ped)
m_sQueueSample.m_vecPos = ped->GetPosition();
- //params.m_bDistanceCalculated = false;
+ // params.m_bDistanceCalculated = false;
params.m_pPed = (CPed *)ped;
params.m_fDistance = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(ped->m_modelIndex == MI_FATMALE02) ProcessPedHeadphones(&params);
@@ -5538,10 +6267,11 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
if(ped->bInVehicle && ped->m_nPedState == PED_DRIVING) {
emittingVol = 10;
- veh = (CAutomobile*)ped->m_pMyVehicle;
+ veh = (CAutomobile *)ped->m_pMyVehicle;
if(veh && veh->IsCar()) {
for(int32 i = 2; i < ARRAYSIZE(veh->Doors); i++) {
- if(!veh->IsDoorClosed((eDoors)i) || veh->IsDoorMissing((eDoors)i)) {
+ if(!veh->IsDoorClosed((eDoors)i) ||
+ veh->IsDoorMissing((eDoors)i)) {
emittingVol = 42;
break;
}
@@ -5551,25 +6281,27 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
emittingVol = 42;
}
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 7.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 7.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 64;
+ m_sQueueSample.m_nCounter = 64;
m_sQueueSample.m_nSampleIndex = SFX_HEADPHONES;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 5;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_HEADPHONES);
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 4.0f;
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 7.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 5;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -5579,14 +6311,6 @@ cAudioManager::ProcessPedHeadphones(cPedParams *params)
}
}
-#if 1
-WRAPPER
-void
-cAudioManager::ProcessPedOneShots(cPedParams *params)
-{
- EAXJMP(0x56F650);
-}
-#else
void
cAudioManager::ProcessPedOneShots(cPedParams *params)
{
@@ -5597,15 +6321,15 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
bool stereo;
int16 sound;
- char noReflection;
+ bool noReflection;
CWeapon *weapon;
- float maxDist;
+ float maxDist = 0.f; // uninitialized variable
static uint8 iSound = 21;
- weapon = nil;
+ weapon = params->m_pPed->GetWeapon();
for(uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
- noReflection = 0;
+ noReflection = false;
stereo = 0;
m_sQueueSample.m_bRequireReflection = false;
sound = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
@@ -5614,7 +6338,8 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
case SOUND_STEP_END:
if(!params->m_pPed->bIsLooking) {
emittingVol = m_anRandomTable[3] % 15 + 45;
- if(FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)
+ if(FindPlayerPed() !=
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)
emittingVol >>= 1;
maxDist = 400.f;
switch(params->m_pPed->m_nSurfaceTouched) {
@@ -5623,7 +6348,8 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
break;
case SURFACE_DIRT:
case SURFACE_DIRTTRACK:
- sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1;
+ sampleIndex =
+ m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1;
break;
case SURFACE_METAL6:
case SURFACE_METAL_DOOR:
@@ -5639,10 +6365,12 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1;
break;
case SURFACE_SAND:
- sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1;
+ sampleIndex =
+ (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1;
break;
case SURFACE_PUDDLE:
- sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1;
+ sampleIndex =
+ (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1;
break;
case SURFACE_WOOD:
case SURFACE_WOOD_BOX:
@@ -5653,37 +6381,46 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1;
break;
default:
- sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1;
+ sampleIndex =
+ m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1;
break;
}
m_sQueueSample.m_nSampleIndex = sampleIndex;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter =
- m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 28;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17);
+ m_sQueueSample.m_nCounter =
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex]
+ .m_awAudioEvent[i] -
+ 28;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency / 17);
switch(params->m_pPed->m_nMoveState) {
- case 2:
+ case PEDMOVE_WALK:
emittingVol >>= 2;
- m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nFrequency =
+ 9 * m_sQueueSample.m_nFrequency / 10;
break;
- case 3:
+ case PEDMOVE_RUN:
emittingVol >>= 1;
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
+ m_sQueueSample.m_nFrequency =
+ 11 * m_sQueueSample.m_nFrequency / 10;
+ break;
+ case PEDMOVE_SPRINT:
+ m_sQueueSample.m_nFrequency =
+ 12 * m_sQueueSample.m_nFrequency / 10;
break;
- case 4: m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; break;
default: break;
}
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 20.0f;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
}
break;
@@ -5701,32 +6438,32 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL;
}
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = 1;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17);
- m_sQueueSample.field_16 = 2;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nCounter = 1;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency / 17);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
- break;
}
break;
case SOUND_FIGHT_PUNCH_33:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 18000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5734,19 +6471,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_KICK_34:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 16500;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5754,19 +6491,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_HEADBUTT_35:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 20000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5774,19 +6511,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_PUNCH_36:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 18000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5794,19 +6531,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_PUNCH_37:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 16500;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5814,19 +6551,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_CLOSE_PUNCH_38:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 20000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5834,19 +6571,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_PUNCH_39:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 18000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5854,19 +6591,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 16500;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5874,19 +6611,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_PUNCH_41:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 20000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5894,19 +6631,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_PUNCH_FROM_BEHIND_42:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 18000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5914,19 +6651,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_KNEE_OR_KICK_43:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 16500;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5934,19 +6671,19 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_FIGHT_KICK_44:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 20000;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound;
+ m_sQueueSample.m_nCounter = iSound;
stereo = 1;
++iSound;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5954,18 +6691,18 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 26 + 100;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_WEAPON_BAT_ATTACK:
m_sQueueSample.m_nSampleIndex = SFX_BAT_HIT_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -5973,12 +6710,12 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nLoopEnd = -1;
emittingVol = m_anRandomTable[2] % 20 + 100;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
if(m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bRequireReflection = true;
else
- noReflection = 1;
+ noReflection = true;
break;
case SOUND_WEAPON_SHOT_FIRED:
weapon = &ped->m_weapons[ped->m_currentWeapon];
@@ -5986,13 +6723,14 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
case WEAPONTYPE_COLT45:
m_sQueueSample.m_nSampleIndex = SFX_COLT45_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_COLT45_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
maxDist = SQR(50);
m_sQueueSample.m_nLoopCount = 1;
@@ -6000,23 +6738,24 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nLoopEnd = -1;
emittingVol = m_anRandomTable[1] % 10 + 90;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
if(m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bRequireReflection = true;
else
- noReflection = 1;
+ noReflection = true;
break;
case WEAPONTYPE_UZI:
m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 80.0f;
maxDist = SQR(80);
m_sQueueSample.m_nLoopCount = 1;
@@ -6024,19 +6763,20 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[3] % 15 + 70;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
break;
case WEAPONTYPE_SHOTGUN:
m_sQueueSample.m_nSampleIndex = SFX_SHOTGUN_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_SHOTGUN_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 60.0f;
maxDist = 3600.f;
m_sQueueSample.m_nLoopCount = 1;
@@ -6044,23 +6784,24 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nLoopEnd = -1;
emittingVol = m_anRandomTable[2] % 10 + 100;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
if(m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bRequireReflection = true;
else
- noReflection = 1;
+ noReflection = true;
break;
case WEAPONTYPE_AK47:
m_sQueueSample.m_nSampleIndex = SFX_AK47_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_AK47_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 80.0f;
maxDist = SQR(80);
m_sQueueSample.m_nLoopCount = 1;
@@ -6068,19 +6809,20 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[1] % 15 + 70;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
break;
case WEAPONTYPE_M16:
m_sQueueSample.m_nSampleIndex = SFX_M16_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_M16_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 80.0f;
maxDist = SQR(80);
m_sQueueSample.m_nLoopCount = 1;
@@ -6088,19 +6830,20 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[4] % 15 + 70;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
break;
case WEAPONTYPE_SNIPERRIFLE:
m_sQueueSample.m_nSampleIndex = SFX_SNIPER_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_SNIPER_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 60.0f;
maxDist = 3600.f;
m_sQueueSample.m_nLoopCount = 1;
@@ -6108,23 +6851,24 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nLoopEnd = -1;
emittingVol = m_anRandomTable[4] % 10 + 110;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
if(m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bRequireReflection = true;
else
- noReflection = 1;
+ noReflection = true;
break;
case WEAPONTYPE_ROCKETLAUNCHER:
m_sQueueSample.m_nSampleIndex = SFX_ROCKET_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
- m_sQueueSample.field_16 = 1;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 90.0f;
maxDist = 8100.f;
m_sQueueSample.m_nLoopCount = 1;
@@ -6132,38 +6876,39 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nLoopEnd = -1;
emittingVol = m_anRandomTable[0] % 20 + 80;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
if(m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bRequireReflection = true;
else
- noReflection = 1;
+ noReflection = true;
break;
case WEAPONTYPE_FLAMETHROWER:
m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = 9;
+ m_sQueueSample.m_nCounter = 9;
emittingVol = 90;
m_sQueueSample.m_nFrequency =
(10 * m_sQueueSample.m_nEntityIndex & 2047) +
SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_LEFT);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 4.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 60.0f;
maxDist = 3600.f;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bEmittingVolume = 90;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 6;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 0;
+ m_sQueueSample.m_nReleasingVolumeDivider = 6;
if(m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bRequireReflection = true;
else
- noReflection = 1;
+ noReflection = true;
break;
default: continue;
}
@@ -6174,164 +6919,70 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
switch(weapon->m_eWeaponType) {
case WEAPONTYPE_COLT45:
m_sQueueSample.m_nSampleIndex = SFX_PISTOL_RELOAD;
- emittingVol = 75;
- m_sQueueSample.m_counter = iSound++;
- stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_PISTOL_RELOAD) +
RandomDisplacement(300);
- m_sQueueSample.m_nFrequency += RandomDisplacement(300);
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bEmittingVolume = 75;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bRequireReflection = true;
break;
case WEAPONTYPE_UZI:
m_sQueueSample.m_nSampleIndex = SFX_M16_RELOAD;
- emittingVol = 75;
- m_sQueueSample.m_counter = iSound++;
- stereo = 1;
m_sQueueSample.m_nFrequency = 39243;
- m_sQueueSample.m_nFrequency += RandomDisplacement(300);
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bEmittingVolume = 75;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bRequireReflection = true;
break;
case WEAPONTYPE_SHOTGUN:
m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD;
- emittingVol = 75;
- m_sQueueSample.m_counter = iSound++;
- stereo = 1;
m_sQueueSample.m_nFrequency = 30290;
- m_sQueueSample.m_nFrequency += RandomDisplacement(300);
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bEmittingVolume = 75;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bRequireReflection = true;
break;
case WEAPONTYPE_AK47:
m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD;
- emittingVol = 75;
- m_sQueueSample.m_counter = iSound++;
- stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_AK47_RELOAD);
- m_sQueueSample.m_nFrequency += RandomDisplacement(300);
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bEmittingVolume = 75;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bRequireReflection = true;
break;
case WEAPONTYPE_M16:
m_sQueueSample.m_nSampleIndex = SFX_M16_RELOAD;
- emittingVol = 75;
- m_sQueueSample.m_counter = iSound++;
- stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_M16_RELOAD);
- m_sQueueSample.m_nFrequency += RandomDisplacement(300);
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bEmittingVolume = 75;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bRequireReflection = true;
break;
case WEAPONTYPE_SNIPERRIFLE:
m_sQueueSample.m_nSampleIndex = SFX_RIFLE_RELOAD;
- emittingVol = 75;
- m_sQueueSample.m_counter = iSound++;
- stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_RIFLE_RELOAD);
- m_sQueueSample.m_nFrequency += RandomDisplacement(300);
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bEmittingVolume = 75;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bRequireReflection = true;
break;
case WEAPONTYPE_ROCKETLAUNCHER:
m_sQueueSample.m_nSampleIndex = SFX_ROCKET_RELOAD;
- emittingVol = 75;
- m_sQueueSample.m_counter = iSound++;
- stereo = 1;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_ROCKET_RELOAD);
- m_sQueueSample.m_nFrequency += RandomDisplacement(300);
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bEmittingVolume = 75;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.m_bRequireReflection = true;
break;
default: continue;
}
+ emittingVol = 75;
+ m_sQueueSample.m_nCounter = iSound++;
+ stereo = 1;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(300);
+ m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 30.0f;
+ maxDist = SQR(30);
+ m_sQueueSample.m_nLoopCount = 1;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ m_sQueueSample.m_bEmittingVolume = 75;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
+ m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_WEAPON_AK47_BULLET_ECHO:
case SOUND_WEAPON_UZI_BULLET_ECHO:
case SOUND_WEAPON_M16_BULLET_ECHO:
m_sQueueSample.m_nSampleIndex = SFX_UZI_END_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_END_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_UZI_END_LEFT);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 80.0f;
maxDist = SQR(80);
m_sQueueSample.m_nLoopCount = 1;
@@ -6339,22 +6990,23 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nLoopEnd = -1;
emittingVol = m_anRandomTable[4] % 10 + 40;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
if(m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bRequireReflection = true;
else
- noReflection = 1;
+ noReflection = true;
break;
case SOUND_WEAPON_FLAMETHROWER_FIRE:
m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_START_LEFT;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_FLAMETHROWER_START_LEFT);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 4.0f;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 60.0f;
maxDist = 3600.f;
m_sQueueSample.m_nLoopCount = 1;
@@ -6362,18 +7014,20 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nLoopEnd = -1;
emittingVol = 70;
m_sQueueSample.m_bEmittingVolume = 70;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
break;
case SOUND_WEAPON_HIT_PED:
m_sQueueSample.m_nSampleIndex = SFX_BULLET_PED;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BULLET_PED);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 3);
- m_sQueueSample.field_16 = 7;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_BULLET_PED);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 3);
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
maxDist = SQR(30);
m_sQueueSample.m_nLoopCount = 1;
@@ -6381,17 +7035,17 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[0] % 20 + 90;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
break;
case SOUND_SPLASH:
m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_counter = iSound++;
+ m_sQueueSample.m_nCounter = iSound++;
stereo = 1;
m_sQueueSample.m_nFrequency = RandomDisplacement(1400) + 20000;
- m_sQueueSample.field_16 = 1;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 40.0f;
maxDist = 1600.f;
m_sQueueSample.m_nLoopCount = 1;
@@ -6399,50 +7053,48 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
emittingVol = m_anRandomTable[2] % 30 + 70;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
m_sQueueSample.m_bRequireReflection = true;
break;
- default:
- SetupPedComments(params, sound);
- continue;
+ default: SetupPedComments(params, sound); continue;
+ }
- if(stereo && iSound > 60) iSound = 21;
- if(params->m_fDistance < maxDist) {
- CalculateDistance((bool *)params, params->m_fDistance);
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
- m_sQueueSample.m_fDistance);
- if(m_sQueueSample.m_bVolume) {
- if(noReflection) {
- if(0.2f * m_sQueueSample.m_fSoundIntensity >
- m_sQueueSample.m_fDistance) {
- noReflection = 0;
- } else {
- m_sQueueSample.m_bIsDistant = true;
- m_sQueueSample.m_bOffset = 0;
- }
+ if(stereo && iSound > 60) iSound = 21;
+ if(params->m_fDistance < maxDist) {
+ CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
+ if(m_sQueueSample.m_bVolume) {
+ if(noReflection) {
+ if(0.2f * m_sQueueSample.m_fSoundIntensity <=
+ m_sQueueSample.m_fDistance) {
+ noReflection = 0;
+ } else {
+ m_sQueueSample.m_bIs2D = true;
+ m_sQueueSample.m_bOffset = 0;
}
- m_sQueueSample.m_bReverbFlag = true;
- AddSampleToRequestedQueue();
- if(noReflection) {
- m_sQueueSample.m_bOffset = 127;
- ++m_sQueueSample.m_nSampleIndex;
- if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] !=
- 47 ||
- weapon->m_eWeaponType != WEAPONTYPE_FLAMETHROWER) {
- m_sQueueSample.m_counter = iSound++;
- if(iSound > 60) iSound = 21;
- } else {
- ++m_sQueueSample.m_counter;
- }
- AddSampleToRequestedQueue();
+ }
+ m_sQueueSample.m_bReverbFlag = true;
+ AddSampleToRequestedQueue();
+ if(noReflection) {
+ m_sQueueSample.m_bOffset = 127;
+ ++m_sQueueSample.m_nSampleIndex;
+ if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex]
+ .m_awAudioEvent[i] != SOUND_WEAPON_SHOT_FIRED ||
+ weapon->m_eWeaponType != WEAPONTYPE_FLAMETHROWER) {
+ m_sQueueSample.m_nCounter = iSound++;
+ if(iSound > 60) iSound = 21;
+ } else {
+ ++m_sQueueSample.m_nCounter;
}
+ AddSampleToRequestedQueue();
}
}
}
}
}
-#endif
void
cAudioManager::ProcessPhysical(int32 id)
@@ -6450,8 +7102,12 @@ cAudioManager::ProcessPhysical(int32 id)
CPhysical *entity = (CPhysical *)m_asAudioEntities[id].m_pEntity;
if(entity) {
switch(entity->m_type) {
- case ENTITY_TYPE_VEHICLE: ProcessVehicle((CVehicle *)m_asAudioEntities[id].m_pEntity); break;
- case ENTITY_TYPE_PED: ProcessPed((CPhysical *)m_asAudioEntities[id].m_pEntity); break;
+ case ENTITY_TYPE_VEHICLE:
+ ProcessVehicle((CVehicle *)m_asAudioEntities[id].m_pEntity);
+ break;
+ case ENTITY_TYPE_PED:
+ ProcessPed((CPhysical *)m_asAudioEntities[id].m_pEntity);
+ break;
default: return;
}
}
@@ -6469,18 +7125,93 @@ cAudioManager::ProcessPlane(cVehicleParams *params)
struct tVehicleSampleData {
eSfxSample m_nAccelerationSampleIndex;
- char m_bEngineSoundType;
+ uint8 m_bEngineSoundType;
char gap_5[3];
eSfxSample m_nHornSample;
int32 m_nHornFrequency;
- char m_nSirenOrAlarmSample;
- int m_nSirenOrAlarmFrequency;
- char m_bDoorType;
+ uint8 m_nSirenOrAlarmSample;
+ int32 m_nSirenOrAlarmFrequency;
+ uint8 m_bDoorType;
char gap_25[3];
};
-int32 *CSWTCH_554 = (int32 *)0x606A50;
-tVehicleSampleData *CarSounds = (tVehicleSampleData *)0x606204;
+// int32 *GearFreqAdj = (int32 *)0x606A50;
+int32 GearFreqAdj[] = {112, 23, 0, 0, 112, 23, 0, 0, 72, 13, 0, 0,
+ 176, 4, 0, 0, 0, 0, 0, 0, 24, 252, 255, 255};
+
+// tVehicleSampleData *CarSounds = (tVehicleSampleData *)0x606204;
+
+const tVehicleSampleData CarSounds[70] = {
+ {SFX_CAR_REV_2, 2, "", SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_56CHEV, 11487, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_8, 8, "", SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_ALARM_1, 10928, 1},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 9935, 2},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_56CHEV, 12893, SFX_CAR_ALARM_1, 8941, 0},
+ {SFX_CAR_REV_5, 5, "", SFX_CAR_HORN_BMW328, 10706, SFX_CAR_ALARM_1, 11922, 1},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 7948, 2},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_TRUCK, 29711, SFX_POLICE_SIREN_SLOW, 11556, 2},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_TRUCK, 31478, SFX_CAR_ALARM_1, 8941, 2},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_BMW328, 9538, SFX_CAR_ALARM_1, 12220, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_3, 3, "", SFX_CAR_HORN_BMW328, 12017, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_2, 2, "", SFX_CAR_HORN_JEEP, 22295, SFX_CAR_ALARM_1, 12200, 1},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_BUS2, 18000, SFX_CAR_ALARM_1, 13400, 1},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_BUS, 18286, SFX_CAR_ALARM_1, 9935, 2},
+ {SFX_CAR_REV_3, 3, "", SFX_CAR_HORN_PORSCHE, 11025, SFX_CAR_ALARM_1, 13600, 1},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_JEEP, 22295, SFX_AMBULANCE_SIREN_SLOW, 8795, 2},
+ {SFX_CAR_REV_5, 5, "", SFX_CAR_HORN_PORSCHE, 9271, SFX_POLICE_SIREN_SLOW, 16168, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_56CHEV, 12170, SFX_CAR_ALARM_1, 8000, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_BUS2, 12345, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_2, 2, "", SFX_CAR_HORN_BMW328, 10796, SFX_CAR_ALARM_1, 8543, 1},
+ {SFX_CAR_REV_5, 5, "", SFX_CAR_HORN_PORSCHE, 9271, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_2, 2, "", SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_PICKUP, 11025, SFX_ICE_CREAM_TUNE, 11025, 0},
+ {SFX_CAR_REV_7, 7, "", SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 10000, 0},
+ {SFX_CAR_REV_5, 5, "", SFX_CAR_HORN_BMW328, 10706, SFX_POLICE_SIREN_SLOW, 13596, 1},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_BUS, 17260, SFX_POLICE_SIREN_SLOW, 13000, 2},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_ALARM_1, 9935, 2},
+ {SFX_CAR_REV_8, 8, "", SFX_CAR_HORN_PORSCHE, 10400, SFX_CAR_ALARM_1, 10123, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 26513, SFX_POLICE_SIREN_SLOW, 13596, 0},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_BUS2, 11652, SFX_CAR_ALARM_1, 10554, 3},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 8000, 2},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_ALARM_1, 9935, 2},
+ {SFX_CAR_REV_1, 0, "", SFX_CAR_HORN_TRUCK, 29711, SFX_CAR_ALARM_1, 9935, 3},
+ {SFX_CAR_REV_1, 0, "", SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CESNA_IDLE, 0, "", SFX_CAR_HORN_JEEP, 26513, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_BUS, 16291, SFX_CAR_ALARM_1, 7500, 3},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_56CHEV, 10233, SFX_CAR_ALARM_1, 8935, 0},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_PICKUP, 8670, SFX_CAR_ALARM_1, 8935, 0},
+ {SFX_CAR_REV_1, 0, "", SFX_CAR_HORN_PICKUP, 2000, SFX_CAR_ALARM_1, 17000, 0},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_5, 5, "", SFX_CAR_HORN_BMW328, 9003, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_2, 2, "", SFX_CAR_HORN_PORSCHE, 12375, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_5, 5, "", SFX_CAR_HORN_BUS2, 15554, SFX_CAR_ALARM_1, 9935, 1},
+ {SFX_CAR_REV_7, 7, "", SFX_CAR_HORN_BUS2, 13857, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_7, 7, "", SFX_CAR_HORN_PICKUP, 10924, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 2},
+ {SFX_CAR_REV_1, 0, "", SFX_CAR_HORN_JEEP, 20143, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 0, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9000, 0},
+ {SFX_CAR_REV_6, 6, "", SFX_CAR_HORN_TRUCK, 28043, SFX_CAR_ALARM_1, 9935, 2},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_BUS, 18286, SFX_CAR_ALARM_1, 9935, 2},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_56CHEV, 10842, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_4, 4, "", SFX_CAR_HORN_BUS2, 18000, SFX_CAR_ALARM_1, 13400, 1},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0},
+ {SFX_CAR_REV_1, 1, "", SFX_CAR_HORN_JEEP, 21043, SFX_CAR_ALARM_1, 9935, 0}};
void
cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *automobile)
@@ -6519,7 +7250,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
processedAccelSampleStopped = 0;
if(bPlayerJustEnteredCar) {
bAccelSampleStopped = 1;
- bPlayerJustEnteredCar = 0;
+ bPlayerJustEnteredCar = false;
nCruising = 0;
LastAccel = 0;
bLostTractionLastFrame = 0;
@@ -6543,7 +7274,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
if(transmission->nDriveType == '4') {
wheelInUseCounter = 0;
- for (uint8 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++){
+ for(uint8 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) {
if(automobile->m_aWheelState[i]) ++wheelInUseCounter;
}
if(wheelInUseCounter > 2) lostTraction = 1;
@@ -6552,7 +7283,8 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
(automobile->m_aWheelState[1] || automobile->m_aWheelState[3])) {
lostTraction = 1;
}
- } else if(transmission->nDriveType == 'R' && (automobile->m_aWheelState[1] || automobile->m_aWheelState[3])) {
+ } else if(transmission->nDriveType == 'R' &&
+ (automobile->m_aWheelState[1] || automobile->m_aWheelState[3])) {
lostTraction = 1;
}
if(0.0f != velocityChange) {
@@ -6574,11 +7306,13 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
SampleManager.StopChannel(m_bActiveSamples);
bAccelSampleStopped = 1;
}
- if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) {
+ if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn ||
+ lostTraction) {
gasPedalAudio = automobile->m_fGasPedalAudio;
} else {
gasPedalAudio =
- min(1.0f, params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity);
+ min(1.0f, params->m_fVelocityChange /
+ params->m_pTransmission->fMaxReverseVelocity);
}
gasPedalAudio = max(0.0f, gasPedalAudio);
automobile->m_fGasPedalAudio = gasPedalAudio;
@@ -6588,16 +7322,19 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
bAccelSampleStopped = 1;
}
nCruising = 0;
- if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction ||
- params->m_fVelocityChange >= 0.01f && automobile->m_fGasPedalAudio > 0.2f) {
+ if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn ||
+ lostTraction ||
+ params->m_fVelocityChange >= 0.01f &&
+ automobile->m_fGasPedalAudio > 0.2f) {
automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.6f;
gasPedalAudio = automobile->m_fGasPedalAudio;
}
if(gasPedalAudio > 0.05f) {
freq = (5000.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 19000;
if(engineSoundType == 6) freq >>= 1;
- AddPlayerCarSample((25.f * (gasPedalAudio - 0.05f) * 20.f / 19) + 40, freq,
- (soundOffset + SFX_CAR_FINGER_OFF_ACCEL_1),
+ AddPlayerCarSample((25.f * (gasPedalAudio - 0.05f) * 20.f / 19) +
+ 40,
+ freq, (soundOffset + SFX_CAR_FINGER_OFF_ACCEL_1),
engineSoundType, 63, 0);
}
}
@@ -6614,16 +7351,19 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
return;
}
if(!nCruising) {
- if(accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn ||
- lostTraction ||
- currentGear < 2 &&
- velocityChange - automobile->m_fVelocityChangeForAudio < 0.01f) { // here could be used abs
- if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction) {
- if(!automobile->m_nWheelsOnGround && automobile->m_nDriveWheelsOnGround ||
+ if(accelerateState < 150 || !automobile->m_nWheelsOnGround ||
+ automobile->bIsHandbrakeOn || lostTraction ||
+ currentGear < 2 && velocityChange - automobile->m_fVelocityChangeForAudio <
+ 0.01f) { // here could be used abs
+ if(!automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn ||
+ lostTraction) {
+ if(!automobile->m_nWheelsOnGround &&
+ automobile->m_nDriveWheelsOnGround ||
(automobile->bIsHandbrakeOn && !bHandbrakeOnLastFrame ||
lostTraction && !bLostTractionLastFrame) &&
automobile->m_nWheelsOnGround) {
- automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.6f;
+ automobile->m_fGasPedalAudio =
+ automobile->m_fGasPedalAudio * 0.6f;
}
freqModifier = 0;
baseFreq = (15000.f * automobile->m_fGasPedalAudio) + 14000;
@@ -6661,13 +7401,14 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
SampleManager.SetChannel3DPosition(m_bActiveSamples, pos.x, pos.y, pos.z);
SampleManager.SetChannel3DDistances(m_bActiveSamples, 50.f, 12.5f);
if(engineSoundType == 6)
- freq = (CSWTCH_554[CurrentPretendGear] + freqModifier + 22050) >> 1;
+ freq =
+ (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050) >> 1;
else
- freq = CSWTCH_554[CurrentPretendGear] + freqModifier + 22050;
+ freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050;
SampleManager.SetChannelFrequency(m_bActiveSamples, freq);
if(!channelUsed) {
- SampleManager.SetChannelReverbFlag(m_bActiveSamples,
- m_bDynamicAcousticModelingStatus != 0);
+ SampleManager.SetChannelReverbFlag(
+ m_bActiveSamples, m_bDynamicAcousticModelingStatus != 0);
SampleManager.StartChannel(m_bActiveSamples);
}
LastAccel = accelerateState;
@@ -6677,20 +7418,22 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
return;
}
if(processedAccelSampleStopped) {
- if(!SampleManager.InitialiseChannel(m_bActiveSamples, soundOffset + 345, 0)) return;
+ if(!SampleManager.InitialiseChannel(m_bActiveSamples, soundOffset + 345, 0))
+ return;
SampleManager.SetChannelLoopCount(m_bActiveSamples, 1);
SampleManager.SetChannelLoopPoints(m_bActiveSamples, 0, -1);
SampleManager.SetChannelEmittingVolume(m_bActiveSamples, 85);
SampleManager.SetChannel3DPosition(m_bActiveSamples, pos.x, pos.y, pos.z);
SampleManager.SetChannel3DDistances(m_bActiveSamples, 50.f, 12.5f);
if(engineSoundType == 6)
- freq = (CSWTCH_554[CurrentPretendGear] + freqModifier + 22050) >> 1;
+ freq =
+ (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050) >> 1;
else
- freq = CSWTCH_554[CurrentPretendGear] + freqModifier + 22050;
+ freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050;
SampleManager.SetChannelFrequency(m_bActiveSamples, freq);
if(!channelUsed) {
- SampleManager.SetChannelReverbFlag(m_bActiveSamples,
- m_bDynamicAcousticModelingStatus != 0);
+ SampleManager.SetChannelReverbFlag(
+ m_bActiveSamples, m_bDynamicAcousticModelingStatus != 0);
SampleManager.StartChannel(m_bActiveSamples);
}
LastAccel = accelerateState;
@@ -6701,20 +7444,21 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
}
if(CurrentPretendGear < params->m_pTransmission->nNumberOfGears - 1) {
++CurrentPretendGear;
- if(!SampleManager.InitialiseChannel(m_bActiveSamples, soundOffset + 345, 0)) return;
+ if(!SampleManager.InitialiseChannel(m_bActiveSamples, soundOffset + 345, 0))
+ return;
SampleManager.SetChannelLoopCount(m_bActiveSamples, 1);
SampleManager.SetChannelLoopPoints(m_bActiveSamples, 0, -1);
SampleManager.SetChannelEmittingVolume(m_bActiveSamples, 85);
SampleManager.SetChannel3DPosition(m_bActiveSamples, pos.x, pos.y, pos.z);
SampleManager.SetChannel3DDistances(m_bActiveSamples, 50.f, 12.5f);
- freq = CSWTCH_554[CurrentPretendGear] + freqModifier + 22050;
+ freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050;
if(engineSoundType == 6) freq >>= 1;
SampleManager.SetChannelFrequency(m_bActiveSamples, freq);
if(!channelUsed) {
- SampleManager.SetChannelReverbFlag(m_bActiveSamples,
- m_bDynamicAcousticModelingStatus != 0);
+ SampleManager.SetChannelReverbFlag(
+ m_bActiveSamples, m_bDynamicAcousticModelingStatus != 0);
SampleManager.StartChannel(m_bActiveSamples);
}
LastAccel = accelerateState;
@@ -6726,8 +7470,8 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
nCruising = 1;
}
bAccelSampleStopped = 1;
- if(accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn || lostTraction ||
- currentGear < params->m_pTransmission->nNumberOfGears - 1) {
+ if(accelerateState < 150 || !automobile->m_nWheelsOnGround || automobile->bIsHandbrakeOn ||
+ lostTraction || currentGear < params->m_pTransmission->nNumberOfGears - 1) {
nCruising = 0;
} else {
if(accelerateState >= 220 &&
@@ -6738,8 +7482,8 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams *params, CAutomobile *
}
freq = 27 * nCruising + freqModifier + 22050;
if(engineSoundType == 6) freq >>= 1;
- AddPlayerCarSample(85, freq, (soundOffset + SFX_CAR_AFTER_ACCEL_1),
- engineSoundType, 64, 1);
+ AddPlayerCarSample(85, freq, (soundOffset + SFX_CAR_AFTER_ACCEL_1), engineSoundType,
+ 64, 1);
}
LastAccel = accelerateState;
@@ -6778,18 +7522,20 @@ cAudioManager::ProcessPoliceCellBeatingScriptObject(uint8 sound)
m_sQueueSample.m_nSampleIndex = sampleIndex;
emittingVol = m_anRandomTable[0] % 50 + 55;
m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
- m_sQueueSample.m_counter = counter++;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ m_sQueueSample.m_nCounter = counter++;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -6861,21 +7607,23 @@ cAudioManager::ProcessPornCinema(uint8 sound)
m_sQueueSample.m_fDistance = Sqrt(distSquared);
if(sound != SCRIPT_SOUND_MISTY_SEX_S && sound != SCRIPT_SOUND_MISTY_SEX_L) {
m_sQueueSample.m_bVolume =
- ComputeVolume(maxVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ ComputeVolume(maxVolume, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_counter = 0;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = maxVolume;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -6884,20 +7632,21 @@ cAudioManager::ProcessPornCinema(uint8 sound)
time = CTimer::GetTimeInMilliseconds();
if(time > gPornNextTime) {
- m_sQueueSample.m_bVolume =
- ComputeVolume(90, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ 90, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
rand = m_anRandomTable[1] & 1;
m_sQueueSample.m_nSampleIndex = rand + sample;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
- m_sQueueSample.m_counter = rand + 1;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
+ m_sQueueSample.m_nCounter = rand + 1;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 6;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bReverbFlag = true;
@@ -6924,7 +7673,7 @@ cAudioManager::ProcessProjectiles()
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_ROCKET_FLY);
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
break;
case WEAPONTYPE_MOLOTOV:
emittingVol = molotovVolume;
@@ -6933,28 +7682,32 @@ cAudioManager::ProcessProjectiles()
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_nFrequency =
32 * SampleManager.GetSampleBaseFrequency(SFX_PED_ON_FIRE) / 25;
- m_sQueueSample.field_16 = 7;
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
break;
default: return;
}
- m_sQueueSample.field_48 = 4.0f;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.m_vecPos = CProjectileInfo::ms_apProjectile[i]->GetPosition();
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_vecPos =
+ CProjectileInfo::ms_apProjectile[i]->GetPosition();
float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
- m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = i;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nCounter = i;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_56 = 0;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -6967,35 +7720,32 @@ cAudioManager::ProcessProjectiles()
void
cAudioManager::ProcessRainOnVehicle(cVehicleParams *params)
{
- float emittingVol;
- CVehicle *veh;
-
if(params->m_fDistance < SQR(rainOnVehicleIntensity) && CWeather::Rain > 0.01f &&
(!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) {
- ++params->m_pVehicle->m_bRainAudioCounter;
- veh = params->m_pVehicle;
+ CVehicle *veh = params->m_pVehicle;
+ ++veh->m_bRainAudioCounter;
if(veh->m_bRainAudioCounter >= 2) {
veh->m_bRainAudioCounter = 0;
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- emittingVol = 30.f * CWeather::Rain;
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, rainOnVehicleIntensity, m_sQueueSample.m_fDistance);
+ float emittingVol = 30.f * CWeather::Rain;
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVol, rainOnVehicleIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = veh->m_bRainSamplesCounter++;
- veh = params->m_pVehicle;
+ m_sQueueSample.m_nCounter = veh->m_bRainSamplesCounter++;
if(veh->m_bRainSamplesCounter > 4) veh->m_bRainSamplesCounter = 68;
- m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_CAR_RAIN_1;
+ m_sQueueSample.m_nSampleIndex =
+ (m_anRandomTable[1] & 3) + SFX_CAR_RAIN_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 9;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 9;
m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 4000 + 28000;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_bEmittingVolume = (uint8)emittingVol;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.field_48 = 0.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = rainOnVehicleIntensity;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = false;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7008,8 +7758,16 @@ void
cAudioManager::ProcessReverb() const
{
if(SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) {
- for(uint32 i = 0; i < channels; i++) { // bug?
- if(m_asActiveSamples[i].m_bReverbFlag) SampleManager.SetChannelReverbFlag(i, 1);
+ for(uint32 i = 0; i <
+#ifdef FIX_BUGS
+ channels
+#else
+ 28
+#endif
+ ;
+ i++) {
+ if(m_asActiveSamples[i].m_bReverbFlag)
+ SampleManager.SetChannelReverbFlag(i, 1);
}
}
}
@@ -7028,7 +7786,8 @@ cAudioManager::ProcessReverseGear(cVehicleParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
automobile = (CAutomobile *)params->m_pVehicle;
if(automobile->m_nWheelsOnGround) {
- modificator = params->m_fVelocityChange / params->m_pTransmission->fMaxReverseVelocity;
+ modificator = params->m_fVelocityChange /
+ params->m_pTransmission->fMaxReverseVelocity;
} else {
if(automobile->m_nDriveWheelsOnGround)
automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.4f;
@@ -7036,28 +7795,30 @@ cAudioManager::ProcessReverseGear(cVehicleParams *params)
}
modificator = Abs(modificator);
emittingVol = (24.f * modificator);
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, reverseGearIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, reverseGearIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
if(params->m_pVehicle->m_fGasPedal >= 0.0f) {
- m_sQueueSample.m_counter = 62;
+ m_sQueueSample.m_nCounter = 62;
m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR_2;
} else {
- m_sQueueSample.m_counter = 61;
+ m_sQueueSample.m_nCounter = 61;
m_sQueueSample.m_nSampleIndex = SFX_REVERSE_GEAR;
}
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nFrequency = (6000.f * modificator) + 7000;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 3.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_fSoundIntensity = reverseGearIntensity;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 5;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7087,36 +7848,38 @@ cAudioManager::ProcessSawMillScriptObject(uint8 sound)
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_LOOP;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SAWMILL_LOOP);
- m_sQueueSample.m_counter = 0;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_SAWMILL_LOOP);
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = 30;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
time = CTimer::GetTimeInMilliseconds();
if(time > gSawMillNextTime) {
- m_sQueueSample.m_bVolume =
- ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ 70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_CUT_WOOD;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_counter = 1;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nCounter = 1;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bReverbFlag = true;
@@ -7150,9 +7913,7 @@ cAudioManager::ProcessShopScriptObject(uint8 sound)
switch(sound) {
case SCRIPT_SOUND_SHOP_LOOP_S:
- case SCRIPT_SOUND_SHOP_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- break;
+ case SCRIPT_SOUND_SHOP_LOOP_L: m_sQueueSample.m_fSoundIntensity = 30.0f; break;
default: return;
}
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
@@ -7163,37 +7924,39 @@ cAudioManager::ProcessShopScriptObject(uint8 sound)
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_SHOP_LOOP;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOP_LOOP);
- m_sQueueSample.m_counter = 0;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_SHOP_LOOP);
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = 30;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
time = CTimer::GetTimeInMilliseconds();
if(time > gShopNextTime) {
- m_sQueueSample.m_bVolume =
- ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ 70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
rand = m_anRandomTable[1] & 1;
m_sQueueSample.m_nSampleIndex = rand + SFX_SHOP_TILL_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_counter = rand + 1;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nCounter = rand + 1;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = 70;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -7223,7 +7986,8 @@ cAudioManager::ProcessSpecial()
CPlayerPed *playerPed = FindPlayerPed();
if(playerPed) {
const PedState &state = playerPed->m_nPedState;
- if(state != PED_ENTER_CAR && state != PED_STEAL_CAR && !playerPed->bInVehicle)
+ if(state != PED_ENTER_CAR && state != PED_STEAL_CAR &&
+ !playerPed->bInVehicle)
SampleManager.StopChannel(m_bActiveSamples);
}
}
@@ -7244,49 +8008,55 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params)
speedMultipler = min(1.0f, train->m_fSpeed * 250.f / 51.f);
emittingVol = (75.f * speedMultipler);
if(train->m_fWagonPosition == 0.0f) {
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 300.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 300.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 32;
+ m_sQueueSample.m_nCounter = 32;
m_sQueueSample.m_nSampleIndex = SFX_TRAIN_FAR;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 2;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_TRAIN_FAR);
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 3.0f;
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_fSoundIntensity = 300.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
}
if(params->m_fDistance < 4900.f) {
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 70.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 70.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 33;
+ m_sQueueSample.m_nCounter = 33;
m_sQueueSample.m_nSampleIndex = SFX_TRAIN_NEAR;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 5;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
m_sQueueSample.m_nFrequency =
SampleManager.GetSampleBaseFrequency(SFX_TRAIN_NEAR) +
100 * m_sQueueSample.m_nEntityIndex % 987;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = 70.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7317,7 +8087,8 @@ cAudioManager::ProcessVehicle(CVehicle *veh)
if(params.m_pVehicle->m_status == STATUS_SIMPLE)
velChange = params.m_pVehicle->AutoPilot.m_fMaxTrafficSpeed * 0.02f;
else
- velChange = DotProduct(params.m_pVehicle->m_vecMoveSpeed, params.m_pVehicle->GetForward());
+ velChange =
+ DotProduct(params.m_pVehicle->m_vecMoveSpeed, params.m_pVehicle->GetForward());
params.m_fVelocityChange = velChange;
switch(params.m_pVehicle->m_vehType) {
case VEHICLE_TYPE_CAR:
@@ -7332,7 +8103,8 @@ cAudioManager::ProcessVehicle(CVehicle *veh)
if(params.m_nIndex == DODO) {
if(!ProcessVehicleRoadNoise(&params)) {
ProcessVehicleOneShots(&params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
+ ((CAutomobile *)veh)->m_fVelocityChangeForAudio =
+ params.m_fVelocityChange;
ProcessRainOnVehicle(&params);
break;
}
@@ -7341,7 +8113,8 @@ cAudioManager::ProcessVehicle(CVehicle *veh)
} else {
if(!ProcessVehicleRoadNoise(&params)) {
ProcessVehicleOneShots(&params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
+ ((CAutomobile *)veh)->m_fVelocityChangeForAudio =
+ params.m_fVelocityChange;
ProcessRainOnVehicle(&params);
break;
}
@@ -7350,7 +8123,8 @@ cAudioManager::ProcessVehicle(CVehicle *veh)
ProcessVehicleSkidding(&params);
ProcessVehicleHorn(&params);
ProcessVehicleSirenOrAlarm(&params);
- if(UsesReverseWarning(params.m_nIndex)) ProcessVehicleReverseWarning(&params);
+ if(UsesReverseWarning(params.m_nIndex))
+ ProcessVehicleReverseWarning(&params);
if(HasAirBrakes(params.m_nIndex)) ProcessAirBrakes(&params);
}
ProcessCarBombTick(&params);
@@ -7405,25 +8179,26 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params)
velocity = min(0.3f, Abs(automobile->Doors[i].m_fAngVel));
if(velocity > 0.0035f) {
emittingVol = (100.f * velocity * 10.f / 3.f);
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, 40.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVol, 40.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = i + 6;
+ m_sQueueSample.m_nCounter = i + 6;
m_sQueueSample.m_nSampleIndex =
m_anRandomTable[1] % 6 + SFX_COL_CAR_PANEL_1;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(
- m_sQueueSample.m_nSampleIndex) +
- RandomDisplacement(1000);
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(
+ m_sQueueSample.m_nSampleIndex) +
+ RandomDisplacement(1000);
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 10;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 10;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.field_48 = 1.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 1.0f;
m_sQueueSample.m_fSoundIntensity = 40.0f;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = true;
AddSampleToRequestedQueue();
@@ -7436,218 +8211,244 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams *params)
}
void
-cAudioManager::ProcessVehicleEngine(cVehicleParams* params)
+cAudioManager::ProcessVehicleEngine(cVehicleParams *params)
{
- CVehicle* playerVeh;
- CVehicle* veh;
- CAutomobile* automobile;
+ CVehicle *playerVeh;
+ CVehicle *veh;
+ CAutomobile *automobile;
float relativeGearChange;
float relativeChange;
float reverseRelativechange;
uint8 volume;
eSfxSample accelerationSample;
- int32 freq;
+ int32 freq = 0; // uinitialized variable
uint8 emittingVol;
- cTransmission* transmission;
+ cTransmission *transmission;
uint8 currentGear;
float modificator;
float traction = 0.f;
- if (params->m_fDistance < SQR(50.f)) {
+ if(params->m_fDistance < SQR(50.f)) {
playerVeh = FindPlayerVehicle();
veh = params->m_pVehicle;
- if (playerVeh == veh && veh->m_status == STATUS_WRECKED) {
+ if(playerVeh == veh && veh->m_status == STATUS_WRECKED) {
SampleManager.StopChannel(m_bActiveSamples);
return;
}
- if (veh->bEngineOn) {
+ if(veh->bEngineOn) {
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- automobile = (CAutomobile*)params->m_pVehicle;
- if (params->m_nIndex == DODO) {
+ automobile = (CAutomobile *)params->m_pVehicle;
+ if(params->m_nIndex == DODO) {
ProcessCesna(params);
return;
}
- if (FindPlayerVehicle() == veh) {
+ if(FindPlayerVehicle() == veh) {
ProcessPlayersVehicleEngine(params, automobile);
return;
}
transmission = params->m_pTransmission;
- if (transmission) {
+ if(transmission) {
currentGear = params->m_pVehicle->m_nCurrentGear;
- if (automobile->m_nWheelsOnGround) {
- if (automobile->bIsHandbrakeOn) {
- if (0.f == params->m_fVelocityChange) traction = 0.9f;
- }
- else if (params->m_pVehicle->m_status == STATUS_SIMPLE) {
+ if(automobile->m_nWheelsOnGround) {
+ if(automobile->bIsHandbrakeOn) {
+ if(0.f == params->m_fVelocityChange)
+ traction = 0.9f;
+ } else if(params->m_pVehicle->m_status == STATUS_SIMPLE) {
traction = 0.f;
- }
- else {
- switch (transmission->nDriveType) {
+ } else {
+ switch(transmission->nDriveType) {
case '4':
- for (int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) {
- if (automobile->m_aWheelState[i] == WHEEL_STATE_SPINNING)
+ for(int32 i = 0;
+ i <
+ ARRAY_SIZE(automobile->m_aWheelState);
+ i++) {
+ if(automobile->m_aWheelState[i] ==
+ WHEEL_STATE_SPINNING)
traction += 0.05f;
}
break;
case 'F':
- if (automobile->m_aWheelState[0] == WHEEL_STATE_SPINNING)
+ if(automobile->m_aWheelState[0] ==
+ WHEEL_STATE_SPINNING)
traction += 0.1f;
- if (automobile->m_aWheelState[2] == WHEEL_STATE_SPINNING)
+ if(automobile->m_aWheelState[2] ==
+ WHEEL_STATE_SPINNING)
traction += 0.1f;
break;
case 'R':
- if (automobile->m_aWheelState[1] == WHEEL_STATE_SPINNING)
+ if(automobile->m_aWheelState[1] ==
+ WHEEL_STATE_SPINNING)
traction += 0.1f;
- if (automobile->m_aWheelState[3] == WHEEL_STATE_SPINNING)
+ if(automobile->m_aWheelState[3] ==
+ WHEEL_STATE_SPINNING)
traction += 0.1f;
break;
}
}
- if (transmission->fMaxVelocity <= 0.f) {
+ if(transmission->fMaxVelocity <= 0.f) {
relativeChange = 0.f;
- }
- else if (currentGear) {
- if ((params->m_fVelocityChange -
- transmission->Gears[currentGear].fShiftDownVelocity) /
- transmission->fMaxVelocity * 2.5f <=
- 1.f)
+ } else if(currentGear) {
+ if((params->m_fVelocityChange -
+ transmission->Gears[currentGear]
+ .fShiftDownVelocity) /
+ transmission->fMaxVelocity * 2.5f <=
+ 1.f)
relativeGearChange =
- (params->m_fVelocityChange -
- transmission->Gears[currentGear].fShiftDownVelocity) /
- transmission->fMaxVelocity * 2.5f;
+ (params->m_fVelocityChange -
+ transmission->Gears[currentGear]
+ .fShiftDownVelocity) /
+ transmission->fMaxVelocity * 2.5f;
else
relativeGearChange = 1.f;
- if (0.f == traction && automobile->m_status != STATUS_SIMPLE &&
- params->m_fVelocityChange >=
- transmission->Gears[1].fShiftUpVelocity) {
+ if(0.f == traction &&
+ automobile->m_status != STATUS_SIMPLE &&
+ params->m_fVelocityChange >=
+ transmission->Gears[1].fShiftUpVelocity) {
traction = 0.7f;
}
- relativeChange = traction * automobile->m_fGasPedalAudio * 0.95f +
- (1.f - traction) * relativeGearChange;
- }
- else {
- reverseRelativechange =
- Abs((params->m_fVelocityChange -
- transmission->Gears[0].fShiftDownVelocity) /
- transmission->fMaxReverseVelocity);
- if (1.f - reverseRelativechange <= 1.f) {
- relativeChange = 1.f - reverseRelativechange;
- }
- else {
+ relativeChange =
+ traction * automobile->m_fGasPedalAudio *
+ 0.95f +
+ (1.f - traction) * relativeGearChange;
+ } else {
+ reverseRelativechange = Abs(
+ (params->m_fVelocityChange -
+ transmission->Gears[0].fShiftDownVelocity) /
+ transmission->fMaxReverseVelocity);
+ if(1.f - reverseRelativechange <= 1.f) {
+ relativeChange =
+ 1.f - reverseRelativechange;
+ } else {
relativeChange = 1.f;
}
}
- }
- else {
- if (automobile->m_nDriveWheelsOnGround)
- automobile->m_fGasPedalAudio = automobile->m_fGasPedalAudio * 0.4f;
+ } else {
+ if(automobile->m_nDriveWheelsOnGround)
+ automobile->m_fGasPedalAudio =
+ automobile->m_fGasPedalAudio * 0.4f;
relativeChange = automobile->m_fGasPedalAudio;
}
modificator = relativeChange;
- if (currentGear || !automobile->m_nWheelsOnGround)
+ if(currentGear || !automobile->m_nWheelsOnGround)
freq = 1200 * currentGear + 18000.f * modificator + 14000;
else
freq = 13000.f * modificator + 14000;
- if (modificator >= 0.75f) {
+ if(modificator >= 0.75f) {
emittingVol = 120;
- volume = ComputeVolume(120, 50.f, m_sQueueSample.m_fDistance);
- }
- else {
+ volume =
+ ComputeVolume(120, 50.f, m_sQueueSample.m_fDistance);
+ } else {
emittingVol = modificator * 4 / 3 * 40.f + 80.f;
- volume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
+ volume = ComputeVolume(emittingVol, 50.f,
+ m_sQueueSample.m_fDistance);
}
- }
- else {
+ } else {
modificator = 0.f;
emittingVol = 80;
volume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance);
}
m_sQueueSample.m_bVolume = volume;
- if (m_sQueueSample.m_bVolume) {
- if (automobile->m_status == STATUS_SIMPLE) {
- if (modificator < 0.02f) {
+ if(m_sQueueSample.m_bVolume) {
+ if(automobile->m_status == STATUS_SIMPLE) {
+ if(modificator < 0.02f) {
m_sQueueSample.m_nSampleIndex =
- CarSounds[params->m_nIndex].m_bEngineSoundType + SFX_CAR_REV_10;
+ CarSounds[params->m_nIndex].m_bEngineSoundType +
+ SFX_CAR_REV_10;
freq = 10000.f * modificator + 22050;
- m_sQueueSample.m_counter = 52;
+ m_sQueueSample.m_nCounter = 52;
m_sQueueSample.m_bBankIndex = 0;
- m_sQueueSample.m_bIsDistant = 0;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nFrequency =
- freq + 100 * m_sQueueSample.m_nEntityIndex % 1000;
- if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 ||
- m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
- m_sQueueSample.m_nFrequency = m_sQueueSample.m_nFrequency >> 1;
+ freq +
+ 100 * m_sQueueSample.m_nEntityIndex % 1000;
+ if(m_sQueueSample.m_nSampleIndex ==
+ SFX_CAR_IDLE_6 ||
+ m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
+ m_sQueueSample.m_nFrequency =
+ m_sQueueSample.m_nFrequency >> 1;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(
- m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 8;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
return;
}
- accelerationSample = CarSounds[params->m_nIndex].m_nAccelerationSampleIndex;
- }
- else {
- if (automobile->m_fGasPedal < 0.05f) {
+ accelerationSample =
+ CarSounds[params->m_nIndex].m_nAccelerationSampleIndex;
+ } else {
+ if(automobile->m_fGasPedal < 0.05f) {
m_sQueueSample.m_nSampleIndex =
- CarSounds[params->m_nIndex].m_bEngineSoundType +
- SFX_CAR_REV_10; // to recheck idle sounds start 1 postion later
+ CarSounds[params->m_nIndex].m_bEngineSoundType +
+ SFX_CAR_REV_10; // to recheck idle sounds start
+ // 1 postion later
freq = 10000.f * modificator + 22050;
- m_sQueueSample.m_counter = 52;
+ m_sQueueSample.m_nCounter = 52;
m_sQueueSample.m_bBankIndex = 0;
- m_sQueueSample.m_bIsDistant = 0;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nFrequency =
- freq + 100 * m_sQueueSample.m_nEntityIndex % 1000;
- if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 ||
- m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
- m_sQueueSample.m_nFrequency = m_sQueueSample.m_nFrequency >> 1;
+ freq +
+ 100 * m_sQueueSample.m_nEntityIndex % 1000;
+ if(m_sQueueSample.m_nSampleIndex ==
+ SFX_CAR_IDLE_6 ||
+ m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
+ m_sQueueSample.m_nFrequency =
+ m_sQueueSample.m_nFrequency >> 1;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(
- m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 8;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
m_sQueueSample.m_bReverbFlag = 1;
m_sQueueSample.m_bRequireReflection = 0;
AddSampleToRequestedQueue();
return;
}
- accelerationSample = CarSounds[params->m_nIndex].m_nAccelerationSampleIndex;
+ accelerationSample =
+ CarSounds[params->m_nIndex].m_nAccelerationSampleIndex;
}
m_sQueueSample.m_nSampleIndex = accelerationSample;
- m_sQueueSample.m_counter = 2;
+ m_sQueueSample.m_nCounter = 2;
m_sQueueSample.m_bBankIndex = 0;
- m_sQueueSample.m_bIsDistant = 0;
- m_sQueueSample.field_16 = 3;
- m_sQueueSample.m_nFrequency = freq + 100 * m_sQueueSample.m_nEntityIndex % 1000;
- if (m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 ||
- m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
- m_sQueueSample.m_nFrequency = m_sQueueSample.m_nFrequency >> 1;
+ m_sQueueSample.m_bIs2D = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nFrequency =
+ freq + 100 * m_sQueueSample.m_nEntityIndex % 1000;
+ if(m_sQueueSample.m_nSampleIndex == SFX_CAR_IDLE_6 ||
+ m_sQueueSample.m_nSampleIndex == SFX_CAR_REV_6)
+ m_sQueueSample.m_nFrequency =
+ m_sQueueSample.m_nFrequency >> 1;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 8;
- m_sQueueSample.m_bReverbFlag = 1;
- m_sQueueSample.m_bRequireReflection = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
return;
}
@@ -7666,32 +8467,43 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams *params)
automobile->m_modelIndex != MI_MRWHOOP) {
if(automobile->m_nCarHornTimer) {
if(params->m_pVehicle->m_status) {
- if(automobile->m_nCarHornTimer > 44) automobile->m_nCarHornTimer = 44;
+ if(automobile->m_nCarHornTimer > 44)
+ automobile->m_nCarHornTimer = 44;
if(automobile->m_nCarHornTimer == 44)
automobile->field_22D =
- (uint8(m_FrameCounter) + uint8(m_sQueueSample.m_nEntityIndex)) & 7;
- if (!hornPatternsArray[automobile->field_22D][44 - automobile->m_nCarHornTimer]) return;
+ (uint8(m_FrameCounter) +
+ uint8(m_sQueueSample.m_nEntityIndex)) &
+ 7;
+ if(!hornPatternsArray[automobile->field_22D]
+ [44 - automobile->m_nCarHornTimer])
+ return;
}
- CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- m_sQueueSample.m_bVolume = ComputeVolume(80, 40.f, m_sQueueSample.m_fDistance);
+ CalculateDistance(params->m_bDistanceCalculated,
+ params->m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(80, 40.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 4;
- m_sQueueSample.m_nSampleIndex = CarSounds[params->m_nIndex].m_nHornSample;
+ m_sQueueSample.m_nCounter = 4;
+ m_sQueueSample.m_nSampleIndex =
+ CarSounds[params->m_nIndex].m_nHornSample;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 2;
- m_sQueueSample.m_nFrequency = CarSounds[params->m_nIndex].m_nHornFrequency;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_nFrequency =
+ CarSounds[params->m_nIndex].m_nHornFrequency;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = 80;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 5.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 5.0f;
m_sQueueSample.m_fSoundIntensity = 40.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7701,11 +8513,517 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams *params)
}
}
-WRAPPER
void
-cAudioManager::ProcessVehicleOneShots(void *)
+cAudioManager::ProcessVehicleOneShots(cVehicleParams *params)
{
- EAXJMP(0x56CD40);
+ int16 event;
+ uint8 emittingVol;
+ float relVol;
+ float vol;
+ bool noReflections;
+ float maxDist;
+ cPedParams pedParams;
+
+ static uint8 WaveIndex = 41;
+ static uint8 GunIndex = 53;
+ static uint8 iWheelIndex = 82;
+ static uint8 CrunchOffset = 0;
+
+ for(int i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
+ noReflections = 0;
+ m_sQueueSample.m_bRequireReflection = false;
+ event = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
+ switch(event) {
+ case SOUND_CAR_DOOR_CLOSE_BONNET:
+ case SOUND_CAR_DOOR_CLOSE_BUMPER:
+ case SOUND_CAR_DOOR_CLOSE_FRONT_LEFT:
+ case SOUND_CAR_DOOR_CLOSE_FRONT_RIGHT:
+ case SOUND_CAR_DOOR_CLOSE_BACK_LEFT:
+ case SOUND_CAR_DOOR_CLOSE_BACK_RIGHT:
+ maxDist = 2500.f;
+ emittingVol = m_anRandomTable[2] % 5 + 122;
+ switch(CarSounds[params->m_nIndex].m_bDoorType) {
+ case 0: m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_CLOSE; break;
+ case 2: m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_CLOSE; break;
+ case 3: m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; break;
+ default: m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_CLOSE; break;
+ }
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter =
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 22;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 50.0f;
+ m_sQueueSample.m_bRequireReflection = true;
+ break;
+ case SOUND_CAR_DOOR_OPEN_BONNET:
+ case SOUND_CAR_DOOR_OPEN_BUMPER:
+ case SOUND_CAR_DOOR_OPEN_FRONT_LEFT:
+ case SOUND_CAR_DOOR_OPEN_FRONT_RIGHT:
+ case SOUND_CAR_DOOR_OPEN_BACK_LEFT:
+ case SOUND_CAR_DOOR_OPEN_BACK_RIGHT:
+ maxDist = 2500.f;
+ emittingVol = m_anRandomTable[1] % 10 + 117;
+ switch(CarSounds[params->m_nIndex].m_bDoorType) {
+ case 0: m_sQueueSample.m_nSampleIndex = SFX_OLD_CAR_DOOR_OPEN; break;
+ case 2: m_sQueueSample.m_nSampleIndex = SFX_TRUCK_DOOR_OPEN; break;
+ case 3: m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES; break;
+ default: m_sQueueSample.m_nSampleIndex = SFX_NEW_CAR_DOOR_OPEN; break;
+ }
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter =
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] + 10;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 50.0f;
+ m_sQueueSample.m_bRequireReflection = true;
+ break;
+ case SOUND_CAR_WINDSHIELD_CRACK:
+ maxDist = 900.f;
+ m_sQueueSample.m_nSampleIndex = SFX_GLASS_CRACK;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 68;
+ emittingVol = m_anRandomTable[1] % 30 + 60;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_GLASS_CRACK);
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 30.0f;
+ break;
+ case SOUND_CAR_JUMP:
+ emittingVol = max(
+ 80.f,
+ 2 * (100.f *
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]));
+ maxDist = 1225.f;
+ m_sQueueSample.m_nSampleIndex = SFX_TYRE_BUMP;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = iWheelIndex++;
+ if(iWheelIndex > 85) iWheelIndex = 82;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_TYRE_BUMP);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
+ if(params->m_nIndex == 41) {
+ m_sQueueSample.m_nFrequency *= 2;
+ emittingVol = emittingVol >> 1;
+ }
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = 35.0f;
+ break;
+ case SOUND_E:
+ case SOUND_F:
+ case SOUND_STEP_START:
+ case SOUND_STEP_END:
+ case SOUND_FALL_LAND:
+ case SOUND_FALL_COLLAPSE:
+ case SOUND_FIGHT_PUNCH_33:
+ case SOUND_FIGHT_KICK_34:
+ case SOUND_FIGHT_HEADBUTT_35:
+ case SOUND_FIGHT_PUNCH_36:
+ case SOUND_FIGHT_PUNCH_37:
+ case SOUND_FIGHT_CLOSE_PUNCH_38:
+ case SOUND_FIGHT_PUNCH_39:
+ case SOUND_FIGHT_PUNCH_OR_KICK_BELOW_40:
+ case SOUND_FIGHT_PUNCH_41:
+ case SOUND_FIGHT_PUNCH_FROM_BEHIND_42:
+ case SOUND_FIGHT_KNEE_OR_KICK_43:
+ case SOUND_FIGHT_KICK_44:
+ case SOUND_WEAPON_BAT_ATTACK:
+ case SOUND_WEAPON_RELOAD:
+ case SOUND_WEAPON_AK47_BULLET_ECHO:
+ case SOUND_WEAPON_UZI_BULLET_ECHO:
+ case SOUND_WEAPON_M16_BULLET_ECHO:
+ case SOUND_WEAPON_FLAMETHROWER_FIRE:
+ case SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM:
+ case SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM:
+ case SOUND_WEAPON_HIT_PED:
+ case SOUND_GARAGE_NO_MONEY:
+ case SOUND_GARAGE_BAD_VEHICLE:
+ case SOUND_GARAGE_OPENING:
+ case SOUND_GARAGE_BOMB_ALREADY_SET:
+ case SOUND_GARAGE_BOMB1_SET:
+ case SOUND_GARAGE_BOMB2_SET:
+ case SOUND_GARAGE_BOMB3_SET:
+ case SOUND_40:
+ case SOUND_41:
+ case SOUND_GARAGE_VEHICLE_DECLINED:
+ case SOUND_GARAGE_VEHICLE_ACCEPTED:
+ case SOUND_GARAGE_DOOR_CLOSED:
+ case SOUND_GARAGE_DOOR_OPENED:
+ case SOUND_CRANE_PICKUP:
+ case SOUND_PICKUP_WEAPON_BOUGHT:
+ case SOUND_PICKUP_WEAPON:
+ case SOUND_PICKUP_HEALTH:
+ case SOUND_4A:
+ case SOUND_4B:
+ case SOUND_PICKUP_ADRENALINE:
+ case SOUND_PICKUP_ARMOUR:
+ case SOUND_PICKUP_BONUS:
+ case SOUND_PICKUP_MONEY:
+ case SOUND_PICKUP_HIDDEN_PACKAGE:
+ case SOUND_PICKUP_PACMAN_PILL:
+ case SOUND_PICKUP_PACMAN_PACKAGE:
+ case SOUND_PICKUP_FLOAT_PACKAGE:
+ case SOUND_RAMPAGE_START:
+ case SOUND_RAMPAGE_ONGOING:
+ case SOUND_RAMPAGE_PASSED:
+ case SOUND_RAMPAGE_FAILED:
+ case SOUND_RAMPAGE_KILL:
+ case SOUND_RAMPAGE_CAR_BLOWN:
+ case SOUND_EVIDENCE_PICKUP:
+ case SOUND_UNLOAD_GOLD:
+ case SOUND_PAGER:
+ case SOUND_PED_DEATH:
+ case SOUND_PED_DAMAGE:
+ case SOUND_PED_HIT:
+ case SOUND_PED_LAND:
+ case SOUND_PED_BULLET_HIT:
+ case SOUND_PED_BOMBER:
+ case SOUND_PED_BURNING:
+ case SOUND_PED_ARREST_FBI:
+ case SOUND_PED_ARREST_SWAT:
+ case SOUND_PED_ARREST_COP:
+ case SOUND_PED_HANDS_UP:
+ case SOUND_PED_HANDS_COWER:
+ case SOUND_PED_FLEE_SPRINT:
+ case SOUND_PED_CAR_JACKING:
+ case SOUND_PED_MUGGING:
+ case SOUND_PED_CAR_JACKED:
+ case SOUND_PED_ROBBED:
+ case SOUND_PED_TAXI_WAIT:
+ case SOUND_PED_ATTACK:
+ case SOUND_PED_DEFEND:
+ case SOUND_PED_PURSUIT_ARMY:
+ case SOUND_PED_PURSUIT_FBI:
+ case SOUND_PED_PURSUIT_SWAT:
+ case SOUND_PED_PURSUIT_COP:
+ case SOUND_PED_HEALING:
+ case SOUND_PED_7B:
+ case SOUND_PED_LEAVE_VEHICLE:
+ case SOUND_PED_EVADE:
+ case SOUND_PED_FLEE_RUN:
+ case SOUND_PED_CAR_COLLISION:
+ case SOUND_PED_SOLICIT:
+ case SOUND_PED_EXTINGUISHING_FIRE:
+ case SOUND_PED_WAIT_DOUBLEBACK:
+ case SOUND_PED_CHAT_SEXY:
+ case SOUND_PED_CHAT_EVENT:
+ case SOUND_PED_CHAT:
+ case SOUND_PED_TAXI_CALL:
+ case SOUND_INJURED_PED_MALE_OUCH:
+ case SOUND_INJURED_PED_FEMALE:
+ case SOUND_8A:
+ case SOUND_RACE_START_3:
+ case SOUND_RACE_START_2:
+ case SOUND_RACE_START_1:
+ case SOUND_RACE_START_GO:
+ case SOUND_SPLASH: continue;
+ case SOUND_CAR_ENGINE_START:
+ emittingVol = 60;
+ maxDist = 1600.f;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_STARTER;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 33;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_CAR_STARTER);
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ m_sQueueSample.m_bRequireReflection = true;
+ break;
+ case SOUND_CAR_LIGHT_BREAK:
+ m_sQueueSample.m_nSampleIndex = SFX_GLASS_SHARD_1;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 37;
+ m_sQueueSample.m_nFrequency =
+ 9 * SampleManager.GetSampleBaseFrequency(SFX_GLASS_SHARD_1) / 10;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 3);
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 30.0f;
+ maxDist = 900.f;
+ emittingVol = m_anRandomTable[4] % 10 + 30;
+ break;
+ case SOUND_CAR_HYDRAULIC_1:
+ case SOUND_CAR_HYDRAULIC_2:
+ if(event == MOONBEAM) // todo check
+ m_sQueueSample.m_nFrequency = 15600;
+ else
+ m_sQueueSample.m_nFrequency = 13118;
+ m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_FAST_MOVE;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 51;
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 3);
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 35.0f;
+ maxDist = 1225.f;
+ emittingVol = m_anRandomTable[0] % 15 + 55;
+ break;
+ case SOUND_CAR_HYDRAULIC_3:
+ m_sQueueSample.m_nSampleIndex = SFX_SUSPENSION_SLOW_MOVE_LOOP;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 86;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_SUSPENSION_SLOW_MOVE_LOOP);
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 35.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
+ noReflections = true;
+ maxDist = 1225.f;
+ emittingVol = m_anRandomTable[0] % 15 + 55;
+ break;
+ case SOUND_CAR_JERK:
+ m_sQueueSample.m_nSampleIndex = SFX_SHAG_SUSPENSION;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 87;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_SHAG_SUSPENSION);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 3);
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 35.0f;
+ maxDist = 1225.f;
+ emittingVol = m_anRandomTable[1] % 15 + 55;
+ break;
+ case SOUND_CAR_SPLASH:
+ vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ if(vol <= 300.f) continue;
+ if(vol > 1200.f)
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] =
+ 1200.0f;
+ relVol = (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] -
+ 300.f) /
+ 900.f;
+ m_sQueueSample.m_nSampleIndex =
+ (m_anRandomTable[0] & 1) + SFX_BOAT_SPLASH_1;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = WaveIndex++;
+ if(WaveIndex > 46) WaveIndex = 41;
+ m_sQueueSample.m_nFrequency = (7000.f * relVol) + 6000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ emittingVol = (55.f * relVol);
+ maxDist = 1600.f;
+ break;
+ case SOUND_17:
+ m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_THUMB_OFF;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 47;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_POLICE_BOAT_THUMB_OFF) +
+ RandomDisplacement(600);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 50.0f;
+ emittingVol =
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ maxDist = 2500.f;
+ break;
+ case SOUND_18:
+ case SOUND_19:
+ m_sQueueSample.m_nSampleIndex = SFX_AIR_BRAKES;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 59;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 11025;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 5.0f;
+ m_sQueueSample.m_fSoundIntensity = 35.0f;
+ maxDist = 1225.f;
+ emittingVol = m_anRandomTable[1] % 20 + 70;
+ break;
+ case SOUND_CAR_TANK_TURRET_ROTATE:
+ vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ if(vol > 0.038400002f) vol = 0.038400002f;
+ m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 79;
+ m_sQueueSample.m_nFrequency = (3000.f * vol * 26.041666f) + 9000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ emittingVol = (37.f * vol * 26.041666f) + 90;
+ maxDist = 1600.f;
+ noReflections = true;
+ break;
+ case SOUND_CAR_BOMB_TICK:
+ m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 80;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_BOMB_BEEP);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 30.0f;
+ maxDist = 900.f;
+ m_sQueueSample.m_bRequireReflection = true;
+ emittingVol = 60;
+ break;
+ case SOUND_PLANE_ON_GROUND:
+ m_sQueueSample.m_nSampleIndex = SFX_JUMBO_LAND_WHEELS;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 81;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_JUMBO_LAND_WHEELS);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 180.0f;
+ maxDist = 32400.f;
+ emittingVol = m_anRandomTable[4] % 25 + 75;
+ break;
+ case SOUND_WEAPON_SHOT_FIRED:
+ emittingVol = m_anRandomTable[2];
+ maxDist = 14400.f;
+ m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = GunIndex++;
+ emittingVol = emittingVol % 15 + 65;
+ if(GunIndex > 58) GunIndex = 53;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 4);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ break;
+ case SOUND_WEAPON_HIT_VEHICLE:
+ m_sQueueSample.m_nSampleIndex =
+ m_anRandomTable[m_sQueueSample.m_nEntityIndex %
+ ARRAY_SIZE(m_anRandomTable)] %
+ 6 +
+ SFX_BULLET_CAR_1;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 34;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency +=
+ RandomDisplacement(m_sQueueSample.m_nFrequency >> 5);
+ m_sQueueSample.m_nReleasingVolumeModificator = 7;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ maxDist = 1600.f;
+ emittingVol = m_anRandomTable[3] % 20 + 90;
+ break;
+ case SOUND_BOMB_TIMED_ACTIVATED:
+ case SOUND_55:
+ case SOUND_BOMB_ONIGNITION_ACTIVATED:
+ case SOUND_BOMB_TICK:
+ m_sQueueSample.m_nSampleIndex = SFX_ARM_BOMB;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 36;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_ARM_BOMB);
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 50.0f;
+ m_sQueueSample.m_bRequireReflection = true;
+ emittingVol = 50;
+ maxDist = 2500.f;
+ break;
+ case SOUND_PED_HELI_PLAYER_FOUND:
+ pedParams.m_pPed = 0;
+ pedParams.m_bDistanceCalculated = 0;
+ pedParams.m_fDistance = 0.0f;
+ pedParams.m_bDistanceCalculated = params->m_bDistanceCalculated;
+ pedParams.m_fDistance = params->m_fDistance;
+ SetupPedComments(&pedParams, SOUND_PED_HELI_PLAYER_FOUND);
+ continue;
+ case SOUND_PED_BODYCAST_HIT:
+ pedParams.m_pPed = 0;
+ pedParams.m_bDistanceCalculated = 0;
+ pedParams.m_fDistance = 0.0f;
+ pedParams.m_bDistanceCalculated = params->m_bDistanceCalculated;
+ pedParams.m_fDistance = params->m_fDistance;
+ SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT);
+ continue;
+ case SOUND_WATER_FALL:
+ m_sQueueSample.m_nSampleIndex = SFX_SPLASH_1;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 15;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1000) + 16000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ maxDist = 1600.f;
+ m_sQueueSample.m_bRequireReflection = true;
+ emittingVol = m_anRandomTable[4] % 20 + 90;
+ break;
+ case SOUND_SPLATTER:
+ m_sQueueSample.m_nSampleIndex = CrunchOffset + SFX_PED_CRUNCH_1;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 48;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_PED_CRUNCH_1) +
+ RandomDisplacement(600);
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ ++CrunchOffset;
+ maxDist = 1600.f;
+ emittingVol = m_anRandomTable[4] % 20 + 55;
+ CrunchOffset &= 1u;
+ m_sQueueSample.m_bRequireReflection = true;
+ break;
+ case SOUND_CAR_PED_COLLISION:
+ vol = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+ if(20.f < vol) vol = 20.f;
+ emittingVol = (vol * 0.05f * 127.f);
+ if(!emittingVol) continue;
+
+ m_sQueueSample.m_nSampleIndex = (m_anRandomTable[2] & 3) + SFX_FIGHT_1;
+ m_sQueueSample.m_bBankIndex = 0;
+ m_sQueueSample.m_nCounter = 50;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex) >>
+ 1;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ maxDist = 1600.f;
+ break;
+ }
+ if(params->m_fDistance < maxDist) {
+ CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
+ if(m_sQueueSample.m_bVolume) {
+ if(noReflections) {
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = 0;
+ } else {
+ m_sQueueSample.m_nLoopCount = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = 1;
+ }
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_bEmittingVolume = emittingVol;
+ m_sQueueSample.m_bReverbFlag = 1;
+ m_sQueueSample.m_bIs2D = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+ }
}
bool
@@ -7719,11 +9037,11 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(60, 50.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 12;
+ m_sQueueSample.m_nCounter = 12;
m_sQueueSample.m_nSampleIndex = SFX_REVERSE_WARNING;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 2;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
m_sQueueSample.m_nFrequency =
(100 * m_sQueueSample.m_nEntityIndex & 1023) +
SampleManager.GetSampleBaseFrequency(SFX_REVERSE_WARNING);
@@ -7731,11 +9049,12 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams *params)
m_sQueueSample.m_bEmittingVolume = 60;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 3.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7758,16 +9077,21 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
if(params->m_pVehicle->m_vecMoveSpeed.z) {
velocity = Abs(params->m_fVelocityChange);
if(velocity > 0.0f) {
- CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
+ CalculateDistance(params->m_bDistanceCalculated,
+ params->m_fDistance);
emittingVol =
- 30.f * min(1.f, velocity / (0.5f * params->m_pTransmission->fMaxVelocity));
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance);
+ 30.f *
+ min(1.f,
+ velocity / (0.5f * params->m_pTransmission->fMaxVelocity));
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 95.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 0;
+ m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
- if(params->m_pVehicle->m_nSurfaceTouched == SURFACE_PUDDLE) {
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ if(params->m_pVehicle->m_nSurfaceTouched ==
+ SURFACE_PUDDLE) {
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
freq = 6050 * emittingVol / 30 + 16000;
} else {
@@ -7775,19 +9099,22 @@ cAudioManager::ProcessVehicleRoadNoise(cVehicleParams *params)
modificator = m_sQueueSample.m_fDistance / 190.f;
sampleFreq = SampleManager.GetSampleBaseFrequency(
SFX_ROAD_NOISE);
- freq = (sampleFreq * modificator) + ((3 * sampleFreq) >> 2);
+ freq = (sampleFreq * modificator) +
+ ((3 * sampleFreq) >> 2);
}
m_sQueueSample.m_nFrequency = freq;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = 95.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 4;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7808,7 +9135,7 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params)
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
m_sQueueSample.m_bVolume = ComputeVolume(80, 110.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 5;
+ m_sQueueSample.m_nCounter = 5;
if(UsesSiren(params->m_nIndex)) {
if(params->m_pVehicle->m_status == STATUS_ABANDONED) return;
if(veh->m_nCarHornTimer && params->m_nIndex != FIRETRUK) {
@@ -7817,8 +9144,9 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params)
m_sQueueSample.m_nFrequency = 16113;
else
m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(SFX_SIREN_FAST);
- m_sQueueSample.m_counter = 60;
+ SampleManager.GetSampleBaseFrequency(
+ SFX_SIREN_FAST);
+ m_sQueueSample.m_nCounter = 60;
} else {
m_sQueueSample.m_nSampleIndex =
CarSounds[params->m_nIndex].m_nSirenOrAlarmSample;
@@ -7826,21 +9154,24 @@ cAudioManager::ProcessVehicleSirenOrAlarm(cVehicleParams *params)
CarSounds[params->m_nIndex].m_nSirenOrAlarmFrequency;
}
} else {
- m_sQueueSample.m_nSampleIndex = CarSounds[params->m_nIndex].m_nSirenOrAlarmSample;
- m_sQueueSample.m_nFrequency = CarSounds[params->m_nIndex].m_nSirenOrAlarmFrequency;
+ m_sQueueSample.m_nSampleIndex =
+ CarSounds[params->m_nIndex].m_nSirenOrAlarmSample;
+ m_sQueueSample.m_nFrequency =
+ CarSounds[params->m_nIndex].m_nSirenOrAlarmFrequency;
}
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = 80;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 7.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 7.0f;
m_sQueueSample.m_fSoundIntensity = 110.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 5;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7863,12 +9194,13 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
if(!automobile->m_nWheelsOnGround) return;
CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
for(int32 i = 0; i < ARRAY_SIZE(automobile->m_aWheelState); i++) {
- if(!automobile->m_aWheelState[i] || automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING)
+ if(!automobile->m_aWheelState[i] ||
+ automobile->Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING)
continue;
transmission = params->m_pTransmission;
if(transmission->nDriveType == '4') {
- newSkidVal =
- GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange);
+ newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission,
+ params->m_fVelocityChange);
if(newSkidVal > skidVal) skidVal = newSkidVal;
continue;
}
@@ -7878,31 +9210,33 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
continue;
}
if(i != 1 && i != 3) {
- newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission,
- params->m_fVelocityChange);
+ newSkidVal = GetVehicleNonDriveWheelSkidValue(
+ i, automobile, transmission, params->m_fVelocityChange);
if(newSkidVal > skidVal) skidVal = newSkidVal;
continue;
}
- newSkidVal =
- GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange);
+ newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission,
+ params->m_fVelocityChange);
if(newSkidVal > skidVal) skidVal = newSkidVal;
continue;
}
if(i == 0 || i == 2) {
- newSkidVal =
- GetVehicleDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange);
+ newSkidVal = GetVehicleDriveWheelSkidValue(i, automobile, transmission,
+ params->m_fVelocityChange);
if(newSkidVal > skidVal) skidVal = newSkidVal;
continue;
}
- newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission, params->m_fVelocityChange);
+ newSkidVal = GetVehicleNonDriveWheelSkidValue(i, automobile, transmission,
+ params->m_fVelocityChange);
if(newSkidVal > skidVal) skidVal = newSkidVal;
}
if(skidVal > 0.0f) {
emittingVol = 50.f * skidVal;
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 40.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 40.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 3;
+ m_sQueueSample.m_nCounter = 3;
switch(params->m_pVehicle->m_nSurfaceTouched) {
case SURFACE_GRASS:
case SURFACE_HEDGE:
@@ -7926,17 +9260,18 @@ cAudioManager::ProcessVehicleSkidding(cVehicleParams *params)
}
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 8;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 8;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 3.0f;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
m_sQueueSample.m_fSoundIntensity = 40.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 3;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7948,29 +9283,33 @@ void cAudioManager::ProcessWaterCannon(int32)
{
for(int32 i = 0; i < NUM_WATERCANNONS; i++) {
if(CWaterCannons::aCannons[i].m_nId) {
- m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur];
+ m_sQueueSample.m_vecPos =
+ CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur];
float distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < 900.f) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_bVolume =
- ComputeVolume(50, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
+ ComputeVolume(50, m_sQueueSample.m_fSoundIntensity,
+ m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_fSoundIntensity = 900.0f;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
m_sQueueSample.m_nFrequency = 15591;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.m_counter = i;
- m_sQueueSample.field_48 = 2.0f;
- m_sQueueSample.field_76 = 8;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_nCounter = i;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bEmittingVolume = 50;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -7986,7 +9325,8 @@ cAudioManager::ProcessWeather(int32 id)
uint8 vol;
static uint8 counter = 0;
- if(m_asAudioEntities[id].m_AudioEvents && m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) {
+ if(m_asAudioEntities[id].m_AudioEvents &&
+ m_asAudioEntities[id].m_awAudioEvent[0] == SOUND_LIGHTNING) {
if(m_asAudioEntities[id].m_afVolume[0] >= 10.f) {
m_sQueueSample.m_nSampleIndex = SFX_EXPLOSION_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
@@ -8001,12 +9341,12 @@ cAudioManager::ProcessWeather(int32 id)
m_sQueueSample.m_bVolume = vol;
if(TheCamera.SoundDistUp < 20.f) m_sQueueSample.m_bVolume >>= 1;
if(counter == 4) counter = 0;
- m_sQueueSample.m_counter = counter++;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_nCounter = counter++;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_bOffset = (m_anRandomTable[2] & 15) + 55;
- m_sQueueSample.m_bIsDistant = true;
+ m_sQueueSample.m_bIs2D = true;
m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.field_56 = 1;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bEmittingVolume = m_sQueueSample.m_bVolume;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -8016,21 +9356,22 @@ cAudioManager::ProcessWeather(int32 id)
}
if(CWeather::Rain > 0.0f && (!CCullZones::CamNoRain() || !CCullZones::PlayerNoRain())) {
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
- m_sQueueSample.m_nFrequency =
- SampleManager.GetSampleBaseFrequency(SFX_RAIN);
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAIN);
m_sQueueSample.m_bVolume = (int32)(25.f * CWeather::Rain);
- m_sQueueSample.m_counter = 4;
+ m_sQueueSample.m_nCounter = 4;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.field_16 = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 0;
m_sQueueSample.m_bOffset = 63;
- m_sQueueSample.m_bIsDistant = true;
+ m_sQueueSample.m_bIs2D = true;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 30;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 30;
m_sQueueSample.m_bReverbFlag = false;
m_sQueueSample.m_bEmittingVolume = m_sQueueSample.m_bVolume;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
@@ -8050,30 +9391,35 @@ cAudioManager::ProcessWetRoadNoise(cVehicleParams *params)
if(params->m_pVehicle->m_vecMoveSpeed.z) {
velChange = Abs(params->m_fVelocityChange);
if(velChange > 0.f) {
- CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
+ CalculateDistance(params->m_bDistanceCalculated,
+ params->m_fDistance);
relativeVelocity =
- min(1.0f, velChange / (0.5f * params->m_pTransmission->fMaxVelocity));
+ min(1.0f,
+ velChange / (0.5f * params->m_pTransmission->fMaxVelocity));
emittingVol = 23.0f * relativeVelocity * CWeather::WetRoads;
- m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_bVolume =
+ ComputeVolume(emittingVol, 30.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 1;
+ m_sQueueSample.m_nCounter = 1;
m_sQueueSample.m_nSampleIndex = SFX_ROAD_NOISE;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 3;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
modificator = m_sQueueSample.m_fDistance / 6.f;
freq = SampleManager.GetSampleBaseFrequency(SFX_ROAD_NOISE);
m_sQueueSample.m_nFrequency = freq + freq * modificator;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
- SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ SampleManager.GetSampleLoopStartOffset(
+ m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
- SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 6.0f;
+ SampleManager.GetSampleLoopEndOffset(
+ m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 4;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -8091,9 +9437,7 @@ cAudioManager::ProcessWorkShopScriptObject(uint8 sound)
switch(sound) {
case SCRIPT_SOUND_WORK_SHOP_LOOP_S:
- case SCRIPT_SOUND_WORK_SHOP_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = 20.0f;
- break;
+ case SCRIPT_SOUND_WORK_SHOP_LOOP_L: m_sQueueSample.m_fSoundIntensity = 20.0f; break;
default: return;
}
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
@@ -8104,17 +9448,19 @@ cAudioManager::ProcessWorkShopScriptObject(uint8 sound)
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_WORKSHOP_1;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_WORKSHOP_1);
- m_sQueueSample.m_counter = 0;
- m_sQueueSample.m_bIsDistant = false;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_WORKSHOP_1);
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_16 = 5;
- m_sQueueSample.field_48 = 2.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_bEmittingVolume = 30;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -8223,15 +9569,10 @@ cAudioManager::Service()
void
cAudioManager::ServiceSoundEffects()
{
- uint32 timeOfRecentCrime;
- cAudioScriptObject *object;
-
- timeOfRecentCrime = m_FrameCounter;
- ++m_FrameCounter;
- if(timeOfRecentCrime % 5)
- field_2 = 0;
+ if(m_FrameCounter++ % 5)
+ m_bFifthFrameFlag = false;
else
- field_2 = 1;
+ m_bFifthFrameFlag = true;
if(m_bUserPause && !m_bPreviousUserPause) {
for(int32 i = 0; i < allChannels; i++) SampleManager.StopChannel(i);
@@ -8259,13 +9600,15 @@ cAudioManager::ServiceSoundEffects()
ProcessMissionAudio();
AdjustSamplesVolume();
ProcessActiveQueues();
- for(int32 i = 0; i < m_nScriptObjectEntityTotal; ++i) {
- object = (cAudioScriptObject *)m_asAudioEntities[m_anScriptObjectEntityIndices[i]].m_pEntity;
+ for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) {
+ cAudioScriptObject *object =
+ (cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]]
+ .m_pEntity;
delete object;
- m_asAudioEntities[m_anScriptObjectEntityIndices[i]].m_pEntity = nil;
- DestroyEntity(m_anScriptObjectEntityIndices[i]);
+ m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]].m_pEntity = nil;
+ DestroyEntity(m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]);
}
- m_nScriptObjectEntityTotal = 0;
+ m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
}
int8
@@ -8309,7 +9652,8 @@ cAudioManager::SetEffectsMasterVolume(uint8 volume) const
void
cAudioManager::SetEntityStatus(int32 id, uint8 status)
{
- if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots && m_asAudioEntities[id].m_bIsUsed) {
+ if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots &&
+ m_asAudioEntities[id].m_bIsUsed) {
m_asAudioEntities[id].m_bStatus = status;
}
}
@@ -8318,7 +9662,7 @@ void
cAudioManager::SetMissionAudioLocation(float x, float y, float z)
{
if(m_bIsInitialised) {
- m_sMissionAudio.field_12 = 0;
+ m_sMissionAudio.m_bPredefinedProperties = 0;
m_sMissionAudio.m_vecPos = {x, y, z};
}
}
@@ -8349,20 +9693,22 @@ cAudioManager::SetupJumboEngineSound(uint8 vol, int32 freq)
uint8 emittingVol = vol - gJumboVolOffsetPercentage / 100;
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 180.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 3;
+ m_sQueueSample.m_nCounter = 3;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_ENGINE;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency = freq;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 4.0f;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 180.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 4;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -8379,20 +9725,23 @@ cAudioManager::SetupJumboFlySound(uint8 emittingVol)
m_sQueueSample.m_bVolume = vol;
if(m_sQueueSample.m_bVolume) {
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY;
- m_sQueueSample.m_counter = 0;
+ m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_bEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY);
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY);
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSoundIntensity = 440.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_48 = 4.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.field_76 = 5;
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
AddSampleToRequestedQueue();
}
return true;
@@ -8406,25 +9755,28 @@ cAudioManager::SetupJumboRumbleSound(uint8 emittingVol)
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 240.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 5;
+ m_sQueueSample.m_nCounter = 5;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = true;
- m_sQueueSample.field_16 = 1;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_RUMBLE);
+ m_sQueueSample.m_bIs2D = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nFrequency =
+ SampleManager.GetSampleBaseFrequency(SFX_JUMBO_RUMBLE);
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 4.0f;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 240.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 12;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 12;
m_sQueueSample.m_bOffset = 0;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
- m_sQueueSample.m_counter = 6;
+ m_sQueueSample.m_nCounter = 6;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_RUMBLE;
m_sQueueSample.m_nFrequency += 200;
m_sQueueSample.m_bOffset = maxVolume;
@@ -8440,24 +9792,27 @@ cAudioManager::SetupJumboTaxiSound(uint8 vol)
uint8 emittingVol = (vol >> 1) + ((vol >> 1) * m_sQueueSample.m_fDistance / 180);
- if(m_sQueueSample.m_fDistance / 180 < 0.7f) emittingVol -= emittingVol * gJumboVolOffsetPercentage / 100;
+ if(m_sQueueSample.m_fDistance / 180 < 0.7f)
+ emittingVol -= emittingVol * gJumboVolOffsetPercentage / 100;
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 180.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 1;
+ m_sQueueSample.m_nCounter = 1;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_TAXI;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency = GetJumboTaxiFreq();
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 4.0f;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 180.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 4;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -8473,20 +9828,22 @@ cAudioManager::SetupJumboWhineSound(uint8 emittingVol, int32 freq)
m_sQueueSample.m_bVolume = ComputeVolume(emittingVol, 170.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) {
- m_sQueueSample.m_counter = 2;
+ m_sQueueSample.m_nCounter = 2;
m_sQueueSample.m_nSampleIndex = SFX_JUMBO_WHINE;
m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = false;
- m_sQueueSample.field_16 = 1;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency = freq;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_bEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.field_48 = 4.0f;
+ m_sQueueSample.m_nLoopStart =
+ SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd =
+ SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 170.0f;
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.field_76 = 4;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -8524,19 +9881,19 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
case SOUND_AMMUNATION_WELCOME_3: emittingVol = maxVolume; break;
default:
if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(),
- m_sQueueSample.m_vecPos, 1, 0, 0, 0, 0, 0,
- 0)) {
+ m_sQueueSample.m_vecPos, 1,
+ 0, 0, 0, 0, 0, 0)) {
emittingVol = maxVolume;
} else {
emittingVol = 31;
}
break;
}
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, soundIntensity, m_sQueueSample.m_fDistance);
- pedComment.field_25 = 10;
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVol, soundIntensity, m_sQueueSample.m_fDistance);
+ pedComment.m_nProcess = 10;
if(m_sQueueSample.m_bVolume) {
- pedComment.m_entityIndex = m_sQueueSample.m_nEntityIndex;
+ pedComment.m_nEntityIndex = m_sQueueSample.m_nEntityIndex;
pedComment.m_vecPos = m_sQueueSample.m_vecPos;
pedComment.m_fDistance = m_sQueueSample.m_fDistance;
pedComment.m_bVolume = m_sQueueSample.m_bVolume;
@@ -8548,26 +9905,30 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
switch(sound) {
case SOUND_PED_HELI_PLAYER_FOUND:
soundIntensity = 400.f;
- pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % 29 +
- SFX_POLICE_HELI_1;
+ pedComment.m_nSampleIndex =
+ m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % 29 +
+ SFX_POLICE_HELI_1;
break;
case SOUND_PED_BODYCAST_HIT:
if(CTimer::GetTimeInMilliseconds() <= gNextCryTime) return;
soundIntensity = 50.f;
gNextCryTime = CTimer::GetTimeInMilliseconds() + 500;
pedComment.m_nSampleIndex =
- (m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] & 3) + SFX_PLASTER_BLOKE_1;
+ (m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] & 3) +
+ SFX_PLASTER_BLOKE_1;
break;
case SOUND_INJURED_PED_MALE_OUCH:
case SOUND_8A:
soundIntensity = 50.f;
- pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % 15 +
- SFX_GENERIC_MALE_GRUNT_1;
+ pedComment.m_nSampleIndex =
+ m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % 15 +
+ SFX_GENERIC_MALE_GRUNT_1;
break;
case SOUND_INJURED_PED_FEMALE:
soundIntensity = 50.f;
- pedComment.m_nSampleIndex = m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % 11 +
- SFX_GENERIC_FEMALE_GRUNT_1;
+ pedComment.m_nSampleIndex =
+ m_anRandomTable[m_sQueueSample.m_nEntityIndex & 3] % 11 +
+ SFX_GENERIC_FEMALE_GRUNT_1;
break;
default: return;
}
@@ -8581,19 +9942,19 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
case SOUND_AMMUNATION_WELCOME_3: emittingVol = maxVolume; break;
default:
if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(),
- m_sQueueSample.m_vecPos, 1, 0, 0, 0, 0, 0,
- 0)) {
+ m_sQueueSample.m_vecPos, 1,
+ 0, 0, 0, 0, 0, 0)) {
emittingVol = maxVolume;
} else {
emittingVol = 31;
}
break;
}
- m_sQueueSample.m_bVolume =
- ComputeVolume(emittingVol, soundIntensity, m_sQueueSample.m_fDistance);
- pedComment.field_25 = 10;
+ m_sQueueSample.m_bVolume = ComputeVolume(
+ emittingVol, soundIntensity, m_sQueueSample.m_fDistance);
+ pedComment.m_nProcess = 10;
if(m_sQueueSample.m_bVolume) {
- pedComment.m_entityIndex = m_sQueueSample.m_nEntityIndex;
+ pedComment.m_nEntityIndex = m_sQueueSample.m_nEntityIndex;
pedComment.m_vecPos = m_sQueueSample.m_vecPos;
pedComment.m_fDistance = m_sQueueSample.m_fDistance;
pedComment.m_bVolume = m_sQueueSample.m_bVolume;
@@ -8616,7 +9977,7 @@ cAudioManager::Terminate()
}
m_nAudioEntitiesTotal = 0;
- m_nScriptObjectEntityTotal = 0;
+ m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
PreTerminateGameSpecificShutdown();
for(uint32 i = 0; i < DIGITALCHANNELS; i++) {
@@ -8625,7 +9986,7 @@ cAudioManager::Terminate()
SampleManager.Terminate();
- m_bIsInitialised = 0;
+ m_bIsInitialised = false;
PostTerminateGameSpecificShutdown();
}
}
@@ -8728,7 +10089,8 @@ cAudioManager::UpdateReflections()
bool
cAudioManager::UsesReverseWarning(int32 model) const
{
- return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH;
+ return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS ||
+ model == COACH;
}
bool
@@ -8761,11 +10123,14 @@ void
cAudioManager::AdjustSamplesVolume()
{
for(int i = 0; i < m_bSampleRequestQueuesStatus[m_bActiveSampleQueue]; i++) {
- tSound* pSample = &m_asSamples[m_bActiveSampleQueue][m_abSampleQueueIndexTable[m_bActiveSampleQueue][i] + 1];
+ tSound *pSample =
+ &m_asSamples[m_bActiveSampleQueue]
+ [m_abSampleQueueIndexTable[m_bActiveSampleQueue][i] + 1];
- if(!pSample->m_bIsDistant)
- pSample->m_bEmittingVolume = ComputeEmittingVolume(
- pSample->m_bEmittingVolume, pSample->m_fSoundIntensity, pSample->m_fDistance);
+ if(!pSample->m_bIs2D)
+ pSample->m_bEmittingVolume =
+ ComputeEmittingVolume(pSample->m_bEmittingVolume,
+ pSample->m_fSoundIntensity, pSample->m_fDistance);
}
}
@@ -8775,220 +10140,221 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa
float quatIntensity = intensity / 4.0f;
float diffIntensity = intensity - quatIntensity;
if(dist > diffIntensity)
- return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume / quatIntensity;
+ return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume /
+ quatIntensity;
return emittingVolume;
}
-STARTPATCHES
-InjectHook(0x57B210, &cAudioManager::AddDetailsToRequestedOrderList, PATCH_JUMP);
-InjectHook(0x56AD30, &cAudioManager::AddPlayerCarSample, PATCH_JUMP);
-InjectHook(0x57B300, &cAudioManager::AddReflectionsToRequestedQueue, PATCH_JUMP);
-InjectHook(0x57B8D0, &cAudioManager::AddReleasingSounds, PATCH_JUMP);
-InjectHook(0x57B070, &cAudioManager::AddSampleToRequestedQueue, PATCH_JUMP);
-InjectHook(0x5697A0, &cAudioManager::CalculateDistance, PATCH_JUMP);
-InjectHook(0x57AA10, &cAudioManager::CheckForAnAudioFileOnCD, PATCH_JUMP);
-InjectHook(0x57C160, &cAudioManager::ClearActiveSamples, PATCH_JUMP);
-InjectHook(0x5796A0, &cAudioManager::ClearMissionAudio, PATCH_JUMP);
-InjectHook(0x57C120, &cAudioManager::ClearRequestedQueue, PATCH_JUMP);
-InjectHook(0x57AE00, &cAudioManager::ComputeDopplerEffectedFrequency, PATCH_JUMP);
-InjectHook(0x57AD20, &cAudioManager::ComputePan, PATCH_JUMP);
-InjectHook(0x57ABB0, &cAudioManager::ComputeVolume, PATCH_JUMP);
-InjectHook(0x57A310, &cAudioManager::CreateEntity, PATCH_JUMP);
-InjectHook(0x57A830, &cAudioManager::DestroyAllGameCreatedEntities, PATCH_JUMP);
-InjectHook(0x57A400, &cAudioManager::DestroyEntity, PATCH_JUMP);
-InjectHook(0x57C290, &cAudioManager::GenerateIntegerRandomNumberTable, PATCH_JUMP);
-InjectHook(0x57A8C0, &cAudioManager::Get3DProviderName, PATCH_JUMP);
-InjectHook(0x571110, &cAudioManager::GetArmyTalkSfx, PATCH_JUMP);
-InjectHook(0x573AB0, &cAudioManager::GetBlackBusinessFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x572050, &cAudioManager::GetBlackCasualFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x574380, &cAudioManager::GetBlackConstructionWorkerTalkSfx, PATCH_JUMP);
-InjectHook(0x571D80, &cAudioManager::GetBlackCriminalTalkSfx, PATCH_JUMP);
-InjectHook(0x5735E0, &cAudioManager::GetBlackDockerMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5724D0, &cAudioManager::GetBlackFatFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5726C0, &cAudioManager::GetBlackFatMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5728B0, &cAudioManager::GetBlackFemaleProstituteTalkSfx, PATCH_JUMP);
-InjectHook(0x572C20, &cAudioManager::GetBlackProjectFemaleOldTalkSfx, PATCH_JUMP);
-InjectHook(0x572D20, &cAudioManager::GetBlackProjectFemaleYoungTalkSfx, PATCH_JUMP);
-InjectHook(0x572AF0, &cAudioManager::GetBlackProjectMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5739C0, &cAudioManager::GetBlackWorkerMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x574FF0, &cAudioManager::GetBomberTalkSfx, PATCH_JUMP);
-InjectHook(0x5712C0, &cAudioManager::GetBusinessMaleOldTalkSfx, PATCH_JUMP);
-InjectHook(0x5713E0, &cAudioManager::GetBusinessMaleYoungTalkSfx, PATCH_JUMP);
-InjectHook(0x572040, &cAudioManager::GetCasualMaleOldTalkSfx, PATCH_JUMP);
-InjectHook(0x574FE0, &cAudioManager::GetCatatalinaTalkSfx, PATCH_JUMP);
-InjectHook(0x57AA30, &cAudioManager::GetCDAudioDriveLetter, PATCH_JUMP);
-InjectHook(0x573010, &cAudioManager::GetChinatownFemaleOldTalkSfx, PATCH_JUMP);
-InjectHook(0x5730F0, &cAudioManager::GetChinatownFemaleYoungTalkSfx, PATCH_JUMP);
-InjectHook(0x572E10, &cAudioManager::GetChinatownMaleOldTalkSfx, PATCH_JUMP);
-InjectHook(0x572F10, &cAudioManager::GetChinatownMaleYoungTalkSfx, PATCH_JUMP);
-InjectHook(0x575120, &cAudioManager::GetChunkyTalkSfx, PATCH_JUMP);
-InjectHook(0x571B00, &cAudioManager::GetColumbianTalkSfx, PATCH_JUMP);
-InjectHook(0x570EA0, &cAudioManager::GetCopTalkSfx, PATCH_JUMP);
-InjectHook(0x57A8F0, &cAudioManager::GetCurrent3DProviderIndex, PATCH_JUMP);
-InjectHook(0x571770, &cAudioManager::GetDiabloTalkSfx, PATCH_JUMP);
-InjectHook(0x569750, &cAudioManager::GetDistanceSquared, PATCH_JUMP);
-InjectHook(0x574DA0, &cAudioManager::GetEightTalkSfx, PATCH_JUMP);
-InjectHook(0x574040, &cAudioManager::GetFanFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x573F60, &cAudioManager::GetFanMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x571040, &cAudioManager::GetFBITalkSfx, PATCH_JUMP);
-InjectHook(0x572280, &cAudioManager::GetFemaleNo3TalkSfx, PATCH_JUMP);
-InjectHook(0x5712B0, &cAudioManager::GetFiremanTalkSfx, PATCH_JUMP);
-InjectHook(0x574E50, &cAudioManager::GetFrankieTalkSfx, PATCH_JUMP);
-InjectHook(0x575510, &cAudioManager::GetGenericFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x575460, &cAudioManager::GetGenericMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x571C30, &cAudioManager::GetHoodTalkSfx, PATCH_JUMP);
-InjectHook(0x5741F0, &cAudioManager::GetHospitalFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x574120, &cAudioManager::GetHospitalMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x56F410, &cAudioManager::GetJumboTaxiFreq, PATCH_JUMP);
-InjectHook(0x573310, &cAudioManager::GetLittleItalyFemaleOldTalkSfx, PATCH_JUMP);
-InjectHook(0x573400, &cAudioManager::GetLittleItalyFemaleYoungTalkSfx, PATCH_JUMP);
-InjectHook(0x5731E0, &cAudioManager::GetLittleItalyMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x571510, &cAudioManager::GetMafiaTalkSfx, PATCH_JUMP);
-InjectHook(0x571F40, &cAudioManager::GetMaleNo2TalkSfx, PATCH_JUMP);
-InjectHook(0x5711C0, &cAudioManager::GetMedicTalkSfx, PATCH_JUMP);
-InjectHook(0x5795D0, &cAudioManager::GetMissionAudioLoadingStatus, PATCH_JUMP);
-InjectHook(0x574F00, &cAudioManager::GetMistyTalkSfx, PATCH_JUMP);
-InjectHook(0x575340, &cAudioManager::GetNormalMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x57A8A0, &cAudioManager::GetNum3DProvidersAvailable, PATCH_JUMP);
-InjectHook(0x574FD0, &cAudioManager::GetOJGTalkSfx, PATCH_JUMP);
-InjectHook(0x570960, &cAudioManager::GetPedCommentSfx, PATCH_JUMP);
-InjectHook(0x570DB0, &cAudioManager::GetPhrase, PATCH_JUMP);
-InjectHook(0x56BF80, &cAudioManager::GetVehicleDriveWheelSkidValue, PATCH_JUMP);
-InjectHook(0x56C120, &cAudioManager::GetVehicleNonDriveWheelSkidValue, PATCH_JUMP);
-InjectHook(0x575240, &cAudioManager::GetPimpTalkSfx, PATCH_JUMP);
-InjectHook(0x570E00, &cAudioManager::GetPlayerTalkSfx, PATCH_JUMP);
-InjectHook(0x5737E0, &cAudioManager::GetScumFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5736D0, &cAudioManager::GetScumMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x575060, &cAudioManager::GetSecurityGuardTalkSfx, PATCH_JUMP);
-InjectHook(0x574480, &cAudioManager::GetShopperFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x574790, &cAudioManager::GetSpecialCharacterTalkSfx, PATCH_JUMP);
-InjectHook(0x573E90, &cAudioManager::GetStewardFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x573DC0, &cAudioManager::GetStewardMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x574690, &cAudioManager::GetStudentFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x574590, &cAudioManager::GetStudentMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x573CD0, &cAudioManager::GetSupermodelFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x573BD0, &cAudioManager::GetSupermodelMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x570F80, &cAudioManager::GetSwatTalkSfx, PATCH_JUMP);
-InjectHook(0x575190, &cAudioManager::GetTaxiDriverTalkSfx, PATCH_JUMP);
-InjectHook(0x571650, &cAudioManager::GetTriadTalkSfx, PATCH_JUMP);
-InjectHook(0x5723A0, &cAudioManager::GetWhiteBusinessFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x572170, &cAudioManager::GetWhiteCasualFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x574290, &cAudioManager::GetWhiteConstructionWorkerTalkSfx, PATCH_JUMP);
-InjectHook(0x571E60, &cAudioManager::GetWhiteCriminalTalkSfx, PATCH_JUMP);
-InjectHook(0x5734F0, &cAudioManager::GetWhiteDockerMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5727B0, &cAudioManager::GetWhiteFatFemaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5725D0, &cAudioManager::GetWhiteFatMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5729D0, &cAudioManager::GetWhiteFemaleProstituteTalkSfx, PATCH_JUMP);
-InjectHook(0x5738D0, &cAudioManager::GetWhiteWorkerMaleTalkSfx, PATCH_JUMP);
-InjectHook(0x5718D0, &cAudioManager::GetYakuzaTalkSfx, PATCH_JUMP);
-InjectHook(0x5719E0, &cAudioManager::GetYardieTalkSfx, PATCH_JUMP);
-InjectHook(0x56CAB0, &cAudioManager::HasAirBrakes, PATCH_JUMP);
-InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP);
-InjectHook(0x57B030, &cAudioManager::InterrogateAudioEntities, PATCH_JUMP);
-InjectHook(0x57AA50, &cAudioManager::IsAudioInitialised, PATCH_JUMP);
-InjectHook(0x579650, &cAudioManager::IsMissionAudioSampleFinished, PATCH_JUMP);
-InjectHook(0x57A9C0, &cAudioManager::IsMP3RadioChannelAvailable, PATCH_JUMP);
-InjectHook(0x579520, &cAudioManager::MissionScriptAudioUsesPoliceChannel, PATCH_JUMP);
-InjectHook(0x56AD10, &cAudioManager::PlayerJustGotInCar, PATCH_JUMP);
-InjectHook(0x56AD20, &cAudioManager::PlayerJustLeftCar, PATCH_JUMP);
-InjectHook(0x579620, &cAudioManager::PlayLoadedMissionAudio, PATCH_JUMP);
-InjectHook(0x57A500, &cAudioManager::PlayOneShot, PATCH_JUMP);
-InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP);
-InjectHook(0x569640, &cAudioManager::PostTerminateGameSpecificShutdown, PATCH_JUMP);
-InjectHook(0x569400, &cAudioManager::PreInitialiseGameSpecificSetup, PATCH_JUMP);
-InjectHook(0x579550, &cAudioManager::PreloadMissionAudio, PATCH_JUMP);
-InjectHook(0x569570, &cAudioManager::PreTerminateGameSpecificShutdown, PATCH_JUMP);
+// STARTPATCHES
+// InjectHook(0x57B210, &cAudioManager::AddDetailsToRequestedOrderList, PATCH_JUMP);
+// InjectHook(0x56AD30, &cAudioManager::AddPlayerCarSample, PATCH_JUMP);
+// InjectHook(0x57B300, &cAudioManager::AddReflectionsToRequestedQueue, PATCH_JUMP);
+// InjectHook(0x57B8D0, &cAudioManager::AddReleasingSounds, PATCH_JUMP);
+// InjectHook(0x57B070, &cAudioManager::AddSampleToRequestedQueue, PATCH_JUMP);
+// InjectHook(0x5697A0, &cAudioManager::CalculateDistance, PATCH_JUMP);
+// InjectHook(0x57AA10, &cAudioManager::CheckForAnAudioFileOnCD, PATCH_JUMP);
+// InjectHook(0x57C160, &cAudioManager::ClearActiveSamples, PATCH_JUMP);
+// InjectHook(0x5796A0, &cAudioManager::ClearMissionAudio, PATCH_JUMP);
+// InjectHook(0x57C120, &cAudioManager::ClearRequestedQueue, PATCH_JUMP);
+// InjectHook(0x57AE00, &cAudioManager::ComputeDopplerEffectedFrequency, PATCH_JUMP);
+// InjectHook(0x57AD20, &cAudioManager::ComputePan, PATCH_JUMP);
+// InjectHook(0x57ABB0, &cAudioManager::ComputeVolume, PATCH_JUMP);
+// InjectHook(0x57A310, &cAudioManager::CreateEntity, PATCH_JUMP);
+// InjectHook(0x57A830, &cAudioManager::DestroyAllGameCreatedEntities, PATCH_JUMP);
+// InjectHook(0x57A400, &cAudioManager::DestroyEntity, PATCH_JUMP);
+// InjectHook(0x57C290, &cAudioManager::GenerateIntegerRandomNumberTable, PATCH_JUMP);
+// InjectHook(0x57A8C0, &cAudioManager::Get3DProviderName, PATCH_JUMP);
+// InjectHook(0x571110, &cAudioManager::GetArmyTalkSfx, PATCH_JUMP);
+// InjectHook(0x573AB0, &cAudioManager::GetBlackBusinessFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x572050, &cAudioManager::GetBlackCasualFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x574380, &cAudioManager::GetBlackConstructionWorkerTalkSfx, PATCH_JUMP);
+// InjectHook(0x571D80, &cAudioManager::GetBlackCriminalTalkSfx, PATCH_JUMP);
+// InjectHook(0x5735E0, &cAudioManager::GetBlackDockerMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5724D0, &cAudioManager::GetBlackFatFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5726C0, &cAudioManager::GetBlackFatMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5728B0, &cAudioManager::GetBlackFemaleProstituteTalkSfx, PATCH_JUMP);
+// InjectHook(0x572C20, &cAudioManager::GetBlackProjectFemaleOldTalkSfx, PATCH_JUMP);
+// InjectHook(0x572D20, &cAudioManager::GetBlackProjectFemaleYoungTalkSfx, PATCH_JUMP);
+// InjectHook(0x572AF0, &cAudioManager::GetBlackProjectMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5739C0, &cAudioManager::GetBlackWorkerMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x574FF0, &cAudioManager::GetBomberTalkSfx, PATCH_JUMP);
+// InjectHook(0x5712C0, &cAudioManager::GetBusinessMaleOldTalkSfx, PATCH_JUMP);
+// InjectHook(0x5713E0, &cAudioManager::GetBusinessMaleYoungTalkSfx, PATCH_JUMP);
+// InjectHook(0x572040, &cAudioManager::GetCasualMaleOldTalkSfx, PATCH_JUMP);
+// InjectHook(0x574FE0, &cAudioManager::GetCatatalinaTalkSfx, PATCH_JUMP);
+// InjectHook(0x57AA30, &cAudioManager::GetCDAudioDriveLetter, PATCH_JUMP);
+// InjectHook(0x573010, &cAudioManager::GetChinatownFemaleOldTalkSfx, PATCH_JUMP);
+// InjectHook(0x5730F0, &cAudioManager::GetChinatownFemaleYoungTalkSfx, PATCH_JUMP);
+// InjectHook(0x572E10, &cAudioManager::GetChinatownMaleOldTalkSfx, PATCH_JUMP);
+// InjectHook(0x572F10, &cAudioManager::GetChinatownMaleYoungTalkSfx, PATCH_JUMP);
+// InjectHook(0x575120, &cAudioManager::GetChunkyTalkSfx, PATCH_JUMP);
+// InjectHook(0x571B00, &cAudioManager::GetColumbianTalkSfx, PATCH_JUMP);
+// InjectHook(0x570EA0, &cAudioManager::GetCopTalkSfx, PATCH_JUMP);
+// InjectHook(0x57A8F0, &cAudioManager::GetCurrent3DProviderIndex, PATCH_JUMP);
+// InjectHook(0x571770, &cAudioManager::GetDiabloTalkSfx, PATCH_JUMP);
+// InjectHook(0x569750, &cAudioManager::GetDistanceSquared, PATCH_JUMP);
+// InjectHook(0x574DA0, &cAudioManager::GetEightTalkSfx, PATCH_JUMP);
+// InjectHook(0x574040, &cAudioManager::GetFanFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x573F60, &cAudioManager::GetFanMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x571040, &cAudioManager::GetFBITalkSfx, PATCH_JUMP);
+// InjectHook(0x572280, &cAudioManager::GetFemaleNo3TalkSfx, PATCH_JUMP);
+// InjectHook(0x5712B0, &cAudioManager::GetFiremanTalkSfx, PATCH_JUMP);
+// InjectHook(0x574E50, &cAudioManager::GetFrankieTalkSfx, PATCH_JUMP);
+// InjectHook(0x575510, &cAudioManager::GetGenericFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x575460, &cAudioManager::GetGenericMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x571C30, &cAudioManager::GetHoodTalkSfx, PATCH_JUMP);
+// InjectHook(0x5741F0, &cAudioManager::GetHospitalFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x574120, &cAudioManager::GetHospitalMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x56F410, &cAudioManager::GetJumboTaxiFreq, PATCH_JUMP);
+// InjectHook(0x573310, &cAudioManager::GetLittleItalyFemaleOldTalkSfx, PATCH_JUMP);
+// InjectHook(0x573400, &cAudioManager::GetLittleItalyFemaleYoungTalkSfx, PATCH_JUMP);
+// InjectHook(0x5731E0, &cAudioManager::GetLittleItalyMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x571510, &cAudioManager::GetMafiaTalkSfx, PATCH_JUMP);
+// InjectHook(0x571F40, &cAudioManager::GetMaleNo2TalkSfx, PATCH_JUMP);
+// InjectHook(0x5711C0, &cAudioManager::GetMedicTalkSfx, PATCH_JUMP);
+// InjectHook(0x5795D0, &cAudioManager::GetMissionAudioLoadingStatus, PATCH_JUMP);
+// InjectHook(0x574F00, &cAudioManager::GetMistyTalkSfx, PATCH_JUMP);
+// InjectHook(0x575340, &cAudioManager::GetNormalMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x57A8A0, &cAudioManager::GetNum3DProvidersAvailable, PATCH_JUMP);
+// InjectHook(0x574FD0, &cAudioManager::GetOJGTalkSfx, PATCH_JUMP);
+// InjectHook(0x570960, &cAudioManager::GetPedCommentSfx, PATCH_JUMP);
+// InjectHook(0x570DB0, &cAudioManager::GetPhrase, PATCH_JUMP);
+// InjectHook(0x56BF80, &cAudioManager::GetVehicleDriveWheelSkidValue, PATCH_JUMP);
+// InjectHook(0x56C120, &cAudioManager::GetVehicleNonDriveWheelSkidValue, PATCH_JUMP);
+// InjectHook(0x575240, &cAudioManager::GetPimpTalkSfx, PATCH_JUMP);
+// InjectHook(0x570E00, &cAudioManager::GetPlayerTalkSfx, PATCH_JUMP);
+// InjectHook(0x5737E0, &cAudioManager::GetScumFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5736D0, &cAudioManager::GetScumMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x575060, &cAudioManager::GetSecurityGuardTalkSfx, PATCH_JUMP);
+// InjectHook(0x574480, &cAudioManager::GetShopperFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x574790, &cAudioManager::GetSpecialCharacterTalkSfx, PATCH_JUMP);
+// InjectHook(0x573E90, &cAudioManager::GetStewardFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x573DC0, &cAudioManager::GetStewardMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x574690, &cAudioManager::GetStudentFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x574590, &cAudioManager::GetStudentMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x573CD0, &cAudioManager::GetSupermodelFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x573BD0, &cAudioManager::GetSupermodelMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x570F80, &cAudioManager::GetSwatTalkSfx, PATCH_JUMP);
+// InjectHook(0x575190, &cAudioManager::GetTaxiDriverTalkSfx, PATCH_JUMP);
+// InjectHook(0x571650, &cAudioManager::GetTriadTalkSfx, PATCH_JUMP);
+// InjectHook(0x5723A0, &cAudioManager::GetWhiteBusinessFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x572170, &cAudioManager::GetWhiteCasualFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x574290, &cAudioManager::GetWhiteConstructionWorkerTalkSfx, PATCH_JUMP);
+// InjectHook(0x571E60, &cAudioManager::GetWhiteCriminalTalkSfx, PATCH_JUMP);
+// InjectHook(0x5734F0, &cAudioManager::GetWhiteDockerMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5727B0, &cAudioManager::GetWhiteFatFemaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5725D0, &cAudioManager::GetWhiteFatMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5729D0, &cAudioManager::GetWhiteFemaleProstituteTalkSfx, PATCH_JUMP);
+// InjectHook(0x5738D0, &cAudioManager::GetWhiteWorkerMaleTalkSfx, PATCH_JUMP);
+// InjectHook(0x5718D0, &cAudioManager::GetYakuzaTalkSfx, PATCH_JUMP);
+// InjectHook(0x5719E0, &cAudioManager::GetYardieTalkSfx, PATCH_JUMP);
+// InjectHook(0x56CAB0, &cAudioManager::HasAirBrakes, PATCH_JUMP);
+// InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP);
+// InjectHook(0x57B030, &cAudioManager::InterrogateAudioEntities, PATCH_JUMP);
+// InjectHook(0x57AA50, &cAudioManager::IsAudioInitialised, PATCH_JUMP);
+// InjectHook(0x579650, &cAudioManager::IsMissionAudioSampleFinished, PATCH_JUMP);
+// InjectHook(0x57A9C0, &cAudioManager::IsMP3RadioChannelAvailable, PATCH_JUMP);
+// InjectHook(0x579520, &cAudioManager::MissionScriptAudioUsesPoliceChannel, PATCH_JUMP);
+// InjectHook(0x56AD10, &cAudioManager::PlayerJustGotInCar, PATCH_JUMP);
+// InjectHook(0x56AD20, &cAudioManager::PlayerJustLeftCar, PATCH_JUMP);
+// InjectHook(0x579620, &cAudioManager::PlayLoadedMissionAudio, PATCH_JUMP);
+// InjectHook(0x57A500, &cAudioManager::PlayOneShot, PATCH_JUMP);
+// InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP);
+// InjectHook(0x569640, &cAudioManager::PostTerminateGameSpecificShutdown, PATCH_JUMP);
+// InjectHook(0x569400, &cAudioManager::PreInitialiseGameSpecificSetup, PATCH_JUMP);
+// InjectHook(0x579550, &cAudioManager::PreloadMissionAudio, PATCH_JUMP);
+// InjectHook(0x569570, &cAudioManager::PreTerminateGameSpecificShutdown, PATCH_JUMP);
// InjectHook(0x57BA60, &cAudioManager::ProcessActiveQueues, PATCH_JUMP);
-InjectHook(0x56C940, &cAudioManager::ProcessAirBrakes, PATCH_JUMP);
-InjectHook(0x577B30, &cAudioManager::ProcessAirportScriptObject, PATCH_JUMP);
-InjectHook(0x56DE80, &cAudioManager::ProcessBoatEngine, PATCH_JUMP);
-InjectHook(0x56E500, &cAudioManager::ProcessBoatMovingOverWater, PATCH_JUMP);
-InjectHook(0x5790D0, &cAudioManager::ProcessBridge, PATCH_JUMP);
-InjectHook(0x579250, &cAudioManager::ProcessBridgeMotor, PATCH_JUMP);
-InjectHook(0x579310, &cAudioManager::ProcessBridgeOneShots, PATCH_JUMP);
-InjectHook(0x579170, &cAudioManager::ProcessBridgeWarning, PATCH_JUMP);
-InjectHook(0x56CC20, &cAudioManager::ProcessCarBombTick, PATCH_JUMP);
-InjectHook(0x577CA0, &cAudioManager::ProcessCinemaScriptObject, PATCH_JUMP);
-InjectHook(0x577E50, &cAudioManager::ProcessDocksScriptObject, PATCH_JUMP);
-InjectHook(0x56CAF0, &cAudioManager::ProcessEngineDamage, PATCH_JUMP);
-InjectHook(0x569870, &cAudioManager::ProcessEntity, PATCH_JUMP);
-InjectHook(0x575AC0, &cAudioManager::ProcessExplosions, PATCH_JUMP);
-InjectHook(0x578FD0, &cAudioManager::ProcessFireHydrant, PATCH_JUMP);
-InjectHook(0x5785E0, &cAudioManager::ProcessFrontEnd, PATCH_JUMP);
-InjectHook(0x56E6A0, &cAudioManager::ProcessHelicopter, PATCH_JUMP);
-InjectHook(0x577FE0, &cAudioManager::ProcessHomeScriptObject, PATCH_JUMP);
-InjectHook(0x56E8F0, &cAudioManager::ProcessJumbo, PATCH_JUMP);
-InjectHook(0x56EA40, &cAudioManager::ProcessJumboAccel, PATCH_JUMP);
-InjectHook(0x56EE40, &cAudioManager::ProcessJumboDecel, PATCH_JUMP);
-InjectHook(0x56ECF0, &cAudioManager::ProcessJumboFlying, PATCH_JUMP);
-InjectHook(0x56ED10, &cAudioManager::ProcessJumboLanding, PATCH_JUMP);
-InjectHook(0x56EC00, &cAudioManager::ProcessJumboTakeOff, PATCH_JUMP);
-InjectHook(0x56EA10, &cAudioManager::ProcessJumboTaxi, PATCH_JUMP);
-InjectHook(0x5777E0, &cAudioManager::ProcessLaunderetteScriptObject, PATCH_JUMP);
-InjectHook(0x576770, &cAudioManager::ProcessLoopingScriptObject, PATCH_JUMP);
-InjectHook(0x5796E0, &cAudioManager::ProcessMissionAudio, PATCH_JUMP);
-InjectHook(0x56A050, &cAudioManager::ProcessModelCarEngine, PATCH_JUMP);
-InjectHook(0x5760C0, &cAudioManager::ProcessOneShotScriptObject, PATCH_JUMP);
-InjectHook(0x56F450, &cAudioManager::ProcessPed, PATCH_JUMP);
-InjectHook(0x56F4D0, &cAudioManager::ProcessPedHeadphones, PATCH_JUMP);
+// InjectHook(0x56C940, &cAudioManager::ProcessAirBrakes, PATCH_JUMP);
+// InjectHook(0x577B30, &cAudioManager::ProcessAirportScriptObject, PATCH_JUMP);
+// InjectHook(0x56DE80, &cAudioManager::ProcessBoatEngine, PATCH_JUMP);
+// InjectHook(0x56E500, &cAudioManager::ProcessBoatMovingOverWater, PATCH_JUMP);
+// InjectHook(0x5790D0, &cAudioManager::ProcessBridge, PATCH_JUMP);
+// InjectHook(0x579250, &cAudioManager::ProcessBridgeMotor, PATCH_JUMP);
+// InjectHook(0x579310, &cAudioManager::ProcessBridgeOneShots, PATCH_JUMP);
+// InjectHook(0x579170, &cAudioManager::ProcessBridgeWarning, PATCH_JUMP);
+// InjectHook(0x56CC20, &cAudioManager::ProcessCarBombTick, PATCH_JUMP);
+// InjectHook(0x577CA0, &cAudioManager::ProcessCinemaScriptObject, PATCH_JUMP);
+// InjectHook(0x577E50, &cAudioManager::ProcessDocksScriptObject, PATCH_JUMP);
+// InjectHook(0x56CAF0, &cAudioManager::ProcessEngineDamage, PATCH_JUMP);
+// InjectHook(0x569870, &cAudioManager::ProcessEntity, PATCH_JUMP);
+// InjectHook(0x575AC0, &cAudioManager::ProcessExplosions, PATCH_JUMP);
+// InjectHook(0x578FD0, &cAudioManager::ProcessFireHydrant, PATCH_JUMP);
+// InjectHook(0x5785E0, &cAudioManager::ProcessFrontEnd, PATCH_JUMP);
+// InjectHook(0x56E6A0, &cAudioManager::ProcessHelicopter, PATCH_JUMP);
+// InjectHook(0x577FE0, &cAudioManager::ProcessHomeScriptObject, PATCH_JUMP);
+// InjectHook(0x56E8F0, &cAudioManager::ProcessJumbo, PATCH_JUMP);
+// InjectHook(0x56EA40, &cAudioManager::ProcessJumboAccel, PATCH_JUMP);
+// InjectHook(0x56EE40, &cAudioManager::ProcessJumboDecel, PATCH_JUMP);
+// InjectHook(0x56ECF0, &cAudioManager::ProcessJumboFlying, PATCH_JUMP);
+// InjectHook(0x56ED10, &cAudioManager::ProcessJumboLanding, PATCH_JUMP);
+// InjectHook(0x56EC00, &cAudioManager::ProcessJumboTakeOff, PATCH_JUMP);
+// InjectHook(0x56EA10, &cAudioManager::ProcessJumboTaxi, PATCH_JUMP);
+// InjectHook(0x5777E0, &cAudioManager::ProcessLaunderetteScriptObject, PATCH_JUMP);
+// InjectHook(0x576770, &cAudioManager::ProcessLoopingScriptObject, PATCH_JUMP);
+// InjectHook(0x5796E0, &cAudioManager::ProcessMissionAudio, PATCH_JUMP);
+// InjectHook(0x56A050, &cAudioManager::ProcessModelCarEngine, PATCH_JUMP);
+// InjectHook(0x5760C0, &cAudioManager::ProcessOneShotScriptObject, PATCH_JUMP);
+// InjectHook(0x56F450, &cAudioManager::ProcessPed, PATCH_JUMP);
+// InjectHook(0x56F4D0, &cAudioManager::ProcessPedHeadphones, PATCH_JUMP);
// InjectHook(0x56F650, &cAudioManager::ProcessPedOneShots, PATCH_JUMP);
-InjectHook(0x5699C0, &cAudioManager::ProcessPhysical, PATCH_JUMP);
-InjectHook(0x56E860, &cAudioManager::ProcessPlane, PATCH_JUMP);
-InjectHook(0x56B0D0, &cAudioManager::ProcessPlayersVehicleEngine, PATCH_JUMP);
-InjectHook(0x578190, &cAudioManager::ProcessPoliceCellBeatingScriptObject, PATCH_JUMP);
-InjectHook(0x577280, &cAudioManager::ProcessPornCinema, PATCH_JUMP);
-InjectHook(0x578A80, &cAudioManager::ProcessProjectiles, PATCH_JUMP);
-InjectHook(0x569CC0, &cAudioManager::ProcessRainOnVehicle, PATCH_JUMP);
-InjectHook(0x569700, &cAudioManager::ProcessReverb, PATCH_JUMP);
-InjectHook(0x569E50, &cAudioManager::ProcessReverseGear, PATCH_JUMP);
-InjectHook(0x577630, &cAudioManager::ProcessSawMillScriptObject, PATCH_JUMP);
-InjectHook(0x576070, &cAudioManager::ProcessScriptObject, PATCH_JUMP);
-InjectHook(0x577970, &cAudioManager::ProcessShopScriptObject, PATCH_JUMP);
-InjectHook(0x5697D0, &cAudioManager::ProcessSpecial, PATCH_JUMP);
-InjectHook(0x56DBF0, &cAudioManager::ProcessTrainNoise, PATCH_JUMP);
-InjectHook(0x569A00, &cAudioManager::ProcessVehicle, PATCH_JUMP);
-InjectHook(0x56C770, &cAudioManager::ProcessVehicleDoors, PATCH_JUMP);
-InjectHook(0x56C200, &cAudioManager::ProcessVehicleHorn, PATCH_JUMP);
-InjectHook(0x56C640, &cAudioManager::ProcessVehicleReverseWarning, PATCH_JUMP);
-InjectHook(0x56A230, &cAudioManager::ProcessVehicleRoadNoise, PATCH_JUMP);
-InjectHook(0x56C420, &cAudioManager::ProcessVehicleSirenOrAlarm, PATCH_JUMP);
-InjectHook(0x56BCB0, &cAudioManager::ProcessVehicleSkidding, PATCH_JUMP);
-InjectHook(0x575F30, &cAudioManager::ProcessWaterCannon, PATCH_JUMP);
-InjectHook(0x578370, &cAudioManager::ProcessWeather, PATCH_JUMP);
-InjectHook(0x56A440, &cAudioManager::ProcessWetRoadNoise, PATCH_JUMP);
-InjectHook(0x577530, &cAudioManager::ProcessWorkShopScriptObject, PATCH_JUMP);
-InjectHook(0x57AF90, &cAudioManager::RandomDisplacement, PATCH_JUMP);
-InjectHook(0x57A9F0, &cAudioManager::ReacquireDigitalHandle, PATCH_JUMP);
-InjectHook(0x57A9E0, &cAudioManager::ReleaseDigitalHandle, PATCH_JUMP);
-InjectHook(0x569650, &cAudioManager::ResetAudioLogicTimers, PATCH_JUMP);
-InjectHook(0x57A7B0, &cAudioManager::ResetTimers, PATCH_JUMP);
-InjectHook(0x57A2A0, &cAudioManager::Service, PATCH_JUMP);
-InjectHook(0x57AA60, &cAudioManager::ServiceSoundEffects, PATCH_JUMP);
-InjectHook(0x57A910, &cAudioManager::SetCurrent3DProvider, PATCH_JUMP);
-InjectHook(0x57AA00, &cAudioManager::SetDynamicAcousticModelingStatus, PATCH_JUMP);
-InjectHook(0x57A770, &cAudioManager::SetEffectsFadeVolume, PATCH_JUMP);
-InjectHook(0x57A730, &cAudioManager::SetEffectsMasterVolume, PATCH_JUMP);
-InjectHook(0x57A4C0, &cAudioManager::SetEntityStatus, PATCH_JUMP);
-InjectHook(0x5795F0, &cAudioManager::SetMissionAudioLocation, PATCH_JUMP);
-InjectHook(0x57A790, &cAudioManager::SetMusicFadeVolume, PATCH_JUMP);
-InjectHook(0x57A750, &cAudioManager::SetMusicMasterVolume, PATCH_JUMP);
-InjectHook(0x57A9A0, &cAudioManager::SetSpeakerConfig, PATCH_JUMP);
-InjectHook(0x56F230, &cAudioManager::SetupJumboFlySound, PATCH_JUMP);
-InjectHook(0x56F310, &cAudioManager::SetupJumboRumbleSound, PATCH_JUMP);
-InjectHook(0x56EF20, &cAudioManager::SetupJumboTaxiSound, PATCH_JUMP);
-InjectHook(0x56F070, &cAudioManager::SetupJumboWhineSound, PATCH_JUMP);
-InjectHook(0x570690, &cAudioManager::SetupPedComments, PATCH_JUMP);
-InjectHook(0x57A150, &cAudioManager::Terminate, PATCH_JUMP);
-InjectHook(0x57AC60, &cAudioManager::TranslateEntity, PATCH_JUMP);
-InjectHook(0x56AC80, &cAudioManager::UpdateGasPedalAudio, PATCH_JUMP);
-InjectHook(0x57B470, &cAudioManager::UpdateReflections, PATCH_JUMP);
-InjectHook(0x56C600, &cAudioManager::UsesReverseWarning, PATCH_JUMP);
-InjectHook(0x56C3C0, &cAudioManager::UsesSiren, PATCH_JUMP);
-InjectHook(0x56C3F0, &cAudioManager::UsesSirenSwitching, PATCH_JUMP);
-
-InjectHook(0x57C2B0, &cAudioManager::AdjustSamplesVolume, PATCH_JUMP);
-InjectHook(0x57C320, &cAudioManager::ComputeEmittingVolume, PATCH_JUMP);
-
-InjectHook(0x5755C0, &cPedComments::Add, PATCH_JUMP);
-InjectHook(0x575730, &cPedComments::Process, PATCH_JUMP);
-ENDPATCHES
+// InjectHook(0x5699C0, &cAudioManager::ProcessPhysical, PATCH_JUMP);
+// InjectHook(0x56E860, &cAudioManager::ProcessPlane, PATCH_JUMP);
+// InjectHook(0x56B0D0, &cAudioManager::ProcessPlayersVehicleEngine, PATCH_JUMP);
+// InjectHook(0x578190, &cAudioManager::ProcessPoliceCellBeatingScriptObject, PATCH_JUMP);
+// InjectHook(0x577280, &cAudioManager::ProcessPornCinema, PATCH_JUMP);
+// InjectHook(0x578A80, &cAudioManager::ProcessProjectiles, PATCH_JUMP);
+// InjectHook(0x569CC0, &cAudioManager::ProcessRainOnVehicle, PATCH_JUMP);
+// InjectHook(0x569700, &cAudioManager::ProcessReverb, PATCH_JUMP);
+// InjectHook(0x569E50, &cAudioManager::ProcessReverseGear, PATCH_JUMP);
+// InjectHook(0x577630, &cAudioManager::ProcessSawMillScriptObject, PATCH_JUMP);
+// InjectHook(0x576070, &cAudioManager::ProcessScriptObject, PATCH_JUMP);
+// InjectHook(0x577970, &cAudioManager::ProcessShopScriptObject, PATCH_JUMP);
+// InjectHook(0x5697D0, &cAudioManager::ProcessSpecial, PATCH_JUMP);
+// InjectHook(0x56DBF0, &cAudioManager::ProcessTrainNoise, PATCH_JUMP);
+// InjectHook(0x569A00, &cAudioManager::ProcessVehicle, PATCH_JUMP);
+// InjectHook(0x56C770, &cAudioManager::ProcessVehicleDoors, PATCH_JUMP);
+// InjectHook(0x56C200, &cAudioManager::ProcessVehicleHorn, PATCH_JUMP);
+// InjectHook(0x56C640, &cAudioManager::ProcessVehicleReverseWarning, PATCH_JUMP);
+// InjectHook(0x56A230, &cAudioManager::ProcessVehicleRoadNoise, PATCH_JUMP);
+// InjectHook(0x56C420, &cAudioManager::ProcessVehicleSirenOrAlarm, PATCH_JUMP);
+// InjectHook(0x56BCB0, &cAudioManager::ProcessVehicleSkidding, PATCH_JUMP);
+// InjectHook(0x575F30, &cAudioManager::ProcessWaterCannon, PATCH_JUMP);
+// InjectHook(0x578370, &cAudioManager::ProcessWeather, PATCH_JUMP);
+// InjectHook(0x56A440, &cAudioManager::ProcessWetRoadNoise, PATCH_JUMP);
+// InjectHook(0x577530, &cAudioManager::ProcessWorkShopScriptObject, PATCH_JUMP);
+// InjectHook(0x57AF90, &cAudioManager::RandomDisplacement, PATCH_JUMP);
+// InjectHook(0x57A9F0, &cAudioManager::ReacquireDigitalHandle, PATCH_JUMP);
+// InjectHook(0x57A9E0, &cAudioManager::ReleaseDigitalHandle, PATCH_JUMP);
+// InjectHook(0x569650, &cAudioManager::ResetAudioLogicTimers, PATCH_JUMP);
+// InjectHook(0x57A7B0, &cAudioManager::ResetTimers, PATCH_JUMP);
+// InjectHook(0x57A2A0, &cAudioManager::Service, PATCH_JUMP);
+// InjectHook(0x57AA60, &cAudioManager::ServiceSoundEffects, PATCH_JUMP);
+// InjectHook(0x57A910, &cAudioManager::SetCurrent3DProvider, PATCH_JUMP);
+// InjectHook(0x57AA00, &cAudioManager::SetDynamicAcousticModelingStatus, PATCH_JUMP);
+// InjectHook(0x57A770, &cAudioManager::SetEffectsFadeVolume, PATCH_JUMP);
+// InjectHook(0x57A730, &cAudioManager::SetEffectsMasterVolume, PATCH_JUMP);
+// InjectHook(0x57A4C0, &cAudioManager::SetEntityStatus, PATCH_JUMP);
+// InjectHook(0x5795F0, &cAudioManager::SetMissionAudioLocation, PATCH_JUMP);
+// InjectHook(0x57A790, &cAudioManager::SetMusicFadeVolume, PATCH_JUMP);
+// InjectHook(0x57A750, &cAudioManager::SetMusicMasterVolume, PATCH_JUMP);
+// InjectHook(0x57A9A0, &cAudioManager::SetSpeakerConfig, PATCH_JUMP);
+// InjectHook(0x56F230, &cAudioManager::SetupJumboFlySound, PATCH_JUMP);
+// InjectHook(0x56F310, &cAudioManager::SetupJumboRumbleSound, PATCH_JUMP);
+// InjectHook(0x56EF20, &cAudioManager::SetupJumboTaxiSound, PATCH_JUMP);
+// InjectHook(0x56F070, &cAudioManager::SetupJumboWhineSound, PATCH_JUMP);
+// InjectHook(0x570690, &cAudioManager::SetupPedComments, PATCH_JUMP);
+// InjectHook(0x57A150, &cAudioManager::Terminate, PATCH_JUMP);
+// InjectHook(0x57AC60, &cAudioManager::TranslateEntity, PATCH_JUMP);
+// InjectHook(0x56AC80, &cAudioManager::UpdateGasPedalAudio, PATCH_JUMP);
+// InjectHook(0x57B470, &cAudioManager::UpdateReflections, PATCH_JUMP);
+// InjectHook(0x56C600, &cAudioManager::UsesReverseWarning, PATCH_JUMP);
+// InjectHook(0x56C3C0, &cAudioManager::UsesSiren, PATCH_JUMP);
+// InjectHook(0x56C3F0, &cAudioManager::UsesSirenSwitching, PATCH_JUMP);
+
+// InjectHook(0x57C2B0, &cAudioManager::AdjustSamplesVolume, PATCH_JUMP);
+// InjectHook(0x57C320, &cAudioManager::ComputeEmittingVolume, PATCH_JUMP);
+
+// InjectHook(0x5755C0, &cPedComments::Add, PATCH_JUMP);
+// InjectHook(0x575730, &cPedComments::Process, PATCH_JUMP);
+// ENDPATCHES
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 0be1e38a..31a07f9b 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -1,13 +1,14 @@
-#pragma once
+#pragma once
-#include "DMAudio.h"
#include "common.h"
#include "config.h"
+
+#include "DMAudio.h"
+
#include "AudioCollision.h"
#include "PoliceRadio.h"
-enum eScriptSounds : int16
-{
+enum eScriptSounds : int16 {
SCRIPT_SOUND_0 = 0,
SCRIPT_SOUND_1 = 1,
SCRIPT_SOUND_2 = 2,
@@ -138,47 +139,47 @@ class tSound
{
public:
int32 m_nEntityIndex;
- int32 m_counter;
+ int32 m_nCounter;
int32 m_nSampleIndex;
uint8 m_bBankIndex;
- bool m_bIsDistant;
- uint8 field_14;
- uint8 field_15;
- int32 field_16;
+ bool m_bIs2D;
+ uint8 field_14; // unused
+ uint8 field_15; // unused
+ int32 m_nReleasingVolumeModificator;
int32 m_nFrequency;
uint8 m_bVolume;
- uint8 field_25;
- uint8 field_26;
- uint8 field_27;
+ uint8 field_25; // unused
+ uint8 field_26; // unused
+ uint8 field_27; // unused
float m_fDistance;
int32 m_nLoopCount;
int32 m_nLoopStart;
int32 m_nLoopEnd;
uint8 m_bEmittingVolume;
- uint8 field_45;
- uint8 field_46;
- uint8 field_47;
- float field_48;
+ uint8 field_45; // unused
+ uint8 field_46; // unused
+ uint8 field_47; // unused
+ float m_fSpeedMultiplier;
float m_fSoundIntensity;
- uint8 field_56;
- uint8 field_57;
- uint8 field_58;
- uint8 field_59;
+ bool m_bReleasingSoundFlag;
+ uint8 field_57; // unused
+ uint8 field_58; // unused
+ uint8 field_59; // unused
CVector m_vecPos;
bool m_bReverbFlag;
uint8 m_bLoopsRemaining;
- bool m_bRequireReflection;
+ bool m_bRequireReflection; // Used for oneshots
uint8 m_bOffset;
- int32 field_76;
- uint8 m_bIsProcessed;
- uint8 m_bLoopEnded;
- uint8 field_82;
- uint8 field_83;
- int32 calculatedVolume;
- int8 field_88;
- uint8 field_89;
- uint8 field_90;
- uint8 field_91;
+ int32 m_nReleasingVolumeDivider;
+ bool m_bIsProcessed;
+ bool m_bLoopEnded;
+ uint8 field_82; // unused
+ uint8 field_83; // unused
+ int32 m_nCalculatedVolume;
+ int8 m_nVolumeChange;
+ uint8 field_89; // unused
+ uint8 field_90; // unused
+ uint8 field_91; // unused
// no methods
};
@@ -196,7 +197,7 @@ public:
bool m_bIsUsed;
uint8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
- uint8 gap_18[2];
+ //uint8 gap_18[2];
float m_afVolume[NUM_AUDIOENTITY_EVENTS];
uint8 m_AudioEvents;
uint8 field_25[3];
@@ -210,12 +211,11 @@ class tPedComment
{
public:
int32 m_nSampleIndex;
- int32 m_entityIndex;
+ int32 m_nEntityIndex;
CVector m_vecPos;
float m_fDistance;
uint8 m_bVolume;
- int8 field_25; // allocated time?
- uint8 gap_26[2];
+ int8 m_nProcess;
// no methods
};
@@ -226,14 +226,13 @@ class cPedComments
{
public:
tPedComment m_asPedComments[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS];
- uint8 indexMap[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS];
- uint8 nrOfCommentsInBank[NUM_PED_COMMENTS_BANKS];
- uint8 activeBank;
- uint8 gap_1163[1];
-
- // reversed all methods
- void Add(tPedComment *com); /// ok
- void Process(); /// ok
+ uint8 m_nIndexMap[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS];
+ uint8 m_nCommentsInBank[NUM_PED_COMMENTS_BANKS];
+ uint8 m_nActiveBank;
+
+ cPedComments();
+ void Add(tPedComment *com);
+ void Process();
};
static_assert(sizeof(cPedComments) == 1164, "cPedComments: error");
@@ -244,23 +243,35 @@ class cMissionAudio
{
public:
CVector m_vecPos;
- uint8 field_12;
- uint8 gap_13[3];
+ bool m_bPredefinedProperties;
+ //uint8 gap_13[3];
int m_nSampleIndex;
uint8 m_bLoadingStatus;
uint8 m_bPlayStatus;
- uint8 field_22;
- uint8 field_23;
- int field_24;
+ uint8 field_22; // todo find a name
+ uint8 field_23; // unused
+ int32 m_nMissionAudioCounter;
bool m_bIsPlayed;
- uint8 field_29;
- uint8 field_30;
- uint8 field_31;
- // no methods
+ uint8 field_29; // unused
+ uint8 field_30; // unused
+ uint8 field_31; // unused
+ // no methods
};
static_assert(sizeof(cMissionAudio) == 32, "cMissionAudio: error");
+// name made up
+class cAudioScriptObjectManager
+{
+public:
+ int32 m_anScriptObjectEntityIndices[NUM_SCRIPT_MAX_ENTITIES];
+ int32 m_nScriptObjectEntityTotal;
+
+ cAudioScriptObjectManager() { m_nScriptObjectEntityTotal = 0; }
+ ~cAudioScriptObjectManager() { m_nScriptObjectEntityTotal = 0; }
+};
+
+
class cVehicleParams;
class CPlane;
class CVehicle;
@@ -289,22 +300,22 @@ class cAudioManager
{
public:
bool m_bIsInitialised;
- uint8 field_1;
- uint8 field_2;
+ uint8 field_1; // unused
+ bool m_bFifthFrameFlag;
uint8 m_bActiveSamples;
- uint8 field_4;
+ uint8 field_4; // unused
bool m_bDynamicAcousticModelingStatus;
- uint8 field_6;
- uint8 field_7;
- float speedOfSound;
+ uint8 field_6; // unused
+ uint8 field_7; // unused
+ float m_fSpeedOfSound;
bool m_bTimerJustReset;
- uint8 field_13;
- uint8 field_14;
- uint8 field_15;
+ uint8 field_13; // unused
+ uint8 field_14; // unused
+ uint8 field_15; // unused
int32 m_nTimer;
tSound m_sQueueSample;
bool m_bActiveSampleQueue;
- uint8 gap_109[3];
+ uint8 gap_109[3]; // unused
tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_bSampleRequestQueuesStatus[NUM_SOUNDS_SAMPLES_BANKS];
@@ -314,8 +325,7 @@ public:
int32 m_nAudioEntitiesTotal;
CVector m_avecReflectionsPos[NUM_AUDIO_REFLECTIONS];
float m_afReflectionsDistances[NUM_AUDIO_REFLECTIONS];
- int32 m_anScriptObjectEntityIndices[NUM_SCRIPT_MAX_ENTITIES];
- int32 m_nScriptObjectEntityTotal;
+ cAudioScriptObjectManager m_sAudioScriptObjectManager;
cPedComments m_sPedComments;
int32 m_nFireAudioEntity;
int32 m_nWaterCannonEntity;
@@ -328,12 +338,15 @@ public:
int32 m_nBridgeEntity;
cMissionAudio m_sMissionAudio;
int32 m_anRandomTable[5];
- uint8 field_19192;
+ uint8 m_bTimeSpent;
uint8 m_bUserPause;
uint8 m_bPreviousUserPause;
- uint8 field_19195; // time?
+ uint8 field_19195; // unused
uint32 m_FrameCounter;
+ cAudioManager();
+ ~cAudioManager();
+
// getters
uint32 GetFrameCounter() const { return m_FrameCounter; }
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
@@ -341,29 +354,29 @@ public:
bool IsMissionAudioPlaying() const { return m_sMissionAudio.m_bPlayStatus == 1; }
// "Should" be in alphabetic order, except "getXTalkSfx"
- void AddDetailsToRequestedOrderList(uint8 sample); /// ok (check once more)
+ void AddDetailsToRequestedOrderList(uint8 sample);
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 unk1,
- uint8 counter, bool notLooping); /// ok
- void AddReflectionsToRequestedQueue(); /// ok (check value)
- void AddReleasingSounds(); /// ok (check)
- void AddSampleToRequestedQueue(); /// ok
- void AgeCrimes(); /// ok
-
- void CalculateDistance(bool &condition, float dist); /// ok
- bool CheckForAnAudioFileOnCD() const; /// ok
- void ClearActiveSamples(); /// ok
- void ClearMissionAudio(); /// ok
- void ClearRequestedQueue(); /// ok
+ uint8 counter, bool notLooping);
+ void AddReflectionsToRequestedQueue();
+ void AddReleasingSounds();
+ void AddSampleToRequestedQueue();
+ void AgeCrimes();
+
+ void CalculateDistance(bool &condition, float dist);
+ bool CheckForAnAudioFileOnCD() const;
+ void ClearActiveSamples();
+ void ClearMissionAudio();
+ void ClearRequestedQueue();
int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
- float speedMultiplier) const; /// ok
- int32 ComputePan(float, CVector *); /// ok
- uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; /// ok
- int32 CreateEntity(int32 type, void *entity); /// ok
+ float speedMultiplier) const;
+ int32 ComputePan(float, CVector *);
+ uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const;
+ int32 CreateEntity(int32 type, void *entity);
- void DestroyAllGameCreatedEntities(); /// ok
- void DestroyEntity(int32 id); /// ok
- void DoJumboVolOffset() const; /// ok
- void DoPoliceRadioCrackle(); /// ok
+ void DestroyAllGameCreatedEntities();
+ void DestroyEntity(int32 id);
+ void DoJumboVolOffset() const;
+ void DoPoliceRadioCrackle();
// functions returning talk sfx,
// order from GetPedCommentSfx
@@ -445,154 +458,151 @@ public:
uint32 GetGenericFemaleTalkSfx(int16 sound);
// end of functions returning talk sfx
- void GenerateIntegerRandomNumberTable(); /// ok
+ void GenerateIntegerRandomNumberTable();
char *Get3DProviderName(uint8 id) const;
uint8 GetCDAudioDriveLetter() const;
- int8 GetCurrent3DProviderIndex() const; /// ok
+ int8 GetCurrent3DProviderIndex() const;
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
- float GetCollisionOneShotRatio(int32 a, float b) const; /// ok
- float GetCollisionRatio(float a, float b, float c, float d) const; /// ok
- float GetDistanceSquared(CVector *v) const; /// ok
- int32 GetJumboTaxiFreq() const; /// ok
- bool GetMissionAudioLoadingStatus() const; /// ok
- int8 GetMissionScriptPoliceAudioPlayingStatus() const; /// ok
+ float GetCollisionOneShotRatio(int32 a, float b) const;
+ float GetCollisionRatio(float a, float b, float c, float d) const;
+ float GetDistanceSquared(CVector *v) const;
+ int32 GetJumboTaxiFreq() const;
+ bool 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); /// ok
+ cTransmission *transmission, float velocityChange);
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
- cTransmission *transmission,
- float velocityChange); /// ok
+ cTransmission *transmission, float velocityChange);
- bool HasAirBrakes(int32 model) const; /// ok
+ bool HasAirBrakes(int32 model) const;
- void Initialise(); /// ok
- void InitialisePoliceRadio(); /// ok
- void InitialisePoliceRadioZones(); /// ok
- void InterrogateAudioEntities(); /// ok
- bool IsAudioInitialised() const; /// ok
- bool IsMissionAudioSampleFinished(); /// ok
+ void Initialise();
+ void InitialisePoliceRadio();
+ void InitialisePoliceRadioZones();
+ void InterrogateAudioEntities();
+ bool IsAudioInitialised() const;
+ bool IsMissionAudioSampleFinished();
bool IsMP3RadioChannelAvailable() const;
- bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; /// ok
-
- void PlayLoadedMissionAudio(); /// ok
- void PlayOneShot(int32 index, int16 sound, float vol); /// ok
- void PlaySuspectLastSeen(float x, float y, float z); /// ok
- void PlayerJustGotInCar() const; /// ok
- void PlayerJustLeftCar() const; /// ok
- void PostInitialiseGameSpecificSetup(); /// ok
- void PostTerminateGameSpecificShutdown(); /// ok
- void PreInitialiseGameSpecificSetup() const; /// ok
- void PreloadMissionAudio(const char *name); /// ok
- void PreTerminateGameSpecificShutdown(); /// ok
+ bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
+
+ void PlayLoadedMissionAudio();
+ void PlayOneShot(int32 index, int16 sound, float vol);
+ void PlaySuspectLastSeen(float x, float y, float z);
+ void PlayerJustGotInCar() const;
+ void PlayerJustLeftCar() const;
+ void PostInitialiseGameSpecificSetup();
+ void PostTerminateGameSpecificShutdown();
+ void PreInitialiseGameSpecificSetup() const;
+ void PreloadMissionAudio(const char *name);
+ void PreTerminateGameSpecificShutdown();
/// processX - main logic of adding new sounds
- void ProcessActiveQueues(); /// ok
- bool ProcessAirBrakes(cVehicleParams *params); /// ok
- void ProcessAirportScriptObject(uint8 sound); /// ok
- bool ProcessBoatEngine(cVehicleParams *params); /// ok
- bool ProcessBoatMovingOverWater(cVehicleParams *params); /// ok
- void ProcessBridge(); /// ok
- void ProcessBridgeMotor(); /// ok
- void ProcessBridgeOneShots(); /// ok
- void ProcessBridgeWarning(); /// ok
- bool ProcessCarBombTick(cVehicleParams *params); /// ok
- void ProcessCesna(cVehicleParams *params); /// ok
- void ProcessCinemaScriptObject(uint8 sound); /// ok
- void ProcessCrane(); /// ok
- void ProcessDocksScriptObject(uint8 sound); /// ok
- bool ProcessEngineDamage(cVehicleParams *params); /// ok
- void ProcessEntity(int32 sound); /// ok
- void ProcessExplosions(int32 explosion); /// ok
- void ProcessFireHydrant(); /// ok
- void ProcessFires(int32 entity); /// ok
- void ProcessFrontEnd(); /// ok
- void ProcessGarages(); /// ok
- bool ProcessHelicopter(cVehicleParams *params); /// ok
- void ProcessHomeScriptObject(uint8 sound); /// ok
- void ProcessJumbo(cVehicleParams *); /// ok
- void ProcessJumboAccel(CPlane *plane); /// ok
- void ProcessJumboDecel(CPlane *plane); /// ok
- void ProcessJumboFlying(); /// ok
- void ProcessJumboLanding(CPlane *plane); /// ok
- void ProcessJumboTakeOff(CPlane *plane); /// ok
- void ProcessJumboTaxi(); /// ok
- void ProcessLaunderetteScriptObject(uint8 sound); /// ok
- void ProcessLoopingScriptObject(uint8 sound); /// ok
- void ProcessMissionAudio(); /// ok
- void ProcessModelCarEngine(cVehicleParams *params); /// ok
- void ProcessOneShotScriptObject(uint8 sound); /// ok
- void ProcessPed(CPhysical *ped); /// ok
- void ProcessPedHeadphones(cPedParams *params); /// ok
- void ProcessPedOneShots(cPedParams *params); // todo later (weird)
- void ProcessPhysical(int32 id); /// ok
- void ProcessPlane(cVehicleParams *params); /// ok
- void ProcessPlayersVehicleEngine(cVehicleParams *params,
- CAutomobile *automobile); /// ok
- void ProcessPoliceCellBeatingScriptObject(uint8 sound); /// ok
- void ProcessPornCinema(uint8 sound); /// ok
- void ProcessProjectiles(); /// ok
- void ProcessRainOnVehicle(cVehicleParams *params); /// ok
- void ProcessReverb() const; /// ok
- bool ProcessReverseGear(cVehicleParams *params); /// ok
- void ProcessSawMillScriptObject(uint8 sound); /// ok
- void ProcessScriptObject(int32 id); /// ok
- void ProcessShopScriptObject(uint8 sound); /// ok
- void ProcessSpecial(); /// ok
- bool ProcessTrainNoise(cVehicleParams *params); /// ok
- void ProcessVehicle(CVehicle *vehicle); /// ok
- bool ProcessVehicleDoors(cVehicleParams *params); /// ok
- void ProcessVehicleEngine(cVehicleParams *params); /// ok
- void ProcessVehicleHorn(cVehicleParams *params); /// ok
- void ProcessVehicleOneShots(void *); // todo
- bool ProcessVehicleReverseWarning(cVehicleParams *params); /// ok
- bool ProcessVehicleRoadNoise(cVehicleParams *params); /// ok
- void ProcessVehicleSirenOrAlarm(cVehicleParams *params); /// ok
- void ProcessVehicleSkidding(cVehicleParams *params); /// ok
- void ProcessWaterCannon(int32); /// ok
- void ProcessWeather(int32 id); /// ok
- bool ProcessWetRoadNoise(cVehicleParams *params); /// ok
- void ProcessWorkShopScriptObject(uint8 sound); /// ok
+ void ProcessActiveQueues();
+ bool ProcessAirBrakes(cVehicleParams *params);
+ void ProcessAirportScriptObject(uint8 sound);
+ bool ProcessBoatEngine(cVehicleParams *params);
+ bool ProcessBoatMovingOverWater(cVehicleParams *params);
+ void ProcessBridge();
+ void ProcessBridgeMotor();
+ void ProcessBridgeOneShots();
+ void ProcessBridgeWarning();
+ bool ProcessCarBombTick(cVehicleParams *params);
+ void ProcessCesna(cVehicleParams *params);
+ void ProcessCinemaScriptObject(uint8 sound);
+ void ProcessCrane();
+ void ProcessDocksScriptObject(uint8 sound);
+ bool ProcessEngineDamage(cVehicleParams *params);
+ void ProcessEntity(int32 sound);
+ void ProcessExplosions(int32 explosion);
+ void ProcessFireHydrant();
+ void ProcessFires(int32 entity);
+ void ProcessFrontEnd();
+ void ProcessGarages();
+ bool ProcessHelicopter(cVehicleParams *params);
+ void ProcessHomeScriptObject(uint8 sound);
+ void ProcessJumbo(cVehicleParams *);
+ 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 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);
+ void ProcessPornCinema(uint8 sound);
+ void ProcessProjectiles();
+ void ProcessRainOnVehicle(cVehicleParams *params);
+ void ProcessReverb() const;
+ bool ProcessReverseGear(cVehicleParams *params);
+ void ProcessSawMillScriptObject(uint8 sound);
+ void ProcessScriptObject(int32 id);
+ void ProcessShopScriptObject(uint8 sound);
+ void ProcessSpecial();
+ bool ProcessTrainNoise(cVehicleParams *params);
+ void ProcessVehicle(CVehicle *vehicle);
+ bool ProcessVehicleDoors(cVehicleParams *params);
+ void ProcessVehicleEngine(cVehicleParams *params);
+ void ProcessVehicleHorn(cVehicleParams *params);
+ void ProcessVehicleOneShots(cVehicleParams *params);
+ bool ProcessVehicleReverseWarning(cVehicleParams *params);
+ bool ProcessVehicleRoadNoise(cVehicleParams *params);
+ void ProcessVehicleSirenOrAlarm(cVehicleParams *params);
+ void ProcessVehicleSkidding(cVehicleParams *params);
+ void ProcessWaterCannon(int32);
+ void ProcessWeather(int32 id);
+ bool ProcessWetRoadNoise(cVehicleParams *params);
+ void ProcessWorkShopScriptObject(uint8 sound);
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); /// ok
- void ReportCrime(int32 crime, const CVector *pos); /// ok
- void ResetAudioLogicTimers(uint32 timer); /// ok
- void ResetPoliceRadio(); /// ok
- void ResetTimers(uint32 time); /// ok
-
- void Service(); /// ok
- void ServiceCollisions(); /// ok
- void ServicePoliceRadio(); /// ok
- void ServicePoliceRadioChannel(int32 wantedLevel); /// ok
- void ServiceSoundEffects(); /// ok
- int8 SetCurrent3DProvider(uint8 which); /// ok
+ void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2,
+ float collisionPower, float intensity2);
+ void ReportCrime(int32 crime, const CVector *pos);
+ void ResetAudioLogicTimers(uint32 timer);
+ void ResetPoliceRadio();
+ void ResetTimers(uint32 time);
+
+ void Service();
+ void ServiceCollisions();
+ void ServicePoliceRadio();
+ void ServicePoliceRadioChannel(int32 wantedLevel);
+ void ServiceSoundEffects();
+ int8 SetCurrent3DProvider(uint8 which);
void SetDynamicAcousticModelingStatus(bool status);
void SetEffectsFadeVolume(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
void SetEntityStatus(int32 id, uint8 status);
- uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(cAudioCollision *audioCollision); /// ok
+ uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(cAudioCollision *audioCollision);
void SetMissionAudioLocation(float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const;
void SetMonoMode(uint8); // todo (mobile)
void SetMusicFadeVolume(uint8 volume) const;
void SetMusicMasterVolume(uint8 volume) const;
void SetSpeakerConfig(int32 conf) const;
- void SetUpLoopingCollisionSound(cAudioCollision *col, uint8 counter); /// ok
- void SetUpOneShotCollisionSound(cAudioCollision *col); /// ok
- bool SetupCrimeReport(); /// ok
- bool SetupJumboEngineSound(uint8 vol, int32 freq); /// ok
- bool SetupJumboFlySound(uint8 emittingVol); /// ok
- bool SetupJumboRumbleSound(uint8 emittingVol); /// ok
- bool SetupJumboTaxiSound(uint8 vol); /// ok
- bool SetupJumboWhineSound(uint8 emittingVol, int32 freq); /// ok
- void SetupPedComments(cPedParams *params, uint32 sound); /// ok
- void SetupSuspectLastSeenReport(); /// ok
+ void SetUpLoopingCollisionSound(cAudioCollision *col, uint8 counter);
+ void SetUpOneShotCollisionSound(cAudioCollision *col);
+ bool SetupCrimeReport();
+ bool SetupJumboEngineSound(uint8 vol, int32 freq);
+ bool SetupJumboFlySound(uint8 emittingVol);
+ bool SetupJumboRumbleSound(uint8 emittingVol);
+ bool SetupJumboTaxiSound(uint8 vol);
+ bool SetupJumboWhineSound(uint8 emittingVol, int32 freq);
+ void SetupPedComments(cPedParams *params, uint32 sound);
+ void SetupSuspectLastSeenReport();
void Terminate();
void TranslateEntity(CVector *v1, CVector *v2) const;
@@ -604,11 +614,10 @@ public:
bool UsesSirenSwitching(int32 model) const;
// only used in pc
- void AdjustSamplesVolume(); /// ok
- uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity,
- float dist); /// ok
+ void AdjustSamplesVolume();
+ uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
};
static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
-extern cAudioManager &AudioManager;
+extern cAudioManager AudioManager;
diff --git a/src/audio/AudioScriptObject.cpp b/src/audio/AudioScriptObject.cpp
index 0ae3834a..da9e1d2e 100644
--- a/src/audio/AudioScriptObject.cpp
+++ b/src/audio/AudioScriptObject.cpp
@@ -61,7 +61,7 @@ cAudioScriptObject::SaveAllAudioScriptObjects(uint8 *buf, uint32 *size)
INITSAVEBUF
int32 pool_size = CPools::GetAudioScriptObjectPool()->GetNoOfUsedSpaces();
- *size = SAVE_HEADER_SIZE + pool_size * (sizeof(cAudioScriptObject) + sizeof(int32));
+ *size = SAVE_HEADER_SIZE + sizeof(int32) + pool_size * (sizeof(cAudioScriptObject) + sizeof(int32));
WriteSaveHeader(buf, 'A', 'U', 'D', '\0', *size - SAVE_HEADER_SIZE);
WriteSaveBuf(buf, pool_size);
diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp
index d162ca4c..255d7026 100644
--- a/src/audio/PoliceRadio.cpp
+++ b/src/audio/PoliceRadio.cpp
@@ -1,789 +1,792 @@
-#include "common.h"
-#include "patcher.h"
-#include "DMAudio.h"
-#include "AudioManager.h"
-#include "AudioSamples.h"
-#include "MusicManager.h"
-#include "PoliceRadio.h"
-#include "PlayerPed.h"
-#include "sampman.h"
-#include "Zones.h"
-#include "Vehicle.h"
-#include "World.h"
-
-const int maxVolume = 127;
-const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
-const int policeChannel = channels + 1;
-
-struct tPoliceRadioZone {
- char m_aName[8];
- uint32 m_nSampleIndex;
- int32 field_12;
-};
-
-tPoliceRadioZone (&ZoneSfx)[NUMAUDIOZONES] = *(tPoliceRadioZone(*)[NUMAUDIOZONES])*(uintptr*)0x880240;
-char *SubZo2Label = (char*)0x6E9918;
-char *SubZo3Label = (char*)0x6E9870;
-
-int32 &g_nMissionAudioSfx = *(int32*)0x60ED84;
-int8 &g_nMissionAudioPlayingStatus = *(int8*)0x60ED88;
-uint8 &gSpecialSuspectLastSeenReport = *(uint8*)0x95CD4D;
-uint32 (&gMinTimeToNextReport)[NUM_CRIME_TYPES] = *(uint32(*)[NUM_CRIME_TYPES])*(uintptr*)0x8E2828;
-
-void
-cAudioManager::InitialisePoliceRadioZones()
-{
- for (int32 i = 0; i < NUMAUDIOZONES; i++)
- memset(ZoneSfx[i].m_aName, 0, 8);
-
-#define SETZONESFX(i, name, sample) \
- strcpy(ZoneSfx[i].m_aName, name); \
- ZoneSfx[i].m_nSampleIndex = sample;
-
- SETZONESFX(0, "HOSPI_2", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(1, "CONSTRU", SFX_POLICE_RADIO_FORT_STAUNTON);
- SETZONESFX(2, "STADIUM", SFX_POLICE_RADIO_ASPATRIA);
- SETZONESFX(3, "YAKUSA", SFX_POLICE_RADIO_TORRINGTON);
- SETZONESFX(4, "SHOPING", SFX_POLICE_RADIO_BEDFORD_POINT);
- SETZONESFX(5, "COM_EAS", SFX_POLICE_RADIO_NEWPORT);
- SETZONESFX(6, "PARK", SFX_POLICE_RADIO_BELLEVILLE_PARK);
- SETZONESFX(7, "UNIVERS", SFX_POLICE_RADIO_LIBERTY_CAMPUS);
- SETZONESFX(8, "BIG_DAM", SFX_POLICE_RADIO_COCHRANE_DAM);
- SETZONESFX(9, "SUB_IND", SFX_POLICE_RADIO_PIKE_CREEK);
- SETZONESFX(10, "SWANKS", SFX_POLICE_RADIO_CEDAR_GROVE);
- SETZONESFX(11, "PROJECT", SFX_POLICE_RADIO_WICHITA_GARDENS);
- SETZONESFX(12, "AIRPORT", SFX_POLICE_RADIO_FRANCIS_INTERNATIONAL_AIRPORT);
- SETZONESFX(13, "PORT_W", SFX_POLICE_RADIO_CALLAHAN_POINT);
- SETZONESFX(14, "PORT_S", SFX_POLICE_RADIO_ATLANTIC_QUAYS);
- SETZONESFX(15, "PORT_E", SFX_POLICE_RADIO_PORTLAND_HARBOUR);
- SETZONESFX(16, "PORT_I", SFX_POLICE_RADIO_TRENTON);
- SETZONESFX(17, "CHINA", SFX_POLICE_RADIO_CHINATOWN);
- SETZONESFX(18, "REDLIGH", SFX_POLICE_RADIO_RED_LIGHT_DISTRICT);
- SETZONESFX(19, "TOWERS", SFX_POLICE_RADIO_HEPBURN_HEIGHTS);
- SETZONESFX(20, "LITTLEI", SFX_POLICE_RADIO_SAINT_MARKS);
- SETZONESFX(21, "HARWOOD", SFX_POLICE_RADIO_HARWOOD);
- SETZONESFX(22, "EASTBAY", SFX_POLICE_RADIO_PORTLAND_BEACH);
- SETZONESFX(23, "S_VIEW", SFX_POLICE_RADIO_PORTLAND_STRAIGHTS);
- SETZONESFX(24, "CITYZON", SFX_POLICE_RADIO_LIBERTY_CITY);
- SETZONESFX(25, "IND_ZON", SFX_POLICE_RADIO_PORTLAND);
- SETZONESFX(26, "COM_ZON", SFX_POLICE_RADIO_STAUNTON_ISLAND);
- SETZONESFX(27, "SUB_ZON", SFX_POLICE_RADIO_SHORESIDE_VALE);
- SETZONESFX(28, "SUB_ZO2", SFX_POLICE_RADIO_SHORESIDE_VALE);
- SETZONESFX(29, "SUB_ZO3", SFX_POLICE_RADIO_SHORESIDE_VALE);
- SETZONESFX(30, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(31, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(32, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(33, "A", SFX_POLICE_RADIO_ROCKFORD);
- SETZONESFX(34, "A", SFX_POLICE_RADIO_ROCKFORD);
-
-#undef SETZONESFX
-
- strcpy(SubZo2Label, "SUB_ZO2");
- strcpy(SubZo3Label, "SUB_ZO3");
-}
-
-void
-cAudioManager::InitialisePoliceRadio()
-{
- m_sPoliceRadioQueue.policeChannelTimer = 0;
- m_sPoliceRadioQueue.policeChannelTimerSeconds = 0;
- m_sPoliceRadioQueue.policeChannelCounterSeconds = 0;
- for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++)
- m_sPoliceRadioQueue.crimes[i].type = 0;
-
- SampleManager.SetChannelReverbFlag(policeChannel, 0);
- gSpecialSuspectLastSeenReport = false;
- for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++)
- gMinTimeToNextReport[i] = m_FrameCounter;
-}
-
-void
-cAudioManager::ResetPoliceRadio()
-{
- if (!m_bIsInitialised) return;
- if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
- InitialisePoliceRadio();
-}
-
-void
-cAudioManager::SetMissionScriptPoliceAudio(int32 sfx) const
-{
- if (!m_bIsInitialised) return;
- if (g_nMissionAudioPlayingStatus != 1) {
- g_nMissionAudioPlayingStatus = 0;
- g_nMissionAudioSfx = sfx;
- }
-}
-
-int8
-cAudioManager::GetMissionScriptPoliceAudioPlayingStatus() const
-{
- return g_nMissionAudioPlayingStatus;
-}
-
-void
-cAudioManager::DoPoliceRadioCrackle()
-{
- m_sQueueSample.m_nEntityIndex = m_nPoliceChannelEntity;
- m_sQueueSample.m_counter = 0;
- m_sQueueSample.m_nSampleIndex = SFX_POLICE_RADIO_CRACKLE;
- m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
- m_sQueueSample.m_bIsDistant = true;
- m_sQueueSample.field_16 = 10;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_RADIO_CRACKLE);
- m_sQueueSample.m_bVolume = m_anRandomTable[2] % 20 + 15;
- m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_bEmittingVolume = m_sQueueSample.m_bVolume;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_POLICE_RADIO_CRACKLE);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_POLICE_RADIO_CRACKLE);
- m_sQueueSample.field_56 = 0;
- m_sQueueSample.m_bReverbFlag = false;
- m_sQueueSample.m_bOffset = 63;
- m_sQueueSample.field_76 = 3;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
-}
-
-void
-cAudioManager::ServicePoliceRadio()
-{
- int32 wantedLevel = 0; // bug?;
- static uint32 nLastSeen = 300;
-
- if (!m_bIsInitialised) return;
-
- if (!m_bUserPause) {
- bool crimeReport = SetupCrimeReport();
- wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel;
- if (!crimeReport) {
- if (wantedLevel) {
- if (nLastSeen) {
- --nLastSeen;
- } else {
- nLastSeen = m_anRandomTable[1] % 1000 + 2000;
- SetupSuspectLastSeenReport();
- }
- }
- }
- }
- ServicePoliceRadioChannel(wantedLevel);
-}
-
-void
-cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel)
-{
- bool processed = false;
- uint32 sample;
- int32 freq;
-
- static int cWait = 0;
- static bool bChannelOpen = false;
- static uint8 bMissionAudioPhysicalPlayingStatus = 0;
- static int32 PoliceChannelFreq = 5500;
-
- if (!m_bIsInitialised) return;
-
- if (m_bUserPause) {
- if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
- if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == 1 &&
- SampleManager.IsStreamPlaying(1)) {
- SampleManager.PauseStream(1, 1);
- }
- } else {
- if (m_bPreviousUserPause && g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES &&
- bMissionAudioPhysicalPlayingStatus == 1) {
- SampleManager.PauseStream(0, 1);
- }
- if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = false;
- if (cWait) {
- --cWait;
- return;
- }
- if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && !bChannelOpen) {
- if (g_nMissionAudioPlayingStatus) {
- if (g_nMissionAudioPlayingStatus == 1 && !bMissionAudioPhysicalPlayingStatus &&
- SampleManager.IsStreamPlaying(1)) {
- bMissionAudioPhysicalPlayingStatus = 1;
- }
- if (bMissionAudioPhysicalPlayingStatus == 1) {
- if (SampleManager.IsStreamPlaying(1)) {
- DoPoliceRadioCrackle();
- } else {
- bMissionAudioPhysicalPlayingStatus = 2;
- g_nMissionAudioPlayingStatus = 2;
- g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
- cWait = 30;
- }
- return;
- }
- } else if (!SampleManager.GetChannelUsedFlag(policeChannel)) {
- SampleManager.PreloadStreamedFile(g_nMissionAudioSfx, 1);
- SampleManager.SetStreamedVolumeAndPan(maxVolume, 63, 1, 1);
- SampleManager.StartPreloadedStreamedFile(1);
- g_nMissionAudioPlayingStatus = 1;
- bMissionAudioPhysicalPlayingStatus = 0;
- return;
- }
- }
- if (bChannelOpen) DoPoliceRadioCrackle();
- if ((g_nMissionAudioSfx == TOTAL_AUDIO_SAMPLES || g_nMissionAudioPlayingStatus != 1) &&
- !SampleManager.GetChannelUsedFlag(policeChannel) && m_sPoliceRadioQueue.policeChannelTimer) {
- if (m_sPoliceRadioQueue.policeChannelTimer) {
- sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds];
- m_sPoliceRadioQueue.policeChannelTimer--;
- m_sPoliceRadioQueue.policeChannelCounterSeconds = (m_sPoliceRadioQueue.policeChannelCounterSeconds + 1) % 60;
- } else {
- sample = TOTAL_AUDIO_SAMPLES;
- }
- if (!wantedLevel) {
- if (gSpecialSuspectLastSeenReport) {
- gSpecialSuspectLastSeenReport = 0;
- } else if (((sample >= SFX_POLICE_RADIO_MESSAGE_NOISE_1) && (sample <= SFX_POLICE_RADIO_MESSAGE_NOISE_3)) || sample == TOTAL_AUDIO_SAMPLES) {
- bChannelOpen = false;
- processed = true;
- }
- }
- if (sample == TOTAL_AUDIO_SAMPLES) {
- if (!processed) cWait = 30;
- } else {
- SampleManager.InitialiseChannel(policeChannel, sample, 0);
- switch (sample) {
- case SFX_POLICE_RADIO_MESSAGE_NOISE_1:
- case SFX_POLICE_RADIO_MESSAGE_NOISE_2:
- case SFX_POLICE_RADIO_MESSAGE_NOISE_3:
- freq = m_anRandomTable[4] % 2000 + 10025;
- bChannelOpen = bChannelOpen == false;
- break;
- default: freq = SampleManager.GetSampleBaseFrequency(sample); break;
- }
- PoliceChannelFreq = freq;
- SampleManager.SetChannelFrequency(policeChannel, freq);
- SampleManager.SetChannelVolume(policeChannel, 100);
- SampleManager.SetChannelPan(policeChannel, 63);
- SampleManager.SetChannelLoopCount(policeChannel, 1);
- SampleManager.SetChannelLoopPoints(policeChannel, 0, -1);
- SampleManager.StartChannel(policeChannel);
- }
- if (processed) ResetPoliceRadio();
- }
- }
-}
-
-bool
-cAudioManager::SetupCrimeReport()
-{
- int16 audioZoneId;
- CZone *zone;
- float rangeX;
- float rangeY;
- float halfX;
- float halfY;
- float quarterX;
- float quarterY;
- int i;
- int32 sampleIndex;
- bool processed = false;
-
- if (MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE) return false;
-
- if (60 - m_sPoliceRadioQueue.policeChannelTimer <= 9) {
- AgeCrimes();
- return true;
- }
-
- for (i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
- if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE)
- break;
- }
-
- if (i == ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) return false;
- audioZoneId = CTheZones::FindAudioZone(&m_sPoliceRadioQueue.crimes[i].position);
- if (audioZoneId >= 0 && audioZoneId < NUMAUDIOZONES) {
- zone = &CTheZones::ZoneArray[CTheZones::AudioZoneArray[audioZoneId]];
- for (int j = 0; j < NUMAUDIOZONES; j++) {
- if (strcmp(zone->name, ZoneSfx[j].m_aName) == 0) {
- sampleIndex = ZoneSfx[j].m_nSampleIndex;
- m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_WEVE_GOT);
- m_sPoliceRadioQueue.Add(m_anRandomTable[1] % 2 + SFX_A_10_1);
- switch (m_sPoliceRadioQueue.crimes[i].type) {
- case CRIME_PED_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED; break;
- case CRIME_COP_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP; break;
- case CRIME_VEHICLE_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break;
- case CRIME_DESTROYED_CESSNA: m_sPoliceRadioQueue.crimes[i].type = CRIME_SHOOT_HELI; break;
- default: break;
- }
- m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1 - 1);
- m_sPoliceRadioQueue.Add(SFX_IN);
- if (sampleIndex == SFX_POLICE_RADIO_SHORESIDE_VALE &&
- (strcmp(zone->name, SubZo2Label) == 0 || strcmp(zone->name, SubZo3Label) == 0)) {
- m_sPoliceRadioQueue.Add(SFX_NORTH);
- m_sPoliceRadioQueue.Add(SFX_EAST);
- } else {
- rangeX = zone->maxx - zone->minx;
- rangeY = zone->maxy - zone->miny;
- halfX = 0.5f * rangeX + zone->minx;
- halfY = 0.5f * rangeY + zone->miny;
- quarterX = 0.25f * rangeX;
- quarterY = 0.25f * rangeY;
-
- if (m_sPoliceRadioQueue.crimes[i].position.y > halfY + quarterY) {
- m_sPoliceRadioQueue.Add(SFX_NORTH);
- processed = true;
- } else if (m_sPoliceRadioQueue.crimes[i].position.y < halfY - quarterY) {
- m_sPoliceRadioQueue.Add(SFX_SOUTH);
- processed = true;
- }
-
- if (m_sPoliceRadioQueue.crimes[i].position.x > halfX + quarterX)
- m_sPoliceRadioQueue.Add(SFX_EAST);
- else if (m_sPoliceRadioQueue.crimes[i].position.x < halfX - quarterX)
- m_sPoliceRadioQueue.Add(SFX_WEST);
- else if (!processed)
- m_sPoliceRadioQueue.Add(SFX_CENTRAL);
-
- m_sPoliceRadioQueue.Add(sampleIndex);
- m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
- }
- break;
- }
- }
- }
- m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
- AgeCrimes();
- return true;
-}
-
-void
-cAudioManager::SetupSuspectLastSeenReport()
-{
- CVehicle *veh;
- uint8 color1;
- int32 main_color;
- int32 sample;
-
- int32 color_pre_modifier;
- int32 color_post_modifier;
-
- const int32 gCarColourTable[][3] = {
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLACK, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_WHITE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_BLUE},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_GREY},
-#else
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#else
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
-#endif
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#ifdef FIX_BUGS
- {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#else
- {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
-#endif
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
- {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}
- };
-
- if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
- veh = FindPlayerVehicle();
- if (veh != nil) {
- if (60 - m_sPoliceRadioQueue.policeChannelTimer > 9) {
- color1 = veh->m_currentColour1;
- if (color1 >= ARRAY_SIZE(gCarColourTable)) {
- debug("\n *** UNKNOWN CAR COLOUR %d *** ", color1);
- } else {
- main_color = gCarColourTable[color1][1];
- color_pre_modifier = gCarColourTable[color1][0];
- color_post_modifier = gCarColourTable[color1][2];
- switch (veh->m_modelIndex) {
-#ifdef FIX_BUGS
- case MI_COLUMB:
- main_color = SFX_POLICE_RADIO_BLUE;
- color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES;
-#endif
- case MI_LANDSTAL:
- case MI_BLISTA: sample = SFX_POLICE_RADIO_CRUISER; break;
-#ifdef FIX_BUGS
- case MI_YARDIE:
- color_pre_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_RED;
- color_post_modifier = SFX_POLICE_RADIO_YELLOW;
- sample = SFX_POLICE_RADIO_CONVERTIBLE; break;
- case MI_DIABLOS:
- main_color = SFX_POLICE_RADIO_BLACK;
-#endif
- case MI_IDAHO:
- case MI_STALLION: sample = SFX_POLICE_RADIO_CONVERTIBLE; break;
-#ifdef FIX_BUGS
- case MI_YAKUZA:
- color_pre_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_SILVER;
- color_post_modifier = SFX_POLICE_RADIO_RED;
-#endif
- case MI_STINGER:
- case MI_INFERNUS:
- case MI_CHEETAH:
- case MI_BANSHEE: sample = SFX_POLICE_RADIO_SPORTS_CAR; break;
-#ifdef FIX_BUGS
- case MI_MAFIA:
- color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_GREY;
- case MI_KURUMA:
-#endif
- case MI_PEREN:
- case MI_SENTINEL:
- case MI_FBICAR: sample = SFX_POLICE_RADIO_SALOON; break;
- case MI_PATRIOT:
- case MI_BOBCAT: sample = SFX_POLICE_RADIO_PICKUP; break;
- case MI_FIRETRUCK: sample = SFX_POLICE_RADIO_FIRE_TRUCK; break;
-#ifdef FIX_BUGS
- case MI_LINERUN:
- case MI_FLATBED:
-#endif
- case MI_TRASH:
- case MI_BARRACKS: sample = SFX_POLICE_RADIO_TRUCK; break;
- case MI_STRETCH: sample = SFX_POLICE_RADIO_LIMO; break;
-#ifdef FIX_BUGS
- case MI_CORPSE:
-#endif
- case MI_MANANA:
- case MI_ESPERANT: sample = SFX_POLICE_RADIO_2_DOOR; break;
-#ifdef FIX_BUGS
- case MI_HOODS:
- color_pre_modifier = TOTAL_AUDIO_SAMPLES;
- main_color = SFX_POLICE_RADIO_BLUE;
- color_post_modifier = SFX_POLICE_RADIO_GREEN;
- case MI_BELLYUP:
- case MI_YANKEE:
- case MI_TOYZ:
- case MI_MRWONGS:
- case MI_PANLANT:
-#endif
- case MI_PONY:
- case MI_MULE:
- case MI_MOONBEAM:
- case MI_ENFORCER:
- case MI_SECURICA:
- case MI_RUMPO: sample = SFX_POLICE_RADIO_VAN; break;
- case MI_AMBULAN: sample = SFX_POLICE_RADIO_AMBULANCE; break;
- case MI_TAXI:
- case MI_CABBIE:
- case MI_BORGNINE: sample = SFX_POLICE_RADIO_TAXI; break;
- case MI_MRWHOOP:
- sample = SFX_POLICE_RADIO_ICE_CREAM_VAN;
- break;
- case MI_BFINJECT: sample = SFX_POLICE_RADIO_BUGGY; break;
- case MI_POLICE: sample = SFX_POLICE_RADIO_POLICE_CAR; break;
-#ifdef FIX_BUGS
- case MI_SPEEDER:
- case MI_REEFER:
- case MI_GHOST:
-#endif
- case MI_PREDATOR: sample = SFX_POLICE_RADIO_BOAT; break;
- case MI_BUS:
- case MI_COACH: sample = SFX_POLICE_RADIO_BUS; break;
- case MI_RHINO:
- sample = SFX_POLICE_RADIO_TANK;
- main_color = TOTAL_AUDIO_SAMPLES;
- color_post_modifier = TOTAL_AUDIO_SAMPLES;
- break;
- case MI_TRAIN:
- sample = SFX_POLICE_RADIO_SUBWAY_CAR;
- main_color = TOTAL_AUDIO_SAMPLES;
- color_post_modifier = TOTAL_AUDIO_SAMPLES;
-
- break;
- default:
- debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->m_modelIndex);
- return;
- }
- m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
- if (m_anRandomTable[3] % 2)
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN);
-#ifdef FIX_BUGS
- if (main_color == SFX_POLICE_RADIO_ORANGE && color_pre_modifier == TOTAL_AUDIO_SAMPLES)
-#else
- if (main_color == SFX_POLICE_RADIO_ORANGE)
-#endif
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_AN);
- else
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_A);
- if (color_pre_modifier != TOTAL_AUDIO_SAMPLES)
- m_sPoliceRadioQueue.Add(color_pre_modifier);
- if (main_color != TOTAL_AUDIO_SAMPLES)
- m_sPoliceRadioQueue.Add(main_color);
- if (color_post_modifier != TOTAL_AUDIO_SAMPLES)
- m_sPoliceRadioQueue.Add(color_post_modifier);
- m_sPoliceRadioQueue.Add(sample);
- m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
- }
- }
- } else if (60 - m_sPoliceRadioQueue.policeChannelTimer > 4) {
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_ON_FOOT);
- m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
- }
- }
-}
-
-
-
-void
-cAudioManager::ReportCrime(int32 type, const CVector *pos)
-{
- int32 lastCrime = ARRAY_SIZE(m_sPoliceRadioQueue.crimes);
- if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 &&
- (type > CRIME_NONE || type < NUM_CRIME_TYPES) && m_FrameCounter >= gMinTimeToNextReport[type]) {
- for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
- if (m_sPoliceRadioQueue.crimes[i].type) {
- if (m_sPoliceRadioQueue.crimes[i].type == type) {
- m_sPoliceRadioQueue.crimes[i].position = *pos;
- m_sPoliceRadioQueue.crimes[i].timer = 0;
- return;
- }
- } else {
- lastCrime = i;
- }
- }
-
- if (lastCrime < ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) {
- m_sPoliceRadioQueue.crimes[lastCrime].type = type;
- m_sPoliceRadioQueue.crimes[lastCrime].position = *pos;
- m_sPoliceRadioQueue.crimes[lastCrime].timer = 0;
- gMinTimeToNextReport[type] = m_FrameCounter + 500;
- }
- }
-}
-
-void
-cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
-{
- int16 audioZone;
- CZone *zone;
- float rangeX;
- float rangeY;
- float halfX;
- float halfY;
- float quarterX;
- float quarterY;
- int32 sample;
- bool processed = false;
- CVector vec = CVector(x, y, z);
-
- if (!m_bIsInitialised) return;
-
- if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && 60 - m_sPoliceRadioQueue.policeChannelTimer > 9) {
- audioZone = CTheZones::FindAudioZone(&vec);
- if (audioZone >= 0 && audioZone < NUMAUDIOZONES) {
- zone = &CTheZones::ZoneArray[CTheZones::AudioZoneArray[audioZone]];
- for (int i = 0; i < NUMAUDIOZONES; i++) {
- if (strcmp(zone->name, ZoneSfx[i].m_aName) == 0) {
- sample = ZoneSfx[i].m_nSampleIndex;
- m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
- m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN);
- m_sPoliceRadioQueue.Add(SFX_IN);
- if (sample == SFX_POLICE_RADIO_SHORESIDE_VALE &&
- (strcmp(zone->name, SubZo2Label) == 0 ||
- strcmp(zone->name, SubZo3Label) == 0)) {
- m_sPoliceRadioQueue.Add(SFX_NORTH);
- m_sPoliceRadioQueue.Add(SFX_EAST);
- } else {
- rangeX = zone->maxx - zone->minx;
- rangeY = zone->maxy - zone->miny;
- halfX = 0.5f * rangeX + zone->minx;
- halfY = 0.5f * rangeY + zone->miny;
- quarterX = 0.25f * rangeX;
- quarterY = 0.25f * rangeY;
-
- if (vec.y > halfY + quarterY) {
- m_sPoliceRadioQueue.Add(SFX_NORTH);
- processed = true;
- } else if (vec.y < halfY - quarterY) {
- m_sPoliceRadioQueue.Add(SFX_SOUTH);
- processed = true;
- }
-
- if (vec.x > halfX + quarterX)
- m_sPoliceRadioQueue.Add(SFX_EAST);
- else if (vec.x < halfX - quarterX)
- m_sPoliceRadioQueue.Add(SFX_WEST);
- else if (!processed)
- m_sPoliceRadioQueue.Add(SFX_CENTRAL);
- }
- m_sPoliceRadioQueue.Add(sample);
- m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
- m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
- gSpecialSuspectLastSeenReport = true;
- break;
- }
- }
- }
- }
-}
-
-void
-cAudioManager::AgeCrimes()
-{
- for (uint8 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
- if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) {
- if (++m_sPoliceRadioQueue.crimes[i].timer > 1500) m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
- }
- }
-}
-
-STARTPATCHES
-InjectHook(0x580AF0, &cAudioManager::AgeCrimes, PATCH_JUMP);
-InjectHook(0x57F060, &cAudioManager::DoPoliceRadioCrackle, PATCH_JUMP);
-InjectHook(0x57F050, &cAudioManager::GetMissionScriptPoliceAudioPlayingStatus, PATCH_JUMP);
-InjectHook(0x57EEC0, &cAudioManager::InitialisePoliceRadio, PATCH_JUMP);
-InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP);
-InjectHook(0x580500, &cAudioManager::PlaySuspectLastSeen, PATCH_JUMP);
-InjectHook(0x5803D0, &cAudioManager::ReportCrime, PATCH_JUMP);
-InjectHook(0x57EFF0, &cAudioManager::ResetPoliceRadio, PATCH_JUMP);
-InjectHook(0x57F110, &cAudioManager::ServicePoliceRadio, PATCH_JUMP);
-InjectHook(0x57F1B0, &cAudioManager::ServicePoliceRadioChannel, PATCH_JUMP);
-InjectHook(0x57F020, &cAudioManager::SetMissionScriptPoliceAudio, PATCH_JUMP);
-InjectHook(0x57F5B0, &cAudioManager::SetupCrimeReport, PATCH_JUMP);
-InjectHook(0x57FCC0, &cAudioManager::SetupSuspectLastSeenReport, PATCH_JUMP);
-ENDPATCHES
+#include "common.h"
+#include "patcher.h"
+#include "DMAudio.h"
+#include "AudioManager.h"
+#include "AudioSamples.h"
+#include "MusicManager.h"
+#include "PoliceRadio.h"
+#include "PlayerPed.h"
+#include "sampman.h"
+#include "Zones.h"
+#include "Vehicle.h"
+#include "World.h"
+
+const int maxVolume = 127;
+const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
+const int policeChannel = channels + 1;
+
+struct tPoliceRadioZone {
+ char m_aName[8];
+ uint32 m_nSampleIndex;
+ int32 field_12;
+};
+
+tPoliceRadioZone (&ZoneSfx)[NUMAUDIOZONES] = *(tPoliceRadioZone(*)[NUMAUDIOZONES])*(uintptr*)0x880240;
+char *SubZo2Label = (char*)0x6E9918;
+char *SubZo3Label = (char*)0x6E9870;
+
+int32 &g_nMissionAudioSfx = *(int32*)0x60ED84;
+int8 &g_nMissionAudioPlayingStatus = *(int8*)0x60ED88;
+uint8 &gSpecialSuspectLastSeenReport = *(uint8*)0x95CD4D;
+uint32 (&gMinTimeToNextReport)[NUM_CRIME_TYPES] = *(uint32(*)[NUM_CRIME_TYPES])*(uintptr*)0x8E2828;
+
+void
+cAudioManager::InitialisePoliceRadioZones()
+{
+ for (int32 i = 0; i < NUMAUDIOZONES; i++)
+ memset(ZoneSfx[i].m_aName, 0, 8);
+
+#define SETZONESFX(i, name, sample) \
+ strcpy(ZoneSfx[i].m_aName, name); \
+ ZoneSfx[i].m_nSampleIndex = sample;
+
+ SETZONESFX(0, "HOSPI_2", SFX_POLICE_RADIO_ROCKFORD);
+ SETZONESFX(1, "CONSTRU", SFX_POLICE_RADIO_FORT_STAUNTON);
+ SETZONESFX(2, "STADIUM", SFX_POLICE_RADIO_ASPATRIA);
+ SETZONESFX(3, "YAKUSA", SFX_POLICE_RADIO_TORRINGTON);
+ SETZONESFX(4, "SHOPING", SFX_POLICE_RADIO_BEDFORD_POINT);
+ SETZONESFX(5, "COM_EAS", SFX_POLICE_RADIO_NEWPORT);
+ SETZONESFX(6, "PARK", SFX_POLICE_RADIO_BELLEVILLE_PARK);
+ SETZONESFX(7, "UNIVERS", SFX_POLICE_RADIO_LIBERTY_CAMPUS);
+ SETZONESFX(8, "BIG_DAM", SFX_POLICE_RADIO_COCHRANE_DAM);
+ SETZONESFX(9, "SUB_IND", SFX_POLICE_RADIO_PIKE_CREEK);
+ SETZONESFX(10, "SWANKS", SFX_POLICE_RADIO_CEDAR_GROVE);
+ SETZONESFX(11, "PROJECT", SFX_POLICE_RADIO_WICHITA_GARDENS);
+ SETZONESFX(12, "AIRPORT", SFX_POLICE_RADIO_FRANCIS_INTERNATIONAL_AIRPORT);
+ SETZONESFX(13, "PORT_W", SFX_POLICE_RADIO_CALLAHAN_POINT);
+ SETZONESFX(14, "PORT_S", SFX_POLICE_RADIO_ATLANTIC_QUAYS);
+ SETZONESFX(15, "PORT_E", SFX_POLICE_RADIO_PORTLAND_HARBOUR);
+ SETZONESFX(16, "PORT_I", SFX_POLICE_RADIO_TRENTON);
+ SETZONESFX(17, "CHINA", SFX_POLICE_RADIO_CHINATOWN);
+ SETZONESFX(18, "REDLIGH", SFX_POLICE_RADIO_RED_LIGHT_DISTRICT);
+ SETZONESFX(19, "TOWERS", SFX_POLICE_RADIO_HEPBURN_HEIGHTS);
+ SETZONESFX(20, "LITTLEI", SFX_POLICE_RADIO_SAINT_MARKS);
+ SETZONESFX(21, "HARWOOD", SFX_POLICE_RADIO_HARWOOD);
+ SETZONESFX(22, "EASTBAY", SFX_POLICE_RADIO_PORTLAND_BEACH);
+ SETZONESFX(23, "S_VIEW", SFX_POLICE_RADIO_PORTLAND_STRAIGHTS);
+ SETZONESFX(24, "CITYZON", SFX_POLICE_RADIO_LIBERTY_CITY);
+ SETZONESFX(25, "IND_ZON", SFX_POLICE_RADIO_PORTLAND);
+ SETZONESFX(26, "COM_ZON", SFX_POLICE_RADIO_STAUNTON_ISLAND);
+ SETZONESFX(27, "SUB_ZON", SFX_POLICE_RADIO_SHORESIDE_VALE);
+ SETZONESFX(28, "SUB_ZO2", SFX_POLICE_RADIO_SHORESIDE_VALE);
+ SETZONESFX(29, "SUB_ZO3", SFX_POLICE_RADIO_SHORESIDE_VALE);
+ SETZONESFX(30, "A", SFX_POLICE_RADIO_ROCKFORD);
+ SETZONESFX(31, "A", SFX_POLICE_RADIO_ROCKFORD);
+ SETZONESFX(32, "A", SFX_POLICE_RADIO_ROCKFORD);
+ SETZONESFX(33, "A", SFX_POLICE_RADIO_ROCKFORD);
+ SETZONESFX(34, "A", SFX_POLICE_RADIO_ROCKFORD);
+
+#undef SETZONESFX
+
+ strcpy(SubZo2Label, "SUB_ZO2");
+ strcpy(SubZo3Label, "SUB_ZO3");
+}
+
+void
+cAudioManager::InitialisePoliceRadio()
+{
+ m_sPoliceRadioQueue.policeChannelTimer = 0;
+ m_sPoliceRadioQueue.policeChannelTimerSeconds = 0;
+ m_sPoliceRadioQueue.policeChannelCounterSeconds = 0;
+ for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++)
+ m_sPoliceRadioQueue.crimes[i].type = 0;
+
+ SampleManager.SetChannelReverbFlag(policeChannel, 0);
+ gSpecialSuspectLastSeenReport = false;
+ for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++)
+ gMinTimeToNextReport[i] = m_FrameCounter;
+}
+
+void
+cAudioManager::ResetPoliceRadio()
+{
+ if (!m_bIsInitialised) return;
+ if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
+ InitialisePoliceRadio();
+}
+
+void
+cAudioManager::SetMissionScriptPoliceAudio(int32 sfx) const
+{
+ if (!m_bIsInitialised) return;
+ if (g_nMissionAudioPlayingStatus != 1) {
+ g_nMissionAudioPlayingStatus = 0;
+ g_nMissionAudioSfx = sfx;
+ }
+}
+
+int8
+cAudioManager::GetMissionScriptPoliceAudioPlayingStatus() const
+{
+ return g_nMissionAudioPlayingStatus;
+}
+
+void
+cAudioManager::DoPoliceRadioCrackle()
+{
+ m_sQueueSample.m_nEntityIndex = m_nPoliceChannelEntity;
+ m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_nSampleIndex = SFX_POLICE_RADIO_CRACKLE;
+ m_sQueueSample.m_bBankIndex = SAMPLEBANK_MAIN;
+ m_sQueueSample.m_bIs2D = true;
+ m_sQueueSample.m_nReleasingVolumeModificator = 10;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_RADIO_CRACKLE);
+ m_sQueueSample.m_bVolume = m_anRandomTable[2] % 20 + 15;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_bEmittingVolume = m_sQueueSample.m_bVolume;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_POLICE_RADIO_CRACKLE);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_POLICE_RADIO_CRACKLE);
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_bReverbFlag = false;
+ m_sQueueSample.m_bOffset = 63;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+}
+
+void
+cAudioManager::ServicePoliceRadio()
+{
+ int32 wantedLevel = 0; // uninitialized variable
+ static uint32 nLastSeen = 300;
+
+ if(!m_bIsInitialised) return;
+
+ if(!m_bUserPause) {
+ bool crimeReport = SetupCrimeReport();
+#ifdef FIX_BUGS // Crash at 0x5fe6ef
+ if(!FindPlayerPed() || !FindPlayerPed()->m_pWanted) return;
+#endif
+ wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel;
+ if(!crimeReport) {
+ if(wantedLevel) {
+ if(nLastSeen) {
+ --nLastSeen;
+ } else {
+ nLastSeen = m_anRandomTable[1] % 1000 + 2000;
+ SetupSuspectLastSeenReport();
+ }
+ }
+ }
+ }
+ ServicePoliceRadioChannel(wantedLevel);
+}
+
+void
+cAudioManager::ServicePoliceRadioChannel(int32 wantedLevel)
+{
+ bool processed = false;
+ uint32 sample;
+ int32 freq;
+
+ static int cWait = 0;
+ static bool bChannelOpen = false;
+ static uint8 bMissionAudioPhysicalPlayingStatus = 0;
+ static int32 PoliceChannelFreq = 5500;
+
+ if (!m_bIsInitialised) return;
+
+ if (m_bUserPause) {
+ if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
+ if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == 1 &&
+ SampleManager.IsStreamPlaying(1)) {
+ SampleManager.PauseStream(1, 1);
+ }
+ } else {
+ if (m_bPreviousUserPause && g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES &&
+ bMissionAudioPhysicalPlayingStatus == 1) {
+ SampleManager.PauseStream(0, 1);
+ }
+ if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = false;
+ if (cWait) {
+ --cWait;
+ return;
+ }
+ if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && !bChannelOpen) {
+ if (g_nMissionAudioPlayingStatus) {
+ if (g_nMissionAudioPlayingStatus == 1 && !bMissionAudioPhysicalPlayingStatus &&
+ SampleManager.IsStreamPlaying(1)) {
+ bMissionAudioPhysicalPlayingStatus = 1;
+ }
+ if (bMissionAudioPhysicalPlayingStatus == 1) {
+ if (SampleManager.IsStreamPlaying(1)) {
+ DoPoliceRadioCrackle();
+ } else {
+ bMissionAudioPhysicalPlayingStatus = 2;
+ g_nMissionAudioPlayingStatus = 2;
+ g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
+ cWait = 30;
+ }
+ return;
+ }
+ } else if (!SampleManager.GetChannelUsedFlag(policeChannel)) {
+ SampleManager.PreloadStreamedFile(g_nMissionAudioSfx, 1);
+ SampleManager.SetStreamedVolumeAndPan(maxVolume, 63, 1, 1);
+ SampleManager.StartPreloadedStreamedFile(1);
+ g_nMissionAudioPlayingStatus = 1;
+ bMissionAudioPhysicalPlayingStatus = 0;
+ return;
+ }
+ }
+ if (bChannelOpen) DoPoliceRadioCrackle();
+ if ((g_nMissionAudioSfx == TOTAL_AUDIO_SAMPLES || g_nMissionAudioPlayingStatus != 1) &&
+ !SampleManager.GetChannelUsedFlag(policeChannel) && m_sPoliceRadioQueue.policeChannelTimer) {
+ if (m_sPoliceRadioQueue.policeChannelTimer) {
+ sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds];
+ m_sPoliceRadioQueue.policeChannelTimer--;
+ m_sPoliceRadioQueue.policeChannelCounterSeconds = (m_sPoliceRadioQueue.policeChannelCounterSeconds + 1) % 60;
+ } else {
+ sample = TOTAL_AUDIO_SAMPLES;
+ }
+ if (!wantedLevel) {
+ if (gSpecialSuspectLastSeenReport) {
+ gSpecialSuspectLastSeenReport = 0;
+ } else if (((sample >= SFX_POLICE_RADIO_MESSAGE_NOISE_1) && (sample <= SFX_POLICE_RADIO_MESSAGE_NOISE_3)) || sample == TOTAL_AUDIO_SAMPLES) {
+ bChannelOpen = false;
+ processed = true;
+ }
+ }
+ if (sample == TOTAL_AUDIO_SAMPLES) {
+ if (!processed) cWait = 30;
+ } else {
+ SampleManager.InitialiseChannel(policeChannel, sample, 0);
+ switch (sample) {
+ case SFX_POLICE_RADIO_MESSAGE_NOISE_1:
+ case SFX_POLICE_RADIO_MESSAGE_NOISE_2:
+ case SFX_POLICE_RADIO_MESSAGE_NOISE_3:
+ freq = m_anRandomTable[4] % 2000 + 10025;
+ bChannelOpen = bChannelOpen == false;
+ break;
+ default: freq = SampleManager.GetSampleBaseFrequency(sample); break;
+ }
+ PoliceChannelFreq = freq;
+ SampleManager.SetChannelFrequency(policeChannel, freq);
+ SampleManager.SetChannelVolume(policeChannel, 100);
+ SampleManager.SetChannelPan(policeChannel, 63);
+ SampleManager.SetChannelLoopCount(policeChannel, 1);
+ SampleManager.SetChannelLoopPoints(policeChannel, 0, -1);
+ SampleManager.StartChannel(policeChannel);
+ }
+ if (processed) ResetPoliceRadio();
+ }
+ }
+}
+
+bool
+cAudioManager::SetupCrimeReport()
+{
+ int16 audioZoneId;
+ CZone *zone;
+ float rangeX;
+ float rangeY;
+ float halfX;
+ float halfY;
+ float quarterX;
+ float quarterY;
+ int i;
+ int32 sampleIndex;
+ bool processed = false;
+
+ if (MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE) return false;
+
+ if (60 - m_sPoliceRadioQueue.policeChannelTimer <= 9) {
+ AgeCrimes();
+ return true;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
+ if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) return false;
+ audioZoneId = CTheZones::FindAudioZone(&m_sPoliceRadioQueue.crimes[i].position);
+ if (audioZoneId >= 0 && audioZoneId < NUMAUDIOZONES) {
+ zone = &CTheZones::ZoneArray[CTheZones::AudioZoneArray[audioZoneId]];
+ for (int j = 0; j < NUMAUDIOZONES; j++) {
+ if (strcmp(zone->name, ZoneSfx[j].m_aName) == 0) {
+ sampleIndex = ZoneSfx[j].m_nSampleIndex;
+ m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_WEVE_GOT);
+ m_sPoliceRadioQueue.Add(m_anRandomTable[1] % 2 + SFX_A_10_1);
+ switch (m_sPoliceRadioQueue.crimes[i].type) {
+ case CRIME_PED_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED; break;
+ case CRIME_COP_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP; break;
+ case CRIME_VEHICLE_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break;
+ case CRIME_DESTROYED_CESSNA: m_sPoliceRadioQueue.crimes[i].type = CRIME_SHOOT_HELI; break;
+ default: break;
+ }
+ m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1 - 1);
+ m_sPoliceRadioQueue.Add(SFX_IN);
+ if (sampleIndex == SFX_POLICE_RADIO_SHORESIDE_VALE &&
+ (strcmp(zone->name, SubZo2Label) == 0 || strcmp(zone->name, SubZo3Label) == 0)) {
+ m_sPoliceRadioQueue.Add(SFX_NORTH);
+ m_sPoliceRadioQueue.Add(SFX_EAST);
+ } else {
+ rangeX = zone->maxx - zone->minx;
+ rangeY = zone->maxy - zone->miny;
+ halfX = 0.5f * rangeX + zone->minx;
+ halfY = 0.5f * rangeY + zone->miny;
+ quarterX = 0.25f * rangeX;
+ quarterY = 0.25f * rangeY;
+
+ if (m_sPoliceRadioQueue.crimes[i].position.y > halfY + quarterY) {
+ m_sPoliceRadioQueue.Add(SFX_NORTH);
+ processed = true;
+ } else if (m_sPoliceRadioQueue.crimes[i].position.y < halfY - quarterY) {
+ m_sPoliceRadioQueue.Add(SFX_SOUTH);
+ processed = true;
+ }
+
+ if (m_sPoliceRadioQueue.crimes[i].position.x > halfX + quarterX)
+ m_sPoliceRadioQueue.Add(SFX_EAST);
+ else if (m_sPoliceRadioQueue.crimes[i].position.x < halfX - quarterX)
+ m_sPoliceRadioQueue.Add(SFX_WEST);
+ else if (!processed)
+ m_sPoliceRadioQueue.Add(SFX_CENTRAL);
+
+ m_sPoliceRadioQueue.Add(sampleIndex);
+ m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ }
+ break;
+ }
+ }
+ }
+ m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
+ AgeCrimes();
+ return true;
+}
+
+void
+cAudioManager::SetupSuspectLastSeenReport()
+{
+ CVehicle *veh;
+ uint8 color1;
+ int32 main_color;
+ int32 sample;
+
+ int32 color_pre_modifier;
+ int32 color_post_modifier;
+
+ const int32 gCarColourTable[][3] = {
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLACK, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_WHITE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+#else
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+#endif
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+#else
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+#endif
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+#else
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+#endif
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+#else
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+#endif
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+#else
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+#endif
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_BLUE},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+#else
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+#endif
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_GREY},
+#else
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+#endif
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+#else
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+#endif
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+#ifdef FIX_BUGS
+ {SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+#else
+ {TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
+#endif
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
+ {SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}
+ };
+
+ if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
+ veh = FindPlayerVehicle();
+ if (veh != nil) {
+ if (60 - m_sPoliceRadioQueue.policeChannelTimer > 9) {
+ color1 = veh->m_currentColour1;
+ if (color1 >= ARRAY_SIZE(gCarColourTable)) {
+ debug("\n *** UNKNOWN CAR COLOUR %d *** ", color1);
+ } else {
+ main_color = gCarColourTable[color1][1];
+ color_pre_modifier = gCarColourTable[color1][0];
+ color_post_modifier = gCarColourTable[color1][2];
+ switch (veh->m_modelIndex) {
+#ifdef FIX_BUGS
+ case MI_COLUMB:
+ main_color = SFX_POLICE_RADIO_BLUE;
+ color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES;
+#endif
+ case MI_LANDSTAL:
+ case MI_BLISTA: sample = SFX_POLICE_RADIO_CRUISER; break;
+#ifdef FIX_BUGS
+ case MI_YARDIE:
+ color_pre_modifier = TOTAL_AUDIO_SAMPLES;
+ main_color = SFX_POLICE_RADIO_RED;
+ color_post_modifier = SFX_POLICE_RADIO_YELLOW;
+ sample = SFX_POLICE_RADIO_CONVERTIBLE; break;
+ case MI_DIABLOS:
+ main_color = SFX_POLICE_RADIO_BLACK;
+#endif
+ case MI_IDAHO:
+ case MI_STALLION: sample = SFX_POLICE_RADIO_CONVERTIBLE; break;
+#ifdef FIX_BUGS
+ case MI_YAKUZA:
+ color_pre_modifier = TOTAL_AUDIO_SAMPLES;
+ main_color = SFX_POLICE_RADIO_SILVER;
+ color_post_modifier = SFX_POLICE_RADIO_RED;
+#endif
+ case MI_STINGER:
+ case MI_INFERNUS:
+ case MI_CHEETAH:
+ case MI_BANSHEE: sample = SFX_POLICE_RADIO_SPORTS_CAR; break;
+#ifdef FIX_BUGS
+ case MI_MAFIA:
+ color_pre_modifier = color_post_modifier = TOTAL_AUDIO_SAMPLES;
+ main_color = SFX_POLICE_RADIO_GREY;
+ case MI_KURUMA:
+#endif
+ case MI_PEREN:
+ case MI_SENTINEL:
+ case MI_FBICAR: sample = SFX_POLICE_RADIO_SALOON; break;
+ case MI_PATRIOT:
+ case MI_BOBCAT: sample = SFX_POLICE_RADIO_PICKUP; break;
+ case MI_FIRETRUCK: sample = SFX_POLICE_RADIO_FIRE_TRUCK; break;
+#ifdef FIX_BUGS
+ case MI_LINERUN:
+ case MI_FLATBED:
+#endif
+ case MI_TRASH:
+ case MI_BARRACKS: sample = SFX_POLICE_RADIO_TRUCK; break;
+ case MI_STRETCH: sample = SFX_POLICE_RADIO_LIMO; break;
+#ifdef FIX_BUGS
+ case MI_CORPSE:
+#endif
+ case MI_MANANA:
+ case MI_ESPERANT: sample = SFX_POLICE_RADIO_2_DOOR; break;
+#ifdef FIX_BUGS
+ case MI_HOODS:
+ color_pre_modifier = TOTAL_AUDIO_SAMPLES;
+ main_color = SFX_POLICE_RADIO_BLUE;
+ color_post_modifier = SFX_POLICE_RADIO_GREEN;
+ case MI_BELLYUP:
+ case MI_YANKEE:
+ case MI_TOYZ:
+ case MI_MRWONGS:
+ case MI_PANLANT:
+#endif
+ case MI_PONY:
+ case MI_MULE:
+ case MI_MOONBEAM:
+ case MI_ENFORCER:
+ case MI_SECURICA:
+ case MI_RUMPO: sample = SFX_POLICE_RADIO_VAN; break;
+ case MI_AMBULAN: sample = SFX_POLICE_RADIO_AMBULANCE; break;
+ case MI_TAXI:
+ case MI_CABBIE:
+ case MI_BORGNINE: sample = SFX_POLICE_RADIO_TAXI; break;
+ case MI_MRWHOOP:
+ sample = SFX_POLICE_RADIO_ICE_CREAM_VAN;
+ break;
+ case MI_BFINJECT: sample = SFX_POLICE_RADIO_BUGGY; break;
+ case MI_POLICE: sample = SFX_POLICE_RADIO_POLICE_CAR; break;
+#ifdef FIX_BUGS
+ case MI_SPEEDER:
+ case MI_REEFER:
+ case MI_GHOST:
+#endif
+ case MI_PREDATOR: sample = SFX_POLICE_RADIO_BOAT; break;
+ case MI_BUS:
+ case MI_COACH: sample = SFX_POLICE_RADIO_BUS; break;
+ case MI_RHINO:
+ sample = SFX_POLICE_RADIO_TANK;
+ main_color = TOTAL_AUDIO_SAMPLES;
+ color_post_modifier = TOTAL_AUDIO_SAMPLES;
+ break;
+ case MI_TRAIN:
+ sample = SFX_POLICE_RADIO_SUBWAY_CAR;
+ main_color = TOTAL_AUDIO_SAMPLES;
+ color_post_modifier = TOTAL_AUDIO_SAMPLES;
+
+ break;
+ default:
+ debug("\n *** UNKNOWN CAR MODEL INDEX %d *** ", veh->m_modelIndex);
+ return;
+ }
+ m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
+ if (m_anRandomTable[3] % 2)
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN);
+#ifdef FIX_BUGS
+ if (main_color == SFX_POLICE_RADIO_ORANGE && color_pre_modifier == TOTAL_AUDIO_SAMPLES)
+#else
+ if (main_color == SFX_POLICE_RADIO_ORANGE)
+#endif
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_AN);
+ else
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_IN_A);
+ if (color_pre_modifier != TOTAL_AUDIO_SAMPLES)
+ m_sPoliceRadioQueue.Add(color_pre_modifier);
+ if (main_color != TOTAL_AUDIO_SAMPLES)
+ m_sPoliceRadioQueue.Add(main_color);
+ if (color_post_modifier != TOTAL_AUDIO_SAMPLES)
+ m_sPoliceRadioQueue.Add(color_post_modifier);
+ m_sPoliceRadioQueue.Add(sample);
+ m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ }
+ }
+ } else if (60 - m_sPoliceRadioQueue.policeChannelTimer > 4) {
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_ON_FOOT);
+ m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ }
+ }
+}
+
+
+
+void
+cAudioManager::ReportCrime(int32 type, const CVector *pos)
+{
+ int32 lastCrime = ARRAY_SIZE(m_sPoliceRadioQueue.crimes);
+ if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 &&
+ (type > CRIME_NONE || type < NUM_CRIME_TYPES) && m_FrameCounter >= gMinTimeToNextReport[type]) {
+ for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
+ if (m_sPoliceRadioQueue.crimes[i].type) {
+ if (m_sPoliceRadioQueue.crimes[i].type == type) {
+ m_sPoliceRadioQueue.crimes[i].position = *pos;
+ m_sPoliceRadioQueue.crimes[i].timer = 0;
+ return;
+ }
+ } else {
+ lastCrime = i;
+ }
+ }
+
+ if (lastCrime < ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) {
+ m_sPoliceRadioQueue.crimes[lastCrime].type = type;
+ m_sPoliceRadioQueue.crimes[lastCrime].position = *pos;
+ m_sPoliceRadioQueue.crimes[lastCrime].timer = 0;
+ gMinTimeToNextReport[type] = m_FrameCounter + 500;
+ }
+ }
+}
+
+void
+cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
+{
+ int16 audioZone;
+ CZone *zone;
+ float rangeX;
+ float rangeY;
+ float halfX;
+ float halfY;
+ float quarterX;
+ float quarterY;
+ int32 sample;
+ bool processed = false;
+ CVector vec = CVector(x, y, z);
+
+ if (!m_bIsInitialised) return;
+
+ if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && 60 - m_sPoliceRadioQueue.policeChannelTimer > 9) {
+ audioZone = CTheZones::FindAudioZone(&vec);
+ if (audioZone >= 0 && audioZone < NUMAUDIOZONES) {
+ zone = &CTheZones::ZoneArray[CTheZones::AudioZoneArray[audioZone]];
+ for (int i = 0; i < NUMAUDIOZONES; i++) {
+ if (strcmp(zone->name, ZoneSfx[i].m_aName) == 0) {
+ sample = ZoneSfx[i].m_nSampleIndex;
+ m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
+ m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_LAST_SEEN);
+ m_sPoliceRadioQueue.Add(SFX_IN);
+ if (sample == SFX_POLICE_RADIO_SHORESIDE_VALE &&
+ (strcmp(zone->name, SubZo2Label) == 0 ||
+ strcmp(zone->name, SubZo3Label) == 0)) {
+ m_sPoliceRadioQueue.Add(SFX_NORTH);
+ m_sPoliceRadioQueue.Add(SFX_EAST);
+ } else {
+ rangeX = zone->maxx - zone->minx;
+ rangeY = zone->maxy - zone->miny;
+ halfX = 0.5f * rangeX + zone->minx;
+ halfY = 0.5f * rangeY + zone->miny;
+ quarterX = 0.25f * rangeX;
+ quarterY = 0.25f * rangeY;
+
+ if (vec.y > halfY + quarterY) {
+ m_sPoliceRadioQueue.Add(SFX_NORTH);
+ processed = true;
+ } else if (vec.y < halfY - quarterY) {
+ m_sPoliceRadioQueue.Add(SFX_SOUTH);
+ processed = true;
+ }
+
+ if (vec.x > halfX + quarterX)
+ m_sPoliceRadioQueue.Add(SFX_EAST);
+ else if (vec.x < halfX - quarterX)
+ m_sPoliceRadioQueue.Add(SFX_WEST);
+ else if (!processed)
+ m_sPoliceRadioQueue.Add(SFX_CENTRAL);
+ }
+ m_sPoliceRadioQueue.Add(sample);
+ m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
+ m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
+ gSpecialSuspectLastSeenReport = true;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void
+cAudioManager::AgeCrimes()
+{
+ for (uint8 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
+ if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) {
+ if (++m_sPoliceRadioQueue.crimes[i].timer > 1500) m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
+ }
+ }
+}
+
+STARTPATCHES
+InjectHook(0x580AF0, &cAudioManager::AgeCrimes, PATCH_JUMP);
+InjectHook(0x57F060, &cAudioManager::DoPoliceRadioCrackle, PATCH_JUMP);
+InjectHook(0x57F050, &cAudioManager::GetMissionScriptPoliceAudioPlayingStatus, PATCH_JUMP);
+InjectHook(0x57EEC0, &cAudioManager::InitialisePoliceRadio, PATCH_JUMP);
+InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP);
+InjectHook(0x580500, &cAudioManager::PlaySuspectLastSeen, PATCH_JUMP);
+InjectHook(0x5803D0, &cAudioManager::ReportCrime, PATCH_JUMP);
+InjectHook(0x57EFF0, &cAudioManager::ResetPoliceRadio, PATCH_JUMP);
+InjectHook(0x57F110, &cAudioManager::ServicePoliceRadio, PATCH_JUMP);
+InjectHook(0x57F1B0, &cAudioManager::ServicePoliceRadioChannel, PATCH_JUMP);
+InjectHook(0x57F020, &cAudioManager::SetMissionScriptPoliceAudio, PATCH_JUMP);
+InjectHook(0x57F5B0, &cAudioManager::SetupCrimeReport, PATCH_JUMP);
+InjectHook(0x57FCC0, &cAudioManager::SetupSuspectLastSeenReport, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/audio/PoliceRadio.h b/src/audio/PoliceRadio.h
index 4c7030f1..0f351f52 100644
--- a/src/audio/PoliceRadio.h
+++ b/src/audio/PoliceRadio.h
@@ -1,46 +1,46 @@
-#pragma once
-
-#include "Wanted.h"
-
-struct cAMCrime {
- int32 type;
- CVector position;
- uint16 timer;
-
- cAMCrime()
- {
- type = CRIME_NONE;
- position = CVector(0.0f, 0.0f, 0.0f);
- timer = 0;
- }
-};
-
-static_assert(sizeof(cAMCrime) == 20, "cAMCrime: error ");
-
-class cPoliceRadioQueue
-{
-public:
- int32 crimesSamples[60];
- uint8 policeChannelTimer;
- uint8 policeChannelTimerSeconds;
- uint8 policeChannelCounterSeconds;
- cAMCrime crimes[10];
-
- cPoliceRadioQueue()
- {
- policeChannelTimerSeconds = 0;
- policeChannelCounterSeconds = 0;
- policeChannelTimer = 0;
- }
-
- void Add(uint32 sample)
- {
- if (policeChannelTimer != 60) {
- crimesSamples[policeChannelTimerSeconds] = sample;
- policeChannelTimer++;
- policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
- }
- }
-};
-
+#pragma once
+
+#include "Wanted.h"
+
+struct cAMCrime {
+ int32 type;
+ CVector position;
+ uint16 timer;
+
+ cAMCrime()
+ {
+ type = CRIME_NONE;
+ position = CVector(0.0f, 0.0f, 0.0f);
+ timer = 0;
+ }
+};
+
+static_assert(sizeof(cAMCrime) == 20, "cAMCrime: error ");
+
+class cPoliceRadioQueue
+{
+public:
+ int32 crimesSamples[60];
+ uint8 policeChannelTimer;
+ uint8 policeChannelTimerSeconds;
+ uint8 policeChannelCounterSeconds;
+ cAMCrime crimes[10];
+
+ cPoliceRadioQueue()
+ {
+ policeChannelTimerSeconds = 0;
+ policeChannelCounterSeconds = 0;
+ policeChannelTimer = 0;
+ }
+
+ void Add(uint32 sample)
+ {
+ if (policeChannelTimer != 60) {
+ crimesSamples[policeChannelTimerSeconds] = sample;
+ policeChannelTimer++;
+ policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
+ }
+ }
+};
+
static_assert(sizeof(cPoliceRadioQueue) == 444, "cPoliceRadioQueue: error "); \ No newline at end of file
diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp
index 70099291..b5bca21d 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -12,17 +12,17 @@ void CAutoPilot::ModifySpeed(float speed)
float positionBetweenNodes = (float)(CTimer::GetTimeInMilliseconds() - m_nTimeEnteredCurve) / m_nTimeToSpendOnCurrentCurve;
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[m_nNextPathNodeInfo];
- float currentPathLinkForwardX = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dirX;
- float currentPathLinkForwardY = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dirY;
- float nextPathLinkForwardX = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dirX;
- float nextPathLinkForwardY = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dirY;
+ float currentPathLinkForwardX = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dir.x;
+ float currentPathLinkForwardY = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dir.y;
+ float nextPathLinkForwardX = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dir.x;
+ float nextPathLinkForwardY = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dir.y;
CVector positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurrentLink->posY - ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurrentLink->pos.x + ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurrentLink->pos.y - ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
&positionOnCurrentLinkIncludingLane,
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index 3174a253..264f1f3f 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -90,7 +90,7 @@ uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(ui
void
CCarCtrl::GenerateRandomCars()
{
- if (CCutsceneMgr::IsCutsceneProcessing())
+ if (CCutsceneMgr::IsRunning())
return;
if (NumRandomCars < 30){
if (CountDownToCarsAtStart == 0){
@@ -393,25 +393,25 @@ CCarCtrl::GenerateOneRandomCar()
pCar->GetRight() = CVector(forwardY, -forwardX, 0.0f);
pCar->GetUp() = CVector(0.0f, 0.0f, 1.0f);
- float currentPathLinkForwardX = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dirX;
- float currentPathLinkForwardY = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dirY;
- float nextPathLinkForwardX = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dirX;
- float nextPathLinkForwardY = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dirY;
+ float currentPathLinkForwardX = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dir.x;
+ float currentPathLinkForwardY = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dir.y;
+ float nextPathLinkForwardX = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dir.x;
+ float nextPathLinkForwardY = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dir.y;
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo];
CVector positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurrentLink->posY - ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurrentLink->pos.x + ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurrentLink->pos.y - ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
- float directionCurrentLinkX = pCurrentLink->dirX * pCar->AutoPilot.m_nCurrentDirection;
- float directionCurrentLinkY = pCurrentLink->dirY * pCar->AutoPilot.m_nCurrentDirection;
- float directionNextLinkX = pNextLink->dirX * pCar->AutoPilot.m_nNextDirection;
- float directionNextLinkY = pNextLink->dirY * pCar->AutoPilot.m_nNextDirection;
+ float directionCurrentLinkX = pCurrentLink->dir.x * pCar->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurrentLink->dir.y * pCar->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pCar->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * pCar->AutoPilot.m_nNextDirection;
/* We want to make a path between two links that may not have the same forward directions a curve. */
pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
&positionOnCurrentLinkIncludingLane,
@@ -763,17 +763,17 @@ CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
return;
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
- float currentPathLinkForwardX = pCurrentLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
- float currentPathLinkForwardY = pCurrentLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
- float nextPathLinkForwardX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- float nextPathLinkForwardY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ float currentPathLinkForwardX = pCurrentLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float currentPathLinkForwardY = pCurrentLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float nextPathLinkForwardX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float nextPathLinkForwardY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
CVector positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
CVector directionCurrentLink(currentPathLinkForwardX, currentPathLinkForwardY, 0.0f);
CVector directionNextLink(nextPathLinkForwardX, nextPathLinkForwardY, 0.0f);
@@ -1553,8 +1553,8 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nNextDirection = -1;
lanesOnNextNode = pNextLink->numRightLanes;
}
- float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirX;
- float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirX;
+ float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.x;
+ float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.x;
if (lanesOnNextNode >= 0){
if ((CGeneral::GetRandomNumber() & 0x600) == 0){
/* 25% chance vehicle will try to switch lane */
@@ -1574,17 +1574,17 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
if (pVehicle->AutoPilot.m_bStayInFastLane)
pVehicle->AutoPilot.m_nNextLane = 0;
CVector positionOnCurrentLinkIncludingLane(
- pCurLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH), /* ...what about Y? */
- pCurLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH), /* ...what about Y? */
+ pCurLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH),
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH),
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
- float directionCurrentLinkX = pCurLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
- float directionCurrentLinkY = pCurLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
- float directionNextLinkX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- float directionNextLinkY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ float directionCurrentLinkX = pCurLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
/* We want to make a path between two links that may not have the same forward directions a curve. */
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
&positionOnCurrentLinkIncludingLane,
@@ -1725,10 +1725,10 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
pVehicle->AutoPilot.m_nNextDirection = -1;
lanesOnNextNode = pNextLink->numRightLanes;
}
- float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirX;
- float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirY;
- float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirX;
- float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirY;
+ float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.x;
+ float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.y;
+ float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.x;
+ float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.y;
if (lanesOnNextNode >= 0) {
CVector2D dist = pNextPathNode->pos - pCurNode->pos;
if (dist.MagnitudeSqr() >= SQR(7.0f)){
@@ -1755,17 +1755,17 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
if (pVehicle->AutoPilot.m_bStayInFastLane)
pVehicle->AutoPilot.m_nNextLane = 0;
CVector positionOnCurrentLinkIncludingLane(
- pCurLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
- float directionCurrentLinkX = pCurLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
- float directionCurrentLinkY = pCurLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
- float directionNextLinkX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- float directionNextLinkY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ float directionCurrentLinkX = pCurLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
/* We want to make a path between two links that may not have the same forward directions a curve. */
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
&positionOnCurrentLinkIncludingLane,
@@ -1814,10 +1814,10 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nNextDirection = -1;
lanesOnNextNode = pNextLink->numRightLanes;
}
- float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirX;
- float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirY;
- float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirX;
- float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirY;
+ float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.x;
+ float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.y;
+ float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.x;
+ float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.y;
if (lanesOnNextNode >= 0) {
CVector2D dist = pNextPathNode->pos - pCurNode->pos;
if (dist.MagnitudeSqr() >= SQR(7.0f) && (CGeneral::GetRandomNumber() & 0x600) == 0) {
@@ -1835,17 +1835,17 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
if (pVehicle->AutoPilot.m_bStayInFastLane)
pVehicle->AutoPilot.m_nNextLane = 0;
CVector positionOnCurrentLinkIncludingLane(
- pCurLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
- float directionCurrentLinkX = pCurLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
- float directionCurrentLinkY = pCurLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
- float directionNextLinkX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- float directionNextLinkY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ float directionCurrentLinkX = pCurLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
/* We want to make a path between two links that may not have the same forward directions a curve. */
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
&positionOnCurrentLinkIncludingLane,
@@ -2192,16 +2192,16 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
forward.Normalise();
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
- CVector2D currentPathLinkForward(pCurrentLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection,
- pCurrentLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection);
- float nextPathLinkForwardX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- float nextPathLinkForwardY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ CVector2D currentPathLinkForward(pCurrentLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection,
+ pCurrentLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection);
+ float nextPathLinkForwardX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float nextPathLinkForwardY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
CVector2D positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
+ pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
CVector2D positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX);
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX);
CVector2D distanceToNextNode = (CVector2D)pVehicle->GetPosition() - positionOnCurrentLinkIncludingLane;
float scalarDistanceToNextNode = distanceToNextNode.Magnitude();
CVector2D distanceBetweenNodes = positionOnNextLinkIncludingLane - positionOnCurrentLinkIncludingLane;
@@ -2230,16 +2230,16 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
}
pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
scalarDistanceToNextNode = CVector2D(
- pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y - pVehicle->GetPosition().x,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x - pVehicle->GetPosition().y).Magnitude();
+ pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y - pVehicle->GetPosition().x,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x - pVehicle->GetPosition().y).Magnitude();
pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
- currentPathLinkForward.x = pCurrentLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
- currentPathLinkForward.y = pCurrentLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
- nextPathLinkForwardX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- nextPathLinkForwardY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ currentPathLinkForward.x = pCurrentLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ currentPathLinkForward.y = pCurrentLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ nextPathLinkForwardX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ nextPathLinkForwardY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
}
- positionOnCurrentLinkIncludingLane.x = pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y;
- positionOnCurrentLinkIncludingLane.y = pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x;
+ positionOnCurrentLinkIncludingLane.x = pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y;
+ positionOnCurrentLinkIncludingLane.y = pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x;
CVector2D projectedPosition = positionOnCurrentLinkIncludingLane - currentPathLinkForward * scalarDistanceToNextNode * 0.4f;
if (scalarDistanceToNextNode > DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN){
projectedPosition.x = positionOnCurrentLinkIncludingLane.x;
@@ -2281,8 +2281,8 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
CCarAI::CarHasReasonToStop(pVehicle);
speedStyleMultiplier = 0.0f;
}
- CVector2D trajectory(pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
+ CVector2D trajectory(pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
trajectory -= pVehicle->GetPosition();
float speedAngleMultiplier = FindSpeedMultiplier(
CGeneral::GetATanOfXY(trajectory.x, trajectory.y) - angleForward,
diff --git a/src/control/Cranes.cpp b/src/control/Cranes.cpp
deleted file mode 100644
index 4c1bf2c8..00000000
--- a/src/control/Cranes.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "common.h"
-#include "patcher.h"
-#include "Cranes.h"
-
-WRAPPER bool CCranes::IsThisCarBeingTargettedByAnyCrane(CVehicle*) { EAXJMP(0x5451E0); }
-WRAPPER bool CCranes::IsThisCarBeingCarriedByAnyCrane(CVehicle*) { EAXJMP(0x545190); }
-WRAPPER bool CCranes::IsThisCarPickedUp(float, float, CVehicle*) { EAXJMP(0x543940); }
-WRAPPER bool CCranes::HaveAllCarsBeenCollectedByMilitaryCrane() { EAXJMP(0x544BE0); }
-WRAPPER void CCranes::ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float) { EAXJMP(0x543650); }
-WRAPPER void CCranes::DeActivateCrane(float, float) { EAXJMP(0x543890); }
-WRAPPER void CCranes::InitCranes(void) { EAXJMP(0x543360); }
-WRAPPER void CCranes::UpdateCranes(void) { EAXJMP(0x5439E0); }
-WRAPPER void CCranes::Save(uint8*, uint32*) { EAXJMP(0x545210); }
-WRAPPER void CranesLoad(uint8*, uint32) { EAXJMP(0x5454d0); }
diff --git a/src/control/Cranes.h b/src/control/Cranes.h
deleted file mode 100644
index b40454ea..00000000
--- a/src/control/Cranes.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#pragma once
-#include "common.h"
-
-class CVehicle;
-class CEntity;
-class CObject;
-
-class CCrane
-{
-public:
- CEntity *m_pObject;
- CObject *m_pMagnet;
- int m_nAudioEntity;
- float m_fPickupX1;
- float m_fPickupX2;
- float m_fPickupY1;
- float m_fPickupY2;
- CVector m_vecDropoffTarget;
- float m_fDropoffHeading;
- float m_fPickupAngle;
- float m_fDropoffAngle;
- float m_fPickupDistance;
- float m_fDropoffDistance;
- float m_fAngle;
- float m_fDistance;
- float m_fHeight;
- float m_fHookOffset;
- float m_fHookHeight;
- CVector m_vecHookInitPos;
- CVector m_vecHookCurPos;
- float m_fHookVelocityX;
- float m_fHookVelocityY;
- CVehicle *m_pVehiclePickedUp;
- int m_nUpdateTimer;
- char m_bCraneActive;
- char m_bCraneStatus;
- char m_bVehiclesCollected;
- char m_bIsCrusher;
- char m_bIsMilitaryCrane;
- char field_125;
- char m_bNotMilitaryCrane;
- char gap_127[1];
-};
-
-static_assert(sizeof(CCrane) == 128, "CCrane: error");
-
-class CCranes
-{
-public:
- static bool IsThisCarBeingTargettedByAnyCrane(CVehicle*);
- static bool IsThisCarBeingCarriedByAnyCrane(CVehicle*);
- static bool IsThisCarPickedUp(float, float, CVehicle*);
- static bool HaveAllCarsBeenCollectedByMilitaryCrane();
- static void ActivateCrane(float, float, float, float, float, float, float, float, bool, bool, float, float);
- static void DeActivateCrane(float, float);
- static void InitCranes(void);
- static void UpdateCranes(void);
- static void Save(uint8*, uint32*);
-};
-
-void CranesLoad(uint8*, uint32); // is this really outside CCranes?
diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp
index 0abae7d6..8e0ea02d 100644
--- a/src/control/GameLogic.cpp
+++ b/src/control/GameLogic.cpp
@@ -1,294 +1,294 @@
#include "common.h"
#include "patcher.h"
-#include "GameLogic.h"
-#include "Clock.h"
-#include "Stats.h"
-#include "Pickups.h"
-#include "Timer.h"
-#include "Streaming.h"
-#include "CutsceneMgr.h"
-#include "World.h"
-#include "PlayerPed.h"
-#include "Wanted.h"
-#include "Camera.h"
-#include "Messages.h"
-#include "CarCtrl.h"
-#include "Restart.h"
-#include "Pad.h"
-#include "References.h"
-#include "Fire.h"
-#include "Script.h"
-#include "Garages.h"
-
-uint8 CGameLogic::ActivePlayers; // 0x95CD5E
-
-void
-CGameLogic::InitAtStartOfGame()
-{
- ActivePlayers = 1;
-}
-
-void
-CGameLogic::PassTime(uint32 time)
-{
- int32 minutes, hours, days;
-
- minutes = time + CClock::GetMinutes();
- hours = CClock::GetHours();
-
- for (; minutes >= 60; minutes -= 60)
- hours++;
-
- if (hours > 23) {
- days = CStats::DaysPassed;
- for (; hours >= 24; hours -= 24)
- days++;
- CStats::DaysPassed = days;
- }
-
- CClock::SetGameClock(hours, minutes);
- CPickups::PassTime(time * 1000);
-}
-
-void
-CGameLogic::SortOutStreamingAndMemory(const CVector &pos)
-{
- CTimer::Stop();
- CStreaming::FlushRequestList();
- CStreaming::DeleteRwObjectsAfterDeath(pos);
- CStreaming::RemoveUnusedModelsInLoadedList();
- CGame::DrasticTidyUpMemory(true);
- CStreaming::LoadScene(pos);
- CTimer::Update();
-}
-
-void
-CGameLogic::Update()
-{
- CVector vecRestartPos;
- float fRestartFloat;
-
- if (CCutsceneMgr::IsCutsceneProcessing()) return;
-
- CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus];
- switch (pPlayerInfo.m_WBState) {
- case WBSTATE_PLAYING:
- if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) {
- pPlayerInfo.m_pPed->ClearAdrenaline();
- pPlayerInfo.KillPlayer();
- }
- if (pPlayerInfo.m_pPed->m_nPedState == PED_ARRESTED) {
- pPlayerInfo.m_pPed->ClearAdrenaline();
- pPlayerInfo.ArrestPlayer();
- }
- break;
- case WBSTATE_WASTED:
- if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
- TheCamera.SetFadeColour(200, 200, 200);
- TheCamera.Fade(2.0f, FADE_OUT);
- }
-
- if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
- pPlayerInfo.m_WBState = WBSTATE_PLAYING;
- if (pPlayerInfo.m_bGetOutOfHospitalFree) {
- pPlayerInfo.m_bGetOutOfHospitalFree = false;
- } else {
- pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000);
- pPlayerInfo.m_pPed->ClearWeapons();
- }
-
- if (pPlayerInfo.m_pPed->bInVehicle) {
- CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
- if (pVehicle != nil) {
- if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
- pVehicle->pDriver = nil;
- if (pVehicle->m_status != STATUS_WRECKED)
- pVehicle->m_status = STATUS_ABANDONED;
- } else
- pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
- }
- }
- CEventList::Initialise();
- CMessages::ClearMessages();
- CCarCtrl::ClearInterestingVehicleList();
- CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
- CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
- CRestart::OverrideHospitalLevel = LEVEL_NONE;
- CRestart::OverridePoliceStationLevel = LEVEL_NONE;
- PassTime(720);
- RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
- SortOutStreamingAndMemory(pPlayerInfo.GetPos());
- TheCamera.m_fCamShakeForce = 0.0f;
- TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
- CPad::GetPad(0)->StopShaking(0);
- CReferences::RemoveReferencesToPlayer();
- CCarCtrl::CountDownToCarsAtStart = 2;
- CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
- if (CRestart::bFadeInAfterNextDeath) {
- TheCamera.SetFadeColour(200, 200, 200);
- TheCamera.Fade(4.0f, FADE_IN);
- } else CRestart::bFadeInAfterNextDeath = true;
- }
- break;
- case WBSTATE_BUSTED:
- if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
- TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(2.0f, FADE_OUT);
- }
- if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
- pPlayerInfo.m_WBState = WBSTATE_PLAYING;
- int takeMoney;
-
- switch (pPlayerInfo.m_pPed->m_pWanted->m_nWantedLevel) {
- case 0:
- case 1:
- takeMoney = 100;
- break;
- case 2:
- takeMoney = 200;
- break;
- case 3:
- takeMoney = 400;
- break;
- case 4:
- takeMoney = 600;
- break;
- case 5:
- takeMoney = 900;
- break;
- case 6:
- takeMoney = 1500;
- break;
- }
- if (pPlayerInfo.m_bGetOutOfJailFree) {
- pPlayerInfo.m_bGetOutOfJailFree = false;
- } else {
- pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney);
- pPlayerInfo.m_pPed->ClearWeapons();
- }
-
- if (pPlayerInfo.m_pPed->bInVehicle) {
- CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
- if (pVehicle != nil) {
- if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
- pVehicle->pDriver = nil;
- if (pVehicle->m_status != STATUS_WRECKED)
- pVehicle->m_status = STATUS_ABANDONED;
- }
- else
- pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
- }
- }
- CEventList::Initialise();
- CMessages::ClearMessages();
- CCarCtrl::ClearInterestingVehicleList();
- CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
- CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
- CRestart::OverrideHospitalLevel = LEVEL_NONE;
- CRestart::OverridePoliceStationLevel = LEVEL_NONE;
- PassTime(720);
- RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
- pPlayerInfo.m_pPed->ClearWeapons();
- SortOutStreamingAndMemory(pPlayerInfo.GetPos());
- TheCamera.m_fCamShakeForce = 0.0f;
- TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
- CPad::GetPad(0)->StopShaking(0);
- CReferences::RemoveReferencesToPlayer();
- CCarCtrl::CountDownToCarsAtStart = 2;
- CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
- if (CRestart::bFadeInAfterNextArrest) {
- TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(4.0f, FADE_IN);
- } else CRestart::bFadeInAfterNextArrest = true;
- }
- break;
- case WBSTATE_FAILED_CRITICAL_MISSION:
- if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) {
- TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(2.0f, FADE_OUT);
- }
- if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
- pPlayerInfo.m_WBState = WBSTATE_PLAYING;
- if (pPlayerInfo.m_pPed->bInVehicle) {
- CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
- if (pVehicle != nil) {
- if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
- pVehicle->pDriver = nil;
- if (pVehicle->m_status != STATUS_WRECKED)
- pVehicle->m_status = STATUS_ABANDONED;
- } else
- pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
- }
- }
- CEventList::Initialise();
- CMessages::ClearMessages();
- CCarCtrl::ClearInterestingVehicleList();
- CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
- CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
- CRestart::OverridePoliceStationLevel = LEVEL_NONE;
- CRestart::OverrideHospitalLevel = LEVEL_NONE;
- RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
- SortOutStreamingAndMemory(pPlayerInfo.GetPos());
- TheCamera.m_fCamShakeForce = 0.0f;
- TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
- CPad::GetPad(0)->StopShaking(0);
- CReferences::RemoveReferencesToPlayer();
- CCarCtrl::CountDownToCarsAtStart = 2;
- CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
- TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(4.0f, FADE_IN);
- }
- break;
- case 4:
- return;
- }
-}
-
-void
-CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle)
-{
- pPlayerPed->m_fHealth = 100.0f;
- pPlayerPed->m_fArmour = 0.0f;
- pPlayerPed->bIsVisible = true;
- pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
- pPlayerPed->bDoBloodyFootprints = false;
- pPlayerPed->ClearAdrenaline();
- pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
- if (pPlayerPed->m_pFire)
- pPlayerPed->m_pFire->Extinguish();
- pPlayerPed->bInVehicle = false;
- pPlayerPed->m_pMyVehicle = nil;
- pPlayerPed->m_pVehicleAnim = nil;
- pPlayerPed->m_pWanted->Reset();
- pPlayerPed->RestartNonPartialAnims();
- pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false);
- pPlayerPed->bRemoveFromWorld = false;
- pPlayerPed->ClearWeaponTarget();
- pPlayerPed->SetInitialState();
- CCarCtrl::ClearInterestingVehicleList();
-
- pos.z += 1.0f;
- pPlayerPed->Teleport(pos);
- pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f));
-
- pPlayerPed->m_fRotationCur = DEGTORAD(angle);
- pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur;
- pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur);
- CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed);
- CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
- pPlayerPed->RestoreHeadingRate();
- TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
- CReferences::RemoveReferencesToPlayer();
- CGarages::PlayerArrestedOrDied();
- CStats::CheckPointReachedUnsuccessfully();
- CWorld::Remove(pPlayerPed);
- CWorld::Add(pPlayerPed);
-}
-
+#include "GameLogic.h"
+#include "Clock.h"
+#include "Stats.h"
+#include "Pickups.h"
+#include "Timer.h"
+#include "Streaming.h"
+#include "CutsceneMgr.h"
+#include "World.h"
+#include "PlayerPed.h"
+#include "Wanted.h"
+#include "Camera.h"
+#include "Messages.h"
+#include "CarCtrl.h"
+#include "Restart.h"
+#include "Pad.h"
+#include "References.h"
+#include "Fire.h"
+#include "Script.h"
+#include "Garages.h"
+
+uint8 CGameLogic::ActivePlayers; // 0x95CD5E
+
+void
+CGameLogic::InitAtStartOfGame()
+{
+ ActivePlayers = 1;
+}
+
+void
+CGameLogic::PassTime(uint32 time)
+{
+ int32 minutes, hours, days;
+
+ minutes = time + CClock::GetMinutes();
+ hours = CClock::GetHours();
+
+ for (; minutes >= 60; minutes -= 60)
+ hours++;
+
+ if (hours > 23) {
+ days = CStats::DaysPassed;
+ for (; hours >= 24; hours -= 24)
+ days++;
+ CStats::DaysPassed = days;
+ }
+
+ CClock::SetGameClock(hours, minutes);
+ CPickups::PassTime(time * 1000);
+}
+
+void
+CGameLogic::SortOutStreamingAndMemory(const CVector &pos)
+{
+ CTimer::Stop();
+ CStreaming::FlushRequestList();
+ CStreaming::DeleteRwObjectsAfterDeath(pos);
+ CStreaming::RemoveUnusedModelsInLoadedList();
+ CGame::DrasticTidyUpMemory(true);
+ CStreaming::LoadScene(pos);
+ CTimer::Update();
+}
+
+void
+CGameLogic::Update()
+{
+ CVector vecRestartPos;
+ float fRestartFloat;
+
+ if (CCutsceneMgr::IsCutsceneProcessing()) return;
+
+ CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus];
+ switch (pPlayerInfo.m_WBState) {
+ case WBSTATE_PLAYING:
+ if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) {
+ pPlayerInfo.m_pPed->ClearAdrenaline();
+ pPlayerInfo.KillPlayer();
+ }
+ if (pPlayerInfo.m_pPed->m_nPedState == PED_ARRESTED) {
+ pPlayerInfo.m_pPed->ClearAdrenaline();
+ pPlayerInfo.ArrestPlayer();
+ }
+ break;
+ case WBSTATE_WASTED:
+ if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
+ TheCamera.SetFadeColour(200, 200, 200);
+ TheCamera.Fade(2.0f, FADE_OUT);
+ }
+
+ if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
+ pPlayerInfo.m_WBState = WBSTATE_PLAYING;
+ if (pPlayerInfo.m_bGetOutOfHospitalFree) {
+ pPlayerInfo.m_bGetOutOfHospitalFree = false;
+ } else {
+ pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000);
+ pPlayerInfo.m_pPed->ClearWeapons();
+ }
+
+ if (pPlayerInfo.m_pPed->bInVehicle) {
+ CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
+ if (pVehicle != nil) {
+ if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
+ pVehicle->pDriver = nil;
+ if (pVehicle->m_status != STATUS_WRECKED)
+ pVehicle->m_status = STATUS_ABANDONED;
+ } else
+ pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
+ }
+ }
+ CEventList::Initialise();
+ CMessages::ClearMessages();
+ CCarCtrl::ClearInterestingVehicleList();
+ CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
+ CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
+ CRestart::OverrideHospitalLevel = LEVEL_NONE;
+ CRestart::OverridePoliceStationLevel = LEVEL_NONE;
+ PassTime(720);
+ RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
+ SortOutStreamingAndMemory(pPlayerInfo.GetPos());
+ TheCamera.m_fCamShakeForce = 0.0f;
+ TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
+ CPad::GetPad(0)->StopShaking(0);
+ CReferences::RemoveReferencesToPlayer();
+ CCarCtrl::CountDownToCarsAtStart = 2;
+ CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
+ if (CRestart::bFadeInAfterNextDeath) {
+ TheCamera.SetFadeColour(200, 200, 200);
+ TheCamera.Fade(4.0f, FADE_IN);
+ } else CRestart::bFadeInAfterNextDeath = true;
+ }
+ break;
+ case WBSTATE_BUSTED:
+ if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(2.0f, FADE_OUT);
+ }
+ if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
+ pPlayerInfo.m_WBState = WBSTATE_PLAYING;
+ int takeMoney;
+
+ switch (pPlayerInfo.m_pPed->m_pWanted->m_nWantedLevel) {
+ case 0:
+ case 1:
+ takeMoney = 100;
+ break;
+ case 2:
+ takeMoney = 200;
+ break;
+ case 3:
+ takeMoney = 400;
+ break;
+ case 4:
+ takeMoney = 600;
+ break;
+ case 5:
+ takeMoney = 900;
+ break;
+ case 6:
+ takeMoney = 1500;
+ break;
+ }
+ if (pPlayerInfo.m_bGetOutOfJailFree) {
+ pPlayerInfo.m_bGetOutOfJailFree = false;
+ } else {
+ pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney);
+ pPlayerInfo.m_pPed->ClearWeapons();
+ }
+
+ if (pPlayerInfo.m_pPed->bInVehicle) {
+ CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
+ if (pVehicle != nil) {
+ if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
+ pVehicle->pDriver = nil;
+ if (pVehicle->m_status != STATUS_WRECKED)
+ pVehicle->m_status = STATUS_ABANDONED;
+ }
+ else
+ pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
+ }
+ }
+ CEventList::Initialise();
+ CMessages::ClearMessages();
+ CCarCtrl::ClearInterestingVehicleList();
+ CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
+ CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
+ CRestart::OverrideHospitalLevel = LEVEL_NONE;
+ CRestart::OverridePoliceStationLevel = LEVEL_NONE;
+ PassTime(720);
+ RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
+ pPlayerInfo.m_pPed->ClearWeapons();
+ SortOutStreamingAndMemory(pPlayerInfo.GetPos());
+ TheCamera.m_fCamShakeForce = 0.0f;
+ TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
+ CPad::GetPad(0)->StopShaking(0);
+ CReferences::RemoveReferencesToPlayer();
+ CCarCtrl::CountDownToCarsAtStart = 2;
+ CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
+ if (CRestart::bFadeInAfterNextArrest) {
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(4.0f, FADE_IN);
+ } else CRestart::bFadeInAfterNextArrest = true;
+ }
+ break;
+ case WBSTATE_FAILED_CRITICAL_MISSION:
+ if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) {
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(2.0f, FADE_OUT);
+ }
+ if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
+ pPlayerInfo.m_WBState = WBSTATE_PLAYING;
+ if (pPlayerInfo.m_pPed->bInVehicle) {
+ CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;
+ if (pVehicle != nil) {
+ if (pVehicle->pDriver == pPlayerInfo.m_pPed) {
+ pVehicle->pDriver = nil;
+ if (pVehicle->m_status != STATUS_WRECKED)
+ pVehicle->m_status = STATUS_ABANDONED;
+ } else
+ pVehicle->RemovePassenger(pPlayerInfo.m_pPed);
+ }
+ }
+ CEventList::Initialise();
+ CMessages::ClearMessages();
+ CCarCtrl::ClearInterestingVehicleList();
+ CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
+ CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
+ CRestart::OverridePoliceStationLevel = LEVEL_NONE;
+ CRestart::OverrideHospitalLevel = LEVEL_NONE;
+ RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat);
+ SortOutStreamingAndMemory(pPlayerInfo.GetPos());
+ TheCamera.m_fCamShakeForce = 0.0f;
+ TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
+ CPad::GetPad(0)->StopShaking(0);
+ CReferences::RemoveReferencesToPlayer();
+ CCarCtrl::CountDownToCarsAtStart = 2;
+ CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED;
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(4.0f, FADE_IN);
+ }
+ break;
+ case 4:
+ return;
+ }
+}
+
+void
+CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle)
+{
+ pPlayerPed->m_fHealth = 100.0f;
+ pPlayerPed->m_fArmour = 0.0f;
+ pPlayerPed->bIsVisible = true;
+ pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0;
+ pPlayerPed->bDoBloodyFootprints = false;
+ pPlayerPed->ClearAdrenaline();
+ pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina;
+ if (pPlayerPed->m_pFire)
+ pPlayerPed->m_pFire->Extinguish();
+ pPlayerPed->bInVehicle = false;
+ pPlayerPed->m_pMyVehicle = nil;
+ pPlayerPed->m_pVehicleAnim = nil;
+ pPlayerPed->m_pWanted->Reset();
+ pPlayerPed->RestartNonPartialAnims();
+ pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false);
+ pPlayerPed->bRemoveFromWorld = false;
+ pPlayerPed->ClearWeaponTarget();
+ pPlayerPed->SetInitialState();
+ CCarCtrl::ClearInterestingVehicleList();
+
+ pos.z += 1.0f;
+ pPlayerPed->Teleport(pos);
+ pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f));
+
+ pPlayerPed->m_fRotationCur = DEGTORAD(angle);
+ pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur;
+ pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur);
+ CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed);
+ CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
+ pPlayerPed->RestoreHeadingRate();
+ TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
+ CReferences::RemoveReferencesToPlayer();
+ CGarages::PlayerArrestedOrDied();
+ CStats::CheckPointReachedUnsuccessfully();
+ CWorld::Remove(pPlayerPed);
+ CWorld::Add(pPlayerPed);
+}
+
STARTPATCHES
InjectHook(0x4213F0, &CGameLogic::InitAtStartOfGame, PATCH_JUMP);
InjectHook(0x421C00, &CGameLogic::PassTime, PATCH_JUMP);
InjectHook(0x421A20, &CGameLogic::SortOutStreamingAndMemory, PATCH_JUMP);
InjectHook(0x421400, &CGameLogic::Update, PATCH_JUMP);
- InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP);
+ InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/control/GameLogic.h b/src/control/GameLogic.h
index db626558..43e244a3 100644
--- a/src/control/GameLogic.h
+++ b/src/control/GameLogic.h
@@ -1,13 +1,13 @@
-#pragma once
-
-class CGameLogic
-{
-public:
- static void InitAtStartOfGame();
- static void PassTime(uint32 time);
- static void SortOutStreamingAndMemory(const CVector &pos);
- static void Update();
- static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle);
-
- static uint8 ActivePlayers;
+#pragma once
+
+class CGameLogic
+{
+public:
+ static void InitAtStartOfGame();
+ static void PassTime(uint32 time);
+ static void SortOutStreamingAndMemory(const CVector &pos);
+ static void Update();
+ static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle);
+
+ static uint8 ActivePlayers;
}; \ No newline at end of file
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 6a91da76..e4b2aee3 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -126,7 +126,6 @@ uint32& CGarages::MessageEndTime = *(uint32*)0x8F597C;
uint32& CGarages::NumGarages = *(uint32*)0x8F29F4;
bool& CGarages::PlayerInGarage = *(bool*)0x95CD83;
int32& CGarages::PoliceCarsCollected = *(int32*)0x941444;
-uint32& CGarages::GarageToBeTidied = *(uint32*)0x623570;
CStoredCar(&CGarages::aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA210;
CStoredCar(&CGarages::aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA300;
CStoredCar(&CGarages::aCarsInSafeHouse3)[NUM_GARAGE_STORED_CARS] = *(CStoredCar(*)[NUM_GARAGE_STORED_CARS]) * (uintptr*)0x6FA3F0;
@@ -322,6 +321,9 @@ void CGarage::Update()
}
}
}
+ break;
+ default:
+ break;
}
}
if (m_bDeactivated && m_eGarageState == GS_FULLYCLOSED)
@@ -408,11 +410,11 @@ void CGarage::Update()
if (!((CAutomobile*)(FindPlayerVehicle()))->bFixedColour) {
uint8 colour1, colour2;
uint16 attempt;
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(FindPlayerVehicle()->GetModelIndex()))->ChooseVehicleColour(colour1, colour2);
+ FindPlayerVehicle()->GetModelInfo()->ChooseVehicleColour(colour1, colour2);
for (attempt = 0; attempt < 10; attempt++) {
if (colour1 != FindPlayerVehicle()->m_currentColour1 || colour2 != FindPlayerVehicle()->m_currentColour2)
break;
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(FindPlayerVehicle()->GetModelIndex()))->ChooseVehicleColour(colour1, colour2);
+ FindPlayerVehicle()->GetModelInfo()->ChooseVehicleColour(colour1, colour2);
}
bChangedColour = (attempt < 10);
FindPlayerVehicle()->m_currentColour1 = colour1;
@@ -490,7 +492,7 @@ void CGarage::Update()
break;
}
if (!CGarages::BombsAreFree && CWorld::Players[CWorld::PlayerInFocus].m_nMoney < BOMB_PRICE) {
- CGarages::TriggerMessage("GA_4", -1, 4000, -1); // "Car bombs are $1000 each"
+ CGarages::TriggerMessage("GA_4", -1, 4000, -1); // "Car bombs are $1000 each" - weird that the price is hardcoded in message
m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayFrontEndSound(SOUND_GARAGE_NO_MONEY, 1);
break;
@@ -524,7 +526,7 @@ void CGarage::Update()
((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed();
if (m_eGarageType == GARAGE_BOMBSHOP3)
CGarages::GivePlayerDetonator();
- CStats::KgOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB;
+ CStats::KgsOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB;
}
switch (m_eGarageType) {
case GARAGE_BOMBSHOP1:
@@ -1184,7 +1186,7 @@ bool CGarage::IsEntityEntirelyInside(CEntity * pEntity)
if (pEntity->GetPosition().x < m_fX1 || pEntity->GetPosition().x > m_fX2 ||
pEntity->GetPosition().y < m_fY1 || pEntity->GetPosition().y > m_fY2)
return false;
- CColModel* pColModel = CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -1201,7 +1203,7 @@ bool CGarage::IsEntityEntirelyInside3D(CEntity * pEntity, float fMargin)
pEntity->GetPosition().y < m_fY1 - fMargin || pEntity->GetPosition().y > m_fY2 + fMargin ||
pEntity->GetPosition().z < m_fZ1 - fMargin || pEntity->GetPosition().z > m_fZ2 + fMargin)
return false;
- CColModel* pColModel = CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -1218,7 +1220,7 @@ bool CGarage::IsEntityEntirelyOutside(CEntity * pEntity, float fMargin)
if (pEntity->GetPosition().x > m_fX1 - fMargin && pEntity->GetPosition().x < m_fX2 + fMargin &&
pEntity->GetPosition().y > m_fY1 - fMargin && pEntity->GetPosition().y < m_fY2 + fMargin)
return false;
- CColModel* pColModel = CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -1250,7 +1252,7 @@ bool CGarage::IsEntityTouching3D(CEntity * pEntity)
pEntity->GetPosition().y - radius < m_fY1 || pEntity->GetPosition().y + radius > m_fY2 ||
pEntity->GetPosition().z - radius < m_fZ1 || pEntity->GetPosition().z + radius > m_fZ2)
return false;
- CColModel* pColModel = CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
radius = pColModel->spheres[i].radius;
@@ -1264,7 +1266,7 @@ bool CGarage::IsEntityTouching3D(CEntity * pEntity)
bool CGarage::EntityHasASphereWayOutsideGarage(CEntity * pEntity, float fMargin)
{
- CColModel* pColModel = CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pEntity->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -1285,7 +1287,7 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException)
continue;
if (!IsEntityTouching3D(pVehicle))
continue;
- CColModel* pColModel = CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pVehicle->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -1307,7 +1309,7 @@ bool CGarage::IsAnyOtherPedTouchingGarage(CPed * pException)
continue;
if (!IsEntityTouching3D(pPed))
continue;
- CColModel* pColModel = CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pException->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pPed->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -1329,7 +1331,7 @@ bool CGarage::IsAnyCarBlockingDoor()
continue;
if (!IsEntityTouching3D(pVehicle))
continue;
- CColModel* pColModel = CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pVehicle->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -1677,7 +1679,7 @@ float CGarage::CalcDistToGarageRectangleSquared(float X, float Y)
else
distX = 0.0f;
if (Y < m_fY1)
- distY = m_fY1 - X;
+ distY = m_fY1 - Y;
else if (Y > m_fY2)
distY = Y - m_fY2;
else
@@ -1698,8 +1700,8 @@ float CGarage::CalcSmallestDistToGarageDoorSquared(float X, float Y)
void CGarage::FindDoorsEntities()
{
- m_pDoor1 = false;
- m_pDoor2 = false;
+ m_pDoor1 = nil;
+ m_pDoor2 = nil;
int xstart = max(0, CWorld::GetSectorIndexX(m_fX1));
int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fX2));
int ystart = max(0, CWorld::GetSectorIndexY(m_fY1));
@@ -1992,7 +1994,7 @@ void CGarage::TidyUpGarageClose()
continue;
bool bRemove = false;
if (m_eGarageState != GS_FULLYCLOSED) {
- CColModel* pColModel = CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel();
+ CColModel* pColModel = pVehicle->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
@@ -2106,7 +2108,7 @@ void CGarages::CloseHideOutGaragesBeforeSave()
aGarages[i].m_eGarageType != GARAGE_HIDEOUT_THREE)
continue;
if (aGarages[i].m_eGarageState != GS_FULLYCLOSED &&
- aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE || !aGarages[i].IsAnyCarBlockingDoor()) {
+ (aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE || !aGarages[i].IsAnyCarBlockingDoor())) {
aGarages[i].m_eGarageState = GS_FULLYCLOSED;
switch (aGarages[i].m_eGarageType) {
case GARAGE_HIDEOUT_ONE:
@@ -2227,6 +2229,7 @@ void CGarages::SetAllDoorsBackToOriginalHeight()
void CGarages::Save(uint8 * buf, uint32 * size)
{
#ifdef FIX_GARAGE_SIZE
+ INITSAVEBUF
*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
#else
* size = 5484;
@@ -2248,6 +2251,9 @@ void CGarages::Save(uint8 * buf, uint32 * size)
}
for (int i = 0; i < NUM_GARAGES; i++)
WriteSaveBuf(buf, aGarages[i]);
+#ifdef FIX_GARAGE_SIZE
+ VALIDATESAVEBUF(*size);
+#endif
}
CStoredCar::CStoredCar(const CStoredCar & other)
@@ -2271,6 +2277,7 @@ CStoredCar::CStoredCar(const CStoredCar & other)
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));
#else
assert(size == 5484);
@@ -2303,6 +2310,9 @@ void CGarages::Load(uint8* buf, uint32 size)
else
aGarages[i].UpdateDoorsHeight();
}
+#ifdef FIX_GARAGE_SIZE
+ VALIDATESAVEBUF(size);
+#endif
}
bool
@@ -2345,8 +2355,7 @@ CGarages::IsModelIndexADoor(uint32 id)
STARTPATCHES
- InjectHook(0x426B20, CGarages::TriggerMessage, PATCH_JUMP); // CCrane::Update, CCrane::FindCarInSectorList
InjectHook(0x427AB0, CGarages::IsPointInAGarageCameraZone, PATCH_JUMP); // CCamera::CamControl
InjectHook(0x427BC0, CGarages::CameraShouldBeOutside, PATCH_JUMP); // CCamera::CamControl
InjectHook(0x428940, CGarages::Load, PATCH_JUMP); // GenericLoad
-ENDPATCHES \ No newline at end of file
+ENDPATCHES
diff --git a/src/control/Garages.h b/src/control/Garages.h
index e3864a48..26e7a89a 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -194,7 +194,6 @@ class CGarages
static uint32 &NumGarages;
static bool &PlayerInGarage;
static int32 &PoliceCarsCollected;
- static uint32 &GarageToBeTidied;
static CGarage(&aGarages)[NUM_GARAGES];
static CStoredCar(&aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS];
static CStoredCar(&aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS];
diff --git a/src/control/OnscreenTimer.h b/src/control/OnscreenTimer.h
index b1e0e622..fb139266 100644
--- a/src/control/OnscreenTimer.h
+++ b/src/control/OnscreenTimer.h
@@ -1,49 +1,49 @@
-#pragma once
-
-enum
-{
- COUNTER_DISPLAY_NUMBER,
- COUNTER_DISPLAY_BAR,
-};
-
-class COnscreenTimerEntry
-{
-public:
- uint32 m_nTimerOffset;
- uint32 m_nCounterOffset;
- char m_aTimerText[10];
- char m_aCounterText[10];
- uint16 m_nType;
- char m_bCounterBuffer[42];
- char m_bTimerBuffer[42];
- bool m_bTimerProcessed;
- bool m_bCounterProcessed;
-
- void Process();
- bool ProcessForDisplay();
-
- void ProcessForDisplayClock();
- void ProcessForDisplayCounter();
-};
-
-static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
-
-class COnscreenTimer
-{
-public:
- COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES];
- bool m_bProcessed;
- bool m_bDisabled;
-
- void Init();
- void Process();
- void ProcessForDisplay();
-
- void ClearCounter(uint32 offset);
- void ClearClock(uint32 offset);
-
- void AddCounter(uint32 offset, uint16 type, char* text);
- void AddClock(uint32 offset, char* text);
-};
-
+#pragma once
+
+enum
+{
+ COUNTER_DISPLAY_NUMBER,
+ COUNTER_DISPLAY_BAR,
+};
+
+class COnscreenTimerEntry
+{
+public:
+ uint32 m_nTimerOffset;
+ uint32 m_nCounterOffset;
+ char m_aTimerText[10];
+ char m_aCounterText[10];
+ uint16 m_nType;
+ char m_bCounterBuffer[42];
+ char m_bTimerBuffer[42];
+ bool m_bTimerProcessed;
+ bool m_bCounterProcessed;
+
+ void Process();
+ bool ProcessForDisplay();
+
+ void ProcessForDisplayClock();
+ void ProcessForDisplayCounter();
+};
+
+static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error");
+
+class COnscreenTimer
+{
+public:
+ COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES];
+ bool m_bProcessed;
+ bool m_bDisabled;
+
+ void Init();
+ void Process();
+ void ProcessForDisplay();
+
+ void ClearCounter(uint32 offset);
+ void ClearClock(uint32 offset);
+
+ void AddCounter(uint32 offset, uint16 type, char* text);
+ void AddClock(uint32 offset, char* text);
+};
+
static_assert(sizeof(COnscreenTimer) == 0x78, "COnscreenTimer: error"); \ No newline at end of file
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index 608a209a..61cd3d4e 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -5,8 +5,13 @@
#include "Camera.h"
#include "Vehicle.h"
#include "World.h"
+#include "Lines.h" // for debug
#include "PathFind.h"
+bool gbShowPedPaths;
+bool gbShowCarPaths;
+bool gbShowCarPathsLinks;
+
CPathFind &ThePaths = *(CPathFind*)0x8F6754;
WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
@@ -466,20 +471,20 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// IMPROVE: use a goto here
// Find existing car path link
for(k = 0; k < m_numCarPathLinks; k++){
- if(m_carPathLinks[k].dirX == tempnodes[j].dirX &&
- m_carPathLinks[k].dirY == tempnodes[j].dirY &&
- m_carPathLinks[k].posX == tempnodes[j].pos.x &&
- m_carPathLinks[k].posY == tempnodes[j].pos.y){
+ if(m_carPathLinks[k].dir.x == tempnodes[j].dirX &&
+ m_carPathLinks[k].dir.y == tempnodes[j].dirY &&
+ m_carPathLinks[k].pos.x == tempnodes[j].pos.x &&
+ m_carPathLinks[k].pos.y == tempnodes[j].pos.y){
m_carPathConnections[m_numConnections] = k;
k = m_numCarPathLinks;
}
}
// k is m_numCarPathLinks+1 if we found one
if(k == m_numCarPathLinks){
- m_carPathLinks[m_numCarPathLinks].dirX = tempnodes[j].dirX;
- m_carPathLinks[m_numCarPathLinks].dirY = tempnodes[j].dirY;
- m_carPathLinks[m_numCarPathLinks].posX = tempnodes[j].pos.x;
- m_carPathLinks[m_numCarPathLinks].posY = tempnodes[j].pos.y;
+ m_carPathLinks[m_numCarPathLinks].dir.x = tempnodes[j].dirX;
+ m_carPathLinks[m_numCarPathLinks].dir.y = tempnodes[j].dirY;
+ m_carPathLinks[m_numCarPathLinks].pos.x = tempnodes[j].pos.x;
+ m_carPathLinks[m_numCarPathLinks].pos.y = tempnodes[j].pos.y;
m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i;
m_carPathLinks[m_numCarPathLinks].numLeftLanes = tempnodes[j].numLeftLanes;
m_carPathLinks[m_numCarPathLinks].numRightLanes = tempnodes[j].numRightLanes;
@@ -529,20 +534,20 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// IMPROVE: use a goto here
// Find existing car path link
for(k = 0; k < m_numCarPathLinks; k++){
- if(m_carPathLinks[k].dirX == dx &&
- m_carPathLinks[k].dirY == dy &&
- m_carPathLinks[k].posX == posx &&
- m_carPathLinks[k].posY == posy){
+ if(m_carPathLinks[k].dir.x == dx &&
+ m_carPathLinks[k].dir.y == dy &&
+ m_carPathLinks[k].pos.x == posx &&
+ m_carPathLinks[k].pos.y == posy){
m_carPathConnections[m_numConnections] = k;
k = m_numCarPathLinks;
}
}
// k is m_numCarPathLinks+1 if we found one
if(k == m_numCarPathLinks){
- m_carPathLinks[m_numCarPathLinks].dirX = dx;
- m_carPathLinks[m_numCarPathLinks].dirY = dy;
- m_carPathLinks[m_numCarPathLinks].posX = posx;
- m_carPathLinks[m_numCarPathLinks].posY = posy;
+ m_carPathLinks[m_numCarPathLinks].dir.x = dx;
+ m_carPathLinks[m_numCarPathLinks].dir.y = dy;
+ m_carPathLinks[m_numCarPathLinks].pos.x = posx;
+ m_carPathLinks[m_numCarPathLinks].pos.y = posy;
m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i;
m_carPathLinks[m_numCarPathLinks].numLeftLanes = -1;
m_carPathLinks[m_numCarPathLinks].numRightLanes = -1;
@@ -760,8 +765,8 @@ CPathFind::SetLinksBridgeLights(float x1, float x2, float y1, float y2, bool ena
{
int i;
for(i = 0; i < m_numCarPathLinks; i++)
- if(x1 < m_carPathLinks[i].posX && m_carPathLinks[i].posX < x2 &&
- y1 < m_carPathLinks[i].posY && m_carPathLinks[i].posY < y2)
+ if(x1 < m_carPathLinks[i].pos.x && m_carPathLinks[i].pos.x < x2 &&
+ y1 < m_carPathLinks[i].pos.y && m_carPathLinks[i].pos.y < y2)
m_carPathLinks[i].bBridgeLights = enable;
}
@@ -1444,6 +1449,132 @@ CPathFind::Load(uint8 *buf, uint32 size)
m_pathNodes[i].bBetweenLevels = false;
}
+void
+CPathFind::DisplayPathData(void)
+{
+ // Not the function from mobm_carPathLinksile but my own!
+
+ int i, j, k;
+ // Draw 50 units around camera
+ CVector pos = TheCamera.GetPosition();
+ const float maxDist = 50.0f;
+
+ // Render car path nodes
+ if(gbShowCarPaths)
+ for(i = 0; i < m_numCarPathNodes; i++){
+ if((m_pathNodes[i].pos - pos).MagnitudeSqr() > SQR(maxDist))
+ continue;
+
+ CVector n1 = m_pathNodes[i].pos;
+ n1.z += 0.3f;
+
+ // Draw node itself
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n1.x, n1.y, n1.z + 1.0f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ for(j = 0; j < m_pathNodes[i].numLinks; j++){
+ k = m_connections[m_pathNodes[i].firstLink + j];
+ CVector n2 = m_pathNodes[k].pos;
+ n2.z += 0.3f;
+ // Draw links to neighbours
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n2.x, n2.y, n2.z,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+ }
+ }
+
+ // Render car path nodes
+ if(gbShowCarPathsLinks)
+ for(i = 0; i < m_numCarPathLinks; i++){
+ CVector2D n1_2d = m_carPathLinks[i].pos;
+ if((n1_2d - pos).MagnitudeSqr() > SQR(maxDist))
+ continue;
+
+ int ni = m_carPathLinks[i].pathNodeIndex;
+ CVector pn1 = m_pathNodes[ni].pos;
+ pn1.z += 0.3f;
+ CVector n1(n1_2d.x, n1_2d.y, pn1.z);
+ n1.z += 0.3f;
+
+ // Draw car node itself
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n1.x, n1.y, n1.z + 1.0f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z + 0.5f,
+ n1.x+m_carPathLinks[i].dir.x, n1.y+m_carPathLinks[i].dir.y, n1.z + 0.5f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ // Draw connection to car path node
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ pn1.x, pn1.y, pn1.z,
+ 0xFF0000FF, 0xFFFFFFFF);
+
+ // traffic light type
+ uint32 col = 0xFF;
+ if((m_carPathLinks[i].trafficLightType&0x7F) == 1)
+ col += 0xFF000000;
+ if((m_carPathLinks[i].trafficLightType&0x7F) == 2)
+ col += 0x00FF0000;
+ if(m_carPathLinks[i].trafficLightType & 0x80)
+ col += 0x0000FF00;
+ CLines::RenderLineWithClipping(n1.x+0.2f, n1.y, n1.z,
+ n1.x+0.2f, n1.y, n1.z + 1.0f,
+ col, col);
+
+ for(j = 0; j < m_pathNodes[ni].numLinks; j++){
+ k = m_carPathConnections[m_pathNodes[ni].firstLink + j];
+ CVector2D n2_2d = m_carPathLinks[k].pos;
+ int nk = m_carPathLinks[k].pathNodeIndex;
+ CVector pn2 = m_pathNodes[nk].pos;
+ pn2.z += 0.3f;
+ CVector n2(n2_2d.x, n2_2d.y, pn2.z);
+ n2.z += 0.3f;
+
+ // Draw links to neighbours
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n2.x, n2.y, n2.z,
+ 0xFF00FFFF, 0xFF00FFFF);
+ }
+ }
+
+ // Render ped path nodes
+ if(gbShowPedPaths)
+ for(i = m_numCarPathNodes; i < m_numPathNodes; i++){
+ if((m_pathNodes[i].pos - pos).MagnitudeSqr() > SQR(maxDist))
+ continue;
+
+ CVector n1 = m_pathNodes[i].pos;
+ n1.z += 0.3f;
+
+ // Draw node itself
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n1.x, n1.y, n1.z + 1.0f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ for(j = 0; j < m_pathNodes[i].numLinks; j++){
+ k = m_connections[m_pathNodes[i].firstLink + j];
+ CVector n2 = m_pathNodes[k].pos;
+ n2.z += 0.3f;
+ // Draw links to neighbours
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n2.x, n2.y, n2.z,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ // Draw connection flags
+ CVector mid = (n1+n2)/2.0f;
+ uint32 col = 0xFF;
+ if(m_connectionFlags[m_pathNodes[i].firstLink + j].bCrossesRoad)
+ col += 0x00FF0000;
+ if(m_connectionFlags[m_pathNodes[i].firstLink + j].bTrafficLight)
+ col += 0xFF000000;
+ CLines::RenderLineWithClipping(mid.x, mid.y, mid.z,
+ mid.x, mid.y, mid.z + 1.0f,
+ col, col);
+ }
+ }
+}
+
STARTPATCHES
InjectHook(0x4294A0, &CPathFind::Init, PATCH_JUMP);
InjectHook(0x42D580, &CPathFind::AllocatePathFindInfoMem, PATCH_JUMP);
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index c51cb7c7..81467cdf 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -84,10 +84,8 @@ union CConnectionFlags
struct CCarPathLink
{
- float posX;
- float posY;
- float dirX;
- float dirY;
+ CVector2D pos;
+ CVector2D dir;
int16 pathNodeIndex;
int8 numLeftLanes;
int8 numRightLanes;
@@ -208,7 +206,13 @@ public:
bool TestCoorsCloseness(CVector target, uint8 type, CVector start);
void Save(uint8 *buf, uint32 *size);
void Load(uint8 *buf, uint32 size);
+
+ void DisplayPathData(void);
};
static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error");
extern CPathFind &ThePaths;
+
+extern bool gbShowPedPaths;
+extern bool gbShowCarPaths;
+extern bool gbShowCarPathsLinks;
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index 3e3c2a48..eb561670 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -1,1049 +1,1452 @@
-#include "common.h"
-#include "patcher.h"
-#include "main.h"
-
-#include "Camera.h"
-#include "Coronas.h"
-#include "Darkel.h"
-#include "Entity.h"
-#include "Explosion.h"
-#include "Font.h"
-#include "Garages.h"
-#include "General.h"
-#include "ModelIndices.h"
-#include "Object.h"
-#include "Pad.h"
-#include "Pickups.h"
-#include "PlayerPed.h"
-#include "Wanted.h"
-#include "DMAudio.h"
-#include "Fire.h"
-#include "PointLights.h"
-#include "Pools.h"
-#ifdef FIX_BUGS
-#include "Replay.h"
-#endif
-#include "Script.h"
-#include "Shadows.h"
-#include "SpecialFX.h"
-#include "Sprite.h"
-#include "Timer.h"
-#include "WaterLevel.h"
-#include "World.h"
-
-CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98;
-int16 CPickups::NumMessages;// = *(int16*)0x95CC98;
-int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];// = *(int32(*)[NUMCOLLECTEDPICKUPS])*(uintptr*)0x87C538;
-int16 CPickups::CollectedPickUpIndex;// = *(int16*)0x95CC8A;
-
-// unused
-bool &CPickups::bPickUpcamActivated = *(bool*)0x95CD71;
-CVehicle *&CPickups::pPlayerVehicle = *(CVehicle**)0x8F29E8;
-CVector &CPickups::StaticCamCoors = *(CVector*)0x9404C8;
-uint32 &CPickups::StaticCamStartTime = *(uint32*)0x8E289C;
-
-tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES];
-
-// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4)
-uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 };
-uint16 AmmoForWeapon_OnStreet[20] = { 0, 1, 9, 25, 5, 30, 60, 5, 1, 50, 1, 1, 0, 200, 0, 100, 0, 0, 0, 0 };
-uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 };
-
-uint8 aWeaponReds[] = { 255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, 255, 128, 0, 255, 0 };
-uint8 aWeaponGreens[] = { 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, 0, 255, 0, 255, 0 };
-uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 255, 0, 0 };
-float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f };
-
-WRAPPER void CPacManPickups::Init(void) { EAXJMP(0x432760); }
-WRAPPER void CPacManPickups::Update(void) { EAXJMP(0x432800); }
-WRAPPER void CPacManPickups::GeneratePMPickUps(CVector, float, int16, uint8) { EAXJMP(0x432AE0); }
-WRAPPER void CPacManPickups::GeneratePMPickUpsForRace(int32) { EAXJMP(0x432D50); }
-WRAPPER void CPacManPickups::GenerateOnePMPickUp(CVector) { EAXJMP(0x432F20); }
-WRAPPER void CPacManPickups::Render(void) { EAXJMP(0x432F60); }
-WRAPPER void CPacManPickups::DoCleanUpPacManStuff(void) { EAXJMP(0x433150); }
-WRAPPER void CPacManPickups::StartPacManRace(int32) { EAXJMP(0x433340); }
-WRAPPER void CPacManPickups::StartPacManRecord(void) { EAXJMP(0x433360); }
-WRAPPER uint32 CPacManPickups::QueryPowerPillsEatenInRace(void) { EAXJMP(0x4333A0); }
-WRAPPER void CPacManPickups::ResetPowerPillsEatenInRace(void) { EAXJMP(0x4333B0); }
-WRAPPER void CPacManPickups::CleanUpPacManStuff(void) { EAXJMP(0x4333C0); }
-WRAPPER void CPacManPickups::StartPacManScramble(CVector, float, int16) { EAXJMP(0x4333D0); }
-WRAPPER uint32 CPacManPickups::QueryPowerPillsCarriedByPlayer(void) { EAXJMP(0x4333F0); }
-WRAPPER void CPacManPickups::ResetPowerPillsCarriedByPlayer(void) { EAXJMP(0x433410); }
-
-
-void
-CPickup::RemoveKeepType()
-{
- CWorld::Remove(m_pObject);
- delete m_pObject;
-
- m_bRemoved = true;
- m_pObject = nil;
-}
-
-void
-CPickup::Remove()
-{
- RemoveKeepType();
- m_eType = PICKUP_NONE;
-}
-
-CObject *
-CPickup::GiveUsAPickUpObject(int32 handle)
-{
- CObject *object;
-
- if (handle <= 0) object = new CObject(m_eModelIndex, false);
- else {
- CPools::MakeSureSlotInObjectPoolIsEmpty(handle);
- object = new(handle) CObject(m_eModelIndex, false);
- }
-
- if (object == nil) return nil;
- object->ObjectCreatedBy = MISSION_OBJECT;
- object->GetPosition() = m_vecPos;
- object->SetOrientation(0.0f, 0.0f, -HALFPI);
- object->GetMatrix().UpdateRW();
- object->UpdateRwFrame();
-
- object->bAffectedByGravity = false;
- object->bExplosionProof = true;
- object->bUsesCollision = false;
- object->bIsPickup = true;
-
- object->field_172 = m_eModelIndex == MI_PICKUP_BONUS ? m_nQuantity : 0;
-
- switch (m_eType)
- {
- case PICKUP_IN_SHOP:
- object->m_obj_flag2 = true;
- object->bOutOfStock = false;
- break;
- case PICKUP_ON_STREET:
- case PICKUP_ONCE:
- case PICKUP_ONCE_TIMEOUT:
- case PICKUP_COLLECTABLE1:
- case PICKUP_MONEY:
- case PICKUP_MINE_INACTIVE:
- case PICKUP_MINE_ARMED:
- case PICKUP_NAUTICAL_MINE_INACTIVE:
- case PICKUP_NAUTICAL_MINE_ARMED:
- case PICKUP_FLOATINGPACKAGE:
- case PICKUP_ON_STREET_SLOW:
- object->m_obj_flag2 = false;
- object->bOutOfStock = false;
- break;
- case PICKUP_IN_SHOP_OUT_OF_STOCK:
- object->m_obj_flag2 = false;
- object->bOutOfStock = true;
- object->bRenderScorched = true;
- break;
- case PICKUP_FLOATINGPACKAGE_FLOATING:
- default:
- break;
- }
- return object;
-}
-
-bool
-CPickup::CanBePickedUp(CPlayerPed *player)
-{
- assert(m_pObject != nil);
- bool cannotBePickedUp =
- (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > 99.5f)
- || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > 99.5f)
- || (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0)
- || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame));
- return !cannotBePickedUp;
-}
-
-bool
-CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
-{
- float waterLevel;
-
- if (m_bRemoved) {
- if (CTimer::GetTimeInMilliseconds() > m_nTimer) {
- // respawn pickup if we're far enough
- float dist = (FindPlayerCoors().x - m_vecPos.x) * (FindPlayerCoors().x - m_vecPos.x) + (FindPlayerCoors().y - m_vecPos.y) * (FindPlayerCoors().y - m_vecPos.y);
- if (dist > 100.0f || m_eType == PICKUP_IN_SHOP && dist > 2.4f) {
- m_pObject = GiveUsAPickUpObject(-1);
- if (m_pObject) {
- CWorld::Add(m_pObject);
- m_bRemoved = false;
- }
- }
- }
- return false;
- }
-
- if (!m_pObject) return false;
-
- if (!IsMine()) {
- // let's check if we touched the pickup
- bool isPickupTouched = false;
- if (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE) {
- if (vehicle != nil) {
- if (vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f))
- isPickupTouched = true;
- }
- else {
- if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) {
- if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) +
- (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f)
- isPickupTouched = true;
- }
- }
- } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA) {
- if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) {
- isPickupTouched = true;
- }
- } else if (vehicle == nil) {
- if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) {
- if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) +
- (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f)
- isPickupTouched = true;
- }
- }
-
- // if we didn't then we've got nothing to do
- if (isPickupTouched && CanBePickedUp(player)) {
- CPad::GetPad(0)->StartShake(120, 100);
- switch (m_eType)
- {
- case PICKUP_IN_SHOP:
- if (CWorld::Players[playerId].m_nMoney < CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]) {
- CGarages::TriggerMessage("PU_MONY", -1, 6000, -1);
- } else {
- CWorld::Players[playerId].m_nMoney -= CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())];
- if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
- player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
- player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON_BOUGHT, m_pObject->GetModelIndex() - MI_GRENADE);
- }
- RemoveKeepType();
- m_nTimer = CTimer::GetTimeInMilliseconds() + 5000;
- return true;
- }
- break;
- case PICKUP_ON_STREET:
- case PICKUP_ON_STREET_SLOW:
- if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
- if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) {
- player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon_OnStreet[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
- if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED)) {
- player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
- }
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE);
- } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA && vehicle != nil) {
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
- CPickups::bPickUpcamActivated = true;
- CPickups::pPlayerVehicle = FindPlayerVehicle();
- CPickups::StaticCamCoors = m_pObject->GetPosition();
- CPickups::StaticCamStartTime = CTimer::GetTimeInMilliseconds();
- }
- }
- if (m_eType == PICKUP_ON_STREET) {
- m_nTimer = CTimer::GetTimeInMilliseconds() + 30000;
- } else if (m_eType == PICKUP_ON_STREET_SLOW) {
- if (MI_PICKUP_BRIBE == m_pObject->m_modelIndex)
- m_nTimer = CTimer::GetTimeInMilliseconds() + 300000;
- else
- m_nTimer = CTimer::GetTimeInMilliseconds() + 720000;
- }
-
- RemoveKeepType();
- return true;
- case PICKUP_ONCE:
- case PICKUP_ONCE_TIMEOUT:
- if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
- if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) {
- player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
- if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED))
- player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
- }
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE);
- }
- Remove();
- return true;
- case PICKUP_COLLECTABLE1:
- CWorld::Players[playerId].m_nCollectedPackages++;
- CWorld::Players[playerId].m_nMoney += 1000;
-
- if (CWorld::Players[playerId].m_nCollectedPackages == CWorld::Players[playerId].m_nTotalPackages) {
- printf("All collectables have been picked up\n");
- CGarages::TriggerMessage("CO_ALL", -1, 5000, -1);
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 1000000;
- } else
- CGarages::TriggerMessage("CO_ONE", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 5000, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
-
- Remove();
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_HIDDEN_PACKAGE, 0);
- return true;
- case PICKUP_MONEY:
- CWorld::Players[playerId].m_nMoney += m_nQuantity;
- sprintf(gString, "$%d", m_nQuantity);
-#ifdef MONEY_MESSAGES
- CMoneyMessages::RegisterOne(m_vecPos + CVector(0.0f, 0.0f, 1.0f), gString, 0, 255, 0, 0.5f, 0.5f);
-#endif
- Remove();
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0);
- return true;
- //case PICKUP_IN_SHOP_OUT_OF_STOCK:
- //case PICKUP_MINE_INACTIVE:
- //case PICKUP_MINE_ARMED:
- //case PICKUP_NAUTICAL_MINE_INACTIVE:
- //case PICKUP_NAUTICAL_MINE_ARMED:
- //case PICKUP_FLOATINGPACKAGE:
- //case PICKUP_FLOATINGPACKAGE_FLOATING:
- default:
- break;
- }
- }
- } else {
- switch (m_eType)
- {
- case PICKUP_MINE_INACTIVE:
- if (vehicle != nil && !vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) {
- m_eType = PICKUP_MINE_ARMED;
- m_nTimer = CTimer::GetTimeInMilliseconds() + 10000;
- }
- break;
- case PICKUP_NAUTICAL_MINE_INACTIVE:
- {
- if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false))
- m_pObject->GetPosition().z = waterLevel + 0.6f;
-
- m_pObject->GetMatrix().UpdateRW();
- m_pObject->UpdateRwFrame();
-
- bool touched = false;
- for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
- CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
- touched = true;
- break; // added break here
- }
- }
-
- if (!touched) {
- m_eType = PICKUP_NAUTICAL_MINE_ARMED;
- m_nTimer = CTimer::GetTimeInMilliseconds() + 10000;
- }
- break;
- }
- case PICKUP_NAUTICAL_MINE_ARMED:
- if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false))
- m_pObject->GetPosition().z = waterLevel + 0.6f;
-
- m_pObject->GetMatrix().UpdateRW();
- m_pObject->UpdateRwFrame();
- // no break here
- case PICKUP_MINE_ARMED:
- {
- bool explode = false;
- if (CTimer::GetTimeInMilliseconds() > m_nTimer)
- explode = true;
- else {// added else here since vehicle lookup is useless
- for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
- CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
- explode = true;
- break; // added break here
- }
- }
- }
- if (explode) {
- CExplosion::AddExplosion(nil, nil, EXPLOSION_MINE, m_pObject->GetPosition(), 0);
- Remove();
- }
- break;
- }
- case PICKUP_FLOATINGPACKAGE:
- m_pObject->m_vecMoveSpeed.z -= 0.01f * CTimer::GetTimeStep();
- m_pObject->GetPosition() += m_pObject->GetMoveSpeed() * CTimer::GetTimeStep();
-
- m_pObject->GetMatrix().UpdateRW();
- m_pObject->UpdateRwFrame();
- if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0) && waterLevel >= m_pObject->GetPosition().z)
- m_eType = PICKUP_FLOATINGPACKAGE_FLOATING;
- break;
- case PICKUP_FLOATINGPACKAGE_FLOATING:
- if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0))
- m_pObject->GetPosition().z = waterLevel;
-
- m_pObject->GetMatrix().UpdateRW();
- m_pObject->UpdateRwFrame();
- if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) {
- Remove();
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_FLOAT_PACKAGE, 0);
- return true;
- }
- break;
- }
- }
- if (!m_bRemoved && (m_eType == PICKUP_ONCE_TIMEOUT || m_eType == PICKUP_MONEY) && CTimer::GetTimeInMilliseconds() > m_nTimer)
- Remove();
- return false;
-}
-
-void
-CPickups::Init(void)
-{
- NumMessages = 0;
- for (int i = 0; i < NUMPICKUPS; i++) {
- aPickUps[i].m_eType = PICKUP_NONE;
- aPickUps[i].m_nIndex = 1;
- aPickUps[i].m_pObject = nil;
- }
-
- for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++)
- aPickUpsCollected[i] = 0;
-
- CollectedPickUpIndex = 0;
-}
-
-bool
-CPickups::IsPickUpPickedUp(int32 pickupId)
-{
- for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) {
- if (pickupId == aPickUpsCollected[i]) {
- aPickUpsCollected[i] = 0;
- return true;
- }
- }
- return false;
-}
-
-void
-CPickups::PassTime(uint32 time)
-{
- for (int i = 0; i < NUMPICKUPS; i++) {
- if (aPickUps[i].m_eType != PICKUP_NONE) {
- if (aPickUps[i].m_nTimer <= time)
- aPickUps[i].m_nTimer = 0;
- else
- aPickUps[i].m_nTimer -= time;
- }
- }
-}
-
-int32
-CPickups::GetActualPickupIndex(int32 index)
-{
- if (index == -1) return -1;
-
- // doesn't look nice
- if ((uint16)((index & 0xFFFF0000) >> 16) != aPickUps[(uint16)index].m_nIndex) return -1;
- return (uint16)index;
-}
-
-bool
-CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex)
-{
- CPlayerPed *player;
-
- if (playerIndex <= 0) player = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
- else player = CWorld::Players[playerIndex].m_pPed;
-
- if (modelIndex == MI_PICKUP_ADRENALINE) {
- player->m_bAdrenalineActive = true;
- player->m_nAdrenalineTime = CTimer::GetTimeInMilliseconds() + 20000;
- player->m_fCurrentStamina = player->m_fMaxStamina;
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_ADRENALINE, 0);
- return true;
- } else if (modelIndex == MI_PICKUP_BODYARMOUR) {
- player->m_fArmour = 100.0f;
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_ARMOUR, 0);
- return true;
- } else if (modelIndex == MI_PICKUP_INFO) {
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
- return true;
- } else if (modelIndex == MI_PICKUP_HEALTH) {
- player->m_fHealth = 100.0f;
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_HEALTH, 0);
- return true;
- } else if (modelIndex == MI_PICKUP_BONUS) {
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
- return true;
- } else if (modelIndex == MI_PICKUP_BRIBE) {
- int32 level = FindPlayerPed()->m_pWanted->m_nWantedLevel - 1;
- if (level < 0) level = 0;
- player->SetWantedLevel(level);
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
- return true;
- } else if (modelIndex == MI_PICKUP_KILLFRENZY) {
- DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
- return true;
- }
- return false;
-}
-
-void
-CPickups::RemoveAllFloatingPickups()
-{
- for (int i = 0; i < NUMPICKUPS; i++) {
- if (aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE || aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE_FLOATING) {
- if (aPickUps[i].m_pObject) {
- CWorld::Remove(aPickUps[i].m_pObject);
- delete aPickUps[i].m_pObject;
- aPickUps[i].m_pObject = nil;
- }
- }
- }
-}
-
-void
-CPickups::RemovePickUp(int32 pickupIndex)
-{
- int32 index = CPickups::GetActualPickupIndex(pickupIndex);
- if (index == -1) return;
-
- if (aPickUps[index].m_pObject) {
- CWorld::Remove(aPickUps[index].m_pObject);
- delete aPickUps[index].m_pObject;
- aPickUps[index].m_pObject = nil;
- }
- aPickUps[index].m_eType = PICKUP_NONE;
- aPickUps[index].m_bRemoved = true;
-}
-
-int32
-CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity)
-{
- bool bFreeFound = false;
- int32 slot = 0;
-
- if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) {
- for (slot = NUMPICKUPS; slot >= 0; slot--) {
- if (aPickUps[slot].m_eType == PICKUP_NONE) {
- bFreeFound = true;
- break;
- }
- }
- } else {
- for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
- if (aPickUps[slot].m_eType == PICKUP_NONE) {
- bFreeFound = true;
- break;
- }
- }
- }
-
- if (!bFreeFound)
- {
- for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
- if (aPickUps[slot].m_eType == PICKUP_MONEY) break;
- }
-
- if (slot >= NUMGENERALPICKUPS)
- {
- for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
- if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT) break;
- }
-
- if (slot >= NUMGENERALPICKUPS) return -1;
- }
- }
-
- if (slot >= NUMPICKUPS) return -1;
-
- aPickUps[slot].m_eType = (ePickupType)type;
- aPickUps[slot].m_bRemoved = false;
- aPickUps[slot].m_nQuantity = quantity;
- if (type == PICKUP_ONCE_TIMEOUT)
- aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 20000;
- else if (type == PICKUP_MONEY)
- aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 30000;
- else if (type == PICKUP_MINE_INACTIVE || type == PICKUP_MINE_ARMED) {
- aPickUps[slot].m_eType = PICKUP_MINE_INACTIVE;
- aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500;
- } else if (type == PICKUP_NAUTICAL_MINE_INACTIVE || type == PICKUP_NAUTICAL_MINE_ARMED) {
- aPickUps[slot].m_eType = PICKUP_NAUTICAL_MINE_INACTIVE;
- aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500;
- }
- aPickUps[slot].m_eModelIndex = modelIndex;
- aPickUps[slot].m_vecPos = pos;
- aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(-1);
- if (aPickUps[slot].m_pObject)
- CWorld::Add(aPickUps[slot].m_pObject);
- return GetNewUniquePickupIndex(slot);
-}
-
-int32
-CPickups::GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity)
-{
- return GenerateNewOne(pos, ModelForWeapon(weaponType), type, quantity);
-}
-
-int32
-CPickups::GetNewUniquePickupIndex(int32 slot)
-{
- if (aPickUps[slot].m_nIndex >= 0xFFFE)
- aPickUps[slot].m_nIndex = 1;
- else
- aPickUps[slot].m_nIndex++;
- return slot | (aPickUps[slot].m_nIndex << 16);
-}
-
-int32
-CPickups::ModelForWeapon(eWeaponType weaponType)
-{
- switch (weaponType)
- {
- case WEAPONTYPE_BASEBALLBAT: return MI_BASEBALL_BAT;
- case WEAPONTYPE_COLT45: return MI_COLT;
- case WEAPONTYPE_UZI: return MI_UZI;
- case WEAPONTYPE_SHOTGUN: return MI_SHOTGUN;
- case WEAPONTYPE_AK47: return MI_AK47;
- case WEAPONTYPE_M16: return MI_M16;
- case WEAPONTYPE_SNIPERRIFLE: return MI_SNIPER;
- case WEAPONTYPE_ROCKETLAUNCHER: return MI_ROCKETLAUNCHER;
- case WEAPONTYPE_FLAMETHROWER: return MI_FLAMETHROWER;
- case WEAPONTYPE_MOLOTOV: return MI_MOLOTOV;
- case WEAPONTYPE_GRENADE: return MI_GRENADE;
- }
- return 0;
-}
-
-eWeaponType
-CPickups::WeaponForModel(int32 model)
-{
- if (model == MI_PICKUP_BODYARMOUR) return WEAPONTYPE_ARMOUR;
- switch (model)
- {
- case MI_GRENADE: return WEAPONTYPE_GRENADE;
- case MI_AK47: return WEAPONTYPE_AK47;
- case MI_BASEBALL_BAT: return WEAPONTYPE_BASEBALLBAT;
- case MI_COLT: return WEAPONTYPE_COLT45;
- case MI_MOLOTOV: return WEAPONTYPE_MOLOTOV;
- case MI_ROCKETLAUNCHER: return WEAPONTYPE_ROCKETLAUNCHER;
- case MI_SHOTGUN: return WEAPONTYPE_SHOTGUN;
- case MI_SNIPER: return WEAPONTYPE_SNIPERRIFLE;
- case MI_UZI: return WEAPONTYPE_UZI;
- case MI_MISSILE: return WEAPONTYPE_UNARMED;
- case MI_M16: return WEAPONTYPE_M16;
- case MI_FLAMETHROWER: return WEAPONTYPE_FLAMETHROWER;
- }
- return WEAPONTYPE_UNARMED;
-}
-
-int32
-CPickups::FindColourIndexForWeaponMI(int32 model)
-{
- return WeaponForModel(model) - 1;
-}
-
-void
-CPickups::AddToCollectedPickupsArray(int32 index)
-{
- aPickUpsCollected[CollectedPickUpIndex++] = index | (aPickUps[index].m_nIndex << 16);
- if (CollectedPickUpIndex >= NUMCOLLECTEDPICKUPS)
- CollectedPickUpIndex = 0;
-}
-
-void
-CPickups::Update()
-{
-#ifdef FIX_BUGS // RIP speedrunning (solution from SA)
- if (CReplay::IsPlayingBack())
- return;
-#endif
-#define PICKUPS_FRAME_SPAN (6)
-#ifdef FIX_BUGS
- for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
-#else // BUG: this code can only reach 318 out of 320 pickups
- for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
-#endif
- if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
- AddToCollectedPickupsArray(i);
- }
- }
-#undef PICKUPS_FRAME_SPAN
- for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) {
- if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
- AddToCollectedPickupsArray(i);
- }
- }
-}
-
-void
-CPickups::DoPickUpEffects(CEntity *entity)
-{
- if (entity->GetModelIndex() == MI_PICKUP_KILLFRENZY)
- entity->m_flagD80 = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame;
-
- if (!entity->m_flagD80) {
- float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
- float modifiedSin = 0.3f * (s + 1.0f);
-
-
- int16 colorId;
-
- if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA)
- colorId = 11;
- else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE)
- colorId = 12;
- else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY)
- colorId = 13;
- else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS)
- colorId = 14;
- else
- colorId = FindColourIndexForWeaponMI(entity->GetModelIndex());
-
- assert(colorId >= 0);
-
- CVector &pos = entity->GetPosition();
-
- float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f;
- CShadows::StoreStaticShadow(
- (uintptr)entity,
- SHADOWTYPE_ADDITIVE,
- gpShadowExplosionTex,
- &pos,
- 2.0f, 0.0f, 0.0f, -2.0f,
- 255, // this is 0 on PC which results in no shadow
- aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier,
- 4.0f, 1.0f, 40.0f, false, 0.0f);
-
- float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f;
- CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true);
- float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f;
- CCoronas::RegisterCorona( (uintptr)entity,
- aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f,
- 255,
- pos,
- size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
-
- CObject *object = (CObject*)entity;
- if (object->m_obj_flag2 || object->bOutOfStock || object->field_172) {
- float dist = (TheCamera.GetPosition() - pos).Magnitude();
- const float MAXDIST = 12.0f;
-
- if (dist < MAXDIST && NumMessages < NUMPICKUPMESSAGES) {
- RwV3d vecOut;
- float fDistX, fDistY;
- if (CSprite::CalcScreenCoors(entity->GetPosition() + CVector(0.0f, 0.0f, 0.7f), &vecOut, &fDistX, &fDistY, true)) {
- aMessages[NumMessages].m_pos.x = vecOut.x;
- aMessages[NumMessages].m_pos.y = vecOut.y;
- aMessages[NumMessages].m_dist.x = fDistX;
- aMessages[NumMessages].m_dist.y = fDistY;
- aMessages[NumMessages].m_weaponType = WeaponForModel(entity->GetModelIndex());
- aMessages[NumMessages].m_color.red = aWeaponReds[colorId];
- aMessages[NumMessages].m_color.green = aWeaponGreens[colorId];
- aMessages[NumMessages].m_color.blue = aWeaponBlues[colorId];
- aMessages[NumMessages].m_color.alpha = (1.0f - dist / MAXDIST) * 128.0f;
- aMessages[NumMessages].m_bOutOfStock = object->bOutOfStock;
- aMessages[NumMessages].m_quantity = object->field_172;
- NumMessages++;
- }
- }
- }
-
- entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]);
- }
-}
-
-void
-CPickups::DoMineEffects(CEntity *entity)
-{
- CVector &pos = entity->GetPosition();
- float dist = (TheCamera.GetPosition() - pos).Magnitude();
- const float MAXDIST = 20.0f;
-
- if (dist < MAXDIST) {
- float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x1FF) * DEGTORAD(360.0f / 0x200));
-
- int32 red = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 64.0f;
- CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos,
- 2.0f, 0.0f, 0.0f, -2.0f,
- 255, // this is 0 on PC which results in no shadow
- red, 0, 0,
- 4.0f, 1.0f, 40.0f, false, 0.0f);
- CCoronas::RegisterCorona((uintptr)entity, red, 0, 0, 255, pos, 0.6f, 60.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
- }
-
- entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x3FF) * DEGTORAD(360.0f / 0x400));
-}
-
-void
-CPickups::DoMoneyEffects(CEntity *entity)
-{
- CVector &pos = entity->GetPosition();
- float dist = (TheCamera.GetPosition() - pos).Magnitude();
- const float MAXDIST = 20.0f;
-
- if (dist < MAXDIST) {
- float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x3FF) * DEGTORAD(360.0f / 0x400));
-
- int32 green = (MAXDIST - dist) * (0.2f * s + 0.3f) / MAXDIST * 64.0f;
- CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos,
- 2.0f, 0.0f, 0.0f, -2.0f,
- 255, // this is 0 on PC which results in no shadow
- 0, green, 0,
- 4.0f, 1.0f, 40.0f, false, 0.0f);
- CCoronas::RegisterCorona((uintptr)entity, 0, green, 0, 255, pos, 0.4f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
- }
-
- entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800));
-}
-
-void
-CPickups::DoCollectableEffects(CEntity *entity)
-{
- CVector &pos = entity->GetPosition();
- float dist = (TheCamera.GetPosition() - pos).Magnitude();
- const float MAXDIST = 14.0f;
-
- if (dist < MAXDIST) {
- float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
-
- int32 color = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 255.0f;
- CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos,
- 2.0f, 0.0f, 0.0f, -2.0f,
- 255, // this is 0 on PC which results in no shadow
- color, color, color,
- 4.0f, 1.0f, 40.0f, false, 0.0f);
- CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
- }
-
- entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0xFFF) * DEGTORAD(360.0f / 0x1000));
-}
-
-void
-CPickups::RenderPickUpText()
-{
- wchar *strToPrint;
- for (int32 i = 0; i < NumMessages; i++) {
- if (aMessages[i].m_quantity <= 39) {
- switch (aMessages[i].m_quantity) // could use some enum maybe
- {
- case 0:
- if (aMessages[i].m_weaponType == WEAPONTYPE_TOTALWEAPONS) { // unreachable code?
- // what is this??
- sprintf(gString, "%d/%d", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 2903);
- } else {
- if (aMessages[i].m_bOutOfStock)
- strToPrint = TheText.Get("STOCK");
- else {
- sprintf(gString, "$%d", CostOfWeapon[aMessages[i].m_weaponType]);
- AsciiToUnicode(gString, gUString);
- strToPrint = gUString;
- }
- }
- break;
- case 1:
- strToPrint = TheText.Get("SECURI");
- break;
- case 2:
- strToPrint = TheText.Get("MOONBM");
- break;
- case 3:
- strToPrint = TheText.Get("COACH");
- break;
- case 4:
- strToPrint = TheText.Get("FLATBED");
- break;
- case 5:
- strToPrint = TheText.Get("LINERUN");
- break;
- case 6:
- strToPrint = TheText.Get("TRASHM");
- break;
- case 7:
- strToPrint = TheText.Get("PATRIOT");
- break;
- case 8:
- strToPrint = TheText.Get("WHOOPEE");
- break;
- case 9:
- strToPrint = TheText.Get("BLISTA");
- break;
- case 10:
- strToPrint = TheText.Get("MULE");
- break;
- case 11:
- strToPrint = TheText.Get("YANKEE");
- break;
- case 12:
- strToPrint = TheText.Get("BOBCAT");
- break;
- case 13:
- strToPrint = TheText.Get("DODO");
- break;
- case 14:
- strToPrint = TheText.Get("BUS");
- break;
- case 15:
- strToPrint = TheText.Get("RUMPO");
- break;
- case 16:
- strToPrint = TheText.Get("PONY");
- break;
- case 17:
- strToPrint = TheText.Get("SENTINL");
- break;
- case 18:
- strToPrint = TheText.Get("CHEETAH");
- break;
- case 19:
- strToPrint = TheText.Get("BANSHEE");
- break;
- case 20:
- strToPrint = TheText.Get("IDAHO");
- break;
- case 21:
- strToPrint = TheText.Get("INFERNS");
- break;
- case 22:
- strToPrint = TheText.Get("TAXI");
- break;
- case 23:
- strToPrint = TheText.Get("KURUMA");
- break;
- case 24:
- strToPrint = TheText.Get("STRETCH");
- break;
- case 25:
- strToPrint = TheText.Get("PEREN");
- break;
- case 26:
- strToPrint = TheText.Get("STINGER");
- break;
- case 27:
- strToPrint = TheText.Get("MANANA");
- break;
- case 28:
- strToPrint = TheText.Get("LANDSTK");
- break;
- case 29:
- strToPrint = TheText.Get("STALION");
- break;
- case 30:
- strToPrint = TheText.Get("BFINJC");
- break;
- case 31:
- strToPrint = TheText.Get("CABBIE");
- break;
- case 32:
- strToPrint = TheText.Get("ESPERAN");
- break;
- case 33:
- strToPrint = TheText.Get("FIRETRK");
- break;
- case 34:
- strToPrint = TheText.Get("AMBULAN");
- break;
- case 35:
- strToPrint = TheText.Get("ENFORCR");
- break;
- case 36:
- strToPrint = TheText.Get("FBICAR");
- break;
- case 37:
- strToPrint = TheText.Get("RHINO");
- break;
- case 38:
- strToPrint = TheText.Get("BARRCKS");
- break;
- case 39:
- strToPrint = TheText.Get("POLICAR");
- break;
- default:
- break;
- }
- }
- CFont::SetPropOn();
- CFont::SetBackgroundOff();
-
- const float MAX_SCALE = 1.0f;
-
- float fScaleY = aMessages[i].m_dist.y / 100.0f;
- if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE;
-
- float fScaleX = aMessages[i].m_dist.x / 100.0f;
- if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE;
-
- CFont::SetScale(fScaleX, fScaleY);
- CFont::SetCentreOn();
- CFont::SetCentreSize(SCREEN_WIDTH);
- CFont::SetJustifyOff();
-
- CFont::SetColor(CRGBA(aMessages[i].m_color.red, aMessages[i].m_color.green, aMessages[i].m_color.blue, aMessages[i].m_color.alpha));
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
- CFont::PrintString(aMessages[i].m_pos.x, aMessages[i].m_pos.y, strToPrint);
- }
- NumMessages = 0;
-}
-
-void
-CPickups::Load(uint8 *buf, uint32 size)
-{
-INITSAVEBUF
-
- for (int32 i = 0; i < NUMPICKUPS; i++) {
- aPickUps[i] = ReadSaveBuf<CPickup>(buf);
-
- if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
- aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((int32)aPickUps[i].m_pObject - 1);
- }
-
- CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);
- ReadSaveBuf<uint16>(buf);
- NumMessages = 0;
-
- for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
- aPickUpsCollected[i] = ReadSaveBuf<int32>(buf);
-
-VALIDATESAVEBUF(size)
-}
-
-void
-CPickups::Save(uint8 *buf, uint32 *size)
-{
- *size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
-
-INITSAVEBUF
-
- for (int32 i = 0; i < NUMPICKUPS; i++) {
- 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(buf_pickup->m_pObject) + 1);
- }
-
- WriteSaveBuf(buf, CollectedPickUpIndex);
- WriteSaveBuf(buf, (uint16)0); // possibly was NumMessages
-
- for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
- WriteSaveBuf(buf, aPickUpsCollected[i]);
-
-VALIDATESAVEBUF(*size)
-}
-
-STARTPATCHES
- InjectHook(0x430220, CPickups::Init, PATCH_JUMP);
- InjectHook(0x4303D0, CPickups::Update, PATCH_JUMP);
- InjectHook(0x432440, CPickups::RenderPickUpText, PATCH_JUMP);
- InjectHook(0x431C30, CPickups::DoCollectableEffects, PATCH_JUMP);
- InjectHook(0x431F40, CPickups::DoMoneyEffects, PATCH_JUMP);
- InjectHook(0x4321C0, CPickups::DoMineEffects, PATCH_JUMP);
- InjectHook(0x431520, CPickups::DoPickUpEffects, PATCH_JUMP);
- InjectHook(0x4304B0, CPickups::GenerateNewOne, PATCH_JUMP);
- InjectHook(0x430660, CPickups::GenerateNewOne_WeaponType, PATCH_JUMP);
- InjectHook(0x4307A0, CPickups::RemovePickUp, PATCH_JUMP);
- InjectHook(0x430800, CPickups::RemoveAllFloatingPickups, PATCH_JUMP);
- InjectHook(0x433D60, CPickups::AddToCollectedPickupsArray, PATCH_JUMP);
- InjectHook(0x430770, CPickups::IsPickUpPickedUp, PATCH_JUMP);
- InjectHook(0x430690, CPickups::ModelForWeapon, PATCH_JUMP);
- InjectHook(0x4306F0, CPickups::WeaponForModel, PATCH_JUMP);
- InjectHook(0x431510, CPickups::FindColourIndexForWeaponMI, PATCH_JUMP);/**/
- InjectHook(0x433DF0, CPickups::GetActualPickupIndex, PATCH_JUMP);
- InjectHook(0x433DB0, CPickups::GetNewUniquePickupIndex, PATCH_JUMP);
- InjectHook(0x433B60, CPickups::PassTime, PATCH_JUMP);
- InjectHook(0x4339F0, CPickups::GivePlayerGoodiesWithPickUpMI, PATCH_JUMP);
- InjectHook(0x433F60, CPickups::Load, PATCH_JUMP);
- InjectHook(0x433E40, CPickups::Save, PATCH_JUMP);
- InjectHook(0x433BA0, &CPickup::GiveUsAPickUpObject, PATCH_JUMP);
- InjectHook(0x430860, &CPickup::Update, PATCH_JUMP);
-ENDPATCHES
+#include "common.h"
+#include "patcher.h"
+#include "main.h"
+
+#include "Camera.h"
+#include "Coronas.h"
+#include "Darkel.h"
+#include "Entity.h"
+#include "Explosion.h"
+#include "Font.h"
+#include "Garages.h"
+#include "General.h"
+#include "ModelIndices.h"
+#include "Object.h"
+#include "Pad.h"
+#include "Pickups.h"
+#include "PlayerPed.h"
+#include "Wanted.h"
+#include "DMAudio.h"
+#include "Fire.h"
+#include "PointLights.h"
+#include "Pools.h"
+#ifdef FIX_BUGS
+#include "Replay.h"
+#endif
+#include "Script.h"
+#include "Shadows.h"
+#include "SpecialFX.h"
+#include "Sprite.h"
+#include "Timer.h"
+#include "WaterLevel.h"
+#include "World.h"
+
+CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98;
+int16 CPickups::NumMessages;// = *(int16*)0x95CC98;
+int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];// = *(int32(*)[NUMCOLLECTEDPICKUPS])*(uintptr*)0x87C538;
+int16 CPickups::CollectedPickUpIndex;// = *(int16*)0x95CC8A;
+
+// unused
+bool &CPickups::bPickUpcamActivated = *(bool*)0x95CD71;
+CVehicle *&CPickups::pPlayerVehicle = *(CVehicle**)0x8F29E8;
+CVector &CPickups::StaticCamCoors = *(CVector*)0x9404C8;
+uint32 &CPickups::StaticCamStartTime = *(uint32*)0x8E289C;
+
+tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES];
+
+// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4)
+uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 };
+uint16 AmmoForWeapon_OnStreet[20] = { 0, 1, 9, 25, 5, 30, 60, 5, 1, 50, 1, 1, 0, 200, 0, 100, 0, 0, 0, 0 };
+uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 };
+
+uint8 aWeaponReds[] = { 255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, 255, 128, 0, 255, 0 };
+uint8 aWeaponGreens[] = { 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, 0, 255, 0, 255, 0 };
+uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 255, 0, 0 };
+float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f };
+
+void
+CPickup::RemoveKeepType()
+{
+ CWorld::Remove(m_pObject);
+ delete m_pObject;
+
+ m_bRemoved = true;
+ m_pObject = nil;
+}
+
+void
+CPickup::Remove()
+{
+ RemoveKeepType();
+ m_eType = PICKUP_NONE;
+}
+
+CObject *
+CPickup::GiveUsAPickUpObject(int32 handle)
+{
+ CObject *object;
+
+ if (handle <= 0) object = new CObject(m_eModelIndex, false);
+ else {
+ CPools::MakeSureSlotInObjectPoolIsEmpty(handle);
+ object = new(handle) CObject(m_eModelIndex, false);
+ }
+
+ if (object == nil) return nil;
+ object->ObjectCreatedBy = MISSION_OBJECT;
+ object->GetPosition() = m_vecPos;
+ object->SetOrientation(0.0f, 0.0f, -HALFPI);
+ object->GetMatrix().UpdateRW();
+ object->UpdateRwFrame();
+
+ object->bAffectedByGravity = false;
+ object->bExplosionProof = true;
+ object->bUsesCollision = false;
+ object->bIsPickup = true;
+
+ object->m_nBonusValue = m_eModelIndex == MI_PICKUP_BONUS ? m_nQuantity : 0;
+
+ switch (m_eType)
+ {
+ case PICKUP_IN_SHOP:
+ object->m_obj_flag2 = true;
+ object->bOutOfStock = false;
+ break;
+ case PICKUP_ON_STREET:
+ case PICKUP_ONCE:
+ case PICKUP_ONCE_TIMEOUT:
+ case PICKUP_COLLECTABLE1:
+ case PICKUP_MONEY:
+ case PICKUP_MINE_INACTIVE:
+ case PICKUP_MINE_ARMED:
+ case PICKUP_NAUTICAL_MINE_INACTIVE:
+ case PICKUP_NAUTICAL_MINE_ARMED:
+ case PICKUP_FLOATINGPACKAGE:
+ case PICKUP_ON_STREET_SLOW:
+ object->m_obj_flag2 = false;
+ object->bOutOfStock = false;
+ break;
+ case PICKUP_IN_SHOP_OUT_OF_STOCK:
+ object->m_obj_flag2 = false;
+ object->bOutOfStock = true;
+ object->bRenderScorched = true;
+ break;
+ case PICKUP_FLOATINGPACKAGE_FLOATING:
+ default:
+ break;
+ }
+ return object;
+}
+
+bool
+CPickup::CanBePickedUp(CPlayerPed *player)
+{
+ assert(m_pObject != nil);
+ bool cannotBePickedUp =
+ (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > 99.5f)
+ || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > 99.5f)
+ || (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0)
+ || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame));
+ return !cannotBePickedUp;
+}
+
+bool
+CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
+{
+ float waterLevel;
+
+ if (m_bRemoved) {
+ if (CTimer::GetTimeInMilliseconds() > m_nTimer) {
+ // respawn pickup if we're far enough
+ float dist = (FindPlayerCoors().x - m_vecPos.x) * (FindPlayerCoors().x - m_vecPos.x) + (FindPlayerCoors().y - m_vecPos.y) * (FindPlayerCoors().y - m_vecPos.y);
+ if (dist > 100.0f || m_eType == PICKUP_IN_SHOP && dist > 2.4f) {
+ m_pObject = GiveUsAPickUpObject(-1);
+ if (m_pObject) {
+ CWorld::Add(m_pObject);
+ m_bRemoved = false;
+ }
+ }
+ }
+ return false;
+ }
+
+ if (!m_pObject) return false;
+
+ if (!IsMine()) {
+ // let's check if we touched the pickup
+ bool isPickupTouched = false;
+ if (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE) {
+ if (vehicle != nil) {
+ if (vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f))
+ isPickupTouched = true;
+ }
+ else {
+ if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) {
+ if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) +
+ (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f)
+ isPickupTouched = true;
+ }
+ }
+ } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA) {
+ if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) {
+ isPickupTouched = true;
+ }
+ } else if (vehicle == nil) {
+ if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) {
+ if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) +
+ (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f)
+ isPickupTouched = true;
+ }
+ }
+
+ // if we didn't then we've got nothing to do
+ if (isPickupTouched && CanBePickedUp(player)) {
+ CPad::GetPad(0)->StartShake(120, 100);
+ switch (m_eType)
+ {
+ case PICKUP_IN_SHOP:
+ if (CWorld::Players[playerId].m_nMoney < CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]) {
+ CGarages::TriggerMessage("PU_MONY", -1, 6000, -1);
+ } else {
+ CWorld::Players[playerId].m_nMoney -= CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())];
+ if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
+ player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
+ player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON_BOUGHT, m_pObject->GetModelIndex() - MI_GRENADE);
+ }
+ RemoveKeepType();
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ return true;
+ }
+ break;
+ case PICKUP_ON_STREET:
+ case PICKUP_ON_STREET_SLOW:
+ if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
+ if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) {
+ player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon_OnStreet[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
+ if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED)) {
+ player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
+ }
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE);
+ } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA && vehicle != nil) {
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
+ CPickups::bPickUpcamActivated = true;
+ CPickups::pPlayerVehicle = FindPlayerVehicle();
+ CPickups::StaticCamCoors = m_pObject->GetPosition();
+ CPickups::StaticCamStartTime = CTimer::GetTimeInMilliseconds();
+ }
+ }
+ if (m_eType == PICKUP_ON_STREET) {
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 30000;
+ } else if (m_eType == PICKUP_ON_STREET_SLOW) {
+ if (MI_PICKUP_BRIBE == m_pObject->m_modelIndex)
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 300000;
+ else
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 720000;
+ }
+
+ RemoveKeepType();
+ return true;
+ case PICKUP_ONCE:
+ case PICKUP_ONCE_TIMEOUT:
+ if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) {
+ if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) {
+ player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]);
+ if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED))
+ player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex()));
+ }
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE);
+ }
+ Remove();
+ return true;
+ case PICKUP_COLLECTABLE1:
+ CWorld::Players[playerId].m_nCollectedPackages++;
+ CWorld::Players[playerId].m_nMoney += 1000;
+
+ if (CWorld::Players[playerId].m_nCollectedPackages == CWorld::Players[playerId].m_nTotalPackages) {
+ printf("All collectables have been picked up\n");
+ CGarages::TriggerMessage("CO_ALL", -1, 5000, -1);
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 1000000;
+ } else
+ CGarages::TriggerMessage("CO_ONE", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 5000, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
+
+ Remove();
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_HIDDEN_PACKAGE, 0);
+ return true;
+ case PICKUP_MONEY:
+ CWorld::Players[playerId].m_nMoney += m_nQuantity;
+ sprintf(gString, "$%d", m_nQuantity);
+#ifdef MONEY_MESSAGES
+ CMoneyMessages::RegisterOne(m_vecPos + CVector(0.0f, 0.0f, 1.0f), gString, 0, 255, 0, 0.5f, 0.5f);
+#endif
+ Remove();
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0);
+ return true;
+ default:
+ break;
+ }
+ }
+ } else {
+ switch (m_eType)
+ {
+ case PICKUP_MINE_INACTIVE:
+ if (vehicle != nil && !vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) {
+ m_eType = PICKUP_MINE_ARMED;
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ }
+ break;
+ case PICKUP_NAUTICAL_MINE_INACTIVE:
+ {
+ if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false))
+ m_pObject->GetPosition().z = waterLevel + 0.6f;
+
+ m_pObject->GetMatrix().UpdateRW();
+ m_pObject->UpdateRwFrame();
+
+ bool touched = false;
+ for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
+ CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
+ touched = true;
+ break; // added break here
+ }
+ }
+
+ if (!touched) {
+ m_eType = PICKUP_NAUTICAL_MINE_ARMED;
+ m_nTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ }
+ break;
+ }
+ case PICKUP_NAUTICAL_MINE_ARMED:
+ if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false))
+ m_pObject->GetPosition().z = waterLevel + 0.6f;
+
+ m_pObject->GetMatrix().UpdateRW();
+ m_pObject->UpdateRwFrame();
+ // no break here
+ case PICKUP_MINE_ARMED:
+ {
+ bool explode = false;
+ if (CTimer::GetTimeInMilliseconds() > m_nTimer)
+ explode = true;
+ else {// added else here since vehicle lookup is useless
+ for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
+ CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
+ explode = true;
+ break; // added break here
+ }
+ }
+ }
+ if (explode) {
+ CExplosion::AddExplosion(nil, nil, EXPLOSION_MINE, m_pObject->GetPosition(), 0);
+ Remove();
+ }
+ break;
+ }
+ case PICKUP_FLOATINGPACKAGE:
+ m_pObject->m_vecMoveSpeed.z -= 0.01f * CTimer::GetTimeStep();
+ m_pObject->GetPosition() += m_pObject->GetMoveSpeed() * CTimer::GetTimeStep();
+
+ m_pObject->GetMatrix().UpdateRW();
+ m_pObject->UpdateRwFrame();
+ if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0) && waterLevel >= m_pObject->GetPosition().z)
+ m_eType = PICKUP_FLOATINGPACKAGE_FLOATING;
+ break;
+ case PICKUP_FLOATINGPACKAGE_FLOATING:
+ if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0))
+ m_pObject->GetPosition().z = waterLevel;
+
+ m_pObject->GetMatrix().UpdateRW();
+ m_pObject->UpdateRwFrame();
+ if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) {
+ Remove();
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_FLOAT_PACKAGE, 0);
+ return true;
+ }
+ break;
+ }
+ }
+ if (!m_bRemoved && (m_eType == PICKUP_ONCE_TIMEOUT || m_eType == PICKUP_MONEY) && CTimer::GetTimeInMilliseconds() > m_nTimer)
+ Remove();
+ return false;
+}
+
+void
+CPickups::Init(void)
+{
+ NumMessages = 0;
+ for (int i = 0; i < NUMPICKUPS; i++) {
+ aPickUps[i].m_eType = PICKUP_NONE;
+ aPickUps[i].m_nIndex = 1;
+ aPickUps[i].m_pObject = nil;
+ }
+
+ for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++)
+ aPickUpsCollected[i] = 0;
+
+ CollectedPickUpIndex = 0;
+}
+
+bool
+CPickups::IsPickUpPickedUp(int32 pickupId)
+{
+ for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) {
+ if (pickupId == aPickUpsCollected[i]) {
+ aPickUpsCollected[i] = 0;
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+CPickups::PassTime(uint32 time)
+{
+ for (int i = 0; i < NUMPICKUPS; i++) {
+ if (aPickUps[i].m_eType != PICKUP_NONE) {
+ if (aPickUps[i].m_nTimer <= time)
+ aPickUps[i].m_nTimer = 0;
+ else
+ aPickUps[i].m_nTimer -= time;
+ }
+ }
+}
+
+int32
+CPickups::GetActualPickupIndex(int32 index)
+{
+ if (index == -1) return -1;
+
+ // doesn't look nice
+ if ((uint16)((index & 0xFFFF0000) >> 16) != aPickUps[(uint16)index].m_nIndex) return -1;
+ return (uint16)index;
+}
+
+bool
+CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex)
+{
+ CPlayerPed *player;
+
+ if (playerIndex <= 0) player = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
+ else player = CWorld::Players[playerIndex].m_pPed;
+
+ if (modelIndex == MI_PICKUP_ADRENALINE) {
+ player->m_bAdrenalineActive = true;
+ player->m_nAdrenalineTime = CTimer::GetTimeInMilliseconds() + 20000;
+ player->m_fCurrentStamina = player->m_fMaxStamina;
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_ADRENALINE, 0);
+ return true;
+ } else if (modelIndex == MI_PICKUP_BODYARMOUR) {
+ player->m_fArmour = 100.0f;
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_ARMOUR, 0);
+ return true;
+ } else if (modelIndex == MI_PICKUP_INFO) {
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
+ return true;
+ } else if (modelIndex == MI_PICKUP_HEALTH) {
+ player->m_fHealth = 100.0f;
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_HEALTH, 0);
+ return true;
+ } else if (modelIndex == MI_PICKUP_BONUS) {
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
+ return true;
+ } else if (modelIndex == MI_PICKUP_BRIBE) {
+ int32 level = FindPlayerPed()->m_pWanted->m_nWantedLevel - 1;
+ if (level < 0) level = 0;
+ player->SetWantedLevel(level);
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
+ return true;
+ } else if (modelIndex == MI_PICKUP_KILLFRENZY) {
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
+ return true;
+ }
+ return false;
+}
+
+void
+CPickups::RemoveAllFloatingPickups()
+{
+ for (int i = 0; i < NUMPICKUPS; i++) {
+ if (aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE || aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE_FLOATING) {
+ if (aPickUps[i].m_pObject) {
+ CWorld::Remove(aPickUps[i].m_pObject);
+ delete aPickUps[i].m_pObject;
+ aPickUps[i].m_pObject = nil;
+ }
+ }
+ }
+}
+
+void
+CPickups::RemovePickUp(int32 pickupIndex)
+{
+ int32 index = CPickups::GetActualPickupIndex(pickupIndex);
+ if (index == -1) return;
+
+ if (aPickUps[index].m_pObject) {
+ CWorld::Remove(aPickUps[index].m_pObject);
+ delete aPickUps[index].m_pObject;
+ aPickUps[index].m_pObject = nil;
+ }
+ aPickUps[index].m_eType = PICKUP_NONE;
+ aPickUps[index].m_bRemoved = true;
+}
+
+int32
+CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity)
+{
+ bool bFreeFound = false;
+ int32 slot = 0;
+
+ if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) {
+ for (slot = NUMPICKUPS; slot >= 0; slot--) {
+ if (aPickUps[slot].m_eType == PICKUP_NONE) {
+ bFreeFound = true;
+ break;
+ }
+ }
+ } else {
+ for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
+ if (aPickUps[slot].m_eType == PICKUP_NONE) {
+ bFreeFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!bFreeFound) {
+ for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
+ if (aPickUps[slot].m_eType == PICKUP_MONEY) break;
+ }
+
+ if (slot >= NUMGENERALPICKUPS) {
+ for (slot = 0; slot < NUMGENERALPICKUPS; slot++) {
+ if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT) break;
+ }
+
+ if (slot >= NUMGENERALPICKUPS) return -1;
+ }
+ }
+
+ if (slot >= NUMPICKUPS) return -1;
+
+ aPickUps[slot].m_eType = (ePickupType)type;
+ aPickUps[slot].m_bRemoved = false;
+ aPickUps[slot].m_nQuantity = quantity;
+ if (type == PICKUP_ONCE_TIMEOUT)
+ aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 20000;
+ else if (type == PICKUP_MONEY)
+ aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 30000;
+ else if (type == PICKUP_MINE_INACTIVE || type == PICKUP_MINE_ARMED) {
+ aPickUps[slot].m_eType = PICKUP_MINE_INACTIVE;
+ aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500;
+ } else if (type == PICKUP_NAUTICAL_MINE_INACTIVE || type == PICKUP_NAUTICAL_MINE_ARMED) {
+ aPickUps[slot].m_eType = PICKUP_NAUTICAL_MINE_INACTIVE;
+ aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500;
+ }
+ aPickUps[slot].m_eModelIndex = modelIndex;
+ aPickUps[slot].m_vecPos = pos;
+ aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(-1);
+ if (aPickUps[slot].m_pObject)
+ CWorld::Add(aPickUps[slot].m_pObject);
+ return GetNewUniquePickupIndex(slot);
+}
+
+int32
+CPickups::GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity)
+{
+ return GenerateNewOne(pos, ModelForWeapon(weaponType), type, quantity);
+}
+
+int32
+CPickups::GetNewUniquePickupIndex(int32 slot)
+{
+ if (aPickUps[slot].m_nIndex >= 0xFFFE)
+ aPickUps[slot].m_nIndex = 1;
+ else
+ aPickUps[slot].m_nIndex++;
+ return slot | (aPickUps[slot].m_nIndex << 16);
+}
+
+int32
+CPickups::ModelForWeapon(eWeaponType weaponType)
+{
+ switch (weaponType)
+ {
+ case WEAPONTYPE_BASEBALLBAT: return MI_BASEBALL_BAT;
+ case WEAPONTYPE_COLT45: return MI_COLT;
+ case WEAPONTYPE_UZI: return MI_UZI;
+ case WEAPONTYPE_SHOTGUN: return MI_SHOTGUN;
+ case WEAPONTYPE_AK47: return MI_AK47;
+ case WEAPONTYPE_M16: return MI_M16;
+ case WEAPONTYPE_SNIPERRIFLE: return MI_SNIPER;
+ case WEAPONTYPE_ROCKETLAUNCHER: return MI_ROCKETLAUNCHER;
+ case WEAPONTYPE_FLAMETHROWER: return MI_FLAMETHROWER;
+ case WEAPONTYPE_MOLOTOV: return MI_MOLOTOV;
+ case WEAPONTYPE_GRENADE: return MI_GRENADE;
+ }
+ return 0;
+}
+
+eWeaponType
+CPickups::WeaponForModel(int32 model)
+{
+ if (model == MI_PICKUP_BODYARMOUR) return WEAPONTYPE_ARMOUR;
+ switch (model)
+ {
+ case MI_GRENADE: return WEAPONTYPE_GRENADE;
+ case MI_AK47: return WEAPONTYPE_AK47;
+ case MI_BASEBALL_BAT: return WEAPONTYPE_BASEBALLBAT;
+ case MI_COLT: return WEAPONTYPE_COLT45;
+ case MI_MOLOTOV: return WEAPONTYPE_MOLOTOV;
+ case MI_ROCKETLAUNCHER: return WEAPONTYPE_ROCKETLAUNCHER;
+ case MI_SHOTGUN: return WEAPONTYPE_SHOTGUN;
+ case MI_SNIPER: return WEAPONTYPE_SNIPERRIFLE;
+ case MI_UZI: return WEAPONTYPE_UZI;
+ case MI_MISSILE: return WEAPONTYPE_UNARMED;
+ case MI_M16: return WEAPONTYPE_M16;
+ case MI_FLAMETHROWER: return WEAPONTYPE_FLAMETHROWER;
+ }
+ return WEAPONTYPE_UNARMED;
+}
+
+int32
+CPickups::FindColourIndexForWeaponMI(int32 model)
+{
+ return WeaponForModel(model) - 1;
+}
+
+void
+CPickups::AddToCollectedPickupsArray(int32 index)
+{
+ aPickUpsCollected[CollectedPickUpIndex++] = index | (aPickUps[index].m_nIndex << 16);
+ if (CollectedPickUpIndex >= NUMCOLLECTEDPICKUPS)
+ CollectedPickUpIndex = 0;
+}
+
+void
+CPickups::Update()
+{
+#ifdef FIX_BUGS // RIP speedrunning (solution from SA)
+ if (CReplay::IsPlayingBack())
+ return;
+#endif
+#define PICKUPS_FRAME_SPAN (6)
+#ifdef FIX_BUGS
+ for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) {
+#else // BUG: this code can only reach 318 out of 320 pickups
+ for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) {
+#endif
+ if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
+ AddToCollectedPickupsArray(i);
+ }
+ }
+#undef PICKUPS_FRAME_SPAN
+ for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) {
+ if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) {
+ AddToCollectedPickupsArray(i);
+ }
+ }
+}
+
+void
+CPickups::DoPickUpEffects(CEntity *entity)
+{
+ if (entity->GetModelIndex() == MI_PICKUP_KILLFRENZY)
+ entity->bDoNotRender = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame;
+
+ if (!entity->bDoNotRender) {
+ float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
+ float modifiedSin = 0.3f * (s + 1.0f);
+
+
+ int16 colorId;
+
+ if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA)
+ colorId = 11;
+ else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE)
+ colorId = 12;
+ else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY)
+ colorId = 13;
+ else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS)
+ colorId = 14;
+ else
+ colorId = FindColourIndexForWeaponMI(entity->GetModelIndex());
+
+ assert(colorId >= 0);
+
+ CVector &pos = entity->GetPosition();
+
+ float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f;
+ CShadows::StoreStaticShadow(
+ (uintptr)entity,
+ SHADOWTYPE_ADDITIVE,
+ gpShadowExplosionTex,
+ &pos,
+ 2.0f, 0.0f, 0.0f, -2.0f,
+ 255, // this is 0 on PC which results in no shadow
+ aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier,
+ 4.0f, 1.0f, 40.0f, false, 0.0f);
+
+ float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f;
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true);
+ float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f;
+ CCoronas::RegisterCorona( (uintptr)entity,
+ aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f,
+ 255,
+ pos,
+ size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+
+ CObject *object = (CObject*)entity;
+ if (object->m_obj_flag2 || object->bOutOfStock || object->m_nBonusValue) {
+ float dist = (TheCamera.GetPosition() - pos).Magnitude();
+ const float MAXDIST = 12.0f;
+
+ if (dist < MAXDIST && NumMessages < NUMPICKUPMESSAGES) {
+ RwV3d vecOut;
+ float fDistX, fDistY;
+ if (CSprite::CalcScreenCoors(entity->GetPosition() + CVector(0.0f, 0.0f, 0.7f), &vecOut, &fDistX, &fDistY, true)) {
+ aMessages[NumMessages].m_pos.x = vecOut.x;
+ aMessages[NumMessages].m_pos.y = vecOut.y;
+ aMessages[NumMessages].m_dist.x = fDistX;
+ aMessages[NumMessages].m_dist.y = fDistY;
+ aMessages[NumMessages].m_weaponType = WeaponForModel(entity->GetModelIndex());
+ aMessages[NumMessages].m_color.red = aWeaponReds[colorId];
+ aMessages[NumMessages].m_color.green = aWeaponGreens[colorId];
+ aMessages[NumMessages].m_color.blue = aWeaponBlues[colorId];
+ aMessages[NumMessages].m_color.alpha = (1.0f - dist / MAXDIST) * 128.0f;
+ aMessages[NumMessages].m_bOutOfStock = object->bOutOfStock;
+ aMessages[NumMessages].m_quantity = object->m_nBonusValue;
+ NumMessages++;
+ }
+ }
+ }
+
+ entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]);
+ }
+}
+
+void
+CPickups::DoMineEffects(CEntity *entity)
+{
+ CVector &pos = entity->GetPosition();
+ float dist = (TheCamera.GetPosition() - pos).Magnitude();
+ const float MAXDIST = 20.0f;
+
+ if (dist < MAXDIST) {
+ float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x1FF) * DEGTORAD(360.0f / 0x200));
+
+ int32 red = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 64.0f;
+ CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos,
+ 2.0f, 0.0f, 0.0f, -2.0f,
+ 255, // this is 0 on PC which results in no shadow
+ red, 0, 0,
+ 4.0f, 1.0f, 40.0f, false, 0.0f);
+ CCoronas::RegisterCorona((uintptr)entity, red, 0, 0, 255, pos, 0.6f, 60.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ }
+
+ entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x3FF) * DEGTORAD(360.0f / 0x400));
+}
+
+void
+CPickups::DoMoneyEffects(CEntity *entity)
+{
+ CVector &pos = entity->GetPosition();
+ float dist = (TheCamera.GetPosition() - pos).Magnitude();
+ const float MAXDIST = 20.0f;
+
+ if (dist < MAXDIST) {
+ float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x3FF) * DEGTORAD(360.0f / 0x400));
+
+ int32 green = (MAXDIST - dist) * (0.2f * s + 0.3f) / MAXDIST * 64.0f;
+ CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos,
+ 2.0f, 0.0f, 0.0f, -2.0f,
+ 255, // this is 0 on PC which results in no shadow
+ 0, green, 0,
+ 4.0f, 1.0f, 40.0f, false, 0.0f);
+ CCoronas::RegisterCorona((uintptr)entity, 0, green, 0, 255, pos, 0.4f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ }
+
+ entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800));
+}
+
+void
+CPickups::DoCollectableEffects(CEntity *entity)
+{
+ CVector &pos = entity->GetPosition();
+ float dist = (TheCamera.GetPosition() - pos).Magnitude();
+ const float MAXDIST = 14.0f;
+
+ if (dist < MAXDIST) {
+ float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
+
+ int32 color = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 255.0f;
+ CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos,
+ 2.0f, 0.0f, 0.0f, -2.0f,
+ 255, // this is 0 on PC which results in no shadow
+ color, color, color,
+ 4.0f, 1.0f, 40.0f, false, 0.0f);
+ CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ }
+
+ entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0xFFF) * DEGTORAD(360.0f / 0x1000));
+}
+
+void
+CPickups::RenderPickUpText()
+{
+ wchar *strToPrint;
+ for (int32 i = 0; i < NumMessages; i++) {
+ if (aMessages[i].m_quantity <= 39) {
+ switch (aMessages[i].m_quantity) // could use some enum maybe
+ {
+ case 0:
+ if (aMessages[i].m_weaponType == WEAPONTYPE_TOTALWEAPONS) { // unreachable code?
+ // what is this??
+ sprintf(gString, "%d/%d", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 2903);
+ } else {
+ if (aMessages[i].m_bOutOfStock)
+ strToPrint = TheText.Get("STOCK");
+ else {
+ sprintf(gString, "$%d", CostOfWeapon[aMessages[i].m_weaponType]);
+ AsciiToUnicode(gString, gUString);
+ strToPrint = gUString;
+ }
+ }
+ break;
+ case 1:
+ strToPrint = TheText.Get("SECURI");
+ break;
+ case 2:
+ strToPrint = TheText.Get("MOONBM");
+ break;
+ case 3:
+ strToPrint = TheText.Get("COACH");
+ break;
+ case 4:
+ strToPrint = TheText.Get("FLATBED");
+ break;
+ case 5:
+ strToPrint = TheText.Get("LINERUN");
+ break;
+ case 6:
+ strToPrint = TheText.Get("TRASHM");
+ break;
+ case 7:
+ strToPrint = TheText.Get("PATRIOT");
+ break;
+ case 8:
+ strToPrint = TheText.Get("WHOOPEE");
+ break;
+ case 9:
+ strToPrint = TheText.Get("BLISTA");
+ break;
+ case 10:
+ strToPrint = TheText.Get("MULE");
+ break;
+ case 11:
+ strToPrint = TheText.Get("YANKEE");
+ break;
+ case 12:
+ strToPrint = TheText.Get("BOBCAT");
+ break;
+ case 13:
+ strToPrint = TheText.Get("DODO");
+ break;
+ case 14:
+ strToPrint = TheText.Get("BUS");
+ break;
+ case 15:
+ strToPrint = TheText.Get("RUMPO");
+ break;
+ case 16:
+ strToPrint = TheText.Get("PONY");
+ break;
+ case 17:
+ strToPrint = TheText.Get("SENTINL");
+ break;
+ case 18:
+ strToPrint = TheText.Get("CHEETAH");
+ break;
+ case 19:
+ strToPrint = TheText.Get("BANSHEE");
+ break;
+ case 20:
+ strToPrint = TheText.Get("IDAHO");
+ break;
+ case 21:
+ strToPrint = TheText.Get("INFERNS");
+ break;
+ case 22:
+ strToPrint = TheText.Get("TAXI");
+ break;
+ case 23:
+ strToPrint = TheText.Get("KURUMA");
+ break;
+ case 24:
+ strToPrint = TheText.Get("STRETCH");
+ break;
+ case 25:
+ strToPrint = TheText.Get("PEREN");
+ break;
+ case 26:
+ strToPrint = TheText.Get("STINGER");
+ break;
+ case 27:
+ strToPrint = TheText.Get("MANANA");
+ break;
+ case 28:
+ strToPrint = TheText.Get("LANDSTK");
+ break;
+ case 29:
+ strToPrint = TheText.Get("STALION");
+ break;
+ case 30:
+ strToPrint = TheText.Get("BFINJC");
+ break;
+ case 31:
+ strToPrint = TheText.Get("CABBIE");
+ break;
+ case 32:
+ strToPrint = TheText.Get("ESPERAN");
+ break;
+ case 33:
+ strToPrint = TheText.Get("FIRETRK");
+ break;
+ case 34:
+ strToPrint = TheText.Get("AMBULAN");
+ break;
+ case 35:
+ strToPrint = TheText.Get("ENFORCR");
+ break;
+ case 36:
+ strToPrint = TheText.Get("FBICAR");
+ break;
+ case 37:
+ strToPrint = TheText.Get("RHINO");
+ break;
+ case 38:
+ strToPrint = TheText.Get("BARRCKS");
+ break;
+ case 39:
+ strToPrint = TheText.Get("POLICAR");
+ break;
+ default:
+ break;
+ }
+ }
+ CFont::SetPropOn();
+ CFont::SetBackgroundOff();
+
+ const float MAX_SCALE = 1.0f;
+
+ float fScaleY = aMessages[i].m_dist.y / 100.0f;
+ if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE;
+
+ float fScaleX = aMessages[i].m_dist.x / 100.0f;
+ if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE;
+
+ CFont::SetScale(fScaleX, fScaleY);
+ CFont::SetCentreOn();
+ CFont::SetCentreSize(SCREEN_WIDTH);
+ CFont::SetJustifyOff();
+
+ CFont::SetColor(CRGBA(aMessages[i].m_color.red, aMessages[i].m_color.green, aMessages[i].m_color.blue, aMessages[i].m_color.alpha));
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::PrintString(aMessages[i].m_pos.x, aMessages[i].m_pos.y, strToPrint);
+ }
+ NumMessages = 0;
+}
+
+void
+CPickups::Load(uint8 *buf, uint32 size)
+{
+INITSAVEBUF
+
+ for (int32 i = 0; i < NUMPICKUPS; i++) {
+ aPickUps[i] = ReadSaveBuf<CPickup>(buf);
+
+ if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
+ aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((int32)aPickUps[i].m_pObject - 1);
+ }
+
+ CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);
+ ReadSaveBuf<uint16>(buf);
+ NumMessages = 0;
+
+ for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
+ aPickUpsCollected[i] = ReadSaveBuf<int32>(buf);
+
+VALIDATESAVEBUF(size)
+}
+
+void
+CPickups::Save(uint8 *buf, uint32 *size)
+{
+ *size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
+
+INITSAVEBUF
+
+ for (int32 i = 0; i < NUMPICKUPS; i++) {
+ 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(buf_pickup->m_pObject) + 1);
+ }
+
+ WriteSaveBuf(buf, CollectedPickUpIndex);
+ WriteSaveBuf(buf, (uint16)0); // possibly was NumMessages
+
+ for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
+ WriteSaveBuf(buf, aPickUpsCollected[i]);
+
+VALIDATESAVEBUF(*size)
+}
+
+void
+CPacManPickup::Update()
+{
+ if (FindPlayerVehicle() == nil) return;
+
+ CVehicle *veh = FindPlayerVehicle();
+
+ if (DistanceSqr2D(FindPlayerVehicle()->GetPosition(), m_vecPosn.x, m_vecPosn.y) < 100.0f && veh->IsSphereTouchingVehicle(m_vecPosn.x, m_vecPosn.y, m_vecPosn.z, 1.5f)) {
+ switch (m_eType)
+ {
+ case PACMAN_SCRAMBLE:
+ {
+ veh->m_nPacManPickupsCarried++;
+ veh->m_vecMoveSpeed *= 0.65f;
+ float massMult = (veh->m_fMass + 250.0f) / veh->m_fMass;
+ veh->m_fMass *= massMult;
+ veh->m_fTurnMass *= massMult;
+ veh->m_fForceMultiplier *= massMult;
+ FindPlayerPed()->m_pWanted->m_nChaos += 10;
+ FindPlayerPed()->m_pWanted->UpdateWantedLevel();
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_PACMAN_PACKAGE, 0);
+ break;
+ }
+ case PACMAN_RACE:
+ CPacManPickups::PillsEatenInRace++;
+ DMAudio.PlayFrontEndSound(SOUND_PICKUP_PACMAN_PILL, 0);
+ break;
+ default:
+ break;
+ }
+ m_eType = PACMAN_NONE;
+ if (m_pObject != nil) {
+ CWorld::Remove(m_pObject);
+ delete m_pObject;
+ m_pObject = nil;
+ }
+ }
+}
+
+int32 CollectGameState;
+int16 ThingsToCollect;
+
+CPacManPickup CPacManPickups::aPMPickUps[NUMPACMANPICKUPS];
+CVector CPacManPickups::LastPickUpCoors;
+int32 CPacManPickups::PillsEatenInRace;
+bool CPacManPickups::bPMActive;
+
+void
+CPacManPickups::Init()
+{
+ for (int i = 0; i < NUMPACMANPICKUPS; i++)
+ aPMPickUps[i].m_eType = PACMAN_NONE;
+ bPMActive = false;
+}
+
+void
+CPacManPickups::Update()
+{
+ if (FindPlayerVehicle()) {
+ float dist = Distance(FindPlayerCoors(), CVector(1072.0f, -948.0f, 14.5f));
+ switch (CollectGameState) {
+ case 1:
+ if (dist < 10.0f) {
+ ThingsToCollect -= FindPlayerVehicle()->m_nPacManPickupsCarried;
+ FindPlayerVehicle()->m_nPacManPickupsCarried = 0;
+ FindPlayerVehicle()->m_fMass /= FindPlayerVehicle()->m_fForceMultiplier;
+ FindPlayerVehicle()->m_fTurnMass /= FindPlayerVehicle()->m_fForceMultiplier;
+ FindPlayerVehicle()->m_fForceMultiplier = 1.0f;
+ }
+ if (ThingsToCollect <= 0) {
+ CollectGameState = 2;
+ ClearPMPickUps();
+ }
+ break;
+ case 2:
+ if (dist > 11.0f)
+ CollectGameState = 0;
+ break;
+ case 20:
+ if (Distance(FindPlayerCoors(), LastPickUpCoors) > 30.0f) {
+ LastPickUpCoors = FindPlayerCoors();
+ printf("%f, %f, %f,\n", LastPickUpCoors.x, LastPickUpCoors.y, LastPickUpCoors.z);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (bPMActive) {
+#define PACMANPICKUPS_FRAME_SPAN (4)
+ for (uint32 i = (CTimer::GetFrameCounter() % PACMANPICKUPS_FRAME_SPAN) * (NUMPACMANPICKUPS / PACMANPICKUPS_FRAME_SPAN); i < ((CTimer::GetFrameCounter() % PACMANPICKUPS_FRAME_SPAN) + 1) * (NUMPACMANPICKUPS / PACMANPICKUPS_FRAME_SPAN); i++) {
+ if (aPMPickUps[i].m_eType != PACMAN_NONE)
+ aPMPickUps[i].Update();
+ }
+#undef PACMANPICKUPS_FRAME_SPAN
+ }
+}
+
+void
+CPacManPickups::GeneratePMPickUps(CVector pos, float scrambleMult, int16 count, uint8 type)
+{
+ int i = 0;
+ while (count > 0) {
+ while (aPMPickUps[i].m_eType != PACMAN_NONE)
+ i++;
+
+ bool bPickupCreated = false;
+ while (!bPickupCreated) {
+ CVector newPos = pos;
+ CColPoint colPoint;
+ CEntity *pRoad;
+ uint16 nRand = CGeneral::GetRandomNumber();
+ newPos.x += ((nRand & 0xFF) - 128) * scrambleMult / 128.0f;
+ newPos.y += (((nRand >> 8) & 0xFF) - 128) * scrambleMult / 128.0f;
+ newPos.z = 1000.0f;
+ if (CWorld::ProcessVerticalLine(newPos, -1000.0f, colPoint, pRoad, true, false, false, false, true, false, nil) && pRoad->IsBuilding() && ((CBuilding*)pRoad)->GetIsATreadable()) {
+ newPos.z = 0.7f + colPoint.point.z;
+ aPMPickUps[i].m_eType = type;
+ aPMPickUps[i].m_vecPosn = newPos;
+ CObject *obj = new CObject(MI_BULLION, true);
+ if (obj != nil) {
+ obj->ObjectCreatedBy = MISSION_OBJECT;
+ obj->GetPosition() = aPMPickUps[i].m_vecPosn;
+ obj->SetOrientation(0.0f, 0.0f, -HALFPI);
+ obj->GetMatrix().UpdateRW();
+ obj->UpdateRwFrame();
+
+ obj->bAffectedByGravity = false;
+ obj->bExplosionProof = true;
+ obj->bUsesCollision = false;
+ obj->bIsPickup = false;
+ CWorld::Add(obj);
+ }
+ aPMPickUps[i].m_pObject = obj;
+ bPickupCreated = true;
+ }
+ }
+ count--;
+ }
+ bPMActive = true;
+}
+
+// diablo porn mission pickups
+static const CVector aRacePoints1[] = {
+ CVector(913.62219f, -155.13692f, 4.9699469f),
+ CVector(913.92401f, -124.12943f, 4.9692569f),
+ CVector(913.27899f, -93.524231f, 7.4325991f),
+ CVector(912.60852f, -63.15905f, 7.4533591f),
+ CVector(934.22144f, -42.049122f, 7.4511471f),
+ CVector(958.88092f, -23.863735f, 7.4652338f),
+ CVector(978.50812f, -0.78458798f, 5.13515f),
+ CVector(1009.4175f, -2.1041219f, 2.4461579f),
+ CVector(1040.6313f, -2.0793829f, 2.293175f),
+ CVector(1070.7863f, -2.084095f, 2.2789791f),
+ CVector(1100.5773f, -8.468729f, 5.3248072f),
+ CVector(1119.9341f, -31.738031f, 7.1913071f),
+ CVector(1122.1664f, -62.762737f, 7.4703908f),
+ CVector(1122.814f, -93.650566f, 8.5577497f),
+ CVector(1125.8253f, -124.26616f, 9.9803305f),
+ CVector(1153.8727f, -135.47169f, 14.150617f),
+ CVector(1184.0831f, -135.82845f, 14.973998f),
+ CVector(1192.0432f, -164.57816f, 19.18627f),
+ CVector(1192.7761f, -194.28871f, 24.799675f),
+ CVector(1215.1527f, -215.0714f, 25.74975f),
+ CVector(1245.79f, -215.39304f, 28.70726f),
+ CVector(1276.2477f, -216.39485f, 33.71236f),
+ CVector(1306.5535f, -216.71007f, 39.711472f),
+ CVector(1335.0244f, -224.59329f, 46.474979f),
+ CVector(1355.4879f, -246.27664f, 49.934841f),
+ CVector(1362.6003f, -276.47064f, 49.96265f),
+ CVector(1363.027f, -307.30847f, 49.969173f),
+ CVector(1365.343f, -338.08609f, 49.967789f),
+ CVector(1367.5957f, -368.01105f, 50.092304f),
+ CVector(1368.2749f, -398.38049f, 50.061268f),
+ CVector(1366.9034f, -429.98483f, 50.057545f),
+ CVector(1356.8534f, -459.09259f, 50.035545f),
+ CVector(1335.5819f, -481.13544f, 47.217903f),
+ CVector(1306.7552f, -491.07443f, 40.202629f),
+ CVector(1275.5978f, -491.33194f, 33.969223f),
+ CVector(1244.702f, -491.46451f, 29.111021f),
+ CVector(1213.2222f, -491.8754f, 25.771168f),
+ CVector(1182.7729f, -492.19995f, 24.749964f),
+ CVector(1152.6874f, -491.42221f, 21.70038f),
+ CVector(1121.5352f, -491.94604f, 20.075182f),
+ CVector(1090.7056f, -492.63751f, 17.585758f),
+ CVector(1059.6008f, -491.65762f, 14.848632f),
+ CVector(1029.113f, -489.66031f, 14.918498f),
+ CVector(998.20679f, -486.78107f, 14.945688f),
+ CVector(968.00555f, -484.91266f, 15.001229f),
+ CVector(937.74939f, -492.09015f, 14.958629f),
+ CVector(927.17352f, -520.97736f, 14.972308f),
+ CVector(929.29749f, -552.08643f, 14.978855f),
+ CVector(950.69525f, -574.47778f, 14.972788f),
+ CVector(974.02826f, -593.56024f, 14.966445f),
+ CVector(989.04779f, -620.12854f, 14.951016f),
+ CVector(1014.1639f, -637.3905f, 14.966736f),
+ CVector(1017.5961f, -667.3736f, 14.956415f),
+ CVector(1041.9735f, -685.94391f, 15.003841f),
+ CVector(1043.3064f, -716.11298f, 14.974236f),
+ CVector(1043.5337f, -746.63855f, 14.96919f),
+ CVector(1044.142f, -776.93823f, 14.965424f),
+ CVector(1044.2657f, -807.29395f, 14.97171f),
+ CVector(1017.0797f, -820.1076f, 14.975431f),
+ CVector(986.23865f, -820.37103f, 14.972883f),
+ CVector(956.10065f, -820.23291f, 14.981133f),
+ CVector(925.86914f, -820.19049f, 14.976553f),
+ CVector(897.69702f, -831.08734f, 14.962709f),
+ CVector(868.06586f, -835.99237f, 14.970685f),
+ CVector(836.93054f, -836.84387f, 14.965049f),
+ CVector(811.63586f, -853.7915f, 15.067576f),
+ CVector(811.46344f, -884.27368f, 12.247812f),
+ CVector(811.60651f, -914.70959f, 9.2393751f),
+ CVector(811.10425f, -945.16272f, 5.817255f),
+ CVector(816.54584f, -975.64587f, 4.998558f),
+ CVector(828.2951f, -1003.3685f, 5.0471172f),
+ CVector(852.28839f, -1021.5963f, 4.9371028f),
+ CVector(882.50067f, -1025.4459f, 5.14077f),
+ CVector(912.84821f, -1026.7874f, 8.3415451f),
+ CVector(943.68274f, -1026.6914f, 11.341879f),
+ CVector(974.4129f, -1027.3682f, 14.410345f),
+ CVector(1004.1079f, -1036.0778f, 14.92961f),
+ CVector(1030.1144f, -1051.1224f, 14.850387f),
+ CVector(1058.7585f, -1060.342f, 14.821624f),
+ CVector(1087.7797f, -1068.3263f, 14.800561f),
+ CVector(1099.8807f, -1095.656f, 11.877907f),
+ CVector(1130.0005f, -1101.994f, 11.853914f),
+ CVector(1160.3809f, -1101.6355f, 11.854824f),
+ CVector(1191.8524f, -1102.1577f, 11.853843f),
+ CVector(1223.3307f, -1102.7448f, 11.852233f),
+ CVector(1253.564f, -1098.1045f, 11.853944f),
+ CVector(1262.0203f, -1069.1785f, 14.8147f),
+ CVector(1290.9998f, -1059.1882f, 14.816016f),
+ CVector(1316.246f, -1041.0635f, 14.81109f),
+ CVector(1331.7539f, -1013.835f, 14.81207f),
+ CVector(1334.0579f, -983.55402f, 14.827253f),
+ CVector(1323.2429f, -954.23083f, 14.954678f),
+ CVector(1302.7495f, -932.21216f, 14.962917f),
+ CVector(1317.418f, -905.89325f, 14.967506f),
+ CVector(1337.9503f, -883.5025f, 14.969675f),
+ CVector(1352.6929f, -855.96954f, 14.967854f),
+ CVector(1357.2388f, -826.26971f, 14.97295f),
+ CVector(1384.8668f, -812.47693f, 12.907736f),
+ CVector(1410.8983f, -795.39056f, 12.052228f),
+ CVector(1433.901f, -775.55811f, 11.96265f),
+ CVector(1443.8615f, -746.92511f, 11.976114f),
+ CVector(1457.7015f, -720.00903f, 11.971177f),
+ CVector(1481.5685f, -701.30237f, 11.977908f),
+ CVector(1511.4004f, -696.83295f, 11.972709f),
+ CVector(1542.1796f, -695.61676f, 11.970441f),
+ CVector(1570.3301f, -684.6239f, 11.969202f),
+ CVector(0.0f, 0.0f, 0.0f),
+};
+
+void
+CPacManPickups::GeneratePMPickUpsForRace(int32 race)
+{
+ const CVector *pPos = nil;
+ int i = 0;
+
+ if (race == 0) pPos = aRacePoints1; // there's only one available
+ assert(pPos != nil);
+
+ while (!pPos->IsZero()) {
+ while (aPMPickUps[i].m_eType != PACMAN_NONE)
+ i++;
+
+ aPMPickUps[i].m_eType = PACMAN_RACE;
+ aPMPickUps[i].m_vecPosn = *(pPos++);
+ if (race == 0) {
+ CObject* obj = new CObject(MI_DONKEYMAG, true);
+ if (obj != nil) {
+ obj->ObjectCreatedBy = MISSION_OBJECT;
+
+ obj->GetPosition() = aPMPickUps[i].m_vecPosn;
+ obj->SetOrientation(0.0f, 0.0f, -HALFPI);
+ obj->GetMatrix().UpdateRW();
+ obj->UpdateRwFrame();
+
+ obj->bAffectedByGravity = false;
+ obj->bExplosionProof = true;
+ obj->bUsesCollision = false;
+ obj->bIsPickup = false;
+
+ CWorld::Add(obj);
+ }
+ aPMPickUps[i].m_pObject = obj;
+ } else
+ aPMPickUps[i].m_pObject = nil;
+ }
+ bPMActive = true;
+}
+
+void
+CPacManPickups::GenerateOnePMPickUp(CVector pos)
+{
+ bPMActive = true;
+ aPMPickUps[0].m_eType = PACMAN_RACE;
+ aPMPickUps[0].m_vecPosn = pos;
+}
+
+void
+CPacManPickups::Render()
+{
+ if (!bPMActive) return;
+
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[6]));
+
+ RwV3d pos;
+ float w, h;
+
+ for (int i = 0; i < NUMPACMANPICKUPS; i++) {
+ switch (aPMPickUps[i].m_eType)
+ {
+ case PACMAN_SCRAMBLE:
+ case PACMAN_RACE:
+ if (CSprite::CalcScreenCoors(aPMPickUps[i].m_vecPosn, &pos, &w, &h, true) && pos.z < 100.0f) {
+ if (aPMPickUps[i].m_pObject != nil) {
+ aPMPickUps[i].m_pObject->GetMatrix().SetRotateZOnly((CTimer::GetTimeInMilliseconds() % 1024) * TWOPI / 1024.0f);
+ aPMPickUps[i].m_pObject->GetMatrix().UpdateRW();
+ aPMPickUps[i].m_pObject->UpdateRwFrame();
+ }
+ float fsin = Sin((CTimer::GetTimeInMilliseconds() % 1024) * 6.28f / 1024.0f); // yes, it is 6.28f when it was TWOPI just now...
+ CSprite::RenderOneXLUSprite(pos.x, pos.y, pos.z, 0.8f * w * fsin, 0.8f * h, 100, 50, 5, 255, 1.0f / pos.z, 255);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, FALSE);
+}
+
+void
+CPacManPickups::ClearPMPickUps()
+{
+ bPMActive = false;
+
+ for (int i = 0; i < NUMPACMANPICKUPS; i++) {
+ if (aPMPickUps[i].m_pObject != nil) {
+ CWorld::Remove(aPMPickUps[i].m_pObject);
+ delete aPMPickUps[i].m_pObject;
+ aPMPickUps[i].m_pObject = nil;
+ }
+ aPMPickUps[i].m_eType = PACMAN_NONE;
+ }
+}
+
+void
+CPacManPickups::StartPacManRace(int32 race)
+{
+ GeneratePMPickUpsForRace(race);
+ PillsEatenInRace = 0;
+}
+
+void
+CPacManPickups::StartPacManRecord()
+{
+ CollectGameState = 20;
+ LastPickUpCoors = FindPlayerCoors();
+}
+
+uint32
+CPacManPickups::QueryPowerPillsEatenInRace()
+{
+ return PillsEatenInRace;
+}
+
+void
+CPacManPickups::ResetPowerPillsEatenInRace()
+{
+ PillsEatenInRace = 0;
+}
+
+void
+CPacManPickups::CleanUpPacManStuff()
+{
+ ClearPMPickUps();
+}
+
+void
+CPacManPickups::StartPacManScramble(CVector pos, float scrambleMult, int16 count)
+{
+ GeneratePMPickUps(pos, scrambleMult, count, PACMAN_SCRAMBLE);
+}
+
+uint32
+CPacManPickups::QueryPowerPillsCarriedByPlayer()
+{
+ if (FindPlayerVehicle())
+ return FindPlayerVehicle()->m_nPacManPickupsCarried;
+ return 0;
+}
+
+void
+CPacManPickups::ResetPowerPillsCarriedByPlayer()
+{
+ if (FindPlayerVehicle() != nil) {
+ FindPlayerVehicle()->m_nPacManPickupsCarried = 0;
+ FindPlayerVehicle()->m_fMass /= FindPlayerVehicle()->m_fForceMultiplier;
+ FindPlayerVehicle()->m_fTurnMass /= FindPlayerVehicle()->m_fForceMultiplier;
+ FindPlayerVehicle()->m_fForceMultiplier = 1.0f;
+ }
+}
+
+STARTPATCHES
+ InjectHook(0x430220, CPickups::Init, PATCH_JUMP);
+ InjectHook(0x4303D0, CPickups::Update, PATCH_JUMP);
+ InjectHook(0x432440, CPickups::RenderPickUpText, PATCH_JUMP);
+ InjectHook(0x431C30, CPickups::DoCollectableEffects, PATCH_JUMP);
+ InjectHook(0x431F40, CPickups::DoMoneyEffects, PATCH_JUMP);
+ InjectHook(0x4321C0, CPickups::DoMineEffects, PATCH_JUMP);
+ InjectHook(0x431520, CPickups::DoPickUpEffects, PATCH_JUMP);
+ InjectHook(0x4304B0, CPickups::GenerateNewOne, PATCH_JUMP);
+ InjectHook(0x430660, CPickups::GenerateNewOne_WeaponType, PATCH_JUMP);
+ InjectHook(0x4307A0, CPickups::RemovePickUp, PATCH_JUMP);
+ InjectHook(0x430800, CPickups::RemoveAllFloatingPickups, PATCH_JUMP);
+ InjectHook(0x433D60, CPickups::AddToCollectedPickupsArray, PATCH_JUMP);
+ InjectHook(0x430770, CPickups::IsPickUpPickedUp, PATCH_JUMP);
+ InjectHook(0x430690, CPickups::ModelForWeapon, PATCH_JUMP);
+ InjectHook(0x4306F0, CPickups::WeaponForModel, PATCH_JUMP);
+ InjectHook(0x431510, CPickups::FindColourIndexForWeaponMI, PATCH_JUMP);/**/
+ InjectHook(0x433DF0, CPickups::GetActualPickupIndex, PATCH_JUMP);
+ InjectHook(0x433DB0, CPickups::GetNewUniquePickupIndex, PATCH_JUMP);
+ InjectHook(0x433B60, CPickups::PassTime, PATCH_JUMP);
+ InjectHook(0x4339F0, CPickups::GivePlayerGoodiesWithPickUpMI, PATCH_JUMP);
+ InjectHook(0x433F60, CPickups::Load, PATCH_JUMP);
+ InjectHook(0x433E40, CPickups::Save, PATCH_JUMP);
+ InjectHook(0x433BA0, &CPickup::GiveUsAPickUpObject, PATCH_JUMP);
+ InjectHook(0x430860, &CPickup::Update, PATCH_JUMP);
+ InjectHook(0x4331B0, &CPacManPickup::Update, PATCH_JUMP);
+ InjectHook(0x432760, CPacManPickups::Init, PATCH_JUMP);
+ InjectHook(0x432800, CPacManPickups::Update, PATCH_JUMP);
+ InjectHook(0x432AE0, CPacManPickups::GeneratePMPickUps, PATCH_JUMP);
+ InjectHook(0x432D50, CPacManPickups::GeneratePMPickUpsForRace, PATCH_JUMP);
+ InjectHook(0x432F20, CPacManPickups::GenerateOnePMPickUp, PATCH_JUMP);
+ InjectHook(0x432F60, CPacManPickups::Render, PATCH_JUMP);
+ InjectHook(0x433150, CPacManPickups::ClearPMPickUps, PATCH_JUMP);
+ InjectHook(0x433340, CPacManPickups::StartPacManRace, PATCH_JUMP);
+ InjectHook(0x433360, CPacManPickups::StartPacManRecord, PATCH_JUMP);
+ InjectHook(0x4333A0, CPacManPickups::QueryPowerPillsEatenInRace, PATCH_JUMP);
+ InjectHook(0x4333B0, CPacManPickups::ResetPowerPillsEatenInRace, PATCH_JUMP);
+ InjectHook(0x4333C0, CPacManPickups::CleanUpPacManStuff, PATCH_JUMP);
+ InjectHook(0x4333D0, CPacManPickups::StartPacManScramble, PATCH_JUMP);
+ InjectHook(0x4333F0, CPacManPickups::QueryPowerPillsCarriedByPlayer, PATCH_JUMP);
+ InjectHook(0x433410, CPacManPickups::ResetPowerPillsCarriedByPlayer, PATCH_JUMP);
+
+ENDPATCHES
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index 4bb0ddff..b5b4f396 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -1,124 +1,147 @@
-#pragma once
-#include "Weapon.h"
-
-enum ePickupType : uint8
-{
- PICKUP_NONE = 0,
- PICKUP_IN_SHOP,
- PICKUP_ON_STREET,
- PICKUP_ONCE,
- PICKUP_ONCE_TIMEOUT,
- PICKUP_COLLECTABLE1,
- PICKUP_IN_SHOP_OUT_OF_STOCK,
- PICKUP_MONEY,
- PICKUP_MINE_INACTIVE,
- PICKUP_MINE_ARMED,
- PICKUP_NAUTICAL_MINE_INACTIVE,
- PICKUP_NAUTICAL_MINE_ARMED,
- PICKUP_FLOATINGPACKAGE,
- PICKUP_FLOATINGPACKAGE_FLOATING,
- PICKUP_ON_STREET_SLOW,
- PICKUP_NUMOFTYPES
-};
-
-class CEntity;
-class CObject;
-class CVehicle;
-class CPlayerPed;
-
-class CPickup
-{
-public:
- ePickupType m_eType;
- bool m_bRemoved;
- uint16 m_nQuantity;
- CObject *m_pObject;
- uint32 m_nTimer;
- int16 m_eModelIndex;
- uint16 m_nIndex;
- CVector m_vecPos;
-
- CObject *GiveUsAPickUpObject(int32 handle);
- bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId);
-private:
- bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; }
- inline bool CanBePickedUp(CPlayerPed *player);
- void RemoveKeepType();
- void Remove();
-};
-
-static_assert(sizeof(CPickup) == 0x1C, "CPickup: error");
-
-struct tPickupMessage
-{
- CVector2D m_pos;
- eWeaponType m_weaponType;
- CVector2D m_dist;
- CRGBA m_color;
- uint8 m_bOutOfStock : 1;
- uint8 m_quantity;
-};
-
-class CPickups
-{
- static int32 aPickUpsCollected[NUMCOLLECTEDPICKUPS];
- static int16 CollectedPickUpIndex;
- static int16 NumMessages;
- static tPickupMessage aMessages[NUMPICKUPMESSAGES];
-public:
- static void Init();
- static void Update();
- static void RenderPickUpText();
- static void DoCollectableEffects(CEntity *ent);
- static void DoMoneyEffects(CEntity *ent);
- static void DoMineEffects(CEntity *ent);
- static void DoPickUpEffects(CEntity *ent);
- static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity);
- static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity);
- static void RemovePickUp(int32 pickupIndex);
- static void RemoveAllFloatingPickups();
- static void AddToCollectedPickupsArray(int32 index);
- static bool IsPickUpPickedUp(int32 pickupId);
- static int32 ModelForWeapon(eWeaponType weaponType);
- static enum eWeaponType WeaponForModel(int32 model);
- static int32 FindColourIndexForWeaponMI(int32 model);
- static int32 GetActualPickupIndex(int32 index);
- static int32 GetNewUniquePickupIndex(int32 slot);
- static void PassTime(uint32 time);
- static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex);
- static void Load(uint8 *buf, uint32 size);
- static void Save(uint8 *buf, uint32 *size);
-
- static CPickup(&aPickUps)[NUMPICKUPS];
-
- // unused
- static bool &bPickUpcamActivated;
- static CVehicle *&pPlayerVehicle;
- static CVector &StaticCamCoors;
- static uint32 &StaticCamStartTime;
-};
-
-extern uint16 AmmoForWeapon[20];
-extern uint16 AmmoForWeapon_OnStreet[20];
-extern uint16 CostOfWeapon[20];
-
-class CPacManPickups
-{
-public:
- static void Init(void);
- static void Update(void);
- static void GeneratePMPickUps(CVector, float, int16, uint8);
- static void GeneratePMPickUpsForRace(int32);
- static void GenerateOnePMPickUp(CVector);
- static void Render(void);
- static void DoCleanUpPacManStuff(void);
- static void StartPacManRace(int32);
- static void StartPacManRecord(void);
- static uint32 QueryPowerPillsEatenInRace(void);
- static void ResetPowerPillsEatenInRace(void);
- static void CleanUpPacManStuff(void);
- static void StartPacManScramble(CVector, float, int16);
- static uint32 QueryPowerPillsCarriedByPlayer(void);
- static void ResetPowerPillsCarriedByPlayer(void);
-
-};
+#pragma once
+#include "Weapon.h"
+
+enum ePickupType : uint8
+{
+ PICKUP_NONE = 0,
+ PICKUP_IN_SHOP,
+ PICKUP_ON_STREET,
+ PICKUP_ONCE,
+ PICKUP_ONCE_TIMEOUT,
+ PICKUP_COLLECTABLE1,
+ PICKUP_IN_SHOP_OUT_OF_STOCK,
+ PICKUP_MONEY,
+ PICKUP_MINE_INACTIVE,
+ PICKUP_MINE_ARMED,
+ PICKUP_NAUTICAL_MINE_INACTIVE,
+ PICKUP_NAUTICAL_MINE_ARMED,
+ PICKUP_FLOATINGPACKAGE,
+ PICKUP_FLOATINGPACKAGE_FLOATING,
+ PICKUP_ON_STREET_SLOW,
+ PICKUP_NUMOFTYPES
+};
+
+class CEntity;
+class CObject;
+class CVehicle;
+class CPlayerPed;
+
+class CPickup
+{
+public:
+ ePickupType m_eType;
+ bool m_bRemoved;
+ uint16 m_nQuantity;
+ CObject *m_pObject;
+ uint32 m_nTimer;
+ int16 m_eModelIndex;
+ uint16 m_nIndex;
+ CVector m_vecPos;
+
+ CObject *GiveUsAPickUpObject(int32 handle);
+ bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId);
+private:
+ bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; }
+ inline bool CanBePickedUp(CPlayerPed *player);
+ void RemoveKeepType();
+ void Remove();
+};
+
+static_assert(sizeof(CPickup) == 0x1C, "CPickup: error");
+
+struct tPickupMessage
+{
+ CVector2D m_pos;
+ eWeaponType m_weaponType;
+ CVector2D m_dist;
+ CRGBA m_color;
+ uint8 m_bOutOfStock : 1;
+ uint8 m_quantity;
+};
+
+class CPickups
+{
+ static int32 aPickUpsCollected[NUMCOLLECTEDPICKUPS];
+ static int16 CollectedPickUpIndex;
+ static int16 NumMessages;
+ static tPickupMessage aMessages[NUMPICKUPMESSAGES];
+public:
+ static void Init();
+ static void Update();
+ static void RenderPickUpText();
+ static void DoCollectableEffects(CEntity *ent);
+ static void DoMoneyEffects(CEntity *ent);
+ static void DoMineEffects(CEntity *ent);
+ static void DoPickUpEffects(CEntity *ent);
+ static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity);
+ static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity);
+ static void RemovePickUp(int32 pickupIndex);
+ static void RemoveAllFloatingPickups();
+ static void AddToCollectedPickupsArray(int32 index);
+ static bool IsPickUpPickedUp(int32 pickupId);
+ static int32 ModelForWeapon(eWeaponType weaponType);
+ static enum eWeaponType WeaponForModel(int32 model);
+ static int32 FindColourIndexForWeaponMI(int32 model);
+ static int32 GetActualPickupIndex(int32 index);
+ static int32 GetNewUniquePickupIndex(int32 slot);
+ static void PassTime(uint32 time);
+ static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex);
+ static void Load(uint8 *buf, uint32 size);
+ static void Save(uint8 *buf, uint32 *size);
+
+ static CPickup(&aPickUps)[NUMPICKUPS];
+
+ // unused
+ static bool &bPickUpcamActivated;
+ static CVehicle *&pPlayerVehicle;
+ static CVector &StaticCamCoors;
+ static uint32 &StaticCamStartTime;
+};
+
+extern uint16 AmmoForWeapon[20];
+extern uint16 AmmoForWeapon_OnStreet[20];
+extern uint16 CostOfWeapon[20];
+
+enum ePacmanPickupType
+{
+ PACMAN_NONE,
+ PACMAN_SCRAMBLE,
+ PACMAN_RACE,
+};
+
+class CPacManPickup
+{
+public:
+ CVector m_vecPosn;
+ CObject *m_pObject;
+ uint8 m_eType;
+
+ void Update();
+};
+
+class CPacManPickups
+{
+ friend CPacManPickup;
+
+ static CPacManPickup aPMPickUps[NUMPACMANPICKUPS];
+ static CVector LastPickUpCoors;
+ static int PillsEatenInRace;
+ static bool bPMActive;
+public:
+ static void Init(void);
+ static void Update(void);
+ static void GeneratePMPickUps(CVector, float, int16, uint8);
+ static void GeneratePMPickUpsForRace(int32);
+ static void GenerateOnePMPickUp(CVector);
+ static void Render(void);
+ static void StartPacManRace(int32);
+ static void StartPacManRecord(void);
+ static uint32 QueryPowerPillsEatenInRace(void);
+ static void ResetPowerPillsEatenInRace(void);
+ static void ClearPMPickUps(void);
+ static void CleanUpPacManStuff(void);
+ static void StartPacManScramble(CVector, float, int16);
+ static uint32 QueryPowerPillsCarriedByPlayer(void);
+ static void ResetPowerPillsCarriedByPlayer(void);
+
+};
diff --git a/src/control/PowerPoints.cpp b/src/control/PowerPoints.cpp
index 4bc773a9..9a74e8d9 100644
--- a/src/control/PowerPoints.cpp
+++ b/src/control/PowerPoints.cpp
@@ -1,22 +1,22 @@
-#include "common.h"
-#include "PowerPoints.h"
-
-// Some cut beta feature
-
-void CPowerPoint::Update()
-{}
-
-void CPowerPoints::Init()
-{}
-
-void CPowerPoints::Update()
-{}
-
-void CPowerPoints::GenerateNewOne(float, float, float, float, float, float, uint8)
-{}
-
-void CPowerPoints::Save(uint8**, uint32*)
-{}
-
-void CPowerPoints::Load(uint8*, uint32)
+#include "common.h"
+#include "PowerPoints.h"
+
+// Some cut beta feature
+
+void CPowerPoint::Update()
+{}
+
+void CPowerPoints::Init()
+{}
+
+void CPowerPoints::Update()
+{}
+
+void CPowerPoints::GenerateNewOne(float, float, float, float, float, float, uint8)
+{}
+
+void CPowerPoints::Save(uint8**, uint32*)
+{}
+
+void CPowerPoints::Load(uint8*, uint32)
{} \ No newline at end of file
diff --git a/src/control/PowerPoints.h b/src/control/PowerPoints.h
index d7478076..ee3750cd 100644
--- a/src/control/PowerPoints.h
+++ b/src/control/PowerPoints.h
@@ -1,26 +1,26 @@
-#pragma once
-
-enum
-{
- POWERPOINT_NONE = 0,
- POWERPOINT_HEALTH,
- POWERPOINT_HIDEOUT_INDUSTRIAL,
- POWERPOINT_HIDEOUT_COMMERCIAL,
- POWERPOINT_HIDEOUT_SUBURBAN
-};
-
-class CPowerPoint
-{
-public:
- void Update();
-};
-
-class CPowerPoints
-{
-public:
- static void Init();
- static void Update();
- static void GenerateNewOne(float, float, float, float, float, float, uint8);
- static void Save(uint8**, uint32*);
- static void Load(uint8*, uint32);
+#pragma once
+
+enum
+{
+ POWERPOINT_NONE = 0,
+ POWERPOINT_HEALTH,
+ POWERPOINT_HIDEOUT_INDUSTRIAL,
+ POWERPOINT_HIDEOUT_COMMERCIAL,
+ POWERPOINT_HIDEOUT_SUBURBAN
+};
+
+class CPowerPoint
+{
+public:
+ void Update();
+};
+
+class CPowerPoints
+{
+public:
+ static void Init();
+ static void Update();
+ static void GenerateNewOne(float, float, float, float, float, float, uint8);
+ static void Save(uint8**, uint32*);
+ static void Load(uint8*, uint32);
}; \ No newline at end of file
diff --git a/src/control/Record.cpp b/src/control/Record.cpp
index 7c330311..ca4128e3 100644
--- a/src/control/Record.cpp
+++ b/src/control/Record.cpp
@@ -2,18 +2,522 @@
#include "patcher.h"
#include "Record.h"
+#include "FileMgr.h"
+#include "Pad.h"
+#include "Pools.h"
+#include "Streaming.h"
+#include "Timer.h"
+#include "VehicleModelInfo.h"
+#include "World.h"
+
uint16 &CRecordDataForGame::RecordingState = *(uint16*)0x95CC24;
+uint8*& CRecordDataForGame::pDataBuffer = *(uint8**)0x8F1B70;
+uint8*& CRecordDataForGame::pDataBufferPointer = *(uint8**)0x8F1AB0;
+int& CRecordDataForGame::FId = *(int*)0x885BA4;
+tGameBuffer& CRecordDataForGame::pDataBufferForFrame = *(tGameBuffer*)0x72CED0;
+
+#define MEMORY_FOR_GAME_RECORD (150000)
+
+void CRecordDataForGame::Init(void)
+{
+ RecordingState = STATE_NONE;
+ delete[] pDataBuffer;
+ pDataBufferPointer = nil;
+ pDataBuffer = nil;
+#ifndef GTA_PS2 // this stuff is not present on PS2
+ FId = CFileMgr::OpenFile("playback.dat", "r");
+ if (FId <= 0) {
+ if ((FId = CFileMgr::OpenFile("record.dat", "r")) <= 0)
+ RecordingState = STATE_NONE;
+ else {
+ CFileMgr::CloseFile(FId);
+ FId = CFileMgr::OpenFileForWriting("record.dat");
+ RecordingState = STATE_RECORD;
+ }
+ }
+ else {
+ RecordingState = STATE_PLAYBACK;
+ }
+ if (RecordingState == STATE_PLAYBACK) {
+ pDataBufferPointer = new uint8[MEMORY_FOR_GAME_RECORD];
+ pDataBuffer = pDataBufferPointer;
+ pDataBuffer[CFileMgr::Read(FId, (char*)pDataBufferPointer, MEMORY_FOR_GAME_RECORD) + 8] = (uint8)-1;
+ CFileMgr::CloseFile(FId);
+ }
+#else
+ RecordingState = STATE_NONE; // second time to make sure
+#endif
+}
+
+void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void)
+{
+ switch (RecordingState) {
+ case STATE_RECORD:
+ {
+ pDataBufferForFrame.m_fTimeStep = CTimer::GetTimeStep();
+ pDataBufferForFrame.m_nTimeInMilliseconds = CTimer::GetTimeInMilliseconds();
+ pDataBufferForFrame.m_nSizeOfPads[0] = 0;
+ pDataBufferForFrame.m_nSizeOfPads[1] = 0;
+ pDataBufferForFrame.m_nChecksum = CalcGameChecksum();
+ uint8* pController1 = PackCurrentPadValues(pDataBufferForFrame.m_ControllerBuffer, &CPad::GetPad(0)->OldState, &CPad::GetPad(0)->NewState);
+ pDataBufferForFrame.m_nSizeOfPads[0] = (pController1 - pDataBufferForFrame.m_ControllerBuffer) / 2;
+ uint8* pController2 = PackCurrentPadValues(pController1, &CPad::GetPad(1)->OldState, &CPad::GetPad(1)->NewState);
+ pDataBufferForFrame.m_nSizeOfPads[1] = (pController2 - pController1) / 2;
+ uint8* pEndPtr = pController2;
+ if ((pDataBufferForFrame.m_nSizeOfPads[0] + pDataBufferForFrame.m_nSizeOfPads[1]) & 1)
+ pEndPtr += 2;
+ CFileMgr::Write(FId, (char*)&pDataBufferForFrame, pEndPtr - (uint8*)&pDataBufferForFrame);
+ break;
+ }
+ case STATE_PLAYBACK:
+ if (pDataBufferPointer[8] == (uint8)-1)
+ CPad::GetPad(0)->NewState.Clear();
+ else {
+ tGameBuffer* pData = (tGameBuffer*)pDataBufferPointer;
+ CTimer::SetTimeInMilliseconds(pData->m_nTimeInMilliseconds);
+ CTimer::SetTimeStep(pData->m_fTimeStep);
+ uint8 size1 = pData->m_nSizeOfPads[0];
+ uint8 size2 = pData->m_nSizeOfPads[1];
+ pDataBufferPointer = (uint8*)&pData->m_ControllerBuffer;
+ pDataBufferPointer = UnPackCurrentPadValues(pDataBufferPointer, size1, &CPad::GetPad(0)->NewState);
+ pDataBufferPointer = UnPackCurrentPadValues(pDataBufferPointer, size2, &CPad::GetPad(1)->NewState);
+ if ((size1 + size2) & 1)
+ pDataBufferPointer += 2;
+ if (pData->m_nChecksum != CalcGameChecksum())
+ printf("Playback out of sync\n");
+ }
+ }
+}
+
+#define PROCESS_BUTTON_STATE_STORE(buf, os, ns, field, id) \
+ do { \
+ if (os->field != ns->field){ \
+ *buf++ = id; \
+ *buf++ = ns->field; \
+ } \
+ } while (0);
+
+uint8* CRecordDataForGame::PackCurrentPadValues(uint8* buf, CControllerState* os, CControllerState* ns)
+{
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickX, 0);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickY, 1);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickX, 2);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickY, 3);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder1, 4);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder2, 5);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShoulder1, 6);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShoulder2, 7);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadUp, 8);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadDown, 9);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadLeft, 10);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadRight, 11);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, Start, 12);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, Select, 13);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, Square, 14);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, Triangle, 15);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, Cross, 16);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, Circle, 17);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShock, 18);
+ PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShock, 19);
+ return buf;
+}
+#undef PROCESS_BUTTON_STATE_STORE
+
+#define PROCESS_BUTTON_STATE_RESTORE(buf, state, field, id) case id: state->field = *buf++; break;
+
+uint8* CRecordDataForGame::UnPackCurrentPadValues(uint8* buf, uint8 total, CControllerState* state)
+{
+ for (uint8 i = 0; i < total; i++) {
+ switch (*buf++) {
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickX, 0);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickY, 1);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickX, 2);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickY, 3);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder1, 4);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder2, 5);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShoulder1, 6);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShoulder2, 7);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadUp, 8);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadDown, 9);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadLeft, 10);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadRight, 11);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, Start, 12);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, Select, 13);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, Square, 14);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, Triangle, 15);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, Cross, 16);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, Circle, 17);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShock, 18);
+ PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShock, 19);
+ }
+ }
+ return buf;
+}
+
+#undef PROCESS_BUTTON_STATE_RESTORE
+
+uint16 CRecordDataForGame::CalcGameChecksum(void)
+{
+ uint32 checksum = 0;
+ int i = CPools::GetPedPool()->GetSize();
+ while (i--) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ checksum ^= pPed->GetModelIndex() ^ *(uint32*)&pPed->GetPosition().z ^ *(uint32*)&pPed->GetPosition().y ^ *(uint32*)&pPed->GetPosition().x;
+ }
+ i = CPools::GetVehiclePool()->GetSize();
+ while (i--) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ checksum ^= pVehicle->GetModelIndex() ^ *(uint32*)&pVehicle->GetPosition().z ^ *(uint32*)&pVehicle->GetPosition().y ^ *(uint32*)&pVehicle->GetPosition().x;
+ }
+ return checksum ^ checksum >> 16;
+}
+
+uint8& CRecordDataForChase::Status = *(uint8*)0x95CDCE;
+int& CRecordDataForChase::PositionChanges = *(int*)0x8F59C8;
+uint8& CRecordDataForChase::CurrentCar = *(uint8*)0x95CDC9;
+CAutomobile* (&CRecordDataForChase::pChaseCars)[NUM_CHASE_CARS] = *(CAutomobile * (*)[NUM_CHASE_CARS])*(uintptr*)0x6F46A8;
+uint32& CRecordDataForChase::AnimStartTime = *(uint32*)0x8F1AEC;
+float& CRecordDataForChase::AnimTime = *(float*)0x880F88;
+CCarStateEachFrame* (&CRecordDataForChase::pBaseMemForCar)[NUM_CHASE_CARS] = *(CCarStateEachFrame * (*)[NUM_CHASE_CARS])*(uintptr*)0x70EA18;
+float& CRecordDataForChase::TimeMultiplier = *(float*)0x8E2A94;
+int& CRecordDataForChase::FId2 = *(int*)0x8E2C18;
+
+#define CHASE_SCENE_LENGTH_IN_SECONDS (80)
+#define CHASE_SCENE_FRAMES_PER_SECOND (15) // skipping every second frame
+#define CHASE_SCENE_FRAMES_IN_RECORDING (CHASE_SCENE_LENGTH_IN_SECONDS * CHASE_SCENE_FRAMES_PER_SECOND)
+#define CHASE_SCENE_LENGTH_IN_FRAMES (CHASE_SCENE_FRAMES_IN_RECORDING * 2)
+
+void CRecordDataForChase::Init(void)
+{
+ Status = STATE_NONE;
+ PositionChanges = 0;
+ CurrentCar = 0;
+ for (int i = 0; i < NUM_CHASE_CARS; i++)
+ pChaseCars[i] = nil;
+ AnimStartTime = 0;
+}
+
+void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void)
+{
+ switch (Status) {
+ case STATE_NONE:
+ return;
+ case STATE_RECORD:
+ {
+ if ((CTimer::GetFrameCounter() & 1) == 0)
+ StoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2]);
+ if (CTimer::GetFrameCounter() < CHASE_SCENE_LENGTH_IN_FRAMES * 2)
+ return;
+ CFileMgr::SetDir("data\\paths");
+ sprintf(gString, "chase%d.dat", CurrentCar);
+ int fid = CFileMgr::OpenFileForWriting(gString);
+ uint32 fs = CHASE_SCENE_LENGTH_IN_FRAMES * sizeof(CCarStateEachFrame);
+ printf("FileSize:%d\n", fs);
+ CFileMgr::Write(fid, (char*)pBaseMemForCar[CurrentCar], fs);
+ CFileMgr::CloseFile(fid);
+ CFileMgr::SetDir("");
+ sprintf(gString, "car%d.max", CurrentCar);
+ int fid2 = CFileMgr::OpenFileForWriting(gString);
+ for (int i = 0; i < CHASE_SCENE_FRAMES_IN_RECORDING; i++) {
+ // WTF? Was it ever used?
+#ifdef FIX_BUGS
+ CCarStateEachFrame* pState = pBaseMemForCar[CurrentCar];
+#else
+ CCarStateEachFrame* pState = (CCarStateEachFrame*)pChaseCars[CurrentCar];
+#endif
+ CVector right = CVector(pState->rightX, pState->rightY, pState->rightZ) / INT8_MAX;
+ CVector forward = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / INT8_MAX;
+ CVector up = CrossProduct(right, forward);
+ sprintf(gString, "%f %f %f\n", pState->pos.x, pState->pos.y, pState->pos.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ sprintf(gString, "%f %f %f\n", right.x, right.y, right.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ sprintf(gString, "%f %f %f\n", forward.x, forward.y, forward.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ sprintf(gString, "%f %f %f\n", up.x, up.y, up.z);
+ CFileMgr::Write(fid2, gString, strlen(gString) - 1);
+ }
+ CFileMgr::CloseFile(fid2);
+ }
+ case STATE_PLAYBACK:
+ case STATE_PLAYBACK_BEFORE_RECORDING:
+ case STATE_PLAYBACK_INIT:
+ break;
+ }
+}
+
+struct tCoors {
+ CVector pos;
+ float angle;
+};
+
+// I guess developer was filling this with actual data before running the game
+tCoors NewCoorsForRecordedCars[7];
+
+void CRecordDataForChase::SaveOrRetrieveCarPositions(void)
+{
+ switch (Status) {
+ case STATE_NONE:
+ return;
+ case STATE_RECORD:
+ case STATE_PLAYBACK_BEFORE_RECORDING:
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (i != CurrentCar && CTimer::GetFrameCounter()) {
+ RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CTimer::GetFrameCounter() / 2], false);
+ pChaseCars[i]->GetMatrix().UpdateRW();
+ pChaseCars[i]->UpdateRwFrame();
+ }
+ }
+ if (Status == STATE_PLAYBACK_BEFORE_RECORDING && CTimer::GetFrameCounter()) {
+ RestoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2], false);
+ pChaseCars[CurrentCar]->GetMatrix().UpdateRW();
+ pChaseCars[CurrentCar]->UpdateRwFrame();
+ }
+ if (CPad::GetPad(0)->GetLeftShockJustDown() && CPad::GetPad(0)->GetRightShockJustDown()) {
+ if (!CPad::GetPad(0)->GetRightShockJustDown()) {
+ pChaseCars[CurrentCar]->GetPosition() = NewCoorsForRecordedCars[PositionChanges].pos;
+ pChaseCars[CurrentCar]->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ pChaseCars[CurrentCar]->GetMatrix().SetRotateZOnly(DEGTORAD(NewCoorsForRecordedCars[PositionChanges].angle));
+ ++PositionChanges;
+ }
+ if (Status == STATE_PLAYBACK_BEFORE_RECORDING) {
+ Status = STATE_RECORD;
+ pChaseCars[CurrentCar]->m_status = STATUS_PLAYER;
+ }
+ }
+ break;
+ case STATE_PLAYBACK_INIT:
+ Status = STATE_PLAYBACK;
+ break;
+ case STATE_PLAYBACK:
+ {
+ TimeMultiplier += CTimer::GetTimeStepNonClippedInSeconds();
+ float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier);
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (!pBaseMemForCar[i])
+ continue;
+ if (!pChaseCars[i])
+ continue;
+ if (EndOfFrameTime < CHASE_SCENE_FRAMES_IN_RECORDING - 1) {
+ int FlooredEOFTime = EndOfFrameTime;
+ RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][FlooredEOFTime], false);
+ CMatrix tmp;
+ float dp = EndOfFrameTime - FlooredEOFTime;
+ RestoreInfoForMatrix(tmp, &pBaseMemForCar[i][FlooredEOFTime + 1]);
+ pChaseCars[i]->GetRight() += (tmp.GetRight() - pChaseCars[i]->GetRight()) * dp;
+ pChaseCars[i]->GetForward() += (tmp.GetForward() - pChaseCars[i]->GetForward()) * dp;
+ pChaseCars[i]->GetUp() += (tmp.GetUp() - pChaseCars[i]->GetUp()) * dp;
+ pChaseCars[i]->GetPosition() += (tmp.GetPosition() - pChaseCars[i]->GetPosition()) * dp;
+ }
+ else{
+ RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CHASE_SCENE_FRAMES_IN_RECORDING - 1], true);
+ if (i == 0)
+ pChaseCars[i]->GetPosition().z += 0.2f;
+ }
+ pChaseCars[i]->GetMatrix().UpdateRW();
+ pChaseCars[i]->UpdateRwFrame();
+ pChaseCars[i]->RemoveAndAdd();
+ }
+ break;
+ }
+ }
+}
+
+void CRecordDataForChase::StoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState)
+{
+ pState->rightX = INT8_MAX * pCar->GetRight().x;
+ pState->rightY = INT8_MAX * pCar->GetRight().y;
+ pState->rightZ = INT8_MAX * pCar->GetRight().z;
+ pState->forwardX = INT8_MAX * pCar->GetForward().x;
+ pState->forwardY = INT8_MAX * pCar->GetForward().y;
+ pState->forwardZ = INT8_MAX * pCar->GetForward().z;
+ pState->pos = pCar->GetPosition();
+ pState->velX = 0.5f * INT16_MAX * pCar->GetMoveSpeed().x;
+ pState->velY = 0.5f * INT16_MAX * pCar->GetMoveSpeed().y;
+ pState->velZ = 0.5f * INT16_MAX * pCar->GetMoveSpeed().z;
+ pState->wheel = 20 * pCar->m_fSteerAngle;
+ pState->gas = 100 * pCar->m_fGasPedal;
+ pState->brake = 100 * pCar->m_fBrakePedal;
+ pState->handbrake = pCar->bIsHandbrakeOn;
+}
+
+void CRecordDataForChase::RestoreInfoForMatrix(CMatrix& matrix, CCarStateEachFrame* pState)
+{
+ matrix.GetRight() = CVector(pState->rightX, pState->rightY, pState->rightZ) / INT8_MAX;
+ matrix.GetForward() = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / INT8_MAX;
+ matrix.GetUp() = CrossProduct(matrix.GetRight(), matrix.GetForward());
+ matrix.GetPosition() = pState->pos;
+}
+
+void CRecordDataForChase::RestoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState, bool stop)
+{
+ CVector oldPos = pCar->GetPosition();
+ RestoreInfoForMatrix(pCar->GetMatrix(), pState);
+ pCar->SetMoveSpeed(CVector(pState->velX, pState->velY, pState->velZ) / INT16_MAX / 0.5f);
+ pCar->SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ pCar->m_fSteerAngle = pState->wheel / 20.0f;
+ pCar->m_fGasPedal = pState->gas / 100.0f;
+ pCar->m_fBrakePedal = pState->brake / 100.0f;
+ pCar->bIsHandbrakeOn = pState->handbrake;
+ if ((oldPos - pCar->GetPosition()).Magnitude() > 15.0f) {
+ if (pCar == pChaseCars[14]) {
+ pCar->m_currentColour1 = 58;
+ pCar->m_currentColour2 = 1;
+ }
+ else
+ pCar->GetModelInfo()->ChooseVehicleColour(pCar->m_currentColour1, pCar->m_currentColour2);
+ }
+ pCar->m_fHealth = min(pCar->m_fHealth, 500.0f);
+ if (stop) {
+ pCar->m_fGasPedal = 0.0f;
+ pCar->m_fBrakePedal = 0.0f;
+ pCar->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ pCar->bIsHandbrakeOn = false;
+ }
+}
+
+void CRecordDataForChase::ProcessControlCars(void)
+{
+ if (Status != STATE_PLAYBACK)
+ return;
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (pChaseCars[i])
+ pChaseCars[i]->ProcessControl();
+ }
+}
+
+#if (defined(GTA_PS2) || defined(FIX_BUGS))
+bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad)
+{
+ // may be wrong
+ if (Status == STATE_NONE || Status == STATE_PLAYBACK)
+ return false;
+ return pad != 0;
+}
+#endif
+
+void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2)
+{
+ CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ if (!CStreaming::HasModelLoaded(mi))
+ return;
+ CAutomobile* pCar = new CAutomobile(mi, MISSION_VEHICLE);
+ pCar->GetPosition() = pos;
+ pCar->m_status = STATUS_PLAYER_PLAYBACKFROMBUFFER;
+ pCar->GetMatrix().SetRotateZOnly(DEGTORAD(angle));
+ pCar->pDriver = nil;
+ pCar->m_currentColour1 = colour1;
+ pCar->m_currentColour2 = colour2;
+ CWorld::Add(pCar);
+ *ppCar = pCar;
+}
+
+void RemoveUnusedCollision(void)
+{
+ static const char* dontDeleteArray[] = {
+ "rd_SrRoad2A50", "rd_SrRoad2A20", "rd_CrossRda1w22", "rd_CrossRda1rw22",
+ "road_broadway02", "road_broadway01", "com_21way5", "com_21way50",
+ "cm1waycrosscom", "com_21way20", "com_21way10", "road_broadway04",
+ "com_rvroads52", "com_roadsrv", "com_roadkb23", "com_roadkb22"
+ };
+ for (int i = 0; i < ARRAY_SIZE(dontDeleteArray); i++)
+ CModelInfo::GetModelInfo(dontDeleteArray[i], nil)->GetColModel()->level = LEVEL_NONE;
+ CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_NONE);
+ for (int i = 0; i < ARRAY_SIZE(dontDeleteArray); i++)
+ CModelInfo::GetModelInfo(dontDeleteArray[i], nil)->GetColModel()->level = LEVEL_COMMERCIAL;
+}
+
+void CRecordDataForChase::StartChaseScene(float startTime)
+{
+ char filename[28];
+ SetUpCarsForChaseScene();
+ Status = STATE_PLAYBACK;
+ AnimTime = startTime;
+ AnimStartTime = CTimer::GetTimeInMilliseconds();
+ RemoveUnusedCollision();
+ CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
+ CGame::TidyUpMemory(true, true);
+ CStreaming::ImGonnaUseStreamingMemory();
+ CFileMgr::SetDir("data\\paths");
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (!pChaseCars[i]) {
+ pBaseMemForCar[i] = nil;
+ continue;
+ }
+ sprintf(filename, "chase%d.dat", i);
+ FId2 = CFileMgr::OpenFile(filename, "rb");
+ if (FId2 <= 0) {
+ pBaseMemForCar[i] = nil;
+ continue;
+ }
+ pBaseMemForCar[i] = new CCarStateEachFrame[CHASE_SCENE_FRAMES_IN_RECORDING];
+ for (int j = 0; j < CHASE_SCENE_FRAMES_IN_RECORDING; j++) {
+ CFileMgr::Read(FId2, (char*)&pBaseMemForCar[i][j], sizeof(CCarStateEachFrame));
+ CFileMgr::Seek(FId2, sizeof(CCarStateEachFrame), 1);
+ }
+ CFileMgr::CloseFile(FId2);
+ }
+ CFileMgr::SetDir("");
+ CStreaming::IHaveUsedStreamingMemory();
+ TimeMultiplier = 0.0f;
+}
+
+void CRecordDataForChase::CleanUpChaseScene(void)
+{
+ if (Status != STATE_PLAYBACK_INIT && Status != STATE_PLAYBACK)
+ return;
+ Status = STATE_NONE;
+ CleanUpCarsForChaseScene();
+ for (int i = 0; i < NUM_CHASE_CARS; i++) {
+ if (pBaseMemForCar[i]) {
+ delete[] pBaseMemForCar[i];
+ pBaseMemForCar[i] = nil;
+ }
+ }
+}
+
+void CRecordDataForChase::SetUpCarsForChaseScene(void)
+{
+ GiveUsACar(MI_POLICE, CVector(273.54221f, -1167.1907f, 24.880601f), 63.0f, &pChaseCars[0], 2, 1);
+ GiveUsACar(MI_ENFORCER, CVector(231.1783f, -1388.8322f, 25.978201f), 90.0f, &pChaseCars[1], 2, 1);
+ GiveUsACar(MI_TAXI, CVector(184.3156f, -1473.251f, 25.978201f), 0.0f, &pChaseCars[4], 6, 6);
+ GiveUsACar(MI_CHEETAH, CVector(173.8868f, -1377.6514f, 25.978201f), 0.0f, &pChaseCars[6], 4, 5);
+ GiveUsACar(MI_STINGER, CVector(102.5946f, -943.93628f, 25.9781f), 270.0f, &pChaseCars[7], 53, 53);
+ GiveUsACar(MI_CHEETAH, CVector(-177.7157f, -862.18652f, 25.978201f), 155.0f, &pChaseCars[10], 41, 1);
+ GiveUsACar(MI_STINGER, CVector(-170.56979f, -889.02362f, 25.978201f), 154.0f, &pChaseCars[11], 10, 10);
+ GiveUsACar(MI_KURUMA, CVector(402.60809f, -917.49628f, 37.381001f), 90.0f, &pChaseCars[14], 34, 1);
+ GiveUsACar(MI_TAXI, CVector(-33.496201f, -938.4563f, 25.9781f), 266.0f, &pChaseCars[16], 6, 6);
+ GiveUsACar(MI_KURUMA, CVector(49.363098f, -987.60498f, 25.9781f), 0.0f, &pChaseCars[18], 51, 1);
+ GiveUsACar(MI_TAXI, CVector(179.0049f, -1154.6686f, 25.9781f), 0.0f, &pChaseCars[19], 6, 76);
+ GiveUsACar(MI_RUMPO, CVector(-28.9762f, -1031.3367f, 25.990601f), 242.0f, &pChaseCars[2], 1, 75);
+ GiveUsACar(MI_PATRIOT, CVector(114.1564f, -796.69379f, 24.978201f), 180.0f, &pChaseCars[3], 0, 0);
+}
+
+void CRecordDataForChase::CleanUpCarsForChaseScene(void)
+{
+ for (int i = 0; i < NUM_CHASE_CARS; i++)
+ RemoveCarFromChase(i);
+}
-uint8 &CRecordDataForChase::Status = *(uint8*)0x95CDCE;
+void CRecordDataForChase::RemoveCarFromChase(int32 i)
+{
+ if (!pChaseCars[i])
+ return;
+ CWorld::Remove(pChaseCars[i]);
+ delete pChaseCars[i];
+ pChaseCars[i] = nil;
+}
-WRAPPER void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void) { EAXJMP(0x4341F0); }
-WRAPPER void CRecordDataForGame::Init(void) { EAXJMP(0x4340F0); }
+CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32 i)
+{
+ CVehicle* pVehicle = pChaseCars[i];
+ pChaseCars[i] = nil;
+ pVehicle->m_status = STATUS_PHYSICS;
+ return pVehicle;
+}
-WRAPPER void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void) { EAXJMP(0x4347F0); }
-WRAPPER void CRecordDataForChase::ProcessControlCars(void) { EAXJMP(0x435540); }
-WRAPPER void CRecordDataForChase::SaveOrRetrieveCarPositions(void) { EAXJMP(0x434B20); }
-WRAPPER void CRecordDataForChase::StartChaseScene(float) { EAXJMP(0x435690); }
-WRAPPER void CRecordDataForChase::CleanUpChaseScene() { EAXJMP(0x4357C0); }
-WRAPPER void CRecordDataForChase::RemoveCarFromChase(int32) { EAXJMP(0x435BC0); }
-WRAPPER CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32) { EAXJMP(0x435C00); }
-WRAPPER void CRecordDataForChase::Init(void) { EAXJMP(0x434780); }
diff --git a/src/control/Record.h b/src/control/Record.h
index e52a623e..4abeb68a 100644
--- a/src/control/Record.h
+++ b/src/control/Record.h
@@ -1,34 +1,106 @@
#pragma once
+class CAutomobile;
class CVehicle;
+class CControllerState;
-enum {
- RECORDSTATE_0,
- RECORDSTATE_1,
- RECORDSTATE_2,
+class CCarStateEachFrame
+{
+public:
+ int16 velX;
+ int16 velY;
+ int16 velZ;
+ int8 rightX;
+ int8 rightY;
+ int8 rightZ;
+ int8 forwardX;
+ int8 forwardY;
+ int8 forwardZ;
+ int8 wheel;
+ uint8 gas;
+ uint8 brake;
+ bool handbrake;
+ CVector pos;
};
+extern char* gString;
+
class CRecordDataForChase
{
-public:
+ enum {
+ NUM_CHASE_CARS = 20
+ };
+ enum {
+ STATE_NONE = 0,
+ STATE_RECORD = 1,
+ STATE_PLAYBACK_INIT = 2,
+ STATE_PLAYBACK = 3,
+ STATE_PLAYBACK_BEFORE_RECORDING = 4
+ };
static uint8 &Status;
+ static int &PositionChanges;
+ static uint8 &CurrentCar;
+ static CAutomobile*(&pChaseCars)[NUM_CHASE_CARS];
+ static float &AnimTime;
+ static uint32 &AnimStartTime;
+ static CCarStateEachFrame* (&pBaseMemForCar)[NUM_CHASE_CARS];
+ static float &TimeMultiplier;
+ static int &FId2;
+public:
+
+ static bool IsRecording(void) { return Status == STATE_RECORD; }
+ static void Init(void);
static void SaveOrRetrieveDataForThisFrame(void);
- static void ProcessControlCars(void);
static void SaveOrRetrieveCarPositions(void);
+ static void StoreInfoForCar(CAutomobile*, CCarStateEachFrame*);
+ static void RestoreInfoForMatrix(CMatrix&, CCarStateEachFrame*);
+ static void RestoreInfoForCar(CAutomobile*, CCarStateEachFrame*, bool);
+ static void ProcessControlCars(void);
+#if (defined(GTA_PS2) || defined(FIX_BUGS))
+ static bool ShouldThisPadBeLeftAlone(uint8 pad);
+#endif
+ static void GiveUsACar(int32, CVector, float, CAutomobile**, uint8, uint8);
static void StartChaseScene(float);
- static void CleanUpChaseScene();
+ static void CleanUpChaseScene(void);
+ static void SetUpCarsForChaseScene(void);
+ static void CleanUpCarsForChaseScene(void);
static void RemoveCarFromChase(int32);
static CVehicle* TurnChaseCarIntoScriptCar(int32);
- static void Init(void);
+
};
+struct tGameBuffer
+{
+ float m_fTimeStep;
+ uint32 m_nTimeInMilliseconds;
+ uint8 m_nSizeOfPads[2];
+ uint16 m_nChecksum;
+ uint8 m_ControllerBuffer[116];
+};
class CRecordDataForGame
{
+ enum {
+ STATE_NONE = 0,
+ STATE_RECORD = 1,
+ STATE_PLAYBACK = 2,
+ };
+ static uint16& RecordingState;
+ static uint8* &pDataBuffer;
+ static uint8* &pDataBufferPointer;
+ static int &FId;
+ static tGameBuffer &pDataBufferForFrame;
+
public:
- static uint16 &RecordingState;
+ static bool IsRecording() { return RecordingState == STATE_RECORD; }
+ static bool IsPlayingBack() { return RecordingState == STATE_PLAYBACK; }
static void SaveOrRetrieveDataForThisFrame(void);
static void Init(void);
+
+private:
+ static uint16 CalcGameChecksum(void);
+ static uint8* PackCurrentPadValues(uint8*, CControllerState*, CControllerState*);
+ static uint8* UnPackCurrentPadValues(uint8*, uint8, CControllerState*);
};
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index 2e325249..0da32dd2 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -1107,7 +1107,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
CStreaming::LoadScene(ff_coord);
}
if (cam_mode == REPLAYCAMMODE_ASSTORED)
- TheCamera.CarZoomIndicator = 5.0f;
+ TheCamera.CarZoomIndicator = CAM_ZOOM_CINEMATIC;
}
void CReplay::StoreStuffInMem(void)
@@ -1129,8 +1129,8 @@ void CReplay::StoreStuffInMem(void)
pEmptyReferences = CReferences::pEmptyList;
pStoredCam = new uint8[sizeof(CCamera)];
memcpy(pStoredCam, &TheCamera, sizeof(CCamera));
- pRadarBlips = new uint8[sizeof(CBlip) * NUMRADARBLIPS];
- memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(CBlip));
+ pRadarBlips = new uint8[sizeof(sRadarTrace) * NUMRADARBLIPS];
+ memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(sRadarTrace));
PlayerWanted = *FindPlayerPed()->m_pWanted;
PlayerInfo = CWorld::Players[0];
Time1 = CTimer::GetTimeInMilliseconds();
@@ -1179,7 +1179,7 @@ void CReplay::RestoreStuffFromMem(void)
memcpy(&TheCamera, pStoredCam, sizeof(CCamera));
delete[] pStoredCam;
pStoredCam = nil;
- memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(CBlip) * NUMRADARBLIPS);
+ memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS);
delete[] pRadarBlips;
pRadarBlips = nil;
FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted);
diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp
index 8e983555..788a054a 100644
--- a/src/control/Restart.cpp
+++ b/src/control/Restart.cpp
@@ -21,234 +21,234 @@ CVector(&CRestart::PoliceRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_R
float(&CRestart::PoliceRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D20;
uint16 &CRestart::NumberOfPoliceRestarts = *(uint16*)0x95CC44;
-void
-CRestart::Initialise()
-{
- OverridePoliceStationLevel = LEVEL_NONE;
- OverrideHospitalLevel = LEVEL_NONE;
- bFadeInAfterNextArrest = true;
- bFadeInAfterNextDeath = true;
- OverrideHeading = 0.0f;
- OverridePosition = CVector(0.0f, 0.0f, 0.0f);
- bOverrideRestart = false;
- NumberOfPoliceRestarts = 0;
- NumberOfHospitalRestarts = 0;
-
- for (int i = 0; i < NUM_RESTART_POINTS; i++) {
- HospitalRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
- HospitalRestartHeadings[i] = 0.0f;
- PoliceRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
- PoliceRestartHeadings[i] = 0.0f;
- }
+void
+CRestart::Initialise()
+{
+ OverridePoliceStationLevel = LEVEL_NONE;
+ OverrideHospitalLevel = LEVEL_NONE;
+ bFadeInAfterNextArrest = true;
+ bFadeInAfterNextDeath = true;
+ OverrideHeading = 0.0f;
+ OverridePosition = CVector(0.0f, 0.0f, 0.0f);
+ bOverrideRestart = false;
+ NumberOfPoliceRestarts = 0;
+ NumberOfHospitalRestarts = 0;
+
+ for (int i = 0; i < NUM_RESTART_POINTS; i++) {
+ HospitalRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
+ HospitalRestartHeadings[i] = 0.0f;
+ PoliceRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f);
+ PoliceRestartHeadings[i] = 0.0f;
+ }
+}
+
+void
+CRestart::AddHospitalRestartPoint(const CVector &pos, float heading)
+{
+ HospitalRestartPoints[NumberOfHospitalRestarts] = pos;
+ HospitalRestartHeadings[NumberOfHospitalRestarts++] = heading;
+}
+
+void
+CRestart::AddPoliceRestartPoint(const CVector &pos, float heading)
+{
+ PoliceRestartPoints[NumberOfPoliceRestarts] = pos;
+ PoliceRestartHeadings[NumberOfPoliceRestarts++] = heading;
+}
+
+void
+CRestart::OverrideNextRestart(const CVector &pos, float heading)
+{
+ bOverrideRestart = true;
+ OverridePosition = pos;
+ OverrideHeading = heading;
}
-void
-CRestart::AddHospitalRestartPoint(const CVector &pos, float heading)
-{
- HospitalRestartPoints[NumberOfHospitalRestarts] = pos;
- HospitalRestartHeadings[NumberOfHospitalRestarts++] = heading;
+void
+CRestart::CancelOverrideRestart()
+{
+ bOverrideRestart = false;
}
-void
-CRestart::AddPoliceRestartPoint(const CVector &pos, float heading)
-{
- PoliceRestartPoints[NumberOfPoliceRestarts] = pos;
- PoliceRestartHeadings[NumberOfPoliceRestarts++] = heading;
+void
+CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
+{
+ if (bOverrideRestart) {
+ *outPos = OverridePosition;
+ *outHeading = OverrideHeading;
+ CancelOverrideRestart();
+ return;
+ }
+
+ eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
+ float fMinDist = 16000000.0f;
+ int closestPoint = NUM_RESTART_POINTS;
+
+ // find closest point on this level
+ for (int i = 0; i < NumberOfHospitalRestarts; i++) {
+ if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) {
+ float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
+ if (fMinDist >= dist) {
+ fMinDist = dist;
+ closestPoint = i;
+ }
+ }
+ }
+
+ // if we didn't find anything, find closest point on any level
+ if (closestPoint == NUM_RESTART_POINTS) {
+ for (int i = 0; i < NumberOfHospitalRestarts; i++) {
+ float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
+ if (fMinDist >= dist) {
+ fMinDist = dist;
+ closestPoint = i;
+ }
+ }
+ }
+
+ // if we still didn't find anything, find closest path node
+ if (closestPoint == NUM_RESTART_POINTS) {
+ *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
+ *outHeading = 0.0f;
+ printf("Couldn't find a hospital restart zone near the player %f %f %f->%f %f %f\n", pos.x, pos.y, pos.z, outPos->x, outPos->y, outPos->z);
+ } else {
+ *outPos = HospitalRestartPoints[closestPoint];
+ *outHeading = HospitalRestartHeadings[closestPoint];
+ }
}
-void
-CRestart::OverrideNextRestart(const CVector &pos, float heading)
-{
- bOverrideRestart = true;
- OverridePosition = pos;
- OverrideHeading = heading;
+void
+CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
+{
+ if (bOverrideRestart) {
+ *outPos = OverridePosition;
+ *outHeading = OverrideHeading;
+ CancelOverrideRestart();
+ return;
+ }
+
+ eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
+ float fMinDist = 16000000.0f;
+ int closestPoint = NUM_RESTART_POINTS;
+
+ // find closest point on this level
+ for (int i = 0; i < NumberOfPoliceRestarts; i++) {
+ if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) {
+ float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
+ if (fMinDist >= dist) {
+ fMinDist = dist;
+ closestPoint = i;
+ }
+ }
+ }
+
+ // if we didn't find anything, find closest point on any level
+ if (closestPoint == NUM_RESTART_POINTS) {
+ for (int i = 0; i < NumberOfPoliceRestarts; i++) {
+ float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
+ if (fMinDist >= dist) {
+ fMinDist = dist;
+ closestPoint = i;
+ }
+ }
+ }
+
+ // if we still didn't find anything, find closest path node
+ if (closestPoint == NUM_RESTART_POINTS) {
+ printf("Couldn't find a police restart zone near the player\n");
+ *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
+ *outHeading = 0.0f;
+ } else {
+ *outPos = PoliceRestartPoints[closestPoint];
+ *outHeading = PoliceRestartHeadings[closestPoint];
+ }
}
-void
-CRestart::CancelOverrideRestart()
-{
- bOverrideRestart = false;
+void
+CRestart::LoadAllRestartPoints(uint8 *buf, uint32 size)
+{
+ Initialise();
+
+INITSAVEBUF
+ CheckSaveHeader(buf, 'R','S','T','\0', size - SAVE_HEADER_SIZE);
+
+ for (int i = 0; i < NUM_RESTART_POINTS; i++) {
+ HospitalRestartPoints[i] = ReadSaveBuf<CVector>(buf);
+ HospitalRestartHeadings[i] = ReadSaveBuf<float>(buf);
+ }
+
+ for (int i = 0; i < NUM_RESTART_POINTS; i++) {
+ PoliceRestartPoints[i] = ReadSaveBuf<CVector>(buf);
+ PoliceRestartHeadings[i] = ReadSaveBuf<float>(buf);
+ }
+
+ NumberOfHospitalRestarts = ReadSaveBuf<uint16>(buf);
+ NumberOfPoliceRestarts = ReadSaveBuf<uint16>(buf);
+ bOverrideRestart = ReadSaveBuf<bool>(buf);
+
+ // skip something unused
+ ReadSaveBuf<uint8>(buf);
+ ReadSaveBuf<uint16>(buf);
+
+ OverridePosition = ReadSaveBuf<CVector>(buf);
+ OverrideHeading = ReadSaveBuf<float>(buf);
+ bFadeInAfterNextDeath = ReadSaveBuf<bool>(buf);
+ bFadeInAfterNextArrest = ReadSaveBuf<bool>(buf);
+ OverrideHospitalLevel = ReadSaveBuf<uint8>(buf);
+ OverridePoliceStationLevel = ReadSaveBuf<uint8>(buf);
+VALIDATESAVEBUF(size);
}
-void
-CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
-{
- if (bOverrideRestart) {
- *outPos = OverridePosition;
- *outHeading = OverrideHeading;
- CancelOverrideRestart();
- return;
- }
-
- eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
- float fMinDist = 16000000.0f;
- int closestPoint = NUM_RESTART_POINTS;
-
- // find closest point on this level
- for (int i = 0; i < NumberOfHospitalRestarts; i++) {
- if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) {
- float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
- if (fMinDist >= dist) {
- fMinDist = dist;
- closestPoint = i;
- }
- }
- }
-
- // if we didn't find anything, find closest point on any level
- if (closestPoint == NUM_RESTART_POINTS) {
- for (int i = 0; i < NumberOfHospitalRestarts; i++) {
- float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
- if (fMinDist >= dist) {
- fMinDist = dist;
- closestPoint = i;
- }
- }
- }
-
- // if we still didn't find anything, find closest path node
- if (closestPoint == NUM_RESTART_POINTS) {
- *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
- *outHeading = 0.0f;
- printf("Couldn't find a hospital restart zone near the player %f %f %f->%f %f %f\n", pos.x, pos.y, pos.z, outPos->x, outPos->y, outPos->z);
- } else {
- *outPos = HospitalRestartPoints[closestPoint];
- *outHeading = HospitalRestartHeadings[closestPoint];
- }
+void
+CRestart::SaveAllRestartPoints(uint8 *buf, uint32 *size)
+{
+ *size = SAVE_HEADER_SIZE
+ + sizeof(HospitalRestartPoints)
+ + sizeof(HospitalRestartHeadings)
+ + sizeof(PoliceRestartPoints)
+ + sizeof(PoliceRestartHeadings)
+ + sizeof(NumberOfHospitalRestarts)
+ + sizeof(NumberOfPoliceRestarts)
+ + sizeof(bOverrideRestart)
+ + sizeof(uint8)
+ + sizeof(uint16)
+ + sizeof(OverridePosition)
+ + sizeof(OverrideHeading)
+ + sizeof(bFadeInAfterNextDeath)
+ + sizeof(bFadeInAfterNextArrest)
+ + sizeof(OverrideHospitalLevel)
+ + sizeof(OverridePoliceStationLevel); // == 292
+
+INITSAVEBUF
+ WriteSaveHeader(buf, 'R','S','T','\0', *size - SAVE_HEADER_SIZE);
+
+ for (int i = 0; i < NUM_RESTART_POINTS; i++) {
+ WriteSaveBuf(buf, HospitalRestartPoints[i]);
+ WriteSaveBuf(buf, HospitalRestartHeadings[i]);
+ }
+
+ for (int i = 0; i < NUM_RESTART_POINTS; i++) {
+ WriteSaveBuf(buf, PoliceRestartPoints[i]);
+ WriteSaveBuf(buf, PoliceRestartHeadings[i]);
+ }
+
+ WriteSaveBuf(buf, NumberOfHospitalRestarts);
+ WriteSaveBuf(buf, NumberOfPoliceRestarts);
+ WriteSaveBuf(buf, bOverrideRestart);
+
+ WriteSaveBuf(buf, (uint8)0);
+ WriteSaveBuf(buf, (uint16)0);
+
+ WriteSaveBuf(buf, OverridePosition);
+ WriteSaveBuf(buf, OverrideHeading);
+ WriteSaveBuf(buf, bFadeInAfterNextDeath);
+ WriteSaveBuf(buf, bFadeInAfterNextArrest);
+ WriteSaveBuf(buf, OverrideHospitalLevel);
+ WriteSaveBuf(buf, OverridePoliceStationLevel);
+VALIDATESAVEBUF(*size);
}
-void
-CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, float *outHeading)
-{
- if (bOverrideRestart) {
- *outPos = OverridePosition;
- *outHeading = OverrideHeading;
- CancelOverrideRestart();
- return;
- }
-
- eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
- float fMinDist = 16000000.0f;
- int closestPoint = NUM_RESTART_POINTS;
-
- // find closest point on this level
- for (int i = 0; i < NumberOfPoliceRestarts; i++) {
- if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) {
- float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
- if (fMinDist >= dist) {
- fMinDist = dist;
- closestPoint = i;
- }
- }
- }
-
- // if we didn't find anything, find closest point on any level
- if (closestPoint == NUM_RESTART_POINTS) {
- for (int i = 0; i < NumberOfPoliceRestarts; i++) {
- float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
- if (fMinDist >= dist) {
- fMinDist = dist;
- closestPoint = i;
- }
- }
- }
-
- // if we still didn't find anything, find closest path node
- if (closestPoint == NUM_RESTART_POINTS) {
- printf("Couldn't find a police restart zone near the player\n");
- *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos;
- *outHeading = 0.0f;
- } else {
- *outPos = PoliceRestartPoints[closestPoint];
- *outHeading = PoliceRestartHeadings[closestPoint];
- }
-}
-
-void
-CRestart::LoadAllRestartPoints(uint8 *buf, uint32 size)
-{
- Initialise();
-
-INITSAVEBUF
- CheckSaveHeader(buf, 'R','S','T','\0', size - SAVE_HEADER_SIZE);
-
- for (int i = 0; i < NUM_RESTART_POINTS; i++) {
- HospitalRestartPoints[i] = ReadSaveBuf<CVector>(buf);
- HospitalRestartHeadings[i] = ReadSaveBuf<float>(buf);
- }
-
- for (int i = 0; i < NUM_RESTART_POINTS; i++) {
- PoliceRestartPoints[i] = ReadSaveBuf<CVector>(buf);
- PoliceRestartHeadings[i] = ReadSaveBuf<float>(buf);
- }
-
- NumberOfHospitalRestarts = ReadSaveBuf<uint16>(buf);
- NumberOfPoliceRestarts = ReadSaveBuf<uint16>(buf);
- bOverrideRestart = ReadSaveBuf<bool>(buf);
-
- // skip something unused
- ReadSaveBuf<uint8>(buf);
- ReadSaveBuf<uint16>(buf);
-
- OverridePosition = ReadSaveBuf<CVector>(buf);
- OverrideHeading = ReadSaveBuf<float>(buf);
- bFadeInAfterNextDeath = ReadSaveBuf<bool>(buf);
- bFadeInAfterNextArrest = ReadSaveBuf<bool>(buf);
- OverrideHospitalLevel = ReadSaveBuf<uint8>(buf);
- OverridePoliceStationLevel = ReadSaveBuf<uint8>(buf);
-VALIDATESAVEBUF(size);
-}
-
-void
-CRestart::SaveAllRestartPoints(uint8 *buf, uint32 *size)
-{
- *size = SAVE_HEADER_SIZE
- + sizeof(HospitalRestartPoints)
- + sizeof(HospitalRestartHeadings)
- + sizeof(PoliceRestartPoints)
- + sizeof(PoliceRestartHeadings)
- + sizeof(NumberOfHospitalRestarts)
- + sizeof(NumberOfPoliceRestarts)
- + sizeof(bOverrideRestart)
- + sizeof(uint8)
- + sizeof(uint16)
- + sizeof(OverridePosition)
- + sizeof(OverrideHeading)
- + sizeof(bFadeInAfterNextDeath)
- + sizeof(bFadeInAfterNextArrest)
- + sizeof(OverrideHospitalLevel)
- + sizeof(OverridePoliceStationLevel); // == 292
-
-INITSAVEBUF
- WriteSaveHeader(buf, 'R','S','T','\0', *size - SAVE_HEADER_SIZE);
-
- for (int i = 0; i < NUM_RESTART_POINTS; i++) {
- WriteSaveBuf(buf, HospitalRestartPoints[i]);
- WriteSaveBuf(buf, HospitalRestartHeadings[i]);
- }
-
- for (int i = 0; i < NUM_RESTART_POINTS; i++) {
- WriteSaveBuf(buf, PoliceRestartPoints[i]);
- WriteSaveBuf(buf, PoliceRestartHeadings[i]);
- }
-
- WriteSaveBuf(buf, NumberOfHospitalRestarts);
- WriteSaveBuf(buf, NumberOfPoliceRestarts);
- WriteSaveBuf(buf, bOverrideRestart);
-
- WriteSaveBuf(buf, (uint8)0);
- WriteSaveBuf(buf, (uint16)0);
-
- WriteSaveBuf(buf, OverridePosition);
- WriteSaveBuf(buf, OverrideHeading);
- WriteSaveBuf(buf, bFadeInAfterNextDeath);
- WriteSaveBuf(buf, bFadeInAfterNextArrest);
- WriteSaveBuf(buf, OverrideHospitalLevel);
- WriteSaveBuf(buf, OverridePoliceStationLevel);
-VALIDATESAVEBUF(*size);
-}
-
-
+
STARTPATCHES
InjectHook(0x435E20, &CRestart::Initialise, PATCH_JUMP);
InjectHook(0x436100, &CRestart::AddHospitalRestartPoint, PATCH_JUMP);
@@ -258,5 +258,5 @@ STARTPATCHES
InjectHook(0x4361A0, &CRestart::FindClosestHospitalRestartPoint, PATCH_JUMP);
InjectHook(0x436450, &CRestart::FindClosestPoliceRestartPoint, PATCH_JUMP);
InjectHook(0x436B20, &CRestart::LoadAllRestartPoints, PATCH_JUMP);
- InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP);
+ InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp
index e39fe481..9548bc0a 100644
--- a/src/control/RoadBlocks.cpp
+++ b/src/control/RoadBlocks.cpp
@@ -2,36 +2,202 @@
#include "patcher.h"
#include "RoadBlocks.h"
#include "PathFind.h"
+#include "ModelIndices.h"
+#include "Streaming.h"
+#include "World.h"
+#include "PedPlacement.h"
+#include "Automobile.h"
+#include "CopPed.h"
+#include "VisibilityPlugins.h"
+#include "PlayerPed.h"
+#include "Wanted.h"
+#include "Camera.h"
+#include "CarCtrl.h"
+#include "General.h"
int16 &CRoadBlocks::NumRoadBlocks = *(int16*)0x95CC34;
int16 (&CRoadBlocks::RoadBlockObjects)[NUMROADBLOCKS] = *(int16(*)[NUMROADBLOCKS]) * (uintptr*)0x72B3A8;
bool (&CRoadBlocks::InOrOut)[NUMROADBLOCKS] = *(bool(*)[NUMROADBLOCKS]) * (uintptr*)0x733810;
-WRAPPER void CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle*, int32, int16) { EAXJMP(0x4376A0); }
-WRAPPER void CRoadBlocks::GenerateRoadBlocks(void) { EAXJMP(0x436FA0); }
-
void
CRoadBlocks::Init(void)
{
- NumRoadBlocks = 0;
- for (int objId = 0; objId < ThePaths.m_numMapObjects; objId++) {
- if (ThePaths.m_objectFlags[objId] & UseInRoadBlock) {
- if (NumRoadBlocks < 600) {
- InOrOut[NumRoadBlocks] = true;
- RoadBlockObjects[NumRoadBlocks] = objId;
- NumRoadBlocks++;
- } else {
+ NumRoadBlocks = 0;
+ for (int objId = 0; objId < ThePaths.m_numMapObjects; objId++) {
+ if (ThePaths.m_objectFlags[objId] & UseInRoadBlock) {
+ if (NumRoadBlocks < NUMROADBLOCKS) {
+ InOrOut[NumRoadBlocks] = true;
+ RoadBlockObjects[NumRoadBlocks] = objId;
+ NumRoadBlocks++;
+ } else {
#ifndef MASTER
- printf("Not enough room for the potential roadblocks\n");
+ printf("Not enough room for the potential roadblocks\n");
#endif
- // FIX: Don't iterate loop after NUMROADBLOCKS
- return;
- }
- }
- }
+ // FIX: Don't iterate loop after NUMROADBLOCKS
+ return;
+ }
+ }
+ }
+
+}
+
+void
+CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode)
+{
+ static const CVector vecRoadBlockOffets[6] = { {-1.5, 1.8f, 0.0f}, {-1.5f, -1.8f, 0.0f}, {1.5f, 1.8f, 0.0f},
+ {1.5f, -1.8f, 0.0f}, {-1.5f, 0.0f, 0.0f}, {1.5, 0.0, 0.0} };
+ CEntity* pEntityToAttack = (CEntity*)FindPlayerVehicle();
+ if (!pEntityToAttack)
+ pEntityToAttack = (CEntity*)FindPlayerPed();
+ CColModel* pPoliceColModel = CModelInfo::GetModelInfo(MI_POLICE)->GetColModel();
+ float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius;
+ for (int32 i = 0; i < 2; i++) {
+ const int32 roadBlockIndex = i + 2 * roadBlockType;
+ CVector posForZ = pVehicle->m_matrix * (fRadius * vecRoadBlockOffets[roadBlockIndex]);
+ int32 modelInfoId = MI_COP;
+ eCopType copType = COP_STREET;
+ switch (pVehicle->GetModelIndex())
+ {
+ case MI_FBICAR:
+ modelInfoId = MI_FBI;
+ copType = COP_FBI;
+ break;
+ case MI_ENFORCER:
+ modelInfoId = MI_SWAT;
+ copType = COP_SWAT;
+ break;
+ case MI_BARRACKS:
+ modelInfoId = MI_ARMY;
+ copType = COP_ARMY;
+ break;
+ }
+ if (!CStreaming::HasModelLoaded(modelInfoId))
+ copType = COP_STREET;
+ CCopPed* pCopPed = new CCopPed(copType);
+ if (copType == COP_STREET)
+ pCopPed->SetCurrentWeapon(WEAPONTYPE_COLT45);
+ CPedPlacement::FindZCoorForPed(&posForZ);
+ pCopPed->m_matrix.GetPosition() = posForZ;
+ CVector vecSavedPos = pCopPed->m_matrix.GetPosition();
+ pCopPed->m_matrix.SetRotate(0.0f, 0.0f, -HALFPI);
+ pCopPed->m_matrix.GetPosition() += vecSavedPos;
+ pCopPed->m_bIsDisabledCop = true;
+ pCopPed->SetIdle();
+ pCopPed->bKindaStayInSamePlace = true;
+ pCopPed->bNotAllowedToDuck = false;
+ pCopPed->m_wRoadblockNode = roadBlockNode;
+ pCopPed->bCrouchWhenShooting = roadBlockType != 2;
+ if (pEntityToAttack) {
+ pCopPed->m_pPointGunAt = pEntityToAttack;
+ pEntityToAttack->RegisterReference(&pCopPed->m_pPointGunAt);
+ pCopPed->SetAttack(pEntityToAttack);
+ }
+ pCopPed->m_pMyVehicle = pVehicle;
+ pVehicle->RegisterReference((CEntity**)&pCopPed->m_pMyVehicle);
+ pCopPed->bCullExtraFarAway = true;
+ CVisibilityPlugins::SetClumpAlpha(pCopPed->GetClump(), 0);
+ CWorld::Add(pCopPed);
+ }
+}
+void
+CRoadBlocks::GenerateRoadBlocks(void)
+{
+ CMatrix offsetMatrix;
+ uint32 frame = CTimer::GetFrameCounter() & 0xF;
+ int16 nRoadblockNode = (int16)(NUMROADBLOCKS * frame) / 16;
+ const int16 maxRoadBlocks = (int16)(NUMROADBLOCKS * (frame + 1)) / 16;
+ int16 numRoadBlocks = CRoadBlocks::NumRoadBlocks;
+ if (CRoadBlocks::NumRoadBlocks >= maxRoadBlocks)
+ numRoadBlocks = maxRoadBlocks;
+ for (; nRoadblockNode < numRoadBlocks; nRoadblockNode++) {
+ CTreadable *mapObject = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[nRoadblockNode]];
+ CVector2D vecDistance = FindPlayerCoors() - mapObject->GetPosition();
+ if (vecDistance.x > -80.0f && vecDistance.x < 80.0f &&
+ vecDistance.y > -80.0f && vecDistance.y < 80.0f &&
+ vecDistance.Magnitude() < 80.0f) {
+ if (!CRoadBlocks::InOrOut[nRoadblockNode]) {
+ CRoadBlocks::InOrOut[nRoadblockNode] = true;
+ if (FindPlayerVehicle() && (CGeneral::GetRandomNumber() & 0x7F) < FindPlayerPed()->m_pWanted->m_RoadblockDensity) {
+ CWanted *pPlayerWanted = FindPlayerPed()->m_pWanted;
+ float fMapObjectRadius = 2.0f * mapObject->GetColModel()->boundingBox.max.x;
+ int32 vehicleId = MI_POLICE;
+ if (pPlayerWanted->AreArmyRequired())
+ vehicleId = MI_BARRACKS;
+ else if (pPlayerWanted->AreFbiRequired())
+ vehicleId = MI_FBICAR;
+ else if (pPlayerWanted->AreSwatRequired())
+ vehicleId = MI_ENFORCER;
+ if (!CStreaming::HasModelLoaded(vehicleId))
+ vehicleId = MI_POLICE;
+ CColModel *pVehicleColModel = CModelInfo::GetModelInfo(vehicleId)->GetColModel();
+ float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f;
+ int16 radius = (int16)(fMapObjectRadius / fModelRadius);
+ if (radius > 0 && radius < 6) {
+ CVector2D vecDistanceToCamera = TheCamera.GetPosition() - mapObject->m_matrix.GetPosition();
+ float fDotProduct = DotProduct2D(vecDistanceToCamera, mapObject->m_matrix.GetUp());
+ float fOffset = 0.5f * fModelRadius * (float)(radius - 1);
+ for (int16 i = 0; i < radius; i++) {
+ uint8 nRoadblockType = fDotProduct < 0.0f;
+ if (CGeneral::GetRandomNumber() & 1) {
+ offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f + HALFPI);
+ }
+ else {
+ nRoadblockType = !nRoadblockType;
+ offsetMatrix.SetRotateZ(((CGeneral::GetRandomNumber() & 0xFF) - 128.0f) * 0.003f - HALFPI);
+ }
+ if (ThePaths.m_objectFlags[CRoadBlocks::RoadBlockObjects[nRoadblockNode]] & ObjectEastWest)
+ offsetMatrix.GetPosition() = CVector(0.0f, -fOffset, 0.6f);
+ else
+ offsetMatrix.GetPosition() = CVector(-fOffset, 0.0f, 0.6f);
+ CMatrix vehicleMatrix = mapObject->m_matrix * offsetMatrix;
+ float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f;
+ int16 colliding = 0;
+ CWorld::FindObjectsKindaColliding(vehicleMatrix.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false);
+ if (!colliding) {
+ CAutomobile *pVehicle = new CAutomobile(vehicleId, RANDOM_VEHICLE);
+ pVehicle->m_status = STATUS_ABANDONED;
+ // pVehicle->GetHeightAboveRoad(); // called but return value is ignored?
+ vehicleMatrix.GetPosition().z += fModelRadius - 0.6f;
+ pVehicle->m_matrix = vehicleMatrix;
+ pVehicle->PlaceOnRoadProperly();
+ pVehicle->bIsStatic = false;
+ pVehicle->m_matrix.UpdateRW();
+ pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
+ CCarCtrl::JoinCarWithRoadSystem(pVehicle);
+ pVehicle->bIsLocked = false;
+ pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ pVehicle->AutoPilot.m_nCurrentLane = 0;
+ pVehicle->AutoPilot.m_nNextLane = 0;
+ pVehicle->AutoPilot.m_fMaxTrafficSpeed = 0.0f;
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0.0f;
+ pVehicle->bExtendedRange = true;
+ if (pVehicle->UsesSiren(pVehicle->GetModelIndex()) && CGeneral::GetRandomNumber() & 1)
+ pVehicle->m_bSirenOrAlarm = true;
+ if (pVehicle->m_matrix.GetForward().z > 0.94f) {
+ CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
+ CWorld::Add(pVehicle);
+ pVehicle->bCreateRoadBlockPeds = true;
+ pVehicle->m_nRoadblockType = nRoadblockType;
+ pVehicle->m_nRoadblockNode = nRoadblockNode;
+ }
+ else {
+ delete pVehicle;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ CRoadBlocks::InOrOut[nRoadblockNode] = false;
+ }
+ }
}
STARTPATCHES
InjectHook(0x436F50, &CRoadBlocks::Init, PATCH_JUMP);
+ InjectHook(0x4376A0, &CRoadBlocks::GenerateRoadBlockCopsForCar, PATCH_JUMP);
+ InjectHook(0x436FA0, &CRoadBlocks::GenerateRoadBlocks, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/control/RoadBlocks.h b/src/control/RoadBlocks.h
index 3f5868e7..16e3a362 100644
--- a/src/control/RoadBlocks.h
+++ b/src/control/RoadBlocks.h
@@ -11,6 +11,6 @@ public:
static bool (&InOrOut)[NUMROADBLOCKS];
static void Init(void);
- static void GenerateRoadBlockCopsForCar(CVehicle*, int32, int16);
+ static void GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType, int16 roadBlockNode);
static void GenerateRoadBlocks(void);
};
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index f96ec060..ff89f0fc 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -91,10 +91,10 @@ uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SP
CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08;
int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200;
int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0;
-CTextLine (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(CTextLine (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
-CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
+intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68;
+intro_script_rectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(intro_script_rectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108;
CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090;
-CScriptSphere(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(CScriptSphere(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
+script_sphere_struct(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(script_sphere_struct(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60;
tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008;
tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8;
int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558;
@@ -313,7 +313,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id)
return false;
}
-void CStuckCarCheckEntry::Reset()
+void stuck_car_data::Reset()
{
m_nVehicleIndex = -1;
m_vecPos = CVector(-5000.0f, -5000.0f, -5000.0f);
@@ -2229,6 +2229,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
if (pos.z <= -100)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
UpdateCompareFlag(TheCamera.IsSphereVisible(pos, *(float*)&ScriptParams[3]));
+ return 0;
}
case COMMAND_DEBUG_ON:
CTheScripts::DbgFlag = true;
@@ -7116,7 +7117,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
case COMMAND_CLOSE_GARAGE:
{
CollectParameters(&m_nIp, 1);
- CGarages::CloseGarage(ScriptParams[1]);
+ CGarages::CloseGarage(ScriptParams[0]);
return 0;
}
case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD:
@@ -7657,13 +7658,13 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
assert(pObject);
if (ScriptParams[1]) {
if (pObject->bIsStatic) {
- pObject->bIsStatic = true;
+ pObject->bIsStatic = false;
pObject->AddToMovingList();
}
}
else {
if (!pObject->bIsStatic) {
- pObject->bIsStatic = false;
+ pObject->bIsStatic = true;
pObject->RemoveFromMovingList();
}
}
@@ -8441,7 +8442,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
pPlayerInfo->MakePlayerSafe(true);
- CCutsceneMgr::SetRunning(true);
+ CCutsceneMgr::StartCutsceneProcessing();
return 0;
}
case COMMAND_USE_TEXT_COMMANDS:
@@ -9140,7 +9141,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
assert(pVehicle);
assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
CAutomobile* pCar = (CAutomobile*)pVehicle;
- pCar->bTakeLessDamage = ScriptParams[1];
+ pCar->bMoreResistantToDamage = ScriptParams[1];
return 0;
}
case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER:
@@ -9152,6 +9153,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
return 0;
}
case COMMAND_LOAD_END_OF_GAME_TUNE:
+ DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
printf("Start preload end of game audio\n");
DMAudio.PreloadCutSceneMusic(STREAMED_SOUND_GAME_COMPLETED);
printf("End preload end of game audio\n");
@@ -11037,6 +11039,7 @@ void CRunningScript::DoDeatharrestCheck()
int contactFlagOffset = CTheScripts::OnAMissionForContactFlag[contact];
if (contactFlagOffset && CTheScripts::ScriptSpace[contactFlagOffset] == 1) {
messageId += CTheScripts::BaseBriefIdForContact[contact];
+ found = true;
}
}
if (!found)
@@ -11331,6 +11334,7 @@ INITSAVEBUF
break;
case 4:
InvisibilitySettingArray[i] = CPools::GetDummyPool()->GetSlot(handle - 1);
+ break;
default:
assert(false);
}
@@ -11369,15 +11373,15 @@ void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntit
continue;
CEntity* pFound = aEntities[i];
int cols;
- if (CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel()->numLines <= 0)
- cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(),
- pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, nil, nil);
+ if (pEntity->GetColModel()->numLines <= 0)
+ cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
+ pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints, nil, nil);
else {
float lines[4];
lines[0] = lines[1] = lines[2] = lines[3] = 1.0f;
- CColPoint tmp;
- cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(),
- pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, &tmp, lines);
+ CColPoint tmp[4];
+ cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
+ pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints,tmp, lines);
}
if (cols <= 0)
continue;
diff --git a/src/control/Script.h b/src/control/Script.h
index fbcdce48..4338bd18 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -15,22 +15,25 @@ class CRunningScript;
#define KEY_LENGTH_IN_SCRIPT 8
-struct CScriptRectangle
+struct intro_script_rectangle
{
- int8 m_bIsUsed;
+ bool m_bIsUsed;
bool m_bBeforeFade;
int16 m_nTextureId;
CRect m_sRect;
CRGBA m_sColor;
+
+ intro_script_rectangle() { }
+ ~intro_script_rectangle() { }
};
-static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error");
+static_assert(sizeof(intro_script_rectangle) == 0x18, "Script.h: error");
enum {
SCRIPT_TEXT_MAX_LENGTH = 500
};
-struct CTextLine
+struct intro_text_line
{
float m_fScaleX;
float m_fScaleY;
@@ -50,6 +53,9 @@ struct CTextLine
float m_fAtY;
wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
+ intro_text_line() { }
+ ~intro_text_line() { }
+
void Reset()
{
m_fScaleX = 0.48f;
@@ -72,15 +78,17 @@ struct CTextLine
}
};
-static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
+static_assert(sizeof(intro_text_line) == 0x414, "Script.h: error");
-struct CScriptSphere
+struct script_sphere_struct
{
bool m_bInUse;
uint16 m_Index;
uint32 m_Id;
CVector m_vecCenter;
float m_fRadius;
+
+ script_sphere_struct() { }
};
struct CStoredLine
@@ -145,7 +153,7 @@ public:
bool HasCarBeenUpsideDownForAWhile(int32);
};
-struct CStuckCarCheckEntry
+struct stuck_car_data
{
int32 m_nVehicleIndex;
CVector m_vecPos;
@@ -154,12 +162,13 @@ struct CStuckCarCheckEntry
uint32 m_nStuckTime;
bool m_bStuck;
+ stuck_car_data() { }
inline void Reset();
};
class CStuckCarCheck
{
- CStuckCarCheckEntry m_sCars[MAX_STUCK_CAR_CHECKS];
+ stuck_car_data m_sCars[MAX_STUCK_CAR_CHECKS];
public:
void Init();
@@ -235,10 +244,10 @@ class CTheScripts
static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
- static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
- static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
+ static intro_text_line(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
+ static intro_script_rectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES];
- static CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
+ static script_sphere_struct(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES];
static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS];
static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS];
diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp
index 2cd09a03..ab9cd92d 100644
--- a/src/control/TrafficLights.cpp
+++ b/src/control/TrafficLights.cpp
@@ -1,23 +1,335 @@
#include "common.h"
#include "patcher.h"
-#include "TrafficLights.h"
+#include "General.h"
+#include "Camera.h"
+#include "World.h"
+#include "PathFind.h"
#include "Timer.h"
+#include "Clock.h"
+#include "Weather.h"
+#include "Timecycle.h"
+#include "Pointlights.h"
+#include "Shadows.h"
+#include "Coronas.h"
+#include "SpecialFX.h"
#include "Vehicle.h"
+#include "TrafficLights.h"
+
+// TODO: figure out the meaning of this
+enum { SOME_FLAG = 0x80 };
+
+void
+CTrafficLights::DisplayActualLight(CEntity *ent)
+{
+ if(ent->GetUp().z < 0.96f || ent->bRenderDamaged)
+ return;
+
+ int phase;
+ if(FindTrafficLightType(ent) == 1)
+ phase = LightForCars1();
+ else
+ phase = LightForCars2();
+
+ int i;
+ CBaseModelInfo *mi = CModelInfo::GetModelInfo(ent->GetModelIndex());
+ float x = mi->Get2dEffect(0)->pos.x;
+ float yMin = mi->Get2dEffect(0)->pos.y;
+ float yMax = mi->Get2dEffect(0)->pos.y;
+ float zMin = mi->Get2dEffect(0)->pos.z;
+ float zMax = mi->Get2dEffect(0)->pos.z;
+ for(i = 1; i < 6; i++){
+ assert(mi->Get2dEffect(i));
+ yMin = min(yMin, mi->Get2dEffect(i)->pos.y);
+ yMax = max(yMax, mi->Get2dEffect(i)->pos.y);
+ zMin = min(zMin, mi->Get2dEffect(i)->pos.z);
+ zMax = max(zMax, mi->Get2dEffect(i)->pos.z);
+ }
+
+ CVector pos1, pos2;
+ uint8 r, g;
+ int id;
+ switch(phase){
+ case CAR_LIGHTS_GREEN:
+ r = 0;
+ g = 255;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, zMin);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, zMin);
+ id = 0;
+ break;
+ case CAR_LIGHTS_YELLOW:
+ r = 255;
+ g = 128;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin+zMax)/2.0f);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin+zMax)/2.0f);
+ id = 1;
+ break;
+ case CAR_LIGHTS_RED:
+ default:
+ r = 255;
+ g = 0;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, zMax);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, zMax);
+ id = 2;
+ break;
+ }
+
+ if(CClock::GetHours() > 19 || CClock::GetHours() < 6 || CWeather::Foggyness > 0.05f)
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f,
+ r/255.0f, g/255.0f, 0/255.0f, CPointLights::FOG_NORMAL, true);
+
+ CShadows::StoreStaticShadow((uintptr)ent,
+ SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1,
+ 8.0f, 0.0f, 0.0f, -8.0f, 128,
+ r*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
+ g*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
+ 0*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
+ 12.0f, 1.0f, 40.0f, false, 0.0f);
+
+ if(DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f)
+ CCoronas::RegisterCorona((uintptr)ent + id,
+ r*CTimeCycle::GetSpriteBrightness()*0.7f,
+ g*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 0*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 255,
+ pos1, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::RegisterCorona((uintptr)ent + id + 3,
+ r*CTimeCycle::GetSpriteBrightness()*0.7f,
+ g*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 0*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 255,
+ pos2, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+
+ CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN);
+ CBrightLights::RegisterOne(pos2, ent->GetUp(), -ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN);
+
+ static const float top = -0.127f;
+ static const float bot = -0.539f;
+ static const float mid = bot + (top-bot)/3.0f;
+ static const float left = 1.256f;
+ static const float right = 0.706f;
+ phase = CTrafficLights::LightForPeds();
+ if(phase == PED_LIGHTS_DONT_WALK){
+ CVector p0(2.7f, right, top);
+ CVector p1(2.7f, left, top);
+ CVector p2(2.7f, right, mid);
+ CVector p3(2.7f, left, mid);
+ CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3,
+ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
+ SHINYTEXT_WALK, 255, 0, 0, 60.0f);
+ }else if(phase == PED_LIGHTS_WALK || CTimer::GetTimeInMilliseconds() & 0x100){
+ CVector p0(2.7f, right, mid);
+ CVector p1(2.7f, left, mid);
+ CVector p2(2.7f, right, bot);
+ CVector p3(2.7f, left, bot);
+ CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3,
+ 1.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f,
+ SHINYTEXT_WALK, 255, 255, 255, 60.0f);
+ }
+}
+
+void
+CTrafficLights::ScanForLightsOnMap(void)
+{
+ int x, y;
+ int i, j, l;
+ CPtrNode *node;
+
+ for(x = 0; x < NUMSECTORS_X; x++)
+ for(y = 0; y < NUMSECTORS_Y; y++){
+ CPtrList &list = CWorld::GetSector(x, y)->m_lists[ENTITYLIST_DUMMIES];
+ for(node = list.first; node; node = node->next){
+ CEntity *light = (CEntity*)node->item;
+ if(light->GetModelIndex() != MI_TRAFFICLIGHTS)
+ continue;
+
+ // Check cars
+ for(i = 0; i < ThePaths.m_numCarPathLinks; i++){
+ CVector2D dist = ThePaths.m_carPathLinks[i].pos - light->GetPosition();
+ float dotY = Abs(DotProduct2D(dist, light->GetForward())); // forward is direction of car light
+ float dotX = DotProduct2D(dist, light->GetRight()); // towards base of light
+ // it has to be on the correct side of the node and also not very far away
+ if(dotX < 0.0f && dotX > -15.0f && dotY < 3.0f){
+ float dz = ThePaths.m_pathNodes[ThePaths.m_carPathLinks[i].pathNodeIndex].pos.z -
+ light->GetPosition().z;
+ if(dz < 15.0f){
+ ThePaths.m_carPathLinks[i].trafficLightType = FindTrafficLightType(light);
+ // Find two neighbour nodes of this one
+ int n1 = -1;
+ int n2 = -1;
+ for(j = 0; j < ThePaths.m_numPathNodes; j++)
+ for(l = 0; l < ThePaths.m_pathNodes[j].numLinks; l++)
+ if(ThePaths.m_carPathConnections[ThePaths.m_pathNodes[j].firstLink + l] == i){
+ if(n1 == -1)
+ n1 = j;
+ else
+ n2 = j;
+ }
+ // What's going on here?
+ if(ThePaths.m_pathNodes[n1].numLinks <= ThePaths.m_pathNodes[n2].numLinks)
+ n1 = n2;
+ if(ThePaths.m_carPathLinks[i].pathNodeIndex != n1)
+ ThePaths.m_carPathLinks[i].trafficLightType |= SOME_FLAG;
+ }
+ }
+ }
+
+ // Check peds
+ for(i = ThePaths.m_numCarPathNodes; i < ThePaths.m_numPathNodes; i++){
+ float dist1, dist2;
+ dist1 = Abs(ThePaths.m_pathNodes[i].pos.x - light->GetPosition().x) +
+ Abs(ThePaths.m_pathNodes[i].pos.y - light->GetPosition().y);
+ if(dist1 < 50.0f){
+ for(l = 0; l < ThePaths.m_pathNodes[i].numLinks; l++){
+ j = ThePaths.m_pathNodes[i].firstLink + l;
+ if(ThePaths.m_connectionFlags[j].bCrossesRoad){
+ dist2 = Abs(ThePaths.m_pathNodes[j].pos.x - light->GetPosition().x) +
+ Abs(ThePaths.m_pathNodes[j].pos.y - light->GetPosition().y);
+ if(dist1 < 15.0f || dist2 < 15.0f)
+ ThePaths.m_connectionFlags[j].bTrafficLight = true;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool
+CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop)
+{
+ int node, type;
-WRAPPER void CTrafficLights::DisplayActualLight(CEntity *ent) { EAXJMP(0x455800); }
-WRAPPER void CTrafficLights::ScanForLightsOnMap(void) { EAXJMP(0x454F40); }
-WRAPPER bool CTrafficLights::ShouldCarStopForLight(CVehicle*, bool) { EAXJMP(0x455350); }
-WRAPPER bool CTrafficLights::ShouldCarStopForBridge(CVehicle*) { EAXJMP(0x456460); }
+ node = vehicle->AutoPilot.m_nNextPathNodeInfo;
+ type = ThePaths.m_carPathLinks[node].trafficLightType;
+ if(type){
+ if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) &&
+ (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode))
+ if(alwaysStop ||
+ (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].pos,
+ ThePaths.m_carPathLinks[node].dir);
+ if(vehicle->AutoPilot.m_nNextDirection == -1){
+ if(dist > 0.0f && dist < 8.0f)
+ return true;
+ }else{
+ if(dist < 0.0f && dist > -8.0f)
+ return true;
+ }
+ }
+ }
+
+ node = vehicle->AutoPilot.m_nCurrentPathNodeInfo;
+ type = ThePaths.m_carPathLinks[node].trafficLightType;
+ if(type){
+ if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) &&
+ (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode))
+ if(alwaysStop ||
+ (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].pos,
+ ThePaths.m_carPathLinks[node].dir);
+ if(vehicle->AutoPilot.m_nCurrentDirection == -1){
+ if(dist > 0.0f && dist < 8.0f)
+ return true;
+ }else{
+ if(dist < 0.0f && dist > -8.0f)
+ return true;
+ }
+ }
+ }
+
+ if(vehicle->m_status == STATUS_PHYSICS){
+ node = vehicle->AutoPilot.m_nPreviousPathNodeInfo;
+ type = ThePaths.m_carPathLinks[node].trafficLightType;
+ if(type){
+ if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) &&
+ (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode))
+ if(alwaysStop ||
+ (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].pos,
+ ThePaths.m_carPathLinks[node].dir);
+ if(vehicle->AutoPilot.m_nPreviousDirection == -1){
+ if(dist > 0.0f && dist < 6.0f)
+ return true;
+ }else{
+ if(dist < 0.0f && dist > -6.0f)
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool
+CTrafficLights::ShouldCarStopForBridge(CVehicle *vehicle)
+{
+ return ThePaths.m_carPathLinks[vehicle->AutoPilot.m_nNextPathNodeInfo].bBridgeLights &&
+ !ThePaths.m_carPathLinks[vehicle->AutoPilot.m_nCurrentPathNodeInfo].bBridgeLights;
+}
+
+int
+CTrafficLights::FindTrafficLightType(CEntity *light)
+{
+ float orientation = RADTODEG(CGeneral::GetATanOfXY(light->GetForward().x, light->GetForward().y));
+ if((orientation > 60.0f && orientation < 60.0f + 90.0f) ||
+ (orientation > 240.0f && orientation < 240.0f + 90.0f))
+ return 1;
+ return 2;
+}
uint8
CTrafficLights::LightForPeds(void)
{
- uint32 period = CTimer::GetTimeInMilliseconds() & 0x3FFF; // Equals to % 16384
+ uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
- if (period >= 15384)
- return PED_LIGHTS_WALK_BLINK;
- else if (period >= 12000)
+ if(period < 12000)
+ return PED_LIGHTS_DONT_WALK;
+ else if(period < 16384 - 1000)
return PED_LIGHTS_WALK;
else
- return PED_LIGHTS_DONT_WALK;
-} \ No newline at end of file
+ return PED_LIGHTS_WALK_BLINK;
+}
+
+uint8
+CTrafficLights::LightForCars1(void)
+{
+ uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
+
+ if(period < 5000)
+ return CAR_LIGHTS_GREEN;
+ else if(period < 5000 + 1000)
+ return CAR_LIGHTS_YELLOW;
+ else
+ return CAR_LIGHTS_RED;
+}
+
+uint8
+CTrafficLights::LightForCars2(void)
+{
+ uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
+
+ if(period < 6000)
+ return CAR_LIGHTS_RED;
+ else if(period < 12000 - 1000)
+ return CAR_LIGHTS_GREEN;
+ else if(period < 12000)
+ return CAR_LIGHTS_YELLOW;
+ else
+ return CAR_LIGHTS_RED;
+}
+
+STARTPATCHES
+ InjectHook(0x455760, &CTrafficLights::LightForCars1, PATCH_JUMP);
+ InjectHook(0x455790, &CTrafficLights::LightForCars2, PATCH_JUMP);
+ InjectHook(0x4557D0, &CTrafficLights::LightForPeds, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/control/TrafficLights.h b/src/control/TrafficLights.h
index 06505ed6..f3df6cd5 100644
--- a/src/control/TrafficLights.h
+++ b/src/control/TrafficLights.h
@@ -7,6 +7,10 @@ enum {
PED_LIGHTS_WALK,
PED_LIGHTS_WALK_BLINK,
PED_LIGHTS_DONT_WALK,
+
+ CAR_LIGHTS_GREEN = 0,
+ CAR_LIGHTS_YELLOW,
+ CAR_LIGHTS_RED
};
class CTrafficLights
@@ -14,7 +18,10 @@ class CTrafficLights
public:
static void DisplayActualLight(CEntity *ent);
static void ScanForLightsOnMap(void);
+ static int FindTrafficLightType(CEntity *light);
static uint8 LightForPeds(void);
+ static uint8 LightForCars1(void);
+ static uint8 LightForCars2(void);
static bool ShouldCarStopForLight(CVehicle*, bool);
static bool ShouldCarStopForBridge(CVehicle*);
};
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index 5b7a53e9..cfdea46a 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -3511,7 +3511,7 @@ CCam::Process_FlyBy(const CVector&, float, float, float)
Up = CVector(0.0f, 0.0f, 1.0f);
if(TheCamera.m_bStartingSpline)
- m_fTimeElapsedFloat += CTimer::GetTimeStepInMilliseconds();
+ m_fTimeElapsedFloat += CTimer::GetTimeStepNonClippedInMilliseconds();
else{
m_fTimeElapsedFloat = 0.0f;
m_uiFinishTime = MS(TheCamera.m_arrPathArray[2].m_arr_PathData[10*((int)TheCamera.m_arrPathArray[2].m_arr_PathData[0]-1) + 1]);
@@ -4672,15 +4672,15 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
else {
switch ((int)TheCamera.CarZoomIndicator) {
// near
- case 1:
+ case CAM_ZOOM_1:
zoomModeAlphaOffset = ZmOneAlphaOffsetLCS[alphaArrPos];
break;
// mid
- case 2:
+ case CAM_ZOOM_2:
zoomModeAlphaOffset = ZmTwoAlphaOffsetLCS[alphaArrPos];
break;
// far
- case 3:
+ case CAM_ZOOM_3:
zoomModeAlphaOffset = ZmThreeAlphaOffsetLCS[alphaArrPos];
break;
default:
@@ -4705,14 +4705,12 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
}
} else {
// 0.6f = fTestShiftHeliCamTarget
- TargetCoors.x += 0.6f * car->GetUp().x * colMaxZ;
- TargetCoors.y += 0.6f * car->GetUp().y * colMaxZ;
- TargetCoors.z += 0.6f * car->GetUp().z * colMaxZ;
+ TargetCoors += 0.6f * car->GetUp() * colMaxZ;
}
float minDistForVehType = CARCAM_SET[camSetArrPos][4];
- if ((int)TheCamera.CarZoomIndicator == 1 && (camSetArrPos < 2 || camSetArrPos == 7)) {
+ if (TheCamera.CarZoomIndicator == CAM_ZOOM_1 && (camSetArrPos < 2 || camSetArrPos == 7)) {
minDistForVehType = minDistForVehType * 0.65f;
}
@@ -4904,8 +4902,8 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// yMovement = 0.0;
if (!nextDirectionIsForward) {
- yMovement = 0.0;
- xMovement = 0.0;
+ yMovement = 0.0f;
+ xMovement = 0.0f;
}
if (camSetArrPos == 0 || camSetArrPos == 7) {
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index e5bc09c8..91dd6573 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -124,8 +124,8 @@ CCamera::Init(void)
m_WideScreenOn = false;
m_fFOV_Wide_Screen = 0.0f;
m_bRestoreByJumpCut = false;
- CarZoomIndicator = 2.0f;
- PedZoomIndicator = 2.0f;
+ CarZoomIndicator = CAM_ZOOM_2;
+ PedZoomIndicator = CAM_ZOOM_2;
CarZoomValueSmooth = 0.0f;
m_fPedZoomValueSmooth = 0.0f;
pTargetEntity = nil;
@@ -142,7 +142,7 @@ CCamera::Init(void)
PlayerExhaustion = 1.0f;
DebugCamMode = CCam::MODE_NONE;
m_PedOrientForBehindOrInFront = 0.0f;
- if(!FrontEndMenuManager.m_bStartGameLoading){
+ if(!FrontEndMenuManager.m_bWantToRestart){
m_bFading = false;
CDraw::FadeValue = 0;
m_fFLOATingFade = 0.0f;
@@ -151,7 +151,7 @@ CCamera::Init(void)
m_fFLOATingFadeMusic = 0.0f;
}
m_bMoveCamToAvoidGeom = false;
- if(FrontEndMenuManager.m_bStartGameLoading)
+ if(FrontEndMenuManager.m_bWantToRestart)
m_bMoveCamToAvoidGeom = true;
m_bStartingSpline = false;
m_iTypeOfSwitch = INTERPOLATION;
@@ -623,11 +623,11 @@ CCamera::CamControl(void)
if(CPad::GetPad(0)->CycleCameraModeUpJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
!m_WideScreenOn)
- CarZoomIndicator -= 1.0f;
+ CarZoomIndicator--;
if(CPad::GetPad(0)->CycleCameraModeDownJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
!m_WideScreenOn)
- CarZoomIndicator += 1.0f;
+ CarZoomIndicator++;
if(!m_bFailedCullZoneTestPreviously){
if(CarZoomIndicator < CAM_ZOOM_1STPRS) CarZoomIndicator = CAM_ZOOM_CINEMATIC;
else if(CarZoomIndicator > CAM_ZOOM_CINEMATIC) CarZoomIndicator = CAM_ZOOM_1STPRS;
@@ -727,12 +727,24 @@ CCamera::CamControl(void)
if(CarZoomIndicator == CAM_ZOOM_1STPRS && !m_bPlayerIsInGarage){
CarZoomValue = 0.0f;
ReqMode = CCam::MODE_1STPERSON;
- }else if(CarZoomIndicator == CAM_ZOOM_1)
- CarZoomValue = 0.05f;
+ }
+#ifdef FREE_CAM
+ else if (bFreeCam) {
+ if (CarZoomIndicator == CAM_ZOOM_1)
+ CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1;
+ else if (CarZoomIndicator == CAM_ZOOM_2)
+ CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2;
+ else if (CarZoomIndicator == CAM_ZOOM_3)
+ CarZoomValue = ((CVehicle*)pTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3;
+ }
+#endif
+ else if(CarZoomIndicator == CAM_ZOOM_1)
+ CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_1;
else if(CarZoomIndicator == CAM_ZOOM_2)
- CarZoomValue = 1.9f;
+ CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_2;
else if(CarZoomIndicator == CAM_ZOOM_3)
- CarZoomValue = 3.9f;
+ CarZoomValue = DEFAULT_CAR_ZOOM_VALUE_3;
+
if(CarZoomIndicator == CAM_ZOOM_TOPDOWN && !m_bPlayerIsInGarage){
CarZoomValue = 1.0f;
ReqMode = CCam::MODE_TOPDOWN;
@@ -800,7 +812,7 @@ CCamera::CamControl(void)
else
PedZoomIndicator = CAM_ZOOM_TOPDOWN;
}else
- PedZoomIndicator -= 1.0f;
+ PedZoomIndicator--;
}
if(CPad::GetPad(0)->CycleCameraModeDownJustDown() && !CReplay::IsPlayingBack() &&
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
@@ -811,7 +823,7 @@ CCamera::CamControl(void)
else
PedZoomIndicator = CAM_ZOOM_TOPDOWN;
}else
- PedZoomIndicator += 1.0f;
+ PedZoomIndicator++;
}
// disabled obbe's cam here
if(PedZoomIndicator < CAM_ZOOM_1) PedZoomIndicator = CAM_ZOOM_TOPDOWN;
@@ -1211,7 +1223,7 @@ CCamera::CamControl(void)
ReqMode == CCam::MODE_1STPERSON_RUNABOUT || ReqMode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
ReqMode == CCam::MODE_FIGHT_CAM_RUNABOUT || ReqMode == CCam::MODE_HELICANNON_1STPERSON ||
WhoIsInControlOfTheCamera == CAMCONTROL_SCRIPT ||
- m_bJustCameOutOfGarage || m_bPlayerIsInGarage)
+ m_bJustCameOutOfGarage || m_bPlayerIsInGarage)
canUseObbeCam = false;
if(m_bObbeCinematicPedCamOn && canUseObbeCam)
@@ -1512,7 +1524,7 @@ CCamera::UpdateTargetEntity(void)
cantOpen = false;
if(PLAYER->GetPedState() == PED_ENTER_CAR && !cantOpen){
- if(!enteringCar && CarZoomIndicator != 0.0f){
+ if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS){
pTargetEntity = PLAYER->m_pMyVehicle;
if(PLAYER->m_pMyVehicle == nil)
pTargetEntity = PLAYER;
@@ -1520,7 +1532,7 @@ CCamera::UpdateTargetEntity(void)
}
if((PLAYER->GetPedState() == PED_CARJACK || PLAYER->GetPedState() == PED_OPEN_DOOR) && !cantOpen){
- if(!enteringCar && CarZoomIndicator != 0.0f)
+ if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS)
#ifdef GTA_PS2_STUFF
// dunno if this has any amazing effects
{
@@ -1537,7 +1549,7 @@ CCamera::UpdateTargetEntity(void)
pTargetEntity = FindPlayerPed();
if(PLAYER->GetPedState() == PED_DRAG_FROM_CAR)
pTargetEntity = FindPlayerPed();
- if(pTargetEntity->IsVehicle() && CarZoomIndicator != 0.0f && FindPlayerPed()->GetPedState() == PED_ARRESTED)
+ if(pTargetEntity->IsVehicle() && CarZoomIndicator != CAM_ZOOM_1STPRS && FindPlayerPed()->GetPedState() == PED_ARRESTED)
pTargetEntity = FindPlayerPed();
}
}
@@ -2956,11 +2968,23 @@ CCamera::SetZoomValueFollowPedScript(int16 dist)
void
CCamera::SetZoomValueCamStringScript(int16 dist)
{
- switch (dist) {
- case 0: m_fCarZoomValueScript = 0.05f; break;
- case 1: m_fCarZoomValueScript = 1.9f; break;
- case 2: m_fCarZoomValueScript = 3.9f; break;
- default: m_fCarZoomValueScript = m_fCarZoomValueScript; break;
+#ifdef FREE_CAM
+ if (bFreeCam) {
+ switch (dist) {
+ case 0: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_1 : FREE_CAR_ZOOM_VALUE_1; break;
+ case 1: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_2 : FREE_CAR_ZOOM_VALUE_2; break;
+ case 2: m_fCarZoomValueScript = ((CVehicle*)Cams[ActiveCam].CamTargetEntity)->IsBoat() ? FREE_BOAT_ZOOM_VALUE_3 : FREE_CAR_ZOOM_VALUE_3; break;
+ default: m_fCarZoomValueScript = m_fCarZoomValueScript; break;
+ }
+ } else
+#endif
+ {
+ switch (dist) {
+ case 0: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_1; break;
+ case 1: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_2; break;
+ case 2: m_fCarZoomValueScript = DEFAULT_CAR_ZOOM_VALUE_3; break;
+ default: m_fCarZoomValueScript = m_fCarZoomValueScript; break;
+ }
}
m_bUseScriptZoomValueCar = true;
@@ -3245,7 +3269,7 @@ void
CCamera::SetRwCamera(RwCamera *cam)
{
m_pRwCamera = cam;
- m_viewMatrix.Attach(&m_pRwCamera->viewMatrix, false);
+ m_viewMatrix.Attach(RwCameraGetViewMatrix(m_pRwCamera), false);
CMBlur::MotionBlurOpen(m_pRwCamera);
}
diff --git a/src/core/Camera.h b/src/core/Camera.h
index f21fe913..eca4518a 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -16,12 +16,29 @@ enum
};
#define DEFAULT_NEAR (0.9f)
-#define CAM_ZOOM_1STPRS (0.0f)
-#define CAM_ZOOM_1 (1.0f)
-#define CAM_ZOOM_2 (2.0f)
-#define CAM_ZOOM_3 (3.0f)
-#define CAM_ZOOM_TOPDOWN (4.0f)
-#define CAM_ZOOM_CINEMATIC (5.0f)
+enum
+{
+ CAM_ZOOM_1STPRS,
+ CAM_ZOOM_1,
+ CAM_ZOOM_2,
+ CAM_ZOOM_3,
+ CAM_ZOOM_TOPDOWN,
+ CAM_ZOOM_CINEMATIC,
+};
+
+#ifdef FREE_CAM // LCS values
+#define FREE_CAR_ZOOM_VALUE_1 (-1.0f)
+#define FREE_CAR_ZOOM_VALUE_2 (2.0f)
+#define FREE_CAR_ZOOM_VALUE_3 (6.0f)
+
+#define FREE_BOAT_ZOOM_VALUE_1 (-2.41f)
+#define FREE_BOAT_ZOOM_VALUE_2 (6.49f)
+#define FREE_BOAT_ZOOM_VALUE_3 (15.0f)
+#endif
+
+#define DEFAULT_CAR_ZOOM_VALUE_1 (0.05f)
+#define DEFAULT_CAR_ZOOM_VALUE_2 (1.9f)
+#define DEFAULT_CAR_ZOOM_VALUE_3 (3.9f)
class CCam
{
@@ -398,7 +415,11 @@ uint32 unknown; // some counter having to do with music
float CamFrontXNorm;
float CamFrontYNorm;
+#if 0 // TODO: FIX_BUGS once GenericLoad is done
+ int32 CarZoomIndicator;
+#else
float CarZoomIndicator;
+#endif
float CarZoomValue;
float CarZoomValueSmooth;
@@ -434,7 +455,11 @@ uint32 unknown; // some counter having to do with music
float m_ScreenReductionSpeed;
float m_AlphaForPlayerAnim1rstPerson;
float Orientation;
+#if 0 // TODO: FIX_BUGS once GenericLoad is done
+ int32 PedZoomIndicator;
+#else
float PedZoomIndicator;
+#endif
float PlayerExhaustion;
float SoundDistUp, SoundDistLeft, SoundDistRight;
float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead;
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index 94ef769e..c884f751 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -34,8 +34,6 @@ enum Direction
eLevelName &CCollision::ms_collisionInMemory = *(eLevelName*)0x8F6250;
CLinkList<CColModel*> &CCollision::ms_colModelCache = *(CLinkList<CColModel*>*)0x95CB58;
-WRAPPER bool CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly) { EAXJMP(0x4105A0); }
-
void
CCollision::Init(void)
{
@@ -927,6 +925,87 @@ CCollision::ProcessVerticalLineTriangle(const CColLine &line,
}
bool
+CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly)
+{
+ float t;
+
+ if(!poly->valid)
+ return false;
+
+ // maybe inlined?
+ CColTriangle tri;
+ tri.a = 0;
+ tri.b = 1;
+ tri.c = 2;
+ CColTrianglePlane plane;
+ plane.Set(poly->verts, tri);
+
+ const CVector &va = poly->verts[tri.a];
+ const CVector &vb = poly->verts[tri.b];
+ const CVector &vc = poly->verts[tri.c];
+ CVector p0 = pos;
+ CVector p1(pos.x, pos.y, z);
+
+ // The rest is pretty much CCollision::ProcessLineTriangle
+
+ // if points are on the same side, no collision
+ if(plane.CalcPoint(p0) * plane.CalcPoint(p1) > 0.0f)
+ return poly->valid = false;
+
+ // intersection parameter on line
+ t = -plane.CalcPoint(p0) / DotProduct(p1 - p0, plane.normal);
+ // find point of intersection
+ CVector p = p0 + (p1-p0)*t;
+
+ CVector2D vec1, vec2, vec3, vect;
+ switch(plane.dir){
+ case DIR_X_POS:
+ vec1.x = va.y; vec1.y = va.z;
+ vec2.x = vc.y; vec2.y = vc.z;
+ vec3.x = vb.y; vec3.y = vb.z;
+ vect.x = p.y; vect.y = p.z;
+ break;
+ case DIR_X_NEG:
+ vec1.x = va.y; vec1.y = va.z;
+ vec2.x = vb.y; vec2.y = vb.z;
+ vec3.x = vc.y; vec3.y = vc.z;
+ vect.x = p.y; vect.y = p.z;
+ break;
+ case DIR_Y_POS:
+ vec1.x = va.z; vec1.y = va.x;
+ vec2.x = vc.z; vec2.y = vc.x;
+ vec3.x = vb.z; vec3.y = vb.x;
+ vect.x = p.z; vect.y = p.x;
+ break;
+ case DIR_Y_NEG:
+ vec1.x = va.z; vec1.y = va.x;
+ vec2.x = vb.z; vec2.y = vb.x;
+ vec3.x = vc.z; vec3.y = vc.x;
+ vect.x = p.z; vect.y = p.x;
+ break;
+ case DIR_Z_POS:
+ vec1.x = va.x; vec1.y = va.y;
+ vec2.x = vc.x; vec2.y = vc.y;
+ vec3.x = vb.x; vec3.y = vb.y;
+ vect.x = p.x; vect.y = p.y;
+ break;
+ case DIR_Z_NEG:
+ vec1.x = va.x; vec1.y = va.y;
+ vec2.x = vb.x; vec2.y = vb.y;
+ vec3.x = vc.x; vec3.y = vc.y;
+ vect.x = p.x; vect.y = p.y;
+ break;
+ default:
+ assert(0);
+ }
+ if(CrossProduct2D(vec2-vec1, vect-vec1) < 0.0f) return poly->valid = false;
+ if(CrossProduct2D(vec3-vec1, vect-vec1) > 0.0f) return poly->valid = false;
+ if(CrossProduct2D(vec3-vec2, vect-vec2) < 0.0f) return poly->valid = false;
+ point.point = p;
+ return poly->valid = true;
+}
+
+bool
CCollision::ProcessLineTriangle(const CColLine &line ,
const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist)
diff --git a/src/core/Collision.h b/src/core/Collision.h
index 429fc17f..1cbd1690 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -144,7 +144,6 @@ public:
static bool ProcessLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough);
static bool ProcessVerticalLine(const CColLine &line, const CMatrix &matrix, CColModel &model, CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly);
static int32 ProcessColModels(const CMatrix &matrixA, CColModel &modelA, const CMatrix &matrixB, CColModel &modelB, CColPoint *spherepoints, CColPoint *linepoints, float *linedists);
- // TODO:
static bool IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly);
static float DistToLine(const CVector *l0, const CVector *l1, const CVector *point);
diff --git a/src/core/Debug.cpp b/src/core/Debug.cpp
index 2b713198..917c99ab 100644
--- a/src/core/Debug.cpp
+++ b/src/core/Debug.cpp
@@ -24,7 +24,7 @@ CDebug::DebugAddText(const char *str)
{
int32 i = 0;
if (*str != '\0') {
- while (i < MAX_STR_LEN) {
+ while (i < MAX_STR_LEN - 1) {
ms_aTextBuffer[ms_nCurrentTextLine][i++] = *(str++);
if (*str == '\0')
break;
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index 6305bf33..e0a0fafc 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -25,8 +25,6 @@
#include "CdStream.h"
#include "FileLoader.h"
-WRAPPER void CFileLoader::ReloadPaths(const char *filename) { EAXJMP(0x476DB0); }
-
char CFileLoader::ms_line[256];
const char*
@@ -311,7 +309,7 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
int n;
RpClump *clump = (RpClump*)data;
- nodename = GetFrameNodeName(RpClumpGetFrame(atomic));
+ nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
GetNameAndLOD(nodename, name, &n);
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
@@ -1198,6 +1196,165 @@ CFileLoader::LoadMapZones(const char *filename)
debug("Finished loading IPL\n");
}
+void
+CFileLoader::ReloadPaths(const char *filename)
+{
+ enum {
+ NONE,
+ PATH,
+ };
+ char *line;
+ int section = NONE;
+ int id, pathType, pathIndex = -1;
+ char pathTypeStr[20];
+ debug("Reloading paths from %s...\n", filename);
+
+ int fd = CFileMgr::OpenFile(filename, "r");
+ for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
+ if (*line == '\0' || *line == '#')
+ continue;
+
+ if (section == NONE) {
+ if (strncmp(line, "path", 4) == 0) {
+ section = PATH;
+ ThePaths.AllocatePathFindInfoMem(4500);
+ }
+ } else if (strncmp(line, "end", 3) == 0) {
+ section = NONE;
+ } else {
+ switch (section) {
+ case PATH:
+ if (pathIndex == -1) {
+ id = LoadPathHeader(line, pathTypeStr);
+ if (strncmp(pathTypeStr, "ped", 4) == 0)
+ pathType = 1;
+ else if (strncmp(pathTypeStr, "car", 4) == 0)
+ pathType = 0;
+ pathIndex = 0;
+ } else {
+ if (pathType == 1)
+ LoadPedPathNode(line, id, pathIndex);
+ else if (pathType == 0)
+ LoadCarPathNode(line, id, pathIndex);
+ pathIndex++;
+ if (pathIndex == 12)
+ pathIndex = -1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ CFileMgr::CloseFile(fd);
+}
+
+void
+CFileLoader::ReloadObjectTypes(const char *filename)
+{
+ enum {
+ NONE,
+ OBJS,
+ TOBJ,
+ TWODFX
+ };
+ char *line;
+ int section = NONE;
+ CModelInfo::ReInit2dEffects();
+ debug("Reloading object types from %s...\n", filename);
+
+ CFileMgr::ChangeDir("\\DATA\\MAPS\\");
+ int fd = CFileMgr::OpenFile(filename, "r");
+ CFileMgr::ChangeDir("\\");
+ for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
+ if (*line == '\0' || *line == '#')
+ continue;
+
+ if (section == NONE) {
+ if (strncmp(line, "objs", 4) == 0) section = OBJS;
+ else if (strncmp(line, "tobj", 4) == 0) section = TOBJ;
+ else if (strncmp(line, "2dfx", 4) == 0) section = TWODFX;
+ } else if (strncmp(line, "end", 3) == 0) {
+ section = NONE;
+ } else {
+ switch (section) {
+ case OBJS:
+ case TOBJ:
+ ReloadObject(line);
+ break;
+ case TWODFX:
+ Load2dEffect(line);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ CFileMgr::CloseFile(fd);
+}
+
+void
+CFileLoader::ReloadObject(const char *line)
+{
+ int id, numObjs;
+ char model[24], txd[24];
+ float dist[3];
+ uint32 flags;
+ CSimpleModelInfo *mi;
+
+ if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
+ return;
+
+ switch(numObjs){
+ case 1:
+ sscanf(line, "%d %s %s %d %f %d",
+ &id, model, txd, &numObjs, &dist[0], &flags);
+ break;
+ case 2:
+ sscanf(line, "%d %s %s %d %f %f %d",
+ &id, model, txd, &numObjs, &dist[0], &dist[1], &flags);
+ break;
+ case 3:
+ sscanf(line, "%d %s %s %d %f %f %f %d",
+ &id, model, txd, &numObjs, &dist[0], &dist[1], &dist[2], &flags);
+ break;
+ }
+
+ mi = (CSimpleModelInfo*) CModelInfo::GetModelInfo(id);
+ if (
+#ifdef FIX_BUGS
+ mi &&
+#endif
+ mi->m_type == MITYPE_SIMPLE && !strcmp(mi->GetName(), model) && mi->m_numAtomics == numObjs) {
+ mi->SetLodDistances(dist);
+ SetModelInfoFlags(mi, flags);
+ } else {
+ printf("Can't reload %s\n", model);
+ }
+}
+
+// unused mobile function - crashes
+void
+CFileLoader::ReLoadScene(const char *filename)
+{
+ char *line;
+ CFileMgr::ChangeDir("\\DATA\\");
+ int fd = CFileMgr::OpenFile(filename, "r");
+ CFileMgr::ChangeDir("\\");
+
+ for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
+ if (*line == '#')
+ continue;
+
+ if (strncmp(line, "EXIT", 9) == 0) // BUG: 9?
+ break;
+
+ if (strncmp(line, "IDE", 3) == 0) {
+ LoadObjectTypes(line + 4);
+ }
+ }
+ CFileMgr::CloseFile(fd);
+}
STARTPATCHES
InjectHook(0x476290, CFileLoader::LoadLevel, PATCH_JUMP);
@@ -1233,4 +1390,8 @@ STARTPATCHES
InjectHook(0x478A90, CFileLoader::LoadCullZone, PATCH_JUMP);
InjectHook(0x478550, CFileLoader::LoadMapZones, PATCH_JUMP);
+
+ InjectHook(0x476DB0, CFileLoader::ReloadPaths, PATCH_JUMP);
+ InjectHook(0x476F30, CFileLoader::ReloadObjectTypes, PATCH_JUMP);
+ InjectHook(0x4772B0, CFileLoader::ReloadObject, PATCH_JUMP);
ENDPATCHES
diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h
index 1b390279..87b8fe61 100644
--- a/src/core/FileLoader.h
+++ b/src/core/FileLoader.h
@@ -43,4 +43,7 @@ public:
static void LoadMapZones(const char *filename);
static void ReloadPaths(const char *filename);
+ static void ReloadObjectTypes(const char *filename);
+ static void ReloadObject(const char *line);
+ static void ReLoadScene(const char *filename); // unused mobile function
};
diff --git a/src/core/FrontEndControls.cpp b/src/core/FrontEndControls.cpp
new file mode 100644
index 00000000..866be42f
--- /dev/null
+++ b/src/core/FrontEndControls.cpp
@@ -0,0 +1,1881 @@
+#include "common.h"
+#include "main.h"
+#include "Timer.h"
+#include "Pad.h"
+#include "ControllerConfig.h"
+#include "VisibilityPlugins.h"
+#include "Sprite2d.h"
+#include "Text.h"
+#include "Font.h"
+#include "Frontend.h"
+#include "FrontEndControls.h"
+
+
+void
+CPlaceableShText::Draw(float x, float y)
+{
+ if(m_text == nil)
+ return;
+
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOn();
+ if(m_bDropShadow){
+ CFont::SetDropShadowPosition(m_shadowOffset.x);
+ CFont::SetDropColor(m_shadowColor);
+ }
+ CFont::SetColor(m_color);
+ CFont::PrintString(x+m_position.x, y+m_position.y, m_text);
+ if(m_bDropShadow)
+ CFont::SetDropShadowPosition(0);
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOff();
+}
+
+void
+CPlaceableShText::Draw(const CRGBA &color, float x, float y)
+{
+ if(m_text == nil)
+ return;
+
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOn();
+ if(m_bDropShadow){
+ CFont::SetDropShadowPosition(m_shadowOffset.x);
+ CFont::SetDropColor(m_shadowColor);
+ }
+ CFont::SetColor(color);
+ CFont::PrintString(x+m_position.x, y+m_position.y, m_text);
+ if(m_bDropShadow)
+ CFont::SetDropShadowPosition(0);
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOff();
+}
+
+void
+CPlaceableShTextTwoLines::Draw(float x, float y)
+{
+ if(m_line1.m_text == nil && m_line2.m_text == nil)
+ return;
+
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOn();
+ if(m_bDropShadow){
+ CFont::SetDropShadowPosition(m_shadowOffset.x);
+ CFont::SetDropColor(m_shadowColor);
+ }
+
+ if(m_line1.m_text){
+ CFont::SetColor(m_line1.m_color);
+ CFont::PrintString(x+m_line1.m_position.x, y+m_line1.m_position.y, m_line1.m_text);
+ }
+ if(m_line2.m_text){
+ CFont::SetColor(m_line2.m_color);
+ CFont::PrintString(x+m_line2.m_position.x, y+m_line2.m_position.y, m_line2.m_text);
+ }
+
+ if(m_bDropShadow)
+ CFont::SetDropShadowPosition(0);
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOff();
+}
+
+void
+CPlaceableShTextTwoLines::Draw(const CRGBA &color, float x, float y)
+{
+ if(m_line1.m_text == nil && m_line2.m_text == nil)
+ return;
+
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOn();
+ if(m_bDropShadow){
+ CFont::SetDropShadowPosition(m_shadowOffset.x);
+ CFont::SetDropColor(m_shadowColor);
+ }
+
+ if(m_line1.m_text){
+ CFont::SetColor(color);
+ CFont::PrintString(x+m_line1.m_position.x, y+m_line1.m_position.y, m_line1.m_text);
+ }
+ if(m_line2.m_text){
+ CFont::SetColor(color);
+ CFont::PrintString(x+m_line2.m_position.x, y+m_line2.m_position.y, m_line2.m_text);
+ }
+
+ if(m_bDropShadow)
+ CFont::SetDropShadowPosition(0);
+ if(m_bRightJustify)
+ CFont::SetRightJustifyOff();
+}
+
+void
+CPlaceableShOption::Draw(const CRGBA &highlightColor, float x, float y, bool bHighlight)
+{
+ if(bHighlight)
+ CPlaceableShText::Draw(highlightColor, x, y);
+ else if(m_bSelected)
+ CPlaceableShText::Draw(m_selectedColor, x, y);
+ else
+ CPlaceableShText::Draw(x, y);
+}
+
+void
+CPlaceableShOptionTwoLines::Draw(const CRGBA &highlightColor, float x, float y, bool bHighlight)
+{
+ if(bHighlight)
+ CPlaceableShTextTwoLines::Draw(highlightColor, x, y);
+ else if(m_bSelected)
+ CPlaceableShTextTwoLines::Draw(m_selectedColor, x, y);
+ else
+ CPlaceableShTextTwoLines::Draw(x, y);
+}
+
+void
+CPlaceableSprite::Draw(float x, float y)
+{
+ Draw(m_color, x, y);
+}
+
+void
+CPlaceableSprite::Draw(const CRGBA &color, float x, float y)
+{
+ if(m_pSprite)
+ m_pSprite->Draw(CRect(m_position.x+x, m_position.y+y,
+ m_position.x+x + m_size.x, m_position.y+y + m_size.y),
+ color);
+}
+
+void
+CPlaceableShSprite::Draw(float x, float y)
+{
+ if(m_bDropShadow)
+ m_shadow.Draw(m_shadow.m_color, m_sprite.m_position.x+x, m_sprite.m_position.y+y);
+ m_sprite.Draw(x, y);
+}
+
+
+/*
+ * CMenuPictureAndText
+ */
+
+void
+CMenuPictureAndText::SetNewOldShadowWrapX(bool bWrapX, float newWrapX, float oldWrapX)
+{
+ m_bWrap = bWrapX;
+ m_wrapX = newWrapX;
+ m_oldWrapx = oldWrapX;
+}
+
+void
+CMenuPictureAndText::SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale)
+{
+ m_bSetTextScale = bTextScale;
+ m_textScale = newScale;
+ m_oldTextScale = oldScale;
+}
+
+void
+CMenuPictureAndText::SetTextsColor(CRGBA const &color)
+{
+ int i;
+ for(i = 0; i < m_numTexts; i++)
+ m_texts[i].m_color = color;
+}
+
+void
+CMenuPictureAndText::AddText(wchar *text, float positionX, float positionY, CRGBA const &color, bool bRightJustify)
+{
+ int i;
+ if(m_numTexts >= 20)
+ return;
+ i = m_numTexts++;
+ m_texts[i].m_text = text;
+ m_texts[i].m_position.x = positionX;
+ m_texts[i].m_position.y = positionY;
+ m_texts[i].m_color = color;
+ m_texts[i].m_bRightJustify = bRightJustify;
+}
+
+void
+CMenuPictureAndText::AddPicture(CSprite2d *sprite, CSprite2d *shadow, float positionX, float positionY, float width, float height, CRGBA const &color)
+{
+ int i;
+ if(m_numSprites >= 5)
+ return;
+ i = m_numSprites++;
+ m_sprites[i].m_sprite.m_pSprite = sprite;
+ m_sprites[i].m_shadow.m_pSprite = shadow;
+ m_sprites[i].m_sprite.m_position.x = positionX;
+ m_sprites[i].m_sprite.m_position.y = positionY;
+ m_sprites[i].m_sprite.m_size.x = width;
+ m_sprites[i].m_sprite.m_size.y = height;
+ m_sprites[i].m_shadow.m_size.x = width;
+ m_sprites[i].m_shadow.m_size.y = height;
+ m_sprites[i].m_sprite.m_color = color;
+}
+
+void
+CMenuPictureAndText::AddPicture(CSprite2d *sprite, float positionX, float positionY, float width, float height, CRGBA const &color)
+{
+ int i;
+ if(m_numSprites >= 5)
+ return;
+ i = m_numSprites++;
+ m_sprites[i].m_sprite.m_pSprite = sprite;
+ m_sprites[i].m_shadow.m_pSprite = nil;
+ m_sprites[i].m_sprite.m_position.x = positionX;
+ m_sprites[i].m_sprite.m_position.y = positionY;
+ m_sprites[i].m_sprite.m_size.x = width;
+ m_sprites[i].m_sprite.m_size.y = height;
+ m_sprites[i].m_shadow.m_size.x = width;
+ m_sprites[i].m_shadow.m_size.y = height;
+ m_sprites[i].m_sprite.m_color = color;
+}
+
+void
+CMenuPictureAndText::Draw(CRGBA const &,CRGBA const &, float x, float y)
+{
+ int i;
+
+ for(i = 0; i < m_numSprites; i++)
+ m_sprites[i].Draw(m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ for(i = 0; i < m_numTexts; i++)
+ if(m_bWrap)
+ m_texts[i].DrawShWrap(m_position.x+x, m_position.y+y, m_wrapX, m_oldWrapx);
+ else
+ m_texts[i].Draw(m_position.x+x, m_position.y+y);
+ if(m_bSetTextScale)
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+}
+
+void
+CMenuPictureAndText::SetAlpha(uint8 alpha)
+{
+ int i;
+
+ for(i = 0; i < m_numSprites; i++)
+ m_sprites[i].SetAlpha(alpha);
+ for(i = 0; i < m_numTexts; i++)
+ m_texts[i].SetAlpha(alpha);
+}
+
+void
+CMenuPictureAndText::SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset)
+{
+ int i;
+
+ for(i = 0; i < 5; i++)
+ m_sprites[i].SetShadows(bDropShadows, shadowColor, shadowOffset);
+ for(i = 0; i < 20; i++)
+ m_texts[i].SetShadows(bDropShadows, shadowColor, shadowOffset);
+}
+
+/*
+ * CMenuMultiChoice
+ */
+
+void
+CMenuMultiChoice::AddTitle(wchar *text, float positionX, float positionY, bool bRightJustify)
+{
+ m_title.m_text = text;
+ m_title.SetPosition(positionX, positionY, bRightJustify);
+}
+
+CPlaceableShOption*
+CMenuMultiChoice::AddOption(wchar *text, float positionX, float positionY, bool bSelected, bool bRightJustify)
+{
+ if(m_numOptions == NUM_MULTICHOICE_OPTIONS)
+ return nil;
+ m_options[m_numOptions].m_text = text;
+ m_options[m_numOptions].SetPosition(positionX, positionY);
+ m_options[m_numOptions].m_bSelected = bSelected;
+ m_options[m_numOptions].m_bRightJustify = bRightJustify;
+ return &m_options[m_numOptions++];
+}
+
+void
+CMenuMultiChoice::SetColors(const CRGBA &title, const CRGBA &normal, const CRGBA &selected)
+{
+ int i;
+ m_title.SetColor(title);
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].SetColors(normal, selected);
+}
+
+void
+CMenuMultiChoice::SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale)
+{
+ m_bSetTextScale = bTextScale;
+ m_textScale = newScale;
+ m_oldTextScale = oldScale;
+ m_bSetTitleTextScale = bTitleTextScale;
+}
+
+void
+CMenuMultiChoice::Draw(CRGBA const &optionHighlight ,CRGBA const &titleHighlight, float x, float y)
+{
+ int i;
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ if(m_cursor == -1)
+ m_title.Draw(m_position.x+x, m_position.y+y);
+ else
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ if(m_cursor == -1)
+ for(i = 0; i < m_numOptions; i++)
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+ else
+ for(i = 0; i < m_numOptions; i++){
+ if(i == m_cursor)
+ m_options[i].Draw(optionHighlight, m_position.x+x, m_position.y+y);
+ else
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+ }
+
+ if(m_bSetTextScale){
+ CFont::DrawFonts();
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+ }
+}
+
+void
+CMenuMultiChoice::DrawNormal(float x, float y)
+{
+ int i;
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ m_title.Draw(m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ for(i = 0; i < m_numOptions; i++)
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+
+ if(m_bSetTextScale){
+ CFont::DrawFonts();
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+ }
+}
+
+void
+CMenuMultiChoice::DrawHighlighted(CRGBA const &titleHighlight, float x, float y)
+{
+ int i;
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ if(m_cursor == -1)
+ m_title.Draw(m_position.x+x, m_position.y+y);
+ else
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ for(i = 0; i < m_numOptions; i++)
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+
+ if(m_bSetTextScale){
+ CFont::DrawFonts();
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+ }
+}
+
+void
+CMenuMultiChoice::SetAlpha(uint8 alpha)
+{
+ int i;
+ m_title.SetAlpha(alpha);
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].SetAlpha(alpha);
+}
+
+void
+CMenuMultiChoice::SetShadows(bool bDropShadows, CRGBA const &shadowColor, CVector2D const &shadowOffset)
+{
+ int i;
+ m_title.SetShadows(bDropShadows, shadowColor, shadowOffset);
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].SetShadows(bDropShadows, shadowColor, shadowOffset);
+}
+
+
+bool
+CMenuMultiChoice::GoNext(void)
+{
+ if(m_cursor == m_numOptions-1){
+ m_cursor = -1;
+ return false;
+ }else{
+ m_cursor++;
+ return true;
+ }
+}
+
+bool
+CMenuMultiChoice::GoPrev(void)
+{
+ if(m_cursor == 0){
+ m_cursor = -1;
+ return false;
+ }else{
+ m_cursor--;
+ return true;
+ }
+}
+
+void
+CMenuMultiChoice::SelectCurrentOptionUnderCursor(void)
+{
+ int i;
+ if(m_cursor == -1)
+ return;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].m_bSelected = false;
+ m_options[m_cursor].m_bSelected = true;
+}
+
+int
+CMenuMultiChoice::GetMenuSelection(void)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ if(m_options[i].m_bSelected)
+ return i;
+ return -1;
+}
+
+void
+CMenuMultiChoice::SetMenuSelection(int selection)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].m_bSelected = false;
+ m_options[selection%NUM_MULTICHOICE_OPTIONS].m_bSelected = true;
+}
+
+/*
+ * CMenuMultiChoiceTriggered
+ */
+
+void
+CMenuMultiChoiceTriggered::Initialise(void)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_triggers[i] = nil;
+ m_defaultCancel = nil;
+}
+
+CPlaceableShOption*
+CMenuMultiChoiceTriggered::AddOption(wchar *text, float positionX, float positionY, Trigger trigger, bool bSelected, bool bRightJustify)
+{
+ CPlaceableShOption *option;
+ option = CMenuMultiChoice::AddOption(text, positionX, positionY, bSelected, bRightJustify);
+ if(option)
+ m_triggers[m_numOptions-1] = trigger;
+ return option;
+}
+
+void
+CMenuMultiChoiceTriggered::SelectCurrentOptionUnderCursor(void)
+{
+ CMenuMultiChoice::SelectCurrentOptionUnderCursor();
+ if(m_cursor != -1)
+ m_triggers[m_cursor](this);
+}
+
+void
+CMenuMultiChoiceTriggered::SelectDefaultCancelAction(void)
+{
+ if(m_defaultCancel)
+ m_defaultCancel(this);
+}
+
+/*
+ * CMenuMultiChoiceTriggeredAlways
+ */
+
+void
+CMenuMultiChoiceTriggeredAlways::Draw(CRGBA const &optionHighlight, CRGBA const &titleHighlight, float x, float y)
+{
+ if(m_alwaysTrigger)
+ m_alwaysTrigger(this);
+ CMenuMultiChoiceTriggered::Draw(optionHighlight, titleHighlight, x, y);
+}
+
+void
+CMenuMultiChoiceTriggeredAlways::DrawNormal(float x, float y)
+{
+ if(m_alwaysNormalTrigger)
+ m_alwaysNormalTrigger(this);
+ CMenuMultiChoiceTriggered::DrawNormal(x, y);
+}
+
+void
+CMenuMultiChoiceTriggeredAlways::DrawHighlighted(CRGBA const &titleHighlight, float x, float y)
+{
+ if(m_alwaysHighlightTrigger)
+ m_alwaysHighlightTrigger(this);
+ CMenuMultiChoiceTriggered::DrawHighlighted(titleHighlight, x, y);
+}
+
+/*
+ * CMenuMultiChoicePictured
+ */
+
+void
+CMenuMultiChoicePictured::Initialise(void)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_bHasSprite[i] = false;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_sprites[i].m_pSprite = nil;
+}
+
+CPlaceableShOption*
+CMenuMultiChoicePictured::AddOption(CSprite2d *sprite, float positionX, float positionY, const CVector2D &size, bool bSelected)
+{
+ CPlaceableShOption *option;
+ option = CMenuMultiChoice::AddOption(nil, 0.0f, 0.0f, bSelected, false);
+ if(option){
+ m_sprites[m_numOptions-1].m_pSprite = sprite;
+ m_sprites[m_numOptions-1].SetPosition(positionX, positionY);
+ m_sprites[m_numOptions-1].m_size = size;
+ m_bHasSprite[m_numOptions-1] = true;
+ }
+ return option;
+}
+
+void
+CMenuMultiChoicePictured::Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y)
+{
+ int i;
+
+ // The title and all the text
+ CMenuMultiChoice::Draw(optionHighlight, titleHighlight, x, y);
+
+ CRGBA selectedColor = m_options[0].GetSelectedColor();
+ CRGBA color = m_options[0].GetColor();
+
+ // The sprites
+ if(m_cursor == -1){
+ for(i = 0; i < m_numOptions; i++)
+ if(m_bHasSprite[i]){
+ if(m_options[i].m_bSelected)
+ m_sprites[i].Draw(selectedColor, m_position.x+x, m_position.y+y);
+ else
+ m_sprites[i].Draw(color, m_position.x+x, m_position.y+y);
+ }
+ }else{
+ for(i = 0; i < m_numOptions; i++)
+ if(i == m_cursor){
+ if(m_bHasSprite[i])
+ m_sprites[i].Draw(CRGBA(255, 255, 255, 255), m_position.x+x, m_position.y+y);
+ }else{
+ if(m_bHasSprite[i]){
+ if(m_options[i].m_bSelected)
+ m_sprites[i].Draw(selectedColor, m_position.x+x, m_position.y+y);
+ else
+ m_sprites[i].Draw(color, m_position.x+x, m_position.y+y);
+ }
+ }
+ }
+}
+
+void
+CMenuMultiChoicePictured::DrawNormal(float x, float y)
+{
+ int i;
+
+ // The title and all the text
+ CMenuMultiChoice::DrawNormal(x, y);
+
+ CRGBA selectedColor = m_options[0].GetSelectedColor();
+ CRGBA color = m_options[0].GetColor();
+
+ // The sprites
+ for(i = 0; i < m_numOptions; i++)
+ if(m_bHasSprite[i]){
+ if(m_options[i].m_bSelected)
+ m_sprites[i].Draw(selectedColor, m_position.x+x, m_position.y+y);
+ else
+ m_sprites[i].Draw(color, m_position.x+x, m_position.y+y);
+ }
+}
+
+void
+CMenuMultiChoicePictured::DrawHighlighted(const CRGBA &titleHighlight, float x, float y)
+{
+ int i;
+
+ // The title and all the text
+ CMenuMultiChoice::DrawHighlighted(titleHighlight, x, y);
+
+ CRGBA selectedColor = m_options[0].GetSelectedColor();
+ CRGBA color = m_options[0].GetColor();
+
+ // The sprites
+ for(i = 0; i < m_numOptions; i++)
+ if(m_bHasSprite[i]){
+ if(m_options[i].m_bSelected)
+ m_sprites[i].Draw(selectedColor, m_position.x+x, m_position.y+y);
+ else
+ m_sprites[i].Draw(color, m_position.x+x, m_position.y+y);
+ }
+}
+
+void
+CMenuMultiChoicePictured::SetAlpha(uint8 alpha)
+{
+ int i;
+ CMenuMultiChoice::SetAlpha(alpha);
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_sprites[i].SetAlpha(alpha);
+
+}
+
+
+/*
+ * CMenuMultiChoicePicturedTriggered
+ */
+
+void
+CMenuMultiChoicePicturedTriggered::Initialise(void)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_triggers[i] = nil;
+ m_defaultCancel = nil; // missing on PS2
+}
+
+CPlaceableShOption*
+CMenuMultiChoicePicturedTriggered::AddOption(CSprite2d *sprite, float positionX, float positionY, const CVector2D &size, Trigger trigger, bool bSelected)
+{
+ CPlaceableShOption *option;
+ option = CMenuMultiChoicePictured::AddOption(sprite, positionX, positionY, size, bSelected);
+ if(option)
+ m_triggers[m_numOptions-1] = trigger;
+ return option;
+}
+
+void
+CMenuMultiChoicePicturedTriggered::SelectCurrentOptionUnderCursor(void)
+{
+ CMenuMultiChoice::SelectCurrentOptionUnderCursor();
+ if(m_cursor != -1)
+ m_triggers[m_cursor](this);
+}
+
+void
+CMenuMultiChoicePicturedTriggered::SelectDefaultCancelAction(void)
+{
+ if(m_defaultCancel)
+ m_defaultCancel(this);
+}
+
+/*
+ * CMenuMultiChoicePicturedTriggeredAnyMove
+ */
+
+void
+CMenuMultiChoicePicturedTriggeredAnyMove::Initialise(void)
+{
+ int i;
+ CMenuMultiChoicePicturedTriggered::Initialise();
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++){
+ m_moveTab[i].right = -1;
+ m_moveTab[i].left = -1;
+ m_moveTab[i].down = -1;
+ m_moveTab[i].up = -1;
+ }
+}
+
+CPlaceableShOption*
+CMenuMultiChoicePicturedTriggeredAnyMove::AddOption(CSprite2d *sprite, FEC_MOVETAB *moveTab, float positionX, float positionY, const CVector2D &size, Trigger trigger, bool bSelected)
+{
+ CPlaceableShOption *option;
+ option = CMenuMultiChoicePicturedTriggered::AddOption(sprite, positionX, positionY, size, trigger, bSelected);
+ if(option && moveTab)
+ m_moveTab[m_numOptions-1] = *moveTab;
+ return option;
+}
+
+bool
+CMenuMultiChoicePicturedTriggeredAnyMove::GoDown(void)
+{
+ int move = m_moveTab[m_cursor].down;
+ if(move == -1)
+ return GoNext();
+ m_cursor = move;
+ return true;
+}
+
+bool
+CMenuMultiChoicePicturedTriggeredAnyMove::GoUp(void)
+{
+ int move = m_moveTab[m_cursor].up;
+ if(move == -1)
+ return GoPrev();
+ m_cursor = move;
+ return true;
+}
+
+bool
+CMenuMultiChoicePicturedTriggeredAnyMove::GoLeft(void)
+{
+ int move = m_moveTab[m_cursor].left;
+ if(move == -1)
+ return GoPrev();
+ m_cursor = move;
+ return true;
+}
+
+bool
+CMenuMultiChoicePicturedTriggeredAnyMove::GoRight(void)
+{
+ int move = m_moveTab[m_cursor].right;
+ if(move == -1)
+ return GoNext();
+ m_cursor = move;
+ return true;
+}
+
+
+/*
+ * CMenuMultiChoiceTwoLines
+ */
+
+void
+CMenuMultiChoiceTwoLines::AddTitle(wchar *text, float positionX, float positionY, bool bRightJustify)
+{
+ m_title.m_text = text;
+ m_title.SetPosition(positionX, positionY, bRightJustify);
+}
+
+CPlaceableShOptionTwoLines*
+CMenuMultiChoiceTwoLines::AddOption(wchar *text, float positionX, float positionY, bool bSelected, bool bRightJustify)
+{
+ return AddOption(text, positionX, positionY, nil, 0.0f, 0.0f, bSelected, bRightJustify);
+}
+
+CPlaceableShOptionTwoLines*
+CMenuMultiChoiceTwoLines::AddOption(wchar *text1, float positionX1, float positionY1, wchar *text2, float positionX2, float positionY2, bool bSelected, bool bRightJustify)
+{
+ if(m_numOptions == NUM_MULTICHOICE_OPTIONS)
+ return nil;
+ m_options[m_numOptions].m_line1.m_text = text1;
+ m_options[m_numOptions].m_line2.m_text = text2;
+ m_options[m_numOptions].m_line1.SetPosition(positionX1, positionY1);
+ m_options[m_numOptions].m_line2.SetPosition(positionX2, positionY2);
+ m_options[m_numOptions].m_bSelected = bSelected;
+ m_options[m_numOptions].m_bRightJustify = bRightJustify;
+ return &m_options[m_numOptions++];
+}
+
+
+void
+CMenuMultiChoiceTwoLines::SetColors(const CRGBA &title, const CRGBA &normal, const CRGBA &selected)
+{
+ int i;
+ m_title.SetColor(title);
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].SetColors(normal, selected);
+}
+
+void
+CMenuMultiChoiceTwoLines::SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale)
+{
+ m_bSetTextScale = bTextScale;
+ m_textScale = newScale;
+ m_oldTextScale = oldScale;
+ m_bSetTitleTextScale = bTitleTextScale;
+}
+
+void
+CMenuMultiChoiceTwoLines::Draw(CRGBA const &optionHighlight ,CRGBA const &titleHighlight, float x, float y)
+{
+ int i;
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ if(m_cursor == -1)
+ m_title.Draw(m_position.x+x, m_position.y+y);
+ else
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ if(m_cursor == -1)
+ for(i = 0; i < m_numOptions; i++)
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+ else
+ for(i = 0; i < m_numOptions; i++){
+ if(i == m_cursor)
+ m_options[i].Draw(optionHighlight, m_position.x+x, m_position.y+y);
+ else
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+ }
+
+ if(m_bSetTextScale){
+ CFont::DrawFonts();
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+ }
+}
+
+void
+CMenuMultiChoiceTwoLines::DrawNormal(float x, float y)
+{
+ int i;
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ m_title.Draw(m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ for(i = 0; i < m_numOptions; i++)
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+
+ if(m_bSetTextScale){
+ CFont::DrawFonts();
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+ }
+}
+
+void
+CMenuMultiChoiceTwoLines::DrawHighlighted(CRGBA const &titleHighlight, float x, float y)
+{
+ int i;
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ if(m_cursor == -1)
+ m_title.Draw(m_position.x+x, m_position.y+y);
+ else
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ for(i = 0; i < m_numOptions; i++)
+ m_options[i].Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+
+ if(m_bSetTextScale){
+ CFont::DrawFonts();
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+ }
+}
+
+void
+CMenuMultiChoiceTwoLines::SetAlpha(uint8 alpha)
+{
+ int i;
+ m_title.SetAlpha(alpha);
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].SetAlpha(alpha);
+}
+
+void
+CMenuMultiChoiceTwoLines::SetShadows(bool bDropShadows, CRGBA const &shadowColor, CVector2D const &shadowOffset)
+{
+ int i;
+ m_title.SetShadows(bDropShadows, shadowColor, shadowOffset);
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].SetShadows(bDropShadows, shadowColor, shadowOffset);
+}
+
+
+bool
+CMenuMultiChoiceTwoLines::GoNext(void)
+{
+ if(m_cursor == m_numOptions-1){
+ m_cursor = -1;
+ return false;
+ }else{
+ m_cursor++;
+ return true;
+ }
+}
+
+bool
+CMenuMultiChoiceTwoLines::GoPrev(void)
+{
+ if(m_cursor == 0){
+ m_cursor = -1;
+ return false;
+ }else{
+ m_cursor--;
+ return true;
+ }
+}
+
+void
+CMenuMultiChoiceTwoLines::SelectCurrentOptionUnderCursor(void)
+{
+ int i;
+ if(m_cursor == -1)
+ return;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].m_bSelected = false;
+ m_options[m_cursor].m_bSelected = true;
+}
+
+int
+CMenuMultiChoiceTwoLines::GetMenuSelection(void)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ if(m_options[i].m_bSelected)
+ return i;
+ return -1;
+}
+
+void
+CMenuMultiChoiceTwoLines::SetMenuSelection(int selection)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_options[i].m_bSelected = false;
+ m_options[selection%NUM_MULTICHOICE_OPTIONS].m_bSelected = true;
+}
+
+/*
+ * CMenuMultiChoiceTwoLinesTriggered
+ */
+
+void
+CMenuMultiChoiceTwoLinesTriggered::Initialise(void)
+{
+ int i;
+ for(i = 0; i < NUM_MULTICHOICE_OPTIONS; i++)
+ m_triggers[i] = nil;
+ m_defaultCancel = nil;
+}
+
+CPlaceableShOptionTwoLines*
+CMenuMultiChoiceTwoLinesTriggered::AddOption(wchar *text, float positionX, float positionY, Trigger trigger, bool bSelected, bool bRightJustify)
+{
+ CPlaceableShOptionTwoLines *option;
+ option = CMenuMultiChoiceTwoLines::AddOption(text, positionX, positionY, bSelected, bRightJustify);
+ if(option)
+ m_triggers[m_numOptions-1] = trigger;
+ return option;
+}
+
+CPlaceableShOptionTwoLines*
+CMenuMultiChoiceTwoLinesTriggered::AddOption(wchar *text1, float positionX1, float positionY1, wchar *text2, float positionX2, float positionY2, Trigger trigger, bool bSelected, bool bRightJustify)
+{
+ CPlaceableShOptionTwoLines *option;
+ option = CMenuMultiChoiceTwoLines::AddOption(text1, positionX1, positionY1, text2, positionX2, positionY2, bSelected, bRightJustify);
+ if(option)
+ m_triggers[m_numOptions-1] = trigger;
+ return option;
+}
+
+void
+CMenuMultiChoiceTwoLinesTriggered::SelectCurrentOptionUnderCursor(void)
+{
+ CMenuMultiChoiceTwoLines::SelectCurrentOptionUnderCursor();
+ if(m_cursor != -1)
+ m_triggers[m_cursor](this);
+}
+
+void
+CMenuMultiChoiceTwoLinesTriggered::SelectDefaultCancelAction(void)
+{
+ if(m_defaultCancel)
+ m_defaultCancel(this);
+}
+
+
+/*
+ * CMenuOnOff
+ */
+
+void
+CMenuOnOff::SetColors(const CRGBA &title, const CRGBA &options)
+{
+ m_title.SetColors(title, title);
+ m_options[0].SetColor(options);
+ m_options[1].SetColor(options);
+}
+
+void
+CMenuOnOff::SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale)
+{
+ m_bSetTextScale = bTextScale;
+ m_textScale = newScale;
+ m_oldTextScale = oldScale;
+ m_bSetTitleTextScale = bTitleTextScale;
+}
+
+void
+CMenuOnOff::SetOptionPosition(float x, float y, bool bRightJustify)
+{
+ m_options[0].SetPosition(x, y, bRightJustify);
+ m_options[1].SetPosition(x, y, bRightJustify);
+}
+
+void
+CMenuOnOff::AddTitle(wchar *text, bool bSelected, float positionX, float positionY, bool bRightJustify)
+{
+ m_title.m_text = text;
+ m_title.m_bSelected = bSelected;
+ m_title.SetPosition(positionX, positionY, bRightJustify);
+}
+
+void
+CMenuOnOff::Draw(CRGBA const &optionHighlight, CRGBA const &titleHighlight, float x, float y)
+{
+ if(m_type == 1){
+ m_options[0].m_text = TheText.Get("FEM_NO");
+ m_options[1].m_text = TheText.Get("FEM_YES");
+ }else if(m_type == 0){
+ m_options[0].m_text = TheText.Get("FEM_OFF");
+ m_options[1].m_text = TheText.Get("FEM_ON");
+ }
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ if(m_bActive)
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+ else
+ m_title.Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ if(m_bActive){
+ if(m_title.m_bSelected)
+ m_options[1].Draw(optionHighlight, m_position.x+x, m_position.y+y);
+ else
+ m_options[0].Draw(optionHighlight, m_position.x+x, m_position.y+y);
+ }else{
+ if(m_title.m_bSelected)
+ m_options[1].Draw(m_position.x+x, m_position.y+y);
+ else
+ m_options[0].Draw(m_position.x+x, m_position.y+y);
+ }
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+}
+
+void
+CMenuOnOff::DrawNormal(float x, float y)
+{
+ if(m_type == 1){
+ m_options[0].m_text = TheText.Get("FEM_NO");
+ m_options[1].m_text = TheText.Get("FEM_YES");
+ }else if(m_type == 0){
+ m_options[0].m_text = TheText.Get("FEM_OFF");
+ m_options[1].m_text = TheText.Get("FEM_ON");
+ }
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ m_title.Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ if(m_title.m_bSelected)
+ m_options[1].Draw(m_position.x+x, m_position.y+y);
+ else
+ m_options[0].Draw(m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+}
+
+void
+CMenuOnOff::DrawHighlighted(CRGBA const &titleHighlight, float x, float y)
+{
+ if(m_type == 1){
+ m_options[0].m_text = TheText.Get("FEM_NO");
+ m_options[1].m_text = TheText.Get("FEM_YES");
+ }else if(m_type == 0){
+ m_options[0].m_text = TheText.Get("FEM_OFF");
+ m_options[1].m_text = TheText.Get("FEM_ON");
+ }
+
+ if(m_bSetTextScale && m_bSetTitleTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+ if(m_bActive)
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+ else
+ m_title.Draw(CRGBA(0,0,0,0), m_position.x+x, m_position.y+y, false);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_textScale.x, m_textScale.y);
+
+ if(m_title.m_bSelected)
+ m_options[1].Draw(m_position.x+x, m_position.y+y);
+ else
+ m_options[0].Draw(m_position.x+x, m_position.y+y);
+
+ if(m_bSetTextScale)
+ CFont::SetScale(m_oldTextScale.x, m_oldTextScale.y);
+}
+
+void
+CMenuOnOff::SetAlpha(uint8 alpha)
+{
+ m_title.SetAlpha(alpha);
+ m_options[0].SetAlpha(alpha);
+ m_options[1].SetAlpha(alpha);
+}
+
+void
+CMenuOnOff::SetShadows(bool bDropShadows, CRGBA const &shadowColor, CVector2D const &shadowOffset)
+{
+ m_title.SetShadows(bDropShadows, shadowColor, shadowOffset);
+ m_options[0].SetShadows(bDropShadows, shadowColor, shadowOffset);
+ m_options[1].SetShadows(bDropShadows, shadowColor, shadowOffset);
+}
+
+/*
+ * CMenuOnOffTriggered
+ */
+
+void
+CMenuOnOffTriggered::SetOptionPosition(float x, float y, Trigger trigger, bool bRightJustify)
+{
+ CMenuOnOff::SetOptionPosition(x, y, bRightJustify);
+ if(trigger)
+ m_trigger = trigger;
+}
+
+void
+CMenuOnOffTriggered::SelectCurrentOptionUnderCursor(void)
+{
+ CMenuOnOff::SelectCurrentOptionUnderCursor();
+ if(m_trigger)
+ m_trigger(this);
+}
+
+
+
+/*
+ * CMenuSlider
+ */
+
+char CMenuSlider::Buf8[8];
+wchar CMenuSlider::Buf16[8];
+
+void
+CMenuSlider::SetColors(const CRGBA &title, const CRGBA &percentage, const CRGBA &left, const CRGBA &right)
+{
+ m_title.SetColor(title);
+ m_percentageText.SetColor(percentage);
+ m_colors[0] = left;
+ m_colors[1] = right;
+}
+
+
+void
+CMenuSlider::AddTickBox(float positionX, float positionY, float width, float heightLeft, float heightRight)
+{
+ m_box.SetPosition(positionX, positionY);
+ m_size[0].x = width;
+ m_size[0].y = heightLeft;
+ m_size[1].x = width;
+ m_size[1].y = heightRight;
+}
+
+void
+CMenuSlider::AddTitle(wchar *text, float positionX, float positionY)
+{
+ m_title.m_text = text;
+ m_title.SetPosition(positionX, positionY);
+}
+
+static CRGBA SELECTED_TEXT_COLOR_0(255, 182, 48, 255);
+
+void
+CMenuSlider::Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y)
+{
+ if(m_bActive){
+ CRGBA selectionCol = m_colors[0];
+ if(selectionCol.red == SELECTED_TEXT_COLOR_0.red &&
+ selectionCol.green == SELECTED_TEXT_COLOR_0.green &&
+ selectionCol.blue == SELECTED_TEXT_COLOR_0.blue &&
+ selectionCol.alpha == SELECTED_TEXT_COLOR_0.alpha)
+ selectionCol = m_colors[1];
+
+ if(m_style == 1){
+ // solid bar
+ CRGBA shadowCol = m_box.GetShadowColor();
+ float f = m_value/1000.0f;
+ CVector2D boxPos = m_box.m_position + m_position + CVector2D(x,y);
+ if(m_box.m_bDropShadow)
+ CSprite2d::DrawRect(
+ CRect(boxPos.x + m_box.m_shadowOffset.x,
+ boxPos.y + m_box.m_shadowOffset.y,
+ boxPos.x + m_box.m_shadowOffset.x + m_size[0].x,
+ boxPos.y + m_box.m_shadowOffset.y + m_size[0].y),
+ shadowCol);
+ CSprite2d::DrawRect(
+ CRect(boxPos.x, boxPos.y,
+ boxPos.x + m_size[0].x, boxPos.y + m_size[0].y),
+ m_colors[1]);
+ CSprite2d::DrawRect(
+ CRect(boxPos.x, boxPos.y,
+ boxPos.x + m_size[0].x*f, boxPos.y + m_size[0].y),
+ selectionCol);
+ }else if(m_style == 0){
+ // ticks...
+ CVector2D boxPos = m_box.m_position + m_position + CVector2D(x,y);
+ DrawTicks(boxPos, m_size[0], m_size[1].y,
+ m_value/1000.0f, m_colors[0], selectionCol, m_colors[1],
+ m_box.m_bDropShadow, m_box.m_shadowOffset, m_box.GetShadowColor());
+ }
+
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+
+ if(m_bDrawPercentage){
+ sprintf(Buf8, "%d%%", m_value/10);
+ AsciiToUnicode(Buf8, Buf16);
+ m_percentageText.m_text = Buf16;
+ m_percentageText.Draw(optionHighlight, m_position.x+x, m_position.y+y);
+ }
+ }else
+ CMenuSlider::DrawNormal(x, y);
+}
+
+void
+CMenuSlider::DrawNormal(float x, float y)
+{
+ if(m_style == 1){
+ // solid bar
+ CRGBA shadowCol = m_box.GetShadowColor();
+ float f = m_value/1000.0f;
+ CVector2D boxPos = m_box.m_position + m_position + CVector2D(x,y);
+ if(m_box.m_bDropShadow)
+ CSprite2d::DrawRect(
+ CRect(boxPos.x + m_box.m_shadowOffset.x,
+ boxPos.y + m_box.m_shadowOffset.y,
+ boxPos.x + m_box.m_shadowOffset.x + m_size[0].x,
+ boxPos.y + m_box.m_shadowOffset.y + m_size[0].y),
+ shadowCol);
+ CSprite2d::DrawRect(
+ CRect(boxPos.x, boxPos.y,
+ boxPos.x + m_size[0].x, boxPos.y + m_size[0].y),
+ m_colors[1]);
+ CSprite2d::DrawRect(
+ CRect(boxPos.x, boxPos.y,
+ boxPos.x + m_size[0].x*f, boxPos.y + m_size[0].y),
+ m_colors[0]);
+ }else if(m_style == 0){
+ // ticks...
+ CVector2D boxPos = m_box.m_position + m_position + CVector2D(x,y);
+ DrawTicks(boxPos, m_size[0], m_size[1].y,
+ m_value/1000.0f, m_colors[0], m_colors[1],
+ m_box.m_bDropShadow, m_box.m_shadowOffset, m_box.GetShadowColor());
+ }
+
+ m_title.Draw(m_position.x+x, m_position.y+y);
+
+ if(m_bDrawPercentage){
+ sprintf(Buf8, "%d%%", m_value/10);
+ AsciiToUnicode(Buf8, Buf16);
+ m_percentageText.m_text = Buf16;
+ m_percentageText.Draw(m_percentageText.GetColor(), m_position.x+x, m_position.y+y);
+ }
+}
+
+void
+CMenuSlider::DrawHighlighted(const CRGBA &titleHighlight, float x, float y)
+{
+ if(m_bActive)
+ m_title.Draw(titleHighlight, m_position.x+x, m_position.y+y);
+ else
+ m_title.Draw(m_position.x+x, m_position.y+y);
+
+ if(m_style == 1){
+ // solid bar
+ CRGBA shadowCol = m_box.GetShadowColor();
+ float f = m_value/1000.0f;
+ CVector2D boxPos = m_box.m_position + m_position + CVector2D(x,y);
+ if(m_box.m_bDropShadow)
+ CSprite2d::DrawRect(
+ CRect(boxPos.x + m_box.m_shadowOffset.x,
+ boxPos.y + m_box.m_shadowOffset.y,
+ boxPos.x + m_box.m_shadowOffset.x + m_size[0].x,
+ boxPos.y + m_box.m_shadowOffset.y + m_size[0].y),
+ shadowCol);
+ CSprite2d::DrawRect(
+ CRect(boxPos.x, boxPos.y,
+ boxPos.x + m_size[0].x, boxPos.y + m_size[0].y),
+ m_colors[1]);
+ CSprite2d::DrawRect(
+ CRect(boxPos.x, boxPos.y,
+ boxPos.x + m_size[0].x*f, boxPos.y + m_size[0].y),
+ m_colors[0]);
+ }else if(m_style == 0){
+ // ticks...
+ CVector2D boxPos = m_box.m_position + m_position + CVector2D(x,y);
+ DrawTicks(boxPos, m_size[0], m_size[1].y,
+ m_value/1000.0f, m_colors[0], m_colors[1],
+ m_box.m_bDropShadow, m_box.m_shadowOffset, m_box.GetShadowColor());
+ }
+
+ if(m_bDrawPercentage){
+ sprintf(Buf8, "%d%%", m_value/10);
+ AsciiToUnicode(Buf8, Buf16);
+ m_percentageText.m_text = Buf16;
+ m_percentageText.Draw(m_percentageText.GetColor(), m_position.x+x, m_position.y+y);
+ }
+}
+
+void
+CMenuSlider::DrawTicks(const CVector2D &position, const CVector2D &size, float heightRight, float level, const CRGBA &leftCol, const CRGBA &selCol, const CRGBA &rightCol, bool bShadow, const CVector2D &shadowOffset, const CRGBA &shadowColor)
+{
+ int i;
+ int numTicks = size.x / 8.0f;
+ float dy = heightRight - size.y;
+ float stepy = dy / numTicks;
+ int left = level*numTicks;
+ int drewSelection = 0;
+ for(i = 0; i < numTicks; i++){
+ CRect rect(position.x + 8.0f*i, position.y + dy - stepy*i,
+ position.x + 8.0f*i + 4.0f, position.y + dy + size.y);
+ if(bShadow){
+ CRect shadowRect = rect;
+ shadowRect.left += shadowOffset.x;
+ shadowRect.right += shadowOffset.x;
+ shadowRect.top += shadowOffset.y;
+ shadowRect.bottom += shadowOffset.y;
+ CSprite2d::DrawRect(shadowRect, shadowColor);
+ }
+ if(i < left)
+ CSprite2d::DrawRect(rect, leftCol);
+ else if(!drewSelection){
+ CSprite2d::DrawRect(rect, selCol);
+ drewSelection = 1;
+ }else
+ CSprite2d::DrawRect(rect, rightCol);
+ }
+}
+
+void
+CMenuSlider::DrawTicks(const CVector2D &position, const CVector2D &size, float heightRight, float level, const CRGBA &leftCol, const CRGBA &rightCol, bool bShadow, const CVector2D &shadowOffset, const CRGBA &shadowColor)
+{
+ int i;
+ int numTicks = size.x / 8.0f;
+ float dy = heightRight - size.y;
+ float stepy = dy / numTicks;
+ int left = level*numTicks;
+ for(i = 0; i < numTicks; i++){
+ CRect rect(position.x + 8.0f*i, position.y + dy - stepy*i,
+ position.x + 8.0f*i + 4.0f, position.y + dy + size.y);
+ if(bShadow){
+ CRect shadowRect = rect;
+ shadowRect.left += shadowOffset.x;
+ shadowRect.right += shadowOffset.x;
+ shadowRect.top += shadowOffset.y;
+ shadowRect.bottom += shadowOffset.y;
+ CSprite2d::DrawRect(shadowRect, shadowColor);
+ }
+ if(i < left)
+ CSprite2d::DrawRect(rect, leftCol);
+ else
+ CSprite2d::DrawRect(rect, rightCol);
+ }
+}
+
+void
+CMenuSlider::SetAlpha(uint8 alpha)
+{
+ m_title.SetAlpha(alpha);
+ m_box.SetAlpha(alpha);
+ m_someAlpha = alpha;
+ m_percentageText.SetAlpha(alpha);
+ m_colors[0].alpha = alpha;
+ m_colors[1].alpha = alpha;
+}
+
+void
+CMenuSlider::SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset)
+{
+ m_title.SetShadows(bDropShadows, shadowColor, shadowOffset);
+ m_box.SetShadows(bDropShadows, shadowColor, shadowOffset);
+ m_percentageText.SetShadows(bDropShadows, shadowColor, shadowOffset);
+}
+
+/*
+ * CMenuSliderTriggered
+ */
+
+void
+CMenuSliderTriggered::AddTickBox(float positionX, float positionY, float width, float heightLeft, float heightRight, Trigger trigger, Trigger alwaysTrigger)
+{
+ CMenuSlider::AddTickBox(positionX, positionY, width, heightLeft, heightRight);
+ m_trigger = trigger;
+ m_alwaysTrigger = alwaysTrigger;
+}
+
+void
+CMenuSliderTriggered::Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y)
+{
+ CMenuSlider::Draw(optionHighlight, titleHighlight, x, y);
+ if(m_alwaysTrigger)
+ m_alwaysTrigger(this);
+}
+
+bool
+CMenuSliderTriggered::GoLeft(void)
+{
+ CMenuSlider::GoLeft();
+ if(m_trigger)
+ m_trigger(this);
+ return true;
+}
+
+bool
+CMenuSliderTriggered::GoRight(void)
+{
+ CMenuSlider::GoRight();
+ if(m_trigger)
+ m_trigger(this);
+ return true;
+}
+
+bool
+CMenuSliderTriggered::GoLeftStill(void)
+{
+ CMenuSlider::GoLeftStill();
+ if(m_trigger)
+ m_trigger(this);
+ return true;
+}
+
+bool
+CMenuSliderTriggered::GoRightStill(void)
+{
+ CMenuSlider::GoRightStill();
+ if(m_trigger)
+ m_trigger(this);
+ return true;
+}
+
+/*
+ * CMenuLineLister
+ */
+
+CMenuLineLister::CMenuLineLister(void)
+ : m_numLines(0), m_width(0.0f), m_height(0.0f),
+ m_scrollPosition(0.0f), m_scrollSpeed(1.0f), m_lineSpacing(15.0f), field_10E8(0)
+{
+ int i;
+ for(i = 0; i < NUM_LINELISTER_LINES_TOTAL; i++){
+ m_lineAlphas[i] = 0;
+ m_lineFade[i] = 0;
+ }
+}
+
+
+void
+CMenuLineLister::SetLinesColor(const CRGBA &color)
+{
+ int i;
+ for(i = 0; i < NUM_LINELISTER_LINES_TOTAL; i++){
+ m_linesLeft[i].SetColor(color);
+ m_linesRight[i].SetColor(color);
+ }
+}
+
+void
+CMenuLineLister::ResetNumberOfTextLines(void)
+{
+ int i;
+ m_numLines = 0;
+ for(i = 0; i < NUM_LINELISTER_LINES_TOTAL; i++){
+ m_lineAlphas[i] = 0;
+ m_lineFade[i] = 0;
+ }
+ for(i = 0; i < NUM_LINELISTER_LINES_TOTAL; i++){
+ // note this doesn't clear lines 0-14, probably an oversight
+ GetLeftLine(i)->m_text = nil;
+ GetRightLine(i)->m_text = nil;
+ }
+}
+
+bool
+CMenuLineLister::AddTextLine(wchar *left, wchar *right)
+{
+ CPlaceableShText *leftLine, *rightLine;
+ if(m_numLines == NUM_LINELISTER_LINES)
+ return false;
+ leftLine = GetLeftLine(m_numLines);
+ leftLine->m_text = left;
+ leftLine->SetPosition(0.0f, m_lineSpacing*(m_numLines+15));
+ rightLine = GetRightLine(m_numLines);
+ rightLine->m_text = right;
+ rightLine->SetPosition(leftLine->m_position.x, leftLine->m_position.y);
+ m_numLines++;
+ return true;
+}
+
+void
+CMenuLineLister::Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y)
+{
+ int i, n;
+
+ m_scrollPosition += m_scrollSpeed;
+ n = m_numLines + 15;
+ if(m_scrollSpeed > 0.0f){
+ if(m_scrollPosition > n*m_lineSpacing)
+ m_scrollPosition = 0.0f;
+ }else{
+ if(m_scrollPosition < 0.0f)
+ m_scrollPosition = n*m_lineSpacing;
+ }
+ // this is a weird condition....
+ for(i = 0;
+ m_scrollPosition < i*m_lineSpacing || m_scrollPosition >= (i+1)*m_lineSpacing;
+ i++);
+
+ float screenPos = 0.0f;
+ for(; i < n; i++){
+ CVector2D linePos = m_linesLeft[i].m_position;
+
+ if(linePos.y+m_position.y - (m_scrollPosition+m_position.y) < 64.0f)
+ m_lineFade[i] = -4.0f*Abs(m_scrollSpeed);
+ else
+ m_lineFade[i] = 4.0f*Abs(m_scrollSpeed);
+ int newAlpha = m_lineAlphas[i] + m_lineFade[i];
+ if(newAlpha < 0) newAlpha = 0;
+ if(newAlpha > 255) newAlpha = 255;
+ m_lineAlphas[i] = newAlpha;
+
+ uint8 alpha = m_linesLeft[i].m_shadowColor.alpha;
+
+ // apply alpha
+ m_linesLeft[i].SetAlpha((alpha*m_lineAlphas[i])>>8);
+ m_linesRight[i].SetAlpha((alpha*m_lineAlphas[i])>>8);
+
+ m_linesLeft[i].Draw(m_position.x+x, m_position.y+y - m_scrollPosition);
+ CFont::SetRightJustifyOn();
+ m_linesRight[i].Draw(m_position.x+x + m_width, m_position.y+y - m_scrollPosition);
+ CFont::SetRightJustifyOff();
+
+ // restore alpha
+ m_linesLeft[i].SetAlpha(alpha);
+ m_linesRight[i].SetAlpha(alpha);
+
+ screenPos += m_lineSpacing;
+ if(screenPos >= m_height)
+ break;
+ }
+
+ m_scrollSpeed = 1.0f;
+}
+
+void
+CMenuLineLister::SetAlpha(uint8 alpha)
+{
+ int i;
+ for(i = 0; i < NUM_LINELISTER_LINES_TOTAL; i++){
+ m_linesLeft[i].SetAlpha(alpha);
+ m_linesRight[i].SetAlpha(alpha);
+ }
+}
+
+void
+CMenuLineLister::SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset)
+{
+ int i;
+ for(i = 0; i < NUM_LINELISTER_LINES_TOTAL; i++){
+ m_linesLeft[i].SetShadows(bDropShadows, shadowColor, shadowOffset);
+ m_linesRight[i].SetShadows(bDropShadows, shadowColor, shadowOffset);
+ }
+}
+
+
+/*
+ * CMenuPage
+ */
+
+void
+CMenuPage::Initialise(void)
+{
+ int i;
+ m_numControls = 0;
+ m_pCurrentControl = nil;
+ m_cursor = 0;
+ for(i = 0; i < NUM_PAGE_WIDGETS; i++)
+ m_controls[i] = nil;
+}
+
+bool
+CMenuPage::AddMenu(CMenuBase *widget)
+{
+ if(m_numControls >= NUM_PAGE_WIDGETS)
+ return false;
+ m_controls[m_numControls] = widget;
+ if(m_numControls == 0){
+ m_pCurrentControl = widget;
+ m_cursor = 0;
+ }
+ m_numControls++;
+ return true;
+}
+
+bool
+CMenuPage::IsActiveMenuTwoState(void)
+{
+ return m_pCurrentControl && m_pCurrentControl->m_bTwoState;
+}
+
+void
+CMenuPage::ActiveMenuTwoState_SelectNextPosition(void)
+{
+ int sel;
+ if(m_pCurrentControl == nil || !m_pCurrentControl->m_bTwoState)
+ return;
+ m_pCurrentControl->GoFirst();
+ sel = m_pCurrentControl->GetMenuSelection();
+ if(sel == 1)
+ m_pCurrentControl->SelectCurrentOptionUnderCursor();
+ else if(sel == 0){
+ m_pCurrentControl->GoNext();
+ m_pCurrentControl->SelectCurrentOptionUnderCursor();
+ }
+}
+
+void
+CMenuPage::Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y)
+{
+ int i;
+ for(i = 0; i < m_numControls; i++)
+ if(m_controls[i]){
+ if(i == m_cursor)
+ m_controls[i]->Draw(optionHighlight, titleHighlight, x, y);
+ else
+ m_controls[i]->DrawNormal(x, y);
+ }
+}
+
+void
+CMenuPage::DrawHighlighted(const CRGBA &titleHighlight, float x, float y)
+{
+ int i;
+ for(i = 0; i< m_numControls; i++)
+ if(m_controls[i]){
+ if(i == m_cursor)
+ m_controls[i]->DrawHighlighted(titleHighlight, x, y);
+ else
+ m_controls[i]->DrawNormal(x, y);
+ }
+}
+
+void
+CMenuPage::DrawNormal(float x, float y)
+{
+ int i;
+ for(i = 0; i< m_numControls; i++)
+ if(m_controls[i])
+ m_controls[i]->DrawNormal(x, y);
+}
+
+void
+CMenuPage::ActivatePage(void)
+{
+ m_cursor = 0;
+ if(m_numControls == 0)
+ return;
+ for(;;){
+ m_pCurrentControl = m_controls[m_cursor];
+ if(m_pCurrentControl->GoFirst())
+ return;
+ if(m_cursor == m_numControls-1)
+ m_cursor = 0;
+ else
+ m_cursor++;
+ }
+}
+
+void
+CMenuPage::SetAlpha(uint8 alpha)
+{
+ int i;
+ for(i = 0; i< m_numControls; i++)
+ if(m_controls[i])
+ m_controls[i]->SetAlpha(alpha);
+}
+
+void
+CMenuPage::SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset)
+{
+ int i;
+ for(i = 0; i< m_numControls; i++)
+ if(m_controls[i])
+ m_controls[i]->SetShadows(bDropShadows, shadowColor, shadowOffset);
+}
+
+void
+CMenuPage::GoUpMenuOnPage(void)
+{
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ do{
+ if(m_cursor == 0)
+ m_cursor = m_numControls-1;
+ else
+ m_cursor--;
+ m_pCurrentControl = m_controls[m_cursor];
+ }while(!m_pCurrentControl->GoLast());
+}
+
+void
+CMenuPage::GoDownMenuOnPage(void)
+{
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ do{
+ if(m_cursor == m_numControls-1)
+ m_cursor = 0;
+ else
+ m_cursor++;
+ m_pCurrentControl = m_controls[m_cursor];
+ }while(!m_pCurrentControl->GoFirst());
+}
+
+void
+CMenuPage::GoLeftMenuOnPage(void)
+{
+ // same as up
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ do{
+ if(m_cursor == 0)
+ m_cursor = m_numControls-1;
+ else
+ m_cursor--;
+ m_pCurrentControl = m_controls[m_cursor];
+ }while(!m_pCurrentControl->GoLast());
+}
+
+void
+CMenuPage::GoRightMenuOnPage(void)
+{
+ // same as right
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ do{
+ if(m_cursor == m_numControls-1)
+ m_cursor = 0;
+ else
+ m_cursor++;
+ m_pCurrentControl = m_controls[m_cursor];
+ }while(!m_pCurrentControl->GoFirst());
+}
+
+/*
+ * CMenuPageAnyMove
+ */
+
+void
+CMenuPageAnyMove::Initialise(void)
+{
+ int i;
+ CMenuPage::Initialise();
+ for(i = 0; i < NUM_PAGE_WIDGETS; i++){
+ m_moveTab[i].left = -1;
+ m_moveTab[i].right = -1;
+ m_moveTab[i].up = -1;
+ m_moveTab[i].down = -1;
+ }
+}
+
+bool
+CMenuPageAnyMove::AddMenu(CMenuBase *widget, FEC_MOVETAB *moveTab)
+{
+ if(AddMenu(widget)){
+ m_moveTab[m_numControls-1] = *moveTab;
+ return true;
+ }
+ return false;
+}
+
+void
+CMenuPageAnyMove::GoUpMenuOnPage(void)
+{
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ int move = m_moveTab[m_cursor].up;
+ if(move == -1)
+ CMenuPage::GoUpMenuOnPage();
+ else{ // BUG: no else in original code
+ m_cursor = move;
+ m_pCurrentControl = m_controls[m_cursor];
+ m_pCurrentControl->GoLast();
+ }
+}
+
+void
+CMenuPageAnyMove::GoDownMenuOnPage(void)
+{
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ int move = m_moveTab[m_cursor].down;
+ if(move == -1)
+ CMenuPage::GoDownMenuOnPage();
+ else{ // BUG: no else in original code
+ m_cursor = move;
+ m_pCurrentControl = m_controls[m_cursor];
+ m_pCurrentControl->GoLast();
+ }
+}
+
+void
+CMenuPageAnyMove::GoLeftMenuOnPage(void)
+{
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ int move = m_moveTab[m_cursor].left;
+ if(move == -1)
+ CMenuPage::GoLeftMenuOnPage();
+ else{ // BUG: no else in original code
+ m_cursor = move;
+ m_pCurrentControl = m_controls[m_cursor];
+ m_pCurrentControl->GoLast();
+ }
+}
+
+void
+CMenuPageAnyMove::GoRightMenuOnPage(void)
+{
+ if(m_pCurrentControl == nil)
+ return;
+ m_pCurrentControl->DeactivateMenu();
+ int move = m_moveTab[m_cursor].right;
+ if(move == -1)
+ CMenuPage::GoRightMenuOnPage();
+ else{ // BUG: no else in original code
+ m_cursor = move;
+ m_pCurrentControl = m_controls[m_cursor];
+ m_pCurrentControl->GoLast();
+ }
+}
diff --git a/src/core/FrontEndControls.h b/src/core/FrontEndControls.h
new file mode 100644
index 00000000..5b6f95bb
--- /dev/null
+++ b/src/core/FrontEndControls.h
@@ -0,0 +1,712 @@
+#pragma once
+
+enum {
+ NUM_MULTICHOICE_OPTIONS = 16,
+ // 50 actual lines and 15 for spacing
+ NUM_LINELISTER_LINES = 50,
+ NUM_LINELISTER_LINES_TOTAL = NUM_LINELISTER_LINES + 15,
+ NUM_PAGE_WIDGETS = 10,
+};
+
+
+class CPlaceableText
+{
+public:
+ CVector2D m_position;
+ CRGBA m_color;
+ wchar *m_text;
+
+ CPlaceableText(void)
+ : m_position(0.0f, 0.0f), m_color(255, 255, 255, 255) {}
+ void SetPosition(float x, float y) { m_position.x = x; m_position.y = y; }
+ void SetColor(const CRGBA &color) { m_color = color; }
+ CRGBA GetColor(void) { return m_color; }
+ void SetAlpha(uint8 alpha) { m_color.alpha = alpha; }
+};
+
+// No trace of this in the game but it makes the other classes simpler
+class CPlaceableTextTwoLines
+{
+public:
+ CPlaceableText m_line1;
+ CPlaceableText m_line2;
+
+ void SetColor(const CRGBA &color) { m_line1.SetColor(color); m_line2.SetColor(color); }
+ void SetAlpha(uint8 alpha) { m_line1.SetAlpha(alpha); m_line2.SetAlpha(alpha); }
+};
+
+// No trace of this in the game but it makes the other classes simpler
+class CShadowInfo
+{
+public:
+ bool m_bRightJustify;
+ bool m_bDropShadow;
+ CRGBA m_shadowColor;
+ CVector2D m_shadowOffset;
+
+ CShadowInfo(void)
+ : m_bRightJustify(false), m_bDropShadow(false),
+ m_shadowColor(255, 255, 255, 255),
+ m_shadowOffset(-1.0f, -1.0f) {}
+ CRGBA GetShadowColor(void) { return m_shadowColor; }
+ void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset){
+ m_bDropShadow = bDropShadows;
+ m_shadowColor = shadowColor;
+ m_shadowOffset = shadowOffset;
+ }
+};
+
+// No trace of this in the game but it makes the other classes simpler
+class CSelectable
+{
+public:
+ bool m_bSelected;
+ CRGBA m_selectedColor;
+
+ CSelectable(void) : m_bSelected(false) {}
+ CRGBA GetSelectedColor(void) { return m_selectedColor; }
+};
+
+class CPlaceableShText : public CPlaceableText, public CShadowInfo
+{
+public:
+ using CPlaceableText::SetPosition;
+ void SetPosition(float x, float y, bool bRightJustify) { SetPosition(x, y); m_bRightJustify = bRightJustify; }
+ void SetAlpha(uint8 alpha) { m_shadowColor.alpha = alpha; CPlaceableText::SetAlpha(alpha); }
+
+ void Draw(float x, float y);
+ void Draw(const CRGBA &color, float x, float y);
+ // unused arguments it seems
+ void DrawShWrap(float x, float y, float wrapX, float wrapY) { Draw(x, y); }
+};
+
+class CPlaceableShTextTwoLines : public CPlaceableTextTwoLines, public CShadowInfo
+{
+public:
+ void SetAlpha(uint8 alpha) { m_shadowColor.alpha = alpha; CPlaceableTextTwoLines::SetAlpha(alpha); }
+
+ void Draw(float x, float y);
+ void Draw(const CRGBA &color, float x, float y);
+};
+
+class CPlaceableShOption : public CPlaceableShText, public CSelectable
+{
+public:
+ void SetColors(const CRGBA &normal, const CRGBA &selection) { CPlaceableShText::SetColor(normal); m_selectedColor = selection; }
+ void SetAlpha(uint8 alpha) { m_selectedColor.alpha = alpha; CPlaceableShText::SetAlpha(alpha); }
+
+ using CPlaceableShText::Draw;
+ void Draw(const CRGBA &highlightColor, float x, float y, bool bHighlight);
+};
+
+class CPlaceableShOptionTwoLines : public CPlaceableShTextTwoLines, public CSelectable
+{
+public:
+ void SetColors(const CRGBA &normal, const CRGBA &selection) { CPlaceableShTextTwoLines::SetColor(normal); m_selectedColor = selection; }
+ void SetAlpha(uint8 alpha) { m_selectedColor.alpha = alpha; CPlaceableShTextTwoLines::SetAlpha(alpha); }
+
+ using CPlaceableShTextTwoLines::Draw;
+ void Draw(const CRGBA &highlightColor, float x, float y, bool bHighlight);
+};
+
+class CPlaceableSprite
+{
+public:
+ CSprite2d *m_pSprite;
+ CVector2D m_position;
+ CVector2D m_size;
+ CRGBA m_color;
+
+ CPlaceableSprite(void)
+ : m_pSprite(nil), m_position(0.0f, 0.0f),
+ m_size(0.0f, 0.0f), m_color(255, 255, 255, 255) {}
+
+ void SetPosition(float x, float y) { m_position.x = x; m_position.y = y; }
+ void SetAlpha(uint8 alpha) { m_color.alpha = alpha; }
+
+ void Draw(float x, float y);
+ void Draw(const CRGBA &color, float x, float y);
+};
+
+class CPlaceableShSprite
+{
+public:
+ CPlaceableSprite m_sprite;
+ CPlaceableSprite m_shadow;
+ bool m_bDropShadow;
+
+ CPlaceableShSprite(void) : m_bDropShadow(false) {}
+
+ void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset){
+ m_bDropShadow = bDropShadows;
+ m_shadow.m_color = shadowColor;
+ m_shadow.m_position = shadowOffset;
+ }
+ void SetAlpha(uint8 alpha) { m_sprite.SetAlpha(alpha); m_shadow.SetAlpha(alpha); }
+
+ void Draw(float x, float y);
+};
+
+
+class CMenuBase
+{
+public:
+ CVector2D m_position;
+ bool m_bTwoState;
+
+ CMenuBase(void)
+ : m_position(0.0f, 0.0f), m_bTwoState(false) {}
+ void SetPosition(float x, float y) { m_position.x = x; m_position.y = y; }
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y) = 0;
+ virtual void DrawNormal(float x, float y) = 0;
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y) = 0;
+ virtual void SetAlpha(uint8 alpha) = 0;
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset) = 0;
+ virtual bool GoNext(void) = 0;
+ virtual bool GoPrev(void) = 0;
+ virtual bool GoDown(void) = 0;
+ virtual bool GoUp(void) = 0;
+ virtual bool GoDownStill(void) = 0;
+ virtual bool GoUpStill(void) = 0;
+ virtual bool GoLeft(void) = 0;
+ virtual bool GoRight(void) = 0;
+ virtual bool GoLeftStill(void) = 0;
+ virtual bool GoRightStill(void) = 0;
+ virtual bool GoFirst(void) = 0;
+ virtual bool GoLast(void) = 0;
+ virtual void SelectCurrentOptionUnderCursor(void) = 0;
+ virtual void SelectDefaultCancelAction(void) = 0;
+ virtual void ActivateMenu(bool first) = 0;
+ virtual void DeactivateMenu(void) = 0;
+ virtual int GetMenuSelection(void) = 0;
+ virtual void SetMenuSelection(int selection) = 0;
+};
+
+class CMenuDummy : public CMenuBase
+{
+public:
+ bool m_bActive;
+
+ virtual void Draw(const CRGBA &, const CRGBA &, float x, float y) {}
+ virtual void DrawNormal(float x, float y) {}
+ virtual void DrawHighlighted(const CRGBA &, float x, float y) {}
+ virtual void SetAlpha(uint8 alpha) {}
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset) {}
+ virtual bool GoNext(void) { DeactivateMenu(); return false; }
+ virtual bool GoPrev(void) { DeactivateMenu(); return false; }
+ virtual bool GoDown(void) { return GoNext(); }
+ virtual bool GoUp(void) { return GoPrev(); }
+ virtual bool GoDownStill(void) { return false; }
+ virtual bool GoUpStill(void) { return false; }
+ virtual bool GoLeft(void) { return true; }
+ virtual bool GoRight(void) { return true; }
+ virtual bool GoLeftStill(void) { return true; }
+ virtual bool GoRightStill(void) { return true; }
+ virtual bool GoFirst(void) { ActivateMenu(true); return true; }
+ virtual bool GoLast(void) { ActivateMenu(true); return true; }
+ virtual void SelectCurrentOptionUnderCursor(void) {}
+ virtual void SelectDefaultCancelAction(void) {}
+ virtual void ActivateMenu(bool first) { m_bActive = true; }
+ virtual void DeactivateMenu(void) { m_bActive = false; }
+ virtual int GetMenuSelection(void) { return -1; }
+ virtual void SetMenuSelection(int) {}
+};
+
+class CMenuPictureAndText : public CMenuBase
+{
+public:
+ int m_numSprites;
+ CPlaceableShSprite m_sprites[5];
+ int m_numTexts;
+ CPlaceableShText m_texts[20];
+
+ CVector2D m_oldTextScale;
+ CVector2D m_textScale;
+ bool m_bSetTextScale;
+
+ float m_wrapX;
+ float m_oldWrapx;
+ bool m_bWrap;
+ // missing some?
+
+
+ CMenuPictureAndText(void)
+ : m_numSprites(0), m_numTexts(0),
+ m_bSetTextScale(false), m_bWrap(false) {}
+
+ void SetNewOldShadowWrapX(bool bWrapX, float newWrapX, float oldWrapX);
+ void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale);
+ void SetTextsColor(const CRGBA &color);
+ void AddText(wchar *text, float positionX, float positionY, const CRGBA &color, bool bRightJustify);
+ void AddPicture(CSprite2d *sprite, CSprite2d *shadow, float positionX, float positionY, float width, float height, const CRGBA &color);
+ void AddPicture(CSprite2d *sprite, float positionX, float positionY, float width, float height, const CRGBA &color);
+
+ virtual void Draw(const CRGBA &, const CRGBA &, float x, float y);
+ virtual void DrawNormal(float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
+ virtual void DrawHighlighted(const CRGBA &, float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
+ virtual void SetAlpha(uint8 alpha);
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
+ virtual bool GoNext(void) { return false; }
+ virtual bool GoPrev(void) { return false; }
+ virtual bool GoDown(void) { return GoNext(); }
+ virtual bool GoUp(void) { return GoPrev(); }
+ virtual bool GoDownStill(void) { return false; }
+ virtual bool GoUpStill(void) { return false; }
+ virtual bool GoLeft(void) { return true; }
+ virtual bool GoRight(void) { return true; }
+ virtual bool GoLeftStill(void) { return true; }
+ virtual bool GoRightStill(void) { return true; }
+ virtual bool GoFirst(void) { return false; }
+ virtual bool GoLast(void) { return false; }
+ virtual void SelectCurrentOptionUnderCursor(void) {}
+ virtual void SelectDefaultCancelAction(void) {}
+ virtual void ActivateMenu(bool first) {}
+ virtual void DeactivateMenu(void) {}
+ virtual int GetMenuSelection(void) { return -1; }
+ virtual void SetMenuSelection(int) {}
+};
+
+class CMenuMultiChoice : public CMenuBase
+{
+public:
+ int m_numOptions;
+ CPlaceableShText m_title;
+ CPlaceableShOption m_options[NUM_MULTICHOICE_OPTIONS];
+ int m_cursor;
+ CVector2D m_oldTextScale;
+ CVector2D m_textScale;
+ bool m_bSetTextScale;
+ bool m_bSetTitleTextScale;
+
+ CMenuMultiChoice(void)
+ : m_numOptions(0), m_cursor(-1),
+ m_bSetTextScale(false), m_bSetTitleTextScale(false) {}
+
+ void AddTitle(wchar *text, float positionX, float positionY, bool bRightJustify);
+ CPlaceableShOption *AddOption(wchar *text, float positionX, float positionY, bool bSelected, bool bRightJustify);
+ void SetColors(const CRGBA &title, const CRGBA &normal, const CRGBA &selected);
+ void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale);
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual void DrawNormal(float x, float y);
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
+ virtual void SetAlpha(uint8 alpha);
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
+ virtual bool GoNext(void);
+ virtual bool GoPrev(void);
+ virtual bool GoDown(void) { return GoNext(); }
+ virtual bool GoUp(void) { return GoPrev(); }
+ virtual bool GoDownStill(void) { return false; }
+ virtual bool GoUpStill(void) { return false; }
+ virtual bool GoLeft(void) { return GoPrev(); }
+ virtual bool GoRight(void) { return GoNext(); }
+ virtual bool GoLeftStill(void) { return true; }
+ virtual bool GoRightStill(void) { return true; }
+ virtual bool GoFirst(void) { m_cursor = 0; return true; }
+ virtual bool GoLast(void) { m_cursor = m_numOptions-1; return true; }
+ virtual void SelectCurrentOptionUnderCursor(void);
+ virtual void SelectDefaultCancelAction(void) {}
+ virtual void ActivateMenu(bool first) { m_cursor = first ? 0 : m_numOptions-1; }
+ virtual void DeactivateMenu(void) { m_cursor = -1; }
+ virtual int GetMenuSelection(void);
+ virtual void SetMenuSelection(int selection);
+};
+
+class CMenuMultiChoiceTriggered : public CMenuMultiChoice
+{
+public:
+ typedef void (*Trigger)(CMenuMultiChoiceTriggered *);
+
+ Trigger m_triggers[NUM_MULTICHOICE_OPTIONS];
+ Trigger m_defaultCancel;
+
+ CMenuMultiChoiceTriggered(void) { Initialise(); }
+
+ void Initialise(void);
+ CPlaceableShOption *AddOption(wchar *text, float positionX, float positionY, Trigger trigger, bool bSelected, bool bRightJustify);
+
+ virtual void SelectCurrentOptionUnderCursor(void);
+ virtual void SelectDefaultCancelAction(void);
+};
+
+class CMenuMultiChoiceTriggeredAlways : public CMenuMultiChoiceTriggered
+{
+public:
+ Trigger m_alwaysNormalTrigger;
+ Trigger m_alwaysHighlightTrigger;
+ Trigger m_alwaysTrigger;
+
+ CMenuMultiChoiceTriggeredAlways(void)
+ : m_alwaysNormalTrigger(nil), m_alwaysHighlightTrigger(nil), m_alwaysTrigger(nil) {}
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual void DrawNormal(float x, float y);
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
+};
+
+class CMenuMultiChoicePictured : public CMenuMultiChoice
+{
+public:
+ CPlaceableSprite m_sprites[NUM_MULTICHOICE_OPTIONS];
+ bool m_bHasSprite[NUM_MULTICHOICE_OPTIONS];
+
+ CMenuMultiChoicePictured(void) { Initialise(); }
+ void Initialise(void);
+ using CMenuMultiChoice::AddOption;
+ CPlaceableShOption *AddOption(CSprite2d *sprite, float positionX, float positionY, const CVector2D &size, bool bSelected);
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual void DrawNormal(float x, float y);
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
+ virtual void SetAlpha(uint8 alpha);
+ // unnecessary - same as base class
+// virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
+};
+
+class CMenuMultiChoicePicturedTriggered : public CMenuMultiChoicePictured
+{
+public:
+ typedef void (*Trigger)(CMenuMultiChoicePicturedTriggered *);
+
+ Trigger m_triggers[NUM_MULTICHOICE_OPTIONS];
+ Trigger m_defaultCancel;
+
+ CMenuMultiChoicePicturedTriggered(void) { Initialise(); }
+
+ void Initialise(void);
+ using CMenuMultiChoicePictured::AddOption;
+ CPlaceableShOption *AddOption(CSprite2d *sprite, float positionX, float positionY, const CVector2D &size, Trigger trigger, bool bSelected);
+
+ virtual void SelectCurrentOptionUnderCursor(void);
+ virtual void SelectDefaultCancelAction(void);
+};
+
+struct FEC_MOVETAB
+{
+ int8 right;
+ int8 left;
+ int8 down;
+ int8 up;
+};
+
+class CMenuMultiChoicePicturedTriggeredAnyMove : public CMenuMultiChoicePicturedTriggered
+{
+public:
+ FEC_MOVETAB m_moveTab[NUM_MULTICHOICE_OPTIONS];
+
+ CMenuMultiChoicePicturedTriggeredAnyMove(void) { Initialise(); }
+
+ void Initialise(void);
+ using CMenuMultiChoicePicturedTriggered::AddOption;
+ CPlaceableShOption *AddOption(CSprite2d *sprite, FEC_MOVETAB *moveTab, float positionX, float positionY, const CVector2D &size, Trigger trigger, bool bSelected);
+
+ virtual bool GoDown(void);
+ virtual bool GoUp(void);
+ virtual bool GoLeft(void);
+ virtual bool GoRight(void);
+};
+
+// copy of CMenuMultiChoice pretty much except for m_options type
+class CMenuMultiChoiceTwoLines : public CMenuBase
+{
+public:
+ int m_numOptions;
+ CPlaceableShText m_title;
+ CPlaceableShOptionTwoLines m_options[NUM_MULTICHOICE_OPTIONS];
+ int m_cursor;
+ CVector2D m_oldTextScale;
+ CVector2D m_textScale;
+ bool m_bSetTextScale;
+ bool m_bSetTitleTextScale;
+
+ CMenuMultiChoiceTwoLines(void)
+ : m_numOptions(0), m_cursor(-1),
+ m_bSetTextScale(false), m_bSetTitleTextScale(false) {}
+
+ void AddTitle(wchar *text, float positionX, float positionY, bool bRightJustify);
+ CPlaceableShOptionTwoLines *AddOption(wchar *text, float positionX, float positionY, bool bSelected, bool bRightJustify);
+ CPlaceableShOptionTwoLines *AddOption(wchar *text1, float positionX1, float positionY1, wchar *text2, float positionX2, float positionY2, bool bSelected, bool bRightJustify);
+ void SetColors(const CRGBA &title, const CRGBA &normal, const CRGBA &selected);
+ void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale);
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual void DrawNormal(float x, float y);
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
+ virtual void SetAlpha(uint8 alpha);
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
+ virtual bool GoNext(void);
+ virtual bool GoPrev(void);
+ virtual bool GoDown(void) { return GoNext(); }
+ virtual bool GoUp(void) { return GoPrev(); }
+ virtual bool GoDownStill(void) { return true; }
+ virtual bool GoUpStill(void) { return true; }
+ virtual bool GoLeft(void) { return GoPrev(); }
+ virtual bool GoRight(void) { return GoNext(); }
+ virtual bool GoLeftStill(void) { return true; }
+ virtual bool GoRightStill(void) { return true; }
+ virtual bool GoFirst(void) { m_cursor = 0; return true; }
+ virtual bool GoLast(void) { m_cursor = m_numOptions-1; return true; }
+ virtual void SelectCurrentOptionUnderCursor(void);
+ virtual void SelectDefaultCancelAction(void) {}
+ virtual void ActivateMenu(bool first) { m_cursor = first ? 0 : m_numOptions-1; }
+ virtual void DeactivateMenu(void) { m_cursor = -1; }
+ virtual int GetMenuSelection(void);
+ virtual void SetMenuSelection(int selection);
+};
+
+// copy of CMenuMultiChoiceTriggered except for m_options
+class CMenuMultiChoiceTwoLinesTriggered : public CMenuMultiChoiceTwoLines
+{
+public:
+ typedef void (*Trigger)(CMenuMultiChoiceTwoLinesTriggered *);
+
+ Trigger m_triggers[NUM_MULTICHOICE_OPTIONS];
+ Trigger m_defaultCancel;
+
+ CMenuMultiChoiceTwoLinesTriggered(void) { Initialise(); }
+
+ void Initialise(void);
+ CPlaceableShOptionTwoLines *AddOption(wchar *text, float positionX, float positionY, Trigger trigger, bool bSelected, bool bRightJustify);
+ CPlaceableShOptionTwoLines *AddOption(wchar *text1, float positionX1, float positionY1, wchar *text2, float positionX2, float positionY2, Trigger trigger, bool bSelected, bool bRightJustify);
+
+ virtual void SelectCurrentOptionUnderCursor(void);
+ virtual void SelectDefaultCancelAction(void);
+};
+
+
+class CMenuOnOff : public CMenuBase
+{
+public:
+ CPlaceableShOption m_title;
+ CPlaceableShText m_options[2];
+ bool m_bActive;
+ bool m_bSetTextScale;
+ bool m_bSetTitleTextScale;
+ CVector2D m_textScale;
+ CVector2D m_oldTextScale;
+ int m_type; // 0: on/off 1: yes/no
+
+ void SetColors(const CRGBA &title, const CRGBA &options);
+ void SetNewOldTextScale(bool bTextScale, const CVector2D &newScale, const CVector2D &oldScale, bool bTitleTextScale);
+ void SetOptionPosition(float x, float y, bool bRightJustify);
+ void AddTitle(wchar *text, bool bSelected, float positionX, float positionY, bool bRightJustify);
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual void DrawNormal(float x, float y);
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
+ virtual void SetAlpha(uint8 alpha);
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
+ virtual bool GoNext(void) { DeactivateMenu(); return false; }
+ virtual bool GoPrev(void) { DeactivateMenu(); return false; }
+ virtual bool GoDown(void) { return GoNext(); }
+ virtual bool GoUp(void) { return GoPrev(); }
+ virtual bool GoDownStill(void) { return false; }
+ virtual bool GoUpStill(void) { return false; }
+ virtual bool GoLeft(void) { SelectCurrentOptionUnderCursor(); return true; }
+ virtual bool GoRight(void) { SelectCurrentOptionUnderCursor(); return true; }
+ virtual bool GoLeftStill(void) { return true; }
+ virtual bool GoRightStill(void) { return true; }
+ virtual bool GoFirst(void) { ActivateMenu(true); return true; }
+ virtual bool GoLast(void) { ActivateMenu(true); return true; }
+ virtual void SelectCurrentOptionUnderCursor(void) { m_title.m_bSelected ^= 1; }
+ virtual void SelectDefaultCancelAction(void) {}
+ virtual void ActivateMenu(bool first) { m_bActive = true; }
+ virtual void DeactivateMenu(void) { m_bActive = false; }
+ virtual int GetMenuSelection(void) { return m_title.m_bSelected; }
+ virtual void SetMenuSelection(int selection) { m_title.m_bSelected = selection; }
+};
+
+class CMenuOnOffTriggered : public CMenuOnOff
+{
+public:
+ typedef void (*Trigger)(CMenuOnOffTriggered *);
+
+ Trigger m_trigger;
+
+ void SetOptionPosition(float x, float y, Trigger trigger, bool bRightJustify);
+
+ virtual void SelectCurrentOptionUnderCursor(void);
+};
+
+class CMenuSlider : public CMenuBase
+{
+public:
+ CPlaceableShText m_title;
+ CPlaceableShText m_box; // not really a text
+ CRGBA m_colors[2]; // left and right
+ CVector2D m_size[2]; // left and right
+ int m_value;
+ CPlaceableShText m_percentageText;
+ bool m_bDrawPercentage;
+// char field_8D;
+// char field_8E;
+// char field_8F;
+ uint8 m_someAlpha;
+// char field_91;
+// char field_92;
+// char field_93;
+ bool m_bActive;
+ int m_style;
+
+ static char Buf8[8];
+ static wchar Buf16[8];
+
+ CMenuSlider(void)
+ : m_value(0), m_bDrawPercentage(false), m_bActive(false), m_style(0) {}
+
+ void SetColors(const CRGBA &title, const CRGBA &percentage, const CRGBA &left, const CRGBA &right);
+ void DrawTicks(const CVector2D &position, const CVector2D &size, float heightRight, float level, const CRGBA &leftCol, const CRGBA &selCol, const CRGBA &rightCol, bool bShadow, const CVector2D &shadowOffset, const CRGBA &shadowColor);
+ void DrawTicks(const CVector2D &position, const CVector2D &size, float heightRight, float level, const CRGBA &leftCol, const CRGBA &rightCol, bool bShadow, const CVector2D &shadowOffset, const CRGBA &shadowColor);
+ void AddTickBox(float positionX, float positionY, float width, float heigthLeft, float heightRight);
+ void AddTitle(wchar *text, float positionX, float positionY);
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual void DrawNormal(float x, float y);
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
+ virtual void SetAlpha(uint8 alpha);
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
+ virtual bool GoNext(void) { DeactivateMenu(); return false; }
+ virtual bool GoPrev(void) { DeactivateMenu(); return false; }
+ virtual bool GoDown(void) { return GoNext(); }
+ virtual bool GoUp(void) { return GoPrev(); }
+ virtual bool GoDownStill(void) { return false; }
+ virtual bool GoUpStill(void) { return false; }
+ virtual bool GoLeft(void) { if(m_value < 0) m_value = 0; return true; }
+ virtual bool GoRight(void) { if(m_value > 1000) m_value = 1000; return true; }
+ virtual bool GoLeftStill(void) { m_value -= 8; if(m_value < 0) m_value = 0; return true; }
+ virtual bool GoRightStill(void) { m_value += 8; if(m_value > 1000) m_value = 1000; return true; }
+ virtual bool GoFirst(void) { ActivateMenu(true); return true; }
+ virtual bool GoLast(void) { ActivateMenu(true); return true; }
+ virtual void SelectCurrentOptionUnderCursor(void) {}
+ virtual void SelectDefaultCancelAction(void) {}
+ virtual void ActivateMenu(bool first) { m_bActive = true; }
+ virtual void DeactivateMenu(void) { m_bActive = false; }
+ virtual int GetMenuSelection(void) { return m_value/10; }
+ virtual void SetMenuSelection(int selection) { m_value = selection*10; }
+};
+
+class CMenuSliderTriggered : public CMenuSlider
+{
+public:
+ typedef void (*Trigger)(CMenuSliderTriggered *);
+
+ Trigger m_trigger;
+ Trigger m_alwaysTrigger;
+
+ CMenuSliderTriggered(void)
+ : m_trigger(nil), m_alwaysTrigger(nil) {}
+
+ void AddTickBox(float positionX, float positionY, float width, float heigthLeft, float heightRight, Trigger trigger, Trigger alwaysTrigger);
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual bool GoLeft(void);
+ virtual bool GoRight(void);
+ virtual bool GoLeftStill(void);
+ virtual bool GoRightStill(void);
+};
+
+
+class CMenuLineLister : public CMenuBase
+{
+public:
+ float m_width;
+ float m_height;
+ int m_numLines;
+ CPlaceableShText m_linesLeft[NUM_LINELISTER_LINES_TOTAL];
+ CPlaceableShText m_linesRight[NUM_LINELISTER_LINES_TOTAL];
+ uint8 m_lineAlphas[NUM_LINELISTER_LINES_TOTAL];
+ int8 m_lineFade[NUM_LINELISTER_LINES_TOTAL];
+ float m_scrollPosition;
+ float m_scrollSpeed;
+ int field_10E8;
+ float m_lineSpacing;
+
+ CMenuLineLister(void);
+
+ void SetLinesColor(const CRGBA &color);
+ void ResetNumberOfTextLines(void);
+ bool AddTextLine(wchar *left, wchar *right);
+
+ CPlaceableShText *GetLeftLine(int i) { return &m_linesLeft[(i%NUM_LINELISTER_LINES) + 15]; };
+ CPlaceableShText *GetRightLine(int i) { return &m_linesRight[(i%NUM_LINELISTER_LINES) + 15]; };
+
+ virtual void Draw(const CRGBA &optionHighlight, const CRGBA &titleHighlight, float x, float y);
+ virtual void DrawNormal(float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
+ virtual void DrawHighlighted(const CRGBA &titleHighlight, float x, float y) { Draw(CRGBA(0,0,0,0), CRGBA(0,0,0,0), x, y); }
+ virtual void SetAlpha(uint8 alpha);
+ virtual void SetShadows(bool bDropShadows, const CRGBA &shadowColor, const CVector2D &shadowOffset);
+ virtual bool GoNext(void) { return false; }
+ virtual bool GoPrev(void) { return false; }
+ virtual bool GoDown(void) { return GoNext(); }
+ virtual bool GoUp(void) { return GoPrev(); }
+ virtual bool GoDownStill(void) { m_scrollSpeed = 0.0f; return true; }
+ virtual bool GoUpStill(void) { m_scrollSpeed *= 6.0f; return true; }
+ virtual bool GoLeft(void) { return true; }
+ virtual bool GoRight(void) { return true; }
+ virtual bool GoLeftStill(void) { return true; }
+ virtual bool GoRightStill(void) { return true; }
+ virtual bool GoFirst(void) { return true; }
+ virtual bool GoLast(void) { return true; }
+ virtual void SelectCurrentOptionUnderCursor(void) {}
+ virtual void SelectDefaultCancelAction(void) {}
+ virtual void ActivateMenu(bool first) {}
+ virtual void DeactivateMenu(void) {}
+ virtual int GetMenuSelection(void) { return -1; }
+ virtual void SetMenuSelection(int selection) {}
+};
+
+class CMenuPage
+{
+public:
+ CMenuBase *m_controls[NUM_PAGE_WIDGETS];
+ int m_numControls;
+ CMenuBase *m_pCurrentControl;
+ int m_cursor;
+
+ CMenuPage(void) { Initialise(); }
+ void Initialise(void);
+ bool AddMenu(CMenuBase *widget);
+
+ bool IsActiveMenuTwoState(void);
+ void ActiveMenuTwoState_SelectNextPosition(void);
+ void Draw(const CRGBA &,const CRGBA &, float, float);
+ void DrawHighlighted(const CRGBA &titleHighlight, float x, float y);
+ void DrawNormal(float x, float y);
+ void ActivatePage(void);
+ void SetAlpha(uint8 alpha);
+ void SetShadows(bool, const CRGBA &, const CVector2D &);
+ void GoPrev(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoPrev()) m_pCurrentControl->GoLast(); } }
+ void GoNext(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoNext()) m_pCurrentControl->GoFirst(); } }
+ void GoLeft(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoLeft()) m_pCurrentControl->GoLast(); } }
+ void GoRight(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoRight()) m_pCurrentControl->GoFirst(); } }
+ void GoUp(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoUp()) m_pCurrentControl->GoLast(); } }
+ void GoDown(void) { if(m_pCurrentControl) { if(!m_pCurrentControl->GoDown()) m_pCurrentControl->GoFirst(); } }
+ void GoLeftStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoLeftStill(); }
+ void GoRightStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoRightStill(); }
+ void GoUpStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoUpStill(); }
+ void GoDownStill(void) { if(m_pCurrentControl) m_pCurrentControl->GoDownStill(); }
+ void SelectDefaultCancelAction(void) { if(m_pCurrentControl) m_pCurrentControl->SelectDefaultCancelAction(); }
+ void SelectCurrentOptionUnderCursor(void) { if(m_pCurrentControl) m_pCurrentControl->SelectCurrentOptionUnderCursor(); }
+
+ virtual void GoUpMenuOnPage(void);
+ virtual void GoDownMenuOnPage(void);
+ virtual void GoLeftMenuOnPage(void);
+ virtual void GoRightMenuOnPage(void);
+};
+
+class CMenuPageAnyMove : public CMenuPage
+{
+public:
+ FEC_MOVETAB m_moveTab[NUM_PAGE_WIDGETS];
+
+ CMenuPageAnyMove(void) { Initialise(); }
+ void Initialise(void);
+ using CMenuPage::AddMenu;
+ bool AddMenu(CMenuBase *widget, FEC_MOVETAB *moveTab);
+
+ virtual void GoUpMenuOnPage(void);
+ virtual void GoDownMenuOnPage(void);
+ virtual void GoLeftMenuOnPage(void);
+ virtual void GoRightMenuOnPage(void);
+}; \ No newline at end of file
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 74729fec..75effc8a 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -8,6 +8,7 @@
#include "Pad.h"
#include "Text.h"
#include "main.h"
+#include "RwHelper.h"
#include "Timer.h"
#include "Game.h"
#include "DMAudio.h"
@@ -27,11 +28,48 @@
#include "World.h"
#include "Renderer.h"
#include "CdStream.h"
+#include "Radar.h"
+#include "Stats.h"
+#include "Messages.h"
+#include "FileLoader.h"
-#define DONT_USE_SUSPICIOUS_FUNCS 1
#define TIDY_UP_PBP // ProcessButtonPresses
#define MAX_VISIBLE_LIST_ROW 30
-#define LIST_HEIGHT 263.0f
+#define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result
+
+#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
+#define MILES_IN_METER 0.000621371192f
+#define FEET_IN_METER 3.28084f
+#else
+#define MILES_IN_METER 0.00059880241f
+#define FEET_IN_METER 3.33f
+#endif
+
+#ifdef SCROLLABLE_STATS_PAGE
+#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS)
+#else
+#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
+#endif
+
+#ifdef TRIANGLE_BACK_BUTTON
+#define GetBackJustUp GetTriangleJustUp
+#define GetBackJustDown GetTriangleJustDown
+#elif defined(CIRCLE_BACK_BUTTON)
+#define GetBackJustUp GetCircleJustUp
+#define GetBackJustDown GetCircleJustDown
+#else
+#define GetBackJustUp GetSquareJustUp
+#define GetBackJustDown GetSquareJustDown
+#endif
+
+#ifdef MENU_MAP
+bool CMenuManager::bMenuMapActive = false;
+bool CMenuManager::bMapMouseShownOnce = false;
+bool CMenuManager::bMapLoaded = false;
+float CMenuManager::fMapSize;
+float CMenuManager::fMapCenterY;
+float CMenuManager::fMapCenterX;
+#endif
#ifdef PS2_LIKE_MENU
BottomBarOption bbNames[8];
@@ -44,56 +82,66 @@ int curBottomBarOption = -1;
int hoveredBottomBarOption = -1;
#endif
-WRAPPER void CMenuManager::PrintController(void) { EAXJMP(0x483990); }
-
-int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78; // 9
-int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92;
-int8 &CMenuManager::m_DisplayControllerOnFoot = *(int8*)0x95CD8D;
-int8 &CMenuManager::m_PrefsVsync = *(int8*)0x5F2E58; // 1
-int8 &CMenuManager::m_PrefsVsyncDisp = *(int8*)0x5F2E5C; // 1
-int8 &CMenuManager::m_PrefsFrameLimiter = *(int8*)0x5F2E60; // 1
-int8 &CMenuManager::m_PrefsShowSubtitles = *(int8*)0x5F2E54; // 1
-int8 &CMenuManager::m_PrefsSpeakers = *(int8*)0x95CD7E;
-int32 &CMenuManager::m_ControlMethod = *(int32*)0x8F5F7C;
-int8 &CMenuManager::m_PrefsDMA = *(int8*)0x5F2F74; // 1
-int32 &CMenuManager::m_PrefsLanguage = *(int32*)0x941238;
-
-bool &CMenuManager::m_PrefsAllowNastyGame = *(bool*)0x5F2E64; // true
-bool &CMenuManager::m_bStartUpFrontEndRequested = *(bool*)0x95CCF4;
-bool &CMenuManager::m_bShutDownFrontEndRequested = *(bool*)0x95CD6A;
-
-int8 &CMenuManager::m_PrefsUseWideScreen = *(int8*)0x95CD23;
-int8 &CMenuManager::m_PrefsRadioStation = *(int8*)0x95CDA4;
-int32 &CMenuManager::m_PrefsBrightness = *(int32*)0x5F2E50; // 256
-float &CMenuManager::m_PrefsLOD = *(float*)0x8F42C4;
-int8 &CMenuManager::m_bFrontEnd_ReloadObrTxtGxt = *(int8*)0x628CFC;
-int32 &CMenuManager::m_PrefsMusicVolume = *(int32*)0x5F2E4C; // 102
-int32 &CMenuManager::m_PrefsSfxVolume = *(int32*)0x5F2E48; // 102
-
-char *CMenuManager::m_PrefsSkinFile = (char*)0x5F2E74; //[256] "$$\"\""
+int32 CMenuManager::OS_Language = LANG_ENGLISH; // *(int32*)0x5F2F78;
+int8 CMenuManager::m_PrefsUseVibration; // = *(int8*)0x95CD92;
+int8 CMenuManager::m_DisplayControllerOnFoot; // = *(int8*)0x95CD8D;
+int8 CMenuManager::m_PrefsVsync = 1; // *(int8*)0x5F2E58;
+int8 CMenuManager::m_PrefsVsyncDisp = 1; // *(int8*)0x5F2E5C;
+int8 CMenuManager::m_PrefsFrameLimiter = 1; // *(int8*)0x5F2E60;
+int8 CMenuManager::m_PrefsShowSubtitles = 1; // *(int8*)0x5F2E54;
+int8 CMenuManager::m_PrefsSpeakers; // = *(int8*)0x95CD7E;
+int32 CMenuManager::m_ControlMethod; // = *(int32*)0x8F5F7C;
+int8 CMenuManager::m_PrefsDMA = 1; // *(int8*)0x5F2F74;
+int32 CMenuManager::m_PrefsLanguage; // = *(int32*)0x941238;
+uint8 CMenuManager::m_PrefsStereoMono; // *(bool*)0x95CDB5; // unused except restore settings
+
+bool CMenuManager::m_PrefsAllowNastyGame = true; // *(bool*)0x5F2E64;
+bool CMenuManager::m_bStartUpFrontEndRequested; // = *(bool*)0x95CCF4;
+bool CMenuManager::m_bShutDownFrontEndRequested; // = *(bool*)0x95CD6A;
+
+int8 CMenuManager::m_PrefsUseWideScreen; // = *(int8*)0x95CD23;
+int8 CMenuManager::m_PrefsRadioStation; // = *(int8*)0x95CDA4;
+int32 CMenuManager::m_PrefsBrightness = 256; // = *(int32*)0x5F2E50;
+float CMenuManager::m_PrefsLOD; // = *(float*)0x8F42C4;
+int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt; // = *(int8*)0x628CFC;
+int32 CMenuManager::m_PrefsMusicVolume = 102; // = *(int32*)0x5F2E4C;
+int32 CMenuManager::m_PrefsSfxVolume = 102; // = *(int32*)0x5F2E48;
+
+char CMenuManager::m_PrefsSkinFile[256] = "$$\"\""; // = (char*)0x5F2E74;
+
+int32 CMenuManager::m_KeyPressedCode = -1; // = *(int32*)0x5F2E70;
+
+// Originally that was PS2 option color, they forget it here and used in PrintBriefs once(but didn't use the output anyway)
+#ifdef PS2_LIKE_MENU
+const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255);
+#else
+const CRGBA TEXT_COLOR = CRGBA(235, 170, 50, 255); // PC briefs text color
+#endif
-int32 &CMenuManager::m_KeyPressedCode = *(int32*)0x5F2E70; // -1
+const float menuXYpadding = MENUACTION_POS_Y; // *(float*)0x5F355C; // not original name
+float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE; //*(float*)0x5F2E40;
+float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE; //*(float*)0x5F2E44;
-float &CMenuManager::menuXYpadding = *(float*)0x5F355C; // don't know the original name. MENUACTION_X_MARGIN, never changes
-float &CMenuManager::actionTextScaleX = *(float*)0x5F2E40;
-float &CMenuManager::actionTextScaleY = *(float*)0x5F2E44;
+bool holdingScrollBar; // *(bool*)0x628D59; // not original name
+int32 CMenuManager::m_SelectedMap; // *(int32*)0x8E2880;
+int32 CMenuManager::m_SelectedGameType; // *(int32*)0x942F88;
-int32 &CMenuManager::sthWithButtons = *(int32*)0x8E2880;
-int32 &CMenuManager::sthWithButtons2 = *(int32*)0x942F88;
+// Used in a hidden menu
+uint8 CMenuManager::m_PrefsPlayerRed = 255;
+uint8 CMenuManager::m_PrefsPlayerGreen = 128;
+uint8 CMenuManager::m_PrefsPlayerBlue; // why??
-CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8;
+CMenuManager FrontEndMenuManager; // = *(CMenuManager*)0x8F59D8;
// Move this somewhere else.
-float &CRenderer::ms_lodDistScale = *(float*)0x5F726C; // 1.2
-
-// Stuff not in CMenuManager:
-uint32 &TimeToStopPadShaking = *(uint32*)0x628CF8;
-char *&pEditString = *(char**)0x628D00;
-int32 *&pControlEdit = *(int32**)0x628D08;
-bool &DisplayComboButtonErrMsg = *(bool*)0x628D14;
-int32 &MouseButtonJustClicked = *(int32*)0x628D0C;
-int32 &JoyButtonJustClicked = *(int32*)0x628D10;
-bool &holdingScrollBar = *(bool*)0x628D59;
+float CRenderer::ms_lodDistScale = 1.2f; // *(float*)0x5F726C;
+
+uint32 TimeToStopPadShaking; // = *(uint32*)0x628CF8;
+char *pEditString; // = *(char**)0x628D00;
+int32 *pControlEdit; // = *(int32**)0x628D08;
+bool DisplayComboButtonErrMsg; // = *(bool*)0x628D14;
+int32 MouseButtonJustClicked; // = *(int32*)0x628D0C;
+int32 JoyButtonJustClicked; // = *(int32*)0x628D10;
//int32 *pControlTemp = 0;
#ifndef MASTER
@@ -131,7 +179,22 @@ const char* FrontendFilenames[][2] = {
{"fe_radio7", "" }, // MSX_FM
{"fe_radio8", "" }, // FLASHBACK
{"fe_radio9", "" }, // CHATTERBOX
-};
+};
+
+#ifdef MENU_MAP
+const char* MapFilenames[][2] = {
+ {"mapMid01", "mapMid01A"},
+ {"mapMid02", "mapMid02A"},
+ {"mapMid03", "mapMid03A"},
+ {"mapBot01", "mapBot01A"},
+ {"mapBot02", "mapBot02A"},
+ {"mapBot03", "mapBot03A"},
+ {"mapTop01", "mapTop01A"},
+ {"mapTop02", "mapTop02A"},
+ {"mapTop03", "mapTop03A"},
+};
+CSprite2d CMenuManager::m_aMapSprites[NUM_MAP_SPRITES];
+#endif
// 0x5F3344
const char* MenuFilenames[][2] = {
@@ -160,7 +223,7 @@ const char* MenuFilenames[][2] = {
#ifdef ASPECT_RATIO_SCALE
// All of the defines below replace the StretchX function. Otherwise use SCREEN_SCALE_X.
#define MENU_X_LEFT_ALIGNED(x) ScaleAndCenterX(x)
-#define MENU_X_RIGHT_ALIGNED(x) ScaleAndCenterX(DEFAULT_SCREEN_WIDTH - x)
+#define MENU_X_RIGHT_ALIGNED(x) ScaleAndCenterX(DEFAULT_SCREEN_WIDTH - (x))
#define MENU_X(x) SCREEN_SCALE_X(x)
#define MENU_Y(y) SCREEN_SCALE_Y(y)
float
@@ -183,8 +246,6 @@ ScaleAndCenterX(float x)
#define MENU_Y(y) StretchY(y)
#endif
-#define isPlainTextScreen(screen) (screen == MENUPAGE_BRIEFS || screen == MENUPAGE_STATS)
-
#ifdef PS2_LIKE_MENU
#define ChangeScreen(screen, option, updateDelay, withReverseAlpha) \
do { \
@@ -224,14 +285,14 @@ ScaleAndCenterX(float x)
#define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \
do { \
- lastBarX = DisplaySlider(SCREEN_STRETCH_FROM_RIGHT(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(freeSpaceInLine), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
+ lastActiveBarX = DisplaySlider(SCREEN_STRETCH_FROM_RIGHT(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
if (i != m_nCurrOption || !itemsAreSelectable) \
break; \
\
- if (CheckHover(hoverStartX, lastBarX - MENU_X(10.0f), MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \
+ if (CheckHover(hoverStartX, lastActiveBarX - MENU_X(10.0f), MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \
m_nHoverOption = decreaseAction; \
\
- if (!CheckHover(MENU_X(10.0f) + lastBarX, hoverEndX, MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \
+ if (!CheckHover(MENU_X(10.0f) + lastActiveBarX, hoverEndX, MENU_Y(nextYToUse), MENU_Y(28.0f + nextYToUse))) \
break; \
\
m_nHoverOption = increaseAction; \
@@ -248,7 +309,7 @@ CMenuManager::ScrollUpListByOne()
if (m_nFirstVisibleRowOnList > 0) {
m_nSelectedListRow--;
m_nFirstVisibleRowOnList--;
- m_nCurListItemY -= LIST_HEIGHT / m_nTotalListRow;
+ m_nScrollbarTopMargin -= SCROLLBAR_MAX_HEIGHT / m_nTotalListRow;
}
} else {
m_nSelectedListRow--;
@@ -262,7 +323,7 @@ CMenuManager::ScrollDownListByOne()
if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
m_nSelectedListRow++;
m_nFirstVisibleRowOnList++;
- m_nCurListItemY += LIST_HEIGHT / m_nTotalListRow;
+ m_nScrollbarTopMargin += SCROLLBAR_MAX_HEIGHT / m_nTotalListRow;
}
} else {
if (m_nSelectedListRow < m_nTotalListRow - 1) {
@@ -285,7 +346,7 @@ CMenuManager::PageUpList(bool playSoundOnSuccess)
m_nFirstVisibleRowOnList = 0;
m_nSelectedListRow = 0;
}
- m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
}
}
@@ -303,7 +364,7 @@ CMenuManager::PageDownList(bool playSoundOnSuccess)
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
m_nSelectedListRow = m_nTotalListRow - 1;
}
- m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
}
}
@@ -335,18 +396,18 @@ CMenuManager::ThingsToDoBeforeLeavingPage()
// ------ Functions not in the game/inlined ends
void
-CMenuManager::BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2)
+CMenuManager::BuildStatLine(char *text, void *stat, bool itsFloat, void *stat2)
{
if (!text)
return;
if (stat2) {
- if (aFloat)
+ if (itsFloat)
sprintf(gString2, " %.2f %s %.2f", *(float*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(float*)stat2);
else
sprintf(gString2, " %d %s %d", *(int*)stat, UnicodeToAscii(TheText.Get("FEST_OO")), *(int*)stat2);
} else if (stat) {
- if (aFloat)
+ if (itsFloat)
sprintf(gString2, " %.2f", *(float*)stat);
else
sprintf(gString2, " %d", *(int*)stat);
@@ -357,14 +418,12 @@ CMenuManager::BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2)
AsciiToUnicode(gString2, gUString2);
}
-#if 0
-WRAPPER void CMenuManager::CentreMousePointer() { EAXJMP(0x48ACE0); }
-#else
-void CMenuManager::CentreMousePointer()
+void
+CMenuManager::CentreMousePointer()
{
tagPOINT Point;
- if (SCREEN_WIDTH * 0.5f == 0.0f && 0.0f == SCREEN_HEIGHT * 0.5f) {
+ if (SCREEN_WIDTH * 0.5f != 0.0f && 0.0f != SCREEN_HEIGHT * 0.5f) {
Point.x = SCREEN_WIDTH / 2;
Point.y = SCREEN_HEIGHT / 2;
ClientToScreen(PSGLOBAL(window), &Point);
@@ -374,28 +433,85 @@ void CMenuManager::CentreMousePointer()
PSGLOBAL(lastMousePos.y) = SCREEN_HEIGHT / 2;
}
}
-#endif
-#if 1
-WRAPPER int CMenuManager::CheckCodesForControls(int32) { EAXJMP(0x48A950); }
-#else
-void CMenuManager::CheckCodesForControls(int, int)
+void
+CMenuManager::CheckCodesForControls(int typeOfControl)
{
- DisplayComboButtonErrMsg = 0;
+ DisplayComboButtonErrMsg = false;
+ bool invalidKey = false;
+ bool escPressed = false;
+ eControllerType typeToSave;
+ // GetStartOptionsCntrlConfigScreens();
+ e_ControllerAction action = (e_ControllerAction) m_CurrCntrlAction;
+
+ if (typeOfControl == KEYBOARD) {
+ if (*pControlEdit == rsESC) {
+ escPressed = true;
+ } else if (*pControlEdit > rsF3 && *pControlEdit != rsF9 && *pControlEdit != rsLWIN &&
+ *pControlEdit != rsRWIN && *pControlEdit != rsRALT) {
+ typeToSave = KEYBOARD;
+ if (ControlsManager.GetControllerKeyAssociatedWithAction(action, KEYBOARD) != rsNULL &&
+ *pControlEdit != ControlsManager.GetControllerKeyAssociatedWithAction(action, KEYBOARD)) {
+ typeToSave = OPTIONAL_EXTRA;
+ }
+ } else {
+ invalidKey = true;
+ }
+ } else if (typeOfControl == MOUSE) {
+ typeToSave = MOUSE;
+ } else if (typeOfControl == JOYSTICK) {
+ typeToSave = JOYSTICK;
+ if (ControlsManager.GetIsActionAButtonCombo(action))
+ DisplayComboButtonErrMsg = true;
+ }
+
+ ControlsManager.ClearSettingsAssociatedWithAction(action, typeToSave);
+ if (!DisplayComboButtonErrMsg && !escPressed && !invalidKey) {
+ if (typeOfControl == KEYBOARD) {
+ ControlsManager.DeleteMatchingActionInitiators(action, *pControlEdit, KEYBOARD);
+ ControlsManager.DeleteMatchingActionInitiators(action, *pControlEdit, OPTIONAL_EXTRA);
+ } else {
+ if (typeOfControl == MOUSE) {
+ ControlsManager.DeleteMatchingActionInitiators(action, MouseButtonJustClicked, MOUSE);
+ } else if (typeOfControl == JOYSTICK) {
+ ControlsManager.DeleteMatchingActionInitiators(action, JoyButtonJustClicked, JOYSTICK);
+ }
+ }
+ if (typeOfControl == KEYBOARD) {
+ ControlsManager.SetControllerKeyAssociatedWithAction(action, *pControlEdit, typeToSave);
+
+ } else if (typeOfControl == MOUSE) {
+ ControlsManager.SetControllerKeyAssociatedWithAction(action, MouseButtonJustClicked, typeToSave);
+ } else {
+ if (typeOfControl == JOYSTICK) {
+ ControlsManager.SetControllerKeyAssociatedWithAction(action, JoyButtonJustClicked, typeToSave);
+ }
+ }
+ pControlEdit = nil;
+ m_bWaitingForNewKeyBind = false;
+ m_KeyPressedCode = -1;
+ m_bStartWaitingForKeyBind = false;
+ SaveSettings();
+ }
+
+ if (escPressed) {
+ pControlEdit = nil;
+ m_bWaitingForNewKeyBind = false;
+ m_KeyPressedCode = -1;
+ m_bStartWaitingForKeyBind = false;
+ SaveSettings();
+ }
}
-#endif
-#if 0
-WRAPPER bool CMenuManager::CheckHover(int, int, int, int) { EAXJMP(0x48ACA0); }
-#else
-bool CMenuManager::CheckHover(int x1, int x2, int y1, int y2)
+bool
+CMenuManager::CheckHover(int x1, int x2, int y1, int y2)
{
return m_nMousePosX > x1 && m_nMousePosX < x2 &&
m_nMousePosY > y1 && m_nMousePosY < y2;
}
-#endif
-void CMenuManager::CheckSliderMovement(int value)
+void
+CMenuManager::CheckSliderMovement(int value)
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_BRIGHTNESS:
@@ -431,110 +547,113 @@ void CMenuManager::CheckSliderMovement(int value)
SaveSettings();
}
-#if 1
-WRAPPER int CMenuManager::CostructStatLine(int) { EAXJMP(0x482800); }
-#else
-int CMenuManager::CostructStatLine(int)
+void
+CMenuManager::DisplayHelperText()
{
+ // there was a unused static bool
+ static uint32 LastFlash = 0;
+ int32 alpha;
-}
-#endif
-
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER void CMenuManager::DisplayHelperText() { EAXJMP(0x48B490); }
-#else
-void CMenuManager::DisplayHelperText()
-{
- static int32 AlphaText = 255;
- static int32 Time = 0;
+ if (m_nHelperTextMsgId != 0 && m_nHelperTextMsgId != 1) {
- if (m_nHelperTextMsgId && m_nHelperTextMsgId != 1) {
- if (CTimer::GetTimeInMillisecondsPauseMode() - Time > 10) {
- Time = CTimer::GetTimeInMillisecondsPauseMode();
+ // FIX: High fps bug
+#ifndef FIX_BUGS
+ if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 10) {
+ LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
m_nHelperTextAlpha -= 2;
+ }
+#else
+ static float fadeAlpha = 0.0f; // To keep it precisely
+ if (m_nHelperTextAlpha >= 255 && fadeAlpha < 250) fadeAlpha = m_nHelperTextAlpha;
- if (AlphaText < 1)
- ResetHelperText();
+ // -2 per every 33 ms (1000.f/30.f - original frame limiter fps)
+ fadeAlpha -= (frameTime / 33.0f) * 2.0f;
+ m_nHelperTextAlpha = fadeAlpha;
+#endif
+ if (m_nHelperTextAlpha < 1)
+ ResetHelperText();
- AlphaText = m_nHelperTextAlpha > 255 ? 255 : m_nHelperTextAlpha;
- }
+ alpha = m_nHelperTextAlpha > 255 ? 255 : m_nHelperTextAlpha;
}
- wchar *HelperTextToPrint = nil;
+ CFont::SetCentreOn();
+ CFont::SetScale(SCREEN_SCALE_X(SMALLESTTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_HEADING);
+
// TODO: name this cases?
switch (m_nHelperTextMsgId) {
- case 0:
- HelperTextToPrint = TheText.Get("FET_MIG");
- break;
- case 1:
- HelperTextToPrint = TheText.Get("FET_APP");
- break;
- case 2:
- HelperTextToPrint = TheText.Get("FET_HRD");
- break;
- case 3:
- HelperTextToPrint = TheText.Get("FET_RSO");
- break;
- case 4:
- HelperTextToPrint = TheText.Get("FET_RSC");
- break;
- default:
- break;
+ case 0:
+ {
+ int action = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
+ if (action != MENUACTION_CHANGEMENU && action != MENUACTION_REDEFCTRL && action != MENUACTION_RESTOREDEF) {
+ CFont::SetColor(CRGBA(255, 255, 255, 255));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_MIG"));
+ }
+ break;
+ }
+ case 1:
+ CFont::SetColor(CRGBA(255, 255, 255, 255));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_APP"));
+ break;
+ case 2:
+ CFont::SetColor(CRGBA(255, 255, 255, alpha));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_HRD"));
+ break;
+ case 3:
+ CFont::SetColor(CRGBA(255, 255, 255, alpha));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSO"));
+ break;
+ case 4:
+ CFont::SetColor(CRGBA(255, 255, 255, alpha));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(320.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f), TheText.Get("FET_RSC"));
+ break;
+ default:
+ break;
}
-
- CFont::SetAlignment(ALIGN_CENTER);
- CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
- CFont::SetFontStyle(FONT_HEADING);
- CFont::SetDropColor(CRGBA(0, 0, 0, AlphaText));
- CFont::SetDropShadowPosition(MENUDROP_COLOR_SIZE);
- CFont::SetColor(CRGBA(255, 255, 255, AlphaText));
-
- CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_FROM_BOTTOM(120.0f), HelperTextToPrint);
+ CFont::SetRightJustifyOff();
}
-#endif
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER int CMenuManager::DisplaySlider(float, float, float, float, float, float) { EAXJMP(0x488420); }
-#else
-int CMenuManager::DisplaySlider(float x, float y, float leftSize, float rightSize, float rectSize, float progress)
+int
+CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress)
{
CRGBA color;
- float sizeRange;
+ float maxBarHeight;
- float input = 0.0f;
+ int lastActiveBarX = 0;
+ float curBarX = 0.0f;
+ float spacing = SCREEN_SCALE_X(10.0f);
for (int i = 0; i < 16; i++) {
- input = i * rectSize/16.0f + x;
+ curBarX = i * rectSize/16.0f + x;
- if (i/16.0f + 1/32.0f < progress)
+ if (i / 16.0f + 1 / 32.0f < progress) {
color = CRGBA(255, 217, 106, FadeIn(255));
- else
+ lastActiveBarX = curBarX;
+ } else
color = CRGBA(185, 120, 0, FadeIn(255));
- sizeRange = max(leftSize, rightSize);
+ maxBarHeight = max(mostLeftBarSize, mostRightBarSize);
- float _x = i * rectSize/16.0f + x;
- float _y = y + sizeRange - ((16 - i) * leftSize + i * rightSize)/16.0f;
- float _w = SCREEN_SCALE_X(10.0f) + i * rectSize/16.0f + x;
- float _h = y + sizeRange;
- float _s = SCREEN_SCALE_X(2.0f);
- CSprite2d::DrawRect(CRect(_x + _s, _y + _s, _w + _s, _h + _s), CRGBA(0, 0, 0, FadeIn(255))); // Shadow
- CSprite2d::DrawRect(CRect(i * rectSize/16.0f + x, y + sizeRange - ((16 - i) * leftSize + i * rightSize)/16.0f, SCREEN_SCALE_X(10.0f) + i * rectSize/16.0f + x, y + sizeRange), color);
+ float curBarFreeSpace = ((16 - i) * mostLeftBarSize + i * mostRightBarSize) / 16.0f;
+ float left = curBarX;
+ float top = y + maxBarHeight - curBarFreeSpace;
+ float right = spacing + curBarX;
+ float bottom = y + maxBarHeight;
+ float shadowOffset = SCREEN_SCALE_X(2.0f);
+ CSprite2d::DrawRect(CRect(left + shadowOffset, top + shadowOffset, right + shadowOffset, bottom + shadowOffset), CRGBA(0, 0, 0, FadeIn(200))); // Shadow
+ CSprite2d::DrawRect(CRect(left, top, right, bottom), color);
}
- return input;
+ return lastActiveBarX;
}
-#endif
-#if 0
-WRAPPER void CMenuManager::DoSettingsBeforeStartingAGame() { EAXJMP(0x48AB40); }
-#else
-void CMenuManager::DoSettingsBeforeStartingAGame()
+void
+CMenuManager::DoSettingsBeforeStartingAGame()
{
CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service();
- m_bStartGameLoading = true;
+ m_bWantToRestart = true;
ShutdownJustMenu();
UnloadTextures();
@@ -542,20 +661,17 @@ void CMenuManager::DoSettingsBeforeStartingAGame()
DMAudio.SetMusicFadeVol(0);
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
}
-#endif
-#if 0
-WRAPPER void CMenuManager::Draw() { EAXJMP(0x47AE00); }
-#else
-void CMenuManager::Draw()
+void
+CMenuManager::Draw()
{
CFont::SetBackgroundOff();
CFont::SetPropOn();
CFont::SetCentreOff();
CFont::SetJustifyOn();
CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENUACTION_X_MARGIN));
- CFont::SetRightJustifyWrap(SCREEN_SCALE_X(38.0f));
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
+ CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
switch (m_nCurrScreen) {
case MENUPAGE_STATS:
@@ -564,6 +680,11 @@ void CMenuManager::Draw()
case MENUPAGE_BRIEFS:
PrintBriefs();
break;
+#ifdef MENU_MAP
+ case MENUPAGE_MAP:
+ PrintMap();
+ break;
+#endif
}
// Header height isn't accounted, we will add that later.
@@ -591,8 +712,8 @@ void CMenuManager::Draw()
}
CFont::SetFontStyle(FONTJAP(FONT_BANK));
- CFont::SetScale(MENU_X(0.9f * actionTextScaleX), MENU_Y(0.9f * actionTextScaleY));
- CFont::SetRightJustifyOff(); // AG used SetAlignment(ALIGN_LEFT);
+ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_X), MENU_Y(MENUACTION_SCALE_MULT * MENU_TEXT_SIZE_Y));
+ CFont::SetRightJustifyOff();
CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
// Label
@@ -623,10 +744,10 @@ void CMenuManager::Draw()
}
#ifdef FIX_BUGS
- // Label is wrapped from right by StretchX(40)px, but wrapped from left by 40px. And this is only place R* didn't use StretchX in menu.
- CFont::PrintString(MENU_X_LEFT_ALIGNED(MENUACTION_X_MARGIN), MENU_Y(menuXYpadding), str);
+ // Label is wrapped from right by StretchX(40)px, but wrapped from left by 40px. And this is only place R* didn't use StretchX in here.
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN), MENU_Y(menuXYpadding), str);
#else
- CFont::PrintString(MENUACTION_X_MARGIN, menuXYpadding, str);
+ CFont::PrintString(MENU_X_MARGIN, menuXYpadding, str);
#endif
}
@@ -647,7 +768,7 @@ void CMenuManager::Draw()
headerHeight = 240;
lineHeight = 24;
CFont::SetFontStyle(FONTJAP(FONT_HEADING));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.75f), MENU_Y(actionTextScaleY = 0.9f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE));
CFont::SetCentreOn();
break;
case MENUPAGE_SOUND_SETTINGS:
@@ -664,7 +785,7 @@ void CMenuManager::Draw()
headerHeight = 0;
lineHeight = 20;
CFont::SetFontStyle(FONTJAP(FONT_HEADING));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.55f), MENU_Y(actionTextScaleY = 0.8f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = MEDIUMTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = MEDIUMTEXT_Y_SCALE));
CFont::SetRightJustifyOff();
break;
case MENUPAGE_CHOOSE_LOAD_SLOT:
@@ -674,7 +795,7 @@ void CMenuManager::Draw()
headerHeight = 38;
lineHeight = 20;
CFont::SetFontStyle(FONTJAP(FONT_BANK));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.45f), MENU_Y(actionTextScaleY = 0.7f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE));
CFont::SetRightJustifyOff();
break;
case MENUPAGE_NEW_GAME_RELOAD:
@@ -686,7 +807,7 @@ void CMenuManager::Draw()
headerHeight = 60;
lineHeight = 24;
CFont::SetFontStyle(FONTJAP(FONT_HEADING));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.75f), MENU_Y(actionTextScaleY = 0.9f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE));
CFont::SetCentreOn();
break;
case MENUPAGE_START_MENU:
@@ -694,7 +815,7 @@ void CMenuManager::Draw()
headerHeight = 140;
lineHeight = 24;
CFont::SetFontStyle(FONTJAP(FONT_HEADING));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.75f), MENU_Y(actionTextScaleY = 0.9f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE));
CFont::SetCentreOn();
break;
case MENUPAGE_PAUSE_MENU:
@@ -702,7 +823,7 @@ void CMenuManager::Draw()
headerHeight = 117;
lineHeight = 24;
CFont::SetFontStyle(FONTJAP(FONT_HEADING));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.75f), MENU_Y(actionTextScaleY = 0.9f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE));
CFont::SetCentreOn();
break;
#ifdef PS2_SAVE_DIALOG
@@ -711,7 +832,7 @@ void CMenuManager::Draw()
headerHeight = 60;
lineHeight = 24;
CFont::SetFontStyle(FONTJAP(FONT_BANK));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.75f), MENU_Y(actionTextScaleY = 0.9f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE));
break;
#endif
default:
@@ -719,11 +840,15 @@ void CMenuManager::Draw()
headerHeight = 40;
lineHeight = 24;
CFont::SetFontStyle(FONTJAP(FONT_HEADING));
- CFont::SetScale(MENU_X(actionTextScaleX = 0.75f), MENU_Y(actionTextScaleY = 0.9f));
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X = BIGTEXT_X_SCALE), MENU_Y(MENU_TEXT_SIZE_Y = BIGTEXT_Y_SCALE));
CFont::SetCentreOn();
break;
}
+#ifdef PS2_LIKE_MENU
+ CFont::SetFontStyle(FONT_BANK);
+#endif
+
switch (m_nCurrScreen) {
case MENUPAGE_CONTROLLER_PC_OLD1:
case MENUPAGE_CONTROLLER_PC_OLD2:
@@ -733,14 +858,14 @@ void CMenuManager::Draw()
if (m_bWaitingForNewKeyBind)
itemsAreSelectable = false;
- CMenuManager::DrawControllerScreenExtraText(nextYToUse - 8.0f, 350, lineHeight);
+ DrawControllerScreenExtraText(nextYToUse - 8.0f, MENU_X_LEFT_ALIGNED(350), lineHeight);
break;
default:
break;
}
float usableLineHeight = lineHeight * 0.9f; // also height of biggest bar in slider
- float freeSpaceInLine = lineHeight * 0.1f; // also height of smallest bar in slider(weird)
+ float smallestSliderBar = lineHeight * 0.1f;
bool foundTheHoveringItem = false;
wchar unicodeTemp[64];
@@ -768,7 +893,7 @@ void CMenuManager::Draw()
case MENUACTION_CHANGEMENU: {
switch (aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu) {
case MENUPAGE_MULTIPLAYER_MAP:
- switch (sthWithButtons) {
+ switch (m_SelectedMap) {
case 0:
rightText = TheText.Get("FEM_MA0");
break;
@@ -798,7 +923,7 @@ void CMenuManager::Draw()
}
break;
case MENUPAGE_MULTIPLAYER_MODE:
- switch (sthWithButtons2) {
+ switch (m_SelectedGameType) {
case 0:
rightText = TheText.Get("FEN_TY0");
break;
@@ -833,7 +958,7 @@ void CMenuManager::Draw()
break;
}
case MENUACTION_CTRLVIBRATION:
- if (CMenuManager::m_PrefsUseVibration)
+ if (m_PrefsUseVibration)
rightText = TheText.Get("FEM_ON");
else
rightText = TheText.Get("FEM_OFF");
@@ -999,23 +1124,23 @@ void CMenuManager::Draw()
#endif
m_nMousePosY < MENU_Y((nextYToCheck + 2) + usableLineHeight)) {
- static int lastHoveringOption = -99;
- static int lastScreen = m_nCurrScreen;
+ static int oldOption = -99;
+ static int oldScreen = m_nCurrScreen;
m_nPrevOption = rowToCheck;
if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) {
m_nCurrOption = rowToCheck;
m_bShowMouse = true;
}
- if (lastHoveringOption != m_nCurrOption) {
- if (lastScreen == m_nCurrScreen && m_bShowMouse)
+ if (oldOption != m_nCurrOption) {
+ if (oldScreen == m_nCurrScreen && m_bShowMouse)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
- lastHoveringOption = m_nCurrOption;
- lastScreen = m_nCurrScreen;
+ oldOption = m_nCurrOption;
+ oldScreen = m_nCurrScreen;
}
- if (lastScreen == m_nPrevScreen)
- lastScreen = m_nCurrScreen;
+ if (oldScreen == m_nPrevScreen)
+ oldScreen = m_nCurrScreen;
m_nHoverOption = HOVEROPTION_RANDOM_ITEM;
foundTheHoveringItem = true;
@@ -1098,7 +1223,7 @@ void CMenuManager::Draw()
// Sliders
// We stretch slider start X here(like original code), because it will always be center of screen
- int lastBarX;
+ int lastActiveBarX;
switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
case MENUACTION_BRIGHTNESS:
ProcessSlider(m_PrefsBrightness / 512.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
@@ -1156,45 +1281,646 @@ void CMenuManager::Draw()
break;
}
- if (m_nCurrScreen == MENUPAGE_CONTROLLER_SETTINGS) {
+ if (m_nCurrScreen == MENUPAGE_CONTROLLER_SETTINGS)
PrintController();
+ else if (m_nCurrScreen == MENUPAGE_SKIN_SELECT_OLD) {
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(180), MENU_Y(98), MENU_X_LEFT_ALIGNED(230), MENU_Y(123)), CRGBA(255, 255, 255, FadeIn(255)));
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(181), MENU_Y(99), MENU_X_LEFT_ALIGNED(229), MENU_Y(122)), CRGBA(m_PrefsPlayerRed, m_PrefsPlayerGreen, m_PrefsPlayerBlue, FadeIn(255)));
}
-/* else if (m_nCurrScreen == MENUPAGE_SKIN_SELECT_OLD) {
- CSprite2d::DrawRect(CRect(StretchX(180), MENU_Y(98), StretchX(230), MENU_Y(123)), CRGBA(255, 255, 255, FadeIn(255)));
- CSprite2d::DrawRect(CRect(StretchX(181), MENU_Y(99), StretchX(229), MENU_Y(233)), CRGBA(Player color from PickNewPlayerColour, FadeIn(255)));
+
+}
+
+int
+CMenuManager::GetNumOptionsCntrlConfigScreens(void)
+{
+ int number = 0;
+ switch (m_nCurrScreen) {
+ case MENUPAGE_CONTROLLER_PC_OLD3:
+ number = 2;
+ break;
+ case MENUPAGE_CONTROLLER_DEBUG:
+ number = 4;
+ break;
+ case MENUPAGE_KEYBOARD_CONTROLS:
+ switch (m_ControlMethod) {
+ case CONTROL_STANDARD:
+ number = 25;
+ break;
+ case CONTROL_CLASSIC:
+ number = 30;
+ break;
+ }
+ break;
}
-*/
+ return number;
}
+
+void
+CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 column)
+{
+ int controllerAction = PED_FIREWEAPON;
+ // GetStartOptionsCntrlConfigScreens();
+ int numOptions = GetNumOptionsCntrlConfigScreens();
+ int bindingMargin = MENU_X(3.0f);
+ float rowHeight;
+ switch (m_ControlMethod) {
+ case CONTROL_STANDARD:
+ rowHeight = CONTSETUP_STANDARD_ROW_HEIGHT;
+ break;
+ case CONTROL_CLASSIC:
+ rowHeight = CONTSETUP_CLASSIC_ROW_HEIGHT;
+ break;
+ default:
+ break;
+ }
+
+ // MENU_Y(rowHeight * 0.0f + yStart);
+ for (int optionIdx = 0, nextY = MENU_Y(yStart); optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) {
+ int nextX = xStart;
+ int bindingsForThisOpt = 0;
+ CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255)));
+
+ if (column == CONTSETUP_PED_COLUMN) {
+ switch (optionIdx) {
+ case 0:
+ controllerAction = PED_FIREWEAPON;
+ break;
+ case 1:
+ controllerAction = PED_CYCLE_WEAPON_RIGHT;
+ break;
+ case 2:
+ controllerAction = PED_CYCLE_WEAPON_LEFT;
+ break;
+ case 3:
+ controllerAction = GO_FORWARD;
+ break;
+ case 4:
+ controllerAction = GO_BACK;
+ break;
+ case 5:
+ controllerAction = GO_LEFT;
+ break;
+ case 6:
+ controllerAction = GO_RIGHT;
+ break;
+ case 7:
+ controllerAction = PED_SNIPER_ZOOM_IN;
+ break;
+ case 8:
+ controllerAction = PED_SNIPER_ZOOM_OUT;
+ break;
+ case 9:
+ controllerAction = VEHICLE_ENTER_EXIT;
+ break;
+ case 10:
+ case 11:
+ case 12:
+ case 16:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ controllerAction = -1;
+ break;
+ case 13:
+ controllerAction = CAMERA_CHANGE_VIEW_ALL_SITUATIONS;
+ break;
+ case 14:
+ controllerAction = PED_JUMPING;
+ break;
+ case 15:
+ controllerAction = PED_SPRINT;
+ break;
+ case 17:
+ controllerAction = PED_LOCK_TARGET;
+ break;
+ case 22:
+ controllerAction = PED_LOOKBEHIND;
+ break;
+ case 23:
+ if (m_ControlMethod == CONTROL_STANDARD)
+ controllerAction = -1;
+ else
+ controllerAction = PED_1RST_PERSON_LOOK_LEFT;
+ break;
+ case 24:
+ if (m_ControlMethod == CONTROL_STANDARD)
+ controllerAction = -1;
+ else
+ controllerAction = PED_1RST_PERSON_LOOK_RIGHT;
+ break;
+ case 25:
+ controllerAction = PED_1RST_PERSON_LOOK_UP;
+ break;
+ case 26:
+ controllerAction = PED_1RST_PERSON_LOOK_DOWN;
+ break;
+ case 27:
+ controllerAction = PED_CYCLE_TARGET_LEFT;
+ break;
+ case 28:
+ controllerAction = PED_CYCLE_TARGET_RIGHT;
+ break;
+ case 29:
+ controllerAction = PED_CENTER_CAMERA_BEHIND_PLAYER;
+ break;
+ default:
+ break;
+ }
+ } else if (column == CONTSETUP_VEHICLE_COLUMN) {
+ switch (optionIdx) {
+ case 0:
+ controllerAction = PED_FIREWEAPON;
+ break;
+ case 1:
+ case 2:
+ case 7:
+ case 8:
+ case 14:
+ case 15:
+ case 17:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ controllerAction = -1;
+ break;
+ case 3:
+ controllerAction = VEHICLE_ACCELERATE;
+ break;
+ case 4:
+ controllerAction = VEHICLE_BRAKE;
+ break;
+ case 5:
+ controllerAction = GO_LEFT;
+ break;
+ case 6:
+ controllerAction = GO_RIGHT;
+ break;
+ case 9:
+ controllerAction = VEHICLE_ENTER_EXIT;
+ break;
+ case 10:
+ controllerAction = VEHICLE_CHANGE_RADIO_STATION;
+ break;
+ case 11:
+ controllerAction = VEHICLE_HORN;
+ break;
+ case 12:
+ controllerAction = TOGGLE_SUBMISSIONS;
+ break;
+ case 13:
+ controllerAction = CAMERA_CHANGE_VIEW_ALL_SITUATIONS;
+ break;
+ case 16:
+ controllerAction = VEHICLE_HANDBRAKE;
+ break;
+ case 18:
+ controllerAction = VEHICLE_TURRETLEFT;
+ break;
+ case 19:
+ controllerAction = VEHICLE_TURRETRIGHT;
+ break;
+ case 20:
+ controllerAction = VEHICLE_TURRETUP;
+ break;
+ case 21:
+ controllerAction = VEHICLE_TURRETDOWN;
+ break;
+ case 22:
+ controllerAction = -2;
+ break;
+ case 23:
+ controllerAction = VEHICLE_LOOKLEFT;
+ break;
+ case 24:
+ controllerAction = VEHICLE_LOOKRIGHT;
+ break;
+ default:
+ break;
+ }
+ }
+ int bindingWhite = 155;
+
+ // Highlight selected column(and make its text black)
+ if (m_nSelectedListRow == optionIdx) {
+ int bgY = m_nSelectedListRow * rowHeight + yStart + 1.0f;
+ if (m_nCurrExLayer == HOVEROPTION_LIST) {
+
+ if (column == CONTSETUP_PED_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_PED_COLUMN) {
+#ifdef FIX_BUGS
+ if (controllerAction == -1) {
+ CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
+ MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150)));
+ } else {
+ CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
+ MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210)));
+ }
+#else
+ if (controllerAction == -1) {
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY),
+ MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150)));
+ } else {
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(bgY),
+ MENU_X_LEFT_ALIGNED(400.0f), MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210)));
+ }
#endif
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ bindingWhite = 0;
-#if 1
-WRAPPER void CMenuManager::DrawControllerBound(int, int, int, uint8) { EAXJMP(0x489710); }
+ } else if (column == CONTSETUP_VEHICLE_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_VEHICLE_COLUMN) {
+#ifdef FIX_BUGS
+ if (controllerAction == -1) {
+ CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
+ MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(235, 170, 50, FadeIn(150)));
+ } else {
+ CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
+ MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210)));
+ }
#else
-void CMenuManager::DrawControllerBound(int, int, int, uint8)
-{
+ if (controllerAction == -1) {
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(235, 170, 50, FadeIn(150)));
+ } else {
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(255, 217, 106, FadeIn(210)));
+ }
+#endif
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ bindingWhite = 0;
+ }
+ }
+ }
+
+ // Print bindings, including seperator (-) between them
+ CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f));
+ for (int contSetOrder = SETORDER_1; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) {
+ wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder);
+ if (settingText) {
+ ++bindingsForThisOpt;
+ if (bindingsForThisOpt > 1) {
+ wchar *seperator = TheText.Get("FEC_IBT");
+ CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80)));
+ CFont::PrintString(nextX, nextY, seperator);
+ CFont::SetColor(CRGBA(bindingWhite, bindingWhite, bindingWhite, FadeIn(255)));
+ nextX += CFont::GetStringWidth(seperator, true) + bindingMargin;
+ }
+ CFont::PrintString(nextX, nextY, settingText);
+ nextX += CFont::GetStringWidth(settingText, true) + bindingMargin;
+ }
+ }
+ if (controllerAction == -1) {
+ CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80)));
+ CFont::PrintString(nextX, nextY, TheText.Get("FEC_NUS")); // not used
+ } else if (controllerAction == -2) {
+ CFont::SetColor(CRGBA(20, 20, 20, FadeIn(80)));
+ CFont::PrintString(nextX, nextY, TheText.Get("FEC_CMP")); // combo: l+r
+ } else if (bindingsForThisOpt == 0) {
+ if (m_nSelectedListRow != optionIdx) {
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound
+ } else if (m_bWaitingForNewKeyBind) {
+ if (column != m_nSelectedContSetupColumn) {
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound
+ }
+ } else {
+ if (column != m_nSelectedContSetupColumn) {
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ }
+ CFont::PrintString(nextX, nextY, TheText.Get("FEC_UNB")); // unbound
+ }
+ }
+ if (column == CONTSETUP_PED_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_PED_COLUMN ||
+ column == CONTSETUP_VEHICLE_COLUMN && m_nSelectedContSetupColumn == CONTSETUP_VEHICLE_COLUMN) {
+
+ if (optionIdx == m_nSelectedListRow && controllerAction != -1 && controllerAction != -2) {
+ m_CurrCntrlAction = controllerAction;
+ if (m_bWaitingForNewKeyBind) {
+ static bool showWaitingText = false;
+ if (bindingsForThisOpt > 0) {
+ wchar *seperator = TheText.Get("FEC_IBT");
+ CFont::PrintString(nextX, nextY, seperator);
+ nextX += CFont::GetStringWidth(seperator, true) + bindingMargin;
+ }
+ static uint32 lastWaitingTextFlash = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastWaitingTextFlash > 150) {
+ showWaitingText = !showWaitingText;
+ lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ if (showWaitingText) {
+ CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255)));
+ CFont::PrintString(nextX, nextY, TheText.Get("FEC_QUE")); // "???"
+ }
+ CFont::SetCentreOn();
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ if (m_bKeyChangeNotProcessed) {
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE
+ } else {
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_RIG")); // SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL
+ }
+
+ CFont::SetRightJustifyOff();
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(0);
+ if (!m_bKeyIsOK)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
+
+ m_bKeyIsOK = true;
+ } else {
+ CFont::SetCentreOn();
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_CIG")); // BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE
+ CFont::SetRightJustifyOff();
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_BANK);
+ m_bKeyIsOK = false;
+ m_bKeyChangeNotProcessed = false;
+ }
+ } else if (optionIdx == m_nSelectedListRow) {
+ CFont::SetCentreOn();
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255)));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(275.0f), SCREEN_SCALE_FROM_BOTTOM(114.0f), TheText.Get("FET_EIG")); // CANNOT SET A CONTROL FOR THIS ACTION
+ CFont::SetRightJustifyOff();
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_BANK);
+ }
+ }
+ }
}
-#endif
-#if 1
-WRAPPER void CMenuManager::DrawControllerScreenExtraText(int, int, int) { EAXJMP(0x4892F0); }
-#else
-void CMenuManager::DrawControllerScreenExtraText(int, int, int)
+void
+CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeight)
{
+ int extraTextStart = GetStartOptionsCntrlConfigScreens();
+ int numOpts = GetNumOptionsCntrlConfigScreens();
+ int spacing = MENU_X(10.0f);
+ for (int i = extraTextStart; i < extraTextStart + numOpts; i++) {
+ int numTextsPrinted = 0;
+ int nextX = xStart;
+ for (int j = 1; j < 5; j++) {
+ wchar *text = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)i, (eContSetOrder)j);
+ if (text)
+ ++numTextsPrinted;
+
+ if (text) {
+ // Seperator
+ if (numTextsPrinted > 1) {
+ CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_IBT"));
+ nextX = CFont::GetStringWidth(TheText.Get("FEC_IBT"), true) + spacing + nextX;
+ }
+ CFont::PrintString(nextX, MENU_Y(yStart), text);
+ }
+ if (text)
+ nextX = CFont::GetStringWidth(text, true) + spacing + nextX;
+ }
+ if (m_nCurrOption == i - extraTextStart && m_bWaitingForNewKeyBind) {
+ static bool waitingTextVisible = false;
+
+ // Seperator
+ if (numTextsPrinted > 0) {
+ CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_IBT"));
+ nextX = CFont::GetStringWidth(TheText.Get("FEC_IBT"), true) + spacing + nextX;
+ }
+ static uint32 lastStateChange = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastStateChange > 150) {
+ waitingTextVisible = !waitingTextVisible;
+ lastStateChange = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ if (waitingTextVisible) {
+ CFont::SetColor(CRGBA(255, 255, 0, FadeIn(255)));
+ CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_QUE"));
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ }
+ }
+ yStart += lineHeight;
+ }
+ wchar *error = nil;
+ if (DisplayComboButtonErrMsg)
+ error = ControlsManager.GetButtonComboText((e_ControllerAction)(m_nCurrOption + extraTextStart));
+ if (error) {
+ CFont::SetColor(CRGBA(233, 22, 159, 255));
+ CFont::PrintString(xStart, MENU_Y(yStart + 10), error);
+ }
}
+
+void
+CMenuManager::DrawControllerSetupScreen()
+{
+ float rowHeight;
+ switch (m_ControlMethod) {
+ case CONTROL_STANDARD:
+ rowHeight = CONTSETUP_STANDARD_ROW_HEIGHT;
+ break;
+ case CONTROL_CLASSIC:
+ rowHeight = CONTSETUP_CLASSIC_ROW_HEIGHT;
+ break;
+ default:
+ break;
+ }
+ CFont::SetBackgroundOff();
+ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
+ CFont::SetPropOn();
+ CFont::SetCentreOff();
+ CFont::SetJustifyOn();
+ CFont::SetRightJustifyOff();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
+ CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
+
+ // Page header
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetRightJustifyOn();
+ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
+ CFont::SetFontStyle(FONT_HEADING);
+ switch (m_ControlMethod) {
+ case CONTROL_STANDARD:
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
+ TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
+ break;
+ case CONTROL_CLASSIC:
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y),
+ TheText.Get("FET_CTI"));
+ break;
+ default:
+ break;
+ }
+ wchar *actionTexts[31];
+ actionTexts[0] = TheText.Get("FEC_FIR");
+ actionTexts[1] = TheText.Get("FEC_NWE");
+ actionTexts[2] = TheText.Get("FEC_PWE");
+ actionTexts[3] = TheText.Get("FEC_FOR");
+ actionTexts[4] = TheText.Get("FEC_BAC");
+ actionTexts[5] = TheText.Get("FEC_LEF");
+ actionTexts[6] = TheText.Get("FEC_RIG");
+ actionTexts[7] = TheText.Get("FEC_ZIN");
+ actionTexts[8] = TheText.Get("FEC_ZOT");
+ actionTexts[9] = TheText.Get("FEC_EEX");
+ actionTexts[10] = TheText.Get("FEC_RAD");
+ actionTexts[11] = TheText.Get("FEC_HRN");
+ actionTexts[12] = TheText.Get("FEC_SUB");
+ actionTexts[13] = TheText.Get("FEC_CMR");
+ actionTexts[14] = TheText.Get("FEC_JMP");
+ actionTexts[15] = TheText.Get("FEC_SPN");
+ actionTexts[16] = TheText.Get("FEC_HND");
+ actionTexts[17] = TheText.Get("FEC_TAR");
+ if (m_ControlMethod == CONTROL_CLASSIC) {
+ actionTexts[18] = TheText.Get("FEC_TFL");
+ actionTexts[19] = TheText.Get("FEC_TFR");
+ actionTexts[20] = TheText.Get("FEC_TFU");
+ actionTexts[21] = TheText.Get("FEC_TFD");
+ actionTexts[22] = TheText.Get("FEC_LBA");
+ actionTexts[23] = TheText.Get("FEC_LOL");
+ actionTexts[24] = TheText.Get("FEC_LOR");
+ actionTexts[25] = TheText.Get("FEC_LUD");
+ actionTexts[26] = TheText.Get("FEC_LDU");
+ actionTexts[27] = TheText.Get("FEC_NTR");
+ actionTexts[28] = TheText.Get("FEC_PTT");
+ actionTexts[29] = TheText.Get("FEC_CEN");
+ actionTexts[30] = nil;
+ } else {
+ actionTexts[18] = TheText.Get("FEC_TFL");
+ actionTexts[19] = TheText.Get("FEC_TFR");
+ actionTexts[20] = TheText.Get("FEC_TFU");
+ actionTexts[21] = TheText.Get("FEC_TFD");
+ actionTexts[22] = TheText.Get("FEC_LBA");
+ actionTexts[23] = TheText.Get("FEC_LOL");
+ actionTexts[24] = TheText.Get("FEC_LOR");
+ actionTexts[25] = nil;
+ }
+
+ // Gray panel background
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT), MENU_Y(CONTSETUP_LIST_TOP),
+ MENU_X_RIGHT_ALIGNED(CONTSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM)),
+ CRGBA(200, 200, 50, FadeIn(50)));
+
+ if (m_nCurrExLayer == HOVEROPTION_LIST)
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+ else
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+
+ // List header
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
+ CFont::SetRightJustifyOff();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CAC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR"));
+ CFont::SetRightJustifyOff();
+ CFont::SetScale(MENU_X_LEFT_ALIGNED(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_BANK);
+ int yStart;
+ if (m_ControlMethod == CONTROL_CLASSIC)
+ yStart = CONTSETUP_LIST_HEADER_HEIGHT + 29;
+ else
+ yStart = CONTSETUP_LIST_HEADER_HEIGHT + 34;
+
+ for (int i = 0; i < ARRAY_SIZE(actionTexts); ++i) {
+ wchar *actionText = actionTexts[i];
+ if (!actionText)
+ break;
+
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) &&
+ m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)) {
+
+ float curOptY = i * rowHeight + yStart;
+ if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) {
+ if (m_nPrevOption != i && m_nCurrExLayer == HOVEROPTION_LIST)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
+
+ m_nPrevOption = i;
+ if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_nSelectedListRow = i;
+
+ // why different number for 3rd column hovering X?? this function is a mess
+#ifdef FIX_BUGS
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(0.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH)) {
+#else
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(0.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(370.0f)) {
#endif
+ if (m_nSelectedContSetupColumn != CONTSETUP_PED_COLUMN && m_nCurrExLayer == HOVEROPTION_LIST)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
-#if 1
-WRAPPER void CMenuManager::DrawControllerSetupScreen() { EAXJMP(0x481210); }
+ m_nSelectedContSetupColumn = CONTSETUP_PED_COLUMN;
+#ifdef FIX_BUGS
+ } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH) && m_nMousePosX < SCREEN_WIDTH) {
#else
-void CMenuManager::DrawControllerSetupScreen()
-{
+ } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(370.0f) && m_nMousePosX < SCREEN_WIDTH) {
+#endif
+ if (m_nSelectedContSetupColumn != CONTSETUP_VEHICLE_COLUMN && m_nCurrExLayer == HOVEROPTION_LIST)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
+ m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN;
+ }
+ }
+ // what??
+ if (m_nHoverOption == HOVEROPTION_SKIN) {
+ if (i == m_nSelectedListRow) {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ m_bWaitingForNewKeyBind = true;
+ m_bStartWaitingForKeyBind = true;
+ pControlEdit = &m_KeyPressedCode;
+ }
+ } else
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
+ }
+ if (m_nSelectedListRow != 35)
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ else if (m_nCurrExLayer == HOVEROPTION_LIST)
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+
+ CFont::SetRightJustifyOff();
+ if (m_PrefsLanguage != LANGUAGE_GERMAN || i != 20 && i != 21)
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
+ else
+ CFont::SetScale(MENU_X(0.32f), MENU_Y(SMALLESTTEXT_Y_SCALE));
+
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText);
+ }
+ DrawControllerBound(yStart, MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), rowHeight, CONTSETUP_PED_COLUMN);
+ DrawControllerBound(yStart, MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), rowHeight, CONTSETUP_VEHICLE_COLUMN);
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y));
+
+ if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM)
+ && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - CONTSETUP_BACK_HEIGHT)) || m_nCurrExLayer == HOVEROPTION_BACK) {
+ m_nHoverOption = HOVEROPTION_BACK;
+
+ } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)
+ && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM + 5.0f)) {
+ m_nHoverOption = HOVEROPTION_LIST;
+
+ } else {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
+
+ // Back button and it's shadow
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y));
+ CFont::SetRightJustifyOn();
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
+ for (int i = 0; i < 2; i++) {
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f - i),
+ SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f - i), TheText.Get("FEDS_TB"));
+
+ if (m_nHoverOption == HOVEROPTION_BACK)
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+ else
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ }
}
-#endif
-void CMenuManager::DrawFrontEnd()
+void
+CMenuManager::DrawFrontEnd()
{
CFont::SetAlphaFade(255.0f);
@@ -1251,7 +1977,8 @@ void CMenuManager::DrawFrontEnd()
}
#ifdef PS2_SAVE_DIALOG
-void CMenuManager::DrawFrontEndSaveZone()
+void
+CMenuManager::DrawFrontEndSaveZone()
{
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
@@ -1263,7 +1990,7 @@ void CMenuManager::DrawFrontEndSaveZone()
m_nMenuFadeAlpha = 255;
RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- CMenuManager::Draw();
+ Draw();
CFont::DrawFonts();
@@ -1294,7 +2021,8 @@ void CMenuManager::DrawFrontEndSaveZone()
#endif
#ifdef PS2_LIKE_MENU
-void CMenuManager::DrawFrontEndNormal()
+void
+CMenuManager::DrawFrontEndNormal()
{
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
@@ -1370,13 +2098,11 @@ void CMenuManager::DrawFrontEndNormal()
reverseAlpha = false;
ChangeScreen(pendingScreen, pendingOption, true, false);
} else {
- float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
-
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
if (!reverseAlpha)
- fadeAlpha += (timestep * 100.f) * 20.f / 33.f;
+ fadeAlpha += (frameTime) * 20.f / 33.f;
else
- fadeAlpha = max(0.0f, fadeAlpha - (timestep * 100.f) * 30.f / 33.f);
+ fadeAlpha = max(0.0f, fadeAlpha - (frameTime) * 30.f / 33.f);
m_nMenuFadeAlpha = fadeAlpha;
}
@@ -1385,8 +2111,7 @@ void CMenuManager::DrawFrontEndNormal()
if (lastState == 0) fadeAlpha = 255.f;
if (reverseAlpha) {
- float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
- fadeAlpha -= (timestep * 100.f) * 30.f / 33.f;
+ fadeAlpha -= (frameTime) * 30.f / 33.f;
m_nMenuFadeAlpha = fadeAlpha;
}
@@ -1408,18 +2133,18 @@ void CMenuManager::DrawFrontEndNormal()
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
switch (m_nCurrScreen) {
case MENUPAGE_SKIN_SELECT:
- CMenuManager::DrawPlayerSetupScreen();
+ DrawPlayerSetupScreen();
break;
case MENUPAGE_KEYBOARD_CONTROLS:
- CMenuManager::DrawControllerSetupScreen();
+ DrawControllerSetupScreen();
break;
default:
- CMenuManager::Draw();
+ Draw();
break;
}
#define optionWidth MENU_X(66.0f)
- #define rawOptionHeight 20.0f
+ #define rawOptionHeight 22.0f
#define optionBottom SCREEN_SCALE_FROM_BOTTOM(20.0f)
#define optionTop SCREEN_SCALE_FROM_BOTTOM(20.0f + rawOptionHeight)
#define leftPadding MENU_X_LEFT_ALIGNED(90.0f)
@@ -1427,7 +2152,7 @@ void CMenuManager::DrawFrontEndNormal()
hoveredBottomBarOption = -1;
if (curBottomBarOption != -1) {
- // This active tab sprite is weird...
+ // This active tab sprite is needlessly big
m_aFrontEndSprites[FE2_TABACTIVE].Draw(CRect(leftPadding - MENU_X(2.0f) + (optionWidth) * curBottomBarOption, optionTop,
leftPadding - MENU_X(5.0f) + optionWidth * (curBottomBarOption + 2), optionBottom + MENU_Y(rawOptionHeight - 9.0f)),
CRGBA(CRGBA(255, 255, 255, 255)));
@@ -1488,7 +2213,8 @@ void CMenuManager::DrawFrontEndNormal()
}
}
#else
-void CMenuManager::DrawFrontEndNormal()
+void
+CMenuManager::DrawFrontEndNormal()
{
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
@@ -1594,10 +2320,8 @@ void CMenuManager::DrawFrontEndNormal()
static float fadeAlpha = 0.0f;
if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f;
- float timestep = CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
-
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
- fadeAlpha += (timestep * 100.f) * 20.f / 33.f;
+ fadeAlpha += (frameTime) * 20.f / 33.f;
m_nMenuFadeAlpha = fadeAlpha;
#else
static uint32 LastFade = 0;
@@ -1642,13 +2366,13 @@ void CMenuManager::DrawFrontEndNormal()
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
switch (m_nCurrScreen) {
case MENUPAGE_SKIN_SELECT:
- CMenuManager::DrawPlayerSetupScreen();
+ DrawPlayerSetupScreen();
break;
case MENUPAGE_KEYBOARD_CONTROLS:
- CMenuManager::DrawControllerSetupScreen();
+ DrawControllerSetupScreen();
break;
default:
- CMenuManager::Draw();
+ Draw();
break;
}
@@ -1680,19 +2404,421 @@ void CMenuManager::DrawFrontEndNormal()
}
#endif
-#if 1
-WRAPPER void CMenuManager::DrawPlayerSetupScreen() { EAXJMP(0x47F2B0); }
-#else
-void CMenuManager::DrawPlayerSetupScreen()
+void
+CMenuManager::DrawPlayerSetupScreen()
{
+ CFont::SetBackgroundOff();
+ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
+ CFont::SetPropOn();
+ CFont::SetCentreOff();
+ CFont::SetJustifyOn();
+ CFont::SetRightJustifyOff();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
+ CFont::SetRightJustifyWrap(SCREEN_SCALE_X(MENUACTION_WIDTH));
-}
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
+ CFont::SetRightJustifyOn();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS"));
+
+ // lstrcpy's changed with strcpy
+
+ if (!m_bSkinsEnumerated) {
+ OutputDebugString("Enumerating skin filenames from skins...");
+ m_pSkinListHead.nextSkin = nil;
+ m_pSelectedSkin = &m_pSkinListHead;
+ m_pSelectedSkin->nextSkin = new tSkinInfo;
+ m_pSelectedSkin = m_pSelectedSkin->nextSkin;
+ m_pSelectedSkin->skinId = 0;
+ strcpy(m_pSelectedSkin->skinNameOriginal, "$$\"\"");
+ strcpy(m_pSelectedSkin->skinNameDisplayed, UnicodeToAscii(TheText.Get("FET_DSN")));
+ int nextSkinId = 1;
+ m_pSelectedSkin->nextSkin = nil;
+
+ WIN32_FIND_DATA FindFileData;
+ SYSTEMTIME SystemTime;
+ HANDLE handle = FindFirstFile("skins\\*.bmp", &FindFileData);
+ for (int i = 1; handle != INVALID_HANDLE_VALUE && i; i = FindNextFile(handle, &FindFileData)) {
+ if (strncmp(FindFileData.cFileName, "$$\"\"", 5) != 0) {
+ m_pSelectedSkin->nextSkin = new tSkinInfo;
+ m_pSelectedSkin = m_pSelectedSkin->nextSkin;
+ m_pSelectedSkin->skinId = nextSkinId;
+ strcpy(m_pSelectedSkin->skinNameOriginal, FindFileData.cFileName);
+ strcpy(m_pSelectedSkin->skinNameDisplayed, FindFileData.cFileName);
+ FileTimeToSystemTime(&FindFileData.ftLastWriteTime, &SystemTime);
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &SystemTime, 0, m_pSelectedSkin->date, 255);
+ ++nextSkinId;
+ m_pSelectedSkin->nextSkin = nil;
+ }
+ }
+ FindClose(handle);
+ m_nSkinsTotal = nextSkinId;
+ char nameTemp[256];
+ for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin; m_pSelectedSkin = m_pSelectedSkin->nextSkin) {
+ // Drop extension
+ int oldLength = strlen(m_pSelectedSkin->skinNameDisplayed);
+ m_pSelectedSkin->skinNameDisplayed[oldLength - 4] = '\0';
+ m_pSelectedSkin->skinNameOriginal[oldLength - 4] = '\0';
+
+ // Fill to 40 bytes-39 chars, idk why. This is done in sepearate function in game.
+ strncpy(nameTemp, m_pSelectedSkin->skinNameDisplayed, 39); // game doesn't do that, but in our day strncpy to same string is forbidden
+ strncpy(m_pSelectedSkin->skinNameDisplayed, nameTemp, 39);
+ if (oldLength - 4 > 39)
+ m_pSelectedSkin->skinNameDisplayed[39] = '\0';
+
+ // Make string lowercase, except first letter
+ strlwr(m_pSelectedSkin->skinNameDisplayed);
+ strncpy(nameTemp, m_pSelectedSkin->skinNameDisplayed, 1);
+ strupr(nameTemp);
+ strncpy(m_pSelectedSkin->skinNameDisplayed, nameTemp, 1);
+
+ // Change some chars
+#ifdef FIX_BUGS
+ for (int k = 0; m_pSelectedSkin->skinNameDisplayed[k] != '\0'; ++k) {
+#else
+ for (int k = 0; m_pSelectedSkin->skinNameOriginal[k] != '\0'; ++k) {
#endif
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "_", 1))
+ strncpy(&m_pSelectedSkin->skinNameDisplayed[k], " ", 1);
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "@", 1))
+ strncpy(&m_pSelectedSkin->skinNameDisplayed[k], " ", 1);
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "{", 1))
+ strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "(", 1);
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "}", 1))
+ strncpy(&m_pSelectedSkin->skinNameDisplayed[k], ")", 1);
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "£", 1))
+ strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "$", 1);
+ }
-#if 0
-WRAPPER int CMenuManager::FadeIn(int alpha) { EAXJMP(0x48AC60); }
+ // Make letters after whitespace uppercase
+ for (int l = 0; m_pSelectedSkin->skinNameDisplayed[l] != '\0'; ++l) {
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[l], " ", 1)) {
+ if (m_pSelectedSkin->skinNameDisplayed[l + 1]) {
+ strncpy(nameTemp, &m_pSelectedSkin->skinNameDisplayed[l + 1], 1);
+ strupr(nameTemp);
+ strncpy(&m_pSelectedSkin->skinNameDisplayed[l + 1], nameTemp, 1);
+ }
+ }
+ }
+ }
+ OutputDebugString("Finished enumerating skin files.");
+ m_bSkinsEnumerated = true;
+ }
+ CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP),
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(200, 200, 50, FadeIn(50)));
+
+ // Header (Skin - Date)
+ if (m_nCurrExLayer == HOVEROPTION_LIST) {
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+ } else {
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ }
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_DATE_COLUMN_RIGHT), MENU_Y(PLAYERSETUP_LIST_TOP), TheText.Get("FES_DAT"));
+ switch (m_PrefsLanguage) {
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_SPANISH:
+ CFont::SetScale(MENU_X(0.6f), MENU_Y(MENUACTION_SCALE_MULT));
+ break;
+ default:
+ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
+ break;
+ }
+ CFont::SetRightJustifyOff();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(PLAYERSETUP_SKIN_COLUMN_LEFT), MENU_Y(PLAYERSETUP_LIST_TOP), TheText.Get("FES_SKN"));
+
+ // Skin list
+ CFont::SetRightJustifyOff();
+ CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE));
+ CFont::SetFontStyle(FONT_BANK);
+ if (m_nSkinsTotal > 0) {
+ for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList;
+ m_pSelectedSkin = m_pSelectedSkin->nextSkin);
+
+ int rowTextY = PLAYERSETUP_LIST_BODY_TOP - 1;
+ int orderInVisibles = 0;
+ int rowEndY = PLAYERSETUP_LIST_BODY_TOP + PLAYERSETUP_ROW_HEIGHT + 1;
+ int rowStartY = PLAYERSETUP_LIST_BODY_TOP;
+ for (int rowIdx = m_nFirstVisibleRowOnList;
+ rowIdx < m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW && m_pSelectedSkin; ) {
+
+ if (m_nMousePosX > MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT) && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT)) {
+ if (m_nMousePosY > MENU_Y(rowStartY) && m_nMousePosY < MENU_Y(rowEndY)) {
+ m_nPrevOption = rowIdx;
+ if (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY) {
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ }
+ if (m_nHoverOption == HOVEROPTION_SKIN) {
+ if (rowIdx == m_nSelectedListRow) {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ if (m_nSkinsTotal > 0) {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
+ strcpy(m_PrefsSkinFile, m_aSkinName);
+ CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
+ SaveSettings();
+ }
+ } else {
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_nSelectedListRow = rowIdx;
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
+ }
+ }
+ }
+
+ // Preview skin/change color of row when we focused on another row.
+ if (orderInVisibles == m_nSelectedListRow - m_nFirstVisibleRowOnList) {
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
+ static int lastSelectedSkin = -1;
+ if (m_nSelectedListRow != lastSelectedSkin) {
+ strcpy(m_aSkinName, m_pSelectedSkin->skinNameOriginal);
+ CWorld::Players[0].SetPlayerSkin(m_aSkinName);
+ }
+ lastSelectedSkin = m_nSelectedListRow;
+ } else if (!strcmp(m_PrefsSkinFile, m_pSelectedSkin->skinNameOriginal)) {
+ CFont::SetColor(CRGBA(255, 255, 155, FadeIn(255)));
+ } else {
+ CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255)));
+ }
+ wchar unicodeTemp[80];
+ AsciiToUnicode(m_pSelectedSkin->skinNameDisplayed, unicodeTemp);
+ CFont::SetRightJustifyOff();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(PLAYERSETUP_SKIN_COLUMN_LEFT), MENU_Y(rowTextY), unicodeTemp);
+
+ // If not "Default skin" option
+ if (rowIdx != 0) {
+ char dateTemp[32];
+ sprintf(dateTemp, "%s", m_pSelectedSkin->date);
+ AsciiToUnicode(dateTemp, unicodeTemp);
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_DATE_COLUMN_RIGHT), MENU_Y(rowTextY), unicodeTemp);
+ }
+ ++orderInVisibles;
+ rowEndY += PLAYERSETUP_ROW_HEIGHT;
+ rowStartY += PLAYERSETUP_ROW_HEIGHT;
+ rowTextY += PLAYERSETUP_ROW_HEIGHT;
+ ++rowIdx;
+ m_pSelectedSkin = m_pSelectedSkin->nextSkin;
+ }
+ // Scrollbar background
+ CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(100, 100, 66, FadeIn(205)));
+
+ // Scrollbar
+ float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal * (float) MAX_VISIBLE_LIST_ROW;
+ float scrollbarBottom, scrollbarTop;
+ if (m_nSkinsTotal <= MAX_VISIBLE_LIST_ROW) {
+ scrollbarBottom = SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 4.0f);
+ scrollbarTop = MENU_Y(PLAYERSETUP_LIST_BODY_TOP);
+
+ // Shadow
+ CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop,
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255)));
+ } else {
+#ifdef FIX_BUGS
+ scrollbarBottom = MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 8 + m_nScrollbarTopMargin + scrollbarHeight);
+ scrollbarTop = MENU_Y(PLAYERSETUP_LIST_BODY_TOP + m_nScrollbarTopMargin);
+#else
+ scrollbarBottom = MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 4 + m_nScrollbarTopMargin + scrollbarHeight - SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal);
+ scrollbarTop = MENU_Y(SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal + PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin);
+#endif
+ // Shadow
+ CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop,
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)),
+ CRGBA(50, 50, 50, FadeIn(255)));
+
+ }
+ CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop,
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom),
+ CRGBA(235, 170, 50, FadeIn(255)));
+
+ // FIX: Scroll button dimensions are buggy, because:
+ // 1 - stretches the original image
+ // 2 - leaves gap between button and scrollbar
+ if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP) {
+#ifdef FIX_BUGS
+ m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
+ CRGBA(255, 255, 255, FadeIn(255)));
+#else
+ m_aMenuSprites[MENUSPRITE_UPON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP),
+ MENU_X_RIGHT_ALIGNED(-20.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)),
+ CRGBA(255, 255, 255, FadeIn(255)));
+#endif
+ } else {
+#ifdef FIX_BUGS
+ m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP),
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), MENU_Y(PLAYERSETUP_LIST_TOP + PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
+ CRGBA(255, 255, 255, FadeIn(255)));
+#else
+ m_aMenuSprites[MENUSPRITE_UPOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), MENU_Y(PLAYERSETUP_LIST_TOP),
+ MENU_X_RIGHT_ALIGNED(-21.0f), MENU_Y(PLAYERSETUP_LIST_TOP + 58)),
+ CRGBA(255, 255, 255, FadeIn(255)));
+#endif
+ }
+
+ if (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN) {
+#ifdef FIX_BUGS
+ m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1),
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
+ CRGBA(255, 255, 255, FadeIn(255)));
+#else
+ m_aMenuSprites[MENUSPRITE_DOWNON].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), SCREEN_SCALE_FROM_BOTTOM(141.0f),
+ MENU_X_RIGHT_ALIGNED(-20.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)),
+ CRGBA(255, 255, 255, FadeIn(255)));
+#endif
+ } else {
+#ifdef FIX_BUGS
+ m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1),
+ MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1 - PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION)),
+ CRGBA(255, 255, 255, FadeIn(255)));
#else
-int CMenuManager::FadeIn(int alpha)
+ m_aMenuSprites[MENUSPRITE_DOWNOFF].Draw(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3), SCREEN_SCALE_FROM_BOTTOM(141.0f),
+ MENU_X_RIGHT_ALIGNED(-21.0f), SCREEN_SCALE_FROM_BOTTOM(83.0f)),
+ CRGBA(255, 255, 255, FadeIn(255)));
+#endif
+
+ }
+ CPlayerSkin::RenderFrontendSkinEdit();
+
+ // Big apply button
+ if (strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
+ CFont::SetFontStyle(FONT_HEADING);
+ switch (m_PrefsLanguage) {
+ case LANGUAGE_FRENCH:
+ CFont::SetScale(MENU_X(1.1f), MENU_Y(1.9f));
+ break;
+ case LANGUAGE_GERMAN:
+ CFont::SetScale(MENU_X(0.85f), MENU_Y(1.9f));
+ break;
+ case LANGUAGE_ITALIAN:
+ case LANGUAGE_SPANISH:
+ CFont::SetScale(MENU_X(1.4f), MENU_Y(1.9f));
+ break;
+ default:
+ CFont::SetScale(MENU_X(1.9f), MENU_Y(1.9f));
+ break;
+ }
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(120)));
+ CFont::SetRightJustifyOff();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(20.0f), MENU_Y(220.0f), TheText.Get("FET_APL"));
+ }
+ CFont::SetFontStyle(FONT_HEADING);
+
+ CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE));
+
+ if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1)
+ && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 3)
+ && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 26))
+ || m_nCurrExLayer == HOVEROPTION_BACK) {
+ if (m_nHoverOption != HOVEROPTION_BACK)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
+
+ m_nHoverOption = HOVEROPTION_BACK;
+
+ } else if ((strcmp(m_aSkinName, m_PrefsSkinFile) != 0
+ && m_nMousePosX > MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT)
+ && m_nMousePosX < MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT) + CFont::GetStringWidth(TheText.Get("FES_SET"), true)
+ && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 3)
+ && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 26))
+ || m_nCurrExLayer == HOVEROPTION_USESKIN) {
+ if (m_nHoverOption != HOVEROPTION_USESKIN)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
+
+ m_nHoverOption = HOVEROPTION_USESKIN;
+
+ } else if (m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH - 2)
+ && m_nMousePosY > MENU_Y(PLAYERSETUP_LIST_TOP)
+ && m_nMousePosY < MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 3)) {
+ if (m_nHoverOption != HOVEROPTION_CLICKED_SCROLL_UP && m_nHoverOption != HOVEROPTION_CLICKED_SCROLL_DOWN)
+ m_nHoverOption = HOVEROPTION_OVER_SCROLL_UP;
+
+ } else if (m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH - 2)
+ && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1)
+ && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)) {
+ if (m_nHoverOption != HOVEROPTION_CLICKED_SCROLL_UP && m_nHoverOption != HOVEROPTION_CLICKED_SCROLL_DOWN)
+ m_nHoverOption = HOVEROPTION_OVER_SCROLL_DOWN;
+
+ } else if (m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH - 2)
+ && m_nMousePosY > MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 3)
+#ifdef FIX_BUGS
+ && m_nMousePosY < MENU_Y(PLAYERSETUP_LIST_BODY_TOP + m_nScrollbarTopMargin)) {
+#else
+ && m_nMousePosY < MENU_Y(SCROLLBAR_MAX_HEIGHT / m_nTotalListRow + PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin)) {
+#endif
+ m_nHoverOption = HOVEROPTION_PAGEUP;
+
+ } else if (m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH - 2)
+#ifdef FIX_BUGS
+ && m_nMousePosY > MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 8 + m_nScrollbarTopMargin + scrollbarHeight)
+#else
+ && m_nMousePosY > MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin + scrollbarHeight - SCROLLBAR_MAX_HEIGHT / m_nTotalListRow)
+#endif
+ && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 1)) {
+ m_nHoverOption = HOVEROPTION_PAGEDOWN;
+
+ } else if (m_nMousePosX > MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4)
+ && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH)
+#ifdef FIX_BUGS
+ && m_nMousePosY > MENU_Y(PLAYERSETUP_LIST_BODY_TOP + m_nScrollbarTopMargin)
+ && m_nMousePosY < MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 8 + m_nScrollbarTopMargin + scrollbarHeight)) {
+#else
+ && m_nMousePosY > MENU_Y(SCROLLBAR_MAX_HEIGHT / m_nTotalListRow + PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin)
+ && m_nMousePosY < MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin + scrollbarHeight - SCROLLBAR_MAX_HEIGHT / m_nTotalListRow)) {
+#endif
+ m_nHoverOption = HOVEROPTION_HOLDING_SCROLLBAR;
+
+ } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(PLAYERSETUP_LIST_LEFT) && m_nMousePosX < MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT)
+ && m_nMousePosY > MENU_Y(PLAYERSETUP_LIST_BODY_TOP + 1) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)) {
+ m_nHoverOption = HOVEROPTION_LIST;
+
+ } else {
+ m_nHoverOption = HOVEROPTION_NOT_HOVERING;
+ }
+ }
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE));
+ CFont::SetRightJustifyOn();
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
+
+ // Back button
+ for (int i = 0; i < 2; i++) {
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 3 - i), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FEDS_TB"));
+ if (m_nHoverOption == HOVEROPTION_BACK) {
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+ } else {
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ }
+ }
+ CFont::SetRightJustifyOff();
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(90)));
+
+ // Use skin button
+ for (int i = 0; i < 2; i++) {
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(i + PLAYERSETUP_LIST_LEFT), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM - 5 - i), TheText.Get("FES_SET"));
+ if (!strcmp(m_aSkinName, m_PrefsSkinFile)) {
+ CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255)));
+ } else if (m_nHoverOption == HOVEROPTION_USESKIN) {
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+ } else {
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ }
+ }
+
+}
+
+int
+CMenuManager::FadeIn(int alpha)
{
if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS ||
m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS ||
@@ -1701,27 +2827,57 @@ int CMenuManager::FadeIn(int alpha)
return min(m_nMenuFadeAlpha, alpha);
}
-#endif
-#if 1
-WRAPPER void CMenuManager::FilterOutColorMarkersFromString(uint16, CRGBA &) { EAXJMP(0x4889C0); }
-#else
-void CMenuManager::FilterOutColorMarkersFromString(uint16, CRGBA &)
+void
+CMenuManager::FilterOutColorMarkersFromString(wchar *str, CRGBA &newColor)
{
-
+ int newIdx = 0;
+ wchar copy[256], *c;
+ UnicodeStrcpy(copy, str);
+
+ for (c = copy; *c != '\0'; c++) {
+ if (*c == '~') {
+ c++;
+ switch (*c) {
+ case 'b': newColor = CRGBA(40, 40, 255, 255); break;
+ case 'g': newColor = CRGBA(40, 235, 40, 255); break;
+ // There is no case for "h", is that a mistake?
+ case 'l': newColor = CRGBA(0, 0, 0, 255); break;
+ case 'p': newColor = CRGBA(255, 0, 255, 255); break;
+ case 'r': newColor = CRGBA(255, 0, 0, 255); break;
+ case 'w': newColor = CRGBA(255, 255, 255, 255); break;
+ case 'y': newColor = CRGBA(255, 255, 0, 255); break;
+ }
+ while (*c != '~') c++;
+ } else {
+ str[newIdx++] = *c;
+ }
+ }
+ str[newIdx] = '\0';
}
-#endif
-#if 1
-WRAPPER int CMenuManager::GetStartOptionsCntrlConfigScreens() { EAXJMP(0x489270); }
-#else
-int CMenuManager::GetStartOptionsCntrlConfigScreens()
+int
+CMenuManager::GetStartOptionsCntrlConfigScreens()
{
-
+ int number = 0;
+ switch (m_nCurrScreen) {
+ case MENUPAGE_CONTROLLER_PC_OLD3:
+ number = 34;
+ break;
+ case MENUPAGE_CONTROLLER_DEBUG:
+ number = 35;
+ break;
+ case MENUPAGE_KEYBOARD_CONTROLS:
+ number = 0;
+ break;
+ default:
+ break;
+ }
+ return number;
}
-#endif
-void CMenuManager::InitialiseChangedLanguageSettings()
+void
+CMenuManager::InitialiseChangedLanguageSettings()
{
if (m_bFrontEnd_ReloadObrTxtGxt) {
m_bFrontEnd_ReloadObrTxtGxt = false;
@@ -1732,7 +2888,7 @@ void CMenuManager::InitialiseChangedLanguageSettings()
CGame::frenchGame = false;
CGame::germanGame = false;
#ifdef MORE_LANGUAGES
- switch (CMenuManager::m_PrefsLanguage) {
+ switch (m_PrefsLanguage) {
case LANGUAGE_RUSSIAN:
CFont::ReloadFonts(FONT_LANGSET_RUSSIAN);
break;
@@ -1745,7 +2901,7 @@ void CMenuManager::InitialiseChangedLanguageSettings()
}
#endif
- switch (CMenuManager::m_PrefsLanguage) {
+ switch (m_PrefsLanguage) {
case LANGUAGE_FRENCH:
CGame::frenchGame = true;
break;
@@ -1763,22 +2919,23 @@ void CMenuManager::InitialiseChangedLanguageSettings()
}
}
-void CMenuManager::LoadAllTextures()
+void
+CMenuManager::LoadAllTextures()
{
if (m_bSpritesLoaded)
return;
- CMenuManager::CentreMousePointer();
+ CentreMousePointer();
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
m_nCurrOption = 0;
m_PrefsRadioStation = DMAudio.GetRadioInCar();
if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (CMenuManager::m_PrefsRadioStation > USERTRACK)
- CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
- } else if (CMenuManager::m_PrefsRadioStation > CHATTERBOX)
- CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
+ if (m_PrefsRadioStation > USERTRACK)
+ m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
+ } else if (m_PrefsRadioStation > CHATTERBOX)
+ m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
CFileMgr::SetDir("");
//CFileMgr::SetDir("");
@@ -1818,14 +2975,18 @@ void CMenuManager::LoadAllTextures()
m_aMenuSprites[i].SetTexture(MenuFilenames[i][0], MenuFilenames[i][1]);
m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
}
-
+#ifdef MENU_MAP
+ for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) {
+ m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]);
+ m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
+ }
+#endif
m_bSpritesLoaded = true;
CTxdStore::PopCurrentTxd();
}
-#if 0
-WRAPPER void CMenuManager::LoadSettings() { EAXJMP(0x488EE0); }
-#else
-void CMenuManager::LoadSettings()
+
+void
+CMenuManager::LoadSettings()
{
CFileMgr::SetDirMyDocuments();
int fileHandle = CFileMgr::OpenFile("gta3.set", "r");
@@ -1914,12 +3075,9 @@ void CMenuManager::LoadSettings()
strcpy(m_aSkinName, "$$\"\"");
}
}
-#endif
-#if 0
-WRAPPER void CMenuManager::SaveSettings() { EAXJMP(0x488CC0); }
-#else
-void CMenuManager::SaveSettings()
+void
+CMenuManager::SaveSettings()
{
static char RubbishString[48] = "stuffmorestuffevenmorestuff etc";
@@ -1962,44 +3120,117 @@ void CMenuManager::SaveSettings()
CFileMgr::CloseFile(fileHandle);
CFileMgr::SetDir("");
}
-#endif
-#if 1
-WRAPPER void CMenuManager::MessageScreen(char *) { EAXJMP(0x48B7E0); }
-#else
-void CMenuManager::MessageScreen(char *)
+bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
+void DoRWStuffEndOfFrame(void);
+
+void
+CMenuManager::MessageScreen(const char *text)
{
+ CSprite2d *splash = LoadSplash(nil);
+ if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
+ return;
+
+ CSprite2d::SetRecipNearClip();
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ DefinedState();
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
+ splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
+
+ CFont::SetBackgroundOff();
+ CFont::SetPropOn();
+ CFont::SetJustifyOn();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
+ CFont::SetRightJustifyWrap(SCREEN_SCALE_FROM_RIGHT(170.0f));
+ CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_SCALE_FROM_BOTTOM(220.0f)), CRGBA(50, 50, 50, 210));
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetCentreSize(SCREEN_SCALE_X(380.0f));
+ CFont::SetCentreOn();
+ CFont::SetColor(CRGBA(255, 217, 106, 255));
+ CFont::SetScale(SCREEN_SCALE_X(SMALLTEXT_X_SCALE), SCREEN_SCALE_Y(SMALLTEXT_Y_SCALE));
+ CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(170.0f), TheText.Get(text));
+ CFont::DrawFonts();
+ DoRWStuffEndOfFrame();
}
-#endif
-#if 1
-WRAPPER void CMenuManager::PickNewPlayerColour() { EAXJMP(0x488C40); }
-#else
-void CMenuManager::PickNewPlayerColour()
+void
+CMenuManager::PickNewPlayerColour()
{
-
+ m_PrefsPlayerRed = 0;
+ m_PrefsPlayerGreen = 0;
+ m_PrefsPlayerBlue = 0;
+ while (true) {
+ int sum = m_PrefsPlayerRed + m_PrefsPlayerGreen + m_PrefsPlayerBlue;
+ if (sum >= 100 && sum <= 650)
+ break;
+ m_PrefsPlayerRed = CGeneral::GetRandomNumber();
+ m_PrefsPlayerGreen = CGeneral::GetRandomNumber();
+ m_PrefsPlayerBlue = CGeneral::GetRandomNumber();
+ }
}
-#endif
-#if 1
-WRAPPER void CMenuManager::PrintBriefs() { EAXJMP(0x484D60); }
-#else
-void CMenuManager::PrintBriefs()
+void
+CMenuManager::PrintBriefs()
{
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetRightJustifyOff();
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why
+
+ float nextY = 40.0f;
+ CRGBA newColor;
+ for (int i = 4; i >= 0; i--) {
+ tPreviousBrief &brief = CMessages::PreviousBriefs[i];
+ if (brief.m_pText) {
+ CMessages::InsertNumberInString(brief.m_pText,
+ brief.m_nNumber[0], brief.m_nNumber[1],
+ brief.m_nNumber[2], brief.m_nNumber[3],
+ brief.m_nNumber[4], brief.m_nNumber[5], gUString);
+ CMessages::InsertStringInString(gUString, brief.m_pString);
+ CMessages::InsertPlayerControlKeysInString(gUString);
+ newColor = TEXT_COLOR;
+ FilterOutColorMarkersFromString(gUString, newColor);
-}
+#ifdef PS2_LIKE_MENU
+ // This PS2 code was always here, but unused
+ bool rgSame = newColor.r == TEXT_COLOR.r && newColor.g == TEXT_COLOR.g;
+ bool bSame = rgSame && newColor.b == TEXT_COLOR.b;
+ bool colorNotChanged = bSame; /* && newColor.a == TEXT_COLOR.a; */
+
+ if (!colorNotChanged) {
+ newColor.r /= 2;
+ newColor.g /= 2;
+ newColor.b /= 2;
+ }
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // But this is from PS2
+ CFont::SetDropShadowPosition(1);
#endif
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER void CMenuManager::PrintErrorMessage() { EAXJMP(0x484F70); }
-#else
-void CMenuManager::PrintErrorMessage()
+#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU)
+ newColor.a = FadeIn(255);
+ CFont::SetColor(newColor);
+#endif
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(50.0f), nextY, gUString);
+ nextY += MENU_Y(menuXYpadding);
+ }
+ }
+
+#ifdef PS2_LIKE_MENU
+ CFont::SetDropShadowPosition(0);
+#endif
+}
+
+// Not sure about name. Not to be confused with CPad::PrintErrorMessage
+void
+CMenuManager::PrintErrorMessage()
{
if (!CPad::bDisplayNoControllerMessage && !CPad::bObsoleteControllerMessage)
return;
- CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(140.0f), SCREEN_WIDTH - SCREEN_SCALE_X(20.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(140.0f)), CRGBA(64, 16, 16, 224));
+ CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(140.0f), SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f)), CRGBA(64, 16, 16, 224));
CFont::SetFontStyle(FONT_BANK);
CFont::SetBackgroundOff();
CFont::SetPropOn();
@@ -2007,36 +3238,106 @@ void CMenuManager::PrintErrorMessage()
CFont::SetJustifyOn();
CFont::SetRightJustifyOff();
CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(SCREEN_WIDTH - 40.0f);
- CFont::SetColor(CRGBA(165, 165, 165, 255));
- CFont::SetScale(SCREEN_SCALE_X(0.9f), SCREEN_SCALE_Y(0.9f));
- CFont::PrintString(SCREEN_SCALE_X(40.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(60.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT"));
+ CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f));
+#ifdef FIX_BUGS
+ CFont::PrintString(SCREEN_SCALE_X(50.0f), SCREEN_SCALE_Y(180.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT"));
+#else
+ CFont::PrintString(SCREEN_SCALE_X(50.0f), SCREEN_SCALE_Y(40.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT"));
+#endif
CFont::DrawFonts();
}
-#endif
-#if 1
-WRAPPER void CMenuManager::PrintStats() { EAXJMP(0x482100); }
-#else
-void CMenuManager::PrintStats()
+void
+CMenuManager::PrintStats()
{
+ int rowNum = ConstructStatLine(99999);
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X * 0.7), MENU_Y(MENU_TEXT_SIZE_Y * 0.9)); // second mulipliers are double, idk why
+ float nextYChange, y, alphaMult;
+
+ // Scroll stats with mouse
+#ifdef SCROLLABLE_STATS_PAGE
+ static float scrollY = 0;
+ static uint32 lastChange = m_nScreenChangeDelayTimer;
+ if (CPad::GetPad(0)->GetLeftMouse()) {
+ scrollY += (m_nMouseOldPosY - m_nMousePosY);
+ lastChange = CTimer::GetTimeInMillisecondsPauseMode();
+ } else {
+ scrollY += MENU_Y(STATS_SLIDE_Y_PER_SECOND) / 1000.0f * (CTimer::GetTimeInMillisecondsPauseMode() - lastChange);
+ lastChange = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+#else
+ // MENU_Y(30.0f) per second
+ float scrollY = MENU_Y(STATS_SLIDE_Y_PER_SECOND) * (CTimer::GetTimeInMillisecondsPauseMode() - m_nScreenChangeDelayTimer) / 1000.0f;
+#endif
+
+ for (int row = 0; row < rowNum; ++row) {
+ // Put just got hidden text at the top back to the bottom, in circular fashion
+ for (y = MENU_Y(STATS_ROW_HEIGHT - 1) * row + SCREEN_HEIGHT - scrollY; MENU_Y(STATS_PUT_BACK_TO_BOTTOM_Y) > y; y += nextYChange) {
+ nextYChange = (MENU_Y(STATS_ROW_HEIGHT) + rowNum) * MENU_Y(STATS_ROW_HEIGHT - 1);
+ }
+
+ // If it's still on screen
+ if (y > 0.0f && SCREEN_HEIGHT > y) {
+ ConstructStatLine(row);
+ // But about to dim from top
+ if (y - MENU_Y(STATS_BOTTOM_MARGIN) < MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH)) {
+ if ((y - MENU_Y(STATS_BOTTOM_MARGIN)) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH) < 0.0f)
+ alphaMult = 0.0f;
+ else
+ alphaMult = (y - MENU_Y(STATS_BOTTOM_MARGIN)) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH);
+
+ // About to dim from bottom
+ } else if (y > SCREEN_SCALE_FROM_BOTTOM(STATS_TOP_DIMMING_AREA_LENGTH) - MENU_Y(STATS_BOTTOM_DIMMING_AREA_LENGTH)) {
+ if ((SCREEN_SCALE_FROM_BOTTOM(STATS_BOTTOM_DIMMING_AREA_LENGTH) - y) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH) < 0.0f)
+ alphaMult = 0.0f;
+ else
+ alphaMult = (SCREEN_SCALE_FROM_BOTTOM(STATS_BOTTOM_DIMMING_AREA_LENGTH) - y) / MENU_Y(STATS_TOP_DIMMING_AREA_LENGTH);
+ } else
+ alphaMult = 1.0f;
+
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255.0f * alphaMult)));
+ CFont::SetRightJustifyOff();
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString);
+ CFont::SetRightJustifyOn();
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(STATS_ROW_X_MARGIN), y - MENU_Y(STATS_BOTTOM_MARGIN - STATS_TOP_MARGIN), gUString2);
+ }
+ }
+ // Game doesn't do that, but it's better
+ float nextX = MENU_X_LEFT_ALIGNED(STATS_RATING_X);
+
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ CFont::SetRightJustifyOff();
+ CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), TheText.Get("CRIMRA")); nextX += MENU_X(10.0f) + CFont::GetStringWidth(TheText.Get("CRIMRA"), true);
+ UnicodeStrcpy(gUString, CStats::FindCriminalRatingString());
+ CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), gUString); nextX += MENU_X(6.0f) + CFont::GetStringWidth(gUString, true);
+ sprintf(gString, "%d", CStats::FindCriminalRatingNumber());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(nextX, MENU_Y(STATS_RATING_Y), gUString);
+
+ // ::Draw already does that.
+ /*
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetRightJustifyOn();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT));
+ CFont::PrintString(MENU_X_RIGHT_ALIGNED(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
+ */
+ CFont::SetScale(MENU_X(MENU_TEXT_SIZE_X), MENU_Y(MENU_TEXT_SIZE_Y));
}
-#endif
-#if 0
-WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); }
-#else
-void CMenuManager::Process(void)
+void
+CMenuManager::Process(void)
{
m_bMenuStateChanged = false;
if (!m_bSaveMenuActive && TheCamera.GetScreenFadeStatus() != FADE_0)
return;
- m_bStartGameLoading = false;
+ m_bWantToRestart = false;
InitialiseChangedLanguageSettings();
+ // Just a hack by R* to not make game continuously resume/pause. But we it seems we can live with it.
if (CPad::GetPad(0)->GetEscapeJustDown())
RequestFrontEndStartUp();
@@ -2076,9 +3377,9 @@ void CMenuManager::Process(void)
if (m_PrefsVsyncDisp != m_PrefsVsync)
m_PrefsVsync = m_PrefsVsyncDisp;
DMAudio.Service();
- m_bStartGameLoading = true;
+ m_bWantToRestart = true;
RequestFrontEndShutDown();
- m_bLoadingSavedGame = true;
+ m_bWantToLoad = true;
b_FoundRecentSavedGameWantToLoad = true;
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
@@ -2103,8 +3404,8 @@ void CMenuManager::Process(void)
m_bStartWaitingForKeyBind = false;
else {
pControlEdit = CPad::EditCodesForControls(pControlEdit, 1);
- JoyButtonJustClicked = 0;
- MouseButtonJustClicked = 0;
+ JoyButtonJustClicked = false;
+ MouseButtonJustClicked = false;
if (CPad::GetPad(0)->GetLeftMouseJustDown())
MouseButtonJustClicked = 1;
@@ -2120,13 +3421,13 @@ void CMenuManager::Process(void)
JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown();
- int32 TypeOfControl = 0;
+ int32 TypeOfControl = KEYBOARD;
if (JoyButtonJustClicked)
- TypeOfControl = 3;
+ TypeOfControl = JOYSTICK;
if (MouseButtonJustClicked)
- TypeOfControl = 2;
+ TypeOfControl = MOUSE;
if (*pControlEdit != rsNULL)
- TypeOfControl = 0;
+ TypeOfControl = KEYBOARD;
if (!m_bKeyIsOK) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
@@ -2134,14 +3435,12 @@ void CMenuManager::Process(void)
m_bWaitingForNewKeyBind = false;
m_KeyPressedCode = -1;
m_bStartWaitingForKeyBind = false;
- }
- else if (!m_bKeyChangeNotProcessed) {
+ } else if (!m_bKeyChangeNotProcessed) {
if (*pControlEdit != rsNULL || MouseButtonJustClicked || JoyButtonJustClicked)
CheckCodesForControls(TypeOfControl);
field_535 = true;
- }
- else {
+ } else {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
for (int i = 0; i < 4; i++)
ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)m_CurrCntrlAction, (eControllerType)i);
@@ -2155,7 +3454,7 @@ void CMenuManager::Process(void)
}
}
- if ((m_nCurrScreen == MENUPAGE_13 || m_nCurrScreen == MENUPAGE_16) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) {
+ if ((m_nCurrScreen == MENUPAGE_NO_MEMORY_CARD || m_nCurrScreen == MENUPAGE_PS2_LOAD_FAILED) && CTimer::GetTimeInMillisecondsPauseMode() > field_558) {
m_nCurrScreen = m_nPrevScreen;
m_nCurrOption = 0;
}
@@ -2175,16 +3474,12 @@ void CMenuManager::Process(void)
m_bWaitingForNewKeyBind = false;
}
- if (!m_bStartGameLoading) {
+ if (!m_bWantToRestart) {
if (m_bGameNotLoaded)
DMAudio.Service();
}
}
-#endif
-#if 0
-WRAPPER void CMenuManager::ProcessButtonPresses() { EAXJMP(0x4856F0); }
-#else
void
CMenuManager::ProcessButtonPresses(void)
{
@@ -2232,7 +3527,7 @@ CMenuManager::ProcessButtonPresses(void)
}
#endif
if (CPad::GetPad(0)->GetBackspaceJustDown() && m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS && !field_535) {
- if (m_nCurrExLayer == 19) {
+ if (m_nCurrExLayer == HOVEROPTION_LIST) {
m_nHoverOption = HOVEROPTION_NOT_HOVERING;
m_bWaitingForNewKeyBind = true;
m_bStartWaitingForKeyBind = true;
@@ -2258,21 +3553,21 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
m_bShowMouse = false;
switch (m_nCurrExLayer) {
- case 9:
+ case HOVEROPTION_BACK:
default:
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
break;
- case 19:
- m_nCurrExLayer = 21;
+ case HOVEROPTION_LIST:
+ m_nCurrExLayer = HOVEROPTION_USESKIN;
break;
- case 21:
- m_nCurrExLayer = 9;
+ case HOVEROPTION_USESKIN:
+ m_nCurrExLayer = HOVEROPTION_BACK;
}
- if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == 21)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) {
- m_nCurrExLayer = 9;
+ if (((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) && strcmp(m_aSkinName, m_PrefsSkinFile) == 0) {
+ m_nCurrExLayer = HOVEROPTION_BACK;
}
- if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == 21)) {
- m_nCurrExLayer = 9;
+ if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) && (m_nCurrExLayer == HOVEROPTION_USESKIN)) {
+ m_nCurrExLayer = HOVEROPTION_BACK;
}
}
@@ -2287,7 +3582,7 @@ CMenuManager::ProcessButtonPresses(void)
// Up
if (pressed) {
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
if (!m_bPressedUpOnList) {
m_bPressedUpOnList = true;
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
@@ -2309,7 +3604,7 @@ CMenuManager::ProcessButtonPresses(void)
// Down
if (pressed) {
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
if (!m_bPressedDownOnList) {
m_bPressedDownOnList = true;
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
@@ -2324,7 +3619,7 @@ CMenuManager::ProcessButtonPresses(void)
if (!CPad::GetPad(0)->GetPageUp()) {
m_bPressedPgUpOnList = false;
} else {
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
if (!m_bPressedPgUpOnList) {
m_bPressedPgUpOnList = true;
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
@@ -2336,7 +3631,7 @@ CMenuManager::ProcessButtonPresses(void)
if (!CPad::GetPad(0)->GetPageDown()) {
m_bPressedPgDnOnList = false;
} else {
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
if (!m_bPressedPgDnOnList) {
m_bPressedPgDnOnList = true;
lastTimeClickedScrollButton = CTimer::GetTimeInMillisecondsPauseMode();
@@ -2346,29 +3641,29 @@ CMenuManager::ProcessButtonPresses(void)
}
}
if (CPad::GetPad(0)->GetHome()) {
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
m_bShowMouse = false;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
m_nFirstVisibleRowOnList = 0;
}
m_nSelectedListRow = 0;
- m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
}
if (CPad::GetPad(0)->GetEnd()) {
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
m_bShowMouse = false;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
}
m_nSelectedListRow = m_nTotalListRow - 1;
- m_nCurListItemY = (LIST_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
+ m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
}
}
#ifndef TIDY_UP_PBP
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetSquareJustDown()) {
+ if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) {
m_bShowMouse = false;
goBack = true;
}
@@ -2385,10 +3680,10 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_PAGEDOWN:
PageDownList(true);
break;
- case HOVEROPTION_CHANGESKIN:
+ case HOVEROPTION_USESKIN:
if (m_nSkinsTotal > 0) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- m_pSelectedSkin = m_sSkin.field_304;
+ m_pSelectedSkin = m_pSkinListHead.nextSkin;
strcpy(m_PrefsSkinFile, m_aSkinName);
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
SaveSettings();
@@ -2404,8 +3699,8 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_OVER_SCROLL_DOWN:
m_nHoverOption = HOVEROPTION_CLICKED_SCROLL_DOWN;
break;
- case HOVEROPTION_19:
- m_nHoverOption = HOVEROPTION_20;
+ case HOVEROPTION_LIST:
+ m_nHoverOption = HOVEROPTION_SKIN;
}
} else if ((CPad::GetPad(0)->GetLeftMouseJustUp())
&& ((m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_UP || (m_nHoverOption == HOVEROPTION_CLICKED_SCROLL_DOWN)))) {
@@ -2418,7 +3713,7 @@ CMenuManager::ProcessButtonPresses(void)
if ((m_nHoverOption == HOVEROPTION_HOLDING_SCROLLBAR) || holdingScrollBar) {
holdingScrollBar = true;
// TODO: This part is a bit hard to reverse. Not much code tho
- assert(0 && "Not done yet");
+ assert(0 && "Holding scrollbar isn't done yet");
} else {
switch (m_nHoverOption) {
case HOVEROPTION_OVER_SCROLL_UP:
@@ -2447,7 +3742,7 @@ CMenuManager::ProcessButtonPresses(void)
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown() || CPad::GetPad(0)->GetLeftMouseJustDown()) {
optionSelected = true;
}
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetSquareJustUp()) {
+ if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustUp()) {
if (m_nCurrScreen != MENUPAGE_START_MENU) {
goBack = true;
}
@@ -2492,10 +3787,10 @@ CMenuManager::ProcessButtonPresses(void)
#ifdef TIDY_UP_PBP
if (m_nHoverOption >= HOVEROPTION_RADIO_0 && m_nHoverOption <= HOVEROPTION_RADIO_9) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = m_nHoverOption - HOVEROPTION_RADIO_0;
+ m_PrefsRadioStation = m_nHoverOption - HOVEROPTION_RADIO_0;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
} else if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM
&& aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESUME) {
@@ -2506,82 +3801,82 @@ CMenuManager::ProcessButtonPresses(void)
switch (m_nHoverOption) {
case HOVEROPTION_RADIO_0:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = HEAD_RADIO;
+ m_PrefsRadioStation = HEAD_RADIO;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_1:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = DOUBLE_CLEF;
+ m_PrefsRadioStation = DOUBLE_CLEF;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_2:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = JAH_RADIO;
+ m_PrefsRadioStation = JAH_RADIO;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_3:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = RISE_FM;
+ m_PrefsRadioStation = RISE_FM;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_4:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = LIPS_106;
+ m_PrefsRadioStation = LIPS_106;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_5:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = GAME_FM;
+ m_PrefsRadioStation = GAME_FM;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_6:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = MSX_FM;
+ m_PrefsRadioStation = MSX_FM;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_7:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = FLASHBACK;
+ m_PrefsRadioStation = FLASHBACK;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_8:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = CHATTERBOX;
+ m_PrefsRadioStation = CHATTERBOX;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_9:
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::m_PrefsRadioStation = USERTRACK;
+ m_PrefsRadioStation = USERTRACK;
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RANDOM_ITEM:
@@ -2598,74 +3893,74 @@ CMenuManager::ProcessButtonPresses(void)
#ifndef TIDY_UP_PBP
switch (m_nHoverOption) {
case HOVEROPTION_INCREASE_BRIGHTNESS:
- CMenuManager::m_PrefsBrightness = CMenuManager::m_PrefsBrightness + 32;
- if (CMenuManager::m_PrefsBrightness < 0) {
- CMenuManager::m_PrefsBrightness = 0;
+ m_PrefsBrightness = m_PrefsBrightness + 32;
+ if (m_PrefsBrightness < 0) {
+ m_PrefsBrightness = 0;
}
- if (510 < CMenuManager::m_PrefsBrightness) {
- CMenuManager::m_PrefsBrightness = 511;
+ if (510 < m_PrefsBrightness) {
+ m_PrefsBrightness = 511;
}
SaveSettings();
break;
case HOVEROPTION_DECREASE_BRIGHTNESS:
- CMenuManager::m_PrefsBrightness = CMenuManager::m_PrefsBrightness - 32;
- if (CMenuManager::m_PrefsBrightness < 0) {
- CMenuManager::m_PrefsBrightness = 0;
+ m_PrefsBrightness = m_PrefsBrightness - 32;
+ if (m_PrefsBrightness < 0) {
+ m_PrefsBrightness = 0;
}
- if (510 < CMenuManager::m_PrefsBrightness) {
- CMenuManager::m_PrefsBrightness = 511;
+ if (510 < m_PrefsBrightness) {
+ m_PrefsBrightness = 511;
}
SaveSettings();
break;
case HOVEROPTION_INCREASE_DRAWDIST:
- CMenuManager::m_PrefsLOD = CMenuManager::m_PrefsLOD + (1.0f / 16);
+ m_PrefsLOD = m_PrefsLOD + (1.0f / 16);
m_PrefsLOD = min(1.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = CMenuManager::m_PrefsLOD;
+ CRenderer::ms_lodDistScale = m_PrefsLOD;
SaveSettings();
break;
case HOVEROPTION_DECREASE_DRAWDIST:
- CMenuManager::m_PrefsLOD = CMenuManager::m_PrefsLOD - (1.0f / 16);
+ m_PrefsLOD = m_PrefsLOD - (1.0f / 16);
m_PrefsLOD = max(0.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = CMenuManager::m_PrefsLOD;
+ CRenderer::ms_lodDistScale = m_PrefsLOD;
SaveSettings();
break;
case HOVEROPTION_INCREASE_MUSICVOLUME:
- CMenuManager::m_PrefsMusicVolume = CMenuManager::m_PrefsMusicVolume + 8;
+ m_PrefsMusicVolume = m_PrefsMusicVolume + 8;
m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 127);
- DMAudio.SetMusicMasterVolume(uchar)(CMenuManager::m_PrefsMusicVolume);
+ DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
SaveSettings();
break;
case HOVEROPTION_DECREASE_MUSICVOLUME:
- CMenuManager::m_PrefsMusicVolume = CMenuManager::m_PrefsMusicVolume - 8;
- if (CMenuManager::m_PrefsMusicVolume < 0) {
- CMenuManager::m_PrefsMusicVolume = 0;
+ m_PrefsMusicVolume = m_PrefsMusicVolume - 8;
+ if (m_PrefsMusicVolume < 0) {
+ m_PrefsMusicVolume = 0;
}
- if (126 < CMenuManager::m_PrefsMusicVolume) {
- CMenuManager::m_PrefsMusicVolume = 127;
+ if (126 < m_PrefsMusicVolume) {
+ m_PrefsMusicVolume = 127;
}
- DMAudio.SetMusicMasterVolume(uchar)(CMenuManager::m_PrefsMusicVolume);
+ DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
SaveSettings();
break;
case HOVEROPTION_INCREASE_SFXVOLUME:
- CMenuManager::m_PrefsSFXVolume = CMenuManager::m_PrefsSFXVolume + 8;
- if (CMenuManager::m_PrefsSFXVolume < 0) {
- CMenuManager::m_PrefsSFXVolume = 0;
+ m_PrefsSFXVolume = m_PrefsSFXVolume + 8;
+ if (m_PrefsSFXVolume < 0) {
+ m_PrefsSFXVolume = 0;
}
- if (126 < CMenuManager::m_PrefsSFXVolume) {
- CMenuManager::m_PrefsSFXVolume = 127;
+ if (126 < m_PrefsSFXVolume) {
+ m_PrefsSFXVolume = 127;
}
- DMAudio.SetEffectsMasterVolume(uchar)(CMenuManager::m_PrefsSFXVolume);
+ DMAudio.SetEffectsMasterVolume(uchar)(m_PrefsSFXVolume);
SaveSettings();
break;
case HOVEROPTION_DECREASE_SFXVOLUME:
- CMenuManager::m_PrefsSFXVolume = CMenuManager::m_PrefsSFXVolume - 8;
- if (CMenuManager::m_PrefsSFXVolume < 0) {
- CMenuManager::m_PrefsSFXVolume = 0;
+ m_PrefsSFXVolume = m_PrefsSFXVolume - 8;
+ if (m_PrefsSFXVolume < 0) {
+ m_PrefsSFXVolume = 0;
}
- if (126 < CMenuManager::m_PrefsSFXVolume) {
- CMenuManager::m_PrefsSFXVolume = 127;
+ if (126 < m_PrefsSFXVolume) {
+ m_PrefsSFXVolume = 127;
}
- DMAudio.SetEffectsMasterVolume(uchar)(CMenuManager::m_PrefsSFXVolume);
+ DMAudio.SetEffectsMasterVolume(uchar)(m_PrefsSFXVolume);
SaveSettings();
break;
case HOVEROPTION_INCREASE_MOUSESENS:
@@ -2715,7 +4010,7 @@ CMenuManager::ProcessButtonPresses(void)
}
#ifndef TIDY_UP_PBP
- if (CPad::GetPad(0)->GetSquareJustDown()) {
+ if (CPad::GetPad(0)->GetBackJustDown()) {
if (m_nCurrScreen != MENUPAGE_START_MENU && m_nCurrScreen != MENUPAGE_PAUSE_MENU) {
m_bShowMouse = false;
goBack = true;
@@ -2756,11 +4051,11 @@ CMenuManager::ProcessButtonPresses(void)
if (!goDown && !goUp && !optionSelected) {
if (m_nCurrScreen != MENUPAGE_START_MENU) {
if (isPlainTextScreen(m_nCurrScreen)) {
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetSquareJustUp()) {
+ if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustUp()) {
goBack = true;
}
} else {
- if (CPad::GetPad(0)->GetEscapeJustDown() || (m_nCurrScreen != MENUPAGE_PAUSE_MENU && CPad::GetPad(0)->GetSquareJustDown())) {
+ if (CPad::GetPad(0)->GetEscapeJustDown() || (m_nCurrScreen != MENUPAGE_PAUSE_MENU && CPad::GetPad(0)->GetBackJustDown())) {
m_bShowMouse = false;
goBack = true;
}
@@ -2869,7 +4164,7 @@ CMenuManager::ProcessButtonPresses(void)
default:
goBack = true;
break;
- case 19:
+ case HOVEROPTION_LIST:
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
m_bWaitingForNewKeyBind = true;
m_bStartWaitingForKeyBind = true;
@@ -2878,16 +4173,16 @@ CMenuManager::ProcessButtonPresses(void)
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
strcpy(m_PrefsSkinFile, m_aSkinName);
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
- m_nCurrExLayer = 9;
- CMenuManager::SaveSettings();
+ m_nCurrExLayer = HOVEROPTION_BACK;
+ SaveSettings();
}
m_nHoverOption = HOVEROPTION_NOT_HOVERING;
break;
- case 21:
+ case HOVEROPTION_USESKIN:
m_nHoverOption = HOVEROPTION_NOT_HOVERING;
strcpy(m_PrefsSkinFile, m_aSkinName);
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
- m_nCurrExLayer = 9;
+ m_nCurrExLayer = HOVEROPTION_BACK;
SaveSettings();
break;
}
@@ -2898,7 +4193,7 @@ CMenuManager::ProcessButtonPresses(void)
*/
} else if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
if (m_nSkinsTotal > 0) {
- m_pSelectedSkin = (tSkinInfo*)(m_sSkin).field_304;
+ m_pSelectedSkin = m_pSkinListHead.nextSkin;
strcpy(m_PrefsSkinFile, m_aSkinName);
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
SaveSettings();
@@ -2915,47 +4210,47 @@ CMenuManager::ProcessButtonPresses(void)
#ifdef TIDY_UP_PBP
assumeIncrease = true;
#else
- ++CMenuManager::m_PrefsRadioStation;
- if (cDMAudio::IsMP3RadioChannelAvailable()) {
- if (CMenuManager::m_PrefsRadioStation > USERTRACK)
- CMenuManager::m_PrefsRadioStation = HEAD_RADIO;
- } else if (CMenuManager::m_PrefsRadioStation > CHATTERBOX) {
- CMenuManager::m_PrefsRadioStation = USERTRACK;
+ ++m_PrefsRadioStation;
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ if (m_PrefsRadioStation > USERTRACK)
+ m_PrefsRadioStation = HEAD_RADIO;
+ } else if (m_PrefsRadioStation > CHATTERBOX) {
+ m_PrefsRadioStation = USERTRACK;
}
SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
#endif
break;
case MENUACTION_LANG_ENG:
m_PrefsLanguage = LANGUAGE_AMERICAN;
m_bFrontEnd_ReloadObrTxtGxt = true;
- CMenuManager::InitialiseChangedLanguageSettings();
- CMenuManager::SaveSettings();
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
break;
case MENUACTION_LANG_FRE:
m_PrefsLanguage = LANGUAGE_FRENCH;
m_bFrontEnd_ReloadObrTxtGxt = true;
- CMenuManager::InitialiseChangedLanguageSettings();
- CMenuManager::SaveSettings();
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
break;
case MENUACTION_LANG_GER:
m_PrefsLanguage = LANGUAGE_GERMAN;
m_bFrontEnd_ReloadObrTxtGxt = true;
- CMenuManager::InitialiseChangedLanguageSettings();
- CMenuManager::SaveSettings();
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
break;
case MENUACTION_LANG_ITA:
m_PrefsLanguage = LANGUAGE_ITALIAN;
m_bFrontEnd_ReloadObrTxtGxt = true;
- CMenuManager::InitialiseChangedLanguageSettings();
- CMenuManager::SaveSettings();
+ InitialiseChangedLanguageSettings();
+ SaveSettings();
break;
case MENUACTION_LANG_SPA:
m_PrefsLanguage = LANGUAGE_SPANISH;
m_bFrontEnd_ReloadObrTxtGxt = true;
- CMenuManager::InitialiseChangedLanguageSettings();
+ InitialiseChangedLanguageSettings();
SaveSettings();
break;
#ifdef MORE_LANGUAGES
@@ -2968,7 +4263,7 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_LANG_JAP:
m_PrefsLanguage = LANGUAGE_JAPANESE;
m_bFrontEnd_ReloadObrTxtGxt = true;
- CMenuManager::InitialiseChangedLanguageSettings();
+ InitialiseChangedLanguageSettings();
SaveSettings();
break;
#endif
@@ -3000,7 +4295,7 @@ CMenuManager::ProcessButtonPresses(void)
if (changeMenu) {
if (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 0) {
#ifndef TIDY_UP_PBP
- CMenuManager::ResetHelperText();
+ ResetHelperText();
if (!m_bGameNotLoaded)
ChangeScreen(aScreens[m_nCurrScreen].m_PreviousPage[1], aScreens[m_nCurrScreen].m_ParentEntry[1], true, true);
else
@@ -3010,6 +4305,12 @@ CMenuManager::ProcessButtonPresses(void)
break;
#endif
} else {
+#ifdef MENU_MAP
+ if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_MAP) {
+ bMapLoaded = false;
+ }
+
+#endif
ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true);
}
}
@@ -3028,11 +4329,10 @@ CMenuManager::ProcessButtonPresses(void)
break;
}
case MENUACTION_NEWGAME:
- CMenuManager::DoSettingsBeforeStartingAGame();
+ DoSettingsBeforeStartingAGame();
break;
case MENUACTION_RELOADIDE:
- // TODO
- // CFileLoader::ReloadObjectTypes("GTA3.IDE");
+ CFileLoader::ReloadObjectTypes("GTA3.IDE");
break;
case MENUACTION_RELOADIPL:
CGame::ReloadIPLs();
@@ -3043,7 +4343,7 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_MEMCARDSAVECONFIRM:
return;
case MENUACTION_RESUME_FROM_SAVEZONE:
- CMenuManager::RequestFrontEndShutDown();
+ RequestFrontEndShutDown();
break;
case MENUACTION_MPMAP_LIBERTY:
case MENUACTION_MPMAP_REDLIGHT:
@@ -3053,8 +4353,8 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_MPMAP_INDUSTPARK:
case MENUACTION_MPMAP_DOCKS:
case MENUACTION_MPMAP_STAUNTON:
- sthWithButtons = option - MENUACTION_MPMAP_LIBERTY;
- CMenuManager::SaveSettings();
+ m_SelectedMap = option - MENUACTION_MPMAP_LIBERTY;
+ SaveSettings();
ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true);
break;
case MENUACTION_MPMAP_DEATHMATCH1:
@@ -3065,14 +4365,14 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_MPMAP_CAPTURE:
case MENUACTION_MPMAP_RATRACE:
case MENUACTION_MPMAP_DOMINATION:
- sthWithButtons2 = option - MENUACTION_MPMAP_DEATHMATCH1;
- CMenuManager::SaveSettings();
+ m_SelectedGameType = option - MENUACTION_MPMAP_DEATHMATCH1;
+ SaveSettings();
ChangeScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, 0, true, true);
break;
case MENUACTION_REDEFCTRL:
ChangeScreen(MENUPAGE_KEYBOARD_CONTROLS, 0, true, true);
m_nSelectedListRow = 0;
- m_nCurrExLayer = 19;
+ m_nCurrExLayer = HOVEROPTION_LIST;
break;
case MENUACTION_GETKEY:
m_CurrCntrlAction = GetStartOptionsCntrlConfigScreens() + m_nCurrOption;
@@ -3087,10 +4387,10 @@ CMenuManager::ProcessButtonPresses(void)
break;
case MENUACTION_RESUME:
#ifndef TIDY_UP_PBP
- if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
- CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
+ if (m_PrefsVsyncDisp != m_PrefsVsync) {
+ m_PrefsVsync = m_PrefsVsyncDisp;
}
- CMenuManager::RequestFrontEndShutDown();
+ RequestFrontEndShutDown();
#else
goBack = true;
#endif
@@ -3137,31 +4437,30 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_PLAYERSETUP:
CPlayerSkin::BeginFrontendSkinEdit();
ChangeScreen(MENUPAGE_SKIN_SELECT, 0, true, true);
- m_nCurrExLayer = 19;
- m_bSkinsFound = 0;
+ m_nCurrExLayer = HOVEROPTION_LIST;
+ m_bSkinsEnumerated = false;
break;
case MENUACTION_RESTOREDEF:
if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
- CMenuManager::m_PrefsSfxVolume = 102;
+ m_PrefsSfxVolume = 102;
m_PrefsSpeakers = 0;
- CMenuManager::m_PrefsMusicVolume = 102;
- // unused
- // byte_95CDB5 = 0;
- CMenuManager::m_PrefsRadioStation = HEAD_RADIO;
+ m_PrefsMusicVolume = 102;
+ m_PrefsStereoMono = 0;
+ m_PrefsRadioStation = HEAD_RADIO;
DMAudio.SetMusicMasterVolume(102);
- DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume);
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
SaveSettings();
} else if (m_nCurrScreen == MENUPAGE_GRAPHICS_SETTINGS) {
- CMenuManager::m_PrefsFrameLimiter = true;
- CMenuManager::m_PrefsBrightness = 256;
- CMenuManager::m_PrefsVsyncDisp = true;
- CMenuManager::m_PrefsLOD = 1.2f;
- CMenuManager::m_PrefsVsync = true;
+ m_PrefsFrameLimiter = true;
+ m_PrefsBrightness = 256;
+ m_PrefsVsyncDisp = true;
+ m_PrefsLOD = 1.2f;
+ m_PrefsVsync = true;
CRenderer::ms_lodDistScale = 1.2f;
- CMenuManager::m_PrefsUseWideScreen = false;
- CMenuManager::m_PrefsShowSubtitles = true;
+ m_PrefsUseWideScreen = false;
+ m_PrefsShowSubtitles = true;
m_nDisplayVideoMode = m_nPrefsVideoMode;
CMBlur::BlurOn = true;
SaveSettings();
@@ -3175,23 +4474,23 @@ CMenuManager::ProcessButtonPresses(void)
PSGLOBAL(joy1)->GetCapabilities(&devCaps);
ControlsManager.InitDefaultControlConfigJoyPad(devCaps.dwButtons);
}
- CMenuManager::m_ControlMethod = CONTROL_STANDARD;
+ m_ControlMethod = CONTROL_STANDARD;
MousePointerStateHelper.bInvertVertically = false;
TheCamera.m_fMouseAccelHorzntl = 0.0025f;
CVehicle::m_bDisableMouseSteering = true;
TheCamera.m_bHeadBob = false;
SaveSettings();
}
- CMenuManager::SetHelperText(2);
+ SetHelperText(2);
break;
case MENUACTION_CTRLMETHOD:
#ifndef TIDY_UP_PBP
- if (CMenuManager::m_ControlMethod == CONTROL_CLASSIC) {
+ if (m_ControlMethod == CONTROL_CLASSIC) {
CCamera::m_bUseMouse3rdPerson = true;
- CMenuManager::m_ControlMethod = CONTROL_STANDARD;
+ m_ControlMethod = CONTROL_STANDARD;
} else {
CCamera::m_bUseMouse3rdPerson = false;
- CMenuManager::m_ControlMethod = CONTROL_CLASSIC;
+ m_ControlMethod = CONTROL_CLASSIC;
}
SaveSettings();
#else
@@ -3200,7 +4499,7 @@ CMenuManager::ProcessButtonPresses(void)
break;
case MENUACTION_LOADRADIO:
ChangeScreen(MENUPAGE_SOUND_SETTINGS, 0, true, true);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
break;
}
@@ -3209,7 +4508,7 @@ CMenuManager::ProcessButtonPresses(void)
}
if (goBack) {
- CMenuManager::ResetHelperText();
+ ResetHelperText();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_EXIT, 0);
#ifdef PS2_LIKE_MENU
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU || bottomBarActive) {
@@ -3217,10 +4516,10 @@ CMenuManager::ProcessButtonPresses(void)
if (m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
#endif
if (!m_bGameNotLoaded && !m_bMenuStateChanged) {
- if (CMenuManager::m_PrefsVsyncDisp != CMenuManager::m_PrefsVsync) {
- CMenuManager::m_PrefsVsync = CMenuManager::m_PrefsVsyncDisp;
+ if (m_PrefsVsyncDisp != m_PrefsVsync) {
+ m_PrefsVsync = m_PrefsVsyncDisp;
}
- CMenuManager::RequestFrontEndShutDown();
+ RequestFrontEndShutDown();
}
// We're already resuming, we don't need further processing.
@@ -3233,7 +4532,7 @@ CMenuManager::ProcessButtonPresses(void)
#else
else if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) {
#endif
- CMenuManager::RequestFrontEndShutDown();
+ RequestFrontEndShutDown();
}
// It's now in ThingsToDoBeforeLeavingPage()
#ifndef TIDY_UP_PBP
@@ -3281,13 +4580,13 @@ CMenuManager::ProcessButtonPresses(void)
if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) {
static uint32 lastSliderDecrease = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) {
- CMenuManager::CheckSliderMovement(-1);
+ CheckSliderMovement(-1);
lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode();
}
} else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) {
static uint32 lastSliderIncrease = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) {
- CMenuManager::CheckSliderMovement(1);
+ CheckSliderMovement(1);
lastSliderIncrease = CTimer::GetTimeInMillisecondsPauseMode();
}
}
@@ -3297,7 +4596,7 @@ CMenuManager::ProcessButtonPresses(void)
increase = true;
} else if (CPad::GetPad(0)->GetMouseWheelUpJustDown() && m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
increase = true;
- CMenuManager::CheckSliderMovement(1);
+ CheckSliderMovement(1);
m_bShowMouse = true;
}
@@ -3305,7 +4604,7 @@ CMenuManager::ProcessButtonPresses(void)
if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
if (m_nCurrScreen != MENUPAGE_KEYBOARD_CONTROLS) {
decrease = true;
- CMenuManager::CheckSliderMovement(-1);
+ CheckSliderMovement(-1);
m_bShowMouse = true;
}
}
@@ -3322,22 +4621,22 @@ CMenuManager::ProcessButtonPresses(void)
if (changeValueBy != 0) {
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_RADIO:
- CMenuManager::m_PrefsRadioStation += changeValueBy;
+ m_PrefsRadioStation += changeValueBy;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (CMenuManager::m_PrefsRadioStation < HEAD_RADIO)
- CMenuManager::m_PrefsRadioStation = USERTRACK;
- if (CMenuManager::m_PrefsRadioStation > USERTRACK)
- CMenuManager::m_PrefsRadioStation = HEAD_RADIO;
+ if (m_PrefsRadioStation < HEAD_RADIO)
+ m_PrefsRadioStation = USERTRACK;
+ if (m_PrefsRadioStation > USERTRACK)
+ m_PrefsRadioStation = HEAD_RADIO;
} else {
- if (CMenuManager::m_PrefsRadioStation < HEAD_RADIO)
- CMenuManager::m_PrefsRadioStation = CHATTERBOX;
- if (CMenuManager::m_PrefsRadioStation > CHATTERBOX)
- CMenuManager::m_PrefsRadioStation = HEAD_RADIO;
+ if (m_PrefsRadioStation < HEAD_RADIO)
+ m_PrefsRadioStation = CHATTERBOX;
+ if (m_PrefsRadioStation > CHATTERBOX)
+ m_PrefsRadioStation = HEAD_RADIO;
}
- CMenuManager::SaveSettings();
- DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
+ SaveSettings();
+ DMAudio.SetRadioInCar(m_PrefsRadioStation);
+ DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case MENUACTION_SCREENRES:
@@ -3373,34 +4672,31 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsSpeakers -= changeValueBy;
m_PrefsSpeakers = clamp(m_PrefsSpeakers, 0, 2);
DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
- CMenuManager::SaveSettings();
+ SaveSettings();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
}
break;
case MENUACTION_CTRLMETHOD:
- CMenuManager::m_ControlMethod = !m_ControlMethod;
+ m_ControlMethod = !m_ControlMethod;
CCamera::m_bUseMouse3rdPerson = !m_ControlMethod;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
- CMenuManager::SaveSettings();
+ SaveSettings();
break;
}
ProcessOnOffMenuOptions();
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
if (changeValueBy < 1) {
- field_530 = 0;
+ m_nSelectedContSetupColumn = CONTSETUP_PED_COLUMN;
} else {
- field_530 = 14;
+ m_nSelectedContSetupColumn = CONTSETUP_VEHICLE_COLUMN;
}
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
}
}
}
-#endif
-#if 0
-WRAPPER void CMenuManager::ProcessOnOffMenuOptions() { EAXJMP(0x48AE60); }
-#else
-void CMenuManager::ProcessOnOffMenuOptions()
+void
+CMenuManager::ProcessOnOffMenuOptions()
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_CTRLVIBRATION:
@@ -3478,7 +4774,9 @@ void CMenuManager::ProcessOnOffMenuOptions()
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
break;
case MENUACTION_MP_PLAYERCOLOR:
- assert(0 && "Not implemented");
+ PickNewPlayerColour();
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
+ SaveSettings();
break;
case MENUACTION_SHOWHEADBOB:
TheCamera.m_bHeadBob = !TheCamera.m_bHeadBob;
@@ -3503,34 +4801,29 @@ void CMenuManager::ProcessOnOffMenuOptions()
break;
}
}
-#endif
-void CMenuManager::RequestFrontEndShutDown()
+void
+CMenuManager::RequestFrontEndShutDown()
{
m_bShutDownFrontEndRequested = true;
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER void CMenuManager::RequestFrontEndStartUp() { EAXJMP(0x488770); }
-#else
-void CMenuManager::RequestFrontEndStartUp()
+void
+CMenuManager::RequestFrontEndStartUp()
{
m_bStartUpFrontEndRequested = true;
}
-#endif
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER void CMenuManager::ResetHelperText() { EAXJMP(0x48B470); }
-#else
-void CMenuManager::ResetHelperText()
+void
+CMenuManager::ResetHelperText()
{
m_nHelperTextMsgId = 0;
m_nHelperTextAlpha = 300;
}
-#endif
-void CMenuManager::SaveLoadFileError_SetUpErrorScreen()
+void
+CMenuManager::SaveLoadFileError_SetUpErrorScreen()
{
switch (PcSaveHelper.nErrorCode) {
case SAVESTATUS_ERR_SAVE_CREATE:
@@ -3554,27 +4847,22 @@ void CMenuManager::SaveLoadFileError_SetUpErrorScreen()
}
}
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER void CMenuManager::SetHelperText(int text) { EAXJMP(0x48B450); }
-#else
-void CMenuManager::SetHelperText(int text)
+void
+CMenuManager::SetHelperText(int text)
{
m_nHelperTextMsgId = text;
m_nHelperTextAlpha = 300;
}
-#endif
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER void CMenuManager::ShutdownJustMenu() { EAXJMP(0x488920); }
-#else
-void CMenuManager::ShutdownJustMenu()
+void
+CMenuManager::ShutdownJustMenu()
{
m_bMenuActive = false;
CTimer::EndUserPause();
}
-#endif
-float CMenuManager::StretchX(float x)
+float
+CMenuManager::StretchX(float x)
{
if (SCREEN_WIDTH == DEFAULT_SCREEN_WIDTH)
return x;
@@ -3592,12 +4880,10 @@ float CMenuManager::StretchY(float y)
return SCREEN_STRETCH_Y(y);
}
-#if 0
-WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); }
-#else
-void CMenuManager::SwitchMenuOnAndOff()
+void
+CMenuManager::SwitchMenuOnAndOff()
{
- bool menuWasActive = !!m_bMenuActive;
+ bool menuWasActive = GetIsMenuActive();
// Reminder: You need REGISTER_START_BUTTON defined to make it work.
if (CPad::GetPad(0)->GetStartJustDown()
@@ -3627,9 +4913,20 @@ void CMenuManager::SwitchMenuOnAndOff()
m_bStartUpFrontEndRequested = false;
pControlEdit = nil;
m_bShutDownFrontEndRequested = false;
- DisplayComboButtonErrMsg = 0;
- CPad::GetPad(0)->Clear(0);
- CPad::GetPad(1)->Clear(0);
+ DisplayComboButtonErrMsg = false;
+
+#ifdef REGISTER_START_BUTTON
+ int16 start1 = CPad::GetPad(0)->PCTempJoyState.Start, start2 = CPad::GetPad(0)->PCTempKeyState.Start,
+ start3 = CPad::GetPad(0)->OldState.Start, start4 = CPad::GetPad(0)->NewState.Start;
+#endif
+ CPad::GetPad(0)->Clear(false);
+ CPad::GetPad(1)->Clear(false);
+#ifdef REGISTER_START_BUTTON
+ CPad::GetPad(0)->PCTempJoyState.Start = start1;
+ CPad::GetPad(0)->PCTempKeyState.Start = start2;
+ CPad::GetPad(0)->OldState.Start = start3;
+ CPad::GetPad(0)->NewState.Start = start4;
+#endif
m_nCurrScreen = MENUPAGE_NONE;
}
}
@@ -3662,12 +4959,9 @@ void CMenuManager::SwitchMenuOnAndOff()
m_bStartUpFrontEndRequested = false;
m_bShutDownFrontEndRequested = false;
}
-#endif
-#if 0
-WRAPPER void CMenuManager::UnloadTextures() { EAXJMP(0x47A440); }
-#else
-void CMenuManager::UnloadTextures()
+void
+CMenuManager::UnloadTextures()
{
if (!m_bSpritesLoaded)
return;
@@ -3682,33 +4976,645 @@ void CMenuManager::UnloadTextures()
printf("REMOVE menu textures\n");
for (int i = 0; i < ARRAY_SIZE(MenuFilenames); ++i)
m_aMenuSprites[i].Delete();
-
+#ifdef MENU_MAP
+ for (int i = 0; i < ARRAY_SIZE(MapFilenames); ++i)
+ m_aMapSprites[i].Delete();
+#endif
int menu = CTxdStore::FindTxdSlot("menu");
CTxdStore::RemoveTxd(menu);
m_bSpritesLoaded = false;
}
+
+void
+CMenuManager::WaitForUserCD()
+{
+ CSprite2d *splash;
+ char *splashscreen = nil;
+
+#ifndef RANDOMSPLASH
+ if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
+ splashscreen = "mainsc2";
+ else
+ splashscreen = "mainsc1";
#endif
-#if DONT_USE_SUSPICIOUS_FUNCS
-WRAPPER void CMenuManager::WaitForUserCD(void) { EAXJMP(0x48ADD0); }
-#else
-void CMenuManager::WaitForUserCD()
+ splash = LoadSplash(splashscreen);
+
+ if (RsGlobal.quit)
+ return;
+
+ HandleExit();
+ CPad::UpdatePads();
+ MessageScreen("NO_PCCD");
+
+ if (CPad::GetPad(0)->GetEscapeJustDown()) {
+ m_bQuitGameNoCD = true;
+ RsEventHandler(rsQUITAPP, nil);
+ }
+}
+
+void
+CMenuManager::PrintController(void)
{
- LoadSplash(0);
- if (!RsGlobal.quit) {
- HandleExit();
- CPad::UpdatePads();
- MessageScreen("NO_PCCD");
+ // FIX: Originally this function doesn't have StretchX/Y, everything had constant pixel size (due to screen was abandoned early?)
+ // Also texts and their alignment were very bad, so I tried to make them readable (commented out the original code, and marked the ones I added with X)
+
+ m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(240.0f), MENU_Y(180.0f), CRGBA(0, 0, 0, 255));
+ m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
+ if (m_DisplayControllerOnFoot) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
+ m_aFrontEndSprites[FE_ARROWS1].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
+ else
+ m_aFrontEndSprites[FE_ARROWS3].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
+ } else {
+ if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
+ m_aFrontEndSprites[FE_ARROWS2].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
+ else
+ m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
+ }
- if (GetPadBack()) {
- m_bQuitGameNoCD = true;
- RsEventHandler(rsQUITAPP, 0);
+ CFont::SetFontStyle(FONT_BANK); // X
+
+ // CFont::SetScale(0.4f, 0.4f);
+ CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); // X
+
+ // CFont::SetColor(CRGBA(128, 128, 128, FadeIn(255)));
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // X
+ CFont::SetDropShadowPosition(1); // X
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); // X
+
+ if (m_DisplayControllerOnFoot) {
+ switch (CPad::GetPad(0)->Mode) {
+ case 0:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
+ break;
+ case 1:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
+ break;
+ case 2:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_ENV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
+ break;
+ case 3:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_NA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
+ break;
+ default:
+ return;
+ }
+ } else {
+ switch (CPad::GetPad(0)->Mode) {
+ case 0:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_RSC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC"));
+ // FIX: Coordinates of this line is undefined in PC...
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3"));
+ break;
+ case 1:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HOR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_RSC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC"));
+ // FIX: Coordinates of this line is undefined in PC...
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3"));
+ break;
+ case 2:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_RS3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HOR"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_HAB"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC"));
+ // FIX: Coordinates of this line is undefined in PC...
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3"));
+ break;
+ case 3:
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HAB"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_TUC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
+ CFont::SetRightJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
+ CFont::SetJustifyOn(); // X
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_CAW"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_SMT"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_RSC"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_NA"));
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_ACC"));
+ // FIX: Coordinates of this line is undefined in PC...
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_BRA"));
+ break;
+ default:
+ return;
}
}
+
+ CFont::SetDropShadowPosition(0); // X
}
+
+#ifdef MENU_MAP
+
+#define ZOOM(x, y, in) \
+ do { \
+ if(fMapSize > SCREEN_WIDTH * 2 && in) \
+ break; \
+ float z2 = in? 1.1f : 1.f/1.1f; \
+ fMapCenterX += (x - fMapCenterX) * (1.0f - z2); \
+ fMapCenterY += (y - fMapCenterY) * (1.0f - z2); \
+ \
+ if (fMapSize < SCREEN_WIDTH / 3 && !in) \
+ break; \
+ \
+ fMapSize *= z2; \
+ } while(0) \
+
+void
+CMenuManager::PrintMap(void)
+{
+ bMenuMapActive = true;
+ CRadar::InitFrontEndMap();
+
+ if (!bMapLoaded) {
+ fMapCenterX = SCREEN_WIDTH / 2;
+ fMapCenterY = SCREEN_HEIGHT / 3;
+ fMapSize = SCREEN_HEIGHT / CDraw::GetAspectRatio();
+ bMapMouseShownOnce = false;
+ bMapLoaded = true;
+
+ // Let's wait for a frame to not toggle the waypoint
+ if (CPad::GetPad(0)->NewState.Cross) {
+ bMenuMapActive = false;
+ return;
+ }
+ }
+
+ // Because fMapSize is half of the map length, and map consists of 3x3 tiles.
+ float halfTile = fMapSize / 3.0f;
+
+ // Darken background a bit
+ CSprite2d::DrawRect(CRect(0, 0,
+ SCREEN_WIDTH, SCREEN_HEIGHT),
+ CRGBA(0, 0, 0, FadeIn(128)));
+
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+
+ if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
+ m_aMapSprites[MAPTOP1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize,
+ fMapCenterX - halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
+ m_aMapSprites[MAPTOP2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize,
+ fMapCenterX + halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
+ m_aMapSprites[MAPTOP3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize,
+ fMapCenterX + fMapSize, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
+ m_aMapSprites[MAPMID1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile,
+ fMapCenterX - halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
+ m_aMapSprites[MAPMID2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile,
+ fMapCenterX + halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
+ m_aMapSprites[MAPMID3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile,
+ fMapCenterX + fMapSize, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
+ m_aMapSprites[MAPBOT1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile,
+ fMapCenterX - halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
+ m_aMapSprites[MAPBOT2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile,
+ fMapCenterX + halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
+ m_aMapSprites[MAPBOT3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile,
+ fMapCenterX + fMapSize, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ CRadar::DrawBlips();
+
+ CVector2D mapPoint;
+ mapPoint.x = m_nMousePosX;
+ mapPoint.y = m_nMousePosY;
+
+ if (m_bShowMouse) {
+ bMapMouseShownOnce = true;
+ } else if (!bMapMouseShownOnce) {
+ mapPoint.x = SCREEN_WIDTH / 2;
+ mapPoint.y = SCREEN_HEIGHT / 2;
+ }
+
+ CSprite2d::DrawRect(CRect(mapPoint.x - MENU_X(1.0f), 0.0f,
+ mapPoint.x + MENU_X(1.0f), SCREEN_HEIGHT),
+ CRGBA(0, 0, 0, 150));
+ CSprite2d::DrawRect(CRect(0.0f, mapPoint.y + MENU_X(1.0f),
+ SCREEN_WIDTH, mapPoint.y - MENU_X(1.0f)),
+ CRGBA(0, 0, 0, 150));
+
+ if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
+ if (mapPoint.y > fMapCenterY - fMapSize && mapPoint.y < fMapCenterY + fMapSize &&
+ mapPoint.x > fMapCenterX - fMapSize && mapPoint.x < fMapCenterX + fMapSize) {
+
+ float diffX = fMapCenterX - fMapSize, diffY = fMapCenterY - fMapSize;
+ float x = ((mapPoint.x - diffX) / (fMapSize * 2)) * 4000.0f - 2000.0f;
+ float y = 2000.0f - ((mapPoint.y - diffY) / (fMapSize * 2)) * 4000.0f;
+ CRadar::ToggleTargetMarker(x, y);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
+ }
+ }
+
+ if (CPad::GetPad(0)->GetLeftMouse()) {
+ fMapCenterX += m_nMousePosX - m_nMouseOldPosX;
+ fMapCenterY += m_nMousePosY - m_nMouseOldPosY;
+ } else if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetDPadLeft()) {
+ fMapCenterX += 15.0f;
+ } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetDPadRight()) {
+ fMapCenterX -= 15.0f;
+ } else if (CPad::GetPad(0)->GetLeftStickX()) {
+ fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f;
+ }
+
+ if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetDPadUp()) {
+ fMapCenterY += 15.0f;
+ } else if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetDPadDown()) {
+ fMapCenterY -= 15.0f;
+ } else if (CPad::GetPad(0)->GetLeftStickY()) {
+ fMapCenterY -= CPad::GetPad(0)->GetLeftStickY() / 128.0f * 20.0f;
+ }
+
+ if (CPad::GetPad(0)->GetMouseWheelDown() || CPad::GetPad(0)->GetPageDown() || CPad::GetPad(0)->GetRightShoulder2()) {
+ if (CPad::GetPad(0)->GetMouseWheelDown())
+ ZOOM(mapPoint.x, mapPoint.y, false);
+ else
+ ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, false);
+ } else if (CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetPageUp() || CPad::GetPad(0)->GetRightShoulder1()) {
+ if (CPad::GetPad(0)->GetMouseWheelUp())
+ ZOOM(mapPoint.x, mapPoint.y, true);
+ else
+ ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true);
+ }
+
+ if (fMapCenterX - fMapSize > SCREEN_WIDTH / 2)
+ fMapCenterX = fMapSize + SCREEN_WIDTH / 2;
+
+ if (fMapCenterX + fMapSize < SCREEN_WIDTH / 2)
+ fMapCenterX = SCREEN_WIDTH / 2 - fMapSize;
+
+ if (fMapCenterY + fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f))
+ fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - fMapSize;
+
+ fMapCenterY = min(fMapCenterY, fMapSize); // To not show beyond north border
+
+ bMenuMapActive = false;
+
+ // CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(5.0f)); // From VC
+ // CFont::SetRightJustifyWrap(10.0f);
+
+ CSprite2d::DrawRect(CRect(MENU_X(14.0f), SCREEN_STRETCH_FROM_BOTTOM(95.0f),
+ SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)),
+ CRGBA(235, 170, 50, 255));
+
+ CFont::SetScale(MENU_X(0.4f), MENU_Y(0.7f));
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+
+ float nextX = MENU_X(30.0f), nextY = 95.0f;
+ wchar *text;
+#define TEXT_PIECE(key,extraSpace) \
+ text = TheText.Get(key); CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), text); nextX += CFont::GetStringWidth(text, true) + MENU_X(extraSpace);
+
+ TEXT_PIECE("FEC_MWF", 3.0f);
+ TEXT_PIECE("FEC_PGU", 1.0f);
+ TEXT_PIECE("FEC_IBT", 1.0f);
+ TEXT_PIECE("FEC_ZIN", 20.0f);
+ TEXT_PIECE("FEC_MWB", 3.0f);
+ TEXT_PIECE("FEC_PGD", 1.0f);
+ TEXT_PIECE("FEC_IBT", 1.0f);
+ CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_ZOT")); nextX = MENU_X(30.0f); nextY -= 11.0f;
+ TEXT_PIECE("FEC_UPA", 2.0f);
+ TEXT_PIECE("FEC_DWA", 2.0f);
+ TEXT_PIECE("FEC_LFA", 2.0f);
+ TEXT_PIECE("FEC_RFA", 2.0f);
+ TEXT_PIECE("FEC_MSL", 1.0f);
+ TEXT_PIECE("FEC_IBT", 1.0f);
+ CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_MOV")); nextX = MENU_X(30.0f); nextY -= 11.0f;
+ TEXT_PIECE("FEC_MSR", 2.0f);
+ TEXT_PIECE("FEC_IBT", 1.0f);
+ CFont::PrintString(nextX, SCREEN_SCALE_FROM_BOTTOM(nextY), TheText.Get("FEC_TAR"));
+#undef TEXT_PIECE
+}
+
+#undef ZOOM
#endif
+// rowIdx 99999 returns total numbers of rows. otherwise it returns 0.
+int
+CMenuManager::ConstructStatLine(int rowIdx)
+{
+#define STAT_LINE(str, left, isFloat, right) \
+ do { \
+ if(counter == rowIdx){ \
+ BuildStatLine(str, left, isFloat, right); \
+ return 0; \
+ } counter++; \
+ } while(0)
+
+ int counter = 0, nTemp;
+
+ STAT_LINE("PL_STAT", nil, false, nil);
+
+ int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
+ CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1));
+ percentCompleted = min(percentCompleted, 100);
+
+ STAT_LINE("PER_COM", &percentCompleted, false, nil);
+ STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil);
+ STAT_LINE("FEST_MP", &CStats::MissionsPassed, 0, &CStats::TotalNumberMissions);
+ if (CGame::nastyGame) {
+ STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, 0, &CStats::TotalNumberKillFrenzies);
+ }
+
+ CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus];
+ float packagesPercent = 0.0f;
+ if (player.m_nTotalPackages != 0)
+ packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages;
+
+ STAT_LINE("PERPIC", &packagesPercent, 0, &(nTemp = 100));
+ STAT_LINE("NOUNIF", &CStats::TotalNumberOfUniqueJumps, 0, &CStats::NumberOfUniqueJumpsFound);
+ STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil);
+ if (CGame::nastyGame) {
+ STAT_LINE("PE_WAST", &CStats::PeopleKilledByPlayer, false, nil);
+ STAT_LINE("PE_WSOT", &CStats::PeopleKilledByOthers, false, nil);
+ }
+ STAT_LINE("CAR_EXP", &CStats::CarsExploded, false, nil);
+ STAT_LINE("TM_BUST", &CStats::TimesArrested, false, nil);
+ STAT_LINE("TM_DED", &CStats::TimesDied, false, nil);
+ STAT_LINE("GNG_WST", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_GANG9] + CStats::PedsKilledOfThisType[PEDTYPE_GANG8]
+ + CStats::PedsKilledOfThisType[PEDTYPE_GANG7] + CStats::PedsKilledOfThisType[PEDTYPE_GANG6]
+ + CStats::PedsKilledOfThisType[PEDTYPE_GANG5] + CStats::PedsKilledOfThisType[PEDTYPE_GANG4]
+ + CStats::PedsKilledOfThisType[PEDTYPE_GANG3] + CStats::PedsKilledOfThisType[PEDTYPE_GANG2]
+ + CStats::PedsKilledOfThisType[PEDTYPE_GANG1]), false, nil);
+ STAT_LINE("DED_CRI", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]), false, nil);
+ STAT_LINE("HEL_DST", &CStats::HelisDestroyed, false, nil);
+ STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, false, nil);
+ STAT_LINE("ACCURA", &(nTemp = (CStats::InstantHitsFiredByPlayer == 0 ? 0 :
+ CStats::InstantHitsHitByPlayer * 100.0f / CStats::InstantHitsFiredByPlayer)), false, nil);
+
+ if (CStats::ElBurroTime > 0) {
+ STAT_LINE("ELBURRO", &CStats::ElBurroTime, false, nil);
+ }
+ if (CStats::Record4x4One > 0) {
+ STAT_LINE("FEST_R1", &CStats::Record4x4One, false, nil);
+ }
+ if (CStats::Record4x4Two > 0) {
+ STAT_LINE("FEST_R2", &CStats::Record4x4Two, false, nil);
+ }
+ if (CStats::Record4x4Three > 0) {
+ STAT_LINE("FEST_R3", &CStats::Record4x4Three, false, nil);
+ }
+ if (CStats::Record4x4Mayhem > 0) {
+ STAT_LINE("FEST_RM", &CStats::Record4x4Mayhem, false, nil);
+ }
+ if (CStats::LongestFlightInDodo > 0) {
+ STAT_LINE("FEST_LF", &CStats::LongestFlightInDodo, false, nil);
+ }
+ if (CStats::TimeTakenDefuseMission > 0) {
+ STAT_LINE("FEST_BD", &CStats::TimeTakenDefuseMission, false, nil);
+ }
+ STAT_LINE("CAR_CRU", &CStats::CarsCrushed, false, nil);
+
+ if (CStats::HighestScores[0] > 0) {
+ STAT_LINE("FEST_BB", nil, false, nil);
+ STAT_LINE("FEST_H0", &CStats::HighestScores[0], false, nil);
+ }
+ if (CStats::HighestScores[4] + CStats::HighestScores[3] + CStats::HighestScores[2] + CStats::HighestScores[1] > 0) {
+ STAT_LINE("FEST_GC", nil, false, nil);
+ }
+ if (CStats::HighestScores[1] > 0) {
+ STAT_LINE("FEST_H1", &CStats::HighestScores[1], false, nil);
+ }
+ if (CStats::HighestScores[2] > 0) {
+ STAT_LINE("FEST_H2", &CStats::HighestScores[2], false, nil);
+ }
+ if (CStats::HighestScores[3] > 0) {
+ STAT_LINE("FEST_H3", &CStats::HighestScores[3], false, nil);
+ }
+ if (CStats::HighestScores[4] > 0) {
+ STAT_LINE("FEST_H4", &CStats::HighestScores[4], false, nil);
+ }
+
+ switch (m_PrefsLanguage) {
+ case LANGUAGE_AMERICAN:
+#ifndef USE_MEASUREMENTS_IN_METERS
+ float fTemp;
+ STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil);
+ STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledInVehicle * MILES_IN_METER), true, nil);
+ STAT_LINE("MMRAIN", &CStats::mmRain, false, nil);
+ STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil);
+ STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil);
+ break;
+#endif
+ case LANGUAGE_FRENCH:
+ case LANGUAGE_GERMAN:
+ case LANGUAGE_ITALIAN:
+ case LANGUAGE_SPANISH:
+#ifdef MORE_LANGUAGES
+ case LANGUAGE_RUSSIAN:
+#endif
+ STAT_LINE("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil);
+ STAT_LINE("FESTDCM", &CStats::DistanceTravelledInVehicle, true, nil);
+ STAT_LINE("MMRAIN", &CStats::mmRain, false, nil);
+ STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil);
+ STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil);
+ break;
+ default:
+ break;
+ }
+
+ STAT_LINE("MXFLIP", &CStats::MaximumJumpFlips, false, nil);
+ STAT_LINE("MXJUMP", &CStats::MaximumJumpSpins, false, nil);
+ STAT_LINE("BSTSTU", nil, false, nil);
+
+ if (counter == rowIdx) {
+ gUString[0] = '\0';
+ switch (CStats::BestStuntJump) {
+ case 1:
+ UnicodeStrcpy(gUString2, TheText.Get("INSTUN"));
+ return 0;
+ case 2:
+ UnicodeStrcpy(gUString2, TheText.Get("PRINST"));
+ return 0;
+ case 3:
+ UnicodeStrcpy(gUString2, TheText.Get("DBINST"));
+ return 0;
+ case 4:
+ UnicodeStrcpy(gUString2, TheText.Get("DBPINS"));
+ return 0;
+ case 5:
+ UnicodeStrcpy(gUString2, TheText.Get("TRINST"));
+ return 0;
+ case 6:
+ UnicodeStrcpy(gUString2, TheText.Get("PRTRST"));
+ return 0;
+ case 7:
+ UnicodeStrcpy(gUString2, TheText.Get("QUINST"));
+ return 0;
+ case 8:
+ UnicodeStrcpy(gUString2, TheText.Get("PQUINS"));
+ return 0;
+ default:
+ UnicodeStrcpy(gUString2, TheText.Get("NOSTUC"));
+ return 0;
+ }
+ }
+ counter++;
+ STAT_LINE("PASDRO", &CStats::PassengersDroppedOffWithTaxi, false, nil);
+ STAT_LINE("MONTAX", &CStats::MoneyMadeWithTaxi, false, nil);
+ STAT_LINE("FEST_LS", &CStats::LivesSavedWithAmbulance, false, nil);
+ STAT_LINE("FEST_HA", &CStats::HighestLevelAmbulanceMission, false, nil);
+ STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil);
+ STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil);
+ STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil);
+ return counter;
+
+#undef STAT_LINE
+}
+
#if 0
uint8 CMenuManager::GetNumberOfMenuOptions()
{
@@ -3723,12 +5629,12 @@ uint8 CMenuManager::GetNumberOfMenuOptions()
}
#endif
+#undef GetBackJustUp
+#undef GetBackJustDown
+
STARTPATCHES
-#if DONT_USE_SUSPICIOUS_FUNCS
-#else
for (int i = 1; i < ARRAY_SIZE(aScreens); i++)
Patch(0x611930 + sizeof(CMenuScreen) * i, aScreens[i]);
-#endif
InjectHook(0x4856F0, &CMenuManager::ProcessButtonPresses, PATCH_JUMP);
InjectHook(0x485100, &CMenuManager::Process, PATCH_JUMP);
InjectHook(0x47A230, &CMenuManager::LoadAllTextures, PATCH_JUMP);
@@ -3741,4 +5647,5 @@ STARTPATCHES
InjectHook(0x47A440, &CMenuManager::UnloadTextures, PATCH_JUMP);
InjectHook(0x48AB40, &CMenuManager::DoSettingsBeforeStartingAGame, PATCH_JUMP);
InjectHook(0x48AE60, &CMenuManager::ProcessOnOffMenuOptions, PATCH_JUMP);
+ InjectHook(0x489710, &CMenuManager::DrawControllerBound, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 74b3990e..792f0c45 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -7,27 +7,10 @@
#define MENUHEADER_WIDTH 0.84f
#define MENUHEADER_HEIGHT 1.6f
-#define MENUACTION_X_MARGIN 40.0f
+#define MENU_X_MARGIN 40.0f
#define MENUACTION_POS_Y 60.0f
-#define MENUACTION_WIDTH 0.405f
-#define MENUACTION_HEIGHT 0.63f
-
-#define MENUCOLUMN_POS_X MENUHEADER_POS_X + 16.0f
-#define MENUCOLUMN_MAX_Y 149.0f
-#define MENUCOLUMN_MID_Y 100.0f
-#define MENUCOLUMN_MIN_Y 110.0f
-#define MENUCOLUMN_PAUSE_Y 25.0f
-#define MENUCOLUMN_START_Y 9.0f
-#define MENUCOLUMN_FEDS 139.0f
-
-#define MENUCOLUMN_SAVE_X 121.0f
-#define MENUCOLUMN_SAVE_Y 111.0f
-
-#define MENUCOLUMN_SPACING_MAX 24.0f
-#define MENUCOLUMN_SPACING_MIN 20.0f
-
-#define MENUSELECT_BOX_MAX 20.5f
-#define MENUSELECT_BOX_MIN 17.0f
+#define MENUACTION_WIDTH 38.0f
+#define MENUACTION_SCALE_MULT 0.9f
#ifndef ASPECT_RATIO_SCALE
#define MENURADIO_ICON_X 31.5f
@@ -38,12 +21,63 @@
#define MENURADIO_ICON_W 60.0f
#define MENURADIO_ICON_H 60.0f
-#define MENUDROP_COLOR_A 150
-#define MENUDROP_COLOR_SIZE -1
-
#define MENUSLIDER_X 256.0f
#define MENUSLIDER_UNK 256.0f
+#define BIGTEXT_X_SCALE 0.75f
+#define BIGTEXT_Y_SCALE 0.9f
+#define MEDIUMTEXT_X_SCALE 0.55f
+#define MEDIUMTEXT_Y_SCALE 0.8f
+#define SMALLTEXT_X_SCALE 0.45f
+#define SMALLTEXT_Y_SCALE 0.7f
+#define SMALLESTTEXT_X_SCALE 0.4f
+#define SMALLESTTEXT_Y_SCALE 0.6f
+
+#define PLAYERSETUP_LIST_TOP 28.0f
+#define PLAYERSETUP_LIST_BOTTOM 125.0f
+#define PLAYERSETUP_LIST_LEFT 200.0f
+#define PLAYERSETUP_LIST_RIGHT 36.0f
+#ifdef FIX_BUGS // See the scrollbar button drawing code
+#define PLAYERSETUP_SCROLLBAR_WIDTH 19.0f
+#else
+#define PLAYERSETUP_SCROLLBAR_WIDTH 16.0f
+#endif
+#define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f
+#define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64
+#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f
+#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f
+#define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f
+#define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f
+#define PLAYERSETUP_LIST_BODY_TOP 47
+#define PLAYERSETUP_ROW_HEIGHT 9
+
+#define STATS_SLIDE_Y_PER_SECOND 30.0f
+#define STATS_ROW_HEIGHT 20.0f
+#define STATS_ROW_X_MARGIN 50.0f
+#define STATS_BOTTOM_MARGIN 135.0f
+#define STATS_TOP_MARGIN 40.0f
+#define STATS_TOP_DIMMING_AREA_LENGTH (93.0f - STATS_TOP_MARGIN)
+#define STATS_BOTTOM_DIMMING_AREA_LENGTH 55.0f
+#define STATS_PUT_BACK_TO_BOTTOM_Y 50.0f
+#define STATS_RATING_X 24.0f
+#define STATS_RATING_Y 20.0f
+
+#define CONTSETUP_STANDARD_ROW_HEIGHT 10.7f
+#define CONTSETUP_CLASSIC_ROW_HEIGHT 9.0f
+#define CONTSETUP_BOUND_HIGHLIGHT_HEIGHT 10
+#define CONTSETUP_BOUND_COLUMN_WIDTH 190.0f
+#define CONTSETUP_LIST_HEADER_HEIGHT 20.0f
+#define CONTSETUP_LIST_TOP 28.0f
+#define CONTSETUP_LIST_RIGHT 18.0f
+#define CONTSETUP_LIST_BOTTOM 120.0f
+#define CONTSETUP_LIST_LEFT 18.0f
+#define CONTSETUP_COLUMN_1_X 40.0f
+#define CONTSETUP_COLUMN_2_X 210.0f
+#define CONTSETUP_COLUMN_3_X (CONTSETUP_COLUMN_2_X + CONTSETUP_BOUND_COLUMN_WIDTH + 10.0f)
+#define CONTSETUP_BACK_RIGHT 35.0f
+#define CONTSETUP_BACK_BOTTOM 122.0f
+#define CONTSETUP_BACK_HEIGHT 25.0f
+
enum eLanguages
{
LANGUAGE_AMERICAN,
@@ -87,6 +121,8 @@ enum eFrontendSprites
FE_RADIO7,
FE_RADIO8,
FE_RADIO9,
+
+ NUM_FE_SPRITES
};
enum eMenuSprites
@@ -110,6 +146,8 @@ enum eMenuSprites
MENUSPRITE_UPOFF,
MENUSPRITE_UPON,
MENUSPRITE_GTA3LOGO,
+ MENUSPRITE_UNUSED,
+ NUM_MENU_SPRITES
};
enum eSaveSlot
@@ -127,6 +165,22 @@ enum eSaveSlot
SAVESLOT_LABEL = 36
};
+#ifdef MENU_MAP
+enum MapSprites
+{
+ MAPMID1,
+ MAPMID2,
+ MAPMID3,
+ MAPBOT1,
+ MAPBOT2,
+ MAPBOT3,
+ MAPTOP1,
+ MAPTOP2,
+ MAPTOP3,
+ NUM_MAP_SPRITES
+};
+#endif
+
enum eMenuScreen
{
MENUPAGE_DISABLED = -1,
@@ -143,19 +197,19 @@ enum eMenuScreen
MENUPAGE_NEW_GAME_RELOAD = 10,
MENUPAGE_LOAD_SLOT_CONFIRM = 11,
MENUPAGE_DELETE_SLOT_CONFIRM = 12,
- MENUPAGE_13 = 13,
+ MENUPAGE_NO_MEMORY_CARD = 13, // hud adjustment page in mobile
MENUPAGE_LOADING_IN_PROGRESS = 14,
MENUPAGE_DELETING_IN_PROGRESS = 15,
- MENUPAGE_16 = 16,
+ MENUPAGE_PS2_LOAD_FAILED = 16,
MENUPAGE_DELETE_FAILED = 17,
MENUPAGE_DEBUG_MENU = 18,
- MENUPAGE_MEMORY_CARD_1 = 19,
- MENUPAGE_MEMORY_CARD_2 = 20,
+ MENUPAGE_MEMORY_CARD_DEBUG = 19,
+ MENUPAGE_MEMORY_CARD_TEST = 20,
MENUPAGE_MULTIPLAYER_MAIN = 21,
- MENUPAGE_SAVE_FAILED_1 = 22,
- MENUPAGE_SAVE_FAILED_2 = 23,
+ MENUPAGE_PS2_SAVE_FAILED = 22,
+ MENUPAGE_PS2_SAVE_FAILED_2 = 23,
MENUPAGE_SAVE = 24,
- MENUPAGE_NO_MEMORY_CARD = 25,
+ MENUPAGE_NO_MEMORY_CARD_2 = 25,
MENUPAGE_CHOOSE_SAVE_SLOT = 26,
MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27,
MENUPAGE_MULTIPLAYER_MAP = 28,
@@ -187,8 +241,11 @@ enum eMenuScreen
MENUPAGE_SKIN_SELECT = 54,
MENUPAGE_KEYBOARD_CONTROLS = 55,
MENUPAGE_MOUSE_CONTROLS = 56,
- MENUPAGE_57 = 57,
+ MENUPAGE_57 = 57, // mission failed, wanna restart page in mobile
MENUPAGE_58 = 58,
+#ifdef MENU_MAP
+ MENUPAGE_MAP = 59,
+#endif
MENUPAGES
};
@@ -322,7 +379,7 @@ enum eCheckHover
HOVEROPTION_6,
HOVEROPTION_7,
HOVEROPTION_8,
- HOVEROPTION_BACK, // used in controller setup
+ HOVEROPTION_BACK, // also layer in controller setup and skin menu
HOVEROPTION_10,
HOVEROPTION_11,
HOVEROPTION_OVER_SCROLL_UP,
@@ -332,9 +389,9 @@ enum eCheckHover
HOVEROPTION_HOLDING_SCROLLBAR,
HOVEROPTION_PAGEUP,
HOVEROPTION_PAGEDOWN,
- HOVEROPTION_19,
- HOVEROPTION_20,
- HOVEROPTION_CHANGESKIN,
+ HOVEROPTION_LIST, // also layer in controller setup and skin menu
+ HOVEROPTION_SKIN,
+ HOVEROPTION_USESKIN, // also layer in controller setup and skin menu
HOVEROPTION_RADIO_0,
HOVEROPTION_RADIO_1,
HOVEROPTION_RADIO_2,
@@ -369,13 +426,20 @@ enum eControlMethod
CONTROL_CLASSIC,
};
+// Why??
+enum ControllerSetupColumn
+{
+ CONTSETUP_PED_COLUMN = 0,
+ CONTSETUP_VEHICLE_COLUMN = 14,
+};
+
struct tSkinInfo
{
- int32 field_0;
- char skinName[256];
- char currSkinName[256];
+ int32 skinId;
+ char skinNameDisplayed[256];
+ char skinNameOriginal[256];
char date[256];
- tSkinInfo *field_304;
+ tSkinInfo *nextSkin;
};
struct BottomBarOption
@@ -387,7 +451,7 @@ struct BottomBarOption
struct CMenuScreen
{
char m_ScreenName[8];
- int32 unk;
+ int32 unk; // 2 on MENUPAGE_MULTIPLAYER_START, 1 on everywhere else
int32 m_PreviousPage[2]; // eMenuScreen
int32 m_ParentEntry[2]; // row
@@ -413,7 +477,7 @@ public:
bool m_bMenuActive;
bool m_bMenuStateChanged;
bool m_bWaitingForNewKeyBind;
- bool m_bStartGameLoading;
+ bool m_bWantToRestart;
bool m_bFirstTime;
bool m_bGameNotLoaded;
int32 m_nMousePosX;
@@ -421,24 +485,24 @@ public:
int32 m_nMouseTempPosX;
int32 m_nMouseTempPosY;
bool m_bShowMouse;
- tSkinInfo m_sSkin;
+ tSkinInfo m_pSkinListHead;
tSkinInfo *m_pSelectedSkin;
int32 m_nFirstVisibleRowOnList;
- float m_nCurListItemY;
+ float m_nScrollbarTopMargin;
int32 m_nTotalListRow;
int32 m_nSkinsTotal;
char _unk0[4];
int32 m_nSelectedListRow;
- bool m_bSkinsFound;
+ bool m_bSkinsEnumerated;
bool m_bQuitGameNoCD;
bool m_bRenderGameInMenu;
bool m_bSaveMenuActive;
- bool m_bLoadingSavedGame;
+ bool m_bWantToLoad;
char field_455;
bool m_bStartWaitingForKeyBind;
bool m_bSpritesLoaded;
- CSprite2d m_aFrontEndSprites[28];
- CSprite2d m_aMenuSprites[20];
+ CSprite2d m_aFrontEndSprites[NUM_FE_SPRITES];
+ CSprite2d m_aMenuSprites[NUM_MENU_SPRITES];
int32 field_518;
int32 m_nMenuFadeAlpha;
bool m_bPressedPgUpOnList;
@@ -448,10 +512,10 @@ public:
bool m_bPressedScrollButton;
int32 m_CurrCntrlAction;
char _unk1[4];
- int32 field_530;
+ int32 m_nSelectedContSetupColumn;
bool m_bKeyIsOK;
bool field_535;
- int8 m_nCurrExLayer; // TODO: What's that?
+ int8 m_nCurrExLayer;
int32 m_nHelperTextAlpha;
int32 m_nMouseOldPosX;
int32 m_nMouseOldPosY;
@@ -468,47 +532,58 @@ public:
bool GetIsMenuActive() {return !!m_bMenuActive;}
public:
- static int32 &OS_Language;
- static int8 &m_PrefsUseVibration;
- static int8 &m_DisplayControllerOnFoot;
- static int8 &m_PrefsUseWideScreen;
- static int8 &m_PrefsRadioStation;
- static int8 &m_PrefsVsync;
- static int8 &m_PrefsVsyncDisp;
- static int8 &m_PrefsFrameLimiter;
- static int8 &m_PrefsShowSubtitles;
- static int8 &m_PrefsSpeakers;
- static int32 &m_ControlMethod;
- static int8 &m_PrefsDMA;
- static int32 &m_PrefsLanguage;
- static int32 &m_PrefsBrightness;
- static float &m_PrefsLOD;
- static int8 &m_bFrontEnd_ReloadObrTxtGxt;
- static int32 &m_PrefsMusicVolume;
- static int32 &m_PrefsSfxVolume;
- static char *m_PrefsSkinFile;
- static int32 &m_KeyPressedCode;
-
- static bool &m_bStartUpFrontEndRequested;
- static bool &m_bShutDownFrontEndRequested;
- static bool &m_PrefsAllowNastyGame;
+ static int32 OS_Language;
+ static int8 m_PrefsUseVibration;
+ static int8 m_DisplayControllerOnFoot;
+ static int8 m_PrefsUseWideScreen;
+ static int8 m_PrefsRadioStation;
+ static int8 m_PrefsVsync;
+ static int8 m_PrefsVsyncDisp;
+ static int8 m_PrefsFrameLimiter;
+ static int8 m_PrefsShowSubtitles;
+ static int8 m_PrefsSpeakers;
+ static int32 m_ControlMethod;
+ static int8 m_PrefsDMA;
+ static int32 m_PrefsLanguage;
+ static int32 m_PrefsBrightness;
+ static float m_PrefsLOD;
+ static int8 m_bFrontEnd_ReloadObrTxtGxt;
+ static int32 m_PrefsMusicVolume;
+ static int32 m_PrefsSfxVolume;
+ static char m_PrefsSkinFile[256];
+ static int32 m_KeyPressedCode;
+
+ static bool m_bStartUpFrontEndRequested;
+ static bool m_bShutDownFrontEndRequested;
+ static bool m_PrefsAllowNastyGame;
- static float &menuXYpadding;
- static float &actionTextScaleX;
- static float &actionTextScaleY;
- static int32 &sthWithButtons;
- static int32 &sthWithButtons2;
-
-#ifndef MASTER
- static bool m_PrefsMarketing;
- static bool m_PrefsDisableTutorials;
-#endif // !MASTER
-
+ static uint8 m_PrefsStereoMono;
+ static int32 m_SelectedMap;
+ static int32 m_SelectedGameType;
+ static uint8 m_PrefsPlayerRed;
+ static uint8 m_PrefsPlayerGreen;
+ static uint8 m_PrefsPlayerBlue;
+
+#ifndef MASTER
+ static bool m_PrefsMarketing;
+ static bool m_PrefsDisableTutorials;
+#endif // !MASTER
+
+#ifdef MENU_MAP
+ static bool bMenuMapActive;
+ static bool bMapMouseShownOnce;
+ static bool bMapLoaded;
+ static float fMapSize;
+ static float fMapCenterY;
+ static float fMapCenterX;
+ static CSprite2d m_aMapSprites[NUM_MAP_SPRITES];
+ void PrintMap();
+#endif
public:
- static void BuildStatLine(char *text, void *stat, uint8 aFloat, void *stat2);
+ static void BuildStatLine(char *text, void *stat, bool itsFloat, void *stat2);
static void CentreMousePointer();
- int CheckCodesForControls(int32);
+ void CheckCodesForControls(int);
bool CheckHover(int x1, int x2, int y1, int y2);
void CheckSliderMovement(int);
int CostructStatLine(int);
@@ -516,7 +591,7 @@ public:
int DisplaySlider(float, float, float, float, float, float);
void DoSettingsBeforeStartingAGame();
void Draw();
- void DrawControllerBound(int, int, int, uint8);
+ void DrawControllerBound(int32, int32, int32, int8);
void DrawControllerScreenExtraText(int, int, int);
void DrawControllerSetupScreen();
void DrawFrontEnd();
@@ -526,13 +601,13 @@ public:
#endif
void DrawPlayerSetupScreen();
int FadeIn(int alpha);
- void FilterOutColorMarkersFromString(uint16, CRGBA &);
+ void FilterOutColorMarkersFromString(wchar*, CRGBA &);
int GetStartOptionsCntrlConfigScreens();
static void InitialiseChangedLanguageSettings();
void LoadAllTextures();
void LoadSettings();
- static void MessageScreen(char *);
- static void PickNewPlayerColour();
+ void MessageScreen(const char *);
+ void PickNewPlayerColour();
void PrintBriefs();
static void PrintErrorMessage();
void PrintStats();
@@ -552,6 +627,8 @@ public:
void UnloadTextures();
void WaitForUserCD();
void PrintController();
+ int GetNumOptionsCntrlConfigScreens();
+ int ConstructStatLine(int);
// New (not in function or inlined in the game)
void ThingsToDoBeforeLeavingPage();
@@ -565,4 +642,4 @@ public:
static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error");
-extern CMenuManager &FrontEndMenuManager;
+extern CMenuManager FrontEndMenuManager;
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 8571e93e..daac3ec5 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -89,8 +89,6 @@
-#define DEFAULT_VIEWWINDOW (0.7f)
-
eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
bool &CGame::nastyGame = *(bool*)0x5F4DD4;
@@ -492,7 +490,7 @@ void CGame::ReInitGameObjectVariables(void)
CParticle::ReloadConfig();
CCullZones::ResolveVisibilities();
- if ( !FrontEndMenuManager.m_bLoadingSavedGame )
+ if ( !FrontEndMenuManager.m_bWantToLoad )
{
CCranes::InitCranes();
CTheScripts::StartTestScript();
@@ -566,7 +564,7 @@ void CGame::InitialiseWhenRestarting(void)
TheCamera.Init();
- if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
+ if ( FrontEndMenuManager.m_bWantToLoad == true )
{
RestoreForStartLoad();
CStreaming::LoadScene(TheCamera.GetPosition());
@@ -574,7 +572,7 @@ void CGame::InitialiseWhenRestarting(void)
ReInitGameObjectVariables();
- if ( FrontEndMenuManager.m_bLoadingSavedGame == true )
+ if ( FrontEndMenuManager.m_bWantToLoad == true )
{
if ( GenericLoad() == true )
{
@@ -593,7 +591,7 @@ void CGame::InitialiseWhenRestarting(void)
ShutDownForRestart();
CTimer::Stop();
CTimer::Initialise();
- FrontEndMenuManager.m_bLoadingSavedGame = false;
+ FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
currLevel = LEVEL_INDUSTRIAL;
CCollision::SortOutCollisionAfterLoad();
@@ -609,6 +607,9 @@ extern void (*DebugMenuProcess)(void);
void CGame::Process(void)
{
CPad::UpdatePads();
+#ifdef GTA_PS2
+ ProcessTidyUpMemory();
+#endif
TheCamera.SetMotionBlurAlpha(0);
if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
@@ -695,6 +696,13 @@ void CGame::TidyUpMemory(bool, bool)
#endif
}
+void CGame::ProcessTidyUpMemory(void)
+{
+#ifdef PS2
+ // meow
+#endif
+}
+
STARTPATCHES
InjectHook(0x48BB80, CGame::InitialiseOnceBeforeRW, PATCH_JUMP);
InjectHook(0x48BBA0, CGame::InitialiseRenderWare, PATCH_JUMP);
diff --git a/src/core/Game.h b/src/core/Game.h
index 318ff54b..30581893 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -39,4 +39,5 @@ public:
// NB: these do something on PS2
static void TidyUpMemory(bool, bool);
static void DrasticTidyUpMemory(bool);
+ static void ProcessTidyUpMemory(void);
};
diff --git a/src/core/MenuScreens.h b/src/core/MenuScreens.h
index 45c5e5d6..8ce2d313 100644
--- a/src/core/MenuScreens.h
+++ b/src/core/MenuScreens.h
@@ -1,18 +1,22 @@
#pragma once
-// There are some missing/wrong entries in here.
+// TODO: There are some missing/wrong entries in here.
const CMenuScreen aScreens[] = {
// MENUPAGE_NONE = 0
- { "", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, },
+ { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, },
- // MENUPAGE_STATS = 1 - Both PrintStats and Draw were printing the page name, so deleted the string Draw looked for.
- { ""/*"FET_STA"*/, MENUPAGE_NONE, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
+ // MENUPAGE_STATS = 1
+#ifdef MENU_MAP
+ { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 3,
+#else
+ { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
+#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_NEW_GAME = 2
- { "FET_SGA", MENUPAGE_NONE, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1,
+ { "FET_SGA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1,
MENUACTION_CHANGEMENU, "FES_SNG", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD,
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMLOAD", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
MENUACTION_POPULATESLOTS_CHANGEMENU, "FES_DGA", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
@@ -20,12 +24,16 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_BRIEFS = 3
- { "FET_BRE", MENUPAGE_NONE, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3,
+#ifdef MENU_MAP
+ { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 4,
+#else
+ { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3,
+#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENU_CONTROLLER_SETTINGS = 4
- { "FET_CON", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
+ { "FET_CON", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
MENUACTION_CTRLDISPLAY, "FEC_CDP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS,
@@ -33,7 +41,7 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_SOUND_SETTINGS = 5
- { "FET_AUD", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 1, 1,
+ { "FET_AUD", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 1, 1,
MENUACTION_MUSICVOLUME, "FEA_MUS", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
MENUACTION_SFXVOLUME, "FEA_SFX", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
MENUACTION_AUDIOHW, "FEA_3DH", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
@@ -45,7 +53,7 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_GRAPHICS_SETTINGS = 6
- { "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2,
+ { "FET_DIS", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 2, 2,
MENUACTION_BRIGHTNESS, "FED_BRI", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
MENUACTION_DRAWDIST, "FEM_LOD", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
MENUACTION_FRAMESYNC, "FEM_VSC", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
@@ -59,7 +67,7 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_LANGUAGE_SETTINGS = 7
- { "FET_LAN", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 3, 3,
+ { "FET_LAN", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 3, 3,
MENUACTION_LANG_ENG, "FEL_ENG", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_FRE, "FEL_FRE", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_LANG_GER, "FEL_GER", SAVESLOT_NONE, MENUPAGE_NONE,
@@ -73,7 +81,7 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_CHOOSE_LOAD_SLOT = 8
- { "FET_LG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 1, 1,
+ { "FET_LG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 1, 1,
MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM,
MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM,
@@ -86,7 +94,7 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_CHOOSE_DELETE_SLOT = 9
- { "FET_DG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 2, 2,
+ { "FET_DG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 2, 2,
MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
MENUACTION_CHECKSAVE, "FEM_SL1", SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM,
MENUACTION_CHECKSAVE, "FEM_SL2", SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM,
@@ -99,104 +107,123 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_NEW_GAME_RELOAD = 10
- { "FET_NG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 0, 0,
+ { "FET_NG", 1, MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, 0, 0,
MENUACTION_LABEL, "FESZ_QR", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
MENUACTION_NEWGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD,
},
// MENUPAGE_LOAD_SLOT_CONFIRM = 11
- { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, 0, 0,
+ { "FET_LG", 1, MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, 0, 0,
MENUACTION_LABEL, "FESZ_QL", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS,
},
// MENUPAGE_DELETE_SLOT_CONFIRM = 12
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
+ { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
MENUACTION_LABEL, "FESZ_QD", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_DELETING,
},
- // MENUPAGE_13 = 13
- { "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // MENUPAGE_NO_MEMORY_CARD = 13
+ { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // hud adjustment page in mobile
},
// MENUPAGE_LOADING_IN_PROGRESS = 14
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_LABEL, "FED_LDW", SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM,
},
// MENUPAGE_DELETING_IN_PROGRESS = 15
- { "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_LABEL, "FEDL_WR", SAVESLOT_NONE, MENUPAGE_NONE,
},
- // MENUPAGE_16 = 16
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_PS2_LOAD_FAILED = 16
+ { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_LABEL, "FES_LOE", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_DELETE_FAILED = 17
- { "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_LABEL, "FES_DEE", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
},
// MENUPAGE_DEBUG_MENU = 18
- { "FED_DBG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ { "FED_DBG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 4, 0,
+ MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_RELOADIPL, "FED_RIP", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_PEDROADGROUPS, "FED_SPR", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_CARROADGROUPS, "FED_SCR", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_COLLISIONPOLYS, "FED_SCP", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_PARSEHEAP, "FED_PAH", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_SHOWCULL, "FED_SCZ", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_DEBUGSTREAM, "FED_DSR", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
- // MENUPAGE_MEMORY_CARD_1 = 19
- { "FEM_MCM", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // MENUPAGE_MEMORY_CARD_DEBUG = 19
+ { "FEM_MCM", 1, MENUPAGE_NONE, MENUPAGE_NONE, 7, 0,
+ MENUACTION_REGMEMCARD1, "FEM_RMC", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_TESTFORMATMEMCARD1, "FEM_TFM", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_TESTUNFORMATMEMCARD1, "FEM_TUM", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_CREATEROOTDIR, "FEM_CRD", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_CREATELOADICONS, "FEM_CLI", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_FILLWITHGUFF, "FEM_FFF", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_SAVEONLYTHEGAME, "FEM_SOG", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_SAVEGAME, "FEM_STG", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_SAVEGAMEUNDERGTA, "FEM_STS", SAVESLOT_NONE, MENUPAGE_NONE,
+ MENUACTION_CREATECOPYPROTECTED, "FEM_CPD", SAVESLOT_NONE, MENUPAGE_NONE,
},
- // MENUPAGE_MEMORY_CARD_2 = 20
- { "FEM_MC2", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_MEMORY_CARD_TEST = 20
+ { "FEM_MC2", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_MULTIPLAYER_MAIN = 21
- { "FET_MP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_MP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
- // MENUPAGE_SAVE_FAILED_1 = 22
- { "MCDNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_PS2_SAVE_FAILED = 22
+ { "MCDNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
},
- // MENUPAGE_SAVE_FAILED_2 = 23
- { "MCGNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ // MENUPAGE_PS2_SAVE_FAILED_2 = 23
+ { "MCGNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
},
// Unused in PC but anyway
// MENUPAGE_SAVE = 24
#ifdef PS2_SAVE_DIALOG
- { "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_CHANGEMENU, "FESZ_SA", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
},
#else
- { "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_LABEL, "FES_SCG", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
},
#endif
- // MENUPAGE_NO_MEMORY_CARD = 25
- { "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // MENUPAGE_NO_MEMORY_CARD_2 = 25
+ { "FES_NOC", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ MENUACTION_CHANGEMENU, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_CHOOSE_SAVE_SLOT = 26
- { "FET_SG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEM_SL1", SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
MENUACTION_CHANGEMENU, "FEM_SL2", SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM,
@@ -209,59 +236,58 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
+ { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
MENUACTION_LABEL, "FESZ_QO", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS,
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
},
// MENUPAGE_MULTIPLAYER_MAP = 28
- { "FET_MAP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_MAP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_MULTIPLAYER_CONNECTION = 29
- { "FET_CON", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_CON", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_MULTIPLAYER_FIND_GAME = 30
- { "FET_FG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_FG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_MULTIPLAYER_MODE = 31
- { "FET_GT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_GT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_MULTIPLAYER_CREATE = 32
- { "FET_HG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_HG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_MULTIPLAYER_START = 33
- { "FEN_STA", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FEN_STA", 2, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_SKIN_SELECT_OLD = 34
- { "FET_PS", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_PS", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_CONTROLLER_PC = 35
- { "FET_CTL", MENUPAGE_DISABLED, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
+ { "FET_CTL", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
MENUACTION_CTRLMETHOD, "FET_CME", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
MENUACTION_CHANGEMENU, "FET_RDK", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS,
MENUACTION_CHANGEMENU, "FET_AMS", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
-
MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_CONTROLLER_PC_OLD1 = 36
- { "FET_CTL", MENUPAGE_DISABLED, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 0, 0,
+ { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 0, 0,
MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
MENUACTION_GETKEY, "FEC_CWR", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1,
@@ -275,12 +301,12 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_CONTROLLER_PC_OLD2 = 37
- { "FET_CTL", MENUPAGE_DISABLED, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
+ { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
},
// MENUPAGE_CONTROLLER_PC_OLD3 = 38
- { "FET_CTL", MENUPAGE_DISABLED, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
+ { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3,
@@ -289,17 +315,25 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_CONTROLLER_PC_OLD4 = 39
- { "FET_CTL", MENUPAGE_DISABLED, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
+ { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
},
// MENUPAGE_CONTROLLER_DEBUG = 40
- { "FEC_DBG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ { "FEC_DBG", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
+ MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
+ MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
+ MENUACTION_GETKEY, "FEC_TSS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
+ MENUACTION_GETKEY, "FEC_SMS", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG,
+ MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_OPTIONS = 41
- { "FET_OPT", MENUPAGE_NONE, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4,
+#ifdef MENU_MAP
+ { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 5,
+#else
+ { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4,
+#endif
MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS,
@@ -309,67 +343,74 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_EXIT = 42
- { "FET_QG", MENUPAGE_NONE, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5,
+#ifdef MENU_MAP
+ { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 6,
+#else
+ { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5,
+#endif
MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_SAVING_IN_PROGRESS = 43
- { "", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
+ { "", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
MENUACTION_LABEL, "FES_WAR", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_SAVE_SUCCESSFUL = 44
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
+ { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
MENUACTION_LABEL, "FES_SSC", SAVESLOT_LABEL, MENUPAGE_NONE,
MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
},
// MENUPAGE_DELETING = 45
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
+ { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
MENUACTION_LABEL, "FED_DLW", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_DELETE_SUCCESS = 46
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
+ { "FET_DG", 1, MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, 0, 0,
MENUACTION_LABEL, "DEL_FNM", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT,
},
// MENUPAGE_SAVE_FAILED = 47
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
+ { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEC_OKK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
},
// MENUPAGE_LOAD_FAILED = 48
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
+ { "FET_SG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
MENUACTION_LABEL, "FEC_SVU", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_LOAD_FAILED_2 = 49
- { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
+ { "FET_LG", 1, MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, 0, 0,
MENUACTION_LABEL, "FEC_LUN", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT,
},
// MENUPAGE_FILTER_GAME = 50
- { "FIL_FLT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FIL_FLT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
},
// MENUPAGE_START_MENU = 51
- { "FEM_MM", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FEM_MM", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
MENUACTION_CHANGEMENU, "FEM_QT", SAVESLOT_NONE, MENUPAGE_EXIT,
},
// MENUPAGE_PAUSE_MENU = 52
- { "FET_PAU", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
+#ifdef MENU_MAP
+ MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP,
+#endif
MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS,
MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
@@ -377,22 +418,24 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_CHOOSE_MODE = 53
- { "FEN_STA", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ { "FEN_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 0, 1,
+ MENUACTION_CHANGEMENU, "FET_SP", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
+ MENUACTION_INITMP, "FET_MP", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN,
+ MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
// MENUPAGE_SKIN_SELECT = 54
- { "FET_PSU", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 4, 4,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN,
+ { "FET_PSU", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 4, 4,
+ MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_MULTIPLAYER_MAIN,
},
// MENUPAGE_KEYBOARD_CONTROLS = 55
- { "FET_STI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
+ { "FET_STI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
+ MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
},
// MENUPAGE_MOUSE_CONTROLS = 56
- { "FET_MTI", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
+ { "FET_MTI", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 2, 2,
MENUACTION_MOUSESENS, "FEC_MSH", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
MENUACTION_INVVERT, "FEC_IVV", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
@@ -400,12 +443,18 @@ const CMenuScreen aScreens[] = {
},
// MENUPAGE_57 = 57
- { "", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
+ // mission failed, wanna restart page in mobile
},
// MENUPAGE_58 = 58
- { "", MENUPAGE_DISABLED, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
+ { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
},
+
+#ifdef MENU_MAP
+ // MENUPAGE_MAP = 59
+ { "FEG_MAP", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
+ },
+#endif
};
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 6bbe00f2..f83998b8 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -21,19 +21,26 @@
#include "Hud.h"
#include "Text.h"
#include "Timer.h"
+#include "Record.h"
#include "World.h"
#include "Vehicle.h"
#include "Ped.h"
#include "Population.h"
+#include "Record.h"
#include "Replay.h"
#include "Weather.h"
#include "win.h"
+#include "Streaming.h"
+#include "PathFind.h"
+#include "Wanted.h"
+#include "General.h"
CPad *Pads = (CPad*)0x6F0360; // [2]
CMousePointerStateHelper &MousePointerStateHelper = *(CMousePointerStateHelper*)0x95CC8C;
bool &CPad::bDisplayNoControllerMessage = *(bool *)0x95CD52;
bool &CPad::bObsoleteControllerMessage = *(bool *)0x95CDB8;
+bool CPad::bOldDisplayNoControllerMessage;
bool &CPad::m_bMapPadOneToPadTwo = *(bool *)0x95CD48;
CKeyboardState &CPad::OldKeyState = *(CKeyboardState*)0x6F1E70;
@@ -49,29 +56,217 @@ CMouseControllerState &CPad::PCTempMouseControllerState = *(CMouseControllerStat
_TODO("gbFastTime");
extern bool &gbFastTime;
-WRAPPER void WeaponCheat() { EAXJMP(0x490D90); }
-WRAPPER void HealthCheat() { EAXJMP(0x490E70); }
-WRAPPER void TankCheat() { EAXJMP(0x490EE0); }
-WRAPPER void BlowUpCarsCheat() { EAXJMP(0x491040); }
-WRAPPER void ChangePlayerCheat() { EAXJMP(0x4910B0); }
-WRAPPER void MayhemCheat() { EAXJMP(0x4911C0); }
-WRAPPER void EverybodyAttacksPlayerCheat() { EAXJMP(0x491270); }
-WRAPPER void WeaponsForAllCheat() { EAXJMP(0x491370); }
-WRAPPER void FastTimeCheat() { EAXJMP(0x4913A0); }
-WRAPPER void SlowTimeCheat() { EAXJMP(0x4913F0); }
-WRAPPER void MoneyCheat() { EAXJMP(0x491430); }
-WRAPPER void ArmourCheat() { EAXJMP(0x491460); }
-WRAPPER void WantedLevelUpCheat() { EAXJMP(0x491490); }
-WRAPPER void WantedLevelDownCheat() { EAXJMP(0x4914F0); }
-WRAPPER void SunnyWeatherCheat() { EAXJMP(0x491520); }
-WRAPPER void CloudyWeatherCheat() { EAXJMP(0x491550); }
-WRAPPER void RainyWeatherCheat() { EAXJMP(0x491580); }
-WRAPPER void FoggyWeatherCheat() { EAXJMP(0x4915B0); }
-WRAPPER void FastWeatherCheat() { EAXJMP(0x4915E0); }
-WRAPPER void OnlyRenderWheelsCheat() { EAXJMP(0x491610); }
-WRAPPER void ChittyChittyBangBangCheat() { EAXJMP(0x491640); }
-WRAPPER void StrongGripCheat() { EAXJMP(0x491670); }
-WRAPPER void NastyLimbsCheat() { EAXJMP(0x4916A0); }
+void WeaponCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT2"), true);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_BASEBALLBAT, 0);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_COLT45, 100);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_UZI, 100);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_SHOTGUN, 20);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_AK47, 200);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_M16, 200);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_SNIPERRIFLE, 5);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_ROCKETLAUNCHER, 5);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_MOLOTOV, 5);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_GRENADE, 5);
+ FindPlayerPed()->GiveWeapon(WEAPONTYPE_FLAMETHROWER, 200);
+}
+
+void HealthCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT3"), true);
+ FindPlayerPed()->m_fHealth = 100.0f;
+ if (FindPlayerVehicle()) {
+ FindPlayerVehicle()->m_fHealth = 1000.0f;
+ if (FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_CAR)
+ ((CAutomobile*)FindPlayerVehicle())->Damage.SetEngineStatus(0);
+ }
+}
+
+void TankCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CStreaming::RequestModel(MI_RHINO, 0);
+ CStreaming::LoadAllRequestedModels(false);
+ if (CStreaming::ms_aInfoForModel[MI_RHINO].m_loadState == STREAMSTATE_LOADED) {
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f);
+
+ if (node < 0) return;
+
+#ifdef FIX_BUGS
+ CAutomobile* tank = new CAutomobile(MI_RHINO, RANDOM_VEHICLE);
+#else
+ CAutomobile *tank = new CAutomobile(MI_RHINO, MISSION_VEHICLE);
+#endif
+ if (tank != nil) {
+ CVector pos = ThePaths.m_pathNodes[node].pos;
+ pos.z += 4.0f;
+ tank->GetPosition() = pos;
+ tank->SetOrientation(0.0f, 0.0f, DEGTORAD(200.0f));
+
+ tank->m_status = STATUS_ABANDONED;
+ tank->m_nDoorLock = CARLOCK_UNLOCKED;
+ CWorld::Add(tank);
+ }
+ }
+}
+
+void BlowUpCarsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+
+ int i = CPools::GetVehiclePool()->GetSize();
+ while (i-- > 0) {
+ if (CVehicle *veh = CPools::GetVehiclePool()->GetSlot(i))
+ veh->BlowUpCar(nil);
+ }
+}
+
+void ChangePlayerCheat()
+{
+ int modelId;
+
+ if (FindPlayerPed()->IsPedInControl() && CModelInfo::GetModelInfo("player", nil)) {
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CPlayerPed *ped = FindPlayerPed();
+ AssocGroupId AnimGrp = ped->m_animGroup;
+ do
+ {
+ do
+ modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1);
+ while (!CModelInfo::GetModelInfo(modelId));
+ } while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D);
+
+ uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags;
+ ped->DeleteRwObject();
+ CStreaming::RequestModel(modelId, STREAMFLAGS_DEPENDENCY| STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+ ped->m_modelIndex = -1;
+ ped->SetModelIndex(modelId);
+ ped->m_animGroup = AnimGrp;
+ if (modelId != MI_PLAYER) {
+ if (!(flags & STREAMFLAGS_DONT_REMOVE))
+ CStreaming::SetModelIsDeletable(modelId);
+ }
+ }
+}
+
+void MayhemCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
+ CPedType::SetThreats(i, PED_FLAG_PLAYER1 | PED_FLAG_PLAYER2 | PED_FLAG_PLAYER3 | PED_FLAG_PLAYER4 |
+ PED_FLAG_CIVMALE | PED_FLAG_CIVFEMALE | PED_FLAG_COP | PED_FLAG_GANG1 |
+ PED_FLAG_GANG2 | PED_FLAG_GANG3 | PED_FLAG_GANG4 | PED_FLAG_GANG5 |
+ PED_FLAG_GANG6 | PED_FLAG_GANG7 | PED_FLAG_GANG8 | PED_FLAG_GANG9 |
+ PED_FLAG_EMERGENCY | PED_FLAG_PROSTITUTE | PED_FLAG_CRIMINAL | PED_FLAG_SPECIAL );
+}
+
+void EverybodyAttacksPlayerCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ for (int i = PEDTYPE_CIVMALE; i < PEDTYPE_SPECIAL; i++)
+ CPedType::AddThreat(i, PED_FLAG_PLAYER1);
+}
+
+void WeaponsForAllCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CPopulation::ms_bGivePedsWeapons = !CPopulation::ms_bGivePedsWeapons;
+}
+
+void FastTimeCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ if (CTimer::GetTimeScale() < 4.0f)
+ CTimer::SetTimeScale(CTimer::GetTimeScale() * 2.0f);
+}
+
+void SlowTimeCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ if (CTimer::GetTimeScale() > 0.25f)
+ CTimer::SetTimeScale(CTimer::GetTimeScale() * 0.5f);
+}
+
+void MoneyCheat()
+{
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 250000;
+ CHud::SetHelpMessage(TheText.Get("CHEAT6"), true);
+}
+
+void ArmourCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT4"), true);
+ FindPlayerPed()->m_fArmour = 100.0f;
+}
+
+void WantedLevelUpCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
+ FindPlayerPed()->SetWantedLevel(min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6));
+}
+
+void WantedLevelDownCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
+ FindPlayerPed()->SetWantedLevel(0);
+}
+
+void SunnyWeatherCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
+ CWeather::ForceWeatherNow(WEATHER_SUNNY);
+}
+
+void CloudyWeatherCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
+ CWeather::ForceWeatherNow(WEATHER_CLOUDY);
+}
+
+void RainyWeatherCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
+ CWeather::ForceWeatherNow(WEATHER_RAINY);
+}
+
+void FoggyWeatherCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT7"), true);
+ CWeather::ForceWeatherNow(WEATHER_FOGGY);
+}
+
+void FastWeatherCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ gbFastTime = !gbFastTime;
+}
+
+void OnlyRenderWheelsCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CVehicle::bWheelsOnlyCheat = !CVehicle::bWheelsOnlyCheat;
+}
+
+
+void ChittyChittyBangBangCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CVehicle::bAllDodosCheat = !CVehicle::bAllDodosCheat;
+}
+
+void StrongGripCheat()
+{
+ CHud::SetHelpMessage(TheText.Get("CHEAT1"), true);
+ CVehicle::bCheat3 = !CVehicle::bCheat3;
+}
+
+void NastyLimbsCheat()
+{
+ CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat;
+}
//////////////////////////////////////////////////////////////////////////
#ifdef KANGAROO_CHEAT
@@ -88,7 +283,7 @@ void KangarooCheat()
string = TheText.Get("CHEAT1");
m_fMass = 15.0f;
}
- CHud::SetHelpMessage(string, 1);
+ CHud::SetHelpMessage(string, true);
playerPed->m_ped_flagI80 = !playerPed->m_ped_flagI80;
playerPed->m_fMass = m_fMass;
@@ -137,6 +332,21 @@ void CKeyboardState::Clear()
LWIN = RWIN = APPS = 0;
}
+#ifdef GTA_PS2_STUFF
+void CPad::Initialise(void)
+{
+ for (int i = 0; i < MAX_PADS; i++)
+ {
+ CPad::GetPad(i)->Clear(true);
+ CPad::GetPad(i)->Mode = 0;
+ }
+
+ bObsoleteControllerMessage = false;
+ bOldDisplayNoControllerMessage = false;
+ bDisplayNoControllerMessage = false;
+}
+#endif
+
void CPad::Clear(bool bResetPlayerControls)
{
NewState.Clear();
@@ -164,13 +374,13 @@ void CPad::Clear(bool bResetPlayerControls)
bApplyBrakes = false;
- for ( int32 i = 0; i < _TODOCONST(5); i++ )
+ for ( int32 i = 0; i < HORNHISTORY_SIZE; i++ )
bHornHistory[i] = false;
iCurrHornHistory = 0;
- for ( int32 i = 0; i < _TODOCONST(12); i++ )
- _unk[i] = ' ';
+ for ( int32 i = 0; i < ARRAY_SIZE(CheatString); i++ )
+ CheatString[i] = ' ';
LastTimeTouched = CTimer::GetTimeInMilliseconds();
AverageWeapon = 0;
@@ -429,6 +639,108 @@ void CPad::StartShake_Train(float fX, float fY)
}
}
+#ifdef GTA_PS2_STUFF
+void CPad::AddToCheatString(char c)
+{
+ for ( int32 i = ARRAY_SIZE(CheatString) - 2; i >= 0; i-- )
+ CheatString[i + 1] = CheatString[i];
+
+#define _CHEATCMP(str) strncmp(str, CheatString, sizeof(str)-1)
+ // "4414LDRULDRU" - R2 R2 L1 R2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+ if ( !_CHEATCMP("URDLURDL4144") )
+ WeaponCheat();
+
+ // "4411LDRULDRU" - R2 R2 L1 L1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+ else if ( !_CHEATCMP("URDLURDL1144") )
+ MoneyCheat();
+
+ // "4412LDRULDRU" - R2 R2 L1 L2 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+ else if ( !_CHEATCMP("URDLURDL2144") )
+ ArmourCheat();
+
+ // "4413LDRULDRU" - R2 R2 L1 R1 LEFT DOWN RIGHT UP LEFT DOWN RIGHT UP
+ else if ( !_CHEATCMP("URDLURDL3144") )
+ HealthCheat();
+
+ // "4414LRLRLR" - R2 R2 L1 R2 LEFT RIGHT LEFT RIGHT LEFT RIGHT
+ else if ( !_CHEATCMP("RLRLRL4144") )
+ WantedLevelUpCheat();
+
+ // "4414UDUDUD" - R2 R2 L1 R2 UP DOWN UP DOWN UP DOWN
+ else if ( !_CHEATCMP("DUDUDU4144") )
+ WantedLevelDownCheat();
+
+ // "1234432T" - L1 L2 R1 R2 R2 R1 L2 TRIANGLE
+ else if ( !_CHEATCMP("T2344321") )
+ SunnyWeatherCheat();
+
+ // "1234432S" - L1 L2 R1 R2 R2 R1 L2 SQUARE
+ else if ( !_CHEATCMP("S2344321") )
+ CloudyWeatherCheat();
+
+ // "1234432C" - L1 L2 R1 R2 R2 R1 L2 CIRCLE
+ else if ( !_CHEATCMP("C2344321") )
+ RainyWeatherCheat();
+
+ // "1234432X" - L1 L2 R1 R2 R2 R1 L2 CROSS
+ else if ( !_CHEATCMP("X2344321") )
+ FoggyWeatherCheat();
+
+ // "CCCCCC321TCT" - CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE
+ else if ( !_CHEATCMP("TCT123CCCCCC") )
+ TankCheat();
+
+ // "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE
+ else if ( !_CHEATCMP("TCT1SSSSSCCC") )
+ FastWeatherCheat();
+
+ // "241324TSCT21" - L2 R2 L1 R1 L2 R2 TRIANGLE SQUARE CIRCLE TRIANGLE L2 L1
+ else if ( !_CHEATCMP("12TCST423142") )
+ BlowUpCarsCheat();
+
+ // "RDLU12ULDR" - RIGHT DOWN LEFT UP L1 L2 UP LEFT DOWN RIGHT
+ else if ( !_CHEATCMP("RDLU21ULDR") )
+ ChangePlayerCheat();
+
+ // "DULUX3421" - DOWN UP LEFT UP CROSS R1 R2 L2 L1
+ else if ( !_CHEATCMP("1243XULUD") )
+ MayhemCheat();
+
+ // "DULUX3412" - DOWN UP LEFT UP CROSS R1 R2 L1 L2
+ else if ( !_CHEATCMP("2143XULUD") )
+ EverybodyAttacksPlayerCheat();
+
+ // "43TX21UD" - R2 R1 TRIANGLE CROSS L2 L1 UP DOWN
+ else if ( !_CHEATCMP("DU12XT34") )
+ WeaponsForAllCheat();
+
+ // "TURDS12" - TRIANGLE UP RIGHT DOWN SQUARE L1 L2
+ else if ( !_CHEATCMP("21SDRUT") )
+ FastTimeCheat();
+
+ // "TURDS34" - TRIANGLE UP RIGHT DOWN SQUARE R1 R2
+ else if ( !_CHEATCMP("43SDRUT") )
+ SlowTimeCheat();
+
+ // "11S4T1T" - L1 L1 SQUARE R2 TRIANGLE L1 TRIANGLE
+ else if ( !_CHEATCMP("T1T4S11") )
+ OnlyRenderWheelsCheat();
+
+ // "R4C32D13" - RIGHT R2 CIRCLE R1 L2 DOWN L1 R1
+ else if ( !_CHEATCMP("31D23C4R") )
+ ChittyChittyBangBangCheat();
+
+ // "3141L33T" - R1 L1 R2 L1 LEFT R1 R1 TRIANGLE
+ else if ( !_CHEATCMP("T33L1413") )
+ StrongGripCheat();
+
+ // "S1CD13TR1X" - SQUARE L1 CIRCLE DOWN L1 R1 TRIANGLE RIGHT L1 CROSS
+ else if ( !_CHEATCMP("X1RT31DC1S") )
+ NastyLimbsCheat();
+#undef _CHEATCMP
+}
+#endif
+
void CPad::AddToPCCheatString(char c)
{
for ( int32 i = ARRAY_SIZE(KeyBoardCheatString) - 2; i >= 0; i-- )
@@ -657,16 +969,21 @@ void CPad::Update(int16 unk)
{
OldState = NewState;
- NewState = ReconcileTwoControllersInput(PCTempKeyState, PCTempJoyState);
- NewState = ReconcileTwoControllersInput(PCTempMouseState, NewState);
-
+#if (defined GTA_PS2 || defined FIX_BUGS)
+ if (!CRecordDataForGame::IsPlayingBack() && !CRecordDataForChase::ShouldThisPadBeLeftAlone(unk))
+#endif
+ {
+ NewState = ReconcileTwoControllersInput(PCTempKeyState, PCTempJoyState);
+ NewState = ReconcileTwoControllersInput(PCTempMouseState, NewState);
+ }
+
PCTempJoyState.Clear();
PCTempKeyState.Clear();
PCTempMouseState.Clear();
ProcessPCSpecificStuff();
- if ( ++iCurrHornHistory >= _TODOCONST(5) )
+ if ( ++iCurrHornHistory >= HORNHISTORY_SIZE )
iCurrHornHistory = 0;
bHornHistory[iCurrHornHistory] = GetHorn();
@@ -683,7 +1000,7 @@ void CPad::DoCheats(void)
void CPad::DoCheats(int16 unk)
{
-#ifdef PS2
+#ifdef GTA_PS2_STUFF
if ( GetTriangleJustDown() )
AddToCheatString('T');
@@ -2086,7 +2403,31 @@ int32 *CPad::EditCodesForControls(int32 *pRsKeys, int32 nSize)
return pRsKeys;
}
-STARTPATCHES
+STARTPATCHES
+ InjectHook(0x490D90, &WeaponCheat, PATCH_JUMP);
+ InjectHook(0x490E70, &HealthCheat, PATCH_JUMP);
+ InjectHook(0x490EE0, &TankCheat, PATCH_JUMP);
+ InjectHook(0x491040, &BlowUpCarsCheat, PATCH_JUMP);
+ InjectHook(0x4910B0, &ChangePlayerCheat, PATCH_JUMP);
+ InjectHook(0x4911C0, &MayhemCheat, PATCH_JUMP);
+ InjectHook(0x491270, &EverybodyAttacksPlayerCheat, PATCH_JUMP);
+ InjectHook(0x491370, &WeaponsForAllCheat, PATCH_JUMP);
+ InjectHook(0x4913A0, &FastTimeCheat, PATCH_JUMP);
+ InjectHook(0x4913F0, &SlowTimeCheat, PATCH_JUMP);
+ InjectHook(0x491430, &MoneyCheat, PATCH_JUMP);
+ InjectHook(0x491460, &ArmourCheat, PATCH_JUMP);
+ InjectHook(0x491490, &WantedLevelUpCheat, PATCH_JUMP);
+ InjectHook(0x4914F0, &WantedLevelDownCheat, PATCH_JUMP);
+ InjectHook(0x491520, &SunnyWeatherCheat, PATCH_JUMP);
+ InjectHook(0x491550, &CloudyWeatherCheat, PATCH_JUMP);
+ InjectHook(0x491580, &RainyWeatherCheat, PATCH_JUMP);
+ InjectHook(0x4915B0, &FoggyWeatherCheat, PATCH_JUMP);
+ InjectHook(0x4915E0, &FastWeatherCheat, PATCH_JUMP);
+ InjectHook(0x491610, &OnlyRenderWheelsCheat, PATCH_JUMP);
+ InjectHook(0x491640, &ChittyChittyBangBangCheat, PATCH_JUMP);
+ InjectHook(0x491670, &StrongGripCheat, PATCH_JUMP);
+ InjectHook(0x4916A0, &NastyLimbsCheat, PATCH_JUMP);
+
InjectHook(0x4916C0, &CControllerState::Clear, PATCH_JUMP);
InjectHook(0x491760, &CKeyboardState::Clear, PATCH_JUMP);
InjectHook(0x491A10, &CPad::Clear, PATCH_JUMP);
diff --git a/src/core/Pad.h b/src/core/Pad.h
index ca44a9f7..cb705c6b 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -136,6 +136,10 @@ enum
class CPad
{
public:
+ enum
+ {
+ HORNHISTORY_SIZE = 5,
+ };
CControllerState NewState;
CControllerState OldState;
CControllerState PCTempKeyState;
@@ -146,11 +150,11 @@ public:
int16 Mode;
int16 ShakeDur;
uint8 ShakeFreq;
- bool bHornHistory[5];
+ bool bHornHistory[HORNHISTORY_SIZE];
uint8 iCurrHornHistory;
uint8 DisablePlayerControls;
int8 bApplyBrakes;
- char _unk[12]; //int32 unk[3];
+ char CheatString[12];
char _pad0[3];
int32 LastTimeTouched;
int32 AverageWeapon;
@@ -161,6 +165,7 @@ public:
static bool &bDisplayNoControllerMessage;
static bool &bObsoleteControllerMessage;
+ static bool bOldDisplayNoControllerMessage;
static bool &m_bMapPadOneToPadTwo;
static CKeyboardState &OldKeyState;
@@ -172,8 +177,9 @@ public:
static CMouseControllerState &PCTempMouseControllerState;
-
-
+#ifdef GTA_PS2_STUFF
+ static void Initialise(void);
+#endif
void Clear(bool bResetPlayerControls);
void ClearMouseHistory();
void UpdateMouse();
@@ -181,6 +187,9 @@ public:
void StartShake(int16 nDur, uint8 nFreq);
void StartShake_Distance(int16 nDur, uint8 nFreq, float fX, float fY, float fz);
void StartShake_Train(float fX, float fY);
+#ifdef GTA_PS2_STUFF
+ void AddToCheatString(char c);
+#endif
void AddToPCCheatString(char c);
static void UpdatePads(void);
@@ -409,6 +418,7 @@ public:
bool GetLeftStickXJustDown() { return !!(NewState.LeftStickX && !OldState.LeftStickX); }
bool GetLeftStickYJustDown() { return !!(NewState.LeftStickY && !OldState.LeftStickY); }
+ bool GetTriangleJustUp() { return !!(!NewState.Triangle && OldState.Triangle); }
bool GetCrossJustUp() { return !!(!NewState.Cross && OldState.Cross); }
bool GetSquareJustUp() { return !!(!NewState.Square && OldState.Square); }
bool GetDPadUpJustUp() { return !!(!NewState.DPadUp && OldState.DPadUp); }
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index ead32ee7..0043c2f4 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -48,45 +48,45 @@ CPlayerInfo::GetPos()
void
CPlayerInfo::LoadPlayerSkin()
-{
- DeletePlayerSkin();
-
- m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
- if (!m_pSkinTexture)
+{
+ DeletePlayerSkin();
+
+ m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
+ if (!m_pSkinTexture)
m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
}
void
CPlayerInfo::DeletePlayerSkin()
-{
- if (m_pSkinTexture) {
- RwTextureDestroy(m_pSkinTexture);
- m_pSkinTexture = nil;
+{
+ if (m_pSkinTexture) {
+ RwTextureDestroy(m_pSkinTexture);
+ m_pSkinTexture = nil;
}
}
-void
-CPlayerInfo::KillPlayer()
-{
- if (m_WBState != WBSTATE_PLAYING) return;
-
- m_WBState = WBSTATE_WASTED;
- m_nWBTime = CTimer::GetTimeInMilliseconds();
- CDarkel::ResetOnPlayerDeath();
- CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
- CStats::TimesDied++;
+void
+CPlayerInfo::KillPlayer()
+{
+ if (m_WBState != WBSTATE_PLAYING) return;
+
+ m_WBState = WBSTATE_WASTED;
+ m_nWBTime = CTimer::GetTimeInMilliseconds();
+ CDarkel::ResetOnPlayerDeath();
+ CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
+ CStats::TimesDied++;
}
-void
-CPlayerInfo::ArrestPlayer()
-{
- if (m_WBState != WBSTATE_PLAYING) return;
-
- m_WBState = WBSTATE_BUSTED;
- m_nWBTime = CTimer::GetTimeInMilliseconds();
- CDarkel::ResetOnPlayerDeath();
- CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
- CStats::TimesArrested++;
+void
+CPlayerInfo::ArrestPlayer()
+{
+ if (m_WBState != WBSTATE_PLAYING) return;
+
+ m_WBState = WBSTATE_BUSTED;
+ m_nWBTime = CTimer::GetTimeInMilliseconds();
+ CDarkel::ResetOnPlayerDeath();
+ CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
+ CStats::TimesArrested++;
}
bool
@@ -105,102 +105,102 @@ CPlayerInfo::PlayerFailedCriticalMission()
CDarkel::ResetOnPlayerDeath();
}
-void
-CPlayerInfo::Clear(void)
-{
- m_pPed = nil;
- m_pRemoteVehicle = nil;
- if (m_pVehicleEx) {
- m_pVehicleEx->bUsingSpecialColModel = false;
- m_pVehicleEx = nil;
- }
- m_nVisibleMoney = 0;
- m_nMoney = m_nVisibleMoney;
- m_WBState = WBSTATE_PLAYING;
- m_nWBTime = 0;
- m_nTrafficMultiplier = 0;
- m_fRoadDensity = 1.0f;
- m_bInRemoteMode = false;
- m_bUnusedTaxiThing = false;
- m_nUnusedTaxiTimer = 0;
- m_nCollectedPackages = 0;
- m_nTotalPackages = 3;
- m_nTimeLastHealthLoss = 0;
- m_nTimeLastArmourLoss = 0;
- m_nNextSexFrequencyUpdateTime = 0;
- m_nNextSexMoneyUpdateTime = 0;
- m_nSexFrequency = 0;
- m_pHooker = nil;
- m_nTimeTankShotGun = 0;
- field_248 = 0;
- m_nUpsideDownCounter = 0;
- m_bInfiniteSprint = false;
- m_bFastReload = false;
- m_bGetOutOfJailFree = false;
- m_bGetOutOfHospitalFree = false;
- m_nPreviousTimeRewardedForExplosion = 0;
- m_nExplosionsSinceLastReward = 0;
+void
+CPlayerInfo::Clear(void)
+{
+ m_pPed = nil;
+ m_pRemoteVehicle = nil;
+ if (m_pVehicleEx) {
+ m_pVehicleEx->bUsingSpecialColModel = false;
+ m_pVehicleEx = nil;
+ }
+ m_nVisibleMoney = 0;
+ m_nMoney = m_nVisibleMoney;
+ m_WBState = WBSTATE_PLAYING;
+ m_nWBTime = 0;
+ m_nTrafficMultiplier = 0;
+ m_fRoadDensity = 1.0f;
+ m_bInRemoteMode = false;
+ m_bUnusedTaxiThing = false;
+ m_nUnusedTaxiTimer = 0;
+ m_nCollectedPackages = 0;
+ m_nTotalPackages = 3;
+ m_nTimeLastHealthLoss = 0;
+ m_nTimeLastArmourLoss = 0;
+ m_nNextSexFrequencyUpdateTime = 0;
+ m_nNextSexMoneyUpdateTime = 0;
+ m_nSexFrequency = 0;
+ m_pHooker = nil;
+ m_nTimeTankShotGun = 0;
+ field_248 = 0;
+ m_nUpsideDownCounter = 0;
+ m_bInfiniteSprint = false;
+ m_bFastReload = false;
+ m_bGetOutOfJailFree = false;
+ m_bGetOutOfHospitalFree = false;
+ m_nPreviousTimeRewardedForExplosion = 0;
+ m_nExplosionsSinceLastReward = 0;
}
-void
-CPlayerInfo::BlowUpRCBuggy(void)
-{
- if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
- return;
-
- CRemote::TakeRemoteControlledCarFromPlayer();
- m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
+void
+CPlayerInfo::BlowUpRCBuggy(void)
+{
+ if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
+ return;
+
+ CRemote::TakeRemoteControlledCarFromPlayer();
+ m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
}
-
-void
-CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
-{
- if (!car || car == m_pPed->m_pMyVehicle) {
- if (m_pPed->EnteringCar())
- m_pPed->QuitEnteringCar();
- }
- if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
- m_pPed->ClearObjective();
+
+void
+CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
+{
+ if (!car || car == m_pPed->m_pMyVehicle) {
+ if (m_pPed->EnteringCar())
+ m_pPed->QuitEnteringCar();
+ }
+ if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
+ m_pPed->ClearObjective();
}
-void
-CPlayerInfo::MakePlayerSafe(bool toggle)
-{
- if (toggle) {
- CTheScripts::ResetCountdownToMakePlayerUnsafe();
- m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
- CWorld::StopAllLawEnforcersInTheirTracks();
- CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
- CPad::StopPadsShaking();
- m_pPed->bBulletProof = true;
- m_pPed->bFireProof = true;
- m_pPed->bCollisionProof = true;
- m_pPed->bMeleeProof = true;
- m_pPed->bOnlyDamagedByPlayer = true;
- m_pPed->bExplosionProof = true;
- m_pPed->m_bCanBeDamaged = false;
- ((CPlayerPed*)m_pPed)->ClearAdrenaline();
- CancelPlayerEnteringCars(false);
- gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
- CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
- CProjectileInfo::RemoveAllProjectiles();
- CWorld::SetAllCarsCanBeDamaged(false);
- CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
- CReplay::DisableReplays();
-
- } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) {
- m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
- CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
- m_pPed->bBulletProof = false;
- m_pPed->bFireProof = false;
- m_pPed->bCollisionProof = false;
- m_pPed->bMeleeProof = false;
- m_pPed->bOnlyDamagedByPlayer = false;
- m_pPed->bExplosionProof = false;
- m_pPed->m_bCanBeDamaged = true;
- CWorld::SetAllCarsCanBeDamaged(true);
- CReplay::EnableReplays();
- }
+void
+CPlayerInfo::MakePlayerSafe(bool toggle)
+{
+ if (toggle) {
+ CTheScripts::ResetCountdownToMakePlayerUnsafe();
+ m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
+ CWorld::StopAllLawEnforcersInTheirTracks();
+ CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20;
+ CPad::StopPadsShaking();
+ m_pPed->bBulletProof = true;
+ m_pPed->bFireProof = true;
+ m_pPed->bCollisionProof = true;
+ m_pPed->bMeleeProof = true;
+ m_pPed->bOnlyDamagedByPlayer = true;
+ m_pPed->bExplosionProof = true;
+ m_pPed->m_bCanBeDamaged = false;
+ ((CPlayerPed*)m_pPed)->ClearAdrenaline();
+ CancelPlayerEnteringCars(false);
+ gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
+ CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
+ CProjectileInfo::RemoveAllProjectiles();
+ CWorld::SetAllCarsCanBeDamaged(false);
+ CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
+ CReplay::DisableReplays();
+
+ } else if (!CGame::playingIntro && !CTheScripts::IsCountdownToMakePlayerUnsafeOn()) {
+ m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
+ CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20;
+ m_pPed->bBulletProof = false;
+ m_pPed->bFireProof = false;
+ m_pPed->bCollisionProof = false;
+ m_pPed->bMeleeProof = false;
+ m_pPed->bOnlyDamagedByPlayer = false;
+ m_pPed->bExplosionProof = false;
+ m_pPed->m_bCanBeDamaged = true;
+ CWorld::SetAllCarsCanBeDamaged(true);
+ CReplay::EnableReplays();
+ }
}
bool
@@ -216,347 +216,347 @@ CPlayerInfo::IsRestartingAfterArrest()
}
// lastCloseness is passed to other calls of this function
-void
-CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
-{
- // This dist used for determining the angle to face
- CVector2D dist(carToTest->GetPosition() - player->GetPosition());
- float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
- while (neededTurn >= PI) {
- neededTurn -= 2 * PI;
- }
-
- while (neededTurn < -PI) {
- neededTurn += 2 * PI;
- }
-
- // This dist used for evaluating cars' distances, weird...
- // Accounts inverted needed turn (or needed turn in long way) and car dist.
- float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
- if (closeness > *lastCloseness) {
- *lastCloseness = closeness;
- *closestCarOutput = (CVehicle*)carToTest;
- }
+void
+CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
+{
+ // This dist used for determining the angle to face
+ CVector2D dist(carToTest->GetPosition() - player->GetPosition());
+ float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
+ while (neededTurn >= PI) {
+ neededTurn -= 2 * PI;
+ }
+
+ while (neededTurn < -PI) {
+ neededTurn += 2 * PI;
+ }
+
+ // This dist used for evaluating cars' distances, weird...
+ // Accounts inverted needed turn (or needed turn in long way) and car dist.
+ float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
+ if (closeness > *lastCloseness) {
+ *lastCloseness = closeness;
+ *closestCarOutput = (CVehicle*)carToTest;
+ }
}
// There is something unfinished in here... Sadly all IDBs we have have it unfinished.
-void
-CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
-{
- if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
- ++m_nExplosionsSinceLastReward;
- else
- m_nExplosionsSinceLastReward = 1;
-
- m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
- int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
- sprintf(gString, "$%d", award);
-#ifdef MONEY_MESSAGES
- // This line is a leftover from PS2, I don't know what it was meant to be.
- // CVector sth(TheCamera.GetPosition() * 4.0f);
-
- CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
-#endif
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
-
- for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
- CGeneral::GetRandomNumber();
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
- }
+void
+CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar)
+{
+ if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000)
+ ++m_nExplosionsSinceLastReward;
+ else
+ m_nExplosionsSinceLastReward = 1;
+
+ m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds();
+ int award = wreckedCar->pHandling->nMonetaryValue * 0.002f;
+ sprintf(gString, "$%d", award);
+#ifdef MONEY_MESSAGES
+ // This line is a leftover from PS2, I don't know what it was meant to be.
+ // CVector sth(TheCamera.GetPosition() * 4.0f);
+
+ CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f);
+#endif
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
+
+ for (int i = m_nExplosionsSinceLastReward; i > 1; --i) {
+ CGeneral::GetRandomNumber();
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award;
+ }
}
-void
-CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
-{
- // Interesting
- *size = sizeof(CPlayerInfo);
-
-INITSAVEBUF
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
- for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
- WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i]);
- }
-// Save struct is different
-// VALIDATESAVEBUF(*size)
+void
+CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
+{
+ // Interesting
+ *size = sizeof(CPlayerInfo);
+
+INITSAVEBUF
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree);
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree);
+ for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
+ WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i]);
+ }
+// Save struct is different
+// VALIDATESAVEBUF(*size)
}
-void
-CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
-{
-INITSAVEBUF
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney = ReadSaveBuf<uint32>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_WBState = ReadSaveBuf<int8>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_nWBTime = ReadSaveBuf<uint32>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier = ReadSaveBuf<int16>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity = ReadSaveBuf<float>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney = ReadSaveBuf<int32>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages = ReadSaveBuf<int32>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ReadSaveBuf<int32>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint = ReadSaveBuf<bool>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_bFastReload = ReadSaveBuf<bool>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree = ReadSaveBuf<bool>(buf);
- CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree = ReadSaveBuf<bool>(buf);
- for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
- CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i] = ReadSaveBuf<char>(buf);
- }
-// Save struct is different
-// VALIDATESAVEBUF(size)
+void
+CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
+{
+INITSAVEBUF
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = ReadSaveBuf<uint32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_WBState = ReadSaveBuf<int8>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nWBTime = ReadSaveBuf<uint32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier = ReadSaveBuf<int16>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity = ReadSaveBuf<float>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney = ReadSaveBuf<int32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages = ReadSaveBuf<int32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ReadSaveBuf<int32>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint = ReadSaveBuf<bool>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bFastReload = ReadSaveBuf<bool>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree = ReadSaveBuf<bool>(buf);
+ CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree = ReadSaveBuf<bool>(buf);
+ for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) {
+ CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i] = ReadSaveBuf<char>(buf);
+ }
+// Save struct is different
+// VALIDATESAVEBUF(size)
}
-void
-CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
-{
- for (CPtrNode* node = carList.first; node; node = node->next) {
- CVehicle *car = (CVehicle*)node->item;
- if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
- if (!car->bUsesCollision || !car->IsVehicle())
- continue;
-
- car->m_scanCode = CWorld::GetCurrentScanCode();
- if (car->m_status != STATUS_WRECKED && car->m_status != STATUS_TRAIN_MOVING
- && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
- CVector carCentre = car->GetBoundCentre();
-
- if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
- float dist = (ped->GetPosition() - carCentre).Magnitude2D();
- if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
- EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
- }
- }
- }
- }
- }
+void
+CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
+{
+ for (CPtrNode* node = carList.first; node; node = node->next) {
+ CVehicle *car = (CVehicle*)node->item;
+ if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
+ if (!car->bUsesCollision || !car->IsVehicle())
+ continue;
+
+ car->m_scanCode = CWorld::GetCurrentScanCode();
+ if (car->m_status != STATUS_WRECKED && car->m_status != STATUS_TRAIN_MOVING
+ && (car->GetUp().z > 0.3f || (car->IsVehicle() && ((CVehicle*)car)->m_vehType == VEHICLE_TYPE_BIKE))) {
+ CVector carCentre = car->GetBoundCentre();
+
+ if (Abs(ped->GetPosition().z - carCentre.z) < 2.0f) {
+ float dist = (ped->GetPosition() - carCentre).Magnitude2D();
+ if (dist <= 10.0f && !CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
+ EvaluateCarPosition(car, ped, dist, lastCloseness, closestCarOutput);
+ }
+ }
+ }
+ }
+ }
}
-void
-CPlayerInfo::Process(void)
-{
- // Unused taxi feature. Gives you a dollar for every second with a passenger. Can be toggled via 0x29A opcode.
- bool startTaxiTimer = true;
- if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
- CVehicle *veh = m_pPed->m_pMyVehicle;
- if ((veh->m_modelIndex == MI_TAXI || veh->m_modelIndex == MI_CABBIE || veh->m_modelIndex == MI_BORGNINE)
- && veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
- for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
- timePassed -= 1000;
- ++m_nMoney;
- }
- startTaxiTimer = false;
- }
- }
- if (startTaxiTimer)
- m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
-
- // The effect that makes money counter does while earning/losing money
- if (m_nVisibleMoney != m_nMoney) {
- int diff = m_nMoney - m_nVisibleMoney;
- int diffAbs = Abs(diff);
- int changeBy;
-
- if (diffAbs > 100000)
- changeBy = 12345;
- else if (diffAbs > 10000)
- changeBy = 1234;
- else if (diffAbs > 1000)
- changeBy = 123;
- else if (diffAbs > 50)
- changeBy = 42;
- else
- changeBy = 1;
-
- if (diff < 0)
- m_nVisibleMoney -= changeBy;
- else
- m_nVisibleMoney += changeBy;
- }
-
- if (!(CTimer::GetFrameCounter() & 15)) {
- CVector2D playerPos = m_pPed->bInVehicle ? m_pPed->m_pMyVehicle->GetPosition() : m_pPed->GetPosition();
- m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
- }
-
- m_fRoadDensity = clamp(m_fRoadDensity, 0.4f, 1.45f);
-
- // Because vehicle enter/exit use same key binding.
- bool enterOrExitVeh;
- if (m_pPed->bVehExitWillBeInstant && m_pPed->bInVehicle)
- enterOrExitVeh = CPad::GetPad(0)->ExitVehicleJustDown();
- else
- enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
-
- if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_ODE) {
- if (m_pPed->bInVehicle) {
- if (!m_pRemoteVehicle) {
- CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
- if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->m_modelIndex)) {
- CVehicle *veh = m_pPed->m_pMyVehicle;
- if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
-
- // This condition will always return true, else block was probably WIP Miami code.
- if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
- if (veh->m_status != STATUS_WRECKED && veh->m_status != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
- if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
- m_pPed->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
- }
- }
- } else {
- CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
- bool found = false;
- float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
-
- if (found)
- sth.z = 1.0f + groundZ;
- m_pPed->m_nPedState = PED_IDLE;
- m_pPed->SetMoveState(PEDMOVE_STILL);
- CPed::PedSetOutCarCB(0, m_pPed);
- CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
- CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f);
- m_pPed->GetPosition() = sth;
- m_pPed->SetMoveState(PEDMOVE_STILL);
- m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
- }
- } else {
- // The code in here was under CPed::SetExitBoat in VC, did the same for here.
- m_pPed->SetExitBoat(veh);
- m_pPed->bTryingToReachDryLand = true;
- }
- }
- }
- } else {
- // Enter vehicle
- if (CPad::GetPad(0)->ExitVehicleJustDown()) {
- bool weAreOnBoat = false;
- float lastCloseness = 0.0f;
- CVehicle *carBelow = nil;
- CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
- if (surfaceBelow && surfaceBelow->IsVehicle()) {
- carBelow = (CVehicle*)surfaceBelow;
- if (carBelow->IsBoat()) {
- weAreOnBoat = true;
- m_pPed->bOnBoat = true;
-#ifdef VC_PED_PORTS
- if (carBelow->m_status != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
-#else
- if (carBelow->m_status != STATUS_WRECKED)
-#endif
- m_pPed->SetSeekBoatPosition(carBelow);
- }
- }
- // Find closest car
- if (!weAreOnBoat) {
- float minX = m_pPed->GetPosition().x - 10.0f;
- float maxX = 10.0f + m_pPed->GetPosition().x;
- float minY = m_pPed->GetPosition().y - 10.0f;
- float maxY = 10.0f + m_pPed->GetPosition().y;
-
- int minXSector = CWorld::GetSectorIndexX(minX);
- if (minXSector < 0) minXSector = 0;
- int minYSector = CWorld::GetSectorIndexY(minY);
- if (minYSector < 0) minYSector = 0;
- int maxXSector = CWorld::GetSectorIndexX(maxX);
- if (maxXSector > NUMSECTORS_X - 1) maxXSector = NUMSECTORS_X - 1;
- int maxYSector = CWorld::GetSectorIndexY(maxY);
- if (maxYSector > NUMSECTORS_Y - 1) maxYSector = NUMSECTORS_Y - 1;
-
- CWorld::AdvanceCurrentScanCode();
-
- for (int curY = minYSector; curY <= maxYSector; curY++) {
- for (int curX = minXSector; curX <= maxXSector; curX++) {
- CSector *sector = CWorld::GetSector(curX, curY);
- FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES], m_pPed,
- minX, minY, maxX, maxY, &lastCloseness, &carBelow);
- FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], m_pPed,
- minX, minY, maxX, maxY, &lastCloseness, &carBelow);
- }
- }
- }
- // carBelow is now closest vehicle
- if (carBelow && !weAreOnBoat) {
- if (carBelow->m_status == STATUS_TRAIN_NOT_MOVING) {
- m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow);
- } else if (carBelow->IsBoat()) {
- if (!carBelow->pDriver) {
- m_pPed->m_vehEnterType = 0;
- m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType);
- }
- } else {
- m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow);
- }
- }
- }
- }
- }
- if (m_bInRemoteMode) {
- uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
- if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
- TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(1.0f, 0);
- }
- if (timeWithoutRemoteCar > 2000) {
- if (m_WBState == WBSTATE_PLAYING) {
- TheCamera.RestoreWithJumpCut();
- TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(1.0f, 1);
- TheCamera.Process();
- CTimer::Stop();
- CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
- CRenderer::RequestObjectsInFrustum();
- CStreaming::LoadAllRequestedModels(false);
- CTimer::Update();
- }
- m_bInRemoteMode = false;
- CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
- if (FindPlayerVehicle()) {
- FindPlayerVehicle()->m_status = STATUS_PLAYER;
- }
- }
- }
- if (!(CTimer::GetFrameCounter() & 31)) {
- CVehicle *veh = FindPlayerVehicle();
- if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
- && veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
-
- if (veh->GetUp().z < -0.5f) {
- m_nUpsideDownCounter += 2;
-
- } else {
- m_nUpsideDownCounter++;
- }
- } else {
- m_nUpsideDownCounter = 0;
- }
-
- if (m_nUpsideDownCounter > 6 && veh->bCanBeDamaged) {
- veh->m_fHealth = 249.0f < veh->m_fHealth ? 249.0f : veh->m_fHealth;
- if (veh->IsCar()) {
- CAutomobile* car = (CAutomobile*)veh;
- car->Damage.SetEngineStatus(225);
- car->m_pSetOnFireEntity = nil;
- }
- }
- }
- if (FindPlayerVehicle()) {
- CVehicle *veh = FindPlayerVehicle();
- veh->m_nZoneLevel = -1;
- for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
- if (veh->pPassengers[i])
- veh->pPassengers[i]->m_nZoneLevel = 0;
- }
- CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
- } else {
- CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
- }
+void
+CPlayerInfo::Process(void)
+{
+ // Unused taxi feature. Gives you a dollar for every second with a passenger. Can be toggled via 0x29A opcode.
+ bool startTaxiTimer = true;
+ if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
+ CVehicle *veh = m_pPed->m_pMyVehicle;
+ if ((veh->m_modelIndex == MI_TAXI || veh->m_modelIndex == MI_CABBIE || veh->m_modelIndex == MI_BORGNINE)
+ && veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
+ for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
+ timePassed -= 1000;
+ ++m_nMoney;
+ }
+ startTaxiTimer = false;
+ }
+ }
+ if (startTaxiTimer)
+ m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
+
+ // The effect that makes money counter does while earning/losing money
+ if (m_nVisibleMoney != m_nMoney) {
+ int diff = m_nMoney - m_nVisibleMoney;
+ int diffAbs = Abs(diff);
+ int changeBy;
+
+ if (diffAbs > 100000)
+ changeBy = 12345;
+ else if (diffAbs > 10000)
+ changeBy = 1234;
+ else if (diffAbs > 1000)
+ changeBy = 123;
+ else if (diffAbs > 50)
+ changeBy = 42;
+ else
+ changeBy = 1;
+
+ if (diff < 0)
+ m_nVisibleMoney -= changeBy;
+ else
+ m_nVisibleMoney += changeBy;
+ }
+
+ if (!(CTimer::GetFrameCounter() & 15)) {
+ CVector2D playerPos = m_pPed->bInVehicle ? m_pPed->m_pMyVehicle->GetPosition() : m_pPed->GetPosition();
+ m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
+ }
+
+ m_fRoadDensity = clamp(m_fRoadDensity, 0.4f, 1.45f);
+
+ // Because vehicle enter/exit use same key binding.
+ bool enterOrExitVeh;
+ if (m_pPed->bVehExitWillBeInstant && m_pPed->bInVehicle)
+ enterOrExitVeh = CPad::GetPad(0)->ExitVehicleJustDown();
+ else
+ enterOrExitVeh = CPad::GetPad(0)->GetExitVehicle();
+
+ if (enterOrExitVeh && m_pPed->m_nPedState != PED_SNIPER_MODE && m_pPed->m_nPedState != PED_ROCKET_ODE) {
+ if (m_pPed->bInVehicle) {
+ if (!m_pRemoteVehicle) {
+ CEntity *surfaceBelowVeh = m_pPed->m_pMyVehicle->m_pCurGroundEntity;
+ if (!surfaceBelowVeh || !CBridge::ThisIsABridgeObjectMovingUp(surfaceBelowVeh->m_modelIndex)) {
+ CVehicle *veh = m_pPed->m_pMyVehicle;
+ if (!veh->IsBoat() || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
+
+ // This condition will always return true, else block was probably WIP Miami code.
+ if (veh->m_vehType != VEHICLE_TYPE_BIKE || veh->m_nDoorLock == CARLOCK_LOCKED_PLAYER_INSIDE) {
+ if (veh->m_status != STATUS_WRECKED && veh->m_status != STATUS_TRAIN_MOVING && veh->m_nDoorLock != CARLOCK_LOCKED_PLAYER_INSIDE) {
+ if (veh->m_vecMoveSpeed.Magnitude() < 0.17f && CTimer::GetTimeScale() >= 0.5f && !veh->bIsInWater) {
+ m_pPed->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
+ }
+ }
+ } else {
+ CVector sth = 0.7f * veh->GetRight() + veh->GetPosition();
+ bool found = false;
+ float groundZ = CWorld::FindGroundZFor3DCoord(sth.x, sth.y, 2.0f + sth.z, &found);
+
+ if (found)
+ sth.z = 1.0f + groundZ;
+ m_pPed->m_nPedState = PED_IDLE;
+ m_pPed->SetMoveState(PEDMOVE_STILL);
+ CPed::PedSetOutCarCB(0, m_pPed);
+ CAnimManager::BlendAnimation(m_pPed->GetClump(), m_pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
+ CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND, 100.0f);
+ m_pPed->GetPosition() = sth;
+ m_pPed->SetMoveState(PEDMOVE_STILL);
+ m_pPed->m_vecMoveSpeed = veh->m_vecMoveSpeed;
+ }
+ } else {
+ // The code in here was under CPed::SetExitBoat in VC, did the same for here.
+ m_pPed->SetExitBoat(veh);
+ m_pPed->bTryingToReachDryLand = true;
+ }
+ }
+ }
+ } else {
+ // Enter vehicle
+ if (CPad::GetPad(0)->ExitVehicleJustDown()) {
+ bool weAreOnBoat = false;
+ float lastCloseness = 0.0f;
+ CVehicle *carBelow = nil;
+ CEntity *surfaceBelow = m_pPed->m_pCurrentPhysSurface;
+ if (surfaceBelow && surfaceBelow->IsVehicle()) {
+ carBelow = (CVehicle*)surfaceBelow;
+ if (carBelow->IsBoat()) {
+ weAreOnBoat = true;
+ m_pPed->bOnBoat = true;
+#ifdef VC_PED_PORTS
+ if (carBelow->m_status != STATUS_WRECKED && carBelow->GetUp().z > 0.3f)
+#else
+ if (carBelow->m_status != STATUS_WRECKED)
+#endif
+ m_pPed->SetSeekBoatPosition(carBelow);
+ }
+ }
+ // Find closest car
+ if (!weAreOnBoat) {
+ float minX = m_pPed->GetPosition().x - 10.0f;
+ float maxX = 10.0f + m_pPed->GetPosition().x;
+ float minY = m_pPed->GetPosition().y - 10.0f;
+ float maxY = 10.0f + m_pPed->GetPosition().y;
+
+ int minXSector = CWorld::GetSectorIndexX(minX);
+ if (minXSector < 0) minXSector = 0;
+ int minYSector = CWorld::GetSectorIndexY(minY);
+ if (minYSector < 0) minYSector = 0;
+ int maxXSector = CWorld::GetSectorIndexX(maxX);
+ if (maxXSector > NUMSECTORS_X - 1) maxXSector = NUMSECTORS_X - 1;
+ int maxYSector = CWorld::GetSectorIndexY(maxY);
+ if (maxYSector > NUMSECTORS_Y - 1) maxYSector = NUMSECTORS_Y - 1;
+
+ CWorld::AdvanceCurrentScanCode();
+
+ for (int curY = minYSector; curY <= maxYSector; curY++) {
+ for (int curX = minXSector; curX <= maxXSector; curX++) {
+ CSector *sector = CWorld::GetSector(curX, curY);
+ FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES], m_pPed,
+ minX, minY, maxX, maxY, &lastCloseness, &carBelow);
+ FindClosestCarSectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], m_pPed,
+ minX, minY, maxX, maxY, &lastCloseness, &carBelow);
+ }
+ }
+ }
+ // carBelow is now closest vehicle
+ if (carBelow && !weAreOnBoat) {
+ if (carBelow->m_status == STATUS_TRAIN_NOT_MOVING) {
+ m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, carBelow);
+ } else if (carBelow->IsBoat()) {
+ if (!carBelow->pDriver) {
+ m_pPed->m_vehEnterType = 0;
+ m_pPed->SetEnterCar(carBelow, m_pPed->m_vehEnterType);
+ }
+ } else {
+ m_pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carBelow);
+ }
+ }
+ }
+ }
+ }
+ if (m_bInRemoteMode) {
+ uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
+ if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING) {
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(1.0f, 0);
+ }
+ if (timeWithoutRemoteCar > 2000) {
+ if (m_WBState == WBSTATE_PLAYING) {
+ TheCamera.RestoreWithJumpCut();
+ TheCamera.SetFadeColour(0, 0, 0);
+ TheCamera.Fade(1.0f, 1);
+ TheCamera.Process();
+ CTimer::Stop();
+ CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
+ CRenderer::RequestObjectsInFrustum();
+ CStreaming::LoadAllRequestedModels(false);
+ CTimer::Update();
+ }
+ m_bInRemoteMode = false;
+ CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle = nil;
+ if (FindPlayerVehicle()) {
+ FindPlayerVehicle()->m_status = STATUS_PLAYER;
+ }
+ }
+ }
+ if (!(CTimer::GetFrameCounter() & 31)) {
+ CVehicle *veh = FindPlayerVehicle();
+ if (veh && m_pPed->bInVehicle && veh->GetUp().z < 0.0f
+ && veh->m_vecMoveSpeed.Magnitude() < 0.05f && veh->IsCar() && !veh->bIsInWater) {
+
+ if (veh->GetUp().z < -0.5f) {
+ m_nUpsideDownCounter += 2;
+
+ } else {
+ m_nUpsideDownCounter++;
+ }
+ } else {
+ m_nUpsideDownCounter = 0;
+ }
+
+ if (m_nUpsideDownCounter > 6 && veh->bCanBeDamaged) {
+ veh->m_fHealth = 249.0f < veh->m_fHealth ? 249.0f : veh->m_fHealth;
+ if (veh->IsCar()) {
+ CAutomobile* car = (CAutomobile*)veh;
+ car->Damage.SetEngineStatus(225);
+ car->m_pSetOnFireEntity = nil;
+ }
+ }
+ }
+ if (FindPlayerVehicle()) {
+ CVehicle *veh = FindPlayerVehicle();
+ veh->m_nZoneLevel = -1;
+ for (int i = 0; i < ARRAY_SIZE(veh->pPassengers); i++) {
+ if (veh->pPassengers[i])
+ veh->pPassengers[i]->m_nZoneLevel = 0;
+ }
+ CStats::DistanceTravelledInVehicle += veh->m_fDistanceTravelled;
+ } else {
+ CStats::DistanceTravelledOnFoot += FindPlayerPed()->m_fDistanceTravelled;
+ }
}
STARTPATCHES
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index 75536b88..6add9e0c 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -1,8 +1,14 @@
#include "common.h"
#include "patcher.h"
#include "Pools.h"
-#include "World.h"
+
+#include "Boat.h"
+#include "CarCtrl.h"
+#include "Population.h"
#include "ProjectileInfo.h"
+#include "Streaming.h"
+#include "Wanted.h"
+#include "World.h"
CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044;
CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448;
@@ -14,13 +20,6 @@ CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28;
CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18;
CAudioScriptObjectPool *&CPools::ms_pAudioScriptObjectPool = *(CAudioScriptObjectPool**)0x8F1B6C;
-WRAPPER void CPools::LoadObjectPool(uint8* buf, uint32 size) { EAXJMP(0x4a2550); }
-WRAPPER void CPools::LoadPedPool(uint8* buf, uint32 size) { EAXJMP(0x4a2b50); }
-WRAPPER void CPools::LoadVehiclePool(uint8* buf, uint32 size) { EAXJMP(0x4a1b40); }
-WRAPPER void CPools::SaveObjectPool(uint8* buf, uint32 *size) { EAXJMP(0x4a22d0); }
-WRAPPER void CPools::SavePedPool(uint8* buf, uint32 *size) { EAXJMP(0x4a29b0); }
-WRAPPER void CPools::SaveVehiclePool(uint8* buf, uint32 *size) { EAXJMP(0x4a2080); }
-
void
CPools::Initialise(void)
{
@@ -99,6 +98,333 @@ CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
}
}
+void CPools::LoadVehiclePool(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ int nNumCars = ReadSaveBuf<int>(buf);
+ int nNumBoats = ReadSaveBuf<int>(buf);
+ for (int i = 0; i < nNumCars + nNumBoats; i++) {
+ uint32 type = ReadSaveBuf<uint32>(buf);
+ int16 model = ReadSaveBuf<int16>(buf);
+ CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ int32 slot = ReadSaveBuf<int32>(buf);
+ CVehicle* pVehicle;
+ char* vbuf = new char[max(sizeof(CAutomobile), sizeof(CBoat))];
+ if (type == VEHICLE_TYPE_BOAT) {
+ memcpy(vbuf, buf, sizeof(CBoat));
+ SkipSaveBuf(buf, sizeof(CBoat));
+ CBoat* pBoat = new(slot) CBoat(model, RANDOM_VEHICLE);
+ pVehicle = pBoat;
+ --CCarCtrl::NumRandomCars; // why?
+ }
+ else if (type == VEHICLE_TYPE_CAR) {
+ memcpy(vbuf, buf, sizeof(CAutomobile));
+ SkipSaveBuf(buf, sizeof(CAutomobile));
+ CStreaming::RequestModel(model, 0); // is it needed?
+ CStreaming::LoadAllRequestedModels(false);
+ CAutomobile* pAutomobile = new(slot) CAutomobile(model, RANDOM_VEHICLE);
+ pVehicle = pAutomobile;
+ CCarCtrl::NumRandomCars--; // why?
+ pAutomobile->Damage = ((CAutomobile*)vbuf)->Damage;
+ pAutomobile->SetupDamageAfterLoad();
+ }
+ else
+ assert(0);
+ CVehicle* pBufferVehicle = (CVehicle*)vbuf;
+ pVehicle->GetMatrix() = pBufferVehicle->GetMatrix();
+ pVehicle->VehicleCreatedBy = pBufferVehicle->VehicleCreatedBy;
+ pVehicle->m_currentColour1 = pBufferVehicle->m_currentColour1;
+ pVehicle->m_currentColour2 = pBufferVehicle->m_currentColour2;
+ pVehicle->m_nAlarmState = pBufferVehicle->m_nAlarmState;
+ pVehicle->m_nNumMaxPassengers = pBufferVehicle->m_nNumMaxPassengers;
+ pVehicle->field_1D0[0] = pBufferVehicle->field_1D0[0];
+ pVehicle->field_1D0[1] = pBufferVehicle->field_1D0[1];
+ pVehicle->field_1D0[2] = pBufferVehicle->field_1D0[2];
+ pVehicle->field_1D0[3] = pBufferVehicle->field_1D0[3];
+ pVehicle->m_fSteerAngle = pBufferVehicle->m_fSteerAngle;
+ pVehicle->m_fGasPedal = pBufferVehicle->m_fGasPedal;
+ pVehicle->m_fBrakePedal = pBufferVehicle->m_fBrakePedal;
+ pVehicle->bIsLawEnforcer = pBufferVehicle->bIsLawEnforcer;
+ pVehicle->bIsLocked = pBufferVehicle->bIsLocked;
+ pVehicle->bEngineOn = pBufferVehicle->bEngineOn;
+ pVehicle->bIsHandbrakeOn = pBufferVehicle->bIsHandbrakeOn;
+ pVehicle->bLightsOn = pBufferVehicle->bLightsOn;
+ pVehicle->bFreebies = pBufferVehicle->bFreebies;
+ pVehicle->m_fHealth = pBufferVehicle->m_fHealth;
+ pVehicle->m_nCurrentGear = pBufferVehicle->m_nCurrentGear;
+ pVehicle->m_fChangeGearTime = pBufferVehicle->m_fChangeGearTime;
+ pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath;
+#ifdef FIX_BUGS //must be copypaste
+ pVehicle->m_nBombTimer = pBufferVehicle->m_nBombTimer;
+#else
+ pVehicle->m_nTimeOfDeath = pBufferVehicle->m_nTimeOfDeath;
+#endif
+ pVehicle->m_nDoorLock = pBufferVehicle->m_nDoorLock;
+ pVehicle->m_status = pBufferVehicle->m_status;
+ pVehicle->m_type = pBufferVehicle->m_type;
+ (pVehicle->GetAddressOfEntityProperties())[0] = (pBufferVehicle->GetAddressOfEntityProperties())[0];
+ (pVehicle->GetAddressOfEntityProperties())[1] = (pBufferVehicle->GetAddressOfEntityProperties())[1];
+ pVehicle->AutoPilot = pBufferVehicle->AutoPilot;
+ CWorld::Add(pVehicle);
+ delete[] vbuf;
+ }
+VALIDATESAVEBUF(size)
+}
+
+void CPools::SaveVehiclePool(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ int nNumCars = 0;
+ int nNumBoats = 0;
+ int nPoolSize = GetVehiclePool()->GetSize();
+ for (int i = 0; i < nPoolSize; i++) {
+ CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ bool bHasPassenger = false;
+ for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) {
+ if (pVehicle->pPassengers[i])
+ bHasPassenger = true;
+ }
+ if (!pVehicle->pDriver && !bHasPassenger) {
+ if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
+ ++nNumCars;
+ if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
+ ++nNumBoats;
+ }
+ }
+ *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CAutomobile)) + sizeof(int) +
+ nNumBoats * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + sizeof(CBoat)) + sizeof(int);
+ WriteSaveBuf(buf, nNumCars);
+ WriteSaveBuf(buf, nNumBoats);
+ for (int i = 0; i < nPoolSize; i++) {
+ CVehicle* pVehicle = GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ bool bHasPassenger = false;
+ for (int j = 0; j < ARRAY_SIZE(pVehicle->pPassengers); j++) {
+ if (pVehicle->pPassengers[j])
+ bHasPassenger = true;
+ }
+ if (!pVehicle->pDriver && !bHasPassenger) {
+ if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+ WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
+ WriteSaveBuf(buf, pVehicle->m_modelIndex);
+ WriteSaveBuf(buf, GetVehicleRef(pVehicle));
+ memcpy(buf, pVehicle, sizeof(CAutomobile));
+ SkipSaveBuf(buf, sizeof(CAutomobile));
+ }
+ if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
+ WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
+ WriteSaveBuf(buf, pVehicle->m_modelIndex);
+ WriteSaveBuf(buf, GetVehicleRef(pVehicle));
+ memcpy(buf, pVehicle, sizeof(CBoat));
+ SkipSaveBuf(buf, sizeof(CBoat));
+ }
+ }
+ }
+VALIDATESAVEBUF(*size)
+}
+
+void CPools::SaveObjectPool(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ CProjectileInfo::RemoveAllProjectiles();
+ CObject::DeleteAllTempObjects();
+ int nObjects = 0;
+ int nPoolSize = GetObjectPool()->GetSize();
+ for (int i = 0; i < nPoolSize; i++) {
+ CObject* pObject = GetObjectPool()->GetSlot(i);
+ if (!pObject)
+ continue;
+ if (pObject->ObjectCreatedBy == MISSION_OBJECT)
+ ++nObjects;
+ }
+ *size = nObjects * (sizeof(int16) + sizeof(int) + sizeof(CCompressedMatrixNotAligned) + sizeof(uint32) +
+ sizeof(float) + sizeof(CCompressedMatrixNotAligned) + sizeof(uint32) + sizeof(int8) + 7 * sizeof(bool) + sizeof(float) +
+ sizeof(int8) + sizeof(int8) + sizeof(uint32) + 2 * sizeof(uint32)) + sizeof(int);
+ WriteSaveBuf(buf, nObjects);
+ for (int i = 0; i < nPoolSize; i++) {
+ CObject* pObject = GetObjectPool()->GetSlot(i);
+ if (!pObject)
+ continue;
+ if (pObject->ObjectCreatedBy == MISSION_OBJECT) {
+ bool bIsPickup = pObject->bIsPickup;
+ bool bFlag2 = pObject->m_obj_flag2;
+ bool bOutOfStock = pObject->bOutOfStock;
+ bool bGlassCracked = pObject->bGlassCracked;
+ bool bGlassBroken = pObject->bGlassBroken;
+ bool bHasBeenDamaged = pObject->bHasBeenDamaged;
+ bool bUseVehicleColours = pObject->bUseVehicleColours;
+ CCompressedMatrixNotAligned tmp;
+ WriteSaveBuf(buf, pObject->m_modelIndex);
+ WriteSaveBuf(buf, GetObjectRef(pObject));
+ tmp.CompressFromFullMatrix(pObject->GetMatrix());
+ WriteSaveBuf(buf, tmp);
+ WriteSaveBuf(buf, (uint32)0); // game writes ununitialized data here
+ WriteSaveBuf(buf, pObject->m_fUprootLimit);
+ tmp.CompressFromFullMatrix(pObject->m_objectMatrix);
+ WriteSaveBuf(buf, tmp);
+ WriteSaveBuf(buf, (uint32)0); // same
+ WriteSaveBuf(buf, pObject->ObjectCreatedBy);
+ WriteSaveBuf(buf, bIsPickup);
+ WriteSaveBuf(buf, bFlag2);
+ WriteSaveBuf(buf, bOutOfStock);
+ WriteSaveBuf(buf, bGlassCracked);
+ WriteSaveBuf(buf, bGlassBroken);
+ WriteSaveBuf(buf, bHasBeenDamaged);
+ WriteSaveBuf(buf, bUseVehicleColours);
+ WriteSaveBuf(buf, pObject->m_fCollisionDamageMultiplier);
+ WriteSaveBuf(buf, pObject->m_nCollisionDamageEffect);
+ WriteSaveBuf(buf, pObject->m_nSpecialCollisionResponseCases);
+ WriteSaveBuf(buf, pObject->m_nEndOfLifeTime);
+ WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[0]);
+ WriteSaveBuf(buf, (pObject->GetAddressOfEntityProperties())[1]);
+ }
+ }
+VALIDATESAVEBUF(*size)
+}
+
+void CPools::LoadObjectPool(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ int nObjects = ReadSaveBuf<int>(buf);
+ for (int i = 0; i < nObjects; i++) {
+ int16 mi = ReadSaveBuf<int16>(buf);
+ int ref = ReadSaveBuf<int>(buf);
+ char* obuf = new char[sizeof(CObject)];
+ CObject* pBufferObject = (CObject*)obuf;
+ CCompressedMatrixNotAligned tmp;
+ tmp = ReadSaveBuf<CCompressedMatrixNotAligned>(buf);
+ tmp.DecompressIntoFullMatrix(pBufferObject->GetMatrix());
+ ReadSaveBuf<uint32>(buf);
+ pBufferObject->m_fUprootLimit = ReadSaveBuf<float>(buf);
+ tmp = ReadSaveBuf<CCompressedMatrixNotAligned>(buf);
+ tmp.DecompressIntoFullMatrix(pBufferObject->m_objectMatrix);
+ ReadSaveBuf<uint32>(buf);
+ pBufferObject->ObjectCreatedBy = ReadSaveBuf<int8>(buf);
+ pBufferObject->bIsPickup = ReadSaveBuf<bool>(buf);
+ pBufferObject->m_flagE2 = ReadSaveBuf<bool>(buf);
+ pBufferObject->bOutOfStock = ReadSaveBuf<bool>(buf);
+ pBufferObject->bGlassCracked = ReadSaveBuf<bool>(buf);
+ pBufferObject->bGlassBroken = ReadSaveBuf<bool>(buf);
+ pBufferObject->bHasBeenDamaged = ReadSaveBuf<bool>(buf);
+ pBufferObject->bUseVehicleColours = ReadSaveBuf<bool>(buf);
+ pBufferObject->m_fCollisionDamageMultiplier = ReadSaveBuf<float>(buf);
+ pBufferObject->m_nCollisionDamageEffect = ReadSaveBuf<uint8>(buf);
+ pBufferObject->m_nSpecialCollisionResponseCases = ReadSaveBuf<uint8>(buf);
+ pBufferObject->m_nEndOfLifeTime = ReadSaveBuf<uint32>(buf);
+ (pBufferObject->GetAddressOfEntityProperties())[0] = ReadSaveBuf<uint32>(buf);
+ (pBufferObject->GetAddressOfEntityProperties())[1] = ReadSaveBuf<uint32>(buf);
+ if (GetObjectPool()->GetSlot(ref >> 8))
+ CPopulation::ConvertToDummyObject(GetObjectPool()->GetSlot(ref >> 8));
+ CObject* pObject = new(ref) CObject(mi, false);
+ pObject->GetMatrix() = pBufferObject->GetMatrix();
+ pObject->m_fUprootLimit = pBufferObject->m_fUprootLimit;
+ pObject->m_objectMatrix = pBufferObject->m_objectMatrix;
+ pObject->ObjectCreatedBy = pBufferObject->ObjectCreatedBy;
+ pObject->bIsPickup = pBufferObject->bIsPickup;
+ pObject->m_flagE2 = pBufferObject->m_flagE2;
+ pObject->bOutOfStock = pBufferObject->bOutOfStock;
+ pObject->bGlassCracked = pBufferObject->bGlassCracked;
+ pObject->bGlassBroken = pBufferObject->bGlassBroken;
+ pObject->bHasBeenDamaged = pBufferObject->bHasBeenDamaged;
+ pObject->bUseVehicleColours = pBufferObject->bUseVehicleColours;
+ pObject->m_fCollisionDamageMultiplier = pBufferObject->m_fCollisionDamageMultiplier;
+ pObject->m_nCollisionDamageEffect = pBufferObject->m_nCollisionDamageEffect;
+ pObject->m_nSpecialCollisionResponseCases = pBufferObject->m_nSpecialCollisionResponseCases;
+ pObject->m_nEndOfLifeTime = pBufferObject->m_nEndOfLifeTime;
+ (pObject->GetAddressOfEntityProperties())[0] = (pBufferObject->GetAddressOfEntityProperties())[0];
+ (pObject->GetAddressOfEntityProperties())[1] = (pBufferObject->GetAddressOfEntityProperties())[1];
+ pObject->bHasCollided = false;
+ CWorld::Add(pObject);
+ delete[] obuf;
+ }
+VALIDATESAVEBUF(size)
+}
+
+void CPools::SavePedPool(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ int nNumPeds = 0;
+ int nPoolSize = GetPedPool()->GetSize();
+ for (int i = 0; i < nPoolSize; i++) {
+ CPed* pPed = GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1)
+ nNumPeds++;
+ }
+ *size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + sizeof(CPlayerPed) +
+ sizeof(CWanted::MaximumWantedLevel) + sizeof(CWanted::nMaximumWantedLevel) + MAX_MODEL_NAME);
+ WriteSaveBuf(buf, nNumPeds);
+ for (int i = 0; i < nPoolSize; i++) {
+ CPed* pPed = GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) {
+ WriteSaveBuf(buf, pPed->m_nPedType);
+ WriteSaveBuf(buf, pPed->m_modelIndex);
+ WriteSaveBuf(buf, GetPedRef(pPed));
+ memcpy(buf, pPed, sizeof(CPlayerPed));
+ SkipSaveBuf(buf, sizeof(CPlayerPed));
+ WriteSaveBuf(buf, CWanted::MaximumWantedLevel);
+ WriteSaveBuf(buf, CWanted::nMaximumWantedLevel);
+ memcpy(buf, CModelInfo::GetModelInfo(pPed->GetModelIndex())->GetName(), MAX_MODEL_NAME);
+ SkipSaveBuf(buf, MAX_MODEL_NAME);
+ }
+ }
+VALIDATESAVEBUF(*size);
+}
+
+void CPools::LoadPedPool(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ int nPeds = ReadSaveBuf<int>(buf);
+ for (int i = 0; i < nPeds; i++) {
+ uint32 pedtype = ReadSaveBuf<uint32>(buf);
+ int16 model = ReadSaveBuf<int16>(buf);
+ int ref = ReadSaveBuf<int>(buf);
+ char* pbuf = new char[sizeof(CPlayerPed)];
+ CPlayerPed* pBufferPlayer = (CPlayerPed*)pbuf;
+ CPed* pPed;
+ char name[MAX_MODEL_NAME];
+ // the code implies that there was idea to load non-player ped
+ if (pedtype == PEDTYPE_PLAYER1) { // always true
+ memcpy(pbuf, buf, sizeof(CPlayerPed));
+ SkipSaveBuf(buf, sizeof(CPlayerPed));
+ CWanted::MaximumWantedLevel = ReadSaveBuf<int32>(buf);
+ CWanted::nMaximumWantedLevel = ReadSaveBuf<int32>(buf);
+ memcpy(name, buf, MAX_MODEL_NAME);
+ SkipSaveBuf(buf, MAX_MODEL_NAME);
+ }
+ CStreaming::RequestSpecialModel(model, name, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+ if (pedtype == PEDTYPE_PLAYER1) {
+ CPlayerPed* pPlayerPed = new(ref) CPlayerPed();
+ for (int i = 0; i < ARRAY_SIZE(pPlayerPed->m_nTargettableObjects); i++)
+ pPlayerPed->m_nTargettableObjects[i] = pBufferPlayer->m_nTargettableObjects[i];
+ pPlayerPed->m_fMaxStamina = pBufferPlayer->m_fMaxStamina;
+ pPed = pPlayerPed;
+ }
+ pPed->GetPosition() = pBufferPlayer->GetPosition();
+ pPed->m_fHealth = pBufferPlayer->m_fHealth;
+ pPed->m_fArmour = pBufferPlayer->m_fArmour;
+ pPed->CharCreatedBy = pBufferPlayer->CharCreatedBy;
+ pPed->m_currentWeapon = 0;
+ pPed->m_maxWeaponTypeAllowed = pBufferPlayer->m_maxWeaponTypeAllowed;
+ for (int i = 0; i < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; i++)
+ pPed->m_weapons[i] = pBufferPlayer->m_weapons[i];
+ if (pedtype == PEDTYPE_PLAYER1) {
+ pPed->m_wepAccuracy = 100;
+ CWorld::Players[0].m_pPed = (CPlayerPed*)pPed;
+ }
+ CWorld::Add(pPed);
+ delete[] pbuf;
+ }
+VALIDATESAVEBUF(size)
+}
STARTPATCHES
InjectHook(0x4A1770, CPools::Initialise, PATCH_JUMP);
@@ -111,4 +437,7 @@ STARTPATCHES
InjectHook(0x4A1B00, CPools::GetObjectRef, PATCH_JUMP);
InjectHook(0x4A1B20, CPools::GetObject, PATCH_JUMP);
InjectHook(0x4A2DB0, CPools::MakeSureSlotInObjectPoolIsEmpty, PATCH_JUMP);
+ InjectHook(0x4A1B40, CPools::LoadVehiclePool, PATCH_JUMP);
+ InjectHook(0x4A2550, CPools::LoadObjectPool, PATCH_JUMP);
+ InjectHook(0x4A2B50, CPools::LoadPedPool, PATCH_JUMP);
ENDPATCHES
diff --git a/src/core/Profile.cpp b/src/core/Profile.cpp
new file mode 100644
index 00000000..56584d12
--- /dev/null
+++ b/src/core/Profile.cpp
@@ -0,0 +1,71 @@
+#include "common.h"
+#include "Profile.h"
+
+#ifndef MASTER
+float CProfile::ms_afStartTime[NUM_PROFILES];
+float CProfile::ms_afCumulativeTime[NUM_PROFILES];
+float CProfile::ms_afEndTime[NUM_PROFILES];
+float CProfile::ms_afMaxEndTime[NUM_PROFILES];
+float CProfile::ms_afMaxCumulativeTime[NUM_PROFILES];
+char *CProfile::ms_pProfileString[NUM_PROFILES];
+RwRGBA CProfile::ms_aBarColours[NUM_PROFILES];
+
+void CProfile::Initialise()
+{
+ ms_afMaxEndTime[PROFILE_FRAME_RATE] = 0.0f;
+ ms_afMaxEndTime[PROFILE_PHYSICS] = 0.0f;
+ ms_afMaxEndTime[PROFILE_COLLISION] = 0.0f;
+ ms_afMaxEndTime[PROFILE_PED_AI] = 0.0f;
+ ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = 0.0f;
+ ms_afMaxEndTime[PROFILE_RENDERING_TIME] = 0.0f;
+ ms_afMaxEndTime[PROFILE_TOTAL] = 0.0f;
+
+ ms_pProfileString[PROFILE_FRAME_RATE] = "Frame rate";
+ ms_pProfileString[PROFILE_PHYSICS] = "Physics";
+ ms_pProfileString[PROFILE_COLLISION] = "Collision";
+ ms_pProfileString[PROFILE_PED_AI] = "Ped AI";
+ ms_pProfileString[PROFILE_PROCESSING_TIME] = "Processing time";
+ ms_pProfileString[PROFILE_RENDERING_TIME] = "Rendering time";
+ ms_pProfileString[PROFILE_TOTAL] = "Total";
+
+ ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_PHYSICS] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_COLLISION] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_PED_AI] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = 0.0f;
+ ms_afMaxCumulativeTime[PROFILE_TOTAL] = 0.0f;
+
+ ms_aBarColours[PROFILE_PHYSICS] = { 0, 127, 255, 255 };
+ ms_aBarColours[PROFILE_COLLISION] = { 0, 255, 255, 255 };
+ ms_aBarColours[PROFILE_PED_AI] = { 255, 0, 0, 255 };
+ ms_aBarColours[PROFILE_PROCESSING_TIME] = { 0, 255, 0, 255 };
+ ms_aBarColours[PROFILE_RENDERING_TIME] = { 0, 0, 255, 255 };
+ ms_aBarColours[PROFILE_TOTAL] = { 255, 255, 255, 255 };
+}
+
+void CProfile::SuspendProfile(eProfile profile)
+{
+ ms_afEndTime[profile] = -ms_afStartTime[profile];
+ ms_afCumulativeTime[profile] -= ms_afStartTime[profile];
+}
+
+void CProfile::ShowResults()
+{
+ ms_afMaxEndTime[PROFILE_FRAME_RATE] = max(ms_afMaxEndTime[PROFILE_FRAME_RATE], ms_afEndTime[PROFILE_FRAME_RATE]);
+ ms_afMaxEndTime[PROFILE_PHYSICS] = max(ms_afMaxEndTime[PROFILE_PHYSICS], ms_afEndTime[PROFILE_PHYSICS]);
+ ms_afMaxEndTime[PROFILE_COLLISION] = max(ms_afMaxEndTime[PROFILE_COLLISION], ms_afEndTime[PROFILE_COLLISION]);
+ ms_afMaxEndTime[PROFILE_PED_AI] = max(ms_afMaxEndTime[PROFILE_PED_AI], ms_afEndTime[PROFILE_PED_AI]);
+ ms_afMaxEndTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxEndTime[PROFILE_PROCESSING_TIME], ms_afEndTime[PROFILE_PROCESSING_TIME]);
+ ms_afMaxEndTime[PROFILE_RENDERING_TIME] = max(ms_afMaxEndTime[PROFILE_RENDERING_TIME], ms_afEndTime[PROFILE_RENDERING_TIME]);
+ ms_afMaxEndTime[PROFILE_TOTAL] = max(ms_afMaxEndTime[PROFILE_TOTAL], ms_afEndTime[PROFILE_TOTAL]);
+
+ ms_afMaxCumulativeTime[PROFILE_FRAME_RATE] = max(ms_afMaxCumulativeTime[PROFILE_FRAME_RATE], ms_afCumulativeTime[PROFILE_FRAME_RATE]);
+ ms_afMaxCumulativeTime[PROFILE_PHYSICS] = max(ms_afMaxCumulativeTime[PROFILE_PHYSICS], ms_afCumulativeTime[PROFILE_PHYSICS]);
+ ms_afMaxCumulativeTime[PROFILE_COLLISION] = max(ms_afMaxCumulativeTime[PROFILE_COLLISION], ms_afCumulativeTime[PROFILE_COLLISION]);
+ ms_afMaxCumulativeTime[PROFILE_PED_AI] = max(ms_afMaxCumulativeTime[PROFILE_PED_AI], ms_afCumulativeTime[PROFILE_PED_AI]);
+ ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_PROCESSING_TIME], ms_afCumulativeTime[PROFILE_PROCESSING_TIME]);
+ ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME] = max(ms_afMaxCumulativeTime[PROFILE_RENDERING_TIME], ms_afCumulativeTime[PROFILE_RENDERING_TIME]);
+ ms_afMaxCumulativeTime[PROFILE_TOTAL] = max(ms_afMaxCumulativeTime[PROFILE_TOTAL], ms_afCumulativeTime[PROFILE_TOTAL]);
+}
+#endif \ No newline at end of file
diff --git a/src/core/Profile.h b/src/core/Profile.h
new file mode 100644
index 00000000..d2e8054b
--- /dev/null
+++ b/src/core/Profile.h
@@ -0,0 +1,28 @@
+#pragma once
+
+enum eProfile
+{
+ PROFILE_FRAME_RATE,
+ PROFILE_PHYSICS,
+ PROFILE_COLLISION,
+ PROFILE_PED_AI,
+ PROFILE_PROCESSING_TIME,
+ PROFILE_RENDERING_TIME,
+ PROFILE_TOTAL,
+ NUM_PROFILES,
+};
+
+class CProfile
+{
+ static float ms_afStartTime[NUM_PROFILES];
+ static float ms_afCumulativeTime[NUM_PROFILES];
+ static float ms_afEndTime[NUM_PROFILES];
+ static float ms_afMaxEndTime[NUM_PROFILES];
+ static float ms_afMaxCumulativeTime[NUM_PROFILES];
+ static char *ms_pProfileString[NUM_PROFILES];
+ static RwRGBA ms_aBarColours[NUM_PROFILES];
+public:
+ static void Initialise();
+ static void SuspendProfile(eProfile profile);
+ static void ShowResults();
+}; \ No newline at end of file
diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp
index f1d8ec96..154e7e9a 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -1,1307 +1,1506 @@
-#include "config.h"
-#include "common.h"
-#include "patcher.h"
-#include "RwHelper.h"
-#include "Radar.h"
-#include "Camera.h"
-#include "Hud.h"
-#include "World.h"
-#include "Frontend.h"
-#include "General.h"
-#include "Vehicle.h"
-#include "Pools.h"
-#include "Script.h"
-#include "TxdStore.h"
-#include "World.h"
-#include "Streaming.h"
-#include "SpecialFX.h"
-
-float &CRadar::m_radarRange = *(float*)0x8E281C;
-CBlip (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(CBlip(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
-CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
-int32 gRadarTxdIds[64];// = (int*)0x6299C0;
-
-CSprite2d CRadar::AsukaSprite;// = *(CSprite2d*)0x8F1A40;
-CSprite2d CRadar::BombSprite;// = (CSprite2d*)0x8F5FB4;
-CSprite2d CRadar::CatSprite;// = (CSprite2d*)0x885B24;
-CSprite2d CRadar::CentreSprite;// = (CSprite2d*)0x8F6268;
-CSprite2d CRadar::CopcarSprite;// = (CSprite2d*)0x8F1A2C;
-CSprite2d CRadar::DonSprite;// = (CSprite2d*)0x8F2BE0;
-CSprite2d CRadar::EightSprite;// = (CSprite2d*)0x8F2BCC;
-CSprite2d CRadar::ElSprite;// = (CSprite2d*)0x8F1B80;
-CSprite2d CRadar::IceSprite;// = (CSprite2d*)0x9415FC;
-CSprite2d CRadar::JoeySprite;// = (CSprite2d*)0x8F2C00;
-CSprite2d CRadar::KenjiSprite;// = (CSprite2d*)0x8F2C68;
-CSprite2d CRadar::LizSprite;// = (CSprite2d*)0x8F5830;
-CSprite2d CRadar::LuigiSprite;// = (CSprite2d*)0x8F1A3C;
-CSprite2d CRadar::NorthSprite;// = (CSprite2d*)0x8F6274;
-CSprite2d CRadar::RaySprite;// = (CSprite2d*)0x8E2A7C;
-CSprite2d CRadar::SalSprite;// = (CSprite2d*)0x8F29EC;
-CSprite2d CRadar::SaveSprite;// = (CSprite2d*)0x8F5F74;
-CSprite2d CRadar::SpraySprite;// = (CSprite2d*)0x94307C;
-CSprite2d CRadar::TonySprite;// = (CSprite2d*)0x885B58;
-CSprite2d CRadar::WeaponSprite;// = (CSprite2d*)0x941534;
-
-CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
- nil,
- &AsukaSprite,
- &BombSprite,
- &CatSprite,
- &CentreSprite,
- &CopcarSprite,
- &DonSprite,
- &EightSprite,
- &ElSprite,
- &IceSprite,
- &JoeySprite,
- &KenjiSprite,
- &LizSprite,
- &LuigiSprite,
- &NorthSprite,
- &RaySprite,
- &SalSprite,
- &SaveSprite,
- &SpraySprite,
- &TonySprite,
- &WeaponSprite
-};
-
-#define RADAR_NUM_TILES (8)
-#define RADAR_TILE_SIZE (WORLD_SIZE_X / RADAR_NUM_TILES)
-static_assert(RADAR_TILE_SIZE == (WORLD_SIZE_Y / RADAR_NUM_TILES), "CRadar: not a square");
-
-#define RADAR_MIN_RANGE (120.0f)
-#define RADAR_MAX_RANGE (350.0f)
-#define RADAR_MIN_SPEED (0.3f)
-#define RADAR_MAX_SPEED (0.9f)
-
-uint8 CRadar::CalculateBlipAlpha(float dist)
-{
- if (dist <= 1.0f)
- return 255;
-
- if (dist <= 5.0f)
- return (128.0f * ((dist - 1.0f) / 4.0f)) + ((1.0f - (dist - 1.0f) / 4.0f) * 255.0f);
-
- return 128;
-}
-
-void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
-{
- int index = GetActualBlipArrayIndex(i);
- if (index != -1)
- ms_RadarTrace[index].m_bDim = bright != 1;
-}
-
-void CRadar::ChangeBlipColour(int32 i, int32 color)
-{
- int index = GetActualBlipArrayIndex(i);
- if (index != -1)
- ms_RadarTrace[index].m_nColor = color;
-}
-
-void CRadar::ChangeBlipDisplay(int32 i, eBlipDisplay display)
-{
- int index = GetActualBlipArrayIndex(i);
- if (index != -1)
- ms_RadarTrace[index].m_eBlipDisplay = display;
-}
-
-void CRadar::ChangeBlipScale(int32 i, int32 scale)
-{
- int index = GetActualBlipArrayIndex(i);
- if (index != -1)
- ms_RadarTrace[index].m_wScale = scale;
-}
-
-void CRadar::ClearBlip(int32 i)
-{
- int index = GetActualBlipArrayIndex(i);
- if (index != -1) {
- SetRadarMarkerState(index, false);
- ms_RadarTrace[index].m_bInUse = false;
- ms_RadarTrace[index].m_eBlipType = BLIP_NONE;
- ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
- ms_RadarTrace[index].m_IconID = RADAR_SPRITE_NONE;
- }
-}
-
-void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
-{
- for (int i = 0; i < NUMRADARBLIPS; i++) {
- if (type == ms_RadarTrace[i].m_eBlipType && id == ms_RadarTrace[i].m_nEntityHandle) {
- SetRadarMarkerState(i, false);
- ms_RadarTrace[i].m_bInUse = false;
- ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
- ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
- ms_RadarTrace[i].m_IconID = RADAR_SPRITE_NONE;
- }
- };
-}
-
-// Why not a proper clipping algorithm?
-int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
-{
- CVector2D corners[4] = {
- { 1.0f, -1.0f }, // top right
- { 1.0f, 1.0f }, // bottom right
- { -1.0f, 1.0f }, // bottom left
- { -1.0f, -1.0f }, // top left
- };
- CVector2D tmp;
- int i, j, n;
- int laste, e, e1, e2;;
- bool inside[4];
-
- for (i = 0; i < 4; i++)
- inside[i] = IsPointInsideRadar(rect[i]);
-
- laste = -1;
- n = 0;
- for (i = 0; i < 4; i++)
- if (inside[i]) {
- // point is inside, just add
- poly[n++] = rect[i];
- }
- else {
- // point is outside but line to this point might be clipped
- e1 = LineRadarBoxCollision(poly[n], rect[i], rect[(i + 4 - 1) % 4]);
- if (e1 != -1) {
- laste = e1;
- n++;
- }
- // and line from this point might be clipped as well
- e2 = LineRadarBoxCollision(poly[n], rect[i], rect[(i + 1) % 4]);
- if (e2 != -1) {
- if (e1 == -1) {
- // if other line wasn't clipped, i.e. it was complete outside,
- // we may have to insert another vertex if last clipped line
- // was on a different edge
-
- // find the last intersection if we haven't seen it yet
- if (laste == -1)
- for (j = 3; j >= i; j--) {
- // game uses an if here for j == 0
- e = LineRadarBoxCollision(tmp, rect[j], rect[(j + 4 - 1) % 4]);
- if (e != -1) {
- laste = e;
- break;
- }
- }
- assert(laste != -1);
-
- // insert corners that were skipped
- tmp = poly[n];
- for (e = laste; e != e2; e = (e + 1) % 4)
- poly[n++] = corners[e];
- poly[n] = tmp;
- }
- n++;
- }
- }
-
- if (n == 0) {
- // If no points, either the rectangle is completely outside or completely surrounds the radar
- // no idea what's going on here...
- float m = (rect[0].y - rect[1].y) / (rect[0].x - rect[1].x);
- if ((m*rect[3].x - rect[3].y) * (m*rect[0].x - rect[0].y) < 0.0f) {
- m = (rect[0].y - rect[3].y) / (rect[0].x - rect[3].x);
- if ((m*rect[1].x - rect[1].y) * (m*rect[0].x - rect[0].y) < 0.0f) {
- poly[0] = corners[0];
- poly[1] = corners[1];
- poly[2] = corners[2];
- poly[3] = corners[3];
- n = 4;
- }
- }
- }
-
- return n;
-}
-
-bool CRadar::DisplayThisBlip(int32 counter)
-{
- switch (ms_RadarTrace[counter].m_IconID) {
- case RADAR_SPRITE_BOMB:
- case RADAR_SPRITE_SPRAY:
- case RADAR_SPRITE_WEAPON:
- return true;
- default:
- return false;
- }
-}
-
-void CRadar::Draw3dMarkers()
-{
- for (int i = 0; i < NUMRADARBLIPS; i++) {
- if (ms_RadarTrace[i].m_bInUse) {
- switch (ms_RadarTrace[i].m_eBlipType) {
- case BLIP_CAR:
- {
- CEntity *entity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- CVector pos = entity->GetPosition();
- pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
- }
- break;
- }
- case BLIP_CHAR:
- {
- CEntity *entity = CPools::GetPedPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
- if (entity != nil) {
- if (((CPed*)entity)->InVehicle())
- entity = ((CPed * )entity)->m_pMyVehicle;
- }
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- CVector pos = entity->GetPosition();
- pos.z += 3.0f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
- }
- break;
- }
- case BLIP_OBJECT:
- {
- CEntity *entity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- CVector pos = entity->GetPosition();
- pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, 0, 128, 255, 255, 1024, 0.2f, 5);
- }
- break;
- }
- case BLIP_COORD:
- break;
- case BLIP_CONTACT_POINT:
- if (!CTheScripts::IsPlayerOnAMission()) {
- if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY)
- C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, 0, 128, 255, 128, 2048, 0.2f, 0);
- }
- break;
- }
- }
- }
-}
-
-void CRadar::DrawBlips()
-{
- if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
-
- CVector2D out;
- CVector2D in = CVector2D(0.0f, 0.0f);
- TransformRadarPointToScreenSpace(out, in);
-
- float angle;
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN)
- angle = PI + FindPlayerHeading();
-#ifdef FIX_BUGS
- else if (TheCamera.GetLookDirection() != LOOKING_FORWARD)
- angle = FindPlayerHeading() - (PI + (TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind).Heading());
-#endif
- else
- angle = FindPlayerHeading() - (PI + TheCamera.GetForward().Heading());
-
- DrawRotatingRadarSprite(&CentreSprite, out.x, out.y, angle, 255);
-
- CVector2D vec2d;
- vec2d.x = vec2DRadarOrigin.x;
- vec2d.y = M_SQRT2 * m_radarRange + vec2DRadarOrigin.y;
- TransformRealWorldPointToRadarSpace(in, vec2d);
- LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255);
-
- CEntity *blipEntity = nil;
- for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
- if (!ms_RadarTrace[blipId].m_bInUse)
- continue;
-
- switch (ms_RadarTrace[blipId].m_eBlipType) {
- case BLIP_CAR:
- case BLIP_CHAR:
- case BLIP_OBJECT:
- if (ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SAVE
- || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_WEAPON) {
-
- switch (ms_RadarTrace[blipId].m_eBlipType) {
- case BLIP_CAR:
- blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- case BLIP_CHAR:
- blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- if (blipEntity != nil) {
- if (((CPed*)blipEntity)->InVehicle())
- blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
- }
- break;
- case BLIP_OBJECT:
- blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- default:
- break;
- }
- if (blipEntity) {
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE) {
- DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
- } else {
-#ifdef TRIANGULAR_BLIPS
- CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- CVector &blipPos = blipEntity->GetPosition();
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
- }
- }
- break;
- case BLIP_COORD:
- case BLIP_CONTACT_POINT:
- if ((ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SAVE
- || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_IconID == RADAR_SPRITE_WEAPON)
- && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
-
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE) {
- DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
- } else {
-#ifdef TRIANGULAR_BLIPS
- CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
- }
- break;
- default:
- break;
- }
- }
- for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
- if (!ms_RadarTrace[blipId].m_bInUse)
- continue;
-
- switch (ms_RadarTrace[blipId].m_eBlipType) {
- case BLIP_CAR:
- case BLIP_CHAR:
- case BLIP_OBJECT:
- if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SAVE
- && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_WEAPON) {
-
- switch (ms_RadarTrace[blipId].m_eBlipType) {
- case BLIP_CAR:
- blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- case BLIP_CHAR:
- blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- if (blipEntity != nil) {
- if (((CPed*)blipEntity)->InVehicle())
- blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
- }
- break;
- case BLIP_OBJECT:
- blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
- break;
- default:
- break;
- }
-
- if (blipEntity) {
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE)
- DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
- else
-#ifdef TRIANGULAR_BLIPS
- {
- CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- CVector &blipPos = blipEntity->GetPosition();
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
- }
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
- }
- break;
- default:
- break;
- }
- }
- for (int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
- if (!ms_RadarTrace[blipId].m_bInUse)
- continue;
-
- switch (ms_RadarTrace[blipId].m_eBlipType) {
- case BLIP_COORD:
- case BLIP_CONTACT_POINT:
- if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SAVE
- && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_WEAPON
- && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
-
- uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
- if (CTheScripts::IsDebugOn()) {
- ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
- ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
- if (ms_RadarTrace[blipId].m_Radius < 1.0f)
- ms_RadarTrace[blipId].m_Radius = 5.0f;
- }
- }
- if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
- TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
- float dist = LimitRadarPoint(in);
- TransformRadarPointToScreenSpace(out, in);
- if (ms_RadarTrace[blipId].m_IconID != RADAR_SPRITE_NONE)
- DrawRadarSprite(ms_RadarTrace[blipId].m_IconID, out.x, out.y, CalculateBlipAlpha(dist));
- else
-#ifdef TRIANGULAR_BLIPS
- {
- CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
- CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
- uint8 mode = BLIP_MODE_TRIANGULAR_UP;
- if (blipPos.z - pos.z <= 2.0f) {
- if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
- else mode = BLIP_MODE_SQUARE;
- }
- ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
- }
-#else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
-#endif
- }
- }
- break;
- default:
- break;
- }
- }
- }
-}
-
-void CRadar::DrawMap()
-{
- if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
- if (FindPlayerVehicle()) {
- float speed = FindPlayerSpeed().Magnitude();
- if (speed < RADAR_MIN_SPEED)
- m_radarRange = RADAR_MIN_RANGE;
- else if (speed < RADAR_MAX_SPEED)
- m_radarRange = (speed - RADAR_MIN_SPEED)/(RADAR_MAX_SPEED-RADAR_MIN_SPEED) * (RADAR_MAX_RANGE-RADAR_MIN_RANGE) + RADAR_MIN_RANGE;
- else
- m_radarRange = RADAR_MAX_RANGE;
- }
- else
- m_radarRange = RADAR_MIN_RANGE;
-
- vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
- DrawRadarMap();
- }
-}
-
-void CRadar::DrawRadarMap()
-{
- // Game calculates an unused CRect here
-
- DrawRadarMask();
-
- // top left ist (0, 0)
- int x = floorf((vec2DRadarOrigin.x - WORLD_MIN_X) / RADAR_TILE_SIZE);
- int y = ceilf((RADAR_NUM_TILES - 1) - (vec2DRadarOrigin.y - WORLD_MIN_Y) / RADAR_TILE_SIZE);
- StreamRadarSections(x, y);
-
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
- RwRenderStateSet(rwRENDERSTATETEXTUREPERSPECTIVE, (void*)FALSE);
-
- DrawRadarSection(x - 1, y - 1);
- DrawRadarSection(x, y - 1);
- DrawRadarSection(x + 1, y - 1);
- DrawRadarSection(x - 1, y);
- DrawRadarSection(x, y);
- DrawRadarSection(x + 1, y);
- DrawRadarSection(x - 1, y + 1);
- DrawRadarSection(x, y + 1);
- DrawRadarSection(x + 1, y + 1);
-}
-
-void CRadar::DrawRadarMask()
-{
- CVector2D corners[4] = {
- CVector2D(1.0f, -1.0f),
- CVector2D(1.0f, 1.0f),
- CVector2D(-1.0f, 1.0f),
- CVector2D(-1.0, -1.0f)
- };
-
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONALWAYS);
-
- CVector2D out[8];
- CVector2D in;
-
- // Draw the shape we want to mask out from the radar in four segments
- for (int i = 0; i < 4; i++) {
- // First point is always the corner itself
- in.x = corners[i].x;
- in.y = corners[i].y;
- TransformRadarPointToScreenSpace(out[0], in);
-
- // Then generate a quarter of the circle
- for (int j = 0; j < 7; j++) {
- in.x = corners[i].x * Cos(j * (PI / 2.0f / 6.0f));
- in.y = corners[i].y * Sin(j * (PI / 2.0f / 6.0f));
- TransformRadarPointToScreenSpace(out[j + 1], in);
- };
-
- CSprite2d::SetMaskVertices(8, (float *)out);
- RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8);
- };
-
- RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER);
-}
-
-void CRadar::DrawRadarSection(int32 x, int32 y)
-{
- int i;
- RwTexDictionary *txd;
- CVector2D worldPoly[8];
- CVector2D radarCorners[4];
- CVector2D radarPoly[8];
- CVector2D texCoords[8];
- CVector2D screenPoly[8];
- int numVertices;
- RwTexture *texture = nil;
-
- GetTextureCorners(x, y, worldPoly);
- ClipRadarTileCoords(x, y);
-
- assert(CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y]));
- txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict;
- if (txd)
- texture = GetFirstTexture(txd);
- if (texture == nil)
- return;
-
- for (i = 0; i < 4; i++)
- TransformRealWorldPointToRadarSpace(radarCorners[i], worldPoly[i]);
-
- numVertices = ClipRadarPoly(radarPoly, radarCorners);
-
- // FIX: can return earlier here
-// if(numVertices == 0)
- if (numVertices < 3)
- return;
-
- for (i = 0; i < numVertices; i++) {
- TransformRadarPointToRealWorldSpace(worldPoly[i], radarPoly[i]);
- TransformRealWorldToTexCoordSpace(texCoords[i], worldPoly[i], x, y);
- TransformRadarPointToScreenSpace(screenPoly[i], radarPoly[i]);
- }
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture));
- CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255));
- // check done above now
-// if(numVertices > 2)
- RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices);
-}
-
-void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
-{
- RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
-}
-
-void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
-{
- CVector curPosn[4];
- CVector oldPosn[4];
-
- curPosn[0].x = x - SCREEN_SCALE_X(5.6f);
- curPosn[0].y = y + SCREEN_SCALE_Y(5.6f);
-
- curPosn[1].x = x + SCREEN_SCALE_X(5.6f);
- curPosn[1].y = y + SCREEN_SCALE_Y(5.6f);
-
- curPosn[2].x = x - SCREEN_SCALE_X(5.6f);
- curPosn[2].y = y - SCREEN_SCALE_Y(5.6f);
-
- curPosn[3].x = x + SCREEN_SCALE_X(5.6f);
- curPosn[3].y = y - SCREEN_SCALE_Y(5.6f);
-
- for (uint32 i = 0; i < 4; i++) {
- oldPosn[i] = curPosn[i];
-
- curPosn[i].x = x + (oldPosn[i].x - x) * Cos(angle) + (oldPosn[i].y - y) * Sin(angle);
- curPosn[i].y = y - (oldPosn[i].x - x) * Sin(angle) + (oldPosn[i].y - y) * Cos(angle);
- }
-
- sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha));
-}
-
-int32 CRadar::GetActualBlipArrayIndex(int32 i)
-{
- if (i == -1)
- return -1;
- else if ((i & 0xFFFF0000) >> 16 != ms_RadarTrace[(uint16)i].m_BlipIndex)
- return -1;
- else
- return (uint16)i;
-}
-
-int32 CRadar::GetNewUniqueBlipIndex(int32 i)
-{
- if (ms_RadarTrace[i].m_BlipIndex >= UINT16_MAX - 1)
- ms_RadarTrace[i].m_BlipIndex = 1;
- else
- ms_RadarTrace[i].m_BlipIndex++;
- return i | (ms_RadarTrace[i].m_BlipIndex << 16);
-}
-
-uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
-{
- int32 c;
- switch (color) {
- case 0:
- if (bright)
- c = 0x712B49FF;
- else
- c = 0x7F0000FF;
- break;
- case 1:
- if (bright)
- c = 0x5FA06AFF;
- else
- c = 0x007F00FF;
- break;
- case 2:
- if (bright)
- c = 0x80A7F3FF;
- else
- c = 0x00007FFF;
- break;
- case 3:
- if (bright)
- c = 0xE1E1E1FF;
- else
- c = 0x7F7F7FFF;
- break;
- case 4:
- if (bright)
- c = 0xFFFF00FF;
- else
- c = 0x7F7F00FF;
- break;
- case 5:
- if (bright)
- c = 0xFF00FFFF;
- else
- c = 0x7F007FFF;
- break;
- case 6:
- if (bright)
- c = 0x00FFFFFF;
- else
- c = 0x007F7FFF;
- break;
- default:
- c = color;
- break;
- };
- return c;
-}
-
-const char* gRadarTexNames[] = {
- "radar00", "radar01", "radar02", "radar03", "radar04", "radar05", "radar06", "radar07",
- "radar08", "radar09", "radar10", "radar11", "radar12", "radar13", "radar14", "radar15",
- "radar16", "radar17", "radar18", "radar19", "radar20", "radar21", "radar22", "radar23",
- "radar24", "radar25", "radar26", "radar27", "radar28", "radar29", "radar30", "radar31",
- "radar32", "radar33", "radar34", "radar35", "radar36", "radar37", "radar38", "radar39",
- "radar40", "radar41", "radar42", "radar43", "radar44", "radar45", "radar46", "radar47",
- "radar48", "radar49", "radar50", "radar51", "radar52", "radar53", "radar54", "radar55",
- "radar56", "radar57", "radar58", "radar59", "radar60", "radar61", "radar62", "radar63",
-};
-
-void
-CRadar::Initialise()
-{
- for (int i = 0; i < NUMRADARBLIPS; i++) {
- ms_RadarTrace[i].m_BlipIndex = 1;
- SetRadarMarkerState(i, false);
- ms_RadarTrace[i].m_bInUse = false;
- ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
- ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
- ms_RadarTrace[i].m_IconID = RADAR_SPRITE_NONE;
- }
-
- m_radarRange = 350.0f;
- for (int i = 0; i < 64; i++)
- gRadarTxdIds[i] = CTxdStore::FindTxdSlot(gRadarTexNames[i]);
-}
-
-float CRadar::LimitRadarPoint(CVector2D &point)
-{
- float dist, invdist;
-
- dist = point.Magnitude();
- if (dist > 1.0f) {
- invdist = 1.0f / dist;
- point.x *= invdist;
- point.y *= invdist;
- }
- return dist;
-}
-
-void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size)
-{
- Initialise();
-INITSAVEBUF
- CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
-
- for (int i = 0; i < NUMRADARBLIPS; i++)
- ms_RadarTrace[i] = ReadSaveBuf<CBlip>(buf);
-
-VALIDATESAVEBUF(size);
-}
-
-void
-CRadar::LoadTextures()
-{
- CTxdStore::PushCurrentTxd();
- CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("hud"));
- AsukaSprite.SetTexture("radar_asuka");
- BombSprite.SetTexture("radar_bomb");
- CatSprite.SetTexture("radar_cat");
- CentreSprite.SetTexture("radar_centre");
- CopcarSprite.SetTexture("radar_copcar");
- DonSprite.SetTexture("radar_don");
- EightSprite.SetTexture("radar_eight");
- ElSprite.SetTexture("radar_el");
- IceSprite.SetTexture("radar_ice");
- JoeySprite.SetTexture("radar_joey");
- KenjiSprite.SetTexture("radar_kenji");
- LizSprite.SetTexture("radar_liz");
- LuigiSprite.SetTexture("radar_luigi");
- NorthSprite.SetTexture("radar_north");
- RaySprite.SetTexture("radar_ray");
- SalSprite.SetTexture("radar_sal");
- SaveSprite.SetTexture("radar_save");
- SpraySprite.SetTexture("radar_spray");
- TonySprite.SetTexture("radar_tony");
- WeaponSprite.SetTexture("radar_weapon");
- CTxdStore::PopCurrentTxd();
-}
-
-void RemoveMapSection(int32 x, int32 y)
-{
- if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
- CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
-}
-
-void CRadar::RemoveRadarSections()
-{
- for (int i = 0; i < 8; i++)
- for (int j = 0; j < 8; j++)
- RemoveMapSection(i, j);
-}
-
-void CRadar::RequestMapSection(int32 x, int32 y)
-{
- ClipRadarTileCoords(x, y);
- CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
-}
-
-void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
-{
- *size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
-INITSAVEBUF
- WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
-
- for (int i = 0; i < NUMRADARBLIPS; i++)
- WriteSaveBuf(buf, ms_RadarTrace[i]);
-
-VALIDATESAVEBUF(*size);
-}
-
-void CRadar::SetBlipSprite(int32 i, int32 icon)
-{
- int index = CRadar::GetActualBlipArrayIndex(i);
- if (index != -1) {
- ms_RadarTrace[index].m_IconID = icon;
- }
-}
-
-int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display)
-{
- int nextBlip;
- for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
- if (!ms_RadarTrace[nextBlip].m_bInUse)
- break;
- }
- ms_RadarTrace[nextBlip].m_eBlipType = type;
- ms_RadarTrace[nextBlip].m_nColor = color;
- ms_RadarTrace[nextBlip].m_bDim = 1;
- ms_RadarTrace[nextBlip].m_bInUse = 1;
- ms_RadarTrace[nextBlip].m_Radius = 1.0f;
- ms_RadarTrace[nextBlip].m_vec2DPos = pos;
- ms_RadarTrace[nextBlip].m_vecPos = pos;
- ms_RadarTrace[nextBlip].m_nEntityHandle = 0;
- ms_RadarTrace[nextBlip].m_wScale = 1;
- ms_RadarTrace[nextBlip].m_eBlipDisplay = display;
- ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
- return CRadar::GetNewUniqueBlipIndex(nextBlip);
-}
-
-int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display)
-{
- int nextBlip;
- for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
- if (!ms_RadarTrace[nextBlip].m_bInUse)
- break;
- }
- ms_RadarTrace[nextBlip].m_eBlipType = type;
- ms_RadarTrace[nextBlip].m_nColor = color;
- ms_RadarTrace[nextBlip].m_bDim = 1;
- ms_RadarTrace[nextBlip].m_bInUse = 1;
- ms_RadarTrace[nextBlip].m_Radius = 1.0f;
- ms_RadarTrace[nextBlip].m_nEntityHandle = handle;
- ms_RadarTrace[nextBlip].m_wScale = 1;
- ms_RadarTrace[nextBlip].m_eBlipDisplay = display;
- ms_RadarTrace[nextBlip].m_IconID = RADAR_SPRITE_NONE;
- return GetNewUniqueBlipIndex(nextBlip);
-}
-
-void CRadar::SetRadarMarkerState(int32 counter, bool flag)
-{
- CEntity *e;
- switch (ms_RadarTrace[counter].m_eBlipType) {
- case BLIP_CAR:
- e = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
- break;
- case BLIP_CHAR:
- e = CPools::GetPedPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
- break;
- case BLIP_OBJECT:
- e = CPools::GetObjectPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
- break;
- default:
- return;
- }
-
- if (e)
- e->bHasBlip = flag;
-}
-
-void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
- float f1 = radius * 1.4f;
- float f2 = radius * 0.5f;
- CVector p1, p2;
-
- p1 = pos + TheCamera.GetUp()*f1;
- p2 = pos + TheCamera.GetUp()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
-
- p1 = pos - TheCamera.GetUp()*f1;
- p2 = pos - TheCamera.GetUp()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
-
- p1 = pos + TheCamera.GetRight()*f1;
- p2 = pos + TheCamera.GetRight()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
-
- p1 = pos - TheCamera.GetRight()*f1;
- p2 = pos - TheCamera.GetRight()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
-}
-
-void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha)
-{
- if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
- return;
-
- CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
- CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
-}
-
-void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha, uint8 mode)
-{
- if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
- return;
-
- switch (mode)
- {
- case BLIP_MODE_TRIANGULAR_UP:
- // size++; // VC does size + 1 for triangles
- CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 3.0f), y + SCREEN_SCALE_Y(size + 2.0f), x - (SCREEN_SCALE_X(size + 3.0f)), y + SCREEN_SCALE_Y(size + 2.0f), x, y - (SCREEN_SCALE_Y(size + 3.0f)), x, y - (SCREEN_SCALE_Y(size + 3.0f)), CRGBA(0, 0, 0, alpha));
- CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 1.0f), y + SCREEN_SCALE_Y(size + 1.0f), x - (SCREEN_SCALE_X(size + 1.0f)), y + SCREEN_SCALE_Y(size + 1.0f), x, y - (SCREEN_SCALE_Y(size + 1.0f)), x, y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
- break;
- case BLIP_MODE_TRIANGULAR_DOWN:
- // size++; // VC does size + 1 for triangles
- CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 2.0f), x, y + SCREEN_SCALE_Y(size + 3.0f), x + SCREEN_SCALE_X(size + 3.0f), y - (SCREEN_SCALE_Y(size + 2.0f)), x - (SCREEN_SCALE_X(size + 3.0f)), y - (SCREEN_SCALE_Y(size + 2.0f)), CRGBA(0, 0, 0, alpha));
- CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 1.0f), x, y + SCREEN_SCALE_Y(size + 1.0f), x + SCREEN_SCALE_X(size + 1.0f), y - (SCREEN_SCALE_Y(size + 1.0f)), x - (SCREEN_SCALE_X(size + 1.0f)), y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
- break;
- case BLIP_MODE_SQUARE:
- CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
- CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
- break;
- }
-}
-
-void CRadar::Shutdown()
-{
- AsukaSprite.Delete();
- BombSprite.Delete();
- CatSprite.Delete();
- CentreSprite.Delete();
- CopcarSprite.Delete();
- DonSprite.Delete();
- EightSprite.Delete();
- ElSprite.Delete();
- IceSprite.Delete();
- JoeySprite.Delete();
- KenjiSprite.Delete();
- LizSprite.Delete();
- LuigiSprite.Delete();
- NorthSprite.Delete();
- RaySprite.Delete();
- SalSprite.Delete();
- SaveSprite.Delete();
- SpraySprite.Delete();
- TonySprite.Delete();
- WeaponSprite.Delete();
- RemoveRadarSections();
-}
-
-void CRadar::StreamRadarSections(const CVector &posn)
-{
- StreamRadarSections(floorf((2000.0f + posn.x) / 500.0f), ceilf(7.0f - (2000.0f + posn.y) / 500.0f));
-}
-
-void CRadar::StreamRadarSections(int32 x, int32 y)
-{
- for (int i = 0; i < RADAR_NUM_TILES; ++i) {
- for (int j = 0; j < RADAR_NUM_TILES; ++j) {
- if ((i >= x - 1 && i <= x + 1) && (j >= y - 1 && j <= y + 1))
- RequestMapSection(i, j);
- else
- RemoveMapSection(i, j);
- };
- };
-}
-
-void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y)
-{
- out.x = in.x - (x * RADAR_TILE_SIZE + WORLD_MIN_X);
- out.y = -(in.y - ((RADAR_NUM_TILES - y) * RADAR_TILE_SIZE + WORLD_MIN_Y));
- out.x /= RADAR_TILE_SIZE;
- out.y /= RADAR_TILE_SIZE;
-}
-
-void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in)
-{
- float s, c;
-
- s = -Sin(TheCamera.GetForward().Heading());
- c = Cos(TheCamera.GetForward().Heading());
-
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) {
- s = 0.0f;
- c = 1.0f;
- }
- else if (TheCamera.GetLookDirection() != LOOKING_FORWARD) {
- CVector forward;
-
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) {
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
- forward.Normalise(); // a bit useless...
- }
- else
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
-
- s = -Sin(forward.Heading());
- c = Cos(forward.Heading());
- }
-
- out.x = s * in.y + c * in.x;
- out.y = c * in.y - s * in.x;
-
- out = out * m_radarRange + vec2DRadarOrigin;
-}
-
-// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
-void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
-{
-#ifdef FIX_BUGS
- out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
-#else
- out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + RADAR_LEFT;
-#endif
- out.y = (1.0f - in.y)*0.5f*SCREEN_SCALE_Y(RADAR_HEIGHT) + SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT);
-}
-
-void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in)
-{
- float s, c;
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) {
- s = 0.0f;
- c = 1.0f;
- }
- else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
- s = Sin(TheCamera.GetForward().Heading());
- c = Cos(TheCamera.GetForward().Heading());
- }
- else {
- CVector forward;
-
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) {
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
- forward.Normalise(); // a bit useless...
- }
- else
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
-
- s = Sin(forward.Heading());
- c = Cos(forward.Heading());
- }
-
- float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_radarRange);
- float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_radarRange);
-
- out.x = s * y + c * x;
- out.y = c * y - s * x;
-}
-
-// Transform from section indices to world coordinates
-void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out)
-{
- x = x - RADAR_NUM_TILES/2;
- y = -(y - RADAR_NUM_TILES/2);
-
- // bottom left
- out[0].x = RADAR_TILE_SIZE * (x);
- out[0].y = RADAR_TILE_SIZE * (y - 1);
-
- // bottom right
- out[1].x = RADAR_TILE_SIZE * (x + 1);
- out[1].y = RADAR_TILE_SIZE * (y - 1);
-
- // top right
- out[2].x = RADAR_TILE_SIZE * (x + 1);
- out[2].y = RADAR_TILE_SIZE * (y);
-
- // top left
- out[3].x = RADAR_TILE_SIZE * (x);
- out[3].y = RADAR_TILE_SIZE * (y);
-}
-
-void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
-{
- if (x < 0)
- x = 0;
- if (x > RADAR_NUM_TILES-1)
- x = RADAR_NUM_TILES-1;
- if (y < 0)
- y = 0;
- if (y > RADAR_NUM_TILES-1)
- y = RADAR_NUM_TILES-1;
-}
-
-
-bool CRadar::IsPointInsideRadar(const CVector2D &point)
-{
- if (point.x < -1.0f || point.x > 1.0f) return false;
- if (point.y < -1.0f || point.y > 1.0f) return false;
- return true;
-}
-
-// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
-int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
-{
- float d1, d2;
- float t;
- float x, y;
- float shortest = 1.0f;
- int edge = -1;
-
- // clip against left edge, x = -1.0
- d1 = -1.0f - p1.x;
- d2 = -1.0f - p2.x;
- if (d1 * d2 < 0.0f) {
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- y = (p2.y - p1.y)*t + p1.y;
- if (y >= -1.0f && y <= 1.0f && t <= shortest) {
- out.x = -1.0f;
- out.y = y;
- edge = 3;
- shortest = t;
- }
- }
-
- // clip against right edge, x = 1.0
- d1 = p1.x - 1.0f;
- d2 = p2.x - 1.0f;
- if (d1 * d2 < 0.0f) {
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- y = (p2.y - p1.y)*t + p1.y;
- if (y >= -1.0f && y <= 1.0f && t <= shortest) {
- out.x = 1.0f;
- out.y = y;
- edge = 1;
- shortest = t;
- }
- }
-
- // clip against top edge, y = -1.0
- d1 = -1.0f - p1.y;
- d2 = -1.0f - p2.y;
- if (d1 * d2 < 0.0f) {
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- x = (p2.x - p1.x)*t + p1.x;
- if (x >= -1.0f && x <= 1.0f && t <= shortest) {
- out.y = -1.0f;
- out.x = x;
- edge = 0;
- shortest = t;
- }
- }
-
- // clip against bottom edge, y = 1.0
- d1 = p1.y - 1.0f;
- d2 = p2.y - 1.0f;
- if (d1 * d2 < 0.0f) {
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- x = (p2.x - p1.x)*t + p1.x;
- if (x >= -1.0f && x <= 1.0f && t <= shortest) {
- out.y = 1.0f;
- out.x = x;
- edge = 2;
- shortest = t;
- }
- }
-
- return edge;
-}
-
-STARTPATCHES
- InjectHook(0x4A3EF0, CRadar::Initialise, PATCH_JUMP);
- InjectHook(0x4A3F60, CRadar::Shutdown, PATCH_JUMP);
- InjectHook(0x4A4030, CRadar::LoadTextures, PATCH_JUMP);
- InjectHook(0x4A4180, CRadar::GetNewUniqueBlipIndex, PATCH_JUMP);
- InjectHook(0x4A41C0, CRadar::GetActualBlipArrayIndex, PATCH_JUMP);
- InjectHook(0x4A4200, CRadar::DrawMap, PATCH_JUMP);
- InjectHook(0x4A42F0, CRadar::DrawBlips, PATCH_JUMP);
- InjectHook(0x4A4C70, CRadar::Draw3dMarkers, PATCH_JUMP);
- InjectHook(0x4A4F30, CRadar::LimitRadarPoint, PATCH_JUMP);
- InjectHook(0x4A4F90, CRadar::CalculateBlipAlpha, PATCH_JUMP);
- InjectHook(0x4A5040, CRadar::TransformRadarPointToScreenSpace, PATCH_JUMP);
- InjectHook(0x4A50D0, CRadar::TransformRealWorldPointToRadarSpace, PATCH_JUMP);
- InjectHook(0x4A5300, CRadar::TransformRadarPointToRealWorldSpace, PATCH_JUMP);
- InjectHook(0x4A5530, CRadar::TransformRealWorldToTexCoordSpace, PATCH_JUMP);
- InjectHook(0x4A5590, CRadar::SetCoordBlip, PATCH_JUMP);
- InjectHook(0x4A5640, CRadar::SetEntityBlip, PATCH_JUMP);
- InjectHook(0x4A56C0, CRadar::ClearBlipForEntity, PATCH_JUMP);
- InjectHook(0x4A5720, CRadar::ClearBlip, PATCH_JUMP);
- InjectHook(0x4A5770, CRadar::ChangeBlipColour, PATCH_JUMP);
- InjectHook(0x4A57A0, CRadar::ChangeBlipBrightness, PATCH_JUMP);
- InjectHook(0x4A57E0, CRadar::ChangeBlipScale, PATCH_JUMP);
- InjectHook(0x4A5810, CRadar::ChangeBlipDisplay, PATCH_JUMP);
- InjectHook(0x4A5840, CRadar::SetBlipSprite, PATCH_JUMP);
- InjectHook(0x4A5870, CRadar::ShowRadarTrace, PATCH_JUMP);
- InjectHook(0x4A59C0, CRadar::ShowRadarMarker, PATCH_JUMP);
- InjectHook(0x4A5BB0, CRadar::GetRadarTraceColour, PATCH_JUMP);
- InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
- InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
- InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, PATCH_JUMP);
- InjectHook(0x4A60E0, CRadar::RemoveRadarSections, PATCH_JUMP);
- InjectHook(0x4A6100, (void (*)(int32, int32))&CRadar::StreamRadarSections, PATCH_JUMP);
- InjectHook(0x4A64A0, CRadar::ClipRadarPoly, PATCH_JUMP);
- InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP);
- InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP);
- InjectHook(0x4A6B60, (void (*)(const CVector&))&CRadar::StreamRadarSections, PATCH_JUMP);
- InjectHook(0x4A6C20, CRadar::DrawRadarMap, PATCH_JUMP);
- InjectHook(0x4A6E30, CRadar::SaveAllRadarBlips, PATCH_JUMP);
- InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP);
-
- InjectHook(0x4A61C0, CRadar::GetTextureCorners, PATCH_JUMP);
- InjectHook(0x4A6160, CRadar::IsPointInsideRadar, PATCH_JUMP);
- InjectHook(0x4A6250, CRadar::LineRadarBoxCollision, PATCH_JUMP);
-ENDPATCHES
+#include "config.h"
+#include "common.h"
+#include "patcher.h"
+#include "RwHelper.h"
+#include "Radar.h"
+#include "Camera.h"
+#include "Hud.h"
+#include "World.h"
+#include "Frontend.h"
+#include "General.h"
+#include "Vehicle.h"
+#include "Pools.h"
+#include "Script.h"
+#include "TxdStore.h"
+#include "World.h"
+#include "Streaming.h"
+#include "SpecialFX.h"
+
+float &CRadar::m_radarRange = *(float*)0x8E281C;
+sRadarTrace (&CRadar::ms_RadarTrace)[NUMRADARBLIPS] = *(sRadarTrace(*)[NUMRADARBLIPS]) * (uintptr*)0x6ED5E0;
+CVector2D &vec2DRadarOrigin = *(CVector2D*)0x6299B8;
+int32 gRadarTxdIds[64];// = (int*)0x6299C0;
+
+CSprite2d CRadar::AsukaSprite;// = *(CSprite2d*)0x8F1A40;
+CSprite2d CRadar::BombSprite;// = (CSprite2d*)0x8F5FB4;
+CSprite2d CRadar::CatSprite;// = (CSprite2d*)0x885B24;
+CSprite2d CRadar::CentreSprite;// = (CSprite2d*)0x8F6268;
+CSprite2d CRadar::CopcarSprite;// = (CSprite2d*)0x8F1A2C;
+CSprite2d CRadar::DonSprite;// = (CSprite2d*)0x8F2BE0;
+CSprite2d CRadar::EightSprite;// = (CSprite2d*)0x8F2BCC;
+CSprite2d CRadar::ElSprite;// = (CSprite2d*)0x8F1B80;
+CSprite2d CRadar::IceSprite;// = (CSprite2d*)0x9415FC;
+CSprite2d CRadar::JoeySprite;// = (CSprite2d*)0x8F2C00;
+CSprite2d CRadar::KenjiSprite;// = (CSprite2d*)0x8F2C68;
+CSprite2d CRadar::LizSprite;// = (CSprite2d*)0x8F5830;
+CSprite2d CRadar::LuigiSprite;// = (CSprite2d*)0x8F1A3C;
+CSprite2d CRadar::NorthSprite;// = (CSprite2d*)0x8F6274;
+CSprite2d CRadar::RaySprite;// = (CSprite2d*)0x8E2A7C;
+CSprite2d CRadar::SalSprite;// = (CSprite2d*)0x8F29EC;
+CSprite2d CRadar::SaveSprite;// = (CSprite2d*)0x8F5F74;
+CSprite2d CRadar::SpraySprite;// = (CSprite2d*)0x94307C;
+CSprite2d CRadar::TonySprite;// = (CSprite2d*)0x885B58;
+CSprite2d CRadar::WeaponSprite;// = (CSprite2d*)0x941534;
+
+CSprite2d *CRadar::RadarSprites[RADAR_SPRITE_COUNT] = {
+ nil,
+ &AsukaSprite,
+ &BombSprite,
+ &CatSprite,
+ &CentreSprite,
+ &CopcarSprite,
+ &DonSprite,
+ &EightSprite,
+ &ElSprite,
+ &IceSprite,
+ &JoeySprite,
+ &KenjiSprite,
+ &LizSprite,
+ &LuigiSprite,
+ &NorthSprite,
+ &RaySprite,
+ &SalSprite,
+ &SaveSprite,
+ &SpraySprite,
+ &TonySprite,
+ &WeaponSprite
+};
+
+#define RADAR_NUM_TILES (8)
+#define RADAR_TILE_SIZE (WORLD_SIZE_X / RADAR_NUM_TILES)
+static_assert(RADAR_TILE_SIZE == (WORLD_SIZE_Y / RADAR_NUM_TILES), "CRadar: not a square");
+
+#define RADAR_MIN_RANGE (120.0f)
+#define RADAR_MAX_RANGE (350.0f)
+#define RADAR_MIN_SPEED (0.3f)
+#define RADAR_MAX_SPEED (0.9f)
+
+#ifdef MENU_MAP
+CRGBA CRadar::ArrowBlipColour1;
+CRGBA CRadar::ArrowBlipColour2;
+uint16 CRadar::MapLegendCounter;
+uint16 CRadar::MapLegendList[NUM_MAP_LEGENDS];
+int CRadar::TargetMarkerId = -1;
+#endif
+
+// taken from VC
+float CRadar::cachedCos;
+float CRadar::cachedSin;
+
+void ClipRadarTileCoords(int32 &x, int32 &y)
+{
+ if (x < 0)
+ x = 0;
+ if (x > RADAR_NUM_TILES-1)
+ x = RADAR_NUM_TILES-1;
+ if (y < 0)
+ y = 0;
+ if (y > RADAR_NUM_TILES-1)
+ y = RADAR_NUM_TILES-1;
+}
+
+void RequestMapSection(int32 x, int32 y)
+{
+ ClipRadarTileCoords(x, y);
+ CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
+}
+
+void RemoveMapSection(int32 x, int32 y)
+{
+ if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
+ CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
+}
+
+// Transform from section indices to world coordinates
+void GetTextureCorners(int32 x, int32 y, CVector2D *out)
+{
+ x = x - RADAR_NUM_TILES/2;
+ y = -(y - RADAR_NUM_TILES/2);
+
+ // bottom left
+ out[0].x = RADAR_TILE_SIZE * (x);
+ out[0].y = RADAR_TILE_SIZE * (y - 1);
+
+ // bottom right
+ out[1].x = RADAR_TILE_SIZE * (x + 1);
+ out[1].y = RADAR_TILE_SIZE * (y - 1);
+
+ // top right
+ out[2].x = RADAR_TILE_SIZE * (x + 1);
+ out[2].y = RADAR_TILE_SIZE * (y);
+
+ // top left
+ out[3].x = RADAR_TILE_SIZE * (x);
+ out[3].y = RADAR_TILE_SIZE * (y);
+}
+
+
+bool IsPointInsideRadar(const CVector2D &point)
+{
+ if (point.x < -1.0f || point.x > 1.0f) return false;
+ if (point.y < -1.0f || point.y > 1.0f) return false;
+ return true;
+}
+
+// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
+int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
+{
+ float d1, d2;
+ float t;
+ float x, y;
+ float shortest = 1.0f;
+ int edge = -1;
+
+ // clip against left edge, x = -1.0
+ d1 = -1.0f - p1.x;
+ d2 = -1.0f - p2.x;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ y = (p2.y - p1.y)*t + p1.y;
+ if (y >= -1.0f && y <= 1.0f && t <= shortest) {
+ out.x = -1.0f;
+ out.y = y;
+ edge = 3;
+ shortest = t;
+ }
+ }
+
+ // clip against right edge, x = 1.0
+ d1 = p1.x - 1.0f;
+ d2 = p2.x - 1.0f;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ y = (p2.y - p1.y)*t + p1.y;
+ if (y >= -1.0f && y <= 1.0f && t <= shortest) {
+ out.x = 1.0f;
+ out.y = y;
+ edge = 1;
+ shortest = t;
+ }
+ }
+
+ // clip against top edge, y = -1.0
+ d1 = -1.0f - p1.y;
+ d2 = -1.0f - p2.y;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ x = (p2.x - p1.x)*t + p1.x;
+ if (x >= -1.0f && x <= 1.0f && t <= shortest) {
+ out.y = -1.0f;
+ out.x = x;
+ edge = 0;
+ shortest = t;
+ }
+ }
+
+ // clip against bottom edge, y = 1.0
+ d1 = p1.y - 1.0f;
+ d2 = p2.y - 1.0f;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ x = (p2.x - p1.x)*t + p1.x;
+ if (x >= -1.0f && x <= 1.0f && t <= shortest) {
+ out.y = 1.0f;
+ out.x = x;
+ edge = 2;
+ shortest = t;
+ }
+ }
+
+ return edge;
+}
+
+
+uint8 CRadar::CalculateBlipAlpha(float dist)
+{
+#ifdef MENU_MAP
+ if (CMenuManager::bMenuMapActive)
+ return 255;
+#endif
+ if (dist <= 1.0f)
+ return 255;
+
+ if (dist <= 5.0f)
+ return (128.0f * ((dist - 1.0f) / 4.0f)) + ((1.0f - (dist - 1.0f) / 4.0f) * 255.0f);
+
+ return 128;
+}
+
+void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
+{
+ int index = GetActualBlipArrayIndex(i);
+ if (index != -1)
+ ms_RadarTrace[index].m_bDim = bright != 1;
+}
+
+void CRadar::ChangeBlipColour(int32 i, int32 color)
+{
+ int index = GetActualBlipArrayIndex(i);
+ if (index != -1)
+ ms_RadarTrace[index].m_nColor = color;
+}
+
+void CRadar::ChangeBlipDisplay(int32 i, eBlipDisplay display)
+{
+ int index = GetActualBlipArrayIndex(i);
+ if (index != -1)
+ ms_RadarTrace[index].m_eBlipDisplay = display;
+}
+
+void CRadar::ChangeBlipScale(int32 i, int32 scale)
+{
+ int index = GetActualBlipArrayIndex(i);
+ if (index != -1)
+ ms_RadarTrace[index].m_wScale = scale;
+}
+
+void CRadar::ClearBlip(int32 i)
+{
+ int index = GetActualBlipArrayIndex(i);
+ if (index != -1) {
+ SetRadarMarkerState(index, false);
+ ms_RadarTrace[index].m_bInUse = false;
+#ifndef MENU_MAP
+ // Ssshhh
+ ms_RadarTrace[index].m_eBlipType = BLIP_NONE;
+ ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
+ ms_RadarTrace[index].m_eRadarSprite = RADAR_SPRITE_NONE;
+#endif
+ }
+}
+
+void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
+{
+ for (int i = 0; i < NUMRADARBLIPS; i++) {
+ if (type == ms_RadarTrace[i].m_eBlipType && id == ms_RadarTrace[i].m_nEntityHandle) {
+ SetRadarMarkerState(i, false);
+ ms_RadarTrace[i].m_bInUse = false;
+ ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
+ ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
+ ms_RadarTrace[i].m_eRadarSprite = RADAR_SPRITE_NONE;
+ }
+ };
+}
+
+// Why not a proper clipping algorithm?
+int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
+{
+ CVector2D corners[4] = {
+ { 1.0f, -1.0f }, // top right
+ { 1.0f, 1.0f }, // bottom right
+ { -1.0f, 1.0f }, // bottom left
+ { -1.0f, -1.0f }, // top left
+ };
+ CVector2D tmp;
+ int i, j, n;
+ int laste, e, e1, e2;;
+ bool inside[4];
+
+ for (i = 0; i < 4; i++)
+ inside[i] = IsPointInsideRadar(rect[i]);
+
+ laste = -1;
+ n = 0;
+ for (i = 0; i < 4; i++)
+ if (inside[i]) {
+ // point is inside, just add
+ poly[n++] = rect[i];
+ }
+ else {
+ // point is outside but line to this point might be clipped
+ e1 = LineRadarBoxCollision(poly[n], rect[i], rect[(i + 4 - 1) % 4]);
+ if (e1 != -1) {
+ laste = e1;
+ n++;
+ }
+ // and line from this point might be clipped as well
+ e2 = LineRadarBoxCollision(poly[n], rect[i], rect[(i + 1) % 4]);
+ if (e2 != -1) {
+ if (e1 == -1) {
+ // if other line wasn't clipped, i.e. it was complete outside,
+ // we may have to insert another vertex if last clipped line
+ // was on a different edge
+
+ // find the last intersection if we haven't seen it yet
+ if (laste == -1)
+ for (j = 3; j >= i; j--) {
+ // game uses an if here for j == 0
+ e = LineRadarBoxCollision(tmp, rect[j], rect[(j + 4 - 1) % 4]);
+ if (e != -1) {
+ laste = e;
+ break;
+ }
+ }
+ assert(laste != -1);
+
+ // insert corners that were skipped
+ tmp = poly[n];
+ for (e = laste; e != e2; e = (e + 1) % 4)
+ poly[n++] = corners[e];
+ poly[n] = tmp;
+ }
+ n++;
+ }
+ }
+
+ if (n == 0) {
+ // If no points, either the rectangle is completely outside or completely surrounds the radar
+ // no idea what's going on here...
+ float m = (rect[0].y - rect[1].y) / (rect[0].x - rect[1].x);
+ if ((m*rect[3].x - rect[3].y) * (m*rect[0].x - rect[0].y) < 0.0f) {
+ m = (rect[0].y - rect[3].y) / (rect[0].x - rect[3].x);
+ if ((m*rect[1].x - rect[1].y) * (m*rect[0].x - rect[0].y) < 0.0f) {
+ poly[0] = corners[0];
+ poly[1] = corners[1];
+ poly[2] = corners[2];
+ poly[3] = corners[3];
+ n = 4;
+ }
+ }
+ }
+
+ return n;
+}
+
+bool CRadar::DisplayThisBlip(int32 counter)
+{
+ switch (ms_RadarTrace[counter].m_eRadarSprite) {
+ case RADAR_SPRITE_BOMB:
+ case RADAR_SPRITE_SPRAY:
+ case RADAR_SPRITE_WEAPON:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void CRadar::Draw3dMarkers()
+{
+ for (int i = 0; i < NUMRADARBLIPS; i++) {
+ if (ms_RadarTrace[i].m_bInUse) {
+ switch (ms_RadarTrace[i].m_eBlipType) {
+ case BLIP_CAR:
+ {
+ CEntity *entity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
+ if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ CVector pos = entity->GetPosition();
+ pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f;
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ }
+ break;
+ }
+ case BLIP_CHAR:
+ {
+ CEntity *entity = CPools::GetPedPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
+ if (entity != nil) {
+ if (((CPed*)entity)->InVehicle())
+ entity = ((CPed * )entity)->m_pMyVehicle;
+ }
+ if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ CVector pos = entity->GetPosition();
+ pos.z += 3.0f;
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ }
+ break;
+ }
+ case BLIP_OBJECT:
+ {
+ CEntity *entity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[i].m_nEntityHandle);
+ if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ CVector pos = entity->GetPosition();
+ pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f;
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ }
+ break;
+ }
+ case BLIP_COORD:
+ break;
+ case BLIP_CONTACT_POINT:
+ if (!CTheScripts::IsPlayerOnAMission()) {
+ if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY)
+ C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, 0, 128, 255, 128, 2048, 0.2f, 0);
+ }
+ break;
+ }
+ }
+ }
+}
+
+void CRadar::DrawBlips()
+{
+ if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+
+ CVector2D out;
+ CVector2D in = CVector2D(0.0f, 0.0f);
+ TransformRadarPointToScreenSpace(out, in);
+
+#ifdef MENU_MAP
+ if (!CMenuManager::bMenuMapActive) {
+#endif
+ float angle;
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN)
+ angle = PI + FindPlayerHeading();
+#ifdef FIX_BUGS
+ else if (TheCamera.GetLookDirection() != LOOKING_FORWARD)
+ angle = FindPlayerHeading() - (PI + (TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind).Heading());
+#endif
+ else
+ angle = FindPlayerHeading() - (PI + TheCamera.GetForward().Heading());
+
+ DrawRotatingRadarSprite(&CentreSprite, out.x, out.y, angle, 255);
+
+ CVector2D vec2d;
+ vec2d.x = vec2DRadarOrigin.x;
+ vec2d.y = M_SQRT2 * m_radarRange + vec2DRadarOrigin.y;
+ TransformRealWorldPointToRadarSpace(in, vec2d);
+ LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ DrawRadarSprite(RADAR_SPRITE_NORTH, out.x, out.y, 255);
+#ifdef MENU_MAP
+ }
+#endif
+
+ CEntity *blipEntity = nil;
+ for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
+#ifdef MENU_MAP
+ // A little hack to reuse cleared blips in menu map. hehe
+ if (!CMenuManager::bMenuMapActive || ms_RadarTrace[blipId].m_eBlipType == BLIP_CAR ||
+ ms_RadarTrace[blipId].m_eBlipType == BLIP_CHAR || ms_RadarTrace[blipId].m_eBlipType == BLIP_OBJECT)
+#endif
+ if (!ms_RadarTrace[blipId].m_bInUse)
+ continue;
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ case BLIP_CHAR:
+ case BLIP_OBJECT:
+ if (ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE
+ || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON) {
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ case BLIP_CHAR:
+ blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ if (blipEntity != nil) {
+ if (((CPed*)blipEntity)->InVehicle())
+ blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
+ }
+ break;
+ case BLIP_OBJECT:
+ blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ default:
+ break;
+ }
+ if (blipEntity) {
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::IsDebugOn()) {
+ ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) {
+ DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
+ } else {
+#ifdef TRIANGULAR_BLIPS
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = blipEntity->GetPosition();
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
+ }
+ }
+ }
+ }
+ break;
+ case BLIP_COORD:
+ case BLIP_CONTACT_POINT:
+ if ((ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_BOMB || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SAVE
+ || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_SPRAY || ms_RadarTrace[blipId].m_eRadarSprite == RADAR_SPRITE_WEAPON)
+ && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
+
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::IsDebugOn()) {
+ ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE) {
+ DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
+ } else {
+#ifdef TRIANGULAR_BLIPS
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ for(int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
+ if (!ms_RadarTrace[blipId].m_bInUse)
+ continue;
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ case BLIP_CHAR:
+ case BLIP_OBJECT:
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE
+ && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON) {
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_CAR:
+ blipEntity = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ case BLIP_CHAR:
+ blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ if (blipEntity != nil) {
+ if (((CPed*)blipEntity)->InVehicle())
+ blipEntity = ((CPed*)blipEntity)->m_pMyVehicle;
+ }
+ break;
+ case BLIP_OBJECT:
+ blipEntity = CPools::GetObjectPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle);
+ break;
+ default:
+ break;
+ }
+
+ if (blipEntity) {
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::IsDebugOn()) {
+ ShowRadarMarker(blipEntity->GetPosition(), color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, blipEntity->GetPosition());
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE)
+ DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
+ else
+#ifdef TRIANGULAR_BLIPS
+ {
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = blipEntity->GetPosition();
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+ }
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ for (int blipId = 0; blipId < NUMRADARBLIPS; blipId++) {
+ if (!ms_RadarTrace[blipId].m_bInUse)
+ continue;
+
+ switch (ms_RadarTrace[blipId].m_eBlipType) {
+ case BLIP_COORD:
+ case BLIP_CONTACT_POINT:
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_BOMB && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SAVE
+ && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_SPRAY && ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_WEAPON
+ && (ms_RadarTrace[blipId].m_eBlipType != BLIP_CONTACT_POINT || !CTheScripts::IsPlayerOnAMission())) {
+
+ uint32 color = GetRadarTraceColour(ms_RadarTrace[blipId].m_nColor, ms_RadarTrace[blipId].m_bDim);
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
+ if (CTheScripts::IsDebugOn()) {
+ ShowRadarMarker(ms_RadarTrace[blipId].m_vecPos, color, ms_RadarTrace[blipId].m_Radius);
+ ms_RadarTrace[blipId].m_Radius = ms_RadarTrace[blipId].m_Radius - 0.1f;
+ if (ms_RadarTrace[blipId].m_Radius < 1.0f)
+ ms_RadarTrace[blipId].m_Radius = 5.0f;
+ }
+ }
+ if (ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[blipId].m_eBlipDisplay == BLIP_DISPLAY_BLIP_ONLY) {
+ TransformRealWorldPointToRadarSpace(in, ms_RadarTrace[blipId].m_vec2DPos);
+ float dist = LimitRadarPoint(in);
+ TransformRadarPointToScreenSpace(out, in);
+ if (ms_RadarTrace[blipId].m_eRadarSprite != RADAR_SPRITE_NONE)
+ DrawRadarSprite(ms_RadarTrace[blipId].m_eRadarSprite, out.x, out.y, CalculateBlipAlpha(dist));
+ else
+#ifdef TRIANGULAR_BLIPS
+ {
+ CVector &pos = FindPlayerCentreOfWorld_NoSniperShift();
+ CVector &blipPos = ms_RadarTrace[blipId].m_vecPos;
+ uint8 mode = BLIP_MODE_TRIANGULAR_UP;
+ if (blipPos.z - pos.z <= 2.0f) {
+ if (blipPos.z - pos.z < -4.0f) mode = BLIP_MODE_TRIANGULAR_DOWN;
+ else mode = BLIP_MODE_SQUARE;
+ }
+ ShowRadarTraceWithHeight(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255, mode);
+ }
+#else
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[blipId].m_wScale, (uint8)(color >> 24), (uint8)(color >> 16), (uint8)(color >> 8), 255);
+#endif
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+#ifdef MENU_MAP
+ if (CMenuManager::bMenuMapActive) {
+ CVector2D in, out;
+ TransformRealWorldPointToRadarSpace(in, FindPlayerCentreOfWorld_NoSniperShift());
+ TransformRadarPointToScreenSpace(out, in);
+ DrawYouAreHereSprite(out.x, out.y);
+ }
+#endif
+ }
+}
+
+void CRadar::DrawMap()
+{
+ if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
+#if 1 // from VC
+ CalculateCachedSinCos();
+#endif
+ if (FindPlayerVehicle()) {
+ float speed = FindPlayerSpeed().Magnitude();
+ if (speed < RADAR_MIN_SPEED)
+ m_radarRange = RADAR_MIN_RANGE;
+ else if (speed < RADAR_MAX_SPEED)
+ m_radarRange = (speed - RADAR_MIN_SPEED)/(RADAR_MAX_SPEED-RADAR_MIN_SPEED) * (RADAR_MAX_RANGE-RADAR_MIN_RANGE) + RADAR_MIN_RANGE;
+ else
+ m_radarRange = RADAR_MAX_RANGE;
+ }
+ else
+ m_radarRange = RADAR_MIN_RANGE;
+
+ vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
+ DrawRadarMap();
+ }
+}
+
+void CRadar::DrawRadarMap()
+{
+ // Game calculates an unused CRect here
+
+ DrawRadarMask();
+
+ // top left ist (0, 0)
+ int x = floorf((vec2DRadarOrigin.x - WORLD_MIN_X) / RADAR_TILE_SIZE);
+ int y = ceilf((RADAR_NUM_TILES - 1) - (vec2DRadarOrigin.y - WORLD_MIN_Y) / RADAR_TILE_SIZE);
+ StreamRadarSections(x, y);
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
+ RwRenderStateSet(rwRENDERSTATETEXTUREPERSPECTIVE, (void*)FALSE);
+
+ DrawRadarSection(x - 1, y - 1);
+ DrawRadarSection(x, y - 1);
+ DrawRadarSection(x + 1, y - 1);
+ DrawRadarSection(x - 1, y);
+ DrawRadarSection(x, y);
+ DrawRadarSection(x + 1, y);
+ DrawRadarSection(x - 1, y + 1);
+ DrawRadarSection(x, y + 1);
+ DrawRadarSection(x + 1, y + 1);
+}
+
+void CRadar::DrawRadarMask()
+{
+ CVector2D corners[4] = {
+ CVector2D(1.0f, -1.0f),
+ CVector2D(1.0f, 1.0f),
+ CVector2D(-1.0f, 1.0f),
+ CVector2D(-1.0, -1.0f)
+ };
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+ CVector2D out[8];
+ CVector2D in;
+
+ // Draw the shape we want to mask out from the radar in four segments
+ for (int i = 0; i < 4; i++) {
+ // First point is always the corner itself
+ in.x = corners[i].x;
+ in.y = corners[i].y;
+ TransformRadarPointToScreenSpace(out[0], in);
+
+ // Then generate a quarter of the circle
+ for (int j = 0; j < 7; j++) {
+ in.x = corners[i].x * Cos(j * (PI / 2.0f / 6.0f));
+ in.y = corners[i].y * Sin(j * (PI / 2.0f / 6.0f));
+ TransformRadarPointToScreenSpace(out[j + 1], in);
+ };
+
+ CSprite2d::SetMaskVertices(8, (float *)out);
+ RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8);
+ };
+}
+
+void CRadar::DrawRadarSection(int32 x, int32 y)
+{
+ int i;
+ RwTexDictionary *txd;
+ CVector2D worldPoly[8];
+ CVector2D radarCorners[4];
+ CVector2D radarPoly[8];
+ CVector2D texCoords[8];
+ CVector2D screenPoly[8];
+ int numVertices;
+ RwTexture *texture = nil;
+
+ GetTextureCorners(x, y, worldPoly);
+ ClipRadarTileCoords(x, y);
+
+ assert(CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y]));
+ txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict;
+ if (txd)
+ texture = GetFirstTexture(txd);
+ if (texture == nil)
+ return;
+
+ for (i = 0; i < 4; i++)
+ TransformRealWorldPointToRadarSpace(radarCorners[i], worldPoly[i]);
+
+ numVertices = ClipRadarPoly(radarPoly, radarCorners);
+
+ // FIX: can return earlier here
+// if(numVertices == 0)
+ if (numVertices < 3)
+ return;
+
+ for (i = 0; i < numVertices; i++) {
+ TransformRadarPointToRealWorldSpace(worldPoly[i], radarPoly[i]);
+ TransformRealWorldToTexCoordSpace(texCoords[i], worldPoly[i], x, y);
+ TransformRadarPointToScreenSpace(screenPoly[i], radarPoly[i]);
+ }
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture));
+ CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255));
+ // check done above now
+// if(numVertices > 2)
+ RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices);
+}
+
+void CRadar::DrawRadarSprite(uint16 sprite, float x, float y, uint8 alpha)
+{
+ RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
+#ifdef MENU_MAP
+ if (CMenuManager::bMenuMapActive) {
+ bool alreadyThere = false;
+ for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
+ if (MapLegendList[i] == sprite)
+ alreadyThere = true;
+ }
+ if (!alreadyThere) {
+ MapLegendList[MapLegendCounter] = sprite;
+ MapLegendCounter++;
+ }
+ }
+#endif
+}
+
+void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
+{
+ CVector curPosn[4];
+ CVector oldPosn[4];
+
+ curPosn[0].x = x - SCREEN_SCALE_X(5.6f);
+ curPosn[0].y = y + SCREEN_SCALE_Y(5.6f);
+
+ curPosn[1].x = x + SCREEN_SCALE_X(5.6f);
+ curPosn[1].y = y + SCREEN_SCALE_Y(5.6f);
+
+ curPosn[2].x = x - SCREEN_SCALE_X(5.6f);
+ curPosn[2].y = y - SCREEN_SCALE_Y(5.6f);
+
+ curPosn[3].x = x + SCREEN_SCALE_X(5.6f);
+ curPosn[3].y = y - SCREEN_SCALE_Y(5.6f);
+
+ for (uint32 i = 0; i < 4; i++) {
+ oldPosn[i] = curPosn[i];
+
+ curPosn[i].x = x + (oldPosn[i].x - x) * Cos(angle) + (oldPosn[i].y - y) * Sin(angle);
+ curPosn[i].y = y - (oldPosn[i].x - x) * Sin(angle) + (oldPosn[i].y - y) * Cos(angle);
+ }
+
+ sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha));
+}
+
+int32 CRadar::GetActualBlipArrayIndex(int32 i)
+{
+ if (i == -1)
+ return -1;
+ else if ((i & 0xFFFF0000) >> 16 != ms_RadarTrace[(uint16)i].m_BlipIndex)
+ return -1;
+ else
+ return (uint16)i;
+}
+
+int32 CRadar::GetNewUniqueBlipIndex(int32 i)
+{
+ if (ms_RadarTrace[i].m_BlipIndex >= UINT16_MAX - 1)
+ ms_RadarTrace[i].m_BlipIndex = 1;
+ else
+ ms_RadarTrace[i].m_BlipIndex++;
+ return i | (ms_RadarTrace[i].m_BlipIndex << 16);
+}
+
+uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
+{
+ int32 c;
+ switch (color) {
+ case 0:
+ if (bright)
+ c = 0x712B49FF;
+ else
+ c = 0x7F0000FF;
+ break;
+ case 1:
+ if (bright)
+ c = 0x5FA06AFF;
+ else
+ c = 0x007F00FF;
+ break;
+ case 2:
+ if (bright)
+ c = 0x80A7F3FF;
+ else
+ c = 0x00007FFF;
+ break;
+ case 3:
+ if (bright)
+ c = 0xE1E1E1FF;
+ else
+ c = 0x7F7F7FFF;
+ break;
+ case 4:
+ if (bright)
+ c = 0xFFFF00FF;
+ else
+ c = 0x7F7F00FF;
+ break;
+ case 5:
+ if (bright)
+ c = 0xFF00FFFF;
+ else
+ c = 0x7F007FFF;
+ break;
+ case 6:
+ if (bright)
+ c = 0x00FFFFFF;
+ else
+ c = 0x007F7FFF;
+ break;
+ default:
+ c = color;
+ break;
+ };
+ return c;
+}
+
+const char* gRadarTexNames[] = {
+ "radar00", "radar01", "radar02", "radar03", "radar04", "radar05", "radar06", "radar07",
+ "radar08", "radar09", "radar10", "radar11", "radar12", "radar13", "radar14", "radar15",
+ "radar16", "radar17", "radar18", "radar19", "radar20", "radar21", "radar22", "radar23",
+ "radar24", "radar25", "radar26", "radar27", "radar28", "radar29", "radar30", "radar31",
+ "radar32", "radar33", "radar34", "radar35", "radar36", "radar37", "radar38", "radar39",
+ "radar40", "radar41", "radar42", "radar43", "radar44", "radar45", "radar46", "radar47",
+ "radar48", "radar49", "radar50", "radar51", "radar52", "radar53", "radar54", "radar55",
+ "radar56", "radar57", "radar58", "radar59", "radar60", "radar61", "radar62", "radar63",
+};
+
+void
+CRadar::Initialise()
+{
+ for (int i = 0; i < NUMRADARBLIPS; i++) {
+ ms_RadarTrace[i].m_BlipIndex = 1;
+ SetRadarMarkerState(i, false);
+ ms_RadarTrace[i].m_bInUse = false;
+ ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
+ ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
+ ms_RadarTrace[i].m_eRadarSprite = RADAR_SPRITE_NONE;
+ }
+
+ m_radarRange = 350.0f;
+ for (int i = 0; i < 64; i++)
+ gRadarTxdIds[i] = CTxdStore::FindTxdSlot(gRadarTexNames[i]);
+}
+
+float CRadar::LimitRadarPoint(CVector2D &point)
+{
+ float dist, invdist;
+
+ dist = point.Magnitude();
+#ifdef MENU_MAP
+ if (CMenuManager::bMenuMapActive)
+ return dist;
+#endif
+ if (dist > 1.0f) {
+ invdist = 1.0f / dist;
+ point.x *= invdist;
+ point.y *= invdist;
+ }
+ return dist;
+}
+
+void CRadar::LoadAllRadarBlips(uint8 *buf, uint32 size)
+{
+ Initialise();
+INITSAVEBUF
+ CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
+
+ for (int i = 0; i < NUMRADARBLIPS; i++)
+ ms_RadarTrace[i] = ReadSaveBuf<sRadarTrace>(buf);
+
+VALIDATESAVEBUF(size);
+}
+
+void
+CRadar::LoadTextures()
+{
+ CTxdStore::PushCurrentTxd();
+ CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("hud"));
+ AsukaSprite.SetTexture("radar_asuka");
+ BombSprite.SetTexture("radar_bomb");
+ CatSprite.SetTexture("radar_cat");
+ CentreSprite.SetTexture("radar_centre");
+ CopcarSprite.SetTexture("radar_copcar");
+ DonSprite.SetTexture("radar_don");
+ EightSprite.SetTexture("radar_eight");
+ ElSprite.SetTexture("radar_el");
+ IceSprite.SetTexture("radar_ice");
+ JoeySprite.SetTexture("radar_joey");
+ KenjiSprite.SetTexture("radar_kenji");
+ LizSprite.SetTexture("radar_liz");
+ LuigiSprite.SetTexture("radar_luigi");
+ NorthSprite.SetTexture("radar_north");
+ RaySprite.SetTexture("radar_ray");
+ SalSprite.SetTexture("radar_sal");
+ SaveSprite.SetTexture("radar_save");
+ SpraySprite.SetTexture("radar_spray");
+ TonySprite.SetTexture("radar_tony");
+ WeaponSprite.SetTexture("radar_weapon");
+ CTxdStore::PopCurrentTxd();
+}
+
+void CRadar::RemoveRadarSections()
+{
+ for (int i = 0; i < 8; i++)
+ for (int j = 0; j < 8; j++)
+ RemoveMapSection(i, j);
+}
+
+void CRadar::SaveAllRadarBlips(uint8 *buf, uint32 *size)
+{
+ *size = SAVE_HEADER_SIZE + sizeof(ms_RadarTrace);
+INITSAVEBUF
+ WriteSaveHeader(buf, 'R', 'D', 'R', '\0', *size - SAVE_HEADER_SIZE);
+
+ for (int i = 0; i < NUMRADARBLIPS; i++)
+ WriteSaveBuf(buf, ms_RadarTrace[i]);
+
+VALIDATESAVEBUF(*size);
+}
+
+void CRadar::SetBlipSprite(int32 i, int32 icon)
+{
+ int index = CRadar::GetActualBlipArrayIndex(i);
+ if (index != -1) {
+ ms_RadarTrace[index].m_eRadarSprite = icon;
+ }
+}
+
+int CRadar::SetCoordBlip(eBlipType type, CVector pos, int32 color, eBlipDisplay display)
+{
+ int nextBlip;
+ for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
+ if (!ms_RadarTrace[nextBlip].m_bInUse)
+ break;
+ }
+ ms_RadarTrace[nextBlip].m_eBlipType = type;
+ ms_RadarTrace[nextBlip].m_nColor = color;
+ ms_RadarTrace[nextBlip].m_bDim = 1;
+ ms_RadarTrace[nextBlip].m_bInUse = 1;
+ ms_RadarTrace[nextBlip].m_Radius = 1.0f;
+ ms_RadarTrace[nextBlip].m_vec2DPos = pos;
+ ms_RadarTrace[nextBlip].m_vecPos = pos;
+ ms_RadarTrace[nextBlip].m_nEntityHandle = 0;
+ ms_RadarTrace[nextBlip].m_wScale = 1;
+ ms_RadarTrace[nextBlip].m_eBlipDisplay = display;
+ ms_RadarTrace[nextBlip].m_eRadarSprite = RADAR_SPRITE_NONE;
+ return CRadar::GetNewUniqueBlipIndex(nextBlip);
+}
+
+int CRadar::SetEntityBlip(eBlipType type, int32 handle, int32 color, eBlipDisplay display)
+{
+ int nextBlip;
+ for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
+ if (!ms_RadarTrace[nextBlip].m_bInUse)
+ break;
+ }
+ ms_RadarTrace[nextBlip].m_eBlipType = type;
+ ms_RadarTrace[nextBlip].m_nColor = color;
+ ms_RadarTrace[nextBlip].m_bDim = 1;
+ ms_RadarTrace[nextBlip].m_bInUse = 1;
+ ms_RadarTrace[nextBlip].m_Radius = 1.0f;
+ ms_RadarTrace[nextBlip].m_nEntityHandle = handle;
+ ms_RadarTrace[nextBlip].m_wScale = 1;
+ ms_RadarTrace[nextBlip].m_eBlipDisplay = display;
+ ms_RadarTrace[nextBlip].m_eRadarSprite = RADAR_SPRITE_NONE;
+ return GetNewUniqueBlipIndex(nextBlip);
+}
+
+void CRadar::SetRadarMarkerState(int32 counter, bool flag)
+{
+ CEntity *e;
+ switch (ms_RadarTrace[counter].m_eBlipType) {
+ case BLIP_CAR:
+ e = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
+ break;
+ case BLIP_CHAR:
+ e = CPools::GetPedPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
+ break;
+ case BLIP_OBJECT:
+ e = CPools::GetObjectPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
+ break;
+ default:
+ return;
+ }
+
+ if (e)
+ e->bHasBlip = flag;
+}
+
+void CRadar::ShowRadarMarker(CVector pos, uint32 color, float radius) {
+ float f1 = radius * 1.4f;
+ float f2 = radius * 0.5f;
+ CVector p1, p2;
+
+ p1 = pos + TheCamera.GetUp()*f1;
+ p2 = pos + TheCamera.GetUp()*f2;
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
+
+ p1 = pos - TheCamera.GetUp()*f1;
+ p2 = pos - TheCamera.GetUp()*f2;
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
+
+ p1 = pos + TheCamera.GetRight()*f1;
+ p2 = pos + TheCamera.GetRight()*f2;
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
+
+ p1 = pos - TheCamera.GetRight()*f1;
+ p2 = pos - TheCamera.GetRight()*f2;
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
+}
+
+void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha)
+{
+ if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
+ return;
+
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
+}
+
+void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red, uint8 green, uint8 blue, uint8 alpha, uint8 mode)
+{
+ if (!CHud::m_Wants_To_Draw_Hud || TheCamera.m_WideScreenOn)
+ return;
+
+ switch (mode)
+ {
+ case BLIP_MODE_TRIANGULAR_UP:
+ // size++; // VC does size + 1 for triangles
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 3.0f), y + SCREEN_SCALE_Y(size + 2.0f), x - (SCREEN_SCALE_X(size + 3.0f)), y + SCREEN_SCALE_Y(size + 2.0f), x, y - (SCREEN_SCALE_Y(size + 3.0f)), x, y - (SCREEN_SCALE_Y(size + 3.0f)), CRGBA(0, 0, 0, alpha));
+ CSprite2d::Draw2DPolygon(x + SCREEN_SCALE_X(size + 1.0f), y + SCREEN_SCALE_Y(size + 1.0f), x - (SCREEN_SCALE_X(size + 1.0f)), y + SCREEN_SCALE_Y(size + 1.0f), x, y - (SCREEN_SCALE_Y(size + 1.0f)), x, y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
+ break;
+ case BLIP_MODE_TRIANGULAR_DOWN:
+ // size++; // VC does size + 1 for triangles
+ CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 2.0f), x, y + SCREEN_SCALE_Y(size + 3.0f), x + SCREEN_SCALE_X(size + 3.0f), y - (SCREEN_SCALE_Y(size + 2.0f)), x - (SCREEN_SCALE_X(size + 3.0f)), y - (SCREEN_SCALE_Y(size + 2.0f)), CRGBA(0, 0, 0, alpha));
+ CSprite2d::Draw2DPolygon(x, y + SCREEN_SCALE_Y(size + 1.0f), x, y + SCREEN_SCALE_Y(size + 1.0f), x + SCREEN_SCALE_X(size + 1.0f), y - (SCREEN_SCALE_Y(size + 1.0f)), x - (SCREEN_SCALE_X(size + 1.0f)), y - (SCREEN_SCALE_Y(size + 1.0f)), CRGBA(red, green, blue, alpha));
+ break;
+ case BLIP_MODE_SQUARE:
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
+ break;
+ }
+#ifdef MENU_MAP
+ // VC uses -1 for coords and -2 for entities but meh, I don't want to edit DrawBlips
+ if (CMenuManager::bMenuMapActive) {
+ bool alreadyThere = false;
+ for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
+ if (MapLegendList[i] == -1)
+ alreadyThere = true;
+ }
+ if (!alreadyThere) {
+ MapLegendList[MapLegendCounter] = -1;
+ MapLegendCounter++;
+ ArrowBlipColour1 = CRGBA(red, green, blue, alpha);
+ }
+ }
+#endif
+}
+
+void CRadar::Shutdown()
+{
+ AsukaSprite.Delete();
+ BombSprite.Delete();
+ CatSprite.Delete();
+ CentreSprite.Delete();
+ CopcarSprite.Delete();
+ DonSprite.Delete();
+ EightSprite.Delete();
+ ElSprite.Delete();
+ IceSprite.Delete();
+ JoeySprite.Delete();
+ KenjiSprite.Delete();
+ LizSprite.Delete();
+ LuigiSprite.Delete();
+ NorthSprite.Delete();
+ RaySprite.Delete();
+ SalSprite.Delete();
+ SaveSprite.Delete();
+ SpraySprite.Delete();
+ TonySprite.Delete();
+ WeaponSprite.Delete();
+ RemoveRadarSections();
+}
+
+void CRadar::StreamRadarSections(const CVector &posn)
+{
+ StreamRadarSections(floorf((2000.0f + posn.x) / 500.0f), ceilf(7.0f - (2000.0f + posn.y) / 500.0f));
+}
+
+void CRadar::StreamRadarSections(int32 x, int32 y)
+{
+ for (int i = 0; i < RADAR_NUM_TILES; ++i) {
+ for (int j = 0; j < RADAR_NUM_TILES; ++j) {
+ if ((i >= x - 1 && i <= x + 1) && (j >= y - 1 && j <= y + 1))
+ RequestMapSection(i, j);
+ else
+ RemoveMapSection(i, j);
+ };
+ };
+}
+
+void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y)
+{
+ out.x = in.x - (x * RADAR_TILE_SIZE + WORLD_MIN_X);
+ out.y = -(in.y - ((RADAR_NUM_TILES - y) * RADAR_TILE_SIZE + WORLD_MIN_Y));
+ out.x /= RADAR_TILE_SIZE;
+ out.y /= RADAR_TILE_SIZE;
+}
+
+void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in)
+{
+ float s, c;
+#if 1
+ s = -cachedSin;
+ c = cachedCos;
+#else
+ // Original code
+
+ s = -Sin(TheCamera.GetForward().Heading());
+ c = Cos(TheCamera.GetForward().Heading());
+
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) {
+ s = 0.0f;
+ c = 1.0f;
+ }
+ else if (TheCamera.GetLookDirection() != LOOKING_FORWARD) {
+ CVector forward;
+
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) {
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
+ forward.Normalise(); // a bit useless...
+ }
+ else
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
+
+ s = -Sin(forward.Heading());
+ c = Cos(forward.Heading());
+ }
+#endif
+
+ out.x = s * in.y + c * in.x;
+ out.y = c * in.y - s * in.x;
+
+ out = out * m_radarRange + vec2DRadarOrigin;
+}
+
+// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
+void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
+{
+#ifdef MENU_MAP
+ if (CMenuManager::bMenuMapActive) {
+ // fMapSize is actually half map size. Radar range is 1000, so if x is -2000, in.x + 2.0f is 0.
+ out.x = (CMenuManager::fMapCenterX - CMenuManager::fMapSize) + (in.x + 2.0f) * CMenuManager::fMapSize * 2.0f / 4.0f;
+ out.y = (CMenuManager::fMapCenterY - CMenuManager::fMapSize) + (2.0f - in.y) * CMenuManager::fMapSize * 2.0f / 4.0f;
+ } else
+#endif
+ {
+#ifdef FIX_BUGS
+ out.x = (in.x + 1.0f) * 0.5f * SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
+#else
+ out.x = (in.x + 1.0f) * 0.5f * SCREEN_SCALE_X(RADAR_WIDTH) + RADAR_LEFT;
+#endif
+ out.y = (1.0f - in.y) * 0.5f * SCREEN_SCALE_Y(RADAR_HEIGHT) + SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT);
+ }
+}
+
+void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in)
+{
+ float s, c;
+#if 1
+ s = cachedSin;
+ c = cachedCos;
+#else
+ // Original code
+
+ float s, c;
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) {
+ s = 0.0f;
+ c = 1.0f;
+ }
+ else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
+ s = Sin(TheCamera.GetForward().Heading());
+ c = Cos(TheCamera.GetForward().Heading());
+ }
+ else {
+ CVector forward;
+
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) {
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
+ forward.Normalise(); // a bit useless...
+ }
+ else
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
+
+ s = Sin(forward.Heading());
+ c = Cos(forward.Heading());
+ }
+#endif
+
+ float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_radarRange);
+ float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_radarRange);
+
+ out.x = s * y + c * x;
+ out.y = c * y - s * x;
+}
+
+void
+CRadar::CalculateCachedSinCos()
+{
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED
+#ifdef MENU_MAP
+ || CMenuManager::bMenuMapActive
+#endif
+ ) {
+ cachedSin = 0.0f;
+ cachedCos = 1.0f;
+ } else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
+ cachedSin = Sin(TheCamera.GetForward().Heading());
+ cachedCos = Cos(TheCamera.GetForward().Heading());
+ } else {
+ CVector forward;
+
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON) {
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
+ forward.Normalise(); // a bit useless...
+ }
+ else
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
+
+ cachedSin = Sin(forward.Heading());
+ cachedCos = Cos(forward.Heading());
+ }
+}
+
+#ifdef MENU_MAP
+void
+CRadar::InitFrontEndMap()
+{
+ CalculateCachedSinCos();
+ vec2DRadarOrigin.x = 0.0f;
+ vec2DRadarOrigin.y = 0.0f;
+ m_radarRange = 1000.0f; // doesn't mean anything, just affects the calculation in TransformRadarPointToScreenSpace
+ for (int i = 0; i < NUM_MAP_LEGENDS; i++) {
+ MapLegendList[i] = RADAR_SPRITE_NONE;
+ }
+ MapLegendCounter = 0;
+ ArrowBlipColour1 = CRGBA(0, 0, 0, 0);
+ ArrowBlipColour2 = CRGBA(0, 0, 0, 0);
+}
+
+void
+CRadar::DrawYouAreHereSprite(float x, float y)
+{
+ static uint32 lastChange = 0;
+ static bool show = true;
+
+ if (show) {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastChange > 500) {
+ lastChange = CTimer::GetTimeInMillisecondsPauseMode();
+ show = !show;
+ }
+ } else {
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastChange > 200) {
+ lastChange = CTimer::GetTimeInMillisecondsPauseMode();
+ show = !show;
+ }
+ }
+
+ if (show) {
+ float left = x - SCREEN_SCALE_X(12.0f);
+ float top = y - SCREEN_SCALE_Y(2.0f);
+ float right = SCREEN_SCALE_X(12.0) + x;
+ float bottom = y - SCREEN_SCALE_Y(26.0f);
+ CentreSprite.Draw(CRect(left, top, right, bottom), CRGBA(255, 255, 255, 255));
+ }
+ MapLegendList[MapLegendCounter++] = RADAR_SPRITE_CENTRE;
+}
+
+void
+CRadar::ToggleTargetMarker(float x, float y)
+{
+ if (TargetMarkerId == -1) {
+ int nextBlip;
+ for (nextBlip = 0; nextBlip < NUMRADARBLIPS; nextBlip++) {
+ if (!ms_RadarTrace[nextBlip].m_bInUse)
+ break;
+ }
+ ms_RadarTrace[nextBlip].m_eBlipType = BLIP_COORD;
+ ms_RadarTrace[nextBlip].m_nColor = 0x333333FF;
+ ms_RadarTrace[nextBlip].m_bDim = 1;
+ ms_RadarTrace[nextBlip].m_bInUse = 1;
+ ms_RadarTrace[nextBlip].m_Radius = 1.0f;
+ CVector pos(x, y, CWorld::FindGroundZForCoord(x,y));
+ ms_RadarTrace[nextBlip].m_vec2DPos = pos;
+ ms_RadarTrace[nextBlip].m_vecPos = pos;
+ ms_RadarTrace[nextBlip].m_nEntityHandle = 0;
+ ms_RadarTrace[nextBlip].m_wScale = 5;
+ ms_RadarTrace[nextBlip].m_eBlipDisplay = BLIP_DISPLAY_BLIP_ONLY;
+ ms_RadarTrace[nextBlip].m_eRadarSprite = RADAR_SPRITE_NONE;
+ TargetMarkerId = CRadar::GetNewUniqueBlipIndex(nextBlip);
+ } else {
+ ClearBlip(TargetMarkerId);
+ TargetMarkerId = -1;
+ }
+}
+#endif
+
+STARTPATCHES
+ InjectHook(0x4A3EF0, CRadar::Initialise, PATCH_JUMP);
+ InjectHook(0x4A3F60, CRadar::Shutdown, PATCH_JUMP);
+ InjectHook(0x4A4030, CRadar::LoadTextures, PATCH_JUMP);
+ InjectHook(0x4A4180, CRadar::GetNewUniqueBlipIndex, PATCH_JUMP);
+ InjectHook(0x4A41C0, CRadar::GetActualBlipArrayIndex, PATCH_JUMP);
+ InjectHook(0x4A4200, CRadar::DrawMap, PATCH_JUMP);
+ InjectHook(0x4A42F0, CRadar::DrawBlips, PATCH_JUMP);
+ InjectHook(0x4A4C70, CRadar::Draw3dMarkers, PATCH_JUMP);
+ InjectHook(0x4A4F30, CRadar::LimitRadarPoint, PATCH_JUMP);
+ InjectHook(0x4A4F90, CRadar::CalculateBlipAlpha, PATCH_JUMP);
+ InjectHook(0x4A5040, CRadar::TransformRadarPointToScreenSpace, PATCH_JUMP);
+ InjectHook(0x4A50D0, CRadar::TransformRealWorldPointToRadarSpace, PATCH_JUMP);
+ InjectHook(0x4A5300, CRadar::TransformRadarPointToRealWorldSpace, PATCH_JUMP);
+ InjectHook(0x4A5530, CRadar::TransformRealWorldToTexCoordSpace, PATCH_JUMP);
+ InjectHook(0x4A5590, CRadar::SetCoordBlip, PATCH_JUMP);
+ InjectHook(0x4A5640, CRadar::SetEntityBlip, PATCH_JUMP);
+ InjectHook(0x4A56C0, CRadar::ClearBlipForEntity, PATCH_JUMP);
+ InjectHook(0x4A5720, CRadar::ClearBlip, PATCH_JUMP);
+ InjectHook(0x4A5770, CRadar::ChangeBlipColour, PATCH_JUMP);
+ InjectHook(0x4A57A0, CRadar::ChangeBlipBrightness, PATCH_JUMP);
+ InjectHook(0x4A57E0, CRadar::ChangeBlipScale, PATCH_JUMP);
+ InjectHook(0x4A5810, CRadar::ChangeBlipDisplay, PATCH_JUMP);
+ InjectHook(0x4A5840, CRadar::SetBlipSprite, PATCH_JUMP);
+ InjectHook(0x4A5870, CRadar::ShowRadarTrace, PATCH_JUMP);
+ InjectHook(0x4A59C0, CRadar::ShowRadarMarker, PATCH_JUMP);
+ InjectHook(0x4A5BB0, CRadar::GetRadarTraceColour, PATCH_JUMP);
+ InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
+ InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
+ InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, PATCH_JUMP);
+ InjectHook(0x4A6020, ClipRadarTileCoords, PATCH_JUMP);
+ InjectHook(0x4A6060, RequestMapSection, PATCH_JUMP);
+ InjectHook(0x4A60A0, RemoveMapSection, PATCH_JUMP);
+ InjectHook(0x4A60E0, CRadar::RemoveRadarSections, PATCH_JUMP);
+ InjectHook(0x4A6100, (void (*)(int32, int32))&CRadar::StreamRadarSections, PATCH_JUMP);
+ InjectHook(0x4A6160, IsPointInsideRadar, PATCH_JUMP);
+ InjectHook(0x4A61C0, GetTextureCorners, PATCH_JUMP);
+ InjectHook(0x4A6250, LineRadarBoxCollision, PATCH_JUMP);
+ InjectHook(0x4A64A0, CRadar::ClipRadarPoly, PATCH_JUMP);
+ InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP);
+ InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP);
+ InjectHook(0x4A6B60, (void (*)(const CVector&))&CRadar::StreamRadarSections, PATCH_JUMP);
+ InjectHook(0x4A6C20, CRadar::DrawRadarMap, PATCH_JUMP);
+ InjectHook(0x4A6E30, CRadar::SaveAllRadarBlips, PATCH_JUMP);
+ InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP);
+ //InjectHook(0x4A7000, `global constructor keyed to'Radar.cpp, PATCH_JUMP);
+ //InjectHook(0x4A7260, sRadarTrace::sRadarTrace, PATCH_JUMP);
+ENDPATCHES \ No newline at end of file
diff --git a/src/core/Radar.h b/src/core/Radar.h
index b0400b0d..27f3a6f0 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -21,6 +21,10 @@ enum eBlipDisplay
enum eRadarSprite
{
+#ifdef MENU_MAP
+ RADAR_SPRITE_ENTITY_BLIP = -2,
+ RADAR_SPRITE_COORD_BLIP = -1,
+#endif
RADAR_SPRITE_NONE = 0,
RADAR_SPRITE_ASUKA = 1,
RADAR_SPRITE_BOMB = 2,
@@ -52,7 +56,7 @@ enum
BLIP_MODE_SQUARE,
};
-struct CBlip
+struct sRadarTrace
{
uint32 m_nColor;
uint32 m_eBlipType; // eBlipType
@@ -65,9 +69,9 @@ struct CBlip
float m_Radius;
int16 m_wScale;
uint16 m_eBlipDisplay; // eBlipDisplay
- uint16 m_IconID; // eRadarSprite
+ uint16 m_eRadarSprite; // eRadarSprite
};
-static_assert(sizeof(CBlip) == 0x30, "CBlip: error");
+static_assert(sizeof(sRadarTrace) == 0x30, "sRadarTrace: error");
// Values for screen space
#define RADAR_LEFT (40.0f)
@@ -79,7 +83,7 @@ class CRadar
{
public:
static float &m_radarRange;
- static CBlip (&ms_RadarTrace)[NUMRADARBLIPS];
+ static sRadarTrace (&ms_RadarTrace)[NUMRADARBLIPS];
static CSprite2d AsukaSprite;
static CSprite2d BombSprite;
static CSprite2d CatSprite;
@@ -101,8 +105,20 @@ public:
static CSprite2d TonySprite;
static CSprite2d WeaponSprite;
static CSprite2d *RadarSprites[21];
+ static float cachedCos;
+ static float cachedSin;
+#ifdef MENU_MAP
+#define NUM_MAP_LEGENDS 75
+ static CRGBA ArrowBlipColour1;
+ static CRGBA ArrowBlipColour2;
+ static uint16 MapLegendList[NUM_MAP_LEGENDS];
+ static uint16 MapLegendCounter;
+ static int TargetMarkerId;
-public:
+ static void InitFrontEndMap();
+ static void DrawYouAreHereSprite(float, float);
+ static void ToggleTargetMarker(float, float);
+#endif
static uint8 CalculateBlipAlpha(float dist);
static void ChangeBlipBrightness(int32 i, int32 bright);
static void ChangeBlipColour(int32 i, int32);
@@ -128,7 +144,6 @@ public:
static void LoadAllRadarBlips(uint8 *buf, uint32 size);
static void LoadTextures();
static void RemoveRadarSections();
- static void RequestMapSection(int32 x, int32 y);
static void SaveAllRadarBlips(uint8*, uint32*);
static void SetBlipSprite(int32 i, int32 icon);
static int32 SetCoordBlip(eBlipType type, CVector pos, int32, eBlipDisplay);
@@ -145,9 +160,6 @@ public:
static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in);
static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
- // no in CRadar in the game:
- static void GetTextureCorners(int32 x, int32 y, CVector2D *out);
- static void ClipRadarTileCoords(int32 &x, int32 &y);
- static bool IsPointInsideRadar(const CVector2D &);
- static int LineRadarBoxCollision(CVector2D &, const CVector2D &, const CVector2D &);
+ // no in CRadar in the game:
+ static void CalculateCachedSinCos();
};
diff --git a/src/core/RwTexRead.cpp b/src/core/RwTexRead.cpp
deleted file mode 100644
index 6b717b34..00000000
--- a/src/core/RwTexRead.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#pragma warning( push )
-#pragma warning( disable : 4005)
-#define DIRECTINPUT_VERSION 0x0800
-#include <dinput.h>
-#pragma warning( pop )
-#include "common.h"
-#include "win.h"
-#include "patcher.h"
-#include "Timer.h"
-
-float &texLoadTime = *(float*)0x8F1B50;
-int32 &texNumLoaded = *(int32*)0x8F252C;
-
-RwTexture*
-RwTextureGtaStreamRead(RwStream *stream)
-{
- RwUInt32 size, version;
- RwTexture *tex;
-
- if(!RwStreamFindChunk(stream, rwID_TEXTURENATIVE, &size, &version))
- return nil;
-
- float preloadTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
-
- if(!RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, &tex, size)))
- return nil;
-
- if (gGameState == GS_INIT_PLAYING_GAME) {
- texLoadTime = (texNumLoaded * texLoadTime + (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond() - preloadTime) / (float)(texNumLoaded+1);
- texNumLoaded++;
- }
- return tex;
-}
-
-RwTexture*
-destroyTexture(RwTexture *texture, void *data)
-{
- RwTextureDestroy(texture);
- return texture;
-}
-
-RwTexDictionary*
-RwTexDictionaryGtaStreamRead(RwStream *stream)
-{
- RwUInt32 size, version;
- RwInt32 numTextures;
- RwTexDictionary *texDict;
- RwTexture *tex;
-
- if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
- return nil;
- assert(size == 4);
- if(RwStreamRead(stream, &numTextures, size) != size)
- return nil;
-
- texDict = RwTexDictionaryCreate();
- if(texDict == nil)
- return nil;
-
- while(numTextures--){
- tex = RwTextureGtaStreamRead(stream);
- if(tex == nil){
- RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
- RwTexDictionaryDestroy(texDict);
- return nil;
- }
- RwTexDictionaryAddTexture(texDict, tex);
- }
-
- return texDict;
-}
-
-static int32 numberTextures = -1;
-static int32 streamPosition;
-
-RwTexDictionary*
-RwTexDictionaryGtaStreamRead1(RwStream *stream)
-{
- RwUInt32 size, version;
- RwInt32 numTextures;
- RwTexDictionary *texDict;
- RwTexture *tex;
-
- numberTextures = 0;
- if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
- return nil;
- assert(size == 4);
- if(RwStreamRead(stream, &numTextures, size) != size)
- return nil;
-
- texDict = RwTexDictionaryCreate();
- if(texDict == nil)
- return nil;
-
- numberTextures = numTextures/2;
-
- while(numTextures > numberTextures){
- numTextures--;
-
- tex = RwTextureGtaStreamRead(stream);
- if(tex == nil){
- RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
- RwTexDictionaryDestroy(texDict);
- return nil;
- }
- RwTexDictionaryAddTexture(texDict, tex);
- }
-
- numberTextures = numTextures;
- streamPosition = stream->Type.memory.position;
-
- return texDict;
-}
-
-RwTexDictionary*
-RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
-{
- RwTexture *tex;
-
- RwStreamSkip(stream, streamPosition - stream->Type.memory.position);
-
- while(numberTextures--){
- tex = RwTextureGtaStreamRead(stream);
- if(tex == nil){
- RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
- RwTexDictionaryDestroy(texDict);
- return nil;
- }
- RwTexDictionaryAddTexture(texDict, tex);
- }
-
- return texDict;
-}
-
-STARTPATCHES
- InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
- InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
- InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
- InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index 9478479b..02092a30 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -1,18 +1,18 @@
#include "common.h"
#include "patcher.h"
#include "Stats.h"
-
-WRAPPER void CStats::SaveStats(uint8 *buf, uint32 *size) { EAXJMP(0x4ab3e0); }
+#include "Text.h"
+#include "World.h"
int32 &CStats::DaysPassed = *(int32*)0x8F2BB8;
int32 &CStats::HeadsPopped = *(int32*)0x8F647C;
-bool& CStats::CommercialPassed = *(bool*)0x8F4334;
-bool& CStats::IndustrialPassed = *(bool*)0x8E2A68;
-bool& CStats::SuburbanPassed = *(bool*)0x8F2740;
+int32& CStats::CommercialPassed = *(int32*)0x8F4334;
+int32& CStats::IndustrialPassed = *(int32*)0x8E2A68;
+int32& CStats::SuburbanPassed = *(int32*)0x8F2740;
int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64;
-int32 *CStats::PedsKilledOfThisType = (int32*)0x880DBC;
+int32(&CStats::PedsKilledOfThisType)[NUM_PEDTYPES] = *(int32(*)[NUM_PEDTYPES]) * (uintptr*)0x880DBC;
int32 &CStats::TimesDied = *(int32*)0x8E2BDC;
int32 &CStats::TimesArrested = *(int32*)0x8E2BEC;
int32 &CStats::KillsSinceLastCheckpoint = *(int32*)0x8F2C8C;
@@ -48,11 +48,73 @@ int32& CStats::LongestFlightInDodo = *(int32*)0x8F5FE4;
int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24;
int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884;
int32& CStats::TotalNumberMissions = *(int32*)0x8E2820;
-int32& CStats::KgOfExplosivesUsed = *(int32*)0x8F2510;
+int32& CStats::RoundsFiredByPlayer = *(int32*)0x8E2BE8;
+int32& CStats::KgsOfExplosivesUsed = *(int32*)0x8F2510;
+int32& CStats::InstantHitsFiredByPlayer = *(int32*)0x943070;
+int32& CStats::InstantHitsHitByPlayer = *(int32*)0x95CB8C;
+int32& CStats::BestTimeBombDefusal = *(int32*)0x880E24;
+int32& CStats::mmRain = *(int32*)0x8F2C98;
int32& CStats::CarsCrushed = *(int32*)0x943050;
int32(&CStats::FastestTimes)[CStats::TOTAL_FASTEST_TIMES] = *(int32(*)[CStats::TOTAL_FASTEST_TIMES])*(uintptr*)0x6E9128;
int32(&CStats::HighestScores)[CStats::TOTAL_HIGHEST_SCORES] = *(int32(*)[CStats::TOTAL_HIGHEST_SCORES]) * (uintptr*)0x8622B0;
+void CStats::Init()
+{
+ PeopleKilledByOthers = 0;
+ PeopleKilledByPlayer = 0;
+ RoundsFiredByPlayer = 0;
+ CarsExploded = 0;
+ HelisDestroyed = 0;
+ ProgressMade = 0;
+ KgsOfExplosivesUsed = 0;
+ InstantHitsFiredByPlayer = 0;
+ InstantHitsHitByPlayer = 0;
+ CarsCrushed = 0;
+ HeadsPopped = 0;
+ TimesArrested = 0;
+ TimesDied = 0;
+ DaysPassed = 0;
+ NumberOfUniqueJumpsFound = 0;
+ mmRain = 0;
+ MaximumJumpFlips = 0;
+ MaximumJumpSpins = 0;
+ MaximumJumpDistance = 0;
+ MaximumJumpHeight = 0;
+ BestStuntJump = 0;
+ TotalNumberOfUniqueJumps = 0;
+ Record4x4One = 0;
+ LongestFlightInDodo = 0;
+ Record4x4Two = 0;
+ PassengersDroppedOffWithTaxi = 0;
+ Record4x4Three = 0;
+ MoneyMadeWithTaxi = 0;
+ Record4x4Mayhem = 0;
+ LivesSavedWithAmbulance = 0;
+ ElBurroTime = 0;
+ CriminalsCaught = 0;
+ MissionsGiven = 0;
+ HighestLevelAmbulanceMission = 0;
+ MissionsPassed = 0;
+ FiresExtinguished = 0;
+ DistanceTravelledOnFoot = 0;
+ TimeTakenDefuseMission = 0;
+ NumberKillFrenziesPassed = 0;
+ DistanceTravelledInVehicle = 0;
+ TotalNumberKillFrenzies = 0;
+ TotalNumberMissions = 0;
+ KillsSinceLastCheckpoint = 0;
+ TotalLegitimateKills = 0;
+ for (int i = 0; i < TOTAL_FASTEST_TIMES; i++)
+ FastestTimes[i] = 0;
+ for (int i = 0; i < TOTAL_HIGHEST_SCORES; i++)
+ HighestScores[i] = 0;
+ for (int i = 0; i < NUM_PEDTYPES; i++)
+ PedsKilledOfThisType[i] = 0;
+ IndustrialPassed = 0;
+ CommercialPassed = 0;
+ SuburbanPassed = 0;
+}
+
void CStats::RegisterFastestTime(int32 index, int32 time)
{
assert(index >= 0 && index < TOTAL_FASTEST_TIMES);
@@ -138,4 +200,229 @@ void CStats::SetTotalNumberMissions(int32 total)
TotalNumberMissions = total;
}
-WRAPPER void CStats::Init() { EAXJMP(0x4AAC60); } \ No newline at end of file
+wchar *CStats::FindCriminalRatingString()
+{
+ int rating = FindCriminalRatingNumber();
+
+ if (rating < 10) return TheText.Get("RATNG1");
+ if (rating < 25) return TheText.Get("RATNG2");
+ if (rating < 70) return TheText.Get("RATNG3");
+ if (rating < 150) return TheText.Get("RATNG4");
+ if (rating < 250) return TheText.Get("RATNG5");
+ if (rating < 450) return TheText.Get("RATNG6");
+ if (rating < 700) return TheText.Get("RATNG7");
+ if (rating < 1000) return TheText.Get("RATNG8");
+ if (rating < 1400) return TheText.Get("RATNG9");
+ if (rating < 1900) return TheText.Get("RATNG10");
+ if (rating < 2500) return TheText.Get("RATNG11");
+ if (rating < 3200) return TheText.Get("RATNG12");
+ if (rating < 4000) return TheText.Get("RATNG13");
+ if (rating < 5000) return TheText.Get("RATNG14");
+ return TheText.Get("RATNG15");
+}
+
+int32 CStats::FindCriminalRatingNumber()
+{
+ int32 rating;
+
+ rating = FiresExtinguished + 10 * HighestLevelAmbulanceMission + CriminalsCaught + LivesSavedWithAmbulance
+ + 30 * HelisDestroyed + TotalLegitimateKills - 3 * TimesArrested - 3 * TimesDied
+ + CWorld::Players[CWorld::PlayerInFocus].m_nMoney / 5000;
+ if (rating <= 0) rating = 0;
+
+ if (InstantHitsFiredByPlayer > 100)
+ rating += (float)CStats::InstantHitsHitByPlayer / (float)CStats::InstantHitsFiredByPlayer * 500.0f;
+ if (TotalProgressInGame)
+ rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
+ if (!IndustrialPassed && rating >= 3521)
+ rating = 3521;
+ if (!CommercialPassed && rating >= 4552)
+ rating = 4552;
+ return rating;
+}
+
+void CStats::SaveStats(uint8 *buf, uint32 *size)
+{
+ CheckPointReachedSuccessfully();
+ uint8 *buf_start = buf;
+ *size = sizeof(PeopleKilledByPlayer) +
+ sizeof(PeopleKilledByOthers) +
+ sizeof(CarsExploded) +
+ sizeof(RoundsFiredByPlayer) +
+ sizeof(PedsKilledOfThisType) +
+ sizeof(HelisDestroyed) +
+ sizeof(ProgressMade) +
+ sizeof(TotalProgressInGame) +
+ sizeof(KgsOfExplosivesUsed) +
+ sizeof(InstantHitsFiredByPlayer) +
+ sizeof(InstantHitsHitByPlayer) +
+ sizeof(CarsCrushed) +
+ sizeof(HeadsPopped) +
+ sizeof(TimesArrested) +
+ sizeof(TimesDied) +
+ sizeof(DaysPassed) +
+ sizeof(mmRain) +
+ sizeof(MaximumJumpDistance) +
+ sizeof(MaximumJumpHeight) +
+ sizeof(MaximumJumpFlips) +
+ sizeof(MaximumJumpSpins) +
+ sizeof(BestStuntJump) +
+ sizeof(NumberOfUniqueJumpsFound) +
+ sizeof(TotalNumberOfUniqueJumps) +
+ sizeof(MissionsGiven) +
+ sizeof(MissionsPassed) +
+ sizeof(PassengersDroppedOffWithTaxi) +
+ sizeof(MoneyMadeWithTaxi) +
+ sizeof(IndustrialPassed) +
+ sizeof(CommercialPassed) +
+ sizeof(SuburbanPassed) +
+ sizeof(ElBurroTime) +
+ sizeof(DistanceTravelledOnFoot) +
+ sizeof(DistanceTravelledInVehicle) +
+ sizeof(Record4x4One) +
+ sizeof(Record4x4Two) +
+ sizeof(Record4x4Three) +
+ sizeof(Record4x4Mayhem) +
+ sizeof(LivesSavedWithAmbulance) +
+ sizeof(CriminalsCaught) +
+ sizeof(HighestLevelAmbulanceMission) +
+ sizeof(FiresExtinguished) +
+ sizeof(LongestFlightInDodo) +
+ sizeof(TimeTakenDefuseMission) +
+ sizeof(NumberKillFrenziesPassed) +
+ sizeof(TotalNumberKillFrenzies) +
+ sizeof(TotalNumberMissions) +
+ sizeof(FastestTimes) +
+ sizeof(HighestScores) +
+ sizeof(KillsSinceLastCheckpoint) +
+ sizeof(TotalLegitimateKills) +
+ sizeof(LastMissionPassedName);
+
+#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
+ CopyToBuf(buf, PeopleKilledByPlayer);
+ CopyToBuf(buf, PeopleKilledByOthers);
+ CopyToBuf(buf, CarsExploded);
+ CopyToBuf(buf, RoundsFiredByPlayer);
+ CopyToBuf(buf, PedsKilledOfThisType);
+ CopyToBuf(buf, HelisDestroyed);
+ CopyToBuf(buf, ProgressMade);
+ CopyToBuf(buf, TotalProgressInGame);
+ CopyToBuf(buf, KgsOfExplosivesUsed);
+ CopyToBuf(buf, InstantHitsFiredByPlayer);
+ CopyToBuf(buf, InstantHitsHitByPlayer);
+ CopyToBuf(buf, CarsCrushed);
+ CopyToBuf(buf, HeadsPopped);
+ CopyToBuf(buf, TimesArrested);
+ CopyToBuf(buf, TimesDied);
+ CopyToBuf(buf, DaysPassed);
+ CopyToBuf(buf, mmRain);
+ CopyToBuf(buf, MaximumJumpDistance);
+ CopyToBuf(buf, MaximumJumpHeight);
+ CopyToBuf(buf, MaximumJumpFlips);
+ CopyToBuf(buf, MaximumJumpSpins);
+ CopyToBuf(buf, BestStuntJump);
+ CopyToBuf(buf, NumberOfUniqueJumpsFound);
+ CopyToBuf(buf, TotalNumberOfUniqueJumps);
+ CopyToBuf(buf, MissionsGiven);
+ CopyToBuf(buf, MissionsPassed);
+ CopyToBuf(buf, PassengersDroppedOffWithTaxi);
+ CopyToBuf(buf, MoneyMadeWithTaxi);
+ CopyToBuf(buf, IndustrialPassed);
+ CopyToBuf(buf, CommercialPassed);
+ CopyToBuf(buf, SuburbanPassed);
+ CopyToBuf(buf, ElBurroTime);
+ CopyToBuf(buf, DistanceTravelledOnFoot);
+ CopyToBuf(buf, DistanceTravelledInVehicle);
+ CopyToBuf(buf, Record4x4One);
+ CopyToBuf(buf, Record4x4Two);
+ CopyToBuf(buf, Record4x4Three);
+ CopyToBuf(buf, Record4x4Mayhem);
+ CopyToBuf(buf, LivesSavedWithAmbulance);
+ CopyToBuf(buf, CriminalsCaught);
+ CopyToBuf(buf, HighestLevelAmbulanceMission);
+ CopyToBuf(buf, FiresExtinguished);
+ CopyToBuf(buf, LongestFlightInDodo);
+ CopyToBuf(buf, TimeTakenDefuseMission);
+ CopyToBuf(buf, NumberKillFrenziesPassed);
+ CopyToBuf(buf, TotalNumberKillFrenzies);
+ CopyToBuf(buf, TotalNumberMissions);
+ CopyToBuf(buf, FastestTimes);
+ CopyToBuf(buf, HighestScores);
+ CopyToBuf(buf, KillsSinceLastCheckpoint);
+ CopyToBuf(buf, TotalLegitimateKills);
+ CopyToBuf(buf, LastMissionPassedName);
+
+ assert(buf - buf_start == *size);
+#undef CopyToBuf
+}
+
+void CStats::LoadStats(uint8 *buf, uint32 size)
+{
+ uint8* buf_start = buf;
+
+#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
+
+ CopyFromBuf(buf, PeopleKilledByPlayer);
+ CopyFromBuf(buf, PeopleKilledByOthers);
+ CopyFromBuf(buf, CarsExploded);
+ CopyFromBuf(buf, RoundsFiredByPlayer);
+ CopyFromBuf(buf, PedsKilledOfThisType);
+ CopyFromBuf(buf, HelisDestroyed);
+ CopyFromBuf(buf, ProgressMade);
+ CopyFromBuf(buf, TotalProgressInGame);
+ CopyFromBuf(buf, KgsOfExplosivesUsed);
+ CopyFromBuf(buf, InstantHitsFiredByPlayer);
+ CopyFromBuf(buf, InstantHitsHitByPlayer);
+ CopyFromBuf(buf, CarsCrushed);
+ CopyFromBuf(buf, HeadsPopped);
+ CopyFromBuf(buf, TimesArrested);
+ CopyFromBuf(buf, TimesDied);
+ CopyFromBuf(buf, DaysPassed);
+ CopyFromBuf(buf, mmRain);
+ CopyFromBuf(buf, MaximumJumpDistance);
+ CopyFromBuf(buf, MaximumJumpHeight);
+ CopyFromBuf(buf, MaximumJumpFlips);
+ CopyFromBuf(buf, MaximumJumpSpins);
+ CopyFromBuf(buf, BestStuntJump);
+ CopyFromBuf(buf, NumberOfUniqueJumpsFound);
+ CopyFromBuf(buf, TotalNumberOfUniqueJumps);
+ CopyFromBuf(buf, MissionsGiven);
+ CopyFromBuf(buf, MissionsPassed);
+ CopyFromBuf(buf, PassengersDroppedOffWithTaxi);
+ CopyFromBuf(buf, MoneyMadeWithTaxi);
+ CopyFromBuf(buf, IndustrialPassed);
+ CopyFromBuf(buf, CommercialPassed);
+ CopyFromBuf(buf, SuburbanPassed);
+ CopyFromBuf(buf, ElBurroTime);
+ CopyFromBuf(buf, DistanceTravelledOnFoot);
+ CopyFromBuf(buf, DistanceTravelledInVehicle);
+ CopyFromBuf(buf, Record4x4One);
+ CopyFromBuf(buf, Record4x4Two);
+ CopyFromBuf(buf, Record4x4Three);
+ CopyFromBuf(buf, Record4x4Mayhem);
+ CopyFromBuf(buf, LivesSavedWithAmbulance);
+ CopyFromBuf(buf, CriminalsCaught);
+ CopyFromBuf(buf, HighestLevelAmbulanceMission);
+ CopyFromBuf(buf, FiresExtinguished);
+ CopyFromBuf(buf, LongestFlightInDodo);
+ CopyFromBuf(buf, TimeTakenDefuseMission);
+ CopyFromBuf(buf, NumberKillFrenziesPassed);
+ CopyFromBuf(buf, TotalNumberKillFrenzies);
+ CopyFromBuf(buf, TotalNumberMissions);
+ CopyFromBuf(buf, FastestTimes);
+ CopyFromBuf(buf, HighestScores);
+ CopyFromBuf(buf, KillsSinceLastCheckpoint);
+ CopyFromBuf(buf, TotalLegitimateKills);
+ CopyFromBuf(buf, LastMissionPassedName);
+
+ assert(buf - buf_start == size);
+#undef CopyFromBuf
+}
+
+STARTPATCHES
+ InjectHook(0x48C5A3, CStats::Init, PATCH_JUMP); // CGame::ReInitGameObjectVariables
+ InjectHook(0x4AB3E0, CStats::SaveStats, PATCH_JUMP);
+ InjectHook(0x4AB670, CStats::LoadStats, PATCH_JUMP);
+ InjectHook(0x4AB090, CStats::FindCriminalRatingString, PATCH_JUMP);
+ InjectHook(0x4AB2A0, CStats::FindCriminalRatingNumber, PATCH_JUMP);
+ENDPATCHES \ No newline at end of file
diff --git a/src/core/Stats.h b/src/core/Stats.h
index 1d220905..ac3259f9 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -1,5 +1,7 @@
#pragma once
+#include "PedType.h"
+
class CStats
{
public:
@@ -8,14 +10,14 @@ public:
TOTAL_HIGHEST_SCORES = 16
};
static int32 &DaysPassed;
- static int32 &HeadsPopped;
- static bool& CommercialPassed;
- static bool& IndustrialPassed;
- static bool& SuburbanPassed;
+ static int32 &HeadsPopped;
+ static int32& CommercialPassed;
+ static int32& IndustrialPassed;
+ static int32& SuburbanPassed;
static int32 &NumberKillFrenziesPassed;
static int32 &PeopleKilledByOthers;
static int32 &HelisDestroyed;
- static int32 *PedsKilledOfThisType; //[NUM_PEDTYPES]
+ static int32(&PedsKilledOfThisType)[ePedType::NUM_PEDTYPES];
static int32 &TimesDied;
static int32 &TimesArrested;
static int32 &KillsSinceLastCheckpoint;
@@ -50,32 +52,39 @@ public:
static int32 &LongestFlightInDodo;
static int32 &TimeTakenDefuseMission;
static int32 &TotalNumberKillFrenzies;
- static int32 &TotalNumberMissions;
+ static int32 &TotalNumberMissions;
+ static int32 &RoundsFiredByPlayer;
+ static int32 &KgsOfExplosivesUsed;
+ static int32 &InstantHitsFiredByPlayer;
+ static int32 &InstantHitsHitByPlayer;
+ static int32 &BestTimeBombDefusal;
+ static int32 &mmRain;
+ static int32 &CarsCrushed;
static int32(&FastestTimes)[TOTAL_FASTEST_TIMES];
static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
- static int32 &KgOfExplosivesUsed;
- static int32 &CarsCrushed;
public:
+ static void Init(void);
static void RegisterFastestTime(int32, int32);
static void RegisterHighestScore(int32, int32);
- static void AnotherKillFrenzyPassed();
- static void AnotherLifeSavedWithAmbulance();
- static void AnotherCriminalCaught();
- static void RegisterLevelAmbulanceMission(int32);
- static void AnotherFireExtinguished();
+ static void RegisterElBurroTime(int32);
static void Register4x4OneTime(int32);
static void Register4x4TwoTime(int32);
static void Register4x4ThreeTime(int32);
static void Register4x4MayhemTime(int32);
+ static void AnotherLifeSavedWithAmbulance();
+ static void AnotherCriminalCaught();
+ static void RegisterLevelAmbulanceMission(int32);
+ static void AnotherFireExtinguished();
+ static wchar *FindCriminalRatingString();
static void RegisterLongestFlightInDodo(int32);
static void RegisterTimeTakenDefuseMission(int32);
+ static void AnotherKillFrenzyPassed();
static void SetTotalNumberKillFrenzies(int32);
static void SetTotalNumberMissions(int32);
- static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
static void CheckPointReachedSuccessfully() { TotalLegitimateKills += KillsSinceLastCheckpoint; KillsSinceLastCheckpoint = 0; };
- static void RegisterElBurroTime(int32);
+ static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
+ static int32 FindCriminalRatingNumber();
static void SaveStats(uint8 *buf, uint32 *size);
-
- static void Init(void);
+ static void LoadStats(uint8 *buf, uint32 size);
};
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index 3dcb767a..d00edf51 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -1247,8 +1247,8 @@ CStreaming::StreamVehiclesAndPeds(void)
static int timeBeforeNextLoad = 0;
static int modelQualityClass = 0;
- if(CRecordDataForGame::RecordingState == RECORDSTATE_1 ||
- CRecordDataForGame::RecordingState == RECORDSTATE_2)
+ if(CRecordDataForGame::IsRecording() ||
+ CRecordDataForGame::IsPlayingBack())
return;
if(FindPlayerPed()->m_pWanted->AreSwatRequired()){
diff --git a/src/core/Timer.cpp b/src/core/Timer.cpp
index 18d6b6a3..fda862f1 100644
--- a/src/core/Timer.cpp
+++ b/src/core/Timer.cpp
@@ -34,6 +34,10 @@ LARGE_INTEGER &perfSuspendCounter = *(LARGE_INTEGER*)0x62A318;
//UInt32 suspendDepth;
uint32 &suspendDepth = *(uint32*)0x62A320;
+#ifdef FIX_BUGS
+double frameTime;
+#endif
+
void CTimer::Initialise(void)
{
debug("Initialising CTimer...\n");
@@ -90,17 +94,21 @@ void CTimer::Update(void)
float updInCyclesScaled = updInCycles * ms_fTimeScale;
- double upd = updInCyclesScaled / (double)_nCyclesPerMS;
+ // We need that real frame time to fix transparent menu bug.
+#ifndef FIX_BUGS
+ double
+#endif
+ frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
- m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + upd;
+ m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
if ( GetIsPaused() )
ms_fTimeStep = 0.0f;
else
{
- m_snTimeInMilliseconds = m_snTimeInMilliseconds + upd;
- m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + upd;
- ms_fTimeStep = updInCyclesScaled / (double)_nCyclesPerMS / 20.0f;
+ m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime;
+ m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime;
+ ms_fTimeStep = frameTime / 1000.0f * 50.0f;
}
}
else
@@ -109,19 +117,23 @@ void CTimer::Update(void)
uint32 updInMs = timer - oldPcTimer;
- double upd = (double)updInMs * ms_fTimeScale;
+ // We need that real frame time to fix transparent menu bug.
+#ifndef FIX_BUGS
+ double
+#endif
+ frameTime = (double)updInMs * ms_fTimeScale;
oldPcTimer = timer;
- m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + upd;
+ m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
if ( GetIsPaused() )
ms_fTimeStep = 0.0f;
else
{
- m_snTimeInMilliseconds = m_snTimeInMilliseconds + upd;
- m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + upd;
- ms_fTimeStep = upd / 1000.0f * 50.0f;
+ m_snTimeInMilliseconds = m_snTimeInMilliseconds + frameTime;
+ m_snTimeInMillisecondsNonClipped = m_snTimeInMillisecondsNonClipped + frameTime;
+ ms_fTimeStep = frameTime / 1000.0f * 50.0f;
}
}
@@ -130,7 +142,7 @@ void CTimer::Update(void)
ms_fTimeStepNonClipped = ms_fTimeStep;
- if ( CRecordDataForGame::RecordingState != RECORDSTATE_2 )
+ if ( !CRecordDataForGame::IsPlayingBack() )
{
ms_fTimeStep = min(3.0f, ms_fTimeStep);
@@ -138,7 +150,7 @@ void CTimer::Update(void)
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
}
- if ( CRecordDataForChase::Status == RECORDSTATE_1 )
+ if ( CRecordDataForChase::IsRecording() )
{
ms_fTimeStep = 1.0f;
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
diff --git a/src/core/Timer.h b/src/core/Timer.h
index 2498ec8a..a4d674da 100644
--- a/src/core/Timer.h
+++ b/src/core/Timer.h
@@ -21,6 +21,7 @@ public:
static float GetTimeStepInMilliseconds() { return ms_fTimeStep / 50.0f * 1000.0f; }
static const float &GetTimeStepNonClipped(void) { return ms_fTimeStepNonClipped; }
static float GetTimeStepNonClippedInSeconds(void) { return ms_fTimeStepNonClipped / 50.0f; }
+ static float GetTimeStepNonClippedInMilliseconds(void) { return ms_fTimeStepNonClipped / 50.0f * 1000.0f; }
static void SetTimeStepNonClipped(float ts) { ms_fTimeStepNonClipped = ts; }
static const uint32 &GetFrameCounter(void) { return m_FrameCounter; }
static void SetFrameCounter(uint32 fc) { m_FrameCounter = fc; }
@@ -52,4 +53,11 @@ public:
static void Stop(void);
static void StartUserPause(void);
static void EndUserPause(void);
+
+ friend bool GenericLoad(void);
+ friend bool GenericSave(int file);
};
+
+#ifdef FIX_BUGS
+extern double frameTime;
+#endif
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 4a0230ce..d64569b3 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -56,6 +56,8 @@ WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const C
WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
+WRAPPER void CWorld::TriggerExplosion(const CVector& a1, float a2, float a3, CEntity *a4, bool a5) { EAXJMP(0x4B1140); }
+WRAPPER void CWorld::SetPedsOnFire(float, float, float, float, CEntity*) { EAXJMP(0x4B3D30); }
void
CWorld::Initialise()
diff --git a/src/core/World.h b/src/core/World.h
index c4103eb2..07e7889f 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -132,6 +132,7 @@ public:
static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float);
static void SetCarsOnFire(float, float, float, float, CEntity*);
+ static void SetPedsOnFire(float, float, float, float, CEntity*);
static void Initialise();
static void AddParticles();
@@ -140,6 +141,7 @@ public:
static void RepositionCertainDynamicObjects();
static void RemoveStaticObjects();
static void Process();
+ static void TriggerExplosion(const CVector &, float, float, CEntity*, bool);
};
extern CColPoint *gaTempSphereColPoints;
diff --git a/src/core/common.h b/src/core/common.h
index b58b93af..7688b182 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -74,9 +74,11 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w)
}
+#ifndef RWLIBS
// little hack
extern void **rwengine;
#define RwEngineInstance (*rwengine)
+#endif
#include "skeleton.h"
#include "Draw.h"
@@ -84,12 +86,14 @@ extern void **rwengine;
#define DEFAULT_SCREEN_WIDTH (640)
#define DEFAULT_SCREEN_HEIGHT (448)
#define DEFAULT_ASPECT_RATIO (4.0f/3.0f)
+#define DEFAULT_VIEWWINDOW (0.7f)
// game uses maximumWidth/Height, but this probably won't work
// with RW windowed mode
#define SCREEN_WIDTH ((float)RsGlobal.width)
#define SCREEN_HEIGHT ((float)RsGlobal.height)
#define SCREEN_ASPECT_RATIO (CDraw::GetAspectRatio())
+#define SCREEN_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
// This scales from PS2 pixel coordinates to the real resolution
#define SCREEN_STRETCH_X(a) ((a) * (float) SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH)
@@ -105,10 +109,8 @@ extern void **rwengine;
#ifdef ASPECT_RATIO_SCALE
#define SCREEN_SCALE_AR(a) ((a) * DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO)
-#define SCREEN_SCALE_AR2(a) ((a) / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO))
#else
#define SCREEN_SCALE_AR(a) (a)
-#define SCREEN_SCALE_AR2(a) (a)
#endif
#include "maths.h"
diff --git a/src/core/config.h b/src/core/config.h
index 373fca2f..f7fde579 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -73,9 +73,13 @@ enum Config {
NUMCORONAS = 56,
NUMPOINTLIGHTS = 32,
NUM3DMARKERS = 32,
+ NUMBRIGHTLIGHTS = 32,
+ NUMSHINYTEXTS = 32,
NUMMONEYMESSAGES = 16,
NUMPICKUPMESSAGES = 16,
NUMBULLETTRACES = 16,
+ NUMMBLURSTREAKS = 4,
+ NUMSKIDMARKS = 32,
NUMONSCREENTIMERENTRIES = 1,
NUMRADARBLIPS = 32,
@@ -83,6 +87,7 @@ enum Config {
NUMSCRIPTEDPICKUPS = 16,
NUMPICKUPS = NUMGENERALPICKUPS + NUMSCRIPTEDPICKUPS,
NUMCOLLECTEDPICKUPS = 20,
+ NUMPACMANPICKUPS = 256,
NUMEVENTS = 64,
NUM_CARGENS = 160,
@@ -120,7 +125,11 @@ enum Config {
NUM_AUDIO_REFLECTIONS = 5,
NUM_SCRIPT_MAX_ENTITIES = 40,
- NUM_GARAGE_STORED_CARS = 6
+ NUM_GARAGE_STORED_CARS = 6,
+
+ NUM_CRANES = 8,
+
+ NUM_EXPLOSIONS = 48,
};
// We'll use this once we're ready to become independent of the game
@@ -145,6 +154,7 @@ enum Config {
//#define MASTER
#if defined GTA_PS2
+# define GTA_PS2_STUFF
# define RANDOMSPLASH
#elif defined GTA_PC
# define GTA3_1_1_PATCH
@@ -183,13 +193,17 @@ enum Config {
// Pad
#define XINPUT
#define KANGAROO_CHEAT
-#define REGISTER_START_BUTTON // currently only in menu sadly. resumes the game
+#define REGISTER_START_BUTTON
// Hud, frontend and radar
#define ASPECT_RATIO_SCALE // Not just makes everything scale with aspect ratio, also adds support for all aspect ratios
#define TRIANGULAR_BLIPS // height indicating triangular radar blips, as in VC
#define PS2_SAVE_DIALOG // PS2 style save dialog with transparent black box
// #define PS2_LIKE_MENU // An effort to recreate PS2 menu, cycling through tabs, different bg etc.
+#define MENU_MAP // VC-like menu map. Make sure you have new menu.txd
+#define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
+#define TRIANGLE_BACK_BUTTON
+// #define CIRCLE_BACK_BUTTON
// Script
#define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 674527f5..f09c2e0a 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -1,6 +1,10 @@
#include "common.h"
+#include "rpmatfx.h"
+#include "rphanim.h"
+#include "rpskin.h"
#include "patcher.h"
#include "main.h"
+#include "CdStream.h"
#include "General.h"
#include "RwHelper.h"
#include "Clouds.h"
@@ -49,12 +53,11 @@
#include "Frontend.h"
#include "AnimViewer.h"
#include "Script.h"
+#include "PathFind.h"
#include "Debug.h"
#include "Console.h"
#include "timebars.h"
-
-#define DEFAULT_VIEWWINDOW (Tan(DEGTORAD(CDraw::GetFOV() * 0.5f)))
-
+#include "GenericGameStorage.h"
GlobalScene &Scene = *(GlobalScene*)0x726768;
@@ -68,293 +71,68 @@ char *gString2 = (char*)0x878A40;
wchar *gUString = (wchar*)0x74B018;
wchar *gUString2 = (wchar*)0x6EDD70;
-bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
-
-
-char version_name[64];
float FramesPerSecond = 30.0f;
bool gbPrintShite = false;
bool &gbModelViewer = *(bool*)0x95CD93;
-bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
-bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
-void DoRWStuffEndOfFrame(void);
+int32 frameCount;
+
+RwRGBA gColourTop;
+
+bool gameAlreadyInitialised;
-void RenderScene(void);
-void RenderDebugShit(void);
-void RenderEffects(void);
-void Render2dStuff(void);
-void RenderMenus(void);
-void DoFade(void);
-void Render2dStuffAfterFade(void);
+float NumberOfChunksLoaded;
+#define TOTALNUMCHUNKS 73.0f
+
+bool g_SlowMode = false;
+char version_name[64];
-CSprite2d *LoadSplash(const char *name);
+void GameInit(void);
+void SystemInit(void);
+void TheGame(void);
extern void (*DebugMenuProcess)(void);
extern void (*DebugMenuRender)(void);
void DebugMenuInit(void);
void DebugMenuPopulate(void);
-void PrintGameVersion();
-
-RwRGBA gColourTop;
-
-void
-InitialiseGame(void)
-{
- LoadingScreen(nil, nil, "loadsc0");
- CGame::Initialise("DATA\\GTA3.DAT");
-}
-
-#ifndef MASTER
-void
-TheModelViewer(void)
-{
-#ifdef ASPECT_RATIO_SCALE
- CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
- CAnimViewer::Update();
- CTimer::Update();
- SetLightsWithTimeOfDayColour(Scene.world);
- CRenderer::ConstructRenderList();
- DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
- CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
- 255);
-
- CSprite2d::InitPerFrame();
- CFont::InitPerFrame();
- DefinedState();
- CVisibilityPlugins::InitAlphaEntityList();
- CAnimViewer::Render();
- Render2dStuff();
- DoRWStuffEndOfFrame();
-}
-#endif
void
-Idle(void *arg)
+ValidateVersion()
{
-#ifdef ASPECT_RATIO_SCALE
- CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
-
- CTimer::Update();
-
-#ifdef TIMEBARS
- tbInit();
-#endif
-
- CSprite2d::InitPerFrame();
- CFont::InitPerFrame();
-
- // We're basically merging FrontendIdle and Idle (just like TheGame on PS2)
-#ifdef PS2_SAVE_DIALOG
- // Only exists on PC FrontendIdle, probably some PS2 bug fix
- if (FrontEndMenuManager.m_bMenuActive)
- CSprite2d::SetRecipNearClip();
-
- if (FrontEndMenuManager.m_bGameNotLoaded) {
- CPad::UpdatePads();
- FrontEndMenuManager.Process();
- } else {
- CPointLights::InitPerFrame();
-#ifdef TIMEBARS
- tbStartTimer(0, "CGame::Process");
-#endif
- CGame::Process();
-#ifdef TIMEBARS
- tbEndTimer("CGame::Process");
- tbStartTimer(0, "DMAudio.Service");
-#endif
- DMAudio.Service();
-
-#ifdef TIMEBARS
- tbEndTimer("DMAudio.Service");
-#endif
- }
-
- if (RsGlobal.quit)
- return;
-#else
- CPointLights::InitPerFrame();
-#ifdef TIMEBARS
- tbStartTimer(0, "CGame::Process");
-#endif
- CGame::Process();
-#ifdef TIMEBARS
- tbEndTimer("CGame::Process");
- tbStartTimer(0, "DMAudio.Service");
-#endif
-
- DMAudio.Service();
-
-#ifdef TIMEBARS
- tbEndTimer("DMAudio.Service");
-#endif
-#endif
-
- if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
- FrontEndMenuManager.m_bStartGameLoading = true;
- FrontEndMenuManager.m_bLoadingSavedGame = false;
- return;
- }
-
- if(FrontEndMenuManager.m_bStartGameLoading || b_FoundRecentSavedGameWantToLoad)
- return;
-
- SetLightsWithTimeOfDayColour(Scene.world);
-
- if(arg == nil)
- return;
-
- if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) &&
- TheCamera.GetScreenFadeStatus() != FADE_2){
-#ifdef GTA_PC
- if (!FrontEndMenuManager.m_bRenderGameInMenu) {
- // This is from SA, but it's nice for windowed mode
- RwV2d pos;
- pos.x = SCREEN_WIDTH / 2.0f;
- pos.y = SCREEN_HEIGHT / 2.0f;
- RsMouseSetPos(&pos);
- }
-#endif
-#ifdef TIMEBARS
- tbStartTimer(0, "CnstrRenderList");
-#endif
- CRenderer::ConstructRenderList();
-#ifdef TIMEBARS
- tbEndTimer("CnstrRenderList");
- tbStartTimer(0, "PreRender");
-#endif
- CRenderer::PreRender();
-#ifdef TIMEBARS
- tbEndTimer("PreRender");
-#endif
+ int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
+ char buff[128];
- if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
- if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
- return;
- }else{
- if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
- CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
- 255))
- return;
+ if ( file != -1 )
+ {
+ CFileMgr::Seek(file, 100, SEEK_SET);
+
+ for ( int i = 0; i < 128; i++ )
+ {
+ CFileMgr::Read(file, &buff[i], sizeof(char));
+ buff[i] -= 23;
+ if ( buff[i] == '\0' )
+ break;
+ CFileMgr::Seek(file, 99, SEEK_CUR);
}
-
- DefinedState();
-
- // BUG. This has to be done BEFORE RwCameraBeginUpdate
- RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
- RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
-
-#ifdef TIMEBARS
- tbStartTimer(0, "RenderScene");
-#endif
- RenderScene();
-#ifdef TIMEBARS
- tbEndTimer("RenderScene");
-#endif
- RenderDebugShit();
- RenderEffects();
-
-#ifdef TIMEBARS
- tbStartTimer(0, "RenderMotionBlur");
-#endif
- if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) &&
- TheCamera.m_ScreenReductionPercentage > 0.0f)
- TheCamera.SetMotionBlurAlpha(150);
- TheCamera.RenderMotionBlur();
-#ifdef TIMEBARS
- tbEndTimer("RenderMotionBlur");
- tbStartTimer(0, "Render2dStuff");
-#endif
- Render2dStuff();
-#ifdef TIMEBARS
- tbEndTimer("Render2dStuff");
-#endif
- }else{
- float viewWindow = DEFAULT_VIEWWINDOW;
-#ifdef ASPECT_RATIO_SCALE
- CameraSize(Scene.camera, nil, viewWindow, SCREEN_ASPECT_RATIO);
-#else
- CameraSize(Scene.camera, nil, viewWindow, DEFAULT_ASPECT_RATIO);
-#endif
- CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
- if(!RsCameraBeginUpdate(Scene.camera))
+
+ if ( !strncmp(buff, "grandtheftauto3", 15) )
+ {
+ strncpy(version_name, &buff[15], 64);
+ CFileMgr::CloseFile(file);
return;
+ }
}
-#ifdef PS2_SAVE_DIALOG
- if (FrontEndMenuManager.m_bMenuActive)
- DefinedState();
-#endif
-#ifdef TIMEBARS
- tbStartTimer(0, "RenderMenus");
-#endif
- RenderMenus();
-#ifdef TIMEBARS
- tbEndTimer("RenderMenus");
- tbStartTimer(0, "DoFade");
-#endif
- DoFade();
-#ifdef TIMEBARS
- tbEndTimer("DoFade");
- tbStartTimer(0, "Render2dStuff-Fade");
-#endif
- Render2dStuffAfterFade();
-#ifdef TIMEBARS
- tbEndTimer("Render2dStuff-Fade");
-#endif
- CCredits::Render();
-
-#ifdef TIMEBARS
- tbDisplay();
-#endif
-
- DoRWStuffEndOfFrame();
-
-// if(g_SlowMode)
-// ProcessSlowMode();
-}
-
-void
-FrontendIdle(void)
-{
-#ifdef ASPECT_RATIO_SCALE
- CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
-
- CTimer::Update();
- CSprite2d::SetRecipNearClip(); // this should be on InitialiseRenderWare according to PS2 asm. seems like a bug fix
- CSprite2d::InitPerFrame();
- CFont::InitPerFrame();
- CPad::UpdatePads();
- FrontEndMenuManager.Process();
-
- if(RsGlobal.quit)
- return;
-
- float viewWindow = DEFAULT_VIEWWINDOW;
-#ifdef ASPECT_RATIO_SCALE
- CameraSize(Scene.camera, nil, viewWindow, SCREEN_ASPECT_RATIO);
-#else
- CameraSize(Scene.camera, nil, viewWindow, DEFAULT_ASPECT_RATIO);
-#endif
- CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
- if(!RsCameraBeginUpdate(Scene.camera))
- return;
-
- DefinedState(); // seems redundant, but breaks resolution change.
- RenderMenus();
- DoFade();
- Render2dStuffAfterFade();
-// CFont::DrawFonts(); // redundant
- DoRWStuffEndOfFrame();
+ LoadingScreen("Invalid version", NULL, NULL);
+
+ while(true)
+ {
+ ;
+ }
}
bool
@@ -363,7 +141,7 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR
CRGBA TopColor(TopRed, TopGreen, TopBlue, Alpha);
CRGBA BottomColor(BottomRed, BottomGreen, BottomBlue, Alpha);
- CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+ CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
@@ -381,7 +159,7 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR
bool
DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha)
{
- CameraSize(Scene.camera, nil, DEFAULT_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+ CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
@@ -394,17 +172,6 @@ DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16
return true;
}
-void
-DoRWStuffEndOfFrame(void)
-{
- CDebug::DisplayScreenStrings(); // custom
- CDebug::DebugDisplayTextBuffer();
- FlushObrsPrintfs();
- RwCameraEndUpdate(Scene.camera);
- RsCameraShowRaster(Scene.camera);
-}
-
-
// This is certainly a very useful function
void
DoRWRenderHorizon(void)
@@ -413,127 +180,6 @@ DoRWRenderHorizon(void)
}
void
-RenderScene(void)
-{
- CClouds::Render();
- DoRWRenderHorizon();
- CRenderer::RenderRoads();
- CCoronas::RenderReflections();
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
- CRenderer::RenderEverythingBarRoads();
- CRenderer::RenderBoats();
- DefinedState();
- CWaterLevel::RenderWater();
- CRenderer::RenderFadingInEntities();
- CRenderer::RenderVehiclesButNotBoats();
- CWeather::RenderRainStreaks();
-}
-
-void
-RenderDebugShit(void)
-{
- CTheScripts::RenderTheScriptDebugLines();
- if(gbShowCollisionLines)
- CRenderer::RenderCollisionLines();
-}
-
-void
-RenderEffects(void)
-{
- CGlass::Render();
- CWaterCannons::Render();
- CSpecialFX::Render();
- CShadows::RenderStaticShadows();
- CShadows::RenderStoredShadows();
- CSkidmarks::Render();
- CAntennas::Render();
- CRubbish::Render();
- CCoronas::Render();
- CParticle::Render();
- CPacManPickups::Render();
- CWeaponEffects::Render();
- CPointLights::RenderFogEffect();
- CMovingThings::Render();
- CRenderer::RenderFirstPersonVehicle();
-}
-
-void
-Render2dStuff(void)
-{
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
-
- CReplay::Display();
- CPickups::RenderPickUpText();
-
- if(TheCamera.m_WideScreenOn)
- TheCamera.DrawBordersForWideScreen();
-
- CPed *player = FindPlayerPed();
- int weaponType = 0;
- if(player)
- weaponType = player->GetWeapon()->m_eWeaponType;
-
- bool firstPersonWeapon = false;
- int cammode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
- if(cammode == CCam::MODE_SNIPER ||
- cammode == CCam::MODE_SNIPER_RUNABOUT ||
- cammode == CCam::MODE_ROCKETLAUNCHER ||
- cammode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT)
- firstPersonWeapon = true;
-
- // Draw black border for sniper and rocket launcher
- if((weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_ROCKETLAUNCHER) && firstPersonWeapon){
- CRGBA black(0, 0, 0, 255);
-
- // top and bottom strips
- if (weaponType == WEAPONTYPE_ROCKETLAUNCHER) {
- CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(180)), black);
- CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(170), SCREEN_WIDTH, SCREEN_HEIGHT), black);
- }
- else {
- CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(210)), black);
- CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(210), SCREEN_WIDTH, SCREEN_HEIGHT), black);
- }
- CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH / 2 - SCREEN_SCALE_X(210), SCREEN_HEIGHT), black);
- CSprite2d::DrawRect(CRect(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(210), 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), black);
- }
-
- MusicManager.DisplayRadioStationName();
- TheConsole.Display();
-/*
- if(CSceneEdit::m_bEditOn)
- CSceneEdit::Draw();
- else
-*/
- CHud::Draw();
- CUserDisplay::OnscnTimer.ProcessForDisplay();
- CMessages::Display();
- CDarkel::DrawMessages();
- CGarages::PrintMessages();
- CPad::PrintErrorMessage();
- CFont::DrawFonts();
-
- DebugMenuRender();
-}
-
-void
-RenderMenus(void)
-{
- if(FrontEndMenuManager.m_bMenuActive)
- FrontEndMenuManager.DrawFrontEnd();
-}
-
-bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4;
-bool &StillToFadeOut = *(bool*)0x95CD99;
-uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC;
-uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564;
-
-void
DoFade(void)
{
if(CTimer::GetIsPaused())
@@ -613,139 +259,95 @@ DoFade(void)
}
}
-float FramesPerSecondCounter;
-int32 FrameSamples;
-
-struct tZonePrint
-{
- char name[12];
- CRect rect;
-};
-
-tZonePrint ZonePrint[] =
-{
- { "suburban", CRect(-1639.4f, 1014.3f, -226.23f, -1347.9f) },
- { "comntop", CRect(-223.52f, 203.62f, 616.79f, -413.6f) },
- { "comnbtm", CRect(-227.24f, -413.6f, 620.51f, -911.84f) },
- { "comse", CRect( 200.35f, -911.84f, 620.51f, -1737.3f) },
- { "comsw", CRect(-223.52f, -911.84f, 200.35f, -1737.3f) },
- { "industsw", CRect( 744.05f, -473.0f, 1067.5f, -1331.5f) },
- { "industne", CRect( 1067.5f, 282.19f, 1915.3f, -473.0f) },
- { "industnw", CRect( 744.05f, 324.95f, 1067.5f, -473.0f) },
- { "industse", CRect( 1070.3f, -473.0f, 1918.1f, -1331.5f) },
- { "no zone", CRect( 0.0f, 0.0f, 0.0f, 0.0f) }
-};
-
-#ifndef MASTER
void
-DisplayGameDebugText()
+DoRWStuffEndOfFrame(void)
{
- static bool bDisplayPosn = false;
- static bool bDisplayRate = false;
+ CDebug::DisplayScreenStrings(); // custom
+ CDebug::DebugDisplayTextBuffer();
+ FlushObrsPrintfs();
+ RwCameraEndUpdate(Scene.camera);
+ RsCameraShowRaster(Scene.camera);
+}
+static RwBool
+PluginAttach(void)
+{
+ if( !RpWorldPluginAttach() )
{
- SETTWEAKPATH("GameDebugText");
- TWEAKBOOL(bDisplayPosn);
- TWEAKBOOL(bDisplayRate);
+ printf("Couldn't attach world plugin\n");
+
+ return FALSE;
}
-
-
- char str[200];
- wchar ustr[200];
- wchar ver[200];
- AsciiToUnicode(version_name, ver);
-
- CFont::SetPropOn();
- CFont::SetBackgroundOff();
- CFont::SetFontStyle(FONT_BANK);
- CFont::SetScale(SCREEN_STRETCH_X(0.5f), SCREEN_STRETCH_Y(0.5f));
- CFont::SetCentreOff();
- CFont::SetRightJustifyOff();
- CFont::SetWrapx(SCREEN_WIDTH);
- CFont::SetJustifyOff();
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetColor(CRGBA(255, 108, 0, 255));
- CFont::PrintString(10.0f, 10.0f, ver);
-
- FrameSamples++;
- FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
- FramesPerSecond = FramesPerSecondCounter / FrameSamples;
-
- if ( FrameSamples > 30 )
+ if( !RpSkinPluginAttach() )
{
- FramesPerSecondCounter = 0.0f;
- FrameSamples = 0;
+ printf("Couldn't attach RpSkin plugin\n");
+
+ return FALSE;
}
-
- if ( !TheCamera.WorldViewerBeingUsed
- && CPad::GetPad(1)->GetSquare()
- && CPad::GetPad(1)->GetTriangle()
- && CPad::GetPad(1)->GetLeftShoulder2JustDown() )
+
+ if( !RpHAnimPluginAttach() )
{
- bDisplayPosn = !bDisplayPosn;
+ printf("Couldn't attach RpHAnim plugin\n");
+
+ return FALSE;
}
-
- if ( CPad::GetPad(1)->GetSquare()
- && CPad::GetPad(1)->GetTriangle()
- && CPad::GetPad(1)->GetRightShoulder2JustDown() )
+
+ if( !NodeNamePluginAttach() )
{
- bDisplayRate = !bDisplayRate;
+ printf("Couldn't attach node name plugin\n");
+
+ return FALSE;
}
- if ( bDisplayPosn || bDisplayRate )
+ if( !CVisibilityPlugins::PluginAttach() )
{
- CVector pos = FindPlayerCoors();
- int32 ZoneId = ARRAY_SIZE(ZonePrint)-1; // no zone
-
- for ( int32 i = 0; i < ARRAY_SIZE(ZonePrint)-1; i++ )
- {
- if ( pos.x > ZonePrint[i].rect.left
- && pos.x < ZonePrint[i].rect.right
- && pos.y > ZonePrint[i].rect.bottom
- && pos.y < ZonePrint[i].rect.top )
- {
- ZoneId = i;
- }
- }
-
- //NOTE: fps should be 30, but its 29 due to different fp2int conversion
- if ( bDisplayRate )
- sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, F-%d, %s", pos.x, pos.y, pos.z, (int32)FramesPerSecond, ZonePrint[ZoneId].name);
- else
- sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, %s", pos.x, pos.y, pos.z, ZonePrint[ZoneId].name);
-
- AsciiToUnicode(str, ustr);
+ printf("Couldn't attach visibility plugins\n");
- CFont::SetPropOff();
- CFont::SetBackgroundOff();
- CFont::SetScale(0.7f, 1.5f);
- CFont::SetCentreOff();
- CFont::SetRightJustifyOff();
- CFont::SetJustifyOff();
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetWrapx(640.0f);
- CFont::SetFontStyle(FONT_HEADING);
+ return FALSE;
+ }
+
+ if( !RpAnimBlendPluginAttach() )
+ {
+ printf("Couldn't attach RpAnimBlend plugin\n");
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(42.0f, 42.0f, ustr);
+ return FALSE;
+ }
+
+ if( !RpMatFXPluginAttach() )
+ {
+ printf("Couldn't attach RpMatFX plugin\n");
- CFont::SetColor(CRGBA(255, 108, 0, 255));
- CFont::PrintString(40.0f, 40.0f, ustr);
+ return FALSE;
}
+
+ return TRUE;
}
-#endif
-void
-Render2dStuffAfterFade(void)
+static RwBool
+Initialise3D(void *param)
{
-#ifndef MASTER
- DisplayGameDebugText();
- //PrintGameVersion();
-#endif
+ if (RsRwInitialise(param))
+ {
+ //
+ DebugMenuInit();
+ DebugMenuPopulate();
+ //
- CHud::DrawAfterFade();
- CFont::DrawFonts();
+ return CGame::InitialiseRenderWare();
+ }
+
+ return (FALSE);
+}
+
+static void
+Terminate3D(void)
+{
+ CGame::ShutdownRenderWare();
+
+ RsRwTerminate();
+
+ return;
}
CSprite2d splash;
@@ -796,8 +398,41 @@ DestroySplashScreen(void)
splashTxdId = -1;
}
-float NumberOfChunksLoaded;
-#define TOTALNUMCHUNKS 73.0f
+char*
+GetRandomSplashScreen(void)
+{
+ int index;
+ static int index2 = 0;
+ static char splashName[128];
+ static int splashIndex[24] = {
+ 25, 22, 4, 13,
+ 1, 21, 14, 16,
+ 10, 12, 5, 9,
+ 11, 18, 3, 2,
+ 19, 23, 7, 17,
+ 15, 6, 8, 20
+ };
+
+ index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)];
+ index2++;
+ if(index2 == 6)
+ index2 = 0;
+ sprintf(splashName, "loadsc%d", index);
+ return splashName;
+}
+
+char*
+GetLevelSplashScreen(int level)
+{
+ static char *splashScreens[4] = {
+ nil,
+ "splash1",
+ "splash2",
+ "splash3",
+ };
+
+ return splashScreens[level];
+}
void
ResetLoadingScreenBar()
@@ -820,8 +455,10 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
splash = LoadSplash(splashscreen);
+#ifndef GTA_PS2
if(RsGlobal.quit)
return;
+#endif
if(DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255)){
CSprite2d::SetRecipNearClip();
@@ -914,131 +551,588 @@ LoadingIslandScreen(const char *levelName)
DoRWStuffEndOfFrame();
}
-char*
-GetLevelSplashScreen(int level)
-{
- static char *splashScreens[4] = {
- nil,
- "splash1",
- "splash2",
- "splash3",
- };
-
- return splashScreens[level];
+void
+ProcessSlowMode(void)
+{
+ int16 lX = CPad::GetPad(0)->NewState.LeftStickX;
+ int16 lY = CPad::GetPad(0)->NewState.LeftStickY;
+ int16 rX = CPad::GetPad(0)->NewState.RightStickX;
+ int16 rY = CPad::GetPad(0)->NewState.RightStickY;
+ int16 L1 = CPad::GetPad(0)->NewState.LeftShoulder1;
+ int16 L2 = CPad::GetPad(0)->NewState.LeftShoulder2;
+ int16 R1 = CPad::GetPad(0)->NewState.RightShoulder1;
+ int16 R2 = CPad::GetPad(0)->NewState.RightShoulder2;
+ int16 up = CPad::GetPad(0)->NewState.DPadUp;
+ int16 down = CPad::GetPad(0)->NewState.DPadDown;
+ int16 left = CPad::GetPad(0)->NewState.DPadLeft;
+ int16 right = CPad::GetPad(0)->NewState.DPadRight;
+ int16 start = CPad::GetPad(0)->NewState.Start;
+ int16 select = CPad::GetPad(0)->NewState.Select;
+ int16 square = CPad::GetPad(0)->NewState.Square;
+ int16 triangle = CPad::GetPad(0)->NewState.Triangle;
+ int16 cross = CPad::GetPad(0)->NewState.Cross;
+ int16 circle = CPad::GetPad(0)->NewState.Circle;
+ int16 L3 = CPad::GetPad(0)->NewState.LeftShock;
+ int16 R3 = CPad::GetPad(0)->NewState.RightShock;
+ int16 networktalk = CPad::GetPad(0)->NewState.NetworkTalk;
+ int16 stop = true;
+
+ do
+ {
+ if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() )
+ break;
+
+ if ( stop )
+ {
+ CTimer::Stop();
+ stop = false;
+ }
+
+ CPad::UpdatePads();
+
+ RwCameraBeginUpdate(Scene.camera);
+ RwCameraEndUpdate(Scene.camera);
+
+ if ( CPad::GetPad(1)->GetLeftShoulder1JustDown() || CPad::GetPad(1)->GetRightShoulder1() )
+ break;
+
+ } while (!CPad::GetPad(1)->GetRightShoulder1());
+
+
+ CPad::GetPad(0)->OldState.LeftStickX = lX;
+ CPad::GetPad(0)->OldState.LeftStickY = lY;
+ CPad::GetPad(0)->OldState.RightStickX = rX;
+ CPad::GetPad(0)->OldState.RightStickY = rY;
+ CPad::GetPad(0)->OldState.LeftShoulder1 = L1;
+ CPad::GetPad(0)->OldState.LeftShoulder2 = L2;
+ CPad::GetPad(0)->OldState.RightShoulder1 = R1;
+ CPad::GetPad(0)->OldState.RightShoulder2 = R2;
+ CPad::GetPad(0)->OldState.DPadUp = up;
+ CPad::GetPad(0)->OldState.DPadDown = down;
+ CPad::GetPad(0)->OldState.DPadLeft = left;
+ CPad::GetPad(0)->OldState.DPadRight = right;
+ CPad::GetPad(0)->OldState.Start = start;
+ CPad::GetPad(0)->OldState.Select = select;
+ CPad::GetPad(0)->OldState.Square = square;
+ CPad::GetPad(0)->OldState.Triangle = triangle;
+ CPad::GetPad(0)->OldState.Cross = cross;
+ CPad::GetPad(0)->OldState.Circle = circle;
+ CPad::GetPad(0)->OldState.LeftShock = L3;
+ CPad::GetPad(0)->OldState.RightShock = R3;
+ CPad::GetPad(0)->OldState.NetworkTalk = networktalk;
+ CPad::GetPad(0)->NewState.LeftStickX = lX;
+ CPad::GetPad(0)->NewState.LeftStickY = lY;
+ CPad::GetPad(0)->NewState.RightStickX = rX;
+ CPad::GetPad(0)->NewState.RightStickY = rY;
+ CPad::GetPad(0)->NewState.LeftShoulder1 = L1;
+ CPad::GetPad(0)->NewState.LeftShoulder2 = L2;
+ CPad::GetPad(0)->NewState.RightShoulder1 = R1;
+ CPad::GetPad(0)->NewState.RightShoulder2 = R2;
+ CPad::GetPad(0)->NewState.DPadUp = up;
+ CPad::GetPad(0)->NewState.DPadDown = down;
+ CPad::GetPad(0)->NewState.DPadLeft = left;
+ CPad::GetPad(0)->NewState.DPadRight = right;
+ CPad::GetPad(0)->NewState.Start = start;
+ CPad::GetPad(0)->NewState.Select = select;
+ CPad::GetPad(0)->NewState.Square = square;
+ CPad::GetPad(0)->NewState.Triangle = triangle;
+ CPad::GetPad(0)->NewState.Cross = cross;
+ CPad::GetPad(0)->NewState.Circle = circle;
+ CPad::GetPad(0)->NewState.LeftShock = L3;
+ CPad::GetPad(0)->NewState.RightShock = R3;
+ CPad::GetPad(0)->NewState.NetworkTalk = networktalk;
}
-char*
-GetRandomSplashScreen(void)
-{
- int index;
- static int index2 = 0;
- static char splashName[128];
- static int splashIndex[24] = {
- 25, 22, 4, 13,
- 1, 21, 14, 16,
- 10, 12, 5, 9,
- 11, 18, 3, 2,
- 19, 23, 7, 17,
- 15, 6, 8, 20
- };
- index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)];
- index2++;
- if(index2 == 6)
- index2 = 0;
- sprintf(splashName, "loadsc%d", index);
- return splashName;
-}
+float FramesPerSecondCounter;
+int32 FrameSamples;
-#include "rwcore.h"
-#include "rpworld.h"
-#include "rpmatfx.h"
-#include "rpskin.h"
-#include "rphanim.h"
-#include "rtbmp.h"
+struct tZonePrint
+{
+ char name[12];
+ CRect rect;
+};
-_TODO("temp, move this includes out of here")
+tZonePrint ZonePrint[] =
+{
+ { "suburban", CRect(-1639.4f, 1014.3f, -226.23f, -1347.9f) },
+ { "comntop", CRect(-223.52f, 203.62f, 616.79f, -413.6f) },
+ { "comnbtm", CRect(-227.24f, -413.6f, 620.51f, -911.84f) },
+ { "comse", CRect( 200.35f, -911.84f, 620.51f, -1737.3f) },
+ { "comsw", CRect(-223.52f, -911.84f, 200.35f, -1737.3f) },
+ { "industsw", CRect( 744.05f, -473.0f, 1067.5f, -1331.5f) },
+ { "industne", CRect( 1067.5f, 282.19f, 1915.3f, -473.0f) },
+ { "industnw", CRect( 744.05f, 324.95f, 1067.5f, -473.0f) },
+ { "industse", CRect( 1070.3f, -473.0f, 1918.1f, -1331.5f) },
+ { "no zone", CRect( 0.0f, 0.0f, 0.0f, 0.0f) }
+};
-static RwBool
-PluginAttach(void)
+#ifndef MASTER
+void
+DisplayGameDebugText()
{
- if( !RpWorldPluginAttach() )
+ static bool bDisplayPosn = false;
+ static bool bDisplayRate = false;
+
{
- printf("Couldn't attach world plugin\n");
-
- return FALSE;
+ SETTWEAKPATH("GameDebugText");
+ TWEAKBOOL(bDisplayPosn);
+ TWEAKBOOL(bDisplayRate);
}
+
+
+ char str[200];
+ wchar ustr[200];
+ wchar ver[200];
- if( !RpSkinPluginAttach() )
- {
- printf("Couldn't attach RpSkin plugin\n");
-
- return FALSE;
- }
+ AsciiToUnicode(version_name, ver);
+
+ CFont::SetPropOn();
+ CFont::SetBackgroundOff();
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetScale(SCREEN_STRETCH_X(0.5f), SCREEN_STRETCH_Y(0.5f));
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOff();
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::SetJustifyOff();
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetColor(CRGBA(255, 108, 0, 255));
+ CFont::PrintString(10.0f, 10.0f, ver);
+
+ FrameSamples++;
+ FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
+ FramesPerSecond = FramesPerSecondCounter / FrameSamples;
- if( !RpHAnimPluginAttach() )
+ if ( FrameSamples > 30 )
{
- printf("Couldn't attach RpHAnim plugin\n");
-
- return FALSE;
+ FramesPerSecondCounter = 0.0f;
+ FrameSamples = 0;
}
-
- if( !NodeNamePluginAttach() )
+
+ if ( !TheCamera.WorldViewerBeingUsed
+ && CPad::GetPad(1)->GetSquare()
+ && CPad::GetPad(1)->GetTriangle()
+ && CPad::GetPad(1)->GetLeftShoulder2JustDown() )
{
- printf("Couldn't attach node name plugin\n");
-
- return FALSE;
+ bDisplayPosn = !bDisplayPosn;
}
-
- if( !CVisibilityPlugins::PluginAttach() )
+
+ if ( CPad::GetPad(1)->GetSquare()
+ && CPad::GetPad(1)->GetTriangle()
+ && CPad::GetPad(1)->GetRightShoulder2JustDown() )
{
- printf("Couldn't attach visibility plugins\n");
-
- return FALSE;
+ bDisplayRate = !bDisplayRate;
}
- if( !RpAnimBlendPluginAttach() )
+ if ( bDisplayPosn || bDisplayRate )
{
- printf("Couldn't attach RpAnimBlend plugin\n");
+ CVector pos = FindPlayerCoors();
+ int32 ZoneId = ARRAY_SIZE(ZonePrint)-1; // no zone
- return FALSE;
- }
-
- if( !RpMatFXPluginAttach() )
- {
- printf("Couldn't attach RpMatFX plugin\n");
+ for ( int32 i = 0; i < ARRAY_SIZE(ZonePrint)-1; i++ )
+ {
+ if ( pos.x > ZonePrint[i].rect.left
+ && pos.x < ZonePrint[i].rect.right
+ && pos.y > ZonePrint[i].rect.bottom
+ && pos.y < ZonePrint[i].rect.top )
+ {
+ ZoneId = i;
+ }
+ }
+
+ //NOTE: fps should be 30, but its 29 due to different fp2int conversion
+ if ( bDisplayRate )
+ sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, F-%d, %s", pos.x, pos.y, pos.z, (int32)FramesPerSecond, ZonePrint[ZoneId].name);
+ else
+ sprintf(str, "X:%5.1f, Y:%5.1f, Z:%5.1f, %s", pos.x, pos.y, pos.z, ZonePrint[ZoneId].name);
- return FALSE;
+ AsciiToUnicode(str, ustr);
+
+ CFont::SetPropOff();
+ CFont::SetBackgroundOff();
+ CFont::SetScale(0.7f, 1.5f);
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOff();
+ CFont::SetJustifyOff();
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetWrapx(640.0f);
+ CFont::SetFontStyle(FONT_HEADING);
+
+ CFont::SetColor(CRGBA(0, 0, 0, 255));
+ CFont::PrintString(42.0f, 42.0f, ustr);
+
+ CFont::SetColor(CRGBA(255, 108, 0, 255));
+ CFont::PrintString(40.0f, 40.0f, ustr);
}
+}
+#endif
- return TRUE;
+void
+RenderScene(void)
+{
+ CClouds::Render();
+ DoRWRenderHorizon();
+ CRenderer::RenderRoads();
+ CCoronas::RenderReflections();
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ CRenderer::RenderEverythingBarRoads();
+ CRenderer::RenderBoats();
+ DefinedState();
+ CWaterLevel::RenderWater();
+ CRenderer::RenderFadingInEntities();
+ CRenderer::RenderVehiclesButNotBoats();
+ CWeather::RenderRainStreaks();
}
-static RwBool
-Initialise3D(void *param)
+void
+RenderDebugShit(void)
{
- if (RsRwInitialise(param))
- {
- //
- DebugMenuInit();
- DebugMenuPopulate();
- //
+ CTheScripts::RenderTheScriptDebugLines();
+#ifndef FINAL
+ if(gbShowCollisionLines)
+ CRenderer::RenderCollisionLines();
+ ThePaths.DisplayPathData();
+#endif
+}
- return CGame::InitialiseRenderWare();
+void
+RenderEffects(void)
+{
+ CGlass::Render();
+ CWaterCannons::Render();
+ CSpecialFX::Render();
+ CShadows::RenderStaticShadows();
+ CShadows::RenderStoredShadows();
+ CSkidmarks::Render();
+ CAntennas::Render();
+ CRubbish::Render();
+ CCoronas::Render();
+ CParticle::Render();
+ CPacManPickups::Render();
+ CWeaponEffects::Render();
+ CPointLights::RenderFogEffect();
+ CMovingThings::Render();
+ CRenderer::RenderFirstPersonVehicle();
+}
+
+void
+Render2dStuff(void)
+{
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
+
+ CReplay::Display();
+ CPickups::RenderPickUpText();
+
+ if(TheCamera.m_WideScreenOn)
+ TheCamera.DrawBordersForWideScreen();
+
+ CPed *player = FindPlayerPed();
+ int weaponType = 0;
+ if(player)
+ weaponType = player->GetWeapon()->m_eWeaponType;
+
+ bool firstPersonWeapon = false;
+ int cammode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ if(cammode == CCam::MODE_SNIPER ||
+ cammode == CCam::MODE_SNIPER_RUNABOUT ||
+ cammode == CCam::MODE_ROCKETLAUNCHER ||
+ cammode == CCam::MODE_ROCKETLAUNCHER_RUNABOUT)
+ firstPersonWeapon = true;
+
+ // Draw black border for sniper and rocket launcher
+ if((weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_ROCKETLAUNCHER) && firstPersonWeapon){
+ CRGBA black(0, 0, 0, 255);
+
+ // top and bottom strips
+ if (weaponType == WEAPONTYPE_ROCKETLAUNCHER) {
+ CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(180)), black);
+ CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(170), SCREEN_WIDTH, SCREEN_HEIGHT), black);
+ }
+ else {
+ CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(210)), black);
+ CSprite2d::DrawRect(CRect(0.0f, SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(210), SCREEN_WIDTH, SCREEN_HEIGHT), black);
+ }
+ CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH / 2 - SCREEN_SCALE_X(210), SCREEN_HEIGHT), black);
+ CSprite2d::DrawRect(CRect(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(210), 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), black);
}
- return (FALSE);
+ MusicManager.DisplayRadioStationName();
+ TheConsole.Display();
+/*
+ if(CSceneEdit::m_bEditOn)
+ CSceneEdit::Draw();
+ else
+*/
+ CHud::Draw();
+ CUserDisplay::OnscnTimer.ProcessForDisplay();
+ CMessages::Display();
+ CDarkel::DrawMessages();
+ CGarages::PrintMessages();
+ CPad::PrintErrorMessage();
+ CFont::DrawFonts();
+
+ DebugMenuRender();
}
+void
+RenderMenus(void)
+{
+#ifdef PS2
+ if (FrontEndMenuManager.m_bWantToDraw)
+ {
+ gMainHeap.PushMemId(_TODOCONST(17));
+ FrontEndMenuManager.DrawFrontEnd();
+ gMainHeap.PopMemId();
+ }
+#else
+ if(FrontEndMenuManager.m_bMenuActive)
+ FrontEndMenuManager.DrawFrontEnd();
+#endif
+}
-static void
-Terminate3D(void)
+void
+Render2dStuffAfterFade(void)
{
- CGame::ShutdownRenderWare();
+#ifndef MASTER
+ DisplayGameDebugText();
+#endif
+
+ CHud::DrawAfterFade();
+ CFont::DrawFonts();
+}
+
+void
+Idle(void *arg)
+{
+#ifdef ASPECT_RATIO_SCALE
+ CDraw::SetAspectRatio(CDraw::FindAspectRatio());
+#endif
+
+ CTimer::Update();
+
+#ifdef TIMEBARS
+ tbInit();
+#endif
+
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+
+ // We're basically merging FrontendIdle and Idle (just like TheGame on PS2)
+#ifdef PS2_SAVE_DIALOG
+ // Only exists on PC FrontendIdle, probably some PS2 bug fix
+ if (FrontEndMenuManager.m_bMenuActive)
+ CSprite2d::SetRecipNearClip();
- RsRwTerminate();
+ if (FrontEndMenuManager.m_bGameNotLoaded) {
+ CPad::UpdatePads();
+ FrontEndMenuManager.Process();
+ } else {
+ CPointLights::InitPerFrame();
+#ifdef TIMEBARS
+ tbStartTimer(0, "CGame::Process");
+#endif
+ CGame::Process();
+#ifdef TIMEBARS
+ tbEndTimer("CGame::Process");
+ tbStartTimer(0, "DMAudio.Service");
+#endif
+ DMAudio.Service();
- return;
+#ifdef TIMEBARS
+ tbEndTimer("DMAudio.Service");
+#endif
+ }
+
+ if (RsGlobal.quit)
+ return;
+#else
+ CPointLights::InitPerFrame();
+#ifdef TIMEBARS
+ tbStartTimer(0, "CGame::Process");
+#endif
+ CGame::Process();
+#ifdef TIMEBARS
+ tbEndTimer("CGame::Process");
+ tbStartTimer(0, "DMAudio.Service");
+#endif
+
+ DMAudio.Service();
+
+#ifdef TIMEBARS
+ tbEndTimer("DMAudio.Service");
+#endif
+#endif
+
+ if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
+ FrontEndMenuManager.m_bWantToRestart = true;
+ FrontEndMenuManager.m_bWantToLoad = false;
+ return;
+ }
+
+ if(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
+ return;
+
+ SetLightsWithTimeOfDayColour(Scene.world);
+
+ if(arg == nil)
+ return;
+
+ if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) &&
+ TheCamera.GetScreenFadeStatus() != FADE_2)
+ {
+#ifdef GTA_PC
+ if (!FrontEndMenuManager.m_bRenderGameInMenu) {
+ // This is from SA, but it's nice for windowed mode
+ RwV2d pos;
+ pos.x = SCREEN_WIDTH / 2.0f;
+ pos.y = SCREEN_HEIGHT / 2.0f;
+ RsMouseSetPos(&pos);
+ }
+#endif
+#ifdef TIMEBARS
+ tbStartTimer(0, "CnstrRenderList");
+#endif
+ CRenderer::ConstructRenderList();
+#ifdef TIMEBARS
+ tbEndTimer("CnstrRenderList");
+ tbStartTimer(0, "PreRender");
+#endif
+ CRenderer::PreRender();
+#ifdef TIMEBARS
+ tbEndTimer("PreRender");
+#endif
+
+ if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
+ if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
+ return;
+ }else{
+ if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
+ CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
+ 255))
+ return;
+ }
+
+ DefinedState();
+
+ // BUG. This has to be done BEFORE RwCameraBeginUpdate
+ RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
+ RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
+
+#ifdef TIMEBARS
+ tbStartTimer(0, "RenderScene");
+#endif
+ RenderScene();
+#ifdef TIMEBARS
+ tbEndTimer("RenderScene");
+#endif
+ RenderDebugShit();
+ RenderEffects();
+
+#ifdef TIMEBARS
+ tbStartTimer(0, "RenderMotionBlur");
+#endif
+ if((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) &&
+ TheCamera.m_ScreenReductionPercentage > 0.0f)
+ TheCamera.SetMotionBlurAlpha(150);
+ TheCamera.RenderMotionBlur();
+#ifdef TIMEBARS
+ tbEndTimer("RenderMotionBlur");
+ tbStartTimer(0, "Render2dStuff");
+#endif
+ Render2dStuff();
+#ifdef TIMEBARS
+ tbEndTimer("Render2dStuff");
+#endif
+ }else{
+#ifdef ASPECT_RATIO_SCALE
+ CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+#else
+ CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
+#endif
+ CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
+ RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ if(!RsCameraBeginUpdate(Scene.camera))
+ return;
+ }
+
+#ifdef PS2_SAVE_DIALOG
+ if (FrontEndMenuManager.m_bMenuActive)
+ DefinedState();
+#endif
+#ifdef TIMEBARS
+ tbStartTimer(0, "RenderMenus");
+#endif
+ RenderMenus();
+#ifdef TIMEBARS
+ tbEndTimer("RenderMenus");
+ tbStartTimer(0, "DoFade");
+#endif
+ DoFade();
+#ifdef TIMEBARS
+ tbEndTimer("DoFade");
+ tbStartTimer(0, "Render2dStuff-Fade");
+#endif
+ Render2dStuffAfterFade();
+#ifdef TIMEBARS
+ tbEndTimer("Render2dStuff-Fade");
+#endif
+ CCredits::Render();
+
+#ifdef TIMEBARS
+ tbDisplay();
+#endif
+
+ DoRWStuffEndOfFrame();
+
+ if(g_SlowMode)
+ ProcessSlowMode();
+}
+
+void
+FrontendIdle(void)
+{
+#ifdef ASPECT_RATIO_SCALE
+ CDraw::SetAspectRatio(CDraw::FindAspectRatio());
+#endif
+
+ CTimer::Update();
+ CSprite2d::SetRecipNearClip(); // this should be on InitialiseRenderWare according to PS2 asm. seems like a bug fix
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ CPad::UpdatePads();
+ FrontEndMenuManager.Process();
+
+ if(RsGlobal.quit)
+ return;
+
+#ifdef ASPECT_RATIO_SCALE
+ CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+#else
+ CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
+#endif
+ CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
+ RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ if(!RsCameraBeginUpdate(Scene.camera))
+ return;
+
+ DefinedState(); // seems redundant, but breaks resolution change.
+ RenderMenus();
+ DoFade();
+ Render2dStuffAfterFade();
+// CFont::DrawFonts(); // redundant
+ DoRWStuffEndOfFrame();
+}
+
+void
+InitialiseGame(void)
+{
+ LoadingScreen(nil, nil, "loadsc0");
+ CGame::Initialise("DATA\\GTA3.DAT");
}
RsEventStatus
@@ -1056,7 +1150,7 @@ AppEventHandler(RsEvent event, void *param)
{
CameraSize(Scene.camera, (RwRect *)param,
- DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
+ SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
return rsEVENTPROCESSED;
}
@@ -1133,58 +1227,615 @@ AppEventHandler(RsEvent event, void *param)
}
}
-void PrintGameVersion()
+#ifndef MASTER
+void
+TheModelViewer(void)
{
- CFont::SetPropOn();
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.5f));
- CFont::SetCentreOff();
- CFont::SetRightJustifyOff();
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetFontStyle(FONT_BANK);
- CFont::SetWrapx(SCREEN_WIDTH);
- CFont::SetDropShadowPosition(0);
- CFont::SetDropColor(CRGBA(0, 0, 0, 255));
- CFont::SetColor(CRGBA(235, 170, 50, 255));
+#if (defined(GTA_PS2) || defined(GTA_XBOX))
+ //TODO
+#else
+#ifdef ASPECT_RATIO_SCALE
+ CDraw::SetAspectRatio(CDraw::FindAspectRatio());
+#endif
+ CAnimViewer::Update();
+ CTimer::Update();
+ SetLightsWithTimeOfDayColour(Scene.world);
+ CRenderer::ConstructRenderList();
+ DoRWStuffStartOfFrame(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
+ CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
+ 255);
- strcpy(gString, "RE3");
- AsciiToUnicode(gString, gUString);
- CFont::PrintString(SCREEN_SCALE_X(10.5f), SCREEN_SCALE_Y(8.0f), gUString);
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ DefinedState();
+ CVisibilityPlugins::InitAlphaEntityList();
+ CAnimViewer::Render();
+ Render2dStuff();
+ DoRWStuffEndOfFrame();
+#endif
}
+#endif
-void
-ValidateVersion()
+void TheGame(void)
{
- int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
- char buff[128];
+ printf("Into TheGame!!!\n");
- if ( file != -1 )
+#ifdef GTA_PS2
+ gMainHeap.PushMemId(_TODOCONST(1));
+#endif
+
+ CTimer::Initialise();
+
+#ifdef GTA_PS2
+ CGame::Initialise();
+#else
+ CGame::Initialise("DATA\\GTA3.DAT");
+#endif
+
+ char *splash = GetRandomSplashScreen(); // inlined here
+
+ LoadingScreen("Starting Game", NULL, splash);
+
+#ifdef GTA_PS2
+ if ( TheMemoryCard.CheckCardInserted(_TODOCONST(0)) == _TODOCONST(26)
+ && TheMemoryCard.ChangeDirectory(_TODOCONST(0), TheMemoryCard.field154)
+ && TheMemoryCard.FindMostRecentFileName(_TODOCONST(0), TheMemoryCard.field37) == 1
+ && TheMemoryCard.CheckDataNotCorrupt(TheMemoryCard.field37))
{
- CFileMgr::Seek(file, 100, SEEK_SET);
-
- for ( int i = 0; i < 128; i++ )
+ strcpy(TheMemoryCard.LoadFileName, TheMemoryCard.field37);
+ TheMemoryCard.b_FoundRecentSavedGameWantToLoad = true;
+
+ if (CMenuManager::m_PrefsLanguage != TheMemoryCard.GetLanguageToLoad())
{
- CFileMgr::Read(file, &buff[i], sizeof(char));
- buff[i] -= 23;
- if ( buff[i] == '\0' )
+ CMenuManager::m_PrefsLanguage = TheMemoryCard.GetLanguageToLoad();
+ TheText.Unload();
+ TheText.Load();
+ }
+
+ CGame::currLevel = TheMemoryCard.GetLevelToLoad();
+ }
+#else
+ //TODO
+#endif
+
+ while (true)
+ {
+#ifdef PS2
+ if (TheMemoryCard.m_bWantToLoad)
+#else
+ if (FrontEndMenuManager.m_bWantToLoad)
+#endif
+ {
+ char *splash1 = GetLevelSplashScreen(CGame::currLevel);
+ LoadSplash(splash1);
+ }
+
+#ifdef PS2
+ TheMemoryCard.m_bWantToLoad = false;
+#else
+ FrontEndMenuManager.m_bWantToLoad = false;
+#endif
+
+ CTimer::Update();
+
+#ifdef PS2
+ while (!(FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad))
+#else
+ while (!(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad))
+#endif
+ {
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+
+#ifdef GTA_PS2
+ gMainHeap.PushMemId(_TODOCONST(12));
+#endif
+ CPointLights::NumLights = 0;
+ CGame::Process();
+#ifdef GTA_PS2
+ gMainHeap.PopMemId();
+#endif
+
+ DMAudio.Service();
+
+ if (CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing())
+ {
+#ifdef PS2
+ TheMemoryCard.m_bWantToLoad = false;
+#else
+ FrontEndMenuManager.m_bWantToLoad = false;
+#endif
+ FrontEndMenuManager.m_bWantToRestart = true;
break;
- CFileMgr::Seek(file, 99, SEEK_CUR);
+ }
+
+#ifdef PS2
+ if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
+#else
+ if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
+#endif
+ break;
+
+ SetLightsWithTimeOfDayColour(Scene.world);
+#ifdef GTA_PS2
+ gMainHeap.PushMemId(_TODOCONST(15));
+#endif
+
+ if (!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true && TheCamera.GetScreenFadeStatus() != FADE_2 )
+ {
+#ifdef GTA_PS2
+ gMainHeap.PushMemId(_TODOCONST(11));
+#endif
+ CRenderer::ConstructRenderList();
+ CRenderer::PreRender();
+#ifdef GTA_PS2
+ gMainHeap.PopMemId();
+#endif
+
+ if (CWeather::LightningFlash && !CCullZones::CamNoRain())
+ DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255);
+ else
+ DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255);
+
+ DefinedState();
+ RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
+ RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
+
+ RenderScene();
+ RenderDebugShit();
+ RenderEffects();
+
+ if ((TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_NORMAL) && TheCamera.m_ScreenReductionPercentage > 0.0f)
+ TheCamera.SetMotionBlurAlpha(150);
+ TheCamera.RenderMotionBlur();
+
+ Render2dStuff();
+ }
+ else
+ {
+ CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
+ CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
+ RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ if (!RsCameraBeginUpdate(Scene.camera))
+ break;
+ }
+
+ RenderMenus();
+
+#ifdef PS2
+ if (TheMemoryCard.m_bWantToLoad)
+#else
+ if (FrontEndMenuManager.m_bWantToLoad)
+#endif
+ {
+#ifdef GTA_PS2
+ gMainHeap.PopMemId();
+#endif
+ break;
+ }
+
+ DoFade();
+ Render2dStuffAfterFade();
+ CCredits::Render();
+
+ DoRWStuffEndOfFrame();
+
+ while (frameCount < 2)
+ ;
+
+ frameCount = 0;
+
+ CTimer::Update();
+
+#ifdef GTA_PS2
+ gMainHeap.PopMemId();
+#endif
+
+ if (g_SlowMode)
+ ProcessSlowMode();
}
-
- if ( !strncmp(buff, "grandtheftauto3", 15) )
+
+ CPad::ResetCheats();
+ CPad::StopPadsShaking();
+ DMAudio.ChangeMusicMode(MUSICMODE_DISABLE);
+ CGame::ShutDownForRestart();
+ CTimer::Stop();
+
+#ifdef PS2
+ if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
+#else
+ if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
+#endif
{
- strncpy(version_name, &buff[15], 64);
- CFileMgr::CloseFile(file);
- return;
+#ifdef PS2
+ if (TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
+#else
+ if (b_FoundRecentSavedGameWantToLoad)
+#endif
+ {
+ FrontEndMenuManager.m_bWantToRestart = true;
+#ifdef PS2
+ TheMemoryCard.m_bWantToLoad = true;
+#else
+ FrontEndMenuManager.m_bWantToLoad = true;
+#endif
+ }
+
+ CGame::InitialiseWhenRestarting();
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ FrontEndMenuManager.m_bWantToRestart = false;
+
+ continue;
}
+
+ break;
}
- LoadingScreen("Invalid version", NULL, NULL);
+ DMAudio.Terminate();
+}
+
+
+void SystemInit()
+{
+#ifdef __MWERKS__
+ mwInit();
+#endif
- while(true)
- {
+#ifdef GTA_PS2
+ InitMemoryMgr();
+#endif
+
+#ifdef GTA_PS2
+ CFileMgr::InitCdSystem();
+
+ char path[256];
+
+ sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP23.IMG");
+
+ sceSifInitRpc(0);
+
+ while ( !sceSifRebootIop(path) )
;
+ while( !sceSifSyncIop() )
+ ;
+
+ sceSifInitRpc(0);
+
+ CFileMgr::InitCdSystem();
+
+ sceFsReset();
+#endif
+
+ CFileMgr::Initialise();
+
+#ifdef GTA_PS2
+ CFileMgr::InitCd();
+
+ Char modulepath[256];
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "SIO2MAN.IRX");
+ LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "PADMAN.IRX");
+ LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "LIBSD.IRX");
+ LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "SDRDRV.IRX");
+ LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "MCMAN.IRX");
+ LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "MCSERV.IRX");
+ LoadModule(modulepath);
+#endif
+
+
+#ifdef GTA_PS2
+ ThreadParam param;
+
+ param.entry = &IdleThread;
+ param.stack = idleThreadStack;
+ param.stackSize = 2048;
+ param.initPriority = 127;
+ param.gpReg = &_gp;
+
+ int thread = CreateThread(&param);
+ StartThread(thread, NULL);
+#else
+ //
+#endif
+
+
+ CPad::Initialise();
+ CPad::GetPad(0)->Mode = 0;
+
+ CGame::frenchGame = false;
+ CGame::germanGame = false;
+ CGame::nastyGame = true;
+ CMenuManager::m_PrefsAllowNastyGame = true;
+
+#ifdef GTA_PS2
+ int32 lang = sceScfGetLanguage();
+ if ( lang == SCE_ITALIAN_LANGUAGE )
+ CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN;
+ else if ( lang == SCE_SPANISH_LANGUAGE )
+ CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH;
+ else if ( lang == SCE_GERMAN_LANGUAGE )
+ {
+ CGame::germanGame = true;
+ CGame::nastyGame = false;
+ CMenuManager::m_PrefsAllowNastyGame = false;
+ CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN;
}
+ else if ( lang == SCE_FRENCH_LANGUAGE )
+ {
+ CGame::frenchGame = true;
+ CGame::nastyGame = false;
+ CMenuManager::m_PrefsAllowNastyGame = false;
+ CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH;
+ }
+ else
+ CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN;
+
+ FrontEndMenuManager.InitialiseMenuContentsAfterLoadingGame();
+#else
+ //
+#endif
+
+#ifdef PS2
+ TheMemoryCard.Init();
+#endif
+}
+
+void GameInit()
+{
+ if ( !gameAlreadyInitialised )
+ {
+#ifdef GTA_PS2
+ char path[256];
+
+ strcpy(path, "cdrom0:\\");
+ strcat(path, "SYSTEM\\");
+ strcat(path, "CDSTREAM.IRX");
+ LoadModule(path);
+
+ strcpy(path, "cdrom0:\\");
+ strcat(path, "SYSTEM\\");
+ strcat(path, "SAMPMAN.IRX");
+ LoadModule(path);
+
+ strcpy(path, "cdrom0:\\");
+ strcat(path, "SYSTEM\\");
+ strcat(path, "MUSICSTR.IRX");
+ LoadModule(path);
+#endif
+ CdStreamInit(MAX_CDCHANNELS);
+
+#ifdef PS2
+ Initialise3D(); //no params
+#else
+ //TODO
+#endif
+
+#ifdef GTA_PS2
+ char *files[] =
+ {
+ "\\ANIM\\CUTS.IMG;1",
+ "\\ANIM\\CUTS.DIR;1",
+ "\\ANIM\\PED.IFP;1",
+ "\\MODELS\\FRONTEND.TXD;1",
+ "\\MODELS\\FONTS.TXD;1",
+ "\\MODELS\\HUD.TXD;1",
+ "\\MODELS\\PARTICLE.TXD;1",
+ "\\MODELS\\MISC.TXD;1",
+ "\\MODELS\\GENERIC.TXD;1",
+ "\\MODELS\\GTA3.DIR;1",
+ "\\TEXT\\ENGLISH.GXT;1",
+ "\\TEXT\\FRENCH.GXT;1",
+ "\\TEXT\\GERMAN.GXT;1",
+ "\\TEXT\\ITALIAN.GXT;1",
+ "\\TEXT\\SPANISH.GXT;1",
+ "\\TXD\\LOADSC0.TXD;1",
+ "\\TXD\\LOADSC1.TXD;1",
+ "\\TXD\\LOADSC2.TXD;1",
+ "\\TXD\\LOADSC3.TXD;1",
+ "\\TXD\\LOADSC4.TXD;1",
+ "\\TXD\\LOADSC5.TXD;1",
+ "\\TXD\\LOADSC6.TXD;1",
+ "\\TXD\\LOADSC7.TXD;1",
+ "\\TXD\\LOADSC8.TXD;1",
+ "\\TXD\\LOADSC9.TXD;1",
+ "\\TXD\\LOADSC10.TXD;1",
+ "\\TXD\\LOADSC11.TXD;1",
+ "\\TXD\\LOADSC12.TXD;1",
+ "\\TXD\\LOADSC13.TXD;1",
+ "\\TXD\\LOADSC14.TXD;1",
+ "\\TXD\\LOADSC15.TXD;1",
+ "\\TXD\\LOADSC16.TXD;1",
+ "\\TXD\\LOADSC17.TXD;1",
+ "\\TXD\\LOADSC18.TXD;1",
+ "\\TXD\\LOADSC19.TXD;1",
+ "\\TXD\\LOADSC20.TXD;1",
+ "\\TXD\\LOADSC21.TXD;1",
+ "\\TXD\\LOADSC22.TXD;1",
+ "\\TXD\\LOADSC23.TXD;1",
+ "\\TXD\\LOADSC24.TXD;1",
+ "\\TXD\\LOADSC25.TXD;1",
+ "\\TXD\\NEWS.TXD;1",
+ "\\MODELS\\COLL\\GENERIC.COL;1",
+ "\\MODELS\\COLL\\INDUST.COL;1",
+ "\\MODELS\\COLL\\COMMER.COL;1",
+ "\\MODELS\\COLL\\SUBURB.COL;1",
+ "\\MODELS\\COLL\\WEAPONS.COL;1",
+ "\\MODELS\\COLL\\VEHICLES.COL;1",
+ "\\MODELS\\COLL\\PEDS.COL;1",
+ "\\MODELS\\GENERIC\\AIR_VLO.DFF;1",
+ "\\MODELS\\GENERIC\\WEAPONS.DFF;1",
+ "\\MODELS\\GENERIC\\WHEELS.DFF;1",
+ "\\MODELS\\GENERIC\\LOPLYGUY.DFF;1",
+ "\\MODELS\\GENERIC\\ARROW.DFF;1",
+ "\\MODELS\\GENERIC\\ZONECYLB.DFF;1",
+ "\\DATA\\MAPS\\COMNTOP.IPL;1",
+ "\\DATA\\MAPS\\COMNBTM.IPL;1",
+ "\\DATA\\MAPS\\COMSE.IPL;1",
+ "\\DATA\\MAPS\\COMSW.IPL;1",
+ "\\DATA\\MAPS\\CULL.IPL;1",
+ "\\DATA\\MAPS\\INDUSTNE.IPL;1",
+ "\\DATA\\MAPS\\INDUSTNW.IPL;1",
+ "\\DATA\\MAPS\\INDUSTSE.IPL;1",
+ "\\DATA\\MAPS\\INDUSTSW.IPL;1",
+ "\\DATA\\MAPS\\SUBURBNE.IPL;1",
+ "\\DATA\\MAPS\\SUBURBSW.IPL;1",
+ "\\DATA\\MAPS\\OVERVIEW.IPL;1",
+ "\\DATA\\MAPS\\PROPS.IPL;1",
+ "\\DATA\\MAPS\\GTA3.IDE;1",
+ "\\DATA\\PATHS\\FLIGHT.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT2.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT3.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT4.DAT;1",
+ "\\DATA\\PATHS\\TRACKS.DAT;1",
+ "\\DATA\\PATHS\\TRACKS2.DAT;1",
+ "\\DATA\\PATHS\\CHASE0.DAT;1",
+ "\\DATA\\PATHS\\CHASE1.DAT;1",
+ "\\DATA\\PATHS\\CHASE2.DAT;1",
+ "\\DATA\\PATHS\\CHASE3.DAT;1",
+ "\\DATA\\PATHS\\CHASE4.DAT;1",
+ "\\DATA\\PATHS\\CHASE5.DAT;1",
+ "\\DATA\\PATHS\\CHASE6.DAT;1",
+ "\\DATA\\PATHS\\CHASE7.DAT;1",
+ "\\DATA\\PATHS\\CHASE10.DAT;1",
+ "\\DATA\\PATHS\\CHASE11.DAT;1",
+ "\\DATA\\PATHS\\CHASE14.DAT;1",
+ "\\DATA\\PATHS\\CHASE16.DAT;1",
+ "\\DATA\\PATHS\\CHASE18.DAT;1",
+ "\\DATA\\PATHS\\CHASE19.DAT;1"
+ };
+
+ for ( int32 i = 0; i < ARRAY_SIZE(files); i++ )
+ SkyRegisterFileOnCd([i]);
+#endif
+
+ CreateDebugFont();
+
+#ifdef GTA_PS2
+ AddIntcHandler(_TODOCONST(2), VBlankCounter, 0);
+#endif
+
+ CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
+
+ CSprite2d::SetRecipNearClip();
+ CTxdStore::Initialise();
+#ifdef GTA_PS2
+ gMainHeap.PushMemId(_TODOCONST(9));
+#endif
+ CFont::Initialise();
+ CHud::Initialise();
+#ifdef GTA_PS2
+ gMainHeap.PopMemId();
+#endif
+
+ ValidateVersion();
+
+#ifdef GTA_PS2
+ sceCdCLOCK rtc;
+ sceCdReadClock(&rtc);
+ uint32 seed = rtc.minute + rtc.day;
+ uint32 seed2 = (seed << 4)-seed;
+ uint32 seed3 = (seed2 << 4)-seed2;
+ srand ((seed3<<4)+rtc.second);
+#else
+ //TODO: mysrand();
+#endif
+
+ gameAlreadyInitialised = true;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+#ifdef __MWERKS__
+ mwInit(); // metrowerks initialisation
+#endif
+
+ SystemInit();
+
+#ifdef PS2
+ int32 state = TheMemoryCard.CheckCardStateAtGameStartUp(_TODOCONST(0));
+
+ if ( state == _TODOCONST(2) || state == _TODOCONST(1) && state != _TODOCONST(3) && state != _TODOCONST(0) )
+ {
+ GameInit();
+
+ TheText.Unload();
+ TheText.Load();
+
+ CFont::Initialise();
+
+ FrontEndMenuManager.DrawMemoryCardStartUpMenus();
+ }
+#endif
+
+#ifdef GTA_PS2
+ {
+ if (gameAlreadyInitialised)
+ RpSkySuspend();
+
+ InitMPEGPlayer();
+
+ PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false);
+
+ if (CGame::frenchGame || CGame::germanGame)
+ PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true);
+ else
+ PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true);
+
+ ShutdownMPEGPlayer();
+
+ if ( gameAlreadyInitialised )
+ RpSkyResume();
+ }
+#else
+ //TODO
+#endif
+
+ GameInit();
+
+ if ( CGame::frenchGame || CGame::germanGame )
+ LoadingScreen(NULL, version_name, "loadsc24");
+ else
+ LoadingScreen(NULL, version_name, "loadsc0");
+
+ DMAudio.Initialise();
+
+ TheGame();
+
+ CGame::ShutDown();
+
+ RwEngineStop();
+ RwEngineClose();
+ RwEngineTerm();
+
+#ifdef __MWERKS__
+ mwExit(); // metrowerks shutdown
+#endif
+
+ return 0;
}
STARTPATCHES
diff --git a/src/core/obrstr.cpp b/src/core/obrstr.cpp
index 3663d134..d9f7e9b4 100644
--- a/src/core/obrstr.cpp
+++ b/src/core/obrstr.cpp
@@ -1,119 +1,119 @@
-#include "common.h"
-#include "Debug.h"
-#include "obrstr.h"
-
-char obrstr[128];
-char obrstr2[128];
-
-void ObrInt(int32 n1)
-{
- IntToStr(n1, obrstr);
- CDebug::DebugAddText(obrstr);
-}
-
-void ObrInt2(int32 n1, int32 n2)
-{
- IntToStr(n1, obrstr);
- strcat(obrstr, " ");
- IntToStr(n2, obrstr2);
- strcat(obrstr, obrstr2);
- CDebug::DebugAddText(obrstr);
-}
-
-void ObrInt3(int32 n1, int32 n2, int32 n3)
-{
- IntToStr(n1, obrstr);
- strcat(obrstr, " ");
- IntToStr(n2, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n3, obrstr2);
- strcat(obrstr, obrstr2);
- CDebug::DebugAddText(obrstr);
-}
-
-void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4)
-{
- IntToStr(n1, obrstr);
- strcat(obrstr, " ");
- IntToStr(n2, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n3, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n4, obrstr2);
- strcat(obrstr, obrstr2);
- CDebug::DebugAddText(obrstr);
-}
-
-void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5)
-{
- IntToStr(n1, obrstr);
- strcat(obrstr, " ");
- IntToStr(n2, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n3, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n4, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n5, obrstr2);
- strcat(obrstr, obrstr2);
- CDebug::DebugAddText(obrstr);
-}
-
-void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
-{
- IntToStr(n1, obrstr);
- strcat(obrstr, " ");
- IntToStr(n2, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n3, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n4, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n5, obrstr2);
- strcat(obrstr, obrstr2);
- strcat(obrstr, " ");
- IntToStr(n6, obrstr2);
- strcat(obrstr, obrstr2);
- CDebug::DebugAddText(obrstr);
-}
-
-void IntToStr(int32 inNum, char *outStr)
-{
- bool isNeg = inNum < 0;
-
- if (isNeg) {
- inNum = -inNum;
- *outStr = '-';
- }
-
- int16 digits = 1;
-
- if (inNum > 9) {
- int32 _inNum = inNum;
- do {
- digits++;
- _inNum /= 10;
- } while (_inNum > 9);
- }
-
- int32 strSize = digits;
- if (isNeg)
- strSize++;
-
- char *pStr = &outStr[strSize];
- int32 i = 0;
- do {
- *(pStr-- - 1) = (inNum % 10) + '0';
- inNum /= 10;
- } while (++i < strSize);
- outStr[strSize] = '\0';
+#include "common.h"
+#include "Debug.h"
+#include "obrstr.h"
+
+char obrstr[128];
+char obrstr2[128];
+
+void ObrInt(int32 n1)
+{
+ IntToStr(n1, obrstr);
+ CDebug::DebugAddText(obrstr);
+}
+
+void ObrInt2(int32 n1, int32 n2)
+{
+ IntToStr(n1, obrstr);
+ strcat(obrstr, " ");
+ IntToStr(n2, obrstr2);
+ strcat(obrstr, obrstr2);
+ CDebug::DebugAddText(obrstr);
+}
+
+void ObrInt3(int32 n1, int32 n2, int32 n3)
+{
+ IntToStr(n1, obrstr);
+ strcat(obrstr, " ");
+ IntToStr(n2, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n3, obrstr2);
+ strcat(obrstr, obrstr2);
+ CDebug::DebugAddText(obrstr);
+}
+
+void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4)
+{
+ IntToStr(n1, obrstr);
+ strcat(obrstr, " ");
+ IntToStr(n2, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n3, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n4, obrstr2);
+ strcat(obrstr, obrstr2);
+ CDebug::DebugAddText(obrstr);
+}
+
+void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5)
+{
+ IntToStr(n1, obrstr);
+ strcat(obrstr, " ");
+ IntToStr(n2, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n3, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n4, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n5, obrstr2);
+ strcat(obrstr, obrstr2);
+ CDebug::DebugAddText(obrstr);
+}
+
+void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6)
+{
+ IntToStr(n1, obrstr);
+ strcat(obrstr, " ");
+ IntToStr(n2, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n3, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n4, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n5, obrstr2);
+ strcat(obrstr, obrstr2);
+ strcat(obrstr, " ");
+ IntToStr(n6, obrstr2);
+ strcat(obrstr, obrstr2);
+ CDebug::DebugAddText(obrstr);
+}
+
+void IntToStr(int32 inNum, char *outStr)
+{
+ bool isNeg = inNum < 0;
+
+ if (isNeg) {
+ inNum = -inNum;
+ *outStr = '-';
+ }
+
+ int16 digits = 1;
+
+ if (inNum > 9) {
+ int32 _inNum = inNum;
+ do {
+ digits++;
+ _inNum /= 10;
+ } while (_inNum > 9);
+ }
+
+ int32 strSize = digits;
+ if (isNeg)
+ strSize++;
+
+ char *pStr = &outStr[strSize];
+ int32 i = 0;
+ do {
+ *(pStr-- - 1) = (inNum % 10) + '0';
+ inNum /= 10;
+ } while (++i < strSize);
+ outStr[strSize] = '\0';
} \ No newline at end of file
diff --git a/src/core/obrstr.h b/src/core/obrstr.h
index 6838afb5..c1633614 100644
--- a/src/core/obrstr.h
+++ b/src/core/obrstr.h
@@ -1,9 +1,9 @@
-#pragma once
-
-void ObrInt(int32 n1);
-void ObrInt2(int32 n1, int32 n2);
-void ObrInt3(int32 n1, int32 n2, int32 n3);
-void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4);
-void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5);
-void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
+#pragma once
+
+void ObrInt(int32 n1);
+void ObrInt2(int32 n1, int32 n2);
+void ObrInt3(int32 n1, int32 n2, int32 n3);
+void ObrInt4(int32 n1, int32 n2, int32 n3, int32 n4);
+void ObrInt5(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5);
+void ObrInt6(int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6);
void IntToStr(int32 inNum, char *outStr); \ No newline at end of file
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 6d4ff252..321ff172 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -21,10 +21,15 @@
#include "Particle.h"
#include "Console.h"
#include "Debug.h"
+#include "Hud.h"
#include <list>
+#ifndef RWLIBS
void **rwengine = *(void***)0x5A10E1;
+#else
+extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list _ArgList);
+#endif
DebugMenuAPI gDebugMenuAPI;
@@ -145,19 +150,6 @@ SpawnCar(int id)
}
static void
-LetThemFollowYou(void) {
- CPed *player = (CPed*) FindPlayerPed();
- for (int i = 0; i < player->m_numNearPeds; i++) {
- CPed *nearPed = player->m_nearPeds[i];
- if (nearPed && !nearPed->IsPlayer()) {
- nearPed->SetObjective(OBJECTIVE_FOLLOW_PED_IN_FORMATION, (void*)player);
- nearPed->m_pedFormation = (eFormation)(1 + (rand() & 7));
- nearPed->bScriptObjectiveCompleted = false;
- }
- }
-}
-
-static void
FixCar(void)
{
CVehicle *veh = FindPlayerVehicle();
@@ -337,7 +329,9 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); });
DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); });
DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); });
+ DebugMenuAddCmd("Spawn", "Spawn Predator", [](){ SpawnCar(MI_PREDATOR); });
+ DebugMenuAddVarBool8("Debug", "Draw hud", (int8*)&CHud::m_Wants_To_Draw_Hud, nil);
DebugMenuAddVar("Debug", "Engine Status", &engineStatus, nil, 1, 0, 226, nil);
DebugMenuAddCmd("Debug", "Set Engine Status", SetEngineStatus);
DebugMenuAddCmd("Debug", "Fix Car", FixCar);
@@ -350,6 +344,9 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
DebugMenuAddVarBool8("Debug", "Script Heli On", (int8*)0x95CD43, nil);
+ DebugMenuAddVarBool8("Debug", "Show Ped Paths", (int8*)&gbShowPedPaths, nil);
+ DebugMenuAddVarBool8("Debug", "Show Car Paths", (int8*)&gbShowCarPaths, nil);
+ DebugMenuAddVarBool8("Debug", "Show Car Path Links", (int8*)&gbShowCarPathsLinks, nil);
DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil);
DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil);
DebugMenuAddVarBool8("Debug", "Show Collision Lines", (int8*)&gbShowCollisionLines, nil);
@@ -359,8 +356,6 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Don't render Peds", (int8*)&gbDontRenderPeds, nil);
DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil);
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
-
- DebugMenuAddCmd("Debug", "Make peds follow you in formation", LetThemFollowYou);
#ifdef TOGGLEABLE_BETA_FEATURES
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
@@ -458,7 +453,7 @@ void re3_debug(const char *format, ...)
vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va);
-// printf("%s", re3_buff);
+ printf("%s", re3_buff);
CDebug::DebugAddText(re3_buff);
}
diff --git a/src/core/timebars.cpp b/src/core/timebars.cpp
index 30421731..93d85f8d 100644
--- a/src/core/timebars.cpp
+++ b/src/core/timebars.cpp
@@ -1,121 +1,121 @@
-#ifndef MASTER
-#include "common.h"
-#include "Font.h"
-#include "Frontend.h"
-#include "Timer.h"
-#include "Text.h"
-
-#define MAX_TIMERS (50)
-#define MAX_MS_COLLECTED (40)
-
-// enables frame time output
-#define FRAMETIME
-
-struct sTimeBar
-{
- char name[20];
- float startTime;
- float endTime;
- int32 unk;
-};
-
-struct
-{
- sTimeBar Timers[MAX_TIMERS];
- uint32 count;
-} TimerBar;
-float MaxTimes[MAX_TIMERS];
-float MaxFrameTime;
-
-uint32 curMS;
-uint32 msCollected[MAX_MS_COLLECTED];
-#ifdef FRAMETIME
-float FrameInitTime;
-#endif
-
-void tbInit()
-{
- TimerBar.count = 0;
- uint32 i = CTimer::GetFrameCounter() & 0x7F;
- if (i == 0) {
- do
- MaxTimes[i++] = 0.0f;
- while (i != MAX_TIMERS);
-#ifdef FRAMETIME
- MaxFrameTime = 0.0f;
-#endif
- }
-#ifdef FRAMETIME
- FrameInitTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
-#endif
-}
-
-void tbStartTimer(int32 unk, char *name)
-{
- strcpy(TimerBar.Timers[TimerBar.count].name, name);
- TimerBar.Timers[TimerBar.count].unk = unk;
- TimerBar.Timers[TimerBar.count].startTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
- TimerBar.count++;
-}
-
-void tbEndTimer(char* name)
-{
- uint32 n = 1500;
- for (uint32 i = 0; i < TimerBar.count; i++) {
- if (strcmp(name, TimerBar.Timers[i].name) == 0)
- n = i;
- }
- assert(n != 1500);
- TimerBar.Timers[n].endTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
-}
-
-float Diag_GetFPS()
-{
- return 39000.0f / (msCollected[(curMS - 1) % MAX_MS_COLLECTED] - msCollected[curMS % MAX_MS_COLLECTED]);
-}
-
-void tbDisplay()
-{
- char temp[200];
- wchar wtemp[200];
-
-#ifdef FRAMETIME
- float FrameEndTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
-#endif
-
- msCollected[(curMS++) % MAX_MS_COLLECTED] = RsTimer();
- CFont::SetBackgroundOff();
- CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
- CFont::SetScale(0.48f, 1.12f);
- CFont::SetCentreOff();
- CFont::SetJustifyOff();
- CFont::SetWrapx(640.0f);
- CFont::SetRightJustifyOff();
- CFont::SetPropOn();
- CFont::SetFontStyle(FONT_BANK);
- sprintf(temp, "FPS: %.2f", Diag_GetFPS());
- AsciiToUnicode(temp, wtemp);
- CFont::SetColor(CRGBA(255, 255, 255, 255));
- if (!CMenuManager::m_PrefsMarketing || !CMenuManager::m_PrefsDisableTutorials) {
- CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * (4.0f / DEFAULT_SCREEN_HEIGHT), wtemp);
-
-#ifndef FINAL
- // Timers output (my own implementation)
- for (uint32 i = 0; i < TimerBar.count; i++) {
- MaxTimes[i] = max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
- sprintf(temp, "%s: %.2f", &TimerBar.Timers[i].name[0], MaxTimes[i]);
- AsciiToUnicode(temp, wtemp);
- CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (i + 2)) / DEFAULT_SCREEN_HEIGHT), wtemp);
- }
-
-#ifdef FRAMETIME
- MaxFrameTime = max(MaxFrameTime, FrameEndTime - FrameInitTime);
- sprintf(temp, "Frame Time: %.2f", MaxFrameTime);
- AsciiToUnicode(temp, wtemp);
-
- CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (TimerBar.count + 4)) / DEFAULT_SCREEN_HEIGHT), wtemp);
-#endif // FRAMETIME
-#endif // !FINAL
- }
-}
+#ifndef MASTER
+#include "common.h"
+#include "Font.h"
+#include "Frontend.h"
+#include "Timer.h"
+#include "Text.h"
+
+#define MAX_TIMERS (50)
+#define MAX_MS_COLLECTED (40)
+
+// enables frame time output
+#define FRAMETIME
+
+struct sTimeBar
+{
+ char name[20];
+ float startTime;
+ float endTime;
+ int32 unk;
+};
+
+struct
+{
+ sTimeBar Timers[MAX_TIMERS];
+ uint32 count;
+} TimerBar;
+float MaxTimes[MAX_TIMERS];
+float MaxFrameTime;
+
+uint32 curMS;
+uint32 msCollected[MAX_MS_COLLECTED];
+#ifdef FRAMETIME
+float FrameInitTime;
+#endif
+
+void tbInit()
+{
+ TimerBar.count = 0;
+ uint32 i = CTimer::GetFrameCounter() & 0x7F;
+ if (i == 0) {
+ do
+ MaxTimes[i++] = 0.0f;
+ while (i != MAX_TIMERS);
+#ifdef FRAMETIME
+ MaxFrameTime = 0.0f;
+#endif
+ }
+#ifdef FRAMETIME
+ FrameInitTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
+#endif
+}
+
+void tbStartTimer(int32 unk, char *name)
+{
+ strcpy(TimerBar.Timers[TimerBar.count].name, name);
+ TimerBar.Timers[TimerBar.count].unk = unk;
+ TimerBar.Timers[TimerBar.count].startTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
+ TimerBar.count++;
+}
+
+void tbEndTimer(char* name)
+{
+ uint32 n = 1500;
+ for (uint32 i = 0; i < TimerBar.count; i++) {
+ if (strcmp(name, TimerBar.Timers[i].name) == 0)
+ n = i;
+ }
+ assert(n != 1500);
+ TimerBar.Timers[n].endTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
+}
+
+float Diag_GetFPS()
+{
+ return 39000.0f / (msCollected[(curMS - 1) % MAX_MS_COLLECTED] - msCollected[curMS % MAX_MS_COLLECTED]);
+}
+
+void tbDisplay()
+{
+ char temp[200];
+ wchar wtemp[200];
+
+#ifdef FRAMETIME
+ float FrameEndTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerFrame();
+#endif
+
+ msCollected[(curMS++) % MAX_MS_COLLECTED] = RsTimer();
+ CFont::SetBackgroundOff();
+ CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
+ CFont::SetScale(0.48f, 1.12f);
+ CFont::SetCentreOff();
+ CFont::SetJustifyOff();
+ CFont::SetWrapx(640.0f);
+ CFont::SetRightJustifyOff();
+ CFont::SetPropOn();
+ CFont::SetFontStyle(FONT_BANK);
+ sprintf(temp, "FPS: %.2f", Diag_GetFPS());
+ AsciiToUnicode(temp, wtemp);
+ CFont::SetColor(CRGBA(255, 255, 255, 255));
+ if (!CMenuManager::m_PrefsMarketing || !CMenuManager::m_PrefsDisableTutorials) {
+ CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * (4.0f / DEFAULT_SCREEN_HEIGHT), wtemp);
+
+#ifndef FINAL
+ // Timers output (my own implementation)
+ for (uint32 i = 0; i < TimerBar.count; i++) {
+ MaxTimes[i] = max(MaxTimes[i], TimerBar.Timers[i].endTime - TimerBar.Timers[i].startTime);
+ sprintf(temp, "%s: %.2f", &TimerBar.Timers[i].name[0], MaxTimes[i]);
+ AsciiToUnicode(temp, wtemp);
+ CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (i + 2)) / DEFAULT_SCREEN_HEIGHT), wtemp);
+ }
+
+#ifdef FRAMETIME
+ MaxFrameTime = max(MaxFrameTime, FrameEndTime - FrameInitTime);
+ sprintf(temp, "Frame Time: %.2f", MaxFrameTime);
+ AsciiToUnicode(temp, wtemp);
+
+ CFont::PrintString(RsGlobal.maximumWidth * (4.0f / DEFAULT_SCREEN_WIDTH), RsGlobal.maximumHeight * ((8.0f * (TimerBar.count + 4)) / DEFAULT_SCREEN_HEIGHT), wtemp);
+#endif // FRAMETIME
+#endif // !FINAL
+ }
+}
#endif // !MASTER \ No newline at end of file
diff --git a/src/core/timebars.h b/src/core/timebars.h
index 8ffccd8e..6d3b853e 100644
--- a/src/core/timebars.h
+++ b/src/core/timebars.h
@@ -1,6 +1,6 @@
-#pragma once
-
-void tbInit();
-void tbStartTimer(int32, char*);
-void tbEndTimer(char*);
+#pragma once
+
+void tbInit();
+void tbStartTimer(int32, char*);
+void tbEndTimer(char*);
void tbDisplay(); \ No newline at end of file
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 8bec1ac8..25e5db48 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -62,11 +62,11 @@ CEntity::CEntity(void)
bRemoveFromWorld = false;
bHasHitWall = false;
bImBeingRendered = false;
- m_flagD8 = false;
+ bTouchingWater = false;
bIsSubway = false;
bDrawLast = false;
bNoBrightHeadLights = false;
- m_flagD80 = false;
+ bDoNotRender = false;
bDistanceFade = false;
m_flagE2 = false;
@@ -275,9 +275,9 @@ CEntity::CreateRwObject(void)
if(IsBuilding())
gBuildings++;
if(RwObjectGetType(m_rwObject) == rpATOMIC)
- m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false);
+ m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
- m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false);
+ m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
mi->AddRef();
}
}
@@ -290,7 +290,7 @@ CEntity::DeleteRwObject(void)
m_matrix.Detach();
if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC){
- f = RpAtomicGetFrame(m_rwObject);
+ f = RpAtomicGetFrame((RpAtomic*)m_rwObject);
RpAtomicDestroy((RpAtomic*)m_rwObject);
RwFrameDestroy(f);
}else if(RwObjectGetType(m_rwObject) == rpCLUMP)
@@ -307,9 +307,9 @@ CEntity::UpdateRwFrame(void)
{
if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC)
- RwFrameUpdateObjects(RpAtomicGetFrame(m_rwObject));
+ RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
- RwFrameUpdateObjects(RpClumpGetFrame(m_rwObject));
+ RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
}
}
@@ -394,13 +394,13 @@ CEntity::PreRender(void)
}else if(GetModelIndex() == MI_GRENADE){
CMotionBlurStreaks::RegisterStreak((uintptr)this,
100, 100, 100,
- TheCamera.GetPosition() - 0.07f*TheCamera.GetRight(),
- TheCamera.GetPosition() + 0.07f*TheCamera.GetRight());
+ GetPosition() - 0.07f*TheCamera.GetRight(),
+ GetPosition() + 0.07f*TheCamera.GetRight());
}else if(GetModelIndex() == MI_MOLOTOV){
CMotionBlurStreaks::RegisterStreak((uintptr)this,
0, 100, 0,
- TheCamera.GetPosition() - 0.07f*TheCamera.GetRight(),
- TheCamera.GetPosition() + 0.07f*TheCamera.GetRight());
+ GetPosition() - 0.07f*TheCamera.GetRight(),
+ GetPosition() + 0.07f*TheCamera.GetRight());
}
}else if(GetModelIndex() == MI_MISSILE){
CVector pos = GetPosition();
@@ -482,9 +482,9 @@ CEntity::AttachToRwObject(RwObject *obj)
m_rwObject = obj;
if(m_rwObject){
if(RwObjectGetType(m_rwObject) == rpATOMIC)
- m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame(m_rwObject)), false);
+ m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
else if(RwObjectGetType(m_rwObject) == rpCLUMP)
- m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame(m_rwObject)), false);
+ m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
}
}
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index 99cc7f17..ca501ba4 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -73,11 +73,11 @@ public:
uint32 bRemoveFromWorld : 1;
uint32 bHasHitWall : 1;
uint32 bImBeingRendered : 1;
- uint32 m_flagD8 : 1; // used by cBuoyancy::ProcessBuoyancy
+ uint32 bTouchingWater : 1; // used by cBuoyancy::ProcessBuoyancy
uint32 bIsSubway : 1; // set when subway, but maybe different meaning?
uint32 bDrawLast : 1;
uint32 bNoBrightHeadLights : 1;
- uint32 m_flagD80 : 1; // CObject visibility?
+ uint32 bDoNotRender : 1;
// flagsE
uint32 bDistanceFade : 1;
@@ -90,6 +90,7 @@ public:
CReference *m_pFirstReference;
CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); }
+ uint32* GetAddressOfEntityProperties() { /* AWFUL */ return (uint32*)((char*)&m_rwObject + sizeof(m_rwObject)); }
CEntity(void);
~CEntity(void);
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index faa8a484..9fc77a8c 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -21,7 +21,7 @@ CPhysical::CPhysical(void)
{
int i;
- fForceMultiplier = 1.0f;
+ m_fForceMultiplier = 1.0f;
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
diff --git a/src/entities/Physical.h b/src/entities/Physical.h
index 1b9f0e02..6fbc3ffd 100644
--- a/src/entities/Physical.h
+++ b/src/entities/Physical.h
@@ -29,7 +29,7 @@ public:
CVector m_vecTurnSpeedAvg;
float m_fMass;
float m_fTurnMass; // moment of inertia
- float fForceMultiplier;
+ float m_fForceMultiplier;
float m_fAirResistance;
float m_fElasticity;
float m_fBuoyancy;
diff --git a/src/entities/Solid.h b/src/entities/Solid.h
index e67c8e29..4ca800c2 100644
--- a/src/entities/Solid.h
+++ b/src/entities/Solid.h
@@ -1,12 +1,12 @@
-#pragma once
-
-#include "Entity.h"
-
-class CSolid : public CEntity
-{
-public:
- CSolid(void) {
- m_type = ENTITY_TYPE_BUILDING;
- bUsesCollision = true;
- }
+#pragma once
+
+#include "Entity.h"
+
+class CSolid : public CEntity
+{
+public:
+ CSolid(void) {
+ m_type = ENTITY_TYPE_BUILDING;
+ bUsesCollision = true;
+ }
}; \ No newline at end of file
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index da38cb1d..35972e7f 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -243,6 +243,17 @@ public:
m_matrix.pos.y = 0.0f;
m_matrix.pos.z = 0.0f;
}
+ void ResetOrientation(void) {
+ m_matrix.right.x = 1.0f;
+ m_matrix.right.y = 0.0f;
+ m_matrix.right.z = 0.0f;
+ m_matrix.up.x = 0.0f;
+ m_matrix.up.y = 1.0f;
+ m_matrix.up.z = 0.0f;
+ m_matrix.at.x = 0.0f;
+ m_matrix.at.y = 0.0f;
+ m_matrix.at.z = 1.0f;
+ }
};
diff --git a/src/math/Vector.h b/src/math/Vector.h
index 6f544ada..1274a4b2 100644
--- a/src/math/Vector.h
+++ b/src/math/Vector.h
@@ -83,7 +83,7 @@ public:
return x == right.x && y == right.y && z == right.z;
}
- bool IsZero(void) { return x == 0.0f && y == 0.0f && z == 0.0f; }
+ bool IsZero(void) const { return x == 0.0f && y == 0.0f && z == 0.0f; }
};
inline CVector operator+(const CVector &left, const CVector &right)
diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h
index a9bafb64..0c4bf934 100644
--- a/src/modelinfo/BaseModelInfo.h
+++ b/src/modelinfo/BaseModelInfo.h
@@ -2,6 +2,8 @@
#include "Collision.h"
+#define MAX_MODEL_NAME (24)
+
enum ModeInfoType : uint8
{
MITYPE_NA = 0,
@@ -21,7 +23,7 @@ class CBaseModelInfo
{
protected:
// TODO?: make more things protected
- char m_name[24];
+ char m_name[MAX_MODEL_NAME];
CColModel *m_colModel;
C2dEffect *m_twodEffects;
int16 m_objectId;
diff --git a/src/modelinfo/MloModelInfo.h b/src/modelinfo/MloModelInfo.h
index 19ae63d5..d4344706 100644
--- a/src/modelinfo/MloModelInfo.h
+++ b/src/modelinfo/MloModelInfo.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include "ClumpModelInfo.h"
-
-class CMloModelInfo : public CClumpModelInfo
-{
-public:
- float field_34; // draw distance?
- int firstInstance;
- int lastInstance;
-public:
- CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {}
- void ConstructClump();
+#pragma once
+
+#include "ClumpModelInfo.h"
+
+class CMloModelInfo : public CClumpModelInfo
+{
+public:
+ float field_34; // draw distance?
+ int firstInstance;
+ int lastInstance;
+public:
+ CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {}
+ void ConstructClump();
}; \ No newline at end of file
diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp
index d956abaa..b6a95992 100644
--- a/src/modelinfo/ModelInfo.cpp
+++ b/src/modelinfo/ModelInfo.cpp
@@ -234,12 +234,6 @@ CModelInfo::RemoveColModelsFromOtherLevels(eLevelName level)
}
}
-CStore<CInstance, MLOINSTANCESIZE>&
-CModelInfo::GetMloInstanceStore()
-{
- return CModelInfo::ms_mloInstanceStore;
-}
-
void
CModelInfo::ConstructMloClumps()
{
@@ -247,6 +241,17 @@ CModelInfo::ConstructMloClumps()
ms_mloModelStore.store[i].ConstructClump();
}
+void
+CModelInfo::ReInit2dEffects()
+{
+ ms_2dEffectStore.clear();
+
+ for (int i = 0; i < MODELINFOSIZE; i++) {
+ if (ms_modelInfoPtrs[i])
+ ms_modelInfoPtrs[i]->Init2dEffects();
+ }
+}
+
STARTPATCHES
InjectHook(0x50B310, CModelInfo::Initialise, PATCH_JUMP);
InjectHook(0x50B5B0, CModelInfo::ShutDown, PATCH_JUMP);
diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h
index 13756ddf..e6dec1d8 100644
--- a/src/modelinfo/ModelInfo.h
+++ b/src/modelinfo/ModelInfo.h
@@ -36,7 +36,7 @@ public:
static CVehicleModelInfo *AddVehicleModel(int id);
static CStore<C2dEffect, TWODFXSIZE> &Get2dEffectStore(void) { return ms_2dEffectStore; }
- static CStore<CInstance, MLOINSTANCESIZE> &GetMloInstanceStore();
+ static CStore<CInstance, MLOINSTANCESIZE> &GetMloInstanceStore(void) { return ms_mloInstanceStore; }
static CBaseModelInfo *GetModelInfo(const char *name, int *id);
static CBaseModelInfo *GetModelInfo(int id){
@@ -47,4 +47,5 @@ public:
static bool IsBikeModel(int32 id);
static void RemoveColModelsFromOtherLevels(eLevelName level);
static void ConstructMloClumps();
+ static void ReInit2dEffects();
};
diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp
index 7b087fbd..015c6949 100644
--- a/src/modelinfo/PedModelInfo.cpp
+++ b/src/modelinfo/PedModelInfo.cpp
@@ -216,7 +216,7 @@ CPedModelInfo::AnimatePedColModel(CColModel* colmodel, RwFrame* frame)
RwMatrixCopy(mat, RwFrameGetMatrix(f));
for (f = RwFrameGetParent(f); f; f = RwFrameGetParent(f)) {
- RwMatrixTransform(mat, &f->modelling, rwCOMBINEPOSTCONCAT);
+ RwMatrixTransform(mat, RwFrameGetMatrix(f), rwCOMBINEPOSTCONCAT);
if (RwFrameGetParent(f) == frame)
break;
}
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp
index 42ad635b..0c45aa12 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -12,6 +12,7 @@
#include "World.h"
#include "Vehicle.h"
#include "Automobile.h"
+#include "Boat.h"
#include "Train.h"
#include "Plane.h"
#include "Heli.h"
@@ -80,9 +81,9 @@ RwObjectNameIdAssocation carIds[] = {
};
RwObjectNameIdAssocation boatIds[] = {
- { "boat_moving_hi", 1, VEHICLE_FLAG_COLLAPSE },
- { "boat_rudder_hi", 3, VEHICLE_FLAG_COLLAPSE },
- { "windscreen", 2, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_COLLAPSE },
+ { "boat_moving_hi", BOAT_MOVING, VEHICLE_FLAG_COLLAPSE },
+ { "boat_rudder_hi", BOAT_RUDDER, VEHICLE_FLAG_COLLAPSE },
+ { "windscreen", BOAT_WINDSCREEN, VEHICLE_FLAG_WINDSCREEN | VEHICLE_FLAG_COLLAPSE },
{ "ped_frontseat", BOAT_POS_FRONTSEAT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID },
{ nil, 0, 0 }
};
@@ -707,7 +708,7 @@ RpMaterial*
CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial *material, void *data)
{
static RwRGBA white = { 255, 255, 255, 255 };
- RwRGBA *col;
+ const RwRGBA *col;
editableMatCBData *cbdata;
cbdata = (editableMatCBData*)data;
@@ -758,8 +759,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
col = ms_vehicleColourTable[c1];
coltex = ms_colourTextureTable[c1];
for(matp = m_materials1; *matp; matp++){
- if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){
- colp = RpMaterialGetColor(*matp);
+ if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
+ colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
colp->green = col.green;
colp->blue = col.blue;
@@ -773,8 +774,8 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
col = ms_vehicleColourTable[c2];
coltex = ms_colourTextureTable[c2];
for(matp = m_materials2; *matp; matp++){
- if(RpMaterialGetTexture(*matp) && RpMaterialGetTexture(*matp)->name[0] != '@'){
- colp = RpMaterialGetColor(*matp);
+ if(RpMaterialGetTexture(*matp) && RwTextureGetName(RpMaterialGetTexture(*matp))[0] != '@'){
+ colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
colp->green = col.green;
colp->blue = col.blue;
@@ -861,7 +862,7 @@ CreateCarColourTexture(uint8 r, uint8 g, uint8 b)
RwImageDestroy(img);
RwFree(pixels);
tex = RwTextureCreate(ras);
- tex->name[0] = '@';
+ RwTextureGetName(tex)[0] = '@';
return tex;
}
@@ -1058,7 +1059,7 @@ CVehicleModelInfo::LoadEnvironmentMaps(void)
}
if(gpWhiteTexture == nil){
gpWhiteTexture = RwTextureRead("white", nil);
- gpWhiteTexture->name[0] = '@';
+ RwTextureGetName(gpWhiteTexture)[0] = '@';
RwTextureSetFilterMode(gpWhiteTexture, rwFILTERLINEAR);
}
CTxdStore::PopCurrentTxd();
diff --git a/src/modelinfo/XtraCompsModelInfo.h b/src/modelinfo/XtraCompsModelInfo.h
index bb37ffe3..9832399c 100644
--- a/src/modelinfo/XtraCompsModelInfo.h
+++ b/src/modelinfo/XtraCompsModelInfo.h
@@ -1,12 +1,12 @@
-#pragma once
-
-#include "ClumpModelInfo.h"
-
-class CXtraCompsModelInfo : public CClumpModelInfo
-{
- int field_34;
-public:
- CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; }
- void SetClump(RpClump*) {};
- void Shutdown(void) {};
+#pragma once
+
+#include "ClumpModelInfo.h"
+
+class CXtraCompsModelInfo : public CClumpModelInfo
+{
+ int field_34;
+public:
+ CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; }
+ void SetClump(RpClump*) {};
+ void Shutdown(void) {};
}; \ No newline at end of file
diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp
index 8c417973..a7722b8a 100644
--- a/src/objects/CutsceneHead.cpp
+++ b/src/objects/CutsceneHead.cpp
@@ -20,7 +20,7 @@ CCutsceneHead::CCutsceneHead(CObject *obj)
m_pHeadNode = RpAnimBlendClumpFindFrame((RpClump*)obj->m_rwObject, "Shead")->frame;
atm = (RpAtomic*)GetFirstObject(m_pHeadNode);
if(atm){
- assert(RwObjectGetType(atm) == rpATOMIC);
+ assert(RwObjectGetType((RwObject*)atm) == rpATOMIC);
RpAtomicSetFlags(atm, RpAtomicGetFlags(atm) & ~rpATOMICRENDER);
}
}
diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp
index aa366aa0..867624c7 100644
--- a/src/objects/Object.cpp
+++ b/src/objects/Object.cpp
@@ -6,12 +6,11 @@
#include "Radar.h"
#include "Object.h"
#include "DummyObject.h"
-
-WRAPPER void CObject::ObjectDamage(float amount) { EAXJMP(0x4BB240); }
-WRAPPER void CObject::DeleteAllTempObjectInArea(CVector, float) { EAXJMP(0x4BBED0); }
-WRAPPER void CObject::Init(void) { EAXJMP(0x4BAEC0); }
-WRAPPER void CObject::ProcessControl(void) { EAXJMP(0x4BB040); }
-WRAPPER void CObject::Teleport(CVector) { EAXJMP(0x4BBDA0); }
+#include "Particle.h"
+#include "General.h"
+#include "ObjectData.h"
+#include "World.h"
+#include "Floater.h"
int16 &CObject::nNoTempObjects = *(int16*)0x95CCA2;
int16 &CObject::nBodyCastHealth = *(int16*)0x5F7D4C; // 1000
@@ -28,13 +27,13 @@ CObject::CObject(void)
m_nCollisionDamageEffect = 0;
m_nSpecialCollisionResponseCases = COLLRESPONSE_NONE;
m_bCameraToAvoidThisObject = false;
- ObjectCreatedBy = 0;
+ ObjectCreatedBy = UNKNOWN_OBJECT;
m_nEndOfLifeTime = 0;
// m_nRefModelIndex = -1; // duplicate
// bUseVehicleColours = false; // duplicate
m_colour2 = 0;
m_colour1 = m_colour2;
- field_172 = 0;
+ m_nBonusValue = 0;
bIsPickup = false;
m_obj_flag2 = false;
bOutOfStock = false;
@@ -82,10 +81,46 @@ CObject::~CObject(void)
nNoTempObjects--;
}
+void
+CObject::ProcessControl(void)
+{
+ CVector point, impulse;
+ if (m_nCollisionDamageEffect)
+ ObjectDamage(m_fDamageImpulse);
+ CPhysical::ProcessControl();
+ if (mod_Buoyancy.ProcessBuoyancy(this, m_fBuoyancy, &point, &impulse)) {
+ bIsInWater = true;
+ bIsStatic = false;
+ ApplyMoveForce(impulse);
+ ApplyTurnForce(impulse, point);
+ float fTimeStep = Pow(0.97f, CTimer::GetTimeStep());
+ m_vecMoveSpeed *= fTimeStep;
+ m_vecTurnSpeed *= fTimeStep;
+ }
+ if ((m_modelIndex == MI_EXPLODINGBARREL || m_modelIndex == MI_PETROLPUMP) && bHasBeenDamaged && bIsVisible
+ && (CGeneral::GetRandomNumber() & 0x1F) == 10) {
+ bExplosionProof = true;
+ bIsVisible = false;
+ bUsesCollision = false;
+ bAffectedByGravity = false;
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ }
+}
+
+void
+CObject::Teleport(CVector vecPos)
+{
+ CWorld::Remove(this);
+ m_matrix.GetPosition() = vecPos;
+ m_matrix.UpdateRW();
+ UpdateRwFrame();
+ CWorld::Add(this);
+}
+
void
CObject::Render(void)
{
- if(m_flagD80)
+ if(bDoNotRender)
return;
if(m_nRefModelIndex != -1 && ObjectCreatedBy == TEMP_OBJECT && bUseVehicleColours){
@@ -117,6 +152,152 @@ CObject::RemoveLighting(bool reset)
WorldReplaceScorchedLightsWithNormal(Scene.world);
}
+void
+CObject::ObjectDamage(float amount)
+{
+ if (!m_nCollisionDamageEffect || !bUsesCollision)
+ return;
+ static int8 nFrameGen = 0;
+ bool bBodyCastDamageEffect = false;
+ if (m_modelIndex == MI_BODYCAST){
+ if (amount > 50.0f)
+ nBodyCastHealth = (int16)(nBodyCastHealth - 0.5f * amount);
+ if (nBodyCastHealth < 0)
+ nBodyCastHealth = 0;
+ if (nBodyCastHealth < 200)
+ bBodyCastDamageEffect = true;
+ amount = 0.0f;
+ }
+ if ((amount * m_fCollisionDamageMultiplier > 150.0f || bBodyCastDamageEffect) && m_nCollisionDamageEffect) {
+ const CVector& vecPos = m_matrix.GetPosition();
+ const float fDirectionZ = 0.0002f * amount;
+ switch (m_nCollisionDamageEffect)
+ {
+ case COLDAMAGE_EFFECT_CHANGE_MODEL:
+ bRenderDamaged = true;
+ break;
+ case COLDAMAGE_EFFECT_SPLIT_MODEL:
+ break;
+ case COLDAMAGE_EFFECT_SMASH_COMPLETELY:
+ bIsVisible = false;
+ bUsesCollision = false;
+ bIsStatic = true;
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ break;
+ case COLDAMAGE_EFFECT_CHANGE_THEN_SMASH:
+ if (!bRenderDamaged) {
+ bRenderDamaged = true;
+ }
+ else {
+ bIsVisible = false;
+ bUsesCollision = false;
+ bIsStatic = true;
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ }
+ break;
+ case COLDAMAGE_EFFECT_SMASH_CARDBOX_COMPLETELY: {
+ bIsVisible = false;
+ bUsesCollision = false;
+ bIsStatic = true;
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color = { 96, 48, 0, 255 };
+ for (int32 i = 0; i < 25; i++) {
+ CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ);
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f);
+ RwRGBA randomColor = { color.red * fRandom, color.green * fRandom , color.blue, color.alpha };
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(_SCRSOUND_CARDBOARD_BOX_SMASH, vecPos);
+ break;
+ }
+ case COLDAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: {
+ bIsVisible = false;
+ bUsesCollision = false;
+ bIsStatic = true;
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color = { 128, 128, 128, 255 };
+ for (int32 i = 0; i < 45; i++) {
+ CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ);
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 0.5f);
+ RwRGBA randomColor = { color.red * fRandom, color.green * fRandom , color.blue * fRandom, color.alpha };
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(_SCRSOUND_WOODEN_BOX_SMASH, vecPos);
+ break;
+ }
+ case COLDAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: {
+ bIsVisible = false;
+ bUsesCollision = false;
+ bIsStatic = true;
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ for (int32 i = 0; i < 10; i++) {
+ CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ);
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA color = color2;
+ if (nFrameGen & 1)
+ color = color1;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(_SCRSOUND_TYRE_BUMP, vecPos);
+ break;
+ }
+ case COLDAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: {
+ bIsVisible = false;
+ bUsesCollision = false;
+ bIsStatic = true;
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ for (int32 i = 0; i < 32; i++) {
+ CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
+ CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ);
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA color = color2;
+ if (nFrameGen & 1)
+ color = color1;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(_SCRSOUND_COL_CAR, vecPos);
+ break;
+ }
+ }
+ }
+}
void
CObject::RefModelInfo(int32 modelId)
@@ -125,6 +306,39 @@ CObject::RefModelInfo(int32 modelId)
CModelInfo::GetModelInfo(modelId)->AddRef();
}
+void
+CObject::Init(void)
+{
+ m_type = ENTITY_TYPE_OBJECT;;
+ CObjectData::SetObjectData(m_modelIndex, *this);
+ m_nEndOfLifeTime = 0;
+ ObjectCreatedBy = GAME_OBJECT;
+ bIsStatic = true;
+ bIsPickup = false;
+ m_obj_flag2 = false;
+ bOutOfStock = false;
+ bGlassCracked = false;
+ bGlassBroken = false;
+ bHasBeenDamaged = false;
+ bUseVehicleColours = false;
+ m_nRefModelIndex = -1;
+ m_colour1 = 0;
+ m_colour2 = 0;
+ m_nBonusValue = 0;
+ m_pCollidingEntity = nil;
+ CColPoint point;
+ CEntity* outEntity = nil;
+ const CVector& vecPos = m_matrix.GetPosition();
+ if (CWorld::ProcessVerticalLine(vecPos, vecPos.z - 10.0f, point, outEntity, true, false, false, false, false, false, nil))
+ m_pCurSurface = outEntity;
+ else
+ m_pCurSurface = nil;
+ if (m_modelIndex == MI_BODYCAST)
+ nBodyCastHealth = 1000;
+ else if (m_modelIndex == MI_BUOY)
+ bTouchingWater = true;
+}
+
bool
CObject::CanBeDeleted(void)
{
@@ -142,6 +356,45 @@ CObject::CanBeDeleted(void)
}
}
+void
+CObject::DeleteAllMissionObjects()
+{
+ CObjectPool* objectPool = CPools::GetObjectPool();
+ for (int32 i = 0; i < objectPool->GetSize(); i++) {
+ CObject* pObject = objectPool->GetSlot(i);
+ if (pObject && pObject->ObjectCreatedBy == MISSION_OBJECT) {
+ CWorld::Remove(pObject);
+ delete pObject;
+ }
+ }
+}
+
+void
+CObject::DeleteAllTempObjects()
+{
+ CObjectPool* objectPool = CPools::GetObjectPool();
+ for (int32 i = 0; i < objectPool->GetSize(); i++) {
+ CObject* pObject = objectPool->GetSlot(i);
+ if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT) {
+ CWorld::Remove(pObject);
+ delete pObject;
+ }
+ }
+}
+
+void
+CObject::DeleteAllTempObjectInArea(CVector point, float fRadius)
+{
+ CObjectPool *objectPool = CPools::GetObjectPool();
+ for (int32 i = 0; i < objectPool->GetSize(); i++) {
+ CObject *pObject = objectPool->GetSlot(i);
+ if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && fRadius * fRadius > pObject->GetPosition().MagnitudeSqr()) {
+ CWorld::Remove(pObject);
+ delete pObject;
+ }
+ }
+}
+
#include <new>
class CObject_ : public CObject
@@ -152,6 +405,9 @@ public:
CObject *ctor(CDummyObject *dummy) { return ::new (this) CObject(dummy); }
void dtor(void) { CObject::~CObject(); }
void Render_(void) { CObject::Render(); }
+ void ProcessControl_(void) { CObject::ProcessControl(); }
+ bool SetupLighting_(void) { return CObject::SetupLighting(); }
+ void RemoveLighting_(bool reset) { CObject::RemoveLighting(reset); }
};
STARTPATCHES
@@ -159,5 +415,16 @@ STARTPATCHES
InjectHook(0x4BACE0, (CObject* (CObject::*)(int32, bool)) &CObject_::ctor, PATCH_JUMP);
InjectHook(0x4BAD50, (CObject* (CObject::*)(CDummyObject*)) &CObject_::ctor, PATCH_JUMP);
InjectHook(0x4BAE00, &CObject_::dtor, PATCH_JUMP);
+ InjectHook(0x4BB040, &CObject_::ProcessControl_, PATCH_JUMP);
+ InjectHook(0x4BBDA0, &CObject::Teleport, PATCH_JUMP);
InjectHook(0x4BB1E0, &CObject_::Render_, PATCH_JUMP);
+ InjectHook(0x4A7C90, &CObject_::SetupLighting_, PATCH_JUMP);
+ InjectHook(0x4A7CD0, &CObject_::RemoveLighting_, PATCH_JUMP);
+ InjectHook(0x4BB240, &CObject::ObjectDamage, PATCH_JUMP);
+ InjectHook(0x4BBD80, &CObject::RefModelInfo, PATCH_JUMP);
+ InjectHook(0x4BAEC0, &CObject::Init, PATCH_JUMP);
+ InjectHook(0x4BB010, &CObject::CanBeDeleted, PATCH_JUMP);
+ InjectHook(0x4BBE60, &CObject::DeleteAllMissionObjects, PATCH_JUMP);
+ InjectHook(0x4BBDF0, &CObject::DeleteAllTempObjects, PATCH_JUMP);
+ InjectHook(0x4BBED0, &CObject::DeleteAllTempObjectInArea, PATCH_JUMP);
ENDPATCHES
diff --git a/src/objects/Object.h b/src/objects/Object.h
index 27346e23..6d04c78a 100644
--- a/src/objects/Object.h
+++ b/src/objects/Object.h
@@ -3,6 +3,7 @@
#include "Physical.h"
enum {
+ UNKNOWN_OBJECT = 0,
GAME_OBJECT = 1,
MISSION_OBJECT = 2,
TEMP_OBJECT = 3,
@@ -10,6 +11,18 @@ enum {
};
enum {
+ COLDAMAGE_EFFECT_NONE = 0,
+ COLDAMAGE_EFFECT_CHANGE_MODEL = 1,
+ COLDAMAGE_EFFECT_SPLIT_MODEL = 2,
+ COLDAMAGE_EFFECT_SMASH_COMPLETELY = 3,
+ COLDAMAGE_EFFECT_CHANGE_THEN_SMASH = 4,
+ COLDAMAGE_EFFECT_SMASH_CARDBOX_COMPLETELY = 50,
+ COLDAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY = 60,
+ COLDAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY = 70,
+ COLDAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY = 80,
+};
+
+enum {
COLLRESPONSE_NONE,
COLLRESPONSE_CHANGE_MODEL,
COLLRESPONSE_SPLIT_MODEL,
@@ -41,21 +54,21 @@ public:
int8 bHasBeenDamaged : 1;
int8 bUseVehicleColours : 1;
int8 m_obj_flag80 : 1;
- int8 field_172; // car for a bonus pickup?
- int8 field_173;
+ int8 m_nBonusValue;
+ int8 field_173;
float m_fCollisionDamageMultiplier;
uint8 m_nCollisionDamageEffect;
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
- int8 field_17B;
- int8 field_17C;
- int8 field_17D;
- int8 field_17E;
- int8 field_17F;
+ int8 field_17B;
+ int8 field_17C;
+ int8 field_17D;
+ int8 field_17E;
+ int8 field_17F;
uint32 m_nEndOfLifeTime;
int16 m_nRefModelIndex;
- int8 field_186;
- int8 field_187;
+ int8 field_186;
+ int8 field_187;
CEntity *m_pCurSurface;
CEntity *m_pCollidingEntity;
int8 m_colour1, m_colour2;
@@ -74,7 +87,7 @@ public:
~CObject(void);
void ProcessControl(void);
- void Teleport(CVector);
+ void Teleport(CVector vecPos);
void Render(void);
bool SetupLighting(void);
void RemoveLighting(bool reset);
@@ -84,6 +97,8 @@ public:
void Init(void);
bool CanBeDeleted(void);
- static void DeleteAllTempObjectInArea(CVector, float);
+ static void DeleteAllMissionObjects();
+ static void DeleteAllTempObjects();
+ static void DeleteAllTempObjectInArea(CVector point, float fRadius);
};
static_assert(sizeof(CObject) == 0x198, "CObject: error");
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index 881510e8..60827411 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -154,7 +154,7 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_nRemoveTimer = 0;
if ( color.alpha != 0 )
- RwRGBAAssign(&pobj->m_Color, &color);
+ pobj->m_Color = color;
else
pobj->m_Color.alpha = 0;
diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp
index 533d7c98..a9e0580e 100644
--- a/src/peds/CivilianPed.cpp
+++ b/src/peds/CivilianPed.cpp
@@ -28,10 +28,8 @@ CCivilianPed::CivilianAI(void)
return;
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
- if (m_pedInObjective) {
- if (m_pedInObjective->IsPlayer())
- return;
- }
+ if (m_pedInObjective && m_pedInObjective->IsPlayer())
+ return;
}
if (CTimer::GetTimeInMilliseconds() <= m_lookTimer)
return;
@@ -75,7 +73,7 @@ CCivilianPed::CivilianAI(void)
} else {
SetMoveState(PEDMOVE_WALK);
}
- } else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
+ } else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
SetFindPathAndFlee(m_threatEntity, 5000);
if (threatDistSqr < sq(10.0f)) {
SetMoveState(PEDMOVE_RUN);
@@ -170,8 +168,8 @@ CCivilianPed::CivilianAI(void)
if (m_threatEntity && m_threatEntity->IsPed()) {
CPed *threatPed = (CPed*)m_threatEntity;
if (m_pedStats->m_fear <= 100 - threatPed->m_pedStats->m_temper && threatPed->m_nPedType != PEDTYPE_COP) {
- if (threatPed->GetWeapon()->IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
- if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
+ if (threatPed->GetWeapon(m_currentWeapon).IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
+ if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
SetFindPathAndFlee(m_threatEntity, 10000);
}
diff --git a/src/control/Gangs.cpp b/src/peds/Gangs.cpp
index ac32ad98..c67fe599 100644
--- a/src/control/Gangs.cpp
+++ b/src/peds/Gangs.cpp
@@ -1,10 +1,9 @@
#include "common.h"
#include "patcher.h"
#include "ModelIndices.h"
-#include "Gangs.h"
+#include "Gangs.h"
#include "Weapon.h"
-//CGangInfo(&CGangs::Gang)[NUM_GANGS] = *(CGangInfo(*)[NUM_GANGS])*(uintptr*)0x6EDF78;
CGangInfo CGangs::Gang[NUM_GANGS];
CGangInfo::CGangInfo() :
@@ -57,20 +56,19 @@ void CGangs::SaveAllGangData(uint8 *buf, uint32 *size)
{
INITSAVEBUF
- *size = SAVE_HEADER_SIZE + sizeof(Gang);
+ *size = SAVE_HEADER_SIZE + sizeof(Gang);
WriteSaveHeader(buf, 'G','N','G','\0', *size - SAVE_HEADER_SIZE);
- for (int i = 0; i < NUM_GANGS; i++)
- WriteSaveBuf(buf, Gang[i]);
-
+ for (int i = 0; i < NUM_GANGS; i++)
+ WriteSaveBuf(buf, Gang[i]);
+
VALIDATESAVEBUF(*size);
}
void CGangs::LoadAllGangData(uint8 *buf, uint32 size)
{
- Initialise();
-
-INITSAVEBUF
- // original: SkipSaveBuf(buf, SAVE_HEADER_SIZE);
+ Initialise();
+
+INITSAVEBUF
CheckSaveHeader(buf, 'G','N','G','\0', size - SAVE_HEADER_SIZE);
for (int i = 0; i < NUM_GANGS; i++)
diff --git a/src/control/Gangs.h b/src/peds/Gangs.h
index dd7a7f93..dd7a7f93 100644
--- a/src/control/Gangs.h
+++ b/src/peds/Gangs.h
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 54816b1c..cee2b323 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -676,7 +676,7 @@ RemoveAllModelCB(RwObject *object, void *data)
{
RpAtomic *atomic = (RpAtomic*)object;
if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) {
- RpClumpRemoveAtomic(atomic->clump, atomic);
+ RpClumpRemoveAtomic(RpAtomicGetClump(atomic), atomic);
RpAtomicDestroy(atomic);
}
return object;
@@ -902,7 +902,7 @@ static RwObject*
SetPedAtomicVisibilityCB(RwObject* object, void* data)
{
if (data == nil)
- RpAtomicSetFlags(object, 0);
+ RpAtomicSetFlags((RpAtomic*)object, 0);
return object;
}
@@ -2733,7 +2733,6 @@ CPed::SetObjective(eObjective newObj, void *entity)
}
#ifdef VC_PED_PORTS
- SetObjectiveTimer(0);
ClearPointGunAt();
#endif
bObjectiveCompleted = false;
@@ -15027,7 +15026,7 @@ CPed::ProcessBuoyancy(void)
#endif
if (mod_Buoyancy.ProcessBuoyancy(this, GRAVITY * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) {
- m_flagD8 = true;
+ bTouchingWater = true;
CEntity *entity;
CColPoint point;
if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, false)
@@ -15093,7 +15092,7 @@ CPed::ProcessBuoyancy(void)
} else
return;
} else
- m_flagD8 = false;
+ bTouchingWater = false;
if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) {
CVector pos = GetPosition();
diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp
index cc4b0dd0..8e450ee6 100644
--- a/src/peds/PedIK.cpp
+++ b/src/peds/PedIK.cpp
@@ -340,7 +340,7 @@ CPedIK::RestoreLookAt(void)
}
void
-CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
+CPedIK::ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch)
{
float f = clamp(DotProduct(mat->up, CVector(0.0f, 1.0f, 0.0f)), -1.0f, 1.0f);
*yaw = Acos(f);
@@ -352,7 +352,7 @@ CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
}
void
-CPedIK::ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch)
+CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
{
float f = clamp(DotProduct(mat->at, CVector(0.0f, 0.0f, 1.0f)), -1.0f, 1.0f);
*yaw = Acos(f);
diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h
index df9017f3..7b82d1ac 100644
--- a/src/peds/PedIK.h
+++ b/src/peds/PedIK.h
@@ -54,8 +54,8 @@ public:
void GetComponentPosition(RwV3d *pos, uint32 node);
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
- void ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch);
- void ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch);
+ void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
+ void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo);
bool RestoreGunPosn(void);
bool LookInDirection(float phi, float theta);
diff --git a/src/peds/PedType.h b/src/peds/PedType.h
index 1f3ecb59..3d927df5 100644
--- a/src/peds/PedType.h
+++ b/src/peds/PedType.h
@@ -85,6 +85,7 @@ public:
static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; }
static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; }
static uint32 GetThreats(int type) { return ms_apPedType[type]->m_threats; }
+ static void SetThreats(int type, uint32 threat) { ms_apPedType[type]->m_threats = threat; }
static void AddThreat(int type, int threat) { ms_apPedType[type]->m_threats |= threat; }
static void RemoveThreat(int type, int threat) { ms_apPedType[type]->m_threats &= ~threat; }
static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; }
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 6dbf7687..ccc0a43a 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -1,1535 +1,1535 @@
-#include "common.h"
-#include "patcher.h"
-#include "PlayerPed.h"
-#include "Wanted.h"
-#include "Fire.h"
-#include "DMAudio.h"
-#include "Pad.h"
-#include "Camera.h"
-#include "WeaponEffects.h"
-#include "ModelIndices.h"
-#include "World.h"
-#include "RpAnimBlend.h"
-#include "AnimBlendAssociation.h"
-#include "General.h"
-#include "Pools.h"
-#include "Darkel.h"
-#include "CarCtrl.h"
-
-#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
-
-CPlayerPed::~CPlayerPed()
-{
- delete m_pWanted;
-}
-
-CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
-{
- m_fMoveSpeed = 0.0f;
- SetModelIndex(MI_PLAYER);
- SetInitialState();
-
- m_pWanted = new CWanted();
- m_pWanted->Initialise();
- m_pArrestingCop = nil;
- m_currentWeapon = WEAPONTYPE_UNARMED;
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- m_nSpeedTimer = 0;
- m_bSpeedTimerFlag = false;
- m_pPointGunAt = nil;
- m_nPedState = PED_IDLE;
- m_fMaxStamina = 150.0f;
- m_fCurrentStamina = m_fMaxStamina;
- m_fStaminaProgress = 0.0f;
- m_nEvadeAmount = 0;
- field_1367 = 0;
- m_nShotDelay = 0;
- field_1376 = 0.0f;
- m_bHaveTargetSelected = false;
- m_bHasLockOnTarget = false;
- m_bCanBeDamaged = true;
- m_fWalkAngle = 0.0f;
- m_fFPSMoveHeading = 0.0f;
- m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
- field_1413 = 0;
- for (int i = 0; i < 6; i++) {
- m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
- m_pPedAtSafePos[i] = nil;
- }
-}
-
-void CPlayerPed::ClearWeaponTarget()
-{
- if (m_nPedType == PEDTYPE_PLAYER1) {
- m_pPointGunAt = nil;
- TheCamera.ClearPlayerWeaponMode();
- CWeaponEffects::ClearCrossHair();
- }
- ClearPointGunAt();
-}
-
-void
-CPlayerPed::SetWantedLevel(int32 level)
-{
- m_pWanted->SetWantedLevel(level);
-}
-
-void
-CPlayerPed::SetWantedLevelNoDrop(int32 level)
-{
- m_pWanted->SetWantedLevelNoDrop(level);
-}
-
-void
-CPlayerPed::MakeObjectTargettable(int32 handle)
-{
- for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- if (
-#ifdef FIX_BUGS
- m_nTargettableObjects[i] == -1 ||
-#endif
- CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
- m_nTargettableObjects[i] = handle;
- return;
- }
- }
-}
-
-// I don't know the actual purpose of parameter
-void
-CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
-{
- if (m_pedStats->m_temper < 52) {
- m_pedStats->m_temper++;
- } else {
- if (annoyedByPassingEntity) {
- if (m_pedStats->m_temper < 55) {
- m_pedStats->m_temper++;
- } else {
- m_pedStats->m_temper = 46;
- }
- }
- }
-}
-
-void
-CPlayerPed::ClearAdrenaline(void)
-{
- if (m_bAdrenalineActive && m_nAdrenalineTime != 0) {
- m_nAdrenalineTime = 0;
- CTimer::SetTimeScale(1.0f);
- }
-}
-
-CPlayerInfo *
-CPlayerPed::GetPlayerInfoForThisPlayerPed()
-{
- if (CWorld::Players[0].m_pPed == this)
- return &CWorld::Players[0];
-
- return nil;
-}
-
-void
-CPlayerPed::SetupPlayerPed(int32 index)
-{
- CPlayerPed *player = new CPlayerPed();
- CWorld::Players[index].m_pPed = player;
-
- player->SetOrientation(0.0f, 0.0f, 0.0f);
-
- CWorld::Add(player);
- player->m_wepAccuracy = 100;
-}
-
-void
-CPlayerPed::DeactivatePlayerPed(int32 index)
-{
- CWorld::Remove(CWorld::Players[index].m_pPed);
-}
-
-void
-CPlayerPed::ReactivatePlayerPed(int32 index)
-{
- CWorld::Add(CWorld::Players[index].m_pPed);
-}
-
-void
-CPlayerPed::UseSprintEnergy(void)
-{
- if (m_fCurrentStamina > -150.0f && !CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint
- && !m_bAdrenalineActive) {
- m_fCurrentStamina = m_fCurrentStamina - CTimer::GetTimeStep();
- m_fStaminaProgress = m_fStaminaProgress + CTimer::GetTimeStep();
- }
-
- if (m_fStaminaProgress >= 500.0f) {
- m_fStaminaProgress = 0;
- if (m_fMaxStamina < 1000.0f)
- m_fMaxStamina += 10.0f;
- }
-}
-
-void
-CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
-{
- if (m_nPedState == PED_SNIPER_MODE) {
- RestorePreviousState();
- TheCamera.ClearPlayerWeaponMode();
- }
- SetCurrentWeapon(weapon);
-
- GetWeapon()->m_nAmmoInClip = min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
-
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
- ClearWeaponTarget();
-
- CAnimBlendAssociation *weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_AnimToPlay);
- if (weaponAnim) {
- weaponAnim->SetRun();
- weaponAnim->flags |= ASSOC_FADEOUTWHENDONE;
- }
- TheCamera.ClearPlayerWeaponMode();
-}
-
-void
-CPlayerPed::ReApplyMoveAnims(void)
-{
- static AnimationId moveAnims[] = { ANIM_WALK, ANIM_RUN, ANIM_SPRINT, ANIM_IDLE_STANCE, ANIM_WALK_START };
-
- for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) {
- CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]);
- if (curMoveAssoc) {
- if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
- CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]);
- newMoveAssoc->blendDelta = curMoveAssoc->blendDelta;
- newMoveAssoc->blendAmount = curMoveAssoc->blendAmount;
- curMoveAssoc->blendDelta = -1000.0f;
- curMoveAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
- }
-}
-
-void
-CPlayerPed::SetInitialState(void)
-{
- m_bAdrenalineActive = false;
- m_nAdrenalineTime = 0;
- CTimer::SetTimeStep(1.0f);
- m_pSeekTarget = nil;
- m_vecSeekPos = { 0.0f, 0.0f, 0.0f };
- m_fleeFromPosX = 0.0f;
- m_fleeFromPosY = 0.0f;
- m_fleeFrom = nil;
- m_fleeTimer = 0;
- m_objective = OBJECTIVE_NONE;
- m_prevObjective = OBJECTIVE_NONE;
- bUsesCollision = true;
- ClearAimFlag();
- ClearLookFlag();
- bIsPointingGunAt = false;
- bRenderPedInCar = true;
- if (m_pFire)
- m_pFire->Extinguish();
- RpAnimBlendClumpRemoveAllAssociations(GetClump());
- m_nPedState = PED_IDLE;
- SetMoveState(PEDMOVE_STILL);
- m_nLastPedState = PED_NONE;
- m_animGroup = ASSOCGRP_PLAYER;
- m_fMoveSpeed = 0.0f;
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- bIsPedDieAnimPlaying = false;
- SetRealMoveAnim();
- m_bCanBeDamaged = true;
- m_pedStats->m_temper = 50;
- m_fWalkAngle = 0.0f;
-}
-
-void
-CPlayerPed::SetRealMoveAnim(void)
-{
- CAnimBlendAssociation *curWalkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK);
- CAnimBlendAssociation *curRunAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN);
- CAnimBlendAssociation *curSprintAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
- CAnimBlendAssociation *curWalkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START);
- CAnimBlendAssociation *curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
- CAnimBlendAssociation *curRunStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
- CAnimBlendAssociation *curRunStopRAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
- if (bResetWalkAnims) {
- if (curWalkAssoc)
- curWalkAssoc->SetCurrentTime(0.0f);
- if (curRunAssoc)
- curRunAssoc->SetCurrentTime(0.0f);
- if (curSprintAssoc)
- curSprintAssoc->SetCurrentTime(0.0f);
- bResetWalkAnims = false;
- }
-
- if (!curIdleAssoc)
- curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- if (!curIdleAssoc)
- curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
-
- if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) {
-
- if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) {
- if (curRunStopAssoc) {
- curRunStopAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curRunStopAssoc->blendAmount = 1.0f;
- curRunStopAssoc->blendDelta = -8.0f;
- } else if (curRunStopRAssoc) {
- curRunStopRAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curRunStopRAssoc->blendAmount = 1.0f;
- curRunStopRAssoc->blendDelta = -8.0f;
- }
-
- RestoreHeadingRate();
- if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
- nil, true, false, false, false, false, false)) {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f);
-
- } else {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
- }
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
- }
- curIdleAssoc->blendAmount = 0.0f;
- curIdleAssoc->blendDelta = 8.0f;
-
- } else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
- if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
- nil, true, false, false, false, false, false)) {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
-
- } else {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
- }
-
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
- }
-
- if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_IDLE_TIRED) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
-
- } else if (m_nPedState != PED_FIGHT) {
- if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_IDLE_TIRED
- && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
-
- } else if (curIdleAssoc->animId != ANIM_IDLE_STANCE) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
- }
- }
-
- m_nMoveState = PEDMOVE_STILL;
- } else {
- if (curIdleAssoc) {
- if (curWalkStartAssoc) {
- curWalkStartAssoc->blendAmount = 1.0f;
- curWalkStartAssoc->blendDelta = 0.0f;
- } else {
- curWalkStartAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK_START);
- }
- if (curWalkAssoc)
- curWalkAssoc->SetCurrentTime(0.0f);
- if (curRunAssoc)
- curRunAssoc->SetCurrentTime(0.0f);
-
- delete curIdleAssoc;
- delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
- delete curSprintAssoc;
-
- curSprintAssoc = nil;
- m_nMoveState = PEDMOVE_WALK;
- }
- if (curRunStopAssoc) {
- delete curRunStopAssoc;
- RestoreHeadingRate();
- }
- if (curRunStopRAssoc) {
- delete curRunStopRAssoc;
- RestoreHeadingRate();
- }
- if (!curWalkAssoc) {
- curWalkAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK);
- curWalkAssoc->blendAmount = 0.0f;
- }
- if (!curRunAssoc) {
- curRunAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_RUN);
- curRunAssoc->blendAmount = 0.0f;
- }
- if (curWalkStartAssoc && !(curWalkStartAssoc->IsRunning())) {
- delete curWalkStartAssoc;
- curWalkStartAssoc = nil;
- curWalkAssoc->SetRun();
- curRunAssoc->SetRun();
- }
- if (m_nMoveState == PEDMOVE_SPRINT) {
- if (m_fCurrentStamina < 0.0f && (m_fCurrentStamina <= -150.0f || !curSprintAssoc || curSprintAssoc->blendDelta < 0.0f))
- m_nMoveState = PEDMOVE_STILL;
-
- if (curWalkStartAssoc)
- m_nMoveState = PEDMOVE_STILL;
- }
-
- if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) {
- if (curSprintAssoc->blendAmount == 0.0f) {
- curSprintAssoc->blendDelta = -1000.0f;
- curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
-
- } else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) {
- if (m_fMoveSpeed < 0.4f) {
- AnimationId runStopAnim;
- if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double
- runStopAnim = ANIM_RUN_STOP;
- else
- runStopAnim = ANIM_RUN_STOP_R;
- CAnimBlendAssociation* newRunStopAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, runStopAnim);
- newRunStopAssoc->blendAmount = 1.0f;
- newRunStopAssoc->SetDeleteCallback(RestoreHeadingRateCB, this);
- m_headingRate = 0.0f;
- curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curSprintAssoc->blendDelta = -1000.0f;
- curWalkAssoc->flags &= ~ASSOC_RUNNING;
- curWalkAssoc->blendAmount = 0.0f;
- curWalkAssoc->blendDelta = 0.0f;
- curRunAssoc->flags &= ~ASSOC_RUNNING;
- curRunAssoc->blendAmount = 0.0f;
- curRunAssoc->blendDelta = 0.0f;
- } else if (curSprintAssoc->blendDelta >= 0.0f) {
-
- // Stop sprinting when tired
- curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curSprintAssoc->blendDelta = -1.0f;
- curRunAssoc->blendDelta = 1.0f;
- }
- } else if (m_fMoveSpeed < 1.0f) {
- curSprintAssoc->blendDelta = -8.0f;
- curRunAssoc->blendDelta = 8.0f;
- }
- } else if (curWalkStartAssoc) {
- curWalkAssoc->flags &= ~ASSOC_RUNNING;
- curRunAssoc->flags &= ~ASSOC_RUNNING;
- curWalkAssoc->blendAmount = 0.0f;
- curRunAssoc->blendAmount = 0.0f;
-
- } else if (m_nMoveState == PEDMOVE_SPRINT) {
- if (curSprintAssoc) {
- if (curSprintAssoc->blendDelta < 0.0f) {
- curSprintAssoc->blendDelta = 2.0f;
- curRunAssoc->blendDelta = -2.0f;
- }
- } else {
- curWalkAssoc->blendAmount = 0.0f;
- curRunAssoc->blendAmount = 1.0f;
- curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f);
- }
- UseSprintEnergy();
- } else {
- if (m_fMoveSpeed < 1.0f) {
- curWalkAssoc->blendAmount = 1.0f;
- curRunAssoc->blendAmount = 0.0f;
- m_nMoveState = PEDMOVE_WALK;
- } else if (m_fMoveSpeed < 2.0f) {
- curWalkAssoc->blendAmount = 2.0f - m_fMoveSpeed;
- curRunAssoc->blendAmount = m_fMoveSpeed - 1.0f;
- m_nMoveState = PEDMOVE_RUN;
- } else {
- curWalkAssoc->blendAmount = 0.0f;
- curRunAssoc->blendAmount = 1.0f;
- m_nMoveState = PEDMOVE_RUN;
- }
- }
- }
- }
- if (m_bAdrenalineActive) {
- if (CTimer::GetTimeInMilliseconds() > m_nAdrenalineTime) {
- m_bAdrenalineActive = false;
- CTimer::SetTimeScale(1.0f);
- if (curWalkStartAssoc)
- curWalkStartAssoc->speed = 1.0f;
- if (curWalkAssoc)
- curWalkAssoc->speed = 1.0f;
- if (curRunAssoc)
- curRunAssoc->speed = 1.0f;
- if (curSprintAssoc)
- curSprintAssoc->speed = 1.0f;
- } else {
- CTimer::SetTimeScale(1.0f / 3);
- if (curWalkStartAssoc)
- curWalkStartAssoc->speed = 2.0f;
- if (curWalkAssoc)
- curWalkAssoc->speed = 2.0f;
- if (curRunAssoc)
- curRunAssoc->speed = 2.0f;
- if (curSprintAssoc)
- curSprintAssoc->speed = 2.0f;
- }
- }
-}
-
-void
-CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
-{
- if (m_fCurrentStamina < m_fMaxStamina)
- m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f;
-}
-
-bool
-CPlayerPed::DoWeaponSmoothSpray(void)
-{
- if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
- eWeaponType weapon = GetWeapon()->m_eWeaponType;
- if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN ||
- weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
- return true;
- }
- return false;
-}
-
-void
-CPlayerPed::DoStuffToGoOnFire(void)
-{
- if (m_nPedState == PED_SNIPER_MODE)
- TheCamera.ClearPlayerWeaponMode();
-}
-
-bool
-CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
-{
- CVector distVec = target - GetPosition();
-
- if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange)
- return true;
-
- if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_AK47)
- return false;
-
- distVec.Normalise();
-
- if (DotProduct(distVec,GetForward()) < 0.4f)
- return true;
-
- return false;
-}
-
-// Cancels landing anim while running & jumping? I think
-void
-CPlayerPed::RunningLand(CPad *padUsed)
-{
- CAnimBlendAssociation *landAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_LAND);
- if (landAssoc && landAssoc->currentTime == 0.0f && m_fMoveSpeed > 1.5f
- && padUsed && (padUsed->GetPedWalkLeftRight() != 0.0f || padUsed->GetPedWalkUpDown() != 0.0f)) {
-
- landAssoc->blendDelta = -1000.0f;
- landAssoc->flags |= ASSOC_DELETEFADEDOUT;
-
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAND)->SetFinishCallback(FinishJumpCB, this);
-
- if (m_nPedState == PED_JUMP)
- RestorePreviousState();
- }
-}
-
-bool
-CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
-{
- if (suspect->m_pPointGunAt == this)
- return true;
-
- switch (suspect->m_objective) {
- case OBJECTIVE_KILL_CHAR_ON_FOOT:
- case OBJECTIVE_KILL_CHAR_ANY_MEANS:
- if (suspect->m_pedInObjective == this)
- return true;
-
- break;
- default:
- break;
- }
- return false;
-}
-
-void
-CPlayerPed::PlayerControlSniper(CPad *padUsed)
-{
- ProcessWeaponSwitch(padUsed);
- TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
-
- if (!padUsed->GetTarget()) {
- RestorePreviousState();
- TheCamera.ClearPlayerWeaponMode();
- }
-
- if (padUsed->WeaponJustDown()) {
- CVector firePos(0.0f, 0.0f, 0.6f);
- firePos = GetMatrix() * firePos;
- GetWeapon()->Fire(this, &firePos);
- }
- GetWeapon()->Update(m_audioEntityId);
-}
-
-// I think R* also used goto in here.
-void
-CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
-{
- if (CDarkel::FrenzyOnGoing())
- goto switchDetectDone;
-
- if (padUsed->CycleWeaponRightJustDown() && !m_pPointGunAt) {
-
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
-
- for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) {
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
- }
- }
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- }
- } else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
-
- for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
- if (m_nSelectedWepSlot < WEAPONTYPE_UNARMED)
- m_nSelectedWepSlot = WEAPONTYPE_DETONATOR;
-
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
- }
- }
- }
- } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) {
- if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
-
- for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
- if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && HasWeapon(WEAPONTYPE_BASEBALLBAT)
- || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE) {
- goto switchDetectDone;
- }
- }
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- }
- }
- }
-
-switchDetectDone:
- if (m_nSelectedWepSlot != m_currentWeapon) {
- if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT)
- MakeChangesForNewWeapon(m_nSelectedWepSlot);
- }
-}
-
-void
-CPlayerPed::PlayerControlM16(CPad *padUsed)
-{
- ProcessWeaponSwitch(padUsed);
- TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
-
- if (!padUsed->GetTarget()) {
- RestorePreviousState();
- TheCamera.ClearPlayerWeaponMode();
- }
-
- if (padUsed->GetWeapon()) {
- CVector firePos(0.0f, 0.0f, 0.6f);
- firePos = GetMatrix() * firePos;
- GetWeapon()->Fire(this, &firePos);
- }
- GetWeapon()->Update(m_audioEntityId);
-}
-
-void
-CPlayerPed::PlayerControlFighter(CPad *padUsed)
-{
- float leftRight = padUsed->GetPedWalkLeftRight();
- float upDown = padUsed->GetPedWalkUpDown();
- float padMove = CVector2D(leftRight, upDown).Magnitude();
-
- if (padMove > 0.0f) {
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
- m_takeAStepAfterAttack = padMove > 2 * PAD_MOVE_TO_GAME_WORLD_MOVE;
- if (padUsed->GetSprint() && padMove > 1 * PAD_MOVE_TO_GAME_WORLD_MOVE)
- bIsAttacking = false;
- }
-
- if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy && padUsed->JumpJustDown()) {
- if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
- SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- } else {
- SetJump();
- }
- }
-}
-
-void
-CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
-{
- float leftRight = padUsed->GetPedWalkLeftRight();
- float upDown = padUsed->GetPedWalkUpDown();
- float padMove = CVector2D(leftRight, upDown).Magnitude();
- float padMoveInGameUnit = padMove / PAD_MOVE_TO_GAME_WORLD_MOVE;
- if (padMoveInGameUnit > 0.0f) {
-#ifdef FREE_CAM
- if (!CCamera::bFreeCam)
- m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
- else
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
-#else
- m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
-#endif
- m_fMoveSpeed = min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed);
- } else {
- m_fMoveSpeed = 0.0f;
- }
-
- if (m_nPedState == PED_JUMP) {
- if (bIsInTheAir) {
- if (bUsesCollision && !bHitSteepSlope &&
- (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
- && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
-
- float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
- float angleCos = Cos(m_fRotationCur);
- ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
- }
- } else if (bIsLanding) {
- m_fMoveSpeed = 0.0f;
- }
- }
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->GetSprint()) {
- m_nMoveState = PEDMOVE_SPRINT;
- }
- if (m_nPedState != PED_FIGHT)
- SetRealMoveAnim();
-
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
- ClearAttack();
- ClearWeaponTarget();
- if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
- SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- } else {
- SetJump();
- }
- }
-}
-
-void
-CPlayerPed::KeepAreaAroundPlayerClear(void)
-{
- BuildPedLists();
- for (int i = 0; i < m_numNearPeds; ++i) {
- CPed *nearPed = m_nearPeds[i];
- if (nearPed->CharCreatedBy == RANDOM_CHAR && !nearPed->DyingOrDead()) {
- if (nearPed->GetIsOnScreen()) {
- if (nearPed->m_objective == OBJECTIVE_NONE) {
- nearPed->SetFindPathAndFlee(this, 5000, true);
- } else {
- if (nearPed->EnteringCar())
- nearPed->QuitEnteringCar();
-
- nearPed->ClearObjective();
- }
- } else {
- nearPed->FlagToDestroyWhenNextProcessed();
- }
- }
- }
- CVector playerPos = (InVehicle() ? m_pMyVehicle->GetPosition() : GetPosition());
-
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity *vehicles[8];
- CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
-
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle *veh = (CVehicle*)vehicles[i];
- if (veh->VehicleCreatedBy != MISSION_VEHICLE) {
- if (veh->m_status != STATUS_PLAYER && veh->m_status != STATUS_PLAYER_DISABLED) {
- if ((veh->GetPosition() - playerPos).MagnitudeSqr() > 25.0f) {
- veh->AutoPilot.m_nTempAction = TEMPACT_WAIT;
- veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 5000;
- } else {
- if (DotProduct2D(playerPos - veh->GetPosition(), veh->GetForward()) > 0.0f)
- veh->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
- else
- veh->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
-
- veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
- }
- CCarCtrl::PossiblyRemoveVehicle(veh);
- }
- }
- }
-}
-
-void
-CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft)
-{
- CVector distVec = candidate->GetPosition() - GetPosition();
- if (distVec.Magnitude2D() <= distLimit) {
- if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
-#ifdef VC_PED_PORTS
- float angleBetweenUs = CGeneral::GetATanOfXY(candidate->GetPosition().x - TheCamera.GetPosition().x,
- candidate->GetPosition().y - TheCamera.GetPosition().y);
-#else
- float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
-#endif
- angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
- float closeness;
- if (lookToLeft) {
- closeness = angleBetweenUs > 0.0f ? -Abs(angleBetweenUs) : -100000.0f;
- } else {
- closeness = angleBetweenUs > 0.0f ? -100000.0f : -Abs(angleBetweenUs);
- }
-
- if (closeness > *lastCloseness) {
- *targetPtr = candidate;
- *lastCloseness = closeness;
- }
- }
- }
-}
-
-void
-CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool priority)
-{
- CVector distVec = candidate->GetPosition() - GetPosition();
- float dist = distVec.Magnitude2D();
- if (dist <= distLimit) {
- if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
- float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
- angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
-
- float closeness = -dist - 5.0f * Abs(angleBetweenUs);
- if (priority) {
- closeness += 5.0f;
- }
-
- if (closeness > *lastCloseness) {
- *targetPtr = candidate;
- *lastCloseness = closeness;
- }
- }
- }
-}
-
-bool
-CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
-{
- CEntity *nextTarget = nil;
- float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
- // nextTarget = nil;
- float lastCloseness = -10000.0f;
- // unused
- // CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
- CVector distVec = previousTarget->GetPosition() - GetPosition();
- float referenceBeta = CGeneral::GetATanOfXY(distVec.x, distVec.y);
-
- for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
- CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
- if (pedToCheck) {
- if (pedToCheck != FindPlayerPed() && pedToCheck != previousTarget) {
- if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
- && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
-
- EvaluateNeighbouringTarget(pedToCheck, &nextTarget, &lastCloseness,
- weaponRange, referenceBeta, lookToLeft);
- }
- }
- }
- }
- for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
- if (obj)
- EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft);
- }
- if (!nextTarget)
- return false;
-
- m_pPointGunAt = nextTarget;
- if (nextTarget)
- nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
- SetPointGunAt(nextTarget);
- return true;
-}
-
-bool
-CPlayerPed::FindWeaponLockOnTarget(void)
-{
- CEntity *nextTarget = nil;
- float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
-
- if (m_pPointGunAt) {
- CVector distVec = m_pPointGunAt->GetPosition() - GetPosition();
- if (distVec.Magnitude2D() > weaponRange) {
- m_pPointGunAt = nil;
- return false;
- } else {
- return true;
- }
- }
-
- // nextTarget = nil;
- float lastCloseness = -10000.0f;
- float referenceBeta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
- for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
- CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
- if (pedToCheck) {
- if (pedToCheck != FindPlayerPed()) {
- if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
- && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
-
- EvaluateTarget(pedToCheck, &nextTarget, &lastCloseness,
- weaponRange, referenceBeta, IsThisPedAttackingPlayer(pedToCheck));
- }
- }
- }
- }
- for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
- if (obj)
- EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, false);
- }
- if (!nextTarget)
- return false;
-
- m_pPointGunAt = nextTarget;
- if (nextTarget)
- nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
- SetPointGunAt(nextTarget);
- return true;
-}
-
-void
-CPlayerPed::ProcessAnimGroups(void)
-{
- AssocGroupId groupToSet;
- if ((m_fWalkAngle <= -DEGTORAD(50.0f) || m_fWalkAngle >= DEGTORAD(50.0f))
- && TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()
- && CanStrafeOrMouseControl()) {
-
- if (m_fWalkAngle >= -DEGTORAD(130.0f) && m_fWalkAngle <= DEGTORAD(130.0f)) {
- if (m_fWalkAngle > 0.0f) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- groupToSet = ASSOCGRP_ROCKETLEFT;
- else
- groupToSet = ASSOCGRP_PLAYERLEFT;
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- groupToSet = ASSOCGRP_ROCKETRIGHT;
- else
- groupToSet = ASSOCGRP_PLAYERRIGHT;
- }
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- groupToSet = ASSOCGRP_ROCKETBACK;
- else
- groupToSet = ASSOCGRP_PLAYERBACK;
- }
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
- groupToSet = ASSOCGRP_PLAYERROCKET;
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT) {
- groupToSet = ASSOCGRP_PLAYERBBBAT;
- } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI) {
- if (!GetWeapon()->IsType2Handed()) {
- groupToSet = ASSOCGRP_PLAYER;
- } else {
- groupToSet = ASSOCGRP_PLAYER2ARMED;
- }
- } else {
- groupToSet = ASSOCGRP_PLAYER1ARMED;
- }
- }
- }
-
- if (m_animGroup != groupToSet) {
- m_animGroup = groupToSet;
- ReApplyMoveAnims();
- }
-}
-
-void
-CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
-{
- CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- if (m_bHasLockOnTarget && !m_pPointGunAt) {
- TheCamera.ClearPlayerWeaponMode();
- CWeaponEffects::ClearCrossHair();
- ClearPointGunAt();
- }
- if (!m_pFire) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER ||
- GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
- if (padUsed->TargetJustDown()) {
- SetStoredState();
- m_nPedState = PED_SNIPER_MODE;
-#ifdef FREE_CAM
- if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
- m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
- SetHeading(m_fRotationCur);
- }
-#endif
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_ROCKETLAUNCHER, 0, 0);
- else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE)
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SNIPER, 0, 0);
- else
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0);
-
- m_fMoveSpeed = 0.0f;
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 1000.0f);
- }
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE
- || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON)
- return;
- }
- }
-
- if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) {
- if (m_nSelectedWepSlot == m_currentWeapon) {
- if (m_pPointGunAt) {
-#ifdef FREE_CAM
- if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f)
- StartFightAttack(padUsed->GetWeapon());
- else
-#endif
- SetAttack(m_pPointGunAt);
- } else if (m_currentWeapon != WEAPONTYPE_UNARMED) {
- if (m_nPedState == PED_ATTACK) {
- if (padUsed->WeaponJustDown()) {
- m_bHaveTargetSelected = true;
- } else if (!m_bHaveTargetSelected) {
- field_1376 += CTimer::GetTimeStepNonClipped();
- }
- } else {
- field_1376 = 0.0f;
- m_bHaveTargetSelected = false;
- }
- SetAttack(nil);
- } else if (padUsed->WeaponJustDown()) {
- if (m_fMoveSpeed < 1.0f)
- StartFightAttack(padUsed->GetWeapon());
- else
- SetAttack(nil);
- }
- }
- } else {
- m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
- if (m_nPedState == PED_ATTACK) {
- m_bHaveTargetSelected = true;
- bIsAttacking = false;
- }
- }
-
-#ifdef FREE_CAM
- // Rotate player/arm when shooting. We don't have auto-rotation anymore
- if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam &&
- m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
-
- // Weapons except throwable and melee ones
- if (weaponInfo->m_bCanAim || weaponInfo->m_b1stPerson || weaponInfo->m_bExpands) {
- if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || padUsed->GetWeapon()) {
- float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
-
- // On this one we can rotate arm.
- if (weaponInfo->m_bCanAimWithArm) {
- if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
- SetPointGunAt(nil);
- bIsPointingGunAt = false; // to not stop after attack
- }
-
- SetLookFlag(limitedCam, true);
- SetAimFlag(limitedCam);
-#ifdef VC_PED_PORTS
- SetLookTimer(INT_MAX); // removing this makes head move for real, but I experinced some bugs.
-#endif
- } else {
- m_fRotationDest = limitedCam;
- m_headingRate = 50.0f;
-
- // Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly)
- if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) {
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
- float limitedRotDest = m_fRotationDest;
-
- if (m_fRotationCur - PI > m_fRotationDest) {
- limitedRotDest += 2 * PI;
- } else if (PI + m_fRotationCur < m_fRotationDest) {
- limitedRotDest -= 2 * PI;
- }
-
- m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2;
- }
- }
- } else if (weaponInfo->m_bCanAimWithArm)
- ClearPointGunAt();
- else
- RestoreHeadingRate();
- }
- }
-#endif
-
- if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
- if (m_pPointGunAt) {
- // what??
- if (!m_pPointGunAt
-#ifdef FREE_CAM
- || (!CCamera::bFreeCam && CCamera::m_bUseMouse3rdPerson)
-#else
- || CCamera::m_bUseMouse3rdPerson
-#endif
- || m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->bInVehicle) {
- ClearWeaponTarget();
- return;
- }
- if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon())) {
- ClearWeaponTarget();
- return;
- }
- if (m_pPointGunAt) {
- if (padUsed->ShiftTargetLeftJustDown())
- FindNextWeaponLockOnTarget(m_pPointGunAt, true);
- if (padUsed->ShiftTargetRightJustDown())
- FindNextWeaponLockOnTarget(m_pPointGunAt, false);
- }
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SYPHON, 0, 0);
- TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition());
- }
-#ifdef FREE_CAM
- else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson)) {
-#else
- else if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) {
-#endif
- if (padUsed->TargetJustDown())
- FindWeaponLockOnTarget();
- }
- } else if (m_pPointGunAt) {
- ClearWeaponTarget();
- }
-
- if (m_pPointGunAt) {
-#ifndef VC_PED_PORTS
- CVector markPos = m_pPointGunAt->GetPosition();
-#else
- CVector markPos;
- if (m_pPointGunAt->IsPed()) {
- ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition((RwV3d*)markPos, PED_MID);
- } else {
- markPos = m_pPointGunAt->GetPosition();
- }
-#endif
- if (bCanPointGunAtTarget) {
- CWeaponEffects::MarkTarget(markPos, 64, 0, 0, 255, 0.8f);
- } else {
- CWeaponEffects::MarkTarget(markPos, 64, 32, 0, 255, 0.8f);
- }
- }
- m_bHasLockOnTarget = m_pPointGunAt != nil;
-}
-
-void
-CPlayerPed::PlayerControlZelda(CPad *padUsed)
-{
- bool doSmoothSpray = DoWeaponSmoothSpray();
- float camOrientation = TheCamera.Orientation;
- float leftRight = padUsed->GetPedWalkLeftRight();
- float upDown = padUsed->GetPedWalkUpDown();
- float padMoveInGameUnit;
- bool smoothSprayWithoutMove = false;
-
- if (doSmoothSpray && upDown > 0.0f) {
- padMoveInGameUnit = 0.0f;
- smoothSprayWithoutMove = true;
- } else {
- padMoveInGameUnit = CVector2D(leftRight, upDown).Magnitude() / PAD_MOVE_TO_GAME_WORLD_MOVE;
- }
-
- if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
- float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
- float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
- if (doSmoothSpray) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45
- || GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI)
- m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 80.0f) * CTimer::GetTimeStep();
- else
- m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 128.0f) * CTimer::GetTimeStep();
- } else {
- m_fRotationDest = neededTurn;
- }
-
- float maxAcc = 0.07f * CTimer::GetTimeStep();
- m_fMoveSpeed = min(padMoveInGameUnit, m_fMoveSpeed + maxAcc);
-
- } else {
- m_fMoveSpeed = 0.0f;
- }
-
- if (m_nPedState == PED_JUMP) {
- if (bIsInTheAir) {
- if (bUsesCollision && !bHitSteepSlope &&
- (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
- && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
-
- float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
- float angleCos = Cos(m_fRotationCur);
- ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
- }
- } else if (bIsLanding) {
- m_fMoveSpeed = 0.0f;
- }
- }
-
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->GetSprint()) {
- m_nMoveState = PEDMOVE_SPRINT;
- }
- if (m_nPedState != PED_FIGHT)
- SetRealMoveAnim();
-
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
- ClearAttack();
- ClearWeaponTarget();
- if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
- SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- } else {
- SetJump();
- }
- }
-}
-
-void
-CPlayerPed::ProcessControl(void)
-{
- if (m_nEvadeAmount != 0)
- --m_nEvadeAmount;
-
- if (m_nEvadeAmount == 0)
- m_pEvadingFrom = nil;
-
- if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
- bTryingToReachDryLand = true;
- } else if (!(((uint8)CTimer::GetFrameCounter() + m_randomSeed) & 0xF)) {
- CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil,
- false, true, false, false, false, false);
- if (nearVeh && nearVeh->IsBoat())
- bTryingToReachDryLand = true;
- else
- bTryingToReachDryLand = false;
- }
- CPed::ProcessControl();
- if (bWasPostponed)
- return;
-
- CPad *padUsed = CPad::GetPad(0);
- m_pWanted->Update();
- CEntity::PruneReferences();
-
- if (m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT)
- RestoreSprintEnergy(1.0f);
- else if (m_nMoveState == PEDMOVE_RUN)
- RestoreSprintEnergy(0.3f);
-
- if (m_nPedState == PED_DEAD) {
- ClearWeaponTarget();
- return;
- }
- if (m_nPedState == PED_DIE) {
- ClearWeaponTarget();
- if (CTimer::GetTimeInMilliseconds() > m_bloodyFootprintCountOrDeathTime + 4000)
- SetDead();
- return;
- }
- if (m_nPedState == PED_DRIVING && m_objective != OBJECTIVE_LEAVE_VEHICLE) {
- if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) {
- CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR);
- if (!rollDoorAssoc) {
- rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW);
- }
-
- // These comparisons are wrong, they return uint16
- if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || padUsed
- && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f
- || padUsed->GetBrake() != 0.0f)) {
-
- if (rollDoorAssoc)
- m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime);
- } else {
- m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
- if (m_pMyVehicle->bLowVehicle)
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW);
- else
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR);
-
- rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
- }
- }
- return;
- }
- if (m_objective == OBJECTIVE_NONE)
- m_nMoveState = PEDMOVE_STILL;
- if (bIsLanding)
- RunningLand(padUsed);
- if (padUsed && padUsed->WeaponJustDown() && m_nPedState != PED_SNIPER_MODE) {
-
- // ...Really?
- eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType;
- if (playerWeapon == WEAPONTYPE_SNIPERRIFLE) {
- DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0);
- } else if (playerWeapon == WEAPONTYPE_ROCKETLAUNCHER) {
- DMAudio.PlayFrontEndSound(SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, 0);
- }
- }
-
- switch (m_nPedState) {
- case PED_NONE:
- case PED_IDLE:
- case PED_FLEE_POS:
- case PED_FLEE_ENTITY:
- case PED_ATTACK:
- case PED_FIGHT:
- case PED_AIM_GUN:
- if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FLAG400)) {
- if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
- if (padUsed)
- PlayerControl1stPersonRunAround(padUsed);
- } else if (m_nPedState == PED_FIGHT) {
- if (padUsed)
- PlayerControlFighter(padUsed);
- } else if (padUsed) {
- PlayerControlZelda(padUsed);
- }
- }
- if (IsPedInControl() && padUsed)
- ProcessPlayerWeapon(padUsed);
- break;
- case PED_LOOK_ENTITY:
- case PED_LOOK_HEADING:
- case PED_WANDER_RANGE:
- case PED_WANDER_PATH:
- case PED_PURSUE:
- case PED_FOLLOW_PATH:
- case PED_ROCKET_ODE:
- case PED_DUMMY:
- case PED_PAUSE:
- case PED_FACE_PHONE:
- case PED_MAKE_CALL:
- case PED_CHAT:
- case PED_MUG:
- case PED_AI_CONTROL:
- case PED_FOLLOW_ROUTE:
- case PED_CPR:
- case PED_SOLICIT:
- case PED_BUY_ICECREAM:
- case PED_INVESTIGATE:
- case PED_STEP_AWAY:
- case PED_ON_FIRE:
- case PED_UNKNOWN:
- case PED_STATES_NO_AI:
- case PED_STAGGER:
- case PED_DIVE_AWAY:
- case PED_STATES_NO_ST:
- case PED_ARREST_PLAYER:
- case PED_DRIVING:
- case PED_PASSENGER:
- case PED_TAXI_PASSENGER:
- case PED_OPEN_DOOR:
- case PED_DIE:
- case PED_DEAD:
- case PED_HANDS_UP:
- break;
- case PED_SEEK_ENTITY:
- m_vecSeekPos = m_pSeekTarget->GetPosition();
-
- // fall through
- case PED_SEEK_POS:
- switch (m_nMoveState) {
- case PEDMOVE_WALK:
- m_fMoveSpeed = 1.0f;
- break;
- case PEDMOVE_RUN:
- m_fMoveSpeed = 1.8f;
- break;
- case PEDMOVE_SPRINT:
- m_fMoveSpeed = 2.5f;
- break;
- default:
- m_fMoveSpeed = 0.0f;
- break;
- }
- SetRealMoveAnim();
- if (Seek()) {
- RestorePreviousState();
- SetMoveState(PEDMOVE_STILL);
- }
- break;
- case PED_SNIPER_MODE:
- if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
- if (padUsed)
- PlayerControlM16(padUsed);
- } else if (padUsed) {
- PlayerControlSniper(padUsed);
- }
- break;
- case PED_SEEK_CAR:
- case PED_SEEK_IN_BOAT:
- if (bVehEnterDoorIsBlocked || bKindaStayInSamePlace) {
- m_fMoveSpeed = 0.0f;
- } else {
- m_fMoveSpeed = min(2.0f, 2.0f * (m_vecSeekPos - GetPosition()).Magnitude2D());
- }
- if (padUsed && !padUsed->ArePlayerControlsDisabled()) {
- if (padUsed->GetTarget() || padUsed->GetLeftStickXJustDown() || padUsed->GetLeftStickYJustDown() ||
- padUsed->GetDPadUpJustDown() || padUsed->GetDPadDownJustDown() || padUsed->GetDPadLeftJustDown() ||
- padUsed->GetDPadRightJustDown()) {
-
- RestorePreviousState();
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- RestorePreviousObjective();
- }
- }
- }
- if (padUsed && padUsed->GetSprint())
- m_nMoveState = PEDMOVE_SPRINT;
- SetRealMoveAnim();
- break;
- case PED_JUMP:
- if (padUsed)
- PlayerControlZelda(padUsed);
- if (bIsLanding)
- break;
-
- // This has been added later it seems
- return;
- case PED_FALL:
- case PED_GETUP:
- case PED_ENTER_TRAIN:
- case PED_EXIT_TRAIN:
- case PED_CARJACK:
- case PED_DRAG_FROM_CAR:
- case PED_ENTER_CAR:
- case PED_STEAL_CAR:
- case PED_EXIT_CAR:
- ClearWeaponTarget();
- break;
- case PED_ARRESTED:
- if (m_nLastPedState == PED_DRAG_FROM_CAR && m_pVehicleAnim)
- BeingDraggedFromCar();
- break;
- }
- if (padUsed && IsPedShootable()) {
- ProcessWeaponSwitch(padUsed);
- GetWeapon()->Update(m_audioEntityId);
- }
- ProcessAnimGroups();
- if (padUsed) {
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FOLLOWPED
- && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_BEHIND) {
-
- m_lookTimer = 0;
- float camAngle = CGeneral::LimitRadianAngle(TheCamera.Cams[TheCamera.ActiveCam].Front.Heading());
- float angleBetweenPlayerAndCam = Abs(camAngle - m_fRotationCur);
- if (m_nPedState != PED_ATTACK
- && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) {
-
- if (angleBetweenPlayerAndCam > DEGTORAD(150.0f) && angleBetweenPlayerAndCam < DEGTORAD(210.0f)) {
- float rightTurnAngle = CGeneral::LimitRadianAngle(m_fRotationCur - DEGTORAD(150.0f));
- float leftTurnAngle = CGeneral::LimitRadianAngle(DEGTORAD(150.0f) + m_fRotationCur);
- if (m_fLookDirection != 999999.0f) {
- if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection))
- camAngle = rightTurnAngle;
- else
- camAngle = leftTurnAngle;
- } else {
- camAngle = rightTurnAngle;
- }
- }
- SetLookFlag(camAngle, true);
- SetLookTimer(CTimer::GetTimeStepInMilliseconds() * 5.0f);
- } else {
- ClearLookFlag();
- }
- }
- }
- if (m_nMoveState == PEDMOVE_SPRINT && bIsLooking) {
- ClearLookFlag();
- SetLookTimer(250);
- }
-
- if (m_vecMoveSpeed.Magnitude2D() < 0.1f) {
- if (m_nSpeedTimer) {
- if (CTimer::GetTimeInMilliseconds() > m_nSpeedTimer)
- m_bSpeedTimerFlag = true;
- } else {
- m_nSpeedTimer = CTimer::GetTimeInMilliseconds() + 500;
- }
- } else {
- m_nSpeedTimer = 0;
- m_bSpeedTimerFlag = false;
- }
-}
-
-#include <new>
-
-class CPlayerPed_ : public CPlayerPed
-{
-public:
- CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); }
- void dtor(void) { CPlayerPed::~CPlayerPed(); }
- void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); }
- void ProcessControl_(void) { CPlayerPed::ProcessControl(); }
-};
-
-STARTPATCHES
- InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP);
- InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
- InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP);
- InjectHook(0x4EFD90, &CPlayerPed_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
- InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
- InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
- InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP);
- InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP);
- InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP);
- InjectHook(0x4F1810, &CPlayerPed::PlayerControlFighter, PATCH_JUMP);
- InjectHook(0x4F1340, &CPlayerPed::RestoreSprintEnergy, PATCH_JUMP);
- InjectHook(0x4F1380, &CPlayerPed::DoWeaponSmoothSpray, PATCH_JUMP);
- InjectHook(0x4F36E0, &CPlayerPed::DoStuffToGoOnFire, PATCH_JUMP);
- InjectHook(0x4F3350, &CPlayerPed::DoesTargetHaveToBeBroken, PATCH_JUMP);
- InjectHook(0x4F31D0, &CPlayerPed::RunningLand, PATCH_JUMP);
- InjectHook(0x4F2D00, &CPlayerPed::IsThisPedAttackingPlayer, PATCH_JUMP);
- InjectHook(0x4F1CF0, &CPlayerPed::PlayerControlSniper, PATCH_JUMP);
- InjectHook(0x4F2310, &CPlayerPed::ProcessWeaponSwitch, PATCH_JUMP);
- InjectHook(0x4F1DF0, &CPlayerPed::PlayerControlM16, PATCH_JUMP);
- InjectHook(0x4F3460, &CPlayerPed::KeepAreaAroundPlayerClear, PATCH_JUMP);
- InjectHook(0x4F1970, &CPlayerPed::PlayerControl1stPersonRunAround, PATCH_JUMP);
- InjectHook(0x4F1EF0, &CPlayerPed::ProcessPlayerWeapon, PATCH_JUMP);
- InjectHook(0x4F2640, &CPlayerPed::ProcessAnimGroups, PATCH_JUMP);
-ENDPATCHES
+#include "common.h"
+#include "patcher.h"
+#include "PlayerPed.h"
+#include "Wanted.h"
+#include "Fire.h"
+#include "DMAudio.h"
+#include "Pad.h"
+#include "Camera.h"
+#include "WeaponEffects.h"
+#include "ModelIndices.h"
+#include "World.h"
+#include "RpAnimBlend.h"
+#include "AnimBlendAssociation.h"
+#include "General.h"
+#include "Pools.h"
+#include "Darkel.h"
+#include "CarCtrl.h"
+
+#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
+
+CPlayerPed::~CPlayerPed()
+{
+ delete m_pWanted;
+}
+
+CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
+{
+ m_fMoveSpeed = 0.0f;
+ SetModelIndex(MI_PLAYER);
+ SetInitialState();
+
+ m_pWanted = new CWanted();
+ m_pWanted->Initialise();
+ m_pArrestingCop = nil;
+ m_currentWeapon = WEAPONTYPE_UNARMED;
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nSpeedTimer = 0;
+ m_bSpeedTimerFlag = false;
+ m_pPointGunAt = nil;
+ m_nPedState = PED_IDLE;
+ m_fMaxStamina = 150.0f;
+ m_fCurrentStamina = m_fMaxStamina;
+ m_fStaminaProgress = 0.0f;
+ m_nEvadeAmount = 0;
+ field_1367 = 0;
+ m_nShotDelay = 0;
+ field_1376 = 0.0f;
+ m_bHaveTargetSelected = false;
+ m_bHasLockOnTarget = false;
+ m_bCanBeDamaged = true;
+ m_fWalkAngle = 0.0f;
+ m_fFPSMoveHeading = 0.0f;
+ m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
+ field_1413 = 0;
+ for (int i = 0; i < 6; i++) {
+ m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
+ m_pPedAtSafePos[i] = nil;
+ }
+}
+
+void CPlayerPed::ClearWeaponTarget()
+{
+ if (m_nPedType == PEDTYPE_PLAYER1) {
+ m_pPointGunAt = nil;
+ TheCamera.ClearPlayerWeaponMode();
+ CWeaponEffects::ClearCrossHair();
+ }
+ ClearPointGunAt();
+}
+
+void
+CPlayerPed::SetWantedLevel(int32 level)
+{
+ m_pWanted->SetWantedLevel(level);
+}
+
+void
+CPlayerPed::SetWantedLevelNoDrop(int32 level)
+{
+ m_pWanted->SetWantedLevelNoDrop(level);
+}
+
+void
+CPlayerPed::MakeObjectTargettable(int32 handle)
+{
+ for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
+ if (
+#ifdef FIX_BUGS
+ m_nTargettableObjects[i] == -1 ||
+#endif
+ CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
+ m_nTargettableObjects[i] = handle;
+ return;
+ }
+ }
+}
+
+// I don't know the actual purpose of parameter
+void
+CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
+{
+ if (m_pedStats->m_temper < 52) {
+ m_pedStats->m_temper++;
+ } else {
+ if (annoyedByPassingEntity) {
+ if (m_pedStats->m_temper < 55) {
+ m_pedStats->m_temper++;
+ } else {
+ m_pedStats->m_temper = 46;
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::ClearAdrenaline(void)
+{
+ if (m_bAdrenalineActive && m_nAdrenalineTime != 0) {
+ m_nAdrenalineTime = 0;
+ CTimer::SetTimeScale(1.0f);
+ }
+}
+
+CPlayerInfo *
+CPlayerPed::GetPlayerInfoForThisPlayerPed()
+{
+ if (CWorld::Players[0].m_pPed == this)
+ return &CWorld::Players[0];
+
+ return nil;
+}
+
+void
+CPlayerPed::SetupPlayerPed(int32 index)
+{
+ CPlayerPed *player = new CPlayerPed();
+ CWorld::Players[index].m_pPed = player;
+
+ player->SetOrientation(0.0f, 0.0f, 0.0f);
+
+ CWorld::Add(player);
+ player->m_wepAccuracy = 100;
+}
+
+void
+CPlayerPed::DeactivatePlayerPed(int32 index)
+{
+ CWorld::Remove(CWorld::Players[index].m_pPed);
+}
+
+void
+CPlayerPed::ReactivatePlayerPed(int32 index)
+{
+ CWorld::Add(CWorld::Players[index].m_pPed);
+}
+
+void
+CPlayerPed::UseSprintEnergy(void)
+{
+ if (m_fCurrentStamina > -150.0f && !CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint
+ && !m_bAdrenalineActive) {
+ m_fCurrentStamina = m_fCurrentStamina - CTimer::GetTimeStep();
+ m_fStaminaProgress = m_fStaminaProgress + CTimer::GetTimeStep();
+ }
+
+ if (m_fStaminaProgress >= 500.0f) {
+ m_fStaminaProgress = 0;
+ if (m_fMaxStamina < 1000.0f)
+ m_fMaxStamina += 10.0f;
+ }
+}
+
+void
+CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
+{
+ if (m_nPedState == PED_SNIPER_MODE) {
+ RestorePreviousState();
+ TheCamera.ClearPlayerWeaponMode();
+ }
+ SetCurrentWeapon(weapon);
+
+ GetWeapon()->m_nAmmoInClip = min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
+
+ if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
+ ClearWeaponTarget();
+
+ CAnimBlendAssociation *weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_AnimToPlay);
+ if (weaponAnim) {
+ weaponAnim->SetRun();
+ weaponAnim->flags |= ASSOC_FADEOUTWHENDONE;
+ }
+ TheCamera.ClearPlayerWeaponMode();
+}
+
+void
+CPlayerPed::ReApplyMoveAnims(void)
+{
+ static AnimationId moveAnims[] = { ANIM_WALK, ANIM_RUN, ANIM_SPRINT, ANIM_IDLE_STANCE, ANIM_WALK_START };
+
+ for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) {
+ CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]);
+ if (curMoveAssoc) {
+ if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
+ CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]);
+ newMoveAssoc->blendDelta = curMoveAssoc->blendDelta;
+ newMoveAssoc->blendAmount = curMoveAssoc->blendAmount;
+ curMoveAssoc->blendDelta = -1000.0f;
+ curMoveAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::SetInitialState(void)
+{
+ m_bAdrenalineActive = false;
+ m_nAdrenalineTime = 0;
+ CTimer::SetTimeStep(1.0f);
+ m_pSeekTarget = nil;
+ m_vecSeekPos = { 0.0f, 0.0f, 0.0f };
+ m_fleeFromPosX = 0.0f;
+ m_fleeFromPosY = 0.0f;
+ m_fleeFrom = nil;
+ m_fleeTimer = 0;
+ m_objective = OBJECTIVE_NONE;
+ m_prevObjective = OBJECTIVE_NONE;
+ bUsesCollision = true;
+ ClearAimFlag();
+ ClearLookFlag();
+ bIsPointingGunAt = false;
+ bRenderPedInCar = true;
+ if (m_pFire)
+ m_pFire->Extinguish();
+ RpAnimBlendClumpRemoveAllAssociations(GetClump());
+ m_nPedState = PED_IDLE;
+ SetMoveState(PEDMOVE_STILL);
+ m_nLastPedState = PED_NONE;
+ m_animGroup = ASSOCGRP_PLAYER;
+ m_fMoveSpeed = 0.0f;
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ bIsPedDieAnimPlaying = false;
+ SetRealMoveAnim();
+ m_bCanBeDamaged = true;
+ m_pedStats->m_temper = 50;
+ m_fWalkAngle = 0.0f;
+}
+
+void
+CPlayerPed::SetRealMoveAnim(void)
+{
+ CAnimBlendAssociation *curWalkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK);
+ CAnimBlendAssociation *curRunAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN);
+ CAnimBlendAssociation *curSprintAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
+ CAnimBlendAssociation *curWalkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START);
+ CAnimBlendAssociation *curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
+ CAnimBlendAssociation *curRunStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
+ CAnimBlendAssociation *curRunStopRAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
+ if (bResetWalkAnims) {
+ if (curWalkAssoc)
+ curWalkAssoc->SetCurrentTime(0.0f);
+ if (curRunAssoc)
+ curRunAssoc->SetCurrentTime(0.0f);
+ if (curSprintAssoc)
+ curSprintAssoc->SetCurrentTime(0.0f);
+ bResetWalkAnims = false;
+ }
+
+ if (!curIdleAssoc)
+ curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
+ if (!curIdleAssoc)
+ curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+
+ if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) {
+
+ if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) {
+ if (curRunStopAssoc) {
+ curRunStopAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curRunStopAssoc->blendAmount = 1.0f;
+ curRunStopAssoc->blendDelta = -8.0f;
+ } else if (curRunStopRAssoc) {
+ curRunStopRAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curRunStopRAssoc->blendAmount = 1.0f;
+ curRunStopRAssoc->blendDelta = -8.0f;
+ }
+
+ RestoreHeadingRate();
+ if (!curIdleAssoc) {
+ if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ nil, true, false, false, false, false, false)) {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f);
+
+ } else {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
+ }
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
+ }
+ curIdleAssoc->blendAmount = 0.0f;
+ curIdleAssoc->blendDelta = 8.0f;
+
+ } else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
+ if (!curIdleAssoc) {
+ if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ nil, true, false, false, false, false, false)) {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
+
+ } else {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+ }
+
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
+ }
+
+ if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_IDLE_TIRED) {
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+
+ } else if (m_nPedState != PED_FIGHT) {
+ if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_IDLE_TIRED
+ && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
+
+ } else if (curIdleAssoc->animId != ANIM_IDLE_STANCE) {
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+ }
+ }
+
+ m_nMoveState = PEDMOVE_STILL;
+ } else {
+ if (curIdleAssoc) {
+ if (curWalkStartAssoc) {
+ curWalkStartAssoc->blendAmount = 1.0f;
+ curWalkStartAssoc->blendDelta = 0.0f;
+ } else {
+ curWalkStartAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK_START);
+ }
+ if (curWalkAssoc)
+ curWalkAssoc->SetCurrentTime(0.0f);
+ if (curRunAssoc)
+ curRunAssoc->SetCurrentTime(0.0f);
+
+ delete curIdleAssoc;
+ delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
+ delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ delete curSprintAssoc;
+
+ curSprintAssoc = nil;
+ m_nMoveState = PEDMOVE_WALK;
+ }
+ if (curRunStopAssoc) {
+ delete curRunStopAssoc;
+ RestoreHeadingRate();
+ }
+ if (curRunStopRAssoc) {
+ delete curRunStopRAssoc;
+ RestoreHeadingRate();
+ }
+ if (!curWalkAssoc) {
+ curWalkAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK);
+ curWalkAssoc->blendAmount = 0.0f;
+ }
+ if (!curRunAssoc) {
+ curRunAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_RUN);
+ curRunAssoc->blendAmount = 0.0f;
+ }
+ if (curWalkStartAssoc && !(curWalkStartAssoc->IsRunning())) {
+ delete curWalkStartAssoc;
+ curWalkStartAssoc = nil;
+ curWalkAssoc->SetRun();
+ curRunAssoc->SetRun();
+ }
+ if (m_nMoveState == PEDMOVE_SPRINT) {
+ if (m_fCurrentStamina < 0.0f && (m_fCurrentStamina <= -150.0f || !curSprintAssoc || curSprintAssoc->blendDelta < 0.0f))
+ m_nMoveState = PEDMOVE_STILL;
+
+ if (curWalkStartAssoc)
+ m_nMoveState = PEDMOVE_STILL;
+ }
+
+ if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) {
+ if (curSprintAssoc->blendAmount == 0.0f) {
+ curSprintAssoc->blendDelta = -1000.0f;
+ curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
+
+ } else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) {
+ if (m_fMoveSpeed < 0.4f) {
+ AnimationId runStopAnim;
+ if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double
+ runStopAnim = ANIM_RUN_STOP;
+ else
+ runStopAnim = ANIM_RUN_STOP_R;
+ CAnimBlendAssociation* newRunStopAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, runStopAnim);
+ newRunStopAssoc->blendAmount = 1.0f;
+ newRunStopAssoc->SetDeleteCallback(RestoreHeadingRateCB, this);
+ m_headingRate = 0.0f;
+ curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curSprintAssoc->blendDelta = -1000.0f;
+ curWalkAssoc->flags &= ~ASSOC_RUNNING;
+ curWalkAssoc->blendAmount = 0.0f;
+ curWalkAssoc->blendDelta = 0.0f;
+ curRunAssoc->flags &= ~ASSOC_RUNNING;
+ curRunAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendDelta = 0.0f;
+ } else if (curSprintAssoc->blendDelta >= 0.0f) {
+
+ // Stop sprinting when tired
+ curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curSprintAssoc->blendDelta = -1.0f;
+ curRunAssoc->blendDelta = 1.0f;
+ }
+ } else if (m_fMoveSpeed < 1.0f) {
+ curSprintAssoc->blendDelta = -8.0f;
+ curRunAssoc->blendDelta = 8.0f;
+ }
+ } else if (curWalkStartAssoc) {
+ curWalkAssoc->flags &= ~ASSOC_RUNNING;
+ curRunAssoc->flags &= ~ASSOC_RUNNING;
+ curWalkAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendAmount = 0.0f;
+
+ } else if (m_nMoveState == PEDMOVE_SPRINT) {
+ if (curSprintAssoc) {
+ if (curSprintAssoc->blendDelta < 0.0f) {
+ curSprintAssoc->blendDelta = 2.0f;
+ curRunAssoc->blendDelta = -2.0f;
+ }
+ } else {
+ curWalkAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendAmount = 1.0f;
+ curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f);
+ }
+ UseSprintEnergy();
+ } else {
+ if (m_fMoveSpeed < 1.0f) {
+ curWalkAssoc->blendAmount = 1.0f;
+ curRunAssoc->blendAmount = 0.0f;
+ m_nMoveState = PEDMOVE_WALK;
+ } else if (m_fMoveSpeed < 2.0f) {
+ curWalkAssoc->blendAmount = 2.0f - m_fMoveSpeed;
+ curRunAssoc->blendAmount = m_fMoveSpeed - 1.0f;
+ m_nMoveState = PEDMOVE_RUN;
+ } else {
+ curWalkAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendAmount = 1.0f;
+ m_nMoveState = PEDMOVE_RUN;
+ }
+ }
+ }
+ }
+ if (m_bAdrenalineActive) {
+ if (CTimer::GetTimeInMilliseconds() > m_nAdrenalineTime) {
+ m_bAdrenalineActive = false;
+ CTimer::SetTimeScale(1.0f);
+ if (curWalkStartAssoc)
+ curWalkStartAssoc->speed = 1.0f;
+ if (curWalkAssoc)
+ curWalkAssoc->speed = 1.0f;
+ if (curRunAssoc)
+ curRunAssoc->speed = 1.0f;
+ if (curSprintAssoc)
+ curSprintAssoc->speed = 1.0f;
+ } else {
+ CTimer::SetTimeScale(1.0f / 3);
+ if (curWalkStartAssoc)
+ curWalkStartAssoc->speed = 2.0f;
+ if (curWalkAssoc)
+ curWalkAssoc->speed = 2.0f;
+ if (curRunAssoc)
+ curRunAssoc->speed = 2.0f;
+ if (curSprintAssoc)
+ curSprintAssoc->speed = 2.0f;
+ }
+ }
+}
+
+void
+CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
+{
+ if (m_fCurrentStamina < m_fMaxStamina)
+ m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f;
+}
+
+bool
+CPlayerPed::DoWeaponSmoothSpray(void)
+{
+ if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
+ eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN ||
+ weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
+ return true;
+ }
+ return false;
+}
+
+void
+CPlayerPed::DoStuffToGoOnFire(void)
+{
+ if (m_nPedState == PED_SNIPER_MODE)
+ TheCamera.ClearPlayerWeaponMode();
+}
+
+bool
+CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
+{
+ CVector distVec = target - GetPosition();
+
+ if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange)
+ return true;
+
+ if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_AK47)
+ return false;
+
+ distVec.Normalise();
+
+ if (DotProduct(distVec,GetForward()) < 0.4f)
+ return true;
+
+ return false;
+}
+
+// Cancels landing anim while running & jumping? I think
+void
+CPlayerPed::RunningLand(CPad *padUsed)
+{
+ CAnimBlendAssociation *landAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_LAND);
+ if (landAssoc && landAssoc->currentTime == 0.0f && m_fMoveSpeed > 1.5f
+ && padUsed && (padUsed->GetPedWalkLeftRight() != 0.0f || padUsed->GetPedWalkUpDown() != 0.0f)) {
+
+ landAssoc->blendDelta = -1000.0f;
+ landAssoc->flags |= ASSOC_DELETEFADEDOUT;
+
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAND)->SetFinishCallback(FinishJumpCB, this);
+
+ if (m_nPedState == PED_JUMP)
+ RestorePreviousState();
+ }
+}
+
+bool
+CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
+{
+ if (suspect->m_pPointGunAt == this)
+ return true;
+
+ switch (suspect->m_objective) {
+ case OBJECTIVE_KILL_CHAR_ON_FOOT:
+ case OBJECTIVE_KILL_CHAR_ANY_MEANS:
+ if (suspect->m_pedInObjective == this)
+ return true;
+
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void
+CPlayerPed::PlayerControlSniper(CPad *padUsed)
+{
+ ProcessWeaponSwitch(padUsed);
+ TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
+
+ if (!padUsed->GetTarget()) {
+ RestorePreviousState();
+ TheCamera.ClearPlayerWeaponMode();
+ }
+
+ if (padUsed->WeaponJustDown()) {
+ CVector firePos(0.0f, 0.0f, 0.6f);
+ firePos = GetMatrix() * firePos;
+ GetWeapon()->Fire(this, &firePos);
+ }
+ GetWeapon()->Update(m_audioEntityId);
+}
+
+// I think R* also used goto in here.
+void
+CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
+{
+ if (CDarkel::FrenzyOnGoing())
+ goto switchDetectDone;
+
+ if (padUsed->CycleWeaponRightJustDown() && !m_pPointGunAt) {
+
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
+
+ for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) {
+ if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
+ goto switchDetectDone;
+ }
+ }
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ }
+ } else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) {
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
+
+ for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
+ if (m_nSelectedWepSlot < WEAPONTYPE_UNARMED)
+ m_nSelectedWepSlot = WEAPONTYPE_DETONATOR;
+
+ if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
+ goto switchDetectDone;
+ }
+ }
+ }
+ } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) {
+ if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) {
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
+
+ for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
+ if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && HasWeapon(WEAPONTYPE_BASEBALLBAT)
+ || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE) {
+ goto switchDetectDone;
+ }
+ }
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ }
+ }
+ }
+
+switchDetectDone:
+ if (m_nSelectedWepSlot != m_currentWeapon) {
+ if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT)
+ MakeChangesForNewWeapon(m_nSelectedWepSlot);
+ }
+}
+
+void
+CPlayerPed::PlayerControlM16(CPad *padUsed)
+{
+ ProcessWeaponSwitch(padUsed);
+ TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
+
+ if (!padUsed->GetTarget()) {
+ RestorePreviousState();
+ TheCamera.ClearPlayerWeaponMode();
+ }
+
+ if (padUsed->GetWeapon()) {
+ CVector firePos(0.0f, 0.0f, 0.6f);
+ firePos = GetMatrix() * firePos;
+ GetWeapon()->Fire(this, &firePos);
+ }
+ GetWeapon()->Update(m_audioEntityId);
+}
+
+void
+CPlayerPed::PlayerControlFighter(CPad *padUsed)
+{
+ float leftRight = padUsed->GetPedWalkLeftRight();
+ float upDown = padUsed->GetPedWalkUpDown();
+ float padMove = CVector2D(leftRight, upDown).Magnitude();
+
+ if (padMove > 0.0f) {
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
+ m_takeAStepAfterAttack = padMove > 2 * PAD_MOVE_TO_GAME_WORLD_MOVE;
+ if (padUsed->GetSprint() && padMove > 1 * PAD_MOVE_TO_GAME_WORLD_MOVE)
+ bIsAttacking = false;
+ }
+
+ if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy && padUsed->JumpJustDown()) {
+ if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
+ SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ } else {
+ SetJump();
+ }
+ }
+}
+
+void
+CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
+{
+ float leftRight = padUsed->GetPedWalkLeftRight();
+ float upDown = padUsed->GetPedWalkUpDown();
+ float padMove = CVector2D(leftRight, upDown).Magnitude();
+ float padMoveInGameUnit = padMove / PAD_MOVE_TO_GAME_WORLD_MOVE;
+ if (padMoveInGameUnit > 0.0f) {
+#ifdef FREE_CAM
+ if (!CCamera::bFreeCam)
+ m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
+ else
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
+#else
+ m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
+#endif
+ m_fMoveSpeed = min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed);
+ } else {
+ m_fMoveSpeed = 0.0f;
+ }
+
+ if (m_nPedState == PED_JUMP) {
+ if (bIsInTheAir) {
+ if (bUsesCollision && !bHitSteepSlope &&
+ (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
+ && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
+
+ float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
+ float angleCos = Cos(m_fRotationCur);
+ ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
+ }
+ } else if (bIsLanding) {
+ m_fMoveSpeed = 0.0f;
+ }
+ }
+ if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->GetSprint()) {
+ m_nMoveState = PEDMOVE_SPRINT;
+ }
+ if (m_nPedState != PED_FIGHT)
+ SetRealMoveAnim();
+
+ if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+ ClearAttack();
+ ClearWeaponTarget();
+ if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
+ SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ } else {
+ SetJump();
+ }
+ }
+}
+
+void
+CPlayerPed::KeepAreaAroundPlayerClear(void)
+{
+ BuildPedLists();
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ CPed *nearPed = m_nearPeds[i];
+ if (nearPed->CharCreatedBy == RANDOM_CHAR && !nearPed->DyingOrDead()) {
+ if (nearPed->GetIsOnScreen()) {
+ if (nearPed->m_objective == OBJECTIVE_NONE) {
+ nearPed->SetFindPathAndFlee(this, 5000, true);
+ } else {
+ if (nearPed->EnteringCar())
+ nearPed->QuitEnteringCar();
+
+ nearPed->ClearObjective();
+ }
+ } else {
+ nearPed->FlagToDestroyWhenNextProcessed();
+ }
+ }
+ }
+ CVector playerPos = (InVehicle() ? m_pMyVehicle->GetPosition() : GetPosition());
+
+ CVector pos = GetPosition();
+ int16 lastVehicle;
+ CEntity *vehicles[8];
+ CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+
+ for (int i = 0; i < lastVehicle; i++) {
+ CVehicle *veh = (CVehicle*)vehicles[i];
+ if (veh->VehicleCreatedBy != MISSION_VEHICLE) {
+ if (veh->m_status != STATUS_PLAYER && veh->m_status != STATUS_PLAYER_DISABLED) {
+ if ((veh->GetPosition() - playerPos).MagnitudeSqr() > 25.0f) {
+ veh->AutoPilot.m_nTempAction = TEMPACT_WAIT;
+ veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 5000;
+ } else {
+ if (DotProduct2D(playerPos - veh->GetPosition(), veh->GetForward()) > 0.0f)
+ veh->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
+ else
+ veh->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+
+ veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
+ }
+ CCarCtrl::PossiblyRemoveVehicle(veh);
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft)
+{
+ CVector distVec = candidate->GetPosition() - GetPosition();
+ if (distVec.Magnitude2D() <= distLimit) {
+ if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
+#ifdef VC_PED_PORTS
+ float angleBetweenUs = CGeneral::GetATanOfXY(candidate->GetPosition().x - TheCamera.GetPosition().x,
+ candidate->GetPosition().y - TheCamera.GetPosition().y);
+#else
+ float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
+#endif
+ angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
+ float closeness;
+ if (lookToLeft) {
+ closeness = angleBetweenUs > 0.0f ? -Abs(angleBetweenUs) : -100000.0f;
+ } else {
+ closeness = angleBetweenUs > 0.0f ? -100000.0f : -Abs(angleBetweenUs);
+ }
+
+ if (closeness > *lastCloseness) {
+ *targetPtr = candidate;
+ *lastCloseness = closeness;
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool priority)
+{
+ CVector distVec = candidate->GetPosition() - GetPosition();
+ float dist = distVec.Magnitude2D();
+ if (dist <= distLimit) {
+ if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
+ float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
+ angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
+
+ float closeness = -dist - 5.0f * Abs(angleBetweenUs);
+ if (priority) {
+ closeness += 5.0f;
+ }
+
+ if (closeness > *lastCloseness) {
+ *targetPtr = candidate;
+ *lastCloseness = closeness;
+ }
+ }
+ }
+}
+
+bool
+CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
+{
+ CEntity *nextTarget = nil;
+ float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
+ // nextTarget = nil;
+ float lastCloseness = -10000.0f;
+ // unused
+ // CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
+ CVector distVec = previousTarget->GetPosition() - GetPosition();
+ float referenceBeta = CGeneral::GetATanOfXY(distVec.x, distVec.y);
+
+ for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
+ CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
+ if (pedToCheck) {
+ if (pedToCheck != FindPlayerPed() && pedToCheck != previousTarget) {
+ if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
+ && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
+
+ EvaluateNeighbouringTarget(pedToCheck, &nextTarget, &lastCloseness,
+ weaponRange, referenceBeta, lookToLeft);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
+ CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
+ if (obj)
+ EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft);
+ }
+ if (!nextTarget)
+ return false;
+
+ m_pPointGunAt = nextTarget;
+ if (nextTarget)
+ nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
+ SetPointGunAt(nextTarget);
+ return true;
+}
+
+bool
+CPlayerPed::FindWeaponLockOnTarget(void)
+{
+ CEntity *nextTarget = nil;
+ float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
+
+ if (m_pPointGunAt) {
+ CVector distVec = m_pPointGunAt->GetPosition() - GetPosition();
+ if (distVec.Magnitude2D() > weaponRange) {
+ m_pPointGunAt = nil;
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ // nextTarget = nil;
+ float lastCloseness = -10000.0f;
+ float referenceBeta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
+ for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
+ CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
+ if (pedToCheck) {
+ if (pedToCheck != FindPlayerPed()) {
+ if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
+ && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
+
+ EvaluateTarget(pedToCheck, &nextTarget, &lastCloseness,
+ weaponRange, referenceBeta, IsThisPedAttackingPlayer(pedToCheck));
+ }
+ }
+ }
+ }
+ for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
+ CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
+ if (obj)
+ EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, false);
+ }
+ if (!nextTarget)
+ return false;
+
+ m_pPointGunAt = nextTarget;
+ if (nextTarget)
+ nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
+ SetPointGunAt(nextTarget);
+ return true;
+}
+
+void
+CPlayerPed::ProcessAnimGroups(void)
+{
+ AssocGroupId groupToSet;
+ if ((m_fWalkAngle <= -DEGTORAD(50.0f) || m_fWalkAngle >= DEGTORAD(50.0f))
+ && TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()
+ && CanStrafeOrMouseControl()) {
+
+ if (m_fWalkAngle >= -DEGTORAD(130.0f) && m_fWalkAngle <= DEGTORAD(130.0f)) {
+ if (m_fWalkAngle > 0.0f) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ groupToSet = ASSOCGRP_ROCKETLEFT;
+ else
+ groupToSet = ASSOCGRP_PLAYERLEFT;
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ groupToSet = ASSOCGRP_ROCKETRIGHT;
+ else
+ groupToSet = ASSOCGRP_PLAYERRIGHT;
+ }
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ groupToSet = ASSOCGRP_ROCKETBACK;
+ else
+ groupToSet = ASSOCGRP_PLAYERBACK;
+ }
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
+ groupToSet = ASSOCGRP_PLAYERROCKET;
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT) {
+ groupToSet = ASSOCGRP_PLAYERBBBAT;
+ } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI) {
+ if (!GetWeapon()->IsType2Handed()) {
+ groupToSet = ASSOCGRP_PLAYER;
+ } else {
+ groupToSet = ASSOCGRP_PLAYER2ARMED;
+ }
+ } else {
+ groupToSet = ASSOCGRP_PLAYER1ARMED;
+ }
+ }
+ }
+
+ if (m_animGroup != groupToSet) {
+ m_animGroup = groupToSet;
+ ReApplyMoveAnims();
+ }
+}
+
+void
+CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
+{
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ if (m_bHasLockOnTarget && !m_pPointGunAt) {
+ TheCamera.ClearPlayerWeaponMode();
+ CWeaponEffects::ClearCrossHair();
+ ClearPointGunAt();
+ }
+ if (!m_pFire) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER ||
+ GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
+ if (padUsed->TargetJustDown()) {
+ SetStoredState();
+ m_nPedState = PED_SNIPER_MODE;
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+ m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
+ SetHeading(m_fRotationCur);
+ }
+#endif
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_ROCKETLAUNCHER, 0, 0);
+ else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE)
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SNIPER, 0, 0);
+ else
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0);
+
+ m_fMoveSpeed = 0.0f;
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 1000.0f);
+ }
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE
+ || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON)
+ return;
+ }
+ }
+
+ if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) {
+ if (m_nSelectedWepSlot == m_currentWeapon) {
+ if (m_pPointGunAt) {
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f)
+ StartFightAttack(padUsed->GetWeapon());
+ else
+#endif
+ SetAttack(m_pPointGunAt);
+ } else if (m_currentWeapon != WEAPONTYPE_UNARMED) {
+ if (m_nPedState == PED_ATTACK) {
+ if (padUsed->WeaponJustDown()) {
+ m_bHaveTargetSelected = true;
+ } else if (!m_bHaveTargetSelected) {
+ field_1376 += CTimer::GetTimeStepNonClipped();
+ }
+ } else {
+ field_1376 = 0.0f;
+ m_bHaveTargetSelected = false;
+ }
+ SetAttack(nil);
+ } else if (padUsed->WeaponJustDown()) {
+ if (m_fMoveSpeed < 1.0f)
+ StartFightAttack(padUsed->GetWeapon());
+ else
+ SetAttack(nil);
+ }
+ }
+ } else {
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
+ if (m_nPedState == PED_ATTACK) {
+ m_bHaveTargetSelected = true;
+ bIsAttacking = false;
+ }
+ }
+
+#ifdef FREE_CAM
+ // Rotate player/arm when shooting. We don't have auto-rotation anymore
+ if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam &&
+ m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+
+ // Weapons except throwable and melee ones
+ if (weaponInfo->m_bCanAim || weaponInfo->m_b1stPerson || weaponInfo->m_bExpands) {
+ if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || padUsed->GetWeapon()) {
+ float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
+
+ // On this one we can rotate arm.
+ if (weaponInfo->m_bCanAimWithArm) {
+ if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
+ SetPointGunAt(nil);
+ bIsPointingGunAt = false; // to not stop after attack
+ }
+
+ SetLookFlag(limitedCam, true);
+ SetAimFlag(limitedCam);
+#ifdef VC_PED_PORTS
+ SetLookTimer(INT_MAX); // removing this makes head move for real, but I experinced some bugs.
+#endif
+ } else {
+ m_fRotationDest = limitedCam;
+ m_headingRate = 50.0f;
+
+ // Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly)
+ if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) {
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ float limitedRotDest = m_fRotationDest;
+
+ if (m_fRotationCur - PI > m_fRotationDest) {
+ limitedRotDest += 2 * PI;
+ } else if (PI + m_fRotationCur < m_fRotationDest) {
+ limitedRotDest -= 2 * PI;
+ }
+
+ m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2;
+ }
+ }
+ } else if (weaponInfo->m_bCanAimWithArm)
+ ClearPointGunAt();
+ else
+ RestoreHeadingRate();
+ }
+ }
+#endif
+
+ if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+ if (m_pPointGunAt) {
+ // what??
+ if (!m_pPointGunAt
+#ifdef FREE_CAM
+ || (!CCamera::bFreeCam && CCamera::m_bUseMouse3rdPerson)
+#else
+ || CCamera::m_bUseMouse3rdPerson
+#endif
+ || m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->bInVehicle) {
+ ClearWeaponTarget();
+ return;
+ }
+ if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon())) {
+ ClearWeaponTarget();
+ return;
+ }
+ if (m_pPointGunAt) {
+ if (padUsed->ShiftTargetLeftJustDown())
+ FindNextWeaponLockOnTarget(m_pPointGunAt, true);
+ if (padUsed->ShiftTargetRightJustDown())
+ FindNextWeaponLockOnTarget(m_pPointGunAt, false);
+ }
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SYPHON, 0, 0);
+ TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition());
+ }
+#ifdef FREE_CAM
+ else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson)) {
+#else
+ else if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) {
+#endif
+ if (padUsed->TargetJustDown())
+ FindWeaponLockOnTarget();
+ }
+ } else if (m_pPointGunAt) {
+ ClearWeaponTarget();
+ }
+
+ if (m_pPointGunAt) {
+#ifndef VC_PED_PORTS
+ CVector markPos = m_pPointGunAt->GetPosition();
+#else
+ CVector markPos;
+ if (m_pPointGunAt->IsPed()) {
+ ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition((RwV3d*)markPos, PED_MID);
+ } else {
+ markPos = m_pPointGunAt->GetPosition();
+ }
+#endif
+ if (bCanPointGunAtTarget) {
+ CWeaponEffects::MarkTarget(markPos, 64, 0, 0, 255, 0.8f);
+ } else {
+ CWeaponEffects::MarkTarget(markPos, 64, 32, 0, 255, 0.8f);
+ }
+ }
+ m_bHasLockOnTarget = m_pPointGunAt != nil;
+}
+
+void
+CPlayerPed::PlayerControlZelda(CPad *padUsed)
+{
+ bool doSmoothSpray = DoWeaponSmoothSpray();
+ float camOrientation = TheCamera.Orientation;
+ float leftRight = padUsed->GetPedWalkLeftRight();
+ float upDown = padUsed->GetPedWalkUpDown();
+ float padMoveInGameUnit;
+ bool smoothSprayWithoutMove = false;
+
+ if (doSmoothSpray && upDown > 0.0f) {
+ padMoveInGameUnit = 0.0f;
+ smoothSprayWithoutMove = true;
+ } else {
+ padMoveInGameUnit = CVector2D(leftRight, upDown).Magnitude() / PAD_MOVE_TO_GAME_WORLD_MOVE;
+ }
+
+ if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
+ float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
+ float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
+ if (doSmoothSpray) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45
+ || GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI)
+ m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 80.0f) * CTimer::GetTimeStep();
+ else
+ m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 128.0f) * CTimer::GetTimeStep();
+ } else {
+ m_fRotationDest = neededTurn;
+ }
+
+ float maxAcc = 0.07f * CTimer::GetTimeStep();
+ m_fMoveSpeed = min(padMoveInGameUnit, m_fMoveSpeed + maxAcc);
+
+ } else {
+ m_fMoveSpeed = 0.0f;
+ }
+
+ if (m_nPedState == PED_JUMP) {
+ if (bIsInTheAir) {
+ if (bUsesCollision && !bHitSteepSlope &&
+ (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
+ && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
+
+ float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
+ float angleCos = Cos(m_fRotationCur);
+ ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
+ }
+ } else if (bIsLanding) {
+ m_fMoveSpeed = 0.0f;
+ }
+ }
+
+ if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->GetSprint()) {
+ m_nMoveState = PEDMOVE_SPRINT;
+ }
+ if (m_nPedState != PED_FIGHT)
+ SetRealMoveAnim();
+
+ if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+ ClearAttack();
+ ClearWeaponTarget();
+ if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
+ SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ } else {
+ SetJump();
+ }
+ }
+}
+
+void
+CPlayerPed::ProcessControl(void)
+{
+ if (m_nEvadeAmount != 0)
+ --m_nEvadeAmount;
+
+ if (m_nEvadeAmount == 0)
+ m_pEvadingFrom = nil;
+
+ if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
+ bTryingToReachDryLand = true;
+ } else if (!(((uint8)CTimer::GetFrameCounter() + m_randomSeed) & 0xF)) {
+ CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil,
+ false, true, false, false, false, false);
+ if (nearVeh && nearVeh->IsBoat())
+ bTryingToReachDryLand = true;
+ else
+ bTryingToReachDryLand = false;
+ }
+ CPed::ProcessControl();
+ if (bWasPostponed)
+ return;
+
+ CPad *padUsed = CPad::GetPad(0);
+ m_pWanted->Update();
+ CEntity::PruneReferences();
+
+ if (m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT)
+ RestoreSprintEnergy(1.0f);
+ else if (m_nMoveState == PEDMOVE_RUN)
+ RestoreSprintEnergy(0.3f);
+
+ if (m_nPedState == PED_DEAD) {
+ ClearWeaponTarget();
+ return;
+ }
+ if (m_nPedState == PED_DIE) {
+ ClearWeaponTarget();
+ if (CTimer::GetTimeInMilliseconds() > m_bloodyFootprintCountOrDeathTime + 4000)
+ SetDead();
+ return;
+ }
+ if (m_nPedState == PED_DRIVING && m_objective != OBJECTIVE_LEAVE_VEHICLE) {
+ if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) {
+ CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR);
+ if (!rollDoorAssoc) {
+ rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW);
+ }
+
+ // These comparisons are wrong, they return uint16
+ if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || padUsed
+ && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f
+ || padUsed->GetBrake() != 0.0f)) {
+
+ if (rollDoorAssoc)
+ m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime);
+ } else {
+ m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
+ if (m_pMyVehicle->bLowVehicle)
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW);
+ else
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR);
+
+ rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
+ }
+ }
+ return;
+ }
+ if (m_objective == OBJECTIVE_NONE)
+ m_nMoveState = PEDMOVE_STILL;
+ if (bIsLanding)
+ RunningLand(padUsed);
+ if (padUsed && padUsed->WeaponJustDown() && m_nPedState != PED_SNIPER_MODE) {
+
+ // ...Really?
+ eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType;
+ if (playerWeapon == WEAPONTYPE_SNIPERRIFLE) {
+ DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0);
+ } else if (playerWeapon == WEAPONTYPE_ROCKETLAUNCHER) {
+ DMAudio.PlayFrontEndSound(SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, 0);
+ }
+ }
+
+ switch (m_nPedState) {
+ case PED_NONE:
+ case PED_IDLE:
+ case PED_FLEE_POS:
+ case PED_FLEE_ENTITY:
+ case PED_ATTACK:
+ case PED_FIGHT:
+ case PED_AIM_GUN:
+ if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FLAG400)) {
+ if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+ if (padUsed)
+ PlayerControl1stPersonRunAround(padUsed);
+ } else if (m_nPedState == PED_FIGHT) {
+ if (padUsed)
+ PlayerControlFighter(padUsed);
+ } else if (padUsed) {
+ PlayerControlZelda(padUsed);
+ }
+ }
+ if (IsPedInControl() && padUsed)
+ ProcessPlayerWeapon(padUsed);
+ break;
+ case PED_LOOK_ENTITY:
+ case PED_LOOK_HEADING:
+ case PED_WANDER_RANGE:
+ case PED_WANDER_PATH:
+ case PED_PURSUE:
+ case PED_FOLLOW_PATH:
+ case PED_ROCKET_ODE:
+ case PED_DUMMY:
+ case PED_PAUSE:
+ case PED_FACE_PHONE:
+ case PED_MAKE_CALL:
+ case PED_CHAT:
+ case PED_MUG:
+ case PED_AI_CONTROL:
+ case PED_FOLLOW_ROUTE:
+ case PED_CPR:
+ case PED_SOLICIT:
+ case PED_BUY_ICECREAM:
+ case PED_INVESTIGATE:
+ case PED_STEP_AWAY:
+ case PED_ON_FIRE:
+ case PED_UNKNOWN:
+ case PED_STATES_NO_AI:
+ case PED_STAGGER:
+ case PED_DIVE_AWAY:
+ case PED_STATES_NO_ST:
+ case PED_ARREST_PLAYER:
+ case PED_DRIVING:
+ case PED_PASSENGER:
+ case PED_TAXI_PASSENGER:
+ case PED_OPEN_DOOR:
+ case PED_DIE:
+ case PED_DEAD:
+ case PED_HANDS_UP:
+ break;
+ case PED_SEEK_ENTITY:
+ m_vecSeekPos = m_pSeekTarget->GetPosition();
+
+ // fall through
+ case PED_SEEK_POS:
+ switch (m_nMoveState) {
+ case PEDMOVE_WALK:
+ m_fMoveSpeed = 1.0f;
+ break;
+ case PEDMOVE_RUN:
+ m_fMoveSpeed = 1.8f;
+ break;
+ case PEDMOVE_SPRINT:
+ m_fMoveSpeed = 2.5f;
+ break;
+ default:
+ m_fMoveSpeed = 0.0f;
+ break;
+ }
+ SetRealMoveAnim();
+ if (Seek()) {
+ RestorePreviousState();
+ SetMoveState(PEDMOVE_STILL);
+ }
+ break;
+ case PED_SNIPER_MODE:
+ if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
+ if (padUsed)
+ PlayerControlM16(padUsed);
+ } else if (padUsed) {
+ PlayerControlSniper(padUsed);
+ }
+ break;
+ case PED_SEEK_CAR:
+ case PED_SEEK_IN_BOAT:
+ if (bVehEnterDoorIsBlocked || bKindaStayInSamePlace) {
+ m_fMoveSpeed = 0.0f;
+ } else {
+ m_fMoveSpeed = min(2.0f, 2.0f * (m_vecSeekPos - GetPosition()).Magnitude2D());
+ }
+ if (padUsed && !padUsed->ArePlayerControlsDisabled()) {
+ if (padUsed->GetTarget() || padUsed->GetLeftStickXJustDown() || padUsed->GetLeftStickYJustDown() ||
+ padUsed->GetDPadUpJustDown() || padUsed->GetDPadDownJustDown() || padUsed->GetDPadLeftJustDown() ||
+ padUsed->GetDPadRightJustDown()) {
+
+ RestorePreviousState();
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ RestorePreviousObjective();
+ }
+ }
+ }
+ if (padUsed && padUsed->GetSprint())
+ m_nMoveState = PEDMOVE_SPRINT;
+ SetRealMoveAnim();
+ break;
+ case PED_JUMP:
+ if (padUsed)
+ PlayerControlZelda(padUsed);
+ if (bIsLanding)
+ break;
+
+ // This has been added later it seems
+ return;
+ case PED_FALL:
+ case PED_GETUP:
+ case PED_ENTER_TRAIN:
+ case PED_EXIT_TRAIN:
+ case PED_CARJACK:
+ case PED_DRAG_FROM_CAR:
+ case PED_ENTER_CAR:
+ case PED_STEAL_CAR:
+ case PED_EXIT_CAR:
+ ClearWeaponTarget();
+ break;
+ case PED_ARRESTED:
+ if (m_nLastPedState == PED_DRAG_FROM_CAR && m_pVehicleAnim)
+ BeingDraggedFromCar();
+ break;
+ }
+ if (padUsed && IsPedShootable()) {
+ ProcessWeaponSwitch(padUsed);
+ GetWeapon()->Update(m_audioEntityId);
+ }
+ ProcessAnimGroups();
+ if (padUsed) {
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FOLLOWPED
+ && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_BEHIND) {
+
+ m_lookTimer = 0;
+ float camAngle = CGeneral::LimitRadianAngle(TheCamera.Cams[TheCamera.ActiveCam].Front.Heading());
+ float angleBetweenPlayerAndCam = Abs(camAngle - m_fRotationCur);
+ if (m_nPedState != PED_ATTACK
+ && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) {
+
+ if (angleBetweenPlayerAndCam > DEGTORAD(150.0f) && angleBetweenPlayerAndCam < DEGTORAD(210.0f)) {
+ float rightTurnAngle = CGeneral::LimitRadianAngle(m_fRotationCur - DEGTORAD(150.0f));
+ float leftTurnAngle = CGeneral::LimitRadianAngle(DEGTORAD(150.0f) + m_fRotationCur);
+ if (m_fLookDirection != 999999.0f) {
+ if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection))
+ camAngle = rightTurnAngle;
+ else
+ camAngle = leftTurnAngle;
+ } else {
+ camAngle = rightTurnAngle;
+ }
+ }
+ SetLookFlag(camAngle, true);
+ SetLookTimer(CTimer::GetTimeStepInMilliseconds() * 5.0f);
+ } else {
+ ClearLookFlag();
+ }
+ }
+ }
+ if (m_nMoveState == PEDMOVE_SPRINT && bIsLooking) {
+ ClearLookFlag();
+ SetLookTimer(250);
+ }
+
+ if (m_vecMoveSpeed.Magnitude2D() < 0.1f) {
+ if (m_nSpeedTimer) {
+ if (CTimer::GetTimeInMilliseconds() > m_nSpeedTimer)
+ m_bSpeedTimerFlag = true;
+ } else {
+ m_nSpeedTimer = CTimer::GetTimeInMilliseconds() + 500;
+ }
+ } else {
+ m_nSpeedTimer = 0;
+ m_bSpeedTimerFlag = false;
+ }
+}
+
+#include <new>
+
+class CPlayerPed_ : public CPlayerPed
+{
+public:
+ CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); }
+ void dtor(void) { CPlayerPed::~CPlayerPed(); }
+ void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); }
+ void ProcessControl_(void) { CPlayerPed::ProcessControl(); }
+};
+
+STARTPATCHES
+ InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP);
+ InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
+ InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP);
+ InjectHook(0x4EFD90, &CPlayerPed_::ProcessControl_, PATCH_JUMP);
+ InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
+ InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
+ InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
+ InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP);
+ InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP);
+ InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP);
+ InjectHook(0x4F1810, &CPlayerPed::PlayerControlFighter, PATCH_JUMP);
+ InjectHook(0x4F1340, &CPlayerPed::RestoreSprintEnergy, PATCH_JUMP);
+ InjectHook(0x4F1380, &CPlayerPed::DoWeaponSmoothSpray, PATCH_JUMP);
+ InjectHook(0x4F36E0, &CPlayerPed::DoStuffToGoOnFire, PATCH_JUMP);
+ InjectHook(0x4F3350, &CPlayerPed::DoesTargetHaveToBeBroken, PATCH_JUMP);
+ InjectHook(0x4F31D0, &CPlayerPed::RunningLand, PATCH_JUMP);
+ InjectHook(0x4F2D00, &CPlayerPed::IsThisPedAttackingPlayer, PATCH_JUMP);
+ InjectHook(0x4F1CF0, &CPlayerPed::PlayerControlSniper, PATCH_JUMP);
+ InjectHook(0x4F2310, &CPlayerPed::ProcessWeaponSwitch, PATCH_JUMP);
+ InjectHook(0x4F1DF0, &CPlayerPed::PlayerControlM16, PATCH_JUMP);
+ InjectHook(0x4F3460, &CPlayerPed::KeepAreaAroundPlayerClear, PATCH_JUMP);
+ InjectHook(0x4F1970, &CPlayerPed::PlayerControl1stPersonRunAround, PATCH_JUMP);
+ InjectHook(0x4F1EF0, &CPlayerPed::ProcessPlayerWeapon, PATCH_JUMP);
+ InjectHook(0x4F2640, &CPlayerPed::ProcessAnimGroups, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index 3bf81066..6959487f 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -29,39 +29,54 @@
#define PED_REMOVE_DIST (MIN_CREATION_DIST + CREATION_RANGE + 1.0f)
#define PED_REMOVE_DIST_SPECIAL (MIN_CREATION_DIST + CREATION_RANGE + 15.0f) // for peds with bCullExtraFarAway flag
-// TO-DO: These are hard-coded, reverse them.
-// More clearly they're transition areas between zones.
-RegenerationPoint (&aSafeZones)[8] = *(RegenerationPoint(*)[8]) * (uintptr*)0x5FA578;
-
-//PedGroup (&CPopulation::ms_pPedGroups)[NUMPEDGROUPS] = *(PedGroup(*)[NUMPEDGROUPS]) * (uintptr*)0x6E9248;
-PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS];
-bool &CPopulation::ms_bGivePedsWeapons = *(bool*)0x95CCF6;
-int32 &CPopulation::m_AllRandomPedsThisType = *(int32*)0x5FA570;
-float &CPopulation::PedDensityMultiplier = *(float*)0x5FA56C;
-uint32 &CPopulation::ms_nTotalMissionPeds = *(uint32*)0x8F5F70;
-int32 &CPopulation::MaxNumberOfPedsInUse = *(int32*)0x5FA574;
-uint32& CPopulation::ms_nNumCivMale = *(uint32*)0x8F2548;
-uint32& CPopulation::ms_nNumCivFemale = *(uint32*)0x8F5F44;
-uint32& CPopulation::ms_nNumCop = *(uint32*)0x885AFC;
-bool& CPopulation::bZoneChangeHasHappened = *(bool*)0x95CD79;
-uint32& CPopulation::ms_nNumEmergency = *(uint32*)0x94071C;
-int8& CPopulation::m_CountDownToPedsAtStart = *(int8*)0x95CD4F;
-uint32& CPopulation::ms_nNumGang1 = *(uint32*)0x8F1B1C;
-uint32& CPopulation::ms_nNumGang2 = *(uint32*)0x8F1B14;
-uint32& CPopulation::ms_nTotalPeds = *(uint32*)0x95CB50;
-uint32& CPopulation::ms_nNumGang3 = *(uint32*)0x8F2548;
-uint32& CPopulation::ms_nTotalGangPeds = *(uint32*)0x885AF0;
-uint32& CPopulation::ms_nNumGang4 = *(uint32*)0x8F1B2C;
-uint32& CPopulation::ms_nTotalCivPeds = *(uint32*)0x8F2C3C;
-uint32& CPopulation::ms_nNumGang5 = *(uint32*)0x8F1B30;
-uint32& CPopulation::ms_nNumDummy = *(uint32*)0x8F1A98;
-uint32& CPopulation::ms_nNumGang6 = *(uint32*)0x8F1B20;
-uint32& CPopulation::ms_nNumGang9 = *(uint32*)0x8F1B10;
-uint32& CPopulation::ms_nNumGang7 = *(uint32*)0x8F1B28;
-uint32& CPopulation::ms_nNumGang8 = *(uint32*)0x8F1B0C;
-CVector &CPopulation::RegenerationPoint_a = *(CVector*)0x8E2AA4;
-CVector &CPopulation::RegenerationPoint_b = *(CVector*)0x8E2A98;
-CVector &CPopulation::RegenerationForward = *(CVector*)0x8F1AD4;
+// Transition areas between zones
+const RegenerationPoint aSafeZones[] = {
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 400.0f, 814.0f, -954.0f, -903.0f, 30.0f, 100.0f,
+ CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(439.0f, -938.0f, 38.0f) },
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 555.0f, 711.0f, 118.0f, 186.0f, -30.0f, -10.0f,
+ CVector(698.0f, 182.0f, -20.0f), CVector(681.0f, 178.0f, -20.0f), CVector(586.0f, 144.0f, -20.0f), CVector(577.0f, 135.0f, -20.0f) },
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 26.0f, 44.0f, 124.0f, 87.0f, 20.0f, 6.0f,
+ CVector(736.0f, -117.0f, -13.0f), CVector(730.0f, -115.0f, -13.0f), CVector(635.0f, -93.0f, -12.5f), CVector(650.0f, -89.0f, -12.5f) },
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 45.0f, 34.0f, 780.0f, 750.0f, 25.0f, 6.0f,
+ CVector(729.0f, -764.0f, -18.0f), CVector(720.0f, -769.0f, -17.0f), CVector(652.0f, -774.0f, -10.5f), CVector(659.0f, -770.0f, -10.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 532.0f, 136.0f, 668.0f, 599.0f, 4.0f, 0.0f,
+ CVector(-172.0f, -619.0f, 44.0f), CVector(-183.0f, -623.0f, 44.0f), CVector(-511.0f, -645.0f, 41.0f), CVector(-493.0f, -639.0f, 41.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 325.0f, 175.0f, 7.0f, 5.0f, 30.0f, 10.0f,
+ CVector(-185.0f, 40.8f, -20.5f), CVector(-202.0f, 37.0f, -20.5f), CVector(-315.0f, 65.5f, -20.5f), CVector(-306.0f, 62.4f, -20.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 410.0f, 310.0f, 1055.0f, 1030.0f, 20.0f, 6.0f,
+ CVector(-321.0f, -1043.0f, -13.2f), CVector(-328.0f, -1045.0f, -13.2f), CVector(-398.0f, -1044.0f, -13.5f), CVector(-390.0f, -1040.5f, -13.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 425.0f, 280.0f, 471.0f, 447.0f, 20.0f, 5.0f,
+ CVector(-292.0f, -457.0f, -11.6f), CVector(-310.0f, -461.0f, -11.6f), CVector(-413.0f, -461.0f, -11.5f), CVector(-399.0f, -457.0f, -11.3f) }
+}; // *(RegenerationPoint(*)[8]) * (uintptr*)0x5FA578;
+
+PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS]; // = *(PedGroup(*)[NUMPEDGROUPS]) * (uintptr*)0x6E9248;
+bool CPopulation::ms_bGivePedsWeapons; // = *(bool*)0x95CCF6;
+int32 CPopulation::m_AllRandomPedsThisType = -1; // = *(int32*)0x5FA570;
+float CPopulation::PedDensityMultiplier = 1.0f; // = *(float*)0x5FA56C;
+uint32 CPopulation::ms_nTotalMissionPeds; // = *(uint32*)0x8F5F70;
+int32 CPopulation::MaxNumberOfPedsInUse = 25; // *(int32*)0x5FA574;
+uint32 CPopulation::ms_nNumCivMale; // = *(uint32*)0x8F2548;
+uint32 CPopulation::ms_nNumCivFemale; // = *(uint32*)0x8F5F44;
+uint32 CPopulation::ms_nNumCop; // = *(uint32*)0x885AFC;
+bool CPopulation::bZoneChangeHasHappened; // = *(bool*)0x95CD79;
+uint32 CPopulation::ms_nNumEmergency; // = *(uint32*)0x94071C;
+int8 CPopulation::m_CountDownToPedsAtStart; // = *(int8*)0x95CD4F;
+uint32 CPopulation::ms_nNumGang1; // = *(uint32*)0x8F1B1C;
+uint32 CPopulation::ms_nNumGang2; // = *(uint32*)0x8F1B14;
+uint32 CPopulation::ms_nTotalPeds; // = *(uint32*)0x95CB50;
+uint32 CPopulation::ms_nNumGang3; // = *(uint32*)0x8F2548;
+uint32 CPopulation::ms_nTotalGangPeds; // = *(uint32*)0x885AF0;
+uint32 CPopulation::ms_nNumGang4; // = *(uint32*)0x8F1B2C;
+uint32 CPopulation::ms_nTotalCivPeds; // = *(uint32*)0x8F2C3C;
+uint32 CPopulation::ms_nNumGang5; // = *(uint32*)0x8F1B30;
+uint32 CPopulation::ms_nNumDummy; // = *(uint32*)0x8F1A98;
+uint32 CPopulation::ms_nNumGang6; // = *(uint32*)0x8F1B20;
+uint32 CPopulation::ms_nNumGang9; // = *(uint32*)0x8F1B10;
+uint32 CPopulation::ms_nNumGang7; // = *(uint32*)0x8F1B28;
+uint32 CPopulation::ms_nNumGang8; // = *(uint32*)0x8F1B0C;
+CVector CPopulation::RegenerationPoint_a; // = *(CVector*)0x8E2AA4;
+CVector CPopulation::RegenerationPoint_b; // = *(CVector*)0x8E2A98;
+CVector CPopulation::RegenerationForward; // = *(CVector*)0x8F1AD4;
void
CPopulation::Initialise()
@@ -704,12 +719,15 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (i != 0) {
// Gang member
newPed->SetLeader(gangLeader);
+#ifndef FIX_BUGS
+ // seems to be a miami leftover (this code is not on PS2) but gang peds end up just being frozen
newPed->m_nPedState = PED_UNKNOWN;
gangLeader->m_nPedState = PED_UNKNOWN;
newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints(
gangLeader->GetPosition().x, gangLeader->GetPosition().y,
newPed->GetPosition().x, newPed->GetPosition().y);
newPed->m_fRotationDest = newPed->m_fRotationCur;
+#endif
} else {
gangLeader = newPed;
}
@@ -964,7 +982,7 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy)
} else if (obj->m_modelIndex == MI_BUOY) {
obj->bIsStatic = false;
obj->m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f);
- obj->m_flagD8 = true;
+ obj->bTouchingWater = true;
obj->AddToMovingList();
}
}
diff --git a/src/peds/Population.h b/src/peds/Population.h
index f9e6c3b7..aa8129c0 100644
--- a/src/peds/Population.h
+++ b/src/peds/Population.h
@@ -34,33 +34,33 @@ class CPopulation
{
public:
static PedGroup ms_pPedGroups[NUMPEDGROUPS];
- static bool &ms_bGivePedsWeapons;
- static int32 &m_AllRandomPedsThisType;
- static float &PedDensityMultiplier;
- static uint32 &ms_nTotalMissionPeds;
- static int32 &MaxNumberOfPedsInUse;
- static uint32& ms_nNumCivMale;
- static uint32 &ms_nNumCivFemale;
- static uint32 &ms_nNumCop;
- static bool &bZoneChangeHasHappened;
- static uint32 &ms_nNumEmergency;
- static int8& m_CountDownToPedsAtStart;
- static uint32& ms_nNumGang1;
- static uint32& ms_nNumGang2;
- static uint32& ms_nTotalPeds;
- static uint32& ms_nNumGang3;
- static uint32& ms_nTotalGangPeds;
- static uint32& ms_nNumGang4;
- static uint32& ms_nTotalCivPeds;
- static uint32& ms_nNumGang5;
- static uint32& ms_nNumDummy;
- static uint32& ms_nNumGang6;
- static uint32& ms_nNumGang9;
- static uint32& ms_nNumGang7;
- static uint32& ms_nNumGang8;
- static CVector& RegenerationPoint_a;
- static CVector& RegenerationPoint_b;
- static CVector& RegenerationForward;
+ static bool ms_bGivePedsWeapons;
+ static int32 m_AllRandomPedsThisType;
+ static float PedDensityMultiplier;
+ static uint32 ms_nTotalMissionPeds;
+ static int32 MaxNumberOfPedsInUse;
+ static uint32 ms_nNumCivMale;
+ static uint32 ms_nNumCivFemale;
+ static uint32 ms_nNumCop;
+ static bool bZoneChangeHasHappened;
+ static uint32 ms_nNumEmergency;
+ static int8 m_CountDownToPedsAtStart;
+ static uint32 ms_nNumGang1;
+ static uint32 ms_nNumGang2;
+ static uint32 ms_nTotalPeds;
+ static uint32 ms_nNumGang3;
+ static uint32 ms_nTotalGangPeds;
+ static uint32 ms_nNumGang4;
+ static uint32 ms_nTotalCivPeds;
+ static uint32 ms_nNumGang5;
+ static uint32 ms_nNumDummy;
+ static uint32 ms_nNumGang6;
+ static uint32 ms_nNumGang9;
+ static uint32 ms_nNumGang7;
+ static uint32 ms_nNumGang8;
+ static CVector RegenerationPoint_a;
+ static CVector RegenerationPoint_b;
+ static CVector RegenerationForward;
static void Initialise();
static void Update(void);
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp
index 2884894c..39866294 100644
--- a/src/render/Clouds.cpp
+++ b/src/render/Clouds.cpp
@@ -87,7 +87,7 @@ CClouds::Render(void)
RwV3d pos = { 0.0f, -100.0f, 15.0f };
RwV3dAdd(&worldpos, &campos, &pos);
if(CSprite::CalcScreenCoors(worldpos, &screenpos, &szx, &szy, false)){
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[2]->raster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[2]));
if(CCoronas::bSmallMoon){
szx *= 4.0f;
szy *= 4.0f;
@@ -116,7 +116,7 @@ CClouds::Render(void)
static float StarCoorsY[9] = { 0.0f, 0.45f, 0.9f, 1.0f, 0.85f, 0.52f, 0.48f, 0.35f, 0.2f };
static float StarSizes[9] = { 1.0f, 1.4f, 0.9f, 1.0f, 0.6f, 1.5f, 1.3f, 1.0f, 0.8f };
int brightness = (1.0f - coverage) * starintens;
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 11; i++){
RwV3d pos = { 100.0f, 0.0f, 10.0f };
if(i >= 9) pos.x = -pos.x;
@@ -132,7 +132,7 @@ CClouds::Render(void)
CSprite::FlushSpriteBuffer();
// *
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
RwV3d pos = { 100.0f, 0.0f, 10.0f };
RwV3dAdd(&worldpos, &campos, &pos);
worldpos.y -= 90.0f;
@@ -156,7 +156,7 @@ CClouds::Render(void)
int b = CTimeCycle::GetLowCloudsBlue() * lowcloudintensity;
for(int cloudtype = 0; cloudtype < 3; cloudtype++){
for(i = cloudtype; i < 12; i += 3){
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[cloudtype]->raster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[cloudtype]));
RwV3d pos = { 800.0f*LowCloudsX[i], 800.0f*LowCloudsY[i], 60.0f*LowCloudsZ[i] };
worldpos.x = campos.x + pos.x;
worldpos.y = campos.y + pos.y;
@@ -202,7 +202,7 @@ CClouds::Render(void)
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[4]->raster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[4]));
for(i = 0; i < 37; i++){
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
worldpos.x = pos.x*rot_cos + pos.y*rot_sin + campos.x;
@@ -244,7 +244,7 @@ CClouds::Render(void)
// Highlights
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCloudTex[3]->raster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCloudTex[3]));
for(i = 0; i < 37; i++){
RwV3d pos = { 2.0f*CoorsOffsetX[i], 2.0f*CoorsOffsetY[i], 40.0f*CoorsOffsetZ[i] + 40.0f };
@@ -269,7 +269,7 @@ CClouds::Render(void)
static uint8 BowRed[6] = { 30, 30, 30, 10, 0, 15 };
static uint8 BowGreen[6] = { 0, 15, 30, 30, 0, 0 };
static uint8 BowBlue[6] = { 0, 0, 0, 10, 30, 30 };
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCoronaTexture[0]->raster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[0]));
for(i = 0; i < 6; i++){
RwV3d pos = { i*1.5f, 100.0f, 5.0f };
RwV3dAdd(&worldpos, &campos, &pos);
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index c934540b..68994b0b 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -320,7 +320,7 @@ CCoronas::Render(void)
CSprite::RenderOneXLUSprite(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * aCoronas[i].size * wscale,
- spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale * hscale),
+ spriteh * aCoronas[i].size * fogscale * hscale,
CCoronas::aCoronas[i].red / fogscale,
CCoronas::aCoronas[i].green / fogscale,
CCoronas::aCoronas[i].blue / fogscale,
@@ -331,7 +331,7 @@ CCoronas::Render(void)
CSprite::RenderOneXLUSprite_Rotate_Aspect(
spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * aCoronas[i].size * fogscale,
- spriteh * SCREEN_SCALE_AR2(aCoronas[i].size * fogscale),
+ spriteh * aCoronas[i].size * fogscale,
CCoronas::aCoronas[i].red / fogscale,
CCoronas::aCoronas[i].green / fogscale,
CCoronas::aCoronas[i].blue / fogscale,
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index 8d7fad92..e2899532 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/Fluff.cpp
@@ -755,14 +755,14 @@ void CTowerClock::Render()
&TempV[1],
m_Position.x + Sin(angleMinute) * m_fScale * m_Size.x,
m_Position.y + Sin(angleMinute) * m_fScale * m_Size.y,
- m_Position.z + Cos(angleMinute) * m_fScale;
+ m_Position.z + Cos(angleMinute) * m_fScale
);
RwIm3DVertexSetPos(&TempV[2], m_Position.x, m_Position.y, m_Position.z);
RwIm3DVertexSetPos(
&TempV[3],
m_Position.x + Sin(angleHour) * 0.75f * m_fScale * m_Size.x,
m_Position.y + Sin(angleHour) * 0.75f * m_fScale * m_Size.y,
- m_Position.z + Cos(angleHour) * 0.75f * m_fScale;
+ m_Position.z + Cos(angleHour) * 0.75f * m_fScale
);
LittleTest();
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index 3c07039c..56a024a7 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -23,55 +23,47 @@
//wchar *CHud::m_HelpMessage = (wchar*)0x86B888;
//wchar *CHud::m_LastHelpMessage = (wchar*)0x6E8F28;
-wchar CHud::m_HelpMessage[256];
-wchar CHud::m_LastHelpMessage[256];
-
-int32 &CHud::m_HelpMessageState = *(int32*)0x880E1C;
-int32 &CHud::m_HelpMessageTimer = *(int32*)0x880FA4;
-int32 &CHud::m_HelpMessageFadeTimer = *(int32*)0x8F6258;
-wchar *CHud::m_HelpMessageToPrint = (wchar*)0x664480;
-float &CHud::m_HelpMessageDisplayTime = *(float*)0x8E2C28;
-float &CHud::m_fTextBoxNumLines = *(float*)0x8E2C28;
-float &CHud::m_fHelpMessageTime = *(float *)0x8E2C28;
-bool &CHud::m_HelpMessageQuick = *(bool *)0x95CCF7;
-int32 CHud::m_ZoneState = *(int32*)0x8F29AC;
+wchar CHud::m_HelpMessageToPrint[256]; // = (wchar*)0x664480;
+float CHud::m_fHelpMessageTime; // *(float *)0x8E2C28;
+bool CHud::m_HelpMessageQuick; // = *(bool*)0x95CCF7;
+uint32 CHud::m_ZoneState; // = *(int32*)0x8F29AC;
int32 CHud::m_ZoneFadeTimer;
-int32 CHud::m_ZoneNameTimer = *(int32*)0x8F1A50;
-wchar *&CHud::m_pZoneName = *(wchar **)0x8E2C2C;
-wchar *CHud::m_pLastZoneName = (wchar*)0x8F432C;
+uint32 CHud::m_ZoneNameTimer; // = *(int32*)0x8F1A50;
+wchar *CHud::m_pZoneName; // = *(wchar**)0x8E2C2C;
+wchar *CHud::m_pLastZoneName; // = (wchar*)0x8F432C;
wchar *CHud::m_ZoneToPrint;
-int32 CHud::m_VehicleState = *(int32*)0x940560;
+uint32 CHud::m_VehicleState; // = *(int32*)0x940560;
int32 CHud::m_VehicleFadeTimer;
-int32 CHud::m_VehicleNameTimer = *(int32*)0x8F2A14;
-wchar *&CHud::m_VehicleName = *(wchar **)0x942FB4;
-wchar *CHud::m_pLastVehicleName = *(wchar **)0x8E2DD8;
+uint32 CHud::m_VehicleNameTimer; // = *(int32*)0x8F2A14;
+wchar *CHud::m_VehicleName; // = *(wchar**)0x942FB4;
+wchar *CHud::m_pLastVehicleName; // = *(wchar**)0x8E2DD8;
wchar *CHud::m_pVehicleNameToPrint;
-wchar *CHud::m_Message = (wchar*)0x72E318;
-wchar *CHud::m_PagerMessage = (wchar*)0x878840;
-bool &CHud::m_Wants_To_Draw_Hud = *(bool*)0x95CD89;
-bool &CHud::m_Wants_To_Draw_3dMarkers = *(bool*)0x95CD62;
-wchar(&CHud::m_BigMessage)[6][128] = *(wchar(*)[6][128])*(uintptr*)0x664CE0;
-int16 &CHud::m_ItemToFlash = *(int16*)0x95CC82;
+wchar CHud::m_Message[256];// = (wchar*)0x72E318;
+wchar CHud::m_PagerMessage[256]; // = (wchar*)0x878840;
+bool CHud::m_Wants_To_Draw_Hud; // (bool*)0x95CD89;
+bool CHud::m_Wants_To_Draw_3dMarkers; // = *(bool*)0x95CD62;
+wchar CHud::m_BigMessage[6][128]; // = *(wchar(*)[6][128]) * (uintptr*)0x664CE0;
+int16 CHud::m_ItemToFlash; // = *(int16*)0x95CC82;
// These aren't really in CHud
float CHud::BigMessageInUse[6];
float CHud::BigMessageAlpha[6];
float CHud::BigMessageX[6];
-float &CHud::OddJob2OffTimer = *(float*)0x942FA0;
-int8 &CHud::CounterOnLastFrame = *(int8*)0x95CD67;
-float &CHud::OddJob2XOffset = *(float*)0x8F1B5C;
-int16 &CHud::CounterFlashTimer = *(int16*)0x95CC20;
-int16 &CHud::OddJob2Timer = *(int16*)0x95CC52;
-int8 &CHud::TimerOnLastFrame = *(int8*)0x95CDA7;
-int16 &CHud::OddJob2On = *(int16*)0x95CC78;
-int16 &CHud::TimerFlashTimer = *(int16*)0x95CC6C;
-int16 &CHud::PagerSoundPlayed = *(int16*)0x95CC4A;
-int32 &CHud::SpriteBrightness = *(int32*)0x95CC54;
-float &CHud::PagerXOffset = *(float*)0x941590;
-int16 &CHud::PagerTimer = *(int16*)0x95CC3A;
-int16 &CHud::PagerOn = *(int16*)0x95CCA0;
-
-CSprite2d *CHud::Sprites = (CSprite2d*)0x95CB9C;
+float CHud::OddJob2OffTimer; // = *(float*)0x942FA0;
+bool CHud::CounterOnLastFrame; // = *(int8*)0x95CD67;
+float CHud::OddJob2XOffset; // = *(float*)0x8F1B5C;
+uint16 CHud::CounterFlashTimer; // = *(int16*)0x95CC20;
+uint16 CHud::OddJob2Timer; // = *(int16*)0x95CC52;
+bool CHud::TimerOnLastFrame; //= *(int8*)0x95CDA7;
+int16 CHud::OddJob2On; //= *(int16*)0x95CC78;
+uint16 CHud::TimerFlashTimer; //= *(int16*)0x95CC6C;
+int16 CHud::PagerSoundPlayed; //= *(int16*)0x95CC4A;
+int32 CHud::SpriteBrightness; //= *(int32*)0x95CC54;
+float CHud::PagerXOffset; //= *(float*)0x941590;
+int16 CHud::PagerTimer; //= *(int16*)0x95CC3A;
+int16 CHud::PagerOn; //= *(int16*)0x95CCA0;
+
+CSprite2d CHud::Sprites[NUM_HUD_SPRITES]; // = (CSprite2d*)0x95CB9C;
struct
{
@@ -93,14 +85,14 @@ struct
{"detonator", "detonator_mask"},
{"", ""},
{"", ""},
- {"radardisc", "radardiscm"},
+ {"radardisc", "radardisc"},
{"pager", "pagerm"},
{"", ""},
{"", ""},
{"bleeder", ""},
{"sitesniper", "sitesniperm"},
{"siteM16", "siteM16m"},
- {"siterocket", "siterocketm"}
+ {"siterocket", "siterocket"}
};
RwTexture *&gpSniperSightTex = *(RwTexture**)0x8F5834;
@@ -418,7 +410,7 @@ void CHud::Draw()
DrawZoneName
*/
if (m_pZoneName) {
- float fZoneAlpha = 0.0f;
+ float fZoneAlpha = 255.0f;
if (m_pZoneName != m_pLastZoneName) {
switch (m_ZoneState) {
@@ -432,7 +424,7 @@ void CHud::Draw()
case 2:
case 3:
case 4:
- m_ZoneNameTimer = 0;
+ m_ZoneNameTimer = 5;
m_ZoneState = 4;
break;
default:
@@ -444,6 +436,7 @@ void CHud::Draw()
if (m_ZoneState) {
switch (m_ZoneState) {
case 1:
+ m_ZoneFadeTimer = 1000;
if (m_ZoneNameTimer > 10000) {
m_ZoneFadeTimer = 1000;
m_ZoneState = 3;
@@ -471,7 +464,6 @@ void CHud::Draw()
if (m_ZoneFadeTimer < 0) {
m_ZoneFadeTimer = 0;
m_ZoneToPrint = m_pLastZoneName;
- m_ZoneNameTimer = 0;
m_ZoneState = 2;
}
fZoneAlpha = m_ZoneFadeTimer * 0.001f * 255.0f;
@@ -503,12 +495,6 @@ void CHud::Draw()
}
}
}
- /*else {
- m_pLastZoneName = nil;
- m_ZoneState = 0;
- m_ZoneFadeTimer = 0;
- m_ZoneNameTimer = 0;
- }*/
/*
DrawVehicleName
@@ -636,9 +622,9 @@ void CHud::Draw()
wchar sTimer[16];
if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerProcessed)
- TimerOnLastFrame = 0;
+ TimerOnLastFrame = false;
if (!CUserDisplay::OnscnTimer.m_sEntries[0].m_bCounterProcessed)
- CounterOnLastFrame = 0;
+ CounterOnLastFrame = false;
#ifdef FIX_BUGS
#define TIMER_RIGHT_OFFSET 34.0f // Taken from VC frenzy timer
@@ -650,7 +636,7 @@ void CHud::Draw()
if (!TimerOnLastFrame)
TimerFlashTimer = 1;
- TimerOnLastFrame = 1;
+ TimerOnLastFrame = true;
if (TimerFlashTimer) {
if (++TimerFlashTimer > 50)
@@ -688,7 +674,7 @@ void CHud::Draw()
if (!CounterOnLastFrame)
CounterFlashTimer = 1;
- CounterOnLastFrame = 1;
+ CounterOnLastFrame = true;
if (CounterFlashTimer) {
if (++CounterFlashTimer > 50)
@@ -742,11 +728,9 @@ void CHud::Draw()
/*
DrawPager
*/
- if (!m_PagerMessage[0]) {
- if (PagerOn == 1) {
- PagerSoundPlayed = false;
- PagerOn = 2;
- }
+ if (!m_PagerMessage[0] && PagerOn == 1) {
+ PagerSoundPlayed = false;
+ PagerOn = 2;
}
if (m_PagerMessage[0] || PagerOn == 2) {
if (!PagerOn) {
@@ -755,7 +739,7 @@ void CHud::Draw()
}
if (PagerOn == 1) {
if (PagerXOffset > 0.0f) {
- float fStep = PagerXOffset * 0.05f;
+ float fStep = PagerXOffset * 0.1f;
if (fStep > 10.0f)
fStep = 10.0f;
PagerXOffset -= fStep * CTimer::GetTimeStep();
@@ -766,10 +750,10 @@ void CHud::Draw()
}
}
else if (PagerOn == 2) {
- float fStep = PagerXOffset * 0.05f;
+ float fStep = PagerXOffset * 0.1f;
if (fStep < 2.0f)
fStep = 2.0f;
- PagerXOffset += fStep * CTimer::GetTimeStep();
+ PagerXOffset += fStep;
if (PagerXOffset > 150.0f) {
PagerXOffset = 150.0f;
PagerOn = 0;
@@ -818,9 +802,7 @@ void CHud::Draw()
DrawScriptText
*/
if (!CTimer::GetIsUserPaused()) {
- CTextLine* IntroText = CTheScripts::IntroTextLines;
-
- for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) {
+ for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroTextLines); i++) {
if (CTheScripts::IntroTextLines[i].m_Text[0] && CTheScripts::IntroTextLines[i].m_bTextBeforeFade) {
CFont::SetScale(SCREEN_SCALE_X(CTheScripts::IntroTextLines[i].m_fScaleX), SCREEN_SCALE_Y(CTheScripts::IntroTextLines[i].m_fScaleY * 0.5f));
CFont::SetColor(CTheScripts::IntroTextLines[i].m_sColor);
@@ -861,31 +843,31 @@ void CHud::Draw()
CFont::SetPropOff();
CFont::SetFontStyle(FONTJAP(CTheScripts::IntroTextLines[i].m_nFont));
- CFont::PrintString(SCREEN_SCALE_X(640.0f - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(448.0f - CTheScripts::IntroTextLines[i].m_fAtY), IntroText->m_Text);
+ CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text);
}
}
+ for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) {
+ intro_script_rectangle &IntroRect = CTheScripts::IntroRectangles[i];
- CScriptRectangle* IntroRect = CTheScripts::IntroRectangles;
-
- for (int i = 0; i < 16; i++) {
- if (CTheScripts::IntroRectangles[i].m_bIsUsed && CTheScripts::IntroRectangles[i].m_bBeforeFade) {
- if (CTheScripts::IntroRectangles[i].m_nTextureId >= 0) {
+ // Yeah, top and bottom changed place. R* vision
+ if (IntroRect.m_bIsUsed && IntroRect.m_bBeforeFade) {
+ if (IntroRect.m_nTextureId >= 0) {
CRect rect = {
- CTheScripts::IntroRectangles[i].m_sRect.left,
- CTheScripts::IntroRectangles[i].m_sRect.bottom,
- CTheScripts::IntroRectangles[i].m_sRect.right,
- CTheScripts::IntroRectangles[i].m_sRect.bottom };
+ IntroRect.m_sRect.left,
+ IntroRect.m_sRect.top,
+ IntroRect.m_sRect.right,
+ IntroRect.m_sRect.bottom };
- CTheScripts::ScriptSprites[CTheScripts::IntroRectangles[i].m_nTextureId].Draw(rect, IntroRect->m_sColor);
+ CTheScripts::ScriptSprites[IntroRect.m_nTextureId].Draw(rect, IntroRect.m_sColor);
}
else {
CRect rect = {
- CTheScripts::IntroRectangles[i].m_sRect.left,
- CTheScripts::IntroRectangles[i].m_sRect.bottom,
- CTheScripts::IntroRectangles[i].m_sRect.right,
- CTheScripts::IntroRectangles[i].m_sRect.bottom };
+ IntroRect.m_sRect.left,
+ IntroRect.m_sRect.top,
+ IntroRect.m_sRect.right,
+ IntroRect.m_sRect.bottom };
- CSprite2d::DrawRect(rect, IntroRect->m_sColor);
+ CSprite2d::DrawRect(rect, IntroRect.m_sColor);
}
}
}
@@ -931,7 +913,7 @@ void CHud::Draw()
CFont::SetCentreSize(SCREEN_SCALE_X(615.0f));
CFont::SetFontStyle(FONT_HEADING);
- if (BigMessageX[0] >= (SCREEN_WIDTH - 20)) {
+ if (BigMessageX[0] >= SCREEN_SCALE_FROM_RIGHT(20.0f)) {
BigMessageInUse[0] += CTimer::GetTimeStep();
if (BigMessageInUse[0] >= 120.0f) {
@@ -948,7 +930,7 @@ void CHud::Draw()
BigMessageX[0] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
BigMessageAlpha[0] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
- if (BigMessageAlpha[0] >= 255.0f)
+ if (BigMessageAlpha[0] > 255.0f)
BigMessageAlpha[0] = 255.0f;
}
@@ -992,7 +974,7 @@ void CHud::Draw()
CFont::SetFontStyle(FONT_HEADING);
CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[2]));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f + 4.0f), SCREEN_SCALE_FROM_BOTTOM(78.0f), m_BigMessage[2]);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f - 4.0f), SCREEN_SCALE_FROM_BOTTOM(78.0f), m_BigMessage[2]);
CFont::SetColor(CRGBA(170, 123, 87, BigMessageAlpha[2]));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(82.0f), m_BigMessage[2]);
@@ -1021,7 +1003,7 @@ void CHud::DrawAfterFade()
m_HelpMessageState = 2;
m_HelpMessageTimer = 0;
CMessages::WideStringCopy(m_HelpMessageToPrint, m_HelpMessage, 256);
- m_HelpMessageDisplayTime = CMessages::GetWideStringLength(m_HelpMessage) * 0.05f + 3.0f;
+ m_fHelpMessageTime = CMessages::GetWideStringLength(m_HelpMessage) * 0.05f + 3.0f;
if (TheCamera.m_ScreenReductionPercentage == 0.0f)
DMAudio.PlayFrontEndSound(SOUND_A0, 0);
@@ -1039,14 +1021,14 @@ void CHud::DrawAfterFade()
CMessages::WideStringCopy(m_LastHelpMessage, m_HelpMessage, 256);
}
- float fAlpha = 255.0f;
+ float fAlpha = 225.0f;
- if (m_HelpMessageState) {
+ if (m_HelpMessageState != 0) {
switch (m_HelpMessageState) {
case 1:
- fAlpha = 255.0f;
+ fAlpha = 225.0f;
m_HelpMessageFadeTimer = 600;
- if (m_HelpMessageTimer > m_fHelpMessageTime * 1000 || m_HelpMessageQuick && m_HelpMessageTimer > 1500) {
+ if (m_HelpMessageTimer > m_fHelpMessageTime * 1000.0f || m_HelpMessageQuick && m_HelpMessageTimer > 1500.0f) {
m_HelpMessageFadeTimer = 600;
m_HelpMessageState = 3;
}
@@ -1057,24 +1039,24 @@ void CHud::DrawAfterFade()
m_HelpMessageState = 1;
m_HelpMessageFadeTimer = 0;
}
- fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f;
+ fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
break;
case 3:
m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
- if (m_HelpMessageFadeTimer >= 0) {
+ if (m_HelpMessageFadeTimer < 0) {
m_HelpMessageState = 0;
m_HelpMessageFadeTimer = 0;
}
- fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f;
+ fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
break;
case 4:
m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
- if (m_HelpMessageFadeTimer >= 0) {
+ if (m_HelpMessageFadeTimer < 0) {
m_HelpMessageState = 2;
m_HelpMessageFadeTimer = 0;
- CMessages::WideStringCopy(m_HelpMessageToPrint, m_LastHelpMessage, 400);
+ CMessages::WideStringCopy(m_HelpMessageToPrint, m_LastHelpMessage, 256);
}
- fAlpha = m_HelpMessageFadeTimer * 0.001f * 255.0f;
+ fAlpha = m_HelpMessageFadeTimer * 0.001f * 225.0f;
break;
default:
break;
@@ -1093,6 +1075,7 @@ void CHud::DrawAfterFade()
else
CFont::SetScale(SCREEN_SCALE_X(0.52f), SCREEN_SCALE_Y(1.1f));
+ CFont::SetColor(CRGBA(175, 175, 175, 255));
CFont::SetJustifyOff();
if (CFont::LanguageSet == FONT_LANGSET_JAPANESE)
CFont::SetWrapx(SCREEN_SCALE_X(229.0f + 26.0f - 4.0f));
@@ -1101,14 +1084,69 @@ void CHud::DrawAfterFade()
CFont::SetFontStyle(FONTJAP(FONT_BANK));
CFont::SetBackgroundOn();
CFont::SetBackGroundOnlyTextOff();
- CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.8f));
- CFont::SetColor(CRGBA(175, 175, 175, 255));
+ CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.9f));
CFont::PrintString(SCREEN_SCALE_X(26.0f), SCREEN_SCALE_Y(28.0f + (150.0f - PagerXOffset) * 0.6f), CHud::m_HelpMessageToPrint);
CFont::SetAlphaFade(255.0f);
}
}
- else
- m_HelpMessageState = 0;
+
+ for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroTextLines); i++) {
+ intro_text_line &line = CTheScripts::IntroTextLines[i];
+ if (line.m_Text[0] != '\0' && !line.m_bTextBeforeFade) {
+ CFont::SetScale(SCREEN_SCALE_X(line.m_fScaleX), SCREEN_SCALE_Y(line.m_fScaleY) / 2);
+
+ CFont::SetColor(line.m_sColor);
+ if (line.m_bJustify)
+ CFont::SetJustifyOn();
+ else
+ CFont::SetJustifyOff();
+
+ if (line.m_bRightJustify)
+ CFont::SetRightJustifyOn();
+ else
+ CFont::SetRightJustifyOff();
+
+ if (line.m_bCentered)
+ CFont::SetCentreOn();
+ else
+ CFont::SetCentreOff();
+
+ CFont::SetWrapx(SCREEN_SCALE_X(line.m_fWrapX));
+ CFont::SetCentreSize(SCREEN_SCALE_X(line.m_fCenterSize));
+ if (line.m_bBackground)
+ CFont::SetBackgroundOn();
+ else
+ CFont::SetBackgroundOff();
+
+ CFont::SetBackgroundColor(line.m_sBackgroundColor);
+ if (line.m_bBackgroundOnly)
+ CFont::SetBackGroundOnlyTextOn();
+ else
+ CFont::SetBackGroundOnlyTextOff();
+
+ if (line.m_bTextProportional)
+ CFont::SetPropOn();
+ else
+ CFont::SetPropOff();
+
+ CFont::SetFontStyle(line.m_nFont);
+ CFont::PrintString(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text);
+ }
+ }
+ for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) {
+ intro_script_rectangle &rectangle = CTheScripts::IntroRectangles[i];
+ if (rectangle.m_bIsUsed && !rectangle.m_bBeforeFade) {
+
+ // Yeah, top and bottom changed place. R* vision
+ if (rectangle.m_nTextureId >= 0) {
+ CTheScripts::ScriptSprites[rectangle.m_nTextureId].Draw(CRect(rectangle.m_sRect.left, rectangle.m_sRect.bottom,
+ rectangle.m_sRect.right, rectangle.m_sRect.top), rectangle.m_sColor);
+ } else {
+ CSprite2d::DrawRect(CRect(rectangle.m_sRect.left, rectangle.m_sRect.bottom,
+ rectangle.m_sRect.right, rectangle.m_sRect.top), rectangle.m_sColor);
+ }
+ }
+ }
/*
DrawBigMessage2
@@ -1150,10 +1188,9 @@ void CHud::DrawAfterFade()
if (OddJob2OffTimer > 0)
OddJob2OffTimer -= CTimer::GetTimeStepInMilliseconds();
- static float fStep;
+ float fStep;
if (m_BigMessage[5][0] && OddJob2OffTimer <= 0.0f) {
- if (OddJob2On <= 3) {
- switch (OddJob2On) {
+ switch (OddJob2On) {
case 0:
OddJob2On = 1;
OddJob2XOffset = 380.0f;
@@ -1164,9 +1201,7 @@ void CHud::DrawAfterFade()
OddJob2On = 2;
}
else {
- fStep = 40.0f;
- if ((OddJob2XOffset / 6.0f) <= 40.0f)
- fStep = OddJob2XOffset / 6.0f;
+ fStep = min(40.0f, OddJob2XOffset / 6.0f);
OddJob2XOffset = OddJob2XOffset - fStep;
}
break;
@@ -1177,9 +1212,7 @@ void CHud::DrawAfterFade()
}
break;
case 3:
- fStep = 30.0f;
- if ((OddJob2XOffset / 5.0f) >= 30.0f)
- fStep = OddJob2XOffset / 5.0f;
+ fStep = max(30.0f, OddJob2XOffset / 5.0f);
OddJob2XOffset = OddJob2XOffset - fStep;
@@ -1190,7 +1223,6 @@ void CHud::DrawAfterFade()
break;
default:
break;
- }
}
if (!m_BigMessage[1][0]) {
@@ -1224,10 +1256,10 @@ void CHud::DrawAfterFade()
CFont::SetScale(SCREEN_SCALE_X(1.04f), SCREEN_SCALE_Y(1.6f));
CFont::SetPropOn();
- CFont::SetRightJustifyWrap(-500.0f);
+ CFont::SetRightJustifyWrap(SCREEN_SCALE_X(-500.0f));
CFont::SetRightJustifyOn();
CFont::SetFontStyle(FONT_HEADING);
- if (BigMessageX[1] >= (SCREEN_WIDTH - 20)) {
+ if (BigMessageX[1] >= SCREEN_SCALE_FROM_RIGHT(20.0f)) {
BigMessageInUse[1] += CTimer::GetTimeStep();
if (BigMessageInUse[1] >= 120.0f) {
@@ -1238,12 +1270,11 @@ void CHud::DrawAfterFade()
m_BigMessage[1][0] = 0;
BigMessageAlpha[1] = 0.0f;
}
- }
- else {
+ } else {
BigMessageX[1] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
BigMessageAlpha[1] += (CTimer::GetTimeStepInMilliseconds() * 0.3f);
- if (BigMessageAlpha[1] >= 255.0f)
+ if (BigMessageAlpha[1] > 255.0f)
BigMessageAlpha[1] = 255.0f;
}
@@ -1281,7 +1312,7 @@ void CHud::GetRidOfAllHudMessages()
m_HelpMessageFadeTimer = 0;
m_HelpMessageState = 0;
m_HelpMessageQuick = 0;
- m_HelpMessageDisplayTime = 1.0f;
+ m_fHelpMessageTime = 1.0f;
m_VehicleName = nil;
m_pLastVehicleName = nil;
m_pVehicleNameToPrint = nil;
@@ -1311,7 +1342,7 @@ void CHud::Initialise()
CTxdStore::PopCurrentTxd();
CTxdStore::SetCurrentTxd(HudTXD);
- for (int i = 0; i < ARRAY_SIZE(WeaponFilenames); i++) {
+ for (int i = 0; i < NUM_HUD_SPRITES; i++) {
Sprites[i].SetTexture(WeaponFilenames[i].name, WeaponFilenames[i].mask);
}
@@ -1322,14 +1353,14 @@ void CHud::Initialise()
if (gpRocketSightTex == nil)
gpRocketSightTex = RwTextureRead("siterocket", nil);
- CounterOnLastFrame = 0;
+ CounterOnLastFrame = false;
m_ItemToFlash = ITEM_NONE;
OddJob2Timer = 0;
OddJob2OffTimer = 0.0f;
OddJob2On = 0;
OddJob2XOffset = 0.0f;
CounterFlashTimer = 0;
- TimerOnLastFrame = 0;
+ TimerOnLastFrame = false;
TimerFlashTimer = 0;
SpriteBrightness = 0;
PagerOn = 0;
@@ -1346,14 +1377,14 @@ void CHud::ReInitialise() {
GetRidOfAllHudMessages();
- CounterOnLastFrame = 0;
+ CounterOnLastFrame = false;
m_ItemToFlash = ITEM_NONE;
OddJob2Timer = 0;
OddJob2OffTimer = 0.0f;
OddJob2On = 0;
OddJob2XOffset = 0.0f;
CounterFlashTimer = 0;
- TimerOnLastFrame = 0;
+ TimerOnLastFrame = false;
TimerFlashTimer = 0;
SpriteBrightness = 0;
PagerOn = 0;
@@ -1443,7 +1474,7 @@ void CHud::SetZoneName(wchar *name)
void CHud::Shutdown()
{
- for (int i = 0; i < ARRAY_SIZE(WeaponFilenames); ++i) {
+ for (int i = 0; i < NUM_HUD_SPRITES; ++i) {
Sprites[i].Delete();
}
diff --git a/src/render/Hud.h b/src/render/Hud.h
index dad3a58d..701e47e2 100644
--- a/src/render/Hud.h
+++ b/src/render/Hud.h
@@ -27,59 +27,60 @@ enum eSprites
HUD_RADARDISC = 15,
HUD_PAGER = 16,
HUD_SITESNIPER = 20,
- HUD_SITEM16 = 21
+ HUD_SITEM16,
+ HUD_SITEROCKET,
+ NUM_HUD_SPRITES,
};
class CHud
{
public:
- static CSprite2d *Sprites;
- static int32 &SpriteBrightness;
+ static CSprite2d Sprites[NUM_HUD_SPRITES];
static wchar m_HelpMessage[256];
static wchar m_LastHelpMessage[256];
- static int32 &m_HelpMessageState;
- static int32 &m_HelpMessageTimer;
- static int32 &m_HelpMessageFadeTimer;
- static wchar *m_HelpMessageToPrint;
+ static uint32 m_HelpMessageState;
+ static uint32 m_HelpMessageTimer;
+ static int32 m_HelpMessageFadeTimer;
+ static wchar m_HelpMessageToPrint[256];
static float &m_HelpMessageDisplayTime;
- static float &m_fTextBoxNumLines;
- static float &m_fHelpMessageTime;
- static bool &m_HelpMessageQuick;
- static int32 m_ZoneState;
+ static float m_fHelpMessageTime;
+ static bool m_HelpMessageQuick;
+ static uint32 m_ZoneState;
static int32 m_ZoneFadeTimer;
- static int32 m_ZoneNameTimer;
- static wchar *&m_pZoneName;
+ static uint32 m_ZoneNameTimer;
+ static wchar *m_pZoneName;
static wchar *m_pLastZoneName;
static wchar *m_ZoneToPrint;
- static wchar *&m_VehicleName;
+ static wchar *m_VehicleName;
static wchar *m_pLastVehicleName;
static wchar *m_pVehicleNameToPrint;
- static int32 m_VehicleState;
+ static uint32 m_VehicleState;
static int32 m_VehicleFadeTimer;
- static int32 m_VehicleNameTimer;
- static wchar *m_Message;
- static wchar *m_PagerMessage;
- static bool &m_Wants_To_Draw_Hud;
- static bool &m_Wants_To_Draw_3dMarkers;
- static wchar(&m_BigMessage)[6][128];
- static int16 &m_ItemToFlash;
+ static uint32 m_VehicleNameTimer;
+ static wchar m_Message[256];
+ static wchar m_PagerMessage[256];
+ static bool m_Wants_To_Draw_Hud;
+ static bool m_Wants_To_Draw_3dMarkers;
+ static wchar m_BigMessage[6][128];
+ static int16 m_ItemToFlash;
// These aren't really in CHud
static float BigMessageInUse[6];
static float BigMessageAlpha[6];
static float BigMessageX[6];
- static float &OddJob2OffTimer;
- static int8 &CounterOnLastFrame;
- static float &OddJob2XOffset;
- static int16 &CounterFlashTimer;
- static int16 &OddJob2Timer;
- static int8 &TimerOnLastFrame;
- static int16 &OddJob2On;
- static int16 &TimerFlashTimer;
- static int16 &PagerSoundPlayed;
- static float &PagerXOffset;
- static int16 &PagerTimer;
- static int16 &PagerOn;
+ static float OddJob2OffTimer;
+ static bool CounterOnLastFrame;
+ static float OddJob2XOffset;
+ static uint16 CounterFlashTimer;
+ static uint16 OddJob2Timer;
+ static bool TimerOnLastFrame;
+ static int16 OddJob2On;
+ static uint16 TimerFlashTimer;
+ static int16 PagerSoundPlayed;
+ static int32 SpriteBrightness;
+ static float PagerXOffset;
+ static int16 PagerTimer;
+ static int16 PagerOn;
public:
static void Draw();
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
index 1cf27ee0..d28671fa 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -4,12 +4,13 @@
#include "Camera.h"
#include "MBlur.h"
+// Originally taken from RW example 'mblur'
+
RwRaster *&CMBlur::pFrontBuffer = *(RwRaster**)0x8E2C48;
bool &CMBlur::ms_bJustInitialised = *(bool*)0x95CDAB;
bool &CMBlur::BlurOn = *(bool*)0x95CDAD;
static RwIm2DVertex Vertex[4];
-//static RwIm2DVertex *Vertex = (RwIm2DVertex*)0x62F780;
static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 };
void
diff --git a/src/core/PlayerSkin.cpp b/src/render/PlayerSkin.cpp
index 4f730b90..2cba45fe 100644
--- a/src/core/PlayerSkin.cpp
+++ b/src/render/PlayerSkin.cpp
@@ -1,173 +1,174 @@
-#include "common.h"
-#include "patcher.h"
-#include "main.h"
-#include "PlayerSkin.h"
-#include "TxdStore.h"
-#include "rtbmp.h"
-#include "ClumpModelInfo.h"
-#include "VisibilityPlugins.h"
-#include "World.h"
-#include "PlayerInfo.h"
-#include "CdStream.h"
-#include "FileMgr.h"
-#include "Directory.h"
-#include "RwHelper.h"
-#include "Timer.h"
-#include "Lights.h"
-
-int CPlayerSkin::m_txdSlot;
-
-void
-FindPlayerDff(uint32 &offset, uint32 &size)
-{
- int file;
- CDirectory::DirectoryInfo info;
-
- file = CFileMgr::OpenFile("models\\gta3.dir", "rb");
-
- do {
- if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
- return;
- } while (strcasecmp("player.dff", info.name) != 0);
-
- offset = info.offset;
- size = info.size;
-}
-
-void
-LoadPlayerDff(void)
-{
- RwStream *stream;
- RwMemory mem;
- uint32 offset, size;
- uint8 *buffer;
- bool streamWasAdded = false;
-
- if (CdStreamGetNumImages() == 0) {
- CdStreamAddImage("models\\gta3.img");
- streamWasAdded = true;
- }
-
- FindPlayerDff(offset, size);
- buffer = (uint8*)RwMallocAlign(size << 11, 2048);
- CdStreamRead(0, buffer, offset, size);
- CdStreamSync(0);
-
- mem.start = buffer;
- mem.length = size << 11;
- stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
-
- if (RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
- gpPlayerClump = RpClumpStreamRead(stream);
-
- RwStreamClose(stream, &mem);
- RwFreeAlign(buffer);
-
- if (streamWasAdded)
- CdStreamRemoveImages();
-}
-
-void
-CPlayerSkin::Initialise(void)
-{
- m_txdSlot = CTxdStore::AddTxdSlot("skin");
- CTxdStore::Create(m_txdSlot);
- CTxdStore::AddRef(m_txdSlot);
-}
-
-void
-CPlayerSkin::Shutdown(void)
-{
- CTxdStore::RemoveTxdSlot(m_txdSlot);
-}
-
-RwTexture *
-CPlayerSkin::GetSkinTexture(const char *texName)
-{
- RwTexture *tex;
- RwRaster *raster;
- int32 width, height, depth, format;
-
- CTxdStore::PushCurrentTxd();
- CTxdStore::SetCurrentTxd(m_txdSlot);
- tex = RwTextureRead(texName, NULL);
- CTxdStore::PopCurrentTxd();
- if (tex) return tex;
-
- if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
- sprintf(gString, "models\\generic\\player.bmp");
- else
- sprintf(gString, "skins\\%s.bmp", texName);
-
- if (RwImage *image = RtBMPImageRead(gString)) {
- RwImageFindRasterFormat(image, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
- raster = RwRasterCreate(width, height, depth, format);
- RwRasterSetFromImage(raster, image);
-
- tex = RwTextureCreate(raster);
- RwTextureSetName(tex, texName);
- RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
- RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
-
- RwImageDestroy(image);
- }
- return tex;
-}
-
-void
-CPlayerSkin::BeginFrontendSkinEdit(void)
-{
- LoadPlayerDff();
- RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, CVisibilityPlugins::RenderPlayerCB);
- CWorld::Players[0].LoadPlayerSkin();
- gOldFov = CDraw::GetFOV();
- CDraw::SetFOV(30.0f);
-}
-
-void
-CPlayerSkin::EndFrontendSkinEdit(void)
-{
- RpClumpDestroy(gpPlayerClump);
- gpPlayerClump = NULL;
- CDraw::SetFOV(gOldFov);
-}
-
-void
-CPlayerSkin::RenderFrontendSkinEdit(void)
-{
- static float rotation = 0.0f;
- RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
- RwV3d pos = { 1.35f, 0.35f, 7.725f };
- const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
- const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
- static uint32 LastFlash = 0;
-
-#ifdef ASPECT_RATIO_SCALE
- pos.x = 1.35f * (SCREEN_ASPECT_RATIO / DEFAULT_ASPECT_RATIO);
-#endif
-
- RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
-
- if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 7) {
- rotation += 2.0f;
- if (rotation > 360.0f)
- rotation -= 360.0f;
- LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
- }
- RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
- RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
- RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
- RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
- RwFrameUpdateObjects(frame);
- SetAmbientColours(&AmbientColor);
- RpClumpRender(gpPlayerClump);
-}
-
-STARTPATCHES
-InjectHook(0x59B9B0, &CPlayerSkin::Initialise, PATCH_JUMP);
-InjectHook(0x59B9E0, &CPlayerSkin::Shutdown, PATCH_JUMP);
-InjectHook(0x59B9F0, &CPlayerSkin::GetSkinTexture, PATCH_JUMP);
-InjectHook(0x59BC70, &CPlayerSkin::BeginFrontendSkinEdit, PATCH_JUMP);
-InjectHook(0x59BCB0, &CPlayerSkin::EndFrontendSkinEdit, PATCH_JUMP);
-InjectHook(0x59BCE0, &CPlayerSkin::RenderFrontendSkinEdit, PATCH_JUMP);
+#include "common.h"
+#include "patcher.h"
+#include "main.h"
+#include "PlayerSkin.h"
+#include "TxdStore.h"
+#include "rtbmp.h"
+#include "ClumpModelInfo.h"
+#include "VisibilityPlugins.h"
+#include "World.h"
+#include "PlayerInfo.h"
+#include "CdStream.h"
+#include "FileMgr.h"
+#include "Directory.h"
+#include "RwHelper.h"
+#include "Timer.h"
+#include "Lights.h"
+
+RpClump *gpPlayerClump;
+float gOldFov;
+
+int CPlayerSkin::m_txdSlot;
+
+void
+FindPlayerDff(uint32 &offset, uint32 &size)
+{
+ int file;
+ CDirectory::DirectoryInfo info;
+
+ file = CFileMgr::OpenFile("models\\gta3.dir", "rb");
+
+ do {
+ if (!CFileMgr::Read(file, (char*)&info, sizeof(CDirectory::DirectoryInfo)))
+ return;
+ } while (strcasecmp("player.dff", info.name) != 0);
+
+ offset = info.offset;
+ size = info.size;
+}
+
+void
+LoadPlayerDff(void)
+{
+ RwStream *stream;
+ RwMemory mem;
+ uint32 offset, size;
+ uint8 *buffer;
+ bool streamWasAdded = false;
+
+ if (CdStreamGetNumImages() == 0) {
+ CdStreamAddImage("models\\gta3.img");
+ streamWasAdded = true;
+ }
+
+ FindPlayerDff(offset, size);
+ buffer = (uint8*)RwMallocAlign(size << 11, 2048);
+ CdStreamRead(0, buffer, offset, size);
+ CdStreamSync(0);
+
+ mem.start = buffer;
+ mem.length = size << 11;
+ stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
+
+ if (RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
+ gpPlayerClump = RpClumpStreamRead(stream);
+
+ RwStreamClose(stream, &mem);
+ RwFreeAlign(buffer);
+
+ if (streamWasAdded)
+ CdStreamRemoveImages();
+}
+
+void
+CPlayerSkin::Initialise(void)
+{
+ m_txdSlot = CTxdStore::AddTxdSlot("skin");
+ CTxdStore::Create(m_txdSlot);
+ CTxdStore::AddRef(m_txdSlot);
+}
+
+void
+CPlayerSkin::Shutdown(void)
+{
+ CTxdStore::RemoveTxdSlot(m_txdSlot);
+}
+
+RwTexture *
+CPlayerSkin::GetSkinTexture(const char *texName)
+{
+ RwTexture *tex;
+ RwRaster *raster;
+ int32 width, height, depth, format;
+
+ CTxdStore::PushCurrentTxd();
+ CTxdStore::SetCurrentTxd(m_txdSlot);
+ tex = RwTextureRead(texName, NULL);
+ CTxdStore::PopCurrentTxd();
+ if (tex != nil) return tex;
+
+ if (strcmp(DEFAULT_SKIN_NAME, texName) == 0)
+ sprintf(gString, "models\\generic\\player.bmp");
+ else
+ sprintf(gString, "skins\\%s.bmp", texName);
+
+ if (RwImage *image = RtBMPImageRead(gString)) {
+ RwImageFindRasterFormat(image, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
+ raster = RwRasterCreate(width, height, depth, format);
+ RwRasterSetFromImage(raster, image);
+
+ tex = RwTextureCreate(raster);
+ RwTextureSetName(tex, texName);
+#ifdef FIX_BUGS
+ RwTextureSetFilterMode(tex, rwFILTERLINEAR); // filtering bugfix from VC
+#endif
+ RwTexDictionaryAddTexture(CTxdStore::GetSlot(m_txdSlot)->texDict, tex);
+
+ RwImageDestroy(image);
+ }
+ return tex;
+}
+
+void
+CPlayerSkin::BeginFrontendSkinEdit(void)
+{
+ LoadPlayerDff();
+ RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, CVisibilityPlugins::RenderPlayerCB);
+ CWorld::Players[0].LoadPlayerSkin();
+ gOldFov = CDraw::GetFOV();
+ CDraw::SetFOV(30.0f);
+}
+
+void
+CPlayerSkin::EndFrontendSkinEdit(void)
+{
+ RpClumpDestroy(gpPlayerClump);
+ gpPlayerClump = NULL;
+ CDraw::SetFOV(gOldFov);
+}
+
+void
+CPlayerSkin::RenderFrontendSkinEdit(void)
+{
+ static float rotation = 0.0f;
+ RwRGBAReal AmbientColor = { 0.65f, 0.65f, 0.65f, 1.0f };
+ const RwV3d pos = { 1.35f, 0.35f, 7.725f };
+ const RwV3d axis1 = { 1.0f, 0.0f, 0.0f };
+ const RwV3d axis2 = { 0.0f, 0.0f, 1.0f };
+ static uint32 LastFlash = 0;
+
+ RwFrame *frame = RpClumpGetFrame(gpPlayerClump);
+
+ if (CTimer::GetTimeInMillisecondsPauseMode() - LastFlash > 7) {
+ rotation += 2.0f;
+ if (rotation > 360.0f)
+ rotation -= 360.0f;
+ LastFlash = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ RwFrameTransform(frame, RwFrameGetMatrix(RwCameraGetFrame(Scene.camera)), rwCOMBINEREPLACE);
+ RwFrameTranslate(frame, &pos, rwCOMBINEPRECONCAT);
+ RwFrameRotate(frame, &axis1, -90.0f, rwCOMBINEPRECONCAT);
+ RwFrameRotate(frame, &axis2, rotation, rwCOMBINEPRECONCAT);
+ RwFrameUpdateObjects(frame);
+ SetAmbientColours(&AmbientColor);
+ RpClumpRender(gpPlayerClump);
+}
+
+STARTPATCHES
+InjectHook(0x59B9B0, &CPlayerSkin::Initialise, PATCH_JUMP);
+InjectHook(0x59B9E0, &CPlayerSkin::Shutdown, PATCH_JUMP);
+InjectHook(0x59B9F0, &CPlayerSkin::GetSkinTexture, PATCH_JUMP);
+InjectHook(0x59BC70, &CPlayerSkin::BeginFrontendSkinEdit, PATCH_JUMP);
+InjectHook(0x59BCB0, &CPlayerSkin::EndFrontendSkinEdit, PATCH_JUMP);
+InjectHook(0x59BCE0, &CPlayerSkin::RenderFrontendSkinEdit, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/core/PlayerSkin.h b/src/render/PlayerSkin.h
index 2d82ec12..e0214ce0 100644
--- a/src/core/PlayerSkin.h
+++ b/src/render/PlayerSkin.h
@@ -2,12 +2,6 @@
#define DEFAULT_SKIN_NAME "$$\"\""
-static RpClump *gpPlayerClump;// = *(RpClump**)0x660FF8;
-static float gOldFov;// = *(float*)0x660FFC;
-
-void LoadPlayerDff(void);
-void FindPlayerDff(uint32 &offset, uint32 &size);
-
class CPlayerSkin
{
static int m_txdSlot;
diff --git a/src/render/Renderer.h b/src/render/Renderer.h
index 89fc23cb..42c154ec 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -29,7 +29,7 @@ class CRenderer
static CVehicle *&m_pFirstPersonVehicle;
public:
- static float &ms_lodDistScale; // defined in Frontend.cpp
+ static float ms_lodDistScale; // defined in Frontend.cpp
static bool &m_loadingPriority;
static void Init(void);
diff --git a/src/render/Rubbish.cpp b/src/render/Rubbish.cpp
index a52e59a0..65d8b2dd 100644
--- a/src/render/Rubbish.cpp
+++ b/src/render/Rubbish.cpp
@@ -1,10 +1,420 @@
#include "common.h"
+#include "main.h"
#include "patcher.h"
+#include "General.h"
+#include "Timer.h"
+#include "Weather.h"
+#include "Camera.h"
+#include "World.h"
+#include "Vehicle.h"
+#include "ZoneCull.h"
+#include "TxdStore.h"
+#include "RenderBuffer.h"
#include "Rubbish.h"
-WRAPPER void CRubbish::Render(void) { EAXJMP(0x512190); }
-WRAPPER void CRubbish::StirUp(CVehicle *veh) { EAXJMP(0x512690); }
-WRAPPER void CRubbish::Update(void) { EAXJMP(0x511B90); }
-WRAPPER void CRubbish::SetVisibility(bool) { EAXJMP(0x512AA0); }
-WRAPPER void CRubbish::Init(void) { EAXJMP(0x511940); }
-WRAPPER void CRubbish::Shutdown(void) { EAXJMP(0x511B50); }
+#define RUBBISH_MAX_DIST (18.0f)
+#define RUBBISH_FADE_DIST (16.5f)
+
+RwTexture *gpRubbishTexture[4];
+RwImVertexIndex RubbishIndexList[6];
+RwImVertexIndex RubbishIndexList2[6]; // unused
+RwIm3DVertex RubbishVertices[4];
+bool CRubbish::bRubbishInvisible;
+int CRubbish::RubbishVisibility;
+COneSheet CRubbish::aSheets[NUM_RUBBISH_SHEETS];
+COneSheet CRubbish::StartEmptyList;
+COneSheet CRubbish::EndEmptyList;
+COneSheet CRubbish::StartStaticsList;
+COneSheet CRubbish::EndStaticsList;
+COneSheet CRubbish::StartMoversList;
+COneSheet CRubbish::EndMoversList;
+
+
+void
+COneSheet::AddToList(COneSheet *list)
+{
+ this->m_next = list->m_next;
+ this->m_prev = list;
+ list->m_next = this;
+ this->m_next->m_prev = this;
+}
+
+void
+COneSheet::RemoveFromList(void)
+{
+ m_next->m_prev = m_prev;
+ m_prev->m_next = m_next;
+}
+
+
+void
+CRubbish::Render(void)
+{
+ int type;
+
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+
+ for(type = 0; type < 4; type++){
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
+
+ TempBufferIndicesStored = 0;
+ TempBufferVerticesStored = 0;
+
+ COneSheet *sheet;
+ for(sheet = &aSheets[type*NUM_RUBBISH_SHEETS / 4];
+ sheet < &aSheets[(type+1)*NUM_RUBBISH_SHEETS / 4];
+ sheet++){
+ if(sheet->m_state == 0)
+ continue;
+
+ uint32 alpha = 128;
+ CVector pos;
+ if(sheet->m_state == 1){
+ pos = sheet->m_basePos;
+ if(!sheet->m_isVisible)
+ alpha = 0;
+ }else{
+ pos = sheet->m_animatedPos;
+ // Not fully visible during animation, calculate current alpha
+ if(!sheet->m_isVisible || !sheet->m_targetIsVisible){
+ float t = (float)(CTimer::GetTimeInMilliseconds() - sheet->m_moveStart)/sheet->m_moveDuration;
+ float f1 = sheet->m_isVisible ? 1.0f-t : 0.0f;
+ float f2 = sheet->m_targetIsVisible ? t : 0.0f;
+ alpha = 128 * (f1+f2);
+ }
+ }
+
+ float camDist = (pos - TheCamera.GetPosition()).Magnitude2D();
+ if(camDist < RUBBISH_MAX_DIST){
+ if(camDist >= RUBBISH_FADE_DIST)
+ alpha -= alpha*(camDist-RUBBISH_FADE_DIST)/(RUBBISH_MAX_DIST-RUBBISH_FADE_DIST);
+ alpha = (RubbishVisibility*alpha)/256;
+
+ float vx = Sin(sheet->m_angle) * 0.4f;
+ float vy = Cos(sheet->m_angle) * 0.4f;
+
+ int v = TempBufferVerticesStored;
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx, pos.y + vy, pos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+0], 255, 255, 255, alpha);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x - vy, pos.y + vx, pos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+1], 255, 255, 255, alpha);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x + vy, pos.y - vx, pos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+2], 255, 255, 255, alpha);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx, pos.y - vy, pos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+3], 255, 255, 255, alpha);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+0], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+0], 0.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+1], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+1], 0.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+2], 0.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+2], 1.0f);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+3], 1.0f);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+3], 1.0f);
+
+ int i = TempBufferIndicesStored;
+ TempBufferRenderIndexList[i+0] = RubbishIndexList[0] + TempBufferVerticesStored;
+ TempBufferRenderIndexList[i+1] = RubbishIndexList[1] + TempBufferVerticesStored;
+ TempBufferRenderIndexList[i+2] = RubbishIndexList[2] + TempBufferVerticesStored;
+ TempBufferRenderIndexList[i+3] = RubbishIndexList[3] + TempBufferVerticesStored;
+ TempBufferRenderIndexList[i+4] = RubbishIndexList[4] + TempBufferVerticesStored;
+ TempBufferRenderIndexList[i+5] = RubbishIndexList[5] + TempBufferVerticesStored;
+ TempBufferVerticesStored += 4;
+ TempBufferIndicesStored += 6;
+ }
+ }
+
+ if(TempBufferIndicesStored != 0){
+ LittleTest();
+ if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
+ RwIm3DEnd();
+ }
+ }
+ }
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+}
+
+void
+CRubbish::StirUp(CVehicle *veh)
+{
+ if((CTimer::GetFrameCounter() ^ (veh->m_randomSeed&3)) == 0)
+ return;
+
+ if(Abs(veh->GetPosition().x - TheCamera.GetPosition().x) < 20.0f &&
+ Abs(veh->GetPosition().y - TheCamera.GetPosition().y) < 20.0f)
+ if(Abs(veh->GetMoveSpeed().x) > 0.05f || Abs(veh->GetMoveSpeed().y) > 0.05f){
+ float speed = veh->GetMoveSpeed().Magnitude2D();
+ if(speed > 0.05f){
+ bool movingForward = DotProduct2D(veh->GetMoveSpeed(), veh->GetForward()) > 0.0f;
+ COneSheet *sheet = StartStaticsList.m_next;
+ CVector2D size = veh->GetColModel()->boundingBox.max;
+
+ // Check all static sheets
+ while(sheet != &EndStaticsList){
+ COneSheet *next = sheet->m_next;
+ CVector2D carToSheet = sheet->m_basePos - veh->GetPosition();
+ float distFwd = DotProduct2D(carToSheet, veh->GetForward());
+
+ // sheet has to be a bit behind car
+ if(movingForward && distFwd < -0.5f*size.y && distFwd > -1.5f*size.y ||
+ !movingForward && distFwd > 0.5f*size.y && distFwd < 1.5f*size.y){
+ float distSide = Abs(DotProduct2D(carToSheet, veh->GetRight()));
+ if(distSide < 1.5*size.x){
+ // Check with higher speed for sheet directly behind car
+ float speedToCheck = distSide < size.x ? speed : speed*0.5f;
+ if(speedToCheck > 0.05f){
+ sheet->m_state = 2;
+ if(speedToCheck > 0.15f)
+ sheet->m_animationType = 2;
+ else
+ sheet->m_animationType = 1;
+ sheet->m_moveDuration = 2000;
+ sheet->m_xDist = veh->GetMoveSpeed().x;
+ sheet->m_yDist = veh->GetMoveSpeed().y;
+ float dist = Sqrt(SQR(sheet->m_xDist)+SQR(sheet->m_yDist));
+ sheet->m_xDist *= 25.0f*speed/dist;
+ sheet->m_yDist *= 25.0f*speed/dist;
+ sheet->m_animHeight = 3.0f*speed;
+ sheet->m_moveStart = CTimer::GetTimeInMilliseconds();
+ float tx = sheet->m_basePos.x + sheet->m_xDist;
+ float ty = sheet->m_basePos.y + sheet->m_yDist;
+ float tz = sheet->m_basePos.z + 3.0f;
+ sheet->m_targetZ = CWorld::FindGroundZFor3DCoord(tx, ty, tz, nil) + 0.1f;
+ sheet->RemoveFromList();
+ sheet->AddToList(&StartMoversList);
+ }
+ }
+ }
+
+ sheet = next;
+ }
+ }
+ }
+}
+
+static float aAnimations[3][34] = {
+ { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
+
+ // Normal move
+ { 0.0f, 0.05f, 0.12f, 0.25f, 0.42f, 0.57f, 0.68f, 0.8f, 0.86f, 0.9f, 0.93f, 0.95f, 0.96f, 0.97f, 0.98f, 0.99f, 1.0f, // XY movemnt
+ 0.15f, 0.35f, 0.6f, 0.9f, 1.2f, 1.25f, 1.3f, 1.2f, 1.1f, 0.95f, 0.8f, 0.6f, 0.45f, 0.3f, 0.2f, 0.1f, 0 }, // Z movement
+
+ // Stirred up by fast vehicle
+ { 0.0f, 0.05f, 0.12f, 0.25f, 0.42f, 0.57f, 0.68f, 0.8f, 0.95f, 1.1f, 1.15f, 1.18f, 1.15f, 1.1f, 1.05f, 1.03f, 1.0f,
+ 0.15f, 0.35f, 0.6f, 0.9f, 1.2f, 1.25f, 1.3f, 1.2f, 1.1f, 0.95f, 0.8f, 0.6f, 0.45f, 0.3f, 0.2f, 0.1f, 0 }
+};
+
+void
+CRubbish::Update(void)
+{
+ bool foundGround;
+
+ // FRAMETIME
+ if(bRubbishInvisible)
+ RubbishVisibility = max(RubbishVisibility-5, 0);
+ else
+ RubbishVisibility = min(RubbishVisibility+5, 255);
+
+ // Spawn a new sheet
+ COneSheet *sheet = StartEmptyList.m_next;
+ if(sheet != &EndEmptyList){
+ float spawnDist;
+ float spawnAngle;
+
+ spawnDist = (CGeneral::GetRandomNumber()&0xFF)/256.0f + RUBBISH_MAX_DIST;
+ uint8 r = CGeneral::GetRandomNumber();
+ if(r&1)
+ spawnAngle = (CGeneral::GetRandomNumber()&0xFF)/256.0f * 6.28f;
+ else
+ spawnAngle = (r-128)/160.0f + TheCamera.Orientation;
+ sheet->m_basePos.x = TheCamera.GetPosition().x + spawnDist*Sin(spawnAngle);
+ sheet->m_basePos.y = TheCamera.GetPosition().y + spawnDist*Cos(spawnAngle);
+ sheet->m_basePos.z = CWorld::FindGroundZFor3DCoord(sheet->m_basePos.x, sheet->m_basePos.y, TheCamera.GetPosition().z, &foundGround) + 0.1f;
+ if(foundGround){
+ // Found ground, so add to statics list
+ sheet->m_angle = (CGeneral::GetRandomNumber()&0xFF)/256.0f * 6.28f;
+ sheet->m_state = 1;
+ if(CCullZones::FindAttributesForCoors(sheet->m_basePos, nil) & ATTRZONE_NORAIN)
+ sheet->m_isVisible = false;
+ else
+ sheet->m_isVisible = true;
+ sheet->RemoveFromList();
+ sheet->AddToList(&StartStaticsList);
+ }
+ }
+
+ // Process animation
+ sheet = StartMoversList.m_next;
+ while(sheet != &EndMoversList){
+ uint32 currentTime = CTimer::GetTimeInMilliseconds() - sheet->m_moveStart;
+ if(currentTime < sheet->m_moveDuration){
+ // Animation
+ int step = 16 * currentTime / sheet->m_moveDuration; // 16 steps in animation
+ int stepTime = sheet->m_moveDuration/16; // time in each step
+ float s = (float)(currentTime - stepTime*step) / stepTime; // position on step
+ float t = (float)currentTime / sheet->m_moveDuration; // position on total animation
+ // factors for xy and z-movment
+ float fxy = aAnimations[sheet->m_animationType][step]*(1.0f-s) + aAnimations[sheet->m_animationType][step+1]*s;
+ float fz = aAnimations[sheet->m_animationType][step+17]*(1.0f-s) + aAnimations[sheet->m_animationType][step+1+17]*s;
+ sheet->m_animatedPos.x = sheet->m_basePos.x + fxy*sheet->m_xDist;
+ sheet->m_animatedPos.y = sheet->m_basePos.y + fxy*sheet->m_yDist;
+ sheet->m_animatedPos.z = (1.0f-t)*sheet->m_basePos.z + t*sheet->m_targetZ + fz*sheet->m_animHeight;
+ sheet->m_angle += CTimer::GetTimeStep()*0.04f;
+ if(sheet->m_angle > 6.28f)
+ sheet->m_angle -= 6.28f;
+ sheet = sheet->m_next;
+ }else{
+ // End of animation, back into statics list
+ sheet->m_basePos.x += sheet->m_xDist;
+ sheet->m_basePos.y += sheet->m_yDist;
+ sheet->m_basePos.z = sheet->m_targetZ;
+ sheet->m_state = 1;
+ sheet->m_isVisible = sheet->m_targetIsVisible;
+
+ COneSheet *next = sheet->m_next;
+ sheet->RemoveFromList();
+ sheet->AddToList(&StartStaticsList);
+ sheet = next;
+ }
+ }
+
+ // Stir up a sheet by wind
+ // FRAMETIME
+ int freq;
+ if(CWeather::Wind < 0.1f)
+ freq = 31;
+ else if(CWeather::Wind < 0.4f)
+ freq = 7;
+ else if(CWeather::Wind < 0.7f)
+ freq = 1;
+ else
+ freq = 0;
+ if((CTimer::GetFrameCounter() & freq) == 0){
+ // Pick a random sheet and set animation state if static
+ int i = CGeneral::GetRandomNumber() % NUM_RUBBISH_SHEETS;
+ if(aSheets[i].m_state == 1){
+ aSheets[i].m_moveStart = CTimer::GetTimeInMilliseconds();
+ aSheets[i].m_moveDuration = CWeather::Wind*1500.0f + 1000.0f;
+ aSheets[i].m_animHeight = 0.2f;
+ aSheets[i].m_xDist = 3.0f*CWeather::Wind;
+ aSheets[i].m_yDist = 3.0f*CWeather::Wind;
+ // Check if target position is ok
+ float tx = aSheets[i].m_basePos.x + aSheets[i].m_xDist;
+ float ty = aSheets[i].m_basePos.y + aSheets[i].m_yDist;
+ float tz = aSheets[i].m_basePos.z + 3.0f;
+ aSheets[i].m_targetZ = CWorld::FindGroundZFor3DCoord(tx, ty, tz, &foundGround) + 0.1f;
+ if(CCullZones::FindAttributesForCoors(CVector(tx, ty, aSheets[i].m_targetZ), nil) & ATTRZONE_NORAIN)
+ aSheets[i].m_targetIsVisible = false;
+ else
+ aSheets[i].m_targetIsVisible = true;
+ if(foundGround){
+ // start animation
+ aSheets[i].m_state = 2;
+ aSheets[i].m_animationType = 1;
+ aSheets[i].RemoveFromList();
+ aSheets[i].AddToList(&StartMoversList);
+ }
+ }
+ }
+
+ // Remove sheets that are too far away
+ int i = (CTimer::GetFrameCounter()%(NUM_RUBBISH_SHEETS/4))*4;
+ int last = ((CTimer::GetFrameCounter()%(NUM_RUBBISH_SHEETS/4)) + 1)*4;
+ for(; i < last; i++){
+ if(aSheets[i].m_state == 1 &&
+ (aSheets[i].m_basePos - TheCamera.GetPosition()).MagnitudeSqr2D() > SQR(RUBBISH_MAX_DIST+1.0f)){
+ aSheets[i].m_state = 0;
+ aSheets[i].RemoveFromList();
+ aSheets[i].AddToList(&StartEmptyList);
+ }
+ }
+}
+
+void
+CRubbish::SetVisibility(bool visible)
+{
+ bRubbishInvisible = !visible;
+}
+
+void
+CRubbish::Init(void)
+{
+ int i;
+ for(i = 0; i < NUM_RUBBISH_SHEETS; i++){
+ aSheets[i].m_state = 0;
+ if(i < NUM_RUBBISH_SHEETS-1)
+ aSheets[i].m_next = &aSheets[i+1];
+ else
+ aSheets[i].m_next = &EndEmptyList;
+ if(i > 0)
+ aSheets[i].m_prev = &aSheets[i-1];
+ else
+ aSheets[i].m_prev = &StartEmptyList;
+ }
+
+ StartEmptyList.m_next = &aSheets[0];
+ StartEmptyList.m_prev = nil;
+ EndEmptyList.m_next = nil;
+ EndEmptyList.m_prev = &aSheets[NUM_RUBBISH_SHEETS-1];
+
+ StartStaticsList.m_next = &EndStaticsList;
+ StartStaticsList.m_prev = nil;
+ EndStaticsList.m_next = nil;
+ EndStaticsList.m_prev = &StartStaticsList;
+
+ StartMoversList.m_next = &EndMoversList;
+ StartMoversList.m_prev = nil;
+ EndMoversList.m_next = nil;
+ EndMoversList.m_prev = &StartMoversList;
+
+ // unused
+ RwIm3DVertexSetU(&RubbishVertices[0], 0.0f);
+ RwIm3DVertexSetV(&RubbishVertices[0], 0.0f);
+ RwIm3DVertexSetU(&RubbishVertices[1], 1.0f);
+ RwIm3DVertexSetV(&RubbishVertices[1], 0.0f);
+ RwIm3DVertexSetU(&RubbishVertices[2], 0.0f);
+ RwIm3DVertexSetV(&RubbishVertices[2], 1.0f);
+ RwIm3DVertexSetU(&RubbishVertices[3], 1.0f);
+ RwIm3DVertexSetV(&RubbishVertices[3], 1.0f);
+
+ // unused
+ RubbishIndexList2[0] = 0;
+ RubbishIndexList2[1] = 2;
+ RubbishIndexList2[2] = 1;
+ RubbishIndexList2[3] = 1;
+ RubbishIndexList2[4] = 2;
+ RubbishIndexList2[5] = 3;
+
+ RubbishIndexList[0] = 0;
+ RubbishIndexList[1] = 1;
+ RubbishIndexList[2] = 2;
+ RubbishIndexList[3] = 1;
+ RubbishIndexList[4] = 3;
+ RubbishIndexList[5] = 2;
+
+ CTxdStore::PushCurrentTxd();
+ int slot = CTxdStore::FindTxdSlot("particle");
+ CTxdStore::SetCurrentTxd(slot);
+ gpRubbishTexture[0] = RwTextureRead("gameleaf01_64", nil);
+ gpRubbishTexture[1] = RwTextureRead("gameleaf02_64", nil);
+ gpRubbishTexture[2] = RwTextureRead("newspaper01_64", nil);
+ gpRubbishTexture[3] = RwTextureRead("newspaper02_64", nil);
+ CTxdStore::PopCurrentTxd();
+ RubbishVisibility = 255;
+ bRubbishInvisible = false;
+}
+
+void
+CRubbish::Shutdown(void)
+{
+ RwTextureDestroy(gpRubbishTexture[0]);
+ RwTextureDestroy(gpRubbishTexture[1]);
+ RwTextureDestroy(gpRubbishTexture[2]);
+ RwTextureDestroy(gpRubbishTexture[3]);
+}
diff --git a/src/render/Rubbish.h b/src/render/Rubbish.h
index 17323694..2be592fe 100644
--- a/src/render/Rubbish.h
+++ b/src/render/Rubbish.h
@@ -2,13 +2,50 @@
class CVehicle;
+enum {
+ // NB: not all values are allowed, check the code
+ NUM_RUBBISH_SHEETS = 64
+};
+
+class COneSheet
+{
+public:
+ CVector m_basePos;
+ CVector m_animatedPos;
+ float m_targetZ;
+ int8 m_state;
+ int8 m_animationType;
+ uint32 m_moveStart;
+ uint32 m_moveDuration;
+ float m_animHeight;
+ float m_xDist;
+ float m_yDist;
+ float m_angle;
+ bool m_isVisible;
+ bool m_targetIsVisible;
+ COneSheet *m_next;
+ COneSheet *m_prev;
+
+ void AddToList(COneSheet *list);
+ void RemoveFromList(void);
+};
+
class CRubbish
{
+ static bool bRubbishInvisible;
+ static int RubbishVisibility;
+ static COneSheet aSheets[NUM_RUBBISH_SHEETS];
+ static COneSheet StartEmptyList;
+ static COneSheet EndEmptyList;
+ static COneSheet StartStaticsList;
+ static COneSheet EndStaticsList;
+ static COneSheet StartMoversList;
+ static COneSheet EndMoversList;
public:
static void Render(void);
static void StirUp(CVehicle *veh); // CAutomobile on PS2
static void Update(void);
- static void SetVisibility(bool);
+ static void SetVisibility(bool visible);
static void Init(void);
static void Shutdown(void);
};
diff --git a/src/render/Shadows.h b/src/render/Shadows.h
index 982cc463..fb41ebbc 100644
--- a/src/render/Shadows.h
+++ b/src/render/Shadows.h
@@ -175,11 +175,18 @@ public:
static void RenderIndicatorShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity);
};
-extern RwTexture *&gpBloodPoolTex;
+extern RwTexture *&gpShadowCarTex;
+extern RwTexture *&gpShadowPedTex;
+extern RwTexture *&gpShadowHeliTex;
extern RwTexture *&gpShadowExplosionTex;
extern RwTexture *&gpShadowHeadLightsTex;
-extern RwTexture *&gpGoalTex;
extern RwTexture *&gpOutline1Tex;
extern RwTexture *&gpOutline2Tex;
extern RwTexture *&gpOutline3Tex;
+extern RwTexture *&gpBloodPoolTex;
+extern RwTexture *&gpReflectionTex;
+extern RwTexture *&gpGoalMarkerTex;
+extern RwTexture *&gpWalkDontTex;
extern RwTexture *&gpCrackedGlassTex;
+extern RwTexture *&gpPostShadowTex;
+extern RwTexture *&gpGoalTex;
diff --git a/src/render/Skidmarks.cpp b/src/render/Skidmarks.cpp
index c2725ed6..41ee5d1d 100644
--- a/src/render/Skidmarks.cpp
+++ b/src/render/Skidmarks.cpp
@@ -1,12 +1,247 @@
#include "common.h"
#include "patcher.h"
+#include "main.h"
+#include "TxdStore.h"
+#include "Timer.h"
+#include "Replay.h"
#include "Skidmarks.h"
-WRAPPER void CSkidmarks::Clear(void) { EAXJMP(0x518130); }
-WRAPPER void CSkidmarks::Update() { EAXJMP(0x518200); }
+CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
-WRAPPER void CSkidmarks::Render(void) { EAXJMP(0x5182E0); }
-WRAPPER void CSkidmarks::RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy) { EAXJMP(0x5185C0); }
+RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
+RwIm3DVertex SkidmarkVertices[SKIDMARK_LENGTH * 2];
+RwTexture *gpSkidTex;
+RwTexture *gpSkidBloodTex;
+RwTexture *gpSkidMudTex;
-WRAPPER void CSkidmarks::Init(void) { EAXJMP(0x517D70); }
-WRAPPER void CSkidmarks::Shutdown(void) { EAXJMP(0x518100); }
+void
+CSkidmarks::Init(void)
+{
+ int i, ix, slot;
+ CTxdStore::PushCurrentTxd();
+ slot = CTxdStore::FindTxdSlot("particle");
+ CTxdStore::SetCurrentTxd(slot);
+ gpSkidTex = RwTextureRead("particleskid", nil);
+ gpSkidBloodTex = RwTextureRead("particleskidblood", nil);
+ gpSkidMudTex = RwTextureRead("particleskidmud", nil);
+ CTxdStore::PopCurrentTxd();
+
+ for(i = 0; i < NUMSKIDMARKS; i++){
+ aSkidmarks[i].m_state = 0;
+ aSkidmarks[i].m_wasUpdated = false;
+ }
+
+ ix = 0;
+ for(i = 0; i < SKIDMARK_LENGTH; i++){
+ SkidmarkIndexList[i*6+0] = ix+0;
+ SkidmarkIndexList[i*6+1] = ix+2;
+ SkidmarkIndexList[i*6+2] = ix+1;
+ SkidmarkIndexList[i*6+3] = ix+1;
+ SkidmarkIndexList[i*6+4] = ix+2;
+ SkidmarkIndexList[i*6+5] = ix+3;
+ ix += 2;
+ }
+
+ for(i = 0; i < SKIDMARK_LENGTH; i++){
+ RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
+ RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
+ RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
+ RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
+ }
+}
+
+void
+CSkidmarks::Shutdown(void)
+{
+ RwTextureDestroy(gpSkidTex);
+ RwTextureDestroy(gpSkidBloodTex);
+ RwTextureDestroy(gpSkidMudTex);
+}
+
+void
+CSkidmarks::Clear(void)
+{
+ int i;
+ for(i = 0; i < NUMSKIDMARKS; i++){
+ aSkidmarks[i].m_state = 0;
+ aSkidmarks[i].m_wasUpdated = false;
+ }
+}
+
+void
+CSkidmarks::Update(void)
+{
+ int i;
+ uint32 t1 = CTimer::GetTimeInMilliseconds() + 2500;
+ uint32 t2 = CTimer::GetTimeInMilliseconds() + 5000;
+ uint32 t3 = CTimer::GetTimeInMilliseconds() + 10000;
+ uint32 t4 = CTimer::GetTimeInMilliseconds() + 20000;
+ for(i = 0; i < NUMSKIDMARKS; i++){
+ switch(aSkidmarks[i].m_state){
+ case 1:
+ if(!aSkidmarks[i].m_wasUpdated){
+ // Didn't continue this one last time, so finish it and set fade times
+ aSkidmarks[i].m_state = 2;
+ if(aSkidmarks[i].m_last < 4){
+ aSkidmarks[i].m_fadeStart = t1;
+ aSkidmarks[i].m_fadeEnd = t2;
+ }else if(aSkidmarks[i].m_last < 9){
+ aSkidmarks[i].m_fadeStart = t2;
+ aSkidmarks[i].m_fadeEnd = t3;
+ }else{
+ aSkidmarks[i].m_fadeStart = t3;
+ aSkidmarks[i].m_fadeEnd = t4;
+ }
+ }
+ break;
+ case 2:
+ if(CTimer::GetTimeInMilliseconds() > aSkidmarks[i].m_fadeEnd)
+ aSkidmarks[i].m_state = 0;
+ break;
+ }
+ aSkidmarks[i].m_wasUpdated = false;
+ }
+}
+
+void
+CSkidmarks::Render(void)
+{
+ int i, j;
+ RwTexture *lastTex = nil;
+
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ for(i = 0; i < NUMSKIDMARKS; i++){
+ if(aSkidmarks[i].m_state == 0 || aSkidmarks[i].m_last < 1)
+ continue;
+
+ if(aSkidmarks[i].m_isBloody){
+ if(lastTex != gpSkidBloodTex){
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidBloodTex));
+ lastTex = gpSkidBloodTex;
+ }
+ }else if(aSkidmarks[i].m_isMuddy){
+ if(lastTex != gpSkidMudTex){
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidMudTex));
+ lastTex = gpSkidMudTex;
+ }
+ }else{
+ if(lastTex != gpSkidTex){
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpSkidTex));
+ lastTex = gpSkidTex;
+ }
+ }
+
+ uint32 fade, alpha;
+ if(aSkidmarks[i].m_state == 1 || CTimer::GetTimeInMilliseconds() < aSkidmarks[i].m_fadeStart)
+ fade = 255;
+ else
+ fade = 255*(aSkidmarks[i].m_fadeEnd - CTimer::GetTimeInMilliseconds()) / (aSkidmarks[i].m_fadeEnd - aSkidmarks[i].m_fadeStart);
+
+ for(j = 0; j <= aSkidmarks[i].m_last; j++){
+ alpha = 128;
+ if(j == 0 || j == aSkidmarks[i].m_last && aSkidmarks[i].m_state == 2)
+ alpha = 0;
+ alpha = alpha*fade/256;
+
+ CVector p1 = aSkidmarks[i].m_pos[j] + aSkidmarks[i].m_side[j];
+ CVector p2 = aSkidmarks[i].m_pos[j] - aSkidmarks[i].m_side[j];
+ RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], 255, 255, 255, alpha);
+ RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
+ RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], 255, 255, 255, alpha);
+ RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
+ }
+
+ LittleTest();
+ if(RwIm3DTransform(SkidmarkVertices, 2*(aSkidmarks[i].m_last+1), nil, rwIM3D_VERTEXUV)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, SkidmarkIndexList, 6*aSkidmarks[i].m_last);
+ RwIm3DEnd();
+ }
+ }
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+}
+
+void
+CSkidmarks::RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody)
+{
+ int i;
+ CVector2D fwd(fwdX, fwdY);
+
+ if(CReplay::IsPlayingBack())
+ return;
+
+ // Find a skidmark to continue
+ for(i = 0; i < NUMSKIDMARKS; i++)
+ if(aSkidmarks[i].m_state == 1 && aSkidmarks[i].m_id == id)
+ break;
+
+ if(i < NUMSKIDMARKS){
+ // Continue this one
+
+ if(aSkidmarks[i].m_isBloody != *isBloody){
+ // Blood-status changed, end this one
+ aSkidmarks[i].m_state = 2;
+ aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
+ aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
+ return;
+ }
+
+ aSkidmarks[i].m_wasUpdated = true;
+
+ if(CTimer::GetTimeInMilliseconds() - aSkidmarks[i].m_lastUpdate <= 100){
+ // Last update was recently, just change last coords
+ aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
+ return;
+ }
+ aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds();
+
+ if(aSkidmarks[i].m_last >= SKIDMARK_LENGTH-1){
+ // No space to continue, end it
+ aSkidmarks[i].m_state = 2;
+ aSkidmarks[i].m_fadeStart = CTimer::GetTimeInMilliseconds() + 10000;
+ aSkidmarks[i].m_fadeEnd = CTimer::GetTimeInMilliseconds() + 20000;
+ *isBloody = false; // stpo blood marks at end
+ return;
+ }
+ aSkidmarks[i].m_last++;
+
+ aSkidmarks[i].m_pos[aSkidmarks[i].m_last] = pos;
+
+ CVector2D dist = aSkidmarks[i].m_pos[aSkidmarks[i].m_last] - aSkidmarks[i].m_pos[aSkidmarks[i].m_last-1];
+ dist.Normalise();
+ CVector2D right(dist.y, -dist.x);
+ float turn = DotProduct2D(fwd, right);
+ turn = Abs(turn) + 1.0f;
+ aSkidmarks[i].m_side[aSkidmarks[i].m_last] = CVector(right.x, right.y, 0.0f) * turn * 0.125f;
+ if(aSkidmarks[i].m_last == 1)
+ aSkidmarks[i].m_side[0] = aSkidmarks[i].m_side[1];
+
+ if(aSkidmarks[i].m_last > 8)
+ *isBloody = false; // stop blood marks after 8
+ return;
+ }
+
+ // Start a new one
+ for(i = 0; i < NUMSKIDMARKS; i++)
+ if(aSkidmarks[i].m_state == 0)
+ break;
+ if(i < NUMSKIDMARKS){
+ // Found a free slot
+ aSkidmarks[i].m_state = 1;
+ aSkidmarks[i].m_id = id;
+ aSkidmarks[i].m_pos[0] = pos;
+ aSkidmarks[i].m_side[0] = CVector(0.0f, 0.0f, 0.0f);
+ aSkidmarks[i].m_wasUpdated = true;
+ aSkidmarks[i].m_last = 0;
+ aSkidmarks[i].m_lastUpdate = CTimer::GetTimeInMilliseconds() - 1000;
+ aSkidmarks[i].m_isBloody = *isBloody;
+ aSkidmarks[i].m_isMuddy = *isMuddy;
+ }else
+ *isBloody = false; // stop blood marks if no space
+}
diff --git a/src/render/Skidmarks.h b/src/render/Skidmarks.h
index bf2da7e4..085b4c6d 100644
--- a/src/render/Skidmarks.h
+++ b/src/render/Skidmarks.h
@@ -1,12 +1,32 @@
#pragma once
+enum { SKIDMARK_LENGTH = 16 };
+
+class CSkidmark
+{
+public:
+ uint8 m_state;
+ bool m_wasUpdated;
+ bool m_isBloody;
+ bool m_isMuddy;
+ uintptr m_id;
+ int16 m_last;
+ uint32 m_lastUpdate;;
+ uint32 m_fadeStart;
+ uint32 m_fadeEnd;
+ CVector m_pos[SKIDMARK_LENGTH];
+ CVector m_side[SKIDMARK_LENGTH];
+};
+
class CSkidmarks
{
+ static CSkidmark aSkidmarks[NUMSKIDMARKS];
public:
+
+ static void Init(void);
+ static void Shutdown(void);
static void Clear(void);
static void Update(void);
static void Render(void);
- static void RegisterOne(uint32 id, CVector pos, float fwdx, float fwdY, bool *isMuddy, bool *isBloddy);
- static void Init(void);
- static void Shutdown(void);
+ static void RegisterOne(uintptr id, CVector pos, float fwdX, float fwdY, bool *isMuddy, bool *isBloody);
};
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index 301ae265..9189a7c2 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "SpecialFX.h"
+#include "RenderBuffer.h"
#include "Timer.h"
#include "Sprite.h"
#include "Font.h"
@@ -8,26 +9,260 @@
#include "TxdStore.h"
#include "FileMgr.h"
#include "FileLoader.h"
+#include "Timecycle.h"
#include "Lights.h"
+#include "ModelIndices.h"
#include "VisibilityPlugins.h"
#include "World.h"
+#include "PlayerPed.h"
#include "Particle.h"
+#include "Shadows.h"
#include "General.h"
#include "Camera.h"
#include "Shadows.h"
#include "main.h"
-WRAPPER void CSpecialFX::Render(void) { EAXJMP(0x518DC0); }
-WRAPPER void CSpecialFX::Update(void) { EAXJMP(0x518D40); }
-WRAPPER void CSpecialFX::Init(void) { EAXJMP(0x5189E0); }
-WRAPPER void CSpecialFX::Shutdown(void) { EAXJMP(0x518BE0); }
+RwIm3DVertex StreakVertices[4];
+RwImVertexIndex StreakIndexList[12];
+
+RwIm3DVertex TraceVertices[6];
+RwImVertexIndex TraceIndexList[12];
+
+
+void
+CSpecialFX::Init(void)
+{
+ CBulletTraces::Init();
+
+ RwIm3DVertexSetU(&StreakVertices[0], 0.0f);
+ RwIm3DVertexSetV(&StreakVertices[0], 0.0f);
+ RwIm3DVertexSetU(&StreakVertices[1], 1.0f);
+ RwIm3DVertexSetV(&StreakVertices[1], 0.0f);
+ RwIm3DVertexSetU(&StreakVertices[2], 0.0f);
+ RwIm3DVertexSetV(&StreakVertices[2], 0.0f);
+ RwIm3DVertexSetU(&StreakVertices[3], 1.0f);
+ RwIm3DVertexSetV(&StreakVertices[3], 0.0f);
+
+ StreakIndexList[0] = 0;
+ StreakIndexList[1] = 1;
+ StreakIndexList[2] = 2;
+ StreakIndexList[3] = 1;
+ StreakIndexList[4] = 3;
+ StreakIndexList[5] = 2;
+ StreakIndexList[6] = 0;
+ StreakIndexList[7] = 2;
+ StreakIndexList[8] = 1;
+ StreakIndexList[9] = 1;
+ StreakIndexList[10] = 2;
+ StreakIndexList[11] = 3;
+
+ RwIm3DVertexSetRGBA(&TraceVertices[0], 20, 20, 20, 255);
+ RwIm3DVertexSetRGBA(&TraceVertices[1], 20, 20, 20, 255);
+ RwIm3DVertexSetRGBA(&TraceVertices[2], 70, 70, 70, 255);
+ RwIm3DVertexSetRGBA(&TraceVertices[3], 70, 70, 70, 255);
+ RwIm3DVertexSetRGBA(&TraceVertices[4], 10, 10, 10, 255);
+ RwIm3DVertexSetRGBA(&TraceVertices[5], 10, 10, 10, 255);
+ RwIm3DVertexSetU(&TraceVertices[0], 0.0);
+ RwIm3DVertexSetV(&TraceVertices[0], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[1], 1.0);
+ RwIm3DVertexSetV(&TraceVertices[1], 0.0);
+ RwIm3DVertexSetU(&TraceVertices[2], 0.0);
+ RwIm3DVertexSetV(&TraceVertices[2], 0.5);
+ RwIm3DVertexSetU(&TraceVertices[3], 1.0);
+ RwIm3DVertexSetV(&TraceVertices[3], 0.5);
+ RwIm3DVertexSetU(&TraceVertices[4], 0.0);
+ RwIm3DVertexSetV(&TraceVertices[4], 1.0);
+ RwIm3DVertexSetU(&TraceVertices[5], 1.0);
+ RwIm3DVertexSetV(&TraceVertices[5], 1.0);
+
+ TraceIndexList[0] = 0;
+ TraceIndexList[1] = 2;
+ TraceIndexList[2] = 1;
+ TraceIndexList[3] = 1;
+ TraceIndexList[4] = 2;
+ TraceIndexList[5] = 3;
+ TraceIndexList[6] = 2;
+ TraceIndexList[7] = 4;
+ TraceIndexList[8] = 3;
+ TraceIndexList[9] = 3;
+ TraceIndexList[10] = 4;
+ TraceIndexList[11] = 5;
+
+ CMotionBlurStreaks::Init();
+ CBrightLights::Init();
+ CShinyTexts::Init();
+ CMoneyMessages::Init();
+ C3dMarkers::Init();
+}
+
+RwObject*
+LookForBatCB(RwObject *object, void *data)
+{
+ static CMatrix MatLTM;
+
+ if(CVisibilityPlugins::GetAtomicModelInfo((RpAtomic*)object) == (CSimpleModelInfo*)data){
+ MatLTM = CMatrix(RwFrameGetLTM(RpAtomicGetFrame((RpAtomic*)object)));
+ CVector p1 = MatLTM * CVector(0.02f, 0.05f, 0.07f);
+ CVector p2 = MatLTM * CVector(0.246f, 0.0325f, 0.796f);
+ CMotionBlurStreaks::RegisterStreak((uintptr)object, 100, 100, 100, p1, p2);
+ }
+ return nil;
+}
+
+void
+CSpecialFX::Update(void)
+{
+ CMotionBlurStreaks::Update();
+ CBulletTraces::Update();
+
+ if(FindPlayerPed() &&
+ FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT &&
+ FindPlayerPed()->GetWeapon()->m_eWeaponState == WEAPONSTATE_FIRING)
+ RwFrameForAllObjects(FindPlayerPed()->GetNodeFrame(PED_HANDR), LookForBatCB, CModelInfo::GetModelInfo(MI_BASEBALL_BAT));
+}
+
+void
+CSpecialFX::Shutdown(void)
+{
+ C3dMarkers::Shutdown();
+}
+
+void
+CSpecialFX::Render(void)
+{
+ CMotionBlurStreaks::Render();
+ CBulletTraces::Render();
+ CBrightLights::Render();
+ CShinyTexts::Render();
+ CMoneyMessages::Render();
+ C3dMarkers::Render();
+}
+
+CRegisteredMotionBlurStreak CMotionBlurStreaks::aStreaks[NUMMBLURSTREAKS];
+
+void
+CRegisteredMotionBlurStreak::Update(void)
+{
+ int i;
+ bool wasUpdated;
+ bool lastWasUpdated = false;
+ for(i = 2; i > 0; i--){
+ m_pos1[i] = m_pos1[i-1];
+ m_pos2[i] = m_pos2[i-1];
+ m_isValid[i] = m_isValid[i-1];
+ wasUpdated = true;
+ if(!lastWasUpdated && !m_isValid[i])
+ wasUpdated = false;
+ lastWasUpdated = wasUpdated;
+ }
+ m_isValid[0] = false;
+ if(!wasUpdated)
+ m_id = 0;
+}
+
+void
+CRegisteredMotionBlurStreak::Render(void)
+{
+ int i;
+ int a1, a2;
+ for(i = 0; i < 2; i++)
+ if(m_isValid[i] && m_isValid[i+1]){
+ a1 = (255/3)*(3-i)/3;
+ RwIm3DVertexSetRGBA(&StreakVertices[0], m_red, m_green, m_blue, a1);
+ RwIm3DVertexSetRGBA(&StreakVertices[1], m_red, m_green, m_blue, a1);
+ a2 = (255/3)*(3-(i+1))/3;
+ RwIm3DVertexSetRGBA(&StreakVertices[2], m_red, m_green, m_blue, a2);
+ RwIm3DVertexSetRGBA(&StreakVertices[3], m_red, m_green, m_blue, a2);
+ RwIm3DVertexSetPos(&StreakVertices[0], m_pos1[i].x, m_pos1[i].y, m_pos1[i].z);
+ RwIm3DVertexSetPos(&StreakVertices[1], m_pos2[i].x, m_pos2[i].y, m_pos2[i].z);
+ RwIm3DVertexSetPos(&StreakVertices[2], m_pos1[i+1].x, m_pos1[i+1].y, m_pos1[i+1].z);
+ RwIm3DVertexSetPos(&StreakVertices[3], m_pos2[i+1].x, m_pos2[i+1].y, m_pos2[i+1].z);
+ LittleTest();
+ if(RwIm3DTransform(StreakVertices, 4, nil, rwIM3D_VERTEXUV)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, StreakIndexList, 12);
+ RwIm3DEnd();
+ }
+ }
+}
+
+void
+CMotionBlurStreaks::Init(void)
+{
+ int i;
+ for(i = 0; i < NUMMBLURSTREAKS; i++)
+ aStreaks[i].m_id = 0;
+}
+
+void
+CMotionBlurStreaks::Update(void)
+{
+ int i;
+ for(i = 0; i < NUMMBLURSTREAKS; i++)
+ if(aStreaks[i].m_id)
+ aStreaks[i].Update();
+}
+
+void
+CMotionBlurStreaks::RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2)
+{
+ int i;
+ for(i = 0; i < NUMMBLURSTREAKS; i++){
+ if(aStreaks[i].m_id == id){
+ // Found a streak from last frame, update
+ aStreaks[i].m_red = r;
+ aStreaks[i].m_green = g;
+ aStreaks[i].m_blue = b;
+ aStreaks[i].m_pos1[0] = p1;
+ aStreaks[i].m_pos2[0] = p2;
+ aStreaks[i].m_isValid[0] = true;
+ return;
+ }
+ }
+ // Find free slot
+ for(i = 0; aStreaks[i].m_id; i++)
+ if(i == NUMMBLURSTREAKS-1)
+ return;
+ // Create a new streak
+ aStreaks[i].m_id = id;
+ aStreaks[i].m_red = r;
+ aStreaks[i].m_green = g;
+ aStreaks[i].m_blue = b;
+ aStreaks[i].m_pos1[0] = p1;
+ aStreaks[i].m_pos2[0] = p2;
+ aStreaks[i].m_isValid[0] = true;
+ aStreaks[i].m_isValid[1] = false;
+ aStreaks[i].m_isValid[2] = false;
+}
-WRAPPER void CMotionBlurStreaks::RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2) { EAXJMP(0x519460); }
+void
+CMotionBlurStreaks::Render(void)
+{
+ bool setRenderStates = false;
+ int i;
+ for(i = 0; i < NUMMBLURSTREAKS; i++)
+ if(aStreaks[i].m_id){
+ if(!setRenderStates){
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGCOLOR,
+ (void*)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255));
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
+ setRenderStates = true;
+ }
+ aStreaks[i].Render();
+ }
+ if(setRenderStates){
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)FALSE);
+ }
+}
-CBulletTrace (&CBulletTraces::aTraces)[NUMBULLETTRACES] = *(CBulletTrace(*)[NUMBULLETTRACES])*(uintptr*)0x72B1B8;
-RxObjSpace3DVertex (&TraceVertices)[6] = *(RxObjSpace3DVertex(*)[6])*(uintptr*)0x649884;
-RwImVertexIndex (&TraceIndexList)[12] = *(RwImVertexIndex(*)[12])*(uintptr*)0x64986C;
+CBulletTrace CBulletTraces::aTraces[NUMBULLETTRACES];
void CBulletTraces::Init(void)
{
@@ -56,10 +291,10 @@ void CBulletTraces::Render(void)
for (int i = 0; i < NUMBULLETTRACES; i++) {
if (!aTraces[i].m_bInUse)
continue;
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)0);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)2);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)2);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpShadowExplosionTex->raster);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpShadowExplosionTex));
CVector inf = aTraces[i].m_vecCurrentPos;
CVector sup = aTraces[i].m_vecTargetPos;
CVector center = (inf + sup) / 2;
@@ -81,9 +316,9 @@ void CBulletTraces::Render(void)
RwIm3DEnd();
}
}
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)5);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)6);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
void CBulletTraces::Update(void)
@@ -115,8 +350,6 @@ void CBulletTrace::Update(void)
m_framesInUse++;
}
-WRAPPER void CBrightLights::RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1, uint8 unk2, uint8 unk3) { EAXJMP(0x51A410); }
-
RpAtomic *
MarkerAtomicCB(RpAtomic *atomic, void *data)
{
@@ -181,8 +414,7 @@ C3dMarker::Render()
{
if (m_pAtomic == nil) return;
- RwRGBA *color = RpMaterialGetColor(m_pMaterial);
- *color = m_Color;
+ RpMaterialSetColor(m_pMaterial, &m_Color);
m_Matrix.UpdateRW();
@@ -201,9 +433,9 @@ C3dMarker::Render()
ReSetAmbientAndDirectionalColours();
}
-C3dMarker(&C3dMarkers::m_aMarkerArray)[NUM3DMARKERS] = *(C3dMarker(*)[NUM3DMARKERS])*(uintptr*)0x72D408;
-int32 &C3dMarkers::NumActiveMarkers = *(int32*)0x8F2A08;
-RpClump* (&C3dMarkers::m_pRpClumpArray)[NUMMARKERTYPES] = *(RpClump*(*)[NUMMARKERTYPES])*(uintptr*)0x8E2888;
+C3dMarker C3dMarkers::m_aMarkerArray[NUM3DMARKERS];
+int32 C3dMarkers::NumActiveMarkers;
+RpClump* C3dMarkers::m_pRpClumpArray[NUMMARKERTYPES];
void
C3dMarkers::Init()
@@ -402,6 +634,377 @@ C3dMarkers::Update()
{
}
+
+#define BRIGHTLIGHTS_MAX_DIST (60.0f) // invisible beyond this
+#define BRIGHTLIGHTS_FADE_DIST (45.0f) // strongest between these two
+#define CARLIGHTS_MAX_DIST (30.0f)
+#define CARLIGHTS_FADE_DIST (15.0f) // 31 for close lights
+
+int CBrightLights::NumBrightLights;
+CBrightLight CBrightLights::aBrightLights[NUMBRIGHTLIGHTS];
+
+void
+CBrightLights::Init(void)
+{
+ NumBrightLights = 0;
+}
+
+void
+CBrightLights::RegisterOne(CVector pos, CVector up, CVector side, CVector front,
+ uint8 type, uint8 red, uint8 green, uint8 blue)
+{
+ if(NumBrightLights >= NUMBRIGHTLIGHTS)
+ return;
+
+ aBrightLights[NumBrightLights].m_camDist = (pos - TheCamera.GetPosition()).Magnitude();
+ if(aBrightLights[NumBrightLights].m_camDist > BRIGHTLIGHTS_MAX_DIST)
+ return;
+
+ aBrightLights[NumBrightLights].m_pos = pos;
+ aBrightLights[NumBrightLights].m_up = up;
+ aBrightLights[NumBrightLights].m_side = side;
+ aBrightLights[NumBrightLights].m_front = front;
+ aBrightLights[NumBrightLights].m_type = type;
+ aBrightLights[NumBrightLights].m_red = red;
+ aBrightLights[NumBrightLights].m_green = green;
+ aBrightLights[NumBrightLights].m_blue = blue;
+
+ NumBrightLights++;
+}
+
+static float TrafficLightsSide[6] = { -0.09f, 0.09f, 0.162f, 0.09f, -0.09f, -0.162f };
+static float TrafficLightsUp[6] = { 0.162f, 0.162f, 0.0f, -0.162f, -0.162f, 0.0f };
+static float LongCarHeadLightsSide[8] = { -0.2f, 0.2f, -0.2f, 0.2f, -0.2f, 0.2f, -0.2f, 0.2f };
+static float LongCarHeadLightsFront[8] = { 0.1f, 0.1f, -0.1f, -0.1f, 0.1f, 0.1f, -0.1f, -0.1f };
+static float LongCarHeadLightsUp[8] = { 0.1f, 0.1f, 0.1f, 0.1f, -0.1f, -0.1f, -0.1f, -0.1f };
+static float SmallCarHeadLightsSide[8] = { -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f };
+static float SmallCarHeadLightsFront[8] = { 0.08f, 0.08f, -0.08f, -0.08f, 0.08f, 0.08f, -0.08f, -0.08f };
+static float SmallCarHeadLightsUp[8] = { 0.08f, 0.08f, 0.08f, 0.08f, -0.08f, -0.08f, -0.08f, -0.08f };
+static float BigCarHeadLightsSide[8] = { -0.15f, 0.15f, -0.15f, 0.15f, -0.15f, 0.15f, -0.15f, 0.15f };
+static float BigCarHeadLightsFront[8] = { 0.15f, 0.15f, -0.15f, -0.15f, 0.15f, 0.15f, -0.15f, -0.15f };
+static float BigCarHeadLightsUp[8] = { 0.15f, 0.15f, 0.15f, 0.15f, -0.15f, -0.15f, -0.15f, -0.15f };
+static float TallCarHeadLightsSide[8] = { -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f, -0.08f, 0.08f };
+static float TallCarHeadLightsFront[8] = { 0.08f, 0.08f, -0.08f, -0.08f, 0.08f, 0.08f, -0.08f, -0.08f };
+static float TallCarHeadLightsUp[8] = { 0.2f, 0.2f, 0.2f, 0.2f, -0.2f, -0.2f, -0.2f, -0.2f };
+static float SirenLightsSide[6] = { -0.04f, 0.04f, 0.06f, 0.04f, -0.04f, -0.06f };
+static float SirenLightsUp[6] = { 0.06f, 0.06f, 0.0f, -0.06f, -0.06f, 0.0f };
+static RwImVertexIndex TrafficLightIndices[4*3] = { 0, 1, 5, 1, 2, 3, 1, 3, 4, 1, 4, 5 };
+static RwImVertexIndex CubeIndices[12*3] = {
+ 0, 2, 1, 1, 2, 3, 3, 5, 1, 3, 7, 5,
+ 2, 7, 3, 2, 6, 7, 4, 0, 1, 4, 1, 5,
+ 6, 0, 4, 6, 2, 0, 6, 5, 7, 6, 4, 5
+};
+
+void
+CBrightLights::Render(void)
+{
+ int i, j;
+ CVector pos;
+
+ if(NumBrightLights == 0)
+ return;
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+
+ for(i = 0; i < NumBrightLights; i++){
+ if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40)
+ RenderOutGeometryBuffer();
+
+ int r, g, b, a;
+ float flicker = (CGeneral::GetRandomNumber()&0xFF) * 0.2f;
+ switch(aBrightLights[i].m_type){
+ case BRIGHTLIGHT_TRAFFIC_GREEN:
+ r = flicker; g = 255; b = flicker;
+ break;
+ case BRIGHTLIGHT_TRAFFIC_YELLOW:
+ r = 255; g = 128; b = flicker;
+ break;
+ case BRIGHTLIGHT_TRAFFIC_RED:
+ r = 255; g = flicker; b = flicker;
+ break;
+
+ case BRIGHTLIGHT_FRONT_LONG:
+ case BRIGHTLIGHT_FRONT_SMALL:
+ case BRIGHTLIGHT_FRONT_BIG:
+ case BRIGHTLIGHT_FRONT_TALL:
+ r = 255; g = 255; b = 255;
+ break;
+
+ case BRIGHTLIGHT_REAR_LONG:
+ case BRIGHTLIGHT_REAR_SMALL:
+ case BRIGHTLIGHT_REAR_BIG:
+ case BRIGHTLIGHT_REAR_TALL:
+ r = 255; g = flicker; b = flicker;
+ break;
+
+ case BRIGHTLIGHT_SIREN:
+ r = aBrightLights[i].m_red;
+ g = aBrightLights[i].m_green;
+ b = aBrightLights[i].m_blue;
+ break;
+ }
+
+ if(aBrightLights[i].m_camDist < BRIGHTLIGHTS_FADE_DIST)
+ a = 255;
+ else
+ a = 255*(1.0f - (aBrightLights[i].m_camDist-BRIGHTLIGHTS_FADE_DIST)/(BRIGHTLIGHTS_MAX_DIST-BRIGHTLIGHTS_FADE_DIST));
+ // fade car lights down to 31 as they come near
+ if(aBrightLights[i].m_type >= BRIGHTLIGHT_FRONT_LONG && aBrightLights[i].m_type <= BRIGHTLIGHT_REAR_TALL){
+ if(aBrightLights[i].m_camDist < CARLIGHTS_FADE_DIST)
+ a = 31;
+ else if(aBrightLights[i].m_camDist < CARLIGHTS_MAX_DIST)
+ a = 31 + (255-31)*((aBrightLights[i].m_camDist-CARLIGHTS_FADE_DIST)/(CARLIGHTS_MAX_DIST-CARLIGHTS_FADE_DIST));
+ }
+
+ switch(aBrightLights[i].m_type){
+ case BRIGHTLIGHT_TRAFFIC_GREEN:
+ case BRIGHTLIGHT_TRAFFIC_YELLOW:
+ case BRIGHTLIGHT_TRAFFIC_RED:
+ for(j = 0; j < 6; j++){
+ pos = TrafficLightsSide[j]*aBrightLights[i].m_side +
+ TrafficLightsUp[j]*aBrightLights[i].m_up +
+ aBrightLights[i].m_pos;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
+ }
+ for(j = 0; j < 4*3; j++)
+ TempBufferRenderIndexList[TempBufferIndicesStored+j] = TrafficLightIndices[j] + TempBufferVerticesStored;
+ TempBufferVerticesStored += 6;
+ TempBufferIndicesStored += 4*3;
+ break;
+
+ case BRIGHTLIGHT_FRONT_LONG:
+ case BRIGHTLIGHT_REAR_LONG:
+ for(j = 0; j < 8; j++){
+ pos = LongCarHeadLightsSide[j]*aBrightLights[i].m_side +
+ LongCarHeadLightsUp[j]*aBrightLights[i].m_up +
+ LongCarHeadLightsFront[j]*aBrightLights[i].m_front +
+ aBrightLights[i].m_pos;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
+ }
+ for(j = 0; j < 12*3; j++)
+ TempBufferRenderIndexList[TempBufferIndicesStored+j] = CubeIndices[j] + TempBufferVerticesStored;
+ TempBufferVerticesStored += 8;
+ TempBufferIndicesStored += 12*3;
+ break;
+
+ case BRIGHTLIGHT_FRONT_SMALL:
+ case BRIGHTLIGHT_REAR_SMALL:
+ for(j = 0; j < 8; j++){
+ pos = SmallCarHeadLightsSide[j]*aBrightLights[i].m_side +
+ SmallCarHeadLightsUp[j]*aBrightLights[i].m_up +
+ SmallCarHeadLightsFront[j]*aBrightLights[i].m_front +
+ aBrightLights[i].m_pos;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
+ }
+ for(j = 0; j < 12*3; j++)
+ TempBufferRenderIndexList[TempBufferIndicesStored+j] = CubeIndices[j] + TempBufferVerticesStored;
+ TempBufferVerticesStored += 8;
+ TempBufferIndicesStored += 12*3;
+ break;
+
+ case BRIGHTLIGHT_FRONT_TALL:
+ case BRIGHTLIGHT_REAR_TALL:
+ for(j = 0; j < 8; j++){
+ pos = TallCarHeadLightsSide[j]*aBrightLights[i].m_side +
+ TallCarHeadLightsUp[j]*aBrightLights[i].m_up +
+ TallCarHeadLightsFront[j]*aBrightLights[i].m_front +
+ aBrightLights[i].m_pos;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
+ }
+ for(j = 0; j < 12*3; j++)
+ TempBufferRenderIndexList[TempBufferIndicesStored+j] = CubeIndices[j] + TempBufferVerticesStored;
+ TempBufferVerticesStored += 8;
+ TempBufferIndicesStored += 12*3;
+ break;
+
+ case BRIGHTLIGHT_SIREN:
+ for(j = 0; j < 6; j++){
+ pos = SirenLightsSide[j]*aBrightLights[i].m_side +
+ SirenLightsUp[j]*aBrightLights[i].m_up +
+ aBrightLights[i].m_pos;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+j], r, g, b, a);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+j], pos.x, pos.y, pos.z);
+ }
+ for(j = 0; j < 4*3; j++)
+ TempBufferRenderIndexList[TempBufferIndicesStored+j] = TrafficLightIndices[j] + TempBufferVerticesStored;
+ TempBufferVerticesStored += 6;
+ TempBufferIndicesStored += 4*3;
+ break;
+
+ }
+ }
+
+ RenderOutGeometryBuffer();
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ NumBrightLights = 0;
+}
+
+void
+CBrightLights::RenderOutGeometryBuffer(void)
+{
+ if(TempBufferIndicesStored != 0){
+ LittleTest();
+ if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
+ RwIm3DEnd();
+ }
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+ }
+}
+
+int CShinyTexts::NumShinyTexts;
+CShinyText CShinyTexts::aShinyTexts[NUMSHINYTEXTS];
+
+void
+CShinyTexts::Init(void)
+{
+ NumShinyTexts = 0;
+}
+
+void
+CShinyTexts::RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
+ float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3,
+ uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist)
+{
+ if(NumShinyTexts >= NUMSHINYTEXTS)
+ return;
+
+ aShinyTexts[NumShinyTexts].m_camDist = (p0 - TheCamera.GetPosition()).Magnitude();
+ if(aShinyTexts[NumShinyTexts].m_camDist > maxDist)
+ return;
+ aShinyTexts[NumShinyTexts].m_verts[0] = p0;
+ aShinyTexts[NumShinyTexts].m_verts[1] = p1;
+ aShinyTexts[NumShinyTexts].m_verts[2] = p2;
+ aShinyTexts[NumShinyTexts].m_verts[3] = p3;
+ aShinyTexts[NumShinyTexts].m_texCoords[0].x = u0;
+ aShinyTexts[NumShinyTexts].m_texCoords[0].y = v0;
+ aShinyTexts[NumShinyTexts].m_texCoords[1].x = u1;
+ aShinyTexts[NumShinyTexts].m_texCoords[1].y = v1;
+ aShinyTexts[NumShinyTexts].m_texCoords[2].x = u2;
+ aShinyTexts[NumShinyTexts].m_texCoords[2].y = v2;
+ aShinyTexts[NumShinyTexts].m_texCoords[3].x = u3;
+ aShinyTexts[NumShinyTexts].m_texCoords[3].y = v3;
+ aShinyTexts[NumShinyTexts].m_type = type;
+ aShinyTexts[NumShinyTexts].m_red = red;
+ aShinyTexts[NumShinyTexts].m_green = green;
+ aShinyTexts[NumShinyTexts].m_blue = blue;
+ // Fade out at half the max dist
+ float halfDist = maxDist*0.5f;
+ if(aShinyTexts[NumShinyTexts].m_camDist > halfDist){
+ float f = 1.0f - (aShinyTexts[NumShinyTexts].m_camDist - halfDist)/halfDist;
+ aShinyTexts[NumShinyTexts].m_red *= f;
+ aShinyTexts[NumShinyTexts].m_green *= f;
+ aShinyTexts[NumShinyTexts].m_blue *= f;
+ }
+
+ NumShinyTexts++;
+}
+
+void
+CShinyTexts::Render(void)
+{
+ int i, ix, v;
+ RwTexture *lastTex = nil;
+
+ if(NumShinyTexts == 0)
+ return;
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+
+ for(i = 0; i < NumShinyTexts; i++){
+ if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-64 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-62)
+ RenderOutGeometryBuffer();
+
+ uint8 r = aShinyTexts[i].m_red;
+ uint8 g = aShinyTexts[i].m_green;
+ uint8 b = aShinyTexts[i].m_blue;
+
+ switch(aShinyTexts[i].m_type){
+ case SHINYTEXT_WALK:
+ if(lastTex != gpWalkDontTex){
+ RenderOutGeometryBuffer();
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpWalkDontTex));
+ lastTex = gpWalkDontTex;
+ }
+ quad:
+ v = TempBufferVerticesStored;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+0], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], aShinyTexts[i].m_verts[0].x, aShinyTexts[i].m_verts[0].y, aShinyTexts[i].m_verts[0].z);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+0], aShinyTexts[i].m_texCoords[0].x);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+0], aShinyTexts[i].m_texCoords[0].y);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+1], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], aShinyTexts[i].m_verts[1].x, aShinyTexts[i].m_verts[1].y, aShinyTexts[i].m_verts[1].z);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+1], aShinyTexts[i].m_texCoords[1].x);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+1], aShinyTexts[i].m_texCoords[1].y);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+2], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], aShinyTexts[i].m_verts[2].x, aShinyTexts[i].m_verts[2].y, aShinyTexts[i].m_verts[2].z);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+2], aShinyTexts[i].m_texCoords[2].x);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+2], aShinyTexts[i].m_texCoords[2].y);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+3], r, g, b, 255);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], aShinyTexts[i].m_verts[3].x, aShinyTexts[i].m_verts[3].y, aShinyTexts[i].m_verts[3].z);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[v+3], aShinyTexts[i].m_texCoords[3].x);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[v+3], aShinyTexts[i].m_texCoords[3].y);
+ ix = TempBufferIndicesStored;
+ TempBufferRenderIndexList[ix+0] = 0 + TempBufferVerticesStored;
+ TempBufferRenderIndexList[ix+1] = 1 + TempBufferVerticesStored;
+ TempBufferRenderIndexList[ix+2] = 2 + TempBufferVerticesStored;
+ TempBufferRenderIndexList[ix+3] = 2 + TempBufferVerticesStored;
+ TempBufferRenderIndexList[ix+4] = 1 + TempBufferVerticesStored;
+ TempBufferRenderIndexList[ix+5] = 3 + TempBufferVerticesStored;
+ TempBufferVerticesStored += 4;
+ TempBufferIndicesStored += 6;
+ break;
+
+ case SHINYTEXT_FLAT:
+ if(lastTex != nil){
+ RenderOutGeometryBuffer();
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ lastTex = nil;
+ }
+ goto quad;
+ }
+ }
+
+ RenderOutGeometryBuffer();
+ NumShinyTexts = 0;
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+}
+
+void
+CShinyTexts::RenderOutGeometryBuffer(void)
+{
+ if(TempBufferIndicesStored != 0){
+ LittleTest();
+ if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
+ RwIm3DEnd();
+ }
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+ }
+}
+
+
+
#define MONEY_MESSAGE_LIFETIME_MS 2000
CMoneyMessage CMoneyMessages::aMoneyMessages[NUMMONEYMESSAGES];
@@ -564,6 +1167,16 @@ STARTPATCHES
InjectHook(0x51B400, C3dMarkers::Render, PATCH_JUMP);
InjectHook(0x51B3B0, C3dMarkers::Shutdown, PATCH_JUMP);
+ InjectHook(0x5197A0, CBrightLights::Init, PATCH_JUMP);
+ InjectHook(0x51A410, CBrightLights::RegisterOne, PATCH_JUMP);
+ InjectHook(0x5197B0, CBrightLights::Render, PATCH_JUMP);
+ InjectHook(0x51A3B0, CBrightLights::RenderOutGeometryBuffer, PATCH_JUMP);
+
+ InjectHook(0x51A5A0, CShinyTexts::Init, PATCH_JUMP);
+ InjectHook(0x51AAB0, CShinyTexts::RegisterOne, PATCH_JUMP);
+ InjectHook(0x51A5B0, CShinyTexts::Render, PATCH_JUMP);
+ InjectHook(0x51AA50, CShinyTexts::RenderOutGeometryBuffer, PATCH_JUMP);
+
InjectHook(0x51AF70, CMoneyMessages::Init, PATCH_JUMP);
InjectHook(0x51B030, CMoneyMessages::Render, PATCH_JUMP);
ENDPATCHES
diff --git a/src/render/SpecialFX.h b/src/render/SpecialFX.h
index fc155a53..2d9f18b1 100644
--- a/src/render/SpecialFX.h
+++ b/src/render/SpecialFX.h
@@ -9,10 +9,29 @@ public:
static void Shutdown(void);
};
+class CRegisteredMotionBlurStreak
+{
+public:
+ uintptr m_id;
+ uint8 m_red;
+ uint8 m_green;
+ uint8 m_blue;
+ CVector m_pos1[3];
+ CVector m_pos2[3];
+ bool m_isValid[3];
+
+ void Update(void);
+ void Render(void);
+};
+
class CMotionBlurStreaks
{
+ static CRegisteredMotionBlurStreak aStreaks[NUMMBLURSTREAKS];
public:
- static void RegisterStreak(int32 id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2);
+ static void Init(void);
+ static void Update(void);
+ static void RegisterStreak(uintptr id, uint8 r, uint8 g, uint8 b, CVector p1, CVector p2);
+ static void Render(void);
};
struct CBulletTrace
@@ -29,7 +48,7 @@ struct CBulletTrace
class CBulletTraces
{
public:
- static CBulletTrace (&aTraces)[NUMBULLETTRACES];
+ static CBulletTrace aTraces[NUMBULLETTRACES];
static void Init(void);
static void AddTrace(CVector*, CVector*);
@@ -37,12 +56,6 @@ public:
static void Update(void);
};
-class CBrightLights
-{
-public:
- static void RegisterOne(CVector pos, CVector up, CVector right, CVector fwd, uint8 type, uint8 unk1 = 0, uint8 unk2 = 0, uint8 unk3 = 0);
-};
-
enum
{
MARKERTYPE_0 = 0,
@@ -57,27 +70,27 @@ enum
class C3dMarker
-{
-public:
- CMatrix m_Matrix;
- RpAtomic *m_pAtomic;
- RpMaterial *m_pMaterial;
- uint16 m_nType;
- bool m_bIsUsed;
- uint32 m_nIdentifier;
- RwRGBA m_Color;
- uint16 m_nPulsePeriod;
- int16 m_nRotateRate;
- uint32 m_nStartTime;
- float m_fPulseFraction;
- float m_fStdSize;
- float m_fSize;
- float m_fBrightness;
- float m_fCameraRange;
-
- bool AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
- void DeleteMarkerObject();
- void Render();
+{
+public:
+ CMatrix m_Matrix;
+ RpAtomic *m_pAtomic;
+ RpMaterial *m_pMaterial;
+ uint16 m_nType;
+ bool m_bIsUsed;
+ uint32 m_nIdentifier;
+ RwRGBA m_Color;
+ uint16 m_nPulsePeriod;
+ int16 m_nRotateRate;
+ uint32 m_nStartTime;
+ float m_fPulseFraction;
+ float m_fStdSize;
+ float m_fSize;
+ float m_fBrightness;
+ float m_fCameraRange;
+
+ bool AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
+ void DeleteMarkerObject();
+ void Render();
};
class C3dMarkers
@@ -87,42 +100,125 @@ public:
static void Shutdown();
static C3dMarker *PlaceMarker(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
static void PlaceMarkerSet(uint32 id, uint16 type, CVector &pos, float size, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate);
- static void Render();
+ static void Render();
static void Update();
- static C3dMarker(&m_aMarkerArray)[NUM3DMARKERS];
- static int32 &NumActiveMarkers;
- static RpClump* (&m_pRpClumpArray)[NUMMARKERTYPES];
-};
-
-class CMoneyMessage
-{
- friend class CMoneyMessages;
-
- uint32 m_nTimeRegistered;
- CVector m_vecPosition;
- wchar m_aText[16];
- CRGBA m_Colour;
- float m_fSize;
- float m_fOpacity;
-public:
- void Render();
-};
-
-class CMoneyMessages
-{
- static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES];
-public:
- static void Init();
- static void Render();
- static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity);
-};
-
-class CSpecialParticleStuff
-{
- static uint32 BoatFromStart;
-public:
- static void CreateFoamAroundObject(CMatrix*, float, float, float, int32);
- static void StartBoatFoamAnimation();
- static void UpdateBoatFoamAnimation(CMatrix*);
-};
+ static C3dMarker m_aMarkerArray[NUM3DMARKERS];
+ static int32 NumActiveMarkers;
+ static RpClump* m_pRpClumpArray[NUMMARKERTYPES];
+};
+
+enum
+{
+ BRIGHTLIGHT_INVALID,
+ BRIGHTLIGHT_TRAFFIC_GREEN,
+ BRIGHTLIGHT_TRAFFIC_YELLOW,
+ BRIGHTLIGHT_TRAFFIC_RED,
+
+ // white
+ BRIGHTLIGHT_FRONT_LONG,
+ BRIGHTLIGHT_FRONT_SMALL,
+ BRIGHTLIGHT_FRONT_BIG,
+ BRIGHTLIGHT_FRONT_TALL,
+
+ // red
+ BRIGHTLIGHT_REAR_LONG,
+ BRIGHTLIGHT_REAR_SMALL,
+ BRIGHTLIGHT_REAR_BIG,
+ BRIGHTLIGHT_REAR_TALL,
+
+ BRIGHTLIGHT_SIREN, // unused
+
+ BRIGHTLIGHT_FRONT = BRIGHTLIGHT_FRONT_LONG,
+ BRIGHTLIGHT_REAR = BRIGHTLIGHT_REAR_LONG,
+};
+
+class CBrightLight
+{
+public:
+ CVector m_pos;
+ CVector m_up;
+ CVector m_side;
+ CVector m_front;
+ float m_camDist;
+ uint8 m_type;
+ uint8 m_red;
+ uint8 m_green;
+ uint8 m_blue;
+};
+
+class CBrightLights
+{
+ static int NumBrightLights;
+ static CBrightLight aBrightLights[NUMBRIGHTLIGHTS];
+public:
+ static void Init(void);
+ static void RegisterOne(CVector pos, CVector up, CVector side, CVector front,
+ uint8 type, uint8 red = 0, uint8 green = 0, uint8 blue = 0);
+ static void Render(void);
+ static void RenderOutGeometryBuffer(void);
+};
+
+
+enum
+{
+ SHINYTEXT_WALK = 1,
+ SHINYTEXT_FLAT
+};
+
+class CShinyText
+{
+public:
+ CVector m_verts[4];
+ CVector2D m_texCoords[4];
+ float m_camDist;
+ uint8 m_type;
+ uint8 m_red;
+ uint8 m_green;
+ uint8 m_blue;
+};
+
+class CShinyTexts
+{
+ static int NumShinyTexts;
+ static CShinyText aShinyTexts[NUMSHINYTEXTS];
+public:
+ static void Init(void);
+ static void RegisterOne(CVector p0, CVector p1, CVector p2, CVector p3,
+ float u0, float v0, float u1, float v1, float u2, float v2, float u3, float v3,
+ uint8 type, uint8 red, uint8 green, uint8 blue, float maxDist);
+ static void Render(void);
+ static void RenderOutGeometryBuffer(void);
+};
+
+class CMoneyMessage
+{
+ friend class CMoneyMessages;
+
+ uint32 m_nTimeRegistered;
+ CVector m_vecPosition;
+ wchar m_aText[16];
+ CRGBA m_Colour;
+ float m_fSize;
+ float m_fOpacity;
+public:
+ void Render();
+};
+
+class CMoneyMessages
+{
+ static CMoneyMessage aMoneyMessages[NUMMONEYMESSAGES];
+public:
+ static void Init();
+ static void Render();
+ static void RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity);
+};
+
+class CSpecialParticleStuff
+{
+ static uint32 BoatFromStart;
+public:
+ static void CreateFoamAroundObject(CMatrix*, float, float, float, int32);
+ static void StartBoatFoamAnimation();
+ static void UpdateBoatFoamAnimation(CMatrix*);
+};
diff --git a/src/render/Sprite.cpp b/src/render/Sprite.cpp
index 24577f41..8ac2315f 100644
--- a/src/render/Sprite.cpp
+++ b/src/render/Sprite.cpp
@@ -30,10 +30,12 @@ CSprite::CalcScreenCoors(const RwV3d &in, RwV3d *out, float *outw, float *outh,
out->x *= SCREEN_WIDTH * recip;
out->y *= SCREEN_HEIGHT * recip;
// What is this? size?
- *outw = 70.0f/CDraw::GetFOV();
- *outh = 70.0f/CDraw::GetFOV();
- *outw *= SCREEN_WIDTH * recip;
- *outh *= SCREEN_HEIGHT * recip;
+ *outw = 70.0f/CDraw::GetFOV() * SCREEN_WIDTH * recip;
+#ifdef ASPECT_RATIO_SCALE
+ *outh = 70.0f/CDraw::GetFOV() / (DEFAULT_ASPECT_RATIO / SCREEN_ASPECT_RATIO) * SCREEN_HEIGHT * recip;
+#else
+ *outh = 70.0f/CDraw::GetFOV() * SCREEN_HEIGHT * recip;
+#endif
return true;
}
@@ -432,6 +434,7 @@ void
CSprite::Set6Vertices2D(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
float screenz, recipz;
+ float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = m_f2DNearScreenZ;
recipz = m_fRecipNearClipPlane;
@@ -496,6 +499,7 @@ CSprite::Set6Vertices2D(RwIm2DVertex *verts, float x1, float y1, float x2, float
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
float screenz, recipz;
+ float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = m_f2DNearScreenZ;
recipz = m_fRecipNearClipPlane;
diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp
index c4dbcdaa..3f21516a 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/render/Sprite2d.cpp
@@ -267,6 +267,7 @@ CSprite2d::SetVertices(float x1, float y1, float x2, float y2, float x3, float y
const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3)
{
float screenz, recipz;
+ float z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
@@ -312,10 +313,11 @@ void
CSprite2d::SetVertices(int n, float *positions, float *uvs, const CRGBA &col)
{
int i;
- float screenz, recipz;
+ float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
+ z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){
@@ -334,10 +336,11 @@ void
CSprite2d::SetMaskVertices(int n, float *positions)
{
int i;
- float screenz, recipz;
+ float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
+ z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
for(i = 0; i < n; i++){
RwIm2DVertexSetScreenX(&maVertices[i], positions[i*2 + 0]);
@@ -345,7 +348,7 @@ CSprite2d::SetMaskVertices(int n, float *positions)
RwIm2DVertexSetScreenZ(&maVertices[i], screenz);
RwIm2DVertexSetCameraZ(&maVertices[i], z);
RwIm2DVertexSetRecipCameraZ(&maVertices[i], recipz);
- RwIm2DVertexSetIntRGBA(&maVertices[i], 0, 0, 0, 0);
+ RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC
}
}
@@ -353,10 +356,11 @@ void
CSprite2d::SetVertices(RwIm2DVertex *verts, const CRect &r, const CRGBA &c0, const CRGBA &c1, const CRGBA &c2, const CRGBA &c3,
float u0, float v0, float u1, float v1, float u3, float v3, float u2, float v2)
{
- float screenz, recipz;
+ float screenz, recipz, z;
screenz = RwIm2DGetNearScreenZ();
recipz = RecipNearClip;
+ z = RwCameraGetNearClipPlane(Scene.camera); // not done by game
RwIm2DVertexSetScreenX(&verts[0], r.left);
RwIm2DVertexSetScreenY(&verts[0], r.top);
@@ -459,15 +463,15 @@ CSprite2d::DrawRectXLU(const CRect &r, const CRGBA &c0, const CRGBA &c1, const C
void CSprite2d::Draw2DPolygon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, const CRGBA &color)
{
- SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
- RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255));
- RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ SetVertices(x1, y1, x2, y2, x3, y3, x4, y4, color, color, color, color);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(color.a != 255));
+ RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::maVertices, 4);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
}
diff --git a/src/render/TexList.cpp b/src/render/TexList.cpp
new file mode 100644
index 00000000..1689837f
--- /dev/null
+++ b/src/render/TexList.cpp
@@ -0,0 +1,41 @@
+#include "common.h"
+#include "TexList.h"
+#include "rtbmp.h"
+#include "FileMgr.h"
+
+bool CTexList::ms_nTexUsed[MAX_TEXUSED];
+
+void
+CTexList::Initialise()
+{}
+
+void
+CTexList::Shutdown()
+{}
+
+RwTexture *
+CTexList::SetTexture(int32 slot, char *name)
+{
+ return nil;
+}
+
+int32
+CTexList::GetFirstFreeTexture()
+{
+ for (int32 i = 0; i < MAX_TEXUSED; i++)
+ if (!ms_nTexUsed[i])
+ return i;
+ return -1;
+}
+
+RwTexture *
+CTexList::LoadFileNameTexture(char *name)
+{
+ return SetTexture(GetFirstFreeTexture(), name);
+}
+
+void
+CTexList::LoadGlobalTextureList()
+{
+ CFileMgr::SetDir("TEXTURES");
+} \ No newline at end of file
diff --git a/src/render/TexList.h b/src/render/TexList.h
new file mode 100644
index 00000000..7e042211
--- /dev/null
+++ b/src/render/TexList.h
@@ -0,0 +1,14 @@
+#pragma once
+
+class CTexList
+{
+ enum { MAX_TEXUSED = 400, };
+ static bool ms_nTexUsed[MAX_TEXUSED];
+public:
+ static void Initialise();
+ static void Shutdown();
+ static RwTexture *SetTexture(int32 slot, char *name);
+ static int32 GetFirstFreeTexture();
+ static RwTexture *LoadFileNameTexture(char *name);
+ static void LoadGlobalTextureList();
+}; \ No newline at end of file
diff --git a/src/render/Timecycle.h b/src/render/Timecycle.h
index 235d559c..ed4a026b 100644
--- a/src/render/Timecycle.h
+++ b/src/render/Timecycle.h
@@ -119,8 +119,10 @@ public:
static int GetSunCoronaBlue(void) { return m_nCurrentSunCoronaBlue; }
static float GetSunSize(void) { return m_fCurrentSunSize; }
static float GetSpriteBrightness(void) { return m_fCurrentSpriteBrightness; }
+ static float GetSpriteSize(void) { return m_fCurrentSpriteSize; }
static int GetShadowStrength(void) { return m_nCurrentShadowStrength; }
static int GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; }
+ static int GetLightOnGroundBrightness(void) { return m_fCurrentLightsOnGroundBrightness; }
static float GetFarClip(void) { return m_fCurrentFarClip; }
static float GetFogStart(void) { return m_fCurrentFogStart; }
@@ -136,6 +138,7 @@ public:
static int GetFogRed(void) { return m_nCurrentFogColourRed; }
static int GetFogGreen(void) { return m_nCurrentFogColourGreen; }
static int GetFogBlue(void) { return m_nCurrentFogColourBlue; }
+ static int GetFogReduction(void) { return m_FogReduction; }
static void Initialise(void);
static void Update(void);
diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp
index c1988ab4..b440e77c 100644
--- a/src/render/Weather.cpp
+++ b/src/render/Weather.cpp
@@ -2,6 +2,22 @@
#include "patcher.h"
#include "Weather.h"
+#include "Camera.h"
+#include "Clock.h"
+#include "CutsceneMgr.h"
+#include "DMAudio.h"
+#include "General.h"
+#include "Pad.h"
+#include "Particle.h"
+#include "RenderBuffer.h"
+#include "Stats.h"
+#include "Shadows.h"
+#include "Timecycle.h"
+#include "Timer.h"
+#include "Vehicle.h"
+#include "World.h"
+#include "ZoneCull.h"
+
int32 &CWeather::SoundHandle = *(int32*)0x5FFBC4;
int32 &CWeather::WeatherTypeInList = *(int32*)0x8F626C;
@@ -32,13 +48,203 @@ int16 &CWeather::Stored_OldWeatherType = *(int16*)0x95CC68;
int16 &CWeather::Stored_NewWeatherType = *(int16*)0x95CCAE;
float &CWeather::Stored_Rain = *(float*)0x885B4C;
-WRAPPER void CWeather::RenderRainStreaks(void) { EAXJMP(0x524550); }
-WRAPPER void CWeather::Update(void) { EAXJMP(0x522C10); }
-WRAPPER void CWeather::Init(void) { EAXJMP(0x522BA0); }
+tRainStreak Streaks[NUM_RAIN_STREAKS];
-void CWeather::ReleaseWeather()
+const int16 WeatherTypesList[] = {
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY,
+ WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_CLOUDY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_CLOUDY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY, WEATHER_CLOUDY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY,
+ WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_CLOUDY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_RAINY, WEATHER_CLOUDY,
+};
+
+const float Windiness[] = {
+ 0.0f, // WEATHER_SUNNY
+ 0.7f, // WEATHER_CLOUDY
+ 1.0f, // WEATHER_RAINY
+ 0.5f // WEATHER_FOGGY
+};
+
+#define MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES (50)
+
+#define RAIN_CHANGE_SPEED (0.003f)
+
+#define DROPLETS_LEFT_OFFSET (10.0f)
+#define DROPLETS_RIGHT_OFFSET (10.0f)
+#define DROPLETS_TOP_OFFSET (10.0f)
+#define DROPLETS_BOTTOM_OFFSET (10.0f)
+
+#define STREAK_U (10.0f)
+#define STREAK_V (18.0f)
+#define LARGE_STREAK_COEFFICIENT (1.23f)
+#define STREAK_MIN_DISTANCE (8.0f)
+#define STREAK_MAX_DISTANCE (16.0f)
+
+#define SPLASH_CHECK_RADIUS (7.0f)
+#define SPLASH_OFFSET_RADIUS (2.0f)
+
+#define STREAK_LIFETIME (4.0f)
+#define STREAK_INTEROLATION_TIME (0.3f)
+
+#define RAIN_COLOUR_R (200)
+#define RAIN_COLOUR_G (200)
+#define RAIN_COLOUR_B (256)
+#define RAIN_ALPHA (255)
+
+void CWeather::Init(void)
{
- ForcedWeatherType = -1;
+ NewWeatherType = WEATHER_SUNNY;
+ bScriptsForceRain = false;
+ OldWeatherType = WEATHER_CLOUDY;
+ Stored_StateStored = false;
+ InterpolationValue = 0.0f;
+ WhenToPlayLightningSound = 0;
+ WeatherTypeInList = 0;
+ ForcedWeatherType = WEATHER_RANDOM;
+ SoundHandle = DMAudio.CreateEntity(AUDIOTYPE_WEATHER, (void*)1);
+ if (SoundHandle >= 0)
+ DMAudio.SetEntityStatus(SoundHandle, 1);
+}
+
+void CWeather::Update(void)
+{
+ float fNewInterpolation = CClock::GetMinutes() * 1.0f / 60;
+ if (fNewInterpolation < InterpolationValue) {
+ // new hour
+ OldWeatherType = NewWeatherType;
+ if (ForcedWeatherType >= 0)
+ NewWeatherType = ForcedWeatherType;
+ else {
+ WeatherTypeInList = (WeatherTypeInList + 1) % ARRAYSIZE(WeatherTypesList);
+ NewWeatherType = WeatherTypesList[WeatherTypeInList];
+#ifdef FIX_BUGS
+ }
+ if (NewWeatherType == WEATHER_RAINY)
+ CStats::mmRain += CGeneral::GetRandomNumber() & 7;
+#else
+ if (NewWeatherType == WEATHER_RAINY)
+ CStats::mmRain += CGeneral::GetRandomNumber() & 7;
+ }
+#endif
+ }
+ InterpolationValue = fNewInterpolation;
+ if (CPad::GetPad(1)->GetRightShockJustDown()) {
+ NewWeatherType = (NewWeatherType + 1) % WEATHER_TOTAL;
+ OldWeatherType = NewWeatherType;
+ }
+
+ // Lightning
+ if (NewWeatherType != WEATHER_RAINY || OldWeatherType != WEATHER_RAINY) {
+ LightningFlash = false;
+ LightningBurst = false;
+ }
+ else{
+ if (LightningBurst) {
+ if ((CGeneral::GetRandomNumber() & 255) >= 32) {
+ // 0.875 probability
+ if (CTimer::GetTimeInMilliseconds() - LightningFlashLastChange > MIN_TIME_BETWEEN_LIGHTNING_FLASH_CHANGES) {
+ bool bOldLightningFlash = LightningFlash;
+ LightningFlash = CGeneral::GetRandomTrueFalse();
+ if (LightningFlash != bOldLightningFlash)
+ LightningFlashLastChange = CTimer::GetTimeInMilliseconds();
+ }
+ }
+ else {
+ // 0.125 probability
+ LightningBurst = false;
+ LightningDuration = min(CTimer::GetFrameCounter() - LightningStart, 20);
+ LightningFlash = false;
+ WhenToPlayLightningSound = CTimer::GetTimeInMilliseconds() + 150 * (20 - LightningDuration);
+ }
+ }
+ else {
+ if (CGeneral::GetRandomNumber() >= 200) {
+ // lower probability on PC due to randomness bug
+ LightningFlash = false;
+ }
+ else {
+ LightningBurst = true;
+ LightningStart = CTimer::GetFrameCounter();
+ LightningFlashLastChange = CTimer::GetTimeInMilliseconds();
+ LightningFlash = true;
+ }
+ }
+ }
+ if (WhenToPlayLightningSound && CTimer::GetTimeInMilliseconds() > WhenToPlayLightningSound) {
+ DMAudio.PlayOneShot(SoundHandle, SOUND_LIGHTNING, LightningDuration);
+ CPad::GetPad(0)->StartShake(40 * LightningDuration + 100, 2 * LightningDuration + 80);
+ WhenToPlayLightningSound = 0;
+ }
+
+ // Wet roads
+ if (OldWeatherType == WEATHER_RAINY) {
+ if (NewWeatherType == WEATHER_RAINY)
+ WetRoads = 1.0f;
+ else
+ WetRoads = 1.0f - InterpolationValue;
+ }
+ else {
+ if (NewWeatherType == WEATHER_RAINY)
+ WetRoads = InterpolationValue;
+ else
+ WetRoads = 0.0f;
+ }
+
+ // Rain
+ float fNewRain;
+ if (NewWeatherType == WEATHER_RAINY) {
+ // if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s
+ fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f;
+ if (OldWeatherType != WEATHER_RAINY) {
+ if (InterpolationValue < 0.4f)
+ // if rain has just started (<24 minutes), always 0.5
+ fNewRain = 0.5f;
+ else
+ // if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s
+ fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f;
+ }
+ }
+ else
+ fNewRain = 0.0f;
+ if (Rain != fNewRain) { // ok to use comparasion
+ if (Rain < fNewRain)
+ Rain = min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
+ else
+ Rain = max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
+ }
+
+ // Clouds
+ if (OldWeatherType != WEATHER_SUNNY)
+ CloudCoverage = 1.0f - InterpolationValue;
+ else
+ CloudCoverage = 0.0f;
+ if (NewWeatherType != WEATHER_SUNNY)
+ CloudCoverage += InterpolationValue;
+
+ // Fog
+ if (OldWeatherType == WEATHER_FOGGY)
+ Foggyness = 1.0f - InterpolationValue;
+ else
+ Foggyness = 0.0f;
+ if (NewWeatherType == WEATHER_FOGGY)
+ Foggyness += InterpolationValue;
+ if (OldWeatherType == WEATHER_RAINY && NewWeatherType == WEATHER_SUNNY && InterpolationValue < 0.5f && CClock::GetHours() > 6 && CClock::GetHours() < 21)
+ Rainbow = 1.0f - 4.0f * Abs(InterpolationValue - 0.25f) / 4.0f;
+ else
+ Rainbow = 0.0f;
+ Wind = InterpolationValue * Windiness[NewWeatherType] + (1.0f - InterpolationValue) * Windiness[OldWeatherType];
+ AddRain();
}
void CWeather::ForceWeather(int16 weather)
@@ -53,6 +259,258 @@ void CWeather::ForceWeatherNow(int16 weather)
ForcedWeatherType = weather;
}
+void CWeather::ReleaseWeather()
+{
+ ForcedWeatherType = -1;
+}
+
+void CWeather::AddRain()
+{
+ if (CCullZones::CamNoRain() || CCullZones::PlayerNoRain())
+ return;
+ if (TheCamera.GetLookingLRBFirstPerson()) {
+ CVehicle* pVehicle = FindPlayerVehicle();
+ if (pVehicle && pVehicle->CarHasRoof()) {
+ CParticle::RemovePSystem(PARTICLE_RAINDROP_2D);
+ return;
+ }
+ }
+ if (Rain <= 0.1f)
+ return;
+ static RwRGBA colour;
+ float screen_width = RsGlobal.width;
+ float screen_height = RsGlobal.height;
+ int cur_frame = (int)(3 * Rain) & 3;
+ int num_drops = (int)(2 * Rain) + 2;
+ static int STATIC_RAIN_ANGLE = -45;
+ static int count = 1500;
+ static int add_angle = 1;
+ if (--count == 0) {
+ count = 1;
+ if (add_angle) {
+ STATIC_RAIN_ANGLE += 12;
+ if (STATIC_RAIN_ANGLE > 45) {
+ count = 1500;
+ add_angle = !add_angle;
+ }
+ }
+ else {
+ STATIC_RAIN_ANGLE -= 12;
+ if (STATIC_RAIN_ANGLE < -45) {
+ count = 1500;
+ add_angle = !add_angle;
+ }
+ }
+ }
+ float rain_angle = DEGTORAD(STATIC_RAIN_ANGLE + ((STATIC_RAIN_ANGLE < 0) ? 360 : 0));
+ float sin_angle = Sin(rain_angle);
+ float cos_angle = Cos(rain_angle);
+ float base_x = 0.0f * cos_angle - 1.0f * sin_angle;
+ float base_y = 1.0f * cos_angle + 0.0f * sin_angle;
+ CVector xpos(0.0f, 0.0f, 0.0f);
+ for (int i = 0; i < 2 * num_drops; i++) {
+ CVector dir;
+ dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
+ dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
+ dir.z = 0;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, xpos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
+ colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
+ xpos.x += screen_width / (2 * num_drops);
+ xpos.x += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
+ }
+ CVector ypos(0.0f, 0.0f, 0.0f);
+ for (int i = 0; i < num_drops; i++) {
+ CVector dir;
+ dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
+ dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
+ dir.z = 0;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
+ colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
+ ypos.y += screen_width / num_drops;
+ ypos.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
+ }
+ CVector ypos2(0.0f, 0.0f, 0.0f);
+ for (int i = 0; i < num_drops; i++) {
+ CVector dir;
+ dir.x = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_x) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
+ dir.y = (CGeneral::GetRandomNumberInRange(-0.5f, 0.5f) + base_y) * CGeneral::GetRandomNumberInRange(10.0f, 25.0f);
+ dir.z = 0;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, ypos2, dir, nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
+ colour, 0, rain_angle + CGeneral::GetRandomNumberInRange(-10, 10), cur_frame);
+ ypos2.y += screen_width / num_drops;
+ ypos2.y += CGeneral::GetRandomNumberInRange(-25.0f, 25.0f);
+ }
+ for (int i = 0; i < num_drops; i++) {
+ CVector pos;
+ pos.x = CGeneral::GetRandomNumberInRange(DROPLETS_LEFT_OFFSET, screen_width - DROPLETS_RIGHT_OFFSET);
+ pos.y = CGeneral::GetRandomNumberInRange(DROPLETS_TOP_OFFSET, screen_height - DROPLETS_TOP_OFFSET);
+ pos.z = 0.0f;
+ CParticle::AddParticle(PARTICLE_RAINDROP_2D, pos, CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.9f),
+ colour, CGeneral::GetRandomNumberInRange(-10, 10), 360 - rain_angle + CGeneral::GetRandomNumberInRange(-30, 30), cur_frame, 0);
+ }
+ int num_splash_attempts = (int)(3 * Rain) + 1;
+ int num_splashes = (int)(3 * Rain) + 4;
+ CVector splash_points[4];
+ splash_points[0] = CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
+ RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
+ splash_points[1] = CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
+ RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
+ splash_points[2] = 4.0f * CVector(-RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
+ RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
+ splash_points[3] = 4.0f * CVector(RwCameraGetViewWindow(TheCamera.m_pRwCamera)->x, RwCameraGetViewWindow(TheCamera.m_pRwCamera)->y, 1.0f) *
+ RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) / (RwCameraGetFarClipPlane(TheCamera.m_pRwCamera) * *(CVector2D*)RwCameraGetViewWindow(TheCamera.m_pRwCamera)).Magnitude();
+ RwV3dTransformPoints((RwV3d*)splash_points, (RwV3d*)splash_points, 4, RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
+ CVector fp = (splash_points[0] + splash_points[1] + splash_points[2] + splash_points[3]) / 4;
+ for (int i = 0; i < num_splash_attempts; i++) {
+ CColPoint point;
+ CEntity* entity;
+ CVector np = fp + CVector(CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), CGeneral::GetRandomNumberInRange(-SPLASH_CHECK_RADIUS, SPLASH_CHECK_RADIUS), 0.0f);
+ if (CWorld::ProcessVerticalLine(np + CVector(0.0f, 0.0f, 40.0f), -40.0f, point, entity, true, false, false, false, true, false, nil)) {
+ for (int j = 0; j < num_splashes; j++)
+ CParticle::AddParticle((CGeneral::GetRandomTrueFalse() ? PARTICLE_RAIN_SPLASH : PARTICLE_RAIN_SPLASHUP),
+ CVector(
+ np.x + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
+ np.y + CGeneral::GetRandomNumberInRange(-SPLASH_OFFSET_RADIUS, SPLASH_OFFSET_RADIUS),
+ point.point.z + 0.1f),
+ CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colour);
+ }
+ }
+}
+
+void RenderOneRainStreak(CVector pos, CVector unused, int intensity, bool scale, float distance)
+{
+ static float RandomTex;
+ static float RandomTexX;
+ static float RandomTexY;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 0] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 1] = TempBufferVerticesStored + 2;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 2] = TempBufferVerticesStored + 1;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 3] = TempBufferVerticesStored + 0;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 4] = TempBufferVerticesStored + 3;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 5] = TempBufferVerticesStored + 2;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 6] = TempBufferVerticesStored + 1;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 7] = TempBufferVerticesStored + 2;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 8] = TempBufferVerticesStored + 4;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 9] = TempBufferVerticesStored + 2;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 10] = TempBufferVerticesStored + 3;
+ TempBufferRenderIndexList[TempBufferIndicesStored + 11] = TempBufferVerticesStored + 4;
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0, 0, 0, 0);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 0], pos.x + 11.0f * TheCamera.GetUp().x, pos.y + 11.0f * TheCamera.GetUp().y, pos.z + 11.0f * TheCamera.GetUp().z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 1], 0, 0, 0, 0);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 1], pos.x - 9.0f * TheCamera.GetRight().x, pos.y - 9.0f * TheCamera.GetRight().y, pos.z - 9.0f * TheCamera.GetUp().z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RAIN_COLOUR_R * intensity / 256, RAIN_COLOUR_G * intensity / 256, RAIN_COLOUR_B * intensity / 256, RAIN_ALPHA);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 2], pos.x, pos.y, pos.z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 3], 0, 0, 0, 0);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 3], pos.x + 9.0f * TheCamera.GetRight().x, pos.y + 9.0f * TheCamera.GetRight().y, pos.z + 9.0f * TheCamera.GetUp().z);
+ RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0, 0, 0, 0);
+ RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored + 4], pos.x - 11.0f * TheCamera.GetUp().x, pos.y - 11.0f * TheCamera.GetUp().y, pos.z - 11.0f * TheCamera.GetUp().z);
+ float u = STREAK_U;
+ float v = STREAK_V;
+ if (scale) {
+ u *= LARGE_STREAK_COEFFICIENT;
+ v *= LARGE_STREAK_COEFFICIENT;
+ }
+ float distance_coefficient;
+ if (distance < STREAK_MIN_DISTANCE)
+ distance_coefficient = 1.0f;
+ else if (distance > STREAK_MAX_DISTANCE)
+ distance_coefficient = 0.5f;
+ else
+ distance_coefficient = 1.0f - 0.5f * (distance - STREAK_MIN_DISTANCE) / (STREAK_MAX_DISTANCE - STREAK_MIN_DISTANCE);
+ u *= distance_coefficient;
+ v *= distance_coefficient;
+ if (!CTimer::GetIsPaused()) {
+ RandomTex = ((CGeneral::GetRandomNumber() & 255) - 128) * 0.01f;
+ RandomTexX = (CGeneral::GetRandomNumber() & 127) * 0.01f;
+ RandomTexY = (CGeneral::GetRandomNumber() & 127) * 0.01f;
+ }
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 0], 0.5f * u - RandomTex + RandomTexX);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 0], -v * 0.5f + RandomTexY);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexX);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 1], RandomTexY);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 2], 0.5f * u + RandomTexX);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 2], RandomTexY);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 3], u + RandomTexX);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 3], RandomTexY);
+ RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored + 4], 0.5f * u + RandomTex + RandomTexX);
+ RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored + 5], 0.5f * v + RandomTexY);
+ TempBufferIndicesStored += 12;
+ TempBufferVerticesStored += 5;
+}
+
+void CWeather::RenderRainStreaks(void)
+{
+ if (CTimer::GetIsCodePaused())
+ return;
+ int base_intensity = (64.0f - CTimeCycle::GetFogReduction()) / 64.0f * int(255 * Rain);
+ if (base_intensity == 0)
+ return;
+ TempBufferIndicesStored = 0;
+ TempBufferVerticesStored = 0;
+ for (int i = 0; i < NUM_RAIN_STREAKS; i++) {
+ if (Streaks[i].timer) {
+ float secondsElapsed = (CTimer::GetTimeInMilliseconds() - Streaks[i].timer) / 1024.0f;
+ if (secondsElapsed > STREAK_LIFETIME)
+ Streaks[i].timer = 0;
+ else{
+ int intensity;
+ if (secondsElapsed < STREAK_INTEROLATION_TIME)
+ intensity = base_intensity * 0.5f * secondsElapsed / STREAK_INTEROLATION_TIME;
+ else if (secondsElapsed > (STREAK_LIFETIME - STREAK_INTEROLATION_TIME))
+ intensity = (STREAK_LIFETIME - secondsElapsed) * 0.5f * base_intensity / STREAK_INTEROLATION_TIME;
+ else
+ intensity = base_intensity * 0.5f;
+ CVector dir = Streaks[i].direction;
+ dir.Normalise();
+ CVector pos = Streaks[i].position + secondsElapsed * Streaks[i].direction;
+ RenderOneRainStreak(pos, dir, intensity, false, (pos - TheCamera.GetPosition()).Magnitude());
+#ifndef FIX_BUGS // remove useless code
+ if (secondsElapsed > 1.0f && secondsElapsed < STREAK_LIFETIME - 1.0f) {
+ CGeneral::GetRandomNumber(), CGeneral::GetRandomNumber();
+ }
+#endif
+ }
+ }
+ else if ((CGeneral::GetRandomNumber() & 0xF00) == 0){
+ // 1/16 probability
+ Streaks[i].direction = CVector(4.0f, 4.0f, -4.0f);
+ Streaks[i].position = 6.0f * TheCamera.GetForward() + TheCamera.GetPosition() + CVector(-1.8f * Streaks[i].direction.x, -1.8f * Streaks[i].direction.y, 8.0f);
+ if (!CCutsceneMgr::IsRunning()) {
+ Streaks[i].position.x += 2.0f * FindPlayerSpeed().x * 60.0f;
+ Streaks[i].position.y += 2.0f * FindPlayerSpeed().y * 60.0f;
+ }
+ else
+ Streaks[i].position += (TheCamera.GetPosition() - TheCamera.m_RealPreviousCameraPosition) * 20.0f;
+ Streaks[i].position.x += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
+ Streaks[i].position.y += ((CGeneral::GetRandomNumber() & 255) - 128) * 0.08f;
+ Streaks[i].timer = CTimer::GetTimeInMilliseconds();
+ }
+ }
+ if (TempBufferIndicesStored){
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRainDropTex[3]));
+ if (RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, 1))
+ {
+ RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
+ RwIm3DEnd();
+ }
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ }
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+}
+
void CWeather::StoreWeatherState()
{
Stored_StateStored = true;
@@ -71,4 +529,4 @@ void CWeather::RestoreWeatherState()
Rain = Stored_Rain;
NewWeatherType = Stored_NewWeatherType;
OldWeatherType = Stored_OldWeatherType;
-} \ No newline at end of file
+}
diff --git a/src/render/Weather.h b/src/render/Weather.h
index 63def9b9..9e4ea378 100644
--- a/src/render/Weather.h
+++ b/src/render/Weather.h
@@ -8,6 +8,14 @@ enum {
class CWeather
{
public:
+ enum {
+ WEATHER_RANDOM = -1,
+ WEATHER_SUNNY = 0,
+ WEATHER_CLOUDY = 1,
+ WEATHER_RAINY = 2,
+ WEATHER_FOGGY = 3,
+ WEATHER_TOTAL = 4
+ };
static int32 &SoundHandle;
static int32 &WeatherTypeInList;
@@ -46,4 +54,18 @@ public:
static void ForceWeatherNow(int16);
static void StoreWeatherState();
static void RestoreWeatherState();
+ static void AddRain();
};
+
+enum {
+ NUM_RAIN_STREAKS = 35
+};
+
+struct tRainStreak
+{
+ CVector position;
+ CVector direction;
+ uint32 timer;
+};
+
+extern RwTexture* (&gpRainDropTex)[4]; \ No newline at end of file
diff --git a/src/core/RwClumpRead.cpp b/src/rw/ClumpRead.cpp
index c9f027e7..c9f027e7 100644
--- a/src/core/RwClumpRead.cpp
+++ b/src/rw/ClumpRead.cpp
diff --git a/src/render/Lights.cpp b/src/rw/Lights.cpp
index cd83a898..cd83a898 100644
--- a/src/render/Lights.cpp
+++ b/src/rw/Lights.cpp
diff --git a/src/render/Lights.h b/src/rw/Lights.h
index 6fdd51de..6fdd51de 100644
--- a/src/render/Lights.h
+++ b/src/rw/Lights.h
diff --git a/src/core/NodeName.cpp b/src/rw/NodeName.cpp
index 2aea3c83..2aea3c83 100644
--- a/src/core/NodeName.cpp
+++ b/src/rw/NodeName.cpp
diff --git a/src/core/NodeName.h b/src/rw/NodeName.h
index 1a3e057b..1a3e057b 100644
--- a/src/core/NodeName.h
+++ b/src/rw/NodeName.h
diff --git a/src/core/RwHelper.cpp b/src/rw/RwHelper.cpp
index 6325bf15..44ca3a0a 100644
--- a/src/core/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -3,6 +3,44 @@
#include "patcher.h"
#include "Timecycle.h"
#include "skeleton.h"
+#if defined(RWLIBS) && !defined(FINAL)
+#include "rtcharse.h"
+#pragma comment( lib, "rtcharse.lib" )
+
+RtCharset *debugCharset;
+#endif
+
+void CreateDebugFont()
+{
+#if defined(RWLIBS) && !defined(FINAL)
+ RwRGBA color = { 255, 255, 128, 255 };
+ RwRGBA colorbg = { 0, 0, 0, 0 };
+ RtCharsetOpen();
+ debugCharset = RtCharsetCreate(&color, &colorbg);
+#endif
+}
+
+void DestroyDebugFont()
+{
+#if defined(RWLIBS) && !defined(FINAL)
+ RtCharsetDestroy(debugCharset);
+ RtCharsetClose();
+#endif
+}
+
+void ObrsPrintfString(const char *str, short x, short y)
+{
+#if defined(RWLIBS) && !defined(FINAL)
+ RtCharsetPrintBuffered(debugCharset, str, x, y, true);
+#endif
+}
+
+void FlushObrsPrintfs()
+{
+#if defined(RWLIBS) && !defined(FINAL)
+ RtCharsetBufferFlush();
+#endif
+}
void *
RwMallocAlign(RwUInt32 size, RwUInt32 align)
@@ -347,28 +385,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer)
return (nil);
}
-WRAPPER void ReadVideoCardCapsFile(uint32&, uint32&, uint32&, uint32&) { EAXJMP(0x5926C0); }
-WRAPPER bool CheckVideoCardCaps(void) { EAXJMP(0x592740); }
-WRAPPER void WriteVideoCardCapsFile(void) { EAXJMP(0x5927D0); }
-WRAPPER void ConvertingTexturesScreen(uint32, uint32, const char*) { EAXJMP(0x592880); }
-WRAPPER void DealWithTxdWriteError(uint32, uint32, const char*) { EAXJMP(0x592BF0); }
-WRAPPER bool CreateTxdImageForVideoCard() { EAXJMP(0x592C70); }
-
-void CreateDebugFont()
-{
- ;
-}
-
-void DestroyDebugFont()
-{
- ;
-}
-
-void FlushObrsPrintfs()
-{
- ;
-}
-
WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); }
WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); }
diff --git a/src/core/RwHelper.h b/src/rw/RwHelper.h
index a9f0bdf4..5b47cb6f 100644
--- a/src/core/RwHelper.h
+++ b/src/rw/RwHelper.h
@@ -5,6 +5,7 @@ void RwFreeAlign(void *mem);
void CreateDebugFont();
void DestroyDebugFont();
+void ObrsPrintfString(const char *str, short x, short y);
void FlushObrsPrintfs();
void DefinedState(void);
RwFrame *GetFirstChild(RwFrame *frame);
diff --git a/src/core/RwMatFX.cpp b/src/rw/RwMatFX.cpp
index ca9a633b..3af6fabe 100644
--- a/src/core/RwMatFX.cpp
+++ b/src/rw/RwMatFX.cpp
@@ -43,8 +43,16 @@ struct MatFX
int effects;
};
+#ifdef RWLIBS
+extern "C" {
+ extern int MatFXMaterialDataOffset;
+ extern int MatFXAtomicDataOffset;
+ void _rpMatFXD3D8AtomicMatFXEnvRender(RxD3D8InstanceData* inst, int flags, int sel, RwTexture* texture, RwTexture* envMap);
+}
+#else
int &MatFXMaterialDataOffset = *(int*)0x66188C;
int &MatFXAtomicDataOffset = *(int*)0x66189C;
+#endif
#ifdef PS2_MATFX
@@ -206,8 +214,13 @@ _rpMatFXD3D8AtomicMatFXEnvRender_ps2(RxD3D8InstanceData *inst, int flags, int se
RwD3D8SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
}
+
STARTPATCHES
+#ifdef RWLIBS
+ InjectHook((uintptr)&_rpMatFXD3D8AtomicMatFXEnvRender, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP);
+#else
InjectHook(0x5CF6C0, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP);
+#endif
ENDPATCHES
#endif
diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp
new file mode 100644
index 00000000..50b99d47
--- /dev/null
+++ b/src/rw/TexRead.cpp
@@ -0,0 +1,349 @@
+#pragma warning( push )
+#pragma warning( disable : 4005)
+#define DIRECTINPUT_VERSION 0x0800
+#include <dinput.h>
+#pragma warning( pop )
+#define WITHWINDOWS
+#include "common.h"
+#include "win.h"
+#include "patcher.h"
+#include "Timer.h"
+#ifdef GTA_PC
+#include "FileMgr.h"
+#include "Pad.h"
+#include "main.h"
+#include "Directory.h"
+#include "Streaming.h"
+#include "TxdStore.h"
+#include "CdStream.h"
+#include "Font.h"
+#include "Sprite2d.h"
+#include "Text.h"
+#include "RwHelper.h"
+#endif //GTA_PC
+
+float &texLoadTime = *(float*)0x8F1B50;
+int32 &texNumLoaded = *(int32*)0x8F252C;
+
+RwTexture*
+RwTextureGtaStreamRead(RwStream *stream)
+{
+ RwUInt32 size, version;
+ RwTexture *tex;
+
+ if(!RwStreamFindChunk(stream, rwID_TEXTURENATIVE, &size, &version))
+ return nil;
+
+ float preloadTime = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
+
+ if(!RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, &tex, size)))
+ return nil;
+
+ if (gGameState == GS_INIT_PLAYING_GAME) {
+ texLoadTime = (texNumLoaded * texLoadTime + (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond() - preloadTime) / (float)(texNumLoaded+1);
+ texNumLoaded++;
+ }
+ return tex;
+}
+
+RwTexture*
+destroyTexture(RwTexture *texture, void *data)
+{
+ RwTextureDestroy(texture);
+ return texture;
+}
+
+RwTexDictionary*
+RwTexDictionaryGtaStreamRead(RwStream *stream)
+{
+ RwUInt32 size, version;
+ RwInt32 numTextures;
+ RwTexDictionary *texDict;
+ RwTexture *tex;
+
+ if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
+ return nil;
+ assert(size == 4);
+ if(RwStreamRead(stream, &numTextures, size) != size)
+ return nil;
+
+ texDict = RwTexDictionaryCreate();
+ if(texDict == nil)
+ return nil;
+
+ while(numTextures--){
+ tex = RwTextureGtaStreamRead(stream);
+ if(tex == nil){
+ RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
+ RwTexDictionaryDestroy(texDict);
+ return nil;
+ }
+ RwTexDictionaryAddTexture(texDict, tex);
+ }
+
+ return texDict;
+}
+
+static int32 numberTextures = -1;
+static int32 streamPosition;
+
+RwTexDictionary*
+RwTexDictionaryGtaStreamRead1(RwStream *stream)
+{
+ RwUInt32 size, version;
+ RwInt32 numTextures;
+ RwTexDictionary *texDict;
+ RwTexture *tex;
+
+ numberTextures = 0;
+ if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
+ return nil;
+ assert(size == 4);
+ if(RwStreamRead(stream, &numTextures, size) != size)
+ return nil;
+
+ texDict = RwTexDictionaryCreate();
+ if(texDict == nil)
+ return nil;
+
+ numberTextures = numTextures/2;
+
+ while(numTextures > numberTextures){
+ numTextures--;
+
+ tex = RwTextureGtaStreamRead(stream);
+ if(tex == nil){
+ RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
+ RwTexDictionaryDestroy(texDict);
+ return nil;
+ }
+ RwTexDictionaryAddTexture(texDict, tex);
+ }
+
+ numberTextures = numTextures;
+ streamPosition = stream->Type.memory.position;
+
+ return texDict;
+}
+
+RwTexDictionary*
+RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
+{
+ RwTexture *tex;
+
+ RwStreamSkip(stream, streamPosition - stream->Type.memory.position);
+
+ while(numberTextures--){
+ tex = RwTextureGtaStreamRead(stream);
+ if(tex == nil){
+ RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
+ RwTexDictionaryDestroy(texDict);
+ return nil;
+ }
+ RwTexDictionaryAddTexture(texDict, tex);
+ }
+
+ return texDict;
+}
+
+#ifdef GTA_PC
+#ifdef RWLIBS
+extern "C" RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
+#else
+WRAPPER RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags) { EAXJMP(0x59A350); }
+#endif
+
+void
+ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8)
+{
+ cap32 = UINT32_MAX;
+ cap24 = UINT32_MAX;
+ cap16 = UINT32_MAX;
+ cap8 = UINT32_MAX;
+
+ int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "rb");
+ if (file != 0) {
+ CFileMgr::Read(file, (char*)&cap32, 4);
+ CFileMgr::Read(file, (char*)&cap24, 4);
+ CFileMgr::Read(file, (char*)&cap16, 4);
+ CFileMgr::Read(file, (char*)&cap8, 4);
+ CFileMgr::CloseFile(file);
+ }
+}
+
+bool
+CheckVideoCardCaps(void)
+{
+ uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
+ uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
+ uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
+ uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
+ uint32 fcap32, fcap24, fcap16, fcap8;
+ ReadVideoCardCapsFile(fcap32, fcap24, fcap16, fcap8);
+ return cap32 != fcap32 || cap24 != fcap24 || cap16 != fcap16 || cap8 != fcap8;
+}
+
+void
+WriteVideoCardCapsFile(void)
+{
+ uint32 cap32 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT8888);
+ uint32 cap24 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT888);
+ uint32 cap16 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMAT1555);
+ uint32 cap8 = _rwD3D8FindCorrectRasterFormat(rwRASTERTYPETEXTURE, rwRASTERFORMATPAL8 | rwRASTERFORMAT8888);
+ int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "wb");
+ if (file != 0) {
+ CFileMgr::Write(file, (char*)&cap32, 4);
+ CFileMgr::Write(file, (char*)&cap24, 4);
+ CFileMgr::Write(file, (char*)&cap16, 4);
+ CFileMgr::Write(file, (char*)&cap8, 4);
+ CFileMgr::CloseFile(file);
+ }
+}
+
+bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
+void DoRWStuffEndOfFrame(void);
+
+void
+ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
+{
+ HandleExit();
+
+ CSprite2d *splash = LoadSplash(nil);
+ if (!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
+ return;
+
+ CSprite2d::SetRecipNearClip();
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ DefinedState();
+
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
+ splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
+
+ CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), SCREEN_SCALE_FROM_RIGHT(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(64, 64, 64, 255));
+ CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 217, 106, 255));
+ CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(220.0f)), CRGBA(50, 50, 50, 210));
+
+ CFont::SetBackgroundOff();
+ CFont::SetPropOn();
+ CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f));
+ CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
+ CFont::SetJustifyOff();
+ CFont::SetColor(CRGBA(255, 217, 106, 255));
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text));
+ CFont::DrawFonts();
+ DoRWStuffEndOfFrame();
+}
+
+void
+DealWithTxdWriteError(uint32 num, uint32 count, const char *text)
+{
+ while (!RsGlobal.quit) {
+ ConvertingTexturesScreen(num, count, text);
+ CPad::UpdatePads();
+ if (CPad::GetPad(0)->GetEscapeJustDown())
+ break;
+ }
+ RsGlobal.quit = false;
+ LoadingScreen(nil, nil, nil);
+ RsGlobal.quit = true;
+}
+
+bool
+CreateTxdImageForVideoCard()
+{
+ uint8 *buf = new uint8[CDSTREAM_SECTOR_SIZE];
+ CDirectory *pDir = new CDirectory(TXDSTORESIZE);
+ CDirectory::DirectoryInfo dirInfo;
+
+ CStreaming::FlushRequestList();
+
+ RwFileFunctions *filesys = RwOsGetFileInterface();
+
+ RwStream *img = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, "models\\txd.img");
+ if (img == nil) {
+ // original code does otherwise and it leaks
+ delete []buf;
+ delete pDir;
+
+ if (_dwOperatingSystemVersion == OS_WINNT || _dwOperatingSystemVersion == OS_WIN2000 || _dwOperatingSystemVersion == OS_WINXP)
+ DealWithTxdWriteError(0, TXDSTORESIZE, "CVT_CRT");
+
+ return false;
+ }
+
+ int32 i;
+ for (i = 0; i < TXDSTORESIZE; i++) {
+ ConvertingTexturesScreen(i, TXDSTORESIZE, "CVT_MSG");
+
+ if (CTxdStore::GetSlot(i) != nil && CStreaming::IsObjectInCdImage(i + STREAM_OFFSET_TXD)) {
+ CStreaming::RequestTxd(i, STREAMFLAGS_KEEP_IN_MEMORY);
+ CStreaming::RequestModelStream(0);
+ CStreaming::FlushChannels();
+
+ char filename[64];
+ sprintf(filename, "%s.txd", CTxdStore::GetTxdName(i));
+
+ if (CTxdStore::GetSlot(i)->texDict) {
+ int32 pos = filesys->rwftell(img->Type.file.fpFile);
+
+ if (RwTexDictionaryStreamWrite(CTxdStore::GetSlot(i)->texDict, img) == nil) {
+ DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
+ RwStreamClose(img, nil);
+ delete []buf;
+ delete pDir;
+ CStreaming::RemoveTxd(i);
+ return false;
+ }
+
+ int32 size = filesys->rwftell(img->Type.file.fpFile) - pos;
+ int32 num = size % CDSTREAM_SECTOR_SIZE;
+
+ size /= CDSTREAM_SECTOR_SIZE;
+ if (num != 0) {
+ size++;
+ num = CDSTREAM_SECTOR_SIZE - num;
+ RwStreamWrite(img, buf, num);
+ }
+
+ dirInfo.offset = pos / CDSTREAM_SECTOR_SIZE;
+ dirInfo.size = size;
+ strncpy(dirInfo.name, filename, sizeof(dirInfo.name));
+ pDir->AddItem(dirInfo);
+ CStreaming::RemoveTxd(i);
+ }
+ CStreaming::FlushRequestList();
+ }
+ }
+
+ RwStreamClose(img, nil);
+ delete []buf;
+
+ if (!pDir->WriteDirFile("models\\txd.dir")) {
+ DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
+ delete pDir;
+ return false;
+ }
+
+ delete pDir;
+
+ WriteVideoCardCapsFile();
+ return true;
+}
+#endif // GTA_PC
+
+STARTPATCHES
+ InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
+ InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
+ InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
+ InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
+
+ InjectHook(0x5926C0, ReadVideoCardCapsFile, PATCH_JUMP);
+ InjectHook(0x592740, CheckVideoCardCaps, PATCH_JUMP);
+ InjectHook(0x5927D0, WriteVideoCardCapsFile, PATCH_JUMP);
+ InjectHook(0x592880, ConvertingTexturesScreen, PATCH_JUMP);
+ InjectHook(0x592BF0, DealWithTxdWriteError, PATCH_JUMP);
+ InjectHook(0x592C70, CreateTxdImageForVideoCard, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/core/TxdStore.cpp b/src/rw/TxdStore.cpp
index c751147d..c751147d 100644
--- a/src/core/TxdStore.cpp
+++ b/src/rw/TxdStore.cpp
diff --git a/src/core/TxdStore.h b/src/rw/TxdStore.h
index 12ac708f..12ac708f 100644
--- a/src/core/TxdStore.h
+++ b/src/rw/TxdStore.h
diff --git a/src/render/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index 74cd2590..f8b1f6b2 100644
--- a/src/render/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -117,7 +117,7 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
RpMaterial*
SetAlphaCB(RpMaterial *material, void *data)
{
- material->color.alpha = (uint8)(uint32)data;
+ ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uint32)data;
return material;
}
diff --git a/src/render/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h
index 65d2675a..65d2675a 100644
--- a/src/render/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
diff --git a/src/core/rw.cpp b/src/rw/rw.cpp
index 52bcf5bb..3875f2a1 100644
--- a/src/core/rw.cpp
+++ b/src/rw/rw.cpp
@@ -11,7 +11,8 @@ typedef RwV3d *(*rwVectorsMultFn) (RwV3d * pointsOut,
const RwV3d * pointsIn,
RwInt32 numPoints,
const RwMatrix * matrix);
-
+
+#ifndef RWLIBS
WRAPPER void _rwObjectHasFrameSetFrame(void* object, RwFrame* frame) { EAXJMP(0x5BC950); }
WRAPPER RpAtomic* AtomicDefaultRenderCallBack(RpAtomic* atomic) { EAXJMP(0x59E690); }
@@ -412,4 +413,427 @@ WRAPPER RxNodeDefinition* RxNodeDefinitionGetAtomicEnumerateLights() { EAXJMP(0x
WRAPPER RxNodeDefinition* RxNodeDefinitionGetMaterialScatter() { EAXJMP(0x5DDAA0); }
WRAPPER RxNodeDefinition* RxNodeDefinitionGetLight() { EAXJMP(0x5DF040); }
WRAPPER RxNodeDefinition* RxNodeDefinitionGetPostLight() { EAXJMP(0x5DF560); }
-WRAPPER void RxD3D8AllInOneSetRenderCallBack(RxPipelineNode* node, RxD3D8AllInOneRenderCallBack callback) { EAXJMP(0x5DFC60); } \ No newline at end of file
+WRAPPER void RxD3D8AllInOneSetRenderCallBack(RxPipelineNode* node, RxD3D8AllInOneRenderCallBack callback) { EAXJMP(0x5DFC60); }
+#else
+
+extern "C"
+{
+ void* _rwFrameOpen(void* instance, RwInt32 offset, RwInt32 size);
+ void* _rwFrameClose(void* instance, RwInt32 offset, RwInt32 size);
+ RwFrame* _rwFrameCloneAndLinkClones(RwFrame* root);
+ RwFrame* _rwFramePurgeClone(RwFrame* root);
+ RwBool RwFrameDirty(RwFrame const* frame);
+ void _rwFrameInit(RwFrame* frame);
+ RwBool _rwMatrixSetMultFn(rwMatrixMultFn multMat);
+ void* _rwMatrixClose(void* instance, RwInt32 offset, RwInt32 size);
+ void* _rwMatrixOpen(void* instance, RwInt32 offset, RwInt32 size);
+ RwBool _rwVectorSetMultFn(rwVectorMultFn multPoint, rwVectorsMultFn multPoints, rwVectorMultFn multVector, rwVectorsMultFn multVectors);
+ void* _rwVectorClose(void* instance, RwInt32 offset, RwInt32 size);
+ void* _rwVectorOpen(void* instance, RwInt32 offset, RwInt32 size);
+ RwBool _rwPluginRegistryOpen();
+ RwBool _rwPluginRegistryClose();
+}
+
+STARTPATCHES
+InjectHook(0x5BC950, &_rwObjectHasFrameSetFrame, PATCH_JUMP);
+InjectHook(0x59E690, &AtomicDefaultRenderCallBack, PATCH_JUMP);
+InjectHook(0x59E6C0, &_rpAtomicResyncInterpolatedSphere, PATCH_JUMP);
+InjectHook(0x59E800, &RpAtomicGetWorldBoundingSphere, PATCH_JUMP);
+InjectHook(0x59ED50, &RpClumpGetNumAtomics, PATCH_JUMP);
+InjectHook(0x59ED80, &RpClumpRender, PATCH_JUMP);
+InjectHook(0x59EDD0, &RpClumpForAllAtomics, PATCH_JUMP);
+InjectHook(0x59EE10, &RpClumpForAllCameras, PATCH_JUMP);
+InjectHook(0x59EE60, &RpClumpForAllLights, PATCH_JUMP);
+InjectHook(0x59EEB0, &RpAtomicCreate, PATCH_JUMP);
+InjectHook(0x59EFA0, &RpAtomicSetGeometry, PATCH_JUMP);
+InjectHook(0x59F020, &RpAtomicDestroy, PATCH_JUMP);
+InjectHook(0x59F0A0, &RpAtomicClone, PATCH_JUMP);
+InjectHook(0x59F1B0, &RpClumpClone, PATCH_JUMP);
+InjectHook(0x59F490, &RpClumpCreate, PATCH_JUMP);
+InjectHook(0x59F500, &RpClumpDestroy, PATCH_JUMP);
+InjectHook(0x59F680, &RpClumpAddAtomic, PATCH_JUMP);
+InjectHook(0x59F6B0, &RpClumpRemoveAtomic, PATCH_JUMP);
+InjectHook(0x59F6E0, &RpClumpRemoveLight, PATCH_JUMP);
+InjectHook(0x59FC50, &RpClumpStreamRead, PATCH_JUMP);
+InjectHook(0x5A0510, &RpAtomicRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5A0540, &RpClumpRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5A0570, &RpAtomicRegisterPluginStream, PATCH_JUMP);
+InjectHook(0x5A05A0, &RpAtomicSetStreamAlwaysCallBack, PATCH_JUMP);
+InjectHook(0x5A05C0, &RpAtomicSetStreamRightsCallBack, PATCH_JUMP);
+InjectHook(0x5A05E0, &RpAtomicGetPluginOffset, PATCH_JUMP);
+InjectHook(0x5A0600, &RpAtomicSetFrame, PATCH_JUMP);
+InjectHook(0x5A0DC0, &RwEngineRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5A0DF0, &RwEngineGetPluginOffset, PATCH_JUMP);
+InjectHook(0x5A0E10, &RwEngineGetNumSubSystems, PATCH_JUMP);
+InjectHook(0x5A0E40, &RwEngineGetSubSystemInfo, PATCH_JUMP);
+InjectHook(0x5A0E70, &RwEngineGetCurrentSubSystem, PATCH_JUMP);
+InjectHook(0x5A0EA0, &RwEngineSetSubSystem, PATCH_JUMP);
+InjectHook(0x5A0ED0, &RwEngineGetNumVideoModes, PATCH_JUMP);
+InjectHook(0x5A0F00, &RwEngineGetVideoModeInfo, PATCH_JUMP);
+InjectHook(0x5A0F30, &RwEngineGetCurrentVideoMode, PATCH_JUMP);
+InjectHook(0x5A0F60, &RwEngineSetVideoMode, PATCH_JUMP);
+InjectHook(0x5A0F90, &RwEngineStop, PATCH_JUMP);
+InjectHook(0x5A0FE0, &RwEngineStart, PATCH_JUMP);
+InjectHook(0x5A1070, &RwEngineClose, PATCH_JUMP);
+InjectHook(0x5A10E0, &RwEngineOpen, PATCH_JUMP);
+InjectHook(0x5A1290, &RwEngineTerm, PATCH_JUMP);
+InjectHook(0x5A12D0, &RwEngineInit, PATCH_JUMP);
+InjectHook(0x5A15E0, &_rwFrameOpen, PATCH_JUMP);
+InjectHook(0x5A1650, &_rwFrameClose, PATCH_JUMP);
+InjectHook(0x5A1690, &_rwFrameCloneAndLinkClones, PATCH_JUMP);
+InjectHook(0x5A1880, &_rwFramePurgeClone, PATCH_JUMP);
+InjectHook(0x5A1930, &RwFrameDirty, PATCH_JUMP);
+InjectHook(0x5A1950, &_rwFrameInit, PATCH_JUMP);
+InjectHook(0x5A1A00, &RwFrameCreate, PATCH_JUMP);
+InjectHook(0x5A1A30, &RwFrameDestroy, PATCH_JUMP);
+InjectHook(0x5A1BF0, &RwFrameDestroyHierarchy, PATCH_JUMP);
+InjectHook(0x5A1C60, &RwFrameUpdateObjects, PATCH_JUMP);
+InjectHook(0x5A1CE0, &RwFrameGetLTM, PATCH_JUMP);
+InjectHook(0x5A1D00, &RwFrameAddChild, PATCH_JUMP);
+InjectHook(0x5A1ED0, &RwFrameRemoveChild, PATCH_JUMP);
+InjectHook(0x5A1FC0, &RwFrameForAllChildren, PATCH_JUMP);
+InjectHook(0x5A2000, &RwFrameTranslate, PATCH_JUMP);
+InjectHook(0x5A20A0, &RwFrameScale, PATCH_JUMP);
+InjectHook(0x5A2140, &RwFrameTransform, PATCH_JUMP);
+InjectHook(0x5A21E0, &RwFrameRotate, PATCH_JUMP);
+InjectHook(0x5A2280, &RwFrameSetIdentity, PATCH_JUMP);
+InjectHook(0x5A2340, &RwFrameForAllObjects, PATCH_JUMP);
+InjectHook(0x5A2380, &RwFrameRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5A23B0, &_rwMatrixSetMultFn, PATCH_JUMP);
+InjectHook(0x5A2520, &_rwMatrixDeterminant, PATCH_JUMP);
+InjectHook(0x5A2570, &_rwMatrixOrthogonalError, PATCH_JUMP);
+InjectHook(0x5A25D0, &_rwMatrixNormalError, PATCH_JUMP);
+InjectHook(0x5A2660, &_rwMatrixIdentityError, PATCH_JUMP);
+InjectHook(0x5A2730, &_rwMatrixClose, PATCH_JUMP);
+InjectHook(0x5A2770, &_rwMatrixOpen, PATCH_JUMP);
+InjectHook(0x5A2820, &RwMatrixOptimize, PATCH_JUMP);
+InjectHook(0x5A28E0, &RwMatrixUpdate, PATCH_JUMP);
+InjectHook(0x5A28F0, &RwMatrixMultiply, PATCH_JUMP);
+InjectHook(0x5A2960, &RwMatrixRotateOneMinusCosineSine, PATCH_JUMP);
+InjectHook(0x5A2BF0, &RwMatrixRotate, PATCH_JUMP);
+InjectHook(0x5A2C90, &RwMatrixInvert, PATCH_JUMP);
+InjectHook(0x5A2EE0, &RwMatrixScale, PATCH_JUMP);
+InjectHook(0x5A3070, &RwMatrixTranslate, PATCH_JUMP);
+InjectHook(0x5A31C0, &RwMatrixTransform, PATCH_JUMP);
+InjectHook(0x5A3300, &RwMatrixDestroy, PATCH_JUMP);
+InjectHook(0x5A3330, &RwMatrixCreate, PATCH_JUMP);
+InjectHook(0x5A3450, &_rwVectorSetMultFn, PATCH_JUMP);
+InjectHook(0x5A3600, &_rwV3dNormalize, PATCH_JUMP);
+InjectHook(0x5A36A0, &RwV3dLength, PATCH_JUMP);
+InjectHook(0x5A3710, &_rwSqrt, PATCH_JUMP);
+InjectHook(0x5A3770, &_rwInvSqrt, PATCH_JUMP);
+InjectHook(0x5A37D0, &RwV3dTransformPoints, PATCH_JUMP);
+InjectHook(0x5A37E0, &RwV3dTransformVectors, PATCH_JUMP);
+InjectHook(0x5A37F0, &_rwVectorClose, PATCH_JUMP);
+InjectHook(0x5A3860, &_rwVectorOpen, PATCH_JUMP);
+InjectHook(0x5A3AD0, &RwStreamRead, PATCH_JUMP);
+InjectHook(0x5A3C30, &RwStreamWrite, PATCH_JUMP);
+InjectHook(0x5A3DF0, &RwStreamSkip, PATCH_JUMP);
+InjectHook(0x5A3F10, &RwStreamClose, PATCH_JUMP);
+InjectHook(0x5A3FE0, &RwStreamOpen, PATCH_JUMP);
+InjectHook(0x5A43A0, &RwIm2DGetNearScreenZ, PATCH_JUMP);
+InjectHook(0x5A43B0, &RwIm2DGetFarScreenZ, PATCH_JUMP);
+InjectHook(0x5A43C0, &RwRenderStateSet, PATCH_JUMP);
+InjectHook(0x5A4410, &RwRenderStateGet, PATCH_JUMP);
+InjectHook(0x5A4420, &RwIm2DRenderLine, PATCH_JUMP);
+InjectHook(0x5A4430, &RwIm2DRenderPrimitive, PATCH_JUMP);
+InjectHook(0x5A4440, &RwIm2DRenderIndexedPrimitive, PATCH_JUMP);
+InjectHook(0x5A5020, &RwCameraEndUpdate, PATCH_JUMP);
+InjectHook(0x5A5030, &RwCameraBeginUpdate, PATCH_JUMP);
+InjectHook(0x5A5040, &RwCameraSetViewOffset, PATCH_JUMP);
+InjectHook(0x5A5070, &RwCameraSetNearClipPlane, PATCH_JUMP);
+InjectHook(0x5A5140, &RwCameraSetFarClipPlane, PATCH_JUMP);
+InjectHook(0x5A5170, &RwCameraFrustumTestSphere, PATCH_JUMP);
+InjectHook(0x5A51E0, &RwCameraClear, PATCH_JUMP);
+InjectHook(0x5A5210, &RwCameraShowRaster, PATCH_JUMP);
+InjectHook(0x5A5240, &RwCameraSetProjection, PATCH_JUMP);
+InjectHook(0x5A52B0, &RwCameraSetViewWindow, PATCH_JUMP);
+InjectHook(0x5A52F0, &RwCameraRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5A5320, &RwCameraDestroy, PATCH_JUMP);
+InjectHook(0x5A5360, &RwCameraCreate, PATCH_JUMP);
+InjectHook(0x5A7100, &RwTextureSetMipmapping, PATCH_JUMP);
+InjectHook(0x5A7120, &RwTextureGetMipmapping, PATCH_JUMP);
+InjectHook(0x5A7130, &RwTextureSetAutoMipmapping, PATCH_JUMP);
+InjectHook(0x5A7150, &RwTextureGetAutoMipmapping, PATCH_JUMP);
+InjectHook(0x5A7160, &RwTexDictionaryCreate, PATCH_JUMP);
+InjectHook(0x5A7200, &RwTexDictionaryDestroy, PATCH_JUMP);
+InjectHook(0x5A7290, &RwTexDictionaryForAllTextures, PATCH_JUMP);
+InjectHook(0x5A72D0, &RwTextureCreate, PATCH_JUMP);
+InjectHook(0x5A7330, &RwTextureDestroy, PATCH_JUMP);
+InjectHook(0x5A73B0, &RwTextureSetName, PATCH_JUMP);
+InjectHook(0x5A7420, &RwTextureSetMaskName, PATCH_JUMP);
+InjectHook(0x5A7490, &RwTexDictionaryAddTexture, PATCH_JUMP);
+InjectHook(0x5A74D0, &RwTexDictionaryFindNamedTexture, PATCH_JUMP);
+InjectHook(0x5A7550, &RwTexDictionarySetCurrent, PATCH_JUMP);
+InjectHook(0x5A7570, &RwTexDictionaryGetCurrent, PATCH_JUMP);
+InjectHook(0x5A7580, &RwTextureRead, PATCH_JUMP);
+InjectHook(0x5A7780, &RwTextureRasterGenerateMipmaps, PATCH_JUMP);
+InjectHook(0x5A9120, &RwImageCreate, PATCH_JUMP);
+InjectHook(0x5A9180, &RwImageDestroy, PATCH_JUMP);
+InjectHook(0x5A91E0, &RwImageAllocatePixels, PATCH_JUMP);
+InjectHook(0x5A92A0, &RwImageFreePixels, PATCH_JUMP);
+InjectHook(0x5A92D0, &RwImageMakeMask, PATCH_JUMP);
+InjectHook(0x5A93A0, &RwImageApplyMask, PATCH_JUMP);
+InjectHook(0x5A9750, &RwImageSetPath, PATCH_JUMP);
+InjectHook(0x5A9810, &RwImageRead, PATCH_JUMP);
+InjectHook(0x5A9B40, &RwImageFindFileType, PATCH_JUMP);
+InjectHook(0x5A9C10, &RwImageReadMaskedImage, PATCH_JUMP);
+InjectHook(0x5A9F50, &RwImageCopy, PATCH_JUMP);
+InjectHook(0x5AA130, &RwImageGammaCorrect, PATCH_JUMP);
+InjectHook(0x5AA2C0, &RwImageSetGamma, PATCH_JUMP);
+InjectHook(0x5AA4E0, &_rwStreamWriteVersionedChunkHeader, PATCH_JUMP);
+InjectHook(0x5AA540, &RwStreamFindChunk, PATCH_JUMP);
+InjectHook(0x5AA640, &RwMemLittleEndian32, PATCH_JUMP);
+InjectHook(0x5AA650, &RwMemNative32, PATCH_JUMP);
+InjectHook(0x5AA660, &RwMemFloat32ToReal, PATCH_JUMP);
+InjectHook(0x5AA680, &RwStreamWriteReal, PATCH_JUMP);
+InjectHook(0x5AA720, &RwStreamWriteInt32, PATCH_JUMP);
+InjectHook(0x5AA740, &RwStreamReadReal, PATCH_JUMP);
+InjectHook(0x5AA7B0, &RwStreamReadInt32, PATCH_JUMP);
+InjectHook(0x5AA800, &RwTextureStreamGetSize, PATCH_JUMP);
+InjectHook(0x5AA870, &RwTextureStreamWrite, PATCH_JUMP);
+InjectHook(0x5AAA40, &RwTextureStreamRead, PATCH_JUMP);
+InjectHook(0x5AB020, &RwTexDictionaryStreamWrite, PATCH_JUMP);
+InjectHook(0x5AC890, &RpMorphTargetCalcBoundingSphere, PATCH_JUMP);
+InjectHook(0x5AC9A0, &RpGeometryAddMorphTargets, PATCH_JUMP);
+InjectHook(0x5ACB60, &RpGeometryTriangleSetVertexIndices, PATCH_JUMP);
+InjectHook(0x5ACB90, &RpGeometryTriangleSetMaterial, PATCH_JUMP);
+InjectHook(0x5ACBF0, &RpGeometryForAllMaterials, PATCH_JUMP);
+InjectHook(0x5ACC30, &RpGeometryLock, PATCH_JUMP);
+InjectHook(0x5ACC60, &RpGeometryUnlock, PATCH_JUMP);
+InjectHook(0x5ACD10, &RpGeometryCreate, PATCH_JUMP);
+InjectHook(0x5ACF40, &_rpGeometryAddRef, PATCH_JUMP);
+InjectHook(0x5ACF50, &RpGeometryDestroy, PATCH_JUMP);
+InjectHook(0x5ACFF0, &RpGeometryRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5AD020, &RpGeometryRegisterPluginStream, PATCH_JUMP);
+InjectHook(0x5AD050, &RpGeometryStreamRead, PATCH_JUMP);
+InjectHook(0x5AD6D0, &RwRasterGetCurrentContext, PATCH_JUMP);
+InjectHook(0x5AD6F0, &RwRasterUnlock, PATCH_JUMP);
+InjectHook(0x5AD710, &RwRasterRenderFast, PATCH_JUMP);
+InjectHook(0x5AD750, &RwRasterUnlockPalette, PATCH_JUMP);
+InjectHook(0x5AD780, &RwRasterDestroy, PATCH_JUMP);
+InjectHook(0x5AD7C0, &RwRasterPushContext, PATCH_JUMP);
+InjectHook(0x5AD810, &RwRasterRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5AD840, &RwRasterLockPalette, PATCH_JUMP);
+InjectHook(0x5AD870, &RwRasterPopContext, PATCH_JUMP);
+InjectHook(0x5AD8C0, &RwRasterGetNumLevels, PATCH_JUMP);
+InjectHook(0x5AD900, &RwRasterShowRaster, PATCH_JUMP);
+InjectHook(0x5AD930, &RwRasterCreate, PATCH_JUMP);
+InjectHook(0x5AD9D0, &RwRasterLock, PATCH_JUMP);
+InjectHook(0x5ADC30, &RpMaterialCreate, PATCH_JUMP);
+InjectHook(0x5ADCB0, &RpMaterialDestroy, PATCH_JUMP);
+InjectHook(0x5ADD10, &RpMaterialSetTexture, PATCH_JUMP);
+InjectHook(0x5ADD40, &RpMaterialRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5ADD70, &RpMaterialRegisterPluginStream, PATCH_JUMP);
+InjectHook(0x5ADDA0, &RpMaterialStreamRead, PATCH_JUMP);
+InjectHook(0x5AE0B0, &_rpSectorDefaultRenderCallBack, PATCH_JUMP);
+InjectHook(0x5AE100, &_rpWorldForAllGlobalLights, PATCH_JUMP);
+InjectHook(0x5AE150, &_rpWorldSectorForAllLocalLights, PATCH_JUMP);
+InjectHook(0x5AE190, &RpWorldUnlock, PATCH_JUMP);
+InjectHook(0x5AE2B0, &RpWorldSectorGetWorld, PATCH_JUMP);
+InjectHook(0x5AE340, &RpWorldDestroy, PATCH_JUMP);
+InjectHook(0x5AE6A0, &RpWorldCreate, PATCH_JUMP);
+InjectHook(0x5AEA40, &RpWorldRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5AEA70, &RpWorldRegisterPluginStream, PATCH_JUMP);
+InjectHook(0x5AEAA0, &RpWorldPluginAttach, PATCH_JUMP);
+InjectHook(0x5AFB80, &RpWorldAddCamera, PATCH_JUMP);
+InjectHook(0x5AFBB0, &RpWorldRemoveCamera, PATCH_JUMP);
+InjectHook(0x5AFC10, &RpAtomicGetWorld, PATCH_JUMP);
+InjectHook(0x5AFC20, &RpWorldAddClump, PATCH_JUMP);
+InjectHook(0x5AFDA0, &RpWorldAddLight, PATCH_JUMP);
+InjectHook(0x5AFDF0, &RpWorldRemoveLight, PATCH_JUMP);
+InjectHook(0x5AFE70, &RtBMPImageRead, PATCH_JUMP);
+InjectHook(0x5B07D0, &RpSkinPluginAttach, PATCH_JUMP);
+InjectHook(0x5B1050, &RpSkinAtomicSetHAnimHierarchy, PATCH_JUMP);
+InjectHook(0x5B1070, &RpSkinAtomicGetHAnimHierarchy, PATCH_JUMP);
+InjectHook(0x5B1080, &RpSkinGeometryGetSkin, PATCH_JUMP);
+InjectHook(0x5B1090, &RpSkinGeometrySetSkin, PATCH_JUMP);
+InjectHook(0x5B10D0, &RpSkinGetSkinToBoneMatrices, PATCH_JUMP);
+InjectHook(0x5B10E0, &RpHAnimHierarchyCreate, PATCH_JUMP);
+InjectHook(0x5B11F0, &RpHAnimFrameGetHierarchy, PATCH_JUMP);
+InjectHook(0x5B1200, &RpHAnimHierarchySetCurrentAnim, PATCH_JUMP);
+InjectHook(0x5B12B0, &RpHAnimHierarchySubAnimTime, PATCH_JUMP);
+InjectHook(0x5B1480, &RpHAnimHierarchyAddAnimTime, PATCH_JUMP);
+InjectHook(0x5B1780, &RpHAnimHierarchyUpdateMatrices, PATCH_JUMP);
+InjectHook(0x5B1C10, &RpHAnimAnimationStreamRead, PATCH_JUMP);
+InjectHook(0x5B1D50, &RpHAnimPluginAttach, PATCH_JUMP);
+InjectHook(0x5B2640, &RpMatFXPluginAttach, PATCH_JUMP);
+InjectHook(0x5B3750, &RpMatFXAtomicEnableEffects, PATCH_JUMP);
+InjectHook(0x5B3780, &RpMatFXMaterialSetEffects, PATCH_JUMP);
+InjectHook(0x5B38D0, &RpMatFXMaterialSetupEnvMap, PATCH_JUMP);
+InjectHook(0x5B3A40, &RpMatFXMaterialSetBumpMapTexture, PATCH_JUMP);
+InjectHook(0x5B3CF0, &RwD3D8SetRenderState, PATCH_JUMP);
+InjectHook(0x5B3D40, &RwD3D8GetRenderState, PATCH_JUMP);
+InjectHook(0x5B3D60, &RwD3D8SetTextureStageState, PATCH_JUMP);
+InjectHook(0x5B53A0, &RwD3D8SetTexture, PATCH_JUMP);
+InjectHook(0x5B6720, &RwIm3DTransform, PATCH_JUMP);
+InjectHook(0x5B67F0, &RwIm3DEnd, PATCH_JUMP);
+InjectHook(0x5B6820, &RwIm3DRenderIndexedPrimitive, PATCH_JUMP);
+InjectHook(0x5B6980, &RwIm3DRenderLine, PATCH_JUMP);
+InjectHook(0x5B6A50, &RwIm3DSetTransformPipeline, PATCH_JUMP);
+InjectHook(0x5B6AC0, &RwIm3DSetRenderPipeline, PATCH_JUMP);
+InjectHook(0x5B95D0, &RwD3D8EngineSetRefreshRate, PATCH_JUMP);
+InjectHook(0x5B9640, &RwD3D8CameraAttachWindow, PATCH_JUMP);
+InjectHook(0x5BAEB0, &RwD3D8DeviceSupportsDXTTexture, PATCH_JUMP);
+InjectHook(0x5BAF90, &RwD3D8SetVertexShader, PATCH_JUMP);
+InjectHook(0x5BAFD0, &RwD3D8SetPixelShader, PATCH_JUMP);
+InjectHook(0x5BB010, &RwD3D8SetStreamSource, PATCH_JUMP);
+InjectHook(0x5BB060, &RwD3D8SetIndices, PATCH_JUMP);
+InjectHook(0x5BB0B0, &RwD3D8DrawIndexedPrimitive, PATCH_JUMP);
+InjectHook(0x5BB140, &RwD3D8DrawPrimitive, PATCH_JUMP);
+InjectHook(0x5BB1D0, &RwD3D8SetTransform, PATCH_JUMP);
+InjectHook(0x5BB310, &RwD3D8GetTransform, PATCH_JUMP);
+InjectHook(0x5BB340, &RwD3D8SetTransformWorld, PATCH_JUMP);
+InjectHook(0x5BB490, &RwD3D8SetSurfaceProperties, PATCH_JUMP);
+InjectHook(0x5BB7A0, &RwD3D8SetLight, PATCH_JUMP);
+InjectHook(0x5BB890, &RwD3D8EnableLight, PATCH_JUMP);
+InjectHook(0x5BB9F0, &RwD3D8DynamicVertexBufferCreate, PATCH_JUMP);
+InjectHook(0x5BBAE0, &RwD3D8DynamicVertexBufferDestroy, PATCH_JUMP);
+InjectHook(0x5BBB10, &RwD3D8IndexBufferCreate, PATCH_JUMP);
+InjectHook(0x5BBB40, &RwD3D8CreatePixelShader, PATCH_JUMP);
+InjectHook(0x5BBB90, &RwD3D8DeletePixelShader, PATCH_JUMP);
+InjectHook(0x5BBC00, &RwD3D8SetPixelShaderConstant, PATCH_JUMP);
+InjectHook(0x5BBC30, &RwD3D8GetCaps, PATCH_JUMP);
+InjectHook(0x5BBC40, &RwD3D8CameraIsSphereFullyInsideFrustum, PATCH_JUMP);
+InjectHook(0x5BBCA0, &RwD3D8CameraIsBBoxFullyInsideFrustum, PATCH_JUMP);
+InjectHook(0x5BBD30, &RwD3D8DynamicVertexBufferLock, PATCH_JUMP);
+InjectHook(0x5BBEB0, &RwD3D8DynamicVertexBufferUnlock, PATCH_JUMP);
+InjectHook(0x5BBED0, &_rwIntelSSEsupported, PATCH_JUMP);
+InjectHook(0x5BBF10, &RwImageSetFromRaster, PATCH_JUMP);
+InjectHook(0x5BBF50, &RwRasterSetFromImage, PATCH_JUMP);
+InjectHook(0x5BBF80, &RwImageFindRasterFormat, PATCH_JUMP);
+InjectHook(0x5BBFF0, &RwFrameRegisterPluginStream, PATCH_JUMP);
+InjectHook(0x5BC020, &_rwFrameListDeinitialize, PATCH_JUMP);
+InjectHook(0x5BC050, &_rwFrameListStreamRead, PATCH_JUMP);
+InjectHook(0x5BC300, &RpLightSetRadius, PATCH_JUMP);
+InjectHook(0x5BC320, &RpLightSetColor, PATCH_JUMP);
+InjectHook(0x5BC370, &RpLightGetConeAngle, PATCH_JUMP);
+InjectHook(0x5BC5B0, &RpLightRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5BC5E0, &RpLightStreamRead, PATCH_JUMP);
+InjectHook(0x5BC780, &RpLightDestroy, PATCH_JUMP);
+InjectHook(0x5BC7C0, &RpLightCreate, PATCH_JUMP);
+InjectHook(0x5BE280, &_rwD3D8TexDictionaryEnableRasterFormatConversion, PATCH_JUMP);
+InjectHook(0x5BF110, &RwOsGetFileInterface, PATCH_JUMP);
+InjectHook(0x5C1720, &RwFreeListDestroy, PATCH_JUMP);
+InjectHook(0x5C1790, &RwFreeListCreate, PATCH_JUMP);
+InjectHook(0x5C19F0, &RwFreeListPurge, PATCH_JUMP);
+InjectHook(0x5C1B90, &RwFreeListPurgeAllFreeLists, PATCH_JUMP);
+InjectHook(0x5C1D40, &RwFreeListForAllUsed, PATCH_JUMP);
+InjectHook(0x5C2780, &_rxPipelineClose, PATCH_JUMP);
+InjectHook(0x5C27E0, &_rxPipelineOpen, PATCH_JUMP);
+InjectHook(0x5C2AD0, &RxHeapGetGlobalHeap, PATCH_JUMP);
+InjectHook(0x5C2AE0, &RxPacketCreate, PATCH_JUMP);
+InjectHook(0x5C2B10, &RxClusterSetExternalData, PATCH_JUMP);
+InjectHook(0x5C2B70, &RxClusterSetData, PATCH_JUMP);
+InjectHook(0x5C2BD0, &RxClusterInitializeData, PATCH_JUMP);
+InjectHook(0x5C2C40, &RxClusterResizeData, PATCH_JUMP);
+InjectHook(0x5C2C90, &RxClusterLockWrite, PATCH_JUMP);
+InjectHook(0x5C2D60, &RxPipelineExecute, PATCH_JUMP);
+InjectHook(0x5C2E00, &RxPipelineCreate, PATCH_JUMP);
+InjectHook(0x5C2E70, &_rxPipelineDestroy, PATCH_JUMP);
+InjectHook(0x5C3080, &RwResourcesFreeResEntry, PATCH_JUMP);
+InjectHook(0x5C30F0, &_rwResourcesPurge, PATCH_JUMP);
+InjectHook(0x5C3170, &RwResourcesAllocateResEntry, PATCH_JUMP);
+InjectHook(0x5C3360, &RwResourcesEmptyArena, PATCH_JUMP);
+InjectHook(0x5C3450, &_rwPluginRegistryOpen, PATCH_JUMP);
+InjectHook(0x5C3480, &_rwPluginRegistryClose, PATCH_JUMP);
+InjectHook(0x5C3590, &_rwPluginRegistryGetPluginOffset, PATCH_JUMP);
+InjectHook(0x5C35C0, &_rwPluginRegistryAddPlugin, PATCH_JUMP);
+InjectHook(0x5C37F0, &_rwPluginRegistryInitObject, PATCH_JUMP);
+InjectHook(0x5C3850, &_rwPluginRegistryDeInitObject, PATCH_JUMP);
+InjectHook(0x5C3880, &_rwPluginRegistryCopyObject, PATCH_JUMP);
+InjectHook(0x5C3910, &RwErrorSet, PATCH_JUMP);
+InjectHook(0x5C3970, &_rwerror, PATCH_JUMP);
+InjectHook(0x5C3980, &_rwPluginRegistryAddPluginStream, PATCH_JUMP);
+InjectHook(0x5C39C0, &_rwPluginRegistryAddPlgnStrmlwysCB, PATCH_JUMP);
+InjectHook(0x5C39F0, &_rwPluginRegistryAddPlgnStrmRightsCB, PATCH_JUMP);
+InjectHook(0x5C3A20, & _rwPluginRegistryReadDataChunks, PATCH_JUMP);
+InjectHook(0x5C3B50, & _rwPluginRegistryInvokeRights, PATCH_JUMP);
+InjectHook(0x5C3BA0, &_rwPluginRegistryGetSize, PATCH_JUMP);
+InjectHook(0x5C3BE0, &_rwPluginRegistryWriteDataChunks, PATCH_JUMP);
+InjectHook(0x5C3CB0, &_rwPluginRegistrySkipDataChunks, PATCH_JUMP);
+InjectHook(0x5C3D30, &RwCameraStreamRead, PATCH_JUMP);
+InjectHook(0x5C5570, &RwBBoxCalculate, PATCH_JUMP);
+InjectHook(0x5C72B0, &RwImageResample, PATCH_JUMP);
+InjectHook(0x5C7B30, &RwImageCreateResample, PATCH_JUMP);
+InjectHook(0x5D9240, &RxRenderStateVectorSetDefaultRenderStateVector, PATCH_JUMP);
+InjectHook(0x5D9340, &RxRenderStateVectorCreate, PATCH_JUMP);
+InjectHook(0x5D9410, &RxRenderStateVectorDestroy, PATCH_JUMP);
+InjectHook(0x5D9460, &RxRenderStateVectorLoadDriverState, PATCH_JUMP);
+InjectHook(0x5D95D0, &_rxEmbeddedPacketBetweenPipelines, PATCH_JUMP);
+InjectHook(0x5D9740, &_rxEmbeddedPacketBetweenNodes, PATCH_JUMP);
+InjectHook(0x5D9810, &_rxPacketDestroy, PATCH_JUMP);
+InjectHook(0x5C8B10, &_rpMaterialListDeinitialize, PATCH_JUMP);
+InjectHook(0x5C8B70, &_rpMaterialListInitialize, PATCH_JUMP);
+InjectHook(0x5C8B80, &_rpMaterialListGetMaterial, PATCH_JUMP);
+InjectHook(0x5C8B90, &_rpMaterialListAppendMaterial, PATCH_JUMP);
+InjectHook(0x5C8C50, &_rpMaterialListFindMaterialIndex, PATCH_JUMP);
+InjectHook(0x5C8C80, &_rpMaterialListStreamRead, PATCH_JUMP);
+InjectHook(0x5C8FE0, &_rpMeshHeaderCreate, PATCH_JUMP);
+InjectHook(0x5C8FF0, &_rpMeshClose, PATCH_JUMP);
+InjectHook(0x5C9020, &_rpMeshOpen, PATCH_JUMP);
+InjectHook(0x5C9140, &_rpBuildMeshCreate, PATCH_JUMP);
+InjectHook(0x5C9220, &_rpBuildMeshDestroy, PATCH_JUMP);
+InjectHook(0x5C9260, &_rpMeshDestroy, PATCH_JUMP);
+InjectHook(0x5C92A0, &_rpBuildMeshAddTriangle, PATCH_JUMP);
+InjectHook(0x5C9380, &_rpMeshHeaderForAllMeshes, PATCH_JUMP);
+InjectHook(0x5C93C0, &_rpMeshWrite, PATCH_JUMP);
+InjectHook(0x5C9510, &_rpMeshRead, PATCH_JUMP);
+InjectHook(0x5C96E0, &_rpMeshSize, PATCH_JUMP);
+InjectHook(0x5C9730, &RpBuildMeshGenerateDefaultTriStrip, PATCH_JUMP);
+InjectHook(0x5CAE10, &_rpTriListMeshGenerate, PATCH_JUMP);
+InjectHook(0x5CB230, &_rpMeshOptimise, PATCH_JUMP);
+InjectHook(0x5CB2B0, &RpWorldSectorRegisterPlugin, PATCH_JUMP);
+InjectHook(0x5CB2E0, &RpWorldSectorRegisterPluginStream, PATCH_JUMP);
+InjectHook(0x5CB630, &RpWorldSetDefaultSectorPipeline, PATCH_JUMP);
+InjectHook(0x5CB670, &RpAtomicSetDefaultPipeline, PATCH_JUMP);
+InjectHook(0x5CDEE0, &RpHAnimStdKeyFrameToMatrix, PATCH_JUMP);
+InjectHook(0x5CE000, &RpHAnimStdKeyFrameInterpolate, PATCH_JUMP);
+InjectHook(0x5CE420, &RpHAnimStdKeyFrameBlend, PATCH_JUMP);
+InjectHook(0x5CE820, &RpHAnimStdKeyFrameStreamRead, PATCH_JUMP);
+InjectHook(0x5CE8C0, &RpHAnimStdKeyFrameStreamWrite, PATCH_JUMP);
+InjectHook(0x5CE930, &RpHAnimStdKeyFrameStreamGetSize, PATCH_JUMP);
+InjectHook(0x5CE950, &RpHAnimStdKeyFrameMulRecip, PATCH_JUMP);
+InjectHook(0x5CEAB0, &RpHAnimStdKeyFrameAdd, PATCH_JUMP);
+InjectHook(0x5D1070, &RxHeapFree, PATCH_JUMP);
+InjectHook(0x5D1260, &RxHeapAlloc, PATCH_JUMP);
+InjectHook(0x5D14D0, &RxHeapRealloc, PATCH_JUMP);
+InjectHook(0x5D1680, &_rxHeapReset, PATCH_JUMP);
+InjectHook(0x5D16F0, &RxHeapDestroy, PATCH_JUMP);
+InjectHook(0x5D1750, &RxHeapCreate, PATCH_JUMP);
+InjectHook(0x5D1EC0, &RxPipelineNodeFindOutputByName, PATCH_JUMP);
+InjectHook(0x5D1F20, &RxPipelineNodeFindInput, PATCH_JUMP);
+InjectHook(0x5D1F30, &RxPipelineNodeRequestCluster, PATCH_JUMP);
+InjectHook(0x5D1FA0, &RxLockedPipeUnlock, PATCH_JUMP);
+InjectHook(0x5D29F0, &RxPipelineLock, PATCH_JUMP);
+InjectHook(0x5D2B10, &RxPipelineFindNodeByName, PATCH_JUMP);
+InjectHook(0x5D2BA0, &RxLockedPipeAddFragment, PATCH_JUMP);
+InjectHook(0x5D2EE0, &RxLockedPipeAddPath, PATCH_JUMP);
+InjectHook(0x5D31C0, &RxNodeDefinitionGetImmRenderSetup, PATCH_JUMP);
+InjectHook(0x5D35C0, &RxNodeDefinitionGetImmMangleTriangleIndices, PATCH_JUMP);
+InjectHook(0x5D3C60, &RxNodeDefinitionGetCullTriangle, PATCH_JUMP);
+InjectHook(0x5D4F80, &RxNodeDefinitionGetClipTriangle, PATCH_JUMP);
+InjectHook(0x5D51C0, &RxNodeDefinitionGetSubmitTriangle, PATCH_JUMP);
+InjectHook(0x5D5400, &RxNodeDefinitionGetImmInstance, PATCH_JUMP);
+InjectHook(0x5D6000, &RxNodeDefinitionGetTransform, PATCH_JUMP);
+InjectHook(0x5D61C0, &RxNodeDefinitionGetImmStash, PATCH_JUMP);
+InjectHook(0x5D6470, &RxNodeDefinitionGetImmMangleLineIndices, PATCH_JUMP);
+InjectHook(0x5D7230, &RxNodeDefinitionGetClipLine, PATCH_JUMP);
+InjectHook(0x5D74C0, &RxNodeDefinitionGetSubmitLine, PATCH_JUMP);
+InjectHook(0x5D9C90, &_rwD3D8LightsOpen, PATCH_JUMP);
+InjectHook(0x5D9EF0, &_rwD3D8LightsClose, PATCH_JUMP);
+InjectHook(0x5D9F80, &_rwD3D8LightsGlobalEnable, PATCH_JUMP);
+InjectHook(0x5DA210, &_rwD3D8LightLocalEnable, PATCH_JUMP);
+InjectHook(0x5DA450, &_rwD3D8LightsEnable, PATCH_JUMP);
+InjectHook(0x5DAAC0, &RxNodeDefinitionGetD3D8WorldSectorAllInOne, PATCH_JUMP);
+InjectHook(0x5DC500, &RxNodeDefinitionGetD3D8AtomicAllInOne, PATCH_JUMP);
+InjectHook(0x5DCC50, &RxNodeDefinitionGetWorldSectorInstance, PATCH_JUMP);
+InjectHook(0x5DCD80, &RxNodeDefinitionGetWorldSectorEnumerateLights, PATCH_JUMP);
+InjectHook(0x5DD800, &RxNodeDefinitionGetAtomicInstance, PATCH_JUMP);
+InjectHook(0x5DD9B0, &RxNodeDefinitionGetAtomicEnumerateLights, PATCH_JUMP);
+InjectHook(0x5DDAA0, &RxNodeDefinitionGetMaterialScatter, PATCH_JUMP);
+InjectHook(0x5DF040, &RxNodeDefinitionGetLight, PATCH_JUMP);
+InjectHook(0x5DF560, &RxNodeDefinitionGetPostLight, PATCH_JUMP);
+InjectHook(0x5DFC60, &RxD3D8AllInOneSetRenderCallBack, PATCH_JUMP);
+ENDPATCHES
+#endif \ No newline at end of file
diff --git a/src/save/Date.h b/src/save/Date.h
index 3e022d09..15646c23 100644
--- a/src/save/Date.h
+++ b/src/save/Date.h
@@ -1,18 +1,18 @@
-#pragma once
-
-class CDate
-{
-public:
- int m_nSecond;
- int m_nMinute;
- int m_nHour;
- int m_nDay;
- int m_nMonth;
- int m_nYear;
-
- CDate();
- bool operator>(const CDate &right);
- bool operator<(const CDate &right);
- bool operator==(const CDate &right);
- void PopulateDateFields(int8 &second, int8 &minute, int8 &hour, int8 &day, int8 &month, int16 year);
+#pragma once
+
+class CDate
+{
+public:
+ int m_nSecond;
+ int m_nMinute;
+ int m_nHour;
+ int m_nDay;
+ int m_nMonth;
+ int m_nYear;
+
+ CDate();
+ bool operator>(const CDate &right);
+ bool operator<(const CDate &right);
+ bool operator==(const CDate &right);
+ void PopulateDateFields(int8 &second, int8 &minute, int8 &hour, int8 &day, int8 &month, int16 year);
}; \ No newline at end of file
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index d71b0c22..0ec0b117 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -9,17 +9,20 @@
#include "Clock.h"
#include "Date.h"
#include "FileMgr.h"
+#include "Frontend.h"
#include "GameLogic.h"
#include "Gangs.h"
#include "Garages.h"
#include "GenericGameStorage.h"
#include "Pad.h"
+#include "Particle.h"
#include "ParticleObject.h"
#include "PathFind.h"
#include "PCSave.h"
#include "Phones.h"
#include "Pickups.h"
#include "PlayerPed.h"
+#include "ProjectileInfo.h"
#include "Pools.h"
#include "Radar.h"
#include "Restart.h"
@@ -48,13 +51,35 @@ char SaveFileNameJustSaved[260];
int (&Slots)[SLOT_COUNT+1] = *(int(*)[SLOT_COUNT+1])*(uintptr*)0x72803C;
CDate &CompileDateAndTime = *(CDate*)0x72BCB8;
+bool &b_FoundRecentSavedGameWantToLoad = *(bool*)0x95CDA8;
+bool &JustLoadedDontFadeInYet = *(bool*)0x95CDB4;
+bool &StillToFadeOut = *(bool*)0x95CD99;
+uint32 &TimeStartedCountingForFade = *(uint32*)0x9430EC;
+uint32 &TimeToStayFadedBeforeFadeOut = *(uint32*)0x611564;
+
#define ReadDataFromBufferPointer(buf, to) memcpy(&to, buf, sizeof(to)); buf += align4bytes(sizeof(to));
#define WriteDataToBufferPointer(buf, from) memcpy(buf, &from, sizeof(from)); buf += align4bytes(sizeof(from));
-WRAPPER bool GenericLoad() { EAXJMP(0x590A00); }
+#define LoadSaveDataBlock()\
+do {\
+ if (!ReadDataFromFile(file, (uint8 *) &size, 4))\
+ return false;\
+ size = align4bytes(size);\
+ if (!ReadDataFromFile(file, work_buff, size))\
+ return false;\
+ buf = work_buff;\
+} while (0)
+#define ReadDataFromBlock(msg,load_func)\
+do {\
+ debug(msg);\
+ ReadDataFromBufferPointer(buf, size);\
+ load_func(buf, size);\
+ size = align4bytes(size);\
+ buf += size;\
+} while (0)
-#define WRITE_BLOCK(save_func)\
+#define WriteSaveDataBlock(save_func)\
do {\
buf = work_buff;\
reserved = 0;\
@@ -110,11 +135,11 @@ GenericSave(int file)
WriteDataToBufferPointer(buf, CClock::ms_nGameClockMinutes);
currPad = CPad::GetPad(0);
WriteDataToBufferPointer(buf, currPad->Mode);
- WriteDataToBufferPointer(buf, CTimer::GetTimeInMilliseconds());
- WriteDataToBufferPointer(buf, CTimer::GetTimeScale());
- WriteDataToBufferPointer(buf, CTimer::GetTimeStep());
- WriteDataToBufferPointer(buf, CTimer::GetTimeStepNonClipped());
- WriteDataToBufferPointer(buf, CTimer::GetFrameCounter());
+ WriteDataToBufferPointer(buf, CTimer::m_snTimeInMilliseconds);
+ WriteDataToBufferPointer(buf, CTimer::ms_fTimeScale);
+ WriteDataToBufferPointer(buf, CTimer::ms_fTimeStep);
+ WriteDataToBufferPointer(buf, CTimer::ms_fTimeStepNonClipped);
+ WriteDataToBufferPointer(buf, CTimer::m_FrameCounter);
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeStep);
WriteDataToBufferPointer(buf, CTimeStep::ms_fFramesPerUpdate);
WriteDataToBufferPointer(buf, CTimeStep::ms_fTimeScale);
@@ -131,7 +156,6 @@ GenericSave(int file)
WriteDataToBufferPointer(buf, CWeather::WeatherTypeInList);
WriteDataToBufferPointer(buf, TheCamera.CarZoomIndicator);
WriteDataToBufferPointer(buf, TheCamera.PedZoomIndicator);
-
assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
// Save scripts, block is nested within the same block as simple vars for some reason
@@ -146,25 +170,25 @@ GenericSave(int file)
totalSize = buf - work_buff;
// Save the rest
- WRITE_BLOCK(CPools::SavePedPool);
- WRITE_BLOCK(CGarages::Save);
- WRITE_BLOCK(CPools::SaveVehiclePool);
- WRITE_BLOCK(CPools::SaveObjectPool);
- WRITE_BLOCK(ThePaths.Save);
- WRITE_BLOCK(CCranes::Save);
- WRITE_BLOCK(CPickups::Save);
- WRITE_BLOCK(gPhoneInfo.Save);
- WRITE_BLOCK(CRestart::SaveAllRestartPoints);
- WRITE_BLOCK(CRadar::SaveAllRadarBlips);
- WRITE_BLOCK(CTheZones::SaveAllZones);
- WRITE_BLOCK(CGangs::SaveAllGangData);
- WRITE_BLOCK(CTheCarGenerators::SaveAllCarGenerators);
- WRITE_BLOCK(CParticleObject::SaveParticle);
- WRITE_BLOCK(cAudioScriptObject::SaveAllAudioScriptObjects);
- WRITE_BLOCK(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo);
- WRITE_BLOCK(CStats::SaveStats);
- WRITE_BLOCK(CStreaming::MemoryCardSave);
- WRITE_BLOCK(CPedType::Save);
+ WriteSaveDataBlock(CPools::SavePedPool);
+ WriteSaveDataBlock(CGarages::Save);
+ WriteSaveDataBlock(CPools::SaveVehiclePool);
+ WriteSaveDataBlock(CPools::SaveObjectPool);
+ WriteSaveDataBlock(ThePaths.Save);
+ WriteSaveDataBlock(CCranes::Save);
+ WriteSaveDataBlock(CPickups::Save);
+ WriteSaveDataBlock(gPhoneInfo.Save);
+ WriteSaveDataBlock(CRestart::SaveAllRestartPoints);
+ WriteSaveDataBlock(CRadar::SaveAllRadarBlips);
+ WriteSaveDataBlock(CTheZones::SaveAllZones);
+ WriteSaveDataBlock(CGangs::SaveAllGangData);
+ WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators);
+ WriteSaveDataBlock(CParticleObject::SaveParticle);
+ WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects);
+ WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo);
+ WriteSaveDataBlock(CStats::SaveStats);
+ WriteSaveDataBlock(CStreaming::MemoryCardSave);
+ WriteSaveDataBlock(CPedType::Save);
// Write padding
for (int i = 0; i < 4; i++) {
@@ -192,6 +216,115 @@ GenericSave(int file)
}
bool
+GenericLoad()
+{
+ uint8 *buf;
+ int32 file;
+ uint32 size;
+
+ int32 saveSize;
+ CPad *currPad;
+
+ // Load SimpleVars and Scripts
+ CheckSum = 0;
+ CDate(CompileDateAndTime);
+ CPad::ResetCheats();
+ if (!ReadInSizeofSaveFileBuffer(file, size))
+ return false;
+ size = align4bytes(size);
+ ReadDataFromFile(file, work_buff, size);
+ buf = (work_buff + 0x40);
+ ReadDataFromBufferPointer(buf, saveSize);
+ ReadDataFromBufferPointer(buf, CGame::currLevel);
+ ReadDataFromBufferPointer(buf, TheCamera.GetPosition().x);
+ ReadDataFromBufferPointer(buf, TheCamera.GetPosition().y);
+ ReadDataFromBufferPointer(buf, TheCamera.GetPosition().z);
+ ReadDataFromBufferPointer(buf, CClock::ms_nMillisecondsPerGameMinute);
+ ReadDataFromBufferPointer(buf, CClock::ms_nLastClockTick);
+ ReadDataFromBufferPointer(buf, CClock::ms_nGameClockHours);
+ ReadDataFromBufferPointer(buf, CClock::ms_nGameClockMinutes);
+ currPad = CPad::GetPad(0);
+ ReadDataFromBufferPointer(buf, currPad->Mode);
+ ReadDataFromBufferPointer(buf, CTimer::m_snTimeInMilliseconds);
+ ReadDataFromBufferPointer(buf, CTimer::ms_fTimeScale);
+ ReadDataFromBufferPointer(buf, CTimer::ms_fTimeStep);
+ ReadDataFromBufferPointer(buf, CTimer::ms_fTimeStepNonClipped);
+ ReadDataFromBufferPointer(buf, CTimer::m_FrameCounter);
+ ReadDataFromBufferPointer(buf, CTimeStep::ms_fTimeStep);
+ ReadDataFromBufferPointer(buf, CTimeStep::ms_fFramesPerUpdate);
+ ReadDataFromBufferPointer(buf, CTimeStep::ms_fTimeScale);
+ ReadDataFromBufferPointer(buf, CWeather::OldWeatherType);
+ ReadDataFromBufferPointer(buf, CWeather::NewWeatherType);
+ ReadDataFromBufferPointer(buf, CWeather::ForcedWeatherType);
+ ReadDataFromBufferPointer(buf, CWeather::InterpolationValue);
+ ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nSecond);
+ ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMinute);
+ ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nHour);
+ ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nDay);
+ ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nMonth);
+ ReadDataFromBufferPointer(buf, CompileDateAndTime.m_nYear);
+ ReadDataFromBufferPointer(buf, CWeather::WeatherTypeInList);
+ ReadDataFromBufferPointer(buf, TheCamera.CarZoomIndicator);
+ ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator);
+ assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
+ ReadDataFromBlock("Loading Scripts \n", CTheScripts::LoadAllScripts);
+
+ // Load the rest
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading PedPool \n", CPools::LoadPedPool);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Garages \n", CGarages::Load);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Vehicles \n", CPools::LoadVehiclePool);
+ LoadSaveDataBlock();
+ CProjectileInfo::RemoveAllProjectiles();
+ CObject::DeleteAllTempObjects();
+ ReadDataFromBlock("Loading Objects \n", CPools::LoadObjectPool);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Paths \n", ThePaths.Load);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Cranes \n", CCranes::Load);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Pickups \n", CPickups::Load);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Phoneinfo \n", gPhoneInfo.Load);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Restart \n", CRestart::LoadAllRestartPoints);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Radar Blips \n", CRadar::LoadAllRadarBlips);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Zones \n", CTheZones::LoadAllZones);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Gang Data \n", CGangs::LoadAllGangData);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Car Generators \n", CTheCarGenerators::LoadAllCarGenerators);
+ CParticle::ReloadConfig();
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Particles \n", CParticleObject::LoadParticle);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading AudioScript Objects \n", cAudioScriptObject::LoadAllAudioScriptObjects);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Player Info \n", CWorld::Players[CWorld::PlayerInFocus].LoadPlayerInfo);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Stats \n", CStats::LoadStats);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading Streaming Stuff \n", CStreaming::MemoryCardLoad);
+ LoadSaveDataBlock();
+ ReadDataFromBlock("Loading PedType Stuff \n", CPedType::Load);
+
+ DMAudio.SetMusicMasterVolume(CMenuManager::m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(CMenuManager::m_PrefsSfxVolume);
+ if (!CloseFile(file)) {
+ PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE;
+ return false;
+ }
+
+ DoGameSpecificStuffAfterSucessLoad();
+ debug("Game successfully loaded \n");
+ return true;
+}
+
+bool
ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size)
{
file = CFileMgr::OpenFile(LoadFileName, "rb");
@@ -404,7 +537,7 @@ align4bytes(int32 size)
STARTPATCHES
InjectHook(0x58F8D0, GenericSave, PATCH_JUMP);
- //InjectHook(0x590A00, GenericLoad, PATCH_JUMP);
+ InjectHook(0x590A00, GenericLoad, PATCH_JUMP);
InjectHook(0x591910, ReadInSizeofSaveFileBuffer, PATCH_JUMP);
InjectHook(0x591990, ReadDataFromFile, PATCH_JUMP);
InjectHook(0x591A00, CloseFile, PATCH_JUMP);
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index e22dfc7e..e6fd2e2d 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -1,37 +1,43 @@
-#pragma once
-
-#include "PCSave.h"
-
-#define SLOT_COUNT (8)
-
-bool GenericSave(int file);
-bool GenericLoad();
-bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size);
-bool ReadDataFromFile(int32 file, uint8 *buf, uint32 size);
-bool CloseFile(int32 file);
-void DoGameSpecificStuffAfterSucessLoad();
-bool CheckSlotDataValid(int32 slot);
-void MakeSpaceForSizeInBufferPointer(uint8 *&presize, uint8 *&buf, uint8 *&postsize);
-void CopySizeAndPreparePointer(uint8 *&buf, uint8 *&postbuf, uint8 *&postbuf2, uint32 &unused, uint32 &size);
-void DoGameSpecificStuffBeforeSave();
-void MakeValidSaveName(int32 slot);
-wchar *GetSavedGameDateAndTime(int32 slot);
-wchar *GetNameOfSavedGame(int32 slot);
-bool CheckDataNotCorrupt(int32 slot, char *name);
-bool RestoreForStartLoad();
-int align4bytes(int32 size);
-
-extern class CDate& CompileDateAndTime;
-
-extern char (&DefaultPCSaveFileName)[260];
-extern char (&ValidSaveName)[260];
-extern char (&LoadFileName)[256];
-extern wchar (&SlotFileName)[SLOT_COUNT][260];
-extern wchar (&SlotSaveDate)[SLOT_COUNT][70];
-extern int &CheckSum;
-extern enum eLevelName &m_LevelToLoad;
-extern int (&Slots)[SLOT_COUNT+1];
-
-extern char SaveFileNameJustSaved[260]; // 8F2570
-
+#pragma once
+
+#include "PCSave.h"
+
+#define SLOT_COUNT (8)
+
+bool GenericSave(int file);
+bool GenericLoad();
+bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size);
+bool ReadDataFromFile(int32 file, uint8 *buf, uint32 size);
+bool CloseFile(int32 file);
+void DoGameSpecificStuffAfterSucessLoad();
+bool CheckSlotDataValid(int32 slot);
+void MakeSpaceForSizeInBufferPointer(uint8 *&presize, uint8 *&buf, uint8 *&postsize);
+void CopySizeAndPreparePointer(uint8 *&buf, uint8 *&postbuf, uint8 *&postbuf2, uint32 &unused, uint32 &size);
+void DoGameSpecificStuffBeforeSave();
+void MakeValidSaveName(int32 slot);
+wchar *GetSavedGameDateAndTime(int32 slot);
+wchar *GetNameOfSavedGame(int32 slot);
+bool CheckDataNotCorrupt(int32 slot, char *name);
+bool RestoreForStartLoad();
+int align4bytes(int32 size);
+
+extern class CDate& CompileDateAndTime;
+
+extern char (&DefaultPCSaveFileName)[260];
+extern char (&ValidSaveName)[260];
+extern char (&LoadFileName)[256];
+extern wchar (&SlotFileName)[SLOT_COUNT][260];
+extern wchar (&SlotSaveDate)[SLOT_COUNT][70];
+extern int &CheckSum;
+extern enum eLevelName &m_LevelToLoad;
+extern int (&Slots)[SLOT_COUNT+1];
+
+extern bool &b_FoundRecentSavedGameWantToLoad;
+extern bool &JustLoadedDontFadeInYet;
+extern bool &StillToFadeOut;
+extern uint32 &TimeStartedCountingForFade;
+extern uint32 &TimeToStayFadedBeforeFadeOut;
+
+extern char SaveFileNameJustSaved[260]; // 8F2570
+
const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET"; \ No newline at end of file
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 7993426a..ec84e968 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -1927,7 +1927,7 @@ _WinMain(HINSTANCE instance,
* Enter the message processing loop...
*/
- while( !RsGlobal.quit && !FrontEndMenuManager.m_bStartGameLoading )
+ while( !RsGlobal.quit && !FrontEndMenuManager.m_bWantToRestart )
{
if( PeekMessage(&message, nil, 0U, 0U, PM_REMOVE|PM_NOYIELD) )
{
@@ -2059,13 +2059,13 @@ _WinMain(HINSTANCE instance,
if (wp.showCmd != SW_SHOWMINIMIZED)
RsEventHandler(rsFRONTENDIDLE, nil);
- if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bLoadingSavedGame )
+ if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
{
gGameState = GS_INIT_PLAYING_GAME;
TRACE("gGameState = GS_INIT_PLAYING_GAME;");
}
- if ( FrontEndMenuManager.m_bLoadingSavedGame )
+ if ( FrontEndMenuManager.m_bWantToLoad )
{
InitialiseGame();
FrontEndMenuManager.m_bGameNotLoaded = false;
@@ -2128,7 +2128,7 @@ _WinMain(HINSTANCE instance,
RwInitialised = FALSE;
FrontEndMenuManager.UnloadTextures();
- if ( !FrontEndMenuManager.m_bStartGameLoading )
+ if ( !FrontEndMenuManager.m_bWantToRestart )
break;
CPad::ResetCheats();
@@ -2138,13 +2138,13 @@ _WinMain(HINSTANCE instance,
CTimer::Stop();
- if ( FrontEndMenuManager.m_bLoadingSavedGame )
+ if ( FrontEndMenuManager.m_bWantToLoad )
{
CGame::ShutDownForRestart();
CGame::InitialiseWhenRestarting();
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- FrontEndMenuManager.m_bLoadingSavedGame = false;
+ FrontEndMenuManager.m_bWantToLoad = false;
}
else
{
@@ -2168,7 +2168,7 @@ _WinMain(HINSTANCE instance,
}
FrontEndMenuManager.m_bFirstTime = false;
- FrontEndMenuManager.m_bStartGameLoading = false;
+ FrontEndMenuManager.m_bWantToRestart = false;
}
diff --git a/src/text/Pager.cpp b/src/text/Pager.cpp
index 9e484c29..5c6b3ee2 100644
--- a/src/text/Pager.cpp
+++ b/src/text/Pager.cpp
@@ -1,194 +1,194 @@
-#include "common.h"
-#include "patcher.h"
-#include "Pager.h"
-#include "Timer.h"
-#include "Messages.h"
-#include "Hud.h"
-#include "Camera.h"
-
-void
-CPager::Init()
-{
- ClearMessages();
- m_nNumDisplayLetters = 8;
-}
-
-void
-CPager::Process()
-{
- if (m_messages[0].m_pText != nil && m_messages[0].m_nCurrentPosition >= (int32)m_messages[0].m_nStringLength) {
- m_messages[0].m_pText = nil;
- uint16 i = 0;
- while (i < NUMPAGERMESSAGES-1) {
- if (m_messages[i + 1].m_pText == nil) break;
- m_messages[i] = m_messages[i + 1];
- i++;
- }
- m_messages[i].m_pText = nil;
- if (m_messages[0].m_pText != nil)
- CMessages::AddToPreviousBriefArray(
- m_messages[0].m_pText,
- m_messages[0].m_nNumber[0],
- m_messages[0].m_nNumber[1],
- m_messages[0].m_nNumber[2],
- m_messages[0].m_nNumber[3],
- m_messages[0].m_nNumber[4],
- m_messages[0].m_nNumber[5],
- 0);
- }
- Display();
- if (m_messages[0].m_pText != nil) {
- if (TheCamera.m_WideScreenOn || !CHud::m_Wants_To_Draw_Hud || CHud::m_BigMessage[0][0] || CHud::m_BigMessage[2][0]) {
- RestartCurrentMessage();
- } else {
- if (CTimer::GetTimeInMilliseconds() > m_messages[0].m_nTimeToChangePosition) {
- m_messages[0].m_nCurrentPosition++;
- m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
- }
- }
- }
-}
-
-void
-CPager::Display()
-{
- wchar outstr1[256];
- wchar outstr2[260];
-
- wchar *pText = m_messages[0].m_pText;
- uint16 i = 0;
- if (pText != nil) {
- CMessages::InsertNumberInString(
- pText,
- m_messages[0].m_nNumber[0],
- m_messages[0].m_nNumber[1],
- m_messages[0].m_nNumber[2],
- m_messages[0].m_nNumber[3],
- m_messages[0].m_nNumber[4],
- m_messages[0].m_nNumber[5],
- outstr1);
- for (; i < m_nNumDisplayLetters; i++) {
- int pos = m_messages[0].m_nCurrentPosition + i;
- if (pos >= 0) {
- if (!outstr1[pos]) break;
-
- outstr2[i] = outstr1[pos];
- } else {
- outstr2[i] = ' ';
- }
- }
- }
- outstr2[i] = '\0';
- CHud::SetPagerMessage(outstr2);
-}
-
-void
-CPager::AddMessage(wchar *str, uint16 speed, uint16 priority, uint16 a5)
-{
- uint16 size = CMessages::GetWideStringLength(str);
- for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
- if (m_messages[i].m_pText) {
- if (m_messages[i].m_nPriority >= priority)
- continue;
-
- for (int j = NUMPAGERMESSAGES-1; j > i; j--)
- m_messages[j] = m_messages[j-1];
-
- }
- m_messages[i].m_pText = str;
- m_messages[i].m_nSpeedMs = speed;
- m_messages[i].m_nPriority = priority;
- m_messages[i].field_10 = a5;
- m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
- m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
- m_messages[i].m_nStringLength = size;
- m_messages[i].m_nNumber[0] = -1;
- m_messages[i].m_nNumber[1] = -1;
- m_messages[i].m_nNumber[2] = -1;
- m_messages[i].m_nNumber[3] = -1;
- m_messages[i].m_nNumber[4] = -1;
- m_messages[i].m_nNumber[5] = -1;
-
- if (i == 0)
- CMessages::AddToPreviousBriefArray(
- m_messages[0].m_pText,
- m_messages[0].m_nNumber[0],
- m_messages[0].m_nNumber[1],
- m_messages[0].m_nNumber[2],
- m_messages[0].m_nNumber[3],
- m_messages[0].m_nNumber[4],
- m_messages[0].m_nNumber[5],
- nil);
- return;
- }
-}
-
-void
-CPager::AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11)
-{
- wchar nstr[520];
-
- CMessages::InsertNumberInString(str, n1, n2, n3, n4, n5, n6, nstr);
- uint16 size = CMessages::GetWideStringLength(nstr);
- for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
- if (m_messages[i].m_pText) {
- if (m_messages[i].m_nPriority >= priority)
- continue;
-
- for (int j = NUMPAGERMESSAGES-1; j > i; j--)
- m_messages[j] = m_messages[j - 1];
-
- }
- m_messages[i].m_pText = str;
- m_messages[i].m_nSpeedMs = speed;
- m_messages[i].m_nPriority = priority;
- m_messages[i].field_10 = a11;
- m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
- m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
- m_messages[i].m_nStringLength = size;
- m_messages[i].m_nNumber[0] = n1;
- m_messages[i].m_nNumber[1] = n2;
- m_messages[i].m_nNumber[2] = n3;
- m_messages[i].m_nNumber[3] = n4;
- m_messages[i].m_nNumber[4] = n5;
- m_messages[i].m_nNumber[5] = n6;
-
- if (i == 0)
- CMessages::AddToPreviousBriefArray(
- m_messages[0].m_pText,
- m_messages[0].m_nNumber[0],
- m_messages[0].m_nNumber[1],
- m_messages[0].m_nNumber[2],
- m_messages[0].m_nNumber[3],
- m_messages[0].m_nNumber[4],
- m_messages[0].m_nNumber[5],
- nil);
- return;
- }
-}
-
-void
-CPager::ClearMessages()
-{
- for (int32 i = 0; i < NUMPAGERMESSAGES; i++)
- m_messages[i].m_pText = nil;
-}
-
-void
-CPager::RestartCurrentMessage()
-{
- if (m_messages[0].m_pText != nil) {
- m_messages[0].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
- m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
- }
-}
-
-STARTPATCHES
- InjectHook(0x52B6F0, &CPager::Init, PATCH_JUMP);
- InjectHook(0x52B740, &CPager::Process, PATCH_JUMP);
- InjectHook(0x52B890, &CPager::Display, PATCH_JUMP);
- InjectHook(0x52B940, &CPager::AddMessage, PATCH_JUMP);
- InjectHook(0x52BB50, &CPager::AddMessageWithNumber, PATCH_JUMP);
- InjectHook(0x52BE50, &CPager::RestartCurrentMessage, PATCH_JUMP);
- InjectHook(0x52BE00, &CPager::ClearMessages, PATCH_JUMP);
+#include "common.h"
+#include "patcher.h"
+#include "Pager.h"
+#include "Timer.h"
+#include "Messages.h"
+#include "Hud.h"
+#include "Camera.h"
+
+void
+CPager::Init()
+{
+ ClearMessages();
+ m_nNumDisplayLetters = 8;
+}
+
+void
+CPager::Process()
+{
+ if (m_messages[0].m_pText != nil && m_messages[0].m_nCurrentPosition >= (int32)m_messages[0].m_nStringLength) {
+ m_messages[0].m_pText = nil;
+ uint16 i = 0;
+ while (i < NUMPAGERMESSAGES-1) {
+ if (m_messages[i + 1].m_pText == nil) break;
+ m_messages[i] = m_messages[i + 1];
+ i++;
+ }
+ m_messages[i].m_pText = nil;
+ if (m_messages[0].m_pText != nil)
+ CMessages::AddToPreviousBriefArray(
+ m_messages[0].m_pText,
+ m_messages[0].m_nNumber[0],
+ m_messages[0].m_nNumber[1],
+ m_messages[0].m_nNumber[2],
+ m_messages[0].m_nNumber[3],
+ m_messages[0].m_nNumber[4],
+ m_messages[0].m_nNumber[5],
+ 0);
+ }
+ Display();
+ if (m_messages[0].m_pText != nil) {
+ if (TheCamera.m_WideScreenOn || !CHud::m_Wants_To_Draw_Hud || CHud::m_BigMessage[0][0] || CHud::m_BigMessage[2][0]) {
+ RestartCurrentMessage();
+ } else {
+ if (CTimer::GetTimeInMilliseconds() > m_messages[0].m_nTimeToChangePosition) {
+ m_messages[0].m_nCurrentPosition++;
+ m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
+ }
+ }
+ }
+}
+
+void
+CPager::Display()
+{
+ wchar outstr1[256];
+ wchar outstr2[260];
+
+ wchar *pText = m_messages[0].m_pText;
+ uint16 i = 0;
+ if (pText != nil) {
+ CMessages::InsertNumberInString(
+ pText,
+ m_messages[0].m_nNumber[0],
+ m_messages[0].m_nNumber[1],
+ m_messages[0].m_nNumber[2],
+ m_messages[0].m_nNumber[3],
+ m_messages[0].m_nNumber[4],
+ m_messages[0].m_nNumber[5],
+ outstr1);
+ for (; i < m_nNumDisplayLetters; i++) {
+ int pos = m_messages[0].m_nCurrentPosition + i;
+ if (pos >= 0) {
+ if (!outstr1[pos]) break;
+
+ outstr2[i] = outstr1[pos];
+ } else {
+ outstr2[i] = ' ';
+ }
+ }
+ }
+ outstr2[i] = '\0';
+ CHud::SetPagerMessage(outstr2);
+}
+
+void
+CPager::AddMessage(wchar *str, uint16 speed, uint16 priority, uint16 a5)
+{
+ uint16 size = CMessages::GetWideStringLength(str);
+ for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
+ if (m_messages[i].m_pText) {
+ if (m_messages[i].m_nPriority >= priority)
+ continue;
+
+ for (int j = NUMPAGERMESSAGES-1; j > i; j--)
+ m_messages[j] = m_messages[j-1];
+
+ }
+ m_messages[i].m_pText = str;
+ m_messages[i].m_nSpeedMs = speed;
+ m_messages[i].m_nPriority = priority;
+ m_messages[i].field_10 = a5;
+ m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
+ m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
+ m_messages[i].m_nStringLength = size;
+ m_messages[i].m_nNumber[0] = -1;
+ m_messages[i].m_nNumber[1] = -1;
+ m_messages[i].m_nNumber[2] = -1;
+ m_messages[i].m_nNumber[3] = -1;
+ m_messages[i].m_nNumber[4] = -1;
+ m_messages[i].m_nNumber[5] = -1;
+
+ if (i == 0)
+ CMessages::AddToPreviousBriefArray(
+ m_messages[0].m_pText,
+ m_messages[0].m_nNumber[0],
+ m_messages[0].m_nNumber[1],
+ m_messages[0].m_nNumber[2],
+ m_messages[0].m_nNumber[3],
+ m_messages[0].m_nNumber[4],
+ m_messages[0].m_nNumber[5],
+ nil);
+ return;
+ }
+}
+
+void
+CPager::AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11)
+{
+ wchar nstr[520];
+
+ CMessages::InsertNumberInString(str, n1, n2, n3, n4, n5, n6, nstr);
+ uint16 size = CMessages::GetWideStringLength(nstr);
+ for (int32 i = 0; i < NUMPAGERMESSAGES; i++) {
+ if (m_messages[i].m_pText) {
+ if (m_messages[i].m_nPriority >= priority)
+ continue;
+
+ for (int j = NUMPAGERMESSAGES-1; j > i; j--)
+ m_messages[j] = m_messages[j - 1];
+
+ }
+ m_messages[i].m_pText = str;
+ m_messages[i].m_nSpeedMs = speed;
+ m_messages[i].m_nPriority = priority;
+ m_messages[i].field_10 = a11;
+ m_messages[i].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
+ m_messages[i].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + speed;
+ m_messages[i].m_nStringLength = size;
+ m_messages[i].m_nNumber[0] = n1;
+ m_messages[i].m_nNumber[1] = n2;
+ m_messages[i].m_nNumber[2] = n3;
+ m_messages[i].m_nNumber[3] = n4;
+ m_messages[i].m_nNumber[4] = n5;
+ m_messages[i].m_nNumber[5] = n6;
+
+ if (i == 0)
+ CMessages::AddToPreviousBriefArray(
+ m_messages[0].m_pText,
+ m_messages[0].m_nNumber[0],
+ m_messages[0].m_nNumber[1],
+ m_messages[0].m_nNumber[2],
+ m_messages[0].m_nNumber[3],
+ m_messages[0].m_nNumber[4],
+ m_messages[0].m_nNumber[5],
+ nil);
+ return;
+ }
+}
+
+void
+CPager::ClearMessages()
+{
+ for (int32 i = 0; i < NUMPAGERMESSAGES; i++)
+ m_messages[i].m_pText = nil;
+}
+
+void
+CPager::RestartCurrentMessage()
+{
+ if (m_messages[0].m_pText != nil) {
+ m_messages[0].m_nCurrentPosition = -(m_nNumDisplayLetters + 10);
+ m_messages[0].m_nTimeToChangePosition = CTimer::GetTimeInMilliseconds() + m_messages[0].m_nSpeedMs;
+ }
+}
+
+STARTPATCHES
+ InjectHook(0x52B6F0, &CPager::Init, PATCH_JUMP);
+ InjectHook(0x52B740, &CPager::Process, PATCH_JUMP);
+ InjectHook(0x52B890, &CPager::Display, PATCH_JUMP);
+ InjectHook(0x52B940, &CPager::AddMessage, PATCH_JUMP);
+ InjectHook(0x52BB50, &CPager::AddMessageWithNumber, PATCH_JUMP);
+ InjectHook(0x52BE50, &CPager::RestartCurrentMessage, PATCH_JUMP);
+ InjectHook(0x52BE00, &CPager::ClearMessages, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/text/Pager.h b/src/text/Pager.h
index 1719e726..a628be6f 100644
--- a/src/text/Pager.h
+++ b/src/text/Pager.h
@@ -1,28 +1,28 @@
-#pragma once
-
-struct PagerMessage {
- wchar *m_pText;
- uint16 m_nSpeedMs;
- int16 m_nCurrentPosition;
- uint16 m_nStringLength;
- uint16 m_nPriority;
- uint32 m_nTimeToChangePosition;
- int16 field_10;
- int32 m_nNumber[6];
-};
-
-#define NUMPAGERMESSAGES 8
-
-class CPager
-{
- int16 m_nNumDisplayLetters;
- PagerMessage m_messages[NUMPAGERMESSAGES];
-public:
- void Init();
- void Process();
- void Display();
- void AddMessage(wchar*, uint16, uint16, uint16);
- void AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11);
- void ClearMessages();
- void RestartCurrentMessage();
+#pragma once
+
+struct PagerMessage {
+ wchar *m_pText;
+ uint16 m_nSpeedMs;
+ int16 m_nCurrentPosition;
+ uint16 m_nStringLength;
+ uint16 m_nPriority;
+ uint32 m_nTimeToChangePosition;
+ int16 field_10;
+ int32 m_nNumber[6];
+};
+
+#define NUMPAGERMESSAGES 8
+
+class CPager
+{
+ int16 m_nNumDisplayLetters;
+ PagerMessage m_messages[NUMPAGERMESSAGES];
+public:
+ void Init();
+ void Process();
+ void Display();
+ void AddMessage(wchar*, uint16, uint16, uint16);
+ void AddMessageWithNumber(wchar *str, int32 n1, int32 n2, int32 n3, int32 n4, int32 n5, int32 n6, uint16 speed, uint16 priority, uint16 a11);
+ void ClearMessages();
+ void RestartCurrentMessage();
}; \ No newline at end of file
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index e6b936f6..257c8d33 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -182,17 +182,17 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_weaponDoorTimerRight = m_weaponDoorTimerLeft;
if(GetModelIndex() == MI_DODO){
- RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
CMatrix mat1;
mat1.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
CMatrix mat2(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF]));
mat1.GetPosition() += CVector(mat2.GetPosition().x + 0.1f, 0.0f, mat2.GetPosition().z);
mat1.UpdateRW();
}else if(GetModelIndex() == MI_MIAMI_SPARROW || GetModelIndex() == MI_MIAMI_RCRAIDER){
- RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
- RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
- RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
- RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
+ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
}else if(GetModelIndex() == MI_RHINO){
bExplosionProof = true;
bBulletProof = true;
@@ -253,7 +253,7 @@ CAutomobile::ProcessControl(void)
ProcessCarAlarm();
- // Scan if this car is committing a crime that the police can see
+ // Scan if this car sees the player committing any crimes
if(m_status != STATUS_ABANDONED && m_status != STATUS_WRECKED &&
m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE && m_status != STATUS_PLAYER_DISABLED){
switch(GetModelIndex())
@@ -356,7 +356,7 @@ CAutomobile::ProcessControl(void)
PruneReferences();
- if(m_status == STATUS_PLAYER && CRecordDataForChase::Status != RECORDSTATE_1)
+ if(m_status == STATUS_PLAYER && CRecordDataForChase::IsRecording())
DoDriveByShootings();
}
break;
@@ -667,7 +667,7 @@ CAutomobile::ProcessControl(void)
if(!strongGrip1 && !CVehicle::bCheat3)
gripCheat = false;
float acceleration = pHandling->Transmission.CalculateDriveAcceleration(m_fGasPedal, m_nCurrentGear, m_fChangeGearTime, fwdSpeed, gripCheat);
- acceleration /= fForceMultiplier;
+ acceleration /= m_fForceMultiplier;
// unused
if(GetModelIndex() == MI_MIAMI_RCBARON ||
@@ -718,7 +718,7 @@ CAutomobile::ProcessControl(void)
else
traction = 0.004f;
traction *= pHandling->fTractionMultiplier / 4.0f;
- traction /= fForceMultiplier;
+ traction /= m_fForceMultiplier;
if(CVehicle::bCheat3)
traction *= 4.0f;
@@ -1727,9 +1727,9 @@ CAutomobile::PreRender(void)
// bright lights
if(Damage.GetLightStatus(VEHLIGHT_FRONT_LEFT) == LIGHT_STATUS_OK && !bNoBrightHeadLights)
- CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + 4);
+ CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + BRIGHTLIGHT_FRONT);
if(Damage.GetLightStatus(VEHLIGHT_FRONT_RIGHT) == LIGHT_STATUS_OK && !bNoBrightHeadLights)
- CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + 4);
+ CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->FrontLights + BRIGHTLIGHT_FRONT);
// Taillights
@@ -1798,9 +1798,9 @@ CAutomobile::PreRender(void)
// bright lights
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
- CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
+ CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
if(Damage.GetLightStatus(VEHLIGHT_REAR_RIGHT) == LIGHT_STATUS_OK)
- CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
+ CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
// Light shadows
if(!alarmOff){
@@ -1873,9 +1873,9 @@ CAutomobile::PreRender(void)
CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
- CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 4);
+ CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_FRONT);
if(Damage.GetLightStatus(VEHLIGHT_REAR_RIGHT) == LIGHT_STATUS_OK)
- CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 4);
+ CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_FRONT);
}else{
// braking
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
@@ -1889,9 +1889,9 @@ CAutomobile::PreRender(void)
CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f);
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
- CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
+ CBrightLights::RegisterOne(lightL, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
if(Damage.GetLightStatus(VEHLIGHT_REAR_RIGHT) == LIGHT_STATUS_OK)
- CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + 8);
+ CBrightLights::RegisterOne(lightR, GetUp(), GetRight(), GetForward(), pHandling->RearLights + BRIGHTLIGHT_REAR);
}
}else{
if(Damage.GetLightStatus(VEHLIGHT_REAR_LEFT) == LIGHT_STATUS_OK)
@@ -2814,7 +2814,7 @@ CAutomobile::ProcessBuoyancy(void)
CVector impulse, point;
if(mod_Buoyancy.ProcessBuoyancy(this, m_fBuoyancy, &point, &impulse)){
- m_flagD8 = true;
+ bTouchingWater = true;
ApplyMoveForce(impulse);
ApplyTurnForce(impulse, point);
@@ -2899,7 +2899,7 @@ CAutomobile::ProcessBuoyancy(void)
}
}else{
bIsInWater = false;
- m_flagD8 = false;
+ bTouchingWater = false;
static RwRGBA splashCol = {155, 155, 185, 196};
static RwRGBA smokeCol = {255, 255, 255, 255};
@@ -3791,7 +3791,7 @@ CAutomobile::BlowUpCar(CEntity *culprit)
}
ChangeLawEnforcerState(false);
- gFireManager.StartFire(this, culprit, 0.8f, 1); // TODO
+ gFireManager.StartFire(this, culprit, 0.8f, true);
CDarkel::RegisterCarBlownUpByPlayer(this);
if(GetModelIndex() == MI_RCBANDIT)
CExplosion::AddExplosion(this, culprit, EXPLOSION_CAR_QUICK, GetPosition(), 0);
@@ -4054,7 +4054,7 @@ CAutomobile::HasCarStoppedBecauseOfLight(void)
if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nNextRouteNode)
break;
if(i < curnode->numLinks &&
- ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO
+ ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3)
return true;
}
@@ -4064,7 +4064,7 @@ CAutomobile::HasCarStoppedBecauseOfLight(void)
if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nPrevRouteNode)
break;
if(i < curnode->numLinks &&
- ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO
+ ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3)
return true;
}
diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h
new file mode 100644
index 00000000..4e7e5a0e
--- /dev/null
+++ b/src/vehicles/Bike.h
@@ -0,0 +1,15 @@
+#pragma once
+
+// some miami bike leftovers
+
+enum eBikeNodes {
+ BIKE_NODE_NONE,
+ BIKE_CHASSIS,
+ BIKE_FORKS_FRONT,
+ BIKE_FORKS_REAR,
+ BIKE_WHEEL_FRONT,
+ BIKE_WHEEL_REAR,
+ BIKE_MUDGUARD,
+ BIKE_HANDLEBARS,
+ BIKE_NUM_NODES
+}; \ No newline at end of file
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 6d584017..0159d168 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -1,12 +1,25 @@
#include "common.h"
#include "patcher.h"
-#include "Boat.h"
+#include "General.h"
+#include "Timecycle.h"
#include "HandlingMgr.h"
+#include "CarCtrl.h"
#include "RwHelper.h"
#include "ModelIndices.h"
+#include "VisibilityPlugins.h"
+#include "DMAudio.h"
+#include "Camera.h"
+#include "Darkel.h"
+#include "Explosion.h"
+#include "Particle.h"
#include "WaterLevel.h"
-#include "Pools.h"
+#include "Floater.h"
#include "World.h"
+#include "Pools.h"
+#include "Pad.h"
+#include "Boat.h"
+
+#define INVALID_ORIENTATION (-9999.99f)
float &fShapeLength = *(float*)0x600E78;
float &fShapeTime = *(float*)0x600E7C;
@@ -19,10 +32,6 @@ float WAKE_LIFETIME = 400.0f;
CBoat * (&CBoat::apFrameWakeGeneratingBoats)[4] = *(CBoat * (*)[4])*(uintptr*)0x8620E0;
-WRAPPER void CBoat::ProcessControl() { EAXJMP(0x53EF10); }
-WRAPPER void CBoat::ProcessControlInputs(uint8) { EAXJMP(0x53EC70); }
-WRAPPER void CBoat::BlowUpCar(CEntity* ent) { EAXJMP(0x541CB0); }
-
CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
{
CVehicleModelInfo *minfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(mi);
@@ -47,35 +56,31 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
m_fGasPedal = 0.0f;
m_fBrakePedal = 0.0f;
- field_288 = 0.25f;
- field_28C = 0.35f;
- field_290 = 0.7f;
- field_294 = 0.998f;
- field_298 = 0.999f;
- field_29C = 0.85f;
- field_2A0 = 0.96f;
- field_2A4 = 0.96f;
+ m_fPropellerZ = 0.25f;
+ m_fPropellerY = 0.35f;
+ m_waterMoveDrag = CVector(0.7f, 0.998f, 0.999f);
+ m_waterTurnDrag = CVector(0.85f, 0.96f, 0.96f);
_unk2 = false;
- m_fTurnForceZ = 7.0f;
- field_2FC = 7.0f;
- m_vecMoveForce = CVector(0.0f, 0.0f, 0.0f);
+ m_fVolumeUnderWater = 7.0f;
+ m_fPrevVolumeUnderWater = 7.0f;
+ m_vecBuoyancePoint = CVector(0.0f, 0.0f, 0.0f);
- field_300 = 0;
- m_bBoatFlag1 = true;
- m_bBoatFlag2 = true;
+ m_nDeltaVolumeUnderWater = 0;
+ bBoatInWater = true;
+ bPropellerInWater = true;
bIsInWater = true;
unk1 = 0.0f;
m_bIsAnchored = true;
- field_2C4 = -9999.99f;
- m_flagD8 = true;
- field_2CC = 0.0f;
- field_2D0 = 0;
+ m_fOrientation = INVALID_ORIENTATION;
+ bTouchingWater = true;
+ m_fDamage = 0.0f;
+ m_pSetOnFireEntity = nil;
m_nNumWakePoints = 0;
- for (int16 i = 0; i < 32; i++)
+ for (int16 i = 0; i < ARRAY_SIZE(m_afWakePointLifeTime); i++)
m_afWakePointLifeTime[i] = 0.0f;
m_nAmmoInClip = 20;
@@ -94,7 +99,542 @@ CBoat::GetComponentWorldPosition(int32 component, CVector &pos)
pos = *RwMatrixGetPos(RwFrameGetLTM(m_aBoatNodes[component]));
}
-RxObjSpace3DVertex KeepWaterOutVertices[4];
+void
+CBoat::ProcessControl(void)
+{
+ if(m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory)
+ return;
+
+ bool onLand = m_fDamageImpulse > 0.0f && m_vecDamageNormal.z > 0.1f;
+
+ PruneWakeTrail();
+
+ int r, g, b;
+ RwRGBA splashColor, jetColor;
+ r = 114.75f*(CTimeCycle::GetAmbientRed() + 0.5f*CTimeCycle::GetDirectionalRed());
+ g = 114.75f*(CTimeCycle::GetAmbientGreen() + 0.5f*CTimeCycle::GetDirectionalGreen());
+ b = 114.75f*(CTimeCycle::GetAmbientBlue() + 0.5f*CTimeCycle::GetDirectionalBlue());
+ r = clamp(r, 0, 255);
+ g = clamp(g, 0, 255);
+ b = clamp(b, 0, 255);
+ splashColor.red = r;
+ splashColor.green = g;
+ splashColor.blue = b;
+ splashColor.alpha = CGeneral::GetRandomNumberInRange(128, 150);
+
+ r = 242.25f*(CTimeCycle::GetAmbientRed() + 0.5f*CTimeCycle::GetDirectionalRed());
+ g = 242.25f*(CTimeCycle::GetAmbientGreen() + 0.5f*CTimeCycle::GetDirectionalGreen());
+ b = 242.25f*(CTimeCycle::GetAmbientBlue() + 0.5f*CTimeCycle::GetDirectionalBlue());
+ r = clamp(r, 0, 255);
+ g = clamp(g, 0, 255);
+ b = clamp(b, 0, 255);
+ jetColor.red = r;
+ jetColor.green = g;
+ jetColor.blue = b;
+ jetColor.alpha = CGeneral::GetRandomNumberInRange(96, 128);
+
+ CGeneral::GetRandomNumber(); // unused
+
+ ProcessCarAlarm();
+
+ switch(m_status){
+ case STATUS_PLAYER:
+ m_bIsAnchored = false;
+ m_fOrientation = INVALID_ORIENTATION;
+ ProcessControlInputs(0);
+ if(GetModelIndex() == MI_PREDATOR)
+ DoFixedMachineGuns();
+ break;
+ case STATUS_SIMPLE:
+ m_bIsAnchored = false;
+ m_fOrientation = INVALID_ORIENTATION;
+ CPhysical::ProcessControl();
+ bBoatInWater = true;
+ bPropellerInWater = true;
+ bIsInWater = true;
+ return;
+ case STATUS_PHYSICS:
+ m_bIsAnchored = false;
+ m_fOrientation = INVALID_ORIENTATION;
+ CCarCtrl::SteerAIBoatWithPhysics(this);
+ break;
+ case STATUS_ABANDONED:
+ case STATUS_WRECKED:
+ bBoatInWater = true;
+ bPropellerInWater = true;
+ bIsInWater = true;
+ m_fSteerAngle = 0.0;
+ bIsHandbrakeOn = false;
+ m_fBrakePedal = 0.5f;
+ m_fGasPedal = 0.0f;
+ if((GetPosition() - CWorld::Players[CWorld::PlayerInFocus].GetPos()).Magnitude() > 150.0f){
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ return;
+ }
+ break;
+ }
+
+ float collisionDamage = pHandling->fCollisionDamageMultiplier * m_fDamageImpulse;
+ if(collisionDamage > 25.0f && m_status != STATUS_WRECKED && m_fHealth >= 150.0f){
+ float prevHealth = m_fHealth;
+ if(this == FindPlayerVehicle()){
+ if(bTakeLessDamage)
+ m_fHealth -= (collisionDamage-25.0f)/6.0f;
+ else
+ m_fHealth -= (collisionDamage-25.0f)/2.0f;
+ }else{
+ if(collisionDamage > 60.0f && pDriver)
+ pDriver->Say(SOUND_PED_CAR_COLLISION);
+ if(bTakeLessDamage)
+ m_fHealth -= (collisionDamage-25.0f)/12.0f;
+ else
+ m_fHealth -= (collisionDamage-25.0f)/4.0f;
+ }
+
+ if(m_fHealth <= 0.0f && prevHealth > 0.0f){
+ m_fHealth = 1.0f;
+ m_pSetOnFireEntity = m_pDamageEntity;
+ }
+ }
+
+ // Damage particles
+ if(m_fHealth <= 600.0f && m_status != STATUS_WRECKED &&
+ Abs(GetPosition().x - TheCamera.GetPosition().x) < 200.0f &&
+ Abs(GetPosition().y - TheCamera.GetPosition().y) < 200.0f){
+ float speedSq = m_vecMoveSpeed.MagnitudeSqr();
+ CVector smokeDir = 0.8f*m_vecMoveSpeed;
+ CVector smokePos;
+ switch(GetModelIndex()){
+ case MI_SPEEDER:
+ smokePos = CVector(0.4f, -2.4f, 0.8f);
+ smokeDir += 0.05f*GetRight();
+ smokeDir.z += 0.2f*m_vecMoveSpeed.z;
+ break;
+ case MI_REEFER:
+ smokePos = CVector(2.0f, -1.0f, 0.5f);
+ smokeDir += 0.07f*GetRight();
+ break;
+ case MI_PREDATOR:
+ default:
+ smokePos = CVector(-1.5f, -0.5f, 1.2f);
+ smokeDir += -0.08f*GetRight();
+ break;
+ }
+
+ smokePos = GetMatrix() * smokePos;
+
+ // On fire
+ if(m_fHealth < 150.0f){
+ CParticle::AddParticle(PARTICLE_CARFLAME, smokePos,
+ CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(2.25f/200.0f, 0.09f)),
+ nil, 0.9f);
+ CVector smokePos2 = smokePos;
+ smokePos2.x += CGeneral::GetRandomNumberInRange(-2.25f/4.0f, 2.25f/4.0f);
+ smokePos2.y += CGeneral::GetRandomNumberInRange(-2.25f/4.0f, 2.25f/4.0f);
+ smokePos2.z += CGeneral::GetRandomNumberInRange(2.25f/4.0f, 2.25f);
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, smokePos2, CVector(0.0f, 0.0f, 0.0f));
+
+ m_fDamage += CTimer::GetTimeStepInMilliseconds();
+ if(m_fDamage > 5000.0f)
+ BlowUpCar(m_pSetOnFireEntity);
+ }
+
+ if(speedSq < 0.25f && (CTimer::GetFrameCounter() + m_randomSeed) & 1)
+ CParticle::AddParticle(PARTICLE_ENGINE_STEAM, smokePos, smokeDir);
+ if(speedSq < 0.25f && m_fHealth <= 350.0f)
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE, smokePos, 1.25f*smokeDir);
+ }
+
+ CPhysical::ProcessControl();
+
+ CVector buoyanceImpulse(0.0f, 0.0f, 0.0f);
+ CVector buoyancePoint(0.0f, 0.0f, 0.0f);
+ if(mod_Buoyancy.ProcessBuoyancy(this, pHandling->fBuoyancy, &buoyancePoint, &buoyanceImpulse)){
+ // Process boat in water
+ if(0.1f * m_fMass * GRAVITY*CTimer::GetTimeStep() < buoyanceImpulse.z){
+ bBoatInWater = true;
+ bIsInWater = true;
+ }else{
+ bBoatInWater = false;
+ bIsInWater = false;
+ }
+
+ m_fVolumeUnderWater = mod_Buoyancy.m_volumeUnderWater;
+ m_vecBuoyancePoint = buoyancePoint;
+ ApplyMoveForce(buoyanceImpulse);
+ if(!onLand)
+ ApplyTurnForce(buoyanceImpulse, buoyancePoint);
+
+ if(!onLand && bBoatInWater && GetUp().z > 0.0f){
+ float impulse;
+ if(m_fGasPedal > 0.05f)
+ impulse = m_vecMoveSpeed.MagnitudeSqr()*pHandling->fSuspensionForceLevel*buoyanceImpulse.z*CTimer::GetTimeStep()*0.5f*m_fGasPedal;
+ else
+ impulse = 0.0f;
+ impulse = min(impulse, GRAVITY*pHandling->fSuspensionDampingLevel*m_fMass*CTimer::GetTimeStep());
+ ApplyMoveForce(impulse*GetUp());
+ ApplyTurnForce(impulse*GetUp(), buoyancePoint - pHandling->fSuspensionBias*GetForward());
+ }
+
+ // Handle boat moving forward
+ if(Abs(m_fGasPedal) > 0.05f || m_vecMoveSpeed.Magnitude() > 0.01f){
+ if(bBoatInWater)
+ AddWakePoint(GetPosition());
+
+ float steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward());
+ if(m_modelIndex == MI_GHOST)
+ steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward())*0.3f;
+ if(steerFactor < 0.0f) steerFactor = 0.0f;
+
+ CVector propeller(0.0f, -pHandling->Dimension.y*m_fPropellerY, -pHandling->Dimension.z*m_fPropellerZ);
+ propeller = Multiply3x3(GetMatrix(), propeller);
+ CVector propellerWorld = GetPosition() + propeller;
+
+ float steerSin = Sin(-m_fSteerAngle * steerFactor);
+ float steerCos = Cos(-m_fSteerAngle * steerFactor);
+ float waterLevel;
+ CWaterLevel::GetWaterLevel(propellerWorld, &waterLevel, true);
+ if(propellerWorld.z-0.5f < waterLevel){
+ float propellerDepth = waterLevel - (propellerWorld.z - 0.5f);
+ if(propellerDepth > 1.0f)
+ propellerDepth = 1.0f;
+ else
+ propellerDepth = SQR(propellerDepth);
+ bPropellerInWater = true;
+
+ if(Abs(m_fGasPedal) > 0.05f){
+ CVector forceDir = Multiply3x3(GetMatrix(), CVector(-steerSin, steerCos, -Abs(m_fSteerAngle)));
+ CVector force = propellerDepth * m_fGasPedal * 40.0f * pHandling->Transmission.fEngineAcceleration * pHandling->fMass * forceDir;
+ if(force.z > 0.2f)
+ force.z = SQR(1.2f - force.z) + 0.2f;
+ if(onLand){
+ if(m_fGasPedal < 0.0f){
+ force.x *= 5.0f;
+ force.y *= 5.0f;
+ }
+ if(force.z < 0.0f)
+ force.z = 0.0f;
+ ApplyMoveForce(force * CTimer::GetTimeStep());
+ }else{
+ ApplyMoveForce(force * CTimer::GetTimeStep());
+ ApplyTurnForce(force * CTimer::GetTimeStep(), propeller - pHandling->fTractionBias*GetUp());
+ float rightForce = DotProduct(GetRight(), force);
+ ApplyTurnForce(-rightForce*GetRight() * CTimer::GetTimeStep(), GetUp());
+ }
+
+ // Spray some particles
+ CVector jetDir = -0.04f * force;
+ if(m_fGasPedal > 0.0f){
+ if(m_status == STATUS_PLAYER){
+ bool cameraHack = TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
+ TheCamera.WhoIsInControlOfTheCamera == CAMCONTROL_OBBE;
+ CVector sternPos = GetColModel()->boundingBox.min;
+ sternPos.x = 0.0f;
+ sternPos.z = 0.0f;
+ sternPos = Multiply3x3(GetMatrix(), sternPos);
+
+ CVector jetPos = GetPosition() + sternPos;
+ if(cameraHack)
+ jetPos.z = 1.0f;
+ else
+ jetPos.z = 0.0f;
+
+ CVector wakePos = GetPosition() + sternPos;
+ wakePos.z -= 0.65f;
+
+ CVector wakeDir = 0.75f * jetDir;
+
+ CParticle::AddParticle(PARTICLE_BOAT_THRUSTJET, jetPos, jetDir, nil, 0.0f, jetColor);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, jetPos, 0.25f * jetDir, nil, 1.0f, splashColor,
+ CGeneral::GetRandomNumberInRange(0, 30),
+ CGeneral::GetRandomNumberInRange(0, 90), 3);
+ if(!cameraHack)
+ CParticle::AddParticle(PARTICLE_BOAT_WAKE, wakePos, wakeDir, nil, 0.0f, jetColor);
+ }else if((CTimer::GetFrameCounter() + m_randomSeed) & 1){
+ jetDir.z = 0.018f;
+ jetDir.x *= 0.01f;
+ jetDir.y *= 0.01f;
+ propellerWorld.z += 1.5f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 1.5f, jetColor);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, propellerWorld, 0.1f * jetDir, nil, 0.5f, splashColor,
+ CGeneral::GetRandomNumberInRange(0, 30),
+ CGeneral::GetRandomNumberInRange(0, 90), 3);
+ }
+ }
+ }else if(!onLand){
+ float force = 50.0f*DotProduct(m_vecMoveSpeed, GetForward());
+ if(force > 10.0f) force = 10.0f;
+ CVector propellerForce = propellerDepth * Multiply3x3(GetMatrix(), force*CVector(-steerSin, 0.0f, 0.0f));
+ ApplyMoveForce(propellerForce * CTimer::GetTimeStep()*0.5f);
+ ApplyTurnForce(propellerForce * CTimer::GetTimeStep()*0.5f, propeller);
+ }
+ }else
+ bPropellerInWater = false;
+ }
+
+ // Slow down or push down boat as it approaches the world limits
+ m_vecMoveSpeed.x = min(m_vecMoveSpeed.x, -(GetPosition().x - 1900.0f)*0.01f); // east
+ m_vecMoveSpeed.x = max(m_vecMoveSpeed.x, -(GetPosition().x - -1515.0f)*0.01f); // west
+ m_vecMoveSpeed.y = min(m_vecMoveSpeed.y, -(GetPosition().y - 600.0f)*0.01f); // north
+ m_vecMoveSpeed.y = max(m_vecMoveSpeed.y, -(GetPosition().y - -1900.0f)*0.01f); // south
+
+ if(!onLand && bBoatInWater)
+ ApplyWaterResistance();
+
+ // No idea what exactly is going on here besides drag in YZ
+ float fx = Pow(m_waterTurnDrag.x, CTimer::GetTimeStep());
+ float fy = Pow(m_waterTurnDrag.y, CTimer::GetTimeStep());
+ float fz = Pow(m_waterTurnDrag.z, CTimer::GetTimeStep());
+ m_vecTurnSpeed = Multiply3x3(m_vecTurnSpeed, GetMatrix()); // invert - to local space
+ // TODO: figure this out
+ float magic = 1.0f/(1000.0f * SQR(m_vecTurnSpeed.x) + 1.0f) * fx;
+ m_vecTurnSpeed.y *= fy;
+ m_vecTurnSpeed.z *= fz;
+ float forceUp = (magic - 1.0f) * m_vecTurnSpeed.x * m_fTurnMass;
+ m_vecTurnSpeed = Multiply3x3(GetMatrix(), m_vecTurnSpeed); // back to world
+ CVector com = Multiply3x3(GetMatrix(), m_vecCentreOfMass);
+ ApplyTurnForce(CVector(0.0f, 0.0f, forceUp), com + GetForward());
+
+ m_nDeltaVolumeUnderWater = (m_fVolumeUnderWater-m_fPrevVolumeUnderWater)*10000;
+
+ // Falling into water
+ if(!onLand && bBoatInWater && GetUp().z > 0.0f && m_nDeltaVolumeUnderWater > 200){
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, m_nDeltaVolumeUnderWater);
+
+ float speedUp = m_vecMoveSpeed.MagnitudeSqr() * m_nDeltaVolumeUnderWater * 0.0004f;
+ if(speedUp + m_vecMoveSpeed.z > pHandling->fBrakeDeceleration)
+ speedUp = pHandling->fBrakeDeceleration - m_vecMoveSpeed.z;
+ if(speedUp < 0.0f) speedUp = 0.0f;
+ float speedFwd = DotProduct(m_vecMoveSpeed, GetForward());
+ speedFwd *= -m_nDeltaVolumeUnderWater * 0.01f * pHandling->fTractionLoss;
+ CVector speed = speedFwd*GetForward() + CVector(0.0f, 0.0f, speedUp);
+ CVector splashImpulse = speed * m_fMass;
+ ApplyMoveForce(splashImpulse);
+ ApplyTurnForce(splashImpulse, buoyancePoint);
+ }
+
+ // Spray particles on sides of boat
+ if(m_nDeltaVolumeUnderWater > 75){
+ float speed = m_vecMoveSpeed.Magnitude();
+ float splash1Size = speed;
+ float splash2Size = m_nDeltaVolumeUnderWater * 0.005f * 0.2f;
+ float front = 0.9f * GetColModel()->boundingBox.max.y;
+ if(splash1Size > 0.75f) splash1Size = 0.75f;
+
+ CVector dir, pos;
+
+ // right
+ dir = -0.5f*m_vecMoveSpeed;
+ dir.z += 0.1f*speed;
+ dir += 0.5f*GetRight()*speed;
+ pos = front*GetForward() + 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
+ CWaterLevel::GetWaterLevel(pos, &pos.z, true);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
+ CGeneral::GetRandomNumberInRange(0, 30),
+ CGeneral::GetRandomNumberInRange(0, 90), 1);
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
+
+ // left
+ dir = -0.5f*m_vecMoveSpeed;
+ dir.z += 0.1f*speed;
+ dir -= 0.5f*GetRight()*speed;
+ pos = front*GetForward() - 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
+ CWaterLevel::GetWaterLevel(pos, &pos.z, true);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
+ CGeneral::GetRandomNumberInRange(0, 30),
+ CGeneral::GetRandomNumberInRange(0, 90), 1);
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
+ }
+
+ m_fPrevVolumeUnderWater = m_fVolumeUnderWater;
+ }else{
+ bBoatInWater = false;
+ bIsInWater = false;
+ }
+
+ if(m_bIsAnchored){
+ m_vecMoveSpeed.x = 0.0f;
+ m_vecMoveSpeed.y = 0.0f;
+
+ if(m_fOrientation == INVALID_ORIENTATION){
+ m_fOrientation = GetForward().Heading();
+ }else{
+ // is this some inlined CPlaceable method?
+ CVector pos = GetPosition();
+ GetMatrix().RotateZ(m_fOrientation - GetForward().Heading());
+ GetPosition() = pos;
+ }
+ }
+
+ ProcessDelayedExplosion();
+}
+
+void
+CBoat::ProcessControlInputs(uint8 pad)
+{
+ m_nPadID = pad;
+ if(m_nPadID > 3)
+ m_nPadID = 3;
+
+ m_fBrake += (CPad::GetPad(pad)->GetBrake()/255.0f - m_fBrake)*0.1f;
+ m_fBrake = clamp(m_fBrake, 0.0f, 1.0f);
+
+ if(m_fBrake < 0.05f){
+ m_fBrake = 0.0f;
+ m_fAccelerate += (CPad::GetPad(pad)->GetAccelerate()/255.0f - m_fAccelerate)*0.1f;
+ m_fAccelerate = clamp(m_fAccelerate, 0.0f, 1.0f);
+ }else
+ m_fAccelerate = -m_fBrake*0.2f;
+
+ m_fSteeringLeftRight += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteeringLeftRight)*0.2f;
+ m_fSteeringLeftRight = clamp(m_fSteeringLeftRight, -1.0f, 1.0f);
+
+ float steeringSq = m_fSteeringLeftRight < 0.0f ? -SQR(m_fSteeringLeftRight) : SQR(m_fSteeringLeftRight);
+ m_fSteerAngle = pHandling->fSteeringLock * DEGTORAD(steeringSq);
+ m_fGasPedal = m_fAccelerate;
+}
+
+void
+CBoat::ApplyWaterResistance(void)
+{
+ float fwdSpeed = DotProduct(GetMoveSpeed(), GetForward());
+ // TODO: figure out how this works
+ float magic = (SQR(fwdSpeed) + 0.05f) * (0.001f * SQR(m_fVolumeUnderWater) * m_fMass) + 1.0f;
+ magic = Abs(magic);
+ // FRAMETIME
+ float fx = Pow(m_waterMoveDrag.x/magic, 0.5f*CTimer::GetTimeStep());
+ float fy = Pow(m_waterMoveDrag.y/magic, 0.5f*CTimer::GetTimeStep());
+ float fz = Pow(m_waterMoveDrag.z/magic, 0.5f*CTimer::GetTimeStep());
+
+ m_vecMoveSpeed = Multiply3x3(m_vecMoveSpeed, GetMatrix()); // invert - to local space
+ m_vecMoveSpeed.x *= fx;
+ m_vecMoveSpeed.y *= fy;
+ m_vecMoveSpeed.z *= fz;
+ float force = (fy - 1.0f) * m_vecMoveSpeed.y * m_fMass;
+ m_vecMoveSpeed = Multiply3x3(GetMatrix(), m_vecMoveSpeed); // back to world
+
+ ApplyTurnForce(force*GetForward(), -GetUp());
+
+ if(m_vecMoveSpeed.z > 0.0f)
+ m_vecMoveSpeed.z *= fz;
+ else
+ m_vecMoveSpeed.z *= (1.0f - fz)*0.5f + fz;
+}
+
+RwObject*
+GetBoatAtomicObjectCB(RwObject *object, void *data)
+{
+ RpAtomic *atomic = (RpAtomic*)object;
+ assert(RwObjectGetType(object) == rpATOMIC);
+ if(RpAtomicGetFlags(atomic) & rpATOMICRENDER)
+ *(RpAtomic**)data = atomic;
+ return object;
+
+
+}
+
+void
+CBoat::BlowUpCar(CEntity *culprit)
+{
+ RpAtomic *atomic;
+ RwFrame *frame;
+ RwMatrix *matrix;
+ CObject *obj;
+
+ if(!bCanBeDamaged)
+ return;
+
+ // explosion pushes vehicle up
+ m_vecMoveSpeed.z += 0.13f;
+ m_status = STATUS_WRECKED;
+ bRenderScorched = true;
+
+ m_fHealth = 0.0;
+ m_nBombTimer = 0;
+ TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z);
+
+ if(this == FindPlayerVehicle())
+ FindPlayerPed()->m_fHealth = 0.0f; // kill player
+ if(pDriver){
+ CDarkel::RegisterKillByPlayer(pDriver, WEAPONTYPE_EXPLOSION);
+ pDriver->SetDead();
+ pDriver->FlagToDestroyWhenNextProcessed();
+ }
+
+ bEngineOn = false;
+ bLightsOn = false;
+ ChangeLawEnforcerState(false);
+
+ CExplosion::AddExplosion(this, culprit, EXPLOSION_CAR, GetPosition(), 0);
+ if(m_aBoatNodes[BOAT_MOVING] == nil)
+ return;
+
+ // much like CAutomobile::SpawnFlyingComponent from here on
+
+ atomic = nil;
+ RwFrameForAllObjects(m_aBoatNodes[BOAT_MOVING], GetBoatAtomicObjectCB, &atomic);
+ if(atomic == nil)
+ return;
+
+ obj = new CObject();
+ if(obj == nil)
+ return;
+
+ obj->SetModelIndexNoCreate(MI_CAR_WHEEL);
+
+ // object needs base model
+ obj->RefModelInfo(GetModelIndex());
+
+ // create new atomic
+ matrix = RwFrameGetLTM(m_aBoatNodes[BOAT_MOVING]);
+ frame = RwFrameCreate();
+ atomic = RpAtomicClone(atomic);
+ *RwFrameGetMatrix(frame) = *matrix;
+ RpAtomicSetFrame(atomic, frame);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ obj->AttachToRwObject((RwObject*)atomic);
+
+ // init object
+ obj->m_fMass = 10.0f;
+ obj->m_fTurnMass = 25.0f;
+ obj->m_fAirResistance = 0.99f;
+ obj->m_fElasticity = 0.1f;
+ obj->m_fBuoyancy = obj->m_fMass*GRAVITY/0.75f;
+ obj->ObjectCreatedBy = TEMP_OBJECT;
+ obj->bIsStatic = false;
+ obj->bIsPickup = false;
+
+ // life time
+ CObject::nNoTempObjects++;
+ obj->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000;
+
+ obj->m_vecMoveSpeed = m_vecMoveSpeed;
+ if(GetUp().z > 0.0f)
+ obj->m_vecMoveSpeed.z = 0.3f;
+ else
+ obj->m_vecMoveSpeed.z = 0.0f;
+
+ obj->m_vecTurnSpeed = m_vecTurnSpeed*2.0f;
+ obj->m_vecTurnSpeed.x = 0.5f;
+
+ // push component away from boat
+ CVector dist = obj->GetPosition() - GetPosition();
+ dist.Normalise();
+ if(GetUp().z > 0.0f)
+ dist += GetUp();
+ obj->GetPosition() += GetUp();
+
+ CWorld::Add(obj);
+
+ atomic = nil;
+ RwFrameForAllObjects(m_aBoatNodes[BOAT_MOVING], GetBoatAtomicObjectCB, &atomic);
+ if(atomic)
+ RpAtomicSetFlags(atomic, 0);
+}
+
+RwIm3DVertex KeepWaterOutVertices[4];
RwImVertexIndex KeepWaterOutIndices[6];
void
@@ -102,8 +642,8 @@ CBoat::Render()
{
CMatrix matrix;
- if (m_aBoatNodes[1] != nil) {
- matrix.Attach(&m_aBoatNodes[1]->modelling);
+ if (m_aBoatNodes[BOAT_MOVING] != nil) {
+ matrix.Attach(RwFrameGetMatrix(m_aBoatNodes[BOAT_MOVING]));
CVector pos = matrix.GetPosition();
matrix.SetRotateZ(m_fMovingHiRotation);
@@ -111,7 +651,7 @@ CBoat::Render()
matrix.UpdateRW();
if (CVehicle::bWheelsOnlyCheat) {
- RpAtomicRenderMacro((RpAtomic*)GetFirstObject(m_aBoatNodes[1]));
+ RpAtomicRender((RpAtomic*)GetFirstObject(m_aBoatNodes[BOAT_MOVING]));
}
}
m_fMovingHiRotation += 0.05f;
@@ -130,47 +670,23 @@ CBoat::Render()
KeepWaterOutIndices[5] = 3;
switch (GetModelIndex()) {
case MI_SPEEDER:
- KeepWaterOutVertices[0].objVertex.x = -1.15f;
- KeepWaterOutVertices[0].objVertex.y = 3.61f;
- KeepWaterOutVertices[0].objVertex.z = 1.03f;
- KeepWaterOutVertices[1].objVertex.x = 1.15f;
- KeepWaterOutVertices[1].objVertex.y = 3.61f;
- KeepWaterOutVertices[1].objVertex.z = 1.03f;
- KeepWaterOutVertices[2].objVertex.x = -1.15f;
- KeepWaterOutVertices[2].objVertex.y = 0.06f;
- KeepWaterOutVertices[2].objVertex.z = 1.03f;
- KeepWaterOutVertices[3].objVertex.x = 1.15f;
- KeepWaterOutVertices[3].objVertex.y = 0.06f;
- KeepWaterOutVertices[3].objVertex.z = 1.03f;
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.15f, 3.61f, 1.03f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.15f, 3.61f, 1.03f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.15f, 0.06f, 1.03f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.15f, 0.06f, 1.03f);
break;
case MI_REEFER:
- KeepWaterOutVertices[2].objVertex.x = -1.9f;
- KeepWaterOutVertices[2].objVertex.y = 2.83f;
- KeepWaterOutVertices[2].objVertex.z = 1.0f;
- KeepWaterOutVertices[3].objVertex.x = 1.9f;
- KeepWaterOutVertices[3].objVertex.y = 2.83f;
- KeepWaterOutVertices[3].objVertex.z = 1.0f;
- KeepWaterOutVertices[0].objVertex.x = -1.66f;
- KeepWaterOutVertices[0].objVertex.y = -4.48f;
- KeepWaterOutVertices[0].objVertex.z = 0.83f;
- KeepWaterOutVertices[1].objVertex.x = 1.66f;
- KeepWaterOutVertices[1].objVertex.y = -4.48f;
- KeepWaterOutVertices[1].objVertex.z = 0.83f;
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.9f, 2.83f, 1.0f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.9f, 2.83f, 1.0f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.66f, -4.48f, 0.83f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.66f, -4.48f, 0.83f);
break;
case MI_PREDATOR:
default:
- KeepWaterOutVertices[0].objVertex.x = -1.45f;
- KeepWaterOutVertices[0].objVertex.y = 1.9f;
- KeepWaterOutVertices[0].objVertex.z = 0.96f;
- KeepWaterOutVertices[1].objVertex.x = 1.45f;
- KeepWaterOutVertices[1].objVertex.y = 1.9f;
- KeepWaterOutVertices[1].objVertex.z = 0.96f;
- KeepWaterOutVertices[2].objVertex.x = -1.45f;
- KeepWaterOutVertices[2].objVertex.y = -3.75f;
- KeepWaterOutVertices[2].objVertex.z = 0.96f;
- KeepWaterOutVertices[3].objVertex.x = 1.45f;
- KeepWaterOutVertices[3].objVertex.y = -3.75f;
- KeepWaterOutVertices[3].objVertex.z = 0.96f;
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[0], -1.45f, 1.9f, 0.96f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[1], 1.45f, 1.9f, 0.96f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[2], -1.45f, -3.75f, 0.96f);
+ RwIm3DVertexSetPos(&KeepWaterOutVertices[3], 1.45f, -3.75f, 0.96f);
break;
}
KeepWaterOutVertices[0].u = 0.0f;
@@ -258,10 +774,9 @@ CBoat::IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat)
void
CBoat::SetupModelNodes()
{
- m_aBoatNodes[0] = nil;
- m_aBoatNodes[1] = nil;
- m_aBoatNodes[2] = nil;
- m_aBoatNodes[3] = nil;
+ int i;
+ for(i = 0; i < ARRAY_SIZE(m_aBoatNodes); i++)
+ m_aBoatNodes[i] = nil;
CClumpModelInfo::FillFrameArray(GetClump(), m_aBoatNodes);
}
@@ -299,6 +814,43 @@ CBoat::FillBoatList()
}
}
+void
+CBoat::PruneWakeTrail(void)
+{
+ int i;
+
+ for(i = 0; i < ARRAY_SIZE(m_afWakePointLifeTime); i++){
+ if(m_afWakePointLifeTime[i] <= 0.0f)
+ break;
+ if(m_afWakePointLifeTime[i] <= CTimer::GetTimeStep()){
+ m_afWakePointLifeTime[i] = 0.0f;
+ break;
+ }
+ m_afWakePointLifeTime[i] -= CTimer::GetTimeStep();
+ }
+ m_nNumWakePoints = i;
+}
+
+void
+CBoat::AddWakePoint(CVector point)
+{
+ int i;
+ if(m_afWakePointLifeTime[0] > 0.0f){
+ if((CVector2D(GetPosition()) - m_avec2dWakePoints[0]).MagnitudeSqr() < SQR(1.0f)){
+ for(i = min(m_nNumWakePoints, ARRAY_SIZE(m_afWakePointLifeTime)-1); i != 0; i--){
+ m_avec2dWakePoints[i] = m_avec2dWakePoints[i-1];
+ m_afWakePointLifeTime[i] = m_afWakePointLifeTime[i-1];
+ }
+ m_avec2dWakePoints[0] = point;
+ m_afWakePointLifeTime[0] = 400.0f;
+ }
+ }else{
+ m_avec2dWakePoints[0] = point;
+ m_afWakePointLifeTime[0] = 400.0f;
+ m_nNumWakePoints = 1;
+ }
+}
+
#include <new>
class CBoat_ : public CBoat
@@ -315,4 +867,7 @@ STARTPATCHES
InjectHook(0x542370, CBoat::IsSectorAffectedByWake, PATCH_JUMP);
InjectHook(0x5424A0, CBoat::IsVertexAffectedByWake, PATCH_JUMP);
InjectHook(0x542250, CBoat::FillBoatList, PATCH_JUMP);
+ InjectHook(0x542140, &CBoat::AddWakePoint, PATCH_JUMP);
+ InjectHook(0x5420D0, &CBoat::PruneWakeTrail, PATCH_JUMP);
+ InjectHook(0x541A30, &CBoat::ApplyWaterResistance, PATCH_JUMP);
ENDPATCHES
diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h
index d3a2ac13..f4c6a747 100644
--- a/src/vehicles/Boat.h
+++ b/src/vehicles/Boat.h
@@ -2,47 +2,41 @@
#include "Vehicle.h"
+enum eBoatNodes
+{
+ BOAT_MOVING = 1,
+ BOAT_RUDDER,
+ BOAT_WINDSCREEN
+};
+
class CBoat : public CVehicle
{
public:
// 0x288
- float field_288;
- float field_28C;
- float field_290;
- float field_294;
- float field_298;
- float field_29C;
- float field_2A0;
- float field_2A4;
+ float m_fPropellerZ;
+ float m_fPropellerY;
+ CVector m_waterMoveDrag;
+ CVector m_waterTurnDrag;
float m_fMovingHiRotation;
int32 _unk0;
RwFrame *m_aBoatNodes[4];
- uint8 m_bBoatFlag1 : 1;
- uint8 m_bBoatFlag2 : 1;
- uint8 m_bBoatFlag3 : 1;
- uint8 m_bBoatFlag4 : 1;
- uint8 m_bBoatFlag5 : 1;
- uint8 m_bBoatFlag6 : 1;
- uint8 m_bBoatFlag7 : 1;
- uint8 m_bBoatFlag8 : 1;
+ uint8 bBoatInWater : 1;
+ uint8 bPropellerInWater : 1;
bool m_bIsAnchored;
- char _pad0[2];
- float field_2C4;
+ float m_fOrientation;
int32 _unk1;
- float field_2CC;
- CEntity *field_2D0;
+ float m_fDamage;
+ CEntity *m_pSetOnFireEntity;
bool _unk2;
- char _pad1[3];
float m_fAccelerate;
float m_fBrake;
float m_fSteeringLeftRight;
uint8 m_nPadID;
- char _pad2[3];
int32 _unk3;
- float m_fTurnForceZ;
- CVector m_vecMoveForce;
- float field_2FC;
- uint16 field_300;
+ float m_fVolumeUnderWater;
+ CVector m_vecBuoyancePoint;
+ float m_fPrevVolumeUnderWater;
+ int16 m_nDeltaVolumeUnderWater;
uint16 m_nNumWakePoints;
CVector2D m_avec2dWakePoints[32];
float m_afWakePointLifeTime[32];
@@ -59,7 +53,10 @@ public:
virtual bool IsComponentPresent(int32 component) { return true; }
virtual void BlowUpCar(CEntity *ent);
+ void ApplyWaterResistance(void);
void SetupModelNodes();
+ void PruneWakeTrail(void);
+ void AddWakePoint(CVector point);
static CBoat *(&apFrameWakeGeneratingBoats)[4];
diff --git a/src/control/CarGen.cpp b/src/vehicles/CarGen.cpp
index 49a96f50..c35005a1 100644
--- a/src/control/CarGen.cpp
+++ b/src/vehicles/CarGen.cpp
@@ -14,11 +14,11 @@
#include "Vehicle.h"
#include "World.h"
-uint8 &CTheCarGenerators::ProcessCounter = *(uint8*)0x95CDAF;
-uint32 &CTheCarGenerators::NumOfCarGenerators = *(uint32*)0x8E2C1C;
-CCarGenerator (&CTheCarGenerators::CarGeneratorArray)[NUM_CARGENS] = *(CCarGenerator(*)[NUM_CARGENS])*(uintptr*)0x87CB18;
-uint8 &CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter = *(uint8*)0x95CDC6;
-uint32 &CTheCarGenerators::CurrentActiveCount = *(uint32*)0x8F2C5C;
+uint8 CTheCarGenerators::ProcessCounter;
+uint32 CTheCarGenerators::NumOfCarGenerators;
+CCarGenerator CTheCarGenerators::CarGeneratorArray[NUM_CARGENS];
+uint8 CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter;
+uint32 CTheCarGenerators::CurrentActiveCount;
void CCarGenerator::SwitchOff()
{
@@ -187,62 +187,9 @@ bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer()
return DotProduct2D(direction, FindPlayerSpeed()) <= 0;
}
-void CCarGenerator::Save(uint8 *&buffer)
-{
- WriteSaveBuf(buffer, m_nModelIndex);
- WriteSaveBuf(buffer, m_vecPos);
- WriteSaveBuf(buffer, m_fAngle);
- WriteSaveBuf(buffer, m_nColor1);
- WriteSaveBuf(buffer, m_nColor2);
- WriteSaveBuf(buffer, m_bForceSpawn);
- WriteSaveBuf(buffer, m_nAlarm);
- WriteSaveBuf(buffer, m_nDoorlock);
- WriteSaveBuf(buffer, (uint8)0);
- WriteSaveBuf(buffer, m_nMinDelay);
- WriteSaveBuf(buffer, m_nMaxDelay);
- WriteSaveBuf(buffer, m_nTimer);
- WriteSaveBuf(buffer, m_nVehicleHandle);
- WriteSaveBuf(buffer, m_nUsesRemaining);
- WriteSaveBuf(buffer, m_bIsBlocking);
- WriteSaveBuf(buffer, (uint8)0);
- WriteSaveBuf(buffer, m_vecInf);
- WriteSaveBuf(buffer, m_vecSup);
- WriteSaveBuf(buffer, m_fSize);
-
- // or
- //WriteSaveBuf(buffer, *this);
-
-}
-
-void CCarGenerator::Load(uint8 *&buffer)
-{
- m_nModelIndex = ReadSaveBuf<uint32>(buffer);
- m_vecPos = ReadSaveBuf<CVector>(buffer);
- m_fAngle = ReadSaveBuf<float>(buffer);
- m_nColor1 = ReadSaveBuf<int16>(buffer);
- m_nColor2 = ReadSaveBuf<int16>(buffer);
- m_bForceSpawn = ReadSaveBuf<uint8>(buffer);
- m_nAlarm = ReadSaveBuf<uint8>(buffer);
- m_nDoorlock = ReadSaveBuf<uint8>(buffer);
- ReadSaveBuf<uint8>(buffer);
- m_nMinDelay = ReadSaveBuf<uint16>(buffer);
- m_nMaxDelay = ReadSaveBuf<uint16>(buffer);
- m_nTimer = ReadSaveBuf<uint32>(buffer);
- m_nVehicleHandle = ReadSaveBuf<int32>(buffer);
- m_nUsesRemaining = ReadSaveBuf<uint16>(buffer);
- m_bIsBlocking = ReadSaveBuf<bool>(buffer);
- ReadSaveBuf<uint8>(buffer);
- m_vecInf = ReadSaveBuf<CVector>(buffer);
- m_vecSup = ReadSaveBuf<CVector>(buffer);
- m_fSize = ReadSaveBuf<float>(buffer);
-
- // or
- //*this = ReadSaveBuf<CCarGenerator>(buffer);
-}
-
void CTheCarGenerators::Process()
{
- if (FindPlayerTrain() || CCutsceneMgr::IsRunning())
+ if (FindPlayerTrain() || CCutsceneMgr::IsCutsceneProcessing())
return;
if (++CTheCarGenerators::ProcessCounter == 4)
CTheCarGenerators::ProcessCounter = 0;
@@ -268,39 +215,38 @@ void CTheCarGenerators::Init()
void CTheCarGenerators::SaveAllCarGenerators(uint8 *buffer, uint32 *size)
{
- *size = 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE;
+ const uint32 nGeneralDataSize = sizeof(NumOfCarGenerators) + sizeof(CurrentActiveCount) + sizeof(ProcessCounter) + sizeof(GenerateEvenIfPlayerIsCloseCounter) + sizeof(int16);
+ *size = sizeof(int) + nGeneralDataSize + sizeof(uint32) + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE;
INITSAVEBUF
WriteSaveHeader(buffer, 'C','G','N','\0', *size - SAVE_HEADER_SIZE);
- WriteSaveBuf(buffer, 12); /* what is this? */
+ WriteSaveBuf(buffer, nGeneralDataSize);
WriteSaveBuf(buffer, NumOfCarGenerators);
WriteSaveBuf(buffer, CurrentActiveCount);
WriteSaveBuf(buffer, ProcessCounter);
WriteSaveBuf(buffer, GenerateEvenIfPlayerIsCloseCounter);
- WriteSaveBuf(buffer, (int16)0);
+ WriteSaveBuf(buffer, (int16)0); // alignment
WriteSaveBuf(buffer, sizeof(CarGeneratorArray));
- for (int i = 0; i < NUM_CARGENS; i++){
- CarGeneratorArray[i].Save(buffer);
- }
+ for (int i = 0; i < NUM_CARGENS; i++)
+ WriteSaveBuf(buffer, CarGeneratorArray[i]);
VALIDATESAVEBUF(*size)
}
void CTheCarGenerators::LoadAllCarGenerators(uint8* buffer, uint32 size)
{
+ const int32 nGeneralDataSize = sizeof(NumOfCarGenerators) + sizeof(CurrentActiveCount) + sizeof(ProcessCounter) + sizeof(GenerateEvenIfPlayerIsCloseCounter) + sizeof(int16);
Init();
INITSAVEBUF
- assert(size == 20 + sizeof(CarGeneratorArray) + SAVE_HEADER_SIZE);
CheckSaveHeader(buffer, 'C','G','N','\0', size - SAVE_HEADER_SIZE);
- ReadSaveBuf<uint32>(buffer);
+ assert(ReadSaveBuf<uint32>(buffer) == nGeneralDataSize);
NumOfCarGenerators = ReadSaveBuf<uint32>(buffer);
CurrentActiveCount = ReadSaveBuf<uint32>(buffer);
ProcessCounter = ReadSaveBuf<uint8>(buffer);
GenerateEvenIfPlayerIsCloseCounter = ReadSaveBuf<uint8>(buffer);
- ReadSaveBuf<int16>(buffer);
+ ReadSaveBuf<int16>(buffer); // alignment
assert(ReadSaveBuf<uint32>(buffer) == sizeof(CarGeneratorArray));
- for (int i = 0; i < NUM_CARGENS; i++) {
- CarGeneratorArray[i].Load(buffer);
- }
+ for (int i = 0; i < NUM_CARGENS; i++)
+ CarGeneratorArray[i] = ReadSaveBuf<CCarGenerator>(buffer);
VALIDATESAVEBUF(size)
}
diff --git a/src/control/CarGen.h b/src/vehicles/CarGen.h
index 75acdd56..9d645318 100644
--- a/src/control/CarGen.h
+++ b/src/vehicles/CarGen.h
@@ -34,19 +34,17 @@ public:
void Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay);
bool CheckForBlockage();
bool CheckIfWithinRangeOfAnyPlayer();
- void Save(uint8*&);
- void Load(uint8*&);
void SetUsesRemaining(uint16 uses) { m_nUsesRemaining = uses; }
};
class CTheCarGenerators
{
public:
- static uint8 &ProcessCounter;
- static uint32 &NumOfCarGenerators;
- static CCarGenerator (&CarGeneratorArray)[NUM_CARGENS];
- static uint8 &GenerateEvenIfPlayerIsCloseCounter;
- static uint32 &CurrentActiveCount;
+ static uint8 ProcessCounter;
+ static uint32 NumOfCarGenerators;
+ static CCarGenerator CarGeneratorArray[NUM_CARGENS];
+ static uint8 GenerateEvenIfPlayerIsCloseCounter;
+ static uint32 CurrentActiveCount;
static void Process();
static int32 CreateCarGenerator(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay);
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
new file mode 100644
index 00000000..dbc3c340
--- /dev/null
+++ b/src/vehicles/Cranes.cpp
@@ -0,0 +1,671 @@
+#include "common.h"
+#include "patcher.h"
+#include "Cranes.h"
+
+#include "Camera.h"
+#include "DMAudio.h"
+#include "Garages.h"
+#include "General.h"
+#include "Entity.h"
+#include "ModelIndices.h"
+#include "Replay.h"
+#include "Object.h"
+#include "World.h"
+
+#define MAX_DISTANCE_TO_FIND_CRANE (10.0f)
+#define CRANE_UPDATE_RADIUS (300.0f)
+#define CRANE_MOVEMENT_PROCESSING_RADIUS (150.0f)
+#define CRUSHER_Z (-0.951f)
+#define MILITARY_Z (10.7862f)
+#define DISTANCE_FROM_PLAYER_TO_REMOVE_VEHICLE (5.0f)
+#define DISTANCE_FROM_HOOK_TO_VEHICLE_TO_COLLECT (0.5f)
+#define CAR_REWARD_MILITARY_CRANE (1500)
+#define CAR_MOVING_SPEED_THRESHOLD (0.01f)
+#define CRANE_SLOWDOWN_MULTIPLIER (0.3f)
+
+#define OSCILLATION_SPEED (0.002f)
+#define CAR_ROTATION_SPEED (0.0035f)
+#define CRANE_MOVEMENT_SPEED (0.001f)
+#define HOOK_ANGLE_MOVEMENT_SPEED (0.004f)
+#define HOOK_OFFSET_MOVEMENT_SPEED (0.1f)
+#define HOOK_HEIGHT_MOVEMENT_SPEED (0.06f)
+
+#define MESSAGE_SHOW_DURATION (4000)
+
+#define MAX_DISTANCE (99999.9f)
+#define MIN_VALID_POSITION (-10000.0f)
+#define DEFAULT_OFFSET (20.0f)
+
+uint32 TimerForCamInterpolation;
+
+uint32 CCranes::CarsCollectedMilitaryCrane;
+int32 CCranes::NumCranes;
+CCrane CCranes::aCranes[NUM_CRANES];
+
+void CCranes::InitCranes(void)
+{
+ CarsCollectedMilitaryCrane = 0;
+ NumCranes = 0;
+ for (int i = 0; i < NUMSECTORS_X; i++) {
+ for (int j = 0; j < NUMSECTORS_Y; j++) {
+ for (CPtrNode* pNode = CWorld::GetSector(i, j)->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_2 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_3 == pEntity->GetModelIndex())
+ AddThisOneCrane(pEntity);
+ }
+ }
+ }
+ for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL).first; pNode; pNode = pNode->next) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_2 == pEntity->GetModelIndex() ||
+ MODELID_CRANE_3 == pEntity->GetModelIndex())
+ AddThisOneCrane(pEntity);
+ }
+}
+
+void CCranes::AddThisOneCrane(CEntity* pEntity)
+{
+ pEntity->GetMatrix().ResetOrientation();
+ if (NumCranes >= NUM_CRANES)
+ return;
+ CCrane* pCrane = &aCranes[NumCranes];
+ pCrane->Init();
+ pCrane->m_pCraneEntity = (CBuilding*)pEntity;
+ pCrane->m_nCraneStatus = CCrane::NONE;
+ pCrane->m_fHookAngle = NumCranes; // lol wtf
+ while (pCrane->m_fHookAngle > TWOPI)
+ pCrane->m_fHookAngle -= TWOPI;
+ pCrane->m_fHookOffset = DEFAULT_OFFSET;
+ pCrane->m_fHookHeight = DEFAULT_OFFSET;
+ pCrane->m_nTimeForNextCheck = 0;
+ pCrane->m_nCraneState = CCrane::IDLE;
+ pCrane->m_bWasMilitaryCrane = false;
+ pCrane->m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[NumCranes]);
+ if (pCrane->m_nAudioEntity >= 0)
+ DMAudio.SetEntityStatus(pCrane->m_nAudioEntity, 1);
+ pCrane->m_bIsTop = (MODELID_CRANE_1 != pEntity->GetModelIndex());
+ // Is this used to avoid military crane?
+ if (pCrane->m_bIsTop || pEntity->GetPosition().y > 0.0f) {
+ CObject* pHook = new CObject(MI_MAGNET, false);
+ pHook->ObjectCreatedBy = MISSION_OBJECT;
+ pHook->bUsesCollision = false;
+ pHook->bExplosionProof = true;
+ pHook->bAffectedByGravity = false;
+ pCrane->m_pHook = pHook;
+ pCrane->CalcHookCoordinates(&pCrane->m_vecHookCurPos.x, &pCrane->m_vecHookCurPos.y, &pCrane->m_vecHookCurPos.z);
+ pCrane->SetHookMatrix();
+ }
+ else
+ pCrane->m_pHook = nil;
+ NumCranes++;
+}
+
+void CCranes::ActivateCrane(float fInfX, float fSupX, float fInfY, float fSupY, float fDropOffX, float fDropOffY, float fDropOffZ, float fHeading, bool bIsCrusher, bool bIsMilitary, float fPosX, float fPosY)
+{
+ float fMinDistance = MAX_DISTANCE;
+ float X = fPosX, Y = fPosY;
+ if (X <= MIN_VALID_POSITION || Y <= MIN_VALID_POSITION) {
+ X = fDropOffX;
+ Y = fDropOffY;
+ }
+ int index = 0;
+ for (int i = 0; i < NumCranes; i++) {
+ float distance = (CVector2D(X, Y) - aCranes[i].m_pCraneEntity->GetPosition()).Magnitude();
+ if (distance < fMinDistance && distance < MAX_DISTANCE_TO_FIND_CRANE) {
+ fMinDistance = distance;
+ index = i;
+ }
+ }
+#ifdef FIX_BUGS // classic
+ if (fMinDistance == MAX_DISTANCE)
+ return;
+#endif
+ CCrane* pCrane = &aCranes[index];
+ pCrane->m_fPickupX1 = fInfX;
+ pCrane->m_fPickupX2 = fSupX;
+ pCrane->m_fPickupY1 = fInfY;
+ pCrane->m_fPickupY2 = fSupY;
+ pCrane->m_vecDropoffTarget.x = fDropOffX;
+ pCrane->m_vecDropoffTarget.y = fDropOffY;
+ pCrane->m_vecDropoffTarget.z = fDropOffZ;
+ pCrane->m_nCraneStatus = CCrane::ACTIVATED;
+ pCrane->m_pVehiclePickedUp = nil;
+ pCrane->m_nVehiclesCollected = 0;
+ pCrane->m_fDropoffHeading = fHeading;
+ pCrane->m_bIsCrusher = bIsCrusher;
+ pCrane->m_bIsMilitaryCrane = bIsMilitary;
+ bool military = true;
+ if (!bIsMilitary && !pCrane->m_bWasMilitaryCrane)
+ military = false;
+ pCrane->m_bWasMilitaryCrane = military;
+ pCrane->m_nTimeForNextCheck = 0;
+ pCrane->m_nCraneState = CCrane::IDLE;
+ float Z;
+ if (bIsCrusher)
+ Z = CRUSHER_Z;
+ else if (bIsMilitary)
+ Z = MILITARY_Z;
+ else
+ Z = CWorld::FindGroundZForCoord((fInfX + fSupX) / 2, (fInfY + fSupY) / 2);
+ pCrane->FindParametersForTarget((fInfX + fSupX) / 2, (fInfY + fSupY) / 2, Z, &pCrane->m_fPickupAngle, &pCrane->m_fPickupDistance, &pCrane->m_fPickupHeight);
+ pCrane->FindParametersForTarget(fDropOffX, fDropOffY, fDropOffZ, &pCrane->m_fDropoffAngle, &pCrane->m_fDropoffDistance, &pCrane->m_fDropoffHeight);
+}
+
+void CCranes::DeActivateCrane(float X, float Y)
+{
+ float fMinDistance = MAX_DISTANCE;
+ int index = 0;
+ for (int i = 0; i < NumCranes; i++) {
+ float distance = (CVector2D(X, Y) - aCranes[i].m_pCraneEntity->GetPosition()).Magnitude();
+ if (distance < fMinDistance && distance < MAX_DISTANCE_TO_FIND_CRANE) {
+ fMinDistance = distance;
+ index = i;
+ }
+ }
+#ifdef FIX_BUGS // classic
+ if (fMinDistance == MAX_DISTANCE)
+ return;
+#endif
+ aCranes[index].m_nCraneStatus = CCrane::DEACTIVATED;
+ aCranes[index].m_nCraneState = CCrane::IDLE;
+}
+
+bool CCranes::IsThisCarPickedUp(float X, float Y, CVehicle* pVehicle)
+{
+ int index = 0;
+ bool result = false;
+ for (int i = 0; i < NumCranes; i++) {
+ float distance = (CVector2D(X, Y) - aCranes[i].m_pCraneEntity->GetPosition()).Magnitude();
+ if (distance < MAX_DISTANCE_TO_FIND_CRANE && aCranes[i].m_pVehiclePickedUp == pVehicle) {
+ if (aCranes[i].m_nCraneStatus == CCrane::LIFTING_TARGET || aCranes[i].m_nCraneStatus == CCrane::ROTATING_TARGET)
+ result = true;
+ }
+ }
+ return true;
+}
+
+void CCranes::UpdateCranes(void)
+{
+ for (int i = 0; i < NumCranes; i++) {
+ if (aCranes[i].m_bIsTop || aCranes[i].m_bIsCrusher ||
+ (TheCamera.GetPosition().x + CRANE_UPDATE_RADIUS > aCranes[i].m_pCraneEntity->GetPosition().x &&
+ TheCamera.GetPosition().x - CRANE_UPDATE_RADIUS < aCranes[i].m_pCraneEntity->GetPosition().x &&
+ TheCamera.GetPosition().y + CRANE_UPDATE_RADIUS > aCranes[i].m_pCraneEntity->GetPosition().y &&
+ TheCamera.GetPosition().y + CRANE_UPDATE_RADIUS < aCranes[i].m_pCraneEntity->GetPosition().y))
+ aCranes[i].Update();
+ }
+}
+
+void CCrane::Update(void)
+{
+ if (CReplay::IsPlayingBack())
+ return;
+ if (((m_nCraneStatus == ACTIVATED || m_nCraneStatus == DEACTIVATED) &&
+ Abs(TheCamera.GetGameCamPosition().x - m_pCraneEntity->GetPosition().x) < CRANE_MOVEMENT_PROCESSING_RADIUS &&
+ Abs(TheCamera.GetGameCamPosition().y - m_pCraneEntity->GetPosition().y) < CRANE_MOVEMENT_PROCESSING_RADIUS) ||
+ m_nCraneState != IDLE) {
+ switch (m_nCraneState) {
+ case IDLE:
+ if (GoTowardsTarget(m_fPickupAngle, m_fPickupDistance, GetHeightToPickup()) &&
+ CTimer::GetTimeInMilliseconds() > m_nTimeForNextCheck) {
+ CWorld::AdvanceCurrentScanCode();
+#ifdef FIX_BUGS
+ int xstart = max(0, CWorld::GetSectorIndexX(m_fPickupX1));
+ int xend = min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fPickupX2));
+ int ystart = max(0, CWorld::GetSectorIndexY(m_fPickupY1));
+ int yend = min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fPickupY2));
+#else
+ int xstart = CWorld::GetSectorIndexX(m_fPickupX1);
+ int xend = CWorld::GetSectorIndexX(m_fPickupX2);
+ int ystart = CWorld::GetSectorIndexY(m_fPickupY1);
+ int yend = CWorld::GetSectorIndexY(m_fPickupY1);
+#endif
+ assert(xstart <= xend);
+ assert(ystart <= yend);
+ for (int i = xstart; i <= xend; i++) {
+ for (int j = ystart; j <= yend; j++) {
+ FindCarInSectorList(&CWorld::GetSector(i, j)->m_lists[ENTITYLIST_VEHICLES]);
+ FindCarInSectorList(&CWorld::GetSector(i, j)->m_lists[ENTITYLIST_VEHICLES_OVERLAP]);
+ }
+ }
+ }
+ break;
+ case GOING_TOWARDS_TARGET:
+ if (m_pVehiclePickedUp){
+ if (m_pVehiclePickedUp->GetPosition().x < m_fPickupX1 ||
+ m_pVehiclePickedUp->GetPosition().x > m_fPickupX2 ||
+ m_pVehiclePickedUp->GetPosition().y < m_fPickupY1 ||
+ m_pVehiclePickedUp->GetPosition().y > m_fPickupY2 ||
+ m_pVehiclePickedUp->pDriver ||
+ Abs(m_pVehiclePickedUp->GetMoveSpeed().x) > CAR_MOVING_SPEED_THRESHOLD ||
+ Abs(m_pVehiclePickedUp->GetMoveSpeed().y) > CAR_MOVING_SPEED_THRESHOLD ||
+ Abs(m_pVehiclePickedUp->GetMoveSpeed().z) > CAR_MOVING_SPEED_THRESHOLD ||
+ FindPlayerPed()->GetPedState() == PED_ENTER_CAR && // TODO: fix carjack bug
+ FindPlayerPed()->m_pSeekTarget == m_pVehiclePickedUp) {
+ m_pVehiclePickedUp = nil;
+ m_nCraneState = IDLE;
+ }
+ else {
+ float fAngle, fOffset, fHeight;
+ FindParametersForTarget(
+ m_pVehiclePickedUp->GetPosition().x,
+ m_pVehiclePickedUp->GetPosition().y,
+ m_pVehiclePickedUp->GetPosition().z + m_pVehiclePickedUp->GetColModel()->boundingBox.max.z,
+ &fAngle, &fOffset, &fHeight);
+ if (GoTowardsTarget(fAngle, fOffset, fHeight)) {
+ CVector distance = m_pVehiclePickedUp->GetPosition() - m_vecHookCurPos;
+ distance.z += m_pVehiclePickedUp->GetColModel()->boundingBox.max.z;
+ if (distance.MagnitudeSqr() < SQR(DISTANCE_FROM_HOOK_TO_VEHICLE_TO_COLLECT)) {
+ m_nCraneState = GOING_TOWARDS_TARGET_ONLY_HEIGHT;
+ m_vecHookVelocity *= 0.4f;
+ m_pVehiclePickedUp->bLightsOn = false;
+ m_pVehiclePickedUp->bUsesCollision = false;
+ if (m_bIsCrusher)
+ m_pVehiclePickedUp->bCollisionProof = true;
+ DMAudio.PlayOneShot(m_nAudioEntity, SOUND_CRANE_PICKUP, 0.0f);
+ }
+ }
+ }
+ }
+ else
+ m_nCraneState = IDLE;
+ break;
+ case LIFTING_TARGET:
+ RotateCarriedCarProperly();
+ if (GoTowardsTarget(m_fDropoffAngle, m_fDropoffDistance, GetHeightToDropoff(), CRANE_SLOWDOWN_MULTIPLIER))
+ m_nCraneState = ROTATING_TARGET;
+ if (!m_pVehiclePickedUp || m_pVehiclePickedUp->pDriver) {
+ m_pVehiclePickedUp = nil;
+ m_nCraneState = IDLE;
+ }
+ break;
+ case GOING_TOWARDS_TARGET_ONLY_HEIGHT:
+ RotateCarriedCarProperly();
+ if (GoTowardsHeightTarget(GetHeightToPickupHeight(), CRANE_SLOWDOWN_MULTIPLIER))
+ m_nCraneState = LIFTING_TARGET;
+ TimerForCamInterpolation = CTimer::GetTimeInMilliseconds();
+ if (!m_pVehiclePickedUp || m_pVehiclePickedUp->pDriver) {
+ m_pVehiclePickedUp = nil;
+ m_nCraneState = IDLE;
+ }
+ break;
+ case ROTATING_TARGET:
+ {
+ bool bRotateFinished = RotateCarriedCarProperly();
+ bool bMovementFinished = GoTowardsTarget(m_fDropoffAngle, m_fDropoffDistance, m_fDropoffHeight, 0.3f);
+ if (bMovementFinished && bRotateFinished) {
+ float fDistanceFromPlayer = m_pVehiclePickedUp ? ((CVector2D)FindPlayerCoors() - (CVector2D)m_pVehiclePickedUp->GetPosition()).Magnitude() : 0.0f;
+ if (fDistanceFromPlayer > DISTANCE_FROM_PLAYER_TO_REMOVE_VEHICLE || !m_bWasMilitaryCrane) {
+ m_nCraneState = DROPPING_TARGET;
+ if (m_pVehiclePickedUp) {
+ m_pVehiclePickedUp->bUsesCollision = true;
+ m_pVehiclePickedUp->m_nStaticFrames = 0;
+ ++m_nVehiclesCollected;
+ if (m_bIsMilitaryCrane) {
+ CCranes::RegisterCarForMilitaryCrane(m_pVehiclePickedUp->GetModelIndex());
+ if (!CCranes::HaveAllCarsBeenCollectedByMilitaryCrane()) {
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney += CAR_REWARD_MILITARY_CRANE;
+ CGarages::TriggerMessage("GA_10", CAR_REWARD_MILITARY_CRANE, MESSAGE_SHOW_DURATION, -1);
+ }
+ CWorld::Remove(m_pVehiclePickedUp);
+ delete m_pVehiclePickedUp;
+ }
+ }
+ m_pVehiclePickedUp = nil;
+ }
+ }
+ break;
+ }
+ case DROPPING_TARGET:
+ if (GoTowardsTarget(m_fDropoffAngle, m_fDropoffDistance, GetHeightToDropoffHeight(), CRANE_SLOWDOWN_MULTIPLIER)) {
+ m_nCraneState = IDLE;
+ m_nTimeForNextCheck = CTimer::GetTimeInMilliseconds() + 10000;
+ }
+ break;
+ default:
+ break;
+ }
+ CVector vecHook;
+ CalcHookCoordinates(&vecHook.x, &vecHook.y, &vecHook.z);
+ m_vecHookVelocity += ((CVector2D)vecHook - (CVector2D)m_vecHookCurPos) * CTimer::GetTimeStep() * CRANE_MOVEMENT_SPEED;
+ m_vecHookVelocity *= Pow(0.98f, CTimer::GetTimeStep());
+ m_vecHookCurPos.x += m_vecHookVelocity.x * CTimer::GetTimeStep();
+ m_vecHookCurPos.y += m_vecHookVelocity.y * CTimer::GetTimeStep();
+ m_vecHookCurPos.z = vecHook.z;
+ switch (m_nCraneState) {
+ case LIFTING_TARGET:
+ case GOING_TOWARDS_TARGET_ONLY_HEIGHT:
+ case ROTATING_TARGET:
+ if (m_pVehiclePickedUp) {
+ m_pVehiclePickedUp->GetPosition() = CVector(m_vecHookCurPos.x, m_vecHookCurPos.y, m_vecHookCurPos.z - m_pVehiclePickedUp->GetColModel()->boundingBox.max.z);
+ m_pVehiclePickedUp->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ CVector up(vecHook.x - m_vecHookCurPos.x, vecHook.y - m_vecHookCurPos.y, 20.0f);
+ up.Normalise();
+ m_pVehiclePickedUp->GetRight() = CrossProduct(m_pVehiclePickedUp->GetForward(), up);
+ m_pVehiclePickedUp->GetForward() = CrossProduct(up, m_pVehiclePickedUp->GetRight());
+ m_pVehiclePickedUp->GetUp() = up;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else {
+ int16 rnd = (m_pCraneEntity->m_randomSeed + (CTimer::GetTimeInMilliseconds() >> 11)) & 0xF;
+ // 16 options, lasting 2048 ms each
+ // a bit awkward: why there are 4 periods for -= and 6 for +=? is it a bug?
+ if (rnd < 4) {
+ m_fHookAngle -= OSCILLATION_SPEED * CTimer::GetTimeStep();
+ if (m_fHookAngle < 0.0f)
+ m_fHookAngle += TWOPI;
+ }
+ else if (rnd > 5 && rnd < 12) {
+ m_fHookAngle += OSCILLATION_SPEED * CTimer::GetTimeStep();
+ if (m_fHookAngle > TWOPI)
+ m_fHookAngle -= TWOPI;
+ }
+ CalcHookCoordinates(&m_vecHookCurPos.x, &m_vecHookCurPos.y, &m_vecHookCurPos.z);
+ m_vecHookVelocity.x = m_vecHookVelocity.y = 0.0f;
+ }
+ float fCos = Cos(m_fHookAngle);
+ float fSin = Sin(m_fHookAngle);
+ m_pCraneEntity->GetRight().x = fCos;
+ m_pCraneEntity->GetForward().y = fCos;
+ m_pCraneEntity->GetRight().y = fSin;
+ m_pCraneEntity->GetForward().x = -fSin;
+ m_pCraneEntity->GetMatrix().UpdateRW();
+ m_pCraneEntity->UpdateRwFrame();
+ SetHookMatrix();
+}
+
+bool CCrane::RotateCarriedCarProperly()
+{
+ if (m_fDropoffHeading <= 0.0f)
+ return true;
+ if (!m_pVehiclePickedUp)
+ return true;
+ float fAngleDelta = m_fDropoffHeading - CGeneral::GetATanOfXY(m_pVehiclePickedUp->GetForward().x, m_pVehiclePickedUp->GetForward().y);
+ while (fAngleDelta < -HALFPI)
+ fAngleDelta += PI;
+ while (fAngleDelta > HALFPI)
+ fAngleDelta -= PI;
+ float fDeltaThisFrame = CAR_ROTATION_SPEED * CTimer::GetTimeStep();
+ if (Abs(fAngleDelta) <= fDeltaThisFrame) // no rotation is actually applied?
+ return true;
+ m_pVehiclePickedUp->GetMatrix().RotateZ(Abs(fDeltaThisFrame));
+ return false;
+}
+
+void CCrane::FindCarInSectorList(CPtrList* pList)
+{
+ CPtrNode* node;
+ for (node = pList->first; node; node = node->next) {
+ CVehicle* pVehicle = (CVehicle*)node->item;
+ if (pVehicle->m_scanCode == CWorld::GetCurrentScanCode())
+ continue;
+ pVehicle->m_scanCode = CWorld::GetCurrentScanCode();
+ if (pVehicle->GetPosition().x < m_fPickupX1 || pVehicle->GetPosition().x > m_fPickupX2 ||
+ pVehicle->GetPosition().y < m_fPickupY1 || pVehicle->GetPosition().y > m_fPickupY2)
+ continue;
+ if (pVehicle->pDriver)
+ continue;
+ if (Abs(pVehicle->GetMoveSpeed().x) >= CAR_MOVING_SPEED_THRESHOLD ||
+ Abs(pVehicle->GetMoveSpeed().y) >= CAR_MOVING_SPEED_THRESHOLD ||
+ Abs(pVehicle->GetMoveSpeed().z) >= CAR_MOVING_SPEED_THRESHOLD)
+ continue;
+ if (!pVehicle->IsCar() || pVehicle->m_status == STATUS_WRECKED || pVehicle->m_fHealth < 250.0f)
+ continue;
+ if (!DoesCranePickUpThisCarType(pVehicle->GetModelIndex()) ||
+ m_bIsMilitaryCrane && CCranes::DoesMilitaryCraneHaveThisOneAlready(pVehicle->GetModelIndex())) {
+ if (!pVehicle->bCraneMessageDone) {
+ pVehicle->bCraneMessageDone = true;
+ if (!m_bIsMilitaryCrane)
+ CGarages::TriggerMessage("CR_1", -1, MESSAGE_SHOW_DURATION, -1); // Crane cannot lift this vehicle.
+ else if (DoesCranePickUpThisCarType(pVehicle->GetModelIndex()))
+ CGarages::TriggerMessage("GA_20", -1, MESSAGE_SHOW_DURATION, -1); // We got more of these than we can shift. Sorry man, no deal.
+ else
+ CGarages::TriggerMessage("GA_19", -1, MESSAGE_SHOW_DURATION, -1); // We're not interested in that model.
+ }
+ }
+ else {
+ m_pVehiclePickedUp = pVehicle;
+ pVehicle->RegisterReference((CEntity**)&m_pVehiclePickedUp);
+ m_nCraneState = GOING_TOWARDS_TARGET;
+ }
+ }
+}
+
+bool CCrane::DoesCranePickUpThisCarType(uint32 mi)
+{
+ if (m_bIsCrusher) {
+ return mi != MI_FIRETRUCK &&
+ mi != MI_TRASH &&
+#ifndef FIX_BUGS // why
+ mi != MI_BLISTA &&
+#endif
+ mi != MI_SECURICA &&
+ mi != MI_BUS &&
+ mi != MI_DODO &&
+ mi != MI_RHINO;
+ }
+ if (m_bIsMilitaryCrane) {
+ return mi == MI_FIRETRUCK ||
+ mi == MI_AMBULAN ||
+ mi == MI_ENFORCER ||
+ mi == MI_FBICAR ||
+ mi == MI_RHINO ||
+ mi == MI_BARRACKS ||
+ mi == MI_POLICE;
+ }
+ return true;
+}
+
+bool CCranes::DoesMilitaryCraneHaveThisOneAlready(uint32 mi)
+{
+ switch (mi) {
+ case MI_FIRETRUCK: return (CarsCollectedMilitaryCrane & 1);
+ case MI_AMBULAN: return (CarsCollectedMilitaryCrane & 2);
+ case MI_ENFORCER: return (CarsCollectedMilitaryCrane & 4);
+ case MI_FBICAR: return (CarsCollectedMilitaryCrane & 8);
+ case MI_RHINO: return (CarsCollectedMilitaryCrane & 0x10);
+ case MI_BARRACKS: return (CarsCollectedMilitaryCrane & 0x20);
+ case MI_POLICE: return (CarsCollectedMilitaryCrane & 0x40);
+ default: break;
+ }
+ return false;
+}
+
+void CCranes::RegisterCarForMilitaryCrane(uint32 mi)
+{
+ switch (mi) {
+ case MI_FIRETRUCK: CarsCollectedMilitaryCrane |= 1; break;
+ case MI_AMBULAN: CarsCollectedMilitaryCrane |= 2; break;
+ case MI_ENFORCER: CarsCollectedMilitaryCrane |= 4; break;
+ case MI_FBICAR: CarsCollectedMilitaryCrane |= 8; break;
+ case MI_RHINO: CarsCollectedMilitaryCrane |= 0x10; break;
+ case MI_BARRACKS: CarsCollectedMilitaryCrane |= 0x20; break;
+ case MI_POLICE: CarsCollectedMilitaryCrane |= 0x40; break;
+ default: break;
+ }
+}
+
+bool CCranes::HaveAllCarsBeenCollectedByMilitaryCrane()
+{
+ return (CarsCollectedMilitaryCrane & 0x7F) == 0x7F;
+}
+
+bool CCrane::GoTowardsTarget(float fAngleToTarget, float fDistanceToTarget, float fTargetHeight, float fSpeedMultiplier)
+{
+ bool bAngleMovementFinished, bOffsetMovementFinished, bHeightMovementFinished;
+ float fHookAngleDelta = fAngleToTarget - m_fHookAngle;
+ while (fHookAngleDelta > PI)
+ fHookAngleDelta -= TWOPI;
+ while (fHookAngleDelta < -PI)
+ fHookAngleDelta += TWOPI;
+ float fHookAngleChangeThisFrame = fSpeedMultiplier * CTimer::GetTimeStep() * HOOK_ANGLE_MOVEMENT_SPEED;
+ if (Abs(fHookAngleDelta) < fHookAngleChangeThisFrame) {
+ m_fHookAngle = fAngleToTarget;
+ bAngleMovementFinished = true;
+ } else {
+ if (fHookAngleDelta < 0.0f) {
+ m_fHookAngle -= fHookAngleChangeThisFrame;
+ if (m_fHookAngle < 0.0f)
+ m_fHookAngle += TWOPI;
+ }
+ else {
+ m_fHookAngle += fHookAngleChangeThisFrame;
+ if (m_fHookAngle > TWOPI)
+ m_fHookAngle -= TWOPI;
+ }
+ bAngleMovementFinished = false;
+ }
+ float fHookOffsetDelta = fDistanceToTarget - m_fHookOffset;
+ float fHookOffsetChangeThisFrame = fSpeedMultiplier * CTimer::GetTimeStep() * HOOK_OFFSET_MOVEMENT_SPEED;
+ if (Abs(fHookOffsetDelta) < fHookOffsetChangeThisFrame) {
+ m_fHookOffset = fDistanceToTarget;
+ bOffsetMovementFinished = true;
+ } else {
+ if (fHookOffsetDelta < 0.0f)
+ m_fHookOffset -= fHookOffsetChangeThisFrame;
+ else
+ m_fHookOffset += fHookOffsetChangeThisFrame;
+ bOffsetMovementFinished = false;
+ }
+ float fHookHeightDelta = fTargetHeight - m_fHookHeight;
+ float fHookHeightChangeThisFrame = fSpeedMultiplier * CTimer::GetTimeStep() * HOOK_HEIGHT_MOVEMENT_SPEED;
+ if (Abs(fHookHeightDelta) < fHookHeightChangeThisFrame) {
+ m_fHookHeight = fTargetHeight;
+ bHeightMovementFinished = true;
+ } else {
+ if (fHookHeightDelta < 0.0f)
+ m_fHookHeight -= fHookHeightChangeThisFrame;
+ else
+ m_fHookHeight += fHookHeightChangeThisFrame;
+ bHeightMovementFinished = false;
+ }
+ return bAngleMovementFinished && bOffsetMovementFinished && bHeightMovementFinished;
+}
+
+bool CCrane::GoTowardsHeightTarget(float fTargetHeight, float fSpeedMultiplier)
+{
+ bool bHeightMovementFinished;
+ float fHookHeightDelta = fTargetHeight - m_fHookHeight;
+ float fHookHeightChangeThisFrame = fSpeedMultiplier * CTimer::GetTimeStep() * HOOK_HEIGHT_MOVEMENT_SPEED;
+ if (Abs(fHookHeightDelta) < fHookHeightChangeThisFrame) {
+ m_fHookHeight = fTargetHeight;
+ bHeightMovementFinished = true;
+ } else {
+ if (fHookHeightDelta < 0.0f)
+ m_fHookHeight -= fHookHeightChangeThisFrame;
+ else
+ m_fHookHeight += fHookHeightChangeThisFrame;
+ bHeightMovementFinished = false;
+ }
+ return bHeightMovementFinished;
+}
+
+void CCrane::FindParametersForTarget(float X, float Y, float Z, float* pAngle, float* pDistance, float* pHeight)
+{
+ *pAngle = CGeneral::GetATanOfXY(X - m_pCraneEntity->GetPosition().x, Y - m_pCraneEntity->GetPosition().y);
+ *pDistance = ((CVector2D(X, Y) - (CVector2D)m_pCraneEntity->GetPosition())).Magnitude();
+ *pHeight = Z;
+}
+
+void CCrane::CalcHookCoordinates(float* pX, float* pY, float* pZ)
+{
+ *pX = Cos(m_fHookAngle) * m_fHookOffset + m_pCraneEntity->GetPosition().x;
+ *pY = Sin(m_fHookAngle) * m_fHookOffset + m_pCraneEntity->GetPosition().y;
+ *pZ = m_fHookHeight;
+}
+
+void CCrane::SetHookMatrix()
+{
+ if (m_pHook == nil)
+ return;
+ m_pHook->GetPosition() = m_vecHookCurPos;
+ CVector up(m_vecHookInitPos.x - m_vecHookCurPos.x, m_vecHookInitPos.y - m_vecHookCurPos.y, 20.0f);
+ up.Normalise();
+ m_pHook->GetRight() = CrossProduct(CVector(0.0f, 1.0f, 0.0f), up);
+ m_pHook->GetForward() = CrossProduct(up, m_pHook->GetRight());
+ m_pHook->GetUp() = up;
+ m_pHook->SetOrientation(0.0f, 0.0f, -HALFPI);
+ m_pHook->GetMatrix().UpdateRW();
+ m_pHook->UpdateRwFrame();
+ CWorld::Remove(m_pHook);
+ CWorld::Add(m_pHook);
+}
+
+bool CCranes::IsThisCarBeingCarriedByAnyCrane(CVehicle* pVehicle)
+{
+ for (int i = 0; i < NumCranes; i++) {
+ if (pVehicle == aCranes[i].m_pVehiclePickedUp) {
+ switch (aCranes[i].m_nCraneState) {
+ case CCrane::GOING_TOWARDS_TARGET_ONLY_HEIGHT:
+ case CCrane::LIFTING_TARGET:
+ case CCrane::ROTATING_TARGET:
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+bool CCranes::IsThisCarBeingTargettedByAnyCrane(CVehicle* pVehicle)
+{
+ for (int i = 0; i < NumCranes; i++) {
+ if (pVehicle == aCranes[i].m_pVehiclePickedUp)
+ return true;
+ }
+ return false;
+}
+
+void CCranes::Save(uint8* buf, uint32* size)
+{
+ INITSAVEBUF
+
+ *size = 2 * sizeof(uint32) + sizeof(aCranes);
+ WriteSaveBuf(buf, NumCranes);
+ WriteSaveBuf(buf, CarsCollectedMilitaryCrane);
+ for (int i = 0; i < NUM_CRANES; i++) {
+ CCrane *pCrane = WriteSaveBuf(buf, aCranes[i]);
+ if (pCrane->m_pCraneEntity != nil)
+ pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex(pCrane->m_pCraneEntity) + 1);
+ if (pCrane->m_pHook != nil)
+ pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pCrane->m_pHook) + 1);
+ if (pCrane->m_pVehiclePickedUp != nil)
+ pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex(pCrane->m_pVehiclePickedUp) + 1);
+ }
+
+ VALIDATESAVEBUF(*size);
+}
+
+void CCranes::Load(uint8* buf, uint32 size)
+{
+ INITSAVEBUF
+
+ NumCranes = ReadSaveBuf<int32>(buf);
+ CarsCollectedMilitaryCrane = ReadSaveBuf<uint32>(buf);
+ for (int i = 0; i < NUM_CRANES; i++)
+ aCranes[i] = ReadSaveBuf<CCrane>(buf);
+ for (int i = 0; i < NUM_CRANES; i++) {
+ CCrane *pCrane = &aCranes[i];
+ if (pCrane->m_pCraneEntity != nil)
+ pCrane->m_pCraneEntity = CPools::GetBuildingPool()->GetSlot((uint32)pCrane->m_pCraneEntity - 1);
+ if (pCrane->m_pHook != nil)
+ pCrane->m_pHook = CPools::GetObjectPool()->GetSlot((uint32)pCrane->m_pHook - 1);
+ if (pCrane->m_pVehiclePickedUp != nil)
+ pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uint32)pCrane->m_pVehiclePickedUp - 1);
+ }
+ for (int i = 0; i < NUM_CRANES; i++) {
+ aCranes[i].m_nAudioEntity = DMAudio.CreateEntity(AUDIOTYPE_CRANE, &aCranes[i]);
+ if (aCranes[i].m_nAudioEntity != 0)
+ DMAudio.SetEntityStatus(aCranes[i].m_nAudioEntity, 1);
+ }
+
+ VALIDATESAVEBUF(size);
+}
diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h
new file mode 100644
index 00000000..c0502638
--- /dev/null
+++ b/src/vehicles/Cranes.h
@@ -0,0 +1,97 @@
+#pragma once
+#include "common.h"
+
+#include "World.h"
+
+class CVehicle;
+class CEntity;
+class CObject;
+class CBuilding;
+
+class CCrane
+{
+public:
+ enum CraneState : uint8 {
+ IDLE = 0,
+ GOING_TOWARDS_TARGET = 1,
+ LIFTING_TARGET = 2,
+ GOING_TOWARDS_TARGET_ONLY_HEIGHT = 3,
+ ROTATING_TARGET = 4,
+ DROPPING_TARGET = 5
+ };
+ enum CraneStatus : uint8 {
+ NONE = 0,
+ ACTIVATED = 1,
+ DEACTIVATED = 2
+ };
+ CBuilding *m_pCraneEntity;
+ CObject *m_pHook;
+ int32 m_nAudioEntity;
+ float m_fPickupX1;
+ float m_fPickupX2;
+ float m_fPickupY1;
+ float m_fPickupY2;
+ CVector m_vecDropoffTarget;
+ float m_fDropoffHeading;
+ float m_fPickupAngle;
+ float m_fDropoffAngle;
+ float m_fPickupDistance;
+ float m_fDropoffDistance;
+ float m_fPickupHeight;
+ float m_fDropoffHeight;
+ float m_fHookAngle;
+ float m_fHookOffset;
+ float m_fHookHeight;
+ CVector m_vecHookInitPos;
+ CVector m_vecHookCurPos;
+ CVector2D m_vecHookVelocity;
+ CVehicle *m_pVehiclePickedUp;
+ uint32 m_nTimeForNextCheck;
+ CraneStatus m_nCraneStatus;
+ CraneState m_nCraneState;
+ uint8 m_nVehiclesCollected;
+ bool m_bIsCrusher;
+ bool m_bIsMilitaryCrane;
+ bool m_bWasMilitaryCrane;
+ bool m_bIsTop;
+
+ void Init(void) { memset(this, 0, sizeof(*this)); }
+ void Update(void);
+ bool RotateCarriedCarProperly(void);
+ void FindCarInSectorList(CPtrList* pList);
+ bool DoesCranePickUpThisCarType(uint32 mi);
+ bool GoTowardsTarget(float fAngleToTarget, float fDistanceToTarget, float fTargetHeight, float fSpeedMultiplier = 1.0f);
+ bool GoTowardsHeightTarget(float fTargetHeight, float fSpeedMultiplier = 1.0f);
+ void FindParametersForTarget(float X, float Y, float Z, float* pAngle, float* pDistance, float* pHeight);
+ void CalcHookCoordinates(float* pX, float* pY, float* pZ);
+ void SetHookMatrix(void);
+
+ float GetHeightToPickup() { return 4.0f + m_fPickupHeight + (m_bIsCrusher ? 4.5f : 0.0f); };
+ float GetHeightToDropoff() { return m_bIsCrusher ? (2.0f + m_fDropoffHeight + 3.0f) : (2.0f + m_fDropoffHeight); }
+ float GetHeightToPickupHeight() { return m_fPickupHeight + (m_bIsCrusher ? 7.0f : 4.0f); }
+ float GetHeightToDropoffHeight() { return m_fDropoffHeight + (m_bIsCrusher ? 7.0f : 2.0f); }
+};
+
+static_assert(sizeof(CCrane) == 128, "CCrane: error");
+
+class CCranes
+{
+public:
+ static void InitCranes(void);
+ static void AddThisOneCrane(CEntity* pCraneEntity);
+ static void ActivateCrane(float fInfX, float fSupX, float fInfY, float fSupY, float fDropOffX, float fDropOffY, float fDropOffZ, float fHeading, bool bIsCrusher, bool bIsMilitary, float fPosX, float fPosY);
+ static void DeActivateCrane(float fX, float fY);
+ static bool IsThisCarPickedUp(float fX, float fY, CVehicle* pVehicle);
+ static void UpdateCranes(void);
+ static bool DoesMilitaryCraneHaveThisOneAlready(uint32 mi);
+ static void RegisterCarForMilitaryCrane(uint32 mi);
+ static bool HaveAllCarsBeenCollectedByMilitaryCrane(void);
+ static bool IsThisCarBeingCarriedByAnyCrane(CVehicle* pVehicle);
+ static bool IsThisCarBeingTargettedByAnyCrane(CVehicle* pVehicle);
+ static void Save(uint8* buf, uint32* size);
+ static void Load(uint8* buf, uint32 size); // on mobile it's CranesLoad outside of the class
+
+ static uint32 CarsCollectedMilitaryCrane;
+ static int32 NumCranes;
+ static CCrane aCranes[NUM_CRANES];
+};
diff --git a/src/vehicles/Floater.cpp b/src/vehicles/Floater.cpp
index 6b8bf755..62d55925 100644
--- a/src/vehicles/Floater.cpp
+++ b/src/vehicles/Floater.cpp
@@ -26,7 +26,7 @@ cBuoyancy::ProcessBuoyancy(CPhysical *phys, float buoyancy, CVector *point, CVec
{
m_numSteps = 2.0f;
- if(!CWaterLevel::GetWaterLevel(phys->GetPosition(), &m_waterlevel, phys->m_flagD8))
+ if(!CWaterLevel::GetWaterLevel(phys->GetPosition(), &m_waterlevel, phys->bTouchingWater))
return false;
m_matrix = phys->GetMatrix();
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index adeba19e..f47fd131 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -482,6 +482,55 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage
}
void
+CVehicle::DoFixedMachineGuns(void)
+{
+ if(CPad::GetPad(0)->GetCarGunFired() && !bGunSwitchedOff){
+ if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 150){
+ CVector source, target;
+ float dx, dy, len;
+
+ dx = GetForward().x;
+ dy = GetForward().y;
+ len = Sqrt(SQR(dx) + SQR(dy));
+ if(len < 0.1f) len = 0.1f;
+ dx /= len;
+ dy /= len;
+
+ m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
+
+ source = GetMatrix() * CVector(2.0f, 2.5f, 1.0f);
+ target = source + CVector(dx, dy, 0.0f)*60.0f;
+ target += CVector(
+ ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
+ ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
+ ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f);
+ CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
+ FireOneInstantHitRound(&source, &target, 15);
+
+ source = GetMatrix() * CVector(-2.0f, 2.5f, 1.0f);
+ target = source + CVector(dx, dy, 0.0f)*60.0f;
+ target += CVector(
+ ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
+ ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
+ ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f);
+ CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
+ FireOneInstantHitRound(&source, &target, 15);
+
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
+
+ m_nAmmoInClip--;
+ if(m_nAmmoInClip == 0){
+ m_nAmmoInClip = 20;
+ m_nGunFiringTime = CTimer::GetTimeInMilliseconds() + 1400;
+ }
+ }
+ }else{
+ if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 1400)
+ m_nAmmoInClip = 20;
+ }
+}
+
+void
CVehicle::ExtinguishCarFire(void)
{
m_fHealth = max(m_fHealth, 300.0f);
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index 4639f3e1..f9becda0 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -130,7 +130,8 @@ public:
int8 m_nGettingInFlags;
int8 m_nGettingOutFlags;
uint8 m_nNumMaxPassengers;
- char field_1CD[19];
+ char field_1CD[3];
+ float field_1D0[4];
CEntity *m_pCurGroundEntity;
CFire *m_pCarFire;
float m_fSteerAngle;
@@ -238,6 +239,7 @@ public:
bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; }
bool IsHeli(void) { return m_vehType == VEHICLE_TYPE_HELI; }
bool IsPlane(void) { return m_vehType == VEHICLE_TYPE_PLANE; }
+ bool IsBike(void) { return m_vehType == VEHICLE_TYPE_BIKE; }
void FlyingControl(eFlightModel flightModel);
void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
@@ -268,6 +270,7 @@ public:
bool IsSphereTouchingVehicle(float sx, float sy, float sz, float radius);
bool ShufflePassengersToMakeSpace(void);
void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage);
+ void DoFixedMachineGuns(void);
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
diff --git a/src/weapons/Explosion.cpp b/src/weapons/Explosion.cpp
index e99dc918..3d00052a 100644
--- a/src/weapons/Explosion.cpp
+++ b/src/weapons/Explosion.cpp
@@ -1,11 +1,29 @@
#include "common.h"
#include "patcher.h"
+#include "Automobile.h"
+#include "Bike.h"
+#include "Camera.h"
+#include "Coronas.h"
#include "DMAudio.h"
+#include "Entity.h"
+#include "EventList.h"
#include "Explosion.h"
+#include "General.h"
+#include "Fire.h"
+#include "Pad.h"
+#include "Particle.h"
+#include "PointLights.h"
+#include "Shadows.h"
+#include "Timer.h"
+#include "Vehicle.h"
+#include "WaterLevel.h"
+#include "World.h"
-CExplosion(&gaExplosion)[48] = *(CExplosion(*)[48])*(uintptr*)0x64E208;
+CExplosion(&gaExplosion)[NUM_EXPLOSIONS] = *(CExplosion(*)[NUM_EXPLOSIONS])*(uintptr*)0x64E208;
-WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); }
+// these two were not initialised in original code, I'm really not sure what were they meant to be
+RwRGBA colMedExpl = { 0, 0, 0, 0 };
+RwRGBA colUpdate = { 0, 0, 0, 0 };
int AudioHandle = AEHANDLE_NONE;
@@ -15,26 +33,25 @@ CExplosion::Initialise()
debug("Initialising CExplosion...\n");
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
gaExplosion[i].m_ExplosionType = EXPLOSION_GRENADE;
- gaExplosion[i].m_vecPosition.x = 0.0f;
- gaExplosion[i].m_vecPosition.y = 0.0f;
- gaExplosion[i].m_vecPosition.z = 0.0f;
+ gaExplosion[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
gaExplosion[i].m_fRadius = 1.0f;
gaExplosion[i].m_fPropagationRate = 0.0f;
- gaExplosion[i].field_38 = 0;
+ gaExplosion[i].m_fZshift = 0.0f;
gaExplosion[i].m_pCreatorEntity = nil;
gaExplosion[i].m_pVictimEntity = nil;
gaExplosion[i].m_fStopTime = 0.0f;
- gaExplosion[i].m_bActive = false;
- gaExplosion[i].m_nStartTime = 0;
- gaExplosion[i].field_34 = 0;
+ gaExplosion[i].m_nIteration = 0;
+ gaExplosion[i].m_fStartTime = 0.0f;
+ gaExplosion[i].m_bIsBoat = false;
}
AudioHandle = DMAudio.CreateEntity(AUDIOTYPE_EXPLOSION, (void*)1);
if (AudioHandle >= 0)
- DMAudio.SetEntityStatus(AudioHandle, 1);
+ DMAudio.SetEntityStatus(AudioHandle, true);
debug("CExplosion ready\n");
}
-void CExplosion::Shutdown()
+void
+CExplosion::Shutdown()
{
debug("Shutting down CExplosion...\n");
if (AudioHandle >= 0) {
@@ -44,21 +61,22 @@ void CExplosion::Shutdown()
debug("CExplosion shut down\n");
}
+int8
+CExplosion::GetExplosionActiveCounter(uint8 id)
+{
+ return gaExplosion[id].m_nActiveCounter;
+}
+
void
-CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
+CExplosion::ResetExplosionActiveCounter(uint8 id)
{
- for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
- if (gaExplosion[i].m_bActive) {
- if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
- gaExplosion[i].m_bActive = false;
- }
- }
+ gaExplosion[id].m_nActiveCounter = 0;
}
-int8
-CExplosion::GetExplosionActiveCounter(uint8 id)
+uint8
+CExplosion::GetExplosionType(uint8 id)
{
- return gaExplosion[id].m_bActiveCounter;
+ return gaExplosion[id].m_ExplosionType;
}
CVector *
@@ -67,24 +85,357 @@ CExplosion::GetExplosionPosition(uint8 id)
return &gaExplosion[id].m_vecPosition;
}
-uint8
-CExplosion::GetExplosionType(uint8 id)
+bool
+CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime)
{
- return gaExplosion[id].m_ExplosionType;
+ CVector pPosn;
+ CVector posGround;
+
+ RwRGBA colorMedium = colMedExpl;
+ bool bDontExplode = false;
+ const RwRGBA color = { 160, 160, 160, 255 };
+ pPosn = pos;
+ pPosn.z += 5.0f;
+#ifdef FIX_BUGS
+ CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 30000, 1.0f);
+#else
+ // last two arguments are swapped resulting in no shadow
+ CShadows::AddPermanentShadow(SHADOWTEX_CAR, gpShadowHeliTex, &pPosn, 8.0f, 0.0f, 0.0f, -8.0f, 200, 0, 0, 0, 10.0f, 1, 30000.0f);
+#endif
+
+ int n = 0;
+ while (gaExplosion[n].m_nIteration != 0 && n < ARRAY_SIZE(gaExplosion))
+ n++;
+ if (n == ARRAY_SIZE(gaExplosion))
+ return false;
+
+ CExplosion &explosion = gaExplosion[n];
+ explosion.m_ExplosionType = type;
+ explosion.m_vecPosition = pos;
+ explosion.m_fRadius = 1.0f;
+ explosion.m_fZshift = 0.0f;
+ explosion.m_pCreatorEntity = culprit;
+ if (culprit != nil)
+ culprit->RegisterReference(&explosion.m_pCreatorEntity);
+ explosion.m_pVictimEntity = explodingEntity;
+ if (explodingEntity != nil)
+ explodingEntity->RegisterReference(&explosion.m_pVictimEntity);
+ explosion.m_nIteration = 1;
+ explosion.m_nActiveCounter = 1;
+ explosion.m_bIsBoat = false;
+ explosion.m_nParticlesExpireTime = lifetime != 0 ? CTimer::GetTimeInMilliseconds() + lifetime : 0;
+ switch (type)
+ {
+ case EXPLOSION_GRENADE:
+ explosion.m_fRadius = 9.0f;
+ explosion.m_fPower = 300.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
+ explosion.m_fPropagationRate = 0.5f;
+ posGround = pos;
+ posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, nil);
+ CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
+ if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
+ CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
+ break;
+ case EXPLOSION_MOLOTOV:
+ {
+ explosion.m_fRadius = 6.0f;
+ explosion.m_fPower = 0.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 3000;
+ explosion.m_fPropagationRate = 0.5f;
+ posGround = pos;
+ bool found;
+ posGround.z = CWorld::FindGroundZFor3DCoord(posGround.x, posGround.y, posGround.z + 3.0f, &found);
+ if (found) {
+ float waterLevel;
+ if (CWaterLevel::GetWaterLevelNoWaves(posGround.x, posGround.y, posGround.z, &waterLevel)
+ && posGround.z < waterLevel
+ && waterLevel - 6.0f < posGround.z) // some subway/tunnels check?
+ bDontExplode = true;
+ else
+ gFireManager.StartFire(posGround, 1.8f, false);
+ }
+ else
+ bDontExplode = true;
+ break;
+ }
+ case EXPLOSION_ROCKET:
+ explosion.m_fRadius = 10.0f;
+ explosion.m_fPower = 300.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
+ explosion.m_fPropagationRate = 0.5f;
+ CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 250);
+ if (Distance(explosion.m_vecPosition, TheCamera.GetPosition()) < 40.0f)
+ CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
+ break;
+ case EXPLOSION_CAR:
+ case EXPLOSION_CAR_QUICK:
+ explosion.m_fRadius = 9.0f;
+ explosion.m_fPower = 300.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 4250;
+ explosion.m_fPropagationRate = 0.5f;
+ explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
+ if (explosion.m_pVictimEntity != nil) {
+ if (explosion.m_pVictimEntity->IsVehicle() && ((CVehicle*)explosion.m_pVictimEntity)->IsBoat())
+ explosion.m_bIsBoat = true;
+ CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, explosion.m_pVictimEntity, nil, 1000);
+ } else
+ CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
+
+ if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
+ int rn = (CGeneral::GetRandomNumber() & 1) + 2;
+ for (int i = 0; i < rn; i++) {
+ CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, colMedExpl);
+ CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
+ }
+ CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
+ int32 component = CAR_WING_LR;
+
+ // miami leftover
+ if (veh->IsBike())
+ component = BIKE_FORKS_REAR;
+
+ if (veh->IsComponentPresent(component)) {
+ CVector componentPos;
+ veh->GetComponentWorldPosition(component, componentPos);
+ rn = (CGeneral::GetRandomNumber() & 1) + 1;
+ for (int i = 0; i < rn; i++)
+ CParticle::AddJetExplosion(componentPos, 1.4f, 0.0f);
+ }
+ }
+ break;
+ case EXPLOSION_HELI:
+ explosion.m_fRadius = 6.0f;
+ explosion.m_fPower = 300.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
+ explosion.m_fPropagationRate = 0.5f;
+ explosion.m_fStartTime = CTimer::GetTimeInMilliseconds();
+ for (int i = 0; i < 10; i++) {
+ CVector randpos;
+ uint8 x, y, z;
+
+ x = CGeneral::GetRandomNumber();
+ y = CGeneral::GetRandomNumber();
+ z = CGeneral::GetRandomNumber();
+ randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
+
+ CParticle::AddParticle(PARTICLE_EXPLOSION_MFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 2.5f, color);
+
+ x = CGeneral::GetRandomNumber();
+ y = CGeneral::GetRandomNumber();
+ z = CGeneral::GetRandomNumber();
+ randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
+
+ CParticle::AddParticle(PARTICLE_EXPLOSION_LFAST, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 5.0f, color);
+
+ x = CGeneral::GetRandomNumber();
+ y = CGeneral::GetRandomNumber();
+ z = CGeneral::GetRandomNumber();
+ randpos = pos + CVector(x - 128, y - 128, z - 128) / 20.0f;
+
+ CParticle::AddJetExplosion(randpos, 1.4f, 3.0f);
+ }
+ CEventList::RegisterEvent(EVENT_EXPLOSION, pos, 1000);
+ break;
+ case EXPLOSION_MINE:
+ explosion.m_fRadius = 10.0f;
+ explosion.m_fPower = 150.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
+ explosion.m_fPropagationRate = 0.5f;
+ posGround = pos;
+ //posGround.z =
+ CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
+ CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
+ break;
+ case EXPLOSION_BARREL:
+ explosion.m_fRadius = 7.0f;
+ explosion.m_fPower = 150.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
+ explosion.m_fPropagationRate = 0.5f;
+ for (int i = 0; i < 6; i++) {
+ CVector randpos;
+ uint8 x, y, z;
+
+ x = CGeneral::GetRandomNumber();
+ y = CGeneral::GetRandomNumber();
+ z = CGeneral::GetRandomNumber();
+ randpos = CVector(x - 128, y - 128, z - 128);
+
+ randpos.x /= 50.0f;
+ randpos.y /= 50.0f;
+ randpos.z /= 25.0f;
+ randpos += pos;
+ CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, randpos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, colorMedium);
+ }
+ posGround = pos;
+ //posGround.z =
+ CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
+ CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
+ break;
+ case EXPLOSION_TANK_GRENADE:
+ explosion.m_fRadius = 10.0f;
+ explosion.m_fPower = 150.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
+ explosion.m_fPropagationRate = 0.5f;
+ posGround = pos;
+ //posGround.z =
+ CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
+ CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
+ break;
+ case EXPLOSION_HELI_BOMB:
+ explosion.m_fRadius = 8.0f;
+ explosion.m_fPower = 50.0f;
+ explosion.m_fStopTime = lifetime + CTimer::GetTimeInMilliseconds() + 750;
+ explosion.m_fPropagationRate = 0.5f;
+ posGround = pos;
+ //posGround.z =
+ CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 4.0f, nil); // BUG? result is unused
+ CEventList::RegisterEvent(EVENT_EXPLOSION, posGround, 250);
+ break;
+ }
+ if (bDontExplode) {
+ explosion.m_nIteration = 0;
+ return false;
+ }
+
+ if (explosion.m_fPower != 0.0f && explosion.m_nParticlesExpireTime == 0)
+ CWorld::TriggerExplosion(pos, explosion.m_fRadius, explosion.m_fPower, culprit, (type == EXPLOSION_ROCKET || type == EXPLOSION_CAR_QUICK || type == EXPLOSION_MINE || type == EXPLOSION_BARREL || type == EXPLOSION_TANK_GRENADE || type == EXPLOSION_HELI_BOMB));
+
+ TheCamera.CamShake(0.6f, pos.x, pos.y, pos.z);
+ CPad::GetPad(0)->StartShake_Distance(300, 128, pos.x, pos.y, pos.z);
+ return true;
}
void
-CExplosion::ResetExplosionActiveCounter(uint8 id)
+CExplosion::Update()
{
- gaExplosion[id].m_bActiveCounter = 0;
+ RwRGBA color = colUpdate;
+ for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
+ CExplosion &explosion = gaExplosion[i];
+ if (explosion.m_nIteration == 0) continue;
+
+ if (explosion.m_nParticlesExpireTime != 0) {
+ if (CTimer::GetTimeInMilliseconds() > explosion.m_nParticlesExpireTime) {
+ explosion.m_nParticlesExpireTime = 0;
+ if (explosion.m_fPower != 0.0f)
+ CWorld::TriggerExplosion(explosion.m_vecPosition, explosion.m_fRadius, explosion.m_fPower, explosion.m_pCreatorEntity, (explosion.m_ExplosionType == EXPLOSION_ROCKET || explosion.m_ExplosionType == EXPLOSION_CAR_QUICK || explosion.m_ExplosionType == EXPLOSION_MINE || explosion.m_ExplosionType == EXPLOSION_BARREL || explosion.m_ExplosionType == EXPLOSION_TANK_GRENADE || explosion.m_ExplosionType == EXPLOSION_HELI_BOMB));
+ }
+ } else {
+ explosion.m_fRadius += explosion.m_fPropagationRate * CTimer::GetTimeStep();
+ int32 someTime = explosion.m_fStopTime - CTimer::GetTimeInMilliseconds();
+ switch (explosion.m_ExplosionType)
+ {
+ case EXPLOSION_GRENADE:
+ case EXPLOSION_ROCKET:
+ case EXPLOSION_HELI:
+ case EXPLOSION_MINE:
+ case EXPLOSION_BARREL:
+ if (CTimer::GetFrameCounter() & 1) {
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 20.0f, 1.0f, 1.0f, 0.5f, CPointLights::FOG_NONE, true);
+ CCoronas::RegisterCorona((uintptr)&explosion, 255, 255, 200, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ } else
+ CCoronas::RegisterCorona((uintptr)&explosion, 128, 128, 100, 255, explosion.m_vecPosition, 8.0f, 120.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 30, 25, 255, explosion.m_vecPosition, explosion.m_fRadius, 120.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ break;
+ case EXPLOSION_MOLOTOV:
+ CWorld::SetPedsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
+ CWorld::SetCarsOnFire(explosion.m_vecPosition.x, explosion.m_vecPosition.y, explosion.m_vecPosition.z, 6.0f, explosion.m_pCreatorEntity);
+ if (explosion.m_nIteration < 10) {
+ if (explosion.m_nIteration == 1) {
+ CVector point1 = explosion.m_vecPosition;
+ point1.z += 5.0f;
+ CColPoint colPoint;
+ CEntity *pEntity;
+ CWorld::ProcessVerticalLine(point1, -1000.0f, colPoint, pEntity, true, false, false, false, true, false, nil);
+ explosion.m_fZshift = colPoint.point.z;
+ }
+ float ff = ((float)explosion.m_nIteration * 0.55f);
+ for (int i = 0; i < 5 * ff; i++) {
+ float angle = CGeneral::GetRandomNumber() / 256.0f * 6.28f;
+
+ CVector pos = explosion.m_vecPosition;
+ pos.x += ff * Sin(angle);
+ pos.y += ff * Cos(angle);
+ pos.z += 5.0f; // what is the point of this?
+
+ pos.z = explosion.m_fZshift + 0.5f;
+ CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
+ }
+ }
+ break;
+ case EXPLOSION_CAR:
+ case EXPLOSION_CAR_QUICK:
+ if (someTime >= 3500) {
+ if (explosion.m_pVictimEntity != nil && !explosion.m_bIsBoat) {
+ if ((CGeneral::GetRandomNumber() & 0xF) == 0) {
+ CVehicle *veh = (CVehicle*)explosion.m_pVictimEntity;
+ uint8 component = CAR_WING_LR;
+
+ // miami leftover
+ if (veh->IsBike())
+ component = BIKE_FORKS_REAR;
+
+ if (veh->IsComponentPresent(component)) {
+ CVector componentPos;
+ veh->GetComponentWorldPosition(component, componentPos);
+ CParticle::AddJetExplosion(componentPos, 1.5f, 0.0f);
+ }
+ }
+ if (CTimer::GetTimeInMilliseconds() > explosion.m_fStartTime) {
+ explosion.m_fStartTime = CTimer::GetTimeInMilliseconds() + 125 + (CGeneral::GetRandomNumber() & 0x7F);
+ CVector pos = explosion.m_pVictimEntity->GetPosition();
+ for (int i = 0; i < (CGeneral::GetRandomNumber() & 1) + 1; i++) {
+ CParticle::AddParticle(PARTICLE_EXPLOSION_MEDIUM, pos, CVector(0.0f, 0.0f, 0.0f), nil, 3.5f, color);
+ CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 5.5f, color);
+ }
+ }
+ }
+ if (CTimer::GetFrameCounter() & 1) {
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, explosion.m_vecPosition, CVector(0.0f, 0.0f, 0.0f), 15.0f, 1.0f, 0.0f, 0.0f, CPointLights::FOG_NONE, true);
+ CCoronas::RegisterCorona((uintptr)&explosion, 200, 100, 0, 255, explosion.m_vecPosition, 6.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ } else
+ CCoronas::RegisterCorona((uintptr)&explosion, 128, 0, 0, 255, explosion.m_vecPosition, 8.0f, 80.0f, gpCoronaTexture[0], CCoronas::TYPE_NORMAL, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+
+ CCoronas::RegisterCorona((uintptr)&explosion + 1, 30, 15, 0, 255, explosion.m_vecPosition, explosion.m_fRadius, 80.0f, gpCoronaTexture[7], CCoronas::TYPE_STAR, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ } else if (explosion.m_nIteration & 1) {
+ if (explosion.m_pVictimEntity != nil)
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, explosion.m_pVictimEntity->GetPosition(), CVector(0.0f, 0.0f, 0.0f), nil, CGeneral::GetRandomNumberInRange(0.5f, 0.8f), color);
+ CVector pos = explosion.m_vecPosition;
+ pos.z += 1.0f;
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, pos, CVector(0.0f, 0.0f, 0.11f), nil, CGeneral::GetRandomNumberInRange(0.5f, 2.0f), color);
+ }
+ break;
+ case EXPLOSION_TANK_GRENADE:
+ case EXPLOSION_HELI_BOMB:
+ if (explosion.m_nIteration < 5) {
+ float ff = ((float)explosion.m_nIteration * 0.65f);
+ for (int i = 0; i < 10 * ff; i++) {
+ uint8 x = CGeneral::GetRandomNumber(), y = CGeneral::GetRandomNumber(), z = CGeneral::GetRandomNumber();
+ CVector pos(x - 128, y - 128, (z % 128) + 1);
+
+ pos.Normalise();
+ pos *= ff / 5.0f;
+ pos += explosion.m_vecPosition;
+ pos.z += 0.5f;
+ CParticle::AddParticle(PARTICLE_EXPLOSION_LARGE, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, CGeneral::GetRandomNumberInRange(-3.0f, 3.0f), CGeneral::GetRandomNumberInRange(-180.0f, 180.0f));
+ }
+ }
+ break;
+ }
+ if (someTime > 0)
+ explosion.m_nIteration++;
+ else
+ explosion.m_nIteration = 0;
+ }
+ }
}
bool
-CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float y1, float y2, float z1, float z2)
+CExplosion::TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2)
{
for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
- if (gaExplosion[i].m_bActive) {
- if (a1 == gaExplosion[i].m_ExplosionType) {
+ if (gaExplosion[i].m_nIteration != 0) {
+ if (type == gaExplosion[i].m_ExplosionType) {
if (gaExplosion[i].m_vecPosition.x >= x1 && gaExplosion[i].m_vecPosition.x <= x2) {
if (gaExplosion[i].m_vecPosition.y >= y1 && gaExplosion[i].m_vecPosition.y <= y2) {
if (gaExplosion[i].m_vecPosition.z >= z1 && gaExplosion[i].m_vecPosition.z <= z2)
@@ -97,13 +448,26 @@ CExplosion::TestForExplosionInArea(eExplosionType a1, float x1, float x2, float
return false;
}
+void
+CExplosion::RemoveAllExplosionsInArea(CVector pos, float radius)
+{
+ for (int i = 0; i < ARRAY_SIZE(gaExplosion); i++) {
+ if (gaExplosion[i].m_nIteration != 0) {
+ if ((pos - gaExplosion[i].m_vecPosition).MagnitudeSqr() < SQR(radius))
+ gaExplosion[i].m_nIteration = 0;
+ }
+ }
+}
+
STARTPATCHES
InjectHook(0x559030, &CExplosion::Initialise, PATCH_JUMP);
InjectHook(0x559100, &CExplosion::Shutdown, PATCH_JUMP);
- InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
InjectHook(0x559140, &CExplosion::GetExplosionActiveCounter, PATCH_JUMP);
- InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
- InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
InjectHook(0x559160, &CExplosion::ResetExplosionActiveCounter, PATCH_JUMP);
+ InjectHook(0x559180, &CExplosion::GetExplosionType, PATCH_JUMP);
+ InjectHook(0x5591A0, &CExplosion::GetExplosionPosition, PATCH_JUMP);
+ InjectHook(0x5591C0, &CExplosion::AddExplosion, PATCH_JUMP);
+ InjectHook(0x55A0C0, &CExplosion::Update, PATCH_JUMP);
InjectHook(0x55AC80, &CExplosion::TestForExplosionInArea, PATCH_JUMP);
+ InjectHook(0x55AD40, &CExplosion::RemoveAllExplosionsInArea, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/weapons/Explosion.h b/src/weapons/Explosion.h
index e6ef9496..45e2d5bb 100644
--- a/src/weapons/Explosion.h
+++ b/src/weapons/Explosion.h
@@ -26,25 +26,24 @@ class CExplosion
CEntity *m_pCreatorEntity;
CEntity *m_pVictimEntity;
float m_fStopTime;
- bool m_bActive;
- int8 m_bActiveCounter;
- int32 m_nStartTime;
+ uint8 m_nIteration;
+ uint8 m_nActiveCounter;
+ float m_fStartTime;
uint32 m_nParticlesExpireTime;
float m_fPower;
- int32 field_34;
- int32 field_38;
+ bool m_bIsBoat;
+ float m_fZshift;
public:
static void Initialise();
static void Shutdown();
- static void AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type,
- const CVector &pos, uint32);
-
static int8 GetExplosionActiveCounter(uint8 id);
- static CVector *GetExplosionPosition(uint8 id);
- static uint8 GetExplosionType(uint8 id);
static void ResetExplosionActiveCounter(uint8 id);
- static void RemoveAllExplosionsInArea(CVector, float);
- static bool TestForExplosionInArea(eExplosionType, float, float, float, float, float, float);
+ static uint8 GetExplosionType(uint8 id);
+ static CVector *GetExplosionPosition(uint8 id);
+ static bool AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime);
+ static void Update();
+ static bool TestForExplosionInArea(eExplosionType type, float x1, float x2, float y1, float y2, float z1, float z2);
+ static void RemoveAllExplosionsInArea(CVector pos, float radius);
};
-extern CExplosion (&gaExplosion)[48]; \ No newline at end of file
+extern CExplosion (&gaExplosion)[NUM_EXPLOSIONS]; \ No newline at end of file
diff --git a/src/weapons/ProjectileInfo.h b/src/weapons/ProjectileInfo.h
index dafb48db..a4ea369a 100644
--- a/src/weapons/ProjectileInfo.h
+++ b/src/weapons/ProjectileInfo.h
@@ -1,32 +1,32 @@
-#pragma once
-
-class CEntity;
-class CObject;
-class CProjectile;
-enum eWeaponType;
-
-class CProjectileInfo
-{
-public:
- eWeaponType m_eWeaponType;
- CEntity* m_pSource;
- uint32 m_nExplosionTime;
- bool m_bInUse;
- CVector m_vecPos;
-
-public:
- static CProjectileInfo* GetProjectileInfo(int32 id);
- static CProjectile* (&ms_apProjectile)[NUM_PROJECTILES];
-
- static void Initialise();
- static void Shutdown();
- static bool AddProjectile(CEntity *ped, eWeaponType weapon, CVector pos, float speed);
- static void RemoveProjectile(CProjectileInfo *info, CProjectile *projectile);
- static void RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos);
- static bool RemoveIfThisIsAProjectile(CObject *pObject);
- static void RemoveAllProjectiles();
- static void Update();
- static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
-};
-
+#pragma once
+
+class CEntity;
+class CObject;
+class CProjectile;
+enum eWeaponType;
+
+class CProjectileInfo
+{
+public:
+ eWeaponType m_eWeaponType;
+ CEntity* m_pSource;
+ uint32 m_nExplosionTime;
+ bool m_bInUse;
+ CVector m_vecPos;
+
+public:
+ static CProjectileInfo* GetProjectileInfo(int32 id);
+ static CProjectile* (&ms_apProjectile)[NUM_PROJECTILES];
+
+ static void Initialise();
+ static void Shutdown();
+ static bool AddProjectile(CEntity *ped, eWeaponType weapon, CVector pos, float speed);
+ static void RemoveProjectile(CProjectileInfo *info, CProjectile *projectile);
+ static void RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector pos);
+ static bool RemoveIfThisIsAProjectile(CObject *pObject);
+ static void RemoveAllProjectiles();
+ static void Update();
+ static bool IsProjectileInRange(float x1, float x2, float y1, float y2, float z1, float z2, bool remove);
+};
+
extern CProjectileInfo (&gaProjectileInfo)[NUM_PROJECTILES]; \ No newline at end of file