diff options
-rw-r--r-- | engines/neverhood/console.cpp | 2 | ||||
-rw-r--r-- | engines/neverhood/detection.cpp | 8 | ||||
-rw-r--r-- | engines/neverhood/neverhood.h | 2 | ||||
-rw-r--r-- | engines/neverhood/resource.cpp | 10 | ||||
-rw-r--r-- | engines/neverhood/resourceman.cpp | 35 | ||||
-rw-r--r-- | engines/neverhood/resourceman.h | 2 | ||||
-rw-r--r-- | engines/neverhood/sound.cpp | 2 |
7 files changed, 50 insertions, 11 deletions
diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp index a2ceed8a2e..708c68746c 100644 --- a/engines/neverhood/console.cpp +++ b/engines/neverhood/console.cpp @@ -252,7 +252,7 @@ bool Console::Cmd_DumpResource(int argc, const char **argv) { if (!handle.isValid()) { DebugPrintf("Invalid resource hash\n"); } else { - _vm->_res->loadResource(handle); + _vm->_res->loadResource(handle, _vm->applyResourceFixes()); Common::DumpFile outFile; outFile.open(outFileName); outFile.write(handle.data(), handle.size()); diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp index 3de087051a..96c87ab3ae 100644 --- a/engines/neverhood/detection.cpp +++ b/engines/neverhood/detection.cpp @@ -52,6 +52,10 @@ Common::Platform NeverhoodEngine::getPlatform() const { return _gameDescription->desc.platform; } +Common::Language NeverhoodEngine::getLanguage() const { + return _gameDescription->desc.language; +} + uint16 NeverhoodEngine::getVersion() const { return _gameDescription->version; } @@ -60,6 +64,10 @@ bool NeverhoodEngine::isDemo() const { return _gameDescription->desc.flags & ADGF_DEMO; } +bool NeverhoodEngine::applyResourceFixes() const { + return getLanguage() == Common::RU_RUS; +} + } static const PlainGameDescriptor neverhoodGames[] = { diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h index 9b65f6740e..0561aa251e 100644 --- a/engines/neverhood/neverhood.h +++ b/engines/neverhood/neverhood.h @@ -72,8 +72,10 @@ public: uint32 getFeatures() const; uint16 getVersion() const; Common::Platform getPlatform() const; + Common::Language getLanguage() const; bool hasFeature(EngineFeature f) const; bool isDemo() const; + bool applyResourceFixes() const; Common::String getTargetName() { return _targetName; }; Common::RandomSource *_rnd; diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp index a1a517f251..b45dbff3b9 100644 --- a/engines/neverhood/resource.cpp +++ b/engines/neverhood/resource.cpp @@ -53,7 +53,7 @@ bool SpriteResource::load(uint32 fileHash, bool doLoadPosition) { unload(); _vm->_res->queryResource(fileHash, _resourceHandle); if (_resourceHandle.isValid() && _resourceHandle.type() == kResTypeBitmap) { - _vm->_res->loadResource(_resourceHandle); + _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes()); const byte *spriteData = _resourceHandle.data(); NPoint *position = doLoadPosition ? &_position : NULL; parseBitmapResource(spriteData, &_rle, &_dimensions, position, NULL, &_pixels); @@ -83,7 +83,7 @@ bool PaletteResource::load(uint32 fileHash) { _vm->_res->queryResource(fileHash, _resourceHandle); if (_resourceHandle.isValid() && (_resourceHandle.type() == kResTypeBitmap || _resourceHandle.type() == kResTypePalette)) { - _vm->_res->loadResource(_resourceHandle); + _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes()); _palette = _resourceHandle.data(); // Check if the palette is stored in a bitmap if (_resourceHandle.type() == kResTypeBitmap) @@ -144,7 +144,7 @@ bool AnimResource::load(uint32 fileHash) { uint16 frameListStartOfs, frameCount; uint32 spriteDataOfs, paletteDataOfs; - _vm->_res->loadResource(_resourceHandle); + _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes()); resourceData = _resourceHandle.data(); animListCount = READ_LE_UINT16(resourceData); @@ -323,7 +323,7 @@ void TextResource::load(uint32 fileHash) { unload(); _vm->_res->queryResource(fileHash, _resourceHandle); if (_resourceHandle.isValid() && _resourceHandle.type() == kResTypeText) { - _vm->_res->loadResource(_resourceHandle); + _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes()); _textData = _resourceHandle.data(); _count = READ_LE_UINT32(_textData); } @@ -359,7 +359,7 @@ void DataResource::load(uint32 fileHash) { unload(); _vm->_res->queryResource(fileHash, _resourceHandle); if (_resourceHandle.isValid() && _resourceHandle.type() == kResTypeData) { - _vm->_res->loadResource(_resourceHandle); + _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes()); data = _resourceHandle.data(); dataSize = _resourceHandle.size(); } diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp index 37089a5bd6..518755a846 100644 --- a/engines/neverhood/resourceman.cpp +++ b/engines/neverhood/resourceman.cpp @@ -85,7 +85,25 @@ void ResourceMan::queryResource(uint32 fileHash, ResourceHandle &resourceHandle) resourceHandle._extData = firstEntry ? firstEntry->archiveEntry->extData : NULL; } -void ResourceMan::loadResource(ResourceHandle &resourceHandle) { +struct EntrySizeFix { + uint32 fileHash; + uint32 offset; + uint32 diskSize; + uint32 size; + uint32 fixedSize; +}; + +static const EntrySizeFix entrySizeFixes[] = { + // fileHash offset diskSize size fixedSize + // Fixes for the Russian "Dyadyushka Risech" version + // TODO + // Fixes for the Russian "Fargus" version + // TODO + // + { 0, 0, 0, 0, 0 } +}; + +void ResourceMan::loadResource(ResourceHandle &resourceHandle, bool applyResourceFixes) { resourceHandle._data = NULL; if (resourceHandle.isValid()) { const uint32 fileHash = resourceHandle.fileHash(); @@ -97,8 +115,19 @@ void ResourceMan::loadResource(ResourceHandle &resourceHandle) { if (resourceData->data != NULL) { resourceData->dataRefCount++; } else { - resourceData->data = new byte[resourceHandle._resourceFileEntry->archiveEntry->size]; - resourceHandle._resourceFileEntry->archive->load(resourceHandle._resourceFileEntry->archiveEntry, resourceData->data, 0); + BlbArchiveEntry *entry = resourceHandle._resourceFileEntry->archiveEntry; + + // Apply fixes for broken resources in Russian versions + if (applyResourceFixes) { + for (const EntrySizeFix *cur = entrySizeFixes; cur->fileHash > 0; ++cur) { + if (entry->fileHash == cur->fileHash && entry->offset == cur->offset && + entry->diskSize == cur->diskSize && entry->size == cur->size) + entry->size = cur->fixedSize; + } + } + + resourceData->data = new byte[entry->size]; + resourceHandle._resourceFileEntry->archive->load(entry, resourceData->data, 0); resourceData->dataRefCount = 1; } resourceHandle._data = resourceData->data; diff --git a/engines/neverhood/resourceman.h b/engines/neverhood/resourceman.h index 5a3697fe0d..29bf40a6b8 100644 --- a/engines/neverhood/resourceman.h +++ b/engines/neverhood/resourceman.h @@ -78,7 +78,7 @@ public: const ResourceFileEntry& getEntry(uint index) { return _entries[index]; } uint getEntryCount() { return _entries.size(); } void queryResource(uint32 fileHash, ResourceHandle &resourceHandle); - void loadResource(ResourceHandle &resourceHandle); + void loadResource(ResourceHandle &resourceHandle, bool applyResourceFixes); void unloadResource(ResourceHandle &resourceHandle); void purgeResources(); protected: diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp index 1fd09674a2..746dd17de0 100644 --- a/engines/neverhood/sound.cpp +++ b/engines/neverhood/sound.cpp @@ -577,7 +577,7 @@ AudioResourceManSoundItem::AudioResourceManSoundItem(NeverhoodEngine *vm, uint32 void AudioResourceManSoundItem::loadSound() { if (!_data && _resourceHandle.isValid() && (_resourceHandle.type() == kResTypeSound || _resourceHandle.type() == kResTypeMusic)) { - _vm->_res->loadResource(_resourceHandle); + _vm->_res->loadResource(_resourceHandle, _vm->applyResourceFixes()); _data = _resourceHandle.data(); } } |