aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2004-10-19 17:12:53 +0000
committerTorbjörn Andersson2004-10-19 17:12:53 +0000
commit82b6902b5661b6b9832d39ae33627bc964cccf34 (patch)
tree111ab2099a766c2a81f870adb9f8265306edd56e
parentd37a55ef19cfe85a67547c0255bd37938d96d8f8 (diff)
downloadscummvm-rg350-82b6902b5661b6b9832d39ae33627bc964cccf34.tar.gz
scummvm-rg350-82b6902b5661b6b9832d39ae33627bc964cccf34.tar.bz2
scummvm-rg350-82b6902b5661b6b9832d39ae33627bc964cccf34.zip
Initial, and slightly buggy, support for sound effects.
svn-id: r15614
-rw-r--r--saga/resnames.h70
-rw-r--r--saga/sfuncs.cpp85
-rw-r--r--saga/sndres.cpp15
-rw-r--r--saga/sndres.h1
-rw-r--r--saga/sound.cpp98
-rw-r--r--saga/sound.h18
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;
};