#include "sound.h"
#include <stdlib.h>
#include <string.h>
#include "brender/brender.h"
#include "controls.h"
#include "globvars.h"
#include "graphics.h"
#include "harness/trace.h"
#include "opponent.h"
#include "pd/sys.h"
#include "piping.h"
#include "replay.h"
#include "s3/s3.h"
#include "s3/s3_brender.h"
#include "utility.h"
int gSound_detail_level;
int gVirgin_pass = 1;
int gOld_sound_detail_level = -1;
int gLast_tune;
int gRandom_MIDI_tunes[3];
int gRandom_Rockin_MIDI_tunes[3];
int gRandom_CDA_tunes[7];
int gCDA_is_playing;
int gServicing_sound;
int gSong_repeat_count;
int gSound_sources_inited;
int gMusic_available;
tS3_sound_tag gCDA_tag;
int gCD_fully_installed;
tS3_outlet_ptr gEffects_outlet;
tS3_outlet_ptr gCar_outlet;
tS3_outlet_ptr gEngine_outlet;
tS3_outlet_ptr gDriver_outlet;
tS3_outlet_ptr gPedestrians_outlet;
tS3_outlet_ptr gMusic_outlet;
tS3_sound_id gMIDI_id;
tS3_outlet_ptr gIndexed_outlets[6];
tU32 gLast_sound_service;
int gCD_is_disabled;
br_vector3 gCamera_left;
br_vector3 gCamera_position;
br_vector3 gOld_camera_position;
br_vector3 gCamera_velocity;
// IDA: void __cdecl UsePathFileToDetermineIfFullInstallation()
void UsePathFileToDetermineIfFullInstallation(void) {
// changed by dethrace for compatibility
// char line1[80];
// char line2[80];
// char line3[80];
// char path_file[80];
char line1[MAX_PATH_LENGTH];
char line2[MAX_PATH_LENGTH];
char line3[MAX_PATH_LENGTH];
char path_file[MAX_PATH_LENGTH];
FILE* fp;
strcpy(path_file
, gApplication_path
);
strcat(path_file
, gDir_separator
);
strcat(path_file
, "PATHS.TXT");
if (PDCheckDriveExists(path_file) != 0) {
fp
= fopen(path_file
, "rt");
if (fp) {
line1[0] = 0;
line2[0] = 0;
line3[0] = 0;
GetALineWithNoPossibleService(fp, (unsigned char*)line1);
GetALineWithNoPossibleService(fp, (unsigned char*)line2);
GetALineWithNoPossibleService(fp, (unsigned char*)line3);
if (strcmp(line3
, "Full") == 0) {
gCD_fully_installed = 1;
}
}
} else {
gCD_fully_installed = 1;
}
}
// IDA: void __cdecl InitSound()
void InitSound(void) {
tPath_name the_path;
//tS3_sound_tag tag; // Pierre-Marie Baty -- unused variable
int engine_channel_count;
int car_channel_count;
int ped_channel_count;
if (gVirgin_pass) {
PathCat(the_path, gApplication_path, "SOUND");
if (gProgram_state.sausage_eater_mode) {
PathCat(the_path, the_path, "KSOUND.TXT");
} else {
PathCat(the_path, the_path, "SOUND.TXT");
}
if (gSound_override) {
gSound_enabled = 0;
gSound_available = 0;
} else {
gSound_enabled = S3Init(the_path, gAusterity_mode) == 0;
gSound_available = gSound_enabled;
}
S3Set3DSoundEnvironment(0.14492753f, -1.0f, -1.0f); // Pierre-Marie Baty -- added type casts
gVirgin_pass = 0;
gCD_is_disabled = 0;
UsePathFileToDetermineIfFullInstallation();
}
if (gSound_available == 0) {
return;
}
switch (gSound_detail_level) {
case 0:
engine_channel_count = 2;
car_channel_count = 2;
ped_channel_count = 3;
break;
case 1:
engine_channel_count = 2;
car_channel_count = 3;
ped_channel_count = 4;
break;
case 2:
engine_channel_count = 6;
car_channel_count = 4;
ped_channel_count = 5;
break;
default:
TELL_ME_IF_WE_PASS_THIS_WAY();
}
if (gDriver_outlet == NULL) {
gDriver_outlet = S3CreateOutlet(1, 1);
gIndexed_outlets[0] = gDriver_outlet;
if (gDriver_outlet == NULL) {
gSound_available = 0;
return;
}
}
if (!gMusic_outlet) {
gMusic_outlet = S3CreateOutlet(1, 1);
gIndexed_outlets[2] = gMusic_outlet;
gMusic_available = gMusic_outlet != 0;
DRS3SetOutletVolume(gMusic_outlet, 42 * gProgram_state.music_volume);
}
if (gSound_detail_level != gOld_sound_detail_level) {
if (gCar_outlet) {
S3ReleaseOutlet(gCar_outlet);
gCar_outlet = 0;
}
if (gPedestrians_outlet) {
S3ReleaseOutlet(gPedestrians_outlet);
gPedestrians_outlet = 0;
}
if (gEngine_outlet) {
S3ReleaseOutlet(gEngine_outlet);
gEngine_outlet = 0;
}
if (gEngine_outlet == NULL) {
gEngine_outlet = S3CreateOutlet(engine_channel_count, engine_channel_count);
gIndexed_outlets[1] = gEngine_outlet;
if (!gEngine_outlet) {
gSound_available = 0;
return;
}
DRS3SetOutletVolume(gEngine_outlet, 42 * gProgram_state.effects_volume);
}
if (gCar_outlet == NULL) {
gCar_outlet = S3CreateOutlet(car_channel_count, car_channel_count);
gIndexed_outlets[3] = gCar_outlet;
if (!gCar_outlet) {
gSound_available = 0;
return;
}
DRS3SetOutletVolume(gCar_outlet, 42 * gProgram_state.effects_volume);
}
if (gPedestrians_outlet == NULL) {
gPedestrians_outlet = S3CreateOutlet(ped_channel_count, ped_channel_count);
gIndexed_outlets[4] = gPedestrians_outlet;
if (!gPedestrians_outlet) {
gSound_available = 0;
return;
}
DRS3SetOutletVolume(gPedestrians_outlet, 42 * gProgram_state.effects_volume);
}
}
if (gEffects_outlet == NULL) {
gEffects_outlet = S3CreateOutlet(2, 2);
gIndexed_outlets[5] = gEffects_outlet;
if (!gEffects_outlet) {
gSound_available = 0;
return;
}
DRS3SetOutletVolume(gEffects_outlet, 42 * gProgram_state.effects_volume);
}
gOld_sound_detail_level = gSound_detail_level;
SetSoundVolumes();
}
// IDA: tS3_sound_tag __usercall DRS3StartSound@<EAX>(tS3_outlet_ptr pOutlet@<EAX>, tS3_sound_id pSound@<EDX>)
tS3_sound_tag DRS3StartSound(tS3_outlet_ptr pOutlet, tS3_sound_id pSound) {
if (!gSound_enabled) {
return 0;
}
if (pSound != 1000 && (pSound < 3000 || pSound > 3007) && (pSound < 5300 || pSound > 5320)) {
PipeSingleSound(pOutlet, pSound, 0, 0, -1, 0);
}
return S3StartSound(pOutlet, pSound);
}
// IDA: tS3_sound_tag __usercall DRS3StartSoundNoPiping@<EAX>(tS3_outlet_ptr pOutlet@<EAX>, tS3_sound_id pSound@<EDX>)
tS3_sound_tag DRS3StartSoundNoPiping(tS3_outlet_ptr pOutlet, tS3_sound_id pSound) {
if (!gSound_enabled) {
return 0;
}
return S3StartSound(pOutlet, pSound);
}
// IDA: tS3_sound_tag __usercall DRS3StartSound2@<EAX>(tS3_outlet_ptr pOutlet@<EAX>, tS3_sound_id pSound@<EDX>, tS3_repeats pRepeats@<EBX>, tS3_volume pLVolume@<ECX>, tS3_volume pRVolume, tS3_pitch pPitch, tS3_speed pSpeed)
tS3_sound_tag DRS3StartSound2(tS3_outlet_ptr pOutlet, tS3_sound_id pSound, tS3_repeats pRepeats, tS3_volume pLVolume, tS3_volume pRVolume, tS3_pitch pPitch, tS3_speed pSpeed) {
LOG_TRACE("(%d, %d, %d, %d, %d, %d, %d)", pOutlet, pSound, pRepeats, pLVolume, pRVolume, pPitch, pSpeed);
if (!gSound_enabled) {
return 0;
}
if (pOutlet != gMusic_outlet
&& pSound != 1000
&& (pSound < 3000 || pSound > 3007)
&& (pSound < 5300 || pSound > 5320)
&& (pLVolume || pRVolume)) {
PipeSingleSound(pOutlet, pSound, pLVolume, pRVolume, pPitch, 0);
}
return S3StartSound2(pOutlet, pSound, pRepeats, pLVolume, pRVolume, pPitch, pSpeed);
}
// IDA: int __usercall DRS3ChangeVolume@<EAX>(tS3_sound_tag pSound_tag@<EAX>, tS3_volume pNew_volume@<EDX>)
int DRS3ChangeVolume(tS3_sound_tag pSound_tag, tS3_volume pNew_volume) {
LOG_TRACE("(%d, %d)", pSound_tag, pNew_volume);
if (gSound_enabled == 0) {
return 0;
}
return S3ChangeVolume(pSound_tag, pNew_volume);
}
// IDA: int __usercall DRS3ChangeLRVolume@<EAX>(tS3_sound_tag pSound_tag@<EAX>, tS3_volume pNew_Lvolume@<EDX>, tS3_volume pNew_Rvolume@<EBX>)
int DRS3ChangeLRVolume(tS3_sound_tag pSound_tag, tS3_volume pNew_Lvolume, tS3_volume pNew_Rvolume) {
LOG_TRACE("(%d, %d, %d)", pSound_tag, pNew_Lvolume, pNew_Rvolume);
NOT_IMPLEMENTED();
}
// IDA: int __usercall DRS3ChangePitch@<EAX>(tS3_sound_tag pTag@<EAX>, tS3_pitch pNew_pitch@<EDX>)
int DRS3ChangePitch(tS3_sound_tag pTag, tS3_pitch pNew_pitch) {
LOG_TRACE("(%d, %d)", pTag, pNew_pitch);
NOT_IMPLEMENTED();
}
// IDA: int __usercall DRS3ChangeSpeed@<EAX>(tS3_sound_tag pTag@<EAX>, tS3_pitch pNew_speed@<EDX>)
int DRS3ChangeSpeed(tS3_sound_tag pTag, tS3_pitch pNew_speed) {
LOG_TRACE("(%d, %d)", pTag, pNew_speed);
NOT_IMPLEMENTED();
return 0;
}
// IDA: int __usercall DRS3ChangePitchSpeed@<EAX>(tS3_sound_tag pTag@<EAX>, tS3_pitch pNew_pitch@<EDX>)
int DRS3ChangePitchSpeed(tS3_sound_tag pTag, tS3_pitch pNew_pitch) {
LOG_TRACE("(%d, %d)", pTag, pNew_pitch);
if (!gSound_enabled) {
return 0;
}
return S3ChangePitchSpeed(pTag, pNew_pitch);
}
// IDA: int __usercall DRS3StopSound@<EAX>(tS3_sound_tag pSound_tag@<EAX>)
int DRS3StopSound(tS3_sound_tag pSound_tag) {
LOG_TRACE("(%d)", pSound_tag);
if (!gSound_enabled) {
return 0;
}
return S3StopSound(pSound_tag);
}
// IDA: int __usercall DRS3LoadSound@<EAX>(tS3_sound_id pThe_sound@<EAX>)
int DRS3LoadSound(tS3_sound_id pThe_sound) {
LOG_TRACE("(%d)", pThe_sound);
if (!gSound_enabled) {
return 0;
}
return S3LoadSample(pThe_sound);
}
// IDA: int __usercall DRS3ReleaseSound@<EAX>(tS3_sound_id pThe_sound@<EAX>)
int DRS3ReleaseSound(tS3_sound_id pThe_sound) {
LOG_TRACE("(%d)", pThe_sound);
if (gSound_enabled == 0) {
return 0;
}
return S3ReleaseSound(pThe_sound);
}
// IDA: void __cdecl DRS3Service()
void DRS3Service(void) {
LOG_TRACE("()");
if (gSound_enabled) {
if (gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0) {
S3Service(1, 1);
} else {
S3Service(0, 1);
}
}
}
// IDA: int __usercall DRS3OutletSoundsPlaying@<EAX>(tS3_outlet_ptr pOutlet@<EAX>)
int DRS3OutletSoundsPlaying(tS3_outlet_ptr pOutlet) {
LOG_TRACE("(%d)", pOutlet);
NOT_IMPLEMENTED();
}
// IDA: int __usercall DRS3SoundStillPlaying@<EAX>(tS3_sound_tag pSound_tag@<EAX>)
int DRS3SoundStillPlaying(tS3_sound_tag pSound_tag) {
LOG_TRACE("(%d)", pSound_tag);
return gSound_enabled && S3SoundStillPlaying(pSound_tag);
}
// IDA: void __cdecl DRS3ShutDown()
void DRS3ShutDown(void) {
LOG_TRACE("()");
if (gSound_enabled) {
gSound_enabled = 0;
S3Shutdown();
}
}
// IDA: int __usercall DRS3SetOutletVolume@<EAX>(tS3_outlet_ptr pOutlet@<EAX>, tS3_volume pVolume@<EDX>)
int DRS3SetOutletVolume(tS3_outlet_ptr pOutlet, tS3_volume pVolume) {
LOG_TRACE("(%d, %d)", pOutlet, pVolume);
if (!gSound_enabled) {
return 0;
}
return S3SetOutletVolume(pOutlet, pVolume);
}
// IDA: int __usercall DRS3OverallVolume@<EAX>(tS3_volume pVolume@<EAX>)
int DRS3OverallVolume(tS3_volume pVolume) {
LOG_TRACE("(%d)", pVolume);
NOT_IMPLEMENTED();
}
// IDA: int __usercall DRS3StopOutletSound@<EAX>(tS3_outlet_ptr pOutlet@<EAX>)
int DRS3StopOutletSound(tS3_outlet_ptr pOutlet) {
if (!gSound_enabled) {
return 0;
}
return S3StopOutletSound(pOutlet);
}
// IDA: int __cdecl DRS3StopAllOutletSounds()
int DRS3StopAllOutletSounds(void) {
LOG_TRACE("()");
if (gSound_enabled) {
S3StopAllOutletSounds();
}
return 0;
}
// IDA: void __cdecl ToggleSoundEnable()
void ToggleSoundEnable(void) {
LOG_TRACE("()");
if (gSound_enabled) {
S3StopAllOutletSounds();
S3Disable();
gSound_enabled = 0;
} else {
S3Enable();
gSound_enabled = 1;
}
}
// IDA: void __cdecl SoundService()
void SoundService(void) {
//br_matrix34 mat; // Pierre-Marie Baty -- unused variable
if (gSound_enabled && !gServicing_sound) {
gServicing_sound = 1;
gLast_sound_service = PDGetTotalTime();
if (gCDA_tag) {
if (!S3IsCDAPlaying2()) {
StopMusic();
StartMusic();
}
}
DRS3Service();
gServicing_sound = 0;
}
}
// IDA: void __cdecl InitSoundSources()
void InitSoundSources(void) {
int cat;
int car_count;
int i;
int toggle;
tCar_spec* the_car;
LOG_TRACE("()");
toggle = 0;
if (!gSound_available) {
return;
}
if (!gSound_enabled) {
ToggleSoundEnable();
toggle = 1;
}
gCamera_position = *(br_vector3*)&gCamera_to_world.m[3][0];
gCamera_left.v[0] = gCamera_to_world.m[0][0] * -1.0;
gCamera_left.v[1] = gCamera_to_world.m[0][1] * -1.0;
gCamera_left.v[2] = gCamera_to_world.m[0][2] * -1.0;
S3BindListenerPositionBRender(&gCamera_position);
S3BindListenerVelocityBRender(&gCamera_velocity);
S3BindListenerLeftBRender(&gCamera_left);
if (!gSound_sources_inited) {
for (cat = eVehicle_self; cat <= eVehicle_rozzer; ++cat) {
if (cat) {
car_count = GetCarCount(cat);
} else {
car_count = 1;
}
for (i = 0; i < car_count; i++) {
PossibleService();
if (cat) {
the_car = GetCarSpec(cat, i);
} else {
the_car = &gProgram_state.current_car;
}
if (the_car->driver == eDriver_local_human || gSound_detail_level == 2 || cat == eVehicle_rozzer) {
the_car->sound_source = S3CreateSoundSourceBR(&the_car->pos, &the_car->velocity_bu_per_sec, gEngine_outlet);
if (the_car->sound_source) {
if (cat == eVehicle_rozzer) {
S3BindAmbientSoundToOutlet(gEngine_outlet, 5350, the_car->sound_source, 250.0, 0, 0, 0, 0x10000, 0x10000);
} else {
S3BindAmbientSoundToOutlet(gEngine_outlet, the_car->engine_noises[0], the_car->sound_source, 250.0, 0, 0, 0, 0x10000, 0x10000);
}
}
}
}
}
gSound_sources_inited = 1;
}
if (toggle) {
ToggleSoundEnable();
}
}
// IDA: void __cdecl DisposeSoundSources()
void DisposeSoundSources(void) {
int cat;
int car_count;
int i;
int toggle;
tCar_spec* the_car;
LOG_TRACE("()");
toggle = 0;
if (gSound_available == 0) {
return;
}
if (!gSound_enabled) {
ToggleSoundEnable();
toggle = 1;
}
if (gSound_sources_inited) {
DRS3StopOutletSound(gEngine_outlet);
if (gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0) {
S3Service(1, 0);
} else {
S3Service(0, 0);
}
for (cat = eVehicle_self; cat <= eVehicle_rozzer; cat++) {
if (cat) {
car_count = GetCarCount(cat);
} else {
car_count = 1;
}
for (i = 0; i < car_count; ++i) {
if (cat) {
the_car = GetCarSpec(cat, i);
} else {
the_car = &gProgram_state.current_car;
}
if (the_car->driver == eDriver_local_human || gSound_detail_level == 2 || cat == eVehicle_rozzer) {
if (the_car->sound_source) {
S3UpdateSoundSource(gEngine_outlet, -1, the_car->sound_source, 0.0f, 0, 0, 0, 0x10000, 0x10000);
S3ReleaseSoundSource(the_car->sound_source);
}
the_car->sound_source = NULL;
}
}
}
gSound_sources_inited = 0;
}
if (toggle) {
ToggleSoundEnable();
}
}
// IDA: tS3_sound_tag __usercall DRS3StartSound3D@<EAX>(tS3_outlet_ptr pOutlet@<EAX>, tS3_sound_id pSound@<EDX>, br_vector3 *pInitial_position@<EBX>, br_vector3 *pInitial_velocity@<ECX>, tS3_repeats pRepeats, tS3_volume pVolume, tS3_pitch pPitch, tS3_speed pSpeed)
tS3_sound_tag DRS3StartSound3D(tS3_outlet_ptr pOutlet, tS3_sound_id pSound, br_vector3* pInitial_position, br_vector3* pInitial_velocity, tS3_repeats pRepeats, tS3_volume pVolume, tS3_pitch pPitch, tS3_speed pSpeed) {
//tS3_sound_tag tag; // Pierre-Marie Baty -- unused variable
LOG_TRACE("(%d, %d, %p, %p, %d, %d, %d, %d)", pOutlet, pSound, pInitial_position, pInitial_velocity, pRepeats, pVolume, pPitch, pSpeed);
if (!gSound_enabled) {
return 0;
}
if (pVolume && pSound != 1000 && (pSound < 3000 || pSound > 3007) && (pSound < 5300 || pSound > 5320)) {
PipeSingleSound(pOutlet, pSound, pVolume, 0, pPitch, pInitial_position);
}
return S3StartSound3D(pOutlet, pSound, (tS3_vector3*)pInitial_position, (tS3_vector3*)pInitial_velocity, pRepeats, pVolume, pPitch, pSpeed);
}
// IDA: tS3_sound_tag __usercall DRS3StartSoundFromSource3@<EAX>(tS3_sound_source_ptr pSource@<EAX>, tS3_sound_id pSound@<EDX>, tS3_repeats pRepeats@<EBX>, tS3_volume pVolume@<ECX>, tS3_pitch pPitch, tS3_speed pSpeed)
tS3_sound_tag DRS3StartSoundFromSource3(tS3_sound_source_ptr pSource, tS3_sound_id pSound, tS3_repeats pRepeats, tS3_volume pVolume, tS3_pitch pPitch, tS3_speed pSpeed) {
//tS3_sound_tag tag; // Pierre-Marie Baty -- unused variable
LOG_TRACE("(%d, %d, %d, %d, %d, %d)", pSource, pSound, pRepeats, pVolume, pPitch, pSpeed);
NOT_IMPLEMENTED();
}
// IDA: tS3_sound_tag __usercall DRS3StartSoundFromSource@<EAX>(tS3_sound_source_ptr pSource@<EAX>, tS3_sound_id pSound@<EDX>)
tS3_sound_tag DRS3StartSoundFromSource(tS3_sound_source_ptr pSource, tS3_sound_id pSound) {
//tS3_sound_tag tag; // Pierre-Marie Baty -- unused variable
LOG_TRACE("(%d, %d)", pSource, pSound);
NOT_IMPLEMENTED();
}
// IDA: void __cdecl MungeEngineNoise()
void MungeEngineNoise(void) {
tCar_spec* the_car;
tU32 pitch;
int vol;
int cat;
int car_count;
int i;
int stop_all;
int type_of_engine_noise;
//tS3_sound_id engine_noise; // Pierre-Marie Baty -- unused variable
// added by dethrace
tU32 frame_period;
frame_period = gFrame_period;
#ifdef DETHRACE_FIX_BUGS
// At framerates higher than 30, `gCamera_velocity` is not stable enough and causes the player car audio to stumble
// as the pitch shifts up and down while applying doppler effect in `S3Calculate3D`.
// We avoid the issue by only updating the engine sounds every MUNGE_ENGINE_INTERVAL ms
static tU32 dethrace_last_executed = 0;
tU32 now = GetTotalTime();
if (now - dethrace_last_executed < MUNGE_ENGINE_INTERVAL) {
return;
}
frame_period = now - dethrace_last_executed;
dethrace_last_executed = now;
#endif
type_of_engine_noise = 0;
if (gSound_available == 0 || gProgram_state.racing == 0) {
return;
}
BrVector3Copy(&gCamera_position, (br_vector3*)&gCamera_to_world.m[3][0]);
BrVector3Negate(&gCamera_left, (br_vector3*)&gCamera_to_world.m[0][0]);
BrVector3Sub(&gCamera_velocity, &gCamera_position, &gOld_camera_position);
if (frame_period) {
BrVector3InvScale(&gCamera_velocity, &gCamera_velocity, ((float)frame_period / 1000.0f));
} else {
BrVector3Set(&gCamera_velocity, 0.0f, 0.0f, 0.0f);
}
BrVector3Copy(&gOld_camera_position, &gCamera_position);
stop_all = (gAction_replay_mode && (fabsf(GetReplayRate()) > 1.0f || GetReplayRate() == 0.0f)) || gFaded_palette || gPalette_fade_time;
for (cat = eVehicle_self; cat <= eVehicle_rozzer; cat++) {
if (cat) {
car_count = GetCarCount(cat);
} else {
car_count = 1;
}
for (i = 0; i < car_count; i++) {
if (cat) {
the_car = GetCarSpec(cat, i);
} else {
the_car = &gProgram_state.current_car;
}
if (the_car->driver == eDriver_local_human || gSound_detail_level == 2 || cat == eVehicle_rozzer) {
if (stop_all || !the_car->active || the_car->knackered || (cat == eVehicle_rozzer && BrVector3LengthSquared(&the_car->v) < 0.0001f)) {
vol = 0;
pitch = 0x10000;
} else {
BrVector3InvScale(&the_car->velocity_bu_per_sec, &the_car->v, WORLD_SCALE);
if (cat == eVehicle_rozzer) {
vol = 255;
pitch = 0x10000;
} else {
if (the_car->last_special_volume) {
type_of_engine_noise = the_car->last_special_volume->engine_noise_index;
}
pitch = the_car->revs * 10.0f + 40960.0f;
if (gAction_replay_mode) {
pitch = fabsf(GetReplayRate()) * pitch;
}
if (type_of_engine_noise == 1) {
pitch = pitch * 0.75f;
} else if (type_of_engine_noise == 2) {
pitch = pitch * 0.55f;
}
pitch = MAX(pitch, 4096);
pitch = MIN(pitch, 131072);
vol = the_car->revs * 0.001f + 64.0f;
if (type_of_engine_noise == 1) {
vol = vol * 5.0f;
} else if (type_of_engine_noise == 2) {
vol = vol * 2.0f;
} else {
vol = vol * 2.5f;
}
vol = MIN(vol, 255);
}
}
S3UpdateSoundSource(gEngine_outlet, -1, the_car->sound_source, gAction_replay_mode == 0 ? 250.0f : 300.0f, 0, 0, vol, pitch, 0x10000);
}
}
}
SoundService();
}
// IDA: void __cdecl SetSoundVolumes()
void SetSoundVolumes(void) {
if (!gSound_enabled) {
return;
}
if (gEffects_outlet != NULL) {
DRS3SetOutletVolume(gEffects_outlet, 42 * gProgram_state.effects_volume);
}
DRS3SetOutletVolume(gCar_outlet, 42 * gProgram_state.effects_volume);
DRS3SetOutletVolume(gEngine_outlet, 42 * gProgram_state.effects_volume);
DRS3SetOutletVolume(gDriver_outlet, 42 * gProgram_state.effects_volume);
DRS3SetOutletVolume(gPedestrians_outlet, 42 * gProgram_state.effects_volume);
DRS3SetOutletVolume(gMusic_outlet, 42 * gProgram_state.music_volume);
}
// IDA: tS3_outlet_ptr __usercall GetOutletFromIndex@<EAX>(int pIndex@<EAX>)
tS3_outlet_ptr GetOutletFromIndex(int pIndex) {
LOG_TRACE("(%d)", pIndex);
return gIndexed_outlets[pIndex];
}
// IDA: int __usercall GetIndexFromOutlet@<EAX>(tS3_outlet_ptr pOutlet@<EAX>)
int GetIndexFromOutlet(tS3_outlet_ptr pOutlet) {
int i;
LOG_TRACE("(%d)", pOutlet);
for (i = 0; i < COUNT_OF(gIndexed_outlets); i++) {
if (gIndexed_outlets[i] == pOutlet) {
return i;
}
}
return 0;
}
// IDA: int __usercall DRS3StartCDA@<EAX>(tS3_sound_id pCDA_id@<EAX>)
int DRS3StartCDA(tS3_sound_id pCDA_id) {
LOG_TRACE("(%d)", pCDA_id);
NOT_IMPLEMENTED();
}
// IDA: int __cdecl DRS3StopCDA()
int DRS3StopCDA(void) {
LOG_TRACE("()");
NOT_IMPLEMENTED();
}
// IDA: void __cdecl StartMusic()
void StartMusic(void) {
}
// IDA: void __cdecl StopMusic()
void StopMusic(void) {
}