mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-05-02 06:37:58 +03:00
mnsound: merge to sound
This commit is contained in:
parent
af767b58d1
commit
aefcc47c96
9 changed files with 446 additions and 463 deletions
|
@ -9,7 +9,6 @@
|
||||||
#include "game/items.h"
|
#include "game/items.h"
|
||||||
#include "game/lara.h"
|
#include "game/lara.h"
|
||||||
#include "game/lot.h"
|
#include "game/lot.h"
|
||||||
#include "game/mnsound.h"
|
|
||||||
#include "game/objects/keyhole.h"
|
#include "game/objects/keyhole.h"
|
||||||
#include "game/objects/puzzle_hole.h"
|
#include "game/objects/puzzle_hole.h"
|
||||||
#include "game/objects/switch.h"
|
#include "game/objects/switch.h"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "game/game.h"
|
#include "game/game.h"
|
||||||
#include "game/lara.h"
|
#include "game/lara.h"
|
||||||
#include "game/mnsound.h"
|
|
||||||
#include "game/option.h"
|
#include "game/option.h"
|
||||||
#include "game/overlay.h"
|
#include "game/overlay.h"
|
||||||
#include "game/savegame.h"
|
#include "game/savegame.h"
|
||||||
|
|
|
@ -1,440 +0,0 @@
|
||||||
#include "game/mnsound.h"
|
|
||||||
|
|
||||||
#include "3dsystem/phd_math.h"
|
|
||||||
#include "game/game.h"
|
|
||||||
#include "global/vars.h"
|
|
||||||
#include "specific/init.h"
|
|
||||||
#include "specific/sndpc.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define SOUND_RANGE 8
|
|
||||||
#define SOUND_RADIUS (SOUND_RANGE << 10)
|
|
||||||
#define SOUND_RANGE_MULT_CONSTANT ((int32_t)(32768 / SOUND_RADIUS))
|
|
||||||
#define MAX_VOLUME_CHANGE 0x2000
|
|
||||||
#define MAX_PITCH_CHANGE 10
|
|
||||||
#define MN_NOT_AUDIBLE -1
|
|
||||||
|
|
||||||
typedef enum SOUND_MODE {
|
|
||||||
SOUND_WAIT = 0,
|
|
||||||
SOUND_RESTART = 1,
|
|
||||||
SOUND_AMBIENT = 2,
|
|
||||||
} SOUND_MODE;
|
|
||||||
|
|
||||||
typedef enum SOUND_FLAG {
|
|
||||||
MN_FX_UNUSED = 0,
|
|
||||||
MN_FX_USED = 1 << 0,
|
|
||||||
MN_FX_AMBIENT = 1 << 1,
|
|
||||||
MN_FX_RESTARTED = 1 << 2,
|
|
||||||
MN_FX_NO_REVERB = 1 << 3,
|
|
||||||
} SOUND_FLAG;
|
|
||||||
|
|
||||||
typedef enum SAMPLE_FLAG {
|
|
||||||
NO_PAN = 1 << 12,
|
|
||||||
PITCH_WIBBLE = 1 << 13,
|
|
||||||
VOLUME_WIBBLE = 1 << 14,
|
|
||||||
} SAMPLE_FLAG;
|
|
||||||
|
|
||||||
static MN_SFX_PLAY_INFO SFXPlaying[MAX_PLAYING_FX] = { 0 };
|
|
||||||
static int32_t MnSoundMasterVolumeDefault = 32;
|
|
||||||
static int16_t MnAmbientLookup[MAX_AMBIENT_FX] = { -1 };
|
|
||||||
static int32_t MnAmbientLookupIdx = 0;
|
|
||||||
|
|
||||||
static MN_SFX_PLAY_INFO *mn_get_fx_slot(
|
|
||||||
int32_t sfx_num, uint32_t loudness, PHD_3DPOS *pos, int16_t mode);
|
|
||||||
static void mn_get_sound_params(MN_SFX_PLAY_INFO *slot);
|
|
||||||
static void mn_clear_fx_slot(MN_SFX_PLAY_INFO *slot);
|
|
||||||
static void mn_clear_handles(MN_SFX_PLAY_INFO *slot);
|
|
||||||
|
|
||||||
void mn_reset_sound_effects()
|
|
||||||
{
|
|
||||||
if (!SoundIsActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MnSoundMasterVolume = MnSoundMasterVolumeDefault;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
|
||||||
mn_clear_fx_slot(&SFXPlaying[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
S_SoundStopAllSamples();
|
|
||||||
|
|
||||||
MnAmbientLookupIdx = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_SAMPLES; i++) {
|
|
||||||
if (SampleLUT[i] < 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SAMPLE_INFO *s = &SampleInfos[SampleLUT[i]];
|
|
||||||
if (s->volume < 0) {
|
|
||||||
S_ExitSystemFmt(
|
|
||||||
"sample info for effect %d has incorrect volume(%d)", i,
|
|
||||||
s->volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((s->flags & 3) == SOUND_AMBIENT) {
|
|
||||||
if (MnAmbientLookupIdx >= MAX_AMBIENT_FX) {
|
|
||||||
S_ExitSystem("Ran out of ambient fx slots in "
|
|
||||||
"mn_reset_sound_effects()");
|
|
||||||
}
|
|
||||||
MnAmbientLookup[MnAmbientLookupIdx] = i;
|
|
||||||
MnAmbientLookupIdx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mn_sound_effect(int32_t sfx_num, PHD_3DPOS *pos, uint32_t flags)
|
|
||||||
{
|
|
||||||
if (!SoundIsActive) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags != SPM_ALWAYS
|
|
||||||
&& (flags & SPM_UNDERWATER)
|
|
||||||
!= (RoomInfo[Camera.pos.room_number].flags & RF_UNDERWATER)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SampleLUT[sfx_num] < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SAMPLE_INFO *s = &SampleInfos[SampleLUT[sfx_num]];
|
|
||||||
if (s->randomness && GetRandomDraw() > (int32_t)s->randomness) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags = 0;
|
|
||||||
int32_t pan = 0x7FFF;
|
|
||||||
int32_t mode = s->flags & 3;
|
|
||||||
uint32_t distance;
|
|
||||||
if (pos) {
|
|
||||||
int32_t x = pos->x - Camera.target.x;
|
|
||||||
int32_t y = pos->y - Camera.target.y;
|
|
||||||
int32_t z = pos->z - Camera.target.z;
|
|
||||||
if (ABS(x) > SOUND_RADIUS || ABS(y) > SOUND_RADIUS
|
|
||||||
|| ABS(z) > SOUND_RADIUS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
distance = SQUARE(x) + SQUARE(y) + SQUARE(z);
|
|
||||||
if (!distance) {
|
|
||||||
pan = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
distance = 0;
|
|
||||||
pan = 0;
|
|
||||||
flags = MN_FX_NO_REVERB;
|
|
||||||
}
|
|
||||||
distance = phd_sqrt(distance);
|
|
||||||
|
|
||||||
int32_t volume = s->volume - distance * SOUND_RANGE_MULT_CONSTANT;
|
|
||||||
if (s->flags & VOLUME_WIBBLE) {
|
|
||||||
volume -= GetRandomDraw() * MAX_VOLUME_CHANGE >> 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->flags & NO_PAN) {
|
|
||||||
pan = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volume <= 0 && mode != SOUND_AMBIENT) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pan) {
|
|
||||||
int16_t angle =
|
|
||||||
phd_atan(pos->z - LaraItem->pos.z, pos->x - LaraItem->pos.x);
|
|
||||||
angle -= LaraItem->pos.y_rot + Lara.torso_y_rot + Lara.head_y_rot;
|
|
||||||
pan = angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t pitch = 100;
|
|
||||||
if (s->flags & PITCH_WIBBLE) {
|
|
||||||
pitch +=
|
|
||||||
((GetRandomDraw() * MAX_PITCH_CHANGE) / 16384) - MAX_PITCH_CHANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t vars = (s->flags >> 2) & 15;
|
|
||||||
int32_t sfx_id = s->number;
|
|
||||||
if (vars != 1) {
|
|
||||||
sfx_id += (GetRandomDraw() * vars) / 0x8000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volume > 0x7FFF) {
|
|
||||||
volume = 0x7FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case SOUND_WAIT: {
|
|
||||||
MN_SFX_PLAY_INFO *fxslot = mn_get_fx_slot(sfx_num, 0, pos, mode);
|
|
||||||
if (!fxslot) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (fxslot->mn_flags & MN_FX_RESTARTED) {
|
|
||||||
fxslot->mn_flags &= 0xFFFF - MN_FX_RESTARTED;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fxslot->handle = S_SoundPlaySample(sfx_id, volume, pitch, pan);
|
|
||||||
if (fxslot->handle == SOUND_INVALID_HANDLE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mn_clear_handles(fxslot);
|
|
||||||
fxslot->mn_flags = flags | MN_FX_USED;
|
|
||||||
fxslot->fxnum = sfx_num;
|
|
||||||
fxslot->pos = pos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SOUND_RESTART: {
|
|
||||||
MN_SFX_PLAY_INFO *fxslot = mn_get_fx_slot(sfx_num, 0, pos, mode);
|
|
||||||
if (!fxslot) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (fxslot->mn_flags & MN_FX_RESTARTED) {
|
|
||||||
S_SoundStopSample(fxslot->handle);
|
|
||||||
fxslot->handle = S_SoundPlaySample(sfx_id, volume, pitch, pan);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fxslot->handle = S_SoundPlaySample(sfx_id, volume, pitch, pan);
|
|
||||||
if (fxslot->handle == SOUND_INVALID_HANDLE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mn_clear_handles(fxslot);
|
|
||||||
fxslot->mn_flags = flags | MN_FX_USED;
|
|
||||||
fxslot->fxnum = sfx_num;
|
|
||||||
fxslot->pos = pos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SOUND_AMBIENT: {
|
|
||||||
uint32_t loudness = distance;
|
|
||||||
MN_SFX_PLAY_INFO *fxslot = mn_get_fx_slot(sfx_num, loudness, pos, mode);
|
|
||||||
if (!fxslot) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fxslot->pos = pos;
|
|
||||||
if (fxslot->mn_flags & MN_FX_AMBIENT) {
|
|
||||||
if (volume > 0) {
|
|
||||||
fxslot->loudness = loudness;
|
|
||||||
fxslot->pan = pan;
|
|
||||||
fxslot->volume = volume;
|
|
||||||
} else {
|
|
||||||
fxslot->loudness = MN_NOT_AUDIBLE;
|
|
||||||
fxslot->volume = 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volume > 0) {
|
|
||||||
fxslot->handle =
|
|
||||||
S_SoundPlaySampleLooped(sfx_id, volume, pitch, pan);
|
|
||||||
if (fxslot->handle == SOUND_INVALID_HANDLE) {
|
|
||||||
mn_clear_fx_slot(fxslot);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mn_clear_handles(fxslot);
|
|
||||||
fxslot->loudness = loudness;
|
|
||||||
fxslot->fxnum = sfx_num;
|
|
||||||
fxslot->pan = pan;
|
|
||||||
fxslot->volume = volume;
|
|
||||||
fxslot->mn_flags |= MN_FX_AMBIENT | MN_FX_USED;
|
|
||||||
fxslot->pos = pos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fxslot->loudness = MN_NOT_AUDIBLE;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MN_SFX_PLAY_INFO *mn_get_fx_slot(
|
|
||||||
int32_t sfx_num, uint32_t loudness, PHD_3DPOS *pos, int16_t mode)
|
|
||||||
{
|
|
||||||
switch (mode) {
|
|
||||||
case SOUND_WAIT:
|
|
||||||
case SOUND_RESTART: {
|
|
||||||
MN_SFX_PLAY_INFO *last_free_slot = NULL;
|
|
||||||
for (int i = MnAmbientLookupIdx; i < MAX_PLAYING_FX; i++) {
|
|
||||||
MN_SFX_PLAY_INFO *result = &SFXPlaying[i];
|
|
||||||
if ((result->mn_flags & MN_FX_USED) && result->fxnum == sfx_num
|
|
||||||
&& result->pos == pos) {
|
|
||||||
result->mn_flags |= MN_FX_RESTARTED;
|
|
||||||
return result;
|
|
||||||
} else if (result->mn_flags == MN_FX_UNUSED) {
|
|
||||||
last_free_slot = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return last_free_slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SOUND_AMBIENT:
|
|
||||||
for (int i = 0; i < MAX_AMBIENT_FX; i++) {
|
|
||||||
if (MnAmbientLookup[i] == sfx_num) {
|
|
||||||
MN_SFX_PLAY_INFO *result = &SFXPlaying[i];
|
|
||||||
if (result->mn_flags != MN_FX_UNUSED
|
|
||||||
&& result->loudness <= loudness) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mn_reset_ambient_loudness()
|
|
||||||
{
|
|
||||||
if (!SoundIsActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MnAmbientLookupIdx; i++) {
|
|
||||||
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
|
||||||
slot->loudness = MN_NOT_AUDIBLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mn_stop_ambient_samples()
|
|
||||||
{
|
|
||||||
if (!SoundIsActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MnAmbientLookupIdx; i++) {
|
|
||||||
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
|
||||||
if (S_SoundSampleIsPlaying(slot->handle)) {
|
|
||||||
S_SoundStopSample(slot->handle);
|
|
||||||
mn_clear_fx_slot(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mn_update_sound_effects()
|
|
||||||
{
|
|
||||||
if (!SoundIsActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
|
||||||
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
|
||||||
if (slot->mn_flags & MN_FX_USED) {
|
|
||||||
if (slot->mn_flags & MN_FX_AMBIENT) {
|
|
||||||
if (slot->loudness != MN_NOT_AUDIBLE
|
|
||||||
&& slot->handle != SOUND_INVALID_HANDLE) {
|
|
||||||
S_SoundSetPanAndVolume(
|
|
||||||
slot->handle, slot->pan, slot->volume);
|
|
||||||
} else {
|
|
||||||
if (slot->handle != SOUND_INVALID_HANDLE) {
|
|
||||||
S_SoundStopSample(slot->handle);
|
|
||||||
}
|
|
||||||
mn_clear_fx_slot(slot);
|
|
||||||
}
|
|
||||||
} else if (S_SoundSampleIsPlaying(slot->handle)) {
|
|
||||||
if (slot->pos != NULL) {
|
|
||||||
mn_get_sound_params(slot);
|
|
||||||
if (slot->volume > 0
|
|
||||||
&& slot->handle != SOUND_INVALID_HANDLE) {
|
|
||||||
S_SoundSetPanAndVolume(
|
|
||||||
slot->handle, slot->pan, slot->volume);
|
|
||||||
} else {
|
|
||||||
if (slot->handle != SOUND_INVALID_HANDLE) {
|
|
||||||
S_SoundStopSample(slot->handle);
|
|
||||||
}
|
|
||||||
mn_clear_fx_slot(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mn_clear_fx_slot(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mn_get_sound_params(MN_SFX_PLAY_INFO *slot)
|
|
||||||
{
|
|
||||||
SAMPLE_INFO *s = &SampleInfos[SampleLUT[slot->fxnum]];
|
|
||||||
|
|
||||||
int32_t x = slot->pos->x - Camera.target.x;
|
|
||||||
int32_t y = slot->pos->y - Camera.target.y;
|
|
||||||
int32_t z = slot->pos->z - Camera.target.z;
|
|
||||||
if (ABS(x) > SOUND_RADIUS || ABS(y) > SOUND_RADIUS
|
|
||||||
|| ABS(z) > SOUND_RADIUS) {
|
|
||||||
slot->volume = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t distance = SQUARE(x) + SQUARE(y) + SQUARE(z);
|
|
||||||
int32_t volume = s->volume - phd_sqrt(distance) * SOUND_RANGE_MULT_CONSTANT;
|
|
||||||
if (volume < 0) {
|
|
||||||
slot->volume = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volume > 0x7FFF) {
|
|
||||||
volume = 0x7FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
slot->volume = volume;
|
|
||||||
|
|
||||||
if (!distance || (s->flags & NO_PAN)) {
|
|
||||||
slot->pan = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t angle = phd_atan(
|
|
||||||
slot->pos->z - LaraItem->pos.z, slot->pos->x - LaraItem->pos.x);
|
|
||||||
angle -= LaraItem->pos.y_rot + Lara.torso_y_rot + Lara.head_y_rot;
|
|
||||||
slot->pan = angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mn_stop_sound_effect(int sfx_num, PHD_3DPOS *pos)
|
|
||||||
{
|
|
||||||
if (!SoundIsActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
|
||||||
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
|
||||||
if ((slot->mn_flags & MN_FX_USED)
|
|
||||||
&& S_SoundSampleIsPlaying(slot->handle)) {
|
|
||||||
if ((!pos && slot->fxnum == sfx_num)
|
|
||||||
|| (pos && sfx_num >= 0 && slot->fxnum == sfx_num)
|
|
||||||
|| (pos && sfx_num < 0)) {
|
|
||||||
S_SoundStopSample(slot->handle);
|
|
||||||
mn_clear_fx_slot(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mn_adjust_master_volume(int8_t volume)
|
|
||||||
{
|
|
||||||
MnSoundMasterVolumeDefault = volume & 0x3F;
|
|
||||||
MnSoundMasterVolume = volume & 0x3F;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mn_clear_fx_slot(MN_SFX_PLAY_INFO *slot)
|
|
||||||
{
|
|
||||||
slot->handle = SOUND_INVALID_HANDLE;
|
|
||||||
slot->pos = NULL;
|
|
||||||
slot->mn_flags = 0;
|
|
||||||
slot->volume = 0;
|
|
||||||
slot->pan = 0;
|
|
||||||
slot->loudness = MN_NOT_AUDIBLE;
|
|
||||||
slot->fxnum = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mn_clear_handles(MN_SFX_PLAY_INFO *slot)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
|
||||||
MN_SFX_PLAY_INFO *rslot = &SFXPlaying[i];
|
|
||||||
if (rslot != slot && rslot->handle == slot->handle) {
|
|
||||||
rslot->handle = SOUND_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
#ifndef T1M_GAME_MNSOUND_H
|
|
||||||
#define T1M_GAME_MNSOUND_H
|
|
||||||
|
|
||||||
#include "global/types.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void mn_reset_sound_effects();
|
|
||||||
bool mn_sound_effect(int32_t sfx_num, PHD_3DPOS *pos, uint32_t flags);
|
|
||||||
void mn_reset_ambient_loudness();
|
|
||||||
void mn_stop_ambient_samples();
|
|
||||||
void mn_update_sound_effects();
|
|
||||||
void mn_stop_sound_effect(int sfx_num, PHD_3DPOS *pos);
|
|
||||||
void mn_adjust_master_volume(int8_t volume);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "game/game.h"
|
#include "game/game.h"
|
||||||
#include "game/inv.h"
|
#include "game/inv.h"
|
||||||
#include "game/mnsound.h"
|
|
||||||
#include "game/requester.h"
|
#include "game/requester.h"
|
||||||
#include "game/settings.h"
|
#include "game/settings.h"
|
||||||
#include "game/sound.h"
|
#include "game/sound.h"
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "game/mnsound.h"
|
|
||||||
#include "game/option.h"
|
#include "game/option.h"
|
||||||
|
#include "game/sound.h"
|
||||||
#include "global/const.h"
|
#include "global/const.h"
|
||||||
#include "global/types.h"
|
#include "global/types.h"
|
||||||
#include "global/vars.h"
|
#include "global/vars.h"
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include "game/items.h"
|
#include "game/items.h"
|
||||||
#include "game/lara.h"
|
#include "game/lara.h"
|
||||||
#include "game/lot.h"
|
#include "game/lot.h"
|
||||||
#include "game/mnsound.h"
|
|
||||||
#include "game/objects/boat.h"
|
#include "game/objects/boat.h"
|
||||||
#include "game/objects/bridge.h"
|
#include "game/objects/bridge.h"
|
||||||
#include "game/objects/cabin.h"
|
#include "game/objects/cabin.h"
|
||||||
|
@ -60,6 +59,7 @@
|
||||||
#include "game/objects/trapdoor.h"
|
#include "game/objects/trapdoor.h"
|
||||||
#include "game/overlay.h"
|
#include "game/overlay.h"
|
||||||
#include "game/savegame.h"
|
#include "game/savegame.h"
|
||||||
|
#include "game/sound.h"
|
||||||
#include "game/text.h"
|
#include "game/text.h"
|
||||||
#include "game/traps/damocles_sword.h"
|
#include "game/traps/damocles_sword.h"
|
||||||
#include "game/traps/dart.h"
|
#include "game/traps/dart.h"
|
||||||
|
|
436
src/game/sound.c
436
src/game/sound.c
|
@ -1,12 +1,54 @@
|
||||||
#include "game/sound.h"
|
#include "game/sound.h"
|
||||||
|
|
||||||
#include "game/mnsound.h"
|
#include "3dsystem/phd_math.h"
|
||||||
|
#include "game/game.h"
|
||||||
#include "global/vars.h"
|
#include "global/vars.h"
|
||||||
|
#include "specific/init.h"
|
||||||
|
#include "specific/sndpc.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define FLIPFLAG 0x40
|
#define FLIPFLAG 0x40
|
||||||
#define UNFLIPFLAG 0x80
|
#define UNFLIPFLAG 0x80
|
||||||
|
#define SOUND_RANGE 8
|
||||||
|
#define SOUND_RADIUS (SOUND_RANGE << 10)
|
||||||
|
#define SOUND_RANGE_MULT_CONSTANT ((int32_t)(32768 / SOUND_RADIUS))
|
||||||
|
#define MAX_VOLUME_CHANGE 0x2000
|
||||||
|
#define MAX_PITCH_CHANGE 10
|
||||||
|
#define MN_NOT_AUDIBLE -1
|
||||||
|
|
||||||
|
typedef enum SOUND_MODE {
|
||||||
|
SOUND_WAIT = 0,
|
||||||
|
SOUND_RESTART = 1,
|
||||||
|
SOUND_AMBIENT = 2,
|
||||||
|
} SOUND_MODE;
|
||||||
|
|
||||||
|
typedef enum SOUND_FLAG {
|
||||||
|
MN_FX_UNUSED = 0,
|
||||||
|
MN_FX_USED = 1 << 0,
|
||||||
|
MN_FX_AMBIENT = 1 << 1,
|
||||||
|
MN_FX_RESTARTED = 1 << 2,
|
||||||
|
MN_FX_NO_REVERB = 1 << 3,
|
||||||
|
} SOUND_FLAG;
|
||||||
|
|
||||||
|
typedef enum SAMPLE_FLAG {
|
||||||
|
NO_PAN = 1 << 12,
|
||||||
|
PITCH_WIBBLE = 1 << 13,
|
||||||
|
VOLUME_WIBBLE = 1 << 14,
|
||||||
|
} SAMPLE_FLAG;
|
||||||
|
|
||||||
|
static MN_SFX_PLAY_INFO SFXPlaying[MAX_PLAYING_FX] = { 0 };
|
||||||
|
static int32_t MnSoundMasterVolumeDefault = 32;
|
||||||
|
static int16_t MnAmbientLookup[MAX_AMBIENT_FX] = { -1 };
|
||||||
|
static int32_t MnAmbientLookupIdx = 0;
|
||||||
|
|
||||||
|
static MN_SFX_PLAY_INFO *mn_get_fx_slot(
|
||||||
|
int32_t sfx_num, uint32_t loudness, PHD_3DPOS *pos, int16_t mode);
|
||||||
|
static void mn_get_sound_params(MN_SFX_PLAY_INFO *slot);
|
||||||
|
static void mn_clear_fx_slot(MN_SFX_PLAY_INFO *slot);
|
||||||
|
static void mn_clear_handles(MN_SFX_PLAY_INFO *slot);
|
||||||
|
|
||||||
void Sound_UpdateEffects()
|
void Sound_UpdateEffects()
|
||||||
{
|
{
|
||||||
|
@ -39,3 +81,395 @@ void Sound_StopEffect(int32_t sfx_num, PHD_3DPOS *pos)
|
||||||
{
|
{
|
||||||
mn_stop_sound_effect(sfx_num, pos);
|
mn_stop_sound_effect(sfx_num, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mn_reset_sound_effects()
|
||||||
|
{
|
||||||
|
if (!SoundIsActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MnSoundMasterVolume = MnSoundMasterVolumeDefault;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
||||||
|
mn_clear_fx_slot(&SFXPlaying[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
S_SoundStopAllSamples();
|
||||||
|
|
||||||
|
MnAmbientLookupIdx = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_SAMPLES; i++) {
|
||||||
|
if (SampleLUT[i] < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SAMPLE_INFO *s = &SampleInfos[SampleLUT[i]];
|
||||||
|
if (s->volume < 0) {
|
||||||
|
S_ExitSystemFmt(
|
||||||
|
"sample info for effect %d has incorrect volume(%d)", i,
|
||||||
|
s->volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((s->flags & 3) == SOUND_AMBIENT) {
|
||||||
|
if (MnAmbientLookupIdx >= MAX_AMBIENT_FX) {
|
||||||
|
S_ExitSystem("Ran out of ambient fx slots in "
|
||||||
|
"mn_reset_sound_effects()");
|
||||||
|
}
|
||||||
|
MnAmbientLookup[MnAmbientLookupIdx] = i;
|
||||||
|
MnAmbientLookupIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mn_sound_effect(int32_t sfx_num, PHD_3DPOS *pos, uint32_t flags)
|
||||||
|
{
|
||||||
|
if (!SoundIsActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags != SPM_ALWAYS
|
||||||
|
&& (flags & SPM_UNDERWATER)
|
||||||
|
!= (RoomInfo[Camera.pos.room_number].flags & RF_UNDERWATER)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SampleLUT[sfx_num] < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SAMPLE_INFO *s = &SampleInfos[SampleLUT[sfx_num]];
|
||||||
|
if (s->randomness && GetRandomDraw() > (int32_t)s->randomness) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
int32_t pan = 0x7FFF;
|
||||||
|
int32_t mode = s->flags & 3;
|
||||||
|
uint32_t distance;
|
||||||
|
if (pos) {
|
||||||
|
int32_t x = pos->x - Camera.target.x;
|
||||||
|
int32_t y = pos->y - Camera.target.y;
|
||||||
|
int32_t z = pos->z - Camera.target.z;
|
||||||
|
if (ABS(x) > SOUND_RADIUS || ABS(y) > SOUND_RADIUS
|
||||||
|
|| ABS(z) > SOUND_RADIUS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
distance = SQUARE(x) + SQUARE(y) + SQUARE(z);
|
||||||
|
if (!distance) {
|
||||||
|
pan = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
distance = 0;
|
||||||
|
pan = 0;
|
||||||
|
flags = MN_FX_NO_REVERB;
|
||||||
|
}
|
||||||
|
distance = phd_sqrt(distance);
|
||||||
|
|
||||||
|
int32_t volume = s->volume - distance * SOUND_RANGE_MULT_CONSTANT;
|
||||||
|
if (s->flags & VOLUME_WIBBLE) {
|
||||||
|
volume -= GetRandomDraw() * MAX_VOLUME_CHANGE >> 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->flags & NO_PAN) {
|
||||||
|
pan = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume <= 0 && mode != SOUND_AMBIENT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pan) {
|
||||||
|
int16_t angle =
|
||||||
|
phd_atan(pos->z - LaraItem->pos.z, pos->x - LaraItem->pos.x);
|
||||||
|
angle -= LaraItem->pos.y_rot + Lara.torso_y_rot + Lara.head_y_rot;
|
||||||
|
pan = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t pitch = 100;
|
||||||
|
if (s->flags & PITCH_WIBBLE) {
|
||||||
|
pitch +=
|
||||||
|
((GetRandomDraw() * MAX_PITCH_CHANGE) / 16384) - MAX_PITCH_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t vars = (s->flags >> 2) & 15;
|
||||||
|
int32_t sfx_id = s->number;
|
||||||
|
if (vars != 1) {
|
||||||
|
sfx_id += (GetRandomDraw() * vars) / 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume > 0x7FFF) {
|
||||||
|
volume = 0x7FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case SOUND_WAIT: {
|
||||||
|
MN_SFX_PLAY_INFO *fxslot = mn_get_fx_slot(sfx_num, 0, pos, mode);
|
||||||
|
if (!fxslot) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fxslot->mn_flags & MN_FX_RESTARTED) {
|
||||||
|
fxslot->mn_flags &= 0xFFFF - MN_FX_RESTARTED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
fxslot->handle = S_SoundPlaySample(sfx_id, volume, pitch, pan);
|
||||||
|
if (fxslot->handle == SOUND_INVALID_HANDLE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mn_clear_handles(fxslot);
|
||||||
|
fxslot->mn_flags = flags | MN_FX_USED;
|
||||||
|
fxslot->fxnum = sfx_num;
|
||||||
|
fxslot->pos = pos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SOUND_RESTART: {
|
||||||
|
MN_SFX_PLAY_INFO *fxslot = mn_get_fx_slot(sfx_num, 0, pos, mode);
|
||||||
|
if (!fxslot) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fxslot->mn_flags & MN_FX_RESTARTED) {
|
||||||
|
S_SoundStopSample(fxslot->handle);
|
||||||
|
fxslot->handle = S_SoundPlaySample(sfx_id, volume, pitch, pan);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
fxslot->handle = S_SoundPlaySample(sfx_id, volume, pitch, pan);
|
||||||
|
if (fxslot->handle == SOUND_INVALID_HANDLE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mn_clear_handles(fxslot);
|
||||||
|
fxslot->mn_flags = flags | MN_FX_USED;
|
||||||
|
fxslot->fxnum = sfx_num;
|
||||||
|
fxslot->pos = pos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SOUND_AMBIENT: {
|
||||||
|
uint32_t loudness = distance;
|
||||||
|
MN_SFX_PLAY_INFO *fxslot = mn_get_fx_slot(sfx_num, loudness, pos, mode);
|
||||||
|
if (!fxslot) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fxslot->pos = pos;
|
||||||
|
if (fxslot->mn_flags & MN_FX_AMBIENT) {
|
||||||
|
if (volume > 0) {
|
||||||
|
fxslot->loudness = loudness;
|
||||||
|
fxslot->pan = pan;
|
||||||
|
fxslot->volume = volume;
|
||||||
|
} else {
|
||||||
|
fxslot->loudness = MN_NOT_AUDIBLE;
|
||||||
|
fxslot->volume = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume > 0) {
|
||||||
|
fxslot->handle =
|
||||||
|
S_SoundPlaySampleLooped(sfx_id, volume, pitch, pan);
|
||||||
|
if (fxslot->handle == SOUND_INVALID_HANDLE) {
|
||||||
|
mn_clear_fx_slot(fxslot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mn_clear_handles(fxslot);
|
||||||
|
fxslot->loudness = loudness;
|
||||||
|
fxslot->fxnum = sfx_num;
|
||||||
|
fxslot->pan = pan;
|
||||||
|
fxslot->volume = volume;
|
||||||
|
fxslot->mn_flags |= MN_FX_AMBIENT | MN_FX_USED;
|
||||||
|
fxslot->pos = pos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fxslot->loudness = MN_NOT_AUDIBLE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MN_SFX_PLAY_INFO *mn_get_fx_slot(
|
||||||
|
int32_t sfx_num, uint32_t loudness, PHD_3DPOS *pos, int16_t mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case SOUND_WAIT:
|
||||||
|
case SOUND_RESTART: {
|
||||||
|
MN_SFX_PLAY_INFO *last_free_slot = NULL;
|
||||||
|
for (int i = MnAmbientLookupIdx; i < MAX_PLAYING_FX; i++) {
|
||||||
|
MN_SFX_PLAY_INFO *result = &SFXPlaying[i];
|
||||||
|
if ((result->mn_flags & MN_FX_USED) && result->fxnum == sfx_num
|
||||||
|
&& result->pos == pos) {
|
||||||
|
result->mn_flags |= MN_FX_RESTARTED;
|
||||||
|
return result;
|
||||||
|
} else if (result->mn_flags == MN_FX_UNUSED) {
|
||||||
|
last_free_slot = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return last_free_slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SOUND_AMBIENT:
|
||||||
|
for (int i = 0; i < MAX_AMBIENT_FX; i++) {
|
||||||
|
if (MnAmbientLookup[i] == sfx_num) {
|
||||||
|
MN_SFX_PLAY_INFO *result = &SFXPlaying[i];
|
||||||
|
if (result->mn_flags != MN_FX_UNUSED
|
||||||
|
&& result->loudness <= loudness) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn_reset_ambient_loudness()
|
||||||
|
{
|
||||||
|
if (!SoundIsActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MnAmbientLookupIdx; i++) {
|
||||||
|
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
||||||
|
slot->loudness = MN_NOT_AUDIBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn_stop_ambient_samples()
|
||||||
|
{
|
||||||
|
if (!SoundIsActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MnAmbientLookupIdx; i++) {
|
||||||
|
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
||||||
|
if (S_SoundSampleIsPlaying(slot->handle)) {
|
||||||
|
S_SoundStopSample(slot->handle);
|
||||||
|
mn_clear_fx_slot(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn_update_sound_effects()
|
||||||
|
{
|
||||||
|
if (!SoundIsActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
||||||
|
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
||||||
|
if (slot->mn_flags & MN_FX_USED) {
|
||||||
|
if (slot->mn_flags & MN_FX_AMBIENT) {
|
||||||
|
if (slot->loudness != MN_NOT_AUDIBLE
|
||||||
|
&& slot->handle != SOUND_INVALID_HANDLE) {
|
||||||
|
S_SoundSetPanAndVolume(
|
||||||
|
slot->handle, slot->pan, slot->volume);
|
||||||
|
} else {
|
||||||
|
if (slot->handle != SOUND_INVALID_HANDLE) {
|
||||||
|
S_SoundStopSample(slot->handle);
|
||||||
|
}
|
||||||
|
mn_clear_fx_slot(slot);
|
||||||
|
}
|
||||||
|
} else if (S_SoundSampleIsPlaying(slot->handle)) {
|
||||||
|
if (slot->pos != NULL) {
|
||||||
|
mn_get_sound_params(slot);
|
||||||
|
if (slot->volume > 0
|
||||||
|
&& slot->handle != SOUND_INVALID_HANDLE) {
|
||||||
|
S_SoundSetPanAndVolume(
|
||||||
|
slot->handle, slot->pan, slot->volume);
|
||||||
|
} else {
|
||||||
|
if (slot->handle != SOUND_INVALID_HANDLE) {
|
||||||
|
S_SoundStopSample(slot->handle);
|
||||||
|
}
|
||||||
|
mn_clear_fx_slot(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mn_clear_fx_slot(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mn_get_sound_params(MN_SFX_PLAY_INFO *slot)
|
||||||
|
{
|
||||||
|
SAMPLE_INFO *s = &SampleInfos[SampleLUT[slot->fxnum]];
|
||||||
|
|
||||||
|
int32_t x = slot->pos->x - Camera.target.x;
|
||||||
|
int32_t y = slot->pos->y - Camera.target.y;
|
||||||
|
int32_t z = slot->pos->z - Camera.target.z;
|
||||||
|
if (ABS(x) > SOUND_RADIUS || ABS(y) > SOUND_RADIUS
|
||||||
|
|| ABS(z) > SOUND_RADIUS) {
|
||||||
|
slot->volume = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t distance = SQUARE(x) + SQUARE(y) + SQUARE(z);
|
||||||
|
int32_t volume = s->volume - phd_sqrt(distance) * SOUND_RANGE_MULT_CONSTANT;
|
||||||
|
if (volume < 0) {
|
||||||
|
slot->volume = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volume > 0x7FFF) {
|
||||||
|
volume = 0x7FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
slot->volume = volume;
|
||||||
|
|
||||||
|
if (!distance || (s->flags & NO_PAN)) {
|
||||||
|
slot->pan = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t angle = phd_atan(
|
||||||
|
slot->pos->z - LaraItem->pos.z, slot->pos->x - LaraItem->pos.x);
|
||||||
|
angle -= LaraItem->pos.y_rot + Lara.torso_y_rot + Lara.head_y_rot;
|
||||||
|
slot->pan = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn_stop_sound_effect(int sfx_num, PHD_3DPOS *pos)
|
||||||
|
{
|
||||||
|
if (!SoundIsActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
||||||
|
MN_SFX_PLAY_INFO *slot = &SFXPlaying[i];
|
||||||
|
if ((slot->mn_flags & MN_FX_USED)
|
||||||
|
&& S_SoundSampleIsPlaying(slot->handle)) {
|
||||||
|
if ((!pos && slot->fxnum == sfx_num)
|
||||||
|
|| (pos && sfx_num >= 0 && slot->fxnum == sfx_num)
|
||||||
|
|| (pos && sfx_num < 0)) {
|
||||||
|
S_SoundStopSample(slot->handle);
|
||||||
|
mn_clear_fx_slot(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mn_adjust_master_volume(int8_t volume)
|
||||||
|
{
|
||||||
|
MnSoundMasterVolumeDefault = volume & 0x3F;
|
||||||
|
MnSoundMasterVolume = volume & 0x3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mn_clear_fx_slot(MN_SFX_PLAY_INFO *slot)
|
||||||
|
{
|
||||||
|
slot->handle = SOUND_INVALID_HANDLE;
|
||||||
|
slot->pos = NULL;
|
||||||
|
slot->mn_flags = 0;
|
||||||
|
slot->volume = 0;
|
||||||
|
slot->pan = 0;
|
||||||
|
slot->loudness = MN_NOT_AUDIBLE;
|
||||||
|
slot->fxnum = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mn_clear_handles(MN_SFX_PLAY_INFO *slot)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_PLAYING_FX; i++) {
|
||||||
|
MN_SFX_PLAY_INFO *rslot = &SFXPlaying[i];
|
||||||
|
if (rslot != slot && rslot->handle == slot->handle) {
|
||||||
|
rslot->handle = SOUND_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,19 @@
|
||||||
|
|
||||||
#include "global/types.h"
|
#include "global/types.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void Sound_UpdateEffects();
|
void Sound_UpdateEffects();
|
||||||
void Sound_Effect(int32_t sfx_num, PHD_3DPOS *pos, uint32_t flags);
|
void Sound_Effect(int32_t sfx_num, PHD_3DPOS *pos, uint32_t flags);
|
||||||
void Sound_StopEffect(int32_t sfx_num, PHD_3DPOS *pos);
|
void Sound_StopEffect(int32_t sfx_num, PHD_3DPOS *pos);
|
||||||
|
|
||||||
|
void mn_reset_sound_effects();
|
||||||
|
bool mn_sound_effect(int32_t sfx_num, PHD_3DPOS *pos, uint32_t flags);
|
||||||
|
void mn_reset_ambient_loudness();
|
||||||
|
void mn_stop_ambient_samples();
|
||||||
|
void mn_update_sound_effects();
|
||||||
|
void mn_stop_sound_effect(int sfx_num, PHD_3DPOS *pos);
|
||||||
|
void mn_adjust_master_volume(int8_t volume);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue