diff options
| author | Paul Gilbert | 2015-05-16 09:29:40 -0400 | 
|---|---|---|
| committer | Paul Gilbert | 2015-05-16 09:29:40 -0400 | 
| commit | af651e19a421781a1498de0e66909a2e9450611c (patch) | |
| tree | ee5991b696600dd4fe03338b04a684a605215a7c | |
| parent | 32d7690e549f5af8fb5f88d9434ae0f54c0e6c69 (diff) | |
| parent | 96e929f5233b23917169c7d0121e9c1e264455c1 (diff) | |
| download | scummvm-rg350-af651e19a421781a1498de0e66909a2e9450611c.tar.gz scummvm-rg350-af651e19a421781a1498de0e66909a2e9450611c.tar.bz2 scummvm-rg350-af651e19a421781a1498de0e66909a2e9450611c.zip  | |
Merge branch 'sherlock' into sherlock2
Conflicts:
	engines/sherlock/decompress.cpp
	engines/sherlock/objects.cpp
	engines/sherlock/objects.h
	engines/sherlock/scene.cpp
	engines/sherlock/scene.h
	engines/sherlock/sound.cpp
26 files changed, 228 insertions, 193 deletions
diff --git a/engines/sherlock/decompress.h b/engines/sherlock/decompress.h deleted file mode 100644 index 694f56aa65..0000000000 --- a/engines/sherlock/decompress.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef SHERLOCK_DECOMPRESS_H -#define SHERLOCK_DECOMPRESS_H - -#include "common/memstream.h" - -namespace Sherlock { - -#include "common/stream.h" - -Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize = -1); - -} // namespace Sherlock - -#endif diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 78ab33bfd0..2804ec1d31 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -25,6 +25,7 @@  #include "sherlock/scalpel/scalpel.h"  #include "sherlock/tattoo/tattoo.h"  #include "common/system.h" +#include "common/translation.h"  #include "engines/advancedDetector.h"  namespace Sherlock { @@ -57,11 +58,29 @@ static const PlainGameDescriptor sherlockGames[] = {  	{0, 0}  }; + +#define GAMEOPTION_ORIGINAL_SAVES	GUIO_GAMEOPTIONS1 + +static const ADExtraGuiOptionsMap optionsList[] = { +	{ +		GAMEOPTION_ORIGINAL_SAVES, +		{ +			_s("Use original savegame dialog"), +			_s("Files button in-game shows original savegame dialog rather than ScummVM menu"), +			"originalsaveload", +			false +		} +	}, + +	AD_EXTRA_GUI_OPTIONS_TERMINATOR +}; +  #include "sherlock/detection_tables.h"  class SherlockMetaEngine : public AdvancedMetaEngine {  public: -	SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription), sherlockGames) {} +	SherlockMetaEngine() : AdvancedMetaEngine(Sherlock::gameDescriptions, sizeof(Sherlock::SherlockGameDescription),  +		sherlockGames, optionsList) {}  	virtual const char *getName() const {  		return "Sherlock Engine"; diff --git a/engines/sherlock/detection_tables.h b/engines/sherlock/detection_tables.h index 975b7323ec..8300a0ffcf 100644 --- a/engines/sherlock/detection_tables.h +++ b/engines/sherlock/detection_tables.h @@ -33,7 +33,7 @@ static const SherlockGameDescription gameDescriptions[] = {  			Common::EN_ANY,  			Common::kPlatformDOS,  			ADGF_UNSTABLE | ADGF_NO_FLAGS, -			GUIO1(GUIO_NOSPEECH) +			GUIO2(GUIO_NOSPEECH, GAMEOPTION_ORIGINAL_SAVES)  		},  		GType_SerratedScalpel,  	}, diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index d8c0104e6c..1997807d15 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -49,8 +49,6 @@ Inventory::Inventory(SherlockEngine *vm) : Common::Array<InventoryItem>(), _vm(v  	_invGraphicsLoaded = false;  	_invIndex = 0;  	_holdings = 0; -	_oldFlag = 0; -	_invFlag = 0;  	_invMode = INVMODE_EXIT;  } @@ -215,7 +213,6 @@ void Inventory::drawInventory(int flag) {  	UserInterface &ui = *_vm->_ui;  	int tempFlag = flag; -	_oldFlag = 7;  	loadInv();  	if (flag == 128) { @@ -257,10 +254,8 @@ void Inventory::drawInventory(int flag) {  	if (flag) {  		ui._oldKey = INVENTORY_COMMANDS[flag]; -		_oldFlag = flag;  	} else {  		ui._oldKey = -1; -		_invFlag = 6;  	}  	invCommands(0); diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index f4cea7729a..eb5aebdd7c 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -75,8 +75,6 @@ public:  	int _holdings;		// Used to hold number of visible items in active inventory.  						// Since Inventory array also contains some special hidden items  	void freeGraphics(); -	int _oldFlag; -	int _invFlag;  public:  	Inventory(SherlockEngine *vm);  	~Inventory(); diff --git a/engines/sherlock/map.cpp b/engines/sherlock/map.cpp index c2eedd46ee..46e233bf7a 100644 --- a/engines/sherlock/map.cpp +++ b/engines/sherlock/map.cpp @@ -146,6 +146,10 @@ int Map::show() {  	int oldFont = screen.fontNumber();  	screen.setFont(0); +	// Initial screen clear +	screen._backBuffer1.clear(); +	screen.clear(); +  	// Load the entire map  	ImageFile bigMap("bigmap.vgs");  	screen.setPalette(bigMap._palette); diff --git a/engines/sherlock/map.h b/engines/sherlock/map.h index 4432ec8553..4a418138b2 100644 --- a/engines/sherlock/map.h +++ b/engines/sherlock/map.h @@ -29,7 +29,7 @@  #include "common/serializer.h"  #include "common/str.h"  #include "common/str-array.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h"  #include "sherlock/objects.h"  namespace Sherlock { diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index babd0c49a0..2ded999ed1 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -5,11 +5,9 @@ MODULE_OBJS = \  	scalpel/scalpel.o \  	tattoo/tattoo.o \  	animation.o \ -	decompress.o \  	debugger.o \  	detection.o \  	events.o \ -	graphics.o \  	inventory.o \  	journal.o \  	map.o \ @@ -22,6 +20,7 @@ MODULE_OBJS = \  	settings.o \  	sherlock.o \  	sound.o \ +	surface.o \  	talk.o \  	user_interface.o diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index 9f2704ac62..bff80c2347 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -21,14 +21,14 @@   */  #include "sherlock/resources.h" -#include "sherlock/decompress.h"  #include "sherlock/screen.h"  #include "sherlock/sherlock.h"  #include "common/debug.h" +#include "common/memstream.h"  namespace Sherlock { -Cache::Cache() { +Cache::Cache(SherlockEngine *vm): _vm(vm) {  }  /** @@ -66,20 +66,17 @@ void Cache::load(const Common::String &name, Common::SeekableReadStream &stream)  	if (_resources.contains(name))  		return; -	// Check whether the file is compressed -	const char LZW_HEADER[5] = { "LZV\x1a" }; -	char header[5]; -	stream.read(header, 5); -	bool isCompressed = !strncmp(header, LZW_HEADER, 5); +	int32 signature = stream.readUint32BE();  	stream.seek(0);  	// Allocate a new cache entry  	_resources[name] = CacheEntry();  	CacheEntry &cacheEntry = _resources[name]; -	if (isCompressed) { +	// Check whether the file is compressed +	if (signature == MKTAG('L', 'Z', 'V', 26)) {  		// It's compressed, so decompress the file and store it's data in the cache entry -		Common::SeekableReadStream *decompressed = decompressLZ(stream); +		Common::SeekableReadStream *decompressed = _vm->_res->decompressLZ(stream);  		cacheEntry.resize(decompressed->size());  		decompressed->read(&cacheEntry[0], decompressed->size()); @@ -102,7 +99,7 @@ Common::SeekableReadStream *Cache::get(const Common::String &filename) const {  /*----------------------------------------------------------------*/ -Resources::Resources() { +Resources::Resources(SherlockEngine *vm): _vm(vm), _cache(vm) {  	_resourceIndex = -1;  	addToCache("vgs.lib"); @@ -169,8 +166,19 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename) {  			stream->seek(entry._offset);  			Common::SeekableReadStream *resStream = stream->readStream(entry._size); -			delete stream; -			return resStream; +			// Check whether the file is compressed +			if (resStream->readUint32BE() == MKTAG('L', 'Z', 'V', 26)) { +				resStream->seek(0); +				// It's compressed, so decompress the sub-file and return it +				Common::SeekableReadStream *decompressed = decompressLZ(*resStream); +				delete stream; +				delete resStream; +				return decompressed; +			} else { +				resStream->seek(0); +				delete stream; +				return resStream; +			}  		}  	} @@ -402,4 +410,62 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {  	}  } +/** + * Decompress an LZW compressed resource + */ +Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source) { +	if (_vm->getGameID() == GType_SerratedScalpel) { +		uint32 id = source.readUint32BE(); +		assert(id == MKTAG('L', 'Z', 'V', 0x1A)); +	} + +	uint32 size = source.readUint32LE(); +	return decompressLZ(source, size); +} + +/** + * Decompresses an LZW block of data with a specified output size + */ +Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) { +	byte lzWindow[4096]; +	uint16 lzWindowPos; +	uint16 cmd; + +	byte *outBuffer = (byte *)malloc(outSize); +	byte *outBufferEnd = outBuffer + outSize; +	Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES); + +	memset(lzWindow, 0xFF, 0xFEE); +	lzWindowPos = 0xFEE; +	cmd = 0; + +	do { +		cmd >>= 1; +		if (!(cmd & 0x100)) +			cmd = source.readByte() | 0xFF00; + +		if (cmd & 1) { +			byte literal = source.readByte(); +			*outBuffer++ = literal; +			lzWindow[lzWindowPos] = literal; +			lzWindowPos = (lzWindowPos + 1) & 0x0FFF; +		} else { +			int copyPos, copyLen; +			copyPos = source.readByte(); +			copyLen = source.readByte(); +			copyPos = copyPos | ((copyLen & 0xF0) << 4); +			copyLen = (copyLen & 0x0F) + 3; +			while (copyLen--) { +				byte literal = lzWindow[copyPos]; +				copyPos = (copyPos + 1) & 0x0FFF; +				*outBuffer++ = literal; +				lzWindow[lzWindowPos] = literal; +				lzWindowPos = (lzWindowPos + 1) & 0x0FFF; +			} +		} +	} while (outBuffer < outBufferEnd); + +	return outS; +} +  } // End of namespace Sherlock diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index bbaac60a33..041f1c64a9 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -52,9 +52,10 @@ class SherlockEngine;  class Cache {  private: +	SherlockEngine *_vm;  	CacheHash _resources;  public: -	Cache(); +	Cache(SherlockEngine *_vm);  	bool isCached(const Common::String &filename) const; @@ -66,6 +67,7 @@ public:  class Resources {  private: +	SherlockEngine *_vm;  	Cache _cache;  	LibraryIndexes _indexes;  	int _resourceIndex; @@ -73,7 +75,7 @@ private:  	void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream,  		bool isNewStyle);  public: -	Resources(); +	Resources(SherlockEngine *vm);  	void addToCache(const Common::String &filename);  	void addToCache(const Common::String &filename, const Common::String &libFilename); @@ -87,6 +89,9 @@ public:  	bool exists(const Common::String &filename) const;  	int resourceIndex() const; + +	static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, uint32 outSize); +	Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source);  };  struct ImageFrame { diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index a78b89b00c..b9ac3e79d6 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -21,7 +21,7 @@   */  #include "sherlock/saveload.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h"  #include "sherlock/sherlock.h"  #include "common/system.h"  #include "graphics/scaler.h" diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index b982079714..521aeb338b 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -255,8 +255,9 @@ void ScalpelEngine::initialize() {  	_flags[39] = true;		// Turn on Baker Street  	// Add some more files to the cache -	_res->addToCache("sequence.txt");  	_res->addToCache("portrait.lib"); +	_res->addToCache("sequence.txt"); +	_res->addToCache("snd.snd");  	// Load the map co-ordinates for each scene and sequence data  	_map->loadPoints(NUM_PLACES, &MAP_X[0], &MAP_Y[0], &MAP_TRANSLATE[0]); diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index d4662ed559..0a25d3dd0f 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -23,7 +23,6 @@  #include "sherlock/scene.h"  #include "sherlock/sherlock.h"  #include "sherlock/scalpel/scalpel.h" -#include "sherlock/decompress.h"  #include "sherlock/screen.h"  namespace Sherlock { @@ -64,7 +63,10 @@ void BgFileHeader::synchronize(Common::SeekableReadStream &s, bool isRoseTattoo)  /*----------------------------------------------------------------*/ -void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void BgfileheaderInfo::load(Common::SeekableReadStream &s) {  	_filesize = s.readUint32LE();  	_maxFrames = s.readByte(); @@ -75,7 +77,10 @@ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) {  /*----------------------------------------------------------------*/ -void Exit::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void Exit::load(Common::SeekableReadStream &s) {  	int xp = s.readSint16LE();  	int yp = s.readSint16LE();  	int xSize = s.readSint16LE(); @@ -91,14 +96,20 @@ void Exit::synchronize(Common::SeekableReadStream &s) {  /*----------------------------------------------------------------*/ -void SceneEntry::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void SceneEntry::load(Common::SeekableReadStream &s) {  	_startPosition.x = s.readSint16LE();  	_startPosition.y = s.readSint16LE();  	_startDir = s.readByte();  	_allow = s.readByte();  } -void SceneSound::synchronize(Common::SeekableReadStream &s) { +/** + * Load the data for the object + */ +void SceneSound::load(Common::SeekableReadStream &s) {  	char buffer[9];  	s.read(buffer, 8);  	buffer[8] = '\0'; @@ -109,6 +120,9 @@ void SceneSound::synchronize(Common::SeekableReadStream &s) {  /*----------------------------------------------------------------*/ +/** + * Retuurn the index of the passed object in the array + */  int ObjectArray::indexOf(const Object &obj) const {  	for (uint idx = 0; idx < size(); ++idx) {  		if (&(*this)[idx] == &obj) @@ -236,6 +250,7 @@ bool Scene::loadScene(const Common::String &filename) {  	Events &events = *_vm->_events;  	Map &map = *_vm->_map;  	People &people = *_vm->_people; +	Resources &res = *_vm->_res;  	SaveManager &saves = *_vm->_saves;  	Screen &screen = *_vm->_screen;  	Sound &sound = *_vm->_sound; @@ -288,7 +303,7 @@ bool Scene::loadScene(const Common::String &filename) {  			// Read in background  			if (_lzwMode) { -				Common::SeekableReadStream *stream = decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT); +				Common::SeekableReadStream *stream = res.decompressLZ(*rrmStream);  				stream->read(screen._backBuffer1.getPixels(), stream->size());  				delete stream;  			} else { @@ -300,12 +315,12 @@ bool Scene::loadScene(const Common::String &filename) {  		bgInfo.resize(bgHeader._numStructs);  		for (uint idx = 0; idx < bgInfo.size(); ++idx) -			bgInfo[idx].synchronize(*rrmStream); +			bgInfo[idx].load(*rrmStream);  		// Read information  		int shapeSize = _vm->getGameID() == GType_SerratedScalpel ? 569 : 591;  		Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream : -			decompressLZ(*rrmStream, bgHeader._numImages * shapeSize + +			Resources::decompressLZ(*rrmStream, bgHeader._numImages * shapeSize +  				bgHeader._descSize + bgHeader._seqSize);  		_bgShapes.resize(bgHeader._numStructs); @@ -333,7 +348,7 @@ bool Scene::loadScene(const Common::String &filename) {  			// Read in the image data  			Common::SeekableReadStream *imageStream = _lzwMode ? -				decompressLZ(*rrmStream, bgInfo[idx]._filesize) : +				Resources::decompressLZ(*rrmStream, bgInfo[idx]._filesize) :  				rrmStream->readStream(bgInfo[idx]._filesize);  			_images[idx + 1]._images = new ImageFile(*imageStream); @@ -362,7 +377,7 @@ bool Scene::loadScene(const Common::String &filename) {  		_cAnim.clear();  		if (bgHeader._numcAnimations) {  			Common::SeekableReadStream *canimStream = _lzwMode ? -				decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) : +				Resources::decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) :  				rrmStream->readStream(65 * bgHeader._numcAnimations);  			_cAnim.resize(bgHeader._numcAnimations); @@ -375,7 +390,7 @@ bool Scene::loadScene(const Common::String &filename) {  		// Read in the room bounding areas  		int size = rrmStream->readUint16LE();  		Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream : -			decompressLZ(*rrmStream, size); +			Resources::decompressLZ(*rrmStream, size);  		_zones.resize(size / 10);  		for (uint idx = 0; idx < _zones.size(); ++idx) { @@ -402,7 +417,7 @@ bool Scene::loadScene(const Common::String &filename) {  		// Read in the walk data  		size = rrmStream->readUint16LE();  		Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream : -			decompressLZ(*rrmStream, size); +			Resources::decompressLZ(*rrmStream, size);  		_walkData.resize(size);  		walkStream->read(&_walkData[0], size); @@ -415,17 +430,17 @@ bool Scene::loadScene(const Common::String &filename) {  		_exits.resize(numExits);  		for (int idx = 0; idx < numExits; ++idx) -			_exits[idx].synchronize(*rrmStream); +			_exits[idx].load(*rrmStream);  		// Read in the entrance -		_entrance.synchronize(*rrmStream); +		_entrance.load(*rrmStream);  		// Initialize sound list  		int numSounds = rrmStream->readByte();  		_sounds.resize(numSounds);  		for (int idx = 0; idx < numSounds; ++idx) -			_sounds[idx].synchronize(*rrmStream); +			_sounds[idx].load(*rrmStream);  		for (int idx = 0; idx < numSounds; ++idx)  			sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); @@ -439,7 +454,7 @@ bool Scene::loadScene(const Common::String &filename) {  		// Read in the background  		Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream : -			decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); +			Resources::decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);  		bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT); @@ -1013,7 +1028,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) {  			// Load the canimation into the cache  			Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) : -				decompressLZ(*rrmStream, cAnim._size); +				Resources::decompressLZ(*rrmStream, cAnim._size);  			res.addToCache(fname, *imgStream);  			delete imgStream; diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index b4b88fa0a1..86b1e3d063 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -65,7 +65,7 @@ struct BgfileheaderInfo {  	int _maxFrames;				// How many unique frames in object  	Common::String _filename;	// Filename of object -	void synchronize(Common::SeekableReadStream &s); +	void load(Common::SeekableReadStream &s);  };  struct Exit { @@ -76,7 +76,7 @@ struct Exit {  	Common::Point _people;  	int _peopleDir; -	void synchronize(Common::SeekableReadStream &s); +	void load(Common::SeekableReadStream &s);  };  struct SceneEntry { @@ -84,14 +84,14 @@ struct SceneEntry {  	int _startDir;  	int _allow; -	void synchronize(Common::SeekableReadStream &s); +	void load(Common::SeekableReadStream &s);  };  struct SceneSound {  	Common::String _name;  	int _priority; -	void synchronize(Common::SeekableReadStream &s); +	void load(Common::SeekableReadStream &s);  };  class ObjectArray: public Common::Array<Object> { diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 0ca10b4a4a..349bf4d024 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -149,6 +149,7 @@ void Screen::fadeToBlack(int speed) {  	}  	setPalette(tempPalette); +	fillRect(Common::Rect(0, 0, this->w, this->h), 0);  }  /** @@ -169,7 +170,7 @@ void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) {   */  void Screen::addDirtyRect(const Common::Rect &r) {  	_dirtyRects.push_back(r); -	assert(r.isValidRect() && r.width() > 0 && r.height() > 0); +	assert(r.width() > 0 && r.height() > 0);  }  /** @@ -224,7 +225,7 @@ void Screen::randomTransition() {  		if (offset < (this->w * this->h))  			*((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset); -		if (idx != 0 && (idx % 100) == 0) { +		if (idx != 0 && (idx % 300) == 0) {  			// Ensure there's a full screen dirty rect for the next frame update  			if (_dirtyRects.empty())  				addDirtyRect(Common::Rect(0, 0, this->w, this->h)); diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 25389166d0..8a8eca13fc 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -26,8 +26,7 @@  #include "common/list.h"  #include "common/rect.h"  #include "common/serializer.h" -#include "graphics/surface.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h"  #include "sherlock/resources.h"  namespace Sherlock { diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 318267bb8f..eea3dcb867 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -21,7 +21,7 @@   */  #include "sherlock/sherlock.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h"  #include "common/scummsys.h"  #include "common/config-manager.h"  #include "common/debug-channels.h" @@ -47,6 +47,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam  	_useEpilogue2 = false;  	_loadGameSlot = -1;  	_canLoadSave = false; +	_showOriginalSavesDialog = false;  }  SherlockEngine::~SherlockEngine() { @@ -75,7 +76,7 @@ void SherlockEngine::initialize() {  	ImageFile::setVm(this);  	Object::setVm(this);  	Sprite::setVm(this); -	_res = new Resources(); +	_res = new Resources(this);  	_animation = new Animation(this);  	_debugger = new Debugger(this);  	_events = new Events(this); @@ -101,6 +102,9 @@ Common::Error SherlockEngine::run() {  	// Initialize the engine  	initialize(); +	// Flag for whether to show original saves dialog rather than the ScummVM GMM +	_showOriginalSavesDialog = ConfMan.getBool("originalsaveload"); +  	// If requested, load a savegame instead of showing the intro  	if (ConfMan.hasKey("save_slot")) {  		int saveSlot = ConfMan.getInt("save_slot"); @@ -122,6 +126,9 @@ Common::Error SherlockEngine::run() {  		if (shouldQuit())  			break; +		// Clear the screen +		_screen->clear(); +  		// Reset UI flags  		_ui->reset(); @@ -207,26 +214,27 @@ void SherlockEngine::loadConfig() {  	// Load sound settings  	syncSoundSettings(); -	// Load other settings -	if (ConfMan.hasKey("font")) -		_screen->setFont(ConfMan.getInt("font")); -	if (ConfMan.hasKey("fade_style")) -		_screen->_fadeStyle = ConfMan.getBool("fade_style"); -	if (ConfMan.hasKey("help_style")) -		_ui->_helpStyle = ConfMan.getBool("help_style"); -	if (ConfMan.hasKey("window_style")) -		_ui->_windowStyle = ConfMan.getInt("window_style"); -	if (ConfMan.hasKey("portraits_on")) -		_people->_portraitsOn = ConfMan.getBool("portraits_on"); +	ConfMan.registerDefault("font", 1); +	ConfMan.registerDefault("fade_style", true); +	ConfMan.registerDefault("help_style", false); +	ConfMan.registerDefault("window_style", 1); +	ConfMan.registerDefault("portraits_on", true); +	ConfMan.registerDefault("originalsaveload", false); + +	_screen->setFont(ConfMan.getInt("font")); +	_screen->_fadeStyle = ConfMan.getBool("fade_style"); +	_ui->_helpStyle = ConfMan.getBool("help_style"); +	_ui->_windowStyle = ConfMan.getInt("window_style"); +	_people->_portraitsOn = ConfMan.getBool("portraits_on");  }  /**   * Saves game configuration information   */  void SherlockEngine::saveConfig() { -	ConfMan.setBool("mute", _sound->_digitized); -	ConfMan.setBool("music_mute", _sound->_music); -	ConfMan.setBool("speech_mute", _sound->_voices); +	ConfMan.setBool("mute", !_sound->_digitized); +	ConfMan.setBool("music_mute", !_sound->_music); +	ConfMan.setBool("speech_mute", !_sound->_voices);  	ConfMan.setInt("font", _screen->fontNumber());  	ConfMan.setBool("fade_style", _screen->_fadeStyle); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index e21ac8c6d6..9261ad5b05 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -108,6 +108,7 @@ public:  	bool _useEpilogue2;  	int _loadGameSlot;  	bool _canLoadSave; +	bool _showOriginalSavesDialog;  public:  	SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);  	virtual ~SherlockEngine(); diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp index 70451a68da..001907917f 100644 --- a/engines/sherlock/sound.cpp +++ b/engines/sherlock/sound.cpp @@ -45,7 +45,8 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer): _vm(vm), _mixer(mixer) {  	_speechOn = true;  	_vm->_res->addToCache("MUSIC.LIB"); -	_vm->_res->addToCache(_vm->getGameID() == GType_SerratedScalpel ? "SND.SND" : "SOUND.LIB"); +	_vm->_res->addToCache("TITLE.SND"); +	_vm->_res->addToCache("EPILOGUE.SND");  }  /** @@ -92,7 +93,11 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit  	Common::String filename = name;  	if (!filename.contains('.'))  		filename += ".SND"; -	Common::SeekableReadStream *stream = _vm->_res->load(filename, "TITLE.SND"); +	 +	Common::SeekableReadStream *stream = _vm->_res->load(filename); + +	if (!stream) +		error("Unable to find sound file '%s'", filename.c_str());  	stream->skip(2);  	int size = stream->readUint32BE(); @@ -115,6 +120,15 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit  	free(data); +#if 0 +	// Debug : used to dump files +	Common::DumpFile outFile; +	outFile.open(filename); +	outFile.write(decoded, (size - 2) * 2); +	outFile.flush(); +	outFile.close(); +#endif +  	Audio::AudioStream *audioStream = Audio::makeRawStream(decoded, (size - 2) * 2, rate, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);  	_mixer->playStream(Audio::Mixer::kPlainSoundType, &_effectsHandle, audioStream, -1,  Audio::Mixer::kMaxChannelVolume);  	_soundPlaying = true; @@ -138,14 +152,6 @@ bool Sound::playSound(const Common::String &name, WaitType waitType, int priorit  	_soundPlaying = false;  	_mixer->stopHandle(_effectsHandle); -#if 0 -	// Debug : used to dump files -	Common::DumpFile outFile; -	outFile.open(filename); -	outFile.write(decoded, (size - 2) * 2); -	outFile.flush(); -	outFile.close(); -#endif  	return retval;  } diff --git a/engines/sherlock/graphics.cpp b/engines/sherlock/surface.cpp index 234928156a..36e625794c 100644 --- a/engines/sherlock/graphics.cpp +++ b/engines/sherlock/surface.cpp @@ -20,7 +20,7 @@   *   */ -#include "sherlock/graphics.h" +#include "sherlock/surface.h"  #include "sherlock/sherlock.h"  #include "common/system.h"  #include "graphics/palette.h" @@ -62,28 +62,7 @@ void Surface::blitFrom(const Graphics::Surface &src) {   * Draws a surface at a given position within this surface   */  void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { -	Common::Rect drawRect(0, 0, src.w, src.h); -	Common::Point destPt = pt; - -	if (destPt.x < 0) { -		drawRect.left += -destPt.x; -		destPt.x = 0; -	} -	if (destPt.y < 0) { -		drawRect.top += -destPt.y; -		destPt.y = 0; -	} -	int right = destPt.x + src.w; -	if (right > this->w) { -		drawRect.right -= (right - this->w); -	} -	int bottom = destPt.y + src.h; -	if (bottom > this->h) { -		drawRect.bottom -= (bottom - this->h); -	} - -	if (drawRect.isValidRect()) -		blitFrom(src, destPt, drawRect); +	blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h));  }  /** @@ -91,11 +70,10 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) {   */  void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt,  		const Common::Rect &srcBounds) { -	Common::Rect destRect(pt.x, pt.y, pt.x + srcBounds.width(), -		pt.y + srcBounds.height());  	Common::Rect srcRect = srcBounds; +	Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); -	if (clip(srcRect, destRect)) { +	if (srcRect.isValidRect() && clip(srcRect, destRect)) {  		// Surface is at least partially or completely on-screen  		addDirtyRect(destRect);  		copyRectToSurface(src, destRect.left, destRect.top, srcRect); @@ -194,4 +172,11 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) {  	return true;  } +/** + * Clear the screen + */ +void Surface::clear() { +	fillRect(Common::Rect(0, 0, this->w, this->h), 0); +} +  } // End of namespace Sherlock diff --git a/engines/sherlock/graphics.h b/engines/sherlock/surface.h index d4a1584968..b2a759aa8d 100644 --- a/engines/sherlock/graphics.h +++ b/engines/sherlock/surface.h @@ -53,6 +53,8 @@ public:  	void fillRect(int x1, int y1, int x2, int y2, byte color);  	void fillRect(const Common::Rect &r, byte color); + +	void clear();  };  } // End of namespace Sherlock diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp index 61f0004fd6..d656431823 100644 --- a/engines/sherlock/talk.cpp +++ b/engines/sherlock/talk.cpp @@ -104,7 +104,6 @@ Talk::Talk(SherlockEngine *vm): _vm(vm) {  	_moreTalkDown = _moreTalkUp = false;  	_scriptMoreFlag = 0;  	_scriptSaveIndex = -1; -	_scriptCurrentIndex = -1;  }  /** @@ -1082,10 +1081,6 @@ void Talk::doScript(const Common::String &script) {  			// Handle control code  			switch (c) {  			case SWITCH_SPEAKER: -				// Save the current point in the script, since it might be intterupted by -				// doing bg anims in the next call, so we need to know where to return to -				_scriptCurrentIndex = str - scriptStart; -  				if (!(_speaker & 128))  					people.clearTalking();  				if (_talkToAbort) @@ -1103,10 +1098,7 @@ void Talk::doScript(const Common::String &script) {  				break;  			case RUN_CANIMATION: -				// Save the current point in the script, since it might be intterupted by -				// doing bg anims in the next call, so we need to know where to return to  				++str; -				_scriptCurrentIndex = (str + 1) - scriptStart;  				scene.startCAnim((str[0] - 1) & 127, (str[0] & 128) ? -1 : 1);  				if (_talkToAbort)  					return; @@ -1143,10 +1135,6 @@ void Talk::doScript(const Common::String &script) {  				break;  			case REMOVE_PORTRAIT: -				// Save the current point in the script, since it might be intterupted by -				// doing bg anims in the next call, so we need to know where to return to -				_scriptCurrentIndex = str - scriptStart; -  				if (_speaker >= 0 && _speaker < 128)  					people.clearTalking();  				pullSequence(); @@ -1203,10 +1191,7 @@ void Talk::doScript(const Common::String &script) {  				}  			case WALK_TO_COORDS: -				// Save the current point in the script, since it might be interrupted by -				// doing bg anims in the next call, so we need to know where to return to  				++str; -				_scriptCurrentIndex = str - scriptStart;  				people.walkToCoords(Common::Point(((str[0] - 1) * 256 + str[1] - 1) * 100,  					str[2] * 100), str[3] - 1); @@ -1217,10 +1202,7 @@ void Talk::doScript(const Common::String &script) {  				break;  			case PAUSE_WITHOUT_CONTROL: -				// Save the current point in the script, since it might be intterupted by -				// doing bg anims in the next call, so we need to know where to return to  				++str; -				_scriptCurrentIndex = str - scriptStart;  				for (int idx = 0; idx < (str[0] - 1); ++idx) {  					scene.doBgAnim(); @@ -1234,10 +1216,6 @@ void Talk::doScript(const Common::String &script) {  				break;  			case BANISH_WINDOW: -				// Save the current point in the script, since it might be intterupted by -				// doing bg anims in the next call, so we need to know where to return to -				_scriptCurrentIndex = str - scriptStart; -  				if (!(_speaker & 128))  					people.clearTalking();  				pullSequence(); @@ -1403,19 +1381,19 @@ void Talk::doScript(const Common::String &script) {  				break;  			} -			case CALL_TALK_FILE: +			case CALL_TALK_FILE: {  				++str;  				for (int idx = 0; idx < 8 && str[idx] != '~'; ++idx)  					tempString += str[idx];  				str += 8; -				_scriptCurrentIndex = str - scriptStart; +				int scriptCurrentIndex = str - scriptStart;  				// Save the current script position and new talk file  				if (_scriptStack.size() < 9) {  					ScriptStackEntry rec1;  					rec1._name = _scriptName; -					rec1._currentIndex = _scriptCurrentIndex; +					rec1._currentIndex = scriptCurrentIndex;  					rec1._select = _scriptSelect;  					_scriptStack.push(rec1); @@ -1433,12 +1411,10 @@ void Talk::doScript(const Common::String &script) {  				endStr = true;  				wait = 0;  				break; +			}  			case MOVE_MOUSE: -				// Save the current point in the script, since it might be intterupted by -				// doing bg anims in the next call, so we need to know where to return to  				++str; -				_scriptCurrentIndex = str - scriptStart;  				events.moveMouse(Common::Point((str[0] - 1) * 256 + str[1] - 1, str[2]));  				if (_talkToAbort)  					return; @@ -1464,10 +1440,6 @@ void Talk::doScript(const Common::String &script) {  				++str;  				CAnim &animation = scene._cAnim[str[0] - 1]; -				// Save the current point in the script, since it might be interrupted by -				// doing bg anims in the next call, so we need to know where to return to -				_scriptCurrentIndex = (str + 1) - scriptStart; -  				people.walkToCoords(animation._goto, animation._gotoDir);  				if (_talkToAbort)  					return; @@ -1614,10 +1586,6 @@ void Talk::doScript(const Common::String &script) {  		}  		if (wait) { -			// Save the current point in the script, since it might be intterupted by -			// doing bg anims in the next call, so we need to know where to return to -			_scriptCurrentIndex = str - scriptStart; -  			// Handling pausing  			if (!pauseFlag && charCount < 160)  				charCount = 160; diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h index d81586228f..b1a735827c 100644 --- a/engines/sherlock/talk.h +++ b/engines/sherlock/talk.h @@ -140,7 +140,6 @@ private:  	int _talkStealth;  	int _talkToFlag;  	int _scriptSaveIndex; -	int _scriptCurrentIndex;  private:  	void stripVoiceCommands();  	void setTalkMap(); diff --git a/engines/sherlock/tattoo/tattoo.cpp b/engines/sherlock/tattoo/tattoo.cpp index 9039e3f9d4..3c684ff3ee 100644 --- a/engines/sherlock/tattoo/tattoo.cpp +++ b/engines/sherlock/tattoo/tattoo.cpp @@ -44,6 +44,7 @@ void TattooEngine::initialize() {  	// Add some more files to the cache  	_res->addToCache("walk.lib"); +	_res->addToCache("sound.lib");  	// Starting scene  	_scene->_goToScene = 91; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 8e7254026b..1ab8fe7294 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -172,11 +172,6 @@ void UserInterface::handleInput() {  			_vm->quitGame();  			events.pollEvents();  			return; -		} else if (keyState.keycode == Common::KEYCODE_SPACE || -				keyState.keycode == Common::KEYCODE_RETURN) { -			events._pressed = false; -			events._oldButtons = 0; -			_keycode = Common::KEYCODE_INVALID;  		}  	} @@ -929,7 +924,7 @@ void UserInterface::doEnvControl() {  			screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?");  			screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); -			screen.makeButton(Common::Rect(112, CONTROLS_Y, 150, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes"); +			screen.makeButton(Common::Rect(112, CONTROLS_Y, 160, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes");  			screen.makeButton(Common::Rect(161, CONTROLS_Y, 209, CONTROLS_Y + 10), 184 - screen.stringWidth("No") / 2, "No");  			screen.slamArea(112, CONTROLS_Y, 97, 10); @@ -1430,17 +1425,24 @@ void UserInterface::doMainControl() {  			break;  		case 'F':  			pushButton(10); -			_menuMode = FILES_MODE;  			// Create a thumbnail of the current screen before the files dialog is shown, in case  			// the user saves the game  			saves.createThumbnail(); -			// Display the dialog -			saves.drawInterface(); -  			_selector = _oldSelector = -1; -			_windowOpen = true; + +			if (_vm->_showOriginalSavesDialog) { +				// Show the original dialog +				_menuMode = FILES_MODE; +				saves.drawInterface(); +				_windowOpen = true; +			} else { +				// Show the ScummVM GMM instead +				_vm->_canLoadSave = true; +				_vm->openMainMenuDialog(); +				_vm->_canLoadSave = false; +			}  			break;  		case 'S':  			pushButton(11); @@ -1699,9 +1701,6 @@ void UserInterface::doTalkControl() {  				sound._speechOn = false;  			} -			// Set the _scriptCurrentIndex so if the statement is irrupted, the entire -			// reply will be shown when it's restarted -			talk._scriptCurrentIndex = 0;  			talk.waitForMore(talk._statements[_selector]._statement.size());  			if (talk._talkToAbort)  				return; diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 79382a19fe..2ff60715e3 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -25,7 +25,7 @@  #include "common/scummsys.h"  #include "common/events.h" -#include "sherlock/graphics.h" +#include "sherlock/surface.h"  #include "sherlock/objects.h"  #include "sherlock/resources.h"  | 
