diff options
author | johndoe123 | 2012-09-27 17:07:41 +0000 |
---|---|---|
committer | Willem Jan Palenstijn | 2013-05-08 20:43:43 +0200 |
commit | a5986fd7222f32dfb00487542086cdd765a39208 (patch) | |
tree | 860f13d4f6ebe0162e8ef5e0d1f2f497dc7f308a /engines | |
parent | 8bdddfdb02c0327af2985b81b4803b79de5a2b33 (diff) | |
download | scummvm-rg350-a5986fd7222f32dfb00487542086cdd765a39208.tar.gz scummvm-rg350-a5986fd7222f32dfb00487542086cdd765a39208.tar.bz2 scummvm-rg350-a5986fd7222f32dfb00487542086cdd765a39208.zip |
NEVERHOOD: Fix resource file reading by introducing SafeMutexedSeekableSubReadStream which locks a mutex during reads and also lock the same mutex in BlbArchive::load; loading resources while music is playing shouldn't mess up the file position now
- Fix loading of non-existent resources (not elegant and not checked everywhere yet, the resource system is subject to a minor rewrite anyway)
- Rename more Klayman stuff
Diffstat (limited to 'engines')
-rw-r--r-- | engines/neverhood/blbarchive.cpp | 34 | ||||
-rw-r--r-- | engines/neverhood/blbarchive.h | 2 | ||||
-rw-r--r-- | engines/neverhood/gamemodule.cpp | 9 | ||||
-rw-r--r-- | engines/neverhood/klayman.cpp | 38 | ||||
-rw-r--r-- | engines/neverhood/klayman.h | 16 | ||||
-rw-r--r-- | engines/neverhood/resourceman.cpp | 16 | ||||
-rw-r--r-- | engines/neverhood/sound.cpp | 11 |
7 files changed, 88 insertions, 38 deletions
diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp index f003728e4f..cb422a10e6 100644 --- a/engines/neverhood/blbarchive.cpp +++ b/engines/neverhood/blbarchive.cpp @@ -25,6 +25,29 @@ namespace Neverhood { +/** + * A special variant of SafeSeekableSubReadStream which locks a mutex during each read. + * This is neccessary because the music is streamed from disk and it could happen + * that a sound effect or another music track is played from the same read stream + * while the first music track is updated/read. + */ + +class SafeMutexedSeekableSubReadStream : public Common::SafeSeekableSubReadStream { +public: + SafeMutexedSeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream, + Common::Mutex &mutex) + : SafeSeekableSubReadStream(parentStream, begin, end, disposeParentStream), _mutex(mutex) { + } + virtual uint32 read(void *dataPtr, uint32 dataSize); +protected: + Common::Mutex &_mutex; +}; + +uint32 SafeMutexedSeekableSubReadStream::read(void *dataPtr, uint32 dataSize) { + Common::StackLock lock(_mutex); + return Common::SafeSeekableSubReadStream::read(dataPtr, dataSize); +} + BlbArchive::BlbArchive() : _extData(NULL) { } @@ -84,6 +107,8 @@ void BlbArchive::open(const Common::String &filename) { } void BlbArchive::load(uint index, byte *buffer, uint32 size) { + Common::StackLock lock(_mutex); + BlbArchiveEntry &entry = _entries[index]; _fd.seek(entry.offset); @@ -95,7 +120,11 @@ void BlbArchive::load(uint index, byte *buffer, uint32 size) { _fd.read(buffer, size); break; case 3: // DCL-compressed - Common::decompressDCL(&_fd, buffer, entry.diskSize, entry.size); + 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); @@ -110,7 +139,8 @@ byte *BlbArchive::getEntryExtData(uint index) { Common::SeekableReadStream *BlbArchive::createStream(uint index) { const BlbArchiveEntry &entry = _entries[index]; - return new Common::SafeSeekableSubReadStream(&_fd, entry.offset, entry.offset + entry.diskSize); + return new SafeMutexedSeekableSubReadStream(&_fd, entry.offset, entry.offset + entry.diskSize, + DisposeAfterUse::NO,_mutex); } } // End of namespace Neverhood diff --git a/engines/neverhood/blbarchive.h b/engines/neverhood/blbarchive.h index ddb3f0196b..cd2fd117b7 100644 --- a/engines/neverhood/blbarchive.h +++ b/engines/neverhood/blbarchive.h @@ -25,6 +25,7 @@ #include "common/array.h" #include "common/file.h" +#include "common/mutex.h" #include "common/stream.h" #include "common/substream.h" #include "neverhood/neverhood.h" @@ -63,6 +64,7 @@ public: Common::SeekableReadStream *createStream(uint index); private: Common::File _fd; + Common::Mutex _mutex; Common::Array<BlbArchiveEntry> _entries; byte *_extData; }; diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp index 3b1a8c9573..5b84e610ac 100644 --- a/engines/neverhood/gamemodule.cpp +++ b/engines/neverhood/gamemodule.cpp @@ -310,7 +310,7 @@ void GameModule::startup() { _vm->gameState().sceneNum = 0; createModule(2000, -1); #endif -#if 1 +#if 0 _vm->gameState().sceneNum = 5; createModule(2200, -1); #endif @@ -344,8 +344,9 @@ void GameModule::startup() { _vm->gameState().sceneNum = 1; createModule(2700, -1); #endif -#if 0 - _vm->gameState().sceneNum = 11; +#if 1 + setGlobalVar(0x1860C990, 1); // DEBUG Make Klayman small + _vm->gameState().sceneNum = 2; createModule(2800, -1); #endif #if 0 @@ -354,7 +355,7 @@ void GameModule::startup() { createModule(2500, -1); #endif #if 0 - _vm->gameState().sceneNum = 2; + _vm->gameState().sceneNum = 1; createModule(2400, -1); #endif } diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp index d7e68e6b30..dd5a5885b8 100644 --- a/engines/neverhood/klayman.cpp +++ b/engines/neverhood/klayman.cpp @@ -5024,7 +5024,7 @@ uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); - GotoState(&KmScene2242::sub444D20); + GotoState(&KmScene2242::stStartWalkingResume); } else { GotoState(&Klayman::stPeekWall); } @@ -5073,8 +5073,8 @@ uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam ¶m) { return 0; } -void KmScene2242::sub444D20() { - int16 frameIndex = (int16)getGlobalVar(0x18288913); +void KmScene2242::stStartWalkingResume() { + int16 frameIndex = getGlobalVar(0x18288913); if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; @@ -5109,7 +5109,7 @@ uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam ¶m case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); - GotoState(&KmHallOfRecords::sub43B130); + GotoState(&KmHallOfRecords::stStartWalkingResume); } else { GotoState(&Klayman::stPeekWall); } @@ -5142,8 +5142,8 @@ uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam ¶m return 0; } -void KmHallOfRecords::sub43B130() { - int16 frameIndex = (int16)getGlobalVar(0x18288913); +void KmHallOfRecords::stStartWalkingResume() { + int16 frameIndex = getGlobalVar(0x18288913); if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; @@ -5178,7 +5178,7 @@ uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam ¶m) { case 0x4804: if (param.asInteger() != 0) { _destX = param.asInteger(); - GotoState(&KmScene2247::sub453520); + GotoState(&KmScene2247::stStartWalkingResume); } else { GotoState(&Klayman::stPeekWall); } @@ -5211,8 +5211,8 @@ uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam ¶m) { return 0; } -void KmScene2247::sub453520() { - int16 frameIndex = (int16)getGlobalVar(0x18288913); +void KmScene2247::stStartWalkingResume() { + int16 frameIndex = getGlobalVar(0x18288913); if (frameIndex < 0 || frameIndex > 13) frameIndex = 0; _status2 = 0; @@ -5384,7 +5384,7 @@ uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam ¶m) { break; case 0x4004: if (!getGlobalVar(0x92603A79)) - GotoState(&KmScene2402::sub415840); + GotoState(&KmScene2402::stStandWonderAbout); else GotoState(&Klayman::stTryStandIdle); break; @@ -5442,7 +5442,7 @@ uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam ¶m) { return messageResult; } -void KmScene2402::sub415840() { +void KmScene2402::stStandWonderAbout() { if (_x > 260) setDoDeltaX(1); _status2 = 0; @@ -6027,11 +6027,11 @@ uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam ¶m) { startWalkToX(_dataResource.getPoint(param.asInteger()).x, false); break; case 0x4831: - GotoState(&KmScene2806::sub40F780); + GotoState(&KmScene2806::stGrow); break; case 0x4832: if (param.asInteger() == 1) { - GotoState(&KmScene2806::sub40F7C0); + GotoState(&KmScene2806::stDrinkPotion); } else { GotoState(&Klayman::stUseTube); } @@ -6040,7 +6040,7 @@ uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam ¶m) { return 0; } -uint32 KmScene2806::handleMessage40F1F0(int messageNum, const MessageParam ¶m, Entity *sender) { +uint32 KmScene2806::hmDrinkPotion(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x1008: @@ -6090,7 +6090,7 @@ uint32 KmScene2806::handleMessage40F1F0(int messageNum, const MessageParam ¶ return messageResult; } -uint32 KmScene2806::handleMessage40F570(int messageNum, const MessageParam ¶m, Entity *sender) { +uint32 KmScene2806::hmGrow(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = handleMessage41D480(messageNum, param, sender); switch (messageNum) { case 0x100D: @@ -6123,23 +6123,23 @@ uint32 KmScene2806::handleMessage40F570(int messageNum, const MessageParam ¶ return messageResult; } -void KmScene2806::sub40F780() { +void KmScene2806::stGrow() { _status2 = 0; _acceptInput = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); - SetMessageHandler(&KmScene2806::handleMessage40F570); + SetMessageHandler(&KmScene2806::hmGrow); startAnimation(0x2838C010, 0, -1); } -void KmScene2806::sub40F7C0() { +void KmScene2806::stDrinkPotion() { _status2 = 1; _acceptInput = false; _flag1 = false; _flag2 = false; SetUpdateHandler(&Klayman::update); SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); - SetMessageHandler(&KmScene2806::handleMessage40F1F0); + SetMessageHandler(&KmScene2806::hmDrinkPotion); startAnimation(0x1C388C04, 0, -1); } diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h index 3f3aafde35..25e6d38d2b 100644 --- a/engines/neverhood/klayman.h +++ b/engines/neverhood/klayman.h @@ -562,7 +562,7 @@ public: protected: void xUpdate(); uint32 xHandleMessage(int messageNum, const MessageParam ¶m); - void sub444D20(); + void stStartWalkingResume(); }; class KmHallOfRecords : public Klayman { @@ -571,7 +571,7 @@ public: protected: void xUpdate(); uint32 xHandleMessage(int messageNum, const MessageParam ¶m); - void sub43B130(); + void stStartWalkingResume(); }; class KmScene2247 : public Klayman { @@ -580,7 +580,7 @@ public: protected: void xUpdate(); uint32 xHandleMessage(int messageNum, const MessageParam ¶m); - void sub453520(); + void stStartWalkingResume(); }; class KmScene2401 : public Klayman { @@ -605,7 +605,7 @@ public: KmScene2402(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y); protected: uint32 xHandleMessage(int messageNum, const MessageParam ¶m); - void sub415840(); + void stStandWonderAbout(); }; class KmScene2403 : public Klayman { @@ -678,10 +678,10 @@ protected: bool _flag1; bool _flag2; uint32 xHandleMessage(int messageNum, const MessageParam ¶m); - uint32 handleMessage40F1F0(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 handleMessage40F570(int messageNum, const MessageParam ¶m, Entity *sender); - void sub40F780(); - void sub40F7C0(); + uint32 hmDrinkPotion(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmGrow(int messageNum, const MessageParam ¶m, Entity *sender); + void stGrow(); + void stDrinkPotion(); }; class KmScene2809 : public Klayman { diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp index c073e976a4..28cef366e1 100644 --- a/engines/neverhood/resourceman.cpp +++ b/engines/neverhood/resourceman.cpp @@ -77,6 +77,8 @@ BlbArchiveEntry *ResourceMan::getArchiveEntry(ResourceFileEntry *entry) const { int ResourceMan::useResource(uint32 fileHash) { ResourceFileEntry *entry = findEntry(fileHash); + if (!entry) + return -1; if (entry->resourceHandle != -1) { _resources[entry->resourceHandle]->useRefCount++; } else { @@ -94,6 +96,8 @@ int ResourceMan::useResource(uint32 fileHash) { } void ResourceMan::unuseResource(int resourceHandle) { + if (resourceHandle < 0) + return; Resource *resource = _resources[resourceHandle]; if (resource->useRefCount > 0) resource->useRefCount--; @@ -111,15 +115,21 @@ int ResourceMan::getResourceHandleByHash(uint32 fileHash) { } 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; } byte ResourceMan::getResourceType(int resourceHandle) { + if (resourceHandle < 0) + return 0; Resource *resource = _resources[resourceHandle]; return _archives[resource->archiveIndex]->getEntry(resource->entryIndex)->type; } @@ -130,6 +140,8 @@ byte ResourceMan::getResourceTypeByHash(uint32 fileHash) { } byte *ResourceMan::getResourceExtData(int resourceHandle) { + if (resourceHandle < 0) + return NULL; Resource *resource = _resources[resourceHandle]; return _archives[resource->archiveIndex]->getEntryExtData(resource->entryIndex); } @@ -140,6 +152,8 @@ byte *ResourceMan::getResourceExtDataByHash(uint32 fileHash) { } byte *ResourceMan::loadResource(int resourceHandle, bool moveToFront) { + if (resourceHandle < 0) + return NULL; Resource *resource = _resources[resourceHandle]; if (resource->data != NULL) { resource->dataRefCount++; @@ -154,6 +168,8 @@ byte *ResourceMan::loadResource(int resourceHandle, bool moveToFront) { } void ResourceMan::unloadResource(int resourceHandle) { + if (resourceHandle < 0) + return; Resource *resource = _resources[resourceHandle]; if (resource->dataRefCount > 0) resource->dataRefCount--; diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp index df66c6b777..c1db48c637 100644 --- a/engines/neverhood/sound.cpp +++ b/engines/neverhood/sound.cpp @@ -306,11 +306,11 @@ void SoundMan::update() { if (musicItem->_countdown) { --musicItem->_countdown; } else if (musicItem->_play && !musicItem->_musicResource->isPlaying()) { - debug("SoundMan: play music %08X (fade %d)", musicItem->_musicFileHash, musicItem->_fadeVolumeStep); + debug(1, "SoundMan: play music %08X (fade %d)", musicItem->_musicFileHash, musicItem->_fadeVolumeStep); musicItem->_musicResource->play(musicItem->_fadeVolumeStep); musicItem->_fadeVolumeStep = 0; } else if (musicItem->_stop) { - debug("SoundMan: stop music %08X (fade %d)", musicItem->_musicFileHash, musicItem->_fadeVolumeStep); + debug(1, "SoundMan: stop music %08X (fade %d)", musicItem->_musicFileHash, musicItem->_fadeVolumeStep); musicItem->_musicResource->stop(musicItem->_fadeVolumeStep); musicItem->_fadeVolumeStep = 0; musicItem->_stop = false; @@ -529,13 +529,11 @@ int16 AudioResourceMan::addSound(uint32 fileHash) { soundItem->_isPlaying = false; soundItem->_volume = 100; soundItem->_panning = 50; - for (uint i = 0; i < _soundItems.size(); ++i) if (!_soundItems[i]) { _soundItems[i] = soundItem; return i; } - int16 soundIndex = (int16)_soundItems.size(); _soundItems.push_back(soundItem); return soundIndex; @@ -591,6 +589,9 @@ void AudioResourceMan::playSound(int16 soundIndex, bool looping) { AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; if (!soundItem->_data) loadSound(soundIndex); + + if (!soundItem->_data) + return; uint32 soundSize = _vm->_res->getResourceSize(soundItem->_resourceHandle); Common::MemoryReadStream *stream = new Common::MemoryReadStream(soundItem->_data, soundSize, DisposeAfterUse::NO); @@ -600,7 +601,7 @@ void AudioResourceMan::playSound(int16 soundIndex, bool looping) { _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &soundItem->_soundHandle, audioStream, -1, VOLUME(soundItem->_volume), PANNING(soundItem->_panning)); - debug("playing sound %08X", soundItem->_fileHash); + debug(1, "playing sound %08X", soundItem->_fileHash); soundItem->_isPlaying = true; |