diff options
Diffstat (limited to 'engines/agos')
-rw-r--r-- | engines/agos/animation.cpp | 103 | ||||
-rw-r--r-- | engines/agos/animation.h | 6 | ||||
-rw-r--r-- | engines/agos/charset-fontdata.cpp | 90 | ||||
-rw-r--r-- | engines/agos/event.cpp | 6 | ||||
-rw-r--r-- | engines/agos/saveload.cpp | 44 |
5 files changed, 135 insertions, 114 deletions
diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index 29d1b36e19..9176412e0e 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -260,9 +260,6 @@ bool MoviePlayerDXA::load() { debug(0, "Playing video %s", videoName.c_str()); CursorMan.showMouse(false); - - _firstFrameOffset = _fileStream->pos(); - return true; } @@ -271,6 +268,10 @@ void MoviePlayerDXA::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) { uint w = getWidth(); const Graphics::Surface *surface = decodeNextFrame(); + + if (!surface) + return; + byte *src = (byte *)surface->pixels; dst += y * pitch + x; @@ -281,7 +282,7 @@ void MoviePlayerDXA::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) { } while (--h); if (hasDirtyPalette()) - setSystemPalette(); + g_system->getPaletteManager()->setPalette(getPalette(), 0, 256); } void MoviePlayerDXA::playVideo() { @@ -302,38 +303,11 @@ void MoviePlayerDXA::stopVideo() { } void MoviePlayerDXA::startSound() { - uint32 offset, size; - - if (getSoundTag() == MKTAG('W','A','V','E')) { - size = _fileStream->readUint32BE(); - - if (_sequenceNum) { - Common::File in; - - _fileStream->seek(size, SEEK_CUR); - - in.open("audio.wav"); - if (!in.isOpen()) { - error("Can't read offset file 'audio.wav'"); - } - - in.seek(_sequenceNum * 8, SEEK_SET); - offset = in.readUint32LE(); - size = in.readUint32LE(); - - in.seek(offset, SEEK_SET); - _bgSoundStream = Audio::makeWAVStream(in.readStream(size), DisposeAfterUse::YES); - in.close(); - } else { - _bgSoundStream = Audio::makeWAVStream(_fileStream->readStream(size), DisposeAfterUse::YES); - } - } else { - _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(baseName); - } + start(); if (_bgSoundStream != NULL) { _vm->_mixer->stopHandle(_bgSound); - _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream); + _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_bgSound, _bgSoundStream, -1, getVolume(), getBalance()); } } @@ -344,8 +318,7 @@ void MoviePlayerDXA::nextFrame() { } if (_vm->_interactiveVideo == TYPE_LOOPING && endOfVideo()) { - _fileStream->seek(_firstFrameOffset); - _curFrame = -1; + rewind(); startSound(); } @@ -374,13 +347,15 @@ bool MoviePlayerDXA::processFrame() { copyFrameToBuffer((byte *)screen->pixels, (_vm->_screenWidth - getWidth()) / 2, (_vm->_screenHeight - getHeight()) / 2, screen->pitch); _vm->_system->unlockScreen(); - Common::Rational soundTime(_mixer->getSoundElapsedTime(_bgSound), 1000); - if ((_bgSoundStream == NULL) || ((soundTime * getFrameRate()).toInt() / 1000 < getCurFrame() + 1)) { + uint32 soundTime = _mixer->getSoundElapsedTime(_bgSound); + uint32 nextFrameStartTime = ((Video::VideoDecoder::VideoTrack *)getTrack(0))->getNextFrameStartTime(); + + if ((_bgSoundStream == NULL) || soundTime < nextFrameStartTime) { if (_bgSoundStream && _mixer->isSoundHandleActive(_bgSound)) { - while (_mixer->isSoundHandleActive(_bgSound) && (soundTime * getFrameRate()).toInt() < getCurFrame()) { + while (_mixer->isSoundHandleActive(_bgSound) && soundTime < nextFrameStartTime) { _vm->_system->delayMillis(10); - soundTime = Common::Rational(_mixer->getSoundElapsedTime(_bgSound), 1000); + soundTime = _mixer->getSoundElapsedTime(_bgSound); } // In case the background sound ends prematurely, update // _ticks so that we can still fall back on the no-sound @@ -399,13 +374,44 @@ bool MoviePlayerDXA::processFrame() { return false; } +void MoviePlayerDXA::readSoundData(Common::SeekableReadStream *stream) { + uint32 tag = stream->readUint32BE(); + + if (tag == MKTAG('W','A','V','E')) { + uint32 size = stream->readUint32BE(); + + if (_sequenceNum) { + Common::File in; + + stream->skip(size); + + in.open("audio.wav"); + if (!in.isOpen()) { + error("Can't read offset file 'audio.wav'"); + } + + in.seek(_sequenceNum * 8, SEEK_SET); + uint32 offset = in.readUint32LE(); + size = in.readUint32LE(); + + in.seek(offset, SEEK_SET); + _bgSoundStream = Audio::makeWAVStream(in.readStream(size), DisposeAfterUse::YES); + in.close(); + } else { + _bgSoundStream = Audio::makeWAVStream(stream->readStream(size), DisposeAfterUse::YES); + } + } else { + _bgSoundStream = Audio::SeekableAudioStream::openStreamFile(baseName); + } +} + /////////////////////////////////////////////////////////////////////////////// // Movie player for Smacker movies /////////////////////////////////////////////////////////////////////////////// MoviePlayerSMK::MoviePlayerSMK(AGOSEngine_Feeble *vm, const char *name) - : MoviePlayer(vm), SmackerDecoder(vm->_mixer) { + : MoviePlayer(vm), SmackerDecoder() { debug(0, "Creating SMK cutscene player"); memset(baseName, 0, sizeof(baseName)); @@ -425,8 +431,6 @@ bool MoviePlayerSMK::load() { CursorMan.showMouse(false); - _firstFrameOffset = _fileStream->pos(); - return true; } @@ -435,6 +439,10 @@ void MoviePlayerSMK::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) { uint w = getWidth(); const Graphics::Surface *surface = decodeNextFrame(); + + if (!surface) + return; + byte *src = (byte *)surface->pixels; dst += y * pitch + x; @@ -445,7 +453,7 @@ void MoviePlayerSMK::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) { } while (--h); if (hasDirtyPalette()) - setSystemPalette(); + g_system->getPaletteManager()->setPalette(getPalette(), 0, 256); } void MoviePlayerSMK::playVideo() { @@ -458,6 +466,7 @@ void MoviePlayerSMK::stopVideo() { } void MoviePlayerSMK::startSound() { + start(); } void MoviePlayerSMK::handleNextFrame() { @@ -467,10 +476,8 @@ void MoviePlayerSMK::handleNextFrame() { } void MoviePlayerSMK::nextFrame() { - if (_vm->_interactiveVideo == TYPE_LOOPING && endOfVideo()) { - _fileStream->seek(_firstFrameOffset); - _curFrame = -1; - } + if (_vm->_interactiveVideo == TYPE_LOOPING && endOfVideo()) + rewind(); if (!endOfVideo()) { decodeNextFrame(); @@ -493,7 +500,7 @@ bool MoviePlayerSMK::processFrame() { uint32 waitTime = getTimeToNextFrame(); - if (!waitTime) { + if (!waitTime && !endOfVideoTracks()) { warning("dropped frame %i", getCurFrame()); return false; } diff --git a/engines/agos/animation.h b/engines/agos/animation.h index 11936aa338..9e31fced6d 100644 --- a/engines/agos/animation.h +++ b/engines/agos/animation.h @@ -67,9 +67,6 @@ protected: virtual void handleNextFrame(); virtual bool processFrame() = 0; virtual void startSound() {} - -protected: - uint32 _firstFrameOffset; }; class MoviePlayerDXA : public MoviePlayer, Video::DXADecoder { @@ -83,6 +80,9 @@ public: void nextFrame(); virtual void stopVideo(); +protected: + void readSoundData(Common::SeekableReadStream *stream); + private: void handleNextFrame(); bool processFrame(); diff --git a/engines/agos/charset-fontdata.cpp b/engines/agos/charset-fontdata.cpp index 87f51cfad2..262ae44f01 100644 --- a/engines/agos/charset-fontdata.cpp +++ b/engines/agos/charset-fontdata.cpp @@ -681,6 +681,51 @@ static const byte feeble_windowFont[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +void AGOSEngine_Feeble::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { + const byte *src; + byte color, *dst; + uint dstPitch, h, w, i; + + if (_noOracleScroll) + return; + + _videoLockOut |= 0x8000; + + dst = getBackGround(); + dstPitch = _backGroundBuf->pitch; + h = 13; + w = getFeebleFontSize(chr); + + if (_language == Common::PL_POL) { + if (!strcmp(getExtra(), "4CD")) + src = polish4CD_feeble_windowFont + (chr - 32) * 13; + else + src = polish2CD_feeble_windowFont + (chr - 32) * 13; + } else { + src = feeble_windowFont + (chr - 32) * 13; + } + dst += y * dstPitch + x + window->textColumnOffset; + + color = window->textColor; + + do { + int8 b = *src++; + i = 0; + do { + if (b < 0) { + if (dst[i] == 0) + dst[i] = color; + } + + b <<= 1; + } while (++i != w); + dst += dstPitch; + } while (--h); + + _videoLockOut &= ~0x8000; +} +#endif + static const byte english_simon1AGAFontData[] = { 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x20,0x10,0x40,0x88,0x30,0x40,0x00,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, @@ -1253,51 +1298,6 @@ void AGOSEngine::renderString(uint vgaSpriteId, uint color, uint width, uint hei } } -void AGOSEngine_Feeble::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { - const byte *src; - byte color, *dst; - uint dstPitch, h, w, i; - - if (_noOracleScroll) - return; - - _videoLockOut |= 0x8000; - - dst = getBackGround(); - dstPitch = _backGroundBuf->pitch; - h = 13; - w = getFeebleFontSize(chr); - - if (_language == Common::PL_POL) { - if (!strcmp(getExtra(), "4CD")) - src = polish4CD_feeble_windowFont + (chr - 32) * 13; - else - src = polish2CD_feeble_windowFont + (chr - 32) * 13; - } else { - src = feeble_windowFont + (chr - 32) * 13; - } - dst += y * dstPitch + x + window->textColumnOffset; - - color = window->textColor; - - do { - int8 b = *src++; - i = 0; - do { - if (b < 0) { - if (dst[i] == 0) - dst[i] = color; - } - - b <<= 1; - } while (++i != w); - dst += dstPitch; - } while (--h); - - _videoLockOut &= ~0x8000; -} -#endif - static const byte czech_simonFont[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x70, 0x70, 0x20, 0x20, 0x00, 0x20, 0x00, diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index ed26b96381..cc1c40c207 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -467,11 +467,7 @@ void AGOSEngine::delay(uint amount) { memset(_saveLoadName, 0, sizeof(_saveLoadName)); sprintf(_saveLoadName, "Quick %d", _saveLoadSlot); _saveLoadType = (event.kbd.hasFlags(Common::KBD_ALT)) ? 1 : 2; - - // We should only allow a load or save when it was possible in original - // This stops load/save during copy protection, conversations and cut scenes - if (!_mouseHideCount && !_showPreposition) - quickLoadOrSave(); + quickLoadOrSave(); } else if (event.kbd.hasFlags(Common::KBD_CTRL)) { if (event.kbd.keycode == Common::KEYCODE_a) { GUI::Dialog *_aboutDialog; diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index b3ec916b47..c6bca1a6e6 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -142,23 +142,41 @@ void AGOSEngine_Feeble::quickLoadOrSave() { } #endif +// The function uses segments of code from the original game scripts +// to allow quick loading and saving, but isn't perfect. +// +// Unfortuntely this allows loading and saving in locations, +// which aren't supported, and will not restore correctly: +// Various locations in Elvira 1/2 and Waxworks where saving +// was disabled void AGOSEngine::quickLoadOrSave() { - // The function uses segments of code from the original game scripts - // to allow quick loading and saving, but isn't perfect. - // - // Unfortuntely this allows loading and saving in locations, - // which aren't supported, and will not restore correctly: - // Any overhead maps in Simon the Sorcerer 2 - // Various locations in Elvira 1/2 and Waxworks where saving - // was disabled - - // The floppy disk demo of Simon the Sorcerer 1 doesn't work. - if (getFeatures() & GF_DEMO) - return; - bool success; Common::String buf; + // Disable loading and saving when it was not possible in the original: + // In overhead maps areas in Simon the Sorcerer 2 + // In the floppy disk demo of Simon the Sorcerer 1 + // In copy protection, conversations and cut scenes + if ((getGameType() == GType_SIMON2 && _boxStarHeight == 200) || + (getGameType() == GType_SIMON1 && (getFeatures() & GF_DEMO)) || + _mouseHideCount || _showPreposition) { + buf = Common::String::format("Quick load or save game isn't supported in this location"); + GUI::MessageDialog dialog(buf, "OK"); + dialog.runModal(); + return; + } + + // Check if Simon is walking, and stop when required + if (getGameType() == GType_SIMON1 && getBitFlag(11)) { + vcStopAnimation(11, 1122); + animate(4, 11, 1122, 0, 0, 2); + waitForSync(1122); + } else if (getGameType() == GType_SIMON2 && getBitFlag(11)) { + vcStopAnimation(11, 232); + animate(4, 11, 232, 0, 0, 2); + waitForSync(1122); + } + char *filename = genSaveName(_saveLoadSlot); if (_saveLoadType == 2) { Subroutine *sub; |