aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMarisa-Chan2014-02-04 08:32:02 +0700
committerMarisa-Chan2014-02-04 08:32:02 +0700
commit4a454ed763c24f94062be5dd57f43e0a84c1b0a2 (patch)
treecbfd6f403c780c696d86bc02397e93a89dba9870 /engines
parent9c9f59d57060617d1acec71bd0d4066504f17c7a (diff)
downloadscummvm-rg350-4a454ed763c24f94062be5dd57f43e0a84c1b0a2.tar.gz
scummvm-rg350-4a454ed763c24f94062be5dd57f43e0a84c1b0a2.tar.bz2
scummvm-rg350-4a454ed763c24f94062be5dd57f43e0a84c1b0a2.zip
ZVISION: New search manager for handle right handle for ZIX-files.
Diffstat (limited to 'engines')
-rw-r--r--engines/zvision/actions.cpp45
-rw-r--r--engines/zvision/animation_node.cpp2
-rw-r--r--engines/zvision/cursor.cpp29
-rw-r--r--engines/zvision/cursor.h2
-rw-r--r--engines/zvision/cursor_manager.cpp24
-rw-r--r--engines/zvision/lever_control.cpp4
-rw-r--r--engines/zvision/meta_animation.cpp8
-rw-r--r--engines/zvision/meta_animation.h3
-rw-r--r--engines/zvision/module.mk3
-rw-r--r--engines/zvision/music_node.cpp2
-rw-r--r--engines/zvision/render_manager.cpp10
-rw-r--r--engines/zvision/render_manager.h3
-rw-r--r--engines/zvision/rlf_animation.cpp116
-rw-r--r--engines/zvision/rlf_animation.h3
-rw-r--r--engines/zvision/scr_file_handling.cpp3
-rw-r--r--engines/zvision/search_manager.cpp274
-rw-r--r--engines/zvision/search_manager.h51
-rw-r--r--engines/zvision/zork_raw.cpp2
-rw-r--r--engines/zvision/zvision.cpp27
-rw-r--r--engines/zvision/zvision.h5
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;
}