aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sherlock/events.cpp24
-rw-r--r--engines/sherlock/events.h10
-rw-r--r--engines/sherlock/resources.cpp57
-rw-r--r--engines/sherlock/resources.h3
-rw-r--r--engines/sherlock/room.cpp2
-rw-r--r--engines/sherlock/room.h3
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp177
-rw-r--r--engines/sherlock/scalpel/scalpel.h12
-rw-r--r--engines/sherlock/screen.cpp1
-rw-r--r--engines/sherlock/screen.h1
-rw-r--r--engines/sherlock/sherlock.cpp16
-rw-r--r--engines/sherlock/sherlock.h4
-rw-r--r--engines/sherlock/sound.cpp14
-rw-r--r--engines/sherlock/sound.h4
14 files changed, 297 insertions, 31 deletions
diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp
index b2d9fc65e8..1a882eedea 100644
--- a/engines/sherlock/events.cpp
+++ b/engines/sherlock/events.cpp
@@ -32,7 +32,8 @@ namespace Sherlock {
EventsManager::EventsManager(SherlockEngine *vm) {
_vm = vm;
- _cursorId = CURSOR_NONE;
+ _cursorSprites = nullptr;
+ _cursorIndex = -1;
_frameCounter = 1;
_priorFrameTime = 0;
_mouseClicked = false;
@@ -40,15 +41,30 @@ EventsManager::EventsManager(SherlockEngine *vm) {
}
EventsManager::~EventsManager() {
+ delete _cursorSprites;
+}
+
+/**
+ * Load a set of cursors from the specified file
+ */
+void EventsManager::loadCursors(const Common::String &filename) {
+ hideCursor();
+ delete _cursorSprites;
+
+ _cursorSprites = new Sprite(filename);
}
/**
* Set the cursor to show
*/
-void EventsManager::setCursor(CursorType cursorId) {
- _cursorId = cursorId;
+void EventsManager::changeCursor(int cursorIndex) {
+ _cursorIndex = cursorIndex;
+
+ // Set the cursor data
+ Graphics::Surface &s = (*_cursorSprites)[cursorIndex];
+ CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff);
- // TODO: Cursor handling
+ showCursor();
}
/**
diff --git a/engines/sherlock/events.h b/engines/sherlock/events.h
index 4493fcdc65..1f7352eeb5 100644
--- a/engines/sherlock/events.h
+++ b/engines/sherlock/events.h
@@ -26,11 +26,10 @@
#include "common/scummsys.h"
#include "common/events.h"
#include "common/stack.h"
+#include "sherlock/sprite.h"
namespace Sherlock {
-enum CursorType { CURSOR_NONE = 0 };
-
#define GAME_FRAME_RATE 60
#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
@@ -42,10 +41,11 @@ private:
uint32 _frameCounter;
uint32 _priorFrameTime;
Common::Point _mousePos;
+ Sprite *_cursorSprites;
bool checkForNextFrameCounter();
public:
- CursorType _cursorId;
+ int _cursorIndex;
byte _mouseButtons;
bool _mouseClicked;
Common::Stack<Common::KeyState> _pendingKeys;
@@ -53,7 +53,9 @@ public:
EventsManager(SherlockEngine *vm);
~EventsManager();
- void setCursor(CursorType cursorId);
+ void loadCursors(const Common::String &filename);
+
+ void changeCursor(int cursorIndex);
void showCursor();
diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp
index 47e2046084..6636ca5be8 100644
--- a/engines/sherlock/resources.cpp
+++ b/engines/sherlock/resources.cpp
@@ -41,43 +41,57 @@ bool Cache::isCached(const Common::String &filename) const {
* If the file is LZW compressed, automatically decompresses it and loads
* the uncompressed version into memory
*/
-void Cache::load(const Common::String &filename) {
+void Cache::load(const Common::String &name) {
// First check if the entry already exists
- if (_resources.contains(filename))
+ if (_resources.contains(name))
return;
- // Allocate a new cache entry
- _resources[filename] = CacheEntry();
- CacheEntry &cacheEntry = _resources[filename];
-
// Open the file for reading
Common::File f;
- if (!f.open(filename))
- error("Could not read file - %s", filename.c_str());
+ if (!f.open(name))
+ error("Could not read file - %s", name.c_str());
+
+ load(name, f);
+
+ f.close();
+}
+
+/**
+ * Load a cache entry based on a passed stream
+ */
+void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) {
+ // First check if the entry already exists
+ if (_resources.contains(name))
+ return;
// Check whether the file is compressed
const char LZW_HEADER[5] = { "LZV\x1a" };
char header[5];
- f.read(header, 5);
+ stream.read(header, 5);
bool isCompressed = !strncmp(header, LZW_HEADER, 5);
- f.seek(0);
+ stream.seek(0);
+
+ // Allocate a new cache entry
+ _resources[name] = CacheEntry();
+ CacheEntry &cacheEntry = _resources[name];
if (isCompressed) {
// It's compressed, so decompress the file and store it's data in the cache entry
- Common::SeekableReadStream *decompressed = decompressLZ(f);
+ Common::SeekableReadStream *decompressed = decompressLZ(stream);
cacheEntry.resize(decompressed->size());
decompressed->read(&cacheEntry[0], decompressed->size());
delete decompressed;
} else {
// It's not, so read the raw data of the file into the cache entry
- cacheEntry.resize(f.size());
- f.read(&cacheEntry[0], f.size());
+ cacheEntry.resize(stream.size());
+ stream.read(&cacheEntry[0], stream.size());
}
-
- f.close();
}
+/**
+ * Get a file from the cache
+ */
Common::SeekableReadStream *Cache::get(const Common::String &filename) const {
// Return a memory stream that encapsulates the data
const CacheEntry &cacheEntry = _resources[filename];
@@ -96,7 +110,6 @@ Resources::Resources() {
addToCache("portrait.lib");
}
-
/**
* Adds the specified file to the cache. If it's a library file, takes care of
* loading it's index for future use
@@ -113,6 +126,18 @@ void Resources::addToCache(const Common::String &filename) {
delete stream;
}
+/**
+ * Adds a resource from a library file tot he cache
+ */
+void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) {
+ // Get the resource
+ Common::SeekableReadStream *stream = load(filename, libFilename);
+
+ _cache.load(filename, *stream);
+
+ delete stream;
+}
+
Common::SeekableReadStream *Resources::load(const Common::String &filename) {
// First check if the file is directly in the cache
if (_cache.isCached(filename))
diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h
index edb9bd8ba0..cd6e60c325 100644
--- a/engines/sherlock/resources.h
+++ b/engines/sherlock/resources.h
@@ -57,6 +57,7 @@ public:
bool isCached(const Common::String &filename) const;
void load(const Common::String &name);
+ void load(const Common::String &name, Common::SeekableReadStream &stream);
Common::SeekableReadStream *get(const Common::String &filename) const;
};
@@ -72,6 +73,8 @@ public:
Resources();
void addToCache(const Common::String &filename);
+ void addToCache(const Common::String &filename, const Common::String &libFilename);
+ bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); }
Common::SeekableReadStream *load(const Common::String &filename);
diff --git a/engines/sherlock/room.cpp b/engines/sherlock/room.cpp
index 9926899953..c06d707b40 100644
--- a/engines/sherlock/room.cpp
+++ b/engines/sherlock/room.cpp
@@ -27,8 +27,8 @@ namespace Sherlock {
Rooms::Rooms() {
for (int roomNum = 0; roomNum < ROOMS_COUNT; ++roomNum)
Common::fill(&_stats[roomNum][0], &_stats[roomNum][9], false);
-
_goToRoom = -1;
+ _oldCharPoint = 0;
}
} // End of namespace Sherlock
diff --git a/engines/sherlock/room.h b/engines/sherlock/room.h
index 75800b623a..0f2bc56a45 100644
--- a/engines/sherlock/room.h
+++ b/engines/sherlock/room.h
@@ -94,6 +94,9 @@ public:
bool _stats[ROOMS_COUNT][9];
bool _savedStats[ROOMS_COUNT][9];
int _goToRoom;
+ Common::Point _bigPos;
+ Common::Point _overPos;
+ int _oldCharPoint;
public:
Rooms();
};
diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp
index 0e5a3bec34..d691bbd8bb 100644
--- a/engines/sherlock/scalpel/scalpel.cpp
+++ b/engines/sherlock/scalpel/scalpel.cpp
@@ -27,6 +27,12 @@ namespace Sherlock {
namespace Scalpel {
+ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
+ SherlockEngine(syst, gameDesc) {
+ _tempFadeStyle = 0;
+ _chessResult = 0;
+}
+
/**
* Game initialization
*/
@@ -131,17 +137,188 @@ bool ScalpelEngine::showCityCutscene() {
}
bool ScalpelEngine::showAlleyCutscene() {
+ // TODO
return true;
}
bool ScalpelEngine::showStreetCutscene() {
+ // TODO
return true;
}
bool ScalpelEngine::showOfficeCutscene() {
+ // TODO
return true;
}
+int ScalpelEngine::doChessBoard() {
+ // TODO
+ return 0;
+}
+
+void ScalpelEngine::playDarts() {
+ // TODO
+}
+
+/**
+ * Starting a scene within the game
+ */
+void ScalpelEngine::startScene() {
+ if (_rooms->_goToRoom == 100 || _rooms->_goToRoom == 98) {
+ // Chessboard selection
+ if (_sound->_musicEnabled) {
+ if (_sound->loadSong(100)) {
+ if (_sound->_music)
+ _sound->startSong();
+ }
+ }
+
+ _rooms->_goToRoom = doChessBoard();
+
+ _sound->freeSong();
+ _hsavedPos = Common::Point(-1, -1);
+ _hsavedFs = -1;
+ }
+
+ // Some rooms are prologue cutscenes, rather than normal game scenes. These are:
+ // 2: Blackwood's capture
+ // 52: Rescuing Anna
+ // 53: Moorehead's death / subway train
+ // 55: Fade out and exit
+ // 70: Brumwell suicide
+ switch (_rooms->_goToRoom) {
+ case 2:
+ case 52:
+ case 53:
+ case 70:
+ if (_sound->_musicEnabled && _sound->loadSong(_rooms->_goToRoom)) {
+ if (_sound->_music)
+ _sound->startSong();
+ }
+
+ switch (_rooms->_goToRoom) {
+ case 2:
+ // Blackwood's capture
+ _res->addToCache("final2.vda", "epilogue.lib");
+ _res->addToCache("final2.vdx", "epilogue.lib");
+ _animation->playPrologue("final1", 1, 3, true, 4);
+ _animation->playPrologue("final22", 1, 0, false, 4);
+ break;
+
+ case 52:
+ // Rescuing Anna
+ _res->addToCache("finalr2.vda", "epilogue.lib");
+ _res->addToCache("finalr2.vdx", "epilogue.lib");
+ _res->addToCache("finale1.vda", "epilogue.lib");
+ _res->addToCache("finale1.vdx", "epilogue.lib");
+ _res->addToCache("finale2.vda", "epilogue.lib");
+ _res->addToCache("finale2.vdx", "epilogue.lib");
+ _res->addToCache("finale3.vda", "epilogue.lib");
+ _res->addToCache("finale3.vdx", "epilogue.lib");
+ _res->addToCache("finale4.vda", "EPILOG2.lib");
+ _res->addToCache("finale4.vdx", "EPILOG2.lib");
+
+ _animation->playPrologue("finalr1", 1, 3, true, 4);
+ _animation->playPrologue("finalr2", 1, 0, false, 4);
+
+ if (!_res->isInCache("finale2.vda")) {
+ // Finale file isn't cached
+ _res->addToCache("finale2.vda", "epilogue.lib");
+ _res->addToCache("finale2.vdx", "epilogue.lib");
+ _res->addToCache("finale3.vda", "epilogue.lib");
+ _res->addToCache("finale3.vdx", "epilogue.lib");
+ _res->addToCache("finale4.vda", "EPILOG2.lib");
+ _res->addToCache("finale4.vdx", "EPILOG2.lib");
+ }
+
+ _animation->playPrologue("finale1", 1, 0, false, 4);
+ _animation->playPrologue("finale2", 1, 0, false, 4);
+ _animation->playPrologue("finale3", 1, 0, false, 4);
+
+ _useEpilogue2 = true;
+ _animation->playPrologue("finale4", 1, 0, false, 4);
+ _useEpilogue2 = false;
+ break;
+
+ case 53:
+ // Moorehead's death / subway train
+ _res->addToCache("SUBWAY2.vda", "epilogue.lib");
+ _res->addToCache("SUBWAY2.vdx", "epilogue.lib");
+ _res->addToCache("SUBWAY3.vda", "epilogue.lib");
+ _res->addToCache("SUBWAY3.vdx", "epilogue.lib");
+
+ _animation->playPrologue("SUBWAY1", 1, 3, true, 4);
+ _animation->playPrologue("SUBWAY2", 1, 0, false, 4);
+ _animation->playPrologue("SUBWAY3", 1, 0, false, 4);
+
+ // Set fading to direct fade temporary so the transition goes quickly.
+ _tempFadeStyle = _screen->_fadeStyle ? 257 : 256;
+ _screen->_fadeStyle = false;
+ break;
+
+ case 70:
+ // Brumwell suicide
+ _animation->playPrologue("suicid", 1, 3, true, 4);
+ break;
+ default:
+ break;
+ }
+
+ // Except for the Moorehead Murder scene, fade to black first
+ if (_rooms->_goToRoom != 53) {
+ _events->wait(40);
+ _screen->fadeToBlack(3);
+ }
+
+ switch (_rooms->_goToRoom) {
+ case 52:
+ _rooms->_goToRoom = 27; // Go to the Lawyer's Office
+ _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position
+ _rooms->_overPos = Common::Point(22900 - 600, 9400 + 900); // Overland position
+ _rooms->_oldCharPoint = 27;
+ break;
+
+ case 53:
+ _rooms->_goToRoom = 17; // Go to St. Pancras Station
+ _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position
+ _rooms->_overPos = Common::Point(32500 - 600, 3000 + 900); // Overland position
+ _rooms->_oldCharPoint = 17;
+ break;
+
+ default:
+ _rooms->_goToRoom = 4; // Back to Baker st.
+ _rooms->_bigPos = Common::Point(0, 0); // Overland scroll position
+ _rooms->_overPos = Common::Point(14500 - 600, 8400 + 900); // Overland position
+ _rooms->_oldCharPoint = 4;
+ break;
+ }
+
+ // Free any song from the previous scene
+ _sound->freeSong();
+ break;
+
+ case 55:
+ // Exit game
+ _screen->fadeToBlack(3);
+ quitGame();
+ return;
+
+ default:
+ break;
+ }
+
+ _events->loadCursors("rmouse.vgs");
+ _events->changeCursor(0);
+
+ if (_rooms->_goToRoom == 99) {
+ // Chess Board
+ playDarts();
+ _chessResult = _rooms->_goToRoom = 19; // Go back to the bar
+ }
+
+ _chessResult = _rooms->_goToRoom;
+}
+
} // End of namespace Scalpel
} // End of namespace Scalpel
diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h
index 584bd78a20..83510064fa 100644
--- a/engines/sherlock/scalpel/scalpel.h
+++ b/engines/sherlock/scalpel/scalpel.h
@@ -31,17 +31,25 @@ namespace Scalpel {
class ScalpelEngine : public SherlockEngine {
private:
+ int _tempFadeStyle;
+ int _chessResult;
+
bool showCityCutscene();
bool showAlleyCutscene();
bool showStreetCutscene();
bool showOfficeCutscene();
+
+ int doChessBoard();
+
+ void playDarts();
protected:
virtual void initialize();
virtual void showOpening();
+
+ virtual void startScene();
public:
- ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) :
- SherlockEngine(syst, gameDesc) {}
+ ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~ScalpelEngine() {}
};
diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp
index 7a4d4863ac..0ec5df9c4c 100644
--- a/engines/sherlock/screen.cpp
+++ b/engines/sherlock/screen.cpp
@@ -31,6 +31,7 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR
_backBuffer(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT),
_backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) {
_transitionSeed = 1;
+ _fadeStyle = false;
setFont(1);
}
diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h
index 78ccffc575..05fd80a8b7 100644
--- a/engines/sherlock/screen.h
+++ b/engines/sherlock/screen.h
@@ -51,6 +51,7 @@ protected:
virtual void addDirtyRect(const Common::Rect &r);
public:
Surface _backBuffer, _backBuffer2;
+ bool _fadeStyle;
public:
Screen(SherlockEngine *vm);
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index add24cba9f..907f0a5a16 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -40,9 +40,10 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
_sound = nullptr;
_talk = nullptr;
_useEpilogue2 = false;
+ _hsavedPos = Common::Point(-1, -1);
+ _hsavedFs = -1;
}
-
SherlockEngine::~SherlockEngine() {
delete _animation;
delete _debugger;
@@ -73,11 +74,11 @@ void SherlockEngine::initialize() {
_midi->setNativeMT32(native_mt32);
*/
+ _res = new Resources();
_animation = new Animation(this);
_debugger = new Debugger(this);
_events = new EventsManager(this);
_journal = new Journal();
- _res = new Resources();
_rooms = new Rooms();
_screen = new Screen(this);
_sound = new Sound(this);
@@ -90,8 +91,15 @@ Common::Error SherlockEngine::run() {
showOpening();
- // TODO: Rest of game
-
+ while (!shouldQuit()) {
+ // Prepare for scene, and handle any game-specific scenes
+ startScene();
+
+ // TODO: Implement game and remove this dummy loop
+ while (!shouldQuit())
+ _events->pollEventsAndWait();
+ }
+
return Common::kNoError;
}
diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h
index cedc57a9f8..7906417d7e 100644
--- a/engines/sherlock/sherlock.h
+++ b/engines/sherlock/sherlock.h
@@ -69,6 +69,8 @@ protected:
virtual void initialize();
virtual void showOpening() = 0;
+
+ virtual void startScene() {}
public:
const SherlockGameDescription *_gameDescription;
Animation *_animation;
@@ -85,6 +87,8 @@ public:
Common::String _soundOverride;
Common::String _titleOverride;
bool _useEpilogue2;
+ Common::Point _hsavedPos;
+ int _hsavedFs;
public:
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~SherlockEngine();
diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp
index 0957315a35..efc1965637 100644
--- a/engines/sherlock/sound.cpp
+++ b/engines/sherlock/sound.cpp
@@ -29,6 +29,7 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) {
_musicEnabled = true;
_voicesEnabled = true;
_playingEpilogue = false;
+ _music = false;
}
void Sound::playSound(const Common::String &name, WaitType waitType) {
@@ -59,5 +60,18 @@ void Sound::stopMusic() {
// TODO
}
+int Sound::loadSong(int songNumber) {
+ // TODO
+ return 0;
+}
+
+void Sound::startSong() {
+ // TODO
+}
+
+void Sound::freeSong() {
+ // TODO
+}
+
} // End of namespace Sherlock
diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h
index 7775016c94..442e908838 100644
--- a/engines/sherlock/sound.h
+++ b/engines/sherlock/sound.h
@@ -42,6 +42,7 @@ public:
bool _musicEnabled;
bool _voicesEnabled;
bool _playingEpilogue;
+ bool _music;
public:
Sound(SherlockEngine *vm);
@@ -50,6 +51,9 @@ public:
void playCachedSound(int index);
void clearCache();
void stopSound();
+ int loadSong(int songNumber);
+ void startSong();
+ void freeSong();
void playMusic(const Common::String &name);
void stopMusic();