From 7101c0ef260fb1f095b8e04a5dc1ceb9e99cf759 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 31 Jan 2007 13:17:50 +0000 Subject: - Correctly setting of Snd::_playingSound - Implemented sound fading in/out - o2_stub0x81 -> o2_scroll svn-id: r25307 --- engines/gob/dataio.h | 2 +- engines/gob/game.cpp | 4 ++- engines/gob/inter.h | 2 +- engines/gob/inter_v2.cpp | 51 +++++++++++++++++++++------------ engines/gob/mult.h | 8 +++--- engines/gob/mult_v1.cpp | 12 ++++---- engines/gob/mult_v2.cpp | 14 +++++----- engines/gob/sound.cpp | 73 ++++++++++++++++++++++++++++++++++++++++-------- engines/gob/sound.h | 14 ++++++++-- 9 files changed, 127 insertions(+), 53 deletions(-) (limited to 'engines') diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h index a2b27e98c4..1e1ebc7875 100644 --- a/engines/gob/dataio.h +++ b/engines/gob/dataio.h @@ -28,7 +28,7 @@ namespace Gob { -#define MAX_DATA_FILES 3 +#define MAX_DATA_FILES 6 #define MAX_SLOT_COUNT 4 class DataIO { diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 205258d628..b227b799b9 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -1058,7 +1058,9 @@ Game::Imd *Game::loadImdFile(const char *path, Video::SurfaceDesc *surfDesc, int if (imdPtr->verMin & 0x4000) { // loc_29C4F - error("GOB2 Stub! loadImdFile, imdPtr->verMin & 0x4000"); + warning("GOB2 Stub! loadImdFile, imdPtr->verMin & 0x4000"); + warning("Can't open IMD \"%s.IMD\"", path); + return 0; // Sound stuff, I presume... } diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 879722a240..10d32a1e97 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -321,7 +321,7 @@ protected: void o2_switchTotSub(void); void o2_stub0x54(void); void o2_stub0x55(void); - void o2_stub0x81(void); + void o2_scroll(void); void o2_stub0x85(void); bool o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag); bool o2_readData(char &cmdCount, int16 &counter, int16 &retFlag); diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 95e13ff43a..278c618e70 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -286,7 +286,7 @@ void Inter_v2::setupOpcodes(void) { {NULL, ""}, /* 80 */ OPCODE(o2_initScreen), - OPCODE(o2_stub0x81), + OPCODE(o2_scroll), OPCODE(o2_setScrollOffset), OPCODE(o2_playImd), /* 84 */ @@ -812,23 +812,6 @@ void Inter_v2::o2_stub0x55(void) { } } -void Inter_v2::o2_stub0x81(void) { - int16 var1; - int16 var2; - int16 var3; - int16 var4; - int16 var5; - int16 var6; - - var1 = _vm->_parse->parseValExpr(); - var2 = _vm->_parse->parseValExpr(); - var3 = _vm->_parse->parseValExpr(); - var4 = _vm->_parse->parseValExpr(); - var5 = _vm->_parse->parseValExpr(); - var6 = _vm->_parse->parseValExpr(); - warning("GOB2 Stub! o2_stub0x81(%d, %d, %d, %d, %d, %d)", var1, var2, var3, var4, var5, var6); -} - void Inter_v2::o2_stub0x85(void) { char dest[32]; @@ -1508,6 +1491,7 @@ bool Inter_v2::o2_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag) { cmd = load16(); _vm->_global->_inter_execPtr += 2; + warning("goblinFunc %d", cmd); if (cmd != 101) executeGoblinOpcode(cmd, extraData, NULL, NULL); return false; @@ -2231,6 +2215,37 @@ void Inter_v2::o2_setScrollOffset(void) { */ } +void Inter_v2::o2_scroll(void) { + int16 startX; + int16 startY; + int16 endX; + int16 endY; + int16 stepX; + int16 stepY; + int16 curX; + int16 curY; + + startX = _vm->_parse->parseValExpr(); + startY = _vm->_parse->parseValExpr(); + endX = _vm->_parse->parseValExpr(); + endY = _vm->_parse->parseValExpr(); + stepX = _vm->_parse->parseValExpr(); + stepY = _vm->_parse->parseValExpr(); + + if ((stepY != 0) || (startY > 0) || (endY > 0)) + warning("GOB2 Stub! Vertical scrolling / high surfaces"); + + curX = startX; + curY = startY; + while ((curX != endX) || (curY != endY)) { + curX = stepX > 0 ? MIN(curX + stepX, (int) endX) : MAX(curX + stepX, (int) endX); + curY = stepY > 0 ? MIN(curY + stepY, (int) endY) : MAX(curY + stepY, (int) endY); + _vm->_draw->_word_2FC9E = curX; + _vm->_video->_scrollOffset = _vm->_draw->_word_2FC9E; + _vm->_video->waitRetrace(_vm->_global->_videoMode); + } +} + void Inter_v2::o2_totSub(void) { char totFile[14]; byte length; diff --git a/engines/gob/mult.h b/engines/gob/mult.h index a6ed15180a..35bd424aa9 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -146,7 +146,7 @@ public: int16 frame; int16 cmd; int16 freq; - int16 channel; + int16 fadeLength; int16 repCount; int16 resId; int16 soundIndex; @@ -248,7 +248,7 @@ public: char handleMouse) = 0; virtual void animate(void) = 0; virtual void playSound(Snd::SoundDesc * soundDesc, int16 repCount, - int16 freq, int16 channel) = 0; + int16 freq, int16 fadeLength) = 0; virtual void freeMult(void) = 0; virtual void freeMultKeys(void) = 0; @@ -280,7 +280,7 @@ public: char handleMouse); virtual void animate(void); virtual void playSound(Snd::SoundDesc * soundDesc, int16 repCount, - int16 freq, int16 channel); + int16 freq, int16 fadeLength); virtual void freeMult(void); virtual void freeMultKeys(void); @@ -367,7 +367,7 @@ public: char handleMouse); virtual void animate(void); virtual void playSound(Snd::SoundDesc * soundDesc, int16 repCount, - int16 freq, int16 channel); + int16 freq, int16 fadeLength); virtual void freeMult(void); virtual void freeMultKeys(void); diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index 4e662ed714..2d5da914ff 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -143,7 +143,7 @@ void Mult_v1::loadMult(int16 resId) { _sndKeys[i].frame = data.readSint16LE(); _sndKeys[i].cmd = data.readSint16LE(); _sndKeys[i].freq = data.readSint16LE(); - _sndKeys[i].channel = data.readSint16LE(); + _sndKeys[i].fadeLength = data.readSint16LE(); _sndKeys[i].repCount = data.readSint16LE(); _sndKeys[i].soundIndex = -1; _sndKeys[i].resId = -1; @@ -589,17 +589,17 @@ char Mult_v1::doSoundAnim(char stop, int16 frame) { _vm->_snd->stopSound(0); stop = 0; playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, - sndKey->freq, sndKey->channel); + sndKey->freq, sndKey->fadeLength); } else if (sndKey->cmd == 4) { _vm->_snd->stopSound(0); stop = 0; playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, - sndKey->freq, sndKey->channel); + sndKey->freq, sndKey->fadeLength); } } else { if (_vm->_snd->_playingSound) - _vm->_snd->stopSound(sndKey->channel); + _vm->_snd->stopSound(sndKey->fadeLength); } } return stop; @@ -904,8 +904,8 @@ void Mult_v1::freeMult(void) { } void Mult_v1::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq, - int16 channel) { - _vm->_snd->playSample(soundDesc, repCount, freq); + int16 fadeLength) { + _vm->_snd->playSample(soundDesc, repCount, freq, fadeLength); } void Mult_v1::freeMultKeys(void) { diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index c082859204..10720b23aa 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -203,7 +203,7 @@ void Mult_v2::loadMult(int16 resId) { _multData2->sndKeys[i].frame = data.readSint16LE(); _multData2->sndKeys[i].cmd = data.readSint16LE(); _multData2->sndKeys[i].freq = data.readSint16LE(); - _multData2->sndKeys[i].channel = data.readSint16LE(); + _multData2->sndKeys[i].fadeLength = data.readSint16LE(); _multData2->sndKeys[i].repCount = data.readSint16LE(); _multData2->sndKeys[i].soundIndex = -1; _multData2->sndKeys[i].resId = -1; @@ -564,8 +564,8 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, _animDataAllocated = 0; } - if (_vm->_snd->_playingSound != 0) - _vm->_snd->stopSound(10); +/* if (_vm->_snd->_playingSound != 0) + _vm->_snd->stopSound(10);*/ WRITE_VAR(57, (uint32)-1); } else @@ -862,11 +862,11 @@ char Mult_v2::doSoundAnim(char stop, int16 frame) { if (_vm->_game->_soundSamples[sndKey->soundIndex] == 0) continue; playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount, - sndKey->freq, sndKey->channel); + sndKey->freq, sndKey->fadeLength); } } else { if (_vm->_snd->_playingSound) - _vm->_snd->stopSound(sndKey->channel); + _vm->_snd->stopSound(sndKey->fadeLength); } } return stop; @@ -1299,8 +1299,8 @@ void Mult_v2::animate(void) { } void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq, - int16 channel) { - _vm->_snd->playSample(soundDesc, repCount, freq); + int16 fadeLength) { + _vm->_snd->playSample(soundDesc, repCount, freq, fadeLength); } void Mult_v2::freeMult(void) { diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp index 500a2e5295..4be47fba80 100644 --- a/engines/gob/sound.cpp +++ b/engines/gob/sound.cpp @@ -72,6 +72,16 @@ Snd::Snd(GobEngine *vm) : _vm(vm) { _repCount = 0; _offset = 0.0; + _frac = 0.0; + _cur = 0; + _last = 0; + + _fade = false; + _fadeVol = 255.0; + _fadeVolStep = 0.0; + _fadeSamples = 0; + _curFadeSamples = 0; + _compositionPos = -1; _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle, @@ -98,16 +108,26 @@ int8 Snd::getCompositionSlot(void) { return _composition[_compositionPos]; } -void Snd::stopSound(int16 arg) +void Snd::stopSound(int16 fadeLength) { Common::StackLock slock(_mutex); - _data = 0; - _end = true; + if (fadeLength <= 0) { + _data = 0; + _end = true; + _playingSound = 0; + return; + } + + _fade = true; + _fadeVol = 255.0; + _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); + _fadeVolStep = 255.0 / ((double) _fadeSamples); + _curFadeSamples = 0; } void Snd::waitEndPlay(void) { - while (!_end) + while (!_end && !_vm->_quitRequested) _vm->_util->longDelay(200); stopSound(0); } @@ -125,7 +145,7 @@ void Snd::nextCompositionPos(void) { while ((++_compositionPos < 50) && ((slot = _composition[_compositionPos]) != -1)) { if ((slot >= 0) && (slot <= 60) && (_vm->_game->_soundSamples[slot] != 0) && !(_vm->_game->_soundTypes[slot] & 8)) { - setSample(_vm->_game->_soundSamples[slot], 1, 0); + setSample(_vm->_game->_soundSamples[slot], 1, 0, 0); return; } } @@ -165,7 +185,7 @@ void Snd::freeSoundDesc(Snd::SoundDesc *sndDesc, bool freedata) { delete sndDesc; } -void Snd::setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) { +void Snd::setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { if (frequency <= 0) frequency = sndDesc->frequency; @@ -183,16 +203,29 @@ void Snd::setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) { _last = 0; _repCount = repCount; _end = false; - _playingSound = 0; + _playingSound = 1; + + _curFadeSamples = 0; + if (fadeLength == 0) { + _fade = false; + _fadeVol = 255.0; + _fadeSamples = 0; + _fadeVolStep = 0.0; + } else { + _fade = true; + _fadeVol = 0.0; + _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); + _fadeVolStep = -(255.0 / ((double) _fadeSamples)); + } } -void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) { +void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { Common::StackLock slock(_mutex); if (!_end) return; - setSample(sndDesc, repCount, frequency); + setSample(sndDesc, repCount, frequency, fadeLength); if (!_vm->_mixer->isSoundHandleActive(_handle)) _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle, this, -1, 255, 0, false, true); @@ -204,7 +237,7 @@ void Snd::checkEndSample(void) { else if ((_repCount == -1) || (--_repCount > 0)) { _offset = 0.0; _end = false; - _playingSound = 0; + _playingSound = 1; } else { _end = true; _playingSound = 0; @@ -224,13 +257,29 @@ int Snd::readBuffer(int16 *buffer, const int numSamples) { if (_end) return i; - *buffer++ = (int) (_last + (_cur - _last) * _frac); + *buffer++ = (int16) ((_last + (_cur - _last) * _frac) * _fadeVol); _frac += _ratio; while (_frac > 1) { _frac -= 1; _last = _cur; - _cur = _data[(int) _offset] << 8; + _cur = _data[(int) _offset]; + } + + if (_fade) { + if (++_curFadeSamples < _fadeSamples) { + _fadeVol -= _fadeVolStep; + } else { + if (_fadeVolStep > 0) { + _data = 0; + _end = true; + _playingSound = 0; + } else { + _fadeVol = 255.0; + _fade = false; + } + } } + _offset += _ratio; } return numSamples; diff --git a/engines/gob/sound.h b/engines/gob/sound.h index dd059b44ee..2fc9a1ce00 100644 --- a/engines/gob/sound.h +++ b/engines/gob/sound.h @@ -52,8 +52,8 @@ public: void speakerOn(int16 frequency, int32 length); void speakerOff(void); SoundDesc *loadSoundData(const char *path); - void stopSound(int16 arg); - void playSample(SoundDesc *sndDesc, int16 repCount, int16 frequency); + void stopSound(int16 fadeLength); + void playSample(SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength = 0); void playComposition(int16 *composition, int16 freqVal); void stopComposition(void); int8 getCompositionSlot(void); @@ -113,10 +113,18 @@ protected: int32 _repCount; double _offset; double _ratio; + double _frac; int16 _cur; int16 _last; + bool _fade; + double _fadeVol; + double _fadeVolStep; + uint8 _fadeLength; + uint32 _fadeSamples; + uint32 _curFadeSamples; + GobEngine *_vm; void cleanupFuncCallback() {;} @@ -127,7 +135,7 @@ protected: void writeAdlib(int16 port, int16 data); void setBlasterPort(int16 port); void setResetTimerFlag(char flag){return;} - void setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency); + void setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency, int16 fadeLength); void checkEndSample(void); void nextCompositionPos(void); }; -- cgit v1.2.3