diff options
Diffstat (limited to 'engines/toon/resource.cpp')
-rw-r--r-- | engines/toon/resource.cpp | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/engines/toon/resource.cpp b/engines/toon/resource.cpp new file mode 100644 index 0000000000..348aa45ae9 --- /dev/null +++ b/engines/toon/resource.cpp @@ -0,0 +1,215 @@ +/* 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. +* +* $URL$ +* $Id$ +* +*/ + +#include "toon/resource.h" +#include "common/file.h" +#include "toon/toon.h" + + +namespace Toon { + +void Resources::openPackage(Common::String fileName, bool preloadEntirePackage) { + debugC(1, kDebugResource, "openPackage(%s, %d)", fileName.c_str(), (preloadEntirePackage) ? 1 : 0); + + Common::File file; + bool opened = file.open(fileName); + + if (!opened) + return; + + + PakFile *pakFile = new PakFile(); + pakFile->open(&file, fileName, preloadEntirePackage); + + if (preloadEntirePackage) + file.close(); + + _pakFiles.push_back(pakFile); +} + +void Resources::closePackage(Common::String fileName) { + for (uint32 i = 0; i < _pakFiles.size(); i++) { + if (_pakFiles[i]->getPackName() == fileName) { + delete _pakFiles[i]; + _pakFiles.remove_at(i); + return; + } + } +} + +Resources::Resources(ToonEngine *vm) : _vm(vm) { + +} + +uint8 *Resources::getFileData(Common::String fileName, uint32 *fileSize) { + debugC(4, kDebugResource, "getFileData(%s, fileSize)", fileName.c_str()); + + // first try to find files outside of .pak + // some patched files have not been included in package. + if (Common::File::exists(fileName)) { + Common::File file; + bool opened = file.open(fileName); + if (!opened) + return 0; + + *fileSize = file.size(); + uint8 *memory = (uint8 *)new uint8[*fileSize]; + file.read(memory, *fileSize); + file.close(); + return memory; + } else { + for (uint32 i = 0; i < _pakFiles.size(); i++) { + uint32 locFileSize = 0; + uint8 *locFileData = 0; + + locFileData = _pakFiles[i]->getFileData(fileName, &locFileSize); + if (locFileData) { + *fileSize = locFileSize; + return locFileData; + } + } + return 0; + } +} + +Common::SeekableReadStream *Resources::openFile(Common::String fileName) { + debugC(1, kDebugResource, "openFile(%s)", fileName.c_str()); + + // first try to find files outside of .pak + // some patched files have not been included in package. + if (Common::File::exists(fileName)) { + Common::File *file = new Common::File(); + bool opened = file->open(fileName); + if (!opened) { + delete file; + return 0; + } + return file; + } else { + for (uint32 i = 0; i < _pakFiles.size(); i++) { + Common::SeekableReadStream *stream = 0; + stream = _pakFiles[i]->createReadStream(fileName); + if (stream) + return stream; + } + + return 0; + } +} +Common::SeekableReadStream *PakFile::createReadStream(Common::String fileName) { + debugC(1, kDebugResource, "createReadStream(%s)", fileName.c_str()); + + int32 offset = 0; + int32 size = 0; + for (uint32 i = 0; i < _numFiles; i++) { + if (fileName.compareToIgnoreCase(_files[i]._name) == 0) { + size = _files[i]._size; + offset = _files[i]._offset; + break; + } + } + if (!size) + return 0; + + if (_fileHandle) + return new Common::SeekableSubReadStream(_fileHandle, offset, offset + size); + else + return new Common::MemoryReadStream(_buffer + offset, size); +} + +uint8 *PakFile::getFileData(Common::String fileName, uint32 *fileSize) { + debugC(4, kDebugResource, "getFileData(%s, fileSize)", fileName.c_str()); + + for (uint32 i = 0; i < _numFiles; i++) { + if (fileName.compareToIgnoreCase(_files[i]._name) == 0) { + *fileSize = _files[i]._size; + return _buffer + _files[i]._offset; + } + } + + return 0; +} + +void PakFile::open(Common::SeekableReadStream *rs, Common::String packName, bool preloadEntirePackage) { + debugC(1, kDebugResource, "open(rs, %d)", (preloadEntirePackage) ? 1 : 0); + + char buffer[64]; + int32 currentPos = 0; + _numFiles = 0; + _packName = packName; + + while (1) { + rs->seek(currentPos); + rs->read(buffer, 64); + + int32 offset = READ_LE_UINT32(buffer); + char *name = buffer + 4; + + if (!*name) + break; + + int32 nameSize = strlen(name) + 1; + int32 nextOffset = READ_LE_UINT32(buffer + 4 + nameSize); + currentPos += 4 + nameSize; + + PakFile::File newFile; + strcpy(newFile._name, name); + newFile._offset = offset; + newFile._size = nextOffset - offset; + _numFiles++; + _files.push_back(newFile); + } + + if (preloadEntirePackage) { + _bufferSize = rs->size(); + _buffer = new uint8[_bufferSize]; + rs->seek(0); + rs->read(_buffer, _bufferSize); + } +} + +void PakFile::close() { + if (_buffer) { + delete[] _buffer; + } + + if (_fileHandle) { + _fileHandle->close(); + delete _fileHandle; + } +} + +PakFile::~PakFile() { + close(); +} + + +PakFile::PakFile() { + _fileHandle = 0; + _buffer = 0; + _bufferSize = 0; +} + +} // End of namespace Toon |