diff options
author | Paul Gilbert | 2015-03-17 23:09:04 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-03-17 23:09:04 -0400 |
commit | 62f3f5d14e391cdac0bbfe200cdde2e4773afba4 (patch) | |
tree | f8edfbab5b33112c8087c20db7f5f7ea588b7895 | |
parent | ec4319923452bebade836b43a912de06958315a6 (diff) | |
download | scummvm-rg350-62f3f5d14e391cdac0bbfe200cdde2e4773afba4.tar.gz scummvm-rg350-62f3f5d14e391cdac0bbfe200cdde2e4773afba4.tar.bz2 scummvm-rg350-62f3f5d14e391cdac0bbfe200cdde2e4773afba4.zip |
SHERLOCK: Remainder of showCityCutscene implemented
-rw-r--r-- | engines/sherlock/animation.cpp | 7 | ||||
-rw-r--r-- | engines/sherlock/events.cpp | 23 | ||||
-rw-r--r-- | engines/sherlock/events.h | 4 | ||||
-rw-r--r-- | engines/sherlock/graphics.cpp | 39 | ||||
-rw-r--r-- | engines/sherlock/graphics.h | 6 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel.cpp | 70 | ||||
-rw-r--r-- | engines/sherlock/screen.cpp | 87 | ||||
-rw-r--r-- | engines/sherlock/screen.h | 11 | ||||
-rw-r--r-- | engines/sherlock/sherlock.cpp | 3 | ||||
-rw-r--r-- | engines/sherlock/sherlock.h | 8 | ||||
-rw-r--r-- | engines/sherlock/sprite.cpp | 37 | ||||
-rw-r--r-- | engines/sherlock/sprite.h | 12 |
12 files changed, 246 insertions, 61 deletions
diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 0e932b6dd2..6788cc51d7 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -95,10 +95,9 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f // Load initial image Common::String vdaName = baseName + ".vda"; - Common::SeekableReadStream *vdaStream = _vm->_res->load(vdaName); - Sprite sprite(*vdaStream, true); + Sprite sprite(vdaName, true); - events.delay(minDelay); + events.wait(minDelay); if (fade != 0 && fade != 255) screen.fadeToBlack(); @@ -150,7 +149,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f sound.playSound(fname); } - events.delay(speed); + events.wait(speed); } if (events.isKeyPressed()) { diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 4a51c4a5fb..c6c013193c 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -158,17 +158,26 @@ void EventsManager::clearEvents() { } /** - * Delay for a given number of cycles, where each cycle is 1/60th of a second + * Delay for a given number of game frames, where each frame is 1/60th of a second */ -void EventsManager::delay(int cycles) { - uint32 totalMilli = cycles * 1000 / GAME_FRAME_RATE; - uint32 delayEnd = g_system->getMillis() + totalMilli; +void EventsManager::wait(int numFrames) { + uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE; + delay(totalMilli); +} + +bool EventsManager::delay(uint32 time, bool interruptable) { + uint32 delayEnd = g_system->getMillis() + time; while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { - g_system->delayMillis(10); + pollEventsAndWait(); - pollEvents(); + if (interruptable && (isKeyPressed() || _mouseClicked)) { + clearEvents(); + return false; + } } + + return true; } /** @@ -183,7 +192,7 @@ void EventsManager::waitForNextFrame() { uint32 frameCtr = getFrameCounter(); while (!_vm->shouldQuit() && frameCtr == _frameCounter) { - delay(1); + pollEventsAndWait(); mouseClicked |= _mouseClicked; mouseButtons |= _mouseButtons; diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h index f4e6964ef5..4493fcdc65 100644 --- a/engines/sherlock/events.h +++ b/engines/sherlock/events.h @@ -75,7 +75,9 @@ public: void clearEvents(); - void delay(int amount); + void wait(int numFrames); + + bool delay(uint32 time, bool interruptable = false); void waitForNextFrame(); diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/graphics.cpp index 2bce822707..a4990fb6c6 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/graphics.cpp @@ -36,6 +36,13 @@ Surface::~Surface() { } /** + * Copy a surface into this one + */ +void Surface::blitFrom(const Graphics::Surface &src) { + blitFrom(src, Common::Point(0, 0)); +} + +/** * Draws a surface at a given position within this surface */ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { @@ -59,18 +66,25 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { drawRect.bottom -= (bottom - this->h); } - if (drawRect.isValidRect()) { - addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), - destPt.y + drawRect.height())); - copyRectToSurface(src, destPt.x, destPt.y, drawRect); - } + if (drawRect.isValidRect()) + blitFrom(src, destPt, drawRect); } +/** + * Draws a sub-section of a surface at a given position within this surface + */ +void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, + const Common::Rect &srcBounds) { + addDirtyRect(Common::Rect(pt.x, pt.y, pt.x + srcBounds.width(), + pt.y + srcBounds.height())); + copyRectToSurface(src, pt.x, pt.y, srcBounds); +} /** * Draws a surface at a given position within this surface with transparency */ -void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt) { +void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped, int overrideColor) { Common::Rect drawRect(0, 0, src.w, src.h); Common::Point destPt = pt; @@ -94,18 +108,25 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p if (!drawRect.isValidRect()) return; + if (flipped) + drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, + src.w - drawRect.left, src.h - drawRect.top); + addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), destPt.y + drawRect.height())); // Draw loop const int TRANSPARENCY = 0xFF; for (int yp = 0; yp < drawRect.height(); ++yp) { - const byte *srcP = (const byte *)src.getBasePtr(drawRect.left, drawRect.top + yp); + const byte *srcP = (const byte *)src.getBasePtr( + flipped ? drawRect.right : drawRect.left, drawRect.top + yp); byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); - for (int xp = 0; xp < drawRect.width(); ++xp, ++srcP, ++destP) { + for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { if (*srcP != TRANSPARENCY) - *destP = *srcP; + *destP = overrideColor ? overrideColor : *srcP; + + srcP = flipped ? srcP - 1 : srcP + 1; } } } diff --git a/engines/sherlock/graphics.h b/engines/sherlock/graphics.h index 983a22a790..82c48307d7 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/graphics.h @@ -35,8 +35,12 @@ public: Surface(uint16 width, uint16 height); ~Surface(); + void blitFrom(const Graphics::Surface &src); void blitFrom(const Graphics::Surface &src, const Common::Point &pt); - void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt); + void blitFrom(const Graphics::Surface &src, const Common::Point &pt, + const Common::Rect &srcBounds); + void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0); void fillRect(int x1, int y1, int x2, int y2, byte color); }; diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 90a93de1b1..0e5a3bec34 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -59,15 +59,75 @@ void ScalpelEngine::showOpening() { } bool ScalpelEngine::showCityCutscene() { -// byte palette[PALETTE_SIZE]; + byte palette[PALETTE_SIZE]; _sound->playMusic("prolog1.mus"); _titleOverride = "title.lib"; _soundOverride = "title.snd"; - _animation->playPrologue("26open1", 1, 255, true, 2); - - // TODO - return true; + bool finished = _animation->playPrologue("26open1", 1, 255, true, 2); + + if (finished) { + Sprite titleSprites("title2.vgs", true); + _screen->_backBuffer.blitFrom(*_screen); + _screen->_backBuffer2.blitFrom(*_screen); + + // London, England + _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(10, 11)); + _screen->randomTransition(); + finished = _events->delay(1000, true); + + // November, 1888 + if (finished) { + _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(101, 102)); + _screen->randomTransition(); + finished = _events->delay(5000, true); + } + + // Transition out the title + _screen->_backBuffer.blitFrom(_screen->_backBuffer2); + _screen->randomTransition(); + } + + if (finished) + finished = _animation->playPrologue("26open2", 1, 0, false, 2); + + if (finished) { + Sprite titleSprites("title.vgs", true); + _screen->_backBuffer.blitFrom(*_screen); + _screen->_backBuffer2.blitFrom(*_screen); + + // The Lost Files of + _screen->_backBuffer.transBlitFrom(titleSprites[0], Common::Point(75, 6)); + // Sherlock Holmes + _screen->_backBuffer.transBlitFrom(titleSprites[1], Common::Point(34, 21)); + // copyright + _screen->_backBuffer.transBlitFrom(titleSprites[2], Common::Point(4, 190)); + + _screen->verticalTransition(); + finished = _events->delay(4000, true); + + if (finished) { + _screen->_backBuffer.blitFrom(_screen->_backBuffer2); + _screen->randomTransition(); + finished = _events->delay(2000); + } + + if (finished) { + _screen->getPalette(palette); + _screen->fadeToBlack(2); + } + + if (finished) { + // In the alley... + _screen->transBlitFrom(titleSprites[3], Common::Point(72, 51)); + _screen->fadeIn(palette, 3); + finished = _events->delay(3000, true); + } + } + + _titleOverride = ""; + _soundOverride = ""; + return finished; } bool ScalpelEngine::showAlleyCutscene() { diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 500abc1197..41cf19e48c 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -28,7 +28,7 @@ namespace Sherlock { Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _vm(vm), - _backBuffer1(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), + _backBuffer(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), _backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) { setFont(1); } @@ -94,27 +94,30 @@ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { return total; } -void Screen::fadeToBlack() { - const int FADE_AMOUNT = 2; - bool repeatFlag; - byte *srcP; - int count; +/** + * Fade out the palette to black + */ +void Screen::fadeToBlack(int speed) { byte tempPalette[PALETTE_SIZE]; + Common::fill(&tempPalette[0], &tempPalette[PALETTE_SIZE], 0); - getPalette(tempPalette); - do { - repeatFlag = false; - for (srcP = &tempPalette[0], count = 0; count < PALETTE_SIZE; ++count, ++srcP) { - int v = *srcP; - if (v) { - repeatFlag = true; - *srcP = MAX(*srcP - FADE_AMOUNT, 0); - } - } + while (equalizePalette(tempPalette)) { + _vm->_events->delay(15 * speed); + } - setPalette(tempPalette); - _vm->_events->pollEventsAndWait(); - } while (repeatFlag && !_vm->shouldQuit()); + setPalette(tempPalette); +} + +/** + * Fade in a given palette + */ +void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { + int count = 50; + while (equalizePalette(palette) && --count) { + _vm->_events->delay(15 * speed); + } + + setPalette(palette); } /** @@ -170,4 +173,50 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co return !destRect.isEmpty(); } +/** + * Do a random pixel transition in from _backBuffer surface to the screen + */ +void Screen::randomTransition() { + EventsManager &events = *_vm->_events; + + for (int idx = 0; idx <= 65535; ++idx) { + int offset = _vm->getRandomNumber(this->w * this->h); + *((byte *)getPixels() + offset) = *((const byte *)_backBuffer.getPixels() + offset); + + if (idx != 0 && (idx % 100) == 0) { + _dirtyRects.clear(); + addDirtyRect(Common::Rect(0, 0, this->w, this->h)); + events.delay(5); + } + } + + // Make sure everything has been transferred + blitFrom(_backBuffer); +} + +/** + * Transition to the surface from _backBuffer using a vertical transition + */ +void Screen::verticalTransition() { + EventsManager &events = *_vm->_events; + + byte table[SHERLOCK_SCREEN_WIDTH]; + Common::fill(&table[0], &table[SHERLOCK_SCREEN_WIDTH], 0); + + for (int yp = 0; yp < SHERLOCK_SCREEN_HEIGHT; ++yp) { + for (int xp = 0; xp < SHERLOCK_SCREEN_WIDTH; ++xp) { + int temp = (table[xp] >= 197) ? SHERLOCK_SCREEN_HEIGHT - table[xp] : + _vm->getRandomNumber(3) + 1; + + if (temp) { + blitFrom(_backBuffer, Common::Point(xp, table[xp]), + Common::Rect(xp, table[xp], xp + 1, table[xp] + temp)); + table[xp] += temp; + } + } + + events.delay(10); + } +} + } // End of namespace Sherlock diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index d244452771..0c0175d2ed 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -41,7 +41,6 @@ class Screen : public Surface { private: SherlockEngine *_vm; int _fontNumber; - Surface _backBuffer1, _backBuffer2; Common::List<Common::Rect> _dirtyRects; void mergeDirtyRects(); @@ -50,6 +49,8 @@ private: protected: virtual void addDirtyRect(const Common::Rect &r); public: + Surface _backBuffer, _backBuffer2; +public: Screen(SherlockEngine *vm); void setFont(int fontNumber); @@ -62,7 +63,13 @@ public: int equalizePalette(const byte palette[PALETTE_SIZE]); - void fadeToBlack(); + void fadeToBlack(int speed = 2); + + void fadeIn(const byte palette[PALETTE_SIZE], int speed = 2); + + void randomTransition(); + + void verticalTransition(); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 1fba746f8d..add24cba9f 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -29,7 +29,7 @@ namespace Sherlock { SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : - Engine(syst), _gameDescription(gameDesc) { + Engine(syst), _gameDescription(gameDesc), _randomSource("Sherlock") { _animation = nullptr; _debugger = nullptr; _events = nullptr; @@ -82,6 +82,7 @@ void SherlockEngine::initialize() { _screen = new Screen(this); _sound = new Sound(this); _talk = new Talk(); + Sprite::setVm(this); } Common::Error SherlockEngine::run() { diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 8d24a78c81..cedc57a9f8 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -26,9 +26,10 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/endian.h" -#include "common/util.h" -#include "common/savefile.h" #include "common/hash-str.h" +#include "common/random.h" +#include "common/savefile.h" +#include "common/util.h" #include "engines/engine.h" #include "sherlock/animation.h" #include "sherlock/debugger.h" @@ -79,6 +80,7 @@ public: Screen *_screen; Sound *_sound; Talk *_talk; + Common::RandomSource _randomSource; Common::Array<bool> _flags; Common::String _soundOverride; Common::String _titleOverride; @@ -96,6 +98,8 @@ public: Common::Platform getPlatform() const; Common::String getGameFile(int fileType); + + int getRandomNumber(int limit) { return _randomSource.getRandomNumber(limit - 1); } }; } // End of namespace Sherlock diff --git a/engines/sherlock/sprite.cpp b/engines/sherlock/sprite.cpp index be5a0e0d27..8a7bb4cf29 100644 --- a/engines/sherlock/sprite.cpp +++ b/engines/sherlock/sprite.cpp @@ -22,10 +22,26 @@ #include "sherlock/sprite.h" #include "sherlock/screen.h" +#include "sherlock/sherlock.h" #include "common/debug.h" namespace Sherlock { +SherlockEngine *Sprite::_vm; + +void Sprite::setVm(SherlockEngine *vm) { + _vm = vm; +} + +Sprite::Sprite(const Common::String &name, bool skipPal) { + Common::SeekableReadStream *stream = _vm->_res->load(name); + + Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); + load(*stream, skipPal); + + delete stream; +} + Sprite::Sprite(Common::SeekableReadStream &stream, bool skipPal) { Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0); load(stream, skipPal); @@ -39,7 +55,7 @@ Sprite::~Sprite() { /** * Load the data of the sprite */ -void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { +void Sprite::load(Common::SeekableReadStream &stream, bool skipPalette) { loadPalette(stream); while (stream.pos() < stream.size()) { @@ -50,7 +66,7 @@ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { frame._position.x = stream.readUint16LE(); frame._position.y = stream.readByte(); - frame._rleEncoded = !skipPal && (frame._position.x == 1); + frame._rleEncoded = !skipPalette && (frame._position.x == 1); if (frame._flags & 0xFF) { // Nibble packed frame data @@ -78,15 +94,20 @@ void Sprite::load(Common::SeekableReadStream &stream, bool skipPal) { * Gets the palette at the start of the sprite file */ void Sprite::loadPalette(Common::SeekableReadStream &stream) { - // Read in the palette + // Check for palette int v1 = stream.readUint16LE() + 1; int v2 = stream.readUint16LE() + 1; int size = v1 * v2; - assert((size - 12) == PALETTE_SIZE); - - stream.seek(4 + 12, SEEK_CUR); - for (int idx = 0; idx < PALETTE_SIZE; ++idx) - _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); + + if ((size - 12) == PALETTE_SIZE) { + // Found palette, so read it in + stream.seek(4 + 12, SEEK_CUR); + for (int idx = 0; idx < PALETTE_SIZE; ++idx) + _palette[idx] = VGA_COLOR_TRANS(stream.readByte()); + } else { + // Not a palette, so rewind to start of frame data for normal frame processing + stream.seek(-4, SEEK_CUR); + } } /** diff --git a/engines/sherlock/sprite.h b/engines/sherlock/sprite.h index 8aedbdb9c5..844013db43 100644 --- a/engines/sherlock/sprite.h +++ b/engines/sherlock/sprite.h @@ -30,6 +30,8 @@ namespace Sherlock { +class SherlockEngine; + struct SpriteFrame { uint32 _size; uint16 _width, _height; @@ -38,18 +40,24 @@ struct SpriteFrame { Common::Point _position; byte _rleMarker; Graphics::Surface _frame; + + operator Graphics::Surface &() { return _frame; } }; class Sprite: public Common::Array<SpriteFrame> { private: - void load(Common::SeekableReadStream &stream, bool skipPal); + static SherlockEngine *_vm; + + void load(Common::SeekableReadStream &stream, bool skipPalette); void loadPalette(Common::SeekableReadStream &stream); void decompressFrame(SpriteFrame &frame, const byte *src); public: byte _palette[256 * 3]; public: - Sprite(Common::SeekableReadStream &stream, bool skipPal = false); + Sprite(const Common::String &name, bool skipPal = false); + Sprite(Common::SeekableReadStream &stream, bool skipPal = false); ~Sprite(); + static void setVm(SherlockEngine *vm); }; } // End of namespace Sherlock |