diff options
| author | Paul Gilbert | 2015-03-18 22:32:41 -0400 | 
|---|---|---|
| committer | Paul Gilbert | 2015-03-18 22:32:41 -0400 | 
| commit | 2dc355ff6ecbbc3650beecb341ebe4415de20101 (patch) | |
| tree | 94faa056336d7a1cd77f23f92a3b5fc6c462d9da | |
| parent | b8ad1ce140c91257ba79fe50f41da34a5a6e74c2 (diff) | |
| download | scummvm-rg350-2dc355ff6ecbbc3650beecb341ebe4415de20101.tar.gz scummvm-rg350-2dc355ff6ecbbc3650beecb341ebe4415de20101.tar.bz2 scummvm-rg350-2dc355ff6ecbbc3650beecb341ebe4415de20101.zip | |
SHERLOCK: Implement Scalpel-specific scene starting
| -rw-r--r-- | engines/sherlock/events.cpp | 24 | ||||
| -rw-r--r-- | engines/sherlock/events.h | 10 | ||||
| -rw-r--r-- | engines/sherlock/resources.cpp | 57 | ||||
| -rw-r--r-- | engines/sherlock/resources.h | 3 | ||||
| -rw-r--r-- | engines/sherlock/room.cpp | 2 | ||||
| -rw-r--r-- | engines/sherlock/room.h | 3 | ||||
| -rw-r--r-- | engines/sherlock/scalpel/scalpel.cpp | 177 | ||||
| -rw-r--r-- | engines/sherlock/scalpel/scalpel.h | 12 | ||||
| -rw-r--r-- | engines/sherlock/screen.cpp | 1 | ||||
| -rw-r--r-- | engines/sherlock/screen.h | 1 | ||||
| -rw-r--r-- | engines/sherlock/sherlock.cpp | 16 | ||||
| -rw-r--r-- | engines/sherlock/sherlock.h | 4 | ||||
| -rw-r--r-- | engines/sherlock/sound.cpp | 14 | ||||
| -rw-r--r-- | engines/sherlock/sound.h | 4 | 
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(); | 
