Initial, and slightly buggy, support for sound effects.

svn-id: r15614
This commit is contained in:
Torbjörn Andersson 2004-10-19 17:12:53 +00:00
parent d37a55ef19
commit 82b6902b56
6 changed files with 217 additions and 74 deletions

View File

@ -102,6 +102,9 @@ namespace Saga {
#define CAVE_VOICE_12 12
#define CAVE_VOICE_13 13
// TODO: I have no idea why the music IDs start at 9 and the sound IDs at 14.
// We should probably just renumber them.
// MUSIC
#define MUSIC_1 9
#define MUSIC_2 10
@ -130,6 +133,73 @@ namespace Saga {
#define MUSIC_25 33
#define MUSIC_26 34
// SOUND EFFECTS
#define FX_DOOR_OPEN 14
#define FX_DOOR_CLOSE 15
#define FX_RUSH_WATER 16
#define FX_CRICKET 17
#define FX_PORTICULLIS 18
#define FX_CLOCK_1 19
#define FX_CLOCK_2 20
#define FX_DAM_MACHINE 21
#define FX_HUM1 22
#define FX_HUM2 23
#define FX_HUM3 24
#define FX_HUM4 25
#define FX_STREAM 26
#define FX_SURF 27
#define FX_FIRELOOP 28
#define FX_SCRAPING 29
#define FX_BEE_SWARM 30
#define FX_SQUEAKBOARD 31
#define FX_KNOCK 32
#define FX_COINS 33
#define FX_STORM 34
#define FX_DOOR_CLOSE_2 35
#define FX_ARCWELD 36
#define FX_RETRACT_ORB 37
#define FX_DRAGON 38
#define FX_SNORES 39
#define FX_SPLASH 40
#define FX_LOBBY_DOOR 41
#define FX_CHIRP_LOOP 42
#define FX_DOOR_CREAK 43
#define FX_SPOON_DIG 44
#define FX_CROW 45
#define FX_COLDWIND 46
#define FX_TOOL_SND_1 47
#define FX_TOOL_SND_2 48
#define FX_TOOL_SND_3 49
#define FX_DOOR_METAL 50
#define FX_WATER_LOOP_S 51
#define FX_WATER_LOOP_L 52
#define FX_DOOR_OPEN_2 53
#define FX_JAIL_DOOR 54
#define FX_KILN_FIRE 55
// TODO: These are only in the CD version, and I can't find them in the source
// code we got. Someone needs to verify these to get the correct values.
// They appear to be a bit off right now.
#define FX_CROWD_01 56
#define FX_CROWD_02 57
#define FX_CROWD_03 58
#define FX_CROWD_04 59
#define FX_CROWD_05 60
#define FX_CROWD_06 61
#define FX_CROWD_07 62
#define FX_CROWD_08 63
#define FX_CROWD_09 64
#define FX_CROWD_10 65
#define FX_CROWD_11 66
#define FX_CROWD_12 67
#define FX_CROWD_13 68
#define FX_CROWD_14 69
#define FX_CROWD_15 70
#define FX_CROWD_16 71
#define FX_CROWD_17 72
} // End of namespace Saga
#endif

View File

@ -31,6 +31,8 @@
#include "saga/console.h"
#include "saga/interface.h"
#include "saga/music.h"
#include "saga/sound.h"
#include "saga/sndres.h"
#include "saga/script.h"
#include "saga/sdata.h"
@ -750,9 +752,7 @@ static int musicTable[] = {
// Script function #63 (0x3F)
int Script::SF_playMusic(R_SCRIPTFUNC_PARAMS) {
SDataWord_T param;
param = thread->pop();
SDataWord_T param = thread->pop();
if (/* param >= 0 && */ param < ARRAYSIZE(musicTable))
_vm->_music->play(musicTable[param]);
@ -762,9 +762,86 @@ int Script::SF_playMusic(R_SCRIPTFUNC_PARAMS) {
return R_SUCCESS;
}
static struct {
int res;
int vol;
} sfxTable[] = {
{ FX_DOOR_OPEN, 127 },
{ FX_DOOR_CLOSE, 127 },
{ FX_RUSH_WATER, 63 }, // Floppy volume: 127
{ FX_RUSH_WATER, 26 }, // Floppy volume: 40
{ FX_CRICKET, 64 },
{ FX_PORTICULLIS, 84 }, // Floppy volume: 127
{ FX_CLOCK_1, 64 },
{ FX_CLOCK_2, 64 },
{ FX_DAM_MACHINE, 64 },
{ FX_DAM_MACHINE, 40 },
{ FX_HUM1, 64 },
{ FX_HUM2, 64 },
{ FX_HUM3, 64 },
{ FX_HUM4, 64 },
{ FX_WATER_LOOP_S, 32 }, // Floppy volume: 64
{ FX_SURF, 42 }, // Floppy volume: 127
{ FX_SURF, 32 }, // Floppy volume: 64
{ FX_FIRELOOP, 64 }, // Floppy volume: 96
{ FX_SCRAPING, 84 }, // Floppy volume: 127
{ FX_BEE_SWARM, 64 }, // Floppy volume: 96
{ FX_BEE_SWARM, 26 }, // Floppy volume: 40
{ FX_SQUEAKBOARD, 64 },
{ FX_KNOCK, 127 },
{ FX_COINS, 32 }, // Floppy volume: 48
{ FX_STORM, 84 }, // Floppy volume: 127
{ FX_DOOR_CLOSE_2, 84 }, // Floppy volume: 127
{ FX_ARCWELD, 84 }, // Floppy volume: 127
{ FX_RETRACT_ORB, 127 },
{ FX_DRAGON, 127 },
{ FX_SNORES, 127 },
{ FX_SPLASH, 127 },
{ FX_LOBBY_DOOR, 127 },
{ FX_CHIRP_LOOP, 26 }, // Floppy volume: 40
{ FX_DOOR_CREAK, 96 },
{ FX_SPOON_DIG, 64 },
{ FX_CROW, 96 },
{ FX_COLDWIND, 42 }, // Floppy volume: 64
{ FX_TOOL_SND_1, 96 },
{ FX_TOOL_SND_2, 127 },
{ FX_TOOL_SND_3, 64 },
{ FX_DOOR_METAL, 96 },
{ FX_WATER_LOOP_S, 32 },
{ FX_WATER_LOOP_L, 32 }, // Floppy volume: 64
{ FX_DOOR_OPEN_2, 127 },
{ FX_JAIL_DOOR, 64 },
{ FX_KILN_FIRE, 53 }, // Floppy volume: 80
// Only in the CD version
{ FX_CROWD_01, 64 },
{ FX_CROWD_02, 64 },
{ FX_CROWD_03, 64 },
{ FX_CROWD_04, 64 },
{ FX_CROWD_05, 64 },
{ FX_CROWD_06, 64 },
{ FX_CROWD_07, 64 },
{ FX_CROWD_08, 64 },
{ FX_CROWD_09, 64 },
{ FX_CROWD_10, 64 },
{ FX_CROWD_11, 64 },
{ FX_CROWD_12, 64 },
{ FX_CROWD_13, 64 },
{ FX_CROWD_14, 64 },
{ FX_CROWD_15, 64 },
{ FX_CROWD_16, 64 },
{ FX_CROWD_17, 64 }
};
// Script function #70 (0x46)
int Script::SF_playSound(R_SCRIPTFUNC_PARAMS) {
thread->pop();
SDataWord_T param = thread->pop() - 14;
if (/* param >= 0 && */ param < ARRAYSIZE(sfxTable))
_vm->_sndRes->playSound(sfxTable[param].res, sfxTable[param].vol);
else
_vm->_sound->stopSound();
return R_SUCCESS;
}

View File

@ -55,6 +55,21 @@ SndRes::SndRes(SagaEngine *vm) : _vm(vm) {
_init = 1;
}
int SndRes::playSound(uint32 sound_rn, int volume) {
R_SOUNDBUFFER snd_buffer;
debug(0, "SndRes::playSound(%ld)", sound_rn);
if (load(_sfx_ctxt, sound_rn, &snd_buffer) != R_SUCCESS) {
debug(0, "Failed to load sound");
return R_FAILURE;
}
_vm->_sound->playSound(&snd_buffer, volume);
return R_SUCCESS;
}
int SndRes::playVoice(uint32 voice_rn) {
R_SOUNDBUFFER snd_buffer;
int result;

View File

@ -67,6 +67,7 @@ public:
SndRes(SagaEngine *vm);
int loadSound(uint32 sound_rn);
int playSound(uint32 sound_rn, int volume);
int playVoice(uint32 voice_rn);
int getVoiceLength(uint32 voice_rn);
int ITEVOC_Resample(long src_freq, long dst_freq, byte *src_buf,

View File

@ -31,21 +31,6 @@ namespace Saga {
Sound::Sound(SagaEngine *vm, SoundMixer *mixer, int enabled) :
_vm(vm), _mixer(mixer), _enabled(enabled) {
int result;
// Load sound module resource file contexts
result = GAME_GetFileContext(&_soundContext, R_GAME_SOUNDFILE, 0);
if (result != R_SUCCESS) {
return;
}
result = GAME_GetFileContext(&_voiceContext, R_GAME_VOICEFILE, 0);
if (result != R_SUCCESS) {
return;
}
// Grab sound resource information for the current game
GAME_GetSoundInfo(&_snd_info);
_soundInitialized = 1;
return;
@ -59,49 +44,7 @@ Sound::~Sound() {
_soundInitialized = 0;
}
int Sound::play(int sound_rn, int channel) {
if (!_soundInitialized) {
return R_FAILURE;
}
if (channel > 3) {
return R_FAILURE;
}
return R_SUCCESS;
}
int Sound::pause(int channel) {
(void)channel;
if (!_soundInitialized) {
return R_FAILURE;
}
return R_SUCCESS;
}
int Sound::resume(int channel) {
(void)channel;
if (!_soundInitialized) {
return R_FAILURE;
}
return R_SUCCESS;
}
int Sound::stop(int channel) {
(void)channel;
if (!_soundInitialized) {
return R_FAILURE;
}
return R_SUCCESS;
}
int Sound::playVoice(R_SOUNDBUFFER *buf) {
int Sound::playSoundBuffer(PlayingSoundHandle *handle, R_SOUNDBUFFER *buf, int volume, bool loop) {
byte flags;
if (!_soundInitialized) {
@ -110,6 +53,9 @@ int Sound::playVoice(R_SOUNDBUFFER *buf) {
flags = SoundMixer::FLAG_AUTOFREE;
if (loop)
flags |= SoundMixer::FLAG_LOOP;
if (buf->s_samplebits == 16)
flags |= (SoundMixer::FLAG_16BITS | SoundMixer::FLAG_LITTLE_ENDIAN);
if (buf->s_stereo)
@ -130,11 +76,49 @@ int Sound::playVoice(R_SOUNDBUFFER *buf) {
}
#endif
_mixer->playRaw(&_voiceHandle, buf->s_buf, buf->s_buf_len, buf->s_freq, flags);
_mixer->playRaw(handle, buf->s_buf, buf->s_buf_len, buf->s_freq, flags, -1, volume);
return R_SUCCESS;
}
int Sound::playSound(R_SOUNDBUFFER *buf, int volume) {
return playSoundBuffer(&_effectHandle, buf, 2 * volume, false);
}
int Sound::pauseSound() {
if (!_soundInitialized) {
return R_FAILURE;
}
_mixer->pauseHandle(_effectHandle, true);
return R_SUCCESS;
}
int Sound::resumeSound() {
if (!_soundInitialized) {
return R_FAILURE;
}
_mixer->pauseHandle(_effectHandle, false);
return R_SUCCESS;
}
int Sound::stopSound() {
if (!_soundInitialized) {
return R_FAILURE;
}
_mixer->stopHandle(_effectHandle);
return R_SUCCESS;
}
int Sound::playVoice(R_SOUNDBUFFER *buf) {
return playSoundBuffer(&_voiceHandle, buf, 255, false);
}
int Sound::pauseVoice() {
if (!_soundInitialized) {
return R_FAILURE;

View File

@ -48,32 +48,28 @@ public:
Sound(SagaEngine *vm, SoundMixer *mixer, int enabled);
~Sound();
int play(int sound_rn, int channel);
int pause(int channel);
int resume(int channel);
int stop(int channel);
int playSound(R_SOUNDBUFFER *buf, int volume);
int pauseSound();
int resumeSound();
int stopSound();
int playVoice(R_SOUNDBUFFER *);
int playVoice(R_SOUNDBUFFER *buf);
int pauseVoice();
int resumeVoice();
int stopVoice();
private:
int playSoundBuffer(PlayingSoundHandle *handle, R_SOUNDBUFFER *buf, int volume, bool loop);
int _soundInitialized;
int _enabled;
R_GAME_SOUNDINFO _snd_info;
R_RSCFILE_CONTEXT *_soundContext;
R_RSCFILE_CONTEXT *_voiceContext;
SagaEngine *_vm;
SoundMixer *_mixer;
PlayingSoundHandle _effectHandle;
PlayingSoundHandle _voiceHandle;
PlayingSoundHandle _musictHandle;
};