mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-23 12:44:02 +00:00
Initial, and slightly buggy, support for sound effects.
svn-id: r15614
This commit is contained in:
parent
d37a55ef19
commit
82b6902b56
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
102
saga/sound.cpp
102
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,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;
|
||||
|
18
saga/sound.h
18
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;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user