Fix reverse warn and air brakes

This commit is contained in:
Filip Gawin 2019-07-07 16:32:28 +02:00
parent d6944ec570
commit 567937a8cd
2 changed files with 165 additions and 11 deletions

View file

@ -91,9 +91,153 @@ enum eVehicleModel
cAudioManager &AudioManager = *(cAudioManager *)0x880FC0; cAudioManager &AudioManager = *(cAudioManager *)0x880FC0;
constexpr int totalAudioEntitiesSlots = 200; constexpr int totalAudioEntitiesSlots = 200;
constexpr int maxVolume = 127;
char &g_nMissionAudioPlayingStatus = *(char *)0x60ED88; char &g_nMissionAudioPlayingStatus = *(char *)0x60ED88;
void
cAudioManager::AddSampleToRequestedQueue()
{
int32 calculatedVolume;
tActiveSample *sample;
int32 unknown1;
uint8 unknown2;
bool bReflections;
if(m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) {
calculatedVolume = m_sQueueSample.field_16 * (maxVolume - m_sQueueSample.m_bVolume);
unknown2 = m_bSampleRequestQueuesStatus[m_bActiveSampleQueue];
if(unknown2 >= m_bActiveSamples) {
unknown1 = 27 * m_bActiveSampleQueue;
unknown2 = *(&m_asSamples[53].field_91 + m_bActiveSamples + unknown1);
if(m_asSamples[unknown1 + unknown2].calculatedVolume <= calculatedVolume)
return;
} else {
++m_bSampleRequestQueuesStatus[m_bActiveSampleQueue];
}
m_sQueueSample.calculatedVolume = calculatedVolume;
m_sQueueSample.m_bLoopEnded = 0;
if(m_sQueueSample.m_bIsDistant) {
m_sQueueSample.m_bRequireReflection = 0;
m_sQueueSample.m_bLoopsRemaining = 0;
}
if(m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) {
bReflections = m_sQueueSample.m_bRequireReflection;
} else {
bReflections = false;
m_sQueueSample.m_bLoopsRemaining = 0;
}
m_sQueueSample.m_bRequireReflection = 0;
if(!m_bDynamicAcousticModelingStatus) m_sQueueSample.m_bReverbFlag = 0;
sample = &m_asSamples[27 * m_bActiveSampleQueue + unknown2];
sample->m_nEntityIndex = m_sQueueSample.m_nEntityIndex;
sample->field_4 = m_sQueueSample.field_4;
sample->m_nSampleIndex = m_sQueueSample.m_nSampleIndex;
sample->m_bBankIndex = m_sQueueSample.m_bBankIndex;
sample->m_bIsDistant = m_sQueueSample.m_bIsDistant;
sample->field_16 = m_sQueueSample.field_16;
sample->m_nFrequency = m_sQueueSample.m_nFrequency;
sample->m_bVolume = m_sQueueSample.m_bVolume;
sample->m_fDistance = m_sQueueSample.m_fDistance;
sample->m_nLoopCount = m_sQueueSample.m_nLoopCount;
sample->m_nLoopStart = m_sQueueSample.m_nLoopStart;
sample->m_nLoopEnd = m_sQueueSample.m_nLoopEnd;
sample->m_bEmittingVolume = m_sQueueSample.m_bEmittingVolume;
sample->field_48 = m_sQueueSample.field_48;
sample->m_fSoundIntensity = m_sQueueSample.m_fSoundIntensity;
sample->field_56 = m_sQueueSample.field_56;
sample->m_vecPos = m_sQueueSample.m_vecPos;
sample->m_bReverbFlag = m_sQueueSample.m_bReverbFlag;
sample->m_bLoopsRemaining = m_sQueueSample.m_bLoopsRemaining;
sample->m_bRequireReflection = m_sQueueSample.m_bRequireReflection;
sample->m_bOffset = m_sQueueSample.m_bOffset;
sample->field_76 = m_sQueueSample.field_76;
sample->m_bIsProcessed = m_sQueueSample.m_bIsProcessed;
sample->m_bLoopEnded = m_sQueueSample.m_bLoopEnded;
sample->calculatedVolume = m_sQueueSample.calculatedVolume;
sample->field_88 = m_sQueueSample.field_88;
AddDetailsToRequestedOrderList(unknown2);
if(bReflections) AddReflectionsToRequestedQueue();
}
}
void
cAudioManager::AddDetailsToRequestedOrderList(uint8 sample)
{
int32 offset;
uint32 i = 0;
if(sample != 0) {
for(; i < sample; i++) {
offset = 27 * m_bActiveSampleQueue;
if(m_asSamples[offset + m_abSampleQueueIndexTable[i + offset]]
.calculatedVolume > m_asSamples[offset + sample].calculatedVolume)
break;
}
if(i < sample) {
memmove(&m_abSampleQueueIndexTable[offset + 1 + i],
&m_abSampleQueueIndexTable[offset + i], m_bActiveSamples - i - 1);
}
}
m_abSampleQueueIndexTable[27 * m_bActiveSampleQueue + i] = sample;
}
void
cAudioManager::AddReflectionsToRequestedQueue()
{
float reflectionDistance;
int32 noise;
uint8 emittingVolume = emittingVolume =
(m_sQueueSample.m_bVolume >> 1) + (m_sQueueSample.m_bVolume >> 3);
for(uint32 i = 0; i < 5u; i++) {
reflectionDistance = m_afReflectionsDistances[i];
if(reflectionDistance > 0.0f && reflectionDistance < 100.f &&
reflectionDistance < m_sQueueSample.m_fSoundIntensity) {
m_sQueueSample.m_bLoopsRemaining = (reflectionDistance * 0.38873f); // @todo assert value
if(m_sQueueSample.m_bLoopsRemaining > 5u) {
m_sQueueSample.m_fDistance = m_afReflectionsDistances[i];
m_sQueueSample.m_bEmittingVolume = emittingVolume;
m_sQueueSample.m_bVolume =
ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity,
m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume > emittingVolume >> 4) {
m_sQueueSample.field_4 += ((i + 1) << 8);
if(m_sQueueSample.m_nLoopCount) {
noise = RandomDisplacement(
m_sQueueSample.m_nFrequency >> 5);
if(noise <= 0)
m_sQueueSample.m_nFrequency += noise;
else
m_sQueueSample.m_nFrequency -= noise;
}
m_sQueueSample.field_16 += 20;
m_sQueueSample.m_vecPos.x = m_avecReflectionsPos[i].x;
m_sQueueSample.m_vecPos.y = m_avecReflectionsPos[i].y;
m_sQueueSample.m_vecPos.z = m_avecReflectionsPos[i].z;
AddSampleToRequestedQueue();
}
}
}
}
}
uint32
cAudioManager::ComputeVolume(int emittingVolume, float soundIntensity, float distance)
{
float newSoundIntensity;
if(soundIntensity <= 0.0f) return 0;
if((soundIntensity * 0.2f) <= distance) {
newSoundIntensity = soundIntensity * 0.2f;
emittingVolume =
sq((soundIntensity - distance) / (soundIntensity - newSoundIntensity)) *
emittingVolume;
}
return emittingVolume;
}
void void
cAudioManager::Initialise() cAudioManager::Initialise()
{ {
@ -409,7 +553,7 @@ cAudioManager::ResetPoliceRadio()
void void
cAudioManager::InterrogateAudioEntities() cAudioManager::InterrogateAudioEntities()
{ {
for(uint32 i = 0; i < m_nAudioEntitiesTotal; i++) { for(int32 i = 0; i < m_nAudioEntitiesTotal; i++) {
ProcessEntity(m_anAudioEntityIndices[i]); ProcessEntity(m_anAudioEntityIndices[i]);
m_asAudioEntities[m_anAudioEntityIndices[i]].field_24 = 0; m_asAudioEntities[m_anAudioEntityIndices[i]].field_24 = 0;
} }
@ -418,7 +562,7 @@ cAudioManager::InterrogateAudioEntities()
void void
cAudioManager::ClearRequestedQueue() cAudioManager::ClearRequestedQueue()
{ {
for(uint32 i = 0; i < m_bActiveSamples; i++) { for(int32 i = 0; i < m_bActiveSamples; i++) {
m_abSampleQueueIndexTable[i + 27 * m_bActiveSampleQueue] = m_bActiveSamples; m_abSampleQueueIndexTable[i + 27 * m_bActiveSampleQueue] = m_bActiveSamples;
} }
m_bSampleRequestQueuesStatus[m_bActiveSampleQueue] = 0; m_bSampleRequestQueuesStatus[m_bActiveSampleQueue] = 0;
@ -432,14 +576,14 @@ cAudioManager::ClearRequestedQueue()
bool bool
cAudioManager::UsesReverseWarning(int32 model) cAudioManager::UsesReverseWarning(int32 model)
{ {
return model == LINERUN || fabs(model - FIRETRUK) <= 1 || model == BUS || return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS ||
model == COACH; // fix model == COACH; // fix
} }
bool bool
cAudioManager::HasAirBrakes(int32 model) cAudioManager::HasAirBrakes(int32 model)
{ {
return model == LINERUN || fabs(model - FIRETRUK) <= 1 || model == BUS || return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS ||
model == COACH; // fix model == COACH; // fix
} }
@ -594,7 +738,7 @@ cAudioManager::DestroyEntity(int32 id)
if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots && if(m_bIsInitialised && id >= 0 && id < totalAudioEntitiesSlots &&
m_asAudioEntities[id].m_bIsUsed) { m_asAudioEntities[id].m_bIsUsed) {
m_asAudioEntities[id].m_bIsUsed = 0; m_asAudioEntities[id].m_bIsUsed = 0;
for(uint32 i = 0; i < m_nAudioEntitiesTotal; ++i) { for(int32 i = 0; i < m_nAudioEntitiesTotal; ++i) {
if(id == m_anAudioEntityIndices[i]) { if(id == m_anAudioEntityIndices[i]) {
if(i < totalAudioEntitiesSlots - 1) if(i < totalAudioEntitiesSlots - 1)
memmove(&m_anAudioEntityIndices[i], memmove(&m_anAudioEntityIndices[i],
@ -2816,6 +2960,11 @@ cAudioManager::Service()
} }
STARTPATCHES STARTPATCHES
InjectHook(0x57B070, &cAudioManager::AddSampleToRequestedQueue, PATCH_JUMP);
InjectHook(0x57B210, &cAudioManager::AddDetailsToRequestedOrderList, PATCH_JUMP);
InjectHook(0x57B300, &cAudioManager::AddReflectionsToRequestedQueue, PATCH_JUMP);
InjectHook(0x57ABB0, &cAudioManager::ComputeVolume, PATCH_JUMP);
InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP); InjectHook(0x57A0E0, &cAudioManager::Initialise, PATCH_JUMP);
InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP); InjectHook(0x569420, &cAudioManager::PostInitialiseGameSpecificSetup, PATCH_JUMP);
//InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP); //InjectHook(0x57EAC0, &cAudioManager::InitialisePoliceRadioZones, PATCH_JUMP);

View file

@ -44,7 +44,7 @@ public:
char m_bLoopEnded; char m_bLoopEnded;
char field_82; char field_82;
char field_83; char field_83;
int field_84; int calculatedVolume;
char field_88; char field_88;
char field_89; char field_89;
char field_90; char field_90;
@ -218,15 +218,20 @@ public:
char field_19195; char field_19195;
int m_nTimeOfRecentCrime; int m_nTimeOfRecentCrime;
void AddSampleToRequestedQueue();
void AddDetailsToRequestedOrderList(uint8 sample);
void AddReflectionsToRequestedQueue();
uint32 ComputeVolume(int emittingVolume, float soundIntensity, float distance);
void Initialise(); void Initialise();
void PostInitialiseGameSpecificSetup(); void PostInitialiseGameSpecificSetup();
void InitialisePoliceRadioZones(); // @todo void InitialisePoliceRadioZones(); // @todo
void ResetAudioLogicTimers(int32 timer); // @todo void ResetAudioLogicTimers(int32 timer); // @todo
void Terminate(); void Terminate();
// done
char GetMissionScriptPoliceAudioPlayingStatus(); char GetMissionScriptPoliceAudioPlayingStatus();
bool GetMissionAudioLoadingStatus(); bool GetMissionAudioLoadingStatus();
@ -270,7 +275,7 @@ public:
void InterrogateAudioEntities(); void InterrogateAudioEntities();
void ClearRequestedQueue(); void ClearRequestedQueue();
// void AgeCrimes(); // void AgeCrimes(); //todo
bool UsesReverseWarning(int32 model); bool UsesReverseWarning(int32 model);
bool HasAirBrakes(int32 model); bool HasAirBrakes(int32 model);
@ -283,7 +288,7 @@ public:
void ProcessPlane(void *); // todo void ProcessPlane(void *); // todo
void ClearMissionAudio(); void ClearMissionAudio();
// void ProcessReverb(); // void ProcessReverb(); // todo
bool IsMissionAudioSampleFinished(); bool IsMissionAudioSampleFinished();