Initial commit
This commit is contained in:
266
engines/zvision/file/file_manager.cpp
Normal file
266
engines/zvision/file/file_manager.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "zvision/file/file_manager.h"
|
||||
#include "zvision/file/zfs_archive.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
const char* genExcluded[] {"*.dll", "*.ini", "*.exe", "*.isu", "*.inf", "*path*.txt", "r.svr", "*.zix", "*.hlp", "*.gid"};
|
||||
|
||||
const char* zgiAlternates[] {
|
||||
"c000h01q.raw", "cm00h01q.raw", "dm00h01q.raw", "e000h01q.raw", "em00h11p.raw", "em00h50q.raw", "gjnph65p.raw",
|
||||
"gjnph72p.raw", "h000h01q.raw", "m000h01q.raw", "p000h01q.raw", "q000h01q.raw", "sw00h01q.raw", "t000h01q.raw",
|
||||
"u000h01q.raw"
|
||||
};
|
||||
|
||||
FileManager::FileManager(ZVision *engine) {
|
||||
}
|
||||
|
||||
Common::File *FileManager::open(const Common::Path &filePath, bool allowSrc) {
|
||||
debugC(5, kDebugFile, "FileManager::open()");
|
||||
Common::File *file = new Common::File();
|
||||
Common::File *out = nullptr;
|
||||
|
||||
Common::String fileName = filePath.baseName();
|
||||
bool open = false;
|
||||
bool altFound = false;
|
||||
bool altOpen = false;
|
||||
|
||||
bool found = SearchMan.hasFile(filePath);
|
||||
if(found) {
|
||||
debugC(5, kDebugFile,"File %s found", fileName.c_str());
|
||||
open = file->open(filePath);
|
||||
if(open)
|
||||
debugC(5, kDebugFile,"File %s opened", fileName.c_str());
|
||||
}
|
||||
|
||||
if (allowSrc) {
|
||||
Common::File *altFile = new Common::File();
|
||||
Common::String altName = fileName;
|
||||
altName.setChar('s', altName.size() - 3);
|
||||
altName.setChar('r', altName.size() - 2);
|
||||
altName.setChar('c', altName.size() - 1);
|
||||
Common::Path altPath = filePath.getParent().appendComponent(altName);
|
||||
altFound = SearchMan.hasFile(altPath);
|
||||
if (altFound) {
|
||||
debugC(5, kDebugFile,"Alternate file %s found", altName.c_str());
|
||||
altOpen = altFile->open(altPath);
|
||||
if (altOpen)
|
||||
debugC(5, kDebugFile,"Alternate file %s opened", altName.c_str());
|
||||
}
|
||||
|
||||
if(altOpen) {
|
||||
if(open)
|
||||
out = file->size() < altFile->size() ? altFile : file;
|
||||
else
|
||||
out = altFile;
|
||||
}
|
||||
else if(open)
|
||||
out = file;
|
||||
else {
|
||||
if (found && altFound)
|
||||
warning("Found file %s and alternate file %s but unable to open either", fileName.c_str(), altName.c_str());
|
||||
else if (found)
|
||||
warning("Found file %s but unable to open; alternate file %s not found", fileName.c_str(), altName.c_str());
|
||||
else if (altFound)
|
||||
warning("File %s not found; alternate file %s found but but unable to open", fileName.c_str(), altName.c_str());
|
||||
else
|
||||
warning("Unable to find file %s or alternate file %s", fileName.c_str(), altName.c_str());
|
||||
}
|
||||
|
||||
if (out == altFile)
|
||||
debugC(5, kDebugFile,"Returning alternate file %s", altName.c_str());
|
||||
else {
|
||||
if(altOpen)
|
||||
altFile->close();
|
||||
delete altFile;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(open)
|
||||
out = file;
|
||||
else if (found)
|
||||
warning("File %s found, but unable to open", fileName.c_str());
|
||||
else
|
||||
warning("File %s not found", fileName.c_str());
|
||||
}
|
||||
|
||||
if (out == file)
|
||||
debugC(5, kDebugFile,"Returning file %s", fileName.c_str());
|
||||
else {
|
||||
if(open)
|
||||
file->close();
|
||||
delete file;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
bool FileManager::exists(Common::Path filePath, bool allowSrc) {
|
||||
Common::File file;
|
||||
if (file.exists(filePath))
|
||||
return true;
|
||||
else if (allowSrc) {
|
||||
if (file.exists(srcPath(filePath)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::Path FileManager::srcPath(Common::Path filePath) {
|
||||
Common::String name = filePath.baseName();
|
||||
name.setChar('s', name.size() - 3);
|
||||
name.setChar('r', name.size() - 2);
|
||||
name.setChar('c', name.size() - 1);
|
||||
return filePath.getParent().appendComponent(name);
|
||||
}
|
||||
|
||||
bool FileManager::loadZix(const Common::Path &zixPath, const Common::FSNode &gameDataDir) {
|
||||
Common::File zixFile;
|
||||
if (!zixFile.open(zixPath))
|
||||
return false;
|
||||
|
||||
Common::String line;
|
||||
|
||||
// Skip first block
|
||||
while (!zixFile.eos()) {
|
||||
line = zixFile.readLine();
|
||||
if (line.matchString("----------*", true))
|
||||
break;
|
||||
}
|
||||
|
||||
if (zixFile.eos())
|
||||
error("Corrupt ZIX file: %s", zixPath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
|
||||
uint8 archives = 0;
|
||||
|
||||
// Parse subdirectories & archives
|
||||
debugC(1, kDebugFile, "Parsing list of subdirectories & archives in %s", zixPath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
while (!zixFile.eos()) {
|
||||
line = zixFile.readLine();
|
||||
line.trim();
|
||||
if (line.matchString("----------*", true))
|
||||
break;
|
||||
else if (line.matchString("DIR:*", true) || line.matchString("CD0:*", true) || line.matchString("CD1:*", true) || line.matchString("CD2:*", true)) {
|
||||
line = Common::String(line.c_str() + 5);
|
||||
for (uint i = 0; i < line.size(); i++)
|
||||
if (line[i] == '\\')
|
||||
line.setChar('/', i);
|
||||
|
||||
// Check if NEMESIS.ZIX/MEDIUM.ZIX refers to the znemesis folder, and
|
||||
// check the game root folder instead
|
||||
if (line.hasPrefix("znemesis/"))
|
||||
line = Common::String(line.c_str() + 9);
|
||||
|
||||
// Check if INQUIS.ZIX refers to the ZGI folder, and check the game
|
||||
// root folder instead
|
||||
if (line.hasPrefix("zgi/"))
|
||||
line = Common::String(line.c_str() + 4);
|
||||
if (line.hasPrefix("zgi_e/"))
|
||||
line = Common::String(line.c_str() + 6);
|
||||
|
||||
if (line.size() && line[0] == '.')
|
||||
line.deleteChar(0);
|
||||
if (line.size() && line[0] == '/')
|
||||
line.deleteChar(0);
|
||||
if (line.size() && line.hasSuffix("/"))
|
||||
line.deleteLastChar();
|
||||
|
||||
Common::Path path(line, '/');
|
||||
|
||||
if (line.matchString("*.zfs", true)) {
|
||||
if (!SearchMan.hasArchive(line)) {
|
||||
path = path.getLastComponent(); //We are using the search manager in "flat" mode, so only filenames are needed
|
||||
debugC(1, kDebugFile, "Adding archive %s to search manager.", path.toString().c_str());
|
||||
Common::Archive *arc;
|
||||
arc = new ZfsArchive(path);
|
||||
SearchMan.add(line, arc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
debugC(1, kDebugFile, "Adding directory %s to search manager.", path.toString().c_str());
|
||||
SearchMan.addSubDirectoryMatching(gameDataDir,path.toString());
|
||||
}
|
||||
archives++;
|
||||
}
|
||||
}
|
||||
|
||||
if (zixFile.eos())
|
||||
error("Corrupt ZIX file: %s", zixPath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
|
||||
//Parse files
|
||||
debugC(1, kDebugFile, "Parsing list of individual resource files in %s", zixPath.toString(Common::Path::kNativeSeparator).c_str());
|
||||
while (!zixFile.eos()) {
|
||||
line = zixFile.readLine();
|
||||
line.trim();
|
||||
uint dr = 0;
|
||||
char buf[32];
|
||||
if (sscanf(line.c_str(), "%u %s", &dr, buf) == 2) {
|
||||
if (dr <= archives && dr > 0) {
|
||||
Common::String name(buf);
|
||||
bool exclude = false;
|
||||
bool allowSrc = false;
|
||||
for (auto excName : genExcluded)
|
||||
if(name.matchString(excName, true)) {
|
||||
exclude = true;
|
||||
break;
|
||||
}
|
||||
for (auto altName : zgiAlternates)
|
||||
if(name.matchString(altName, true)) {
|
||||
allowSrc = true;
|
||||
break;
|
||||
}
|
||||
if (!exclude) {
|
||||
Common::Path path(name);
|
||||
// No need to add file, just verify that it exists
|
||||
if (allowSrc) {
|
||||
Common::Path altPath = srcPath(path);
|
||||
if (!SearchMan.hasFile(path) && !SearchMan.hasFile(altPath))
|
||||
warning("Missing files %s and/or %s", path.toString().c_str(), altPath.toString().c_str());
|
||||
else if (SearchMan.hasFile(path))
|
||||
debugC(5, kDebugFile, "File found: %s", path.toString().c_str());
|
||||
else
|
||||
debugC(5, kDebugFile, "Alternate file found: %s", altPath.toString().c_str());
|
||||
}
|
||||
else {
|
||||
if (!SearchMan.hasFile(path))
|
||||
warning("Missing file %s", path.toString().c_str());
|
||||
else
|
||||
debugC(5, kDebugFile, "File found: %s", path.toString().c_str());
|
||||
}
|
||||
if (name.matchString("*.zfs", true))
|
||||
if (!SearchMan.hasArchive(name)) {
|
||||
Common::Path path_(path);
|
||||
debugC(kDebugFile, "Adding archive %s to search manager.", path.toString().c_str());
|
||||
Common::Archive *arc;
|
||||
arc = new ZfsArchive(path_);
|
||||
SearchMan.add(name, arc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Zvision
|
||||
46
engines/zvision/file/file_manager.h
Normal file
46
engines/zvision/file/file_manager.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/path.h"
|
||||
#include "zvision/zvision.h"
|
||||
|
||||
#ifndef ZVISION_FILE_MANAGER
|
||||
#define ZVISION_FILE_MANAGER
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class FileManager {
|
||||
public:
|
||||
FileManager(ZVision *engine);
|
||||
~FileManager() {};
|
||||
|
||||
bool loadZix(const Common::Path &zixPath, const Common::FSNode &gameDataDir);
|
||||
Common::File *open(const Common::Path &fileName, bool allowSrc=true); // Wrapper to automatically handle loading of files which may be empty & have an alternate .src file
|
||||
bool exists(Common::Path filePath, bool allowSrc=true); // Wrapper to automatically handle checking existence of files which may be empty & have an alternate .src file
|
||||
|
||||
private:
|
||||
Common::Path srcPath(Common::Path filePath);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
101
engines/zvision/file/lzss_read_stream.cpp
Normal file
101
engines/zvision/file/lzss_read_stream.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "zvision/file/lzss_read_stream.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
LzssReadStream::LzssReadStream(Common::SeekableReadStream *source)
|
||||
: _source(source),
|
||||
// It's convention to set the starting cursor position to blockSize - 16
|
||||
_windowCursor(0x0FEE),
|
||||
_eosFlag(false) {
|
||||
// All values up to _windowCursor inits by 0x20
|
||||
memset(_window, 0x20, _windowCursor);
|
||||
memset(_window + _windowCursor, 0, BLOCK_SIZE - _windowCursor);
|
||||
}
|
||||
|
||||
uint32 LzssReadStream::decompressBytes(byte *destination, uint32 numberOfBytes) {
|
||||
uint32 destinationCursor = 0;
|
||||
|
||||
while (destinationCursor < numberOfBytes) {
|
||||
byte flagbyte = _source->readByte();
|
||||
if (_source->eos())
|
||||
break;
|
||||
uint mask = 1;
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ((flagbyte & mask) == mask) {
|
||||
byte data = _source->readByte();
|
||||
if (_source->eos()) {
|
||||
return destinationCursor;
|
||||
}
|
||||
|
||||
_window[_windowCursor] = data;
|
||||
destination[destinationCursor++] = data;
|
||||
|
||||
// Increment and wrap the window cursor
|
||||
_windowCursor = (_windowCursor + 1) & 0xFFF;
|
||||
} else {
|
||||
byte low = _source->readByte();
|
||||
if (_source->eos()) {
|
||||
return destinationCursor;
|
||||
}
|
||||
|
||||
byte high = _source->readByte();
|
||||
if (_source->eos()) {
|
||||
return destinationCursor;
|
||||
}
|
||||
|
||||
uint16 length = (high & 0xF) + 2;
|
||||
uint16 offset = low | ((high & 0xF0) << 4);
|
||||
|
||||
for (int j = 0; j <= length; ++j) {
|
||||
byte temp = _window[(offset + j) & 0xFFF];
|
||||
_window[_windowCursor] = temp;
|
||||
destination[destinationCursor++] = temp;
|
||||
_windowCursor = (_windowCursor + 1) & 0xFFF;
|
||||
}
|
||||
}
|
||||
|
||||
mask = mask << 1;
|
||||
}
|
||||
}
|
||||
|
||||
return destinationCursor;
|
||||
}
|
||||
|
||||
bool LzssReadStream::eos() const {
|
||||
return _eosFlag;
|
||||
}
|
||||
|
||||
uint32 LzssReadStream::read(void *dataPtr, uint32 dataSize) {
|
||||
uint32 bytesRead = decompressBytes(static_cast<byte *>(dataPtr), dataSize);
|
||||
if (bytesRead < dataSize) {
|
||||
// Flag that we're at EOS
|
||||
_eosFlag = true;
|
||||
}
|
||||
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
70
engines/zvision/file/lzss_read_stream.h
Normal file
70
engines/zvision/file/lzss_read_stream.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_LZSS_STREAM_H
|
||||
#define ZVISION_LZSS_STREAM_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class LzssReadStream : public Common::ReadStream {
|
||||
public:
|
||||
/**
|
||||
* A class that decompresses LZSS data and implements ReadStream for easy access
|
||||
* to the decompiled data.
|
||||
*
|
||||
* @param source The source data
|
||||
*/
|
||||
LzssReadStream(Common::SeekableReadStream *source);
|
||||
|
||||
private:
|
||||
enum {
|
||||
BLOCK_SIZE = 0x1000
|
||||
};
|
||||
|
||||
private:
|
||||
Common::SeekableReadStream *_source;
|
||||
byte _window[BLOCK_SIZE];
|
||||
uint _windowCursor;
|
||||
bool _eosFlag;
|
||||
|
||||
public:
|
||||
bool eos() const override;
|
||||
uint32 read(void *dataPtr, uint32 dataSize) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Decompress the next <numberOfBytes> from the source stream. Or until EOS
|
||||
*
|
||||
* @param numberOfBytes How many bytes to decompress. This is a count of source bytes, not destination bytes
|
||||
*/
|
||||
uint32 decompressBytes(byte *destination, uint32 numberOfBytes);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
275
engines/zvision/file/save_manager.cpp
Normal file
275
engines/zvision/file/save_manager.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/system.h"
|
||||
#include "common/translation.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "graphics/thumbnail.h"
|
||||
#include "gui/message.h"
|
||||
#include "gui/saveload.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/file/save_manager.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G');
|
||||
|
||||
bool SaveManager::scummVMSaveLoadDialog(bool isSave) {
|
||||
GUI::SaveLoadChooser *dialog;
|
||||
Common::String desc;
|
||||
int slot;
|
||||
|
||||
if (isSave) {
|
||||
dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
|
||||
|
||||
slot = dialog->runModalWithCurrentTarget();
|
||||
desc = dialog->getResultString();
|
||||
|
||||
if (desc.empty()) {
|
||||
// create our own description for the saved game, the user didn't enter it
|
||||
desc = dialog->createDefaultSaveDescription(slot);
|
||||
}
|
||||
|
||||
if (desc.size() > 28)
|
||||
desc = Common::String(desc.c_str(), 28);
|
||||
} else {
|
||||
dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
|
||||
slot = dialog->runModalWithCurrentTarget();
|
||||
}
|
||||
|
||||
delete dialog;
|
||||
|
||||
if (slot < 0)
|
||||
return false;
|
||||
if (!isSave) {
|
||||
Common::ErrorCode result = loadGame(slot).getCode();
|
||||
return (result == Common::kNoError);
|
||||
}
|
||||
saveGame(slot, desc, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SaveManager::saveGame(uint slot, const Common::String &saveName, bool useSaveBuffer) {
|
||||
if (!_tempSave && useSaveBuffer)
|
||||
return;
|
||||
|
||||
Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
|
||||
Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->getSaveStateName(slot));
|
||||
|
||||
writeSaveGameHeader(file, saveName, useSaveBuffer);
|
||||
|
||||
if (useSaveBuffer)
|
||||
file->write(_tempSave->getData(), _tempSave->size());
|
||||
else
|
||||
_engine->getScriptManager()->serialize(file);
|
||||
|
||||
file->finalize();
|
||||
delete file;
|
||||
|
||||
if (useSaveBuffer)
|
||||
flushSaveBuffer();
|
||||
|
||||
_lastSaveTime = g_system->getMillis();
|
||||
}
|
||||
|
||||
void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName, bool useSaveBuffer) {
|
||||
file->writeUint32BE(SAVEGAME_ID);
|
||||
|
||||
// Write version
|
||||
file->writeByte(SAVE_VERSION);
|
||||
|
||||
// Write savegame name
|
||||
file->writeString(saveName);
|
||||
file->writeByte(0);
|
||||
|
||||
// Save the game thumbnail
|
||||
if (useSaveBuffer)
|
||||
file->write(_tempThumbnail->getData(), _tempThumbnail->size());
|
||||
else
|
||||
Graphics::saveThumbnail(*file);
|
||||
|
||||
// Write out the save date/time
|
||||
TimeDate td;
|
||||
g_system->getTimeAndDate(td);
|
||||
file->writeSint16LE(td.tm_year + 1900);
|
||||
file->writeSint16LE(td.tm_mon + 1);
|
||||
file->writeSint16LE(td.tm_mday);
|
||||
file->writeSint16LE(td.tm_hour);
|
||||
file->writeSint16LE(td.tm_min);
|
||||
|
||||
file->writeUint32LE(g_engine->getTotalPlayTime() / 1000);
|
||||
}
|
||||
|
||||
Common::Error SaveManager::loadGame(int slot) {
|
||||
Common::SeekableReadStream *saveFile = NULL;
|
||||
if (slot < 0) {
|
||||
// Restart game, used by ZGI death screen only
|
||||
_engine->getScriptManager()->initialize(true);
|
||||
return Common::kNoError;
|
||||
}
|
||||
saveFile = getSlotFile(slot);
|
||||
if (!saveFile)
|
||||
return Common::kPathDoesNotExist;
|
||||
// Read the header
|
||||
SaveGameHeader header;
|
||||
if (!readSaveGameHeader(saveFile, header))
|
||||
return Common::kUnknownError;
|
||||
ScriptManager *scriptManager = _engine->getScriptManager();
|
||||
// Update the state table values
|
||||
scriptManager->deserialize(saveFile);
|
||||
delete saveFile;
|
||||
if (_engine->getGameId() == GID_NEMESIS) {
|
||||
// Zork Nemesis has no in-game option to select panorama quality or animation options
|
||||
// We set them here to ensure loaded games don't override current game configuration
|
||||
scriptManager->setStateValue(StateKey_HighQuality, ConfMan.getBool("highquality"));
|
||||
scriptManager->setStateValue(StateKey_NoTurnAnim, ConfMan.getBool("noanimwhileturning"));
|
||||
if (scriptManager->getCurrentLocation() == "tv2f") {
|
||||
// WORKAROUND for script bug #6793: location tv2f (stairs) has two states:
|
||||
// one at the top of the stairs, and one at the bottom. When the player
|
||||
// goes to the bottom of the stairs, the screen changes, and hotspot
|
||||
// 4652 (exit opposite the stairs) is enabled. However, the variable that
|
||||
// controls the state (2408) is reset when the player goes down the stairs.
|
||||
// Furthermore, the room's initialization script disables the stair exit
|
||||
// control (4652). This leads to an impossible situation, where all the
|
||||
// exit controls are disabled, and the player can't more anywhere. Thus,
|
||||
// when loading a game in that room, we check for that impossible
|
||||
// situation, which only occurs after the player has moved down the stairs,
|
||||
// and fix it here by setting the correct background, and enabling the
|
||||
// stair exit hotspot.
|
||||
if ((scriptManager->getStateFlag(2411) & Puzzle::DISABLED) &&
|
||||
(scriptManager->getStateFlag(2408) & Puzzle::DISABLED) &&
|
||||
(scriptManager->getStateFlag(4652) & Puzzle::DISABLED)) {
|
||||
_engine->getRenderManager()->setBackgroundImage("tv2fb21c.tga");
|
||||
scriptManager->unsetStateFlag(4652, Puzzle::DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_engine->setTotalPlayTime(header.playTime * 1000);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail) {
|
||||
header.saveYear = 0;
|
||||
header.saveMonth = 0;
|
||||
header.saveDay = 0;
|
||||
header.saveHour = 0;
|
||||
header.saveMinutes = 0;
|
||||
header.playTime = 0;
|
||||
header.saveName.clear();
|
||||
header.thumbnail = nullptr;
|
||||
header.version = 0;
|
||||
|
||||
uint32 tag = in->readUint32BE();
|
||||
// Check if it's original savegame than fill header structure
|
||||
if (tag == MKTAG('Z', 'N', 'S', 'G')) {
|
||||
header.saveName = "Original Save";
|
||||
header.version = SAVE_ORIGINAL;
|
||||
in->seek(-4, SEEK_CUR);
|
||||
return true;
|
||||
}
|
||||
if (tag != SAVEGAME_ID) {
|
||||
warning("File is not a Z-Vision saved game. Aborting load");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in the version
|
||||
header.version = in->readByte();
|
||||
|
||||
// Check that the save version isn't newer than this binary
|
||||
if (header.version > SAVE_VERSION) {
|
||||
uint tempVersion = header.version;
|
||||
GUI::MessageDialog dialog(
|
||||
Common::U32String::format(
|
||||
_("This saved game uses version %u, but this engine only "
|
||||
"supports up to version %d. You will need an updated version "
|
||||
"of the engine to use this saved game."), tempVersion, SAVE_VERSION
|
||||
));
|
||||
dialog.runModal();
|
||||
}
|
||||
|
||||
// Read in the save name
|
||||
char ch;
|
||||
while ((ch = (char)in->readByte()) != '\0')
|
||||
header.saveName += ch;
|
||||
|
||||
// Get the thumbnail
|
||||
if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in save date/time
|
||||
header.saveYear = in->readSint16LE();
|
||||
header.saveMonth = in->readSint16LE();
|
||||
header.saveDay = in->readSint16LE();
|
||||
header.saveHour = in->readSint16LE();
|
||||
header.saveMinutes = in->readSint16LE();
|
||||
|
||||
if (header.version >= 2) {
|
||||
header.playTime = in->readUint32LE();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *SaveManager::getSlotFile(uint slot) {
|
||||
Common::SeekableReadStream *saveFile = g_system->getSavefileManager()->openForLoading(_engine->getSaveStateName(slot));
|
||||
if (saveFile == NULL) {
|
||||
// Try to load standard save file
|
||||
Common::Path filename;
|
||||
if (_engine->getGameId() == GID_GRANDINQUISITOR)
|
||||
filename = Common::Path(Common::String::format("inqsav%u.sav", slot));
|
||||
else if (_engine->getGameId() == GID_NEMESIS)
|
||||
filename = Common::Path(Common::String::format("nemsav%u.sav", slot));
|
||||
|
||||
Common::File *tmpFile = new Common::File;
|
||||
if (!tmpFile->open(filename))
|
||||
delete tmpFile;
|
||||
else
|
||||
saveFile = tmpFile;
|
||||
}
|
||||
return saveFile;
|
||||
}
|
||||
|
||||
void SaveManager::prepareSaveBuffer() {
|
||||
delete _tempThumbnail;
|
||||
_tempThumbnail = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
|
||||
Graphics::saveThumbnail(*_tempThumbnail);
|
||||
|
||||
delete _tempSave;
|
||||
_tempSave = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
|
||||
_engine->getScriptManager()->serialize(_tempSave);
|
||||
}
|
||||
|
||||
void SaveManager::flushSaveBuffer() {
|
||||
delete _tempThumbnail;
|
||||
_tempThumbnail = NULL;
|
||||
|
||||
delete _tempSave;
|
||||
_tempSave = NULL;
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
103
engines/zvision/file/save_manager.h
Normal file
103
engines/zvision/file/save_manager.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_SAVE_MANAGER_H
|
||||
#define ZVISION_SAVE_MANAGER_H
|
||||
|
||||
#include "common/memstream.h"
|
||||
#include "common/savefile.h"
|
||||
|
||||
namespace Common {
|
||||
class String;
|
||||
}
|
||||
|
||||
namespace Graphics {
|
||||
struct Surface;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class ZVision;
|
||||
|
||||
struct SaveGameHeader {
|
||||
byte version;
|
||||
Common::String saveName;
|
||||
Graphics::Surface *thumbnail;
|
||||
int16 saveYear, saveMonth, saveDay;
|
||||
int16 saveHour, saveMinutes;
|
||||
uint32 playTime;
|
||||
};
|
||||
|
||||
class SaveManager {
|
||||
public:
|
||||
SaveManager(ZVision *engine) : _engine(engine), _tempSave(NULL), _tempThumbnail(NULL), _lastSaveTime(0) {}
|
||||
~SaveManager() {
|
||||
flushSaveBuffer();
|
||||
}
|
||||
|
||||
uint32 getLastSaveTime() const {
|
||||
return _lastSaveTime;
|
||||
}
|
||||
|
||||
private:
|
||||
ZVision *_engine;
|
||||
uint32 _lastSaveTime;
|
||||
static const uint32 SAVEGAME_ID;
|
||||
|
||||
enum {
|
||||
SAVE_ORIGINAL = 0,
|
||||
SAVE_VERSION = 2
|
||||
};
|
||||
|
||||
Common::MemoryWriteStreamDynamic *_tempThumbnail;
|
||||
Common::MemoryWriteStreamDynamic *_tempSave;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Copies the data from the last auto-save into a new save file. We
|
||||
* can't use the current state data because the save menu *IS* a room.
|
||||
* The file is named using ZVision::generateSaveFileName(slot)
|
||||
*
|
||||
* @param slot The save slot this save pertains to. Must be [1, 20]
|
||||
* @param saveName The internal name for this save. This is NOT the name of the actual save file.
|
||||
*/
|
||||
void saveGame(uint slot, const Common::String &saveName, bool useSaveBuffer);
|
||||
/**
|
||||
* Loads the state data from the save file that slot references. Uses
|
||||
* ZVision::generateSaveFileName(slot) to get the save file name.
|
||||
*
|
||||
* @param slot The save slot to load. Must be [1, 20]
|
||||
*/
|
||||
Common::Error loadGame(int slot);
|
||||
|
||||
Common::SeekableReadStream *getSlotFile(uint slot);
|
||||
bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header, bool skipThumbnail = true);
|
||||
|
||||
void prepareSaveBuffer();
|
||||
void flushSaveBuffer();
|
||||
bool scummVMSaveLoadDialog(bool isSave);
|
||||
private:
|
||||
void writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName, bool useSaveBuffer);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
156
engines/zvision/file/zfs_archive.cpp
Normal file
156
engines/zvision/file/zfs_archive.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/file.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "zvision/detection.h"
|
||||
#include "zvision/file/zfs_archive.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
ZfsArchive::ZfsArchive(const Common::Path &fileName) : _fileName(fileName) {
|
||||
Common::File zfsFile;
|
||||
memset(&_header, 0, sizeof(_header));
|
||||
|
||||
if (!zfsFile.open(_fileName)) {
|
||||
warning("ZFSArchive::ZFSArchive(): Could not find the archive file");
|
||||
return;
|
||||
}
|
||||
|
||||
readHeaders(&zfsFile);
|
||||
|
||||
debugC(1, kDebugFile, "ZfsArchive::ZfsArchive(%s): Located %d files", _fileName.toString(Common::Path::kNativeSeparator).c_str(), _entryHeaders.size());
|
||||
}
|
||||
|
||||
ZfsArchive::ZfsArchive(const Common::Path &fileName, Common::SeekableReadStream *stream) : _fileName(fileName) {
|
||||
readHeaders(stream);
|
||||
|
||||
debugC(1, kDebugFile, "ZfsArchive::ZfsArchive(%s): Located %d files", _fileName.toString(Common::Path::kNativeSeparator).c_str(), _entryHeaders.size());
|
||||
}
|
||||
|
||||
ZfsArchive::~ZfsArchive() {
|
||||
debugC(1, kDebugFile, "ZfsArchive Destructor Called");
|
||||
ZfsEntryHeaderMap::iterator it = _entryHeaders.begin();
|
||||
for (; it != _entryHeaders.end(); ++it) {
|
||||
delete it->_value;
|
||||
}
|
||||
}
|
||||
|
||||
void ZfsArchive::readHeaders(Common::SeekableReadStream *stream) {
|
||||
// Don't do a straight struct cast since we can't guarantee endianness
|
||||
_header.magic = stream->readUint32LE();
|
||||
_header.unknown1 = stream->readUint32LE();
|
||||
_header.maxNameLength = stream->readUint32LE();
|
||||
_header.filesPerBlock = stream->readUint32LE();
|
||||
_header.fileCount = stream->readUint32LE();
|
||||
_header.xorKey[0] = stream->readByte();
|
||||
_header.xorKey[1] = stream->readByte();
|
||||
_header.xorKey[2] = stream->readByte();
|
||||
_header.xorKey[3] = stream->readByte();
|
||||
_header.fileSectionOffset = stream->readUint32LE();
|
||||
|
||||
uint32 nextOffset;
|
||||
|
||||
do {
|
||||
// Read the offset to the next block
|
||||
nextOffset = stream->readUint32LE();
|
||||
|
||||
// Read in each entry header
|
||||
for (uint32 i = 0; i < _header.filesPerBlock; ++i) {
|
||||
ZfsEntryHeader entryHeader;
|
||||
|
||||
entryHeader.name = readEntryName(stream);
|
||||
entryHeader.offset = stream->readUint32LE();
|
||||
entryHeader.id = stream->readUint32LE();
|
||||
entryHeader.size = stream->readUint32LE();
|
||||
entryHeader.time = stream->readUint32LE();
|
||||
entryHeader.unknown = stream->readUint32LE();
|
||||
|
||||
if (entryHeader.size != 0)
|
||||
_entryHeaders[entryHeader.name] = new ZfsEntryHeader(entryHeader);
|
||||
}
|
||||
|
||||
// Seek to the next block of headers
|
||||
stream->seek(nextOffset);
|
||||
} while (nextOffset != 0);
|
||||
}
|
||||
|
||||
Common::String ZfsArchive::readEntryName(Common::SeekableReadStream *stream) const {
|
||||
// Entry Names are at most 16 bytes and are null padded
|
||||
char buffer[16];
|
||||
stream->read(buffer, 16);
|
||||
|
||||
return Common::String(buffer);
|
||||
}
|
||||
|
||||
bool ZfsArchive::hasFile(const Common::Path &path) const {
|
||||
Common::String name = path.toString();
|
||||
return _entryHeaders.contains(name);
|
||||
}
|
||||
|
||||
int ZfsArchive::listMembers(Common::ArchiveMemberList &list) const {
|
||||
int matches = 0;
|
||||
|
||||
for (ZfsEntryHeaderMap::const_iterator it = _entryHeaders.begin(); it != _entryHeaders.end(); ++it) {
|
||||
list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(it->_value->name, *this)));
|
||||
matches++;
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
const Common::ArchiveMemberPtr ZfsArchive::getMember(const Common::Path &path) const {
|
||||
if (!hasFile(path))
|
||||
return Common::ArchiveMemberPtr();
|
||||
|
||||
return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(path, *this));
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *ZfsArchive::createReadStreamForMember(const Common::Path &path) const {
|
||||
Common::String name = path.toString();
|
||||
if (!_entryHeaders.contains(name)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZfsEntryHeader *entryHeader = _entryHeaders[name];
|
||||
|
||||
Common::File zfsArchive;
|
||||
zfsArchive.open(_fileName);
|
||||
zfsArchive.seek(entryHeader->offset);
|
||||
|
||||
// This *HAS* to be malloc (not new[]) because MemoryReadStream uses free() to free the memory
|
||||
byte *buffer = (byte *)malloc(entryHeader->size);
|
||||
zfsArchive.read(buffer, entryHeader->size);
|
||||
// Decrypt the data in place
|
||||
if (_header.xorKey[0] + _header.xorKey[1] + _header.xorKey[2] + _header.xorKey[3] != 0)
|
||||
unXor(buffer, entryHeader->size, _header.xorKey);
|
||||
|
||||
return new Common::MemoryReadStream(buffer, entryHeader->size, DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
void ZfsArchive::unXor(byte *buffer, uint32 length, const byte *xorKey) const {
|
||||
for (uint32 i = 0; i < length; ++i)
|
||||
buffer[i] ^= xorKey[i % 4];
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
124
engines/zvision/file/zfs_archive.h
Normal file
124
engines/zvision/file/zfs_archive.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_ZFS_ARCHIVE_H
|
||||
#define ZVISION_ZFS_ARCHIVE_H
|
||||
|
||||
#include "common/archive.h"
|
||||
#include "common/hashmap.h"
|
||||
#include "common/hash-str.h"
|
||||
|
||||
namespace Common {
|
||||
class String;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
struct ZfsHeader {
|
||||
uint32 magic;
|
||||
uint32 unknown1;
|
||||
uint32 maxNameLength;
|
||||
uint32 filesPerBlock;
|
||||
uint32 fileCount;
|
||||
uint8 xorKey[4];
|
||||
uint32 fileSectionOffset;
|
||||
};
|
||||
|
||||
struct ZfsEntryHeader {
|
||||
Common::String name;
|
||||
uint32 offset;
|
||||
uint32 id;
|
||||
uint32 size;
|
||||
uint32 time;
|
||||
uint32 unknown;
|
||||
};
|
||||
|
||||
typedef Common::HashMap<Common::String, ZfsEntryHeader *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ZfsEntryHeaderMap;
|
||||
|
||||
class ZfsArchive : public Common::Archive {
|
||||
public:
|
||||
ZfsArchive(const Common::Path &fileName);
|
||||
ZfsArchive(const Common::Path &fileName, Common::SeekableReadStream *stream);
|
||||
~ZfsArchive() override;
|
||||
|
||||
/**
|
||||
* Check if a member with the given name is present in the Archive.
|
||||
* Patterns are not allowed, as this is meant to be a quick File::exists()
|
||||
* replacement.
|
||||
*/
|
||||
bool hasFile(const Common::Path &path) const override;
|
||||
|
||||
/**
|
||||
* Add all members of the Archive to list.
|
||||
* Must only append to list, and not remove elements from it.
|
||||
*
|
||||
* @return The number of names added to list
|
||||
*/
|
||||
int listMembers(Common::ArchiveMemberList &list) const override;
|
||||
|
||||
/**
|
||||
* Returns a ArchiveMember representation of the given file.
|
||||
*/
|
||||
const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
|
||||
|
||||
/**
|
||||
* Create a stream bound to a member with the specified name in the
|
||||
* archive. If no member with this name exists, 0 is returned.
|
||||
*
|
||||
* @return The newly created input stream
|
||||
*/
|
||||
Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
|
||||
|
||||
private:
|
||||
const Common::Path _fileName;
|
||||
ZfsHeader _header;
|
||||
ZfsEntryHeaderMap _entryHeaders;
|
||||
|
||||
/**
|
||||
* Parses the zfs file into file entry headers that can be used later
|
||||
* to get the entry data.
|
||||
*
|
||||
* @param stream The contents of the zfs file
|
||||
*/
|
||||
void readHeaders(Common::SeekableReadStream *stream);
|
||||
|
||||
/**
|
||||
* Entry names are contained within a 16 byte block. This reads the block
|
||||
* and converts it the name to a Common::String
|
||||
*
|
||||
* @param stream The zfs file stream
|
||||
* @return The entry file name
|
||||
*/
|
||||
Common::String readEntryName(Common::SeekableReadStream *stream) const;
|
||||
|
||||
/**
|
||||
* ZFS file entries can be encrypted using XOR encoding. This method
|
||||
* decodes the buffer in place using the supplied xorKey.
|
||||
*
|
||||
* @param buffer The data to decode
|
||||
* @param length Length of buffer
|
||||
*/
|
||||
void unXor(byte *buffer, uint32 length, const byte *xorKey) const;
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user