aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232012-09-27 17:07:41 +0000
committerWillem Jan Palenstijn2013-05-08 20:43:43 +0200
commita5986fd7222f32dfb00487542086cdd765a39208 (patch)
tree860f13d4f6ebe0162e8ef5e0d1f2f497dc7f308a
parent8bdddfdb02c0327af2985b81b4803b79de5a2b33 (diff)
downloadscummvm-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
-rw-r--r--engines/neverhood/blbarchive.cpp34
-rw-r--r--engines/neverhood/blbarchive.h2
-rw-r--r--engines/neverhood/gamemodule.cpp9
-rw-r--r--engines/neverhood/klayman.cpp38
-rw-r--r--engines/neverhood/klayman.h16
-rw-r--r--engines/neverhood/resourceman.cpp16
-rw-r--r--engines/neverhood/sound.cpp11
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 &param) {
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 &param) {
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 &param
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 &param
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 &param) {
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 &param) {
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 &param) {
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 &param) {
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 &param) {
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 &param) {
return 0;
}
-uint32 KmScene2806::handleMessage40F1F0(int messageNum, const MessageParam &param, Entity *sender) {
+uint32 KmScene2806::hmDrinkPotion(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage41D480(messageNum, param, sender);
switch (messageNum) {
case 0x1008:
@@ -6090,7 +6090,7 @@ uint32 KmScene2806::handleMessage40F1F0(int messageNum, const MessageParam &para
return messageResult;
}
-uint32 KmScene2806::handleMessage40F570(int messageNum, const MessageParam &param, Entity *sender) {
+uint32 KmScene2806::hmGrow(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage41D480(messageNum, param, sender);
switch (messageNum) {
case 0x100D:
@@ -6123,23 +6123,23 @@ uint32 KmScene2806::handleMessage40F570(int messageNum, const MessageParam &para
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 &param);
- void sub444D20();
+ void stStartWalkingResume();
};
class KmHallOfRecords : public Klayman {
@@ -571,7 +571,7 @@ public:
protected:
void xUpdate();
uint32 xHandleMessage(int messageNum, const MessageParam &param);
- void sub43B130();
+ void stStartWalkingResume();
};
class KmScene2247 : public Klayman {
@@ -580,7 +580,7 @@ public:
protected:
void xUpdate();
uint32 xHandleMessage(int messageNum, const MessageParam &param);
- 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 &param);
- void sub415840();
+ void stStandWonderAbout();
};
class KmScene2403 : public Klayman {
@@ -678,10 +678,10 @@ protected:
bool _flag1;
bool _flag2;
uint32 xHandleMessage(int messageNum, const MessageParam &param);
- uint32 handleMessage40F1F0(int messageNum, const MessageParam &param, Entity *sender);
- uint32 handleMessage40F570(int messageNum, const MessageParam &param, Entity *sender);
- void sub40F780();
- void sub40F7C0();
+ uint32 hmDrinkPotion(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmGrow(int messageNum, const MessageParam &param, 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;