audio stuff
Collision audio and police radio stuff moved to a separate cpp's like in the original code cPoliceRadioQueue added, code refactored correspondingly cAudioManager::ServiceCollisions reversed PlayOneShotScriptObject reversed cAudioScriptObject moved to AudioScriptObject.cpp Fixed use of numbers on non-integer types (bools, pointers) enum is now used for ped audio calculation Added fixes for vehicle description in the police radio (missing vehicles and wrong colors)
This commit is contained in:
parent
6ff06ff7c6
commit
da253837d1
399
src/audio/AudioCollision.cpp
Normal file
399
src/audio/AudioCollision.cpp
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
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, 60.f, 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 = 0;
|
||||||
|
m_sQueueSample.m_bIsDistant = 0;
|
||||||
|
m_sQueueSample.field_16 = 7;
|
||||||
|
m_sQueueSample.m_nLoopCount = 0;
|
||||||
|
m_sQueueSample.m_bEmittingVolume = emittingVol;
|
||||||
|
m_sQueueSample.m_nLoopStart =
|
||||||
|
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
|
||||||
|
m_sQueueSample.m_nLoopEnd =
|
||||||
|
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
|
||||||
|
m_sQueueSample.field_48 = 4.0f;
|
||||||
|
m_sQueueSample.m_fSoundIntensity = 60.0f;
|
||||||
|
m_sQueueSample.field_56 = 0;
|
||||||
|
m_sQueueSample.field_76 = 5;
|
||||||
|
m_sQueueSample.m_bReverbFlag = 1;
|
||||||
|
m_sQueueSample.m_bRequireReflection = 0;
|
||||||
|
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, 60.f, 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 = 0;
|
||||||
|
m_sQueueSample.m_bIsDistant = 0;
|
||||||
|
m_sQueueSample.field_16 = 11;
|
||||||
|
m_sQueueSample.m_nLoopCount = 1;
|
||||||
|
m_sQueueSample.m_bEmittingVolume = emittingVol;
|
||||||
|
m_sQueueSample.m_nLoopStart = 0;
|
||||||
|
m_sQueueSample.m_nLoopEnd = -1;
|
||||||
|
m_sQueueSample.field_48 = 4.0f;
|
||||||
|
m_sQueueSample.m_fSoundIntensity = 60.0f;
|
||||||
|
m_sQueueSample.field_56 = 1;
|
||||||
|
m_sQueueSample.m_bReverbFlag = 1;
|
||||||
|
m_sQueueSample.m_bRequireReflection = 0;
|
||||||
|
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 = 0;
|
||||||
|
m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = 0;
|
||||||
|
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 dist;
|
||||||
|
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;
|
||||||
|
dist = GetDistanceSquared(&pos);
|
||||||
|
if(dist < SQR(60.f)) {
|
||||||
|
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 = dist;
|
||||||
|
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
|
36
src/audio/AudioCollision.h
Normal file
36
src/audio/AudioCollision.h
Normal file
@ -0,0 +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
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error");
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "AudioCollision.h"
|
||||||
|
#include "PoliceRadio.h"
|
||||||
|
|
||||||
enum eScriptSounds : int16
|
enum eScriptSounds : int16
|
||||||
{
|
{
|
||||||
@ -182,25 +184,6 @@ public:
|
|||||||
|
|
||||||
static_assert(sizeof(tSound) == 92, "tSound: error");
|
static_assert(sizeof(tSound) == 92, "tSound: error");
|
||||||
|
|
||||||
enum eAudioType : int32
|
|
||||||
{
|
|
||||||
AUDIOTYPE_PHYSICAL = 0,
|
|
||||||
AUDIOTYPE_EXPLOSION = 1,
|
|
||||||
AUDIOTYPE_FIRE = 2,
|
|
||||||
AUDIOTYPE_WEATHER = 3,
|
|
||||||
AUDIOTYPE_CRANE = 4,
|
|
||||||
AUDIOTYPE_SCRIPTOBJECT = 5,
|
|
||||||
AUDIOTYPE_BRIDGE = 6,
|
|
||||||
AUDIOTYPE_COLLISION = 7,
|
|
||||||
AUDIOTYPE_FRONTEND = 8,
|
|
||||||
AUDIOTYPE_PROJECTILE = 9,
|
|
||||||
AUDIOTYPE_GARAGE = 10,
|
|
||||||
AUDIOTYPE_FIREHYDRANT = 11,
|
|
||||||
AUDIOTYPE_WATERCANNON = 12,
|
|
||||||
AUDIOTYPE_POLICERADIO = 13,
|
|
||||||
TOTAL_AUDIO_TYPES = 14,
|
|
||||||
};
|
|
||||||
|
|
||||||
class CPhysical;
|
class CPhysical;
|
||||||
class CAutomobile;
|
class CAutomobile;
|
||||||
|
|
||||||
@ -256,42 +239,6 @@ static_assert(sizeof(cPedComments) == 1164, "cPedComments: error");
|
|||||||
|
|
||||||
class CEntity;
|
class CEntity;
|
||||||
|
|
||||||
class cAudioCollision
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CEntity *m_pEntity1;
|
|
||||||
CEntity *m_pEntity2;
|
|
||||||
uint8 m_bSurface1;
|
|
||||||
uint8 m_bSurface2;
|
|
||||||
uint8 field_10;
|
|
||||||
uint8 field_11;
|
|
||||||
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[10];
|
|
||||||
cAudioCollision m_asCollisions2[10];
|
|
||||||
uint8 m_bIndicesTable[10];
|
|
||||||
uint8 m_bCollisionsInQueue;
|
|
||||||
uint8 gap_811;
|
|
||||||
cAudioCollision m_sQueue;
|
|
||||||
|
|
||||||
// reversed all methods
|
|
||||||
void AddCollisionToRequestedQueue(); /// ok
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(cAudioCollisionManager) == 852, "cAudioCollisionManager: error");
|
|
||||||
|
|
||||||
class cMissionAudio
|
class cMissionAudio
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -320,24 +267,6 @@ class CPed;
|
|||||||
class cPedParams;
|
class cPedParams;
|
||||||
class cTransmission;
|
class cTransmission;
|
||||||
|
|
||||||
class cAudioScriptObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int16 AudioId;
|
|
||||||
char _pad0[2];
|
|
||||||
CVector Posn;
|
|
||||||
int32 AudioEntity;
|
|
||||||
|
|
||||||
void Reset(); /// ok
|
|
||||||
|
|
||||||
static void *operator new(size_t);
|
|
||||||
static void *operator new(size_t, int);
|
|
||||||
static void operator delete(void *, size_t);
|
|
||||||
static void operator delete(void *, int);
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(cAudioScriptObject) == 20, "cAudioScriptObject: error");
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/*
|
/*
|
||||||
REFLECTION_YMAX = 0, top
|
REFLECTION_YMAX = 0, top
|
||||||
@ -355,23 +284,6 @@ enum {
|
|||||||
MAX_REFLECTIONS,
|
MAX_REFLECTIONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AudioEntityHandle {
|
|
||||||
AEHANDLE_NONE = -5,
|
|
||||||
AEHANDLE_ERROR_NOAUDIOSYS = -4,
|
|
||||||
AEHANDLE_ERROR_NOFREESLOT = -3,
|
|
||||||
AEHANDLE_ERROR_NOENTITY = -2,
|
|
||||||
AEHANDLE_ERROR_BADAUDIOTYPE = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cAMCrime {
|
|
||||||
int32 type;
|
|
||||||
CVector position;
|
|
||||||
uint16 timer;
|
|
||||||
uint16 gap;
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(cAMCrime) == 20, "cAMCrime: error ");
|
|
||||||
|
|
||||||
class cAudioManager
|
class cAudioManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -407,12 +319,7 @@ public:
|
|||||||
int32 m_nFireAudioEntity;
|
int32 m_nFireAudioEntity;
|
||||||
int32 m_nWaterCannonEntity;
|
int32 m_nWaterCannonEntity;
|
||||||
int32 m_nPoliceChannelEntity;
|
int32 m_nPoliceChannelEntity;
|
||||||
int32 crimesSamples[60];
|
cPoliceRadioQueue m_sPoliceRadioQueue;
|
||||||
uint8 policeChannelTimer;
|
|
||||||
uint8 policeChannelTimerSeconds;
|
|
||||||
uint8 policeChannelCounterSeconds;
|
|
||||||
uint8 gap30;
|
|
||||||
cAMCrime crimes[10];
|
|
||||||
int32 m_nFrontEndEntity;
|
int32 m_nFrontEndEntity;
|
||||||
int32 m_nCollisionEntity;
|
int32 m_nCollisionEntity;
|
||||||
cAudioCollisionManager m_sCollisionManager;
|
cAudioCollisionManager m_sCollisionManager;
|
||||||
@ -546,7 +453,7 @@ public:
|
|||||||
float GetDistanceSquared(CVector *v) const; /// ok
|
float GetDistanceSquared(CVector *v) const; /// ok
|
||||||
int32 GetJumboTaxiFreq() const; /// ok
|
int32 GetJumboTaxiFreq() const; /// ok
|
||||||
bool GetMissionAudioLoadingStatus() const; /// ok
|
bool GetMissionAudioLoadingStatus() const; /// ok
|
||||||
char GetMissionScriptPoliceAudioPlayingStatus() const; /// ok
|
int8 GetMissionScriptPoliceAudioPlayingStatus() const; /// ok
|
||||||
uint8 GetNum3DProvidersAvailable() const;
|
uint8 GetNum3DProvidersAvailable() const;
|
||||||
int32 GetPedCommentSfx(CPed *ped, int32 sound);
|
int32 GetPedCommentSfx(CPed *ped, int32 sound);
|
||||||
void GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const;
|
void GetPhrase(uint32 *phrase, uint32 *prevPhrase, uint32 sample, uint32 maxOffset) const;
|
||||||
@ -658,7 +565,7 @@ public:
|
|||||||
void ResetTimers(uint32 time); /// ok
|
void ResetTimers(uint32 time); /// ok
|
||||||
|
|
||||||
void Service(); /// ok
|
void Service(); /// ok
|
||||||
void ServiceCollisions(); // todo
|
void ServiceCollisions(); /// ok
|
||||||
void ServicePoliceRadio(); /// ok
|
void ServicePoliceRadio(); /// ok
|
||||||
void ServicePoliceRadioChannel(int32 wantedLevel); /// ok
|
void ServicePoliceRadioChannel(int32 wantedLevel); /// ok
|
||||||
void ServiceSoundEffects(); /// ok
|
void ServiceSoundEffects(); /// ok
|
||||||
@ -696,8 +603,13 @@ public:
|
|||||||
|
|
||||||
// only used in pc
|
// only used in pc
|
||||||
void AdjustSamplesVolume(); /// ok
|
void AdjustSamplesVolume(); /// ok
|
||||||
int32 ComputeEmittingVolume(uint8 emittingVolume, float intensity,
|
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity,
|
||||||
float dist); /// ok
|
float dist); /// ok
|
||||||
|
public:
|
||||||
|
static const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
|
||||||
|
static const int policeChannel = channels + 1;
|
||||||
|
static const int allChannels = channels + 2;
|
||||||
|
static const int maxVolume = 127;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
|
static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
|
||||||
|
@ -1,7 +1,48 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
#include "AudioScriptObject.h"
|
#include "AudioScriptObject.h"
|
||||||
|
#include "Pools.h"
|
||||||
|
|
||||||
void PlayOneShotScriptObject(uint8 id, CVector const &pos)
|
void
|
||||||
|
cAudioScriptObject::Reset()
|
||||||
{
|
{
|
||||||
((void (__cdecl *)(uint8, CVector const &))0x57C5F0)(id, pos);
|
AudioId = 125;
|
||||||
}
|
Posn = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
AudioEntity = AEHANDLE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
cAudioScriptObject::operator new(size_t sz)
|
||||||
|
{
|
||||||
|
return CPools::GetAudioScriptObjectPool()->New();
|
||||||
|
}
|
||||||
|
void *
|
||||||
|
cAudioScriptObject::operator new(size_t sz, int handle)
|
||||||
|
{
|
||||||
|
return CPools::GetAudioScriptObjectPool()->New(handle);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
cAudioScriptObject::operator delete(void *p, size_t sz)
|
||||||
|
{
|
||||||
|
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
cAudioScriptObject::operator delete(void *p, int handle)
|
||||||
|
{
|
||||||
|
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PlayOneShotScriptObject(uint8 id, CVector const &pos)
|
||||||
|
{
|
||||||
|
cAudioScriptObject *audioScriptObject = new cAudioScriptObject();
|
||||||
|
audioScriptObject->Posn = pos;
|
||||||
|
audioScriptObject->AudioId = id;
|
||||||
|
audioScriptObject->AudioEntity = AEHANDLE_NONE;
|
||||||
|
DMAudio.CreateOneShotScriptObject(audioScriptObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTPATCHES
|
||||||
|
InjectHook(0x57C430, &cAudioScriptObject::Reset, PATCH_JUMP);
|
||||||
|
InjectHook(0x57C5F0, &PlayOneShotScriptObject, PATCH_JUMP);
|
||||||
|
ENDPATCHES
|
@ -128,4 +128,21 @@ enum
|
|||||||
_SCRSOUND_BULLET_SHELL_HIT_GROUND_2 = 123,
|
_SCRSOUND_BULLET_SHELL_HIT_GROUND_2 = 123,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cAudioScriptObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int16 AudioId;
|
||||||
|
CVector Posn;
|
||||||
|
int32 AudioEntity;
|
||||||
|
|
||||||
|
void Reset(); /// ok
|
||||||
|
|
||||||
|
static void* operator new(size_t);
|
||||||
|
static void* operator new(size_t, int);
|
||||||
|
static void operator delete(void*, size_t);
|
||||||
|
static void operator delete(void*, int);
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(cAudioScriptObject) == 20, "cAudioScriptObject: error");
|
||||||
|
|
||||||
extern void PlayOneShotScriptObject(uint8 id, CVector const &pos);
|
extern void PlayOneShotScriptObject(uint8 id, CVector const &pos);
|
@ -3,6 +3,7 @@
|
|||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
#include "MusicManager.h"
|
#include "MusicManager.h"
|
||||||
#include "AudioManager.h"
|
#include "AudioManager.h"
|
||||||
|
#include "AudioScriptObject.h"
|
||||||
#include "sampman.h"
|
#include "sampman.h"
|
||||||
|
|
||||||
cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE;
|
cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE;
|
||||||
|
786
src/audio/PoliceRadio.cpp
Normal file
786
src/audio/PoliceRadio.cpp
Normal file
@ -0,0 +1,786 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
|
||||||
|
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_nTimeOfRecentCrime;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 0;
|
||||||
|
m_sQueueSample.m_bIsDistant = 1;
|
||||||
|
m_sQueueSample.field_16 = 10;
|
||||||
|
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_RADIO_CRACKLE);
|
||||||
|
m_sQueueSample.m_bVolume = m_anRandomTable[2] % 20 + 15;
|
||||||
|
m_sQueueSample.m_nLoopCount = 0;
|
||||||
|
m_sQueueSample.m_bEmittingVolume = m_sQueueSample.m_bVolume;
|
||||||
|
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_POLICE_RADIO_CRACKLE);
|
||||||
|
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_POLICE_RADIO_CRACKLE);
|
||||||
|
m_sQueueSample.field_56 = 0;
|
||||||
|
m_sQueueSample.m_bReverbFlag = 0;
|
||||||
|
m_sQueueSample.m_bOffset = 63;
|
||||||
|
m_sQueueSample.field_76 = 3;
|
||||||
|
m_sQueueSample.m_bRequireReflection = 0;
|
||||||
|
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_nTimeOfRecentCrime >= 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_nTimeOfRecentCrime + 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
|
44
src/audio/PoliceRadio.h
Normal file
44
src/audio/PoliceRadio.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
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 ");
|
@ -225,4 +225,31 @@ enum eStreamedSounds
|
|||||||
STREAMED_SOUND_MISSION_CAT1 = 195,
|
STREAMED_SOUND_MISSION_CAT1 = 195,
|
||||||
TOTAL_STREAMED_SOUNDS = 196,
|
TOTAL_STREAMED_SOUNDS = 196,
|
||||||
NO_STREAMED_SOUND = 197,
|
NO_STREAMED_SOUND = 197,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AudioEntityHandle {
|
||||||
|
AEHANDLE_NONE = -5,
|
||||||
|
AEHANDLE_ERROR_NOAUDIOSYS = -4,
|
||||||
|
AEHANDLE_ERROR_NOFREESLOT = -3,
|
||||||
|
AEHANDLE_ERROR_NOENTITY = -2,
|
||||||
|
AEHANDLE_ERROR_BADAUDIOTYPE = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eAudioType : int32
|
||||||
|
{
|
||||||
|
AUDIOTYPE_PHYSICAL = 0,
|
||||||
|
AUDIOTYPE_EXPLOSION = 1,
|
||||||
|
AUDIOTYPE_FIRE = 2,
|
||||||
|
AUDIOTYPE_WEATHER = 3,
|
||||||
|
AUDIOTYPE_CRANE = 4,
|
||||||
|
AUDIOTYPE_SCRIPTOBJECT = 5,
|
||||||
|
AUDIOTYPE_BRIDGE = 6,
|
||||||
|
AUDIOTYPE_COLLISION = 7,
|
||||||
|
AUDIOTYPE_FRONTEND = 8,
|
||||||
|
AUDIOTYPE_PROJECTILE = 9,
|
||||||
|
AUDIOTYPE_GARAGE = 10,
|
||||||
|
AUDIOTYPE_FIREHYDRANT = 11,
|
||||||
|
AUDIOTYPE_WATERCANNON = 12,
|
||||||
|
AUDIOTYPE_POLICERADIO = 13,
|
||||||
|
TOTAL_AUDIO_TYPES = 14,
|
||||||
|
};
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "PlayerPed.h"
|
#include "PlayerPed.h"
|
||||||
#include "Automobile.h"
|
#include "Automobile.h"
|
||||||
#include "DummyPed.h"
|
#include "DummyPed.h"
|
||||||
#include "AudioManager.h"
|
#include "AudioScriptObject.h"
|
||||||
|
|
||||||
typedef CPool<CPtrNode> CCPtrNodePool;
|
typedef CPool<CPtrNode> CCPtrNodePool;
|
||||||
typedef CPool<CEntryInfoNode> CEntryInfoNodePool;
|
typedef CPool<CEntryInfoNode> CEntryInfoNodePool;
|
||||||
@ -18,7 +18,7 @@ typedef CPool<CBuilding> CBuildingPool;
|
|||||||
typedef CPool<CTreadable> CTreadablePool;
|
typedef CPool<CTreadable> CTreadablePool;
|
||||||
typedef CPool<CObject, CCutsceneHead> CObjectPool;
|
typedef CPool<CObject, CCutsceneHead> CObjectPool;
|
||||||
typedef CPool<CDummy, CDummyPed> CDummyPool;
|
typedef CPool<CDummy, CDummyPed> CDummyPool;
|
||||||
typedef CPool<cAudioScriptObject, cAudioScriptObject> CAudioScriptObjectPool;
|
typedef CPool<cAudioScriptObject> CAudioScriptObjectPool;
|
||||||
|
|
||||||
class CPools
|
class CPools
|
||||||
{
|
{
|
||||||
|
@ -22,6 +22,7 @@ enum eCrimeType
|
|||||||
CRIME_COP_BURNED,
|
CRIME_COP_BURNED,
|
||||||
CRIME_VEHICLE_BURNED,
|
CRIME_VEHICLE_BURNED,
|
||||||
CRIME_DESTROYED_CESSNA,
|
CRIME_DESTROYED_CESSNA,
|
||||||
|
NUM_CRIME_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCrimeBeingQd
|
class CCrimeBeingQd
|
||||||
|
Loading…
Reference in New Issue
Block a user