aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorSven Hesse2010-10-31 20:07:14 +0000
committerSven Hesse2010-10-31 20:07:14 +0000
commit16a3cc8a8440c4ca6b45b6408d7baf7e9c001553 (patch)
treec1c208521c0098bbec5fc3a19e5ad27076a66e2d /engines/gob
parent88892dc982362cdaae8fa67fec7600041375fbd9 (diff)
downloadscummvm-rg350-16a3cc8a8440c4ca6b45b6408d7baf7e9c001553.tar.gz
scummvm-rg350-16a3cc8a8440c4ca6b45b6408d7baf7e9c001553.tar.bz2
scummvm-rg350-16a3cc8a8440c4ca6b45b6408d7baf7e9c001553.zip
GOB: Clean up class DataIO
Removing the need for class DataStream and that handle mess. svn-id: r53984
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/dataio.cpp673
-rw-r--r--engines/gob/dataio.h125
-rw-r--r--engines/gob/draw.cpp5
-rw-r--r--engines/gob/gob.cpp2
-rw-r--r--engines/gob/init.cpp87
-rw-r--r--engines/gob/inter_bargon.cpp4
-rw-r--r--engines/gob/inter_playtoons.cpp18
-rw-r--r--engines/gob/inter_v1.cpp48
-rw-r--r--engines/gob/inter_v2.cpp31
-rw-r--r--engines/gob/inter_v6.cpp10
-rw-r--r--engines/gob/map_v1.cpp14
-rw-r--r--engines/gob/resources.cpp21
-rw-r--r--engines/gob/script.cpp25
-rw-r--r--engines/gob/script.h2
-rw-r--r--engines/gob/sound/cdrom.cpp2
-rw-r--r--engines/gob/sound/cdrom.h4
-rw-r--r--engines/gob/sound/sound.cpp29
-rw-r--r--engines/gob/totfile.cpp4
-rw-r--r--engines/gob/video.cpp4
-rw-r--r--engines/gob/videoplayer.cpp4
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 &params) {
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 &params) {
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 &params) {
int32 size;
int32 offset;
uint16 dataVar;
- int16 handle;
byte *buf;
SaveLoad::SaveMode mode;
@@ -329,13 +328,10 @@ bool Inter_Playtoons::oPlaytoons_readData(OpFuncParams &params) {
}
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 &params) {
}
bool Inter_v1::o1_checkData(OpFuncParams &params) {
- 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 &params) {
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 &params) {
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 &params) {
_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 &params) {
}
bool Inter_v2::o2_checkData(OpFuncParams &params) {
- int16 handle;
int16 varOff;
int32 size;
SaveLoad::SaveMode mode;
@@ -1301,7 +1300,6 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
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 &params) {
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 &params) {
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 &params) {
int32 size;
int32 offset;
int16 dataVar;
- int16 handle;
byte *buf;
SaveLoad::SaveMode mode;
@@ -1391,13 +1384,10 @@ bool Inter_v2::o2_readData(OpFuncParams &params) {
}
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 &params) {
}
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;