summaryrefslogtreecommitdiffstats
path: root/src/audio
diff options
context:
space:
mode:
authorNikolay Korolev <nickvnuk@gmail.com>2020-04-10 20:17:00 +0200
committerNikolay Korolev <nickvnuk@gmail.com>2020-04-10 20:17:00 +0200
commitbe260b49b1e5421a96f78ae2f0512220d5805274 (patch)
tree16f21f6f45c749120e3853a4369fe39348344102 /src/audio
parentrecord init (diff)
parentdisabling the code that freezes gang members (diff)
downloadre3-be260b49b1e5421a96f78ae2f0512220d5805274.tar
re3-be260b49b1e5421a96f78ae2f0512220d5805274.tar.gz
re3-be260b49b1e5421a96f78ae2f0512220d5805274.tar.bz2
re3-be260b49b1e5421a96f78ae2f0512220d5805274.tar.lz
re3-be260b49b1e5421a96f78ae2f0512220d5805274.tar.xz
re3-be260b49b1e5421a96f78ae2f0512220d5805274.tar.zst
re3-be260b49b1e5421a96f78ae2f0512220d5805274.zip
Diffstat (limited to 'src/audio')
-rw-r--r--src/audio/AudioCollision.cpp806
-rw-r--r--src/audio/AudioCollision.h70
-rw-r--r--src/audio/AudioManager.h2
-rw-r--r--src/audio/PoliceRadio.cpp1578
-rw-r--r--src/audio/PoliceRadio.h90
5 files changed, 1273 insertions, 1273 deletions
diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp
index 608b1a8d..4039bd75 100644
--- a/src/audio/AudioCollision.cpp
+++ b/src/audio/AudioCollision.cpp
@@ -1,403 +1,403 @@
-#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_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 = 0;
- 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_counter = 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 = 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;
+
+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_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 = 0;
+ 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_counter = 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 = 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
diff --git a/src/audio/AudioCollision.h b/src/audio/AudioCollision.h
index cf201735..956da3e3 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;
+
+ // reversed all methods
+ void AddCollisionToRequestedQueue(); /// ok
+};
+
static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error"); \ No newline at end of file
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 0e656475..910ffcaf 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include "DMAudio.h"
#include "common.h"
diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp
index 91312867..3ba16ef3 100644
--- a/src/audio/PoliceRadio.cpp
+++ b/src/audio/PoliceRadio.cpp
@@ -1,789 +1,789 @@
-#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_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 = 0;
- 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; // 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_counter = 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 = 0;
+ 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; // 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
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