SAGA2 HRS resources should be loaded correctly now

svn-id: r35539
This commit is contained in:
Filippos Karapetis 2008-12-25 15:19:33 +00:00
parent 52f464534c
commit dd7ea11ac4
4 changed files with 57 additions and 32 deletions

View File

@ -484,8 +484,7 @@ void Resource::clearContexts() {
}
}
if (_vm->isSaga2()) {
free(context->base);
free(context->groups);
free(context->categories);
}
free(context->table);
}

View File

@ -84,9 +84,7 @@ struct ResourceContext {
bool isBigEndian;
ResourceData *table;
size_t count;
uint32 firstGroupOffset; // SAGA2
ResourceData *base; // SAGA2
ResourceData *groups; // SAGA2
ResourceData *categories; // SAGA2
Common::File *getFile(ResourceData *resourceData) const {
if (resourceData->patchData != NULL) {
@ -109,6 +107,16 @@ struct ResourceContext {
return &table[resourceId];
}
// SAGA 2
int32 getEntryNum(uint32 id) {
for (int32 i = 0; i < (int32)count; i++) {
if (table[i].id == id) {
return i;
}
}
return -1;
}
};
struct MetaResource {
@ -146,8 +154,7 @@ public:
virtual void loadGlobalResources(int chapter, int actorsEntrance) = 0;
ResourceContext *getContext(uint16 fileType, int serial = 0) {
int i;
for (i = 0; i < _contextsCount; i++) {
for (int i = 0; i < _contextsCount; i++) {
if ((_contexts[i].fileType & fileType) && _contexts[i].serial == serial) {
return &_contexts[i];
}

View File

@ -42,10 +42,12 @@ namespace Saga {
bool Resource_HRS::loadResContext_v2(ResourceContext *context, uint32 contextSize) {
ResourceData *origin = new ResourceData();
uint32 firstGroupOffset;
uint32 size;
uint32 firstEntryOffset;
uint32 tableSize;
int i, count;
const uint32 resourceSize = 4 + 4 + 4; // id, size, offset
debug(3, "Context %s", context->fileName);
context->file->seek(0, SEEK_SET);
// Read head element (origin)
@ -59,39 +61,41 @@ bool Resource_HRS::loadResContext_v2(ResourceContext *context, uint32 contextSiz
return false;
}
// Read first group offset
// Read offset of first entry
context->file->seek(origin->offset - sizeof(uint32), SEEK_SET);
firstGroupOffset = context->file->readUint32LE();
firstEntryOffset = context->file->readUint32LE();
// Allocate buffers for root/base node, groups and data
context->base = (ResourceData *) calloc(origin->size / sizeof(*context->base), sizeof(*context->base));
size = origin->offset - firstGroupOffset - sizeof(uint32);
context->groups = (ResourceData *) calloc(size / sizeof(*context->groups), sizeof(*context->groups));
// Allocate buffers for table, categories and data
context->categories = (ResourceData *) calloc(origin->size / resourceSize, sizeof(*context->categories));
tableSize = origin->offset - firstEntryOffset - sizeof(uint32);
context->table = (ResourceData *) calloc(tableSize / resourceSize, sizeof(*context->table));
if (context->base == NULL || context->groups == NULL) {
if (context->categories == NULL || context->table == NULL) {
free(origin);
return false;
}
// Read base
count = origin->size / sizeof(*context->base);
// Read categories
count = origin->size / resourceSize;
for (i = 0; i < count; i++) {
context->base[i].id = context->file->readUint32LE();
context->base[i].offset = context->file->readUint32LE();
context->base[i].size = context->file->readUint32LE();
context->categories[i].id = context->file->readUint32BE();
context->categories[i].offset = context->file->readUint32LE();
context->categories[i].size = context->file->readUint32LE();
debug(3, "Category entry: id %u, offset %u, size %u", context->categories[i].id, context->categories[i].offset, context->categories[i].size);
}
context->file->seek(firstGroupOffset, SEEK_SET);
context->file->seek(firstEntryOffset, SEEK_SET);
// Read groups
count = size / sizeof(*context->groups);
// Read table entries
count = tableSize / resourceSize;
for (i = 0; i < count; i++) {
context->groups[i].id = context->file->readUint32LE();
context->groups[i].offset = context->file->readUint32LE();
context->groups[i].size = context->file->readUint32LE();
context->table[i].id = context->file->readUint32BE();
context->table[i].offset = context->file->readUint32LE();
context->table[i].size = context->file->readUint32LE();
debug(3, "Table entry: id %u, offset %u, size %u", context->table[i].id, context->table[i].offset, context->table[i].size);
}
context->count = origin->size / sizeof(*origin);
context->count = tableSize / resourceSize;
free(origin);
return true;

View File

@ -85,15 +85,30 @@ Script::Script(SagaEngine *vm) : _vm(vm) {
error("Script::Script() resource context not found");
}
uint32 scriptResourceId = 0;
if (!_vm->isSaga2()) {
scriptResourceId = _vm->getResourceDescription()->moduleLUTResourceId;
debug(3, "Loading module LUT from resource %i", scriptResourceId);
_vm->_resource->loadResource(resourceContext, scriptResourceId, resourcePointer, resourceLength);
} else {
uint32 saga2DataSegId = MKID_BE('__DA');
int32 scr = _scriptContext->getEntryNum(saga2DataSegId);
if (scr < 0)
error("Unable to locate the script's data segment");
scriptResourceId = (uint32)scr;
debug(3, "Loading module LUT from resource %i", scriptResourceId);
_vm->_resource->loadResource(_scriptContext, scriptResourceId, resourcePointer, resourceLength);
//uint32 saga2ExportSegId = MKID_BE('_EXP');
// TODO: SAGA2 script export segment
}
// Do nothing for SAGA2 games for now
if (_vm->isSaga2()) {
return;
}
debug(3, "Loading module LUT from resource %i", _vm->getResourceDescription()->moduleLUTResourceId);
_vm->_resource->loadResource(resourceContext, _vm->getResourceDescription()->moduleLUTResourceId, resourcePointer, resourceLength);
// Create logical script LUT from resource
if (resourceLength % S_LUT_ENTRYLEN_ITECD == 0) {
_modulesLUTEntryLen = S_LUT_ENTRYLEN_ITECD;