diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/gob/dataio.cpp | 673 | ||||
-rw-r--r-- | engines/gob/dataio.h | 125 | ||||
-rw-r--r-- | engines/gob/draw.cpp | 5 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 2 | ||||
-rw-r--r-- | engines/gob/init.cpp | 87 | ||||
-rw-r--r-- | engines/gob/inter_bargon.cpp | 4 | ||||
-rw-r--r-- | engines/gob/inter_playtoons.cpp | 18 | ||||
-rw-r--r-- | engines/gob/inter_v1.cpp | 48 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 31 | ||||
-rw-r--r-- | engines/gob/inter_v6.cpp | 10 | ||||
-rw-r--r-- | engines/gob/map_v1.cpp | 14 | ||||
-rw-r--r-- | engines/gob/resources.cpp | 21 | ||||
-rw-r--r-- | engines/gob/script.cpp | 25 | ||||
-rw-r--r-- | engines/gob/script.h | 2 | ||||
-rw-r--r-- | engines/gob/sound/cdrom.cpp | 2 | ||||
-rw-r--r-- | engines/gob/sound/cdrom.h | 4 | ||||
-rw-r--r-- | engines/gob/sound/sound.cpp | 29 | ||||
-rw-r--r-- | engines/gob/totfile.cpp | 4 | ||||
-rw-r--r-- | engines/gob/video.cpp | 4 | ||||
-rw-r--r-- | engines/gob/videoplayer.cpp | 4 |
20 files changed, 392 insertions, 720 deletions
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index 55ca3350af..e53d40754f 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -24,7 +24,8 @@ */ #include "common/endian.h" -#include "common/str.h" +#include "common/types.h" +#include "common/stream.h" #include "gob/gob.h" #include "gob/dataio.h" @@ -33,198 +34,91 @@ namespace Gob { -DataStream::DataStream(DataIO &io, int16 handle, uint32 dSize, bool dispose) { - _io = &io; - - _handle = handle; - _size = dSize; - _dispose = dispose; - - _data = 0; - _stream = 0; -} - -DataStream::DataStream(byte *buf, uint32 dSize, bool dispose) { - _data = buf; - _size = dSize; - _stream = new Common::MemoryReadStream(_data, _size); - _dispose = dispose; - - _io = 0; - _handle = -1; -} - -DataStream::~DataStream() { - delete _stream; - - if (_dispose) { - delete[] _data; - if ((_handle >= 0) && _io) - _io->closeData(_handle); - } -} - -int32 DataStream::pos() const { - if (_stream) - return _stream->pos(); - - int32 resPos = _io->getChunkPos(_handle); - if (resPos != -1) - return resPos; - - return _io->file_getHandle(_handle)->pos(); -} - -int32 DataStream::size() const { - if (_stream) - return _stream->size(); - - return _size; -} - -bool DataStream::seek(int32 offset, int whence) { - if (_stream) - return _stream->seek(offset, whence); - else if (!_io->isDataFileChunk(_handle)) - return _io->file_getHandle(_handle)->seek(offset, whence); - else { - _io->seekChunk(_handle, offset, whence); - return true; - } +DataIO::File::File() : size(0), offset(0), packed(false), archive(0) { } -bool DataStream::eos() const { - if (_stream) - return _stream->eos(); - - return pos() >= size(); // FIXME (eos definition change) +DataIO::File::File(const Common::String &n, uint32 s, uint32 o, bool p, Archive &a) : + name(n), size(s), offset(o), packed(p), archive(&a) { } -uint32 DataStream::read(void *dataPtr, uint32 dataSize) { - if (_stream) - return _stream->read(dataPtr, dataSize); - - if (!_io->isDataFileChunk(_handle)) - return _io->file_getHandle(_handle)->read((byte *)dataPtr, dataSize); - - byte *data = (byte *)dataPtr; - uint32 haveRead = 0; - while (dataSize > 0x3FFF) { - _io->readChunk(_handle, (byte *)data, 0x3FFF); - dataSize -= 0x3FFF; - data += 0x3FFF; - haveRead += 0x3FFF; - } - _io->readChunk(_handle, (byte *)data, dataSize); - - return haveRead + dataSize; -} -DataIO::DataIO(GobEngine *vm) : _vm(vm) { - for (int i = 0; i < MAX_DATA_FILES; i++) { - _dataFiles[i] = 0; - _numDataChunks[i] = 0; - _dataFileHandles[i] = -1; - } +DataIO::DataIO() { + // Reserve memory for the standard max amount of archives + _archives.reserve(kMaxArchives); + for (int i = 0; i < kMaxArchives; i++) + _archives.push_back(0); } DataIO::~DataIO() { - for (int i = 0; i < MAX_DATA_FILES; i++) { - if (_dataFiles[i]) - file_getHandle(_dataFileHandles[i])->close(); - delete[] _dataFiles[i]; - } -} + // Close all archives + for (Common::Array<Archive *>::iterator it = _archives.begin(); it != _archives.end(); ++it) { + if (!*it) + continue; -bool DataIO::isDataFileChunk(int16 handle) const { - return (handle >= 50) && (handle < 128); + closeArchive(**it); + delete *it; + } } -bool DataIO::isPacked(int16 handle) const { - if (!isDataFileChunk(handle)) - return false; +byte *DataIO::unpack(const byte *src, uint32 srcSize, int32 &size) { + size = READ_LE_UINT32(src); - return _chunk[getIndex(handle)]->packed != 0; -} - -int DataIO::getFile(int16 handle) const { - if (!isDataFileChunk(handle)) - return -1; - - return (handle - 50) / 10; -} - -int DataIO::getSlot(int16 handle) const { - if (!isDataFileChunk(handle)) - return -1; + byte *data = new byte[size]; - return (handle - 50) % 10; + Common::MemoryReadStream srcStream(src + 4, srcSize - 4); + unpack(srcStream, data, size); + return data; } -int DataIO::getIndex(int16 handle) const { - if (!isDataFileChunk(handle)) - return -1; +Common::SeekableReadStream *DataIO::unpack(Common::SeekableReadStream &src) { + uint32 size = src.readUint32LE(); - return getIndex(getFile(handle), getSlot(handle)); -} - -int DataIO::getIndex(int file, int slot) const { - return file * MAX_SLOT_COUNT + slot; -} + byte *data = (byte *) malloc(size); -int16 DataIO::getHandle(int file, int slot) const { - return file * 10 + slot + 50; + unpack(src, data, size); + return new Common::MemoryReadStream(data, size, DisposeAfterUse::YES); } -int32 DataIO::unpackData(byte *src, byte *dest) { - uint32 realSize; - uint32 counter; - uint16 cmd; - byte *tmpBuf; - int16 off; - byte len; - uint16 tmpIndex; - - tmpBuf = new byte[4114]; +void DataIO::unpack(Common::SeekableReadStream &src, byte *dest, uint32 size) { + byte *tmpBuf = new byte[4114]; assert(tmpBuf); - counter = realSize = READ_LE_UINT32(src); + uint32 counter = size; for (int i = 0; i < 4078; i++) tmpBuf[i] = 0x20; - tmpIndex = 4078; - - src += 4; + uint16 tmpIndex = 4078; - cmd = 0; + uint16 cmd = 0; while (1) { cmd >>= 1; - if ((cmd & 0x0100) == 0) { - cmd = *src | 0xFF00; - src++; - } + if ((cmd & 0x0100) == 0) + cmd = src.readByte() | 0xFF00; + if ((cmd & 1) != 0) { /* copy */ - *dest++ = *src; - tmpBuf[tmpIndex] = *src; - src++; + byte tmp = src.readByte(); + + *dest++ = tmp; + tmpBuf[tmpIndex] = tmp; + tmpIndex++; tmpIndex %= 4096; counter--; if (counter == 0) break; } else { /* copy string */ + byte tmp1 = src.readByte(); + byte tmp2 = src.readByte(); - off = *src++; - off |= (*src & 0xF0) << 4; - len = (*src & 0x0F) + 3; - src++; + int16 off = tmp1 | ((tmp2 & 0xF0) << 4); + byte len = (tmp2 & 0x0F) + 3; for (int i = 0; i < len; i++) { *dest++ = tmpBuf[(off + i) % 4096]; counter--; if (counter == 0) { delete[] tmpBuf; - return realSize; + return; } tmpBuf[tmpIndex] = tmpBuf[(off + i) % 4096]; tmpIndex++; @@ -233,390 +127,251 @@ int32 DataIO::unpackData(byte *src, byte *dest) { } } - delete[] tmpBuf; - return realSize; -} - -Common::File *DataIO::file_getHandle(int16 handle) { - return &_filesHandles[handle]; -} -const Common::File *DataIO::file_getHandle(int16 handle) const { - return &_filesHandles[handle]; + delete[] tmpBuf; } -int16 DataIO::file_open(const char *path) { - int16 i; - - for (i = 0; i < MAX_FILES; i++) { - if (!file_getHandle(i)->isOpen()) +bool DataIO::openArchive(Common::String name, bool base) { + // Look for a free archive slot + Archive **archive = 0; + int i = 0; + for (Common::Array<Archive *>::iterator it = _archives.begin(); it != _archives.end(); ++it, i++) { + if (!*it) { + archive = &*it; break; + } } - if (i == MAX_FILES) - return -1; - if (file_getHandle(i)->open(path)) - return i; + if (!archive) { + // No free slot, create a new one - return -1; -} - -int16 DataIO::getChunk(const char *chunkName) { - for (int16 file = 0; file < MAX_DATA_FILES; file++) { - if (_dataFiles[file] == 0) - return -1; + warning("DataIO::openArchive(): Need to increase archive count to %d", _archives.size() + 1); + _archives.push_back(0); - int16 slot; - for (slot = 0; slot < MAX_SLOT_COUNT; slot++) - if (_chunkPos[file * MAX_SLOT_COUNT + slot] == -1) - break; - - if (slot == MAX_SLOT_COUNT) { - warning("Chunk slots full"); - return -1; - } - - ChunkDesc *dataDesc = _dataFiles[file]; - for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { - if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) - continue; + Common::Array<Archive *>::iterator it = _archives.end(); + archive = &*(--it); + } - int index = getIndex(file, slot); + // Add extension if necessary + if (!name.contains('.')) + name += ".stk"; - _isCurrentSlot[index] = false; - _chunk [index] = dataDesc; - _chunkPos [index] = 0; + // Try to open + *archive = openArchive(name); + if (!*archive) + return false; - return getHandle(file, slot); - } - } - return -1; + (*archive)->base = base; + return true; } -char DataIO::freeChunk(int16 handle) { - if (isDataFileChunk(handle)) { - _chunkPos[getIndex(handle)] = -1; +DataIO::Archive *DataIO::openArchive(const Common::String &name) { + Archive *archive = new Archive; + if (!archive->file.open(name)) { + delete archive; return 0; } - return 1; -} - -int32 DataIO::readChunk(int16 handle, byte *buf, uint16 size) { - if (!isDataFileChunk(handle)) - return -2; - - int file = getFile(handle); - int slot = getSlot(handle); - int index = getIndex(file, slot); - _chunkPos[index] = CLIP<int32>(_chunkPos[index], 0, _chunk[index]->size); + archive->name = name; - if (!_isCurrentSlot[index]) { - for (int16 i = 0; i < MAX_SLOT_COUNT; i++) - _isCurrentSlot[file * MAX_SLOT_COUNT + i] = false; + uint16 fileCount = archive->file.readUint16LE(); + for (uint16 i = 0; i < fileCount; i++) { + File file; - int32 offset = _chunk[index]->offset + _chunkPos[index]; + char fileName[14]; - debugC(7, kDebugFileIO, "seek: %d, %d", _chunk[index]->offset, _chunkPos[index]); + archive->file.read(fileName, 13); + fileName[13] = '\0'; - file_getHandle(_dataFileHandles[file])->seek(offset, SEEK_SET); - } - - _isCurrentSlot[index] = true; - if ((_chunkPos[index] + size) > (int32) (_chunk[index]->size)) - size = _chunk[index]->size - _chunkPos[index]; - - file_getHandle(_dataFileHandles[file])->read(buf, size); - _chunkPos[index] += size; - return size; -} + file.size = archive->file.readUint32LE(); + file.offset = archive->file.readUint32LE(); + file.packed = archive->file.readByte() != 0; -int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) { - if (!isDataFileChunk(handle)) - return -1; - - int file = getFile(handle); - int slot = getSlot(handle); - int index = getIndex(file, slot); - - _isCurrentSlot[index] = false; - if (from == SEEK_SET) - _chunkPos[index] = pos; - else if (from == SEEK_CUR) - _chunkPos[index] += pos; - else if (from == SEEK_END) - _chunkPos[index] = _chunk[index]->size - pos; + // Replacing cyrillic characters + Util::replaceChar(fileName, (char) 0x85, 'E'); + Util::replaceChar(fileName, (char) 0x8A, 'K'); + Util::replaceChar(fileName, (char) 0x8E, 'O'); + Util::replaceChar(fileName, (char) 0x91, 'C'); + Util::replaceChar(fileName, (char) 0x92, 'T'); - return _chunkPos[index]; -} + file.name = fileName; -uint32 DataIO::getChunkPos(int16 handle) const { - if (!isDataFileChunk(handle)) - return 0xFFFFFFFF; + // Geisha use 0ot files, which are compressed TOT files without the packed byte set. + if (file.name.hasSuffix(".0OT")) { + file.name.setChar(file.name.size() - 3, 'T'); + file.packed = true; + } - int file = getFile(handle); - int slot = getSlot(handle); + file.archive = archive; + archive->files.setVal(file.name, file); + } - return _chunkPos[file * MAX_SLOT_COUNT + slot]; + return archive; } -int32 DataIO::getChunkSize(const char *chunkName, int32 &packSize) { - packSize = -1; - - for (int file = 0; file < MAX_DATA_FILES; file++) { - if (_dataFiles[file] == 0) - return -1; - - ChunkDesc *dataDesc = _dataFiles[file]; - for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { - if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) - continue; +bool DataIO::closeArchive(bool base) { + // Look for a matching archive and close it + for (int archive = _archives.size() - 1; archive >= 0; archive--) { + if (_archives[archive] && (_archives[archive]->base == base)) { + closeArchive(*_archives[archive]); + delete _archives[archive]; + _archives[archive] = 0; - if (dataDesc->packed == 0) - return dataDesc->size; - - for (int16 slot = 0; slot < MAX_SLOT_COUNT; slot++) - _isCurrentSlot[slot] = false; - - int32 realSize; - - file_getHandle(_dataFileHandles[file])->seek(dataDesc->offset, SEEK_SET); - realSize = file_getHandle(_dataFileHandles[file])->readUint32LE(); - packSize = dataDesc->size; - - return realSize; + return true; } } - return -1; -} -void DataIO::openDataFile(const char *src, bool itk) { - char path[128]; - - Common::strlcpy(path, src, 128); - if (!strchr(path, '.')) { - path[123] = 0; - strcat(path, ".stk"); - } - - int16 file; - for (file = 0; file < MAX_DATA_FILES; file++) - if (_dataFiles[file] == 0) - break; - - if (file == MAX_DATA_FILES) - error("DataIO::openDataFile(): Data file slots are full"); - - _dataFileHandles[file] = file_open(path); + return false; +} - if (_dataFileHandles[file] == -1) - error("DataIO::openDataFile(): Can't open data file \"%s\"", path); +bool DataIO::closeArchive(Archive &archive) { + archive.file.close(); - _dataFileItk [file] = itk; - _numDataChunks[file] = file_getHandle(_dataFileHandles[file])->readUint16LE(); + return true; +} - debugC(7, kDebugFileIO, "DataChunks: %d [for %s]", _numDataChunks[file], path); +bool DataIO::hasFile(const Common::String &name){ + // Look up the files in the opened archives + if (findFile(name)) + return true; - ChunkDesc *dataDesc = new ChunkDesc[_numDataChunks[file]]; - _dataFiles[file] = dataDesc; + // Else, look if a plain file that matches exists + return Common::File::exists(name); +} - for (int i = 0; i < _numDataChunks[file]; i++) { - file_getHandle(_dataFileHandles[file])->read(dataDesc[i].chunkName, 13); - dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE(); - dataDesc[i].offset = file_getHandle(_dataFileHandles[file])->readUint32LE(); - dataDesc[i].packed = file_getHandle(_dataFileHandles[file])->readByte(); +int32 DataIO::fileSize(const Common::String &name) { + // Try to find the file in the archives + File *file = findFile(name); + if (file) { + if (!file->packed) + return file->size; - // Replacing cyrillic characters - Util::replaceChar(dataDesc[i].chunkName, (char) 0x85, 'E'); - Util::replaceChar(dataDesc[i].chunkName, (char) 0x8A, 'K'); - Util::replaceChar(dataDesc[i].chunkName, (char) 0x8E, 'O'); - Util::replaceChar(dataDesc[i].chunkName, (char) 0x91, 'C'); - Util::replaceChar(dataDesc[i].chunkName, (char) 0x92, 'T'); + // Sanity checks + assert(file->size >= 4); + assert(file->archive); + assert(file->archive->file.isOpen()); - // Geisha use 0ot files, which are compressed TOT files without the packed byte set. - char *fakeTotPtr = strstr(dataDesc[i].chunkName, "0OT"); - if (fakeTotPtr != 0) { - strncpy(fakeTotPtr, "TOT", 3); - dataDesc[i].packed = 1; - } + // Read the full, unpacked size + file->archive->file.seek(file->offset); + return file->archive->file.readUint32LE(); } - for (int i = 0; i < _numDataChunks[file]; i++) - debugC(7, kDebugFileIO, "%d: %s %d", i, dataDesc[i].chunkName, dataDesc[i].size); + // Else, try to find a matching plain file + Common::File f; + if (!f.open(name)) + return -1; - for (int i = 0; i < MAX_SLOT_COUNT; i++) - _chunkPos[file * MAX_SLOT_COUNT + i] = -1; + return f.size(); } -void DataIO::closeDataFile(bool itk) { - for (int file = MAX_DATA_FILES - 1; file >= 0; file--) { - if (_dataFiles[file] && (_dataFileItk[file] == itk)) { - delete[] _dataFiles[file]; - _dataFiles[file] = 0; - file_getHandle(_dataFileHandles[file])->close(); - return; - } +Common::SeekableReadStream *DataIO::getFile(const Common::String &name) { + // Try to open the file in the archives + File *file = findFile(name); + if (file) { + Common::SeekableReadStream *data = getFile(*file); + if (data) + return data; } -} - -byte *DataIO::getUnpackedData(const char *name) { - int32 realSize; - int32 packSize = -1; - realSize = getChunkSize(name, packSize); - - if ((packSize == -1) || (realSize == -1)) - return 0; - - int16 chunk = getChunk(name); - if (chunk == -1) + // Else, try to open a matching plain file + Common::File f; + if (!f.open(name)) return 0; - byte *unpackBuf = new byte[realSize]; - assert(unpackBuf); - - byte *packBuf = new byte[packSize]; - assert(packBuf); - - int32 sizeLeft = packSize; - byte *ptr = packBuf; - while (sizeLeft > 0x4000) { - readChunk(chunk, ptr, 0x4000); - sizeLeft -= 0x4000; - ptr += 0x4000; - } - readChunk(chunk, ptr, sizeLeft); - freeChunk(chunk); - unpackData(packBuf, unpackBuf); - - delete[] packBuf; - return unpackBuf; -} - -void DataIO::closeData(int16 handle) { - if (freeChunk(handle) != 0) - file_getHandle(handle)->close(); + return f.readStream(f.size()); } -int16 DataIO::openData(const char *path) { - int16 handle = getChunk(path); - if (handle >= 0) - return handle; - - return file_open(path); -} - -bool DataIO::existData(const char *path) { - if (!path || (path[0] == '\0')) - return false; +byte *DataIO::getFile(const Common::String &name, int32 &size) { + // Try to open the file in the archives + File *file = findFile(name); + if (file) { + byte *data = getFile(*file, size); + if (data) + return data; + } - int16 handle = openData(path); - if (handle < 0) - return false; + // Else, try to open a matching plain file + Common::File f; + if (!f.open(name)) + return 0; - closeData(handle); - return true; -} + size = f.size(); -DataStream *DataIO::openAsStream(int16 handle, bool dispose) { - uint32 curPos = getPos(handle); - seekData(handle, 0, SEEK_END); - uint32 size = getPos(handle); - seekData(handle, curPos, SEEK_SET); + byte *data = new byte[size]; + if (f.read(data, size) != ((uint32) size)) { + delete[] data; + return 0; + } - return new DataStream(*this, handle, size, dispose); + return 0; } -uint32 DataIO::getPos(int16 handle) { - uint32 resPos = getChunkPos(handle); - if (resPos != 0xFFFFFFFF) - return resPos; - - return file_getHandle(handle)->pos(); -} +DataIO::File *DataIO::findFile(const Common::String &name) { + for (int i = _archives.size() - 1; i >= 0; i--) { + Archive *archive = _archives[i]; + if (!archive) + // Empty slot + continue; -void DataIO::seekData(int16 handle, int32 pos, int16 from) { - int32 resPos = seekChunk(handle, pos, from); - if (resPos != -1) - return; + // Look up the file in the file map + FileMap::iterator file = archive->files.find(name); + if (file != archive->files.end()) + return &file->_value; + } - file_getHandle(handle)->seek(pos, from); + return 0; } -int32 DataIO::readData(int16 handle, byte *buf, uint16 size) { - int16 res = readChunk(handle, buf, size); - if (res >= 0) - return res; +Common::SeekableReadStream *DataIO::getFile(File &file) { + if (!file.archive) + return 0; - return file_getHandle(handle)->read(buf, size); -} + if (!file.archive->file.isOpen()) + return 0; -int32 DataIO::getDataSize(const char *name) { - char buf[128]; - int32 chunkSize; - int32 packSize = -1; + if (!file.archive->file.seek(file.offset)) + return 0; - Common::strlcpy(buf, name, 128); + Common::SeekableReadStream *rawData = file.archive->file.readStream(file.size); + if (!rawData) + return 0; - chunkSize = getChunkSize(buf, packSize); - if (chunkSize >= 0) - return chunkSize; + if (!file.packed) + return rawData; - Common::File file; - if (!file.open(buf)) - error("DataIO::getDataSize(): Can't find data \"%s\"", name); + Common::SeekableReadStream *unpackedData = unpack(*rawData); - chunkSize = file.size(); - file.close(); + delete rawData; - return chunkSize; + return unpackedData; } -byte *DataIO::getData(const char *path) { - byte *data = getUnpackedData(path); - if (data) - return data; - - int32 size = getDataSize(path); - - data = new byte[size]; - assert(data); +byte *DataIO::getFile(File &file, int32 &size) { + if (!file.archive) + return 0; - int16 handle = openData(path); + if (!file.archive->file.isOpen()) + return 0; - byte *ptr = data; - while (size > 0x4000) { - readData(handle, ptr, 0x4000); - size -= 0x4000; - ptr += 0x4000; - } - readData(handle, ptr, size); - closeData(handle); - return data; -} + if (!file.archive->file.seek(file.offset)) + return 0; -DataStream *DataIO::getDataStream(const char *path) { - if (!existData(path)) - return 0; + size = file.size; - int16 handle = openData(path); - if (handle < 0) + byte *rawData = new byte[file.size]; + if (file.archive->file.read(rawData, file.size) != file.size) { + delete[] rawData; return 0; + } - if (isDataFileChunk(handle) && isPacked(handle)) { - // It's a packed chunk in the data files, packed, - // so we have to read it in completely and unpack it - - closeData(handle); + if (!file.packed) + return rawData; - uint32 size = getDataSize(path); - byte *data = getData(path); + byte *unpackedData = unpack(rawData, file.size, size); - return new DataStream(data, size); + delete[] rawData; - } else - // Otherwise, we can just return a stream - return openAsStream(handle, true); + return unpackedData; } } // End of namespace Gob diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h index 6a86667e1b..e18ab16803 100644 --- a/engines/gob/dataio.h +++ b/engines/gob/dataio.h @@ -27,113 +27,74 @@ #define GOB_DATAIO_H #include "common/endian.h" +#include "common/str.h" +#include "common/hashmap.h" +#include "common/array.h" #include "common/file.h" -namespace Gob { - -#define MAX_FILES 30 -#define MAX_DATA_FILES 8 -#define MAX_SLOT_COUNT 8 - -class DataIO; - -class DataStream : public Common::SeekableReadStream { -public: - DataStream(DataIO &io, int16 handle, uint32 dSize, bool dispose = false); - DataStream(byte *buf, uint32 dSize, bool dispose = true); - virtual ~DataStream(); - - virtual int32 pos() const; - virtual int32 size() const; +namespace Common { + class SeekableReadStream; +} - virtual bool seek(int32 offset, int whence = SEEK_SET); - - virtual bool eos() const; - - virtual uint32 read(void *dataPtr, uint32 dataSize); - -private: - DataIO *_io; - int16 _handle; - uint32 _size; - byte *_data; - bool _dispose; - Common::MemoryReadStream *_stream; -}; +namespace Gob { class DataIO { public: - struct ChunkDesc { - char chunkName[13]; - uint32 size; - uint32 offset; - byte packed; - ChunkDesc() : size(0), offset(0), packed(0) { chunkName[0] = 0; } - }; - - int32 unpackData(byte *src, byte *dest); - - void openDataFile(const char *src, bool itk = 0); - void closeDataFile(bool itk = 0); + DataIO(); + ~DataIO(); - byte *getUnpackedData(const char *name); + bool openArchive(Common::String name, bool base); + bool closeArchive(bool base); - void closeData(int16 handle); - int16 openData(const char *path); - bool existData(const char *path); + bool hasFile(const Common::String &name); - DataStream *openAsStream(int16 handle, bool dispose = false); + int32 fileSize(const Common::String &name); - int32 getDataSize(const char *name); - byte *getData(const char *path); - DataStream *getDataStream(const char *path); + Common::SeekableReadStream *getFile(const Common::String &name); + byte *getFile(const Common::String &name, int32 &size); - DataIO(class GobEngine *vm); - ~DataIO(); + static byte *unpack(const byte *src, uint32 srcSize, int32 &size); + static Common::SeekableReadStream *unpack(Common::SeekableReadStream &src); -protected: - Common::File _filesHandles[MAX_FILES]; +private: + static const int kMaxArchives = 8; - ChunkDesc *_dataFiles [MAX_DATA_FILES]; - uint16 _numDataChunks [MAX_DATA_FILES]; - int16 _dataFileHandles[MAX_DATA_FILES]; - bool _dataFileItk [MAX_DATA_FILES]; + struct Archive; - ChunkDesc *_chunk [MAX_SLOT_COUNT * MAX_DATA_FILES]; - int32 _chunkPos [MAX_SLOT_COUNT * MAX_DATA_FILES]; - bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES]; + struct File { + Common::String name; + uint32 size; + uint32 offset; + bool packed; - class GobEngine *_vm; + Archive *archive; - bool isDataFileChunk(int16 handle) const; - bool isPacked (int16 handle) const; + File(); + File(const Common::String &n, uint32 s, uint32 o, bool p, Archive &a); + }; - int getFile (int16 handle) const; - int getSlot (int16 handle) const; - int getIndex(int16 handle) const; + typedef Common::HashMap<Common::String, File, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap; - int getIndex (int file, int slot) const; - int16 getHandle(int file, int slot) const; + struct Archive { + Common::String name; + Common::File file; - int16 file_open(const char *path); - Common::File *file_getHandle(int16 handle); - const Common::File *file_getHandle(int16 handle) const; + FileMap files; - int16 getChunk(const char *chunkName); - char freeChunk(int16 handle); - int32 readChunk(int16 handle, byte *buf, uint16 size); - int16 seekChunk(int16 handle, int32 pos, int16 from); + bool base; + }; - uint32 getChunkPos(int16 handle) const; + Common::Array<Archive *> _archives; - int32 getChunkSize(const char *chunkName, int32 &packSize); + Archive *openArchive(const Common::String &name); + bool closeArchive(Archive &archive); - uint32 getPos(int16 handle); - void seekData(int16 handle, int32 pos, int16 from); + File *findFile(const Common::String &name); - int32 readData(int16 handle, byte *buf, uint16 size); + Common::SeekableReadStream *getFile(File &file); + byte *getFile(File &file, int32 &size); - friend class DataStream; + static void unpack(Common::SeekableReadStream &src, byte *dest, uint32 size); }; } // End of namespace Gob diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index bb357168b7..ae1bbd4e8e 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -639,10 +639,11 @@ void Draw::wobble(Surface &surfDesc) { } Font *Draw::loadFont(const char *path) const { - if (!_vm->_dataIO->existData(path)) + if (!_vm->_dataIO->hasFile(path)) return 0; - byte *data = _vm->_dataIO->getData(path); + int32 size; + byte *data = _vm->_dataIO->getFile(path, size); return new Font(data); } diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index a1d3b1a61d..4906b8f117 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -370,7 +370,7 @@ bool GobEngine::initGameParts() { _global = new Global(this); _util = new Util(this); - _dataIO = new DataIO(this); + _dataIO = new DataIO(); _palAnim = new PalAnim(this); _vidPlayer = new VideoPlayer(this); _sound = new Sound(this); diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 5c59a5692f..fa209c317f 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -57,7 +57,7 @@ void Init::cleanup() { _vm->_sound->speakerOff(); _vm->_sound->blasterStop(0); - _vm->_dataIO->closeDataFile(); + _vm->_dataIO->closeArchive(true); } void Init::doDemo() { @@ -81,17 +81,12 @@ void Init::doDemo() { } void Init::initGame() { - byte *infBuf; - char *infPtr; - char *infEnd; - char buffer[128]; - initVideo(); updateConfig(); if (!_vm->isDemo()) { - if (_vm->_dataIO->existData(_vm->_startStk.c_str())) - _vm->_dataIO->openDataFile(_vm->_startStk.c_str()); + if (_vm->_dataIO->hasFile(_vm->_startStk)) + _vm->_dataIO->openArchive(_vm->_startStk, true); } _vm->_util->initInput(); @@ -126,37 +121,31 @@ void Init::initGame() { return; } - if (!_vm->_dataIO->existData("intro.inf")) { + Common::SeekableReadStream *infFile = _vm->_dataIO->getFile("intro.inf"); + if (!infFile) { for (int i = 0; i < 4; i++) _vm->_draw->loadFont(i, _fontNames[i]); } else { - infBuf = _vm->_dataIO->getData("intro.inf"); - infPtr = (char *)infBuf; - - infEnd = (char *)(infBuf + _vm->_dataIO->getDataSize("intro.inf")); - - for (int i = 0; i < 8; i++, infPtr++) { - int j; - - for (j = 0; infPtr < infEnd && *infPtr >= ' '; j++, infPtr++) - buffer[j] = *infPtr; - buffer[j] = 0; - strcat(buffer, ".let"); - - _vm->_draw->loadFont(i, buffer); + for (int i = 0; i < 8; i++) { + if (infFile->eos()) + break; - if ((infPtr + 1) >= infEnd) + Common::String font = infFile->readLine(); + if (infFile->eos() && font.empty()) break; - infPtr++; + font += ".let"; + + _vm->_draw->loadFont(i, font.c_str()); } - delete[] infBuf; + + delete infFile; } - if (_vm->_dataIO->existData(_vm->_startTot.c_str())) { + if (_vm->_dataIO->hasFile(_vm->_startTot)) { _vm->_inter->allocateVars(Script::getVariablesCount(_vm->_startTot.c_str(), _vm)); strcpy(_vm->_game->_curTotFile, _vm->_startTot.c_str()); @@ -165,7 +154,7 @@ void Init::initGame() { _vm->_sound->cdLoadLIC("gob.lic"); // Search for a Coktel logo animation or image to display - if (_vm->_dataIO->existData("coktel.imd")) { + if (_vm->_dataIO->hasFile("coktel.imd")) { _vm->_draw->initScreen(); _vm->_draw->_cursorIndex = -1; @@ -179,26 +168,28 @@ void Init::initGame() { } _vm->_draw->closeScreen(); - } else if (_vm->_dataIO->existData("coktel.clt")) { - _vm->_draw->initScreen(); - _vm->_util->clearPalette(); - - DataStream *stream = _vm->_dataIO->getDataStream("coktel.clt"); - stream->read((byte *)_vm->_draw->_vgaPalette, 768); - delete stream; - - if (_vm->_dataIO->existData("coktel.ims")) { - byte *sprBuf; - - sprBuf = _vm->_dataIO->getData("coktel.ims"); - _vm->_video->drawPackedSprite(sprBuf, 320, 200, 0, 0, 0, - *_vm->_draw->_frontSurface); - _vm->_palAnim->fade(_palDesc, 0, 0); - _vm->_util->delay(500); - - delete[] sprBuf; + } else if (_vm->_dataIO->hasFile("coktel.clt")) { + Common::SeekableReadStream *stream = _vm->_dataIO->getFile("coktel.clt"); + if (stream) { + _vm->_draw->initScreen(); + _vm->_util->clearPalette(); + + stream->read((byte *)_vm->_draw->_vgaPalette, 768); + delete stream; + + int32 size; + byte *sprite = _vm->_dataIO->getFile("coktel.ims", size); + if (sprite) { + _vm->_video->drawPackedSprite(sprite, 320, 200, 0, 0, 0, + *_vm->_draw->_frontSurface); + _vm->_palAnim->fade(_palDesc, 0, 0); + _vm->_util->delay(500); + + delete[] sprite; + } + + _vm->_draw->closeScreen(); } - _vm->_draw->closeScreen(); } _vm->_game->start(); @@ -209,7 +200,7 @@ void Init::initGame() { } delete _palDesc; - _vm->_dataIO->closeDataFile(); + _vm->_dataIO->closeArchive(true); _vm->_video->initPrimary(-1); cleanup(); } diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index 3afb70d6c0..5ed24c614e 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -175,10 +175,12 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { static const char *sndFiles[] = {"1INTROIV.snd", "2INTROIV.snd"}; static const char *palFiles[] = {"2ou2.clt", "2ou3.clt", "2ou4.clt", "2ou5.clt"}; + int32 size; + for (int i = 0; i < 2; i++) _vm->_sound->sampleLoad(&samples[i], SOUND_SND, sndFiles[i]); for (int i = 0; i < 4; i++) - palettes[i] = _vm->_dataIO->getData(palFiles[i]); + palettes[i] = _vm->_dataIO->getFile(palFiles[i], size); palBak = _vm->_global->_pPaletteDesc->vgaPal; _vm->_sound->blasterPlayComposition(comp, 0, samples, 2); diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp index 050bbce132..05032d712c 100644 --- a/engines/gob/inter_playtoons.cpp +++ b/engines/gob/inter_playtoons.cpp @@ -246,10 +246,10 @@ bool Inter_Playtoons::oPlaytoons_checkData(OpFuncParams ¶ms) { mode = _vm->_saveLoad->getSaveMode(file); if (mode == SaveLoad::kSaveModeNone) { - if (_vm->_dataIO->existData(file)) - size = _vm->_dataIO->getDataSize(file); - else + size = _vm->_dataIO->fileSize(file); + if (size == -1) warning("File \"%s\" not found", file); + } else if (mode == SaveLoad::kSaveModeSave) size = _vm->_saveLoad->getSize(file); else if (mode == SaveLoad::kSaveModeExists) @@ -272,7 +272,6 @@ bool Inter_Playtoons::oPlaytoons_readData(OpFuncParams ¶ms) { int32 size; int32 offset; uint16 dataVar; - int16 handle; byte *buf; SaveLoad::SaveMode mode; @@ -329,13 +328,10 @@ bool Inter_Playtoons::oPlaytoons_readData(OpFuncParams ¶ms) { } WRITE_VAR(1, 1); - handle = _vm->_dataIO->openData(file); - - if (handle < 0) + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(file); + if (!stream) return false; - DataStream *stream = _vm->_dataIO->openAsStream(handle, true); - _vm->_draw->animateCursor(4); if (offset < 0) stream->seek(offset + 1, SEEK_END); @@ -435,9 +431,9 @@ void Inter_Playtoons::oPlaytoons_openItk() { // Workaround for Bambou : In the script, the path is hardcoded (!!) if ((backSlash = strrchr(fileName, '\\'))) { debugC(2, kDebugFileIO, "Opening ITK file \"%s\" instead of \"%s\"", backSlash + 1, fileName); - _vm->_dataIO->openDataFile(backSlash + 1, true); + _vm->_dataIO->openArchive(backSlash + 1, false); } else - _vm->_dataIO->openDataFile(fileName, true); + _vm->_dataIO->openArchive(fileName, false); // All the other checks are meant to verify (if not found at the first try) // if the file is present on the CD or not. As everything is supposed to // be copied, those checks are skipped diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 6dab8161d0..fdcee310c2 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1630,18 +1630,17 @@ bool Inter_v1::o1_getFreeMem(OpFuncParams ¶ms) { } bool Inter_v1::o1_checkData(OpFuncParams ¶ms) { - int16 handle; int16 varOff; _vm->_game->_script->evalExpr(0); varOff = _vm->_game->_script->readVarIndex(); - handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr()); - WRITE_VAR_OFFSET(varOff, handle); - if (handle >= 0) - _vm->_dataIO->closeData(handle); - else + if (!_vm->_dataIO->hasFile(_vm->_game->_script->getResultStr())) { warning("File \"%s\" not found", _vm->_game->_script->getResultStr()); + WRITE_VAR_OFFSET(varOff, -1); + } else + WRITE_VAR_OFFSET(varOff, 50); // "handle" between 50 and 128 = in archive + return false; } @@ -1767,7 +1766,6 @@ bool Inter_v1::o1_readData(OpFuncParams ¶ms) { int16 size; int16 dataVar; int16 offset; - int16 handle; _vm->_game->_script->evalExpr(0); dataVar = _vm->_game->_script->readVarIndex(); @@ -1776,26 +1774,26 @@ bool Inter_v1::o1_readData(OpFuncParams ¶ms) { retSize = 0; WRITE_VAR(1, 1); - handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr()); - if (handle >= 0) { - DataStream *stream = _vm->_dataIO->openAsStream(handle, true); - _vm->_draw->animateCursor(4); - if (offset < 0) - stream->seek(offset + 1, SEEK_END); - else - stream->seek(offset); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_vm->_game->_script->getResultStr()); + if (!stream) + return false; - if (((dataVar >> 2) == 59) && (size == 4)) - WRITE_VAR(59, stream->readUint32LE()); - else - retSize = stream->read((byte *)_variables->getAddressOff8(dataVar), size); + _vm->_draw->animateCursor(4); + if (offset < 0) + stream->seek(offset + 1, SEEK_END); + else + stream->seek(offset); - if (retSize == size) - WRITE_VAR(1, 0); + if (((dataVar >> 2) == 59) && (size == 4)) + WRITE_VAR(59, stream->readUint32LE()); + else + retSize = stream->read((byte *)_variables->getAddressOff8(dataVar), size); - delete stream; - } + if (retSize == size) + WRITE_VAR(1, 0); + + delete stream; return false; } @@ -1824,9 +1822,9 @@ bool Inter_v1::o1_manageDataFile(OpFuncParams ¶ms) { _vm->_game->_script->evalExpr(0); if (_vm->_game->_script->getResultStr()[0] != 0) - _vm->_dataIO->openDataFile(_vm->_game->_script->getResultStr()); + _vm->_dataIO->openArchive(_vm->_game->_script->getResultStr(), true); else - _vm->_dataIO->closeDataFile(); + _vm->_dataIO->closeArchive(true); return false; } diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 2cb430ff9b..d8d36d7a41 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1035,11 +1035,11 @@ void Inter_v2::o2_openItk() { if (!strchr(fileName, '.')) strcat(fileName, ".ITK"); - _vm->_dataIO->openDataFile(fileName, true); + _vm->_dataIO->openArchive(fileName, false); } void Inter_v2::o2_closeItk() { - _vm->_dataIO->closeDataFile(true); + _vm->_dataIO->closeArchive(false); } void Inter_v2::o2_setImdFrontSurf() { @@ -1292,7 +1292,6 @@ bool Inter_v2::o2_getFreeMem(OpFuncParams ¶ms) { } bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { - int16 handle; int16 varOff; int32 size; SaveLoad::SaveMode mode; @@ -1301,7 +1300,6 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { varOff = _vm->_game->_script->readVarIndex(); size = -1; - handle = 1; char *file = _vm->_game->_script->getResultStr(); @@ -1313,9 +1311,8 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { mode = _vm->_saveLoad->getSaveMode(file); if (mode == SaveLoad::kSaveModeNone) { - if (_vm->_dataIO->existData(file)) - size = _vm->_dataIO->getDataSize(file); - else + size = _vm->_dataIO->fileSize(file); + if (size == -1) warning("File \"%s\" not found", file); } else if (mode == SaveLoad::kSaveModeSave) @@ -1323,13 +1320,10 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { else if (mode == SaveLoad::kSaveModeExists) size = 23; - if (size == -1) - handle = -1; - debugC(2, kDebugFileIO, "Requested size of file \"%s\": %d", file, size); - WRITE_VAR_OFFSET(varOff, handle); + WRITE_VAR_OFFSET(varOff, (size == -1) ? -1 : 50); WRITE_VAR(16, (uint32) size); return false; @@ -1340,7 +1334,6 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) { int32 size; int32 offset; int16 dataVar; - int16 handle; byte *buf; SaveLoad::SaveMode mode; @@ -1391,13 +1384,10 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) { } WRITE_VAR(1, 1); - handle = _vm->_dataIO->openData(file); - - if (handle < 0) + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(file); + if (!file) return false; - DataStream *stream = _vm->_dataIO->openAsStream(handle, true); - _vm->_draw->animateCursor(4); if (offset < 0) stream->seek(offset + 1, SEEK_END); @@ -1512,16 +1502,13 @@ void Inter_v2::o2_handleGoblins(OpGobParams ¶ms) { } int16 Inter_v2::loadSound(int16 search) { - byte *dataPtr; int16 id; int16 slot; uint16 slotIdMask; - uint32 dataSize; SoundType type; type = SOUND_SND; slotIdMask = 0; - dataSize = 0; if (!search) { slot = _vm->_game->_script->readValExpr(); @@ -1567,8 +1554,8 @@ int16 Inter_v2::loadSound(int16 search) { else strcat(sndfile, ".SND"); - dataPtr = _vm->_dataIO->getData(sndfile); - dataSize = _vm->_dataIO->getDataSize(sndfile); + int32 dataSize; + byte *dataPtr = _vm->_dataIO->getFile(sndfile, dataSize); if (!dataPtr) return 0; diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp index e1eff279b5..b6884c6fbe 100644 --- a/engines/gob/inter_v6.cpp +++ b/engines/gob/inter_v6.cpp @@ -191,16 +191,16 @@ void Inter_v6::o6_openItk() { if (!strchr(fileName, '.')) strcat(fileName, ".ITK"); - _vm->_dataIO->openDataFile(fileName, true); + _vm->_dataIO->openArchive(fileName, false); // WORKAROUND: The CD number detection in Urban Runner is quite daft // (it checks CD1.ITK - CD4.ITK and the first that's found determines // the CD number), while its NO_CD modus wants everything in CD1.ITK. // So we just open the other ITKs, too. if (_vm->_global->_noCd && !scumm_stricmp(fileName, "CD1.ITK")) { - _vm->_dataIO->openDataFile("CD2.ITK", true); - _vm->_dataIO->openDataFile("CD3.ITK", true); - _vm->_dataIO->openDataFile("CD4.ITK", true); + _vm->_dataIO->openArchive("CD2.ITK", false); + _vm->_dataIO->openArchive("CD3.ITK", false); + _vm->_dataIO->openArchive("CD4.ITK", false); } } @@ -439,7 +439,7 @@ void Inter_v6::probe16bitMusic(char *fileName) { fileName[len - 1] = 'V'; - if (_vm->_dataIO->existData(fileName)) + if (_vm->_dataIO->hasFile(fileName)) return; fileName[len - 1] = '8'; diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp index aa6603fd55..3df1cb8512 100644 --- a/engines/gob/map_v1.cpp +++ b/engines/gob/map_v1.cpp @@ -75,13 +75,13 @@ void Map_v1::loadMapObjects(const char *avjFile) { strcpy(avoName, _sourceFile); strcat(avoName, ".avo"); - if (_vm->_dataIO->existData(avoName)) { - _loadFromAvo = true; - dataBuf = _vm->_dataIO->getData(avoName); - } else { + int32 size; + dataBuf = _vm->_dataIO->getFile(avoName, size); + if (!dataBuf) { + dataBuf = _vm->_dataIO->getFile(avjFile, size); _loadFromAvo = false; - dataBuf = _vm->_dataIO->getData(avjFile); - } + } else + _loadFromAvo = true; Common::MemoryReadStream mapData(dataBuf, 4294967295U); @@ -165,7 +165,7 @@ void Map_v1::loadSounds(Common::SeekableReadStream &data) { _vm->_sound->sampleLoad(&_vm->_goblin->_soundData[14], SOUND_SND, "diamant1.snd"); for (int i = 0; i < count; i++) { - if (!_vm->_dataIO->existData(sndNames[i])) + if (!_vm->_dataIO->hasFile(sndNames[i])) continue; _vm->_sound->sampleLoad(&_vm->_goblin->_soundData[i], SOUND_SND, sndNames[i]); diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp index 8241821039..b5b3d7aaa2 100644 --- a/engines/gob/resources.cpp +++ b/engines/gob/resources.cpp @@ -293,7 +293,7 @@ bool Resources::loadTOTResourceTable() { bool Resources::loadEXTResourceTable() { _extResourceTable = new EXTResourceTable; - DataStream *stream = _vm->_dataIO->getDataStream(_extFile.c_str()); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_extFile); if (!stream) return false; @@ -396,7 +396,7 @@ bool Resources::loadIMFile() { imFile += num; - DataStream *stream = _vm->_dataIO->getDataStream(imFile.c_str()); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(imFile); if (!stream) return true; @@ -431,7 +431,7 @@ bool Resources::loadEXFile() { _exFile = "commun.ex"; _exFile += totProps.exFileNumber + '0'; - if (!_vm->_dataIO->existData(_exFile.c_str())) { + if (!_vm->_dataIO->hasFile(_exFile)) { _exFile.clear(); return true; } @@ -473,7 +473,7 @@ Common::String Resources::getLocTextFile(const Common::String &fileBase, break; } - if (!_vm->_dataIO->existData(locTextFile.c_str())) + if (!_vm->_dataIO->hasFile(locTextFile)) locTextFile.clear(); return locTextFile; @@ -525,8 +525,7 @@ byte *Resources::loadTOTLocTexts(const Common::String &fileBase, int32 &size) { if (locTextFile.empty()) return 0; - size = _vm->_dataIO->getDataSize(locTextFile.c_str()); - return _vm->_dataIO->getData(locTextFile.c_str()); + return _vm->_dataIO->getFile(locTextFile, size); } Resource *Resources::getResource(uint16 id, int16 *width, int16 *height) const { @@ -682,10 +681,10 @@ Resource *Resources::getEXTResource(uint16 id) const { if (extItem.packed) { byte *packedData = data; - size = READ_LE_UINT32(packedData); - data = new byte[size]; + int32 unpackSize; + data = _vm->_dataIO->unpack(packedData, size, unpackSize); - _vm->_dataIO->unpackData(packedData, data); + size = unpackSize; delete[] packedData; } @@ -724,7 +723,7 @@ byte *Resources::getIMData(TOTResourceItem &totItem) const { } byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { - DataStream *stream = _vm->_dataIO->getDataStream(_extFile.c_str()); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_extFile); if (!stream) return 0; @@ -745,7 +744,7 @@ byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { } byte *Resources::getEXData(EXTResourceItem &extItem, uint32 size) const { - DataStream *stream = _vm->_dataIO->getDataStream(_exFile.c_str()); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_exFile); if (!stream) return 0; diff --git a/engines/gob/script.cpp b/engines/gob/script.cpp index 339199c9b1..0b0fcd4cda 100644 --- a/engines/gob/script.cpp +++ b/engines/gob/script.cpp @@ -43,7 +43,7 @@ Script::Script(GobEngine *vm) : _vm(vm) { _totPtr = 0; _totSize = 0; - _lomHandle = -1; + _lom = 0; memset(&_totProperties, 0, sizeof(TOTFile::Properties)); } @@ -380,20 +380,16 @@ bool Script::loadTOT(const Common::String &fileName) { bool Script::loadLOM(const Common::String &fileName) { warning("Stub: Script::loadLOM(%s)", _totFile.c_str()); - _lomHandle = _vm->_dataIO->openData(_totFile.c_str()); - if (_lomHandle < 0) + _lom = _vm->_dataIO->getFile(_totFile); + if (!_lom) return false; - DataStream *stream = _vm->_dataIO->openAsStream(_lomHandle); - - stream->seek(48); - _totSize = stream->readUint32LE(); - stream->seek(0); + _lom->seek(48); + _totSize = _lom->readUint32LE(); + _lom->seek(0); _totData = new byte[_totSize]; - stream->read(_totData, _totSize); - - delete stream; + _lom->read(_totData, _totSize); return false; } @@ -403,8 +399,8 @@ void Script::unload() { } void Script::unloadTOT() { - if (_lomHandle >= 0) - _vm->_dataIO->closeData(_lomHandle); + delete _lom; + _lom = 0; // Unwind the call stack while (!_callStack.empty()) @@ -415,7 +411,6 @@ void Script::unloadTOT() { _totData = 0; _totSize = 0; _totPtr = 0; - _lomHandle = -1; _totFile.clear(); _finished = true; @@ -518,7 +513,7 @@ uint16 Script::getFunctionOffset(uint8 function) const { } uint32 Script::getVariablesCount(const char *fileName, GobEngine *vm) { - DataStream *stream = vm->_dataIO->getDataStream(fileName); + Common::SeekableReadStream *stream = vm->_dataIO->getFile(fileName); if (!stream) return 0; diff --git a/engines/gob/script.h b/engines/gob/script.h index 84daeaf1af..cf9eb246ce 100644 --- a/engines/gob/script.h +++ b/engines/gob/script.h @@ -150,7 +150,7 @@ private: byte *_totPtr; uint32 _totSize; - int16 _lomHandle; + Common::SeekableReadStream *_lom; TOTFile::Properties _totProperties; diff --git a/engines/gob/sound/cdrom.cpp b/engines/gob/sound/cdrom.cpp index 2e1673b12a..cfd26e6bed 100644 --- a/engines/gob/sound/cdrom.cpp +++ b/engines/gob/sound/cdrom.cpp @@ -49,7 +49,7 @@ CDROM::~CDROM() { stop(); } -void CDROM::readLIC(DataStream &stream) { +void CDROM::readLIC(Common::SeekableReadStream &stream) { uint16 version, startChunk, pos; freeLICBuffer(); diff --git a/engines/gob/sound/cdrom.h b/engines/gob/sound/cdrom.h index 6f01e6f90a..894744ca15 100644 --- a/engines/gob/sound/cdrom.h +++ b/engines/gob/sound/cdrom.h @@ -28,14 +28,12 @@ namespace Gob { -class DataStream; - class CDROM { public: CDROM(); ~CDROM(); - void readLIC(DataStream &stream); + void readLIC(Common::SeekableReadStream &stream); void freeLICBuffer(); void startTrack(const char *trackName); diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index bc4495fafd..dc80699ce0 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -114,19 +114,13 @@ bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName, debugC(2, kDebugSound, "Loading sample \"%s\"", fileName); - if (!_vm->_dataIO->existData(fileName)) { + int32 size; + byte *data = _vm->_dataIO->getFile(fileName, size); + if (!data) { warning("Can't open sample file \"%s\"", fileName); return false; } - byte *data; - uint32 size; - - data = (byte *)_vm->_dataIO->getData(fileName); - if (!data) - return false; - - size = _vm->_dataIO->getDataSize(fileName); return sndDesc->load(type, data, size); } @@ -279,13 +273,12 @@ bool Sound::adlibLoadMDY(const char *fileName) { debugC(1, kDebugSound, "AdLib: Loading MDY data (\"%s\")", fileName); - if (!_vm->_dataIO->existData(fileName)) { + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); + if (!stream) { warning("Can't open MDY file \"%s\"", fileName); return false; } - DataStream *stream = _vm->_dataIO->getDataStream(fileName); - bool loaded = _mdyPlayer->loadMDY(*stream); delete stream; @@ -300,15 +293,14 @@ bool Sound::adlibLoadTBR(const char *fileName) { if (!_mdyPlayer) _mdyPlayer = new MDYPlayer(*_vm->_mixer); - if (!_vm->_dataIO->existData(fileName)) { + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); + if (!stream) { warning("Can't open TBR file \"%s\"", fileName); return false; } debugC(1, kDebugSound, "AdLib: Loading MDY instruments (\"%s\")", fileName); - DataStream *stream = _vm->_dataIO->getDataStream(fileName); - bool loaded = _mdyPlayer->loadTBR(*stream); delete stream; @@ -522,13 +514,10 @@ void Sound::cdLoadLIC(const char *fname) { debugC(1, kDebugSound, "CDROM: Loading LIC \"%s\"", fname); - if (!_vm->_dataIO->existData(fname)) + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fname); + if (!stream) return; - _vm->_dataIO->getUnpackedData(fname); - - DataStream *stream = _vm->_dataIO->getDataStream(fname); - _cdrom->readLIC(*stream); delete stream; diff --git a/engines/gob/totfile.cpp b/engines/gob/totfile.cpp index 178deeaf58..82dd0c38c0 100644 --- a/engines/gob/totfile.cpp +++ b/engines/gob/totfile.cpp @@ -45,11 +45,11 @@ TOTFile::~TOTFile() { bool TOTFile::load(const Common::String &fileName) { // Trying to open normally - _stream = _vm->_dataIO->getDataStream(fileName.c_str()); + _stream = _vm->_dataIO->getFile(fileName); if (!_stream) // Trying to open from video - _stream = _vm->_vidPlayer->getEmbeddedFile(fileName.c_str()); + _stream = _vm->_vidPlayer->getEmbeddedFile(fileName); if (!_stream) return false; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index ee73f14dfa..91e3737832 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -331,9 +331,9 @@ void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, } void Video::drawPackedSprite(const char *path, Surface &dest, int width) { - byte *data; + int32 size; + byte *data = _vm->_dataIO->getFile(path, size); - data = _vm->_dataIO->getData(path); drawPackedSprite(data, width, dest.getHeight(), 0, 0, 0, dest); delete[] data; } diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 020c72d0c1..917bdc66c5 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -686,7 +686,7 @@ Common::String VideoPlayer::findFile(const Common::String &file, Properties &pro if ((properties.type == kVideoTypeTry) || (properties.type == ((Type) i))) { fileName = base + "." + _extensions[i]; - if (_vm->_dataIO->existData(fileName.c_str())) { + if (_vm->_dataIO->hasFile(fileName)) { properties.type = (Type) i; break; } @@ -707,7 +707,7 @@ Graphics::CoktelDecoder *VideoPlayer::openVideo(const Common::String &file, Prop if (fileName.empty()) return 0; - Common::SeekableReadStream *stream = _vm->_dataIO->getDataStream(fileName.c_str()); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); if (!stream) return 0; |