/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, 0xwhose 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, 0xor (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, 0xwrite to the Free Software * Foundation, 0xInc., 0x51 Franklin Street, 0xFifth Floor, 0xBoston, 0xMA 02110-1301, 0xUSA. * */ #include "access/files.h" #include "access/amazon/amazon_resources.h" #include "access/access.h" namespace Access { FileManager::FileManager(AccessEngine *vm): _vm(vm) { switch (vm->getGameID()) { case GType_Amazon: _filenames = &Amazon::FILENAMES[0]; break; default: error("Unknown game"); } _fileNumber = -1; _stream = nullptr; } FileManager::~FileManager() { delete _stream; _file.close(); } byte *FileManager::loadFile(int fileNum, int subfile) { setAppended(fileNum); gotoAppended(subfile); return handleFile(); } byte *FileManager::loadFile(const Common::String &filename) { // Open the file openFile(filename); // Get a stream for the entire file delete _stream; _stream = _file.readStream(_file.size()); return handleFile(); } void FileManager::openFile(const Common::String &filename) { // Open up the file _fileNumber = -1; _file.close(); if (!_file.open(filename)) error("Could not open file - %s", filename.c_str()); _filesize = _file.size(); } void FileManager::loadScreen(int fileNum, int subfile) { setAppended(fileNum); gotoAppended(subfile); _vm->_screen->loadPalette(_stream); // Get the data for the screen, and copy it over byte *pSrc = handleFile(); Common::copy(pSrc, pSrc + _filesize, (byte *)_vm->_screen->getPixels()); delete[] pSrc; } void FileManager::loadScreen(const Common::String &filename) { // Open the file openFile(filename); // Get the palette _vm->_screen->loadPalette(&_file); // Get a stream for the remainder of the file delete _stream; _stream = _file.readStream(_file.size() - _file.pos()); // Get the data for the screen, and copy it over byte *pSrc = handleFile(); Common::copy(pSrc, pSrc + _filesize, (byte *)_vm->_screen->getPixels()); delete[] pSrc; } byte *FileManager::handleFile() { char header[3]; _stream->read(&header[0], 3); _stream->seek(-3, SEEK_CUR); bool isCompressed = !strncmp(header, "DBE", 3); // Get the data from the file or resource _filesize = _stream->size() - _stream->pos(); byte *data = new byte[_filesize]; _stream->read(data, _filesize); // If the data is compressed, uncompress it if (isCompressed) { byte *src = data; _filesize = decompressDBE(src, &data); delete[] src; } return data; } void FileManager::setAppended(int fileNum) { if (_fileNumber != fileNum) { _fileNumber = fileNum; _file.close(); if (!_file.open(_filenames[fileNum])) error("Could not open file %s", _filenames[fileNum]); // Read in the file index int count = _file.readUint16LE(); assert(count <= 100); _fileIndex.resize(count); for (int i = 0; i < count; ++i) _fileIndex[i] = _file.readUint32LE(); } } void FileManager::gotoAppended(int subfile) { uint32 offset = _fileIndex[subfile]; uint32 size = (subfile == (int)_fileIndex.size() - 1) ? _file.size() - offset : _fileIndex[subfile + 1] - offset; _file.seek(offset); delete _stream; _stream = _file.readStream(size); } } // End of namespace Access