From f80bdba62fd694c29a61b90898c57af8104793c5 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Thu, 18 Nov 2004 17:34:54 +0000 Subject: Partial support for WAV sound playback, which apparently will be needed for IHNM support. I used the partial IHNM intro as my test case, and it seems to work that far at least. svn-id: r15827 --- saga/ihnm_introproc.cpp | 8 ++++++ saga/sndres.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ saga/sndres.h | 1 + 3 files changed, 77 insertions(+) (limited to 'saga') diff --git a/saga/ihnm_introproc.cpp b/saga/ihnm_introproc.cpp index f2e7ca8a12..241a457d7e 100644 --- a/saga/ihnm_introproc.cpp +++ b/saga/ihnm_introproc.cpp @@ -276,6 +276,14 @@ int Scene::IHNMHateProc(int param, SCENE_INFO *scene_info) { q_event = _vm->_events->queue(&event); + event.type = ONESHOT_EVENT; + event.code = VOICE_EVENT; + event.op = EVENT_PLAY; + event.param = 0; + event.time = 0; + + q_event = _vm->_events->queue(&event); + _vm->_anim->setFlag(0, ANIM_LOOP); _vm->_anim->play(0, 0); break; diff --git a/saga/sndres.cpp b/saga/sndres.cpp index f491f0aff3..096e83752b 100644 --- a/saga/sndres.cpp +++ b/saga/sndres.cpp @@ -156,6 +156,13 @@ int SndRes::load(RSCFILE_CONTEXT *snd_ctxt, uint32 snd_rn, SOUNDBUFFER *snd_buf_ return FAILURE; } break; + case GAME_SOUND_WAV: + result = loadWavSound(snd_res, snd_res_len, snd_buf_i); + RSC_FreeResource(snd_res); + if (result != SUCCESS) { + return FAILURE; + } + break; default: /* Unknown sound type */ RSC_FreeResource(snd_res); @@ -250,6 +257,64 @@ int SndRes::loadVocSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf return SUCCESS; } +int SndRes::loadWavSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf_i) { + // TODO: This function should, perhaps, be made more robust. + + MemoryReadStream readS(snd_res, snd_res_len); + + byte buf[4]; + + readS.read(buf, sizeof(buf)); + if (memcmp(buf, "RIFF", sizeof(buf)) != 0) { + return FAILURE; + } + + readS.readUint32LE(); + + readS.read(buf, sizeof(buf)); + if (memcmp(buf, "WAVE", sizeof(buf)) != 0) { + return FAILURE; + } + + readS.read(buf, sizeof(buf)); + if (memcmp(buf, "fmt ", sizeof(buf)) != 0) { + return FAILURE; + } + + uint32 len = readS.readUint32LE(); + uint32 pos = readS.pos(); + + readS.readUint16LE(); + + snd_buf_i->s_stereo = (readS.readUint16LE() == 2) ? 1 : 0; + snd_buf_i->s_freq = readS.readUint16LE(); + snd_buf_i->s_samplebits = 16; + snd_buf_i->s_signed = 1; + + readS.seek(pos + len); + + for (;;) { + readS.read(buf, sizeof(buf)); + if (memcmp(buf, "data", sizeof(buf)) == 0) { + break; + } + + len = readS.readUint32LE(); + readS.seek(len, SEEK_CUR); + } + + snd_buf_i->s_buf_len = readS.readUint32LE(); + + byte *data = (byte *)malloc(snd_buf_i->s_buf_len); + if (!data) { + return FAILURE; + } + + readS.read(data, snd_buf_i->s_buf_len); + snd_buf_i->s_buf = data; + return SUCCESS; +} + int SndRes::getVoiceLength(uint32 voice_rn) { int res_type = _snd_info.res_type; uint32 length = 0; @@ -303,6 +368,9 @@ int SndRes::getVoiceLength(uint32 voice_rn) { // Rough hack, fix this to be accurate ms_f = (double)length / 14705 * 1000.0; ms_i = (int)ms_f; + } else if (res_type == GAME_SOUND_WAV) { + // TODO! + return -1; } else { return -1; } diff --git a/saga/sndres.h b/saga/sndres.h index bbe91fe02d..ec823a8673 100644 --- a/saga/sndres.h +++ b/saga/sndres.h @@ -74,6 +74,7 @@ public: private: int load(RSCFILE_CONTEXT *snd_ctxt, uint32 snd_rn, SOUNDBUFFER *snd_buf_i); int loadVocSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf_i); + int loadWavSound(byte *snd_res, size_t snd_res_len, SOUNDBUFFER *snd_buf_i); int _init; -- cgit v1.2.3