[Scummvm-cvs-logs] CVS: scummvm/scumm/imuse_digi dimuse_bndmgr.cpp,1.2,1.3 dimuse_bndmgr.h,1.1,1.2
Pawel Kolodziejski
aquadran at users.sourceforge.net
Tue Jan 6 19:35:04 CET 2004
Update of /cvsroot/scummvm/scummvm/scumm/imuse_digi
In directory sc8-pr-cvs1:/tmp/cvs-serv16354
Modified Files:
dimuse_bndmgr.cpp dimuse_bndmgr.h
Log Message:
optimized i/o access in bundle manager
Index: dimuse_bndmgr.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_bndmgr.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- dimuse_bndmgr.cpp 7 Jan 2004 01:07:37 -0000 1.2
+++ dimuse_bndmgr.cpp 7 Jan 2004 03:34:41 -0000 1.3
@@ -25,16 +25,23 @@
namespace Scumm {
+struct FileDirChache {
+ char fileName[20];
+ BundleMgr::AudioTable *bundleTable;
+ int32 numFiles;
+ int32 instance;
+} budleDirChache[4];
+
BundleMgr::BundleMgr() {
- _compTable = NULL;
_bundleTable = NULL;
+ _compTable = NULL;
_numFiles = 0;
_curSample = -1;
+ _fileBundleId = -1;
}
BundleMgr::~BundleMgr() {
- free(_bundleTable);
- free(_compTable);
+ closeFile();
}
bool BundleMgr::openFile(const char *filename, const char *directory) {
@@ -48,51 +55,83 @@
return false;
}
-/*
- TODO / FIXME
-This is another spot were lots and lots of time is wasted, because the same data is read over
-and over again from the disk. Disk I/O is *slooow*.
-This function by itself actually isn't what is really slow - normally we would call
-it once and then be done with it.
-However, for whatever strange reasons, the higher level code constantly keeps creating
-new BundleMgr, uses them to open a file, play a piece of sound, then delete the BundleMgr.
-Repeat ad infinitum -> extremly slow.
-*/
+ bool found = false;
+ int freeSlot = -1;
+ int fileId;
- tag = _file.readUint32BE();
- offset = _file.readUint32BE();
- _numFiles = _file.readUint32BE();
+ for (fileId = 0; fileId < ARRAYSIZE(budleDirChache); fileId++) {
+ if ((budleDirChache[fileId].instance == 0) && (freeSlot == -1)) {
+ freeSlot = fileId;
+ }
+ if (scumm_stricmp(filename, budleDirChache[fileId].fileName) == 0) {
+ found = true;
+ }
+ }
- _bundleTable = (AudioTable *) malloc(_numFiles * sizeof(AudioTable));
+ if (!found) {
+ if (freeSlot == -1)
+ error("BundleMgr::openFile() Can't find free slot for file bundle dir cache");
- _file.seek(offset, SEEK_SET);
+ tag = _file.readUint32BE();
+ offset = _file.readUint32BE();
+
+ strcpy(budleDirChache[freeSlot].fileName, filename);
+ budleDirChache[freeSlot].numFiles = _numFiles = _file.readUint32BE();
+ budleDirChache[freeSlot].bundleTable = _bundleTable = (AudioTable *) malloc(_numFiles * sizeof(AudioTable));
- for (int32 i = 0; i < _numFiles; i++) {
- char name[13], c;
- int32 z = 0;
- int32 z2;
+ _file.seek(offset, SEEK_SET);
- for (z2 = 0; z2 < 8; z2++)
- if ((c = _file.readByte()) != 0)
- name[z++] = c;
- name[z++] = '.';
- for (z2 = 0; z2 < 4; z2++)
- if ((c = _file.readByte()) != 0)
- name[z++] = c;
- name[z] = '\0';
- strcpy(_bundleTable[i].filename, name);
- _bundleTable[i].offset = _file.readUint32BE();
- _bundleTable[i].size = _file.readUint32BE();
+ for (int32 i = 0; i < _numFiles; i++) {
+ char name[13], c;
+ int32 z = 0;
+ int32 z2;
+
+ for (z2 = 0; z2 < 8; z2++)
+ if ((c = _file.readByte()) != 0)
+ name[z++] = c;
+ name[z++] = '.';
+ for (z2 = 0; z2 < 4; z2++)
+ if ((c = _file.readByte()) != 0)
+ name[z++] = c;
+
+ name[z] = '\0';
+ strcpy(_bundleTable[i].filename, name);
+ _bundleTable[i].offset = _file.readUint32BE();
+ _bundleTable[i].size = _file.readUint32BE();
+ }
+ budleDirChache[freeSlot].instance++;
+ _fileBundleId = freeSlot;
+ } else {
+ _fileBundleId = fileId;
+ _numFiles = budleDirChache[fileId].numFiles;
+ _bundleTable = budleDirChache[fileId].bundleTable;
+ budleDirChache[fileId].instance++;
}
+ _compTableLoaded = false;
+ _lastCacheOutputSize = 0;
+ _lastBlock = -1;
+
return true;
}
void BundleMgr::closeFile() {
if (_file.isOpen()) {
_file.close();
- free(_bundleTable);
+ if (--budleDirChache[_fileBundleId].instance <= 0) {
+ free (budleDirChache[_fileBundleId].bundleTable);
+ budleDirChache[_fileBundleId].instance = 0;
+ budleDirChache[_fileBundleId].fileName[0] = 0;
+ budleDirChache[_fileBundleId].numFiles = 0;
+ }
_bundleTable = NULL;
+ _numFiles = 0;
+ _compTableLoaded = false;
+ _lastBlock = -1;
+ _lastCacheOutputSize = 0;
+ _curSample = -1;
+ free(_compTable);
+ _compTable = NULL;
}
}
@@ -112,31 +151,26 @@
return 0;
}
-/*
-FIXME / TODO
- This function is a major speed hog. It re-reads the same data over and over and over again.
- Disk I/O is about the slowest thing on any modern computer. We used to cache all this data,
- with good reason... this will have to be done again.
-*/
-
- _file.seek(_bundleTable[index].offset, SEEK_SET);
- tag = _file.readUint32BE();
- num = _file.readUint32BE();
- _file.readUint32BE();
- _file.readUint32BE();
+ if (!_compTableLoaded) {
+ _file.seek(_bundleTable[index].offset, SEEK_SET);
+ tag = _file.readUint32BE();
+ num = _file.readUint32BE();
+ _file.readUint32BE();
+ _file.readUint32BE();
- if (tag != MKID_BE('COMP')) {
- warning("BundleMgr::decompressSampleByIndex() Compressed sound %d invalid (%s)", index, tag2str(tag));
- return 0;
- }
+ if (tag != MKID_BE('COMP')) {
+ warning("BundleMgr::decompressSampleByIndex() Compressed sound %d invalid (%s)", index, tag2str(tag));
+ return 0;
+ }
- free(_compTable);
- _compTable = (CompTable *)malloc(sizeof(CompTable) * num);
- for (i = 0; i < num; i++) {
- _compTable[i].offset = _file.readUint32BE();
- _compTable[i].size = _file.readUint32BE();
- _compTable[i].codec = _file.readUint32BE();
- _file.readUint32BE();
+ _compTable = (CompTable *)malloc(sizeof(CompTable) * num);
+ for (i = 0; i < num; i++) {
+ _compTable[i].offset = _file.readUint32BE();
+ _compTable[i].size = _file.readUint32BE();
+ _compTable[i].codec = _file.readUint32BE();
+ _file.readUint32BE();
+ }
+ _compTableLoaded = true;
}
int first_block = (offset + header_size) / 0x2000;
@@ -154,20 +188,29 @@
comp_input = (byte *)malloc(_compTable[i].size + 1);
comp_input[_compTable[i].size] = 0;
- _file.seek(_bundleTable[index].offset + _compTable[i].offset, SEEK_SET);
- _file.read(comp_input, _compTable[i].size);
+ if (_lastBlock != i) {
+ _file.seek(_bundleTable[index].offset + _compTable[i].offset, SEEK_SET);
+ _file.read(comp_input, _compTable[i].size);
+
+ output_size = BundleCodecs::decompressCodec(_compTable[i].codec, comp_input, comp_output, _compTable[i].size);
+ assert(output_size <= 0x2000);
+ _lastBlock = i;
+ _lastCacheOutputSize = output_size;
+ memcpy(&_blockChache, comp_output, output_size);
+ } else {
+ output_size = _lastCacheOutputSize;
+ memcpy(comp_output, &_blockChache, output_size);
+ }
- output_size = BundleCodecs::decompressCodec(_compTable[i].codec, comp_input, comp_output, _compTable[i].size);
- assert(output_size <= 0x2000);
if ((header_size != 0) && (skip > header_size))
output_size -= skip;
if (output_size > size)
output_size = size;
+
memcpy(*comp_final + final_size, comp_output + skip, output_size);
final_size += output_size;
size -= output_size;
- if (skip > 0)
- skip = 0;
+ skip = 0;
free(comp_input);
}
Index: dimuse_bndmgr.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/imuse_digi/dimuse_bndmgr.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dimuse_bndmgr.h 6 Jan 2004 17:28:29 -0000 1.1
+++ dimuse_bndmgr.h 7 Jan 2004 03:34:41 -0000 1.2
@@ -27,6 +27,13 @@
namespace Scumm {
class BundleMgr {
+public:
+
+ struct AudioTable {
+ char filename[13];
+ int32 size;
+ int32 offset;
+ };
private:
@@ -36,19 +43,19 @@
int32 codec;
};
- struct AudioTable {
- char filename[13];
- int32 size;
- int32 offset;
- };
-
- CompTable *_compTable;
AudioTable *_bundleTable;
+ CompTable *_compTable;
int32 _numFiles;
int32 _curSample;
File _file;
+ bool _compTableLoaded;
+ int _fileBundleId;
+ byte _blockChache[0x2000];
+ int32 _lastCacheOutputSize;
+ int32 _lastBlock;
public:
+
BundleMgr();
~BundleMgr();
More information about the Scummvm-git-logs
mailing list