aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sherlock/animation.cpp7
-rw-r--r--engines/sherlock/events.cpp23
-rw-r--r--engines/sherlock/events.h4
-rw-r--r--engines/sherlock/graphics.cpp39
-rw-r--r--engines/sherlock/graphics.h6
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp70
-rw-r--r--engines/sherlock/screen.cpp87
-rw-r--r--engines/sherlock/screen.h11
-rw-r--r--engines/sherlock/sherlock.cpp3
-rw-r--r--engines/sherlock/sherlock.h8
-rw-r--r--engines/sherlock/sprite.cpp37
-rw-r--r--engines/sherlock/sprite.h12
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