diff options
-rw-r--r-- | saga/resnames.h | 70 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 85 | ||||
-rw-r--r-- | saga/sndres.cpp | 15 | ||||
-rw-r--r-- | saga/sndres.h | 1 | ||||
-rw-r--r-- | saga/sound.cpp | 98 | ||||
-rw-r--r-- | saga/sound.h | 18 |
6 files changed, 215 insertions, 72 deletions
diff --git a/saga/resnames.h b/saga/resnames.h index 321853fe73..ceea4ff14a 100644 --- a/saga/resnames.h +++ b/saga/resnames.h @@ -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 diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index fbf0ce983b..1bbc36b063 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -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; } diff --git a/saga/sndres.cpp b/saga/sndres.cpp index ef69ebe9bc..f8ed8b41e7 100644 --- a/saga/sndres.cpp +++ b/saga/sndres.cpp @@ -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; diff --git a/saga/sndres.h b/saga/sndres.h index 49956c4fd3..1453b6f056 100644 --- a/saga/sndres.h +++ b/saga/sndres.h @@ -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, diff --git a/saga/sound.cpp b/saga/sound.cpp index 7b96fd9f5a..513f607b98 100644 --- a/saga/sound.cpp +++ b/saga/sound.cpp @@ -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,82 +44,81 @@ Sound::~Sound() { _soundInitialized = 0; } -int Sound::play(int sound_rn, int channel) { +int Sound::playSoundBuffer(PlayingSoundHandle *handle, R_SOUNDBUFFER *buf, int volume, bool loop) { + byte flags; + if (!_soundInitialized) { return R_FAILURE; } - if (channel > 3) { - return R_FAILURE; - } - - return R_SUCCESS; -} + flags = SoundMixer::FLAG_AUTOFREE; -int Sound::pause(int channel) { - (void)channel; + if (loop) + flags |= SoundMixer::FLAG_LOOP; - if (!_soundInitialized) { - return R_FAILURE; - } + if (buf->s_samplebits == 16) + flags |= (SoundMixer::FLAG_16BITS | SoundMixer::FLAG_LITTLE_ENDIAN); + if (buf->s_stereo) + flags |= SoundMixer::FLAG_STEREO; + if (!buf->s_signed) + flags |= SoundMixer::FLAG_UNSIGNED; - return R_SUCCESS; -} + // FIXME: Remove the code below if the code above works. -int Sound::resume(int channel) { - (void)channel; +#if 0 + int game_id = GAME_GetGame(); - if (!_soundInitialized) { - return R_FAILURE; + if((game_id == R_GAME_ITE_DISK) || (game_id == R_GAME_ITE_DEMO)) { + flags = SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE; + } else { + flags = SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS | + SoundMixer::FLAG_LITTLE_ENDIAN; } +#endif + + _mixer->playRaw(handle, buf->s_buf, buf->s_buf_len, buf->s_freq, flags, -1, volume); return R_SUCCESS; } -int Sound::stop(int channel) { - (void)channel; +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::playVoice(R_SOUNDBUFFER *buf) { - byte flags; - +int Sound::resumeSound() { if (!_soundInitialized) { return R_FAILURE; } - flags = SoundMixer::FLAG_AUTOFREE; + _mixer->pauseHandle(_effectHandle, false); - if (buf->s_samplebits == 16) - flags |= (SoundMixer::FLAG_16BITS | SoundMixer::FLAG_LITTLE_ENDIAN); - if (buf->s_stereo) - flags |= SoundMixer::FLAG_STEREO; - if (!buf->s_signed) - flags |= SoundMixer::FLAG_UNSIGNED; - - // FIXME: Remove the code below if the code above works. - -#if 0 - int game_id = GAME_GetGame(); + return R_SUCCESS; +} - if((game_id == R_GAME_ITE_DISK) || (game_id == R_GAME_ITE_DEMO)) { - flags = SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE; - } else { - flags = SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS | - SoundMixer::FLAG_LITTLE_ENDIAN; +int Sound::stopSound() { + if (!_soundInitialized) { + return R_FAILURE; } -#endif - _mixer->playRaw(&_voiceHandle, buf->s_buf, buf->s_buf_len, buf->s_freq, flags); + _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; diff --git a/saga/sound.h b/saga/sound.h index dfb7b0835e..bccb872735 100644 --- a/saga/sound.h +++ b/saga/sound.h @@ -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; }; |