aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/neverhood/blbarchive.cpp54
-rw-r--r--engines/neverhood/blbarchive.h5
-rw-r--r--engines/neverhood/navigationscene.cpp4
-rw-r--r--engines/neverhood/neverhood.cpp10
-rw-r--r--engines/neverhood/resourceman.cpp93
-rw-r--r--engines/neverhood/resourceman.h45
6 files changed, 111 insertions, 100 deletions
diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp
index cb422a10e6..5551ff07f1 100644
--- a/engines/neverhood/blbarchive.cpp
+++ b/engines/neverhood/blbarchive.cpp
@@ -56,7 +56,8 @@ BlbArchive::~BlbArchive() {
}
void BlbArchive::open(const Common::String &filename) {
- BlbHeader header;
+ BlbHeader header;
+ uint16 *extDataOffsets;
_entries.clear();
@@ -72,7 +73,7 @@ void BlbArchive::open(const Common::String &filename) {
if (header.id1 != 0x2004940 || header.id2 != 7 || header.fileSize != _fd.size())
error("BlbArchive::open() %s seems to be corrupt", filename.c_str());
- debug(2, "fileCount = %d", header.fileCount);
+ debug(2, "%s: fileCount = %d", filename.c_str(), header.fileCount);
_entries.reserve(header.fileCount);
@@ -83,63 +84,80 @@ void BlbArchive::open(const Common::String &filename) {
_entries.push_back(entry);
}
+ extDataOffsets = new uint16[header.fileCount];
+
// Load file records
for (uint i = 0; i < header.fileCount; i++) {
BlbArchiveEntry &entry = _entries[i];
entry.type = _fd.readByte();
entry.comprType = _fd.readByte();
- entry.extDataOfs = _fd.readUint16LE();
+ //entry.extDataOfs = _fd.readUint16LE();
+ entry.extData = NULL;
+ extDataOffsets[i] = _fd.readUint16LE();
entry.timeStamp = _fd.readUint32LE();
entry.offset = _fd.readUint32LE();
entry.diskSize = _fd.readUint32LE();
entry.size = _fd.readUint32LE();
debug(2, "%08X: %03d, %02X, %04X, %08X, %08X, %08X, %08X",
- entry.fileHash, entry.type, entry.comprType, entry.extDataOfs, entry.timeStamp,
+ entry.fileHash, entry.type, entry.comprType, extDataOffsets[i], entry.timeStamp,
entry.offset, entry.diskSize, entry.size);
}
-
+
// Load ext data
if (header.extDataSize > 0) {
_extData = new byte[header.extDataSize];
_fd.read(_extData, header.extDataSize);
+ for (uint i = 0; i < header.fileCount; i++)
+ _entries[i].extData = extDataOffsets[i] > 0 ? _extData + extDataOffsets[i] - 1 : NULL;
}
+ delete[] extDataOffsets;
+
}
void BlbArchive::load(uint index, byte *buffer, uint32 size) {
+ load(&_entries[index], buffer, size);
+}
+
+void BlbArchive::load(BlbArchiveEntry *entry, byte *buffer, uint32 size) {
Common::StackLock lock(_mutex);
- BlbArchiveEntry &entry = _entries[index];
+ _fd.seek(entry->offset);
- _fd.seek(entry.offset);
-
- switch (entry.comprType) {
+ switch (entry->comprType) {
case 1: // Uncompressed
if (size == 0)
- size = entry.diskSize;
+ size = entry->diskSize;
_fd.read(buffer, size);
break;
case 3: // DCL-compressed
- if (!Common::decompressDCL(&_fd, buffer, entry.diskSize, entry.size)) {
- debug("decompressDCL(diskSize: %d; size: %d)", entry.diskSize, entry.size);
- debug("-> fileHash: %08X; type: %d; offset: %08X; endOffset: %08X", entry.fileHash, entry.type, entry.offset, entry.offset + entry.diskSize);
+ if (!Common::decompressDCL(&_fd, buffer, entry->diskSize, entry->size)) {
+ debug("decompressDCL(diskSize: %d; size: %d)", entry->diskSize, entry->size);
+ debug("-> fileHash: %08X; type: %d; offset: %08X; endOffset: %08X", entry->fileHash, entry->type, entry->offset, entry->offset + entry->diskSize);
debug("-> fd.pos() = %08X", _fd.pos());
}
break;
default:
- error("BlbArchive::load() Unknown compression type %d", entry.comprType);
+ error("BlbArchive::load() Unknown compression type %d", entry->comprType);
}
}
byte *BlbArchive::getEntryExtData(uint index) {
- BlbArchiveEntry &entry = _entries[index];
- return (_extData && entry.extDataOfs != 0) ? &_extData[entry.extDataOfs - 1] : NULL;
+ return getEntryExtData(&_entries[index]);
+}
+
+byte *BlbArchive::getEntryExtData(BlbArchiveEntry *entry) {
+ //return (_extData && entry->extDataOfs != 0) ? &_extData[entry->extDataOfs - 1] : NULL;
+ return entry->extData;
}
Common::SeekableReadStream *BlbArchive::createStream(uint index) {
- const BlbArchiveEntry &entry = _entries[index];
- return new SafeMutexedSeekableSubReadStream(&_fd, entry.offset, entry.offset + entry.diskSize,
+ return createStream(&_entries[index]);
+}
+
+Common::SeekableReadStream *BlbArchive::createStream(BlbArchiveEntry *entry) {
+ return new SafeMutexedSeekableSubReadStream(&_fd, entry->offset, entry->offset + entry->diskSize,
DisposeAfterUse::NO,_mutex);
}
diff --git a/engines/neverhood/blbarchive.h b/engines/neverhood/blbarchive.h
index cd2fd117b7..620b12b8ac 100644
--- a/engines/neverhood/blbarchive.h
+++ b/engines/neverhood/blbarchive.h
@@ -44,7 +44,7 @@ struct BlbArchiveEntry {
uint32 fileHash;
byte type;
byte comprType;
- uint16 extDataOfs;
+ byte *extData;
uint32 timeStamp;
uint32 offset;
uint32 diskSize;
@@ -57,11 +57,14 @@ public:
~BlbArchive();
void open(const Common::String &filename);
void load(uint index, byte *buffer, uint32 size);
+ void load(BlbArchiveEntry *entry, byte *buffer, uint32 size);
byte *getEntryExtData(uint index);
+ byte *getEntryExtData(BlbArchiveEntry *entry);
uint32 getSize(uint index) { return _entries[index].size; }
BlbArchiveEntry *getEntry(uint index) { return &_entries[index]; }
uint getCount() { return _entries.size(); }
Common::SeekableReadStream *createStream(uint index);
+ Common::SeekableReadStream *createStream(BlbArchiveEntry *entry);
private:
Common::File _fd;
Common::Mutex _mutex;
diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp
index 5dc80c9322..bf3de5d812 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -80,6 +80,10 @@ void NavigationScene::update() {
_vm->_screen->clear();
_vm->_screen->setSmackerDecoder(_smackerPlayer->getSmackerDecoder());
_smackerDone = false;
+ /*
+ if (!_interactive)
+ _smackerDone = true;
+ */
_smackerFileHash = 0;
} else if (_smackerDone) {
if (_leaveSceneAfter) {
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index cfeaf927d3..72fa3601ed 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -238,11 +238,11 @@ void NeverhoodEngine::dumpAllResources() {
for (uint i = 0; i < entriesCount; i++) {
const ResourceFileEntry &entry = _res->getEntry(i);
- int type = _res->getResourceTypeByHash(entry.fileHash);
- debug("hash: %08X; type: %d", entry.fileHash, type);
+ int type = _res->getResourceTypeByHash(entry.archiveEntry->fileHash);
+ debug("hash: %08X; type: %d", entry.archiveEntry->fileHash, type);
if (type == 4) {
AnimResource anim(this);
- anim.load(entry.fileHash);
+ anim.load(entry.archiveEntry->fileHash);
for (uint frameIndex = 0; frameIndex < anim.getFrameCount(); frameIndex++) {
const AnimFrameInfo &frameInfo = anim.getFrameInfo(frameIndex);
int16 width = (frameInfo.rect.width + 3) & 0xFFFC;
@@ -251,8 +251,8 @@ void NeverhoodEngine::dumpAllResources() {
anim.draw(frameIndex, pixels, width, false, false);
Common::String filename =
frameInfo.frameHash != 0
- ? Common::String::format("%08X_%03d_%08X.tga", entry.fileHash, frameIndex, frameInfo.frameHash)
- : Common::String::format("%08X_%03d.tga", entry.fileHash, frameIndex);
+ ? Common::String::format("%08X_%03d_%08X.tga", entry.archiveEntry->fileHash, frameIndex, frameInfo.frameHash)
+ : Common::String::format("%08X_%03d.tga", entry.archiveEntry->fileHash, frameIndex);
writeTga(filename.c_str(), pixels, vgaPalette, width, frameInfo.rect.height);
delete[] pixels;
}
diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp
index 28cef366e1..eb6aa01533 100644
--- a/engines/neverhood/resourceman.cpp
+++ b/engines/neverhood/resourceman.cpp
@@ -32,49 +32,40 @@ ResourceMan::~ResourceMan() {
void ResourceMan::addArchive(const Common::String &filename) {
BlbArchive *archive = new BlbArchive();
- uint archiveIndex = _archives.size();
archive->open(filename);
_archives.push_back(archive);
debug(3, "ResourceMan::addArchive(%s) %d files", filename.c_str(), archive->getCount());
- _entries.reserve(_entries.size() + archive->getCount());
for (uint archiveEntryIndex = 0; archiveEntryIndex < archive->getCount(); archiveEntryIndex++) {
BlbArchiveEntry *archiveEntry = archive->getEntry(archiveEntryIndex);
ResourceFileEntry *entry = findEntrySimple(archiveEntry->fileHash);
if (entry) {
- if (archiveEntry->timeStamp > _archives[entry->archiveIndex]->getEntry(entry->entryIndex)->timeStamp) {
- entry->archiveIndex = archiveIndex;
- entry->entryIndex = archiveEntryIndex;
+ if (archiveEntry->timeStamp > entry->archiveEntry->timeStamp) {
+ entry->archive = archive;
+ entry->archiveEntry = archiveEntry;
}
} else {
ResourceFileEntry newEntry;
- newEntry.fileHash = archiveEntry->fileHash;
newEntry.resourceHandle = -1;
- newEntry.archiveIndex = archiveIndex;
- newEntry.entryIndex = archiveEntryIndex;
- _entries.push_back(newEntry);
+ newEntry.archive = archive;
+ newEntry.archiveEntry = archiveEntry;
+ _entries[archiveEntry->fileHash] = newEntry;
}
}
+ debug("_entries.size() = %d", _entries.size());
}
ResourceFileEntry *ResourceMan::findEntrySimple(uint32 fileHash) {
- for (uint i = 0; i < _entries.size(); i++) {
- if (_entries[i].fileHash == fileHash)
- return &_entries[i];
- }
- return NULL;
+ EntriesMap::iterator p = _entries.find(fileHash);
+ return p != _entries.end() ? &(*p)._value : NULL;
}
ResourceFileEntry *ResourceMan::findEntry(uint32 fileHash) {
ResourceFileEntry *entry = findEntrySimple(fileHash);
- for (; entry && getArchiveEntry(entry)->comprType == 0x65; fileHash = getArchiveEntry(entry)->diskSize)
+ for (; entry && entry->archiveEntry->comprType == 0x65; fileHash = entry->archiveEntry->diskSize)
entry = findEntrySimple(fileHash);
return entry;
}
-BlbArchiveEntry *ResourceMan::getArchiveEntry(ResourceFileEntry *entry) const {
- return _archives[entry->archiveIndex]->getEntry(entry->entryIndex);
-}
-
int ResourceMan::useResource(uint32 fileHash) {
ResourceFileEntry *entry = findEntry(fileHash);
if (!entry)
@@ -83,11 +74,7 @@ int ResourceMan::useResource(uint32 fileHash) {
_resources[entry->resourceHandle]->useRefCount++;
} else {
Resource *resource = new Resource();
- resource->fileHash = entry->fileHash;
- resource->archiveIndex = entry->archiveIndex;
- resource->entryIndex = entry->entryIndex;
- resource->data = NULL;
- resource->dataRefCount = 0;
+ resource->entry = entry;
resource->useRefCount = 1;
entry->resourceHandle = (int)_resources.size();
_resources.push_back(resource);
@@ -103,86 +90,68 @@ void ResourceMan::unuseResource(int resourceHandle) {
resource->useRefCount--;
}
-void ResourceMan::unuseResourceByHash(uint32 fileHash) {
- ResourceFileEntry *entry = findEntry(fileHash);
- if (entry->resourceHandle != -1)
- unuseResource(entry->resourceHandle);
-}
-
-int ResourceMan::getResourceHandleByHash(uint32 fileHash) {
- ResourceFileEntry *entry = findEntry(fileHash);
- return entry->resourceHandle;
-}
-
-bool ResourceMan::isResourceDataValid(int resourceHandle) const {
- if (resourceHandle < 0)
- return false;
- return _resources[resourceHandle]->data != NULL;
-}
-
uint32 ResourceMan::getResourceSize(int resourceHandle) const {
if (resourceHandle < 0)
return 0;
Resource *resource = _resources[resourceHandle];
- return _archives[resource->archiveIndex]->getEntry(resource->entryIndex)->size;
+ return resource->entry->archiveEntry->size;
}
byte ResourceMan::getResourceType(int resourceHandle) {
if (resourceHandle < 0)
return 0;
Resource *resource = _resources[resourceHandle];
- return _archives[resource->archiveIndex]->getEntry(resource->entryIndex)->type;
+ return resource->entry->archiveEntry->type;
}
byte ResourceMan::getResourceTypeByHash(uint32 fileHash) {
ResourceFileEntry *entry = findEntry(fileHash);
- return getArchiveEntry(entry)->type;
+ return entry->archiveEntry->type;
}
byte *ResourceMan::getResourceExtData(int resourceHandle) {
if (resourceHandle < 0)
return NULL;
Resource *resource = _resources[resourceHandle];
- return _archives[resource->archiveIndex]->getEntryExtData(resource->entryIndex);
+ return resource->entry->archive->getEntryExtData(resource->entry->archiveEntry);
}
byte *ResourceMan::getResourceExtDataByHash(uint32 fileHash) {
ResourceFileEntry *entry = findEntrySimple(fileHash);
- return entry ? _archives[entry->archiveIndex]->getEntryExtData(entry->entryIndex) : NULL;
+ return entry ? entry->archive->getEntryExtData(entry->archiveEntry) : NULL;
}
byte *ResourceMan::loadResource(int resourceHandle, bool moveToFront) {
if (resourceHandle < 0)
return NULL;
Resource *resource = _resources[resourceHandle];
- if (resource->data != NULL) {
- resource->dataRefCount++;
+ ResourceData *resourceData = _data[resource->entry->archiveEntry->fileHash];
+ if (!resourceData) {
+ resourceData = new ResourceData();
+ _data[resource->entry->archiveEntry->fileHash] = resourceData;
+ }
+ if (resourceData->data != NULL) {
+ resourceData->dataRefCount++;
} else {
- BlbArchive *archive = _archives[resource->archiveIndex];
- BlbArchiveEntry *archiveEntry = archive->getEntry(resource->entryIndex);
- resource->data = new byte[archiveEntry->size];
- archive->load(resource->entryIndex, resource->data, 0);
- resource->dataRefCount = 1;
+ resourceData->data = new byte[resource->entry->archiveEntry->size];
+ resource->entry->archive->load(resource->entry->archiveEntry, resourceData->data, 0);
+ resourceData->dataRefCount = 1;
}
- return resource->data;
+ return resourceData->data;
}
void ResourceMan::unloadResource(int resourceHandle) {
if (resourceHandle < 0)
return;
Resource *resource = _resources[resourceHandle];
- if (resource->dataRefCount > 0)
- resource->dataRefCount--;
-}
-
-void ResourceMan::freeResource(Resource *resource) {
- delete[] resource->data;
- resource->data = NULL;
+ ResourceData *resourceData = _data[resource->entry->archiveEntry->fileHash];
+ if (resourceData && resourceData->dataRefCount > 0)
+ resourceData->dataRefCount--;
}
Common::SeekableReadStream *ResourceMan::createStream(uint32 fileHash) {
ResourceFileEntry *entry = findEntry(fileHash);
- return _archives[entry->archiveIndex]->createStream(entry->entryIndex);
+ return entry->archive->createStream(entry->archiveEntry);
}
} // End of namespace Neverhood
diff --git a/engines/neverhood/resourceman.h b/engines/neverhood/resourceman.h
index ed5bffaf9b..5ca8fa2b04 100644
--- a/engines/neverhood/resourceman.h
+++ b/engines/neverhood/resourceman.h
@@ -25,26 +25,43 @@
#include "common/array.h"
#include "common/file.h"
+#include "common/hashmap.h"
#include "neverhood/neverhood.h"
#include "neverhood/blbarchive.h"
namespace Neverhood {
struct ResourceFileEntry {
- uint32 fileHash;
int resourceHandle;
- uint archiveIndex;
- uint entryIndex;
+ BlbArchive *archive;
+ BlbArchiveEntry *archiveEntry;
};
struct Resource {
- uint32 fileHash;
- uint archiveIndex;
- uint entryIndex;
+ ResourceFileEntry *entry;
+ int useRefCount;
+};
+
+struct ResourceData {
byte *data;
int dataRefCount;
- int useRefCount;
+ ResourceData() : data(NULL), dataRefCount() {}
+};
+
+#if 0
+class ResourceMan;
+
+struct ResourceHandle {
+public:
+ ResourceHandle();
+ ~ResourceHandle();
+ const byte *data();
+ uint32 size() const { return _archiveEntry ? _archiveEntry->size : 0 };
+protected:
+ ResourceMan *_res;
+ ResourceFileEntry *_resourceFileEntry;
};
+#endif
class ResourceMan {
public:
@@ -53,12 +70,8 @@ public:
void addArchive(const Common::String &filename);
ResourceFileEntry *findEntrySimple(uint32 fileHash);
ResourceFileEntry *findEntry(uint32 fileHash);
- BlbArchiveEntry *getArchiveEntry(ResourceFileEntry *entry) const;
int useResource(uint32 fileHash);
void unuseResource(int resourceHandle);
- void unuseResourceByHash(uint32 fileHash);
- int getResourceHandleByHash(uint32 fileHash);
- bool isResourceDataValid(int resourceHandle) const;
uint32 getResourceSize(int resourceHandle) const;
byte getResourceType(int resourceHandle);
byte getResourceTypeByHash(uint32 fileHash);
@@ -66,13 +79,17 @@ public:
byte *getResourceExtDataByHash(uint32 fileHash);
byte *loadResource(int resourceHandle, bool moveToFront = false);
void unloadResource(int resourceHandle);
- void freeResource(Resource *resource);
Common::SeekableReadStream *createStream(uint32 fileHash);
const ResourceFileEntry& getEntry(uint index) { return _entries[index]; }
uint getEntryCount() { return _entries.size(); }
-private:
+#if 0
+ ResourceHandle getResource(uint32 fileHash);
+#endif
+protected:
+ typedef Common::HashMap<uint32, ResourceFileEntry> EntriesMap;
Common::Array<BlbArchive*> _archives;
- Common::Array<ResourceFileEntry> _entries;
+ EntriesMap _entries;
+ Common::HashMap<uint32, ResourceData*> _data;
Common::Array<Resource*> _resources;
};