aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232011-07-29 21:12:59 +0000
committerWillem Jan Palenstijn2013-05-08 20:39:34 +0200
commitd88836596d4c12763332d300c0da2282e24f535d (patch)
tree3ef10265c6cf0d86e08a6c734195f948c7c0853f
parent63fe7bd18a10e2799d6c6d4566aa6655636ad637 (diff)
downloadscummvm-rg350-d88836596d4c12763332d300c0da2282e24f535d.tar.gz
scummvm-rg350-d88836596d4c12763332d300c0da2282e24f535d.tar.bz2
scummvm-rg350-d88836596d4c12763332d300c0da2282e24f535d.zip
NEVERHOOD: More work on Module3000 and Scene3009 (incomplete)
-rw-r--r--engines/neverhood/gamemodule.cpp35
-rw-r--r--engines/neverhood/gamemodule.h1
-rw-r--r--engines/neverhood/module.cpp5
-rw-r--r--engines/neverhood/module.h3
-rw-r--r--engines/neverhood/module1800.cpp2
-rw-r--r--engines/neverhood/module3000.cpp857
-rw-r--r--engines/neverhood/module3000.h82
-rw-r--r--engines/neverhood/scene.cpp6
-rw-r--r--engines/neverhood/scene.h1
-rw-r--r--engines/neverhood/sprite.cpp2
-rw-r--r--engines/neverhood/sprite.h2
11 files changed, 979 insertions, 17 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 6d9c577065..f280399a01 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -214,12 +214,13 @@ void GameModule::startup() {
// createModule1500(0); // Logos and intro video //Real
// createModule1000(-1);
// createModule2300(2);
- _vm->gameState().sceneNum = 4;
+ _vm->gameState().sceneNum = 8;
//createModule1200(-1);
//createModule1800(-1);
//createModule1700(-1);
//createModule1700(1);
- createModule1400(-1);
+ //createModule1400(-1);
+ createModule3000(-1);
}
void GameModule::createModule1000(int which) {
@@ -418,7 +419,35 @@ void GameModule::createModule2400(int which) {
}
void GameModule::createModule3000(int which) {
- error("createModule3000");
+ setGlobalVar(0x91080831, 0x81293110);
+ _childObject = new Module3000(_vm, this, which);
+ SetUpdateHandler(&GameModule::updateModule3000);
+}
+
+void GameModule::updateModule3000() {
+ if (!_childObject)
+ return;
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 1) {
+ // TODO createModule1900(0);
+ // TODO _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ // WEIRD: Sets the errorFlag
+ } else if (_field20 == 3) {
+ createModule1800(3);
+ _childObject->handleUpdate();
+ } else if (_field20 == 4) {
+ // TODO createModule3000(0);
+ // TODO _childObject->handleUpdate();
+ } else {
+ createModule2300(4);
+ _childObject->handleUpdate();
+ }
+ }
}
} // End of namespace Neverhood
diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h
index d93a7994a7..8d5aace8e4 100644
--- a/engines/neverhood/gamemodule.h
+++ b/engines/neverhood/gamemodule.h
@@ -67,6 +67,7 @@ protected:
void updateModule2300();
void createModule2400(int which);
void createModule3000(int which);
+ void updateModule3000();
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/module.cpp b/engines/neverhood/module.cpp
index 15960e8e44..edf67c7ea3 100644
--- a/engines/neverhood/module.cpp
+++ b/engines/neverhood/module.cpp
@@ -72,6 +72,11 @@ uint32 Module::handleMessage(int messageNum, const MessageParam &param, Entity *
return 0;
}
+NavigationScene *Module::navigationScene() {
+ // Not so nice
+ return (NavigationScene*)_childObject;
+}
+
void Module::createNavigationScene(uint32 navigationListId, int navigationIndex, const byte *itemsTypes) {
_childObject = new NavigationScene(_vm, this, navigationListId, navigationIndex, itemsTypes);
}
diff --git a/engines/neverhood/module.h b/engines/neverhood/module.h
index fd35f0d135..470fe36c98 100644
--- a/engines/neverhood/module.h
+++ b/engines/neverhood/module.h
@@ -36,6 +36,8 @@
namespace Neverhood {
+class NavigationScene;
+
class Module : public Entity {
public:
Module(NeverhoodEngine *vm, Module *parentModule);
@@ -48,6 +50,7 @@ protected:
int16 _field24, _field26, _field28;
uint32 _field20;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ NavigationScene *navigationScene();
void createNavigationScene(uint32 navigationListId, int navigationIndex, const byte *itemsTypes = NULL);
void createSmackerScene(uint32 fileHash, bool doubleSurface, bool flag1, bool canAbort);
};
diff --git a/engines/neverhood/module1800.cpp b/engines/neverhood/module1800.cpp
index 1ce2d0f116..e2c88dc2b6 100644
--- a/engines/neverhood/module1800.cpp
+++ b/engines/neverhood/module1800.cpp
@@ -173,7 +173,7 @@ void Module1800::updateScene1801() {
void Module1800::updateScene1802() {
_childObject->handleUpdate();
if (_done) {
- int areaType = ((NavigationScene*)_childObject)->getNavigationAreaType();
+ int areaType = navigationScene()->getNavigationAreaType();
_done = false;
delete _childObject;
_childObject = NULL;
diff --git a/engines/neverhood/module3000.cpp b/engines/neverhood/module3000.cpp
index b2fd80f1e9..c82c111c82 100644
--- a/engines/neverhood/module3000.cpp
+++ b/engines/neverhood/module3000.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/module3000.h"
+#include "neverhood/navigationscene.h"
namespace Neverhood {
@@ -101,36 +102,115 @@ Module3000::~Module3000() {
// TODO Sound1ChList_sub_407A50(0x81293110);
}
+uint32 Module3000::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Module::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1009:
+ _moduleDone = true;
+ _moduleDoneStatus = param.asInteger();
+ break;
+ }
+ return messageResult;
+}
+
void Module3000::createScene3002(int which) {
- // TODO
+ _vm->gameState().sceneNum = 1;
+ if (!getGlobalVar(0x01BA1A52)) {
+ createNavigationScene(0x004B7C80, which);
+ } else if (getGlobalVar(0x10938830)) {
+ createNavigationScene(0x004B7CE0, which);
+ } else {
+ createNavigationScene(0x004B7CB0, which);
+ }
+ SetUpdateHandler(&Module3000::updateScene3002);
+}
+
+void Module3000::createScene3002b(int which) {
+ _vm->gameState().sceneNum = 1;
+ if (!getGlobalVar(0x01BA1A52)) {
+ if (getGlobalVar(0x10938830)) {
+ createSmackerScene(0x00940021, true, true, false);
+ } else {
+ createSmackerScene(0x01140021, true, true, false);
+ }
+ } else {
+ if (getGlobalVar(0x10938830)) {
+ createSmackerScene(0x001011B1, true, true, false);
+ } else {
+ createSmackerScene(0x001021B1, true, true, false);
+ }
+ }
+ SetUpdateHandler(&Module3000::updateScene3002b);
+ setGlobalVar(0x01BA1A52, getGlobalVar(0x01BA1A52) ? 0 : 1);
}
void Module3000::createScene3003(int which) {
- // TODO
+ _vm->gameState().sceneNum = 2;
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x40030A51, 0xC862CA15, 0);
+ if (_flag) {
+ _soundVolume = 90;
+ // TODO Sound1ChList_setVolume(0x90F0D1C3, 90);
+ }
+ if (getGlobalVar(0x10938830)) {
+ createNavigationScene(0x004B7D58, which);
+ } else {
+ createNavigationScene(0x004B7D10, which);
+ }
+ SetUpdateHandler(&Module3000::updateScene3003);
}
void Module3000::createScene3004(int which) {
- // TODO
+ _vm->gameState().sceneNum = 3;
+ if (getGlobalVar(0x09221A62)) {
+ createNavigationScene(0x004B7E60, which);
+ } else if (getGlobalVar(0x10938830)) {
+ createNavigationScene(0x004B7DA0, which);
+ } else {
+ createNavigationScene(0x004B7E00, which);
+ }
+ SetUpdateHandler(&Module3000::updateScene3004);
}
void Module3000::createScene3005(int which) {
- // TODO
+ _vm->gameState().sceneNum = 4;
+ if (getGlobalVar(0x09221A62)) {
+ createNavigationScene(0x004B7F20, which);
+ } else {
+ createNavigationScene(0x004B7EC0, which);
+ }
+ SetUpdateHandler(&Module3000::updateScene3005);
}
void Module3000::createScene3006(int which) {
- // TODO
+ static const byte kNavigationTypes[] = {3, 0};
+ _vm->gameState().sceneNum = 5;
+ createNavigationScene(0x004B7F80, which, kNavigationTypes);
+ SetUpdateHandler(&Module3000::updateScene3006);
}
void Module3000::createScene3007(int which) {
- // TODO
+ static const byte kNavigationTypes[] = {5};
+ _vm->gameState().sceneNum = 6;
+ createNavigationScene(0x004B7FB0, which, kNavigationTypes);
+ SetUpdateHandler(&Module3000::updateScene3007);
}
void Module3000::createScene3008(int which) {
- // TODO
+ _vm->gameState().sceneNum = 6;
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4B7FC8, 0, 0, 0, 0, 0);
+ if (!getSubVar(0x40050052, 0x089809C2)) {
+ setSubVar(0x40050052, 0x089809C2, 1);
+ createSmackerScene(0x90022001, true, true, false);
+ } else {
+ createSmackerScene(0x98022001, true, true, false);
+ }
+ SetUpdateHandler(&Module3000::updateScene3002b);
}
void Module3000::createScene3009(int which) {
- // TODO
+ _vm->gameState().sceneNum = 7;
+ _childObject = new Scene3009(_vm, this, which);
+ SetUpdateHandler(&Module3000::updateScene3009);
}
void Module3000::createScene3010(int which) {
@@ -144,11 +224,260 @@ void Module3000::createScene3011(int which) {
}
void Module3000::createScene3012(int which) {
- // TODO
+ _vm->gameState().sceneNum = 11;
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4B7FC8, 0, 0, 0, 0, 0);
+ if (!getSubVar(0x40050052, 0x10130993)) {
+ setSubVar(0x40050052, 0x10130993, 1);
+ createSmackerScene(0x31093019, true, true, false);
+ } else {
+ createSmackerScene(0x20093019, true, true, false);
+ }
+ SetUpdateHandler(&Module3000::updateScene3002b);
}
void Module3000::createScene3013(int which) {
- // TODO
+ _vm->gameState().sceneNum = 12;
+ _childObject = new Scene3010(_vm, this, 1);
+ SetUpdateHandler(&Module3000::updateScene3002b);
+}
+
+void Module3000::updateScene3002() {
+ _childObject->handleUpdate();
+#if 0 // ALL TODO
+ if (navigationScene()->getSoundFlag1()) {
+ uint32 frameNumber = navigationScene()->getFrameNumber();
+ int navigationIndex = navigationScene()->getIndex();
+ if (navigationIndex == 1) {
+ if (frameNumber == 0) {
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x48498E46, 0x50399F64, 0);
+ // TODO Sound1ChList_setVolume(0x48498E46, 70);
+ // TODO Sound1ChList_setVolume(0x50399F64, 70);
+ } else if (frameNumber == 100) {
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x41861371, 0x43A2507F, 0);
+ }
+ } else if (navigationIndex == 0) {
+ if (frameNumber == 0) {
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x48498E46, 0x50399F64, 0);
+ // TODO Sound1ChList_setVolume(0x48498E46, 70);
+ // TODO Sound1ChList_setVolume(0x50399F64, 70);
+ } else if (frameNumber == 10) {
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x40030A51, 0xC862CA15, 0);
+ }
+ if (_flag && _soundVolume < 90 && frameNumber % 2) {
+ if (frameNumber == 0)
+ _soundVolume = 40;
+ else
+ _soundVolume++;
+ // TODO Sound1ChList_setVolume(0x90F0D1C3, _soundVolume);
+ }
+ }
+ }
+#endif
+ if (_moduleDone) {
+ int areaType = navigationScene()->getNavigationAreaType();
+ _moduleDone = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (!getGlobalVar(0x01BA1A52)) {
+ if (_moduleDoneStatus == 0) {
+ createScene3010(-1);
+ _childObject->handleUpdate();
+ } else if (_moduleDoneStatus == 1) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ } else {
+ if (_moduleDoneStatus == 0) {
+ if (areaType == 2) {
+ createScene3003(0);
+ _childObject->handleUpdate();
+ } else {
+ //createScene3002b(-1);
+ _childObject->handleUpdate();
+ }
+ } else if (_moduleDoneStatus == 1) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ }
+ }
+}
+
+void Module3000::updateScene3002b() {
+ _childObject->handleUpdate();
+ if (_moduleDone) {
+ _moduleDone = false;
+ delete _childObject;
+ _childObject = NULL;
+ switch (_vm->gameState().sceneNum) {
+ case 1:
+ if (getGlobalVar(0x01BA1A52)) {
+ createScene3002(0);
+ _childObject->handleUpdate();
+ } else {
+ createScene3013(-1);
+ _childObject->handleUpdate();
+ }
+ break;
+ case 7:
+ case 8:
+ createScene3009(-1);
+ break;
+ case 11:
+ _parentModule->sendMessage(0x1009, 3, this);
+ break;
+ case 12:
+ createScene3002(0);
+ _childObject->handleUpdate();
+ break;
+ default:
+ createScene3006(0);
+ break;
+ }
+ }
+}
+
+void Module3000::updateScene3003() {
+ _childObject->handleUpdate();
+#if 0 // ALL TODO
+ if (navigationScene()->getSoundFlag1()) {
+ uint32 frameNumber = navigationScene()->getFrameNumber();
+ int navigationIndex = navigationScene()->getIndex();
+ if (_flag && _soundVolume > 1 && frameNumber % 2) {
+ _soundVolume--;
+ // TODO Sound1ChList_setVolume(0x90F0D1C3, _soundVolume);
+ }
+ if (navigationIndex == 0) {
+ if (frameNumber == 35) {
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x41861371, 0x43A2507F, 0);
+ }
+ } else if (navigationIndex == 1) {
+ if (frameNumber == 55) {
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x48498E46, 0x50399F64, 0);
+ // TODO Sound1ChList_setVolume(0x48498E46, 70);
+ // TODO Sound1ChList_setVolume(0x50399F64, 70);
+ }
+ }
+ }
+#endif
+ if (_moduleDone) {
+ _moduleDone = false;
+ delete _childObject;
+ _childObject = NULL;
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x41861371, 0x43A2507F, 0);
+ if (_flag) {
+ _soundVolume = 0;
+ // TODO Sound1ChList_setVolume(0x90F0D1C3, 0);
+ }
+ if (_moduleDoneStatus == 0) {
+ createScene3004(0);
+ _childObject->handleUpdate();
+ } else if (_moduleDoneStatus == 1) {
+ setGlobalVar(0x01BA1A52, 0);
+ createScene3002(1);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module3000::updateScene3004() {
+ _childObject->handleUpdate();
+#if 0 // ALL TODO
+ if (navigationScene()->getSoundFlag1()) {
+ uint32 frameNumber = navigationScene()->getFrameNumber();
+ int navigationIndex = navigationScene()->getIndex();
+ if (navigationIndex == 2) {
+ if (frameNumber == 40) {
+ // TODO Sound1ChList_sub_407C70(0x81293110, 0x40030A51, 0xC862CA15, 0);
+ }
+ if (_flag && _soundVolume < 90 && frameNumber % 2) {
+ if (frameNumber == 0)
+ _soundVolume = 40;
+ else
+ _soundVolume++;
+ // TODO Sound1ChList_setVolume(0x90F0D1C3, _soundVolume);
+ }
+ }
+ }
+#endif
+ if (_moduleDone) {
+ _moduleDone = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_moduleDoneStatus == 1) {
+ createScene3005(0);
+ _childObject->handleUpdate();
+ } else if (_moduleDoneStatus == 3) {
+ createScene3011(-1);
+ _childObject->handleUpdate();
+ } else if (getGlobalVar(0x09221A62)) {
+ createScene3006(0);
+ _childObject->handleUpdate();
+ } else {
+ createScene3003(1);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module3000::updateScene3005() {
+ _childObject->handleUpdate();
+ if (_moduleDone) {
+ _moduleDone = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_moduleDoneStatus == 0) {
+ _parentModule->sendMessage(0x1009, 1, this);
+ } else if (_moduleDoneStatus == 1) {
+ createScene3008(-1);
+ _childObject->handleUpdate();
+ } else if (_moduleDoneStatus == 2) {
+ createScene3004(3);
+ _childObject->handleUpdate();
+ }
+ }
+ // NOTE: Skipped resource preloading stuff
+}
+
+void Module3000::updateScene3006() {
+ _childObject->handleUpdate();
+#if 0 // ALL TODO
+ if (navigationScene()->getSoundFlag1() && navigationScene()->getIndex() == 0) {
+ // TODO Sound1ChList_sub_4080B0(false);
+ }
+#endif
+ if (_moduleDone) {
+ _moduleDone = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_moduleDoneStatus == 0) {
+ createScene3007(0);
+ _childObject->handleUpdate();
+ } else if (_moduleDoneStatus == 1) {
+ createScene3004(0);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module3000::updateScene3007() {
+ _childObject->handleUpdate();
+ if (_moduleDone) {
+ int areaType = navigationScene()->getNavigationAreaType();
+ _moduleDone = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (areaType == 4) {
+ createScene3012(-1);
+ _childObject->handleUpdate();
+ } else {
+ createSmackerScene(0x080810C5, true, true, false);
+ SetUpdateHandler(&Module3000::updateScene3002b);
+ }
+ }
+}
+
+void Module3000::updateScene3009() {
+ _childObject->handleUpdate();
+ // TODO...
}
void Module3000::updateScene3010() {
@@ -157,9 +486,517 @@ void Module3000::updateScene3010() {
_done = false;
delete _childObject;
_childObject = NULL;
+ if (_moduleDoneStatus == 0 || _moduleDoneStatus == 2) {
+ createScene3002(0);
+ _childObject->handleUpdate();
+ } else if (_moduleDoneStatus == 1) {
+ createScene3002b(-1);
+ _childObject->handleUpdate();
+ }
}
}
+// Scene3009
+
+static const uint32 kScene3009SmackerFileHashes[] = {
+ 0x1010000D,
+ 0x340A0049,
+ 0x340A0049,
+ 0x0282081D,
+ 0x0082080D,
+ 0x0882080D,
+ 0x0882080D,
+ 0x0282081D,
+ 0x004B000B,
+ 0x014B000B,
+ 0x044B000B,
+ 0x0282081D,
+ 0x0282081D,
+ 0x0282081D,
+ 0x340A0049
+};
+
+static const uint32 kScene3009VarValues[] = {
+ 0x00000000,
+ 0x8004001B,
+ 0x0004001A,
+ 0x1048404B,
+ 0x50200109,
+ 0x12032109,
+ 0x10201109,
+ 0x000A2030,
+ 0x000A0028,
+ 0x000A0028,
+ 0x000A0028,
+ 0x040A1069,
+ 0x040A1069,
+ 0x040A1069,
+ 0x240A1101
+};
+
+static const uint32 kClass439FileHashes[] = {
+ 0x618827A0,
+ 0xB1A92322
+};
+
+static const uint32 kClass440FileHashes[] = {
+ 0x4011018C,
+ 0x15086623
+};
+
+static const NPoint kClass524Points[] = {
+ {289, 338},
+ {285, 375},
+ {284, 419},
+ {456, 372},
+ {498, 372},
+ {541, 372}
+};
+
+static const uint32 kClass524FileHashes[] = {
+ 0x24542582,
+ 0x1CD61D96
+};
+
+static const uint32 kClass441FileHashes1[] = {
+ 0x24016060,
+ 0x21216221,
+ 0x486160A0,
+ 0x42216422,
+ 0x90A16120,
+ 0x84216824,
+ 0x08017029,
+ 0x08217029,
+ 0x10014032,
+ 0x10214032,
+ 0x20012004,
+ 0x20212004
+};
+
+static const uint32 kClass441FileHashes2[] = {
+ 0x40092024,
+ 0x01636002,
+ 0x8071E028,
+ 0x02A56064,
+ 0x00806031,
+ 0x052960A8,
+ 0x0A116130,
+ 0x0A316130,
+ 0x14216200,
+ 0x14016200,
+ 0x28416460,
+ 0x28616460
+};
+
+Class438::Class438(NeverhoodEngine *vm, Scene3009 *parentScene)
+ : StaticSprite(vm, 1400), _soundResource(vm), _parentScene(parentScene),
+ _flag1(false) {
+
+ _spriteResource.load2(0x120B24B0);
+ createSurface(400, _spriteResource.getDimensions().width, _spriteResource.getDimensions().height);
+ _x = _spriteResource.getPosition().x;
+ _y = _spriteResource.getPosition().y;
+ _drawRect.x = 0;
+ _drawRect.y = 0;
+ _drawRect.width = _spriteResource.getDimensions().width;
+ _drawRect.height = _spriteResource.getDimensions().height;
+ _deltaRect.x = 0;
+ _deltaRect.y = 0;
+ _deltaRect.width = _spriteResource.getDimensions().width;
+ _deltaRect.height = _spriteResource.getDimensions().height;
+ _surface->setVisible(false);
+ processDelta();
+ _needRefresh = true;
+ SetUpdateHandler(&Class438::update);
+ SetMessageHandler(&Class438::handleMessage);
+ _soundResource.load(0x3901B44F);
+}
+
+void Class438::update() {
+ StaticSprite::update();
+ if (_flag1 && !_soundResource.isPlaying()) {
+ _parentScene->sendMessage(0x2000, 0, this);
+ _surface->setVisible(false);
+ }
+}
+
+uint32 Class438::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_flag1 && !_parentScene->sub462E90()) {
+ _flag1 = true;
+ _surface->setVisible(true);
+ _soundResource.play();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+Class439::Class439(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400), _blinkCountdown(0) {
+
+ _spriteResource.load2(kClass439FileHashes[index]);
+ createSurface(600, _spriteResource.getDimensions().width, _spriteResource.getDimensions().height);
+ _x = _spriteResource.getPosition().x;
+ _y = _spriteResource.getPosition().y;
+ _drawRect.x = 0;
+ _drawRect.y = 0;
+ _drawRect.width = _spriteResource.getDimensions().width;
+ _drawRect.height = _spriteResource.getDimensions().height;
+ _needRefresh = true;
+ if (getGlobalVar(0x0C0288F4)) {
+ hide();
+ } else {
+ startBlinking();
+ }
+ SetUpdateHandler(&Class439::update);
+}
+
+void Class439::update() {
+ if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
+ if (_blinkToggle) {
+ _surface->setVisible(true);
+ } else {
+ _surface->setVisible(false);
+ }
+ StaticSprite::update();
+ _blinkCountdown = 3;
+ _blinkToggle = !_blinkToggle;
+ }
+}
+
+void Class439::show() {
+ _surface->setVisible(true);
+ StaticSprite::update();
+ _blinkCountdown = 0;
+}
+
+void Class439::hide() {
+ _surface->setVisible(false);
+ StaticSprite::update();
+ _blinkCountdown = 0;
+}
+
+void Class439::startBlinking() {
+ _surface->setVisible(true);
+ StaticSprite::update();
+ _blinkCountdown = 3;
+ _blinkToggle = true;
+}
+
+Class440::Class440(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400) {
+
+ _spriteResource.load2(kClass440FileHashes[index]);
+ createSurface(600, _spriteResource.getDimensions().width, _spriteResource.getDimensions().height);
+ _x = _spriteResource.getPosition().x;
+ _y = _spriteResource.getPosition().y;
+ _drawRect.x = 0;
+ _drawRect.y = 0;
+ _drawRect.width = _spriteResource.getDimensions().width;
+ _drawRect.height = _spriteResource.getDimensions().height;
+ _surface->setVisible(false);
+ _needRefresh = true;
+}
+
+Class522::Class522(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
+
+ _x = 300;
+ _y = getGlobalVar(0x000809C2) ? 52 : 266;
+ createSurface1(0xC2463913, 1200);
+ _needRefresh = true;
+ updatePosition();
+ _surface->setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Class522::handleMessage);
+}
+
+void Class522::show() {
+ setFileHash(0xC2463913, 0, -1);
+ _surface->setVisible(true);
+ updatePosition();
+ _enabled = true;
+}
+
+uint32 Class522::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled) {
+ _parentScene->sendMessage(0x2002, 0, this);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _flag1(false), _flag2(false),
+ _flag3(false), _flag4(false), _countdown1(1), _countdown2(1) {
+
+ _varValue = getGlobalVar(0x20580A86);
+
+ // TODO _vm->gameModule()->initScene3009Vars();
+
+ setGlobalVar(0xF0402B0A, 0);
+ _surfaceFlag = true;
+
+ _vm->_screen->clear();
+
+ _background = addBackground(new DirtyBackground(_vm, 0xD000420C, 0, 0));
+ _palette = new Palette(_vm, 0xD000420C);
+ _palette->usePalette();
+ _mouseCursor = addSprite(new Mouse435(_vm, 0x04208D08, 20, 620));
+
+ _class438 = addSprite(new Class438(_vm, this));
+ _vm->_collisionMan->addSprite(_class438);
+
+ _class522 = new Class522(_vm, this, _varValue);
+ addSprite(_class522);
+ _vm->_collisionMan->addSprite(_class522);
+
+#if 0
+ _class523 = new Class523(_vm, this, _varValue);
+ addSprite(_class523);
+ _vm->_collisionMan->addSprite(_class523);
+#endif
+
+ if (_varValue != 0 && _varValue != 8 && _varValue != 9 && _varValue != 9) {
+ _flag1 = true;
+ } else {
+ _flag1 = false;
+ if (_varValue == 0) {
+#if 0
+ _class523->stMoveUp();
+#endif
+ _flag4 = true;
+ }
+ }
+
+ _smackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, kScene3009SmackerFileHashes[_varValue], false, _flag1));
+ _smackerPlayer->setDrawPos(89, 37);
+
+ addSprite(new StaticSprite(_vm, 0x8540252C, 400));
+
+ for (int i = 0; i < 2; i++) {
+ _class439Array[i] = new Class439(_vm, i);
+ addSprite(_class439Array[i]);
+ _class440Array[i] = new Class440(_vm, i);
+ addSprite(_class440Array[i]);
+ }
+
+
+#if 0
+ for (int i = 0; i < 6; i++) {
+ _class524Array[i] = new Class524(_vm, this, i);
+ addSprite(_class524Array[i]);
+ if (i < 3)
+ _varValueArray[i] = getSubVar(0x00504B86, i);
+ else
+ _varValueArray[i] = getSubVar(0x0A4C0A9A, i - 3);
+ }
+#endif
+
+ SetMessageHandler(&Scene3009::handleMessage);
+ SetUpdateHandler(&Scene3009::update);
+}
+
+void Scene3009::update() {
+ Scene::update();
+ if (!_flag1 && _smackerPlayer->getFrameNumber() + 1 == _smackerPlayer->getFrameCount() && _varValue <= 14) {
+ switch (_varValue) {
+ case 0:
+ case 14:
+ _smackerPlayer->open(0x340A0049, true);
+ _palette->usePalette();
+ _flag1 = true;
+ break;
+ case 8:
+ _smackerPlayer->open(0x0082080D, true);
+ _palette->usePalette();
+ _flag1 = true;
+ _flag4 = false;
+ break;
+ case 9:
+ _smackerPlayer->open(0x0282080D, true);
+ _palette->usePalette();
+ _flag1 = true;
+ _flag4 = false;
+ break;
+ case 10:
+ _smackerPlayer->open(0x0882080D, true);
+ _palette->usePalette();
+ _flag1 = true;
+ _flag4 = false;
+ break;
+ case 11:
+ case 12:
+ case 13:
+ if (_flag2) {
+ if (_varValue == 11)
+ _smackerPlayer->open(0x110A000F, false);
+ else if (_varValue == 12)
+ _smackerPlayer->open(0x500B004F, false);
+ else if (_varValue == 13)
+ _smackerPlayer->open(0x100B010E, false);
+ _palette->usePalette();
+ _flag2 = false;
+#if 0
+ _class523->stMoveDown();
+#endif
+ } else {
+ sub462DC0();
+ }
+ break;
+ }
+ }
+
+ if (_countdown1 != 0 && (--_countdown1 == 0) && sub462E10()) {
+#if 0
+ for (int i = 0; i < 3; i++)
+ _class524Array[i]->hide();
+#endif
+ if (!getGlobalVar(0x0C0288F4) || getGlobalVar(0x000809C2) || getGlobalVar(0x9040018A)) {
+ _class439Array[0]->show();
+ _class440Array[0]->getSurface()->setVisible(true);
+ // TODO _class440Array->StaticSprite_update
+ _class522->show();
+ }
+ }
+
+ if (_countdown2 != 0 && (--_countdown2 == 0) && sub462E50()) {
+#if 0
+ for (int i = 0; i < 6; i++)
+ _class524Array[i]->hide();
+#endif
+ if (!getGlobalVar(0x0C0288F4) || getGlobalVar(0x000809C2) || getGlobalVar(0x9040018A)) {
+ _class439Array[1]->show();
+ _class440Array[1]->getSurface()->setVisible(true);
+#if 0
+ // TODO _class440Array[1]->StaticSprite_update
+ _class523->show();
+#endif
+ }
+ }
+
+}
+
+uint32 Scene3009::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ // TODO: Debug stuff
+ if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !getGlobalVar(0x000809C2)) {
+ setGlobalVar(0x20580A86, 0);
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ break;
+ case 0x000D:
+ // TODO: Debug stuff
+ break;
+ case 0x2000:
+ if (!getGlobalVar(0x000809C2)) {
+ if (!getGlobalVar(0x10938830)) {
+ _varValue = 1;
+ setGlobalVar(0x10938830, 1);
+ } else {
+ _varValue = 2;
+ }
+ } else if (!getGlobalVar(0x9040018A)) {
+ _varValue = 3;
+ } else if (!getGlobalVar(0x610210B7)) {
+ _varValue = 4;
+ } else if (!getGlobalVar(0x0C0288F4)) {
+ setGlobalVar(0x0C0288F4, 1);
+ _varValue = 5;
+ } else {
+ _varValue = 6;
+ }
+ sub462DC0();
+ break;
+ case 0x2001:
+ _countdown1 = 24;
+ break;
+ case 0x2002:
+ if (!getGlobalVar(0x9040018A) && !_flag4) {
+ if (getGlobalVar(0x000809C2)) {
+ _varValue = 14;
+ setGlobalVar(0x000809C2, 0);
+ } else {
+ _varValue = 7;
+ setGlobalVar(0x000809C2, 1);
+ }
+ sub462DC0();
+ }
+ break;
+ case 0x2003:
+ _countdown2 = 24;
+ break;
+ case 0x2004:
+ if (getGlobalVar(0x000809C2)) {
+ if (!getGlobalVar(0x9040018A)) {
+ if (!getGlobalVar(0x610210B7)) {
+ _varValue = 8;
+ } else {
+ if (!getGlobalVar(0x0C0288F4)) {
+ _varValue = 9;
+ } else {
+ _varValue = 10;
+ }
+ }
+ setGlobalVar(0x9040018A, 1);
+ _flag4 = true;
+ sub462DC0();
+ } else if (!getGlobalVar(0x610210B7)) {
+ _varValue = 11;
+ _smackerPlayer->open(0x108A000F, false);
+ } else if (!getGlobalVar(0x0C0288F4)) {
+ _varValue = 12;
+ _smackerPlayer->open(0x500B002F, false);
+ } else {
+ _varValue = 13;
+ _smackerPlayer->open(0x100B008E, false);
+ }
+ _palette->usePalette();
+ _flag2 = true;
+ _flag4 = true;
+ _flag1 = false;
+ setGlobalVar(0x9040018A, 0);
+ }
+ break;
+ }
+ return 0;
+}
+
+void Scene3009::sub462DC0() {
+ setGlobalVar(0x20580A86, _varValue);
+ setGlobalVar(0xF0402B0A, kScene3009VarValues[_varValue]);
+ _parentModule->sendMessage(0x1009, 1, this);
+}
+
+bool Scene3009::sub462E10() {
+ for (int i = 0; i < 3; i++)
+ if (_varValueArray[i] != getSubVar(0x00000914, i))
+ return false;
+ return true;
+}
+
+bool Scene3009::sub462E50() {
+ for (int i = 0; i < 6; i++)
+ if (_varValueArray[i] != getSubVar(0x00000914, i))
+ return false;
+ return true;
+}
+
+bool Scene3009::sub462E90() {
+ return _flag3 || _flag4;
+}
+
// Scene3010
static const uint32 kScene3010VarNameHashes[] = {
diff --git a/engines/neverhood/module3000.h b/engines/neverhood/module3000.h
index b2375fca13..9bda5db2af 100644
--- a/engines/neverhood/module3000.h
+++ b/engines/neverhood/module3000.h
@@ -39,7 +39,9 @@ protected:
int _moduleDoneStatus;
int _soundVolume;
bool _flag;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void createScene3002(int which);
+ void createScene3002b(int which);
void createScene3003(int which);
void createScene3004(int which);
void createScene3005(int which);
@@ -51,9 +53,89 @@ protected:
void createScene3011(int which);
void createScene3012(int which);
void createScene3013(int which);
+ void updateScene3002();
+ void updateScene3002b();
+ void updateScene3003();
+ void updateScene3004();
+ void updateScene3005();
+ void updateScene3006();
+ void updateScene3007();
+ void updateScene3009();
void updateScene3010();
};
+// Scene3009
+
+class Scene3009;
+
+class Class438 : public StaticSprite {
+public:
+ Class438(NeverhoodEngine *vm, Scene3009 *parentScene);
+protected:
+ Scene3009 *_parentScene;
+ SoundResource _soundResource;
+ bool _flag1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class Class439 : public StaticSprite {
+public:
+ Class439(NeverhoodEngine *vm, int index);
+ void show();
+ void hide();
+ void startBlinking();
+protected:
+ int _blinkCountdown;
+ bool _blinkToggle;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class Class440 : public StaticSprite {
+public:
+ Class440(NeverhoodEngine *vm, int index);
+};
+
+class Class522 : public AnimatedSprite {
+public:
+ Class522(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
+ void show();
+protected:
+ Scene3009 *_parentScene;
+ bool _enabled;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class Scene3009 : public Scene {
+public:
+ Scene3009(NeverhoodEngine *vm, Module *parentModule, int which);
+ bool sub462E90();
+protected:
+ int _countdown1;
+ int _countdown2;
+ SmackerPlayer *_smackerPlayer;
+ Sprite *_class438;
+ Class439 *_class439Array[2];
+ Class440 *_class440Array[2];
+ Class522 *_class522;
+#if 0
+ Class523 *_class523;
+ Class524 *_class524Array[6];
+#endif
+ uint32 _varValue;
+ uint32 _varValueArray[6];
+ bool _flag1;
+ bool _flag2;
+ bool _flag3;
+ bool _flag4;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void sub462DC0();
+ bool sub462E10();
+ bool sub462E50();
+};
+
// Scene3010
class SsScene3010DeadBoltButton : public StaticSprite {
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index b9a464c1e9..2c6b10ef4b 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -179,6 +179,12 @@ Background *Scene::addBackground(Background *background) {
return background;
}
+SmackerPlayer *Scene::addSmackerPlayer(SmackerPlayer *smackerPlayer) {
+ addEntity(smackerPlayer);
+ addSurface(smackerPlayer->getSurface());
+ return smackerPlayer;
+}
+
void Scene::update() {
if (_smkFileHash != 0) {
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index 65326c310f..ab5cf9f90e 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -50,6 +50,7 @@ public:
void setSurfacePriority(BaseSurface *surface, int priority);
void deleteSprite(Sprite **sprite);
Background *addBackground(Background *background);
+ SmackerPlayer *addSmackerPlayer(SmackerPlayer *smackerPlayer);
void update();
protected:
Module *_parentModule;
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index ee6e7aa942..deb54af8e1 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -140,8 +140,6 @@ void StaticSprite::init(uint32 fileHash, int surfacePriority, int16 x, int16 y,
_x = x == kDefPosition ? _spriteResource.getPosition().x : x;
_y = y == kDefPosition ? _spriteResource.getPosition().y : y;
- debug("StaticSprite::init() final: x = %d; y = %d", _x, _y);
-
_drawRect.x = 0;
_drawRect.y = 0;
_drawRect.width = width;
diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h
index a518c39da2..7ec5d9124a 100644
--- a/engines/neverhood/sprite.h
+++ b/engines/neverhood/sprite.h
@@ -96,7 +96,7 @@ public:
void update();
protected:
SpriteResource _spriteResource;
- void init(uint32 fileHash, int surfacePriority, int16 x, int16 y, int16 width, int16 height);
+ void init(uint32 fileHash, int surfacePriority, int16 x = kDefPosition, int16 y = kDefPosition, int16 width = 0, int16 height = 0);
};
#define SetAnimationCallback1(callback) _callback1Cb = static_cast <void (AnimatedSprite::*)(void)> (callback); debug("SetAnimationCallback1(" #callback ")"); _callback1CbName = #callback