diff options
| -rw-r--r-- | engines/zvision/actions.cpp | 45 | ||||
| -rw-r--r-- | engines/zvision/animation_node.cpp | 2 | ||||
| -rw-r--r-- | engines/zvision/cursor.cpp | 29 | ||||
| -rw-r--r-- | engines/zvision/cursor.h | 2 | ||||
| -rw-r--r-- | engines/zvision/cursor_manager.cpp | 24 | ||||
| -rw-r--r-- | engines/zvision/lever_control.cpp | 4 | ||||
| -rw-r--r-- | engines/zvision/meta_animation.cpp | 8 | ||||
| -rw-r--r-- | engines/zvision/meta_animation.h | 3 | ||||
| -rw-r--r-- | engines/zvision/module.mk | 3 | ||||
| -rw-r--r-- | engines/zvision/music_node.cpp | 2 | ||||
| -rw-r--r-- | engines/zvision/render_manager.cpp | 10 | ||||
| -rw-r--r-- | engines/zvision/render_manager.h | 3 | ||||
| -rw-r--r-- | engines/zvision/rlf_animation.cpp | 116 | ||||
| -rw-r--r-- | engines/zvision/rlf_animation.h | 3 | ||||
| -rw-r--r-- | engines/zvision/scr_file_handling.cpp | 3 | ||||
| -rw-r--r-- | engines/zvision/search_manager.cpp | 274 | ||||
| -rw-r--r-- | engines/zvision/search_manager.h | 51 | ||||
| -rw-r--r-- | engines/zvision/zork_raw.cpp | 2 | ||||
| -rw-r--r-- | engines/zvision/zvision.cpp | 27 | ||||
| -rw-r--r-- | engines/zvision/zvision.h | 5 | 
20 files changed, 518 insertions, 98 deletions
diff --git a/engines/zvision/actions.cpp b/engines/zvision/actions.cpp index 5d1dc9a608..7b9050f47a 100644 --- a/engines/zvision/actions.cpp +++ b/engines/zvision/actions.cpp @@ -312,27 +312,11 @@ ActionMusic::~ActionMusic() {  bool ActionMusic::execute() {  	if (_engine->getScriptManager()->getSideFX(_slotkey))  		return true; -	Common::File *file = new Common::File(); -	if (!file->exists(_fileName) && _fileName.size() >= 12) { -		_fileName.setChar('r', 9); -		_fileName.setChar('a', 10); -		_fileName.setChar('w', 11); -		if (!file->exists(_fileName)) { -			_fileName.setChar('i', 9); -			_fileName.setChar('f', 10); -			_fileName.setChar('p', 11); -			if (!file->exists(_fileName)) { -				_fileName.setChar('s', 9); -				_fileName.setChar('r', 10); -				_fileName.setChar('c', 11); -				if (!file->exists(_fileName)) -					return true; -			} -		} -	} -	if (file->exists(_fileName)) -		_engine->getScriptManager()->addSideFX(new MusicNode(_engine, _slotkey, _fileName, _loop, _volume)); -	delete file; + +	if (!_engine->getSearchManager()->hasFile(_fileName)) +		return true; + +	_engine->getScriptManager()->addSideFX(new MusicNode(_engine, _slotkey, _fileName, _loop, _volume));  	return true;  } @@ -585,16 +569,21 @@ ActionStreamVideo::ActionStreamVideo(ZVision *engine, int32 slotkey, const Commo  bool ActionStreamVideo::execute() {  	ZorkAVIDecoder decoder; -	if (!decoder.loadFile(_fileName)) { -		return true; -	} +	Common::File *_file = _engine->getSearchManager()->openFile(_fileName); + +	if (_file) { +		if (!decoder.loadStream(_file)) { +			return true; +		} + +		Common::Rect destRect; +		if ((_flags & DIFFERENT_DIMENSIONS) == DIFFERENT_DIMENSIONS) { +			destRect = Common::Rect(_x1, _y1, _x2, _y2); +		} -	Common::Rect destRect; -	if ((_flags & DIFFERENT_DIMENSIONS) == DIFFERENT_DIMENSIONS) { -		destRect = Common::Rect(_x1, _y1, _x2, _y2); +		_engine->playVideo(decoder, destRect, _skippable);  	} -	_engine->playVideo(decoder, destRect, _skippable);  	return true;  } diff --git a/engines/zvision/animation_node.cpp b/engines/zvision/animation_node.cpp index 11275b5c7d..89d0f5e451 100644 --- a/engines/zvision/animation_node.cpp +++ b/engines/zvision/animation_node.cpp @@ -41,7 +41,7 @@ AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::S  	  _animation(NULL) {  	if (fileName.hasSuffix(".rlf") || fileName.hasSuffix(".avi")) { -		_animation = new MetaAnimation(fileName); +		_animation = new MetaAnimation(fileName, engine);  		_frmDelay = _animation->frameTime();  	} else {  		warning("Unrecognized animation file type: %s", fileName.c_str()); diff --git a/engines/zvision/cursor.cpp b/engines/zvision/cursor.cpp index 5386c8ead6..e2e3d7ee72 100644 --- a/engines/zvision/cursor.cpp +++ b/engines/zvision/cursor.cpp @@ -66,6 +66,35 @@ ZorkCursor::ZorkCursor(const Common::String &fileName)  	_surface.convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));  } +ZorkCursor::ZorkCursor(ZVision *engine, const Common::String &fileName) +	: _width(0), +	  _height(0), +	  _hotspotX(0), +	  _hotspotY(0) { +	Common::File file; +	if (!engine->getSearchManager()->openFile(file, fileName)) +		return; + +	uint32 magic = file.readUint32BE(); +	if (magic != MKTAG('Z', 'C', 'R', '1')) { +		warning("%s is not a Zork Cursor file", fileName.c_str()); +		return; +	} + +	_hotspotX = file.readUint16LE(); +	_hotspotY = file.readUint16LE(); +	_width = file.readUint16LE(); +	_height = file.readUint16LE(); + +	uint dataSize = _width * _height * sizeof(uint16); +	_surface.create(_width, _height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); +	uint32 bytesRead = file.read(_surface.getPixels(), dataSize); +	assert(bytesRead == dataSize); + +	// Convert to RGB 565 +	_surface.convertToInPlace(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); +} +  ZorkCursor::ZorkCursor(const ZorkCursor &other) {  	_width = other._width;  	_height = other._height; diff --git a/engines/zvision/cursor.h b/engines/zvision/cursor.h index 8f119c8982..2304bf4c82 100644 --- a/engines/zvision/cursor.h +++ b/engines/zvision/cursor.h @@ -24,6 +24,7 @@  #define ZVISION_CURSOR_H  #include "graphics/surface.h" +#include "zvision/zvision.h"  namespace Common { @@ -40,6 +41,7 @@ class ZorkCursor {  public:  	ZorkCursor();  	ZorkCursor(const Common::String &fileName); +	ZorkCursor(ZVision *engine, const Common::String &fileName);  	ZorkCursor(const ZorkCursor &other);  	~ZorkCursor(); diff --git a/engines/zvision/cursor_manager.cpp b/engines/zvision/cursor_manager.cpp index aaf3bb8ee4..c66fa650a8 100644 --- a/engines/zvision/cursor_manager.cpp +++ b/engines/zvision/cursor_manager.cpp @@ -57,15 +57,15 @@ CursorManager::CursorManager(ZVision *engine, const Graphics::PixelFormat *pixel  		if (_engine->getGameId() == GID_NEMESIS) {  			Common::String name;  			name = Common::String::format("%sa.zcr", _zNemCursorFileNames[i]); -			_cursors[i][0] = ZorkCursor(name); // Up cursor +			_cursors[i][0] = ZorkCursor(_engine, name); // Up cursor  			name = Common::String::format("%sb.zcr", _zNemCursorFileNames[i]); -			_cursors[i][1] = ZorkCursor(name); // Down cursor +			_cursors[i][1] = ZorkCursor(_engine, name); // Down cursor  		} else if (_engine->getGameId() == GID_GRANDINQUISITOR) { -			_cursors[i][0] = ZorkCursor(_zgiCursorFileNames[i]); // Up cursor +			_cursors[i][0] = ZorkCursor(_engine, _zgiCursorFileNames[i]); // Up cursor  			char buffer[25];  			strcpy(buffer, _zgiCursorFileNames[i]);  			buffer[3] += 2; -			_cursors[i][1] = ZorkCursor(buffer); // Down cursor +			_cursors[i][1] = ZorkCursor(_engine, buffer); // Down cursor  		}  	}  } @@ -76,22 +76,22 @@ void CursorManager::setItemID(int id) {  			Common::String file;  			if (_engine->getGameId() == GID_NEMESIS) {  				file = Common::String::format("%2.2d%s%c.zcr", id, "idle", 'a'); -				_cursors[NUM_CURSORS][0] = ZorkCursor(file); +				_cursors[NUM_CURSORS][0] = ZorkCursor(_engine, file);  				file = Common::String::format("%2.2d%s%c.zcr", id, "idle", 'b'); -				_cursors[NUM_CURSORS][1] = ZorkCursor(file); +				_cursors[NUM_CURSORS][1] = ZorkCursor(_engine, file);  				file = Common::String::format("%2.2d%s%c.zcr", id, "act", 'a'); -				_cursors[NUM_CURSORS + 1][0] = ZorkCursor(file); +				_cursors[NUM_CURSORS + 1][0] = ZorkCursor(_engine, file);  				file = Common::String::format("%2.2d%s%c.zcr", id, "act", 'b'); -				_cursors[NUM_CURSORS + 1][0] = ZorkCursor(file); +				_cursors[NUM_CURSORS + 1][0] = ZorkCursor(_engine, file);  			} else if (_engine->getGameId() == GID_GRANDINQUISITOR) {  				file = Common::String::format("g0b%cc%2.2x1.zcr", 'a' , id); -				_cursors[NUM_CURSORS][0] = ZorkCursor(file); +				_cursors[NUM_CURSORS][0] = ZorkCursor(_engine, file);  				file = Common::String::format("g0b%cc%2.2x1.zcr", 'c' , id); -				_cursors[NUM_CURSORS][1] = ZorkCursor(file); +				_cursors[NUM_CURSORS][1] = ZorkCursor(_engine, file);  				file = Common::String::format("g0b%cc%2.2x1.zcr", 'b' , id); -				_cursors[NUM_CURSORS + 1][0] = ZorkCursor(file); +				_cursors[NUM_CURSORS + 1][0] = ZorkCursor(_engine, file);  				file = Common::String::format("g0b%cc%2.2x1.zcr", 'd' , id); -				_cursors[NUM_CURSORS + 1][1] = ZorkCursor(file); +				_cursors[NUM_CURSORS + 1][1] = ZorkCursor(_engine, file);  			} else  				return;  		} diff --git a/engines/zvision/lever_control.cpp b/engines/zvision/lever_control.cpp index e96c873033..33aa2be592 100644 --- a/engines/zvision/lever_control.cpp +++ b/engines/zvision/lever_control.cpp @@ -86,7 +86,7 @@ LeverControl::~LeverControl() {  void LeverControl::parseLevFile(const Common::String &fileName) {  	Common::File file; -	if (!file.open(fileName)) { +	if (!_engine->getSearchManager()->openFile(file, fileName)) {  		warning("LEV file %s could could be opened", fileName.c_str());  		return;  	} @@ -103,7 +103,7 @@ void LeverControl::parseLevFile(const Common::String &fileName) {  			Common::String animationFileName(fileNameBuffer);  			if (animationFileName.hasSuffix(".avi") || animationFileName.hasSuffix(".rlf")) -				_animation = new MetaAnimation(animationFileName); +				_animation = new MetaAnimation(animationFileName, _engine);  		} else if (line.matchString("*skipcolor*", true)) {  			// Not used diff --git a/engines/zvision/meta_animation.cpp b/engines/zvision/meta_animation.cpp index 430b1436cb..33ae92a523 100644 --- a/engines/zvision/meta_animation.cpp +++ b/engines/zvision/meta_animation.cpp @@ -37,17 +37,19 @@  namespace ZVision { -MetaAnimation::MetaAnimation(const Common::String &fileName) +MetaAnimation::MetaAnimation(const Common::String &fileName, ZVision *engine)  	: _fileType(RLF),  	  _cur_frame(NULL) {  	if (fileName.hasSuffix(".rlf")) {  		_fileType = RLF; -		_animation.rlf = new RlfAnimation(fileName, false); +		Common::File *_file = engine->getSearchManager()->openFile(fileName); +		_animation.rlf = new RlfAnimation(_file, false);  		_frmDelay = _animation.rlf->frameTime();  	} else if (fileName.hasSuffix(".avi")) {  		_fileType = AVI; +		Common::File *_file = engine->getSearchManager()->openFile(fileName);  		_animation.avi = new ZorkAVIDecoder(); -		_animation.avi->loadFile(fileName); +		_animation.avi->loadStream(_file);  		_frmDelay = 1000.0 / _animation.avi->getDuration().framerate();  	} else {  		warning("Unrecognized animation file type: %s", fileName.c_str()); diff --git a/engines/zvision/meta_animation.h b/engines/zvision/meta_animation.h index fea7a6a6c1..e259955891 100644 --- a/engines/zvision/meta_animation.h +++ b/engines/zvision/meta_animation.h @@ -24,6 +24,7 @@  #define ZVISION_METAANIM_NODE_H  #include "zvision/sidefx.h" +#include "zvision/zvision.h"  #include "common/rect.h"  #include "common/list.h" @@ -47,7 +48,7 @@ class RlfAnimation;  class MetaAnimation {  public: -	MetaAnimation(const Common::String &fileName); +	MetaAnimation(const Common::String &fileName, ZVision *engine);  	~MetaAnimation();  	struct playnode { diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk index 62a1293663..b8dca9e63a 100644 --- a/engines/zvision/module.mk +++ b/engines/zvision/module.mk @@ -35,7 +35,8 @@ MODULE_OBJS := \  	inventory_manager.o \  	slot_control.o \  	menu.o \ -	meta_animation.o +	meta_animation.o \ +	search_manager.o  MODULE_DIRS += \  	engines/zvision diff --git a/engines/zvision/music_node.cpp b/engines/zvision/music_node.cpp index 30271480c1..d47a796382 100644 --- a/engines/zvision/music_node.cpp +++ b/engines/zvision/music_node.cpp @@ -51,7 +51,7 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool  	if (filename.contains(".wav")) {  		Common::File *file = new Common::File(); -		if (file->open(filename)) { +		if (_engine->getSearchManager()->openFile(*file, filename)) {  			audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);  		}  	} else { diff --git a/engines/zvision/render_manager.cpp b/engines/zvision/render_manager.cpp index f5d6847cf3..6cfc0509c7 100644 --- a/engines/zvision/render_manager.cpp +++ b/engines/zvision/render_manager.cpp @@ -22,6 +22,7 @@  #include "common/scummsys.h" +#include "zvision/zvision.h"  #include "zvision/render_manager.h"  #include "zvision/lzss_read_stream.h" @@ -37,8 +38,9 @@  namespace ZVision { -RenderManager::RenderManager(OSystem *system, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat) -	: _system(system), +RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat) +	: _engine(engine), +	  _system(engine->_system),  	  _wrkWidth(workingWindow.width()),  	  _wrkHeight(workingWindow.height()),  	  _screenCenterX(_wrkWidth / 2), @@ -113,7 +115,7 @@ void RenderManager::renderImageToBackground(const Common::String &fileName, int1  void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination) {  	Common::File file; -	if (!file.open(fileName)) { +	if (!_engine->getSearchManager()->openFile(file, fileName)) {  		warning("Could not open file %s", fileName.c_str());  		return;  	} @@ -207,7 +209,7 @@ void RenderManager::readImageToSurface(const Common::String &fileName, Graphics:  void RenderManager::readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed) {  	Common::File file; -	if (!file.open(fileName)) { +	if (!_engine->getSearchManager()->openFile(file, fileName)) {  		warning("Could not open file %s", fileName.c_str());  		return;  	} diff --git a/engines/zvision/render_manager.h b/engines/zvision/render_manager.h index 901385b453..3c03331d0f 100644 --- a/engines/zvision/render_manager.h +++ b/engines/zvision/render_manager.h @@ -47,7 +47,7 @@ namespace ZVision {  class RenderManager {  public: -	RenderManager(OSystem *system, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat); +	RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat);  	~RenderManager();  private: @@ -70,6 +70,7 @@ private:  	typedef Common::HashMap<uint16, oneSub> subMap;  private: +	ZVision *_engine;  	OSystem *_system;  	const Graphics::PixelFormat _pixelFormat; diff --git a/engines/zvision/rlf_animation.cpp b/engines/zvision/rlf_animation.cpp index dab32aed17..f23f569d98 100644 --- a/engines/zvision/rlf_animation.cpp +++ b/engines/zvision/rlf_animation.cpp @@ -37,6 +37,7 @@ namespace ZVision {  RlfAnimation::RlfAnimation(const Common::String &fileName, bool stream)  	: _stream(stream), +	  _readStream(NULL),  	  _lastFrameRead(0),  	  _frameCount(0),  	  _width(0), @@ -45,11 +46,15 @@ RlfAnimation::RlfAnimation(const Common::String &fileName, bool stream)  	  _frames(0),  	  _currentFrame(0),  	  _frameBufferByteSize(0) { -	if (!_file.open(fileName)) { + +	Common::File *_file = new Common::File; +	if (!_file->open(fileName)) {  		warning("RLF animation file %s could not be opened", fileName.c_str());  		return;  	} +	_readStream = _file; +  	if (!readHeader()) {  		warning("%s is not a RLF animation file. Wrong magic number", fileName.c_str());  		return; @@ -68,59 +73,90 @@ RlfAnimation::RlfAnimation(const Common::String &fileName, bool stream)  	}  } +RlfAnimation::RlfAnimation(Common::SeekableReadStream *rstream, bool stream) +	: _stream(stream), +	  _readStream(rstream), +	  _lastFrameRead(0), +	  _frameCount(0), +	  _width(0), +	  _height(0), +	  _frameTime(0), +	  _frames(0), +	  _currentFrame(0), +	  _frameBufferByteSize(0) { + +	if (!readHeader()) { +		warning("Stream is not a RLF animation. Wrong magic number"); +		return; +	} + +	_currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>()); +	_frameBufferByteSize = _width * _height * sizeof(uint16); + +	if (!stream) { +		_frames = new Frame[_frameCount]; + +		// Read in each frame +		for (uint i = 0; i < _frameCount; ++i) { +			_frames[i] = readNextFrame(); +		} +	} +} +  RlfAnimation::~RlfAnimation() {  	for (uint i = 0; i < _frameCount; ++i) {  		delete[] _frames[i].encodedData;  	}  	delete[] _frames; +	delete _readStream;  	_currentFrameBuffer.free();  }  bool RlfAnimation::readHeader() { -	if (_file.readUint32BE() != MKTAG('F', 'E', 'L', 'R')) { +	if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {  		return false;  	}  	// Read the header -	_file.readUint32LE();                // Size1 -	_file.readUint32LE();                // Unknown1 -	_file.readUint32LE();                // Unknown2 -	_frameCount = _file.readUint32LE();  // Frame count +	_readStream->readUint32LE();                // Size1 +	_readStream->readUint32LE();                // Unknown1 +	_readStream->readUint32LE();                // Unknown2 +	_frameCount = _readStream->readUint32LE();  // Frame count  	// Since we don't need any of the data, we can just seek right to the  	// entries we need rather than read in all the individual entries. -	_file.seek(136, SEEK_CUR); +	_readStream->seek(136, SEEK_CUR);  	//// Read CIN header -	//_file.readUint32BE();          // Magic number FNIC -	//_file.readUint32LE();          // Size2 -	//_file.readUint32LE();          // Unknown3 -	//_file.readUint32LE();          // Unknown4 -	//_file.readUint32LE();          // Unknown5 -	//_file.seek(0x18, SEEK_CUR);    // VRLE -	//_file.readUint32LE();          // LRVD -	//_file.readUint32LE();          // Unknown6 -	//_file.seek(0x18, SEEK_CUR);    // HRLE -	//_file.readUint32LE();          // ELHD -	//_file.readUint32LE();          // Unknown7 -	//_file.seek(0x18, SEEK_CUR);    // HKEY -	//_file.readUint32LE();          // ELRH +	//_readStream->readUint32BE();          // Magic number FNIC +	//_readStream->readUint32LE();          // Size2 +	//_readStream->readUint32LE();          // Unknown3 +	//_readStream->readUint32LE();          // Unknown4 +	//_readStream->readUint32LE();          // Unknown5 +	//_readStream->seek(0x18, SEEK_CUR);    // VRLE +	//_readStream->readUint32LE();          // LRVD +	//_readStream->readUint32LE();          // Unknown6 +	//_readStream->seek(0x18, SEEK_CUR);    // HRLE +	//_readStream->readUint32LE();          // ELHD +	//_readStream->readUint32LE();          // Unknown7 +	//_readStream->seek(0x18, SEEK_CUR);    // HKEY +	//_readStream->readUint32LE();          // ELRH  	//// Read MIN info header -	//_file.readUint32BE();          // Magic number FNIM -	//_file.readUint32LE();          // Size3 -	//_file.readUint32LE();          // OEDV -	//_file.readUint32LE();          // Unknown8 -	//_file.readUint32LE();          // Unknown9 -	//_file.readUint32LE();          // Unknown10 -	_width = _file.readUint32LE();   // Width -	_height = _file.readUint32LE();  // Height +	//_readStream->readUint32BE();          // Magic number FNIM +	//_readStream->readUint32LE();          // Size3 +	//_readStream->readUint32LE();          // OEDV +	//_readStream->readUint32LE();          // Unknown8 +	//_readStream->readUint32LE();          // Unknown9 +	//_readStream->readUint32LE();          // Unknown10 +	_width = _readStream->readUint32LE();   // Width +	_height = _readStream->readUint32LE();  // Height  	// Read time header -	_file.readUint32BE();                    // Magic number EMIT -	_file.readUint32LE();                    // Size4 -	_file.readUint32LE();                    // Unknown11 -	_frameTime = _file.readUint32LE() / 10;  // Frame time in microseconds +	_readStream->readUint32BE();                    // Magic number EMIT +	_readStream->readUint32LE();                    // Size4 +	_readStream->readUint32LE();                    // Unknown11 +	_frameTime = _readStream->readUint32LE() / 10;  // Frame time in microseconds  	return true;  } @@ -128,17 +164,17 @@ bool RlfAnimation::readHeader() {  RlfAnimation::Frame RlfAnimation::readNextFrame() {  	RlfAnimation::Frame frame; -	_file.readUint32BE();                        // Magic number MARF -	uint32 size = _file.readUint32LE();          // Size -	_file.readUint32LE();                        // Unknown1 -	_file.readUint32LE();                        // Unknown2 -	uint32 type = _file.readUint32BE();          // Either ELHD or ELRH -	uint32 headerSize = _file.readUint32LE();    // Offset from the beginning of this frame to the frame data. Should always be 28 -	_file.readUint32LE();                        // Unknown3 +	_readStream->readUint32BE();                        // Magic number MARF +	uint32 size = _readStream->readUint32LE();          // Size +	_readStream->readUint32LE();                        // Unknown1 +	_readStream->readUint32LE();                        // Unknown2 +	uint32 type = _readStream->readUint32BE();          // Either ELHD or ELRH +	uint32 headerSize = _readStream->readUint32LE();    // Offset from the beginning of this frame to the frame data. Should always be 28 +	_readStream->readUint32LE();                        // Unknown3  	frame.encodedSize = size - headerSize;  	frame.encodedData = new int8[frame.encodedSize]; -	_file.read(frame.encodedData, frame.encodedSize); +	_readStream->read(frame.encodedData, frame.encodedSize);  	if (type == MKTAG('E', 'L', 'H', 'D')) {  		frame.type = Masked; diff --git a/engines/zvision/rlf_animation.h b/engines/zvision/rlf_animation.h index 35916de6cb..3764465786 100644 --- a/engines/zvision/rlf_animation.h +++ b/engines/zvision/rlf_animation.h @@ -37,6 +37,7 @@ namespace ZVision {  class RlfAnimation {  public:  	RlfAnimation(const Common::String &fileName, bool stream = true); +	RlfAnimation(Common::SeekableReadStream *rstream, bool stream);  	~RlfAnimation();  private: @@ -52,7 +53,7 @@ private:  	};  private: -	Common::File _file; +	Common::SeekableReadStream *_readStream;  	bool _stream;  	uint _lastFrameRead; diff --git a/engines/zvision/scr_file_handling.cpp b/engines/zvision/scr_file_handling.cpp index 833db11ad1..db4e8fa9b1 100644 --- a/engines/zvision/scr_file_handling.cpp +++ b/engines/zvision/scr_file_handling.cpp @@ -22,6 +22,7 @@  #include "common/scummsys.h" +#include "zvision/zvision.h"  #include "zvision/script_manager.h"  #include "zvision/utility.h" @@ -40,7 +41,7 @@ namespace ZVision {  void ScriptManager::parseScrFile(const Common::String &fileName, script_scope &scope) {  	Common::File file; -	if (!file.open(fileName)) { +	if (!_engine->getSearchManager()->openFile(file, fileName)) {  		warning("Script file not found: %s", fileName.c_str());  		return;  	} diff --git a/engines/zvision/search_manager.cpp b/engines/zvision/search_manager.cpp new file mode 100644 index 0000000000..5c94ff0a26 --- /dev/null +++ b/engines/zvision/search_manager.cpp @@ -0,0 +1,274 @@ +/* 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. +* +*/ +#include "common/debug.h" + +#include "zvision/search_manager.h" +#include "zvision/zfs_archive.h" +#include "common/fs.h" +#include "common/stream.h" + + +namespace ZVision { + +sManager::sManager(const Common::String &root_path, int depth) { +	_root = root_path; +	if (_root[_root.size() - 1] == '\\' || _root[_root.size() - 1] == '/') +		_root.deleteLastChar(); + +	Common::FSNode fs_node(_root); + +	list_dir_recursive(dir_list, fs_node, depth); + +	for (Common::List<Common::String>::iterator it = dir_list.begin(); it != dir_list.end();) +		if (it->size() == _root.size()) +			it = dir_list.erase(it); +		else if (it->size() > _root.size()) { +			*it = Common::String(it->c_str() + _root.size() + 1); +			it++; +		} else +			it++; +} + +sManager::~sManager() { +	Common::List<Common::Archive *>::iterator it = archList.begin(); +	while (it != archList.end()) { +		delete *it; +		it++; +	} + +	archList.clear(); +} + +void sManager::addPatch(const Common::String &src, const Common::String &dst) { +	Common::String lw_name = dst; +	lw_name.toLowercase(); + +	sManager::MatchList::iterator it = files.find(lw_name); + +	if (it != files.end()) { +		lw_name = src; +		lw_name.toLowercase(); +		files[lw_name] = it->_value; +	} +} + +void sManager::addFile(const Common::String &name, Common::Archive *arch) { +	bool addArch = true; +	Common::List<Common::Archive *>::iterator it = archList.begin(); +	while (it != archList.end()) { +		if (*it == arch) { +			addArch = false; +			break; +		} +		it++; +	} +	if (addArch) +		archList.push_back(arch); + +	Common::String lw_name = name; +	lw_name.toLowercase(); + +	sManager::Node nod; +	nod.name = lw_name; +	nod.arch = arch; + +	sManager::MatchList::iterator fit = files.find(lw_name); + +	if (fit == files.end()) { +		files[lw_name] = nod; +	} else { +		Common::SeekableReadStream *stream = fit->_value.arch->createReadStreamForMember(fit->_value.name); +		if (stream) { +			if (stream->size() < 10) +				fit->_value.arch = arch; +			delete stream; +		} else { +			files[lw_name] = nod; +		} +	} +} + +Common::File *sManager::openFile(const Common::String &name) { +	Common::String lw_name = name; +	lw_name.toLowercase(); + +	sManager::MatchList::iterator fit = files.find(lw_name); + +	if (fit != files.end()) { +		Common::File *tmp = new Common::File(); +		tmp->open(fit->_value.name, *fit->_value.arch); +		return tmp; +	} +	return NULL; +} + +bool sManager::openFile(Common::File &file, const Common::String &name) { +	Common::String lw_name = name; +	lw_name.toLowercase(); + +	sManager::MatchList::iterator fit = files.find(lw_name); + +	if (fit != files.end()) +		return file.open(fit->_value.name, *fit->_value.arch); +	return false; +} + +bool sManager::hasFile(const Common::String &name) { +	Common::String lw_name = name; +	lw_name.toLowercase(); + +	sManager::MatchList::iterator fit = files.find(lw_name); + +	if (fit != files.end()) +		return true; +	return false; +} + +void sManager::loadZix(const Common::String &name) { +	Common::File file; +	file.open(name); + +	Common::String line; + +	while (!file.eos()) { +		line = file.readLine(); +		if (line.matchString("----------*", true)) +			break; +	} + +	if (file.eos()) +		return; + +	Common::Array<Common::Archive *> archives; + +	while (!file.eos()) { +		line = file.readLine(); +		line.trim(); +		if (line.matchString("----------*", true)) +			break; +		else if (line.matchString("DIR:*", true)) { +			Common::String path(line.c_str() + 5); +			Common::Archive *arc; +			char n_path[128]; +			strcpy(n_path, path.c_str()); +			for (uint i = 0; i < path.size(); i++) +				if (n_path[i] == '\\') +					n_path[i] = '/'; + +			path = Common::String(n_path); +			if (path.size() && path[0] == '.') +				path.deleteChar(0); +			if (path.size() && path[0] == '/') +				path.deleteChar(0); + +			if (path.matchString("*.zfs", true)) +				arc = new ZfsArchive(path); +			else { +				if (path.size()) { +					if (path[path.size() - 1] == '\\' || path[path.size() - 1] == '/') +						path.deleteLastChar(); +					if (path.size()) +						for (Common::List<Common::String>::iterator it = dir_list.begin(); it != dir_list.end(); ++it) +							if (path.equalsIgnoreCase(*it)) { +								path = *it; +								break; +							} +				} + +				path = Common::String::format("%s/%s", _root.c_str(), path.c_str()); + +				arc = new Common::FSDirectory(path); +			} +			archives.push_back(arc); +		} +	} + +	if (file.eos()) +		return; + +	while (!file.eos()) { +		line = file.readLine(); +		line.trim(); +		uint dr = 0; +		char buf[32]; +		if (sscanf(line.c_str(), "%u %s", &dr, buf) == 2) { +			if (dr < archives.size() && dr > 0) { +				addFile(Common::String(buf), archives[dr - 1]); +			} +		} +	} +} + +void sManager::addDir(const Common::String &name) { +	Common::String path; +	for (Common::List<Common::String>::iterator it = dir_list.begin(); it != dir_list.end(); ++it) +		if (name.equalsIgnoreCase(*it)) { +			path = *it; +			break; +		} + +	if (path.size() == 0) +		return; + +	path = Common::String::format("%s/%s", _root.c_str(), path.c_str()); + +	Common::FSDirectory *dir = new Common::FSDirectory(path); + +	Common::ArchiveMemberList list; +	dir->listMatchingMembers(list, "*.zfs"); + + +	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) { +		Common::String flname = (*iter)->getName(); + +		ZfsArchive *zfs = new ZfsArchive(Common::String::format("%s/%s", name.c_str(), flname.c_str())); + +		Common::ArchiveMemberList zfslist; +		zfs->listMembers(zfslist); + +		for (Common::ArchiveMemberList::iterator ziter = zfslist.begin(); ziter != zfslist.end(); ++ziter) { +			Common::String z_name = (*ziter)->getName(); +			addFile(z_name, zfs); +		} +	} + +	list.clear(); +	dir->listMembers(list); + +	for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) { +		Common::String flname = (*iter)->getName(); +		addFile(flname, dir); +	} +} + +void sManager::list_dir_recursive(Common::List<Common::String> &_list, const Common::FSNode &fs_node, int depth) { +	Common::FSList fs_list; +	fs_node.getChildren(fs_list); + +	_list.push_back(fs_node.getPath()); + +	if (depth > 1) +		for (Common::FSList::const_iterator it = fs_list.begin(); it != fs_list.end(); ++it) +			list_dir_recursive(_list, *it, depth - 1); +} + +} // End of namespace ZVision diff --git a/engines/zvision/search_manager.h b/engines/zvision/search_manager.h new file mode 100644 index 0000000000..c768cb8b00 --- /dev/null +++ b/engines/zvision/search_manager.h @@ -0,0 +1,51 @@ +#ifndef SEARCH_MANAGER_H_INCLUDED +#define SEARCH_MANAGER_H_INCLUDED + +#include "common/str.h" +#include "common/hash-str.h" +#include "common/hashmap.h" +#include "common/archive.h" +#include "common/file.h" +#include "common/list.h" + +namespace ZVision { + +class sManager { +public: +	sManager(const Common::String &root_path, int depth); +	~sManager(); + +	void addFile(const Common::String &name, Common::Archive *arch); +	void addDir(const Common::String &name); +	void addPatch(const Common::String &src, const Common::String &dst); + +	Common::File *openFile(const Common::String &name); +	bool openFile(Common::File &file, const Common::String &name); +	bool hasFile(const Common::String &name); + +	void loadZix(const Common::String &name); + +private: + +	void list_dir_recursive(Common::List<Common::String> &dir_list, const Common::FSNode &fs_node, int depth); + +	struct Node { +		Common::String name; +		Common::Archive *arch; +	}; + +	Common::List<Common::String> dir_list; + +	typedef Common::HashMap<Common::String, Node, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> MatchList; + +	Common::List<Common::Archive *> archList; +	MatchList files; + +	Common::String _root; + +private: +}; + +} + +#endif // SEARCH_MANAGER_H_INCLUDED diff --git a/engines/zvision/zork_raw.cpp b/engines/zvision/zork_raw.cpp index e7cc71a70b..a4d091f3c0 100644 --- a/engines/zvision/zork_raw.cpp +++ b/engines/zvision/zork_raw.cpp @@ -254,7 +254,7 @@ Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,  Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine) {  	Common::File *file = new Common::File(); -	assert(file->open(filePath)); +	assert(engine->getSearchManager()->openFile(*file, filePath));  	Common::String fileName = getFileName(filePath);  	fileName.toLowercase(); diff --git a/engines/zvision/zvision.cpp b/engines/zvision/zvision.cpp index f21498c315..bf945f859a 100644 --- a/engines/zvision/zvision.cpp +++ b/engines/zvision/zvision.cpp @@ -33,8 +33,10 @@  #include "zvision/zfs_archive.h"  #include "zvision/detection.h"  #include "zvision/menu.h" +#include "zvision/search_manager.h"  #include "common/config-manager.h" +#include "common/str.h"  #include "common/debug.h"  #include "common/debug-channels.h"  #include "common/textconsole.h" @@ -88,6 +90,29 @@ ZVision::~ZVision() {  void ZVision::initialize() {  	const Common::FSNode gameDataDir(ConfMan.get("path")); + +	_searchManager = new sManager(ConfMan.get("path"), 6); + +	_searchManager->addDir("addon"); + +	if (_gameDescription->gameId == GID_GRANDINQUISITOR) { +		_searchManager->loadZix("INQUIS.ZIX"); +		_searchManager->addPatch("C000H01Q.RAW", "C000H01Q.SRC"); +		_searchManager->addPatch("CM00H01Q.RAW", "CM00H01Q.SRC"); +		_searchManager->addPatch("DM00H01Q.RAW", "DM00H01Q.SRC"); +		_searchManager->addPatch("E000H01Q.RAW", "E000H01Q.SRC"); +		_searchManager->addPatch("EM00H50Q.RAW", "EM00H50Q.SRC"); +		_searchManager->addPatch("GJNPH65P.RAW", "GJNPH65P.SRC"); +		_searchManager->addPatch("GJNPH72P.RAW", "GJNPH72P.SRC"); +		_searchManager->addPatch("H000H01Q.RAW", "H000H01Q.SRC"); +		_searchManager->addPatch("M000H01Q.RAW", "M000H01Q.SRC"); +		_searchManager->addPatch("P000H01Q.RAW", "P000H01Q.SRC"); +		_searchManager->addPatch("Q000H01Q.RAW", "Q000H01Q.SRC"); +		_searchManager->addPatch("SW00H01Q.RAW", "SW00H01Q.SRC"); +		_searchManager->addPatch("T000H01Q.RAW", "T000H01Q.SRC"); +		_searchManager->addPatch("U000H01Q.RAW", "U000H01Q.SRC"); +	} else if (_gameDescription->gameId == GID_NEMESIS) +		_searchManager->loadZix("NEMESIS.ZIX");  	// TODO: There are 10 file clashes when we flatten the directories.  	// From a quick look, the files are exactly the same, so it shouldn't matter.  	// But I'm noting it here just in-case it does become a problem. @@ -123,7 +148,7 @@ void ZVision::initialize() {  	// Create managers  	_scriptManager = new ScriptManager(this); -	_renderManager = new RenderManager(_system, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _pixelFormat); +	_renderManager = new RenderManager(this, WINDOW_WIDTH, WINDOW_HEIGHT, _workingWindow, _pixelFormat);  	_saveManager = new SaveManager(this);  	_stringManager = new StringManager(this);  	_cursorManager = new CursorManager(this, &_pixelFormat); diff --git a/engines/zvision/zvision.h b/engines/zvision/zvision.h index 26d7644eb0..c9e14e8651 100644 --- a/engines/zvision/zvision.h +++ b/engines/zvision/zvision.h @@ -26,6 +26,7 @@  #include "zvision/detection.h"  #include "zvision/clock.h" +#include "zvision/search_manager.h"  #include "common/random.h"  #include "common/events.h" @@ -99,6 +100,7 @@ private:  	SaveManager *_saveManager;  	StringManager *_stringManager;  	menuHandler *_menu; +	sManager *_searchManager;  	// Clock  	Clock _clock; @@ -135,6 +137,9 @@ public:  	StringManager *getStringManager() const {  		return _stringManager;  	} +	sManager *getSearchManager() const { +		return _searchManager; +	}  	Common::RandomSource *getRandomSource() const {  		return _rnd;  	}  | 
