aboutsummaryrefslogtreecommitdiff
path: root/engines/neverhood
diff options
context:
space:
mode:
Diffstat (limited to 'engines/neverhood')
-rw-r--r--engines/neverhood/POTFILES2
-rw-r--r--engines/neverhood/blbarchive.cpp3
-rw-r--r--engines/neverhood/console.cpp98
-rw-r--r--engines/neverhood/console.h5
-rw-r--r--engines/neverhood/detection.cpp8
-rw-r--r--engines/neverhood/gamemodule.cpp2
-rw-r--r--engines/neverhood/klaymen.cpp3394
-rw-r--r--engines/neverhood/klaymen.h406
-rw-r--r--engines/neverhood/menumodule.cpp12
-rw-r--r--engines/neverhood/menumodule.h1
-rw-r--r--engines/neverhood/module.h1
-rw-r--r--engines/neverhood/module.mk18
-rw-r--r--engines/neverhood/modules/module1000.cpp984
-rw-r--r--engines/neverhood/modules/module1000.h190
-rw-r--r--engines/neverhood/modules/module1000_sprites.cpp1567
-rw-r--r--engines/neverhood/modules/module1000_sprites.h257
-rw-r--r--engines/neverhood/modules/module1100.cpp190
-rw-r--r--engines/neverhood/modules/module1100.h51
-rw-r--r--engines/neverhood/modules/module1100_sprites.cpp265
-rw-r--r--engines/neverhood/modules/module1100_sprites.h88
-rw-r--r--engines/neverhood/modules/module1200.cpp642
-rw-r--r--engines/neverhood/modules/module1200.h136
-rw-r--r--engines/neverhood/modules/module1200_sprites.cpp810
-rw-r--r--engines/neverhood/modules/module1200_sprites.h187
-rw-r--r--engines/neverhood/modules/module1300.cpp620
-rw-r--r--engines/neverhood/modules/module1300.h129
-rw-r--r--engines/neverhood/modules/module1300_sprites.cpp935
-rw-r--r--engines/neverhood/modules/module1300_sprites.h200
-rw-r--r--engines/neverhood/modules/module1400.cpp878
-rw-r--r--engines/neverhood/modules/module1400.h151
-rw-r--r--engines/neverhood/modules/module1400_sprites.cpp1129
-rw-r--r--engines/neverhood/modules/module1400_sprites.h198
-rw-r--r--engines/neverhood/modules/module1600.cpp827
-rw-r--r--engines/neverhood/modules/module1600.h91
-rw-r--r--engines/neverhood/modules/module1600_sprites.cpp934
-rw-r--r--engines/neverhood/modules/module1600_sprites.h126
-rw-r--r--engines/neverhood/modules/module1700.cpp46
-rw-r--r--engines/neverhood/modules/module1700.h17
-rw-r--r--engines/neverhood/modules/module1700_sprites.cpp156
-rw-r--r--engines/neverhood/modules/module1700_sprites.h55
-rw-r--r--engines/neverhood/modules/module1800.cpp5
-rw-r--r--engines/neverhood/modules/module1900.cpp393
-rw-r--r--engines/neverhood/modules/module1900.h73
-rw-r--r--engines/neverhood/modules/module1900_sprites.cpp456
-rw-r--r--engines/neverhood/modules/module1900_sprites.h107
-rw-r--r--engines/neverhood/modules/module2000.cpp3
-rw-r--r--engines/neverhood/modules/module2000.h3
-rw-r--r--engines/neverhood/modules/module2000_sprites.cpp92
-rw-r--r--engines/neverhood/modules/module2000_sprites.h41
-rw-r--r--engines/neverhood/modules/module2100.cpp123
-rw-r--r--engines/neverhood/modules/module2100.h32
-rw-r--r--engines/neverhood/modules/module2100_sprites.cpp260
-rw-r--r--engines/neverhood/modules/module2100_sprites.h75
-rw-r--r--engines/neverhood/modules/module2200.cpp866
-rw-r--r--engines/neverhood/modules/module2200.h176
-rw-r--r--engines/neverhood/modules/module2200_sprites.cpp1429
-rw-r--r--engines/neverhood/modules/module2200_sprites.h275
-rw-r--r--engines/neverhood/modules/module2300.cpp2
-rw-r--r--engines/neverhood/modules/module2400.cpp335
-rw-r--r--engines/neverhood/modules/module2400.h70
-rw-r--r--engines/neverhood/modules/module2400_sprites.cpp741
-rw-r--r--engines/neverhood/modules/module2400_sprites.h139
-rw-r--r--engines/neverhood/modules/module2500.cpp54
-rw-r--r--engines/neverhood/modules/module2500.h18
-rw-r--r--engines/neverhood/modules/module2500_sprites.cpp127
-rw-r--r--engines/neverhood/modules/module2500_sprites.h51
-rw-r--r--engines/neverhood/modules/module2600.cpp89
-rw-r--r--engines/neverhood/modules/module2600.h18
-rw-r--r--engines/neverhood/modules/module2600_sprites.cpp115
-rw-r--r--engines/neverhood/modules/module2600_sprites.h54
-rw-r--r--engines/neverhood/modules/module2700.cpp82
-rw-r--r--engines/neverhood/modules/module2700.h35
-rw-r--r--engines/neverhood/modules/module2700_sprites.cpp178
-rw-r--r--engines/neverhood/modules/module2700_sprites.h74
-rw-r--r--engines/neverhood/modules/module2800.cpp1025
-rw-r--r--engines/neverhood/modules/module2800.h236
-rw-r--r--engines/neverhood/modules/module2800_sprites.cpp1626
-rw-r--r--engines/neverhood/modules/module2800_sprites.h337
-rw-r--r--engines/neverhood/modules/module2900.cpp207
-rw-r--r--engines/neverhood/modules/module2900.h36
-rw-r--r--engines/neverhood/modules/module2900_sprites.cpp232
-rw-r--r--engines/neverhood/modules/module2900_sprites.h72
-rw-r--r--engines/neverhood/modules/module3000.cpp661
-rw-r--r--engines/neverhood/modules/module3000.h156
-rw-r--r--engines/neverhood/modules/module3000_sprites.cpp763
-rw-r--r--engines/neverhood/modules/module3000_sprites.h185
-rw-r--r--engines/neverhood/navigationscene.cpp1
-rw-r--r--engines/neverhood/navigationscene.h2
-rw-r--r--engines/neverhood/neverhood.cpp1
-rw-r--r--engines/neverhood/neverhood.h5
-rw-r--r--engines/neverhood/palette.cpp5
-rw-r--r--engines/neverhood/resource.cpp10
-rw-r--r--engines/neverhood/resourceman.cpp44
-rw-r--r--engines/neverhood/resourceman.h2
-rw-r--r--engines/neverhood/scene.cpp32
-rw-r--r--engines/neverhood/scene.h17
-rw-r--r--engines/neverhood/screen.cpp3
-rw-r--r--engines/neverhood/smackerscene.h1
-rw-r--r--engines/neverhood/sound.cpp45
-rw-r--r--engines/neverhood/sound.h2
-rw-r--r--engines/neverhood/sprite.cpp6
-rw-r--r--engines/neverhood/staticdata.cpp16
102 files changed, 14755 insertions, 13373 deletions
diff --git a/engines/neverhood/POTFILES b/engines/neverhood/POTFILES
new file mode 100644
index 0000000000..36628cf4dd
--- /dev/null
+++ b/engines/neverhood/POTFILES
@@ -0,0 +1,2 @@
+engines/neverhood/detection.cpp
+engines/neverhood/menumodule.cpp
diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp
index d730d75718..c743037e63 100644
--- a/engines/neverhood/blbarchive.cpp
+++ b/engines/neverhood/blbarchive.cpp
@@ -131,7 +131,8 @@ void BlbArchive::load(BlbArchiveEntry *entry, byte *buffer, uint32 size) {
break;
case 3: // DCL-compressed
if (!Common::decompressDCL(&_fd, buffer, entry->diskSize, entry->size))
- error("BlbArchive::load() Error during decompression of %08X", entry->fileHash);
+ error("BlbArchive::load() Error during decompression of %08X (offset: %d, disk size: %d, size: %d)",
+ entry->fileHash, entry->offset, entry->diskSize, entry->size);
break;
default:
error("BlbArchive::load() Unknown compression type %d", entry->comprType);
diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp
index 733d7dd8a4..34438d821f 100644
--- a/engines/neverhood/console.cpp
+++ b/engines/neverhood/console.cpp
@@ -24,32 +24,63 @@
#include "gui/debugger.h"
#include "neverhood/neverhood.h"
#include "neverhood/gamemodule.h"
+#include "neverhood/navigationscene.h"
#include "neverhood/scene.h"
+#include "neverhood/smackerscene.h"
#include "neverhood/sound.h"
#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
Console::Console(NeverhoodEngine *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("cheat", WRAP_METHOD(Console, Cmd_Cheat));
+ DCmd_Register("checkresource", WRAP_METHOD(Console, Cmd_CheckResource));
+ DCmd_Register("dumpresource", WRAP_METHOD(Console, Cmd_DumpResource));
DCmd_Register("dumpvars", WRAP_METHOD(Console, Cmd_Dumpvars));
- DCmd_Register("room", WRAP_METHOD(Console, Cmd_Room));
- DCmd_Register("surfaces", WRAP_METHOD(Console, Cmd_Surfaces));
DCmd_Register("playsound", WRAP_METHOD(Console, Cmd_PlaySound));
+ DCmd_Register("scene", WRAP_METHOD(Console, Cmd_Scene));
+ DCmd_Register("surfaces", WRAP_METHOD(Console, Cmd_Surfaces));
}
Console::~Console() {
}
-bool Console::Cmd_Room(int argc, const char **argv) {
- int currentModule = _vm->_gameModule->getCurrentModuleNum();
- int previousModule = _vm->_gameModule->getPreviousModuleNum();
- int scene = _vm->gameState().sceneNum;
-
- DebugPrintf("Current module: %d, previous module: %d, scene %d\n", currentModule, previousModule, scene);
-
+bool Console::Cmd_Scene(int argc, const char **argv) {
if (argc != 3) {
- DebugPrintf("Use room <module> <scene> to change rooms\n");
+ int currentModule = _vm->_gameModule->getCurrentModuleNum();
+ int previousModule = _vm->_gameModule->getPreviousModuleNum();
+ int scenenNum = _vm->gameState().sceneNum;
+ SceneType sceneType = ((GameModule *)_vm->_gameModule->_childObject)->getSceneType();
+
+ const char *sceneTypes[] = { "normal", "smacker", "navigation" };
+
+ DebugPrintf("Current module: %d, previous module: %d, scene %d (%s scene)\n", currentModule, previousModule, scenenNum, sceneTypes[sceneType]);
+
+ if (sceneType == kSceneTypeNormal) {
+ Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ // Normal scenes have a background and a cursor file hash
+ DebugPrintf("Background hash: 0x%x, cursor hash: 0x%x\n", scene->getBackgroundFileHash(), scene->getCursorFileHash());
+ } else if (sceneType == kSceneTypeSmacker) {
+ SmackerScene *scene = (SmackerScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ // Smacker scenes have a file hash, or a list of hashes
+ // TODO: Only the first file hash is shown - any additional hashes, found in
+ // scenes with a list of hashes (two scenes in module 1100 and the making of
+ // video) aren't shown yet
+ DebugPrintf("File hash: 0x%x\n", scene->getSmackerFileHash());
+ } else if (sceneType == kSceneTypeNavigation) {
+ NavigationScene *scene = (NavigationScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
+ // Navigation scenes have a navigation list and its index
+ NavigationList *navigationList = _vm->_staticData->getNavigationList(scene->getNavigationListId());
+ int navigationIndex = scene->getGlobalVar(V_NAVIGATION_INDEX);
+ NavigationItem curNavigation = (*navigationList)[navigationIndex];
+ DebugPrintf("Navigation list ID: 0x%x, index: %d\n", scene->getNavigationListId(), navigationIndex);
+ DebugPrintf("File hash: 0x%x, cursor hash: 0x%x, Smacker hashes: [left: 0x%x, middle: 0x%x, right: 0x%x\n",
+ curNavigation.fileHash, curNavigation.mouseCursorFileHash,
+ curNavigation.leftSmackerFileHash, curNavigation.middleSmackerFileHash, curNavigation.rightSmackerFileHash);
+ }
+
+ DebugPrintf("Use %s <module> <scene> to change scenes\n", argv[0]);
DebugPrintf("Modules are incremental by 100, from 1000 to 3000\n");
} else {
int newModule = atoi(argv[1]);
@@ -188,4 +219,51 @@ bool Console::Cmd_PlaySound(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_CheckResource(int argc, const char **argv) {
+ const char *resourceNames[] = { "unknown", "unknown", "bitmap", "palette", "animation", "data", "text", "sound", "music", "unknown", "video" };
+
+ if (argc < 2) {
+ DebugPrintf("Gets information about a resource\n");
+ DebugPrintf("Usage: %s <resource hash>\n", argv[0]);
+ } else {
+ uint32 resourceHash = strtol(argv[1], NULL, 0);
+ ResourceHandle handle;
+
+ _vm->_res->queryResource(resourceHash, handle);
+ if (!handle.isValid()) {
+ DebugPrintf("Invalid resource hash\n");
+ } else {
+ DebugPrintf("Resource type: %d (%s). Size: %d bytes\n", handle.type(), resourceNames[handle.type()], handle.size());
+ }
+ }
+
+ return true;
+}
+
+bool Console::Cmd_DumpResource(int argc, const char **argv) {
+ if (argc < 3) {
+ DebugPrintf("Dumps a resource to disk\n");
+ DebugPrintf("Usage: %s <resource hash> <output file>\n", argv[0]);
+ } else {
+ uint32 resourceHash = strtol(argv[1], NULL, 0);
+ const char *outFileName = argv[2];
+ ResourceHandle handle;
+
+ _vm->_res->queryResource(resourceHash, handle);
+ if (!handle.isValid()) {
+ DebugPrintf("Invalid resource hash\n");
+ } else {
+ _vm->_res->loadResource(handle, _vm->applyResourceFixes());
+ Common::DumpFile outFile;
+ outFile.open(outFileName);
+ outFile.write(handle.data(), handle.size());
+ outFile.finalize();
+ outFile.close();
+ _vm->_res->unloadResource(handle);
+ }
+ }
+
+ return true;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/console.h b/engines/neverhood/console.h
index 62d65bd693..70260a96af 100644
--- a/engines/neverhood/console.h
+++ b/engines/neverhood/console.h
@@ -37,11 +37,14 @@ public:
private:
NeverhoodEngine *_vm;
- bool Cmd_Room(int argc, const char **argv);
+ bool Cmd_Scene(int argc, const char **argv);
bool Cmd_Surfaces(int argc, const char **argv);
bool Cmd_Cheat(int argc, const char **argv);
bool Cmd_Dumpvars(int argc, const char **argv);
bool Cmd_PlaySound(int argc, const char **argv);
+ bool Cmd_CheckResource(int argc, const char **argv);
+ bool Cmd_DumpResource(int argc, const char **argv);
+
};
} // End of namespace Neverhood
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/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 47cc818fea..50c7c503d3 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -411,7 +411,9 @@ void GameModule::checkRequests() {
}
if (_restoreGameRequested) {
_restoreGameRequested = false;
+ _vm->_audioResourceMan->stopAllMusic();
_vm->_audioResourceMan->stopAllSounds();
+ _vm->_soundMan->stopAllMusic();
_vm->_soundMan->stopAllSounds();
delete _childObject;
delete _prevChildObject;
diff --git a/engines/neverhood/klaymen.cpp b/engines/neverhood/klaymen.cpp
index 8ed27c825a..666b20a08a 100644
--- a/engines/neverhood/klaymen.cpp
+++ b/engines/neverhood/klaymen.cpp
@@ -47,17 +47,6 @@ static const KlaymenIdleTableItem klaymenIdleTable3[] = {
{1, kIdleTeleporterHands2}
};
-static const KlaymenIdleTableItem klaymenIdleTable4[] = {
- {1, kIdleSpinHead},
- {1, kIdleChest},
- {1, kIdleHeadOff},
-};
-
-static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
- {1, kIdlePickEar},
- {2, kIdleWonderAbout}
-};
-
// Klaymen
Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRectArray *clipRects)
@@ -65,7 +54,7 @@ Klaymen::Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRec
_isWalkingOpenDoorNotified(false), _spitOutCountdown(0), _tapesToInsert(0), _keysToInsert(0), _busyStatus(0), _acceptInput(true),
_attachedSprite(NULL), _isWalking(false), _actionStatus(1), _parentScene(parentScene), _isSneaking(false), _isLargeStep(false),
_doYHitIncr(false), _isLeverDown(false), _isSittingInTeleporter(false), _actionStatusChanged(false), _ladderStatus(0), _pathPoints(NULL), _soundFlag(false),
- _idleTableNum(0), _otherSprite(NULL), _moveObjectCountdown(0), _readyToSpit(false), _walkResumeFrameIncr(0) {
+ _idleTableNum(0), _otherSprite(NULL), _moveObjectCountdown(0), _walkResumeFrameIncr(0) {
createSurface(1000, 320, 200);
_x = x;
@@ -628,36 +617,6 @@ void Klaymen::startWalkToX(int16 x, bool walkExt) {
}
}
-void Klaymen::stWakeUp() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x527AC970, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevelAnimation);
- SetSpriteUpdate(NULL);
-}
-
-void Klaymen::stSleeping() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x5A38C110, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSleeping);
- SetSpriteUpdate(NULL);
-}
-
-uint32 Klaymen::hmSleeping(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevel(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x03060012) {
- playSound(0, 0xC0238244);
- }
- break;
- }
- return messageResult;
-}
-
bool Klaymen::stStartAction(AnimationCb callback3) {
if (_busyStatus == 1) {
_busyStatus = 2;
@@ -1512,112 +1471,11 @@ uint32 Klaymen::hmPeekWall(int messageNum, const MessageParam &param, Entity *se
return hmLowLevelAnimation(messageNum, param, sender);
}
-void Klaymen::stJumpToRing1() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing1))) {
- _busyStatus = 0;
- startAnimation(0xD82890BA, 0, -1);
- setupJumpToRing();
- }
-}
-
-void Klaymen::setupJumpToRing() {
- _acceptInput = false;
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpToRing);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- NextState(&Klaymen::stHangOnRing);
- sendMessage(_attachedSprite, 0x482B, 0);
-}
-
-uint32 Klaymen::hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x4806, 0);
- _acceptInput = true;
- } else if (param.asInteger() == 0x320AC306) {
- playSound(0, 0x5860C640);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::suUpdateDestX() {
AnimatedSprite::updateDeltaXY();
_destX = _x;
}
-void Klaymen::stHangOnRing() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x4829E0B8, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(NULL);
-}
-
-void Klaymen::stJumpToRing2() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing2))) {
- _busyStatus = 0;
- startAnimation(0x900980B2, 0, -1);
- setupJumpToRing();
- }
-}
-
-void Klaymen::stJumpToRing3() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing3))) {
- _busyStatus = 0;
- _acceptInput = false;
- startAnimation(0xBA1910B2, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- SetMessageHandler(&Klaymen::hmJumpToRing3);
- NextState(&Klaymen::stHoldRing3);
- sendMessage(_attachedSprite, 0x482B, 0);
- }
-}
-
-uint32 Klaymen::hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x4806, 0);
- } else if (param.asInteger() == 0x320AC306) {
- playSound(0, 0x5860C640);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stHoldRing3() {
- _busyStatus = 0;
- _acceptInput = true;
- startAnimation(0x4A293FB0, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHoldRing3);
- SetSpriteUpdate(NULL);
-}
-
-uint32 Klaymen::hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender) {
- if (messageNum == 0x1008) {
- stReleaseRing();
- return 0;
- }
- return hmLowLevel(messageNum, param, sender);
-}
-
void Klaymen::stReleaseRing() {
_busyStatus = 1;
_acceptInput = false;
@@ -1629,14 +1487,6 @@ void Klaymen::stReleaseRing() {
SetSpriteUpdate(NULL);
}
-void Klaymen::stJumpToRing4() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRing4))) {
- _busyStatus = 0;
- startAnimation(0xB8699832, 0, -1);
- setupJumpToRing();
- }
-}
-
void Klaymen::startWalkToAttachedSpriteXDistance(int16 distance) {
startWalkToXDistance(_attachedSprite->getX(), distance);
}
@@ -1885,29 +1735,6 @@ uint32 Klaymen::hmTurnToBackToUse(int messageNum, const MessageParam &param, Ent
return messageResult;
}
-void Klaymen::stClayDoorOpen() {
- if (!stStartAction(AnimationCallback(&Klaymen::stClayDoorOpen))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x5CCCB330, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmClayDoorOpen);
- SetSpriteUpdate(&Klaymen::suUpdateDestX);
- }
-}
-
-uint32 Klaymen::hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x040D4186) {
- sendMessage(_attachedSprite, 0x4808, 0);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::stTurnToUse() {
if (!stStartAction(AnimationCallback(&Klaymen::stTurnToUse))) {
_busyStatus = 2;
@@ -2336,29 +2163,6 @@ uint32 Klaymen::hmTeleporterAppearDisappear(int messageNum, const MessageParam &
return messageResult;
}
-uint32 Klaymen::hmShrink(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x80C110B5)
- sendMessage(_parentScene, 0x482A, 0);
- else if (param.asInteger() == 0x33288344)
- playSound(2, 0x10688664);
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stShrink() {
- _busyStatus = 0;
- _acceptInput = false;
- playSound(0, 0x4C69EA53);
- startAnimation(0x1AE88904, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmShrink);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
void Klaymen::stStandWonderAbout() {
if (_x > 260)
setDoDeltaX(1);
@@ -2537,61 +2341,6 @@ void Klaymen::stInsertKey() {
}
}
-uint32 Klaymen::hmReadNote(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x04684052) {
- _acceptInput = true;
- sendMessage(_parentScene, 0x2002, 0);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stReadNote() {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x123E9C9F, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmReadNote);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 Klaymen::hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- int16 speedUpFrameIndex;
- switch (messageNum) {
- case 0x1008:
- speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
- if (_currFrameIndex < speedUpFrameIndex) {
- startAnimation(0x35AA8059, speedUpFrameIndex, -1);
- _y = 438;
- }
- messageResult = 0;
- break;
- case 0x100D:
- if (param.asInteger() == 0x1A1A0785) {
- playSound(0, 0x40F0A342);
- } else if (param.asInteger() == 0x60428026) {
- playSound(0, 0x40608A59);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stHitByDoor() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x35AA8059, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHitByDoor);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- playSound(0, 0x402E82D4);
-}
-
uint32 Klaymen::hmPeekWallReturn(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
@@ -2657,65 +2406,6 @@ void Klaymen::stPeekWallReturn() {
SetSpriteUpdate(NULL);
}
-void Klaymen::stPullHammerLever() {
- if (!stStartAction(AnimationCallback(&Klaymen::stPullHammerLever))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x00648953, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmPullHammerLever);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- }
-}
-
-uint32 Klaymen::hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLever(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209)
- sendMessage(_attachedSprite, 0x480F, 0);
- break;
- }
- return messageResult;
-}
-
-void Klaymen::suRidePlatformDown() {
- _platformDeltaY++;
- _y += _platformDeltaY;
- if (_y > 600)
- sendMessage(this, 0x1019, 0);
-}
-
-void Klaymen::stRidePlatformDown() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stRidePlatformDown))) {
- _busyStatus = 1;
- sendMessage(_parentScene, 0x4803, 0);
- _acceptInput = false;
- _platformDeltaY = 0;
- startAnimation(0x5420E254, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(&Klaymen::suRidePlatformDown);
- _vm->_soundMan->playSoundLooping(0xD3B02847);
- }
-}
-
-void Klaymen::stCrashDown() {
- playSound(0, 0x41648271);
- _busyStatus = 1;
- _acceptInput = false;
- startAnimationByHash(0x000BAB02, 0x88003000, 0);
- SetUpdateHandler(&Klaymen::update);
- SetSpriteUpdate(NULL);
- SetMessageHandler(&Klaymen::hmLowLevelAnimation);
- NextState(&Klaymen::stCrashDownFinished);
-}
-
-void Klaymen::stCrashDownFinished() {
- setDoDeltaX(2);
- stTryStandIdle();
-}
-
void Klaymen::upSpitOutFall() {
Klaymen::update();
if (_spitOutCountdown != 0 && (--_spitOutCountdown == 0)) {
@@ -2724,24 +2414,6 @@ void Klaymen::upSpitOutFall() {
}
}
-uint32 Klaymen::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x168050A0) {
- sendMessage(_attachedSprite, 0x480F, 0);
- } else if (param.asInteger() == 0x586B0300) {
- sendMessage(_otherSprite, 0x480E, 1);
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- }
- break;
- }
- return messageResult;
-}
-
uint32 Klaymen::hmStandIdleSpecial(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
case 0x4811:
@@ -2784,53 +2456,6 @@ uint32 Klaymen::hmPressDoorButton(int messageNum, const MessageParam &param, Ent
return messageResult;
}
-uint32 Klaymen::hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x01084280) {
- sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX);
- } else if (param.asInteger() == 0x02421405) {
- if (_isMoveObjectRequested) {
- if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0)
- stContinueMovingVenusFlyTrap();
- } else {
- SetMessageHandler(&Klaymen::hmFirstMoveVenusFlyTrap);
- }
- } else if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- } else if (param.asInteger() == 0x32180101) {
- playSound(0, 0x405002D8);
- } else if (param.asInteger() == 0x0A2A9098) {
- playSound(0, 0x0460E2FA);
- }
- break;
- case 0x480A:
- _isMoveObjectRequested = true;
- return 0;
- }
- return hmLowLevelAnimation(messageNum, param, sender);
-}
-
-uint32 Klaymen::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
- } else if (param.asInteger() == 0x32180101) {
- playSound(0, 0x405002D8);
- } else if (param.asInteger() == 0x0A2A9098) {
- playSound(0, 0x0460E2FA);
- }
- break;
- }
- return messageResult;
-}
-
uint32 Klaymen::hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender) {
int16 speedUpFrameIndex;
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
@@ -2854,18 +2479,6 @@ uint32 Klaymen::hmHitByBoxingGlove(int messageNum, const MessageParam &param, En
return messageResult;
}
-uint32 Klaymen::hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevel(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x1307050A) {
- playSound(0, 0x40428A09);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::suFallDown() {
AnimatedSprite::updateDeltaXY();
HitRect *hitRect = _parentScene->findHitRectAtPos(_x, _y + 10);
@@ -2877,19 +2490,6 @@ void Klaymen::suFallDown() {
_parentScene->checkCollision(this, 0xFFFF, 0x4810, 0);
}
-void Klaymen::stJumpToRingVenusFlyTrap() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpToRingVenusFlyTrap))) {
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x584984B4, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpToRingVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&Klaymen::stLandOnFeet);
- sendMessage(_attachedSprite, 0x482B, 0);
- }
-}
-
void Klaymen::stStandIdleSpecial() {
playSound(0, 0x56548280);
_busyStatus = 0;
@@ -2946,34 +2546,6 @@ void Klaymen::stFallTouchdown() {
stTryStandIdle();
}
-void Klaymen::stJumpAndFall() {
- if (!stStartAction(AnimationCallback(&Klaymen::stJumpAndFall))) {
- sendMessage(_parentScene, 0x1024, 3);
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0xB93AB151, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmJumpAndFall);
- SetSpriteUpdate(&Klaymen::suFallDown);
- NextState(&Klaymen::stLandOnFeet);
- }
-}
-
-void Klaymen::stDropFromRing() {
- if (_attachedSprite) {
- _x = _attachedSprite->getX();
- sendMessage(_attachedSprite, 0x4807, 0);
- _attachedSprite = NULL;
- }
- _busyStatus = 2;
- _acceptInput = false;
- startAnimation(0x586984B1, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(&Klaymen::suFallDown);
- NextState(&Klaymen::stLandOnFeet);
-}
-
void Klaymen::stPressDoorButton() {
_busyStatus = 2;
_acceptInput = true;
@@ -2998,34 +2570,6 @@ void Klaymen::evHitByBoxingGloveDone() {
sendMessage(_parentScene, 0x1024, 1);
}
-void Klaymen::stMoveVenusFlyTrap() {
- if (!stStartAction(AnimationCallback(&Klaymen::stMoveVenusFlyTrap))) {
- _busyStatus = 2;
- _isMoveObjectRequested = false;
- _acceptInput = true;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x5C01A870, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMoveVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evMoveVenusFlyTrapDone);
- }
-}
-
-void Klaymen::stContinueMovingVenusFlyTrap() {
- _isMoveObjectRequested = false;
- _acceptInput = true;
- startAnimationByHash(0x5C01A870, 0x01084280, 0);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMoveVenusFlyTrap);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evMoveVenusFlyTrapDone);
-}
-
-void Klaymen::evMoveVenusFlyTrapDone() {
- sendMessage(_attachedSprite, 0x482A, 0);
-}
-
void Klaymen::suFallSkipJump() {
updateDeltaXY();
HitRect *hitRect = _parentScene->findHitRectAtPos(_x, _y + 10);
@@ -3052,49 +2596,6 @@ void Klaymen::upMoveObject() {
Klaymen::update();
}
-uint32 Klaymen::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x51281850) {
- setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
- } else if (param.asInteger() == 0x43000538) {
- playSound(0, 0x21043059);
- } else if (param.asInteger() == 0x02B20220) {
- playSound(0, 0xC5408620);
- } else if (param.asInteger() == 0x0A720138) {
- playSound(0, 0xD4C08010);
- } else if (param.asInteger() == 0xB613A180) {
- playSound(0, 0x44051000);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stFetchMatch() {
- if (!stStartAction(AnimationCallback(&Klaymen::stFetchMatch))) {
- _busyStatus = 0;
- _acceptInput = false;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x9CAA0218, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMatch);
- SetSpriteUpdate(NULL);
- NextState(&Klaymen::stLightMatch);
- }
-}
-
-void Klaymen::stLightMatch() {
- _busyStatus = 1;
- _acceptInput = false;
- setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
- startAnimation(0x1222A513, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmMatch);
- SetSpriteUpdate(NULL);
-}
-
uint32 Klaymen::hmMoveObject(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
case 0x100D:
@@ -3114,18 +2615,6 @@ uint32 Klaymen::hmMoveObject(int messageNum, const MessageParam &param, Entity *
return Klaymen::hmLowLevelAnimation(messageNum, param, sender);
}
-uint32 Klaymen::hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000F0082) {
- playSound(0, 0x74E2810F);
- }
- break;
- }
- return messageResult;
-}
-
void Klaymen::stMoveObject() {
if (!stStartAction(AnimationCallback(&Klaymen::stMoveObject))) {
_busyStatus = 2;
@@ -3147,93 +2636,6 @@ void Klaymen::stContinueMoveObject() {
SetMessageHandler(&Klaymen::hmMoveObject);
}
-void Klaymen::stTumbleHeadless() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stTumbleHeadless))) {
- _busyStatus = 1;
- _acceptInput = false;
- setDoDeltaX(0);
- startAnimation(0x2821C590, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmTumbleHeadless);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&Klaymen::stTryStandIdle);
- sendMessage(_parentScene, 0x8000, 0);
- playSound(0, 0x62E0A356);
- }
-}
-
-void Klaymen::stCloseEyes() {
- if (!stStartActionFromIdle(AnimationCallback(&Klaymen::stCloseEyes))) {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x5420E254, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmLowLevel);
- SetSpriteUpdate(NULL);
- }
-}
-
-uint32 Klaymen::hmSpit(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x16401CA6) {
- _canSpitPipe = true;
- if (_contSpitPipe)
- spitIntoPipe();
- } else if (param.asInteger() == 0xC11C0008) {
- _canSpitPipe = false;
- _acceptInput = false;
- _readyToSpit = false;
- } else if (param.asInteger() == 0x018A0001) {
- sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
- }
- break;
- }
- return messageResult;
-}
-
-void Klaymen::stTrySpitIntoPipe() {
- if (_readyToSpit) {
- _contSpitPipe = true;
- _spitContDestPipeIndex = _spitPipeIndex;
- if (_canSpitPipe)
- spitIntoPipe();
- } else if (!stStartAction(AnimationCallback(&Klaymen::stTrySpitIntoPipe))) {
- _busyStatus = 2;
- _acceptInput = true;
- _spitDestPipeIndex = _spitPipeIndex;
- _readyToSpit = true;
- _canSpitPipe = false;
- _contSpitPipe = false;
- startAnimation(0x1808B150, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
- }
-}
-
-void Klaymen::spitIntoPipe() {
- _contSpitPipe = false;
- _spitDestPipeIndex = _spitContDestPipeIndex;
- _canSpitPipe = false;
- _acceptInput = false;
- startAnimation(0x1B08B553, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
- NextState(&Klaymen::stContSpitIntoPipe);
-}
-
-void Klaymen::stContSpitIntoPipe() {
- _canSpitPipe = true;
- _acceptInput = true;
- startAnimationByHash(0x1808B150, 0x16401CA6, 0);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmSpit);
- SetSpriteUpdate(NULL);
-}
-
void Klaymen::suRidePlatform() {
_x = _attachedSprite->getX() - 20;
_y = _attachedSprite->getY() + 46;
@@ -3344,2798 +2746,4 @@ void Klaymen::stPeekInsideBlink() {
_blinkCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
}
-// KmScene1001
-
-KmScene1001::KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-}
-
-uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stSleeping);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullHammerLever);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4836:
- if (param.asInteger() == 1) {
- sendMessage(_parentScene, 0x2002, 0);
- GotoState(&Klaymen::stWakeUp);
- }
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1002
-
-KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable1();
-}
-
-void KmScene1002::xUpdate() {
- if (_x >= 250 && _x <= 435 && _y >= 420) {
- if (_idleTableNum == 0) {
- setKlaymenIdleTable(klaymenIdleTable1002, ARRAYSIZE(klaymenIdleTable1002));
- _idleTableNum = 1;
- }
- } else if (_idleTableNum == 1) {
- setKlaymenIdleTable1();
- _idleTableNum = 0;
- }
-}
-
-uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x2001:
- GotoState(&Klaymen::stStandIdleSpecial);
- break;
- case 0x2007:
- _otherSprite = (Sprite*)param.asEntity();
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stJumpAndFall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stDropFromRing);
- break;
- case 0x4804:
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4805:
- switch (param.asInteger()) {
- case 1:
- GotoState(&Klaymen::stJumpToRing1);
- break;
- case 2:
- GotoState(&Klaymen::stJumpToRing2);
- break;
- case 3:
- GotoState(&Klaymen::stJumpToRing3);
- break;
- case 4:
- GotoState(&Klaymen::stJumpToRing4);
- break;
- }
- break;
- case 0x480A:
- GotoState(&Klaymen::stMoveVenusFlyTrap);
- break;
- case 0x480D:
- GotoState(&Klaymen::stJumpToRingVenusFlyTrap);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressDoorButton);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- startWalkToAttachedSpriteXDistance(param.asInteger());
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2005, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2005, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2005, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2006, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1004
-
-KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _dataResource.load(0x01900A04);
-}
-
-uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReadNote);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x4824:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4825:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4828:
- GotoState(&Klaymen::stTurnToBackToUse);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0x2C2A4A1C);
- break;
- case 0x483E:
- teleporterDisappear(0x3C2E4245);
- break;
- }
- return messageResult;
-}
-
-// KmScene1201
-
-KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4));
- _doYHitIncr = true;
-}
-
-uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- GotoState(&Klaymen::stMoveObject);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4813:
- GotoState(&Klaymen::stFetchMatch);
- break;
- case 0x4814:
- GotoState(&Klaymen::stTumbleHeadless);
- break;
- case 0x4815:
- GotoState(&Klaymen::stCloseEyes);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4804:
- GotoState(&Klaymen::stPeekWall1);
- break;
- case 0x483B:
- GotoState(&Klaymen::stPeekWallReturn);
- break;
- case 0x483C:
- GotoState(&Klaymen::stPeekWall2);
- break;
- }
- return 0;
-}
-
-KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- GotoState(&Klaymen::stCrashDown);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- }
- return 0;
-}
-
-KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- else
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- else
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xEE084A04);
- break;
- case 0x483E:
- teleporterDisappear(0xB86A4274);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x480D:
- GotoState(&Klaymen::stUseLever);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stInsertKey);
- else
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1401
-
-KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- }
- return 0;
-}
-
-// KmScene1402
-
-KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- SetFilterY(&Sprite::defFilterY);
-}
-
-uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- }
- return 0;
-}
-
-// KmScene1403
-
-KmScene1403::KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- setKlaymenIdleTable(klaymenIdleTable4, ARRAYSIZE(klaymenIdleTable4));
-}
-
-uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x480D:
- GotoState(&Klaymen::stUseLever);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-// KmScene1404
-
-KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480A:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
- else
- GotoState(&Klaymen::stMoveObjectFaceObject);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2032:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2032, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2032, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-// KmScene1705
-
-KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- GotoState(&Klaymen::stFallSkipJump);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter) {
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- }
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0x5E0A4905);
- break;
- case 0x483E:
- teleporterDisappear(0xD86E4477);
- break;
- }
- return messageResult;
-}
-
-KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xBE68CC54);
- break;
- case 0x483E:
- teleporterDisappear(0x18AB4ED4);
- break;
- }
- return messageResult;
-}
-
-KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4811:
- GotoState(&Klaymen::stHitByDoor);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xFF290E30);
- break;
- case 0x483E:
- teleporterDisappear(0x9A28CA1C);
- break;
- }
- return messageResult;
-}
-
-KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
- _dataResource.load(0x04104242);
-}
-
-uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4819:
- GotoState(&Klaymen::stClayDoorOpen);
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2205::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2206::KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _walkResumeFrameIncr = 1;
- _vm->_soundMan->addSound(0x80101800, 0xD3B02847);
-}
-
-KmScene2206::~KmScene2206() {
- _vm->_soundMan->deleteSoundGroup(0x80101800);
-}
-
-void KmScene2206::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- GotoState(&Klaymen::stRidePlatformDown);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4837:
- stopWalking();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x2001:
- GotoState(&Klaymen::stRidePlatform);
- break;
- case 0x2005:
- suRidePlatform();
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480D:
- GotoState(&Klaymen::stInteractLever);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x4827:
- GotoState(&Klaymen::stReleaseLever);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
-KmScene2242::KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2242::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
- // Empty
-}
-
-void KmHallOfRecords::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2247::KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-void KmScene2247::xUpdate() {
- setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
-}
-
-uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stStartWalkingResume);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4832:
- GotoState(&Klaymen::stUseTube);
- break;
- case 0x4833:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAbout);
- else {
- _spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stTrySpitIntoPipe);
- }
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (!getGlobalVar(V_TV_JOKE_TOLD))
- GotoState(&Klaymen::stStandWonderAbout);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4816:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stPressButton);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stPressFloorButton);
- else
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- if (param.asInteger() != 0) {
- _destX = param.asInteger();
- GotoState(&Klaymen::stWalkingFirst);
- } else
- GotoState(&Klaymen::stPeekWall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- }
- return messageResult;
-}
-
-KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4804:
- GotoState(&Klaymen::stPeekInside);
- break;
- case 0x483C:
- GotoState(&Klaymen::stPeekInsideReturn);
- break;
- }
- return 0;
-}
-
-KmScene2801::KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2803::KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
- _dataResource.load(0x00900849);
-}
-
-uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrab);
- break;
- case 0x4804:
- if (param.asInteger() == 3)
- GotoState(&Klaymen::stFinishGrow);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else
- GotoState(&Klaymen::stWonderAboutHalf);
- break;
- case 0x482E:
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4838:
- GotoState(&Klaymen::stJumpToGrabRelease);
- break;
- }
- return 0;
-}
-
-KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- _dataResource.load(0x81120132);
-}
-
-uint32 KmScene2803Small::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToXSmall(param.asPoint().x);
- break;
- case 0x4004:
- GotoState(&Klaymen::stStandIdleSmall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfterSmall);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalfSmall);
- else
- GotoState(&Klaymen::stWonderAboutSmall);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStepSmall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stWalkToFront2Small);
- else
- GotoState(&Klaymen::stWalkToFrontSmall);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToBackHalfSmall);
- else if (param.asInteger() == 2)
- GotoState(&Klaymen::stTurnToBackWalkSmall);
- else
- GotoState(&Klaymen::stTurnToBackSmall);
- break;
- case 0x4830:
- GotoState(&Klaymen::stShrink);
- break;
- }
- return 0;
-}
-
-KmScene2805::KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
- uint32 messageResult = 0;
- switch (messageNum) {
- case 0x2000:
- _isSittingInTeleporter = param.asInteger() != 0;
- messageResult = 1;
- break;
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stSitIdleTeleporter);
- else
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481D:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stTurnToUseInTeleporter);
- break;
- case 0x481E:
- if (_isSittingInTeleporter)
- GotoState(&Klaymen::stReturnFromUseInTeleporter);
- break;
- case 0x4834:
- GotoState(&Klaymen::stStepOver);
- break;
- case 0x4835:
- sendMessage(_parentScene, 0x2000, 1);
- _isSittingInTeleporter = true;
- GotoState(&Klaymen::stSitInTeleporter);
- break;
- case 0x4836:
- sendMessage(_parentScene, 0x2000, 0);
- _isSittingInTeleporter = false;
- GotoState(&Klaymen::stGetUpFromTeleporter);
- break;
- case 0x483D:
- teleporterAppear(0xDE284B74);
- break;
- case 0x483E:
- teleporterDisappear(0xD82A4094);
- break;
- }
- return messageResult;
-}
-
-KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- if (needsLargeSurface) {
- NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
- delete _surface;
- createSurface(1000, dimensions.width, dimensions.height);
- loadSound(3, 0x58E0C341);
- loadSound(4, 0x40A00342);
- loadSound(5, 0xD0A1C348);
- loadSound(6, 0x166FC6E0);
- loadSound(7, 0x00018040);
- }
-
- _dataResource.load(0x98182003);
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- startWalkToX(440, true);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4831:
- GotoState(&Klaymen::stGrow);
- break;
- case 0x4832:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stDrinkPotion);
- else
- GotoState(&Klaymen::stUseTube);
- break;
- }
- return 0;
-}
-
-KmScene2809::KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- if (needsLargeSurface) {
- NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
- delete _surface;
- createSurface(1000, dimensions.width, dimensions.height);
- loadSound(3, 0x58E0C341);
- loadSound(4, 0x40A00342);
- loadSound(5, 0xD0A1C348);
- loadSound(6, 0x166FC6E0);
- loadSound(7, 0x00018040);
- }
-
- _dataResource.load(0x1830009A);
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4804:
- startWalkToX(226, true);
- break;
- case 0x480D:
- GotoState(&Klaymen::stPullCord);
- break;
- case 0x4816:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stPressButtonSide);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x4831:
- GotoState(&Klaymen::stGrow);
- break;
- case 0x4832:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stDrinkPotion);
- else
- GotoState(&Klaymen::stUseTube);
- break;
- }
- return 0;
-}
-
-KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToXSmall(param.asPoint().x);
- break;
- case 0x4004:
- GotoState(&Klaymen::stStandIdleSmall);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
- break;
- case 0x481F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfterSmall);
- else if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalfSmall);
- else
- GotoState(&Klaymen::stWonderAboutSmall);
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStepSmall);
- else
- GotoState(&Klaymen::stWalkToFrontSmall);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToBackHalfSmall);
- else
- GotoState(&Klaymen::stTurnToBackSmall);
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, uint clipRectsCount)
- : Klaymen(vm, parentScene, x, y) {
-
- _surface->setClipRects(clipRects, clipRectsCount);
-}
-
-uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4803:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrab);
- break;
- case 0x4804:
- if (param.asInteger() == 3)
- GotoState(&Klaymen::stFinishGrow);
- break;
- case 0x4812:
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x4818:
- startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481F:
- if (param.asInteger() == 0)
- GotoState(&Klaymen::stWonderAboutHalf);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stWonderAboutAfter);
- else if (param.asInteger() == 3)
- GotoState(&Klaymen::stTurnToUseHalf);
- else if (param.asInteger() == 4)
- GotoState(&Klaymen::stTurnAwayFromUse);
- else if (param.asInteger() == 5)
- GotoState(&Klaymen::stTurnToUseExt);
- else
- GotoState(&Klaymen::stWonderAbout);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2000, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x4824:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4825:
- sendMessage(_parentScene, 0x2000, 0);
- _destY = _dataResource.getPoint(param.asInteger()).y;
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x4837:
- stopWalking();
- break;
- }
- return 0;
-}
-
-KmScene2812::KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : Klaymen(vm, parentScene, x, y) {
-
- // Empty
-}
-
-uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
- switch (messageNum) {
- case 0x4001:
- case 0x4800:
- startWalkToX(param.asPoint().x, false);
- break;
- case 0x4004:
- GotoState(&Klaymen::stTryStandIdle);
- break;
- case 0x4805:
- _destY = param.asInteger();
- GotoState(&Klaymen::stJumpToGrabFall);
- break;
- case 0x4812:
- if (param.asInteger() == 2)
- GotoState(&Klaymen::stPickUpNeedle);
- else if (param.asInteger() == 1)
- GotoState(&Klaymen::stPickUpTube);
- else
- GotoState(&Klaymen::stPickUpGeneric);
- break;
- case 0x4817:
- setDoDeltaX(param.asInteger());
- gotoNextStateExt();
- break;
- case 0x481A:
- GotoState(&Klaymen::stInsertDisk);
- break;
- case 0x481B:
- if (param.asPoint().y != 0)
- startWalkToXDistance(param.asPoint().y, param.asPoint().x);
- else
- startWalkToAttachedSpriteXDistance(param.asPoint().x);
- break;
- case 0x481D:
- GotoState(&Klaymen::stTurnToUse);
- break;
- case 0x481E:
- GotoState(&Klaymen::stReturnFromUse);
- break;
- case 0x4820:
- sendMessage(_parentScene, 0x2001, 0);
- GotoState(&Klaymen::stContinueClimbLadderUp);
- break;
- case 0x4821:
- sendMessage(_parentScene, 0x2001, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderDown);
- break;
- case 0x4822:
- sendMessage(_parentScene, 0x2001, 0);
- _destY = param.asInteger();
- GotoState(&Klaymen::stStartClimbLadderUp);
- break;
- case 0x4823:
- sendMessage(_parentScene, 0x2002, 0);
- GotoState(&Klaymen::stClimbLadderHalf);
- break;
- case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
- gotoNextStateExt();
- break;
- case 0x482E:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stWalkToFrontNoStep);
- else
- GotoState(&Klaymen::stWalkToFront);
- break;
- case 0x482F:
- if (param.asInteger() == 1)
- GotoState(&Klaymen::stTurnToFront);
- else
- GotoState(&Klaymen::stTurnToBack);
- break;
- case 0x483F:
- startSpecialWalkRight(param.asInteger());
- break;
- case 0x4840:
- startSpecialWalkLeft(param.asInteger());
- break;
- }
- return 0;
-}
-
} // End of namespace Neverhood
diff --git a/engines/neverhood/klaymen.h b/engines/neverhood/klaymen.h
index 9e461a9c9c..524bb9a9f2 100644
--- a/engines/neverhood/klaymen.h
+++ b/engines/neverhood/klaymen.h
@@ -33,7 +33,6 @@ namespace Neverhood {
// TODO This code is horrible and weird and a lot of stuff needs renaming once a better name is found
// TODO Also the methods should probably rearranged and be grouped together more consistently
-class Klaymen;
class Scene;
const uint32 kKlaymenSpeedUpHash = 0x004A2148;
@@ -67,29 +66,25 @@ public:
void startIdleAnimation(uint32 fileHash, AnimationCb callback);
void upIdleAnimation();
+ // Idle animations - start
void stIdlePickEar();
void evIdlePickEarDone();
- uint32 hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleSpinHead();
- uint32 hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleArms();
void evIdleArmsDone();
- uint32 hmIdleArms(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleChest();
- uint32 hmIdleChest(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleHeadOff();
- uint32 hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender);
-
void stIdleWonderAbout();
-
void stIdleTeleporterHands();
-
void stIdleTeleporterHands2();
+ uint32 hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleArms(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleChest(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender);
+ // Idle animations - end
+
void stTryStandIdle();
void stStandAround();
void upStandIdle();
@@ -150,12 +145,6 @@ public:
void stInsertKey();
uint32 hmInsertKey(int messageNum, const MessageParam &param, Entity *sender);
- void stReadNote();
- uint32 hmReadNote(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHitByDoor();
- uint32 hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender);
-
void stPeekWall();
uint32 hmPeekWall(int messageNum, const MessageParam &param, Entity *sender);
@@ -166,21 +155,8 @@ public:
void upPeekWallBlink();
void stPeekWall1();
-
void stPeekWall2();
- void stPullHammerLever();
- uint32 hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender);
-
- void stRidePlatformDown();
- void suRidePlatformDown();
-
- void stCrashDown();
- void stCrashDownFinished();
-
- void stShrink();
- uint32 hmShrink(int messageNum, const MessageParam &param, Entity *sender);
-
void stGrow();
uint32 hmGrow(int messageNum, const MessageParam &param, Entity *sender);
@@ -203,11 +179,6 @@ public:
void stLetGoOfLever();
void evLeverReleasedEvent();
- void stWakeUp();
-
- void stSleeping();
- uint32 hmSleeping(int messageNum, const MessageParam &param, Entity *sender);
-
void stPressButton();
void stPressFloorButton();
void stPressButtonSide();
@@ -228,20 +199,6 @@ public:
void stClimbLadderHalf();
uint32 hmClimbLadderHalf(int messageNum, const MessageParam &param, Entity *sender);
- void setupJumpToRing();
- void stJumpToRing1();
- void stJumpToRing2();
- void stJumpToRing4();
- uint32 hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHangOnRing();
-
- void stJumpToRing3();
- uint32 hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender);
-
- void stHoldRing3();
- uint32 hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender);
-
void stReleaseRing();
void stLandOnFeet();
@@ -272,24 +229,17 @@ public:
void stSitIdleTeleporter();
void upSitIdleTeleporter();
-
void stSitIdleTeleporterBlink();
-
void stSitIdleTeleporterBlinkSecond();
void stTurnToUseInTeleporter();
-
void stReturnFromUseInTeleporter();
-
void stGetUpFromTeleporter();
void teleporterAppear(uint32 fileHash);
void teleporterDisappear(uint32 fileHash);
uint32 hmTeleporterAppearDisappear(int messageNum, const MessageParam &param, Entity *sender);
- void stClayDoorOpen();
- uint32 hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender);
-
void stFallSkipJump();
void suFallSkipJump();
@@ -298,15 +248,6 @@ public:
uint32 hmMoveObject(int messageNum, const MessageParam &param, Entity *sender);
void upMoveObject();
- void stCloseEyes();
-
- void stTumbleHeadless();
- uint32 hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender);
-
- void stFetchMatch();
- void stLightMatch();
- uint32 hmMatch(int messageNum, const MessageParam &param, Entity *sender);
-
void stHitByBoxingGlove();
uint32 hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender);
void evHitByBoxingGloveDone();
@@ -327,11 +268,6 @@ public:
void stFinishGrow();
uint32 hmFinishGrow(int messageNum, const MessageParam &param, Entity *sender);
- void stJumpToRingVenusFlyTrap();
- uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
-
- void stDropFromRing();
-
void stStandIdleSpecial();
uint32 hmStandIdleSpecial(int messageNum, const MessageParam &param, Entity *sender);
@@ -343,18 +279,9 @@ public:
void suFallDown();
void upSpitOutFall();
- void stJumpAndFall();
- uint32 hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender);
-
void stFalling();
void stFallTouchdown();
- void stMoveVenusFlyTrap();
- void stContinueMovingVenusFlyTrap();
- uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
- void evMoveVenusFlyTrapDone();
-
void stPeekInside();
void stPeekInsideReturn();
void stPeekInsideBlink();
@@ -378,11 +305,6 @@ public:
void setSoundFlag(bool value) { _soundFlag = value; }
- void spitIntoPipe();
- void stTrySpitIntoPipe();
- void stContSpitIntoPipe();
- uint32 hmSpit(int messageNum, const MessageParam &param, Entity *sender);
-
void stRidePlatform();
void suRidePlatform();
void stPullLever();
@@ -432,13 +354,6 @@ protected:
int _moveObjectCountdown;
- bool _canSpitPipe;
- bool _contSpitPipe;
- bool _readyToSpit;
- uint32 _spitPipeIndex;
- uint32 _spitDestPipeIndex;
- uint32 _spitContDestPipeIndex;
-
virtual void xUpdate();
virtual uint32 xHandleMessage(int messageNum, const MessageParam &param);
@@ -459,311 +374,6 @@ protected:
void enterIdleAnimation(uint idleAnimation);
void walkAlongPathPoints();
-
-};
-
-class KmScene1001 : public Klaymen {
-public:
- KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1002 : public Klaymen {
-public:
- KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1004 : public Klaymen {
-public:
- KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1109 : public Klaymen {
-public:
- KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1201 : public Klaymen {
-public:
- KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1303 : public Klaymen {
-public:
- KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1304 : public Klaymen {
-public:
- KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1305 : public Klaymen {
-public:
- KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1306 : public Klaymen {
-public:
- KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1308 : public Klaymen {
-public:
- KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1401 : public Klaymen {
-public:
- KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1402 : public Klaymen {
-public:
- KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1403 : public Klaymen {
-public:
- KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1404 : public Klaymen {
-public:
- KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1608 : public Klaymen {
-public:
- KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1705 : public Klaymen {
-public:
- KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene1901 : public Klaymen {
-public:
- KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2001 : public Klaymen {
-public:
- KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2101 : public Klaymen {
-public:
- KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2201 : public Klaymen {
-public:
- KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2203 : public Klaymen {
-public:
- KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2205 : public Klaymen {
-public:
- KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2206 : public Klaymen {
-public:
- KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
- ~KmScene2206();
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2207 : public Klaymen {
-public:
- KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2242 : public Klaymen {
-public:
- KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmHallOfRecords : public Klaymen {
-public:
- KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2247 : public Klaymen {
-public:
- KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- void xUpdate();
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2401 : public Klaymen {
-public:
- KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2402 : public Klaymen {
-public:
- KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2403 : public Klaymen {
-public:
- KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2406 : public Klaymen {
-public:
- KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2501 : public Klaymen {
-public:
- KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2732 : public Klaymen {
-public:
- KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2801 : public Klaymen {
-public:
- KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2803 : public Klaymen {
-public:
- KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2803Small : public Klaymen {
-public:
- KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2805 : public Klaymen {
-public:
- KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2806 : public Klaymen {
-public:
- KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2809 : public Klaymen {
-public:
- KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2810Small : public Klaymen {
-public:
- KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2810 : public Klaymen {
-public:
- KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
- NRect *clipRects, uint clipRectsCount);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
-};
-
-class KmScene2812 : public Klaymen {
-public:
- KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
-protected:
- uint32 xHandleMessage(int messageNum, const MessageParam &param);
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp
index 7bf64a4602..5ad2dd69d7 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -160,7 +160,8 @@ void MenuModule::updateScene() {
createScene(MAKING_OF, -1);
break;
case kMainMenuToggleMusic:
- // TODO Toggle music 0048A367
+ _vm->toggleMusic(!_vm->musicIsEnabled());
+ _vm->_mixer->muteSoundType(Audio::Mixer::kMusicSoundType, !_vm->musicIsEnabled());
createScene(MAIN_MENU, -1);
break;
case kMainMenuDeleteGame:
@@ -353,11 +354,11 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule)
setPalette(0x08C0020C);
insertScreenMouse(0x00208084);
- insertStaticSprite(0x41137051, 100);
- insertStaticSprite(0xC10B2015, 100);
+ insertStaticSprite(0x41137051, 100); // "Options" header text
+ insertStaticSprite(0xC10B2015, 100); // Button texts
- // TODO Only if music is enabled
- _musicOnButton = insertStaticSprite(0x0C24C0EE, 100);
+ if (!_vm->musicIsEnabled())
+ insertStaticSprite(0x0C24C0EE, 100); // "Music is off" button
for (uint buttonIndex = 0; buttonIndex < 9; ++buttonIndex) {
Sprite *menuButton = insertSprite<MenuButton>(this, buttonIndex,
@@ -573,6 +574,7 @@ TextEditWidget::TextEditWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateM
_maxVisibleChars = (_rect.x2 - _rect.x1) / _fontSurface->getCharWidth();
_cursorPos = 0;
+ _textLabelWidget = NULL;
SetUpdateHandler(&TextEditWidget::update);
SetMessageHandler(&TextEditWidget::handleMessage);
diff --git a/engines/neverhood/menumodule.h b/engines/neverhood/menumodule.h
index f201654ceb..9da9c849a9 100644
--- a/engines/neverhood/menumodule.h
+++ b/engines/neverhood/menumodule.h
@@ -79,7 +79,6 @@ class MainMenu : public Scene {
public:
MainMenu(NeverhoodEngine *vm, Module *parentModule);
protected:
- Sprite *_musicOnButton;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
diff --git a/engines/neverhood/module.h b/engines/neverhood/module.h
index ba1e1fa3db..8ab2159030 100644
--- a/engines/neverhood/module.h
+++ b/engines/neverhood/module.h
@@ -48,6 +48,7 @@ public:
Module(NeverhoodEngine *vm, Module *parentModule);
virtual ~Module();
virtual void draw();
+ SceneType getSceneType() { return _sceneType; }
Entity *_childObject;
protected:
diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk
index 030c78a407..9c1220134c 100644
--- a/engines/neverhood/module.mk
+++ b/engines/neverhood/module.mk
@@ -15,26 +15,44 @@ MODULE_OBJS = \
microtiles.o \
module.o \
modules/module1000.o \
+ modules/module1000_sprites.o \
modules/module1100.o \
+ modules/module1100_sprites.o \
modules/module1200.o \
+ modules/module1200_sprites.o \
modules/module1300.o \
+ modules/module1300_sprites.o \
modules/module1400.o \
+ modules/module1400_sprites.o \
modules/module1500.o \
modules/module1600.o \
+ modules/module1600_sprites.o \
modules/module1700.o \
+ modules/module1700_sprites.o \
modules/module1800.o \
modules/module1900.o \
+ modules/module1900_sprites.o \
modules/module2000.o \
+ modules/module2000_sprites.o \
modules/module2100.o \
+ modules/module2100_sprites.o \
modules/module2200.o \
+ modules/module2200_sprites.o \
modules/module2300.o \
modules/module2400.o \
+ modules/module2400_sprites.o \
modules/module2500.o \
+ modules/module2500_sprites.o \
modules/module2600.o \
+ modules/module2600_sprites.o \
modules/module2700.o \
+ modules/module2700_sprites.o \
modules/module2800.o \
+ modules/module2800_sprites.o \
modules/module2900.o \
+ modules/module2900_sprites.o \
modules/module3000.o \
+ modules/module3000_sprites.o \
mouse.o \
navigationscene.o \
neverhood.o \
diff --git a/engines/neverhood/modules/module1000.cpp b/engines/neverhood/modules/module1000.cpp
index f65b89899d..534fb2ec2f 100644
--- a/engines/neverhood/modules/module1000.cpp
+++ b/engines/neverhood/modules/module1000.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module1000.h"
+#include "neverhood/modules/module1000_sprites.h"
namespace Neverhood {
@@ -118,219 +119,6 @@ void Module1000::updateScene() {
}
}
-// Scene1001
-
-AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(800, 137, 242);
- _x = 726;
- _y = 440;
- stShowIdleDoor();
- loadSound(1, 0xED403E03);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Door::handleMessage);
-}
-
-uint32 AsScene1001Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- hammerHitsDoor();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return 0;
-}
-
-void AsScene1001Door::hammerHitsDoor() {
- switch (getGlobalVar(V_DOOR_STATUS)) {
- case 0:
- case 1:
- playSound(0, 0x65482F03);
- startAnimation(0x624C0498, 1, 3);
- NextState(&AsScene1001Door::stShowIdleDoor);
- break;
- case 2:
- playSound(1);
- startAnimation(0x624C0498, 6, 6);
- NextState(&AsScene1001Door::stBustedDoorMove);
- break;
- default:
- // Nothing
- break;
- }
- incGlobalVar(V_DOOR_STATUS, 1);
-}
-
-void AsScene1001Door::stShowIdleDoor() {
- switch (getGlobalVar(V_DOOR_STATUS)) {
- case 1:
- startAnimation(0x624C0498, 4, -1);
- _newStickFrameIndex = 4;
- break;
- case 2:
- startAnimation(0x624C0498, 1, -1);
- _newStickFrameIndex = 1;
- break;
- case 3:
- stopAnimation();
- setVisible(false);
- break;
- default:
- startAnimation(0x624C0498, 0, -1);
- _newStickFrameIndex = 0;
- break;
- }
-}
-
-void AsScene1001Door::stBustedDoorMove() {
- setGlobalVar(V_DOOR_BUSTED, 1);
- startAnimation(0x624C0498, 6, 6);
- NextState(&AsScene1001Door::stBustedDoorGone);
- _x = 30;
-}
-
-void AsScene1001Door::stBustedDoorGone() {
- playSound(0);
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
- : AnimatedSprite(vm, 1100), _asDoor(asDoor) {
-
- _x = 547;
- _y = 206;
- createSurface(900, 177, 192);
- startAnimation(0x022C90D4, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Hammer::handleMessage);
-}
-
-uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x00352100)
- sendMessage(_asDoor, 0x2000, 0);
- else if (param.asInteger() == 0x0A1A0109)
- playSound(0, 0x66410886);
- break;
- case 0x2000:
- startAnimation(0x022C90D4, 1, -1);
- playSound(0, 0xE741020A);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return 0;
-}
-
-AsScene1001Window::AsScene1001Window(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- _x = 320;
- _y = 240;
- createSurface(100, 66, 129);
- startAnimation(0xC68C2299, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Window::handleMessage);
-}
-
-uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x0E0A1410)
- playSound(0, 0x60803F10);
- break;
- case 0x2001:
- startAnimation(0xC68C2299, 0, -1);
- break;
- case 0x3002:
- SetMessageHandler(NULL);
- setGlobalVar(V_WINDOW_OPEN, 1);
- setVisible(false);
- break;
- }
- return 0;
-}
-
-AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(1010, 71, 73);
- setDoDeltaX(deltaXType);
- startAnimation(0x04A98C36, 0, -1);
- _newStickFrameIndex = 0;
- _x = x;
- _y = y;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1001Lever::handleMessage);
-}
-
-uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x00C0C444)
- sendMessage(_parentScene, 0x480F, 0);
- else if (param.asInteger() == 0xC41A02C0)
- playSound(0, 0x40581882);
- break;
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x3002:
- startAnimation(0x04A98C36, 0, -1);
- _newStickFrameIndex = 0;
- break;
- case 0x480F:
- startAnimation(0x04A98C36, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) {
-
- _priority = 1100;
- _soundFileHash = soundFileHash ? soundFileHash : 0x44141000;
- setVisible(false);
- SetUpdateHandler(&SsCommonButtonSprite::update);
- SetMessageHandler(&SsCommonButtonSprite::handleMessage);
-}
-
-void SsCommonButtonSprite::update() {
- if (_countdown != 0 && (--_countdown) == 0)
- setVisible(false);
-}
-
-uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- setVisible(true);
- _countdown = 8;
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asDoor(NULL), _asWindow(NULL) {
@@ -439,719 +227,6 @@ uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-// Scene1002
-
-AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
-
- SetUpdateHandler(&AsScene1002Ring::update);
-
- if (_isSpecial) {
- createSurface(990, 68, 314);
- if (isRingLow) {
- startAnimation(0x04103090, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- } else {
- startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
- SetMessageHandler(&AsScene1002Ring::hmRingIdle);
- }
- } else {
- createSurface(990, 68, 138);
- startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
- SetMessageHandler(&AsScene1002Ring::hmRingIdle);
- }
-
- setClipRect(0, clipY1, 640, 480);
-
- _x = x;
- _y = y;
-
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
-
-}
-
-void AsScene1002Ring::update() {
- updateAnim();
- updatePosition();
-}
-
-uint32 AsScene1002Ring::hmRingIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4806:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- sendMessage(_parentScene, 0x4806, 0);
- SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
- startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
- break;
- case 0x480F:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- sendMessage(_parentScene, 0x480F, 0);
- SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
- startAnimation(0x861A2020, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- break;
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0x8258A030, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(0x04103090, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0x8258A030, 0, -1);
- SetMessageHandler(&AsScene1002Ring::hmRingReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmRingIdle(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x05410F72)
- playSound(0, 0x21EE40A9);
- break;
- case 0x3002:
- startAnimation(0xA85C4011, 0, -1);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect)
- : StaticSprite(vm, 1200) {
-
- loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239);
- setClipRect(clipRect);
- SetUpdateHandler(&AsScene1002Door::update);
- SetMessageHandler(&AsScene1002Door::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1002Door::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1002Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
- SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
- break;
- case 0x4809:
- setGlobalVar(V_FLYTRAP_RING_DOOR, 0);
- SetSpriteUpdate(&AsScene1002Door::suCloseDoor);
- break;
- }
- return messageResult;
-}
-
-void AsScene1002Door::suOpenDoor() {
- if (_y > 49) {
- _y -= 8;
- if (_y < 49) {
- SetSpriteUpdate(NULL);
- _y = 49;
- }
- _needRefresh = true;
- }
-}
-
-void AsScene1002Door::suCloseDoor() {
- if (_y < 239) {
- _y += 8;
- if (_y > 239) {
- SetSpriteUpdate(NULL);
- _y = 239;
- }
- _needRefresh = true;
- }
-}
-
-AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface(1025, 88, 165);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
-}
-
-uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- _x = ((Sprite*)sender)->getX() - 98;
- _y = ((Sprite*)sender)->getY() - 111;
- startAnimation(0x0422255A, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene1002DoorSpy::AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect)
- : AnimatedSprite(vm, 1300), _clipRect(clipRect), _parentScene(parentScene), _asDoor(asDoor), _asBoxingGloveHitEffect(asScene1002BoxingGloveHitEffect) {
-
- createSurface(800, 136, 147);
- setClipRect(clipRect);
- suDoorSpy();
- loadSound(0, 0xC0C40298);
- startAnimation(0x586C1D48, 0, 0);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
- SetSpriteUpdate(&AsScene1002DoorSpy::suDoorSpy);
-}
-
-uint32 AsScene1002DoorSpy::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0xA61CA1C2)
- sendMessage(_asBoxingGloveHitEffect, 0x2004, 0);
- else if (param.asInteger() == 0x14CE0620)
- playSound(0);
- break;
- case 0x2003:
- stDoorSpyBoxingGlove();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002DoorSpy::hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1002DoorSpy::suDoorSpy() {
- _x = _asDoor->getX() + 34;
- _y = _asDoor->getY() + 175;
-}
-
-void AsScene1002DoorSpy::stDoorSpyIdle() {
- setClipRect(_clipRect);
- _parentScene->setSurfacePriority(getSurface(), 800);
- startAnimation(0x586C1D48, 0, 0);
- SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
-}
-
-void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
- setClipRect(0, 0, 640, 480);
- _parentScene->setSurfacePriority(getSurface(), 1200);
- startAnimation(0x586C1D48, 1, -1);
- SetMessageHandler(&AsScene1002DoorSpy::hmDoorSpyAnimation);
- NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
-}
-
-SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0), _countdown(0) {
-
- _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000;
- _fileHashes[0] = fileHash1;
- _fileHashes[1] = fileHash2;
- createSurface(surfacePriority, 40, 40);
- loadSprite(fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- setVisible(false);
- SetUpdateHandler(&SsCommonPressButton::update);
- SetMessageHandler(&SsCommonPressButton::handleMessage);
-}
-
-void SsCommonPressButton::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
- _fileHashes[0] = fileHash1;
- _fileHashes[1] = fileHash2;
- loadSprite(_status == 2 ? fileHash2 : fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
-}
-
-void SsCommonPressButton::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- if (_status == 1) {
- _status = 2;
- loadSprite(_fileHashes[1], kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 4;
- } else if (_status == 2) {
- _status = 3;
- loadSprite(_fileHashes[0], kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 4;
- } else if (_status == 3) {
- _status = 0;
- setVisible(false);
- }
- }
-}
-
-uint32 SsCommonPressButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- _status = 1;
- _countdown = 4;
- setVisible(true);
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
-AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _isSecond(isSecond), _countdown(0) {
-
- createSurface(995, 175, 195);
- if (!_isSecond) {
- if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- setDoDeltaX(1);
- _x = 366;
- _y = 435;
- stRingGrabbed();
- } else {
- _x = 174 + getGlobalVar(V_FLYTRAP_POSITION_1) * 32;
- _y = 435;
- stIdle();
- }
- } else {
- _x = 186 + getGlobalVar(V_FLYTRAP_POSITION_2) * 32;
- _y = 364;
- if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE)) {
- stRingGrabbed();
- } else {
- stIdle();
- }
- }
- _flags = 4;
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-void AsScene1002VenusFlyTrap::update() {
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- AnimatedSprite::update();
-}
-
-void AsScene1002VenusFlyTrap::upIdle() {
- if (_countdown == 0 && _klaymen->getX() - 20 > _x)
- setDoDeltaX(1);
- else if (_klaymen->getX() + 20 < _x)
- setDoDeltaX(0);
- update();
-}
-
-uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000890C4)
- playSound(0, 0xC21190D8);
- else if (param.asInteger() == 0x522200A0)
- playSound(0, 0x931080C8);
- break;
- case 0x1011:
- if (_isSecond) {
- if (_x >= 154 && _x <= 346) {
- sendMessage(_parentScene, 0x2000, 0);
- messageResult = 1;
- }
- } else {
- if (_x >= 174 && _x <= 430) {
- sendMessage(_parentScene, 0x2000, 0);
- messageResult = 1;
- }
- }
- break;
- case 0x480B:
- setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
- if (!_isSecond) {
- if (getGlobalVar(V_FLYTRAP_RING_DOOR))
- stRelease();
- else
- stWalk();
- } else {
- if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE))
- stRelease();
- else
- stWalk();
- }
- break;
- case 0x480C:
- if (_isSecond) {
- if (_x >= 154 && _x <= 346)
- messageResult = 1;
- else
- messageResult = 0;
- } else {
- if (_x >= 174 && _x <= 430)
- messageResult = 1;
- else
- messageResult = 0;
- }
- break;
- case 0x480E:
- if (param.asInteger() == 1)
- stGrabRing();
- break;
- case 0x4810:
- swallowKlaymen();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 995);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1015);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x000890C4)
- playSound(0, 0xC21190D8);
- else if (param.asInteger() == 0x41881801) {
- if (_isSecond) {
- if (_x > 330)
- sendMessage(_klaymen, 0x4811, 2);
- else
- sendMessage(_klaymen, 0x4811, 0);
- } else {
- sendMessage(_klaymen, 0x4811, 0);
- }
- } else if (param.asInteger() == 0x522200A0)
- playSound(0, 0x931080C8);
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 995);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1015);
- break;
- }
- return messageResult;
-}
-
-void AsScene1002VenusFlyTrap::stWalkBack() {
- setDoDeltaX(2);
- startAnimation(0xC4080034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stWalk() {
- startAnimation(0xC4080034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stRelease() {
- sendMessage(_parentScene, 0x4807, 0);
- startAnimation(0x82292851, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::stGrabRing() {
- setDoDeltaX(1);
- startAnimation(0x86A82A11, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
- NextState(&AsScene1002VenusFlyTrap::stRingGrabbed);
-}
-
-void AsScene1002VenusFlyTrap::stRingGrabbed() {
- startAnimation(0xB5A86034, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
-}
-
-void AsScene1002VenusFlyTrap::stKlaymenInside() {
- startAnimation(0x31303094, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(NULL);
- NextState(&AsScene1002VenusFlyTrap::stKlaymenInsideMoving);
- _countdown = 24;
-}
-
-void AsScene1002VenusFlyTrap::stIdle() {
- startAnimation(0xC8204250, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::upIdle);
- SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
- if (_isSecond) {
- if (_x >= 154 && _x <= 346)
- setGlobalVar(V_FLYTRAP_POSITION_2, (_x - 186) / 32);
- else {
- NextState(&AsScene1002VenusFlyTrap::stWalkBack);
- _countdown = 12;
- }
- } else {
- if (_x >= 174 && _x <= 430)
- setGlobalVar(V_FLYTRAP_POSITION_1, (_x - 174) / 32);
- else {
- NextState(&AsScene1002VenusFlyTrap::stWalkBack);
- _countdown = 12;
- }
- }
-}
-
-void AsScene1002VenusFlyTrap::stKlaymenInsideMoving() {
- startAnimation(0x152920C4, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stSpitOutKlaymen);
-}
-
-void AsScene1002VenusFlyTrap::stSpitOutKlaymen() {
- startAnimation(0x84001117, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stIdle);
-}
-
-void AsScene1002VenusFlyTrap::swallowKlaymen() {
- if (_x - 15 < _klaymen->getX() && _x + 15 > _klaymen->getX()) {
- if (_isSecond)
- setDoDeltaX(_x > 265 && _x < 330 ? 1 : 0);
- else
- setDoDeltaX(_x > 320 ? 1 : 0);
- sendMessage(_klaymen, 0x2001, 0);
- startAnimation(0x8C2C80D4, 0, -1);
- SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
- SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
- NextState(&AsScene1002VenusFlyTrap::stKlaymenInside);
- }
-}
-
-AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _countdown(0) {
-
- createSurface(850, 186, 212);
- _x = 320;
- _y = 240;
- if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- startAnimation(0x004A4495, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else
- setVisible(false);
- SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
-}
-
-void AsScene1002OutsideDoorBackground::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- if (_isDoorClosed)
- stCloseDoor();
- else
- stOpenDoor();
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene1002OutsideDoorBackground::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageResult) {
- case 0x4808:
- _isDoorClosed = false;
- _countdown = 2;
- break;
- case 0x4809:
- _isDoorClosed = true;
- _countdown = 2;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1002OutsideDoorBackground::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageResult) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1002OutsideDoorBackground::stOpenDoor() {
- startAnimation(0x004A4495, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
-}
-
-void AsScene1002OutsideDoorBackground::stCloseDoor() {
- startAnimation(0x004A4495, -1, -1);
- _playBackwards = true;
- setVisible(true);
- SetMessageHandler(&AsScene1002OutsideDoorBackground::hmAnimation);
- NextState(&AsScene1002OutsideDoorBackground::stDoorClosed);
-}
-
-void AsScene1002OutsideDoorBackground::stDoorClosed() {
- setVisible(false);
- stopAnimation();
-}
-
-AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
- : AnimatedSprite(vm, 1200), _klaymen(klaymen) {
-
- createSurface(1200, 40, 163);
- setVisible(false);
- SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene1002KlaymenLadderHands::update() {
- if (_klaymen->getCurrAnimFileHash() == 0x3A292504) {
- startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) {
- startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else
- setVisible(false);
- AnimatedSprite::update();
-}
-
-AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen)
- : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen),
- _isClipRectSaved(false) {
-
- createSurface(1000, 33, 41);
- setVisible(false);
- SetUpdateHandler(&AsScene1002KlaymenPeekHand::update);
- SetMessageHandler(&AsScene1002KlaymenPeekHand::handleMessage);
-}
-
-void AsScene1002KlaymenPeekHand::update() {
- if (_klaymen->getCurrAnimFileHash() == 0xAC20C012 && _klaymen->getFrameIndex() < 50) {
- startAnimation(0x9820C913, _klaymen->getFrameIndex(), -1);
- _newStickFrameIndex = _klaymen->getFrameIndex();
- setVisible(true);
- _x = _klaymen->getX();
- _y = _klaymen->getY();
- setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
- } else
- setVisible(false);
- AnimatedSprite::update();
-}
-
-uint32 AsScene1002KlaymenPeekHand::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4AB28209) {
- sendMessage(_parentScene, 0x1022, 1200);
- _isClipRectSaved = true;
- _savedClipRect = _surface->getClipRect();
- setClipRect(0, 0, 640, 480);
- } else if (param.asInteger() == 0x88001184) {
- sendMessage(_parentScene, 0x1022, 1000);
- if (_isClipRectSaved)
- setClipRect(_savedClipRect);
- }
- break;
- }
- return messageResult;
-}
-
Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isKlaymenFloor(false), _isClimbingLadder(false) {
@@ -1383,61 +458,6 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-// StaticScene
-
-StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash)
- : Scene(vm, parentModule) {
-
- SetMessageHandler(&StaticScene::handleMessage);
-
- setBackground(backgroundFileHash);
- setPalette(backgroundFileHash);
- insertPuzzleMouse(cursorFileHash, 20, 620);
-}
-
-uint32 StaticScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Scene::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x0001:
- if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
- leaveScene(0);
- break;
- }
- return 0;
-}
-
-// Scene1004
-
-AsScene1004TrashCan::AsScene1004TrashCan(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 330;
- _y = 327;
- createSurface(800, 56, 50);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1004TrashCan::handleMessage);
-}
-
-uint32 AsScene1004TrashCan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x225A8587)
- playSound(0, 0x109AFC4C);
- break;
- case 0x2002:
- startAnimation(0xEB312C11, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return 0;
-}
-
Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteAreaStatus(-1) {
@@ -1536,8 +556,6 @@ void Scene1004::updatePaletteArea() {
}
}
-// Scene1005
-
Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
diff --git a/engines/neverhood/modules/module1000.h b/engines/neverhood/modules/module1000.h
index 8461ecfc6f..4b17c92b3b 100644
--- a/engines/neverhood/modules/module1000.h
+++ b/engines/neverhood/modules/module1000.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1000
-
class Module1000 : public Module {
public:
Module1000(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,53 +40,6 @@ protected:
void updateScene();
};
-// Scene1001
-
-class AsScene1001Door : public AnimatedSprite {
-public:
- AsScene1001Door(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void hammerHitsDoor();
- void stShowIdleDoor();
- void stBustedDoorMove();
- void stBustedDoorGone();
-};
-
-class AsScene1001Hammer : public AnimatedSprite {
-public:
- AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
-protected:
- Sprite *_asDoor;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1001Window : public AnimatedSprite {
-public:
- AsScene1001Window(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1001Lever : public AnimatedSprite {
-public:
- AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsCommonButtonSprite : public StaticSprite {
-public:
- SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- int16 _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1001 : public Scene {
public:
Scene1001(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -102,136 +53,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// TODO: Move this to some common file since it's used several times
-
-class StaticScene : public Scene {
-public:
- StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-// Scene1002
-
-class AsScene1002Ring : public AnimatedSprite {
-public:
- AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
-protected:
- Scene *_parentScene;
- bool _isSpecial;
- void update();
- uint32 hmRingIdle(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRingReleased(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002Door : public StaticSprite {
-public:
- AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
-protected:
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suOpenDoor();
- void suCloseDoor();
-};
-
-class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
-public:
- AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002DoorSpy : public AnimatedSprite {
-public:
- AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
-protected:
- Scene *_parentScene;
- Sprite *_asDoor;
- Sprite *_asBoxingGloveHitEffect;
- NRect _clipRect;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void suDoorSpy();
- void stDoorSpyIdle();
- void stDoorSpyBoxingGlove();
-};
-
-class SsCommonPressButton : public StaticSprite {
-public:
- SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
- void setFileHashes(uint32 fileHash1, uint32 fileHash2);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- uint32 _fileHashes[2];
- int _status;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1002VenusFlyTrap : public AnimatedSprite {
-public:
- AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- int _countdown;
- bool _isSecond;
- void update();
- void upIdle();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender);
- void stWalkBack();
- void stWalk();
- void stRelease();
- void stGrabRing();
- void stRingGrabbed();
- void stKlaymenInside();
- void stIdle();
- void stKlaymenInsideMoving();
- void stSpitOutKlaymen();
- void swallowKlaymen();
-};
-
-class AsScene1002OutsideDoorBackground : public AnimatedSprite {
-public:
- AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
-protected:
- int _countdown;
- bool _isDoorClosed;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stDoorClosed();
-};
-
-class AsScene1002KlaymenLadderHands : public AnimatedSprite {
-public:
- AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
-protected:
- Klaymen *_klaymen;
- void update();
-};
-
-class AsScene1002KlaymenPeekHand : public AnimatedSprite {
-public:
- AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
-protected:
- Scene *_parentScene;
- Klaymen *_klaymen;
- bool _isClipRectSaved;
- NRect _savedClipRect;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1002 : public Scene {
public:
Scene1002(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -260,15 +81,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1004
-
-class AsScene1004TrashCan : public AnimatedSprite {
-public:
- AsScene1004TrashCan(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1004 : public Scene {
public:
Scene1004(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -281,8 +93,6 @@ protected:
void updatePaletteArea();
};
-// Scene1005
-
class Scene1005 : public Scene {
public:
Scene1005(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1000_sprites.cpp b/engines/neverhood/modules/module1000_sprites.cpp
new file mode 100644
index 0000000000..55618f0124
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.cpp
@@ -0,0 +1,1567 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1000_sprites.h"
+
+namespace Neverhood {
+
+AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(800, 137, 242);
+ _x = 726;
+ _y = 440;
+ stShowIdleDoor();
+ loadSound(1, 0xED403E03);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Door::handleMessage);
+}
+
+uint32 AsScene1001Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ hammerHitsDoor();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return 0;
+}
+
+void AsScene1001Door::hammerHitsDoor() {
+ switch (getGlobalVar(V_DOOR_STATUS)) {
+ case 0:
+ case 1:
+ playSound(0, 0x65482F03);
+ startAnimation(0x624C0498, 1, 3);
+ NextState(&AsScene1001Door::stShowIdleDoor);
+ break;
+ case 2:
+ playSound(1);
+ startAnimation(0x624C0498, 6, 6);
+ NextState(&AsScene1001Door::stBustedDoorMove);
+ break;
+ default:
+ // Nothing
+ break;
+ }
+ incGlobalVar(V_DOOR_STATUS, 1);
+}
+
+void AsScene1001Door::stShowIdleDoor() {
+ switch (getGlobalVar(V_DOOR_STATUS)) {
+ case 1:
+ startAnimation(0x624C0498, 4, -1);
+ _newStickFrameIndex = 4;
+ break;
+ case 2:
+ startAnimation(0x624C0498, 1, -1);
+ _newStickFrameIndex = 1;
+ break;
+ case 3:
+ stopAnimation();
+ setVisible(false);
+ break;
+ default:
+ startAnimation(0x624C0498, 0, -1);
+ _newStickFrameIndex = 0;
+ break;
+ }
+}
+
+void AsScene1001Door::stBustedDoorMove() {
+ setGlobalVar(V_DOOR_BUSTED, 1);
+ startAnimation(0x624C0498, 6, 6);
+ NextState(&AsScene1001Door::stBustedDoorGone);
+ _x = 30;
+}
+
+void AsScene1001Door::stBustedDoorGone() {
+ playSound(0);
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1001Hammer::AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor)
+ : AnimatedSprite(vm, 1100), _asDoor(asDoor) {
+
+ _x = 547;
+ _y = 206;
+ createSurface(900, 177, 192);
+ startAnimation(0x022C90D4, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Hammer::handleMessage);
+}
+
+uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x00352100)
+ sendMessage(_asDoor, 0x2000, 0);
+ else if (param.asInteger() == 0x0A1A0109)
+ playSound(0, 0x66410886);
+ break;
+ case 0x2000:
+ startAnimation(0x022C90D4, 1, -1);
+ playSound(0, 0xE741020A);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return 0;
+}
+
+AsScene1001Window::AsScene1001Window(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ _x = 320;
+ _y = 240;
+ createSurface(100, 66, 129);
+ startAnimation(0xC68C2299, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Window::handleMessage);
+}
+
+uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x0E0A1410)
+ playSound(0, 0x60803F10);
+ break;
+ case 0x2001:
+ startAnimation(0xC68C2299, 0, -1);
+ break;
+ case 0x3002:
+ SetMessageHandler(NULL);
+ setGlobalVar(V_WINDOW_OPEN, 1);
+ setVisible(false);
+ break;
+ }
+ return 0;
+}
+
+AsScene1001Lever::AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(1010, 71, 73);
+ setDoDeltaX(deltaXType);
+ startAnimation(0x04A98C36, 0, -1);
+ _newStickFrameIndex = 0;
+ _x = x;
+ _y = y;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1001Lever::handleMessage);
+}
+
+uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x00C0C444)
+ sendMessage(_parentScene, 0x480F, 0);
+ else if (param.asInteger() == 0xC41A02C0)
+ playSound(0, 0x40581882);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x3002:
+ startAnimation(0x04A98C36, 0, -1);
+ _newStickFrameIndex = 0;
+ break;
+ case 0x480F:
+ startAnimation(0x04A98C36, 0, -1);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+SsCommonButtonSprite::SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene), _countdown(0) {
+
+ _priority = 1100;
+ _soundFileHash = soundFileHash ? soundFileHash : 0x44141000;
+ setVisible(false);
+ SetUpdateHandler(&SsCommonButtonSprite::update);
+ SetMessageHandler(&SsCommonButtonSprite::handleMessage);
+}
+
+void SsCommonButtonSprite::update() {
+ if (_countdown != 0 && (--_countdown) == 0)
+ setVisible(false);
+}
+
+uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ setVisible(true);
+ _countdown = 8;
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002Ring::AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isSpecial(isSpecial) {
+
+ SetUpdateHandler(&AsScene1002Ring::update);
+
+ if (_isSpecial) {
+ createSurface(990, 68, 314);
+ if (isRingLow) {
+ startAnimation(0x04103090, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ } else {
+ startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingIdle);
+ }
+ } else {
+ createSurface(990, 68, 138);
+ startAnimation(0xA85C4011, _vm->_rnd->getRandomNumber(15), -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingIdle);
+ }
+
+ setClipRect(0, clipY1, 640, 480);
+
+ _x = x;
+ _y = y;
+
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+
+}
+
+void AsScene1002Ring::update() {
+ updateAnim();
+ updatePosition();
+}
+
+uint32 AsScene1002Ring::hmRingIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4806:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, 0x4806, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
+ startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
+ break;
+ case 0x480F:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, 0x480F, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
+ startAnimation(0x861A2020, 0, -1);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case 0x4807:
+ sendMessage(_parentScene, 0x4807, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(0x04103090, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4807:
+ sendMessage(_parentScene, 0x4807, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmRingIdle(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x05410F72)
+ playSound(0, 0x21EE40A9);
+ break;
+ case 0x3002:
+ startAnimation(0xA85C4011, 0, -1);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002Door::AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect)
+ : StaticSprite(vm, 1200) {
+
+ loadSprite(0x1052370F, kSLFDefDrawOffset | kSLFSetPosition, 800, 526, getGlobalVar(V_FLYTRAP_RING_DOOR) ? 49 : 239);
+ setClipRect(clipRect);
+ SetUpdateHandler(&AsScene1002Door::update);
+ SetMessageHandler(&AsScene1002Door::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1002Door::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1002Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4808:
+ setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
+ SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
+ break;
+ case 0x4809:
+ setGlobalVar(V_FLYTRAP_RING_DOOR, 0);
+ SetSpriteUpdate(&AsScene1002Door::suCloseDoor);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002Door::suOpenDoor() {
+ if (_y > 49) {
+ _y -= 8;
+ if (_y < 49) {
+ SetSpriteUpdate(NULL);
+ _y = 49;
+ }
+ _needRefresh = true;
+ }
+}
+
+void AsScene1002Door::suCloseDoor() {
+ if (_y < 239) {
+ _y += 8;
+ if (_y > 239) {
+ SetSpriteUpdate(NULL);
+ _y = 239;
+ }
+ _needRefresh = true;
+ }
+}
+
+AsScene1002BoxingGloveHitEffect::AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface(1025, 88, 165);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1002BoxingGloveHitEffect::handleMessage);
+}
+
+uint32 AsScene1002BoxingGloveHitEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ _x = ((Sprite*)sender)->getX() - 98;
+ _y = ((Sprite*)sender)->getY() - 111;
+ startAnimation(0x0422255A, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002DoorSpy::AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect)
+ : AnimatedSprite(vm, 1300), _clipRect(clipRect), _parentScene(parentScene), _asDoor(asDoor), _asBoxingGloveHitEffect(asScene1002BoxingGloveHitEffect) {
+
+ createSurface(800, 136, 147);
+ setClipRect(clipRect);
+ suDoorSpy();
+ loadSound(0, 0xC0C40298);
+ startAnimation(0x586C1D48, 0, 0);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
+ SetSpriteUpdate(&AsScene1002DoorSpy::suDoorSpy);
+}
+
+uint32 AsScene1002DoorSpy::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0xA61CA1C2)
+ sendMessage(_asBoxingGloveHitEffect, 0x2004, 0);
+ else if (param.asInteger() == 0x14CE0620)
+ playSound(0);
+ break;
+ case 0x2003:
+ stDoorSpyBoxingGlove();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002DoorSpy::hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002DoorSpy::suDoorSpy() {
+ _x = _asDoor->getX() + 34;
+ _y = _asDoor->getY() + 175;
+}
+
+void AsScene1002DoorSpy::stDoorSpyIdle() {
+ setClipRect(_clipRect);
+ _parentScene->setSurfacePriority(getSurface(), 800);
+ startAnimation(0x586C1D48, 0, 0);
+ SetMessageHandler(&AsScene1002DoorSpy::handleMessage);
+}
+
+void AsScene1002DoorSpy::stDoorSpyBoxingGlove() {
+ setClipRect(0, 0, 640, 480);
+ _parentScene->setSurfacePriority(getSurface(), 1200);
+ startAnimation(0x586C1D48, 1, -1);
+ SetMessageHandler(&AsScene1002DoorSpy::hmDoorSpyAnimation);
+ NextState(&AsScene1002DoorSpy::stDoorSpyIdle);
+}
+
+SsCommonPressButton::SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, 1100), _parentScene(parentScene), _status(0), _countdown(0) {
+
+ _soundFileHash = soundFileHash != 0 ? soundFileHash : 0x44141000;
+ _fileHashes[0] = fileHash1;
+ _fileHashes[1] = fileHash2;
+ createSurface(surfacePriority, 40, 40);
+ loadSprite(fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ setVisible(false);
+ SetUpdateHandler(&SsCommonPressButton::update);
+ SetMessageHandler(&SsCommonPressButton::handleMessage);
+}
+
+void SsCommonPressButton::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
+ _fileHashes[0] = fileHash1;
+ _fileHashes[1] = fileHash2;
+ loadSprite(_status == 2 ? fileHash2 : fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+}
+
+void SsCommonPressButton::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ if (_status == 1) {
+ _status = 2;
+ loadSprite(_fileHashes[1], kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 4;
+ } else if (_status == 2) {
+ _status = 3;
+ loadSprite(_fileHashes[0], kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 4;
+ } else if (_status == 3) {
+ _status = 0;
+ setVisible(false);
+ }
+ }
+}
+
+uint32 SsCommonPressButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ _status = 1;
+ _countdown = 4;
+ setVisible(true);
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1002VenusFlyTrap::AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _isSecond(isSecond), _countdown(0) {
+
+ createSurface(995, 175, 195);
+ if (!_isSecond) {
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
+ setDoDeltaX(1);
+ _x = 366;
+ _y = 435;
+ stRingGrabbed();
+ } else {
+ _x = 174 + getGlobalVar(V_FLYTRAP_POSITION_1) * 32;
+ _y = 435;
+ stIdle();
+ }
+ } else {
+ _x = 186 + getGlobalVar(V_FLYTRAP_POSITION_2) * 32;
+ _y = 364;
+ if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE)) {
+ stRingGrabbed();
+ } else {
+ stIdle();
+ }
+ }
+ _flags = 4;
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+void AsScene1002VenusFlyTrap::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ AnimatedSprite::update();
+}
+
+void AsScene1002VenusFlyTrap::upIdle() {
+ if (_countdown == 0 && _klaymen->getX() - 20 > _x)
+ setDoDeltaX(1);
+ else if (_klaymen->getX() + 20 < _x)
+ setDoDeltaX(0);
+ update();
+}
+
+uint32 AsScene1002VenusFlyTrap::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x000890C4)
+ playSound(0, 0xC21190D8);
+ else if (param.asInteger() == 0x522200A0)
+ playSound(0, 0x931080C8);
+ break;
+ case 0x1011:
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346) {
+ sendMessage(_parentScene, 0x2000, 0);
+ messageResult = 1;
+ }
+ } else {
+ if (_x >= 174 && _x <= 430) {
+ sendMessage(_parentScene, 0x2000, 0);
+ messageResult = 1;
+ }
+ }
+ break;
+ case 0x480B:
+ setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
+ if (!_isSecond) {
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR))
+ stRelease();
+ else
+ stWalk();
+ } else {
+ if (getGlobalVar(V_FLYTRAP_RING_BRIDGE) || getGlobalVar(V_FLYTRAP_RING_FENCE))
+ stRelease();
+ else
+ stWalk();
+ }
+ break;
+ case 0x480C:
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346)
+ messageResult = 1;
+ else
+ messageResult = 0;
+ } else {
+ if (_x >= 174 && _x <= 430)
+ messageResult = 1;
+ else
+ messageResult = 0;
+ }
+ break;
+ case 0x480E:
+ if (param.asInteger() == 1)
+ stGrabRing();
+ break;
+ case 0x4810:
+ swallowKlaymen();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 995);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1015);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x000890C4)
+ playSound(0, 0xC21190D8);
+ else if (param.asInteger() == 0x41881801) {
+ if (_isSecond) {
+ if (_x > 330)
+ sendMessage(_klaymen, 0x4811, 2);
+ else
+ sendMessage(_klaymen, 0x4811, 0);
+ } else {
+ sendMessage(_klaymen, 0x4811, 0);
+ }
+ } else if (param.asInteger() == 0x522200A0)
+ playSound(0, 0x931080C8);
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 995);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1015);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002VenusFlyTrap::stWalkBack() {
+ setDoDeltaX(2);
+ startAnimation(0xC4080034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stWalk() {
+ startAnimation(0xC4080034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stRelease() {
+ sendMessage(_parentScene, 0x4807, 0);
+ startAnimation(0x82292851, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::stGrabRing() {
+ setDoDeltaX(1);
+ startAnimation(0x86A82A11, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationSimple);
+ NextState(&AsScene1002VenusFlyTrap::stRingGrabbed);
+}
+
+void AsScene1002VenusFlyTrap::stRingGrabbed() {
+ startAnimation(0xB5A86034, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+}
+
+void AsScene1002VenusFlyTrap::stKlaymenInside() {
+ startAnimation(0x31303094, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(NULL);
+ NextState(&AsScene1002VenusFlyTrap::stKlaymenInsideMoving);
+ _countdown = 24;
+}
+
+void AsScene1002VenusFlyTrap::stIdle() {
+ startAnimation(0xC8204250, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::upIdle);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::handleMessage);
+ if (_isSecond) {
+ if (_x >= 154 && _x <= 346)
+ setGlobalVar(V_FLYTRAP_POSITION_2, (_x - 186) / 32);
+ else {
+ NextState(&AsScene1002VenusFlyTrap::stWalkBack);
+ _countdown = 12;
+ }
+ } else {
+ if (_x >= 174 && _x <= 430)
+ setGlobalVar(V_FLYTRAP_POSITION_1, (_x - 174) / 32);
+ else {
+ NextState(&AsScene1002VenusFlyTrap::stWalkBack);
+ _countdown = 12;
+ }
+ }
+}
+
+void AsScene1002VenusFlyTrap::stKlaymenInsideMoving() {
+ startAnimation(0x152920C4, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stSpitOutKlaymen);
+}
+
+void AsScene1002VenusFlyTrap::stSpitOutKlaymen() {
+ startAnimation(0x84001117, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stIdle);
+}
+
+void AsScene1002VenusFlyTrap::swallowKlaymen() {
+ if (_x - 15 < _klaymen->getX() && _x + 15 > _klaymen->getX()) {
+ if (_isSecond)
+ setDoDeltaX(_x > 265 && _x < 330 ? 1 : 0);
+ else
+ setDoDeltaX(_x > 320 ? 1 : 0);
+ sendMessage(_klaymen, 0x2001, 0);
+ startAnimation(0x8C2C80D4, 0, -1);
+ SetUpdateHandler(&AsScene1002VenusFlyTrap::update);
+ SetMessageHandler(&AsScene1002VenusFlyTrap::hmAnimationExt);
+ NextState(&AsScene1002VenusFlyTrap::stKlaymenInside);
+ }
+}
+
+AsScene1002OutsideDoorBackground::AsScene1002OutsideDoorBackground(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _countdown(0), _isDoorClosed(true) {
+
+ createSurface(850, 186, 212);
+ _x = 320;
+ _y = 240;
+ if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
+ startAnimation(0x004A4495, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002OutsideDoorBackground::update);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
+}
+
+void AsScene1002OutsideDoorBackground::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ if (_isDoorClosed)
+ stCloseDoor();
+ else
+ stOpenDoor();
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1002OutsideDoorBackground::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageResult) {
+ case 0x4808:
+ _isDoorClosed = false;
+ _countdown = 2;
+ break;
+ case 0x4809:
+ _isDoorClosed = true;
+ _countdown = 2;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002OutsideDoorBackground::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageResult) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1002OutsideDoorBackground::stOpenDoor() {
+ startAnimation(0x004A4495, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::handleMessage);
+}
+
+void AsScene1002OutsideDoorBackground::stCloseDoor() {
+ startAnimation(0x004A4495, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ SetMessageHandler(&AsScene1002OutsideDoorBackground::hmAnimation);
+ NextState(&AsScene1002OutsideDoorBackground::stDoorClosed);
+}
+
+void AsScene1002OutsideDoorBackground::stDoorClosed() {
+ setVisible(false);
+ stopAnimation();
+}
+
+AsScene1002KlaymenLadderHands::AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1200), _klaymen(klaymen) {
+
+ createSurface(1200, 40, 163);
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002KlaymenLadderHands::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene1002KlaymenLadderHands::update() {
+ if (_klaymen->getCurrAnimFileHash() == 0x3A292504) {
+ startAnimation(0xBA280522, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else if (_klaymen->getCurrAnimFileHash() == 0x122D1505) {
+ startAnimation(0x1319150C, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else
+ setVisible(false);
+ AnimatedSprite::update();
+}
+
+AsScene1002KlaymenPeekHand::AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1200), _parentScene(parentScene), _klaymen(klaymen),
+ _isClipRectSaved(false) {
+
+ createSurface(1000, 33, 41);
+ setVisible(false);
+ SetUpdateHandler(&AsScene1002KlaymenPeekHand::update);
+ SetMessageHandler(&AsScene1002KlaymenPeekHand::handleMessage);
+}
+
+void AsScene1002KlaymenPeekHand::update() {
+ if (_klaymen->getCurrAnimFileHash() == 0xAC20C012 && _klaymen->getFrameIndex() < 50) {
+ startAnimation(0x9820C913, _klaymen->getFrameIndex(), -1);
+ _newStickFrameIndex = _klaymen->getFrameIndex();
+ setVisible(true);
+ _x = _klaymen->getX();
+ _y = _klaymen->getY();
+ setDoDeltaX(_klaymen->isDoDeltaX() ? 1 : 0);
+ } else
+ setVisible(false);
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1002KlaymenPeekHand::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_parentScene, 0x1022, 1200);
+ _isClipRectSaved = true;
+ _savedClipRect = _surface->getClipRect();
+ setClipRect(0, 0, 640, 480);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_parentScene, 0x1022, 1000);
+ if (_isClipRectSaved)
+ setClipRect(_savedClipRect);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1004TrashCan::AsScene1004TrashCan(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 330;
+ _y = 327;
+ createSurface(800, 56, 50);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1004TrashCan::handleMessage);
+}
+
+uint32 AsScene1004TrashCan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x225A8587)
+ playSound(0, 0x109AFC4C);
+ break;
+ case 0x2002:
+ startAnimation(0xEB312C11, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return 0;
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1002[] = {
+ {1, kIdlePickEar},
+ {2, kIdleWonderAbout}
+};
+
+KmScene1001::KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+}
+
+uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 2)
+ GotoState(&KmScene1001::stSleeping);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1001::stPullHammerLever);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4836:
+ if (param.asInteger() == 1) {
+ sendMessage(_parentScene, 0x2002, 0);
+ GotoState(&KmScene1001::stWakeUp);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1001::stWakeUp() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x527AC970, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevelAnimation);
+ SetSpriteUpdate(NULL);
+}
+
+void KmScene1001::stSleeping() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x5A38C110, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1001::hmSleeping);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1001::hmSleeping(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevel(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x03060012) {
+ playSound(0, 0xC0238244);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1001::stPullHammerLever() {
+ if (!stStartAction(AnimationCallback(&KmScene1001::stPullHammerLever))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x00648953, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1001::hmPullHammerLever);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ }
+}
+
+uint32 KmScene1001::hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLever(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209)
+ sendMessage(_attachedSprite, 0x480F, 0);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1002::KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable1();
+}
+
+void KmScene1002::setupJumpToRing() {
+ _acceptInput = false;
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpToRing);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ NextState(&KmScene1002::stHangOnRing);
+ sendMessage(_attachedSprite, 0x482B, 0);
+}
+
+void KmScene1002::stJumpToRing1() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing1))) {
+ _busyStatus = 0;
+ startAnimation(0xD82890BA, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::xUpdate() {
+ if (_x >= 250 && _x <= 435 && _y >= 420) {
+ if (_idleTableNum == 0) {
+ setKlaymenIdleTable(klaymenIdleTable1002, ARRAYSIZE(klaymenIdleTable1002));
+ _idleTableNum = 1;
+ }
+ } else if (_idleTableNum == 1) {
+ setKlaymenIdleTable1();
+ _idleTableNum = 0;
+ }
+}
+
+uint32 KmScene1002::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x2001:
+ GotoState(&Klaymen::stStandIdleSpecial);
+ break;
+ case 0x2007:
+ _otherSprite = (Sprite*)param.asEntity();
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ if (param.asInteger() == 1)
+ GotoState(&KmScene1002::stJumpAndFall);
+ else if (param.asInteger() == 2)
+ GotoState(&KmScene1002::stDropFromRing);
+ break;
+ case 0x4804:
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4805:
+ switch (param.asInteger()) {
+ case 1:
+ GotoState(&KmScene1002::stJumpToRing1);
+ break;
+ case 2:
+ GotoState(&KmScene1002::stJumpToRing2);
+ break;
+ case 3:
+ GotoState(&KmScene1002::stJumpToRing3);
+ break;
+ case 4:
+ GotoState(&KmScene1002::stJumpToRing4);
+ break;
+ }
+ break;
+ case 0x480A:
+ GotoState(&KmScene1002::stMoveVenusFlyTrap);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1002::stJumpToRingVenusFlyTrap);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressDoorButton);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ startWalkToAttachedSpriteXDistance(param.asInteger());
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2005, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2005, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2005, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2006, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene1004::KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _dataResource.load(0x01900A04);
+}
+
+uint32 KmScene1004::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481E:
+ GotoState(&KmScene1004::stReadNote);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x4824:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4825:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4828:
+ GotoState(&Klaymen::stTurnToBackToUse);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+uint32 KmScene1002::hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, 0x4806, 0);
+ _acceptInput = true;
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stHangOnRing() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x4829E0B8, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(NULL);
+}
+
+void KmScene1002::stJumpToRing2() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing2))) {
+ _busyStatus = 0;
+ startAnimation(0x900980B2, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRing3() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing3))) {
+ _busyStatus = 0;
+ _acceptInput = false;
+ startAnimation(0xBA1910B2, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ SetMessageHandler(&KmScene1002::hmJumpToRing3);
+ NextState(&KmScene1002::stHoldRing3);
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, 0x4806, 0);
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stHoldRing3() {
+ _busyStatus = 0;
+ _acceptInput = true;
+ startAnimation(0x4A293FB0, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmHoldRing3);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1002::hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender) {
+ if (messageNum == 0x1008) {
+ stReleaseRing();
+ return 0;
+ }
+ return hmLowLevel(messageNum, param, sender);
+}
+
+void KmScene1002::stJumpToRing4() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing4))) {
+ _busyStatus = 0;
+ startAnimation(0xB8699832, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+void KmScene1002::stJumpToRingVenusFlyTrap() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRingVenusFlyTrap))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x584984B4, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpToRingVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&KmScene1002::stLandOnFeet);
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, 0x480F, 0);
+ } else if (param.asInteger() == 0x586B0300) {
+ sendMessage(_otherSprite, 0x480E, 1);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stJumpAndFall() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpAndFall))) {
+ sendMessage(_parentScene, 0x1024, 3);
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0xB93AB151, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpAndFall);
+ SetSpriteUpdate(&Klaymen::suFallDown);
+ NextState(&KmScene1002::stLandOnFeet);
+ }
+}
+
+void KmScene1002::stDropFromRing() {
+ if (_attachedSprite) {
+ _x = _attachedSprite->getX();
+ sendMessage(_attachedSprite, 0x4807, 0);
+ _attachedSprite = NULL;
+ }
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x586984B1, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(&Klaymen::suFallDown);
+ NextState(&KmScene1002::stLandOnFeet);
+}
+
+uint32 KmScene1002::hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevel(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x1307050A) {
+ playSound(0, 0x40428A09);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stMoveVenusFlyTrap() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stMoveVenusFlyTrap))) {
+ _busyStatus = 2;
+ _isMoveObjectRequested = false;
+ _acceptInput = true;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x5C01A870, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
+ }
+}
+
+void KmScene1002::stContinueMovingVenusFlyTrap() {
+ _isMoveObjectRequested = false;
+ _acceptInput = true;
+ startAnimationByHash(0x5C01A870, 0x01084280, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmMoveVenusFlyTrap);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evMoveVenusFlyTrapDone);
+}
+
+void KmScene1002::evMoveVenusFlyTrapDone() {
+ sendMessage(_attachedSprite, 0x482A, 0);
+}
+
+uint32 KmScene1002::hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x01084280) {
+ sendMessage(_attachedSprite, 0x480B, (uint32)_doDeltaX);
+ } else if (param.asInteger() == 0x02421405) {
+ if (_isMoveObjectRequested) {
+ if (sendMessage(_attachedSprite, 0x480C, (uint32)_doDeltaX) != 0)
+ stContinueMovingVenusFlyTrap();
+ } else {
+ SetMessageHandler(&KmScene1002::hmFirstMoveVenusFlyTrap);
+ }
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ case 0x480A:
+ _isMoveObjectRequested = true;
+ return 0;
+ }
+ return hmLowLevelAnimation(messageNum, param, sender);
+}
+
+uint32 KmScene1002::hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene1004::hmReadNote(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x04684052) {
+ _acceptInput = true;
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1004::stReadNote() {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x123E9C9F, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1004::hmReadNote);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1000_sprites.h b/engines/neverhood/modules/module1000_sprites.h
new file mode 100644
index 0000000000..540a258ddc
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.h
@@ -0,0 +1,257 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene1001Door : public AnimatedSprite {
+public:
+ AsScene1001Door(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void hammerHitsDoor();
+ void stShowIdleDoor();
+ void stBustedDoorMove();
+ void stBustedDoorGone();
+};
+
+class AsScene1001Hammer : public AnimatedSprite {
+public:
+ AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
+protected:
+ Sprite *_asDoor;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1001Window : public AnimatedSprite {
+public:
+ AsScene1001Window(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1001Lever : public AnimatedSprite {
+public:
+ AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsCommonButtonSprite : public StaticSprite {
+public:
+ SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ int16 _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002Ring : public AnimatedSprite {
+public:
+ AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
+protected:
+ Scene *_parentScene;
+ bool _isSpecial;
+ void update();
+ uint32 hmRingIdle(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRingReleased(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002Door : public StaticSprite {
+public:
+ AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
+protected:
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suOpenDoor();
+ void suCloseDoor();
+};
+
+class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
+public:
+ AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002DoorSpy : public AnimatedSprite {
+public:
+ AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
+protected:
+ Scene *_parentScene;
+ Sprite *_asDoor;
+ Sprite *_asBoxingGloveHitEffect;
+ NRect _clipRect;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmDoorSpyAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void suDoorSpy();
+ void stDoorSpyIdle();
+ void stDoorSpyBoxingGlove();
+};
+
+class SsCommonPressButton : public StaticSprite {
+public:
+ SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
+ void setFileHashes(uint32 fileHash1, uint32 fileHash2);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ uint32 _fileHashes[2];
+ int _status;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1002VenusFlyTrap : public AnimatedSprite {
+public:
+ AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ int _countdown;
+ bool _isSecond;
+ void update();
+ void upIdle();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender);
+ void stWalkBack();
+ void stWalk();
+ void stRelease();
+ void stGrabRing();
+ void stRingGrabbed();
+ void stKlaymenInside();
+ void stIdle();
+ void stKlaymenInsideMoving();
+ void stSpitOutKlaymen();
+ void swallowKlaymen();
+};
+
+class AsScene1002OutsideDoorBackground : public AnimatedSprite {
+public:
+ AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
+protected:
+ int _countdown;
+ bool _isDoorClosed;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stDoorClosed();
+};
+
+class AsScene1002KlaymenLadderHands : public AnimatedSprite {
+public:
+ AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
+protected:
+ Klaymen *_klaymen;
+ void update();
+};
+
+class AsScene1002KlaymenPeekHand : public AnimatedSprite {
+public:
+ AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
+protected:
+ Scene *_parentScene;
+ Klaymen *_klaymen;
+ bool _isClipRectSaved;
+ NRect _savedClipRect;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1004TrashCan : public AnimatedSprite {
+public:
+ AsScene1004TrashCan(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1001 : public Klaymen {
+public:
+ KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stWakeUp();
+ void stSleeping();
+ void stPullHammerLever();
+ uint32 hmSleeping(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPullHammerLever(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1002 : public Klaymen {
+public:
+ KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stJumpToRing1();
+ void stJumpToRing2();
+ void stJumpToRing3();
+ void stJumpToRing4();
+ void setupJumpToRing();
+ void stHangOnRing();
+ void stHoldRing3();
+ void stDropFromRing();
+ void stJumpToRingVenusFlyTrap();
+ void stJumpAndFall();
+ void stMoveVenusFlyTrap();
+ void stContinueMovingVenusFlyTrap();
+ void evMoveVenusFlyTrapDone();
+
+ uint32 hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmHoldRing3(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmJumpAndFall(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender);
+
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1004 : public Klaymen {
+public:
+ KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stReadNote();
+ uint32 hmReadNote(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1000_SPRITES_H */
diff --git a/engines/neverhood/modules/module1100.cpp b/engines/neverhood/modules/module1100.cpp
index faa0516d7e..af2df2e742 100644
--- a/engines/neverhood/modules/module1100.cpp
+++ b/engines/neverhood/modules/module1100.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module1100.h"
#include "neverhood/gamemodule.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module1100.h"
+#include "neverhood/modules/module1100_sprites.h"
namespace Neverhood {
@@ -236,6 +237,13 @@ void Module1100::updateScene() {
}
}
+static const uint32 kScene1105BackgroundFileHashes[] = {
+ 0x20018662,
+ 0x20014202,
+ 0x20012202,
+ 0x20010002 // CHECKME: This used ??
+};
+
static const uint32 kScene1105FileHashes[] = {
0x00028006,
0x0100A425,
@@ -249,186 +257,6 @@ static const uint32 kScene1105FileHashes[] = {
0xB14A891E
};
-static const uint32 kScene1105BackgroundFileHashes[] = {
- 0x20018662,
- 0x20014202,
- 0x20012202,
- 0x20010002 // CHECKME: This used ??
-};
-
-static const uint32 kSsScene1105SymbolDieFileHashes[] = {
- 0,
- 0x90898414,
- 0x91098414,
- 0x92098414,
- 0x94098414,
- 0x98098414,
- 0x80098414,
- 0xB0098414,
- 0xD0098414,
- 0x10098414
-};
-
-SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
- : StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
-
- _collisionBounds = collisionBounds;
- SetMessageHandler(&SsScene1105Button::handleMessage);
- SetUpdateHandler(&SsScene1105Button::update);
- setVisible(false);
-}
-
-void SsScene1105Button::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- sendMessage(_parentScene, 0x4807, 0);
- setVisible(false);
- }
-}
-
-uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- }
- break;
- case 0x480B:
- _countdown = 8;
- setVisible(true);
- playSound(0, 0x44141000);
- break;
- }
- return messageResult;
-}
-
-SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
- : StaticSprite(vm, 0) {
-
- loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
-}
-
-void SsScene1105Symbol::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
- : StaticSprite(vm, 1100), _dieIndex(dieIndex) {
-
- _x = x;
- _y = y;
- createSurface(200, 50, 50);
- loadSymbolSprite();
- SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
-}
-
-uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- loadSymbolSprite();
- break;
- }
- return messageResult;
-}
-
-void SsScene1105SymbolDie::loadSymbolSprite() {
- loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
-}
-
-void SsScene1105SymbolDie::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(100, 556, 328);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
- startAnimation(0x65084002, 0, -1);
- _newStickFrameIndex = 0;
- setVisible(false);
- _needRefresh = true;
- updatePosition();
- loadSound(0, 0xCE840261);
- loadSound(1, 0xCCA41A62);
-}
-
-uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- if (getGlobalVar(V_ROBOT_TARGET)) {
- startAnimation(0x6B0C0432, 0, -1);
- playSound(0);
- } else {
- startAnimation(0x65084002, 0, -1);
- playSound(1);
- }
- break;
- case 0x3002:
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
- break;
- }
- return messageResult;
-}
-
-void AsScene1105TeddyBear::show() {
- setVisible(true);
- _needRefresh = true;
- updatePosition();
-}
-
-void AsScene1105TeddyBear::hide() {
- setVisible(false);
- _needRefresh = true;
- updatePosition();
-}
-
-SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
- : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
-
- loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44045140);
- SetUpdateHandler(&SsScene1105OpenButton::update);
- SetMessageHandler(&SsScene1105OpenButton::handleMessage);
-}
-
-void SsScene1105OpenButton::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- setVisible(false);
- sendMessage(_parentScene, 0x2001, 0);
- }
-}
-
-uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = 0;
- Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_isClicked) {
- playSound(0);
- setVisible(true);
- _isClicked = true;
- _countdown = 4;
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene1105::Scene1105(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _countdown(0), _isPanelOpen(false), _isActionButtonClicked(false), _doMoveTeddy(false),
_isClosePanelDone(false), _leaveResult(0), _backgroundIndex(0) {
diff --git a/engines/neverhood/modules/module1100.h b/engines/neverhood/modules/module1100.h
index 373f6b703f..38bac1f298 100644
--- a/engines/neverhood/modules/module1100.h
+++ b/engines/neverhood/modules/module1100.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1100
-
class Module1100 : public Module {
public:
Module1100(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,52 +40,9 @@ protected:
void updateScene();
};
-class SsScene1105Button : public StaticSprite {
-public:
- SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene1105Symbol : public StaticSprite {
-public:
- SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
- void hide();
-};
-
-class SsScene1105SymbolDie : public StaticSprite {
-public:
- SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
- void hide();
-protected:
- uint _dieIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void loadSymbolSprite();
-};
-
-class AsScene1105TeddyBear : public AnimatedSprite {
-public:
- AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
- void show();
- void hide();
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene1105OpenButton : public StaticSprite {
-public:
- SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- bool _isClicked;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class AsScene1105TeddyBear;
+class SsScene1105Symbol;
+class SsScene1105SymbolDie;
class Scene1105 : public Scene {
public:
diff --git a/engines/neverhood/modules/module1100_sprites.cpp b/engines/neverhood/modules/module1100_sprites.cpp
new file mode 100644
index 0000000000..51e0bb3f49
--- /dev/null
+++ b/engines/neverhood/modules/module1100_sprites.cpp
@@ -0,0 +1,265 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1100_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kSsScene1105SymbolDieFileHashes[] = {
+ 0,
+ 0x90898414,
+ 0x91098414,
+ 0x92098414,
+ 0x94098414,
+ 0x98098414,
+ 0x80098414,
+ 0xB0098414,
+ 0xD0098414,
+ 0x10098414
+};
+
+SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
+ : StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
+
+ _collisionBounds = collisionBounds;
+ SetMessageHandler(&SsScene1105Button::handleMessage);
+ SetUpdateHandler(&SsScene1105Button::update);
+ setVisible(false);
+}
+
+void SsScene1105Button::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ sendMessage(_parentScene, 0x4807, 0);
+ setVisible(false);
+ }
+}
+
+uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ }
+ break;
+ case 0x480B:
+ _countdown = 8;
+ setVisible(true);
+ playSound(0, 0x44141000);
+ break;
+ }
+ return messageResult;
+}
+
+SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
+ : StaticSprite(vm, 0) {
+
+ loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
+}
+
+void SsScene1105Symbol::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
+ : StaticSprite(vm, 1100), _dieIndex(dieIndex) {
+
+ _x = x;
+ _y = y;
+ createSurface(200, 50, 50);
+ loadSymbolSprite();
+ SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
+}
+
+uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ loadSymbolSprite();
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene1105SymbolDie::loadSymbolSprite() {
+ loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
+}
+
+void SsScene1105SymbolDie::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(100, 556, 328);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
+ startAnimation(0x65084002, 0, -1);
+ _newStickFrameIndex = 0;
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+ loadSound(0, 0xCE840261);
+ loadSound(1, 0xCCA41A62);
+}
+
+uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ if (getGlobalVar(V_ROBOT_TARGET)) {
+ startAnimation(0x6B0C0432, 0, -1);
+ playSound(0);
+ } else {
+ startAnimation(0x65084002, 0, -1);
+ playSound(1);
+ }
+ break;
+ case 0x3002:
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1105TeddyBear::show() {
+ setVisible(true);
+ _needRefresh = true;
+ updatePosition();
+}
+
+void AsScene1105TeddyBear::hide() {
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+}
+
+SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
+
+ loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44045140);
+ SetUpdateHandler(&SsScene1105OpenButton::update);
+ SetMessageHandler(&SsScene1105OpenButton::handleMessage);
+}
+
+void SsScene1105OpenButton::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2001, 0);
+ }
+}
+
+uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_isClicked) {
+ playSound(0);
+ setVisible(true);
+ _isClicked = true;
+ _countdown = 4;
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0x2C2A4A1C);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x3C2E4245);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1100_sprites.h b/engines/neverhood/modules/module1100_sprites.h
new file mode 100644
index 0000000000..c8e5a838da
--- /dev/null
+++ b/engines/neverhood/modules/module1100_sprites.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1100_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1100_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene1105Button : public StaticSprite {
+public:
+ SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene1105Symbol : public StaticSprite {
+public:
+ SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
+ void hide();
+};
+
+class SsScene1105SymbolDie : public StaticSprite {
+public:
+ SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
+ void hide();
+protected:
+ uint _dieIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void loadSymbolSprite();
+};
+
+class AsScene1105TeddyBear : public AnimatedSprite {
+public:
+ AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
+ void show();
+ void hide();
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene1105OpenButton : public StaticSprite {
+public:
+ SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ bool _isClicked;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1109 : public Klaymen {
+public:
+ KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1100_SPRITES_H */
diff --git a/engines/neverhood/modules/module1200.cpp b/engines/neverhood/modules/module1200.cpp
index e7766419f9..975545091d 100644
--- a/engines/neverhood/modules/module1200.cpp
+++ b/engines/neverhood/modules/module1200.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module1200_sprites.h"
namespace Neverhood {
@@ -92,566 +93,10 @@ void Module1200::updateScene() {
}
}
-// Scene1201
-
static const uint32 kScene1201InitArray[] = {
1, 0, 2, 4, 5, 3, 6, 7, 8, 10, 9, 11, 13, 14, 12, 16, 17, 15
};
-static const NPoint kScene1201PointArray[] = {
- {218, 193}, {410, 225}, {368, 277},
- {194, 227}, {366, 174}, {458, 224},
- {242, 228}, {512, 228}, {458, 277},
- {217, 233}, {458, 173}, {410, 276},
- {203, 280}, {371, 226}, {508, 279},
- {230, 273}, {410, 171}, {493, 174}
-};
-
-static const uint32 kScene1201TntFileHashList1[] = {
- 0x2098212D, 0x1600437E, 0x1600437E,
- 0x00A840E3, 0x1A1830F6, 0x1A1830F6,
- 0x00212062, 0x384010B6, 0x384010B6,
- 0x07A01080, 0xD80C2837, 0xD80C2837,
- 0x03A22092, 0xD8802CB6, 0xD8802CB6,
- 0x03A93831, 0xDA460476, 0xDA460476
-};
-
-static const uint32 kScene1201TntFileHashList2[] = {
- 0x3040C676, 0x10914448, 0x10914448,
- 0x3448A066, 0x1288C049, 0x1288C049,
- 0x78C0E026, 0x3098D05A, 0x3098D05A,
- 0x304890E6, 0x1284E048, 0x1284E048,
- 0xB140A1E6, 0x5088A068, 0x5088A068,
- 0x74C4C866, 0x3192C059, 0x3192C059
-};
-
-SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
- : StaticSprite(vm, 900) {
-
- int16 x = kScene1201PointArray[pointIndex].x;
- int16 y = kScene1201PointArray[pointIndex].y;
- if (x < 300)
- loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
- else
- loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
- setClipRect(0, 0, 640, clipY2);
-}
-
-AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
- : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
-
- if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
- SetMessageHandler(&AsScene1201Tape::handleMessage);
- } else {
- setVisible(false);
- SetMessageHandler(NULL);
- }
-}
-
-uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_TAPE, _nameHash, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
-AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
- : AnimatedSprite(vm, 1200) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201TntManRope::handleMessage);
- createSurface(10, 34, 149);
- _x = 202;
- _y = -32;
- if (isDummyHanging) {
- startAnimation(0x928F0C10, 15, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(0x928F0C10, 0, -1);
- _newStickFrameIndex = 0;
- }
-}
-
-uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018)
- playSound(0, 0x47900E06);
- break;
- case 0x2006:
- startAnimation(0x928F0C10, 1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return messageResult;
-}
-
-AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
-
- createSurface1(0xD088AC30, 100);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AsScene1201RightDoor::update);
- SetMessageHandler(&AsScene1201RightDoor::handleMessage);
- _newStickFrameIndex = STICK_LAST_FRAME;
- if (isOpen) {
- startAnimation(0xD088AC30, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- _countdown = 25;
- } else {
- stopAnimation();
- setVisible(false);
- }
-}
-
-void AsScene1201RightDoor::update() {
- if (_countdown != 0 && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4829:
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201RightDoor::stOpenDoor() {
- startAnimation(0xD088AC30, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen20"));
-}
-
-void AsScene1201RightDoor::stCloseDoor() {
- startAnimation(0xD088AC30, -1, -1);
- _playBackwards = true;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose20"));
- NextState(&AsScene1201RightDoor::stCloseDoorDone);
-}
-
-void AsScene1201RightDoor::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- createSurface(1200, 69, 98);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- setVisible(false);
-}
-
-uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2006:
- _x = 436;
- _y = 339;
- startAnimation(0xA060C599, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
- _isMoving(false) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- createSurface(990, 106, 181);
- _x = 201;
- if (isComingDown) {
- _y = 297;
- stComingDown();
- } else {
- _y = 334;
- stStanding();
- }
-}
-
-AsScene1201TntMan::~AsScene1201TntMan() {
- _vm->_soundMan->deleteSoundGroup(0x01D00560);
-}
-
-uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x092870C0)
- sendMessage(_asTntManRope, 0x2006, 0);
- else if (param.asInteger() == 0x11CA0144)
- playSound(0, 0x51800A04);
- break;
- case 0x1011:
- sendMessage(_parentScene, 0x2002, 0);
- messageResult = 1;
- break;
- case 0x480B:
- if (!_isMoving) {
- _sprite = (Sprite*)sender;
- stMoving();
- }
- break;
- }
- return messageResult;
-
-}
-
-uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201TntMan::suMoving() {
- _x = _sprite->getX() + 100;
-}
-
-void AsScene1201TntMan::stStanding() {
- startAnimation(0x654913D0, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1201TntMan::stComingDown() {
- startAnimation(0x356803D0, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::hmComingDown);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- NextState(&AsScene1201TntMan::stStanding);
-}
-
-void AsScene1201TntMan::stMoving() {
- _vm->_soundMan->addSound(0x01D00560, 0x4B044624);
- _vm->_soundMan->playSoundLooping(0x4B044624);
- _isMoving = true;
- startAnimation(0x85084190, 0, -1);
- SetMessageHandler(&AsScene1201TntMan::handleMessage);
- SetSpriteUpdate(&AsScene1201TntMan::suMoving);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
- : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
-
- createSurface1(0x828C0411, 995);
- SetUpdateHandler(&AsScene1201TntManFlame::update);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
- startAnimation(0x828C0411, 0, -1);
- setVisible(false);
-}
-
-AsScene1201TntManFlame::~AsScene1201TntManFlame() {
- _vm->_soundMan->deleteSoundGroup(0x041080A4);
-}
-
-void AsScene1201TntManFlame::update() {
- AnimatedSprite::update();
- if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
- setVisible(true);
- SetUpdateHandler(&AnimatedSprite::update);
- _vm->_soundMan->addSound(0x041080A4, 0x460A1050);
- _vm->_soundMan->playSoundLooping(0x460A1050);
- }
-}
-
-void AsScene1201TntManFlame::suUpdate() {
- _x = _asTntMan->getX() - 18;
- _y = _asTntMan->getY() - 158;
-}
-
-AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
-
- createSurface(1100, 57, 60);
- SetUpdateHandler(&AsScene1201Match::update);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- switch (getGlobalVar(V_MATCH_STATUS)) {
- case 0:
- _x = 521;
- _y = 112;
- _status = 0;
- stIdleOnDoorFrame();
- break;
- case 1:
- _x = 521;
- _y = 112;
- _status = 2;
- stOnDoorFrameAboutToMove();
- loadSound(0, 0xD00230CD);
- break;
- case 2:
- setDoDeltaX(1);
- _x = 403;
- _y = 337;
- _status = 0;
- stIdleOnFloor();
- break;
- }
-}
-
-void AsScene1201Match::update() {
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x86668011)
- playSound(0);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2001, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setVisible(false);
- setGlobalVar(V_MATCH_STATUS, 3);
- break;
- }
- return messageResult;
-}
-
-void AsScene1201Match::stOnDoorFrameMoving() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
- if (_status == 0) {
- NextState(&AsScene1201Match::stFallingFromDoorFrame);
- } else {
- NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
- }
-}
-
-void AsScene1201Match::stFallingFromDoorFrame() {
- setGlobalVar(V_MATCH_STATUS, 2);
- _x -= 199;
- _y += 119;
- startAnimation(0x018D0240, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
- NextState(&AsScene1201Match::stIdleOnFloor);
-}
-
-void AsScene1201Match::stOnDoorFrameAboutToMove() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
- _newStickFrameIndex = 0;
- if (_status != 0) {
- _countdown = 36;
- _status--;
- NextState(&AsScene1201Match::stOnDoorFrameMoving);
- }
-}
-
-void AsScene1201Match::stIdleOnDoorFrame() {
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmIdle);
- _newStickFrameIndex = 0;
-}
-
-void AsScene1201Match::stIdleOnFloor() {
- setDoDeltaX(1);
- _x = 403;
- _y = 337;
- startAnimation(0x00842374, 0, -1);
- SetMessageHandler(&AsScene1201Match::hmIdle);
- _newStickFrameIndex = 0;
-}
-
-AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
-
- // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
-
- createSurface(1100, 203, 199);
- SetUpdateHandler(&AsScene1201Creature::update);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- _x = 540;
- _y = 320;
- stWaiting();
-}
-
-void AsScene1201Creature::update() {
- bool oldKlaymenTooClose = _klaymenTooClose;
- _klaymenTooClose = _klaymen->getX() >= 385;
- if (_klaymenTooClose != oldKlaymenTooClose)
- stWaiting();
- if (_countdown != 0 && (--_countdown == 0))
- gotoNextState();
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018)
- playSound(0, 0xCD298116);
- break;
- case 0x2004:
- GotoState(&AsScene1201Creature::stStartReachForTntDummy);
- break;
- case 0x2006:
- GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmWaiting(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x02060018) {
- playSound(0, 0xCD298116);
- sendMessage(_parentScene, 0x4814, 0);
- sendMessage(_klaymen, 0x4814, 0);
- }
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201Creature::stWaiting() {
- startAnimation(0x08081513, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- NextState(&AsScene1201Creature::stPincerSnap);
- _countdown = 36;
-}
-
-void AsScene1201Creature::stPincerSnap() {
- if (!_klaymenTooClose) {
- startAnimation(0xCA287133, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
- NextState(&AsScene1201Creature::stWaiting);
- }
-}
-
-void AsScene1201Creature::stStartReachForTntDummy() {
- startAnimation(0x08081513, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- NextState(&AsScene1201Creature::stReachForTntDummy);
- _countdown = 48;
-}
-
-void AsScene1201Creature::stReachForTntDummy() {
- startAnimation(0x5A201453, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmWaiting);
- _countdown = 0;
-}
-
-void AsScene1201Creature::stPincerSnapKlaymen() {
- startAnimation(0xCA287133, 0, -1);
- SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
- NextState(&AsScene1201Creature::stWaiting);
- _countdown = 0;
-}
-
-AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen) {
-
- _x = 320;
- _y = 240;
- createSurface(800, 55, 199);
- if (_klaymen->getX() < 100) {
- startAnimation(0x508A111B, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen03"));
- } else {
- startAnimation(0x508A111B, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
-}
-
-uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1201LeftDoor::stCloseDoor() {
- startAnimation(0x508A111B, -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
-}
-
Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _creatureExploded(false), _asMatch(NULL), _asTntMan(NULL),
_asCreature(NULL), _asTntManRope(NULL), _asLeftDoor(NULL), _asRightDoor(NULL), _asTape(NULL) {
@@ -908,95 +353,10 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-// Scene1202
-
static const uint32 kScene1202Table[] = {
1, 2, 0, 4, 5, 3, 7, 8, 6, 10, 11, 9, 13, 14, 12, 16, 17, 15
};
-static const NPoint kScene1202Points[] = {
- {203, 140}, {316, 212}, {277, 264},
- {176, 196}, {275, 159}, {366, 212},
- {230, 195}, {412, 212}, {368, 263},
- {204, 192}, {365, 164}, {316, 262},
- {191, 255}, {280, 213}, {406, 266},
- {214, 254}, {316, 158}, {402, 161}
-};
-
-static const uint32 kScene1202FileHashes[] = {
- 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
- 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
- 0x1AC50B8, 0x1AC14B8, 0x1AC14B8
-};
-
-AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
-
- int positionIndex;
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
- positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
- createSurface(900, 37, 67);
- _x = kScene1202Points[positionIndex].x;
- _y = kScene1202Points[positionIndex].y;
- stShowIdle();
-}
-
-uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2000, _itemIndex);
- messageResult = 1;
- break;
- case 0x2001:
- _newPosition = (int)param.asInteger();
- stChangePositionFadeOut();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1202TntItem::stShowIdle() {
- startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
- SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
- _newStickFrameIndex = 0;
-}
-
-void AsScene1202TntItem::stChangePositionFadeOut() {
- startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
- SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
- NextState(&AsScene1202TntItem::stChangePositionFadeIn);
-}
-
-void AsScene1202TntItem::stChangePositionFadeIn() {
- _x = kScene1202Points[_newPosition].x;
- _y = kScene1202Points[_newPosition].y;
- startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
- _playBackwards = true;
- SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
- NextState(&AsScene1202TntItem::stChangePositionDone);
-}
-
-void AsScene1202TntItem::stChangePositionDone() {
- sendMessage(_parentScene, 0x2002, _itemIndex);
- stShowIdle();
-}
-
Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _paletteResource(vm),
_soundToggle(true), _isPuzzleSolved(false), _counter(0), _clickedIndex(-1) {
diff --git a/engines/neverhood/modules/module1200.h b/engines/neverhood/modules/module1200.h
index c97dc98986..d9d4dd11f2 100644
--- a/engines/neverhood/modules/module1200.h
+++ b/engines/neverhood/modules/module1200.h
@@ -29,8 +29,6 @@
namespace Neverhood {
-// Module1200
-
class Module1200 : public Module {
public:
Module1200(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -41,123 +39,7 @@ protected:
void updateScene();
};
-// Scene1201
-
-class AsScene1201Tape : public AnimatedSprite {
-public:
- AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 _nameHash;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201TntManRope : public AnimatedSprite {
-public:
- AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201RightDoor : public AnimatedSprite {
-public:
- AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
-protected:
- Sprite *_klaymen;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene1201KlaymenHead : public AnimatedSprite {
-public:
- AsScene1201KlaymenHead(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene1201TntMan : public AnimatedSprite {
-public:
- AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
- virtual ~AsScene1201TntMan();
-protected:
- Scene *_parentScene;
- Sprite *_asTntManRope;
- Sprite *_sprite;
- bool _isMoving;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmComingDown(int messageNum, const MessageParam &param, Entity *sender);
- void suMoving();
- void stStanding();
- void stComingDown();
- void stMoving();
-};
-
-class AsScene1201TntManFlame : public AnimatedSprite {
-public:
- AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
- ~AsScene1201TntManFlame();
-protected:
- Sprite *_asTntMan;
- void update();
- void suUpdate();
-};
-
-class AsScene1201Match : public AnimatedSprite {
-public:
- AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- int _status;
- void update();
- uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmIdle(int messageNum, const MessageParam &param, Entity *sender);
- void stOnDoorFrameMoving();
- void stFallingFromDoorFrame();
- void stOnDoorFrameAboutToMove();
- void stIdleOnDoorFrame();
- void stIdleOnFloor();
-};
-
-class AsScene1201Creature : public AnimatedSprite {
-public:
- AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- int _countdown;
- bool _klaymenTooClose;
- void update();
- uint32 hmWaiting(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender);
- void stWaiting();
- void stPincerSnap();
- void stStartReachForTntDummy();
- void stReachForTntDummy();
- void stPincerSnapKlaymen();
-};
-
-class AsScene1201LeftDoor : public AnimatedSprite {
-public:
- AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
-protected:
- Sprite *_klaymen;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stCloseDoor();
-};
-
-class SsScene1201Tnt : public StaticSprite {
-public:
- SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
-protected:
- uint32 _elemIndex;
-};
+class AsScene1201TntMan;
class Scene1201 : public Scene {
public:
@@ -177,22 +59,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1202
-
-class AsScene1202TntItem : public AnimatedSprite {
-public:
- AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
-protected:
- Scene *_parentScene;
- int _itemIndex, _newPosition;
- uint32 hmShowIdle(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmChangePosition(int messageNum, const MessageParam &param, Entity *sender);
- void stShowIdle();
- void stChangePositionFadeOut();
- void stChangePositionFadeIn();
- void stChangePositionDone();
-};
-
class Scene1202 : public Scene {
public:
Scene1202(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module1200_sprites.cpp b/engines/neverhood/modules/module1200_sprites.cpp
new file mode 100644
index 0000000000..da38924d9a
--- /dev/null
+++ b/engines/neverhood/modules/module1200_sprites.cpp
@@ -0,0 +1,810 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1200_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kScene1201TntFileHashList1[] = {
+ 0x2098212D, 0x1600437E, 0x1600437E,
+ 0x00A840E3, 0x1A1830F6, 0x1A1830F6,
+ 0x00212062, 0x384010B6, 0x384010B6,
+ 0x07A01080, 0xD80C2837, 0xD80C2837,
+ 0x03A22092, 0xD8802CB6, 0xD8802CB6,
+ 0x03A93831, 0xDA460476, 0xDA460476
+};
+
+static const uint32 kScene1201TntFileHashList2[] = {
+ 0x3040C676, 0x10914448, 0x10914448,
+ 0x3448A066, 0x1288C049, 0x1288C049,
+ 0x78C0E026, 0x3098D05A, 0x3098D05A,
+ 0x304890E6, 0x1284E048, 0x1284E048,
+ 0xB140A1E6, 0x5088A068, 0x5088A068,
+ 0x74C4C866, 0x3192C059, 0x3192C059
+};
+
+SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
+ : StaticSprite(vm, 900) {
+
+ int16 x = kScene1201PointArray[pointIndex].x;
+ int16 y = kScene1201PointArray[pointIndex].y;
+ if (x < 300)
+ loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
+ else
+ loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
+ setClipRect(0, 0, 640, clipY2);
+}
+
+AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
+ : AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
+
+ if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
+ SetMessageHandler(&AsScene1201Tape::handleMessage);
+ } else {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setSubVar(VA_HAS_TAPE, _nameHash, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
+ : AnimatedSprite(vm, 1200) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201TntManRope::handleMessage);
+ createSurface(10, 34, 149);
+ _x = 202;
+ _y = -32;
+ if (isDummyHanging) {
+ startAnimation(0x928F0C10, 15, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(0x928F0C10, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+}
+
+uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0x47900E06);
+ break;
+ case 0x2006:
+ startAnimation(0x928F0C10, 1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
+
+ createSurface1(0xD088AC30, 100);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AsScene1201RightDoor::update);
+ SetMessageHandler(&AsScene1201RightDoor::handleMessage);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ if (isOpen) {
+ startAnimation(0xD088AC30, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _countdown = 25;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+}
+
+void AsScene1201RightDoor::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4829:
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201RightDoor::stOpenDoor() {
+ startAnimation(0xD088AC30, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen20"));
+}
+
+void AsScene1201RightDoor::stCloseDoor() {
+ startAnimation(0xD088AC30, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose20"));
+ NextState(&AsScene1201RightDoor::stCloseDoorDone);
+}
+
+void AsScene1201RightDoor::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ createSurface(1200, 69, 98);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ setVisible(false);
+}
+
+uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2006:
+ _x = 436;
+ _y = 339;
+ startAnimation(0xA060C599, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
+ _isMoving(false) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ createSurface(990, 106, 181);
+ _x = 201;
+ if (isComingDown) {
+ _y = 297;
+ stComingDown();
+ } else {
+ _y = 334;
+ stStanding();
+ }
+}
+
+AsScene1201TntMan::~AsScene1201TntMan() {
+ _vm->_soundMan->deleteSoundGroup(0x01D00560);
+}
+
+uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x092870C0)
+ sendMessage(_asTntManRope, 0x2006, 0);
+ else if (param.asInteger() == 0x11CA0144)
+ playSound(0, 0x51800A04);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, 0x2002, 0);
+ messageResult = 1;
+ break;
+ case 0x480B:
+ if (!_isMoving) {
+ _sprite = (Sprite*)sender;
+ stMoving();
+ }
+ break;
+ }
+ return messageResult;
+
+}
+
+uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201TntMan::suMoving() {
+ _x = _sprite->getX() + 100;
+}
+
+void AsScene1201TntMan::stStanding() {
+ startAnimation(0x654913D0, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1201TntMan::stComingDown() {
+ startAnimation(0x356803D0, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::hmComingDown);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&AsScene1201TntMan::stStanding);
+}
+
+void AsScene1201TntMan::stMoving() {
+ _vm->_soundMan->addSound(0x01D00560, 0x4B044624);
+ _vm->_soundMan->playSoundLooping(0x4B044624);
+ _isMoving = true;
+ startAnimation(0x85084190, 0, -1);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ SetSpriteUpdate(&AsScene1201TntMan::suMoving);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
+ : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
+
+ createSurface1(0x828C0411, 995);
+ SetUpdateHandler(&AsScene1201TntManFlame::update);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
+ startAnimation(0x828C0411, 0, -1);
+ setVisible(false);
+}
+
+AsScene1201TntManFlame::~AsScene1201TntManFlame() {
+ _vm->_soundMan->deleteSoundGroup(0x041080A4);
+}
+
+void AsScene1201TntManFlame::update() {
+ AnimatedSprite::update();
+ if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
+ setVisible(true);
+ SetUpdateHandler(&AnimatedSprite::update);
+ _vm->_soundMan->addSound(0x041080A4, 0x460A1050);
+ _vm->_soundMan->playSoundLooping(0x460A1050);
+ }
+}
+
+void AsScene1201TntManFlame::suUpdate() {
+ _x = _asTntMan->getX() - 18;
+ _y = _asTntMan->getY() - 158;
+}
+
+AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
+
+ createSurface(1100, 57, 60);
+ SetUpdateHandler(&AsScene1201Match::update);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ switch (getGlobalVar(V_MATCH_STATUS)) {
+ case 0:
+ _x = 521;
+ _y = 112;
+ _status = 0;
+ stIdleOnDoorFrame();
+ break;
+ case 1:
+ _x = 521;
+ _y = 112;
+ _status = 2;
+ stOnDoorFrameAboutToMove();
+ loadSound(0, 0xD00230CD);
+ break;
+ case 2:
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ _status = 0;
+ stIdleOnFloor();
+ break;
+ }
+}
+
+void AsScene1201Match::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x86668011)
+ playSound(0);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setVisible(false);
+ setGlobalVar(V_MATCH_STATUS, 3);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Match::stOnDoorFrameMoving() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
+ if (_status == 0) {
+ NextState(&AsScene1201Match::stFallingFromDoorFrame);
+ } else {
+ NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
+ }
+}
+
+void AsScene1201Match::stFallingFromDoorFrame() {
+ setGlobalVar(V_MATCH_STATUS, 2);
+ _x -= 199;
+ _y += 119;
+ startAnimation(0x018D0240, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
+ NextState(&AsScene1201Match::stIdleOnFloor);
+}
+
+void AsScene1201Match::stOnDoorFrameAboutToMove() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
+ _newStickFrameIndex = 0;
+ if (_status != 0) {
+ _countdown = 36;
+ _status--;
+ NextState(&AsScene1201Match::stOnDoorFrameMoving);
+ }
+}
+
+void AsScene1201Match::stIdleOnDoorFrame() {
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmIdle);
+ _newStickFrameIndex = 0;
+}
+
+void AsScene1201Match::stIdleOnFloor() {
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ startAnimation(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::hmIdle);
+ _newStickFrameIndex = 0;
+}
+
+AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
+
+ // NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
+
+ createSurface(1100, 203, 199);
+ SetUpdateHandler(&AsScene1201Creature::update);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ _x = 540;
+ _y = 320;
+ stWaiting();
+}
+
+void AsScene1201Creature::update() {
+ bool oldKlaymenTooClose = _klaymenTooClose;
+ _klaymenTooClose = _klaymen->getX() >= 385;
+ if (_klaymenTooClose != oldKlaymenTooClose)
+ stWaiting();
+ if (_countdown != 0 && (--_countdown == 0))
+ gotoNextState();
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0xCD298116);
+ break;
+ case 0x2004:
+ GotoState(&AsScene1201Creature::stStartReachForTntDummy);
+ break;
+ case 0x2006:
+ GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmWaiting(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018) {
+ playSound(0, 0xCD298116);
+ sendMessage(_parentScene, 0x4814, 0);
+ sendMessage(_klaymen, 0x4814, 0);
+ }
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Creature::stWaiting() {
+ startAnimation(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ NextState(&AsScene1201Creature::stPincerSnap);
+ _countdown = 36;
+}
+
+void AsScene1201Creature::stPincerSnap() {
+ if (!_klaymenTooClose) {
+ startAnimation(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
+ NextState(&AsScene1201Creature::stWaiting);
+ }
+}
+
+void AsScene1201Creature::stStartReachForTntDummy() {
+ startAnimation(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ NextState(&AsScene1201Creature::stReachForTntDummy);
+ _countdown = 48;
+}
+
+void AsScene1201Creature::stReachForTntDummy() {
+ startAnimation(0x5A201453, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmWaiting);
+ _countdown = 0;
+}
+
+void AsScene1201Creature::stPincerSnapKlaymen() {
+ startAnimation(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
+ NextState(&AsScene1201Creature::stWaiting);
+ _countdown = 0;
+}
+
+AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface(800, 55, 199);
+ if (_klaymen->getX() < 100) {
+ startAnimation(0x508A111B, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen03"));
+ } else {
+ startAnimation(0x508A111B, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
+}
+
+uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4809:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201LeftDoor::stCloseDoor() {
+ startAnimation(0x508A111B, -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+}
+
+static const NPoint kScene1202Points[] = {
+ {203, 140}, {316, 212}, {277, 264},
+ {176, 196}, {275, 159}, {366, 212},
+ {230, 195}, {412, 212}, {368, 263},
+ {204, 192}, {365, 164}, {316, 262},
+ {191, 255}, {280, 213}, {406, 266},
+ {214, 254}, {316, 158}, {402, 161}
+};
+
+static const uint32 kScene1202FileHashes[] = {
+ 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
+ 0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
+ 0x1AC50B8, 0x1AC14B8, 0x1AC14B8
+};
+
+AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
+
+ int positionIndex;
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
+ positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
+ createSurface(900, 37, 67);
+ _x = kScene1202Points[positionIndex].x;
+ _y = kScene1202Points[positionIndex].y;
+ stShowIdle();
+}
+
+uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2000, _itemIndex);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _newPosition = (int)param.asInteger();
+ stChangePositionFadeOut();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1202TntItem::stShowIdle() {
+ startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
+ _newStickFrameIndex = 0;
+}
+
+void AsScene1202TntItem::stChangePositionFadeOut() {
+ startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
+ NextState(&AsScene1202TntItem::stChangePositionFadeIn);
+}
+
+void AsScene1202TntItem::stChangePositionFadeIn() {
+ _x = kScene1202Points[_newPosition].x;
+ _y = kScene1202Points[_newPosition].y;
+ startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
+ _playBackwards = true;
+ SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
+ NextState(&AsScene1202TntItem::stChangePositionDone);
+}
+
+void AsScene1202TntItem::stChangePositionDone() {
+ sendMessage(_parentScene, 0x2002, _itemIndex);
+ stShowIdle();
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1201[] = {
+ {1, kIdleSpinHead},
+ {1, kIdleChest},
+ {1, kIdleHeadOff},
+};
+
+KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable(klaymenIdleTable1201, ARRAYSIZE(klaymenIdleTable1201));
+ _doYHitIncr = true;
+}
+
+uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ GotoState(&Klaymen::stMoveObject);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4813:
+ GotoState(&KmScene1201::stFetchMatch);
+ break;
+ case 0x4814:
+ GotoState(&KmScene1201::stTumbleHeadless);
+ break;
+ case 0x4815:
+ GotoState(&KmScene1201::stCloseEyes);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene1201::stTumbleHeadless() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stTumbleHeadless))) {
+ _busyStatus = 1;
+ _acceptInput = false;
+ setDoDeltaX(0);
+ startAnimation(0x2821C590, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmTumbleHeadless);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ NextState(&Klaymen::stTryStandIdle);
+ sendMessage(_parentScene, 0x8000, 0);
+ playSound(0, 0x62E0A356);
+ }
+}
+
+void KmScene1201::stCloseEyes() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stCloseEyes))) {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+uint32 KmScene1201::hmMatch(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x51281850) {
+ setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
+ } else if (param.asInteger() == 0x43000538) {
+ playSound(0, 0x21043059);
+ } else if (param.asInteger() == 0x02B20220) {
+ playSound(0, 0xC5408620);
+ } else if (param.asInteger() == 0x0A720138) {
+ playSound(0, 0xD4C08010);
+ } else if (param.asInteger() == 0xB613A180) {
+ playSound(0, 0x44051000);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1201::stFetchMatch() {
+ if (!stStartAction(AnimationCallback(&KmScene1201::stFetchMatch))) {
+ _busyStatus = 0;
+ _acceptInput = false;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x9CAA0218, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmMatch);
+ SetSpriteUpdate(NULL);
+ NextState(&KmScene1201::stLightMatch);
+ }
+}
+
+void KmScene1201::stLightMatch() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
+ startAnimation(0x1222A513, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1201::hmMatch);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 KmScene1201::hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x000F0082) {
+ playSound(0, 0x74E2810F);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1200_sprites.h b/engines/neverhood/modules/module1200_sprites.h
new file mode 100644
index 0000000000..ef1ec40ced
--- /dev/null
+++ b/engines/neverhood/modules/module1200_sprites.h
@@ -0,0 +1,187 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1200_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1200_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Used for both the scene sprites and the scene itself (for clipping)
+static const NPoint kScene1201PointArray[] = {
+ {218, 193}, {410, 225}, {368, 277},
+ {194, 227}, {366, 174}, {458, 224},
+ {242, 228}, {512, 228}, {458, 277},
+ {217, 233}, {458, 173}, {410, 276},
+ {203, 280}, {371, 226}, {508, 279},
+ {230, 273}, {410, 171}, {493, 174}
+};
+
+class AsScene1201Tape : public AnimatedSprite {
+public:
+ AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _nameHash;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201TntManRope : public AnimatedSprite {
+public:
+ AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201RightDoor : public AnimatedSprite {
+public:
+ AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
+protected:
+ Sprite *_klaymen;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene1201KlaymenHead : public AnimatedSprite {
+public:
+ AsScene1201KlaymenHead(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1201TntMan : public AnimatedSprite {
+public:
+ AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
+ virtual ~AsScene1201TntMan();
+protected:
+ Scene *_parentScene;
+ Sprite *_asTntManRope;
+ Sprite *_sprite;
+ bool _isMoving;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmComingDown(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoving();
+ void stStanding();
+ void stComingDown();
+ void stMoving();
+};
+
+class AsScene1201TntManFlame : public AnimatedSprite {
+public:
+ AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
+ ~AsScene1201TntManFlame();
+protected:
+ Sprite *_asTntMan;
+ void update();
+ void suUpdate();
+};
+
+class AsScene1201Match : public AnimatedSprite {
+public:
+ AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ int _status;
+ void update();
+ uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmIdle(int messageNum, const MessageParam &param, Entity *sender);
+ void stOnDoorFrameMoving();
+ void stFallingFromDoorFrame();
+ void stOnDoorFrameAboutToMove();
+ void stIdleOnDoorFrame();
+ void stIdleOnFloor();
+};
+
+class AsScene1201Creature : public AnimatedSprite {
+public:
+ AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ int _countdown;
+ bool _klaymenTooClose;
+ void update();
+ uint32 hmWaiting(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPincerSnap(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender);
+ void stWaiting();
+ void stPincerSnap();
+ void stStartReachForTntDummy();
+ void stReachForTntDummy();
+ void stPincerSnapKlaymen();
+};
+
+class AsScene1201LeftDoor : public AnimatedSprite {
+public:
+ AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
+protected:
+ Sprite *_klaymen;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stCloseDoor();
+};
+
+class SsScene1201Tnt : public StaticSprite {
+public:
+ SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
+};
+
+class AsScene1202TntItem : public AnimatedSprite {
+public:
+ AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
+protected:
+ Scene *_parentScene;
+ int _itemIndex, _newPosition;
+ uint32 hmShowIdle(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmChangePosition(int messageNum, const MessageParam &param, Entity *sender);
+ void stShowIdle();
+ void stChangePositionFadeOut();
+ void stChangePositionFadeIn();
+ void stChangePositionDone();
+};
+
+class KmScene1201 : public Klaymen {
+public:
+ KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stCloseEyes();
+ void stTumbleHeadless();
+ void stFetchMatch();
+ void stLightMatch();
+
+ uint32 hmTumbleHeadless(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmMatch(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1200_SPRITES_H */
diff --git a/engines/neverhood/modules/module1300.cpp b/engines/neverhood/modules/module1300.cpp
index c8a561af76..312fb85ae7 100644
--- a/engines/neverhood/modules/module1300.cpp
+++ b/engines/neverhood/modules/module1300.cpp
@@ -20,16 +20,15 @@
*
*/
-#include "neverhood/modules/module1300.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module1400.h"
-#include "neverhood/modules/module2200.h"
-#include "neverhood/gamemodule.h"
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
#include "neverhood/menumodule.h"
-#include "neverhood/navigationscene.h"
-#include "neverhood/smackerscene.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1300.h"
+#include "neverhood/modules/module1300_sprites.h"
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
@@ -311,113 +310,6 @@ void Module1300::updateScene() {
}
}
-AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x88148150, 500);
- if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
- startAnimation(0x88148150, 0, -1);
- _newStickFrameIndex = 0;
- } else {
- startAnimation(0x88148150, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
- loadSound(0, 0x68895082);
- loadSound(1, 0x689BD0C1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1302Bridge::handleMessage);
-}
-
-uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stLowerBridge();
- break;
- case 0x4809:
- stRaiseBridge();
- break;
- }
- return messageResult;
-}
-
-void AsScene1302Bridge::stLowerBridge() {
- startAnimation(0x88148150, 0, -1);
- playSound(1);
- NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
-}
-
-void AsScene1302Bridge::stRaiseBridge() {
- startAnimation(0x88148150, 7, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
- playSound(0);
-}
-
-void AsScene1302Bridge::cbLowerBridgeEvent() {
- sendMessage(_parentScene, 0x2032, 0);
- startAnimation(0x88148150, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
- : StaticSprite(vm, 0x11122122, 200) {
-
- _firstY = _y;
- if (getGlobalVar(V_FLYTRAP_RING_FENCE))
- _y += 152;
- loadSound(0, 0x7A00400C);
- loadSound(1, 0x78184098);
- SetUpdateHandler(&SsScene1302Fence::update);
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void SsScene1302Fence::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- playSound(0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
- break;
- case 0x4809:
- playSound(1);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
- break;
- }
- return messageResult;
-}
-
-void SsScene1302Fence::suMoveDown() {
- if (_y < _firstY + 152)
- _y += 8;
- else {
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void SsScene1302Fence::suMoveUp() {
- if (_y > _firstY)
- _y -= 8;
- else {
- SetMessageHandler(&SsScene1302Fence::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -581,56 +473,8 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(200, 128, 315);
- _x = 289;
- _y = 390;
- startAnimation(0x800278D2, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1303Balloon::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x2000:
- stPopBalloon();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x020B0003)
- playSound(0, 0x742B0055);
- break;
- case 0x3002:
- playSound(0, 0x470007EE);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
-void AsScene1303Balloon::stPopBalloon() {
- startAnimation(0xAC004CD0, 0, -1);
- SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
-}
-
Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
- : Scene(vm, parentModule) {
+ : Scene(vm, parentModule), _asBalloon(NULL) {
SetMessageHandler(&Scene1303::handleMessage);
@@ -668,29 +512,6 @@ uint32 Scene1303::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
- : AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
-
- // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
- SetMessageHandler(&AsScene1304Needle::handleMessage);
-}
-
-uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setGlobalVar(V_HAS_NEEDLE, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asNeedle(NULL) {
@@ -781,91 +602,6 @@ uint32 Scene1305::handleMessage(int messageNum, const MessageParam &param, Entit
return Scene::handleMessage(messageNum, param, sender);
}
-AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
- _countdown(0) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x043B0270, 100);
- startAnimation(0x043B0270, 0, -1);
- _newStickFrameIndex = 0;
- loadSound(0, 0x1C100E83);
- loadSound(1, 0x1C08CEC5);
- loadSound(2, 0x5D011E87);
- SetMessageHandler(&AsScene1306Elevator::handleMessage);
-}
-
-void AsScene1306Elevator::update() {
- if (_isUp && _countdown != 0 && (--_countdown == 0))
- stGoingDown();
- AnimatedSprite::update();
- if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
- playSound(1);
- _asElevatorDoor->setVisible(false);
- }
-}
-
-void AsScene1306Elevator::upGoingDown() {
- AnimatedSprite::update();
- if (_currFrameIndex == 5)
- _asElevatorDoor->setVisible(true);
-}
-
-uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- if (_isUp)
- _countdown = 144;
- messageResult = _isUp ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- if (_isDown)
- stGoingUp();
- break;
- }
- return messageResult;
-}
-
-void AsScene1306Elevator::stGoingUp() {
- setVisible(true);
- _isDown = false;
- startAnimation(0x043B0270, 0, -1);
- playSound(0);
- SetUpdateHandler(&AsScene1306Elevator::update);
- NextState(&AsScene1306Elevator::cbGoingUpEvent);
-}
-
-void AsScene1306Elevator::cbGoingUpEvent() {
- sendMessage(_parentScene, 0x4808, 0);
- _isUp = true;
- _countdown = 144;
- stopAnimation();
- setVisible(false);
- SetUpdateHandler(&AsScene1306Elevator::update);
-}
-
-void AsScene1306Elevator::stGoingDown() {
- _isUp = false;
- setVisible(true);
- startAnimation(0x043B0270, -1, -1);
- _playBackwards = true;
- playSound(1);
- SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
- NextState(&AsScene1306Elevator::cbGoingDownEvent);
-}
-
-void AsScene1306Elevator::cbGoingDownEvent() {
- _isDown = true;
- sendMessage(_parentScene, 0x4809, 0);
- stopAnimation();
- SetUpdateHandler(&AsScene1306Elevator::update);
-}
-
Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1039,188 +775,6 @@ uint32 Scene1306::handleMessage416EB0(int messageNum, const MessageParam &param,
return 0;
}
-static const uint32 kAsScene1307KeyResourceList1[] = {
- 0x0438069C, 0x45B0023C, 0x05700217
-};
-
-static const uint32 kAsScene1307KeyResourceList2[] = {
- 0x04441334, 0x061433F0, 0x06019390
-};
-
-static const uint32 kAsScene1307KeyResourceList3[] = {
- 0x11A80030, 0x178812B1, 0x1488121C
-};
-
-static const uint32 *kAsScene1307KeyResourceLists[] = {
- kAsScene1307KeyResourceList1,
- kAsScene1307KeyResourceList2,
- kAsScene1307KeyResourceList3
-};
-
-static const int kAsScene1307KeySurfacePriorities[] = {
- 700, 500, 300, 100
-};
-
-const uint kAsScene1307KeyPointsCount = 12;
-
-static const NPoint kAsScene1307KeyPoints[] = {
- {-2, 0}, {-5, 0}, { 5, 0},
- {12, 0}, {17, 0}, {25, 0},
- {16, -2}, {10, -6}, { 0, -7},
- {-7, -3}, {-3, 4}, { 2, 2}
-};
-
-const uint kAsScene1307KeyFrameIndicesCount = 20;
-
-static const int16 kAsScene1307KeyFrameIndices[] = {
- 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
- 15, 14, 12, 10, 9, 7, 5, 3, 2, 1
-};
-
-const int kAsScene1307KeyDivValue = 200;
-const int16 kAsScene1307KeyXDelta = 70;
-const int16 kAsScene1307KeyYDelta = -12;
-
-AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
- _isClickable(true) {
-
- NPoint pt;
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
-
- _dataResource.load(0x22102142);
- _pointList = _dataResource.getPointArray(0xAC849240);
- pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- _x = pt.x;
- _y = pt.y;
- createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
- startAnimation(fileHashes[0], 0, -1);
- loadSound(0, 0xDC4A1280);
- loadSound(1, 0xCC021233);
- loadSound(2, 0xC4C23844);
- loadSound(3, 0xC4523208);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1307Key::handleMessage);
-}
-
-uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_isClickable) {
- sendMessage(_parentScene, 0x4826, 0);
- stRemoveKey();
- messageResult = 1;
- }
- break;
- case 0x2000:
- _isClickable = param.asInteger() != 0;
- break;
- case 0x2001:
- setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
- stMoveKey();
- break;
- case 0x2003:
- playSound(3);
- stUnlock();
- break;
- case 0x2004:
- playSound(2);
- stInsert();
- break;
- }
- return messageResult;
-}
-
-void AsScene1307Key::suRemoveKey() {
- if (_pointIndex < kAsScene1307KeyPointsCount) {
- _x += kAsScene1307KeyPoints[_pointIndex].x;
- _y += kAsScene1307KeyPoints[_pointIndex].y;
- updateBounds();
- _pointIndex++;
- } else {
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1307Key::suInsertKey() {
- if (_pointIndex < kAsScene1307KeyPointsCount) {
- _x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
- _y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
- updateBounds();
- _pointIndex++;
- if (_pointIndex == 7)
- playSound(0);
- } else {
- SetSpriteUpdate(NULL);
- sendMessage(_parentScene, 0x2002, 0);
- }
-}
-
-void AsScene1307Key::suMoveKey() {
- if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
- _frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
- _x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
- _y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
- updateBounds();
- _pointIndex++;
- } else {
- NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- _x = pt.x + kAsScene1307KeyXDelta;
- _y = pt.y + kAsScene1307KeyYDelta;
- stInsertKey();
- }
-}
-
-void AsScene1307Key::stRemoveKey() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- _pointIndex = 0;
- startAnimation(fileHashes[0], 0, -1);
- playSound(1);
- SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
-}
-
-void AsScene1307Key::stInsertKey() {
- _pointIndex = 0;
- sendMessage(_parentScene, 0x1022, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
- setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetSpriteUpdate(&AsScene1307Key::suInsertKey);
-}
-
-void AsScene1307Key::stMoveKey() {
- NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
- int16 newX = pt.x + kAsScene1307KeyXDelta;
- int16 newY = pt.y + kAsScene1307KeyYDelta;
- sendMessage(_parentScene, 0x1022, 1000);
- setClipRect(0, 0, 640, 480);
- _prevX = _x;
- _prevY = _y;
- if (newX == _x && newY == _y) {
- stInsertKey();
- } else {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- _pointIndex = 0;
- _frameIndex = 0;
- _deltaX = newX - _x;
- _deltaY = newY - _y;
- startAnimation(fileHashes[0], 0, -1);
- SetSpriteUpdate(&AsScene1307Key::suMoveKey);
- }
-}
-
-void AsScene1307Key::stUnlock() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- startAnimation(fileHashes[1], 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsScene1307Key::stInsert() {
- const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
- startAnimation(fileHashes[2], 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
Scene1307::Scene1307(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _countdown(0), _asCurrKey(NULL),
_isInsertingKey(false), _doLeaveScene(false), _isPuzzleSolved(false) {
@@ -1360,164 +914,6 @@ static const uint32 kScene1308NumberFileHashes[] = {
0x00306322
};
-AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
-
- setVisible(false);
- stopAnimation();
- SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
-}
-
-uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stOpenDoor();
- break;
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308JaggyDoor::stOpenDoor() {
- startAnimation(0xBA0AE050, 0, -1);
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen38"));
- NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
-}
-
-void AsScene1308JaggyDoor::stOpenDoorDone() {
- sendMessage(_parentScene, 0x2000, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1308JaggyDoor::stCloseDoor() {
- startAnimation(0xBA0AE050, -1, -1);
- _playBackwards = true;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose38"));
- NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
-}
-
-void AsScene1308JaggyDoor::stCloseDoorDone() {
- sendMessage(_parentScene, 0x2001, 0);
- stopAnimation();
-}
-
-AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
-
- playSound(0, 0x51456049);
- SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
- NextState(&AsScene1308KeyboardDoor::stFallingKeys);
-}
-
-uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308KeyboardDoor::stFallingKeys() {
- startAnimation(0x6238B191, 0, -1);
- _x = 580;
- _y = 383;
- NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
-}
-
-void AsScene1308KeyboardDoor::stFallingKeysDone() {
- sendMessage(_parentScene, 0x2004, 0);
- stopAnimation();
- setVisible(false);
-}
-
-AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
-
- setVisible(false);
- stopAnimation();
- Entity::_priority = 1200;
- SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
-}
-
-uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- stFadeIn();
- break;
- case 0x2003:
- stFadeOut();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1308LightWallSymbols::stFadeIn() {
- startAnimation(0x80180A10, 0, -1);
- setVisible(true);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsScene1308LightWallSymbols::stFadeOut() {
- startAnimation(0x80180A10, -1, -1);
- _playBackwards = true;
- NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
-}
-
-void AsScene1308LightWallSymbols::stFadeOutDone() {
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
- setVisible(false);
-}
-
-SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
- : StaticSprite(vm, fileHash, 100) {
-
- setVisible(false);
- _x = _spriteResource.getPosition().x + index * 20;
- updatePosition();
-}
-
-AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 286;
- _y = 429;
- createSurface1(0xA282C472, 100);
- startAnimation(0xA282C472, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1308Mouse::handleMessage);
-}
-
-uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x66382026)
- playSound(0, 0x0CD84468);
- else if (param.asInteger() == 0x6E28061C)
- playSound(0, 0x78C8402C);
- else if (param.asInteger() == 0x462F0410)
- playSound(0, 0x60984E28);
- break;
- }
- return messageResult;
-}
-
Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isProjecting(false), _asProjector(NULL) {
diff --git a/engines/neverhood/modules/module1300.h b/engines/neverhood/modules/module1300.h
index 501f76304f..2f59ff16c2 100644
--- a/engines/neverhood/modules/module1300.h
+++ b/engines/neverhood/modules/module1300.h
@@ -30,8 +30,6 @@
namespace Neverhood {
-// Module1300
-
class Module1300 : public Module {
public:
Module1300(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -43,28 +41,6 @@ protected:
void updateScene();
};
-class AsScene1302Bridge : public AnimatedSprite {
-public:
- AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stLowerBridge();
- void stRaiseBridge();
- void cbLowerBridgeEvent();
-};
-
-class SsScene1302Fence : public StaticSprite {
-public:
- SsScene1302Fence(NeverhoodEngine *vm);
-protected:
- int16 _firstY;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveDown();
- void suMoveUp();
-};
-
class Scene1302 : public Scene {
public:
Scene1302(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -84,16 +60,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1303Balloon : public AnimatedSprite {
-public:
- AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender);
- void stPopBalloon();
-};
-
class Scene1303 : public Scene {
public:
Scene1303(NeverhoodEngine *vm, Module *parentModule);
@@ -103,14 +69,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1304Needle : public AnimatedSprite {
-public:
- AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1304 : public Scene {
public:
Scene1304(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -128,24 +86,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1306Elevator : public AnimatedSprite {
-public:
- AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
-protected:
- Scene *_parentScene;
- AnimatedSprite *_asElevatorDoor;
- bool _isUp;
- bool _isDown;
- int _countdown;
- void update();
- void upGoingDown();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stGoingUp();
- void cbGoingUpEvent();
- void stGoingDown();
- void cbGoingDownEvent();
-};
-
class Scene1306 : public Scene {
public:
Scene1306(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -161,30 +101,6 @@ protected:
uint32 handleMessage416EB0(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1307Key : public AnimatedSprite {
-public:
- AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
-protected:
- Scene *_parentScene;
- NPointArray *_pointList;
- uint _pointIndex;
- int _frameIndex;
- uint _keyIndex;
- NRect *_clipRects;
- bool _isClickable;
- int16 _prevX, _prevY;
- int16 _deltaX, _deltaY;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suRemoveKey();
- void suInsertKey();
- void suMoveKey();
- void stRemoveKey();
- void stInsertKey();
- void stMoveKey();
- void stUnlock();
- void stInsert();
-};
-
class Scene1307 : public Scene {
public:
Scene1307(NeverhoodEngine *vm, Module *parentModule);
@@ -202,51 +118,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene1308JaggyDoor : public AnimatedSprite {
-public:
- AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stOpenDoorDone();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene1308KeyboardDoor : public AnimatedSprite {
-public:
- AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stFallingKeys();
- void stFallingKeysDone();
-};
-
-class AsScene1308LightWallSymbols : public AnimatedSprite {
-public:
- AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stFadeIn();
- void stFadeOut();
- void stFadeOutDone();
-};
-
-class SsScene1308Number : public StaticSprite {
-public:
- SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
-};
-
-class AsScene1308Mouse : public AnimatedSprite {
-public:
- AsScene1308Mouse(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1308 : public Scene {
public:
Scene1308(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1300_sprites.cpp b/engines/neverhood/modules/module1300_sprites.cpp
new file mode 100644
index 0000000000..a65f2363a3
--- /dev/null
+++ b/engines/neverhood/modules/module1300_sprites.cpp
@@ -0,0 +1,935 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1300_sprites.h"
+
+namespace Neverhood {
+
+AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x88148150, 500);
+ if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
+ startAnimation(0x88148150, 0, -1);
+ _newStickFrameIndex = 0;
+ } else {
+ startAnimation(0x88148150, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+ loadSound(0, 0x68895082);
+ loadSound(1, 0x689BD0C1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1302Bridge::handleMessage);
+}
+
+uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ stLowerBridge();
+ break;
+ case 0x4809:
+ stRaiseBridge();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1302Bridge::stLowerBridge() {
+ startAnimation(0x88148150, 0, -1);
+ playSound(1);
+ NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
+}
+
+void AsScene1302Bridge::stRaiseBridge() {
+ startAnimation(0x88148150, 7, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+ playSound(0);
+}
+
+void AsScene1302Bridge::cbLowerBridgeEvent() {
+ sendMessage(_parentScene, 0x2032, 0);
+ startAnimation(0x88148150, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
+ : StaticSprite(vm, 0x11122122, 200) {
+
+ _firstY = _y;
+ if (getGlobalVar(V_FLYTRAP_RING_FENCE))
+ _y += 152;
+ loadSound(0, 0x7A00400C);
+ loadSound(1, 0x78184098);
+ SetUpdateHandler(&SsScene1302Fence::update);
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void SsScene1302Fence::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4808:
+ playSound(0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
+ break;
+ case 0x4809:
+ playSound(1);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene1302Fence::suMoveDown() {
+ if (_y < _firstY + 152)
+ _y += 8;
+ else {
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void SsScene1302Fence::suMoveUp() {
+ if (_y > _firstY)
+ _y -= 8;
+ else {
+ SetMessageHandler(&SsScene1302Fence::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(200, 128, 315);
+ _x = 289;
+ _y = 390;
+ startAnimation(0x800278D2, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1303Balloon::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x2000:
+ stPopBalloon();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x020B0003)
+ playSound(0, 0x742B0055);
+ break;
+ case 0x3002:
+ playSound(0, 0x470007EE);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1303Balloon::stPopBalloon() {
+ startAnimation(0xAC004CD0, 0, -1);
+ SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
+}
+
+AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
+
+ // NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
+ SetMessageHandler(&AsScene1304Needle::handleMessage);
+}
+
+uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setGlobalVar(V_HAS_NEEDLE, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
+ _countdown(0) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x043B0270, 100);
+ startAnimation(0x043B0270, 0, -1);
+ _newStickFrameIndex = 0;
+ loadSound(0, 0x1C100E83);
+ loadSound(1, 0x1C08CEC5);
+ loadSound(2, 0x5D011E87);
+ SetMessageHandler(&AsScene1306Elevator::handleMessage);
+}
+
+void AsScene1306Elevator::update() {
+ if (_isUp && _countdown != 0 && (--_countdown == 0))
+ stGoingDown();
+ AnimatedSprite::update();
+ if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
+ playSound(1);
+ _asElevatorDoor->setVisible(false);
+ }
+}
+
+void AsScene1306Elevator::upGoingDown() {
+ AnimatedSprite::update();
+ if (_currFrameIndex == 5)
+ _asElevatorDoor->setVisible(true);
+}
+
+uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ if (_isUp)
+ _countdown = 144;
+ messageResult = _isUp ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ if (_isDown)
+ stGoingUp();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1306Elevator::stGoingUp() {
+ setVisible(true);
+ _isDown = false;
+ startAnimation(0x043B0270, 0, -1);
+ playSound(0);
+ SetUpdateHandler(&AsScene1306Elevator::update);
+ NextState(&AsScene1306Elevator::cbGoingUpEvent);
+}
+
+void AsScene1306Elevator::cbGoingUpEvent() {
+ sendMessage(_parentScene, 0x4808, 0);
+ _isUp = true;
+ _countdown = 144;
+ stopAnimation();
+ setVisible(false);
+ SetUpdateHandler(&AsScene1306Elevator::update);
+}
+
+void AsScene1306Elevator::stGoingDown() {
+ _isUp = false;
+ setVisible(true);
+ startAnimation(0x043B0270, -1, -1);
+ _playBackwards = true;
+ playSound(1);
+ SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
+ NextState(&AsScene1306Elevator::cbGoingDownEvent);
+}
+
+void AsScene1306Elevator::cbGoingDownEvent() {
+ _isDown = true;
+ sendMessage(_parentScene, 0x4809, 0);
+ stopAnimation();
+ SetUpdateHandler(&AsScene1306Elevator::update);
+}
+
+static const uint32 kAsScene1307KeyResourceList1[] = {
+ 0x0438069C, 0x45B0023C, 0x05700217
+};
+
+static const uint32 kAsScene1307KeyResourceList2[] = {
+ 0x04441334, 0x061433F0, 0x06019390
+};
+
+static const uint32 kAsScene1307KeyResourceList3[] = {
+ 0x11A80030, 0x178812B1, 0x1488121C
+};
+
+static const uint32 *kAsScene1307KeyResourceLists[] = {
+ kAsScene1307KeyResourceList1,
+ kAsScene1307KeyResourceList2,
+ kAsScene1307KeyResourceList3
+};
+
+static const int kAsScene1307KeySurfacePriorities[] = {
+ 700, 500, 300, 100
+};
+
+const uint kAsScene1307KeyPointsCount = 12;
+
+static const NPoint kAsScene1307KeyPoints[] = {
+ {-2, 0}, {-5, 0}, { 5, 0},
+ {12, 0}, {17, 0}, {25, 0},
+ {16, -2}, {10, -6}, { 0, -7},
+ {-7, -3}, {-3, 4}, { 2, 2}
+};
+
+const uint kAsScene1307KeyFrameIndicesCount = 20;
+
+static const int16 kAsScene1307KeyFrameIndices[] = {
+ 1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
+ 15, 14, 12, 10, 9, 7, 5, 3, 2, 1
+};
+
+const int kAsScene1307KeyDivValue = 200;
+const int16 kAsScene1307KeyXDelta = 70;
+const int16 kAsScene1307KeyYDelta = -12;
+
+AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
+ _isClickable(true) {
+
+ NPoint pt;
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+
+ _dataResource.load(0x22102142);
+ _pointList = _dataResource.getPointArray(0xAC849240);
+ pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ _x = pt.x;
+ _y = pt.y;
+ createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
+ startAnimation(fileHashes[0], 0, -1);
+ loadSound(0, 0xDC4A1280);
+ loadSound(1, 0xCC021233);
+ loadSound(2, 0xC4C23844);
+ loadSound(3, 0xC4523208);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1307Key::handleMessage);
+}
+
+uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_isClickable) {
+ sendMessage(_parentScene, 0x4826, 0);
+ stRemoveKey();
+ messageResult = 1;
+ }
+ break;
+ case 0x2000:
+ _isClickable = param.asInteger() != 0;
+ break;
+ case 0x2001:
+ setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
+ stMoveKey();
+ break;
+ case 0x2003:
+ playSound(3);
+ stUnlock();
+ break;
+ case 0x2004:
+ playSound(2);
+ stInsert();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1307Key::suRemoveKey() {
+ if (_pointIndex < kAsScene1307KeyPointsCount) {
+ _x += kAsScene1307KeyPoints[_pointIndex].x;
+ _y += kAsScene1307KeyPoints[_pointIndex].y;
+ updateBounds();
+ _pointIndex++;
+ } else {
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1307Key::suInsertKey() {
+ if (_pointIndex < kAsScene1307KeyPointsCount) {
+ _x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
+ _y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
+ updateBounds();
+ _pointIndex++;
+ if (_pointIndex == 7)
+ playSound(0);
+ } else {
+ SetSpriteUpdate(NULL);
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+}
+
+void AsScene1307Key::suMoveKey() {
+ if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
+ _frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
+ _x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
+ _y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
+ updateBounds();
+ _pointIndex++;
+ } else {
+ NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ _x = pt.x + kAsScene1307KeyXDelta;
+ _y = pt.y + kAsScene1307KeyYDelta;
+ stInsertKey();
+ }
+}
+
+void AsScene1307Key::stRemoveKey() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ _pointIndex = 0;
+ startAnimation(fileHashes[0], 0, -1);
+ playSound(1);
+ SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
+}
+
+void AsScene1307Key::stInsertKey() {
+ _pointIndex = 0;
+ sendMessage(_parentScene, 0x1022, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
+ setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetSpriteUpdate(&AsScene1307Key::suInsertKey);
+}
+
+void AsScene1307Key::stMoveKey() {
+ NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
+ int16 newX = pt.x + kAsScene1307KeyXDelta;
+ int16 newY = pt.y + kAsScene1307KeyYDelta;
+ sendMessage(_parentScene, 0x1022, 1000);
+ setClipRect(0, 0, 640, 480);
+ _prevX = _x;
+ _prevY = _y;
+ if (newX == _x && newY == _y) {
+ stInsertKey();
+ } else {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ _pointIndex = 0;
+ _frameIndex = 0;
+ _deltaX = newX - _x;
+ _deltaY = newY - _y;
+ startAnimation(fileHashes[0], 0, -1);
+ SetSpriteUpdate(&AsScene1307Key::suMoveKey);
+ }
+}
+
+void AsScene1307Key::stUnlock() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ startAnimation(fileHashes[1], 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsScene1307Key::stInsert() {
+ const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
+ startAnimation(fileHashes[2], 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
+
+ setVisible(false);
+ stopAnimation();
+ SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
+}
+
+uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ stOpenDoor();
+ break;
+ case 0x4809:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308JaggyDoor::stOpenDoor() {
+ startAnimation(0xBA0AE050, 0, -1);
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen38"));
+ NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
+}
+
+void AsScene1308JaggyDoor::stOpenDoorDone() {
+ sendMessage(_parentScene, 0x2000, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1308JaggyDoor::stCloseDoor() {
+ startAnimation(0xBA0AE050, -1, -1);
+ _playBackwards = true;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose38"));
+ NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
+}
+
+void AsScene1308JaggyDoor::stCloseDoorDone() {
+ sendMessage(_parentScene, 0x2001, 0);
+ stopAnimation();
+}
+
+AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
+
+ playSound(0, 0x51456049);
+ SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
+ NextState(&AsScene1308KeyboardDoor::stFallingKeys);
+}
+
+uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308KeyboardDoor::stFallingKeys() {
+ startAnimation(0x6238B191, 0, -1);
+ _x = 580;
+ _y = 383;
+ NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
+}
+
+void AsScene1308KeyboardDoor::stFallingKeysDone() {
+ sendMessage(_parentScene, 0x2004, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
+
+ setVisible(false);
+ stopAnimation();
+ Entity::_priority = 1200;
+ SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
+}
+
+uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ stFadeIn();
+ break;
+ case 0x2003:
+ stFadeOut();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1308LightWallSymbols::stFadeIn() {
+ startAnimation(0x80180A10, 0, -1);
+ setVisible(true);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsScene1308LightWallSymbols::stFadeOut() {
+ startAnimation(0x80180A10, -1, -1);
+ _playBackwards = true;
+ NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
+}
+
+void AsScene1308LightWallSymbols::stFadeOutDone() {
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ setVisible(false);
+ _x = _spriteResource.getPosition().x + index * 20;
+ updatePosition();
+}
+
+AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 286;
+ _y = 429;
+ createSurface1(0xA282C472, 100);
+ startAnimation(0xA282C472, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1308Mouse::handleMessage);
+}
+
+uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x66382026)
+ playSound(0, 0x0CD84468);
+ else if (param.asInteger() == 0x6E28061C)
+ playSound(0, 0x78C8402C);
+ else if (param.asInteger() == 0x462F0410)
+ playSound(0, 0x60984E28);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4804:
+ GotoState(&Klaymen::stPeekWall1);
+ break;
+ case 0x483B:
+ GotoState(&Klaymen::stPeekWallReturn);
+ break;
+ case 0x483C:
+ GotoState(&Klaymen::stPeekWall2);
+ break;
+ }
+ return 0;
+}
+
+KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ GotoState(&KmScene1305::stCrashDown);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ }
+ return 0;
+}
+
+void KmScene1305::stCrashDown() {
+ playSound(0, 0x41648271);
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimationByHash(0x000BAB02, 0x88003000, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetSpriteUpdate(NULL);
+ SetMessageHandler(&Klaymen::hmLowLevelAnimation);
+ NextState(&KmScene1305::stCrashDownFinished);
+}
+
+void KmScene1305::stCrashDownFinished() {
+ setDoDeltaX(2);
+ stTryStandIdle();
+}
+
+KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ else
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ else
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xEE084A04);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xB86A4274);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stInsertKey);
+ else
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x4827:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1300_sprites.h b/engines/neverhood/modules/module1300_sprites.h
new file mode 100644
index 0000000000..e044d3cec8
--- /dev/null
+++ b/engines/neverhood/modules/module1300_sprites.h
@@ -0,0 +1,200 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1300_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1300_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/smackerplayer.h"
+
+namespace Neverhood {
+
+class AsScene1302Bridge : public AnimatedSprite {
+public:
+ AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stLowerBridge();
+ void stRaiseBridge();
+ void cbLowerBridgeEvent();
+};
+
+class SsScene1302Fence : public StaticSprite {
+public:
+ SsScene1302Fence(NeverhoodEngine *vm);
+protected:
+ int16 _firstY;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveDown();
+ void suMoveUp();
+};
+
+class AsScene1303Balloon : public AnimatedSprite {
+public:
+ AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender);
+ void stPopBalloon();
+};
+
+class AsScene1304Needle : public AnimatedSprite {
+public:
+ AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene1306Elevator : public AnimatedSprite {
+public:
+ AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
+protected:
+ Scene *_parentScene;
+ AnimatedSprite *_asElevatorDoor;
+ bool _isUp;
+ bool _isDown;
+ int _countdown;
+ void update();
+ void upGoingDown();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stGoingUp();
+ void cbGoingUpEvent();
+ void stGoingDown();
+ void cbGoingDownEvent();
+};
+
+class AsScene1307Key : public AnimatedSprite {
+public:
+ AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
+protected:
+ Scene *_parentScene;
+ NPointArray *_pointList;
+ uint _pointIndex;
+ int _frameIndex;
+ uint _keyIndex;
+ NRect *_clipRects;
+ bool _isClickable;
+ int16 _prevX, _prevY;
+ int16 _deltaX, _deltaY;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suRemoveKey();
+ void suInsertKey();
+ void suMoveKey();
+ void stRemoveKey();
+ void stInsertKey();
+ void stMoveKey();
+ void stUnlock();
+ void stInsert();
+};
+
+class AsScene1308JaggyDoor : public AnimatedSprite {
+public:
+ AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stOpenDoorDone();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene1308KeyboardDoor : public AnimatedSprite {
+public:
+ AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stFallingKeys();
+ void stFallingKeysDone();
+};
+
+class AsScene1308LightWallSymbols : public AnimatedSprite {
+public:
+ AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stFadeIn();
+ void stFadeOut();
+ void stFadeOutDone();
+};
+
+class SsScene1308Number : public StaticSprite {
+public:
+ SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
+};
+
+class AsScene1308Mouse : public AnimatedSprite {
+public:
+ AsScene1308Mouse(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1303 : public Klaymen {
+public:
+ KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1304 : public Klaymen {
+public:
+ KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1305 : public Klaymen {
+public:
+ KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stCrashDown();
+ void stCrashDownFinished();
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1306 : public Klaymen {
+public:
+ KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1308 : public Klaymen {
+public:
+ KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1300_SPRITES_H */
diff --git a/engines/neverhood/modules/module1400.cpp b/engines/neverhood/modules/module1400.cpp
index 0a029632b6..2fc1052ab1 100644
--- a/engines/neverhood/modules/module1400.cpp
+++ b/engines/neverhood/modules/module1400.cpp
@@ -20,12 +20,14 @@
*
*/
-#include "neverhood/modules/module1400.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module2100.h"
-#include "neverhood/modules/module2200.h"
#include "neverhood/diskplayerscene.h"
#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1400.h"
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module2100_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
@@ -135,497 +137,6 @@ void Module1400::updateScene() {
}
}
-// Scene1401
-
-AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) {
-
- createSurface(900, 152, 147);
- _x = 454;
- _y = 217;
- startAnimation(0x4C210500, 0, -1);
- SetUpdateHandler(&AsScene1401Pipe::update);
- SetMessageHandler(&AsScene1401Pipe::handleMessage);
-}
-
-AsScene1401Pipe::~AsScene1401Pipe() {
- _vm->_soundMan->deleteSoundGroup(0x01104C08);
-}
-
-void AsScene1401Pipe::update() {
- AnimatedSprite::update();
- if (_countdown1 != 0 && (--_countdown1 == 0))
- stDoneSucking();
- if (_countdown2 != 0 && (--_countdown2 == 0)) {
- _vm->_soundMan->addSound(0x01104C08, 0x4A116437);
- _vm->_soundMan->playSoundLooping(0x4A116437);
- }
-}
-
-void AsScene1401Pipe::upSuckInProjector() {
- AnimatedSprite::update();
- if (_countdown1 != 0)
- _countdown1--;
-}
-
-uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x0A8A1490)
- playSound(1, 0x6AB6666F);
- break;
- case 0x2000:
- _countdown1 = 70;
- _countdown2 = 8;
- stStartSucking();
- break;
- case 0x483A:
- stSuckInProjector();
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1401Pipe::hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- if (_countdown1 != 0)
- stStartSucking();
- else
- stDoneSucking();
- SetMessageHandler(&AsScene1401Pipe::handleMessage);
- SetUpdateHandler(&AsScene1401Pipe::update);
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Pipe::stStartSucking() {
- startAnimation(0x4C240100, 0, -1);
- playSound(0, 0x4A30063F);
-}
-
-void AsScene1401Pipe::stDoneSucking() {
- _vm->_soundMan->deleteSound(0x4A116437);
- playSound(0, 0x4A120435);
- startAnimation(0x4C210500, 0, -1);
-}
-
-void AsScene1401Pipe::stSuckInProjector() {
- startAnimation(0x6C210810, 0, -1);
- SetUpdateHandler(&AsScene1401Pipe::upSuckInProjector);
- SetMessageHandler(&AsScene1401Pipe::hmSuckInProjector);
-}
-
-AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(100, 71, 41);
- _x = 478;
- _y = 433;
- startAnimation(0xA282C472, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1401Mouse::handleMessage);
-}
-
-uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x66382026)
- playSound(0, 0x0CD84468);
- else if (param.asInteger() == 0x6E28061C)
- playSound(0, 0x78C8402C);
- else if (param.asInteger() == 0x462F0410)
- playSound(0, 0x60984E28);
- break;
- case 0x4839:
- stSuckedIn();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Mouse::suSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- playSound(0, 0x0E32247F);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1401Mouse::stSuckedIn() {
- startAnimation(0x34880040, 0, -1);
- SetSpriteUpdate(&AsScene1401Mouse::suSuckedIn);
-}
-
-AsScene1401Cheese::AsScene1401Cheese(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(200, 152, 147);
- _x = 427;
- _y = 433;
- startAnimation(0x461A1490, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1401Cheese::handleMessage);
-}
-
-uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4839:
- stSuckedIn();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401Cheese::suSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- playSound(0, 0x18020439);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1401Cheese::stSuckedIn() {
- startAnimation(0x103B8020, 0, -1);
- SetSpriteUpdate(&AsScene1401Cheese::suSuckedIn);
-}
-
-AsScene1401BackDoor::AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0), _isOpen(isOpen) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x04551900, 100);
- if (isOpen) {
- startAnimation(0x04551900, -1, -1);
- _countdown = 48;
- } else {
- stopAnimation();
- setVisible(false);
- }
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AsScene1401BackDoor::update);
- SetMessageHandler(&AsScene1401BackDoor::handleMessage);
-}
-
-void AsScene1401BackDoor::update() {
- if (_countdown != 0 && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-
-uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- if (_isOpen)
- _countdown = 168;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 168;
- if (!_isOpen)
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene1401BackDoor::stOpenDoor() {
- _isOpen = true;
- setVisible(true);
- startAnimation(0x04551900, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen24"));
-}
-
-void AsScene1401BackDoor::stCloseDoor() {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x04551900, -1, -1);
- playSound(0, calcHash("fxDoorClose24"));
- _playBackwards = true;
- NextState(&AsScene1401BackDoor::stCloseDoorDone);
-}
-
-void AsScene1401BackDoor::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-static const AsCommonProjectorItem kAsCommonProjectorItems[] = {
- {{154, 453}, 4, 2, 0, 0, 1},
- {{104, 391}, 4, -1, -1, 1, 1},
- {{ 22, 447}, 6, -1, -1, 1, 1},
- {{112, 406}, 2, -1, -1, 1, 0},
- {{262, 433}, 1, 1, 0, 0, 0}
-};
-
-AsCommonProjector::AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _asPipe(asPipe) {
-
- _asProjectorItem = &kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)];
- createSurface(990, 101, 182);
- startAnimation(0x10E3042B, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- _x = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- _lockedInSlot = true;
- moveProjector();
- setDoDeltaX(1);
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
- stStayLockedInSlot();
- loadSound(2, 0xC8C2507C);
-}
-
-AsCommonProjector::~AsCommonProjector() {
- _vm->_soundMan->deleteSoundGroup(0x05331081);
-}
-
-uint32 AsCommonProjector::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4807:
- setGlobalVar(V_PROJECTOR_SLOT, (_x - _asProjectorItem->point.x) / 108);
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
- stStartLockedInSlot();
- else
- stIdle();
- break;
- case 0x480B:
- if (param.asInteger() != 1) {
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
- incGlobalVar(V_PROJECTOR_SLOT, 1);
- } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
- incGlobalVar(V_PROJECTOR_SLOT, -1);
- stMoving();
- break;
- case 0x480C:
- // Check if the projector can be moved
- if (param.asInteger() != 1)
- messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
- else
- messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- case 0x4839:
- stStartSuckedIn();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonProjector::hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (param.asPoint().x - _x >= 17 && param.asPoint().x - _x <= 56 &&
- param.asPoint().y - _y >= -120 && param.asPoint().y - _y <= -82) {
- sendMessage(_parentScene, 0x4826, 1);
- } else
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4807:
- sendMessage(_parentScene, 0x4807, 0);
- stStopProjecting();
- break;
- case 0x480B:
- if (param.asInteger() != 1) {
- if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
- incGlobalVar(V_PROJECTOR_SLOT, 1);
- } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
- incGlobalVar(V_PROJECTOR_SLOT, -1);
- stTurnToFront();
- break;
- case 0x480C:
- // Check if the projector can be moved
- if (param.asInteger() != 1)
- messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
- else
- messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
- break;
- case 0x480F:
- stStartProjecting();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonProjector::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsCommonProjector::suMoving() {
- if (_x <= _klaymen->getX())
- _x = _klaymen->getX() - 100;
- else
- _x = _klaymen->getX() + 100;
- moveProjector();
- if (_beforeMoveX == _x) {
- if (getGlobalVar(V_PROJECTOR_SLOT) == 0 && _asProjectorItem->leftBorderLeaves != 0) {
- sendMessage(_parentScene, 0x1019, 0);
- incGlobalVar(V_PROJECTOR_LOCATION, -1);
- setGlobalVar(V_PROJECTOR_SLOT, kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)].maxSlotCount);
- } else if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->maxSlotCount && _asProjectorItem->rightBorderLeaves != 0) {
- sendMessage(_parentScene, 0x1019, 1);
- incGlobalVar(V_PROJECTOR_LOCATION, +1);
- setGlobalVar(V_PROJECTOR_SLOT, 0);
- }
- }
- Sprite::updateBounds();
-}
-
-void AsCommonProjector::moveProjector() {
-
- bool nowLockedInSlot = false;
-
- _y = _asProjectorItem->point.y;
-
- if (_asProjectorItem->index1 != -1) {
- int16 elX = _asProjectorItem->index1 * 108 + _asProjectorItem->point.x;
- if (elX - 20 < _x && elX + 20 > _x) {
- nowLockedInSlot = true;
- _y = _asProjectorItem->point.y + 10;
- }
- }
-
- if (_asProjectorItem->lockSlotIndex != -1) {
- int16 elX = _asProjectorItem->lockSlotIndex * 108 + _asProjectorItem->point.x;
- if (elX - 20 < _x && elX + 20 > _x) {
- nowLockedInSlot = true;
- _y = _asProjectorItem->point.y + 10;
- }
- }
-
- if (_lockedInSlot && !nowLockedInSlot)
- _lockedInSlot = false;
- else if (!_lockedInSlot && nowLockedInSlot) {
- playSound(1, 0x5440E474);
- _lockedInSlot = true;
- }
-
-}
-
-void AsCommonProjector::stSuckedIn() {
- AnimatedSprite::updateDeltaXY();
- if (_collisionBounds.y1 <= 150) {
- sendMessage(_asPipe, 0x483A, 0);
- stopAnimation();
- setVisible(false);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsCommonProjector::stIdle() {
- startAnimation(0x10E3042B, 0, -1);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stMoving() {
- _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- startAnimation(0x14A10137, 0, -1);
- playSound(1, 0xEC008474);
- SetMessageHandler(&AsCommonProjector::handleMessage);
- SetSpriteUpdate(&AsCommonProjector::suMoving);
-}
-
-void AsCommonProjector::stStartLockedInSlot() {
- startAnimation(0x80C32213, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stStayLockedInSlot);
-}
-
-void AsCommonProjector::stStayLockedInSlot() {
- startAnimation(0xD23B207F, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stStartProjecting() {
- startAnimation(0x50A80517, 0, -1);
- setGlobalVar(V_PROJECTOR_ACTIVE, 1);
- playSound(0, 0xCC4A8456);
- _vm->_soundMan->addSound(0x05331081, 0xCE428854);
- _vm->_soundMan->playSoundLooping(0xCE428854);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stLockedInSlot);
-}
-
-void AsCommonProjector::stLockedInSlot() {
- sendMessage(_parentScene, 0x480F, 0);
- startAnimation(0xD833207F, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
- SetSpriteUpdate(NULL);
-}
-
-void AsCommonProjector::stStopProjecting() {
- startAnimation(0x50A94417, 0, -1);
- setGlobalVar(V_PROJECTOR_ACTIVE, 0);
- playSound(0, 0xCC4A8456);
- _vm->_soundMan->deleteSound(0xCE428854);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(NULL);
- NextState(&AsCommonProjector::stStayLockedInSlot);
-}
-
-void AsCommonProjector::stTurnToFront() {
- _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
- startAnimation(0x22CB4A33, 0, -1);
- SetMessageHandler(&AsCommonProjector::hmAnimation);
- SetSpriteUpdate(&AsCommonProjector::suMoving);
- NextState(&AsCommonProjector::stMoving);
-}
-
-void AsCommonProjector::stStartSuckedIn() {
- setGlobalVar(V_PROJECTOR_LOCATION, 4);
- setGlobalVar(V_PROJECTOR_SLOT, 0);
- startAnimation(0x708D4712, 0, -1);
- playSound(2);
- SetMessageHandler(&Sprite::handleMessage);
- SetSpriteUpdate(&AsCommonProjector::stSuckedIn);
-}
-
Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(NULL), _asProjector(NULL),
_asPipe(NULL), _asMouse(NULL), _asCheese(NULL), _asBackDoor(NULL),
@@ -768,77 +279,6 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1402
-
-SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
- : StaticSprite(vm, fileHash, surfacePriority) {
-
- SetFilterY(&Sprite::defFilterY);
- SetUpdateHandler(&StaticSprite::updatePosition);
-}
-
-AsScene1402PuzzleBox::AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(900, 347, 230);
-
- SetFilterY(&Sprite::defFilterY);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1402PuzzleBox::handleMessage);
- _x = 279;
- _y = 270;
- if (status == 2) {
- // Puzzle box after the puzzle was solved
- startAnimation(0x20060259, 0, -1);
- playSound(0, 0x419014AC);
- loadSound(1, 0x61901C29);
- NextState(&AsScene1402PuzzleBox::stMoveDownSolvedDone);
- } else if (status == 1) {
- // Puzzle box appears
- startAnimation(0x210A0213, 0, -1);
- playSound(0, 0x41809C6C);
- NextState(&AsScene1402PuzzleBox::stMoveUpDone);
- } else {
- // Puzzle box is here
- startAnimation(0x20060259, -1, -1);
- loadSound(1, 0x61901C29);
- _newStickFrameIndex = STICK_LAST_FRAME;
- }
-}
-
-uint32 AsScene1402PuzzleBox::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- playSound(1);
- startAnimation(0x20060259, -1, -1);
- _playBackwards = true;
- NextState(&AsScene1402PuzzleBox::stMoveDownDone);
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1402PuzzleBox::stMoveUpDone() {
- sendMessage(_parentScene, 0x2000, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1402PuzzleBox::stMoveDownDone() {
- sendMessage(_parentScene, 0x2001, 0);
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene1402PuzzleBox::stMoveDownSolvedDone() {
- sendMessage(_parentScene, 0x2003, 0);
- stopAnimation();
-}
-
Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isShaking(false), _asPuzzleBox(NULL), _asProjector(NULL) {
@@ -988,237 +428,6 @@ void Scene1402::stopShaking() {
_isShaking = false;
}
-// Scene1407
-
-static const int16 kScene1407MouseFloorY[] = {
- 106, 150, 191, 230, 267, 308, 350, 395
-};
-
-static const struct {
- int16 x;
- int16 floorIndex;
- int16 sectionIndex;
- int16 nextHoleIndex;
-} kScene1407MouseHoles[] = {
- {125, 0, 0, 7},
- {452, 7, 21, 0},
- {337, 4, 11, 4},
- {286, 6, 17, 6},
- {348, 6, 17, 39},
- {536, 6, 18, 42},
- {111, 1, 3, 18},
- {203, 1, 3, 38},
- {270, 1, 3, 9},
- {197, 5, 14, 3},
- {252, 5, 14, 35},
- {297, 5, 14, 7},
- {359, 5, 14, 8},
- {422, 4, 12, 26},
- {467, 4, 12, 2},
- {539, 4, 12, 40},
- {111, 5, 13, 17},
- {211, 0, 1, 20},
- {258, 0, 1, 11},
- {322, 0, 1, 16},
- { 99, 6, 16, 31},
- {142, 6, 16, 27},
- {194, 6, 16, 12},
- {205, 2, 6, 45},
- {264, 2, 6, 10},
- { 98, 4, 10, 2},
- {152, 4, 10, 37},
- {199, 4, 10, 13},
- {258, 4, 10, 16},
- {100, 7, 19, 43},
- {168, 7, 19, 23},
- {123, 3, 8, 14},
- {181, 3, 8, 39},
- {230, 3, 8, 28},
- {292, 3, 8, 22},
- {358, 3, 8, 36},
- {505, 3, 9, 44},
- {400, 2, 7, 34},
- {454, 2, 7, 32},
- {532, 2, 7, 46},
- {484, 5, 15, 25},
- {529, 5, 15, 30},
- {251, 7, 20, 48},
- {303, 7, 20, 21},
- {360, 7, 20, 33},
- {503, 0, 2, 5},
- {459, 1, 4, 19},
- {530, 1, 4, 42},
- {111, 2, 5, 47},
- {442, 6, 18, 1}
-};
-
-static const struct {
- int16 x1, x2;
- int16 goodHoleIndex;
-} kScene1407MouseSections[] = {
- {100, 149, 0},
- {182, 351, 17},
- {430, 524, 45},
- { 89, 293, 7},
- {407, 555, 47},
- { 89, 132, 48},
- {178, 303, 23},
- {367, 551, 38},
- {105, 398, 31},
- {480, 537, 36},
- { 84, 275, 27},
- {318, 359, 2},
- {402, 560, 15},
- { 91, 132, 16},
- {179, 400, 10},
- {461, 552, 41},
- { 86, 218, 21},
- {267, 376, 4},
- {420, 560, 49},
- { 77, 188, 30},
- {237, 394, 44},
- {438, 515, 5}
-};
-
-AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
-
- createSurface(100, 117, 45);
- _x = 108;
- _y = 106;
- stIdleLookAtGoodHole();
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene1407Mouse::suWalkTo() {
- int16 xdelta = _walkDestX - _x;
- if (xdelta > _deltaX)
- xdelta = _deltaX;
- else if (xdelta < -_deltaX)
- xdelta = -_deltaX;
- _deltaX = 0;
- if (_walkDestX == _x)
- sendMessage(this, 0x1019, 0);
- else {
- _x += xdelta;
- updateBounds();
- }
-}
-
-void AsScene1407Mouse::upGoThroughHole() {
- if (_countdown != 0 && (--_countdown == 0)) {
- SetUpdateHandler(&AnimatedSprite::update);
- gotoNextState();
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene1407Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x0001:
- {
- int16 mouseX = param.asPoint().x;
- int16 mouseY = param.asPoint().y;
- int holeIndex;
- for (holeIndex = 0; holeIndex < 50; holeIndex++) {
- int16 holeX = kScene1407MouseHoles[holeIndex].x;
- int16 holeY = kScene1407MouseFloorY[kScene1407MouseHoles[holeIndex].floorIndex];
- if (mouseX >= holeX - 14 && mouseX <= holeX + 14 && mouseY >= holeY - 36 && mouseY <= holeY)
- break;
- }
- if (holeIndex < 50 && kScene1407MouseHoles[holeIndex].sectionIndex == _currSectionIndex) {
- _nextHoleIndex = kScene1407MouseHoles[holeIndex].nextHoleIndex;
- _walkDestX = kScene1407MouseHoles[holeIndex].x;
- stWalkToHole();
- } else {
- if (mouseX < kScene1407MouseSections[_currSectionIndex].x1)
- _walkDestX = kScene1407MouseSections[_currSectionIndex].x1;
- else if (mouseX > kScene1407MouseSections[_currSectionIndex].x2)
- _walkDestX = kScene1407MouseSections[_currSectionIndex].x2;
- else
- _walkDestX = mouseX;
- stWalkToDest();
- }
- }
- break;
- case 0x1019:
- gotoNextState();
- break;
- case 0x2001:
- {
- // Reset the position
- // Find the nearest hole and go through it, and exit at the first hole
- int16 distance = 640;
- int matchIndex = 50;
- for (int index = 0; index < 50; index++)
- if (kScene1407MouseHoles[index].sectionIndex == _currSectionIndex &&
- ABS(kScene1407MouseHoles[index].x - _x) < distance) {
- matchIndex = index;
- distance = ABS(kScene1407MouseHoles[index].x - _x);
- }
- if (matchIndex < 50) {
- _nextHoleIndex = 0;
- _walkDestX = kScene1407MouseHoles[matchIndex].x;
- stWalkToHole();
- }
- }
- break;
- }
- return messageResult;
-}
-
-void AsScene1407Mouse::stIdleLookAtGoodHole() {
- setDoDeltaX(kScene1407MouseHoles[kScene1407MouseSections[_currSectionIndex].goodHoleIndex].x < _x ? 1 : 0);
- startAnimation(0x72215194, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene1407Mouse::stWalkToDest() {
- if (_walkDestX != _x) {
- setDoDeltaX(_walkDestX < _x ? 1 : 0);
- startAnimation(0x22291510, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
- NextState(&AsScene1407Mouse::stIdleLookAtGoodHole);
- }
-}
-
-void AsScene1407Mouse::stWalkToHole() {
- setDoDeltaX(_walkDestX < _x ? 1 : 0);
- startAnimation(0x22291510, 0, -1);
- SetMessageHandler(&AsScene1407Mouse::handleMessage);
- SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
- NextState(&AsScene1407Mouse::stGoThroughHole);
-}
-
-void AsScene1407Mouse::stGoThroughHole() {
- startAnimation(0x72215194, 0, -1);
- setVisible(false);
- _countdown = 12;
- SetUpdateHandler(&AsScene1407Mouse::upGoThroughHole);
- SetMessageHandler(NULL);
- SetSpriteUpdate(NULL);
- NextState(&AsScene1407Mouse::stArriveAtHole);
-}
-
-void AsScene1407Mouse::stArriveAtHole() {
- _currSectionIndex = kScene1407MouseHoles[_nextHoleIndex].sectionIndex;
- _x = kScene1407MouseHoles[_nextHoleIndex].x;
- _y = kScene1407MouseFloorY[kScene1407MouseHoles[_nextHoleIndex].floorIndex];
- if (_nextHoleIndex == 1) {
- sendMessage(_parentScene, 0x2000, 0);
- _walkDestX = 512;
- stWalkToDest();
- setVisible(true);
- } else {
- _walkDestX = _x + 14;
- stWalkToDest();
- setVisible(true);
- }
-}
-
Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _puzzleSolvedCountdown(0), _resetButtonCountdown(0) {
@@ -1275,8 +484,6 @@ uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1403
-
Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _isProjecting(false) {
@@ -1379,8 +586,6 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1404
-
Scene1404::Scene1404(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asProjector(NULL), _asKey(NULL) {
@@ -1480,77 +685,6 @@ uint32 Scene1404::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene1405
-
-static const NPoint kAsScene1405TileItemPositions[] = {
- {100, 80}, {162, 78}, {222, 76}, {292, 76},
- {356, 82}, {422, 84}, {488, 86}, {550, 90},
- {102, 134}, {164, 132}, {224, 136}, {294, 136},
- {360, 136}, {422, 138}, {484, 144}, {548, 146},
- { 98, 196}, {160, 200}, {228, 200}, {294, 202},
- {360, 198}, {424, 200}, {482, 202}, {548, 206},
- { 98, 260}, {160, 264}, {226, 260}, {296, 262},
- {358, 260}, {424, 262}, {486, 264}, {550, 266},
- { 94, 322}, {160, 316}, {226, 316}, {296, 320},
- {358, 322}, {422, 324}, {488, 322}, {550, 322},
- { 98, 380}, {160, 376}, {226, 376}, {294, 378},
- {356, 380}, {420, 380}, {490, 378}, {552, 376}
-};
-
-AsScene1405Tile::AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _tileIndex(tileIndex), _countdown(0), _isShowing(false) {
-
- loadSound(0, 0x05308101);
- setSoundPan(0, (tileIndex % 8 * 4 + 4) * 25 / 8);
- _x = kAsScene1405TileItemPositions[_tileIndex].x;
- _y = kAsScene1405TileItemPositions[_tileIndex].y;
- createSurface1(0x844B805C, 1100);
- setVisible(false);
- if (getSubVar(VA_IS_TILE_MATCH, _tileIndex))
- _countdown = _vm->_rnd->getRandomNumber(36 - 1) + 1;
- startAnimation(0x844B805C, getSubVar(VA_TILE_SYMBOLS, _tileIndex), -1);
- _newStickFrameIndex = (int16)getSubVar(VA_TILE_SYMBOLS, _tileIndex);
- SetUpdateHandler(&AsScene1405Tile::update);
- SetMessageHandler(&AsScene1405Tile::handleMessage);
-}
-
-void AsScene1405Tile::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0))
- show();
-}
-
-uint32 AsScene1405Tile::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (getSubVar(VA_IS_TILE_MATCH, _tileIndex) == 0 && _parentScene->getCountdown() == 0) {
- show();
- sendMessage(_parentScene, 0x2000, _tileIndex);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene1405Tile::show() {
- if (!_isShowing) {
- _isShowing = true;
- playSound(0);
- setVisible(true);
- }
-}
-
-void AsScene1405Tile::hide() {
- if (_isShowing) {
- _isShowing = false;
- playSound(0);
- setVisible(false);
- }
-}
-
Scene1405::Scene1405(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _selectFirstTile(true), _tilesLeft(48), _countdown(0) {
diff --git a/engines/neverhood/modules/module1400.h b/engines/neverhood/modules/module1400.h
index 9a592c2952..53ad7125ab 100644
--- a/engines/neverhood/modules/module1400.h
+++ b/engines/neverhood/modules/module1400.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -40,92 +39,9 @@ protected:
void updateScene();
};
-// Scene1401
-
-class AsScene1401Pipe : public AnimatedSprite {
-public:
- AsScene1401Pipe(NeverhoodEngine *vm);
- virtual ~AsScene1401Pipe();
-protected:
- int _countdown1;
- int _countdown2;
- void update();
- void upSuckInProjector();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender);
- void stStartSucking();
- void stDoneSucking();
- void stSuckInProjector();
-};
-
-class AsScene1401Mouse : public AnimatedSprite {
-public:
- AsScene1401Mouse(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSuckedIn();
- void stSuckedIn();
-};
-
-class AsScene1401Cheese : public AnimatedSprite {
-public:
- AsScene1401Cheese(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSuckedIn();
- void stSuckedIn();
-};
-
-class AsScene1401BackDoor : public AnimatedSprite {
-public:
- AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
-protected:
- Sprite *_klaymen;
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-struct AsCommonProjectorItem {
- NPoint point;
- int8 maxSlotCount;
- int8 lockSlotIndex;
- int8 index1;
- int8 leftBorderLeaves;
- int8 rightBorderLeaves;
-};
-
-class AsCommonProjector : public AnimatedSprite {
-public:
- AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
- virtual ~AsCommonProjector();
-protected:
- Scene *_parentScene;
- Sprite *_klaymen;
- Sprite *_asPipe;
- const AsCommonProjectorItem *_asProjectorItem;
- int16 _beforeMoveX;
- bool _lockedInSlot;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void suMoving();
- void moveProjector();
- void stSuckedIn();
- void stIdle();
- void stMoving();
- void stStartLockedInSlot();
- void stStayLockedInSlot();
- void stStartProjecting();
- void stLockedInSlot();
- void stStopProjecting();
- void stTurnToFront();
- void stStartSuckedIn();
-};
+class AsCommonProjector;
+class AsScene1201Tape;
+class AsScene1405Tile;
class Scene1401 : public Scene {
public:
@@ -146,24 +62,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1402
-
-class SsScene1402BridgePart : public StaticSprite {
-public:
- SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
-};
-
-class AsScene1402PuzzleBox : public AnimatedSprite {
-public:
- AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stMoveUpDone();
- void stMoveDownDone();
- void stMoveDownSolvedDone();
-};
-
class Scene1402 : public Scene {
public:
Scene1402(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -180,27 +78,6 @@ protected:
void stopShaking();
};
-// Scene1407
-
-class AsScene1407Mouse : public AnimatedSprite {
-public:
- AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int16 _walkDestX;
- int16 _currSectionIndex;
- int16 _nextHoleIndex;
- int _countdown;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suWalkTo();
- void upGoThroughHole();
- void stIdleLookAtGoodHole();
- void stWalkToDest();
- void stWalkToHole();
- void stGoThroughHole();
- void stArriveAtHole();
-};
-
class Scene1407 : public Scene {
public:
Scene1407(NeverhoodEngine *vm, Module *parentModule);
@@ -213,8 +90,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1403
-
class Scene1403 : public Scene {
public:
Scene1403(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -229,8 +104,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1404
-
class Scene1404 : public Scene {
public:
Scene1404(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -243,24 +116,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene1405
-
-class Scene1405;
-
-class AsScene1405Tile : public AnimatedSprite {
-public:
- AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
- void show();
- void hide();
-protected:
- Scene1405 *_parentScene;
- bool _isShowing;
- uint32 _tileIndex;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1405 : public Scene {
public:
Scene1405(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module1400_sprites.cpp b/engines/neverhood/modules/module1400_sprites.cpp
new file mode 100644
index 0000000000..c0ab73c93d
--- /dev/null
+++ b/engines/neverhood/modules/module1400_sprites.cpp
@@ -0,0 +1,1129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1400_sprites.h"
+#include "neverhood/modules/module1400.h"
+
+namespace Neverhood {
+
+AsScene1401Pipe::AsScene1401Pipe(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100), _countdown1(0), _countdown2(0) {
+
+ createSurface(900, 152, 147);
+ _x = 454;
+ _y = 217;
+ startAnimation(0x4C210500, 0, -1);
+ SetUpdateHandler(&AsScene1401Pipe::update);
+ SetMessageHandler(&AsScene1401Pipe::handleMessage);
+}
+
+AsScene1401Pipe::~AsScene1401Pipe() {
+ _vm->_soundMan->deleteSoundGroup(0x01104C08);
+}
+
+void AsScene1401Pipe::update() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0 && (--_countdown1 == 0))
+ stDoneSucking();
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ _vm->_soundMan->addSound(0x01104C08, 0x4A116437);
+ _vm->_soundMan->playSoundLooping(0x4A116437);
+ }
+}
+
+void AsScene1401Pipe::upSuckInProjector() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0)
+ _countdown1--;
+}
+
+uint32 AsScene1401Pipe::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x0A8A1490)
+ playSound(1, 0x6AB6666F);
+ break;
+ case 0x2000:
+ _countdown1 = 70;
+ _countdown2 = 8;
+ stStartSucking();
+ break;
+ case 0x483A:
+ stSuckInProjector();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1401Pipe::hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ if (_countdown1 != 0)
+ stStartSucking();
+ else
+ stDoneSucking();
+ SetMessageHandler(&AsScene1401Pipe::handleMessage);
+ SetUpdateHandler(&AsScene1401Pipe::update);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Pipe::stStartSucking() {
+ startAnimation(0x4C240100, 0, -1);
+ playSound(0, 0x4A30063F);
+}
+
+void AsScene1401Pipe::stDoneSucking() {
+ _vm->_soundMan->deleteSound(0x4A116437);
+ playSound(0, 0x4A120435);
+ startAnimation(0x4C210500, 0, -1);
+}
+
+void AsScene1401Pipe::stSuckInProjector() {
+ startAnimation(0x6C210810, 0, -1);
+ SetUpdateHandler(&AsScene1401Pipe::upSuckInProjector);
+ SetMessageHandler(&AsScene1401Pipe::hmSuckInProjector);
+}
+
+AsScene1401Mouse::AsScene1401Mouse(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(100, 71, 41);
+ _x = 478;
+ _y = 433;
+ startAnimation(0xA282C472, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1401Mouse::handleMessage);
+}
+
+uint32 AsScene1401Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x66382026)
+ playSound(0, 0x0CD84468);
+ else if (param.asInteger() == 0x6E28061C)
+ playSound(0, 0x78C8402C);
+ else if (param.asInteger() == 0x462F0410)
+ playSound(0, 0x60984E28);
+ break;
+ case 0x4839:
+ stSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Mouse::suSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ playSound(0, 0x0E32247F);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1401Mouse::stSuckedIn() {
+ startAnimation(0x34880040, 0, -1);
+ SetSpriteUpdate(&AsScene1401Mouse::suSuckedIn);
+}
+
+AsScene1401Cheese::AsScene1401Cheese(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(200, 152, 147);
+ _x = 427;
+ _y = 433;
+ startAnimation(0x461A1490, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1401Cheese::handleMessage);
+}
+
+uint32 AsScene1401Cheese::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4839:
+ stSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401Cheese::suSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ playSound(0, 0x18020439);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1401Cheese::stSuckedIn() {
+ startAnimation(0x103B8020, 0, -1);
+ SetSpriteUpdate(&AsScene1401Cheese::suSuckedIn);
+}
+
+AsScene1401BackDoor::AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0), _isOpen(isOpen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x04551900, 100);
+ if (isOpen) {
+ startAnimation(0x04551900, -1, -1);
+ _countdown = 48;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AsScene1401BackDoor::update);
+ SetMessageHandler(&AsScene1401BackDoor::handleMessage);
+}
+
+void AsScene1401BackDoor::update() {
+ if (_countdown != 0 && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+
+uint32 AsScene1401BackDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ if (_isOpen)
+ _countdown = 168;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 168;
+ if (!_isOpen)
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1401BackDoor::stOpenDoor() {
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x04551900, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen24"));
+}
+
+void AsScene1401BackDoor::stCloseDoor() {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x04551900, -1, -1);
+ playSound(0, calcHash("fxDoorClose24"));
+ _playBackwards = true;
+ NextState(&AsScene1401BackDoor::stCloseDoorDone);
+}
+
+void AsScene1401BackDoor::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+static const AsCommonProjectorItem kAsCommonProjectorItems[] = {
+ {{154, 453}, 4, 2, 0, 0, 1},
+ {{104, 391}, 4, -1, -1, 1, 1},
+ {{ 22, 447}, 6, -1, -1, 1, 1},
+ {{112, 406}, 2, -1, -1, 1, 0},
+ {{262, 433}, 1, 1, 0, 0, 0}
+};
+
+AsCommonProjector::AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klaymen(klaymen), _asPipe(asPipe) {
+
+ _asProjectorItem = &kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)];
+ createSurface(990, 101, 182);
+ startAnimation(0x10E3042B, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ _x = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ _lockedInSlot = true;
+ moveProjector();
+ setDoDeltaX(1);
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
+ stStayLockedInSlot();
+ loadSound(2, 0xC8C2507C);
+}
+
+AsCommonProjector::~AsCommonProjector() {
+ _vm->_soundMan->deleteSoundGroup(0x05331081);
+}
+
+uint32 AsCommonProjector::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4807:
+ setGlobalVar(V_PROJECTOR_SLOT, (_x - _asProjectorItem->point.x) / 108);
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->lockSlotIndex)
+ stStartLockedInSlot();
+ else
+ stIdle();
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
+ incGlobalVar(V_PROJECTOR_SLOT, 1);
+ } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
+ incGlobalVar(V_PROJECTOR_SLOT, -1);
+ stMoving();
+ break;
+ case 0x480C:
+ // Check if the projector can be moved
+ if (param.asInteger() != 1)
+ messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
+ else
+ messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ case 0x4839:
+ stStartSuckedIn();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonProjector::hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (param.asPoint().x - _x >= 17 && param.asPoint().x - _x <= 56 &&
+ param.asPoint().y - _y >= -120 && param.asPoint().y - _y <= -82) {
+ sendMessage(_parentScene, 0x4826, 1);
+ } else
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4807:
+ sendMessage(_parentScene, 0x4807, 0);
+ stStopProjecting();
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount)
+ incGlobalVar(V_PROJECTOR_SLOT, 1);
+ } else if (getGlobalVar(V_PROJECTOR_SLOT) > 0)
+ incGlobalVar(V_PROJECTOR_SLOT, -1);
+ stTurnToFront();
+ break;
+ case 0x480C:
+ // Check if the projector can be moved
+ if (param.asInteger() != 1)
+ messageResult = (int8)getGlobalVar(V_PROJECTOR_SLOT) < _asProjectorItem->maxSlotCount ? 1 : 0;
+ else
+ messageResult = getGlobalVar(V_PROJECTOR_SLOT) > 0 ? 1 : 0;
+ break;
+ case 0x480F:
+ stStartProjecting();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonProjector::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsCommonProjector::suMoving() {
+ if (_x <= _klaymen->getX())
+ _x = _klaymen->getX() - 100;
+ else
+ _x = _klaymen->getX() + 100;
+ moveProjector();
+ if (_beforeMoveX == _x) {
+ if (getGlobalVar(V_PROJECTOR_SLOT) == 0 && _asProjectorItem->leftBorderLeaves != 0) {
+ sendMessage(_parentScene, 0x1019, 0);
+ incGlobalVar(V_PROJECTOR_LOCATION, -1);
+ setGlobalVar(V_PROJECTOR_SLOT, kAsCommonProjectorItems[getGlobalVar(V_PROJECTOR_LOCATION)].maxSlotCount);
+ } else if ((int8)getGlobalVar(V_PROJECTOR_SLOT) == _asProjectorItem->maxSlotCount && _asProjectorItem->rightBorderLeaves != 0) {
+ sendMessage(_parentScene, 0x1019, 1);
+ incGlobalVar(V_PROJECTOR_LOCATION, +1);
+ setGlobalVar(V_PROJECTOR_SLOT, 0);
+ }
+ }
+ Sprite::updateBounds();
+}
+
+void AsCommonProjector::moveProjector() {
+
+ bool nowLockedInSlot = false;
+
+ _y = _asProjectorItem->point.y;
+
+ if (_asProjectorItem->index1 != -1) {
+ int16 elX = _asProjectorItem->index1 * 108 + _asProjectorItem->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ nowLockedInSlot = true;
+ _y = _asProjectorItem->point.y + 10;
+ }
+ }
+
+ if (_asProjectorItem->lockSlotIndex != -1) {
+ int16 elX = _asProjectorItem->lockSlotIndex * 108 + _asProjectorItem->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ nowLockedInSlot = true;
+ _y = _asProjectorItem->point.y + 10;
+ }
+ }
+
+ if (_lockedInSlot && !nowLockedInSlot)
+ _lockedInSlot = false;
+ else if (!_lockedInSlot && nowLockedInSlot) {
+ playSound(1, 0x5440E474);
+ _lockedInSlot = true;
+ }
+
+}
+
+void AsCommonProjector::stSuckedIn() {
+ AnimatedSprite::updateDeltaXY();
+ if (_collisionBounds.y1 <= 150) {
+ sendMessage(_asPipe, 0x483A, 0);
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsCommonProjector::stIdle() {
+ startAnimation(0x10E3042B, 0, -1);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stMoving() {
+ _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ startAnimation(0x14A10137, 0, -1);
+ playSound(1, 0xEC008474);
+ SetMessageHandler(&AsCommonProjector::handleMessage);
+ SetSpriteUpdate(&AsCommonProjector::suMoving);
+}
+
+void AsCommonProjector::stStartLockedInSlot() {
+ startAnimation(0x80C32213, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stStayLockedInSlot);
+}
+
+void AsCommonProjector::stStayLockedInSlot() {
+ startAnimation(0xD23B207F, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stStartProjecting() {
+ startAnimation(0x50A80517, 0, -1);
+ setGlobalVar(V_PROJECTOR_ACTIVE, 1);
+ playSound(0, 0xCC4A8456);
+ _vm->_soundMan->addSound(0x05331081, 0xCE428854);
+ _vm->_soundMan->playSoundLooping(0xCE428854);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stLockedInSlot);
+}
+
+void AsCommonProjector::stLockedInSlot() {
+ sendMessage(_parentScene, 0x480F, 0);
+ startAnimation(0xD833207F, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmLockedInSlot);
+ SetSpriteUpdate(NULL);
+}
+
+void AsCommonProjector::stStopProjecting() {
+ startAnimation(0x50A94417, 0, -1);
+ setGlobalVar(V_PROJECTOR_ACTIVE, 0);
+ playSound(0, 0xCC4A8456);
+ _vm->_soundMan->deleteSound(0xCE428854);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(NULL);
+ NextState(&AsCommonProjector::stStayLockedInSlot);
+}
+
+void AsCommonProjector::stTurnToFront() {
+ _beforeMoveX = getGlobalVar(V_PROJECTOR_SLOT) * 108 + _asProjectorItem->point.x;
+ startAnimation(0x22CB4A33, 0, -1);
+ SetMessageHandler(&AsCommonProjector::hmAnimation);
+ SetSpriteUpdate(&AsCommonProjector::suMoving);
+ NextState(&AsCommonProjector::stMoving);
+}
+
+void AsCommonProjector::stStartSuckedIn() {
+ setGlobalVar(V_PROJECTOR_LOCATION, 4);
+ setGlobalVar(V_PROJECTOR_SLOT, 0);
+ startAnimation(0x708D4712, 0, -1);
+ playSound(2);
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteUpdate(&AsCommonProjector::stSuckedIn);
+}
+
+SsScene1402BridgePart::SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
+ : StaticSprite(vm, fileHash, surfacePriority) {
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&StaticSprite::updatePosition);
+}
+
+AsScene1402PuzzleBox::AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(900, 347, 230);
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1402PuzzleBox::handleMessage);
+ _x = 279;
+ _y = 270;
+ if (status == 2) {
+ // Puzzle box after the puzzle was solved
+ startAnimation(0x20060259, 0, -1);
+ playSound(0, 0x419014AC);
+ loadSound(1, 0x61901C29);
+ NextState(&AsScene1402PuzzleBox::stMoveDownSolvedDone);
+ } else if (status == 1) {
+ // Puzzle box appears
+ startAnimation(0x210A0213, 0, -1);
+ playSound(0, 0x41809C6C);
+ NextState(&AsScene1402PuzzleBox::stMoveUpDone);
+ } else {
+ // Puzzle box is here
+ startAnimation(0x20060259, -1, -1);
+ loadSound(1, 0x61901C29);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ }
+}
+
+uint32 AsScene1402PuzzleBox::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ playSound(1);
+ startAnimation(0x20060259, -1, -1);
+ _playBackwards = true;
+ NextState(&AsScene1402PuzzleBox::stMoveDownDone);
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1402PuzzleBox::stMoveUpDone() {
+ sendMessage(_parentScene, 0x2000, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1402PuzzleBox::stMoveDownDone() {
+ sendMessage(_parentScene, 0x2001, 0);
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene1402PuzzleBox::stMoveDownSolvedDone() {
+ sendMessage(_parentScene, 0x2003, 0);
+ stopAnimation();
+}
+
+static const int16 kScene1407MouseFloorY[] = {
+ 106, 150, 191, 230, 267, 308, 350, 395
+};
+
+static const struct {
+ int16 x;
+ int16 floorIndex;
+ int16 sectionIndex;
+ int16 nextHoleIndex;
+} kScene1407MouseHoles[] = {
+ {125, 0, 0, 7},
+ {452, 7, 21, 0},
+ {337, 4, 11, 4},
+ {286, 6, 17, 6},
+ {348, 6, 17, 39},
+ {536, 6, 18, 42},
+ {111, 1, 3, 18},
+ {203, 1, 3, 38},
+ {270, 1, 3, 9},
+ {197, 5, 14, 3},
+ {252, 5, 14, 35},
+ {297, 5, 14, 7},
+ {359, 5, 14, 8},
+ {422, 4, 12, 26},
+ {467, 4, 12, 2},
+ {539, 4, 12, 40},
+ {111, 5, 13, 17},
+ {211, 0, 1, 20},
+ {258, 0, 1, 11},
+ {322, 0, 1, 16},
+ { 99, 6, 16, 31},
+ {142, 6, 16, 27},
+ {194, 6, 16, 12},
+ {205, 2, 6, 45},
+ {264, 2, 6, 10},
+ { 98, 4, 10, 2},
+ {152, 4, 10, 37},
+ {199, 4, 10, 13},
+ {258, 4, 10, 16},
+ {100, 7, 19, 43},
+ {168, 7, 19, 23},
+ {123, 3, 8, 14},
+ {181, 3, 8, 39},
+ {230, 3, 8, 28},
+ {292, 3, 8, 22},
+ {358, 3, 8, 36},
+ {505, 3, 9, 44},
+ {400, 2, 7, 34},
+ {454, 2, 7, 32},
+ {532, 2, 7, 46},
+ {484, 5, 15, 25},
+ {529, 5, 15, 30},
+ {251, 7, 20, 48},
+ {303, 7, 20, 21},
+ {360, 7, 20, 33},
+ {503, 0, 2, 5},
+ {459, 1, 4, 19},
+ {530, 1, 4, 42},
+ {111, 2, 5, 47},
+ {442, 6, 18, 1}
+};
+
+static const struct {
+ int16 x1, x2;
+ int16 goodHoleIndex;
+} kScene1407MouseSections[] = {
+ {100, 149, 0},
+ {182, 351, 17},
+ {430, 524, 45},
+ { 89, 293, 7},
+ {407, 555, 47},
+ { 89, 132, 48},
+ {178, 303, 23},
+ {367, 551, 38},
+ {105, 398, 31},
+ {480, 537, 36},
+ { 84, 275, 27},
+ {318, 359, 2},
+ {402, 560, 15},
+ { 91, 132, 16},
+ {179, 400, 10},
+ {461, 552, 41},
+ { 86, 218, 21},
+ {267, 376, 4},
+ {420, 560, 49},
+ { 77, 188, 30},
+ {237, 394, 44},
+ {438, 515, 5}
+};
+
+AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
+
+ createSurface(100, 117, 45);
+ _x = 108;
+ _y = 106;
+ stIdleLookAtGoodHole();
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene1407Mouse::suWalkTo() {
+ int16 xdelta = _walkDestX - _x;
+ if (xdelta > _deltaX)
+ xdelta = _deltaX;
+ else if (xdelta < -_deltaX)
+ xdelta = -_deltaX;
+ _deltaX = 0;
+ if (_walkDestX == _x)
+ sendMessage(this, 0x1019, 0);
+ else {
+ _x += xdelta;
+ updateBounds();
+ }
+}
+
+void AsScene1407Mouse::upGoThroughHole() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ SetUpdateHandler(&AnimatedSprite::update);
+ gotoNextState();
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1407Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ {
+ int16 mouseX = param.asPoint().x;
+ int16 mouseY = param.asPoint().y;
+ int holeIndex;
+ for (holeIndex = 0; holeIndex < 50; holeIndex++) {
+ int16 holeX = kScene1407MouseHoles[holeIndex].x;
+ int16 holeY = kScene1407MouseFloorY[kScene1407MouseHoles[holeIndex].floorIndex];
+ if (mouseX >= holeX - 14 && mouseX <= holeX + 14 && mouseY >= holeY - 36 && mouseY <= holeY)
+ break;
+ }
+ if (holeIndex < 50 && kScene1407MouseHoles[holeIndex].sectionIndex == _currSectionIndex) {
+ _nextHoleIndex = kScene1407MouseHoles[holeIndex].nextHoleIndex;
+ _walkDestX = kScene1407MouseHoles[holeIndex].x;
+ stWalkToHole();
+ } else {
+ if (mouseX < kScene1407MouseSections[_currSectionIndex].x1)
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x1;
+ else if (mouseX > kScene1407MouseSections[_currSectionIndex].x2)
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x2;
+ else
+ _walkDestX = mouseX;
+ stWalkToDest();
+ }
+ }
+ break;
+ case 0x1019:
+ gotoNextState();
+ break;
+ case 0x2001:
+ {
+ // Reset the position
+ // Find the nearest hole and go through it, and exit at the first hole
+ int16 distance = 640;
+ int matchIndex = 50;
+ for (int index = 0; index < 50; index++)
+ if (kScene1407MouseHoles[index].sectionIndex == _currSectionIndex &&
+ ABS(kScene1407MouseHoles[index].x - _x) < distance) {
+ matchIndex = index;
+ distance = ABS(kScene1407MouseHoles[index].x - _x);
+ }
+ if (matchIndex < 50) {
+ _nextHoleIndex = 0;
+ _walkDestX = kScene1407MouseHoles[matchIndex].x;
+ stWalkToHole();
+ }
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1407Mouse::stIdleLookAtGoodHole() {
+ setDoDeltaX(kScene1407MouseHoles[kScene1407MouseSections[_currSectionIndex].goodHoleIndex].x < _x ? 1 : 0);
+ startAnimation(0x72215194, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene1407Mouse::stWalkToDest() {
+ if (_walkDestX != _x) {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ startAnimation(0x22291510, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
+ NextState(&AsScene1407Mouse::stIdleLookAtGoodHole);
+ }
+}
+
+void AsScene1407Mouse::stWalkToHole() {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ startAnimation(0x22291510, 0, -1);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetSpriteUpdate(&AsScene1407Mouse::suWalkTo);
+ NextState(&AsScene1407Mouse::stGoThroughHole);
+}
+
+void AsScene1407Mouse::stGoThroughHole() {
+ startAnimation(0x72215194, 0, -1);
+ setVisible(false);
+ _countdown = 12;
+ SetUpdateHandler(&AsScene1407Mouse::upGoThroughHole);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(NULL);
+ NextState(&AsScene1407Mouse::stArriveAtHole);
+}
+
+void AsScene1407Mouse::stArriveAtHole() {
+ _currSectionIndex = kScene1407MouseHoles[_nextHoleIndex].sectionIndex;
+ _x = kScene1407MouseHoles[_nextHoleIndex].x;
+ _y = kScene1407MouseFloorY[kScene1407MouseHoles[_nextHoleIndex].floorIndex];
+ if (_nextHoleIndex == 1) {
+ sendMessage(_parentScene, 0x2000, 0);
+ _walkDestX = 512;
+ stWalkToDest();
+ setVisible(true);
+ } else {
+ _walkDestX = _x + 14;
+ stWalkToDest();
+ setVisible(true);
+ }
+}
+
+static const NPoint kAsScene1405TileItemPositions[] = {
+ {100, 80}, {162, 78}, {222, 76}, {292, 76},
+ {356, 82}, {422, 84}, {488, 86}, {550, 90},
+ {102, 134}, {164, 132}, {224, 136}, {294, 136},
+ {360, 136}, {422, 138}, {484, 144}, {548, 146},
+ { 98, 196}, {160, 200}, {228, 200}, {294, 202},
+ {360, 198}, {424, 200}, {482, 202}, {548, 206},
+ { 98, 260}, {160, 264}, {226, 260}, {296, 262},
+ {358, 260}, {424, 262}, {486, 264}, {550, 266},
+ { 94, 322}, {160, 316}, {226, 316}, {296, 320},
+ {358, 322}, {422, 324}, {488, 322}, {550, 322},
+ { 98, 380}, {160, 376}, {226, 376}, {294, 378},
+ {356, 380}, {420, 380}, {490, 378}, {552, 376}
+};
+
+AsScene1405Tile::AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _tileIndex(tileIndex), _countdown(0), _isShowing(false) {
+
+ loadSound(0, 0x05308101);
+ setSoundPan(0, (tileIndex % 8 * 4 + 4) * 25 / 8);
+ _x = kAsScene1405TileItemPositions[_tileIndex].x;
+ _y = kAsScene1405TileItemPositions[_tileIndex].y;
+ createSurface1(0x844B805C, 1100);
+ setVisible(false);
+ if (getSubVar(VA_IS_TILE_MATCH, _tileIndex))
+ _countdown = _vm->_rnd->getRandomNumber(36 - 1) + 1;
+ startAnimation(0x844B805C, getSubVar(VA_TILE_SYMBOLS, _tileIndex), -1);
+ _newStickFrameIndex = (int16)getSubVar(VA_TILE_SYMBOLS, _tileIndex);
+ SetUpdateHandler(&AsScene1405Tile::update);
+ SetMessageHandler(&AsScene1405Tile::handleMessage);
+}
+
+void AsScene1405Tile::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0))
+ show();
+}
+
+uint32 AsScene1405Tile::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (getSubVar(VA_IS_TILE_MATCH, _tileIndex) == 0 && _parentScene->getCountdown() == 0) {
+ show();
+ sendMessage(_parentScene, 0x2000, _tileIndex);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1405Tile::show() {
+ if (!_isShowing) {
+ _isShowing = true;
+ playSound(0);
+ setVisible(true);
+ }
+}
+
+void AsScene1405Tile::hide() {
+ if (_isShowing) {
+ _isShowing = false;
+ playSound(0);
+ setVisible(false);
+ }
+}
+
+KmScene1401::KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1401::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ }
+ return 0;
+}
+
+KmScene1402::KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ SetFilterY(&Sprite::defFilterY);
+}
+
+uint32 KmScene1402::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ }
+ return 0;
+}
+
+static const KlaymenIdleTableItem klaymenIdleTable1403[] = {
+ {1, kIdleSpinHead},
+ {1, kIdleChest},
+ {1, kIdleHeadOff},
+};
+
+KmScene1403::KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ setKlaymenIdleTable(klaymenIdleTable1403, ARRAYSIZE(klaymenIdleTable1403));
+}
+
+uint32 KmScene1403::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x4827:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+// KmScene1404
+
+KmScene1404::KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480A:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1400_sprites.h b/engines/neverhood/modules/module1400_sprites.h
new file mode 100644
index 0000000000..49b91fe0cf
--- /dev/null
+++ b/engines/neverhood/modules/module1400_sprites.h
@@ -0,0 +1,198 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1400_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1400_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene1401Pipe : public AnimatedSprite {
+public:
+ AsScene1401Pipe(NeverhoodEngine *vm);
+ virtual ~AsScene1401Pipe();
+protected:
+ int _countdown1;
+ int _countdown2;
+ void update();
+ void upSuckInProjector();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmSuckInProjector(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartSucking();
+ void stDoneSucking();
+ void stSuckInProjector();
+};
+
+class AsScene1401Mouse : public AnimatedSprite {
+public:
+ AsScene1401Mouse(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSuckedIn();
+ void stSuckedIn();
+};
+
+class AsScene1401Cheese : public AnimatedSprite {
+public:
+ AsScene1401Cheese(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSuckedIn();
+ void stSuckedIn();
+};
+
+class AsScene1401BackDoor : public AnimatedSprite {
+public:
+ AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
+protected:
+ Sprite *_klaymen;
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+struct AsCommonProjectorItem {
+ NPoint point;
+ int8 maxSlotCount;
+ int8 lockSlotIndex;
+ int8 index1;
+ int8 leftBorderLeaves;
+ int8 rightBorderLeaves;
+};
+
+class AsCommonProjector : public AnimatedSprite {
+public:
+ AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
+ virtual ~AsCommonProjector();
+protected:
+ Scene *_parentScene;
+ Sprite *_klaymen;
+ Sprite *_asPipe;
+ const AsCommonProjectorItem *_asProjectorItem;
+ int16 _beforeMoveX;
+ bool _lockedInSlot;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmLockedInSlot(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoving();
+ void moveProjector();
+ void stSuckedIn();
+ void stIdle();
+ void stMoving();
+ void stStartLockedInSlot();
+ void stStayLockedInSlot();
+ void stStartProjecting();
+ void stLockedInSlot();
+ void stStopProjecting();
+ void stTurnToFront();
+ void stStartSuckedIn();
+};
+
+class SsScene1402BridgePart : public StaticSprite {
+public:
+ SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
+};
+
+class AsScene1402PuzzleBox : public AnimatedSprite {
+public:
+ AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stMoveUpDone();
+ void stMoveDownDone();
+ void stMoveDownSolvedDone();
+};
+
+class AsScene1407Mouse : public AnimatedSprite {
+public:
+ AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int16 _walkDestX;
+ int16 _currSectionIndex;
+ int16 _nextHoleIndex;
+ int _countdown;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suWalkTo();
+ void upGoThroughHole();
+ void stIdleLookAtGoodHole();
+ void stWalkToDest();
+ void stWalkToHole();
+ void stGoThroughHole();
+ void stArriveAtHole();
+};
+
+class Scene1405;
+
+class AsScene1405Tile : public AnimatedSprite {
+public:
+ AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
+ void show();
+ void hide();
+protected:
+ Scene1405 *_parentScene;
+ bool _isShowing;
+ uint32 _tileIndex;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1401 : public Klaymen {
+public:
+ KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1402 : public Klaymen {
+public:
+ KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1403 : public Klaymen {
+public:
+ KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1404 : public Klaymen {
+public:
+ KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1400_SPRITES_H */
diff --git a/engines/neverhood/modules/module1600.cpp b/engines/neverhood/modules/module1600.cpp
index a5a785e130..0df7dd8925 100644
--- a/engines/neverhood/modules/module1600.cpp
+++ b/engines/neverhood/modules/module1600.cpp
@@ -20,10 +20,12 @@
*
*/
-#include "neverhood/modules/module1600.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module2200.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
@@ -183,825 +185,6 @@ void Module1600::updateScene() {
}
}
-AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
-
- createSurface(200, 556, 328);
- _x = x;
- _y = y;
-
- _inMainArea = false;
- _exitDirection = 0;
- _currPointIndex = 0;
- _hasAgainDestPoint = false;
- _stepError = 0;
- _hasAgainDestPointIndex = false;
- _steps = 0;
- _isBraking = false;
- _yMoveTotalSteps = 0;
- _isBusy = false;
- _isIdle = false;
- _isMoving = true;
- _rectFlag = false;
- _newDeltaXType = -1;
- _soundCounter = 0;
- _pathPoints = NULL;
- _currMoveDirection = 0;
-
- startAnimation(0xD4220027, 0, -1);
- setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
-
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-AsCommonCar::~AsCommonCar() {
- if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
- setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
-}
-
-void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
- _pathPoints = pathPoints;
-}
-
-void AsCommonCar::update() {
- if (_newDeltaXType >= 0) {
- setDoDeltaX(_newDeltaXType);
- _newDeltaXType = -1;
- }
- AnimatedSprite::update();
- if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- sendPointMessage(this, 0x2004, _againDestPoint);
- } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPointIndex = false;
- sendMessage(this, 0x2003, _againDestPointIndex);
- }
- updateMovement();
- updateSound();
-}
-
-void AsCommonCar::upIdle() {
- update();
- if (++_idleCounter >= _idleCounterMax)
- stIdleBlink();
- updateSound();
-}
-
-uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1019:
- SetSpriteUpdate(NULL);
- break;
- case 0x2002:
- // Set the current position without moving
- _currPointIndex = param.asInteger();
- _stepError = 0;
- _x = pathPoint(_currPointIndex).x;
- _y = pathPoint(_currPointIndex).y;
- break;
- case 0x2003:
- // Move to a point by its index
- {
- int newPointIndex = param.asInteger();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- _destX = pathPoint(newPointIndex).x;
- _destY = pathPoint(newPointIndex).y;
- if (_currPointIndex < newPointIndex) {
- moveToNextPoint();
- } else if (_currPointIndex == newPointIndex && _stepError == 0) {
- if (_currPointIndex == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2005, 0);
- } else if (_currPointIndex == (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2006, 0);
- }
- } else {
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPointIndex = true;
- _againDestPointIndex = newPointIndex;
- }
- }
- break;
- case 0x2004:
- // Move to the point closest to the parameter point
- {
- int minMatchIndex = -1;
- int minMatchDistance, distance;
- NPoint pt = param.asPoint();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- // Check if we're already exiting (or something)
- if ((pt.x <= 20 && _exitDirection == 1) ||
- (pt.x >= 620 && _exitDirection == 3) ||
- (pt.y <= 20 && _exitDirection == 2) ||
- (pt.y >= 460 && _exitDirection == 4))
- break;
- _destX = pt.x;
- _destY = pt.y;
- minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
- for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- for (int i = _currPointIndex; i >= 0; i--) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- if (minMatchIndex == -1) {
- if (_currPointIndex == 0)
- moveToPrevPoint();
- else
- SetSpriteUpdate(NULL);
- } else {
- if (minMatchIndex > _currPointIndex)
- moveToNextPoint();
- else
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPoint = true;
- _againDestPoint = pt;
- }
- }
- break;
- case 0x2007:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- break;
- case 0x2008:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- break;
- case 0x2009:
- stEnterCar();
- break;
- case 0x200A:
- stLeaveCar();
- break;
- case 0x200E:
- stTurnCar();
- break;
- case 0x200F:
- stCarAtHome();
- _newDeltaXType = param.asInteger();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_isBusy && param.asInteger() == 0x025424A2)
- gotoNextState();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
- switch (messageNum) {
- case 0x2009:
- stEnterCar();
- break;
- case 0x3002:
- sendMessage(_parentScene, 0x200A, 0);
- SetMessageHandler(&AsCommonCar::handleMessage);
- break;
- }
- return 0;
-}
-
-void AsCommonCar::stCarAtHome() {
- bool doDeltaX = _doDeltaX;
- SetSpriteUpdate(NULL);
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- _isBraking = false;
- _isBusy = false;
- _isIdle = false;
- _isMoving = false;
- _rectFlag = false;
- NextState(&AsCommonCar::stLeanForwardIdle);
- startAnimation(0x35698F78, 0, -1);
- setDoDeltaX(doDeltaX ? 1 : 0);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::updateTurnMovement() {
- if (_turnMoveStatus == 1) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- } else if (_turnMoveStatus == 2) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- }
-}
-
-void AsCommonCar::updateMovement() {
- if (_isBraking && !_isIdle && !_isBusy) {
- gotoNextState();
- _isMoving = false;
- _isIdle = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
- } else if (!_isBraking && _steps && _isIdle) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
- gotoNextState();
- _currMoveDirection = _newMoveDirection;
- stUpdateMoveDirection();
- }
-}
-
-void AsCommonCar::stEnterCar() {
- startAnimation(0xA86A9538, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stLeaveCar() {
- startAnimation(0xA86A9538, -1, -1);
- _playBackwards = true;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmLeaveCar);
-}
-
-void AsCommonCar::stLeanForwardIdle() {
- startAnimation(0x35698F78, 0, -1);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::evIdleDone() {
- SetUpdateHandler(&AsCommonCar::update);
-}
-
-void AsCommonCar::stIdleBlink() {
- startAnimation(0xB579A77C, 0, -1);
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stUpdateMoveDirection() {
- _isMoving = true;
- if (_currMoveDirection == 1)
- startAnimation(0xD4AA03A4, 0, -1);
- else if (_currMoveDirection == 3)
- startAnimation(0xD00A1364, 0, -1);
- else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
- stTurnCar();
- else
- startAnimation(0xD4220027, 0, -1);
- setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
-}
-
-void AsCommonCar::moveToNextPoint() {
- if (_currPointIndex >= (int)_pathPoints->size() - 1) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- } else {
- NPoint nextPt = pathPoint(_currPointIndex + 1);
- NPoint currPt = pathPoint(_currPointIndex);
- if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
- (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToNextPoint();
- else
- stBrakeMoveToNextPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToNextPoint() {
- gotoNextState();
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
-}
-
-void AsCommonCar::stTurnCar() {
- // Turn to left/right #1
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 0;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToNextPoint() {
- // Turn to left/right #2
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 1;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToPrevPoint() {
- // Turn to left/right #3
- FinalizeState(NULL);
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 2;
- updateTurnMovement();
-}
-
-void AsCommonCar::moveToPrevPoint() {
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- } else {
- NPoint prevPt;
- NPoint currPt;
- if (_stepError == 0) {
- prevPt = pathPoint(_currPointIndex - 1);
- currPt = pathPoint(_currPointIndex);
- } else {
- prevPt = pathPoint(_currPointIndex);
- currPt = pathPoint(_currPointIndex + 1);
- }
- if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
- (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToPrevPoint();
- else
- stBrakeMoveToPrevPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToPrevPoint() {
- FinalizeState(NULL);
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
-}
-
-void AsCommonCar::evTurnCarDone() {
- _isBusy = false;
- setDoDeltaX(2);
- _newMoveDirection = 0;
- stUpdateMoveDirection();
-}
-
-void AsCommonCar::suMoveToNextPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex >= (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 2;
- if (pt1.x < pt2.x)
- _newMoveDirection = 4;
- if (stepsCtr + _stepError >= deltaX) {
- stepsCtr -= deltaX;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX += stepsCtr;
- else
- newX -= stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 3;
- if (pt1.y < pt2.y)
- _newMoveDirection = 1;
- if (firstTime) {
- if (pt1.y >= pt2.y)
- stepsCtr += 7;
- else {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- }
- _ySteps = stepsCtr;
- }
- if (stepsCtr + _stepError >= deltaY) {
- stepsCtr -= deltaY;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY += stepsCtr;
- else
- newY -= stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(_pathPoints->size() - 1).x;
- _destY = pathPoint(_pathPoints->size() - 1).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == (int)_pathPoints->size() - 1) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- }
- }
-
-}
-
-void AsCommonCar::suMoveToPrevPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- if (_stepError == 0)
- _currPointIndex--;
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 4;
- if (pt1.x < pt2.x)
- _newMoveDirection = 2;
- if (_stepError == 0)
- _stepError = deltaX;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX -= stepsCtr;
- else
- newX += stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 1;
- if (pt1.y < pt2.y)
- _newMoveDirection = 3;
- if (firstTime) {
- if (pt1.y >= pt2.y) {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- } else {
- stepsCtr += 7;
- }
- _ySteps = stepsCtr;
- }
- if (_stepError == 0)
- _stepError = deltaY;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY -= stepsCtr;
- else
- newY += stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(0).x;
- _destY = pathPoint(0).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == 0 && _stepError == 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- }
- }
-
-}
-
-void AsCommonCar::updateSound() {
- int maxSoundCounter = 0;
- _soundCounter++;
- if (_steps != 0 && !_isIdle) {
- if (_currMoveDirection == 1)
- maxSoundCounter = 18 - _steps;
- else if (_currMoveDirection == 3) {
- maxSoundCounter = 5 - _steps;
- if (maxSoundCounter < 1)
- maxSoundCounter = 1;
- } else
- maxSoundCounter = 14 - _steps;
- } else
- maxSoundCounter = 21;
- if (_soundCounter >= maxSoundCounter) {
- sendMessage(_parentScene, 0x200D, 0);
- _soundCounter = 0;
- }
-}
-
-AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
-
- setDoDeltaX(1);
- startAnimation(0x1209E09F, 1, -1);
- _newStickFrameIndex = 1;
-}
-
-AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
-
- setDoDeltaX(1);
- _newStickFrameIndex = 0;
-}
-
-AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
- : AnimatedSprite(vm, 1100), _asCar(asCar) {
-
- createSurface1(0x60281C10, 150);
- startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AsCommonCarConnector::update);
-}
-
-void AsCommonCarConnector::update() {
- _x = _asCar->getX();
- _y = _asCar->getY();
- AnimatedSprite::update();
-}
-
-void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource) {
- const uint trackCount = size();
- minMatchTrackIndex = -1;
- minMatchDistance = 640;
- for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
- NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
- for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
- NPoint testPt = (*pointList)[pointIndex];
- int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
- if (distance < minMatchDistance) {
- minMatchTrackIndex = trackIndex;
- minMatchDistance = distance;
- }
- }
- }
-}
-
Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asCar(NULL), _countdown1(0) {
diff --git a/engines/neverhood/modules/module1600.h b/engines/neverhood/modules/module1600.h
index 5f0da528ab..f08eaad8fc 100644
--- a/engines/neverhood/modules/module1600.h
+++ b/engines/neverhood/modules/module1600.h
@@ -26,13 +26,9 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/console.h"
-#include "neverhood/modules/module3000.h"
namespace Neverhood {
-// Module1600
-
class Module1600 : public Module {
public:
Module1600(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -43,90 +39,7 @@ protected:
void updateScene();
};
-class AsCommonCar : public AnimatedSprite {
-public:
- AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
- ~AsCommonCar();
- void setPathPoints(NPointArray *pathPoints);
-protected:
- Scene *_parentScene;
- NPointArray *_pathPoints;
- int _newMoveDirection;
- int _currMoveDirection;
- int _exitDirection;
- int _currPointIndex;
- bool _hasAgainDestPoint;
- NPoint _againDestPoint;
- bool _hasAgainDestPointIndex;
- int _againDestPointIndex;
- bool _inMainArea;
- bool _isBraking;
- bool _isBusy;
- bool _isIdle;
- bool _isMoving;
- bool _rectFlag;
- int _idleCounter;
- int _idleCounterMax;
- int _steps;
- int _stepError;
- int _lastDistance;
- int _yMoveTotalSteps;
- int _ySteps;
- int _newDeltaXType;
- int _soundCounter;
- int _turnMoveStatus;
- int16 _destX, _destY;
- NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
- void update();
- void upIdle();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
- void stCarAtHome();
- void updateTurnMovement();
- void updateMovement();
- void stEnterCar();
- void stLeaveCar();
- void stLeanForwardIdle();
- void evIdleDone();
- void stIdleBlink();
- void stUpdateMoveDirection();
- void stTurnCar();
- void moveToNextPoint();
- void stBrakeMoveToNextPoint();
- void stTurnCarMoveToNextPoint();
- void moveToPrevPoint();
- void stBrakeMoveToPrevPoint();
- void stTurnCarMoveToPrevPoint();
- void evTurnCarDone();
- void suMoveToNextPoint();
- void suMoveToPrevPoint();
- void updateSound();
-};
-
-class AsCommonIdleCarLower : public AnimatedSprite {
-public:
- AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonIdleCarFull : public AnimatedSprite {
-public:
- AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonCarConnector : public AnimatedSprite {
-public:
- AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
-protected:
- AsCommonCar *_asCar;
- void update();
-};
-
-class Tracks : public Common::Array<TrackInfo*> {
-public:
- void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource);
-};
+class AsCommonCar;
class Scene1608 : public Scene {
public:
@@ -162,6 +75,8 @@ protected:
void updateKlaymenCliprect();
};
+class AsScene3011Symbol;
+
class Scene1609 : public Scene {
friend class Console;
public:
diff --git a/engines/neverhood/modules/module1600_sprites.cpp b/engines/neverhood/modules/module1600_sprites.cpp
new file mode 100644
index 0000000000..06a00c82c0
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.cpp
@@ -0,0 +1,934 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1600_sprites.h"
+
+namespace Neverhood {
+
+AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
+
+ createSurface(200, 556, 328);
+ _x = x;
+ _y = y;
+
+ _inMainArea = false;
+ _exitDirection = 0;
+ _currPointIndex = 0;
+ _hasAgainDestPoint = false;
+ _stepError = 0;
+ _hasAgainDestPointIndex = false;
+ _steps = 0;
+ _isBraking = false;
+ _yMoveTotalSteps = 0;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = true;
+ _rectFlag = false;
+ _newDeltaXType = -1;
+ _soundCounter = 0;
+ _pathPoints = NULL;
+ _currMoveDirection = 0;
+
+ startAnimation(0xD4220027, 0, -1);
+ setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
+
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+AsCommonCar::~AsCommonCar() {
+ if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
+ setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
+}
+
+void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
+ _pathPoints = pathPoints;
+}
+
+void AsCommonCar::update() {
+ if (_newDeltaXType >= 0) {
+ setDoDeltaX(_newDeltaXType);
+ _newDeltaXType = -1;
+ }
+ AnimatedSprite::update();
+ if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ sendPointMessage(this, 0x2004, _againDestPoint);
+ } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPointIndex = false;
+ sendMessage(this, 0x2003, _againDestPointIndex);
+ }
+ updateMovement();
+ updateSound();
+}
+
+void AsCommonCar::upIdle() {
+ update();
+ if (++_idleCounter >= _idleCounterMax)
+ stIdleBlink();
+ updateSound();
+}
+
+uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1019:
+ SetSpriteUpdate(NULL);
+ break;
+ case 0x2002:
+ // Set the current position without moving
+ _currPointIndex = param.asInteger();
+ _stepError = 0;
+ _x = pathPoint(_currPointIndex).x;
+ _y = pathPoint(_currPointIndex).y;
+ break;
+ case 0x2003:
+ // Move to a point by its index
+ {
+ int newPointIndex = param.asInteger();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ _destX = pathPoint(newPointIndex).x;
+ _destY = pathPoint(newPointIndex).y;
+ if (_currPointIndex < newPointIndex) {
+ moveToNextPoint();
+ } else if (_currPointIndex == newPointIndex && _stepError == 0) {
+ if (_currPointIndex == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, 0x2005, 0);
+ } else if (_currPointIndex == (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, 0x2006, 0);
+ }
+ } else {
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPointIndex = true;
+ _againDestPointIndex = newPointIndex;
+ }
+ }
+ break;
+ case 0x2004:
+ // Move to the point closest to the parameter point
+ {
+ int minMatchIndex = -1;
+ int minMatchDistance, distance;
+ NPoint pt = param.asPoint();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ // Check if we're already exiting (or something)
+ if ((pt.x <= 20 && _exitDirection == 1) ||
+ (pt.x >= 620 && _exitDirection == 3) ||
+ (pt.y <= 20 && _exitDirection == 2) ||
+ (pt.y >= 460 && _exitDirection == 4))
+ break;
+ _destX = pt.x;
+ _destY = pt.y;
+ minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
+ for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ for (int i = _currPointIndex; i >= 0; i--) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ if (minMatchIndex == -1) {
+ if (_currPointIndex == 0)
+ moveToPrevPoint();
+ else
+ SetSpriteUpdate(NULL);
+ } else {
+ if (minMatchIndex > _currPointIndex)
+ moveToNextPoint();
+ else
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPoint = true;
+ _againDestPoint = pt;
+ }
+ }
+ break;
+ case 0x2007:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ break;
+ case 0x2008:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ break;
+ case 0x2009:
+ stEnterCar();
+ break;
+ case 0x200A:
+ stLeaveCar();
+ break;
+ case 0x200E:
+ stTurnCar();
+ break;
+ case 0x200F:
+ stCarAtHome();
+ _newDeltaXType = param.asInteger();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (_isBusy && param.asInteger() == 0x025424A2)
+ gotoNextState();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case 0x2009:
+ stEnterCar();
+ break;
+ case 0x3002:
+ sendMessage(_parentScene, 0x200A, 0);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ break;
+ }
+ return 0;
+}
+
+void AsCommonCar::stCarAtHome() {
+ bool doDeltaX = _doDeltaX;
+ SetSpriteUpdate(NULL);
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ _isBraking = false;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = false;
+ _rectFlag = false;
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ startAnimation(0x35698F78, 0, -1);
+ setDoDeltaX(doDeltaX ? 1 : 0);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::updateTurnMovement() {
+ if (_turnMoveStatus == 1) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ } else if (_turnMoveStatus == 2) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ }
+}
+
+void AsCommonCar::updateMovement() {
+ if (_isBraking && !_isIdle && !_isBusy) {
+ gotoNextState();
+ _isMoving = false;
+ _isIdle = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ } else if (!_isBraking && _steps && _isIdle) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
+ gotoNextState();
+ _currMoveDirection = _newMoveDirection;
+ stUpdateMoveDirection();
+ }
+}
+
+void AsCommonCar::stEnterCar() {
+ startAnimation(0xA86A9538, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stLeaveCar() {
+ startAnimation(0xA86A9538, -1, -1);
+ _playBackwards = true;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmLeaveCar);
+}
+
+void AsCommonCar::stLeanForwardIdle() {
+ startAnimation(0x35698F78, 0, -1);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::evIdleDone() {
+ SetUpdateHandler(&AsCommonCar::update);
+}
+
+void AsCommonCar::stIdleBlink() {
+ startAnimation(0xB579A77C, 0, -1);
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stUpdateMoveDirection() {
+ _isMoving = true;
+ if (_currMoveDirection == 1)
+ startAnimation(0xD4AA03A4, 0, -1);
+ else if (_currMoveDirection == 3)
+ startAnimation(0xD00A1364, 0, -1);
+ else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
+ stTurnCar();
+ else
+ startAnimation(0xD4220027, 0, -1);
+ setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
+}
+
+void AsCommonCar::moveToNextPoint() {
+ if (_currPointIndex >= (int)_pathPoints->size() - 1) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ } else {
+ NPoint nextPt = pathPoint(_currPointIndex + 1);
+ NPoint currPt = pathPoint(_currPointIndex);
+ if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToNextPoint();
+ else
+ stBrakeMoveToNextPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToNextPoint() {
+ gotoNextState();
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
+}
+
+void AsCommonCar::stTurnCar() {
+ // Turn to left/right #1
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 0;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToNextPoint() {
+ // Turn to left/right #2
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 1;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToPrevPoint() {
+ // Turn to left/right #3
+ FinalizeState(NULL);
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 2;
+ updateTurnMovement();
+}
+
+void AsCommonCar::moveToPrevPoint() {
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ } else {
+ NPoint prevPt;
+ NPoint currPt;
+ if (_stepError == 0) {
+ prevPt = pathPoint(_currPointIndex - 1);
+ currPt = pathPoint(_currPointIndex);
+ } else {
+ prevPt = pathPoint(_currPointIndex);
+ currPt = pathPoint(_currPointIndex + 1);
+ }
+ if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToPrevPoint();
+ else
+ stBrakeMoveToPrevPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToPrevPoint() {
+ FinalizeState(NULL);
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
+}
+
+void AsCommonCar::evTurnCarDone() {
+ _isBusy = false;
+ setDoDeltaX(2);
+ _newMoveDirection = 0;
+ stUpdateMoveDirection();
+}
+
+void AsCommonCar::suMoveToNextPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex >= (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, 0x1019, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 2;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 4;
+ if (stepsCtr + _stepError >= deltaX) {
+ stepsCtr -= deltaX;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX += stepsCtr;
+ else
+ newX -= stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 3;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 1;
+ if (firstTime) {
+ if (pt1.y >= pt2.y)
+ stepsCtr += 7;
+ else {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (stepsCtr + _stepError >= deltaY) {
+ stepsCtr -= deltaY;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY += stepsCtr;
+ else
+ newY -= stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(_pathPoints->size() - 1).x;
+ _destY = pathPoint(_pathPoints->size() - 1).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == (int)_pathPoints->size() - 1) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::suMoveToPrevPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, 0x1019, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ if (_stepError == 0)
+ _currPointIndex--;
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 4;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 2;
+ if (_stepError == 0)
+ _stepError = deltaX;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX -= stepsCtr;
+ else
+ newX += stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 1;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 3;
+ if (firstTime) {
+ if (pt1.y >= pt2.y) {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ } else {
+ stepsCtr += 7;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (_stepError == 0)
+ _stepError = deltaY;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY -= stepsCtr;
+ else
+ newY += stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(0).x;
+ _destY = pathPoint(0).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::updateSound() {
+ int maxSoundCounter = 0;
+ _soundCounter++;
+ if (_steps != 0 && !_isIdle) {
+ if (_currMoveDirection == 1)
+ maxSoundCounter = 18 - _steps;
+ else if (_currMoveDirection == 3) {
+ maxSoundCounter = 5 - _steps;
+ if (maxSoundCounter < 1)
+ maxSoundCounter = 1;
+ } else
+ maxSoundCounter = 14 - _steps;
+ } else
+ maxSoundCounter = 21;
+ if (_soundCounter >= maxSoundCounter) {
+ sendMessage(_parentScene, 0x200D, 0);
+ _soundCounter = 0;
+ }
+}
+
+AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
+
+ setDoDeltaX(1);
+ startAnimation(0x1209E09F, 1, -1);
+ _newStickFrameIndex = 1;
+}
+
+AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
+
+ setDoDeltaX(1);
+ _newStickFrameIndex = 0;
+}
+
+AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
+ : AnimatedSprite(vm, 1100), _asCar(asCar) {
+
+ createSurface1(0x60281C10, 150);
+ startAnimation(0x60281C10, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AsCommonCarConnector::update);
+}
+
+void AsCommonCarConnector::update() {
+ _x = _asCar->getX();
+ _y = _asCar->getY();
+ AnimatedSprite::update();
+}
+
+void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource) {
+ const uint trackCount = size();
+ minMatchTrackIndex = -1;
+ minMatchDistance = 640;
+ for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
+ NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
+ for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
+ NPoint testPt = (*pointList)[pointIndex];
+ int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
+ if (distance < minMatchDistance) {
+ minMatchTrackIndex = trackIndex;
+ minMatchDistance = distance;
+ }
+ }
+ }
+}
+
+KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2032:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2032, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2032, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1600_sprites.h b/engines/neverhood/modules/module1600_sprites.h
new file mode 100644
index 0000000000..fa59475dad
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.h
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsCommonCar : public AnimatedSprite {
+public:
+ AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+ ~AsCommonCar();
+ void setPathPoints(NPointArray *pathPoints);
+protected:
+ Scene *_parentScene;
+ NPointArray *_pathPoints;
+ int _newMoveDirection;
+ int _currMoveDirection;
+ int _exitDirection;
+ int _currPointIndex;
+ bool _hasAgainDestPoint;
+ NPoint _againDestPoint;
+ bool _hasAgainDestPointIndex;
+ int _againDestPointIndex;
+ bool _inMainArea;
+ bool _isBraking;
+ bool _isBusy;
+ bool _isIdle;
+ bool _isMoving;
+ bool _rectFlag;
+ int _idleCounter;
+ int _idleCounterMax;
+ int _steps;
+ int _stepError;
+ int _lastDistance;
+ int _yMoveTotalSteps;
+ int _ySteps;
+ int _newDeltaXType;
+ int _soundCounter;
+ int _turnMoveStatus;
+ int16 _destX, _destY;
+ NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
+ void update();
+ void upIdle();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
+ void stCarAtHome();
+ void updateTurnMovement();
+ void updateMovement();
+ void stEnterCar();
+ void stLeaveCar();
+ void stLeanForwardIdle();
+ void evIdleDone();
+ void stIdleBlink();
+ void stUpdateMoveDirection();
+ void stTurnCar();
+ void moveToNextPoint();
+ void stBrakeMoveToNextPoint();
+ void stTurnCarMoveToNextPoint();
+ void moveToPrevPoint();
+ void stBrakeMoveToPrevPoint();
+ void stTurnCarMoveToPrevPoint();
+ void evTurnCarDone();
+ void suMoveToNextPoint();
+ void suMoveToPrevPoint();
+ void updateSound();
+};
+
+class AsCommonIdleCarLower : public AnimatedSprite {
+public:
+ AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonIdleCarFull : public AnimatedSprite {
+public:
+ AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonCarConnector : public AnimatedSprite {
+public:
+ AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
+protected:
+ AsCommonCar *_asCar;
+ void update();
+};
+
+class Tracks : public Common::Array<TrackInfo*> {
+public:
+ void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource);
+};
+
+class KmScene1608 : public Klaymen {
+public:
+ KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1600_SPRITES_H */
diff --git a/engines/neverhood/modules/module1700.cpp b/engines/neverhood/modules/module1700.cpp
index 2aeae466ff..e3a5fc3663 100644
--- a/engines/neverhood/modules/module1700.cpp
+++ b/engines/neverhood/modules/module1700.cpp
@@ -20,8 +20,9 @@
*
*/
-#include "neverhood/modules/module1700.h"
#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1700.h"
+#include "neverhood/modules/module1700_sprites.h"
namespace Neverhood {
@@ -126,8 +127,6 @@ void Module1700::updateScene() {
}
}
-// Scene1705
-
static const uint32 kScene1705FileHashes[] = {
0x910EA801, 0x920EA801, 0x940EA801,
0x980EA801, 0x800EA801, 0xB00EA801,
@@ -135,47 +134,6 @@ static const uint32 kScene1705FileHashes[] = {
0xD10EA801, 0x110EA801, 0x910EA800
};
-SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
- : StaticSprite(vm, fileHash, 100) {
-
- _x = _spriteResource.getPosition().x + symbolIndex * 30;
- _y = _spriteResource.getPosition().y + 160;
- updatePosition();
-}
-
-SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
- : StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
-
- if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
- SetMessageHandler(&SsScene1705Tape::handleMessage);
- } else {
- setVisible(false);
- SetMessageHandler(NULL);
- }
- _collisionBoundsOffset = _drawOffset;
- _collisionBoundsOffset.x -= 4;
- _collisionBoundsOffset.y -= 8;
- _collisionBoundsOffset.width += 8;
- _collisionBoundsOffset.height += 16;
- Sprite::updateBounds();
-}
-
-uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(1) {
diff --git a/engines/neverhood/modules/module1700.h b/engines/neverhood/modules/module1700.h
index deb5573f2b..09daff2acf 100644
--- a/engines/neverhood/modules/module1700.h
+++ b/engines/neverhood/modules/module1700.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/smackerscene.h"
namespace Neverhood {
@@ -40,22 +39,6 @@ protected:
void updateScene();
};
-// Scene1705
-
-class SsScene1705WallSymbol : public StaticSprite {
-public:
- SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
-};
-
-class SsScene1705Tape : public StaticSprite {
-public:
- SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 _tapeIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene1705 : public Scene {
public:
Scene1705(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module1700_sprites.cpp b/engines/neverhood/modules/module1700_sprites.cpp
new file mode 100644
index 0000000000..6274e5a8cc
--- /dev/null
+++ b/engines/neverhood/modules/module1700_sprites.cpp
@@ -0,0 +1,156 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1700_sprites.h"
+
+namespace Neverhood {
+
+SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = _spriteResource.getPosition().x + symbolIndex * 30;
+ _y = _spriteResource.getPosition().y + 160;
+ updatePosition();
+}
+
+SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
+
+ if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
+ SetMessageHandler(&SsScene1705Tape::handleMessage);
+ } else {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ _collisionBoundsOffset = _drawOffset;
+ _collisionBoundsOffset.x -= 4;
+ _collisionBoundsOffset.y -= 8;
+ _collisionBoundsOffset.width += 8;
+ _collisionBoundsOffset.height += 16;
+ Sprite::updateBounds();
+}
+
+uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&Klaymen::stFallSkipJump);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter) {
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ }
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0x5E0A4905);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xD86E4477);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1700_sprites.h b/engines/neverhood/modules/module1700_sprites.h
new file mode 100644
index 0000000000..4117de01d9
--- /dev/null
+++ b/engines/neverhood/modules/module1700_sprites.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1700_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1700_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene1705WallSymbol : public StaticSprite {
+public:
+ SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
+};
+
+class SsScene1705Tape : public StaticSprite {
+public:
+ SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _tapeIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1705 : public Klaymen {
+public:
+ KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1700_SPRITES_H */
diff --git a/engines/neverhood/modules/module1800.cpp b/engines/neverhood/modules/module1800.cpp
index b312678467..282292a516 100644
--- a/engines/neverhood/modules/module1800.cpp
+++ b/engines/neverhood/modules/module1800.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module1800.h"
-#include "neverhood/navigationscene.h"
+#include "neverhood/diskplayerscene.h"
#include "neverhood/menumodule.h"
+#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module1800.h"
namespace Neverhood {
diff --git a/engines/neverhood/modules/module1900.cpp b/engines/neverhood/modules/module1900.cpp
index 29c20083f9..a920893755 100644
--- a/engines/neverhood/modules/module1900.cpp
+++ b/engines/neverhood/modules/module1900.cpp
@@ -21,7 +21,7 @@
*/
#include "neverhood/modules/module1900.h"
-#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1900_sprites.h"
namespace Neverhood {
@@ -84,8 +84,6 @@ void Module1900::updateScene() {
}
}
-// Scene1901
-
Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -126,395 +124,6 @@ Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
}
-static const NPoint kAsScene1907SymbolGroundPositions[] = {
- {160, 310}, { 90, 340}, {210, 335},
- {210, 380}, {310, 340}, {290, 400},
- {400, 375}, {370, 435}, {475, 415}
-};
-
-static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
- {275, 125}, {244, 125}, {238, 131},
- {221, 135}, {199, 136}, {168, 149},
- {145, 152}, {123, 154}, {103, 157}
-};
-
-static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
- {275, 299}, {244, 299}, {238, 305},
- {221, 309}, {199, 310}, {168, 323},
- {145, 326}, {123, 328}, {103, 331}
-};
-
-static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
- {275, 136}, {244, 156}, {238, 183},
- {221, 207}, {199, 228}, {168, 262},
- {145, 285}, {123, 307}, {103, 331}
-};
-
-static const uint32 kAsScene1907SymbolFileHashes[] = {
- 0x006A1034, 0x006A1010, 0x006A1814,
- 0x006A1016, 0x006A0014, 0x002A1014,
- 0x00EA1014, 0x206A1014, 0x046A1414
-};
-
-bool AsScene1907Symbol::_plugInFailed = false;
-int AsScene1907Symbol::_plugInTryCount = 0;
-
-AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
- : AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
-
- _plugInFailed = false;
- _plugInTryCount = 0;
-
- if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- _isPluggedIn = true;
- _currPositionIndex = elementIndex;
- if (!getGlobalVar(V_STAIRS_DOWN)) {
- _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
- } else {
- _x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
- }
- createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- _isPluggedIn = false;
- _currPositionIndex = positionIndex;
- loadSound(0, 0x74231924);
- loadSound(1, 0x36691914);
- loadSound(2, 0x5421D806);
- _parentScene->setPositionFree(_currPositionIndex, false);
- _x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
- createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- _newStickFrameIndex = 0;
- }
- _collisionBoundsOffset.set(0, 0, 80, 80);
- Sprite::updateBounds();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
-
-}
-
-void AsScene1907Symbol::update() {
- updateAnim();
- handleSpriteUpdate();
- updatePosition();
- if (_plugInFailed && _plugInTryCount == 0)
- _plugInFailed = false;
-}
-
-uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isPluggedIn && !_plugInFailed) {
- tryToPlugIn();
- messageResult = 1;
- } else
- messageResult = 0;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1907Symbol::suTryToPlugIn() {
- _currStep++;
- _x -= _deltaX;
- _y -= _deltaY;
- if (_currStep == 16) {
- _x -= _smallDeltaX;
- _y -= _smallDeltaY;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::suFallOff() {
- if (_fallOffDelay != 0) {
- _fallOffDelay--;
- } else {
- _y += _yAccel;
- _yAccel += 8;
- if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
- _y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
- stFallOffHitGround();
- }
- }
-}
-
-void AsScene1907Symbol::suFallOffHitGround() {
-
- if (_x == _someX - _xBreak)
- _x -= _smallDeltaX;
- else
- _x -= _deltaX;
-
- if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
- _y -= _someY;
- }
-
- if (_currStep < 8) {
- _y -= _yAccel;
- _yAccel -= 4;
- if (_yAccel < 0)
- _yAccel = 0;
- } else if (_currStep < 15) {
- _y += _yAccel;
- _yAccel += 4;
- } else {
- _y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
- cbFallOffHitGroundEvent();
- }
-
- _currStep++;
-}
-
-void AsScene1907Symbol::suMoveDown() {
- _y += _yIncr;
- if (_yIncr < 11)
- _yIncr++;
- if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
- _y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
- _isMoving = false;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::suMoveUp() {
- _y -= _yIncr;
- if (getGlobalVar(V_WALL_BROKEN)) {
- if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
- _yIncr--;
- else
- _yIncr++;
- } else
- _yIncr = 2;
- if (_yIncr > 9)
- _yIncr = 9;
- else if (_yIncr < 1)
- _yIncr = 1;
- if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
- _y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
- _isMoving = false;
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene1907Symbol::tryToPlugIn() {
- _isPluggedIn = true;
- _plugInTryCount++;
- _newPositionIndex = _parentScene->getNextPosition();
- _parentScene->setPositionFree(_currPositionIndex, true);
- sendMessage(_parentScene, 0x1022, 1100 + _newPositionIndex);
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- SetUpdateHandler(&AsScene1907Symbol::update);
- SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
- SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
- _currStep = 0;
- _deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
- _smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
- _deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
- _smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
- if (_elementIndex == _newPositionIndex) {
- NextState(&AsScene1907Symbol::stPlugIn);
- } else {
- _plugInFailed = true;
- NextState(&AsScene1907Symbol::stPlugInFail);
- }
-}
-
-void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
- _isPluggedIn = false;
- _newPositionIndex = newPositionIndex;
- _fallOffDelay = fallOffDelay;
- _parentScene->setPositionFree(_newPositionIndex, false);
- _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
- _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
- _someX = _x;
- _someY = _y;
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
- _playBackwards = true;
- _newStickFrameIndex = STICK_LAST_FRAME;
- _currStep = 0;
- _yAccel = 1;
- SetUpdateHandler(&AsScene1907Symbol::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
-}
-
-void AsScene1907Symbol::stFallOffHitGround() {
- playSound(1);
- sendMessage(_parentScene, 0x1022, 1000 + _newPositionIndex);
- Entity::_priority = 1000 - _newPositionIndex;
- _parentScene->removeCollisionSprite(this);
- _parentScene->addCollisionSprite(this);
- SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
- NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
- _newStickFrameIndex = 0;
- _currStep = 0;
- _yAccel = 30;
- _deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
- _xBreak = _deltaX * 15;
- _smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
- _someY = 0;
- if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
- _someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
-}
-
-void AsScene1907Symbol::cbFallOffHitGroundEvent() {
- _currPositionIndex = _newPositionIndex;
- if (_plugInTryCount > 0)
- _plugInTryCount--;
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(NULL);
- updateBounds();
- playSound(2);
-}
-
-void AsScene1907Symbol::stPlugIn() {
- playSound(0);
- _currPositionIndex = _newPositionIndex;
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(NULL);
- if (_elementIndex == 8)
- sendMessage(_parentScene, 0x2001, 0);
-}
-
-void AsScene1907Symbol::stPlugInFail() {
- _currPositionIndex = _newPositionIndex;
- stopAnimation();
- _parentScene->plugInFailed();
-}
-
-void AsScene1907Symbol::moveUp() {
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
- _yIncr = 1;
- _isMoving = true;
-}
-
-void AsScene1907Symbol::moveDown() {
- startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
- stopAnimation();
- SetMessageHandler(&AsScene1907Symbol::handleMessage);
- SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
- _yIncr = 4;
- _isMoving = true;
-}
-
-SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
- _countdown1(0) {
-
- loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
- setVisible(false);
- loadSound(0, 0x44061000);
- SetUpdateHandler(&SsScene1907UpDownButton::update);
- SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
- if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- if (getGlobalVar(V_STAIRS_DOWN))
- setToDownPosition();
- else
- setToUpPosition();
- }
-}
-
-void SsScene1907UpDownButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1 == 0)) {
- setVisible(false);
- sendMessage(_parentScene, 0x2000, 0);
- }
-}
-
-uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
- setVisible(true);
- _countdown1 = 4;
- updatePosition();
- playSound(0);
- }
- messageResult = 1;
- }
- return messageResult;
-}
-
-void SsScene1907UpDownButton::setToUpPosition() {
- _y = _spriteResource.getPosition().y;
- updateBounds();
- updatePosition();
-}
-
-void SsScene1907UpDownButton::setToDownPosition() {
- _y = _spriteResource.getPosition().y + 174;
- updateBounds();
- updatePosition();
-}
-
-AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface1(0x110A1061, 1500);
- _x = 320;
- _y = 240;
- startAnimation(0x110A1061, 0, -1);
- _newStickFrameIndex = 0;
- setVisible(false);
- _needRefresh = true;
- AnimatedSprite::updatePosition();
- SetUpdateHandler(&AsScene1907WaterHint::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene1907WaterHint::update() {
- updateAnim();
- updatePosition();
-}
-
-uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene1907WaterHint::show() {
- setVisible(true);
- startAnimation(0x110A1061, 0, -1);
- SetMessageHandler(&AsScene1907WaterHint::hmShowing);
- NextState(&AsScene1907WaterHint::hide);
-}
-
-void AsScene1907WaterHint::hide() {
- stopAnimation();
- setVisible(false);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0),
_moveDownCountdown(0), _moveUpCountdown(0), _countdown3(0), _hasPlugInFailed(false) {
diff --git a/engines/neverhood/modules/module1900.h b/engines/neverhood/modules/module1900.h
index abb5eb1d87..d785c6f506 100644
--- a/engines/neverhood/modules/module1900.h
+++ b/engines/neverhood/modules/module1900.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,80 +40,14 @@ protected:
void updateScene();
};
-// Scene1901
-
class Scene1901 : public Scene {
public:
Scene1901(NeverhoodEngine *vm, Module *parentModule, int which);
};
-// Scene1907
-
-class Scene1907;
-
-class AsScene1907Symbol : public AnimatedSprite {
-public:
- AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
- void moveUp();
- void moveDown();
- void fallOff(int newPositionIndex, int fallOffDelay);
- bool isPluggedIn() { return _isPluggedIn; }
- bool isMoving() { return _isMoving; }
-protected:
- Scene1907 *_parentScene;
- int _elementIndex;
- int _currPositionIndex;
- int _newPositionIndex;
- bool _isPluggedIn;
- bool _isMoving;
- int _someX, _someY;
- int _xBreak;
- int _currStep;
- int _yAccel;
- int _yIncr;
- int _fallOffDelay;
- int _deltaX, _smallDeltaX;
- int _deltaY, _smallDeltaY;
- // Dumb, change if possible
- static bool _plugInFailed;
- static int _plugInTryCount;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender);
- void suTryToPlugIn();
- void suFallOff();
- void suFallOffHitGround();
- void suMoveDown();
- void suMoveUp();
- void tryToPlugIn();
- void stFallOffHitGround();
- void cbFallOffHitGroundEvent();
- void stPlugIn();
- void stPlugInFail();
-};
-
-class AsScene1907WaterHint : public AnimatedSprite {
-public:
- AsScene1907WaterHint(NeverhoodEngine *vm);
- void show();
-protected:
- void update();
- uint32 hmShowing(int messageNum, const MessageParam &param, Entity *sender);
- void hide();
-};
-
-class SsScene1907UpDownButton : public StaticSprite {
-public:
- SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
- void setToUpPosition();
- void setToDownPosition();
-protected:
- Scene1907 *_parentScene;
- AsScene1907Symbol *_asScene1907Symbol;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class AsScene1907Symbol;
+class SsScene1907UpDownButton;
+class AsScene1907WaterHint;
class Scene1907 : public Scene {
public:
diff --git a/engines/neverhood/modules/module1900_sprites.cpp b/engines/neverhood/modules/module1900_sprites.cpp
new file mode 100644
index 0000000000..09c0b132d5
--- /dev/null
+++ b/engines/neverhood/modules/module1900_sprites.cpp
@@ -0,0 +1,456 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module1900.h"
+#include "neverhood/modules/module1900_sprites.h"
+
+namespace Neverhood {
+
+static const NPoint kAsScene1907SymbolGroundPositions[] = {
+ {160, 310}, { 90, 340}, {210, 335},
+ {210, 380}, {310, 340}, {290, 400},
+ {400, 375}, {370, 435}, {475, 415}
+};
+
+static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
+ {275, 125}, {244, 125}, {238, 131},
+ {221, 135}, {199, 136}, {168, 149},
+ {145, 152}, {123, 154}, {103, 157}
+};
+
+static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
+ {275, 299}, {244, 299}, {238, 305},
+ {221, 309}, {199, 310}, {168, 323},
+ {145, 326}, {123, 328}, {103, 331}
+};
+
+static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
+ {275, 136}, {244, 156}, {238, 183},
+ {221, 207}, {199, 228}, {168, 262},
+ {145, 285}, {123, 307}, {103, 331}
+};
+
+static const uint32 kAsScene1907SymbolFileHashes[] = {
+ 0x006A1034, 0x006A1010, 0x006A1814,
+ 0x006A1016, 0x006A0014, 0x002A1014,
+ 0x00EA1014, 0x206A1014, 0x046A1414
+};
+
+bool AsScene1907Symbol::_plugInFailed = false;
+int AsScene1907Symbol::_plugInTryCount = 0;
+
+AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
+ : AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
+
+ _plugInFailed = false;
+ _plugInTryCount = 0;
+
+ if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ _isPluggedIn = true;
+ _currPositionIndex = elementIndex;
+ if (!getGlobalVar(V_STAIRS_DOWN)) {
+ _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
+ } else {
+ _x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
+ }
+ createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ _isPluggedIn = false;
+ _currPositionIndex = positionIndex;
+ loadSound(0, 0x74231924);
+ loadSound(1, 0x36691914);
+ loadSound(2, 0x5421D806);
+ _parentScene->setPositionFree(_currPositionIndex, false);
+ _x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
+ createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ _collisionBoundsOffset.set(0, 0, 80, 80);
+ Sprite::updateBounds();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+
+}
+
+void AsScene1907Symbol::update() {
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+ if (_plugInFailed && _plugInTryCount == 0)
+ _plugInFailed = false;
+}
+
+uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isPluggedIn && !_plugInFailed) {
+ tryToPlugIn();
+ messageResult = 1;
+ } else
+ messageResult = 0;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1907Symbol::suTryToPlugIn() {
+ _currStep++;
+ _x -= _deltaX;
+ _y -= _deltaY;
+ if (_currStep == 16) {
+ _x -= _smallDeltaX;
+ _y -= _smallDeltaY;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::suFallOff() {
+ if (_fallOffDelay != 0) {
+ _fallOffDelay--;
+ } else {
+ _y += _yAccel;
+ _yAccel += 8;
+ if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
+ _y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
+ stFallOffHitGround();
+ }
+ }
+}
+
+void AsScene1907Symbol::suFallOffHitGround() {
+
+ if (_x == _someX - _xBreak)
+ _x -= _smallDeltaX;
+ else
+ _x -= _deltaX;
+
+ if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
+ _y -= _someY;
+ }
+
+ if (_currStep < 8) {
+ _y -= _yAccel;
+ _yAccel -= 4;
+ if (_yAccel < 0)
+ _yAccel = 0;
+ } else if (_currStep < 15) {
+ _y += _yAccel;
+ _yAccel += 4;
+ } else {
+ _y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
+ cbFallOffHitGroundEvent();
+ }
+
+ _currStep++;
+}
+
+void AsScene1907Symbol::suMoveDown() {
+ _y += _yIncr;
+ if (_yIncr < 11)
+ _yIncr++;
+ if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
+ _y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
+ _isMoving = false;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::suMoveUp() {
+ _y -= _yIncr;
+ if (getGlobalVar(V_WALL_BROKEN)) {
+ if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
+ _yIncr--;
+ else
+ _yIncr++;
+ } else
+ _yIncr = 2;
+ if (_yIncr > 9)
+ _yIncr = 9;
+ else if (_yIncr < 1)
+ _yIncr = 1;
+ if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
+ _y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
+ _isMoving = false;
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene1907Symbol::tryToPlugIn() {
+ _isPluggedIn = true;
+ _plugInTryCount++;
+ _newPositionIndex = _parentScene->getNextPosition();
+ _parentScene->setPositionFree(_currPositionIndex, true);
+ sendMessage(_parentScene, 0x1022, 1100 + _newPositionIndex);
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ SetUpdateHandler(&AsScene1907Symbol::update);
+ SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
+ SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
+ _currStep = 0;
+ _deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
+ _smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
+ _deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
+ _smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
+ if (_elementIndex == _newPositionIndex) {
+ NextState(&AsScene1907Symbol::stPlugIn);
+ } else {
+ _plugInFailed = true;
+ NextState(&AsScene1907Symbol::stPlugInFail);
+ }
+}
+
+void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
+ _isPluggedIn = false;
+ _newPositionIndex = newPositionIndex;
+ _fallOffDelay = fallOffDelay;
+ _parentScene->setPositionFree(_newPositionIndex, false);
+ _x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
+ _y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
+ _someX = _x;
+ _someY = _y;
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
+ _playBackwards = true;
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _currStep = 0;
+ _yAccel = 1;
+ SetUpdateHandler(&AsScene1907Symbol::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
+}
+
+void AsScene1907Symbol::stFallOffHitGround() {
+ playSound(1);
+ sendMessage(_parentScene, 0x1022, 1000 + _newPositionIndex);
+ Entity::_priority = 1000 - _newPositionIndex;
+ _parentScene->removeCollisionSprite(this);
+ _parentScene->addCollisionSprite(this);
+ SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
+ NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
+ _newStickFrameIndex = 0;
+ _currStep = 0;
+ _yAccel = 30;
+ _deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
+ _xBreak = _deltaX * 15;
+ _smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
+ _someY = 0;
+ if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
+ _someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
+}
+
+void AsScene1907Symbol::cbFallOffHitGroundEvent() {
+ _currPositionIndex = _newPositionIndex;
+ if (_plugInTryCount > 0)
+ _plugInTryCount--;
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(NULL);
+ updateBounds();
+ playSound(2);
+}
+
+void AsScene1907Symbol::stPlugIn() {
+ playSound(0);
+ _currPositionIndex = _newPositionIndex;
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(NULL);
+ if (_elementIndex == 8)
+ sendMessage(_parentScene, 0x2001, 0);
+}
+
+void AsScene1907Symbol::stPlugInFail() {
+ _currPositionIndex = _newPositionIndex;
+ stopAnimation();
+ _parentScene->plugInFailed();
+}
+
+void AsScene1907Symbol::moveUp() {
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
+ _yIncr = 1;
+ _isMoving = true;
+}
+
+void AsScene1907Symbol::moveDown() {
+ startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
+ stopAnimation();
+ SetMessageHandler(&AsScene1907Symbol::handleMessage);
+ SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
+ _yIncr = 4;
+ _isMoving = true;
+}
+
+SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
+ _countdown1(0) {
+
+ loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
+ setVisible(false);
+ loadSound(0, 0x44061000);
+ SetUpdateHandler(&SsScene1907UpDownButton::update);
+ SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
+ if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ if (getGlobalVar(V_STAIRS_DOWN))
+ setToDownPosition();
+ else
+ setToUpPosition();
+ }
+}
+
+void SsScene1907UpDownButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+}
+
+uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
+ setVisible(true);
+ _countdown1 = 4;
+ updatePosition();
+ playSound(0);
+ }
+ messageResult = 1;
+ }
+ return messageResult;
+}
+
+void SsScene1907UpDownButton::setToUpPosition() {
+ _y = _spriteResource.getPosition().y;
+ updateBounds();
+ updatePosition();
+}
+
+void SsScene1907UpDownButton::setToDownPosition() {
+ _y = _spriteResource.getPosition().y + 174;
+ updateBounds();
+ updatePosition();
+}
+
+AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface1(0x110A1061, 1500);
+ _x = 320;
+ _y = 240;
+ startAnimation(0x110A1061, 0, -1);
+ _newStickFrameIndex = 0;
+ setVisible(false);
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+ SetUpdateHandler(&AsScene1907WaterHint::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene1907WaterHint::update() {
+ updateAnim();
+ updatePosition();
+}
+
+uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1907WaterHint::show() {
+ setVisible(true);
+ startAnimation(0x110A1061, 0, -1);
+ SetMessageHandler(&AsScene1907WaterHint::hmShowing);
+ NextState(&AsScene1907WaterHint::hide);
+}
+
+void AsScene1907WaterHint::hide() {
+ stopAnimation();
+ setVisible(false);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1900_sprites.h b/engines/neverhood/modules/module1900_sprites.h
new file mode 100644
index 0000000000..7e57b11618
--- /dev/null
+++ b/engines/neverhood/modules/module1900_sprites.h
@@ -0,0 +1,107 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1900_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1900_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class Scene1907;
+
+class AsScene1907Symbol : public AnimatedSprite {
+public:
+ AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
+ void moveUp();
+ void moveDown();
+ void fallOff(int newPositionIndex, int fallOffDelay);
+ bool isPluggedIn() { return _isPluggedIn; }
+ bool isMoving() { return _isMoving; }
+protected:
+ Scene1907 *_parentScene;
+ int _elementIndex;
+ int _currPositionIndex;
+ int _newPositionIndex;
+ bool _isPluggedIn;
+ bool _isMoving;
+ int _someX, _someY;
+ int _xBreak;
+ int _currStep;
+ int _yAccel;
+ int _yIncr;
+ int _fallOffDelay;
+ int _deltaX, _smallDeltaX;
+ int _deltaY, _smallDeltaY;
+ // Dumb, change if possible
+ static bool _plugInFailed;
+ static int _plugInTryCount;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmTryToPlugIn(int messageNum, const MessageParam &param, Entity *sender);
+ void suTryToPlugIn();
+ void suFallOff();
+ void suFallOffHitGround();
+ void suMoveDown();
+ void suMoveUp();
+ void tryToPlugIn();
+ void stFallOffHitGround();
+ void cbFallOffHitGroundEvent();
+ void stPlugIn();
+ void stPlugInFail();
+};
+
+class AsScene1907WaterHint : public AnimatedSprite {
+public:
+ AsScene1907WaterHint(NeverhoodEngine *vm);
+ void show();
+protected:
+ void update();
+ uint32 hmShowing(int messageNum, const MessageParam &param, Entity *sender);
+ void hide();
+};
+
+class SsScene1907UpDownButton : public StaticSprite {
+public:
+ SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
+ void setToUpPosition();
+ void setToDownPosition();
+protected:
+ Scene1907 *_parentScene;
+ AsScene1907Symbol *_asScene1907Symbol;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene1901 : public Klaymen {
+public:
+ KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1900_SPRITES_H */
diff --git a/engines/neverhood/modules/module2000.cpp b/engines/neverhood/modules/module2000.cpp
index fcccdefbdd..3364f60f8b 100644
--- a/engines/neverhood/modules/module2000.cpp
+++ b/engines/neverhood/modules/module2000.cpp
@@ -21,8 +21,7 @@
*/
#include "neverhood/modules/module2000.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module2000_sprites.h"
namespace Neverhood {
diff --git a/engines/neverhood/modules/module2000.h b/engines/neverhood/modules/module2000.h
index fa62f9a70e..8dc72c57dc 100644
--- a/engines/neverhood/modules/module2000.h
+++ b/engines/neverhood/modules/module2000.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,8 +40,6 @@ protected:
void updateScene();
};
-// Scene2001
-
class Scene2001 : public Scene {
public:
Scene2001(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2000_sprites.cpp b/engines/neverhood/modules/module2000_sprites.cpp
new file mode 100644
index 0000000000..c9c1481aa7
--- /dev/null
+++ b/engines/neverhood/modules/module2000_sprites.cpp
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2000_sprites.h"
+
+namespace Neverhood {
+
+KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xBE68CC54);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x18AB4ED4);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2000_sprites.h b/engines/neverhood/modules/module2000_sprites.h
new file mode 100644
index 0000000000..ca84aa73ca
--- /dev/null
+++ b/engines/neverhood/modules/module2000_sprites.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class KmScene2001 : public Klaymen {
+public:
+ KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2000_SPRITES_H */
diff --git a/engines/neverhood/modules/module2100.cpp b/engines/neverhood/modules/module2100.cpp
index bcff9d9d1b..db7258b066 100644
--- a/engines/neverhood/modules/module2100.cpp
+++ b/engines/neverhood/modules/module2100.cpp
@@ -20,9 +20,9 @@
*
*/
+#include "neverhood/modules/module1200_sprites.h"
#include "neverhood/modules/module2100.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module2100_sprites.h"
namespace Neverhood {
@@ -74,125 +74,6 @@ void Module2100::updateScene() {
}
}
-// Scene2101
-
-AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(100, 328, 347);
- _x = 320;
- _y = 240;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2101Door::handleMessage);
- if (isOpen) {
- startAnimation(0x0C202B9C, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else
- setVisible(false);
-}
-
-uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- stOpenDoor();
- break;
- case 0x4809:
- stCloseDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene2101Door::stOpenDoor() {
- startAnimation(0x0C202B9C, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorOpen32"));
-}
-
-void AsScene2101Door::stCloseDoor() {
- startAnimation(0xC222A8D4, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- setVisible(true);
- playSound(0, calcHash("fxDoorClose32"));
- NextState(&AsScene2101Door::stCloseDoorDone);
-}
-
-void AsScene2101Door::stCloseDoorDone() {
- stopAnimation();
- setVisible(false);
-}
-
-AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
- : AnimatedSprite(vm, 1400), _klaymen(klaymen) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
- createSurface(1200, 88, 165);
- setVisible(false);
-}
-
-uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- _x = _klaymen->getX();
- _y = _klaymen->getY() - 132;
- startAnimation(0x0422255A, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
- : StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
- _fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
-
- SetUpdateHandler(&SsCommonFloorButton::update);
- SetMessageHandler(&SsCommonFloorButton::handleMessage);
- if (_soundFileHash == 0)
- _soundFileHash = 0x44141000;
- createSurface(1010, 61, 30);
- if (_fileHash1)
- loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- else
- setVisible(false);
-}
-
-void SsCommonFloorButton::update() {
- if (_countdown != 0 && (--_countdown == 0)) {
- sendMessage(_parentScene, 0x1022, 1010);
- if (_fileHash1)
- loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
- else
- setVisible(false);
- }
-}
-
-uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x480B:
- sendMessage(_parentScene, 0x480B, 0);
- setVisible(true);
- sendMessage(_parentScene, 0x1022, 990);
- loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
- _countdown = 16;
- playSound(0, _soundFileHash);
- break;
- }
- return messageResult;
-}
-
Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
diff --git a/engines/neverhood/modules/module2100.h b/engines/neverhood/modules/module2100.h
index d76bed0780..c5256434d9 100644
--- a/engines/neverhood/modules/module2100.h
+++ b/engines/neverhood/modules/module2100.h
@@ -40,38 +40,6 @@ protected:
void updateScene();
};
-// Scene1901
-
-class AsScene2101Door : public AnimatedSprite {
-public:
- AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
- void stCloseDoorDone();
-};
-
-class AsScene2101HitByDoorEffect : public AnimatedSprite {
-public:
- AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
-protected:
- Sprite *_klaymen;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsCommonFloorButton : public StaticSprite {
-public:
- SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
-protected:
- Scene *_parentScene;
- uint32 _soundFileHash;
- uint32 _fileHash1, _fileHash2;
- int16 _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2101 : public Scene {
public:
Scene2101(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2100_sprites.cpp b/engines/neverhood/modules/module2100_sprites.cpp
new file mode 100644
index 0000000000..707ebe342f
--- /dev/null
+++ b/engines/neverhood/modules/module2100_sprites.cpp
@@ -0,0 +1,260 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2100_sprites.h"
+
+namespace Neverhood {
+
+AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface(100, 328, 347);
+ _x = 320;
+ _y = 240;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2101Door::handleMessage);
+ if (isOpen) {
+ startAnimation(0x0C202B9C, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else
+ setVisible(false);
+}
+
+uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ stOpenDoor();
+ break;
+ case 0x4809:
+ stCloseDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2101Door::stOpenDoor() {
+ startAnimation(0x0C202B9C, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorOpen32"));
+}
+
+void AsScene2101Door::stCloseDoor() {
+ startAnimation(0xC222A8D4, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ setVisible(true);
+ playSound(0, calcHash("fxDoorClose32"));
+ NextState(&AsScene2101Door::stCloseDoorDone);
+}
+
+void AsScene2101Door::stCloseDoorDone() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
+ : AnimatedSprite(vm, 1400), _klaymen(klaymen) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
+ createSurface(1200, 88, 165);
+ setVisible(false);
+}
+
+uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ _x = _klaymen->getX();
+ _y = _klaymen->getY() - 132;
+ startAnimation(0x0422255A, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
+ : StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
+ _fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
+
+ SetUpdateHandler(&SsCommonFloorButton::update);
+ SetMessageHandler(&SsCommonFloorButton::handleMessage);
+ if (_soundFileHash == 0)
+ _soundFileHash = 0x44141000;
+ createSurface(1010, 61, 30);
+ if (_fileHash1)
+ loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ else
+ setVisible(false);
+}
+
+void SsCommonFloorButton::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ sendMessage(_parentScene, 0x1022, 1010);
+ if (_fileHash1)
+ loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
+ else
+ setVisible(false);
+ }
+}
+
+uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x480B:
+ sendMessage(_parentScene, 0x480B, 0);
+ setVisible(true);
+ sendMessage(_parentScene, 0x1022, 990);
+ loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
+ _countdown = 16;
+ playSound(0, _soundFileHash);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4811:
+ GotoState(&KmScene2101::stHitByDoor);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xFF290E30);
+ break;
+ case 0x483E:
+ teleporterDisappear(0x9A28CA1C);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene2101::hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ int16 speedUpFrameIndex;
+ switch (messageNum) {
+ case 0x1008:
+ speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
+ if (_currFrameIndex < speedUpFrameIndex) {
+ startAnimation(0x35AA8059, speedUpFrameIndex, -1);
+ _y = 438;
+ }
+ messageResult = 0;
+ break;
+ case 0x100D:
+ if (param.asInteger() == 0x1A1A0785) {
+ playSound(0, 0x40F0A342);
+ } else if (param.asInteger() == 0x60428026) {
+ playSound(0, 0x40608A59);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2101::stHitByDoor() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x35AA8059, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2101::hmHitByDoor);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ playSound(0, 0x402E82D4);
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2100_sprites.h b/engines/neverhood/modules/module2100_sprites.h
new file mode 100644
index 0000000000..85a6b9f27d
--- /dev/null
+++ b/engines/neverhood/modules/module2100_sprites.h
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2100_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2100_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene2101Door : public AnimatedSprite {
+public:
+ AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+ void stCloseDoorDone();
+};
+
+class AsScene2101HitByDoorEffect : public AnimatedSprite {
+public:
+ AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
+protected:
+ Sprite *_klaymen;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsCommonFloorButton : public StaticSprite {
+public:
+ SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
+protected:
+ Scene *_parentScene;
+ uint32 _soundFileHash;
+ uint32 _fileHash1, _fileHash2;
+ int16 _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2101 : public Klaymen {
+public:
+ KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+
+ void stHitByDoor();
+ uint32 hmHitByDoor(int messageNum, const MessageParam &param, Entity *sender);
+
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2100_SPRITES_H */
diff --git a/engines/neverhood/modules/module2200.cpp b/engines/neverhood/modules/module2200.cpp
index 99f21cad74..745af42f72 100644
--- a/engines/neverhood/modules/module2200.cpp
+++ b/engines/neverhood/modules/module2200.cpp
@@ -20,11 +20,12 @@
*
*/
-#include "neverhood/modules/module2200.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/gamemodule.h"
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module2200.h"
+#include "neverhood/modules/module2200_sprites.h"
namespace Neverhood {
@@ -445,95 +446,6 @@ void Module2200::createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId)
_childObject = new HallOfRecordsScene(_vm, this, which, hallOfRecordsInfoId);
}
-// Scene2201
-
-AsScene2201CeilingFan::AsScene2201CeilingFan(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- _x = 403;
- _y = 259;
- createSurface(100, 233, 96);
- startAnimation(0x8600866, 0, -1);
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
-
- _x = 408;
- _y = 290;
- createSurface(900, 63, 266);
- SetUpdateHandler(&AsScene2201Door::update);
- SetMessageHandler(&AsScene2201Door::handleMessage);
- if (_isOpen) {
- startAnimation(0xE2CB0412, -1, -1);
- _countdown = 48;
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(0xE2CB0412, 0, -1);
- _newStickFrameIndex = 0;
- _ssDoorLight->setVisible(false);
- }
-}
-
-void AsScene2201Door::update() {
- if (_countdown != 0 && _isOpen && (--_countdown == 0))
- stCloseDoor();
- AnimatedSprite::update();
-}
-
-uint32 AsScene2201Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x11001090) {
- if (_isOpen)
- _ssDoorLight->setVisible(true);
- } else if (param.asInteger() == 0x11283090) {
- if (!_isOpen)
- _ssDoorLight->setVisible(false);
- }
- break;
- case 0x2000:
- if (_isOpen)
- _countdown = 144;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 144;
- if (!_isOpen)
- stOpenDoor();
- break;
- }
- return messageResult;
-}
-
-void AsScene2201Door::stOpenDoor() {
- _isOpen = true;
- startAnimation(0xE2CB0412, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen33"));
-}
-
-void AsScene2201Door::stCloseDoor() {
- _isOpen = false;
- startAnimation(0xE2CB0412, -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
- playSound(0, calcHash("fxDoorClose33"));
-}
-
-SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex)
- : StaticSprite(vm, 900) {
-
- createSurface(100, 16, 16);
- loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0,
- kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y);
-}
-
Scene2201::Scene2201(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isSoundPlaying(false) {
@@ -661,215 +573,6 @@ uint32 Scene2201::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-static const NPoint kSsScene2202PuzzleCubePoints[] = {
- {196, 105}, {323, 102}, {445, 106},
- {192, 216}, {319, 220}, {446, 216},
- {188, 320}, {319, 319}, {443, 322}
-};
-
-static const uint32 kSsScene2202PuzzleCubeFileHashes1[] = {
- 0xA500800C, 0x2182910C, 0x2323980C,
- 0x23049084, 0x21008080, 0x2303900C,
- 0x6120980C, 0x2504D808
-};
-
-static const uint32 kSsScene2202PuzzleCubeFileHashes2[] = {
- 0x0AAD8080, 0x0A290291, 0x0A2BA398,
- 0x822B8490, 0x86298080, 0x0A2B8390,
- 0x0A69A098, 0x0E2D84D8
-};
-
-SsScene2202PuzzleCube::SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol)
- : StaticSprite(vm, 900), _parentScene(parentScene), _cubeSymbol(cubeSymbol), _cubePosition(cubePosition), _isMoving(false) {
-
- int surfacePriority;
-
- SetUpdateHandler(&SsScene2202PuzzleCube::update);
- SetMessageHandler(&SsScene2202PuzzleCube::handleMessage);
- if (_cubePosition >= 0 && _cubePosition <= 2)
- surfacePriority = 100;
- else if (_cubePosition >= 3 && _cubePosition <= 5)
- surfacePriority = 300;
- else
- surfacePriority = 500;
- debug(1, "TODO: Unused SurfacePriority: %d", surfacePriority);
- loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset | kSLFSetPosition | kSLFDefCollisionBoundsOffset, 0,
- kSsScene2202PuzzleCubePoints[_cubePosition].x, kSsScene2202PuzzleCubePoints[_cubePosition].y);
- loadSound(0, 0x40958621);
- loadSound(1, 0x51108241);
-}
-
-void SsScene2202PuzzleCube::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isMoving && !getGlobalVar(V_TILE_PUZZLE_SOLVED))
- sendMessage(_parentScene, 0x2000, _cubePosition);
- messageResult = 1;
- break;
- case 0x2001:
- _isMoving = true;
- moveCube(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-void SsScene2202PuzzleCube::suMoveCubeX() {
-
- bool done = false;
-
- if (_counterDirection) {
- if (_counter > 2)
- _counter -= 2;
- } else {
- if (_counter < 20)
- _counter += 2;
- }
-
- for (int16 i = 0; i < _counter; i++) {
- _x += _xIncr;
- _errValue += _yDelta;
- if (_errValue >= _xDelta) {
- _errValue -= _xDelta;
- _y += _yIncr;
- }
- if (_x == _newX && _y == _newY) {
- done = true;
- break;
- }
- if (_x == _xFlagPos)
- _counterDirection = true;
- }
-
- if (done)
- stopMoving();
-
- updateBounds();
-
-}
-
-void SsScene2202PuzzleCube::suMoveCubeY() {
-
- bool done = false;
-
- if (_counterDirection) {
- if (_counter > 2)
- _counter -= 2;
- } else {
- if (_counter < 20)
- _counter += 2;
- }
-
- for (int16 i = 0; i < _counter; i++) {
- _y += _yIncr;
- _errValue += _xDelta;
- if (_errValue >= _yDelta) {
- _errValue -= _yDelta;
- _x += _xIncr;
- }
- if (_x == _newX && _y == _newY) {
- done = true;
- break;
- }
- if (_x == _xFlagPos)
- _counterDirection = true;
- }
-
- if (done)
- stopMoving();
-
- updateBounds();
-
-}
-
-void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
-
- loadSprite(kSsScene2202PuzzleCubeFileHashes1[_cubeSymbol], kSLFCenteredDrawOffset);
-
- setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
- setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
-
- _cubePosition = newCubePosition;
- _errValue = 0;
- _counterDirection = false;
- _counter = 0;
- _newX = kSsScene2202PuzzleCubePoints[newCubePosition].x;
- _newY = kSsScene2202PuzzleCubePoints[newCubePosition].y;
-
- if (_x == _newX && _y == _newY)
- return;
-
- if (_x <= _newX) {
- if (_y <= _newY) {
- _xDelta = _newX - _x;
- _yDelta = _newY - _y;
- _xIncr = 1;
- _yIncr = 1;
- } else {
- _xDelta = _newX - _x;
- _yDelta = _y - _newY;
- _xIncr = 1;
- _yIncr = -1;
- }
- } else {
- if (_y <= _newY) {
- _xDelta = _x - _newX;
- _yDelta = _newY - _y;
- _xIncr = -1;
- _yIncr = 1;
- } else {
- _xDelta = _x - _newX;
- _yDelta = _y - _newY;
- _xIncr = -1;
- _yIncr = -1;
- }
- }
-
- if (_xDelta > _yDelta) {
- SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeX);
- if (_xIncr > 0) {
- if (_newX - _x >= 180)
- _xFlagPos = _newX - 90;
- else
- _xFlagPos = _x + _newX / 2;
- } else {
- if (_x - _newX >= 180)
- _xFlagPos = _x + 90;
- else
- _xFlagPos = _x / 2 + _newX;
- }
- playSound(0);
- } else {
- SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeY);
- if (_yIncr > 0) {
- if (_newY - _y >= 180)
- _xFlagPos = _newY - 90;
- else
- _xFlagPos = _y + _newY / 2;
- } else {
- if (_y - _newY >= 180)
- _xFlagPos = _y + 90;
- else
- _xFlagPos = _y / 2 + _newY;
- }
- playSound(1);
- }
-
-}
-
-void SsScene2202PuzzleCube::stopMoving() {
- loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset);
- SetSpriteUpdate(NULL);
- _isMoving = false;
- sendMessage(_parentScene, 0x2002, _cubePosition);
-}
-
Scene2202::Scene2202(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isSolved(false), _leaveScene(false), _isCubeMoving(false),
_ssMovingCube(NULL), _ssDoneMovingCube(NULL) {
@@ -991,100 +694,6 @@ bool Scene2202::testIsSolved() {
getSubVar(VA_CUBE_POSITIONS, 8) == 7;
}
-static const uint32 kAsCommonKeyFileHashes[] = {
- 0x2450D850, 0x0C9CE8D0, 0x2C58A152
-};
-
-AsCommonKey::AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y)
- : AnimatedSprite(vm, kAsCommonKeyFileHashes[keyIndex], surfacePriority, x, y), _parentScene(parentScene), _keyIndex(keyIndex) {
-
- if (!getSubVar(VA_HAS_KEY, _keyIndex) && !getSubVar(VA_IS_KEY_INSERTED, _keyIndex)) {
- SetMessageHandler(&AsCommonKey::handleMessage);
- } else {
- // If Klaymen already has the key or it's already inserted then don't show it
- setVisible(false);
- SetMessageHandler(NULL);
- }
-}
-
-uint32 AsCommonKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setSubVar(VA_HAS_KEY, _keyIndex, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- }
- return messageResult;
-}
-
-static const uint32 kAsScene2203DoorFileHashes[] = {
- 0x7868AE10, 0x1A488110
-};
-
-AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _doorIndex(doorIndex) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2203Door::handleMessage);
- _x = 320;
- _y = 240;
- createSurface1(kAsScene2203DoorFileHashes[_doorIndex], 900);
- if (getGlobalVar(V_LARGE_DOOR_NUMBER) == _doorIndex) {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 0, -1);
- _newStickFrameIndex = 0;
- }
-}
-
-uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
- sendMessage(_parentScene, 0x2002, 0);
- else
- sendMessage(_parentScene, 0x2001, 0);
- messageResult = 1;
- break;
- case 0x2000:
- _otherDoor = (Sprite*)param.asEntity();
- break;
- case 0x3002:
- if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
- sendMessage(_parentScene, 0x4808, 0);
- stopAnimation();
- break;
- case 0x4808:
- setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
- sendMessage(_otherDoor, 0x4809, 0);
- openDoor();
- break;
- case 0x4809:
- closeDoor();
- sendMessage(_parentScene, 0x2003, 0);
- break;
- }
- return messageResult;
-}
-
-void AsScene2203Door::openDoor() {
- playSound(0, 0x341014C4);
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 1, -1);
-}
-
-void AsScene2203Door::closeDoor() {
- startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
- _playBackwards = true;
- _newStickFrameIndex = 0;
-}
-
Scene2203::Scene2203(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1197,24 +806,6 @@ uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-SsScene2205DoorFrame::SsScene2205DoorFrame(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- SetMessageHandler(&SsScene2205DoorFrame::handleMessage);
- createSurface(1100, 45, 206);
- loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
-}
-
-uint32 SsScene2205DoorFrame::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
- break;
- }
- return messageResult;
-}
-
Scene2205::Scene2205(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1325,134 +916,6 @@ static const int16 kScene2206XPositions[] = {
384, 480, 572
};
-static const uint32 kScene2206MessageIds1[] = {
- 0x004B8998, 0x004B89B8, 0x004B89D8
-};
-
-static const uint32 kScene2206MessageIds2[] = {
- 0x004B89F8, 0x004B8A20, 0x004B8A48
-};
-
-static const int16 kAsScene2206DoorSpikesXDeltasOpen[] = {
- -24, -28, -18, 6, 9, -8
-};
-
-static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
- -8, 7, 11, 26, 13, 14
-};
-
-AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, fileHash, 200) {
-
- if (getGlobalVar(V_SPIKES_RETRACTED))
- _x -= 63;
- SetUpdateHandler(&AsScene2206DoorSpikes::update);
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene2206DoorSpikes::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene2206DoorSpikes::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4808:
- _deltaIndex = 0;
- playSound(0, 0x032746E0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
- break;
- case 0x4809:
- _deltaIndex = 0;
- playSound(0, 0x002642C0);
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206DoorSpikes::suClose);
- break;
- }
- return messageResult;
-}
-
-void AsScene2206DoorSpikes::suOpen() {
- if (_deltaIndex < 6) {
- _x += kAsScene2206DoorSpikesXDeltasOpen[_deltaIndex];
- _deltaIndex++;
- } else {
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-void AsScene2206DoorSpikes::suClose() {
- if (_deltaIndex < 6) {
- _x += kAsScene2206DoorSpikesXDeltasClose[_deltaIndex];
- _deltaIndex++;
- } else {
- SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
- SetSpriteUpdate(NULL);
- }
-}
-
-AsScene2206Platform::AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, fileHash, 50) {
-
- SetUpdateHandler(&AsScene2206Platform::update);
- SetMessageHandler(&AsScene2206Platform::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-void AsScene2206Platform::update() {
- handleSpriteUpdate();
- updatePosition();
-}
-
-uint32 AsScene2206Platform::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4803:
- _yDelta = 0;
- SetMessageHandler(NULL);
- SetSpriteUpdate(&AsScene2206Platform::suMoveDown);
- break;
- }
- return messageResult;
-}
-
-void AsScene2206Platform::suMoveDown() {
- _yDelta++;
- _y += _yDelta;
-}
-
-SsScene2206TestTube::SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash)
- : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene) {
-
- if (getGlobalVar(V_HAS_TEST_TUBE)) {
- setVisible(false);
- SetMessageHandler(NULL);
- } else
- SetMessageHandler(&SsScene2206TestTube::handleMessage);
- _collisionBoundsOffset = _drawOffset;
- updateBounds();
-}
-
-uint32 SsScene2206TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x4806:
- setGlobalVar(V_HAS_TEST_TUBE, 1);
- setVisible(false);
- SetMessageHandler(NULL);
- break;
- }
- return messageResult;
-}
-
Scene2206::Scene2206(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1597,6 +1060,14 @@ void Scene2206::klaymenBehindSpikes() {
_klaymen->setClipRect(_sprite2->getDrawRect().x, 0, _sprite3->getDrawRect().x2(), _sprite1->getDrawRect().y2());
}
+static const uint32 kScene2206MessageIds1[] = {
+ 0x004B8998, 0x004B89B8, 0x004B89D8
+};
+
+static const uint32 kScene2206MessageIds2[] = {
+ 0x004B89F8, 0x004B8A20, 0x004B8A48
+};
+
void Scene2206::readClickedColumn() {
setGlobalVar(V_CLICKED_COLUMN_INDEX, (_mouseClickPos.x - 354) / 96);
if (getGlobalVar(V_CLICKED_COLUMN_INDEX) > 2)
@@ -1617,317 +1088,6 @@ static const uint32 kScene2207FileHashes[] = {
0x3BB1E12E, 0x23B1E12E, 0x13B1E12E
};
-AsScene2207Elevator::AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 900), _parentScene(parentScene), _pointIndex(0), _destPointIndex(0), _destPointIndexDelta(0) {
-
- NPoint pt;
-
- _dataResource.load(0x00524846);
- _pointArray = _dataResource.getPointArray(0x005B02B7);
- pt = _dataResource.getPoint(0x403A82B1);
- _x = pt.x;
- _y = pt.y;
- createSurface(1100, 129, 103);
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, 0, 0);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2207Elevator::update);
- SetMessageHandler(&AsScene2207Elevator::handleMessage);
- SetSpriteUpdate(&AsScene2207Elevator::suSetPosition);
-}
-
-AsScene2207Elevator::~AsScene2207Elevator() {
- _vm->_soundMan->deleteSoundGroup(0x02700413);
-}
-
-void AsScene2207Elevator::update() {
-
- if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
- _pointIndex++;
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
- if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
- if (_destPointIndexDelta != 0)
- _destPointIndexDelta = 0;
- else {
- _vm->_soundMan->deleteSound(0xD3B02847);
- playSound(0, 0x53B8284A);
- }
- }
- }
-
- if (_destPointIndex + _destPointIndexDelta < _pointIndex) {
- _pointIndex--;
- if (_pointIndex == 0)
- sendMessage(_parentScene, 0x2003, 0);
- startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
- _newStickFrameIndex = _pointIndex;
- if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
- if (_destPointIndexDelta != 0)
- _destPointIndexDelta = 0;
- else {
- _vm->_soundMan->deleteSound(0xD3B02847);
- playSound(0, 0x53B8284A);
- }
- }
- }
-
- if (_pointIndex > 20 && _surface->getPriority() != 900)
- sendMessage(_parentScene, 0x2002, 900);
- else if (_pointIndex < 20 && _surface->getPriority() != 1100)
- sendMessage(_parentScene, 0x2002, 1100);
-
- AnimatedSprite::update();
-
- if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) {
- sendMessage(_parentScene, 0x2004, 0);
- _isMoving = false;
- }
-
-}
-
-void AsScene2207Elevator::suSetPosition() {
- _x = (*_pointArray)[_pointIndex].x;
- _y = (*_pointArray)[_pointIndex].y - 60;
- updateBounds();
-}
-
-uint32 AsScene2207Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- moveToY(param.asInteger());
- break;
- }
- return messageResult;
-}
-
-void AsScene2207Elevator::moveToY(int16 y) {
- int16 minDistance = 480;
-
- if (!_pointArray || _pointArray->size() == 0)
- return;
-
- for (uint i = 0; i < _pointArray->size(); i++) {
- int16 distance = ABS(y - (*_pointArray)[i].y);
- if (distance < minDistance) {
- minDistance = distance;
- _destPointIndex = i;
- }
- }
-
- if (_destPointIndex != _pointIndex) {
- if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1)
- _destPointIndexDelta = 0;
- else if (_destPointIndex < _pointIndex)
- _destPointIndexDelta = -2;
- else
- _destPointIndexDelta = 2;
- _vm->_soundMan->addSound(0x02700413, 0xD3B02847);
- _vm->_soundMan->playSoundLooping(0xD3B02847);
- }
-
- _isMoving = true;
-
-}
-
-AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- _x = x;
- _y = y;
- createSurface(1010, 71, 73);
- setDoDeltaX(doDeltaX);
- startAnimation(0x80880090, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207Lever::handleMessage);
-}
-
-uint32 AsScene2207Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x4826, 0);
- messageResult = 1;
- break;
- case 0x3002:
- gotoNextState();
- stopAnimation();
- break;
- case 0x4807:
- stLeverUp();
- break;
- case 0x480F:
- stLeverDown();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-void AsScene2207Lever::stLeverDown() {
- startAnimation(0x80880090, 1, -1);
- playSound(0, 0x40581882);
- FinalizeState(&AsScene2207Lever::stLeverDownEvent);
-}
-
-void AsScene2207Lever::stLeverDownEvent() {
- sendMessage(_parentScene, 0x480F, 0);
-}
-
-void AsScene2207Lever::stLeverUp() {
- startAnimation(0x80880090, 6, -1);
- _playBackwards = true;
- playSound(0, 0x40581882);
- FinalizeState(&AsScene2207Lever::stLeverUpEvent);
-}
-
-void AsScene2207Lever::stLeverUpEvent() {
- sendMessage(_parentScene, 0x4807, 0);
-}
-
-AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1200), _idle(true) {
-
- _x = 309;
- _y = 320;
- createSurface1(0xCCFD6090, 100);
- startAnimation(0xCCFD6090, 0, -1);
- _newStickFrameIndex = 0;
- loadSound(1, 0x40330872);
- loadSound(2, 0x72A2914A);
- loadSound(3, 0xD4226080);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207WallRobotAnimation::handleMessage);
-}
-
-AsScene2207WallRobotAnimation::~AsScene2207WallRobotAnimation() {
- _vm->_soundMan->deleteSoundGroup(0x80D00820);
-}
-
-uint32 AsScene2207WallRobotAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (!_idle) {
- if (param.asInteger() == 0x3423093) {
- _vm->_soundMan->addSound(0x80D00820, 0x12121943);
- _vm->_soundMan->playSoundLooping(0x12121943);
- } else if (param.asInteger() == 0x834AB011) {
- stopSound(0);
- stopSound(1);
- stopSound(2);
- stopSound(3);
- _vm->_soundMan->deleteSound(0x12121943);
- } else if (param.asInteger() == 0x3A980501)
- playSound(1);
- else if (param.asInteger() == 0x2A2AD498)
- playSound(2);
- else if (param.asInteger() == 0xC4980008)
- playSound(3);
- else if (param.asInteger() == 0x06B84228)
- playSound(0, 0xE0702146);
- }
- break;
- case 0x2006:
- stStartAnimation();
- break;
- case 0x2007:
- stStopAnimation();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2207WallRobotAnimation::stStartAnimation() {
- if (!_idle) {
- NextState(NULL);
- } else {
- startAnimation(0xCCFD6090, 0, -1);
- _idle = false;
- setVisible(true);
- }
-}
-
-void AsScene2207WallRobotAnimation::stStopAnimation() {
- NextState(&AsScene2207WallRobotAnimation::cbStopAnimation);
-}
-
-void AsScene2207WallRobotAnimation::cbStopAnimation() {
- stopAnimation();
- stopSound(0);
- stopSound(1);
- stopSound(2);
- stopSound(3);
- _vm->_soundMan->deleteSound(0x12121943);
- _idle = true;
- setVisible(false);
-}
-
-AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _idle(true) {
-
- _x = 309;
- _y = 320;
- createSurface1(0x8CAA0099, 100);
- startAnimation(0x8CAA0099, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2207WallCannonAnimation::handleMessage);
-}
-
-uint32 AsScene2207WallCannonAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2006:
- stStartAnimation();
- break;
- case 0x2007:
- stStopAnimation();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2207WallCannonAnimation::stStartAnimation() {
- if (!_idle) {
- NextState(NULL);
- } else {
- setVisible(true);
- startAnimation(0x8CAA0099, 0, -1);
- _idle = false;
- }
-}
-
-void AsScene2207WallCannonAnimation::stStopAnimation() {
- NextState(&AsScene2207WallCannonAnimation::cbStopAnimation);
-}
-
-void AsScene2207WallCannonAnimation::cbStopAnimation() {
- stopAnimation();
- setVisible(false);
- _idle = true;
-}
-
-SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index)
- : StaticSprite(vm, fileHash, 100) {
-
- _x = 330;
- _y = 246 + index * 50;
- updatePosition();
-}
-
Scene2207::Scene2207(NeverhoodEngine *vm, Module *parentModule)
: Scene(vm, parentModule), _klaymenAtElevator(true), _elevatorSurfacePriority(0) {
diff --git a/engines/neverhood/modules/module2200.h b/engines/neverhood/modules/module2200.h
index 5c19f2a818..6b414304ae 100644
--- a/engines/neverhood/modules/module2200.h
+++ b/engines/neverhood/modules/module2200.h
@@ -31,8 +31,6 @@
namespace Neverhood {
-// Module2200
-
class Module2200 : public Module {
public:
Module2200(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -44,43 +42,6 @@ protected:
void createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId);
};
-// Scene2201
-
-static const NPoint kSsScene2201PuzzleCubePoints[] = {
- {305, 305}, {321, 305}, {336, 305}, {305, 319},
- {321, 319}, {336, 319}, {305, 332}, {321, 332},
- {336, 333}
-};
-
-static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
- 0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
- 0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
-};
-
-class AsScene2201CeilingFan : public AnimatedSprite {
-public:
- AsScene2201CeilingFan(NeverhoodEngine *vm);
-};
-
-class AsScene2201Door : public AnimatedSprite {
-public:
- AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
-protected:
- Klaymen *_klaymen;
- Sprite *_ssDoorLight;
- bool _isOpen;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stOpenDoor();
- void stCloseDoor();
-};
-
-class SsScene2201PuzzleCube : public StaticSprite {
-public:
- SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
-};
-
class Scene2201 : public Scene {
public:
Scene2201(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -96,30 +57,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2202PuzzleCube : public StaticSprite {
-public:
- SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
-protected:
- Scene *_parentScene;
- int16 _cubeSymbol;
- int16 _cubePosition;
- int16 _newX, _newY;
- int16 _xDelta, _yDelta;
- int16 _xIncr;
- int16 _yIncr;
- int16 _errValue;
- int16 _counter;
- int16 _xFlagPos;
- bool _counterDirection;
- bool _isMoving;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveCubeX();
- void suMoveCubeY();
- void moveCube(int16 newCubePosition);
- void stopMoving();
-};
-
class Scene2202 : public Scene {
public:
Scene2202(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -138,27 +75,6 @@ protected:
bool testIsSolved();
};
-class AsCommonKey : public AnimatedSprite {
-public:
- AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
-protected:
- Scene *_parentScene;
- int _keyIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2203Door : public AnimatedSprite {
-public:
- AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
-protected:
- Scene *_parentScene;
- Sprite *_otherDoor;
- uint _doorIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void openDoor();
- void closeDoor();
-};
-
class Scene2203 : public Scene {
public:
Scene2203(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -175,12 +91,7 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2205DoorFrame : public StaticSprite {
-public:
- SsScene2205DoorFrame(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsCommonPressButton;
class Scene2205 : public Scene {
public:
@@ -194,35 +105,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2206DoorSpikes : public StaticSprite {
-public:
- AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
-protected:
- int _deltaIndex;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suOpen();
- void suClose();
-};
-
-class AsScene2206Platform : public StaticSprite {
-public:
- AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
-protected:
- int16 _yDelta;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveDown();
-};
-
-class SsScene2206TestTube : public StaticSprite {
-public:
- SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2206 : public Scene {
public:
Scene2206(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -241,62 +123,6 @@ protected:
void readClickedColumn();
};
-class AsScene2207Elevator : public AnimatedSprite {
-public:
- AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
- ~AsScene2207Elevator();
-protected:
- Scene *_parentScene;
- NPointArray *_pointArray;
- int16 _pointIndex;
- int16 _destPointIndex, _destPointIndexDelta;
- bool _isMoving;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suSetPosition();
- void moveToY(int16 y);
-};
-
-class AsScene2207Lever : public AnimatedSprite {
-public:
- AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stLeverDown();
- void stLeverDownEvent();
- void stLeverUp();
- void stLeverUpEvent();
-};
-
-class AsScene2207WallRobotAnimation : public AnimatedSprite {
-public:
- AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
- ~AsScene2207WallRobotAnimation();
-protected:
- bool _idle;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stStartAnimation();
- void stStopAnimation();
- void cbStopAnimation();
-};
-
-class AsScene2207WallCannonAnimation : public AnimatedSprite {
-public:
- AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
-protected:
- bool _idle;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stStartAnimation();
- void stStopAnimation();
- void cbStopAnimation();
-};
-
-class SsScene2207Symbol : public StaticSprite {
-public:
- SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
-};
-
class Scene2207 : public Scene {
public:
Scene2207(NeverhoodEngine *vm, Module *parentModule);
diff --git a/engines/neverhood/modules/module2200_sprites.cpp b/engines/neverhood/modules/module2200_sprites.cpp
new file mode 100644
index 0000000000..30f0404cf1
--- /dev/null
+++ b/engines/neverhood/modules/module2200_sprites.cpp
@@ -0,0 +1,1429 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2200_sprites.h"
+
+namespace Neverhood {
+
+AsScene2201CeilingFan::AsScene2201CeilingFan(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ _x = 403;
+ _y = 259;
+ createSurface(100, 233, 96);
+ startAnimation(0x8600866, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+AsScene2201Door::AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _ssDoorLight(ssDoorLight), _countdown(0), _isOpen(isOpen) {
+
+ _x = 408;
+ _y = 290;
+ createSurface(900, 63, 266);
+ SetUpdateHandler(&AsScene2201Door::update);
+ SetMessageHandler(&AsScene2201Door::handleMessage);
+ if (_isOpen) {
+ startAnimation(0xE2CB0412, -1, -1);
+ _countdown = 48;
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = 0;
+ _ssDoorLight->setVisible(false);
+ }
+}
+
+void AsScene2201Door::update() {
+ if (_countdown != 0 && _isOpen && (--_countdown == 0))
+ stCloseDoor();
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2201Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x11001090) {
+ if (_isOpen)
+ _ssDoorLight->setVisible(true);
+ } else if (param.asInteger() == 0x11283090) {
+ if (!_isOpen)
+ _ssDoorLight->setVisible(false);
+ }
+ break;
+ case 0x2000:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 144;
+ if (!_isOpen)
+ stOpenDoor();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2201Door::stOpenDoor() {
+ _isOpen = true;
+ startAnimation(0xE2CB0412, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen33"));
+}
+
+void AsScene2201Door::stCloseDoor() {
+ _isOpen = false;
+ startAnimation(0xE2CB0412, -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+ playSound(0, calcHash("fxDoorClose33"));
+}
+
+SsScene2201PuzzleCube::SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex)
+ : StaticSprite(vm, 900) {
+
+ createSurface(100, 16, 16);
+ loadSprite(kSsScene2201PuzzleCubeFileHashes[cubeIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 0,
+ kSsScene2201PuzzleCubePoints[positionIndex].x, kSsScene2201PuzzleCubePoints[positionIndex].y);
+}
+
+static const NPoint kSsScene2202PuzzleCubePoints[] = {
+ {196, 105}, {323, 102}, {445, 106},
+ {192, 216}, {319, 220}, {446, 216},
+ {188, 320}, {319, 319}, {443, 322}
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes1[] = {
+ 0xA500800C, 0x2182910C, 0x2323980C,
+ 0x23049084, 0x21008080, 0x2303900C,
+ 0x6120980C, 0x2504D808
+};
+
+static const uint32 kSsScene2202PuzzleCubeFileHashes2[] = {
+ 0x0AAD8080, 0x0A290291, 0x0A2BA398,
+ 0x822B8490, 0x86298080, 0x0A2B8390,
+ 0x0A69A098, 0x0E2D84D8
+};
+
+SsScene2202PuzzleCube::SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _cubeSymbol(cubeSymbol), _cubePosition(cubePosition), _isMoving(false) {
+
+ int surfacePriority;
+
+ SetUpdateHandler(&SsScene2202PuzzleCube::update);
+ SetMessageHandler(&SsScene2202PuzzleCube::handleMessage);
+ if (_cubePosition >= 0 && _cubePosition <= 2)
+ surfacePriority = 100;
+ else if (_cubePosition >= 3 && _cubePosition <= 5)
+ surfacePriority = 300;
+ else
+ surfacePriority = 500;
+ debug(1, "TODO: Unused SurfacePriority: %d", surfacePriority);
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset | kSLFSetPosition | kSLFDefCollisionBoundsOffset, 0,
+ kSsScene2202PuzzleCubePoints[_cubePosition].x, kSsScene2202PuzzleCubePoints[_cubePosition].y);
+ loadSound(0, 0x40958621);
+ loadSound(1, 0x51108241);
+}
+
+void SsScene2202PuzzleCube::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 SsScene2202PuzzleCube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isMoving && !getGlobalVar(V_TILE_PUZZLE_SOLVED))
+ sendMessage(_parentScene, 0x2000, _cubePosition);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _isMoving = true;
+ moveCube(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene2202PuzzleCube::suMoveCubeX() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _x += _xIncr;
+ _errValue += _yDelta;
+ if (_errValue >= _xDelta) {
+ _errValue -= _xDelta;
+ _y += _yIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::suMoveCubeY() {
+
+ bool done = false;
+
+ if (_counterDirection) {
+ if (_counter > 2)
+ _counter -= 2;
+ } else {
+ if (_counter < 20)
+ _counter += 2;
+ }
+
+ for (int16 i = 0; i < _counter; i++) {
+ _y += _yIncr;
+ _errValue += _xDelta;
+ if (_errValue >= _yDelta) {
+ _errValue -= _yDelta;
+ _x += _xIncr;
+ }
+ if (_x == _newX && _y == _newY) {
+ done = true;
+ break;
+ }
+ if (_x == _xFlagPos)
+ _counterDirection = true;
+ }
+
+ if (done)
+ stopMoving();
+
+ updateBounds();
+
+}
+
+void SsScene2202PuzzleCube::moveCube(int16 newCubePosition) {
+
+ loadSprite(kSsScene2202PuzzleCubeFileHashes1[_cubeSymbol], kSLFCenteredDrawOffset);
+
+ setSubVar(VA_CUBE_POSITIONS, _cubePosition, (uint32)-1);
+ setSubVar(VA_CUBE_POSITIONS, newCubePosition, (uint32)_cubeSymbol);
+
+ _cubePosition = newCubePosition;
+ _errValue = 0;
+ _counterDirection = false;
+ _counter = 0;
+ _newX = kSsScene2202PuzzleCubePoints[newCubePosition].x;
+ _newY = kSsScene2202PuzzleCubePoints[newCubePosition].y;
+
+ if (_x == _newX && _y == _newY)
+ return;
+
+ if (_x <= _newX) {
+ if (_y <= _newY) {
+ _xDelta = _newX - _x;
+ _yDelta = _newY - _y;
+ _xIncr = 1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _newX - _x;
+ _yDelta = _y - _newY;
+ _xIncr = 1;
+ _yIncr = -1;
+ }
+ } else {
+ if (_y <= _newY) {
+ _xDelta = _x - _newX;
+ _yDelta = _newY - _y;
+ _xIncr = -1;
+ _yIncr = 1;
+ } else {
+ _xDelta = _x - _newX;
+ _yDelta = _y - _newY;
+ _xIncr = -1;
+ _yIncr = -1;
+ }
+ }
+
+ if (_xDelta > _yDelta) {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeX);
+ if (_xIncr > 0) {
+ if (_newX - _x >= 180)
+ _xFlagPos = _newX - 90;
+ else
+ _xFlagPos = _x + _newX / 2;
+ } else {
+ if (_x - _newX >= 180)
+ _xFlagPos = _x + 90;
+ else
+ _xFlagPos = _x / 2 + _newX;
+ }
+ playSound(0);
+ } else {
+ SetSpriteUpdate(&SsScene2202PuzzleCube::suMoveCubeY);
+ if (_yIncr > 0) {
+ if (_newY - _y >= 180)
+ _xFlagPos = _newY - 90;
+ else
+ _xFlagPos = _y + _newY / 2;
+ } else {
+ if (_y - _newY >= 180)
+ _xFlagPos = _y + 90;
+ else
+ _xFlagPos = _y / 2 + _newY;
+ }
+ playSound(1);
+ }
+
+}
+
+void SsScene2202PuzzleCube::stopMoving() {
+ loadSprite(kSsScene2202PuzzleCubeFileHashes2[_cubeSymbol], kSLFCenteredDrawOffset);
+ SetSpriteUpdate(NULL);
+ _isMoving = false;
+ sendMessage(_parentScene, 0x2002, _cubePosition);
+}
+
+static const uint32 kAsCommonKeyFileHashes[] = {
+ 0x2450D850, 0x0C9CE8D0, 0x2C58A152
+};
+
+AsCommonKey::AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, kAsCommonKeyFileHashes[keyIndex], surfacePriority, x, y), _parentScene(parentScene), _keyIndex(keyIndex) {
+
+ if (!getSubVar(VA_HAS_KEY, _keyIndex) && !getSubVar(VA_IS_KEY_INSERTED, _keyIndex)) {
+ SetMessageHandler(&AsCommonKey::handleMessage);
+ } else {
+ // If Klaymen already has the key or it's already inserted then don't show it
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 AsCommonKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setSubVar(VA_HAS_KEY, _keyIndex, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ return messageResult;
+}
+
+static const uint32 kAsScene2203DoorFileHashes[] = {
+ 0x7868AE10, 0x1A488110
+};
+
+AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _doorIndex(doorIndex) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2203Door::handleMessage);
+ _x = 320;
+ _y = 240;
+ createSurface1(kAsScene2203DoorFileHashes[_doorIndex], 900);
+ if (getGlobalVar(V_LARGE_DOOR_NUMBER) == _doorIndex) {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 0, -1);
+ _newStickFrameIndex = 0;
+ }
+}
+
+uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, 0x2002, 0);
+ else
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case 0x2000:
+ _otherDoor = (Sprite*)param.asEntity();
+ break;
+ case 0x3002:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, 0x4808, 0);
+ stopAnimation();
+ break;
+ case 0x4808:
+ setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
+ sendMessage(_otherDoor, 0x4809, 0);
+ openDoor();
+ break;
+ case 0x4809:
+ closeDoor();
+ sendMessage(_parentScene, 0x2003, 0);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2203Door::openDoor() {
+ playSound(0, 0x341014C4);
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], 1, -1);
+}
+
+void AsScene2203Door::closeDoor() {
+ startAnimation(kAsScene2203DoorFileHashes[_doorIndex], -1, -1);
+ _playBackwards = true;
+ _newStickFrameIndex = 0;
+}
+
+SsScene2205DoorFrame::SsScene2205DoorFrame(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ SetMessageHandler(&SsScene2205DoorFrame::handleMessage);
+ createSurface(1100, 45, 206);
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+}
+
+uint32 SsScene2205DoorFrame::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ loadSprite(getGlobalVar(V_LIGHTS_ON) ? 0x24306227 : 0xD90032A0, kSLFDefDrawOffset | kSLFDefPosition);
+ break;
+ }
+ return messageResult;
+}
+
+static const int16 kAsScene2206DoorSpikesXDeltasOpen[] = {
+ -24, -28, -18, 6, 9, -8
+};
+
+static const int16 kAsScene2206DoorSpikesXDeltasClose[] = {
+ -8, 7, 11, 26, 13, 14
+};
+
+AsScene2206DoorSpikes::AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 200) {
+
+ if (getGlobalVar(V_SPIKES_RETRACTED))
+ _x -= 63;
+ SetUpdateHandler(&AsScene2206DoorSpikes::update);
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206DoorSpikes::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206DoorSpikes::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4808:
+ _deltaIndex = 0;
+ playSound(0, 0x032746E0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
+ break;
+ case 0x4809:
+ _deltaIndex = 0;
+ playSound(0, 0x002642C0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suClose);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206DoorSpikes::suOpen() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasOpen[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void AsScene2206DoorSpikes::suClose() {
+ if (_deltaIndex < 6) {
+ _x += kAsScene2206DoorSpikesXDeltasClose[_deltaIndex];
+ _deltaIndex++;
+ } else {
+ SetMessageHandler(&AsScene2206DoorSpikes::handleMessage);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+AsScene2206Platform::AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, fileHash, 50) {
+
+ SetUpdateHandler(&AsScene2206Platform::update);
+ SetMessageHandler(&AsScene2206Platform::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+void AsScene2206Platform::update() {
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene2206Platform::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4803:
+ _yDelta = 0;
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206Platform::suMoveDown);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2206Platform::suMoveDown() {
+ _yDelta++;
+ _y += _yDelta;
+}
+
+SsScene2206TestTube::SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority), _parentScene(parentScene) {
+
+ if (getGlobalVar(V_HAS_TEST_TUBE)) {
+ setVisible(false);
+ SetMessageHandler(NULL);
+ } else
+ SetMessageHandler(&SsScene2206TestTube::handleMessage);
+ _collisionBoundsOffset = _drawOffset;
+ updateBounds();
+}
+
+uint32 SsScene2206TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setGlobalVar(V_HAS_TEST_TUBE, 1);
+ setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2207Elevator::AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _pointIndex(0), _destPointIndex(0), _destPointIndexDelta(0) {
+
+ NPoint pt;
+
+ _dataResource.load(0x00524846);
+ _pointArray = _dataResource.getPointArray(0x005B02B7);
+ pt = _dataResource.getPoint(0x403A82B1);
+ _x = pt.x;
+ _y = pt.y;
+ createSurface(1100, 129, 103);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, 0, 0);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2207Elevator::update);
+ SetMessageHandler(&AsScene2207Elevator::handleMessage);
+ SetSpriteUpdate(&AsScene2207Elevator::suSetPosition);
+}
+
+AsScene2207Elevator::~AsScene2207Elevator() {
+ _vm->_soundMan->deleteSoundGroup(0x02700413);
+}
+
+void AsScene2207Elevator::update() {
+
+ if (_destPointIndex + _destPointIndexDelta > _pointIndex) {
+ _pointIndex++;
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_destPointIndex + _destPointIndexDelta < _pointIndex) {
+ _pointIndex--;
+ if (_pointIndex == 0)
+ sendMessage(_parentScene, 0x2003, 0);
+ startAnimation(getGlobalVar(V_LIGHTS_ON) ? 0xC858CC19 : 0x294B3377, _pointIndex, _pointIndex);
+ _newStickFrameIndex = _pointIndex;
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex) {
+ if (_destPointIndexDelta != 0)
+ _destPointIndexDelta = 0;
+ else {
+ _vm->_soundMan->deleteSound(0xD3B02847);
+ playSound(0, 0x53B8284A);
+ }
+ }
+ }
+
+ if (_pointIndex > 20 && _surface->getPriority() != 900)
+ sendMessage(_parentScene, 0x2002, 900);
+ else if (_pointIndex < 20 && _surface->getPriority() != 1100)
+ sendMessage(_parentScene, 0x2002, 1100);
+
+ AnimatedSprite::update();
+
+ if (_destPointIndex + _destPointIndexDelta == _pointIndex && _isMoving) {
+ sendMessage(_parentScene, 0x2004, 0);
+ _isMoving = false;
+ }
+
+}
+
+void AsScene2207Elevator::suSetPosition() {
+ _x = (*_pointArray)[_pointIndex].x;
+ _y = (*_pointArray)[_pointIndex].y - 60;
+ updateBounds();
+}
+
+uint32 AsScene2207Elevator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ moveToY(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Elevator::moveToY(int16 y) {
+ int16 minDistance = 480;
+
+ if (!_pointArray || _pointArray->size() == 0)
+ return;
+
+ for (uint i = 0; i < _pointArray->size(); i++) {
+ int16 distance = ABS(y - (*_pointArray)[i].y);
+ if (distance < minDistance) {
+ minDistance = distance;
+ _destPointIndex = i;
+ }
+ }
+
+ if (_destPointIndex != _pointIndex) {
+ if (_destPointIndex == 0 || _destPointIndex == (int)_pointArray->size() - 1)
+ _destPointIndexDelta = 0;
+ else if (_destPointIndex < _pointIndex)
+ _destPointIndexDelta = -2;
+ else
+ _destPointIndexDelta = 2;
+ _vm->_soundMan->addSound(0x02700413, 0xD3B02847);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+
+ _isMoving = true;
+
+}
+
+AsScene2207Lever::AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ _x = x;
+ _y = y;
+ createSurface(1010, 71, 73);
+ setDoDeltaX(doDeltaX);
+ startAnimation(0x80880090, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207Lever::handleMessage);
+}
+
+uint32 AsScene2207Lever::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case 0x3002:
+ gotoNextState();
+ stopAnimation();
+ break;
+ case 0x4807:
+ stLeverUp();
+ break;
+ case 0x480F:
+ stLeverDown();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Lever::stLeverDown() {
+ startAnimation(0x80880090, 1, -1);
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverDownEvent);
+}
+
+void AsScene2207Lever::stLeverDownEvent() {
+ sendMessage(_parentScene, 0x480F, 0);
+}
+
+void AsScene2207Lever::stLeverUp() {
+ startAnimation(0x80880090, 6, -1);
+ _playBackwards = true;
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverUpEvent);
+}
+
+void AsScene2207Lever::stLeverUpEvent() {
+ sendMessage(_parentScene, 0x4807, 0);
+}
+
+AsScene2207WallRobotAnimation::AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0xCCFD6090, 100);
+ startAnimation(0xCCFD6090, 0, -1);
+ _newStickFrameIndex = 0;
+ loadSound(1, 0x40330872);
+ loadSound(2, 0x72A2914A);
+ loadSound(3, 0xD4226080);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallRobotAnimation::handleMessage);
+}
+
+AsScene2207WallRobotAnimation::~AsScene2207WallRobotAnimation() {
+ _vm->_soundMan->deleteSoundGroup(0x80D00820);
+}
+
+uint32 AsScene2207WallRobotAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (!_idle) {
+ if (param.asInteger() == 0x3423093) {
+ _vm->_soundMan->addSound(0x80D00820, 0x12121943);
+ _vm->_soundMan->playSoundLooping(0x12121943);
+ } else if (param.asInteger() == 0x834AB011) {
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ } else if (param.asInteger() == 0x3A980501)
+ playSound(1);
+ else if (param.asInteger() == 0x2A2AD498)
+ playSound(2);
+ else if (param.asInteger() == 0xC4980008)
+ playSound(3);
+ else if (param.asInteger() == 0x06B84228)
+ playSound(0, 0xE0702146);
+ }
+ break;
+ case 0x2006:
+ stStartAnimation();
+ break;
+ case 0x2007:
+ stStopAnimation();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallRobotAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ startAnimation(0xCCFD6090, 0, -1);
+ _idle = false;
+ setVisible(true);
+ }
+}
+
+void AsScene2207WallRobotAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallRobotAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallRobotAnimation::cbStopAnimation() {
+ stopAnimation();
+ stopSound(0);
+ stopSound(1);
+ stopSound(2);
+ stopSound(3);
+ _vm->_soundMan->deleteSound(0x12121943);
+ _idle = true;
+ setVisible(false);
+}
+
+AsScene2207WallCannonAnimation::AsScene2207WallCannonAnimation(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _idle(true) {
+
+ _x = 309;
+ _y = 320;
+ createSurface1(0x8CAA0099, 100);
+ startAnimation(0x8CAA0099, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2207WallCannonAnimation::handleMessage);
+}
+
+uint32 AsScene2207WallCannonAnimation::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2006:
+ stStartAnimation();
+ break;
+ case 0x2007:
+ stStopAnimation();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207WallCannonAnimation::stStartAnimation() {
+ if (!_idle) {
+ NextState(NULL);
+ } else {
+ setVisible(true);
+ startAnimation(0x8CAA0099, 0, -1);
+ _idle = false;
+ }
+}
+
+void AsScene2207WallCannonAnimation::stStopAnimation() {
+ NextState(&AsScene2207WallCannonAnimation::cbStopAnimation);
+}
+
+void AsScene2207WallCannonAnimation::cbStopAnimation() {
+ stopAnimation();
+ setVisible(false);
+ _idle = true;
+}
+
+SsScene2207Symbol::SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = 330;
+ _y = 246 + index * 50;
+ updatePosition();
+}
+
+KmScene2201::KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+ _dataResource.load(0x04104242);
+}
+
+uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2203::KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4819:
+ GotoState(&KmScene2203::stClayDoorOpen);
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2203::stClayDoorOpen() {
+ if (!stStartAction(AnimationCallback(&KmScene2203::stClayDoorOpen))) {
+ _busyStatus = 2;
+ _acceptInput = false;
+ startAnimation(0x5CCCB330, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2203::hmClayDoorOpen);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ }
+}
+
+uint32 KmScene2203::hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x040D4186) {
+ sendMessage(_attachedSprite, 0x4808, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2205::KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2205::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2205::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2206::KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _walkResumeFrameIncr = 1;
+ _vm->_soundMan->addSound(0x80101800, 0xD3B02847);
+}
+
+KmScene2206::~KmScene2206() {
+ _vm->_soundMan->deleteSoundGroup(0x80101800);
+}
+
+void KmScene2206::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2206::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&KmScene2206::stRidePlatformDown);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+void KmScene2206::suRidePlatformDown() {
+ _platformDeltaY++;
+ _y += _platformDeltaY;
+ if (_y > 600)
+ sendMessage(this, 0x1019, 0);
+}
+
+void KmScene2206::stRidePlatformDown() {
+ if (!stStartActionFromIdle(AnimationCallback(&KmScene2206::stRidePlatformDown))) {
+ _busyStatus = 1;
+ sendMessage(_parentScene, 0x4803, 0);
+ _acceptInput = false;
+ _platformDeltaY = 0;
+ startAnimation(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&Klaymen::hmLowLevel);
+ SetSpriteUpdate(&KmScene2206::suRidePlatformDown);
+ _vm->_soundMan->playSoundLooping(0xD3B02847);
+ }
+}
+
+KmScene2207::KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2207::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x2001:
+ GotoState(&Klaymen::stRidePlatform);
+ break;
+ case 0x2005:
+ suRidePlatform();
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stInteractLever);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x4827:
+ GotoState(&Klaymen::stReleaseLever);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+KmScene2242::KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2242::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2242::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmHallOfRecords::KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+ // Empty
+}
+
+void KmHallOfRecords::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmHallOfRecords::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2247::KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+void KmScene2247::xUpdate() {
+ setGlobalVar(V_KLAYMEN_FRAMEINDEX, _currFrameIndex);
+}
+
+uint32 KmScene2247::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2200_sprites.h b/engines/neverhood/modules/module2200_sprites.h
new file mode 100644
index 0000000000..9aaf3b6aae
--- /dev/null
+++ b/engines/neverhood/modules/module2200_sprites.h
@@ -0,0 +1,275 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2200_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2200_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/graphics.h"
+
+namespace Neverhood {
+
+static const NPoint kSsScene2201PuzzleCubePoints[] = {
+ {305, 305}, {321, 305}, {336, 305}, {305, 319},
+ {321, 319}, {336, 319}, {305, 332}, {321, 332},
+ {336, 333}
+};
+
+static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
+ 0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
+ 0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
+};
+
+class AsScene2201CeilingFan : public AnimatedSprite {
+public:
+ AsScene2201CeilingFan(NeverhoodEngine *vm);
+};
+
+class AsScene2201Door : public AnimatedSprite {
+public:
+ AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
+protected:
+ Klaymen *_klaymen;
+ Sprite *_ssDoorLight;
+ bool _isOpen;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stOpenDoor();
+ void stCloseDoor();
+};
+
+class SsScene2201PuzzleCube : public StaticSprite {
+public:
+ SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
+};
+
+class SsScene2202PuzzleCube : public StaticSprite {
+public:
+ SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
+protected:
+ Scene *_parentScene;
+ int16 _cubeSymbol;
+ int16 _cubePosition;
+ int16 _newX, _newY;
+ int16 _xDelta, _yDelta;
+ int16 _xIncr;
+ int16 _yIncr;
+ int16 _errValue;
+ int16 _counter;
+ int16 _xFlagPos;
+ bool _counterDirection;
+ bool _isMoving;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveCubeX();
+ void suMoveCubeY();
+ void moveCube(int16 newCubePosition);
+ void stopMoving();
+};
+
+class AsCommonKey : public AnimatedSprite {
+public:
+ AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
+protected:
+ Scene *_parentScene;
+ int _keyIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2203Door : public AnimatedSprite {
+public:
+ AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
+protected:
+ Scene *_parentScene;
+ Sprite *_otherDoor;
+ uint _doorIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void openDoor();
+ void closeDoor();
+};
+
+class SsScene2205DoorFrame : public StaticSprite {
+public:
+ SsScene2205DoorFrame(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2206DoorSpikes : public StaticSprite {
+public:
+ AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
+protected:
+ int _deltaIndex;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suOpen();
+ void suClose();
+};
+
+class AsScene2206Platform : public StaticSprite {
+public:
+ AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
+protected:
+ int16 _yDelta;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveDown();
+};
+
+class SsScene2206TestTube : public StaticSprite {
+public:
+ SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2207Elevator : public AnimatedSprite {
+public:
+ AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
+ ~AsScene2207Elevator();
+protected:
+ Scene *_parentScene;
+ NPointArray *_pointArray;
+ int16 _pointIndex;
+ int16 _destPointIndex, _destPointIndexDelta;
+ bool _isMoving;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suSetPosition();
+ void moveToY(int16 y);
+};
+
+class AsScene2207Lever : public AnimatedSprite {
+public:
+ AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stLeverDown();
+ void stLeverDownEvent();
+ void stLeverUp();
+ void stLeverUpEvent();
+};
+
+class AsScene2207WallRobotAnimation : public AnimatedSprite {
+public:
+ AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
+ ~AsScene2207WallRobotAnimation();
+protected:
+ bool _idle;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartAnimation();
+ void stStopAnimation();
+ void cbStopAnimation();
+};
+
+class AsScene2207WallCannonAnimation : public AnimatedSprite {
+public:
+ AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
+protected:
+ bool _idle;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stStartAnimation();
+ void stStopAnimation();
+ void cbStopAnimation();
+};
+
+class SsScene2207Symbol : public StaticSprite {
+public:
+ SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
+};
+
+class KmScene2201 : public Klaymen {
+public:
+ KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2203 : public Klaymen {
+public:
+ KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stClayDoorOpen();
+ uint32 hmClayDoorOpen(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2205 : public Klaymen {
+public:
+ KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2206 : public Klaymen {
+public:
+ KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+ ~KmScene2206();
+protected:
+ void stRidePlatformDown();
+ void suRidePlatformDown();
+
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2207 : public Klaymen {
+public:
+ KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2242 : public Klaymen {
+public:
+ KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmHallOfRecords : public Klaymen {
+public:
+ KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2247 : public Klaymen {
+public:
+ KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void xUpdate();
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2200_SPRITES_H */
diff --git a/engines/neverhood/modules/module2300.cpp b/engines/neverhood/modules/module2300.cpp
index 2a46df1ee2..689d53570f 100644
--- a/engines/neverhood/modules/module2300.cpp
+++ b/engines/neverhood/modules/module2300.cpp
@@ -20,8 +20,8 @@
*
*/
-#include "neverhood/modules/module2300.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module2300.h"
namespace Neverhood {
diff --git a/engines/neverhood/modules/module2400.cpp b/engines/neverhood/modules/module2400.cpp
index 21ea390ba2..dab39b24f6 100644
--- a/engines/neverhood/modules/module2400.cpp
+++ b/engines/neverhood/modules/module2400.cpp
@@ -20,7 +20,13 @@
*
*/
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
#include "neverhood/modules/module2400.h"
+#include "neverhood/modules/module2100_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module2400_sprites.h"
+#include "neverhood/modules/module2800_sprites.h"
namespace Neverhood {
@@ -175,198 +181,6 @@ static const NRect kScene2401Rects[] = {
{ 465, 331, 491, 389 }
};
-static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
- 0x5C044690, 0x5C644690, 0x5CA44690,
- 0x5D244690, 0x5E244690
-};
-
-static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
- 0xF4418408, 0xF4418808, 0xF4419008,
- 0xF441A008, 0xCD4F8411
-};
-
-AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- _x = 240;
- _y = 447;
- createSurface(100, 146, 74);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
-}
-
-uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x120A0013)
- playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
- break;
- case 0x2000:
- _x = 240;
- _y = 447;
- _soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
- startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
- setVisible(true);
- playSound(0, 0x48640244);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
-
- _x = 88;
- _y = 421;
- createSurface1(0x10203116, 100);
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
-}
-
-AsScene2401FlowingWater::~AsScene2401FlowingWater() {
- _vm->_soundMan->deleteSoundGroup(0x40F11C09);
-}
-
-uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_isWaterFlowing && param.asInteger() == 0x02421405)
- startAnimationByHash(0x10203116, 0x01084280, 0);
- break;
- case 0x2002:
- if (!_isWaterFlowing) {
- _vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
- _vm->_soundMan->playSoundLooping(0x980C1420);
- startAnimation(0x10203116, 0, -1);
- setVisible(true);
- _isWaterFlowing = true;
- }
- break;
- case 0x2003:
- _vm->_soundMan->deleteSound(0x980C1420);
- _isWaterFlowing = false;
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
-
- _x = x;
- _y = y;
- createSurface1(0xB8596884, 100);
- setVisible(false);
- SetUpdateHandler(&AsScene2401WaterFlushing::update);
- SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
-}
-
-void AsScene2401WaterFlushing::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- setDoDeltaX(_vm->_rnd->getRandomNumber(1));
- startAnimation(0xB8596884, 0, -1);
- setVisible(true);
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
- startAnimationByHash(0xB8596884, 0x01084280, 0);
- _flushLoopCount--;
- }
- break;
- case 0x2002:
- if (param.asInteger() > 0) {
- _flushLoopCount = param.asInteger() - 1;
- _countdown = _vm->_rnd->getRandomNumber(3) + 1;
- }
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
-AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
- : AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x44687810, 100);
- _newStickFrameIndex = STICK_LAST_FRAME;
- if (_isOpen) {
- stopAnimation();
- setVisible(false);
- _countdown = 48;
- } else {
- startAnimation(0x44687810, 0, -1);
- _newStickFrameIndex = 0;
- }
- SetUpdateHandler(&AsScene2401Door::update);
- SetMessageHandler(&AsScene2401Door::handleMessage);
-}
-
-void AsScene2401Door::update() {
- if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x44687810, -1, -1);
- _newStickFrameIndex = 0;
- _playBackwards = true;
- playSound(0, calcHash("fxDoorClose38"));
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- if (_isOpen)
- _countdown = 168;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- if (!_isOpen) {
- _countdown = 168;
- _isOpen = true;
- setVisible(true);
- startAnimation(0x44687810, 0, -1);
- playSound(0, calcHash("fxDoorOpen38"));
- NextState(&AsScene2401Door::stDoorOpenFinished);
- }
- break;
- }
- return messageResult;
-}
-
-void AsScene2401Door::stDoorOpenFinished() {
- stopAnimation();
- setVisible(false);
-}
-
Scene2401::Scene2401(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _unkFlag(false),
_soundToggle(false), _asWaterSpitIndex(0) {
@@ -546,143 +360,6 @@ static const uint32 kScene2402FileHashes[] = {
0xD0910068, 0xD09100A8
};
-AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
-
- _x = 320;
- _y = 240;
- createSurface1(0x80495831, 100);
- if (_isOpen) {
- startAnimation(0x80495831, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- _countdown = 48;
- } else {
- stopAnimation();
- setVisible(false);
- }
- SetUpdateHandler(&AsScene2402Door::update);
- SetMessageHandler(&AsScene2402Door::handleMessage);
-}
-
-void AsScene2402Door::update() {
- if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
- _isOpen = false;
- setVisible(true);
- startAnimation(0x80495831, -1, -1);
- _playBackwards = true;
- playSound(0, calcHash("fxDoorClose38"));
- NextState(&AsScene2402Door::stDoorClosingFinished);
- }
- AnimatedSprite::update();
-}
-
-uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- if (_isOpen)
- _countdown = 144;
- messageResult = _isOpen ? 1 : 0;
- break;
- case 0x3002:
- gotoNextState();
- break;
- case 0x4808:
- _countdown = 144;
- _isOpen = true;
- setVisible(true);
- startAnimation(0x80495831, 0, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- playSound(0, calcHash("fxDoorOpen38"));
- break;
- }
- return messageResult;
-}
-
-void AsScene2402Door::stDoorClosingFinished() {
- sendMessage(_parentScene, 0x2001, 0);
- setVisible(false);
-}
-
-AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
- : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
-
- _x = 260;
- _y = 210;
- createSurface(100, 127, 90);
- setDoDeltaX(1);
- SetMessageHandler(&Sprite::handleMessage);
- if (!getGlobalVar(V_TV_JOKE_TOLD)) {
- loadSound(0, 0x58208810);
- _countdown1 = 48;
- startAnimation(0x4919397A, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2402TV::upWait);
- } else {
- int16 frameIndex;
- if (_klaymen->getX() > 320)
- _currFrameIndex = 29;
- frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
- startAnimation(0x050A0103, frameIndex, -1);
- _newStickFrameIndex = frameIndex;
- _countdown1 = 0;
- SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
- }
-}
-
-AsScene2402TV::~AsScene2402TV() {
- _vm->_soundMan->deleteSoundGroup(0x01520123);
-}
-
-void AsScene2402TV::upWait() {
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- startAnimation(0x4919397A, 0, -1);
- SetMessageHandler(&AsScene2402TV::hmJoke);
- NextState(&AsScene2402TV::stJokeFinished);
- }
- AnimatedSprite::update();
-}
-
-void AsScene2402TV::upFocusKlaymen() {
- int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
- if (frameIndex != _currFrameIndex) {
- if (frameIndex > _currFrameIndex)
- _currFrameIndex++;
- else if (frameIndex < _currFrameIndex)
- _currFrameIndex--;
- startAnimation(0x050A0103, _currFrameIndex, -1);
- _newStickFrameIndex = _currFrameIndex;
- if (_countdown2 == 0) {
- _vm->_soundMan->addSound(0x01520123, 0xC42D4528);
- _vm->_soundMan->playSoundLooping(0xC42D4528);
- }
- _countdown2 = 5;
- } else if (_countdown2 != 0 && (--_countdown2 == 0))
- _vm->_soundMan->deleteSound(0xC42D4528);
- AnimatedSprite::update();
-}
-
-void AsScene2402TV::stJokeFinished() {
- setGlobalVar(V_TV_JOKE_TOLD, 1);
- startAnimation(0x050A0103, 0, -1);
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
-}
-
-uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x431EA0B0)
- playSound(0);
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _soundToggle(false) {
diff --git a/engines/neverhood/modules/module2400.h b/engines/neverhood/modules/module2400.h
index b50fff91c4..61603f3e00 100644
--- a/engines/neverhood/modules/module2400.h
+++ b/engines/neverhood/modules/module2400.h
@@ -27,12 +27,6 @@
#include "neverhood/module.h"
#include "neverhood/scene.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1100.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module2100.h"
-#include "neverhood/modules/module2200.h"
-#include "neverhood/modules/module2800.h"
#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -50,44 +44,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2401WaterSpit : public AnimatedSprite {
-public:
- AsScene2401WaterSpit(NeverhoodEngine *vm);
-protected:
- int _soundIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401FlowingWater : public AnimatedSprite {
-public:
- AsScene2401FlowingWater(NeverhoodEngine *vm);
- virtual ~AsScene2401FlowingWater();
-protected:
- bool _isWaterFlowing;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401WaterFlushing : public AnimatedSprite {
-public:
- AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
-protected:
- int _countdown;
- int _flushLoopCount;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2401Door : public AnimatedSprite {
-public:
- AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
-protected:
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stDoorOpenFinished();
-};
-
class Scene2401 : public Scene {
public:
Scene2401(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -111,32 +67,6 @@ protected:
void playPipeSound(uint32 fileHash);
};
-class AsScene2402Door : public AnimatedSprite {
-public:
- AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
-protected:
- Scene *_parentScene;
- int _countdown;
- bool _isOpen;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void stDoorClosingFinished();
-};
-
-class AsScene2402TV : public AnimatedSprite {
-public:
- AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
- virtual ~AsScene2402TV();
-protected:
- Klaymen *_klaymen;
- int _countdown1;
- int _countdown2;
- void upWait();
- void upFocusKlaymen();
- void stJokeFinished();
- uint32 hmJoke(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2402 : public Scene {
public:
Scene2402(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2400_sprites.cpp b/engines/neverhood/modules/module2400_sprites.cpp
new file mode 100644
index 0000000000..bf85b0dc37
--- /dev/null
+++ b/engines/neverhood/modules/module2400_sprites.cpp
@@ -0,0 +1,741 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2400_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
+ 0x5C044690, 0x5C644690, 0x5CA44690,
+ 0x5D244690, 0x5E244690
+};
+
+static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
+ 0xF4418408, 0xF4418808, 0xF4419008,
+ 0xF441A008, 0xCD4F8411
+};
+
+AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ _x = 240;
+ _y = 447;
+ createSurface(100, 146, 74);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x120A0013)
+ playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
+ break;
+ case 0x2000:
+ _x = 240;
+ _y = 447;
+ _soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
+ startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
+ setVisible(true);
+ playSound(0, 0x48640244);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
+
+ _x = 88;
+ _y = 421;
+ createSurface1(0x10203116, 100);
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
+}
+
+AsScene2401FlowingWater::~AsScene2401FlowingWater() {
+ _vm->_soundMan->deleteSoundGroup(0x40F11C09);
+}
+
+uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (_isWaterFlowing && param.asInteger() == 0x02421405)
+ startAnimationByHash(0x10203116, 0x01084280, 0);
+ break;
+ case 0x2002:
+ if (!_isWaterFlowing) {
+ _vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
+ _vm->_soundMan->playSoundLooping(0x980C1420);
+ startAnimation(0x10203116, 0, -1);
+ setVisible(true);
+ _isWaterFlowing = true;
+ }
+ break;
+ case 0x2003:
+ _vm->_soundMan->deleteSound(0x980C1420);
+ _isWaterFlowing = false;
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
+
+ _x = x;
+ _y = y;
+ createSurface1(0xB8596884, 100);
+ setVisible(false);
+ SetUpdateHandler(&AsScene2401WaterFlushing::update);
+ SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
+}
+
+void AsScene2401WaterFlushing::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0xB8596884, 0, -1);
+ setVisible(true);
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
+ startAnimationByHash(0xB8596884, 0x01084280, 0);
+ _flushLoopCount--;
+ }
+ break;
+ case 0x2002:
+ if (param.asInteger() > 0) {
+ _flushLoopCount = param.asInteger() - 1;
+ _countdown = _vm->_rnd->getRandomNumber(3) + 1;
+ }
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
+ : AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x44687810, 100);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ if (_isOpen) {
+ stopAnimation();
+ setVisible(false);
+ _countdown = 48;
+ } else {
+ startAnimation(0x44687810, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ SetUpdateHandler(&AsScene2401Door::update);
+ SetMessageHandler(&AsScene2401Door::handleMessage);
+}
+
+void AsScene2401Door::update() {
+ if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x44687810, -1, -1);
+ _newStickFrameIndex = 0;
+ _playBackwards = true;
+ playSound(0, calcHash("fxDoorClose38"));
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ if (_isOpen)
+ _countdown = 168;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ if (!_isOpen) {
+ _countdown = 168;
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x44687810, 0, -1);
+ playSound(0, calcHash("fxDoorOpen38"));
+ NextState(&AsScene2401Door::stDoorOpenFinished);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2401Door::stDoorOpenFinished() {
+ stopAnimation();
+ setVisible(false);
+}
+
+AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(0x80495831, 100);
+ if (_isOpen) {
+ startAnimation(0x80495831, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ _countdown = 48;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+ SetUpdateHandler(&AsScene2402Door::update);
+ SetMessageHandler(&AsScene2402Door::handleMessage);
+}
+
+void AsScene2402Door::update() {
+ if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x80495831, -1, -1);
+ _playBackwards = true;
+ playSound(0, calcHash("fxDoorClose38"));
+ NextState(&AsScene2402Door::stDoorClosingFinished);
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 144;
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x80495831, 0, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ playSound(0, calcHash("fxDoorOpen38"));
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2402Door::stDoorClosingFinished() {
+ sendMessage(_parentScene, 0x2001, 0);
+ setVisible(false);
+}
+
+AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
+ : AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
+
+ _x = 260;
+ _y = 210;
+ createSurface(100, 127, 90);
+ setDoDeltaX(1);
+ SetMessageHandler(&Sprite::handleMessage);
+ if (!getGlobalVar(V_TV_JOKE_TOLD)) {
+ loadSound(0, 0x58208810);
+ _countdown1 = 48;
+ startAnimation(0x4919397A, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upWait);
+ } else {
+ int16 frameIndex;
+ if (_klaymen->getX() > 320)
+ _currFrameIndex = 29;
+ frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
+ startAnimation(0x050A0103, frameIndex, -1);
+ _newStickFrameIndex = frameIndex;
+ _countdown1 = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
+ }
+}
+
+AsScene2402TV::~AsScene2402TV() {
+ _vm->_soundMan->deleteSoundGroup(0x01520123);
+}
+
+void AsScene2402TV::upWait() {
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ startAnimation(0x4919397A, 0, -1);
+ SetMessageHandler(&AsScene2402TV::hmJoke);
+ NextState(&AsScene2402TV::stJokeFinished);
+ }
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::upFocusKlaymen() {
+ int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
+ if (frameIndex != _currFrameIndex) {
+ if (frameIndex > _currFrameIndex)
+ _currFrameIndex++;
+ else if (frameIndex < _currFrameIndex)
+ _currFrameIndex--;
+ startAnimation(0x050A0103, _currFrameIndex, -1);
+ _newStickFrameIndex = _currFrameIndex;
+ if (_countdown2 == 0) {
+ _vm->_soundMan->addSound(0x01520123, 0xC42D4528);
+ _vm->_soundMan->playSoundLooping(0xC42D4528);
+ }
+ _countdown2 = 5;
+ } else if (_countdown2 != 0 && (--_countdown2 == 0))
+ _vm->_soundMan->deleteSound(0xC42D4528);
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::stJokeFinished() {
+ setGlobalVar(V_TV_JOKE_TOLD, 1);
+ startAnimation(0x050A0103, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
+}
+
+uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x431EA0B0)
+ playSound(0);
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y),
+ _canSpitPipe(false), _contSpitPipe(false), _readyToSpit(false),
+ _spitPipeIndex(0), _spitDestPipeIndex(0), _spitContDestPipeIndex(0) {
+
+ // Empty
+}
+
+uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4832:
+ GotoState(&Klaymen::stUseTube);
+ break;
+ case 0x4833:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAbout);
+ else {
+ _spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&KmScene2401::stTrySpitIntoPipe);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene2401::hmSpit(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x16401CA6) {
+ _canSpitPipe = true;
+ if (_contSpitPipe)
+ spitIntoPipe();
+ } else if (param.asInteger() == 0xC11C0008) {
+ _canSpitPipe = false;
+ _acceptInput = false;
+ _readyToSpit = false;
+ } else if (param.asInteger() == 0x018A0001) {
+ sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2401::stTrySpitIntoPipe() {
+ if (_readyToSpit) {
+ _contSpitPipe = true;
+ _spitContDestPipeIndex = _spitPipeIndex;
+ if (_canSpitPipe)
+ spitIntoPipe();
+ } else if (!stStartAction(AnimationCallback(&KmScene2401::stTrySpitIntoPipe))) {
+ _busyStatus = 2;
+ _acceptInput = true;
+ _spitDestPipeIndex = _spitPipeIndex;
+ _readyToSpit = true;
+ _canSpitPipe = false;
+ _contSpitPipe = false;
+ startAnimation(0x1808B150, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+void KmScene2401::spitIntoPipe() {
+ _contSpitPipe = false;
+ _spitDestPipeIndex = _spitContDestPipeIndex;
+ _canSpitPipe = false;
+ _acceptInput = false;
+ startAnimation(0x1B08B553, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+ NextState(&KmScene2401::stContSpitIntoPipe);
+}
+
+void KmScene2401::stContSpitIntoPipe() {
+ _canSpitPipe = true;
+ _acceptInput = true;
+ startAnimationByHash(0x1808B150, 0x16401CA6, 0);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2401::hmSpit);
+ SetSpriteUpdate(NULL);
+}
+
+KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (!getGlobalVar(V_TV_JOKE_TOLD))
+ GotoState(&Klaymen::stStandWonderAbout);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPressButton);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPressFloorButton);
+ else
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2400_sprites.h b/engines/neverhood/modules/module2400_sprites.h
new file mode 100644
index 0000000000..a901eb101c
--- /dev/null
+++ b/engines/neverhood/modules/module2400_sprites.h
@@ -0,0 +1,139 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2400_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2400_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/gamemodule.h"
+
+namespace Neverhood {
+
+class AsScene2401WaterSpit : public AnimatedSprite {
+public:
+ AsScene2401WaterSpit(NeverhoodEngine *vm);
+protected:
+ int _soundIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401FlowingWater : public AnimatedSprite {
+public:
+ AsScene2401FlowingWater(NeverhoodEngine *vm);
+ virtual ~AsScene2401FlowingWater();
+protected:
+ bool _isWaterFlowing;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401WaterFlushing : public AnimatedSprite {
+public:
+ AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
+protected:
+ int _countdown;
+ int _flushLoopCount;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2401Door : public AnimatedSprite {
+public:
+ AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
+protected:
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stDoorOpenFinished();
+};
+
+class AsScene2402Door : public AnimatedSprite {
+public:
+ AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ bool _isOpen;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stDoorClosingFinished();
+};
+
+class AsScene2402TV : public AnimatedSprite {
+public:
+ AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
+ virtual ~AsScene2402TV();
+protected:
+ Klaymen *_klaymen;
+ int _countdown1;
+ int _countdown2;
+ void upWait();
+ void upFocusKlaymen();
+ void stJokeFinished();
+ uint32 hmJoke(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2401 : public Klaymen {
+public:
+ KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ bool _canSpitPipe;
+ bool _contSpitPipe;
+ bool _readyToSpit;
+ uint32 _spitPipeIndex;
+ uint32 _spitDestPipeIndex;
+ uint32 _spitContDestPipeIndex;
+
+ void spitIntoPipe();
+ void stTrySpitIntoPipe();
+ void stContSpitIntoPipe();
+ uint32 hmSpit(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2402 : public Klaymen {
+public:
+ KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2403 : public Klaymen {
+public:
+ KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2406 : public Klaymen {
+public:
+ KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2400_SPRITES_H */
diff --git a/engines/neverhood/modules/module2500.cpp b/engines/neverhood/modules/module2500.cpp
index 46ce2ba4fc..d0e60adf65 100644
--- a/engines/neverhood/modules/module2500.cpp
+++ b/engines/neverhood/modules/module2500.cpp
@@ -20,8 +20,12 @@
*
*/
+#include "neverhood/modules/module1600.h" // for Scene1608
+#include "neverhood/modules/module1600_sprites.h"
#include "neverhood/modules/module2500.h"
-#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module2500_sprites.h"
+#include "neverhood/modules/module2700.h" // for Scene2704
+#include "neverhood/modules/module2700_sprites.h"
namespace Neverhood {
@@ -470,54 +474,6 @@ void Scene2501::updateKlaymenClipRect() {
_kmScene2501->setClipRect(0, 0, 640, 388);
}
-SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
- : StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
-
- loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x4600204C);
- loadSound(1, 0x408C0034);
- loadSound(2, 0x44043000);
- loadSound(3, 0x44045000);
- SetMessageHandler(&SsScene2504Button::handleMessage);
- SetUpdateHandler(&SsScene2504Button::update);
-}
-
-void SsScene2504Button::update() {
- updatePosition();
- if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
- playSound(3);
- setVisible(false);
- _isSoundPlaying = false;
- }
- if (_countdown != 0 && (--_countdown) == 0) {
- if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
- playSound(0);
- else
- playSound(1);
- _isSoundPlaying = true;
- }
-}
-
-uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_isSoundPlaying) {
- setVisible(true);
- _countdown = 2;
- if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
- setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
- else
- setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
- playSound(2);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
diff --git a/engines/neverhood/modules/module2500.h b/engines/neverhood/modules/module2500.h
index 07db7907d5..de6226ef0c 100644
--- a/engines/neverhood/modules/module2500.h
+++ b/engines/neverhood/modules/module2500.h
@@ -26,14 +26,10 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1600.h"
-#include "neverhood/modules/module2700.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
-// Module2500
-
class Module2500 : public Module {
public:
Module2500(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -47,6 +43,8 @@ protected:
void createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
};
+class AsCommonCar;
+
class Scene2501 : public Scene {
public:
Scene2501(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -79,16 +77,6 @@ protected:
void updateKlaymenClipRect();
};
-class SsScene2504Button : public StaticSprite {
-public:
- SsScene2504Button(NeverhoodEngine *vm);
-protected:
- int _countdown;
- bool _isSoundPlaying;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2504 : public Scene {
public:
Scene2504(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2500_sprites.cpp b/engines/neverhood/modules/module2500_sprites.cpp
new file mode 100644
index 0000000000..ab6b3dcfbe
--- /dev/null
+++ b/engines/neverhood/modules/module2500_sprites.cpp
@@ -0,0 +1,127 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2500_sprites.h"
+
+namespace Neverhood {
+
+SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
+ : StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
+
+ loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x4600204C);
+ loadSound(1, 0x408C0034);
+ loadSound(2, 0x44043000);
+ loadSound(3, 0x44045000);
+ SetMessageHandler(&SsScene2504Button::handleMessage);
+ SetUpdateHandler(&SsScene2504Button::update);
+}
+
+void SsScene2504Button::update() {
+ updatePosition();
+ if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
+ playSound(3);
+ setVisible(false);
+ _isSoundPlaying = false;
+ }
+ if (_countdown != 0 && (--_countdown) == 0) {
+ if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
+ playSound(0);
+ else
+ playSound(1);
+ _isSoundPlaying = true;
+ }
+}
+
+uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_isSoundPlaying) {
+ setVisible(true);
+ _countdown = 2;
+ if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
+ setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
+ else
+ setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
+ playSound(2);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2500_sprites.h b/engines/neverhood/modules/module2500_sprites.h
new file mode 100644
index 0000000000..e7f7b05702
--- /dev/null
+++ b/engines/neverhood/modules/module2500_sprites.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2500_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2500_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsScene2504Button : public StaticSprite {
+public:
+ SsScene2504Button(NeverhoodEngine *vm);
+protected:
+ int _countdown;
+ bool _isSoundPlaying;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2501 : public Klaymen {
+public:
+ KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2500_SPRITES_H */
diff --git a/engines/neverhood/modules/module2600.cpp b/engines/neverhood/modules/module2600.cpp
index 2fce82b777..a6484a4926 100644
--- a/engines/neverhood/modules/module2600.cpp
+++ b/engines/neverhood/modules/module2600.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module2600.h"
+#include "neverhood/modules/module2600_sprites.h"
namespace Neverhood {
@@ -219,94 +220,6 @@ void Module2600::updateScene() {
}
}
-SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
-
- SetUpdateHandler(&SsScene2609Button::update);
- SetMessageHandler(&SsScene2609Button::handleMessage);
-
- loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- if (!getGlobalVar(V_WATER_RUNNING))
- setVisible(false);
- loadSound(0, 0x10267160);
- loadSound(1, 0x7027FD64);
- loadSound(2, 0x44043000);
- loadSound(3, 0x44045000);
-}
-
-void SsScene2609Button::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- if (getGlobalVar(V_WATER_RUNNING)) {
- setGlobalVar(V_WATER_RUNNING, 0);
- sendMessage(_parentScene, 0x2001, 0);
- } else {
- setGlobalVar(V_WATER_RUNNING, 1);
- sendMessage(_parentScene, 0x2002, 0);
- }
- }
-}
-
-uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- sendMessage(_parentScene, 0x2000, 0);
- if (getGlobalVar(V_WATER_RUNNING)) {
- setVisible(false);
- playSound(3);
- playSound(1);
- _countdown = 12;
- } else {
- setVisible(true);
- playSound(2);
- playSound(0);
- _countdown = 96;
- }
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1000) {
-
- _x = 240;
- _y = 420;
- setDoDeltaX(1);
- createSurface1(0x9C210C90, 1200);
- setClipRect(260, 260, 400, 368);
- _vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2609Water::handleMessage);
- if (getGlobalVar(V_WATER_RUNNING))
- sendMessage(this, 0x2002, 0);
-}
-
-AsScene2609Water::~AsScene2609Water() {
- _vm->_soundMan->deleteSoundGroup(0x08526C36);
-}
-
-uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2001:
- stopAnimation();
- setVisible(false);
- _vm->_soundMan->stopSound(0xDC2769B0);
- break;
- case 0x2002:
- startAnimation(0x9C210C90, 0, -1);
- setVisible(true);
- _vm->_soundMan->playSoundLooping(0xDC2769B0);
- break;
- }
- return messageResult;
-}
-
Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _isBusy(false) {
diff --git a/engines/neverhood/modules/module2600.h b/engines/neverhood/modules/module2600.h
index d972e0fb0d..99ec3a34ca 100644
--- a/engines/neverhood/modules/module2600.h
+++ b/engines/neverhood/modules/module2600.h
@@ -41,24 +41,6 @@ protected:
void updateScene();
};
-class SsScene2609Button : public StaticSprite {
-public:
- SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2609Water : public AnimatedSprite {
-public:
- AsScene2609Water(NeverhoodEngine *vm);
- virtual ~AsScene2609Water();
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2609 : public Scene {
public:
Scene2609(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2600_sprites.cpp b/engines/neverhood/modules/module2600_sprites.cpp
new file mode 100644
index 0000000000..2c24b533f3
--- /dev/null
+++ b/engines/neverhood/modules/module2600_sprites.cpp
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2600_sprites.h"
+
+namespace Neverhood {
+
+SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
+
+ SetUpdateHandler(&SsScene2609Button::update);
+ SetMessageHandler(&SsScene2609Button::handleMessage);
+
+ loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ if (!getGlobalVar(V_WATER_RUNNING))
+ setVisible(false);
+ loadSound(0, 0x10267160);
+ loadSound(1, 0x7027FD64);
+ loadSound(2, 0x44043000);
+ loadSound(3, 0x44045000);
+}
+
+void SsScene2609Button::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ if (getGlobalVar(V_WATER_RUNNING)) {
+ setGlobalVar(V_WATER_RUNNING, 0);
+ sendMessage(_parentScene, 0x2001, 0);
+ } else {
+ setGlobalVar(V_WATER_RUNNING, 1);
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+ }
+}
+
+uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ sendMessage(_parentScene, 0x2000, 0);
+ if (getGlobalVar(V_WATER_RUNNING)) {
+ setVisible(false);
+ playSound(3);
+ playSound(1);
+ _countdown = 12;
+ } else {
+ setVisible(true);
+ playSound(2);
+ playSound(0);
+ _countdown = 96;
+ }
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1000) {
+
+ _x = 240;
+ _y = 420;
+ setDoDeltaX(1);
+ createSurface1(0x9C210C90, 1200);
+ setClipRect(260, 260, 400, 368);
+ _vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2609Water::handleMessage);
+ if (getGlobalVar(V_WATER_RUNNING))
+ sendMessage(this, 0x2002, 0);
+}
+
+AsScene2609Water::~AsScene2609Water() {
+ _vm->_soundMan->deleteSoundGroup(0x08526C36);
+}
+
+uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ stopAnimation();
+ setVisible(false);
+ _vm->_soundMan->stopSound(0xDC2769B0);
+ break;
+ case 0x2002:
+ startAnimation(0x9C210C90, 0, -1);
+ setVisible(true);
+ _vm->_soundMan->playSoundLooping(0xDC2769B0);
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2600_sprites.h b/engines/neverhood/modules/module2600_sprites.h
new file mode 100644
index 0000000000..c36e72cae8
--- /dev/null
+++ b/engines/neverhood/modules/module2600_sprites.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2600_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2600_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Module2600
+
+class SsScene2609Button : public StaticSprite {
+public:
+ SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2609Water : public AnimatedSprite {
+public:
+ AsScene2609Water(NeverhoodEngine *vm);
+ virtual ~AsScene2609Water();
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2600_SPRITES_H */
diff --git a/engines/neverhood/modules/module2700.cpp b/engines/neverhood/modules/module2700.cpp
index 7aea82f6b1..1b78615fdb 100644
--- a/engines/neverhood/modules/module2700.cpp
+++ b/engines/neverhood/modules/module2700.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module2700.h"
#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
+#include "neverhood/modules/module1600_sprites.h"
+#include "neverhood/modules/module2700.h"
+#include "neverhood/modules/module2700_sprites.h"
namespace Neverhood {
@@ -536,83 +537,6 @@ void Module2700::createScene2704(int which, uint32 trackInfoId, int16 value, con
_childObject = new Scene2704(_vm, this, which, trackInfoId, value, staticSprites, clipRect);
}
-static const NPoint kCarShadowOffsets[] = {
- {-63, 3}, {-48, 40}, {-33, 58},
- { 0, 65}, { 40, 53}, { 56, 27},
- { 63, 0}, {-30, 26}, { 0, 30},
- { 26, 25}
-};
-
-SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
- : StaticSprite(vm, 0) {
-
- loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
-}
-
-AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index)
- : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
-
- SetUpdateHandler(&AsCommonCarShadow::update);
- createShadowSurface(shadowSurface, 211, 147, 100);
- updateShadow();
-}
-
-void AsCommonCarShadow::update() {
- updateShadow();
- AnimatedSprite::update();
-}
-
-void AsCommonCarShadow::updateShadow() {
- if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
- uint32 fileHash = _asCar->getCurrAnimFileHash();
- if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
- fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
- fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
- fileHash == 0xF46A0324) {
- startAnimation(fileHash, _asCar->getFrameIndex(), -1);
- _newStickFrameIndex = _asCar->getFrameIndex();
- }
- _animFileHash = fileHash;
- }
- _x = _asCar->getX() + kCarShadowOffsets[_index].x;
- _y = _asCar->getY() + kCarShadowOffsets[_index].y;
- if (!_asCar->getVisible()) {
- startAnimation(0x1209E09F, 0, -1);
- _newStickFrameIndex = 0;
- }
- setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
-}
-
-AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index)
- : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
-
- SetUpdateHandler(&AsCommonCarConnectorShadow::update);
- createShadowSurface1(shadowSurface, 0x60281C10, 150);
- startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
-}
-
-void AsCommonCarConnectorShadow::update() {
- _x = _asCar->getX() + kCarShadowOffsets[_index].x;
- _y = _asCar->getY() + kCarShadowOffsets[_index].y;
- AnimatedSprite::update();
-}
-
-AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex)
- : AnimatedSprite(vm, 1100), _asCar(asCar) {
-
- SetUpdateHandler(&AsCommonCarTrackShadow::update);
- createShadowSurface1(shadowSurface, 0x0759129C, 100);
- startAnimation(0x0759129C, frameIndex, -1);
- _newStickFrameIndex = frameIndex;
-}
-
-void AsCommonCarTrackShadow::update() {
- _x = _asCar->getX();
- _y = _asCar->getY();
- AnimatedSprite::update();
-}
-
Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
diff --git a/engines/neverhood/modules/module2700.h b/engines/neverhood/modules/module2700.h
index 158bb609e9..97b4f1cbea 100644
--- a/engines/neverhood/modules/module2700.h
+++ b/engines/neverhood/modules/module2700.h
@@ -26,7 +26,7 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
@@ -49,38 +49,7 @@ protected:
void createScene2704(int which, uint32 trackInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
};
-class SsCommonTrackShadowBackground : public StaticSprite {
-public:
- SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
-};
-
-class AsCommonCarShadow : public AnimatedSprite {
-public:
- AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index);
-protected:
- uint _index;
- AnimatedSprite *_asCar;
- uint32 _animFileHash;
- void update();
- void updateShadow();
-};
-
-class AsCommonCarConnectorShadow : public AnimatedSprite {
-public:
- AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index);
-protected:
- uint _index;
- Sprite *_asCar;
- void update();
-};
-
-class AsCommonCarTrackShadow : public AnimatedSprite {
-public:
- AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex);
-protected:
- Sprite *_asCar;
- void update();
-};
+class AsCommonCar;
class Scene2701 : public Scene {
public:
diff --git a/engines/neverhood/modules/module2700_sprites.cpp b/engines/neverhood/modules/module2700_sprites.cpp
new file mode 100644
index 0000000000..8dd2fa3461
--- /dev/null
+++ b/engines/neverhood/modules/module2700_sprites.cpp
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2700_sprites.h"
+
+namespace Neverhood {
+
+static const NRect kScene2710ClipRect = { 0, 0, 626, 480 };
+
+static const uint32 kScene2710StaticSprites[] = {
+ 0x0D2016C0,
+ 0
+};
+
+static const NRect kScene2711ClipRect = { 0, 0, 521, 480 };
+
+static const uint32 kScene2711FileHashes1[] = {
+ 0,
+ 0x100801A1,
+ 0x201081A0,
+ 0x006800A4,
+ 0x40390120,
+ 0x000001B1,
+ 0x001000A1,
+ 0
+};
+
+static const uint32 kScene2711FileHashes2[] = {
+ 0,
+ 0x40403308,
+ 0x71403168,
+ 0x80423928,
+ 0x224131A8,
+ 0x50401328,
+ 0x70423328,
+ 0
+};
+
+static const uint32 kScene2711FileHashes3[] = {
+ 0,
+ 0x1088A021,
+ 0x108120E5,
+ 0x18A02321,
+ 0x148221A9,
+ 0x10082061,
+ 0x188820E1,
+ 0
+};
+
+static const NRect kScene2724ClipRect = { 0, 141, 640, 480 };
+
+static const uint32 kScene2724StaticSprites[] = {
+ 0xC20D00A5,
+ 0
+};
+
+static const NRect kScene2725ClipRect = { 0, 0, 640, 413 };
+
+static const uint32 kScene2725StaticSprites[] = {
+ 0xC20E00A5,
+ 0
+};
+
+static const NPoint kCarShadowOffsets[] = {
+ {-63, 3}, {-48, 40}, {-33, 58},
+ { 0, 65}, { 40, 53}, { 56, 27},
+ { 63, 0}, {-30, 26}, { 0, 30},
+ { 26, 25}
+};
+
+SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
+ : StaticSprite(vm, 0) {
+
+ loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
+}
+
+AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index)
+ : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
+
+ SetUpdateHandler(&AsCommonCarShadow::update);
+ createShadowSurface(shadowSurface, 211, 147, 100);
+ updateShadow();
+}
+
+void AsCommonCarShadow::update() {
+ updateShadow();
+ AnimatedSprite::update();
+}
+
+void AsCommonCarShadow::updateShadow() {
+ if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
+ uint32 fileHash = _asCar->getCurrAnimFileHash();
+ if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
+ fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
+ fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
+ fileHash == 0xF46A0324) {
+ startAnimation(fileHash, _asCar->getFrameIndex(), -1);
+ _newStickFrameIndex = _asCar->getFrameIndex();
+ }
+ _animFileHash = fileHash;
+ }
+ _x = _asCar->getX() + kCarShadowOffsets[_index].x;
+ _y = _asCar->getY() + kCarShadowOffsets[_index].y;
+ if (!_asCar->getVisible()) {
+ startAnimation(0x1209E09F, 0, -1);
+ _newStickFrameIndex = 0;
+ }
+ setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
+}
+
+AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index)
+ : AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
+
+ SetUpdateHandler(&AsCommonCarConnectorShadow::update);
+ createShadowSurface1(shadowSurface, 0x60281C10, 150);
+ startAnimation(0x60281C10, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+}
+
+void AsCommonCarConnectorShadow::update() {
+ _x = _asCar->getX() + kCarShadowOffsets[_index].x;
+ _y = _asCar->getY() + kCarShadowOffsets[_index].y;
+ AnimatedSprite::update();
+}
+
+AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex)
+ : AnimatedSprite(vm, 1100), _asCar(asCar) {
+
+ SetUpdateHandler(&AsCommonCarTrackShadow::update);
+ createShadowSurface1(shadowSurface, 0x0759129C, 100);
+ startAnimation(0x0759129C, frameIndex, -1);
+ _newStickFrameIndex = frameIndex;
+}
+
+void AsCommonCarTrackShadow::update() {
+ _x = _asCar->getX();
+ _y = _asCar->getY();
+ AnimatedSprite::update();
+}
+
+KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4804:
+ GotoState(&Klaymen::stPeekInside);
+ break;
+ case 0x483C:
+ GotoState(&Klaymen::stPeekInsideReturn);
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2700_sprites.h b/engines/neverhood/modules/module2700_sprites.h
new file mode 100644
index 0000000000..394ba896a1
--- /dev/null
+++ b/engines/neverhood/modules/module2700_sprites.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2700_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2700_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class SsCommonTrackShadowBackground : public StaticSprite {
+public:
+ SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
+};
+
+class AsCommonCarShadow : public AnimatedSprite {
+public:
+ AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, BaseSurface *shadowSurface, uint index);
+protected:
+ uint _index;
+ AnimatedSprite *_asCar;
+ uint32 _animFileHash;
+ void update();
+ void updateShadow();
+};
+
+class AsCommonCarConnectorShadow : public AnimatedSprite {
+public:
+ AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, uint index);
+protected:
+ uint _index;
+ Sprite *_asCar;
+ void update();
+};
+
+class AsCommonCarTrackShadow : public AnimatedSprite {
+public:
+ AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, BaseSurface *shadowSurface, int16 frameIndex);
+protected:
+ Sprite *_asCar;
+ void update();
+};
+
+class KmScene2732 : public Klaymen {
+public:
+ KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2700_SPRITES_H */
diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp
index 1c0f9fc9fb..0578a5df2e 100644
--- a/engines/neverhood/modules/module2800.cpp
+++ b/engines/neverhood/modules/module2800.cpp
@@ -20,13 +20,15 @@
*
*/
-#include "neverhood/modules/module2800.h"
-#include "neverhood/gamemodule.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/modules/module1700.h"
-#include "neverhood/modules/module2200.h"
#include "neverhood/diskplayerscene.h"
+#include "neverhood/gamemodule.h"
+#include "neverhood/scene.h"
+#include "neverhood/modules/module1000_sprites.h"
+#include "neverhood/modules/module1200_sprites.h"
+#include "neverhood/modules/module1700_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module2800.h"
+#include "neverhood/modules/module2800_sprites.h"
namespace Neverhood {
@@ -294,30 +296,8 @@ void Module2800::updateScene() {
createScene(8, 0);
else if (_moduleResult == 6)
createScene(2, 6);
- else if (_moduleResult == 11)
- createScene(12, 0);
- else if (_moduleResult == 12)
- createScene(13, 0);
- else if (_moduleResult == 13)
- createScene(14, 0);
- else if (_moduleResult == 14)
- createScene(15, 0);
- else if (_moduleResult == 15)
- createScene(16, 0);
- else if (_moduleResult == 16)
- createScene(17, 0);
- else if (_moduleResult == 17)
- createScene(18, 0);
- else if (_moduleResult == 18)
- createScene(19, 0);
- else if (_moduleResult == 19)
- createScene(20, 0);
- else if (_moduleResult == 20)
- createScene(21, 0);
- else if (_moduleResult == 21)
- createScene(22, 0);
- else if (_moduleResult == 22)
- createScene(23, 0);
+ else if (_moduleResult >= 11 && _moduleResult <= 22)
+ createScene(_moduleResult + 1, 0);
else
createScene(2, 4);
break;
@@ -335,40 +315,18 @@ void Module2800::updateScene() {
createScene(9, 1);
break;
case 12:
- createScene(9, 11);
- break;
case 13:
- createScene(9, 12);
- break;
case 14:
- createScene(9, 13);
- break;
case 15:
- createScene(9, 14);
- break;
case 16:
- createScene(9, 15);
- break;
case 17:
- createScene(9, 16);
- break;
case 18:
- createScene(9, 17);
- break;
case 19:
- createScene(9, 18);
- break;
case 20:
- createScene(9, 19);
- break;
case 21:
- createScene(9, 20);
- break;
case 22:
- createScene(9, 21);
- break;
case 23:
- createScene(9, 22);
+ createScene(9, _sceneNum - 1);
break;
case 24:
createScene(9, 3);
@@ -687,154 +645,6 @@ void Scene2802::changeTuneStatus(int prevTuneStatus, int newTuneStatus) {
}
-AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _fileHash1(fileHash1), _fileHash2(fileHash2),
- _isPulled(false), _isBusy(false) {
-
- createSurface(1010, 28, 379);
- SetUpdateHandler(&AnimatedSprite::update);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- _x = x;
- _y = y;
- stIdle();
-}
-
-uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) {
- sendMessage(_parentScene, 0x480F, 0);
- playSound(0, 0x4E1CA4A0);
- }
- break;
- case 0x480F:
- stPulled();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2803LightCord::stPulled() {
- _isBusy = false;
- _isPulled = true;
- startAnimation(_fileHash2, 0, -1);
- SetMessageHandler(&AsScene2803LightCord::hmPulled);
- NextState(&AsScene2803LightCord::stIdle);
-}
-
-void AsScene2803LightCord::stIdle() {
- _isPulled = false;
- startAnimation(_fileHash1, 0, -1);
- SetMessageHandler(&AsScene2803LightCord::handleMessage);
-}
-
-void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
- _fileHash1 = fileHash1;
- _fileHash2 = fileHash2;
- if (_isPulled) {
- startAnimation(_fileHash2, _currFrameIndex, -1);
- _isBusy = true;
- } else {
- startAnimation(_fileHash1, 0, -1);
- }
-}
-
-AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2)
- : AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) {
-
- createSurface1(fileHash1, 100);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2803TestTubeOne::handleMessage);
- _x = 529;
- _y = 326;
-}
-
-uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- if (param.asInteger())
- startAnimation(_fileHash2, 0, -1);
- else
- startAnimation(_fileHash1, 0, -1);
- break;
- }
- return messageResult;
-}
-
-AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(990, 68, 476);
- SetUpdateHandler(&AnimatedSprite::update);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- SetMessageHandler(&AsScene2803Rope::handleMessage);
- startAnimation(0x9D098C23, 35, 53);
- NextState(&AsScene2803Rope::stReleased);
- _x = x;
- _y = -276;
-}
-
-uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(0x9D098C23, 50, -1);
- SetMessageHandler(&AsScene2803Rope::hmReleased);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-void AsScene2803Rope::stReleased() {
- startAnimation(0x8258A030, 0, 1);
- NextState(&AsScene2803Rope::stHide);
-}
-
-void AsScene2803Rope::stHide() {
- stopAnimation();
- setVisible(false);
-}
-
Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(0) {
@@ -1350,379 +1160,6 @@ void Scene2803Small::updatePaletteArea(bool instantly) {
_palette->startFadeToPalette(instantly ? 0 : 12);
}
-SsScene2804RedButton::SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene)
- : StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene) {
-
- loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? 0x51A10202 : 0x11814A21, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- SetUpdateHandler(&SsScene2804RedButton::update);
- SetMessageHandler(&SsScene2804RedButton::handleMessage);
- loadSound(0, 0x44241240);
-}
-
-void SsScene2804RedButton::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_parentScene->isWorking()) {
- playSound(0);
- setVisible(true);
- _countdown = 4;
- sendMessage(_parentScene, 0x2000, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
- SetMessageHandler(&SsScene2804LightCoil::handleMessage);
-}
-
-uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- setVisible(true);
- updatePosition();
- messageResult = 1;
- break;
- case 0x2003:
- setVisible(false);
- updatePosition();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
- SetMessageHandler(&SsScene2804LightTarget::handleMessage);
-}
-
-uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- setVisible(true);
- updatePosition();
- messageResult = 1;
- break;
- case 0x2005:
- setVisible(false);
- updatePosition();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
- loadSound(0, 0xCB36BA54);
-}
-
-void SsScene2804Flash::show() {
- setVisible(true);
- updatePosition();
- playSound(0);
-}
-
-SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm)
- : StaticSprite(vm, 900) {
-
- loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400);
- setVisible(false);
-}
-
-AsScene2804CrystalWaves::AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex)
- : AnimatedSprite(vm, 1100), _crystalIndex(crystalIndex) {
-
- static const NPoint kAsScene2804CrystalWavesPoints[] = {
- {323, 245},
- {387, 76},
- {454, 260},
- {527, 70}
- };
-
- _x = kAsScene2804CrystalWavesPoints[crystalIndex].x;
- _y = kAsScene2804CrystalWavesPoints[crystalIndex].y;
- createSurface1(0x840C41F0, 1200);
- if (crystalIndex & 1)
- setDoDeltaY(1);
- setVisible(false);
- _needRefresh = true;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&Sprite::handleMessage);
-}
-
-void AsScene2804CrystalWaves::show() {
- setVisible(true);
- startAnimation(0x840C41F0, 0, -1);
-}
-
-void AsScene2804CrystalWaves::hide() {
- setVisible(false);
- stopAnimation();
-}
-
-static const int16 kAsScene2804CrystalFrameNums[] = {
- 0, 6, 2, 8, 1, 10, 0, 0
-};
-
-static const uint32 kAsScene2804CrystalFileHashes[] = {
- 0x000540B0,
- 0x001280D0,
- 0x003D0010,
- 0x00620190,
- 0x00DC0290
-};
-
-AsScene2804Crystal::AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex)
- : AnimatedSprite(vm, 1100), _asCrystalWaves(asCrystalWaves), _crystalIndex(crystalIndex), _isShowing(false) {
-
- static const NPoint kAsScene2804CrystalPoints[] = {
- {204, 196},
- {272, 316},
- {334, 206},
- {410, 334},
- {470, 180}
- };
-
- _colorNum = (int16)getSubVar(VA_CURR_CRYSTAL_COLORS, crystalIndex);
- _isLightOn = getGlobalVar(V_SHRINK_LIGHTS_ON) != 0;
- if (_isLightOn) {
- _x = kAsScene2804CrystalPoints[crystalIndex].x;
- _y = kAsScene2804CrystalPoints[crystalIndex].y;
- createSurface1(0x108DFB12, 1200);
- startAnimation(0x108DFB12, kAsScene2804CrystalFrameNums[_colorNum], -1);
- _needRefresh = true;
- _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
- } else {
- _x = 320;
- _y = 240;
- createSurface1(kAsScene2804CrystalFileHashes[crystalIndex], 1200);
- startAnimation(kAsScene2804CrystalFileHashes[crystalIndex], _colorNum, -1);
- setVisible(false);
- _needRefresh = true;
- _newStickFrameIndex = _colorNum;
- }
- loadSound(0, 0x725294D4);
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene2804Crystal::show() {
- if (!_isLightOn) {
- setVisible(true);
- _isShowing = true;
- if (_asCrystalWaves)
- _asCrystalWaves->show();
- playSound(0);
- }
-}
-
-void AsScene2804Crystal::hide() {
- if (!_isLightOn) {
- setVisible(false);
- _isShowing = false;
- if (_asCrystalWaves)
- _asCrystalWaves->hide();
- }
-}
-
-void AsScene2804Crystal::activate() {
- if (!_isShowing) {
- int16 frameNum = kAsScene2804CrystalFrameNums[_colorNum];
- _colorNum++;
- if (_colorNum >= 6)
- _colorNum = 0;
- if (_isLightOn) {
- startAnimation(0x108DFB12, frameNum, kAsScene2804CrystalFrameNums[_colorNum]);
- _playBackwards = kAsScene2804CrystalFrameNums[_colorNum] < _colorNum;
- _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
- } else {
- startAnimation(kAsScene2804CrystalFileHashes[_crystalIndex], _colorNum, -1);
- _newStickFrameIndex = _colorNum;
- }
- setSubVar(VA_CURR_CRYSTAL_COLORS, _crystalIndex, _colorNum);
- }
-}
-
-SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex)
- : StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene), _asCrystal(asCrystal), _crystalIndex(crystalIndex) {
-
- static const uint32 kSsScene2804CrystalButtonFileHashes1[] = {
- 0x911101B0,
- 0x22226001,
- 0x4444A362,
- 0x888925A4,
- 0x11122829
- };
-
- static const uint32 kSsScene2804CrystalButtonFileHashes2[] = {
- 0xB500A1A0,
- 0x6A012021,
- 0xD4022322,
- 0xA8042525,
- 0x5008292B
- };
-
- loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex],
- kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44045140);
- SetUpdateHandler(&SsScene2804CrystalButton::update);
- SetMessageHandler(&SsScene2804CrystalButton::handleMessage);
-}
-
-void SsScene2804CrystalButton::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0 && !_parentScene->isWorking()) {
- playSound(0);
- setVisible(true);
- _countdown = 4;
- _asCrystal->activate();
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody)
- : AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) {
-
- createSurface1(0x00494891, 1000);
- _x = 125;
- _y = 184;
- setVisible(false);
- _needRefresh = true;
- AnimatedSprite::updatePosition();
- loadSound(0, 0x6352F051);
- _vm->_soundMan->addSound(0xC5EA0B28, 0xEF56B094);
- SetUpdateHandler(&AsScene2804BeamCoil::update);
- SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
-}
-
-AsScene2804BeamCoil::~AsScene2804BeamCoil() {
- _vm->_soundMan->deleteSoundGroup(0xC5EA0B28);
-}
-
-void AsScene2804BeamCoil::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- sendMessage(_parentScene, 0x2001, 0);
- }
-}
-
-uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2002:
- show();
- _countdown = 92;
- messageResult = 1;
- break;
- case 0x2003:
- hide();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene2804BeamCoil::show() {
- _ssBeamCoilBody->setVisible(true);
- setVisible(true);
- startAnimation(0x00494891, 0, -1);
- playSound(0);
- SetMessageHandler(&AsScene2804BeamCoil::hmBeaming);
- NextState(&AsScene2804BeamCoil::stBeaming);
-}
-
-void AsScene2804BeamCoil::hide() {
- stopAnimation();
- SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
- setVisible(false);
- _ssBeamCoilBody->setVisible(false);
- _vm->_soundMan->stopSound(0xEF56B094);
-}
-
-void AsScene2804BeamCoil::stBeaming() {
- startAnimation(0x00494891, 93, -1);
- NextState(&AsScene2804BeamCoil::stBeaming);
- _vm->_soundMan->playSoundLooping(0xEF56B094);
-}
-
-uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1400) {
-
- createSurface1(0x03842000, 1000);
- _x = 475;
- _y = 278;
- setVisible(false);
- _needRefresh = true;
- updatePosition();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2804BeamTarget::handleMessage);
-}
-
-uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2004:
- setVisible(true);
- startAnimation(0x03842000, 0, -1);
- messageResult = 1;
- break;
- case 0x2005:
- setVisible(false);
- stopAnimation();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _countdown3(0),
_beamStatus(0), _isSolved(false), _isWorking(false) {
@@ -1892,34 +1329,6 @@ uint32 Scene2805::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- createSurface1(0x04211490, 1200);
- _x = 378;
- _y = 423;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2806Spew::handleMessage);
- setDoDeltaX(1);
- setVisible(false);
-}
-
-uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- playSound(0, 0x48640244);
- startAnimation(0x04211490, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -2111,267 +1520,6 @@ static const uint32 kClass428FileHashes[] = {
0x40800711
};
-static const int kClass428Countdowns1[] = {
- 18, 16, 10, 0
-};
-
-static const int kClass428Countdowns2[] = {
- 9, 9, 8, 8, 5, 5, 0, 0
-};
-
-static const uint32 kClass490FileHashes[] = {
- 0x08100071,
- 0x24084215,
- 0x18980A10
-};
-
-static const int16 kClass490FrameIndices1[] = {
- 0, 8, 15, 19
-};
-
-static const int16 kClass490FrameIndices2[] = {
- 0, 4, 8, 11, 15, 17, 19, 0
-};
-
-SsScene2808Dispenser::SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex)
- : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _testTubeSetNum(testTubeSetNum),
- _testTubeIndex(testTubeIndex) {
-
- loadSprite(kClass428FileHashes[testTubeSetNum * 3 + testTubeIndex], kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1500);
- setVisible(false);
- SetUpdateHandler(&SsScene2808Dispenser::update);
- SetMessageHandler(&SsScene2808Dispenser::handleMessage);
-}
-
-void SsScene2808Dispenser::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- sendMessage(_parentScene, 0x2000, _testTubeIndex);
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void SsScene2808Dispenser::startCountdown(int index) {
- setVisible(true);
- updatePosition();
- if (_testTubeSetNum == 0) {
- _countdown = kClass428Countdowns1[index];
- } else {
- _countdown = kClass428Countdowns2[index];
- }
-}
-
-AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser)
- : AnimatedSprite(vm, 1100), _testTubeSetNum(testTubeSetNum), _testTubeIndex(testTubeIndex), _ssDispenser(ssDispenser), _fillLevel(0) {
-
- if (testTubeSetNum == 0) {
- _x = 504;
- _y = 278;
- } else {
- setDoDeltaX(1);
- _x = 136;
- _y = 278;
- }
-
- createSurface1(kClass490FileHashes[testTubeIndex], 1100);
-
- if (testTubeSetNum == 0) {
- loadSound(0, 0x30809E2D);
- loadSound(1, 0x72811E2D);
- loadSound(2, 0x78B01625);
- } else {
- loadSound(3, 0x70A41E0C);
- loadSound(4, 0x50205E2D);
- loadSound(5, 0xF8621E2D);
- loadSound(6, 0xF1A03C2D);
- loadSound(7, 0x70A43D2D);
- loadSound(8, 0xF0601E2D);
- }
-
- startAnimation(kClass490FileHashes[testTubeIndex], 0, -1);
- _newStickFrameIndex = 0;
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2808TestTube::handleMessage);
-
- if (_fillLevel == 0)
- setVisible(false);
-
-}
-
-uint32 AsScene2808TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- fill();
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene2808TestTube::fill() {
- if ((int)_fillLevel < _testTubeSetNum * 3 + 3) {
- if (_testTubeSetNum == 0) {
- playSound(_fillLevel);
- setVisible(true);
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], kClass490FrameIndices1[_fillLevel + 1]);
- _newStickFrameIndex = kClass490FrameIndices1[_fillLevel + 1];
- } else {
- playSound(3 + _fillLevel);
- setVisible(true);
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], kClass490FrameIndices2[_fillLevel + 1]);
- _newStickFrameIndex = kClass490FrameIndices2[_fillLevel + 1];
- }
- _ssDispenser->startCountdown(_fillLevel);
- _fillLevel++;
- }
-}
-
-void AsScene2808TestTube::flush() {
- if (_fillLevel != 0) {
- if (_testTubeSetNum == 0) {
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], -1);
- } else {
- startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], -1);
- }
- _newStickFrameIndex = 0;
- _playBackwards = true;
- setVisible(true);
- }
-}
-
-AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
- : AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) {
-
- loadSound(0, 0xE18D1F30);
- _x = 320;
- _y = 240;
- if (_testTubeSetNum == 1)
- setDoDeltaX(1);
- createSurface1(0x040900D0, 1300);
- startAnimation(0x040900D0, 0, -1);
- _needRefresh = true;
- _newStickFrameIndex = 0;
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2808Handle::handleMessage);
- AnimatedSprite::updatePosition();
-}
-
-uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isActivated) {
- sendMessage(_parentScene, 0x2001, 0);
- playSound(0);
- activate();
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2808Handle::activate() {
- startAnimation(0x040900D0, 0, -1);
- SetMessageHandler(&AsScene2808Handle::hmActivating);
- NextState(&AsScene2808Handle::stActivated);
- _isActivated = true;
- _newStickFrameIndex = -1;
-}
-
-void AsScene2808Handle::stActivated() {
- stopAnimation();
- sendMessage(_parentScene, 0x2002, 0);
-}
-
-AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum) {
-
- if (testTubeSetNum == 0) {
- _x = 312;
- _y = 444;
- } else {
- _x = 328;
- _y = 444;
- }
- createSurface1(0xB8414818, 1200);
- startAnimation(0xB8414818, 0, -1);
- setVisible(false);
- _newStickFrameIndex = 0;
- _needRefresh = true;
- loadSound(0, 0x6389B652);
- SetUpdateHandler(&AnimatedSprite::update);
- AnimatedSprite::updatePosition();
-}
-
-uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2808Flow::start() {
- startAnimation(0xB8414818, 0, -1);
- setVisible(true);
- SetMessageHandler(&AsScene2808Flow::hmFlowing);
- NextState(&AsScene2808Flow::stKeepFlowing);
- playSound(0);
-}
-
-void AsScene2808Flow::stKeepFlowing() {
- startAnimation(0xB8414818, 1, -1);
- NextState(&AsScene2808Flow::stKeepFlowing);
-}
-
-AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum)
- : AnimatedSprite(vm, 800), _countdown(1) {
-
- _x = 320;
- _y = 240;
- if (testTubeSetNum == 1)
- setDoDeltaX(1);
- createSurface1(0x804C2404, 800);
- SetUpdateHandler(&AsScene2808LightEffect::update);
- _needRefresh = true;
- AnimatedSprite::updatePosition();
-}
-
-void AsScene2808LightEffect::update() {
- if (_countdown != 0 && (--_countdown) == 0) {
- int16 frameIndex = _vm->_rnd->getRandomNumber(3 - 1);
- startAnimation(0x804C2404, frameIndex, frameIndex);
- updateAnim();
- updatePosition();
- _countdown = _vm->_rnd->getRandomNumber(3 - 1) + 1;
- }
-}
-
Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _testTubeSetNum(which), _leaveResult(0), _isFlowing(false) {
@@ -2466,34 +1614,6 @@ bool Scene2808::isAnyTestTubeFilled() {
_asTestTubes[2]->getFillLevel() > 0;
}
-AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1200) {
-
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2809Spew::handleMessage);
- createSurface1(0x04211490, 1200);
- _x = 262;
- _y = 423;
- setDoDeltaX(0);
- setVisible(false);
-}
-
-uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- playSound(0, 0x48640244);
- startAnimation(0x04211490, 0, -1);
- setVisible(true);
- break;
- case 0x3002:
- stopAnimation();
- setVisible(false);
- break;
- }
- return messageResult;
-}
-
Scene2809::Scene2809(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -2613,34 +1733,6 @@ void Scene2809::findClosestPoint() {
}
-AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
- : AnimatedSprite(vm, 1100) {
-
- createSurface(990, 68, 476);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2810Rope::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- _x = x;
- _y = -276;
- startAnimation(0x9D098C23, 35, 53);
-}
-
-uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- startAnimation(0x9D098C23, 35, 53);
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -2862,101 +1954,6 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 1100) {
-
- createSurface1(0x20DA08A0, 1200);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2812Winch::handleMessage);
- setVisible(false);
- _x = 280;
- _y = 184;
-}
-
-AsScene2812Winch::~AsScene2812Winch() {
- _vm->_soundMan->deleteSoundGroup(0x00B000E2);
-}
-
-uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- startAnimation(0x20DA08A0, 0, -1);
- setVisible(true);
- _vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C);
- _vm->_soundMan->playSoundLooping(0xC874EE6C);
- break;
- case 0x3002:
- startAnimation(0x20DA08A0, 7, -1);
- break;
- }
- return messageResult;
-}
-
-AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
-
- createSurface(990, 68, 476);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene2812Rope::handleMessage);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- startAnimation(0xAE080551, 0, -1);
- _x = 334;
- _y = 201;
-}
-
-uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x4806:
- setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
- stRopingDown();
- break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
- break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
- break;
- }
- return messageResult;
-}
-
-uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene2812Rope::stRopingDown() {
- sendMessage(_parentScene, 0x4806, 0);
- startAnimation(0x9D098C23, 0, -1);
- SetMessageHandler(&AsScene2812Rope::hmRopingDown);
-}
-
-AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
- : AnimatedSprite(vm, 0x805D0029, 100, 320, 240) {
-
- SetMessageHandler(&AsScene2812TrapDoor::handleMessage);
- _newStickFrameIndex = 0;
-}
-
-uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2000:
- startAnimation(0x805D0029, 0, -1);
- playSound(0, 0xEA005F40);
- _newStickFrameIndex = STICK_LAST_FRAME;
- break;
- }
- return messageResult;
-}
-
Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _paletteArea(0) {
diff --git a/engines/neverhood/modules/module2800.h b/engines/neverhood/modules/module2800.h
index 54a9daeb16..26e44bc543 100644
--- a/engines/neverhood/modules/module2800.h
+++ b/engines/neverhood/modules/module2800.h
@@ -70,38 +70,7 @@ protected:
void changeTuneStatus(int prevTuneStatus, int newTuneStatus);
};
-class AsScene2803LightCord : public AnimatedSprite {
-public:
- AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y);
- void stPulled();
- void stIdle();
- void setFileHashes(uint32 fileHash1, uint32 fileHash2);
-protected:
- Scene *_parentScene;
- uint32 _fileHash1, _fileHash2;
- bool _isPulled, _isBusy;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmPulled(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2803TestTubeOne : public AnimatedSprite {
-public:
- AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2);
-protected:
- uint32 _fileHash1, _fileHash2;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2803Rope : public AnimatedSprite {
-public:
- AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmReleased(int messageNum, const MessageParam &param, Entity *sender);
- void stReleased();
- void stHide();
-};
+class AsScene2803LightCord;
class Scene2803 : public Scene {
public:
@@ -158,101 +127,8 @@ protected:
void updatePaletteArea(bool instantly);
};
-class Scene2804;
-
-class SsScene2804RedButton : public StaticSprite {
-public:
- SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene);
-protected:
- Scene2804 *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2804LightCoil : public StaticSprite {
-public:
- SsScene2804LightCoil(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2804BeamCoilBody : public StaticSprite {
-public:
- SsScene2804BeamCoilBody(NeverhoodEngine *vm);
-};
-
-class SsScene2804LightTarget : public StaticSprite {
-public:
- SsScene2804LightTarget(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2804Flash : public StaticSprite {
-public:
- SsScene2804Flash(NeverhoodEngine *vm);
- void show();
-};
-
-class AsScene2804CrystalWaves : public AnimatedSprite {
-public:
- AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex);
- void show();
- void hide();
-protected:
- uint _crystalIndex;
-};
-
-class AsScene2804Crystal : public AnimatedSprite {
-public:
- AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex);
- void show();
- void hide();
- void activate();
- int16 getColorNum() const { return _colorNum; }
-protected:
- AsScene2804CrystalWaves *_asCrystalWaves;
- uint _crystalIndex;
- int16 _colorNum;
- bool _isLightOn;
- bool _isShowing;
-};
-
-class SsScene2804CrystalButton : public StaticSprite {
-public:
- SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex);
-protected:
- Scene2804 *_parentScene;
- AsScene2804Crystal *_asCrystal;
- uint _crystalIndex;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2804BeamCoil : public AnimatedSprite {
-public:
- AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody);
- virtual ~AsScene2804BeamCoil();
-protected:
- Scene *_parentScene;
- SsScene2804BeamCoilBody *_ssBeamCoilBody;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void show();
- void hide();
- void stBeaming();
- uint32 hmBeaming(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2804BeamTarget : public AnimatedSprite {
-public:
- AsScene2804BeamTarget(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene2804Flash;
+class AsScene2804Crystal;
class Scene2804 : public Scene {
public:
@@ -284,13 +160,6 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class AsScene2806Spew : public AnimatedSprite {
-public:
- AsScene2806Spew(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2806 : public Scene {
public:
Scene2806(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -315,63 +184,8 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class SsScene2808Dispenser : public StaticSprite {
-public:
- SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex);
- void startCountdown(int index);
-protected:
- Scene *_parentScene;
- int _countdown;
- int _testTubeSetNum, _testTubeIndex;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808TestTube : public AnimatedSprite {
-public:
- AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser);
- void fill();
- void flush();
- uint32 getFillLevel() const { return _fillLevel; }
-protected:
- SsScene2808Dispenser *_ssDispenser;
- int _testTubeSetNum;
- uint32 _fillLevel;
- int _testTubeIndex;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808Handle : public AnimatedSprite {
-public:
- AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
- void activate();
- void stActivated();
-protected:
- Scene *_parentScene;
- int _testTubeSetNum;
- bool _isActivated;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmActivating(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808Flow : public AnimatedSprite {
-public:
- AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
- void start();
- void stKeepFlowing();
-protected:
- Scene *_parentScene;
- int _testTubeSetNum;
- uint32 hmFlowing(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2808LightEffect : public AnimatedSprite {
-public:
- AsScene2808LightEffect(NeverhoodEngine *vm, int which);
-protected:
- int _countdown;
- void update();
-};
+class AsScene2808Flow;
+class AsScene2808TestTube;
class Scene2808 : public Scene {
public:
@@ -389,13 +203,6 @@ protected:
bool isAnyTestTubeFilled();
};
-class AsScene2809Spew : public AnimatedSprite {
-public:
- AsScene2809Spew(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2809 : public Scene {
public:
Scene2809(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -413,14 +220,6 @@ protected:
void findClosestPoint();
};
-class AsScene2810Rope : public AnimatedSprite {
-public:
- AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2810 : public Scene {
public:
Scene2810(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -440,31 +239,6 @@ protected:
void insertKlaymenLadder();
};
-class AsScene2812Winch : public AnimatedSprite {
-public:
- AsScene2812Winch(NeverhoodEngine *vm);
- virtual ~AsScene2812Winch();
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene2812Rope : public AnimatedSprite {
-public:
- AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene);
-protected:
- Scene *_parentScene;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmRopingDown(int messageNum, const MessageParam &param, Entity *sender);
- void stRopingDown();
-};
-
-class AsScene2812TrapDoor : public AnimatedSprite {
-public:
- AsScene2812TrapDoor(NeverhoodEngine *vm);
-protected:
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
class Scene2812 : public Scene {
public:
Scene2812(NeverhoodEngine *vm, Module *parentModule, int which);
diff --git a/engines/neverhood/modules/module2800_sprites.cpp b/engines/neverhood/modules/module2800_sprites.cpp
new file mode 100644
index 0000000000..a600c55dd3
--- /dev/null
+++ b/engines/neverhood/modules/module2800_sprites.cpp
@@ -0,0 +1,1626 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2800.h"
+#include "neverhood/modules/module2800_sprites.h"
+
+namespace Neverhood {
+
+AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _fileHash1(fileHash1), _fileHash2(fileHash2),
+ _isPulled(false), _isBusy(false) {
+
+ createSurface(1010, 28, 379);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ _x = x;
+ _y = y;
+ stIdle();
+}
+
+uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) {
+ sendMessage(_parentScene, 0x480F, 0);
+ playSound(0, 0x4E1CA4A0);
+ }
+ break;
+ case 0x480F:
+ stPulled();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2803LightCord::stPulled() {
+ _isBusy = false;
+ _isPulled = true;
+ startAnimation(_fileHash2, 0, -1);
+ SetMessageHandler(&AsScene2803LightCord::hmPulled);
+ NextState(&AsScene2803LightCord::stIdle);
+}
+
+void AsScene2803LightCord::stIdle() {
+ _isPulled = false;
+ startAnimation(_fileHash1, 0, -1);
+ SetMessageHandler(&AsScene2803LightCord::handleMessage);
+}
+
+void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) {
+ _fileHash1 = fileHash1;
+ _fileHash2 = fileHash2;
+ if (_isPulled) {
+ startAnimation(_fileHash2, _currFrameIndex, -1);
+ _isBusy = true;
+ } else {
+ startAnimation(_fileHash1, 0, -1);
+ }
+}
+
+AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2)
+ : AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) {
+
+ createSurface1(fileHash1, 100);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2803TestTubeOne::handleMessage);
+ _x = 529;
+ _y = 326;
+}
+
+uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ if (param.asInteger())
+ startAnimation(_fileHash2, 0, -1);
+ else
+ startAnimation(_fileHash1, 0, -1);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(990, 68, 476);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ SetMessageHandler(&AsScene2803Rope::handleMessage);
+ startAnimation(0x9D098C23, 35, 53);
+ NextState(&AsScene2803Rope::stReleased);
+ _x = x;
+ _y = -276;
+}
+
+uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(0x9D098C23, 50, -1);
+ SetMessageHandler(&AsScene2803Rope::hmReleased);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2803Rope::stReleased() {
+ startAnimation(0x8258A030, 0, 1);
+ NextState(&AsScene2803Rope::stHide);
+}
+
+void AsScene2803Rope::stHide() {
+ stopAnimation();
+ setVisible(false);
+}
+
+SsScene2804RedButton::SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene)
+ : StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene) {
+
+ loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? 0x51A10202 : 0x11814A21, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ SetUpdateHandler(&SsScene2804RedButton::update);
+ SetMessageHandler(&SsScene2804RedButton::handleMessage);
+ loadSound(0, 0x44241240);
+}
+
+void SsScene2804RedButton::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_parentScene->isWorking()) {
+ playSound(0);
+ setVisible(true);
+ _countdown = 4;
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+ SetMessageHandler(&SsScene2804LightCoil::handleMessage);
+}
+
+uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ setVisible(true);
+ updatePosition();
+ messageResult = 1;
+ break;
+ case 0x2003:
+ setVisible(false);
+ updatePosition();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+ SetMessageHandler(&SsScene2804LightTarget::handleMessage);
+}
+
+uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ setVisible(true);
+ updatePosition();
+ messageResult = 1;
+ break;
+ case 0x2005:
+ setVisible(false);
+ updatePosition();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+ loadSound(0, 0xCB36BA54);
+}
+
+void SsScene2804Flash::show() {
+ setVisible(true);
+ updatePosition();
+ playSound(0);
+}
+
+SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400);
+ setVisible(false);
+}
+
+AsScene2804CrystalWaves::AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex)
+ : AnimatedSprite(vm, 1100), _crystalIndex(crystalIndex) {
+
+ static const NPoint kAsScene2804CrystalWavesPoints[] = {
+ {323, 245},
+ {387, 76},
+ {454, 260},
+ {527, 70}
+ };
+
+ _x = kAsScene2804CrystalWavesPoints[crystalIndex].x;
+ _y = kAsScene2804CrystalWavesPoints[crystalIndex].y;
+ createSurface1(0x840C41F0, 1200);
+ if (crystalIndex & 1)
+ setDoDeltaY(1);
+ setVisible(false);
+ _needRefresh = true;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Sprite::handleMessage);
+}
+
+void AsScene2804CrystalWaves::show() {
+ setVisible(true);
+ startAnimation(0x840C41F0, 0, -1);
+}
+
+void AsScene2804CrystalWaves::hide() {
+ setVisible(false);
+ stopAnimation();
+}
+
+static const int16 kAsScene2804CrystalFrameNums[] = {
+ 0, 6, 2, 8, 1, 10, 0, 0
+};
+
+static const uint32 kAsScene2804CrystalFileHashes[] = {
+ 0x000540B0,
+ 0x001280D0,
+ 0x003D0010,
+ 0x00620190,
+ 0x00DC0290
+};
+
+AsScene2804Crystal::AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex)
+ : AnimatedSprite(vm, 1100), _asCrystalWaves(asCrystalWaves), _crystalIndex(crystalIndex), _isShowing(false) {
+
+ static const NPoint kAsScene2804CrystalPoints[] = {
+ {204, 196},
+ {272, 316},
+ {334, 206},
+ {410, 334},
+ {470, 180}
+ };
+
+ _colorNum = (int16)getSubVar(VA_CURR_CRYSTAL_COLORS, crystalIndex);
+ _isLightOn = getGlobalVar(V_SHRINK_LIGHTS_ON) != 0;
+ if (_isLightOn) {
+ _x = kAsScene2804CrystalPoints[crystalIndex].x;
+ _y = kAsScene2804CrystalPoints[crystalIndex].y;
+ createSurface1(0x108DFB12, 1200);
+ startAnimation(0x108DFB12, kAsScene2804CrystalFrameNums[_colorNum], -1);
+ _needRefresh = true;
+ _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
+ } else {
+ _x = 320;
+ _y = 240;
+ createSurface1(kAsScene2804CrystalFileHashes[crystalIndex], 1200);
+ startAnimation(kAsScene2804CrystalFileHashes[crystalIndex], _colorNum, -1);
+ setVisible(false);
+ _needRefresh = true;
+ _newStickFrameIndex = _colorNum;
+ }
+ loadSound(0, 0x725294D4);
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene2804Crystal::show() {
+ if (!_isLightOn) {
+ setVisible(true);
+ _isShowing = true;
+ if (_asCrystalWaves)
+ _asCrystalWaves->show();
+ playSound(0);
+ }
+}
+
+void AsScene2804Crystal::hide() {
+ if (!_isLightOn) {
+ setVisible(false);
+ _isShowing = false;
+ if (_asCrystalWaves)
+ _asCrystalWaves->hide();
+ }
+}
+
+void AsScene2804Crystal::activate() {
+ if (!_isShowing) {
+ int16 frameNum = kAsScene2804CrystalFrameNums[_colorNum];
+ _colorNum++;
+ if (_colorNum >= 6)
+ _colorNum = 0;
+ if (_isLightOn) {
+ startAnimation(0x108DFB12, frameNum, kAsScene2804CrystalFrameNums[_colorNum]);
+ _playBackwards = kAsScene2804CrystalFrameNums[_colorNum] < _colorNum;
+ _newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum];
+ } else {
+ startAnimation(kAsScene2804CrystalFileHashes[_crystalIndex], _colorNum, -1);
+ _newStickFrameIndex = _colorNum;
+ }
+ setSubVar(VA_CURR_CRYSTAL_COLORS, _crystalIndex, _colorNum);
+ }
+}
+
+SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex)
+ : StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene), _asCrystal(asCrystal), _crystalIndex(crystalIndex) {
+
+ static const uint32 kSsScene2804CrystalButtonFileHashes1[] = {
+ 0x911101B0,
+ 0x22226001,
+ 0x4444A362,
+ 0x888925A4,
+ 0x11122829
+ };
+
+ static const uint32 kSsScene2804CrystalButtonFileHashes2[] = {
+ 0xB500A1A0,
+ 0x6A012021,
+ 0xD4022322,
+ 0xA8042525,
+ 0x5008292B
+ };
+
+ loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex],
+ kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44045140);
+ SetUpdateHandler(&SsScene2804CrystalButton::update);
+ SetMessageHandler(&SsScene2804CrystalButton::handleMessage);
+}
+
+void SsScene2804CrystalButton::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0 && !_parentScene->isWorking()) {
+ playSound(0);
+ setVisible(true);
+ _countdown = 4;
+ _asCrystal->activate();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody)
+ : AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) {
+
+ createSurface1(0x00494891, 1000);
+ _x = 125;
+ _y = 184;
+ setVisible(false);
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+ loadSound(0, 0x6352F051);
+ _vm->_soundMan->addSound(0xC5EA0B28, 0xEF56B094);
+ SetUpdateHandler(&AsScene2804BeamCoil::update);
+ SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
+}
+
+AsScene2804BeamCoil::~AsScene2804BeamCoil() {
+ _vm->_soundMan->deleteSoundGroup(0xC5EA0B28);
+}
+
+void AsScene2804BeamCoil::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ sendMessage(_parentScene, 0x2001, 0);
+ }
+}
+
+uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ show();
+ _countdown = 92;
+ messageResult = 1;
+ break;
+ case 0x2003:
+ hide();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2804BeamCoil::show() {
+ _ssBeamCoilBody->setVisible(true);
+ setVisible(true);
+ startAnimation(0x00494891, 0, -1);
+ playSound(0);
+ SetMessageHandler(&AsScene2804BeamCoil::hmBeaming);
+ NextState(&AsScene2804BeamCoil::stBeaming);
+}
+
+void AsScene2804BeamCoil::hide() {
+ stopAnimation();
+ SetMessageHandler(&AsScene2804BeamCoil::handleMessage);
+ setVisible(false);
+ _ssBeamCoilBody->setVisible(false);
+ _vm->_soundMan->stopSound(0xEF56B094);
+}
+
+void AsScene2804BeamCoil::stBeaming() {
+ startAnimation(0x00494891, 93, -1);
+ NextState(&AsScene2804BeamCoil::stBeaming);
+ _vm->_soundMan->playSoundLooping(0xEF56B094);
+}
+
+uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1400) {
+
+ createSurface1(0x03842000, 1000);
+ _x = 475;
+ _y = 278;
+ setVisible(false);
+ _needRefresh = true;
+ updatePosition();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2804BeamTarget::handleMessage);
+}
+
+uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2004:
+ setVisible(true);
+ startAnimation(0x03842000, 0, -1);
+ messageResult = 1;
+ break;
+ case 0x2005:
+ setVisible(false);
+ stopAnimation();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ createSurface1(0x04211490, 1200);
+ _x = 378;
+ _y = 423;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2806Spew::handleMessage);
+ setDoDeltaX(1);
+ setVisible(false);
+}
+
+uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ playSound(0, 0x48640244);
+ startAnimation(0x04211490, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+static const uint32 kScene2808FileHashes1[] = {
+ 0x90B0392,
+ 0x90B0192
+};
+
+static const uint32 kScene2808FileHashes2[] = {
+ 0xB0396098,
+ 0xB0196098
+};
+
+static const uint32 kClass428FileHashes[] = {
+ 0x140022CA,
+ 0x4C30A602,
+ 0xB1633402,
+ 0x12982135,
+ 0x0540B728,
+ 0x002A81E3,
+ 0x08982841,
+ 0x10982841,
+ 0x20982841,
+ 0x40982841,
+ 0x80982841,
+ 0x40800711
+};
+
+static const int kClass428Countdowns1[] = {
+ 18, 16, 10, 0
+};
+
+static const int kClass428Countdowns2[] = {
+ 9, 9, 8, 8, 5, 5, 0, 0
+};
+
+static const uint32 kClass490FileHashes[] = {
+ 0x08100071,
+ 0x24084215,
+ 0x18980A10
+};
+
+static const int16 kClass490FrameIndices1[] = {
+ 0, 8, 15, 19
+};
+
+static const int16 kClass490FrameIndices2[] = {
+ 0, 4, 8, 11, 15, 17, 19, 0
+};
+
+SsScene2808Dispenser::SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _testTubeSetNum(testTubeSetNum),
+ _testTubeIndex(testTubeIndex) {
+
+ loadSprite(kClass428FileHashes[testTubeSetNum * 3 + testTubeIndex], kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1500);
+ setVisible(false);
+ SetUpdateHandler(&SsScene2808Dispenser::update);
+ SetMessageHandler(&SsScene2808Dispenser::handleMessage);
+}
+
+void SsScene2808Dispenser::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ sendMessage(_parentScene, 0x2000, _testTubeIndex);
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene2808Dispenser::startCountdown(int index) {
+ setVisible(true);
+ updatePosition();
+ if (_testTubeSetNum == 0) {
+ _countdown = kClass428Countdowns1[index];
+ } else {
+ _countdown = kClass428Countdowns2[index];
+ }
+}
+
+AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser)
+ : AnimatedSprite(vm, 1100), _testTubeSetNum(testTubeSetNum), _testTubeIndex(testTubeIndex), _ssDispenser(ssDispenser), _fillLevel(0) {
+
+ if (testTubeSetNum == 0) {
+ _x = 504;
+ _y = 278;
+ } else {
+ setDoDeltaX(1);
+ _x = 136;
+ _y = 278;
+ }
+
+ createSurface1(kClass490FileHashes[testTubeIndex], 1100);
+
+ if (testTubeSetNum == 0) {
+ loadSound(0, 0x30809E2D);
+ loadSound(1, 0x72811E2D);
+ loadSound(2, 0x78B01625);
+ } else {
+ loadSound(3, 0x70A41E0C);
+ loadSound(4, 0x50205E2D);
+ loadSound(5, 0xF8621E2D);
+ loadSound(6, 0xF1A03C2D);
+ loadSound(7, 0x70A43D2D);
+ loadSound(8, 0xF0601E2D);
+ }
+
+ startAnimation(kClass490FileHashes[testTubeIndex], 0, -1);
+ _newStickFrameIndex = 0;
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2808TestTube::handleMessage);
+
+ if (_fillLevel == 0)
+ setVisible(false);
+
+}
+
+uint32 AsScene2808TestTube::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ fill();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2808TestTube::fill() {
+ if ((int)_fillLevel < _testTubeSetNum * 3 + 3) {
+ if (_testTubeSetNum == 0) {
+ playSound(_fillLevel);
+ setVisible(true);
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], kClass490FrameIndices1[_fillLevel + 1]);
+ _newStickFrameIndex = kClass490FrameIndices1[_fillLevel + 1];
+ } else {
+ playSound(3 + _fillLevel);
+ setVisible(true);
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], kClass490FrameIndices2[_fillLevel + 1]);
+ _newStickFrameIndex = kClass490FrameIndices2[_fillLevel + 1];
+ }
+ _ssDispenser->startCountdown(_fillLevel);
+ _fillLevel++;
+ }
+}
+
+void AsScene2808TestTube::flush() {
+ if (_fillLevel != 0) {
+ if (_testTubeSetNum == 0) {
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], -1);
+ } else {
+ startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], -1);
+ }
+ _newStickFrameIndex = 0;
+ _playBackwards = true;
+ setVisible(true);
+ }
+}
+
+AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
+ : AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) {
+
+ loadSound(0, 0xE18D1F30);
+ _x = 320;
+ _y = 240;
+ if (_testTubeSetNum == 1)
+ setDoDeltaX(1);
+ createSurface1(0x040900D0, 1300);
+ startAnimation(0x040900D0, 0, -1);
+ _needRefresh = true;
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2808Handle::handleMessage);
+ AnimatedSprite::updatePosition();
+}
+
+uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isActivated) {
+ sendMessage(_parentScene, 0x2001, 0);
+ playSound(0);
+ activate();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2808Handle::activate() {
+ startAnimation(0x040900D0, 0, -1);
+ SetMessageHandler(&AsScene2808Handle::hmActivating);
+ NextState(&AsScene2808Handle::stActivated);
+ _isActivated = true;
+ _newStickFrameIndex = -1;
+}
+
+void AsScene2808Handle::stActivated() {
+ stopAnimation();
+ sendMessage(_parentScene, 0x2002, 0);
+}
+
+AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum) {
+
+ if (testTubeSetNum == 0) {
+ _x = 312;
+ _y = 444;
+ } else {
+ _x = 328;
+ _y = 444;
+ }
+ createSurface1(0xB8414818, 1200);
+ startAnimation(0xB8414818, 0, -1);
+ setVisible(false);
+ _newStickFrameIndex = 0;
+ _needRefresh = true;
+ loadSound(0, 0x6389B652);
+ SetUpdateHandler(&AnimatedSprite::update);
+ AnimatedSprite::updatePosition();
+}
+
+uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2808Flow::start() {
+ startAnimation(0xB8414818, 0, -1);
+ setVisible(true);
+ SetMessageHandler(&AsScene2808Flow::hmFlowing);
+ NextState(&AsScene2808Flow::stKeepFlowing);
+ playSound(0);
+}
+
+void AsScene2808Flow::stKeepFlowing() {
+ startAnimation(0xB8414818, 1, -1);
+ NextState(&AsScene2808Flow::stKeepFlowing);
+}
+
+AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum)
+ : AnimatedSprite(vm, 800), _countdown(1) {
+
+ _x = 320;
+ _y = 240;
+ if (testTubeSetNum == 1)
+ setDoDeltaX(1);
+ createSurface1(0x804C2404, 800);
+ SetUpdateHandler(&AsScene2808LightEffect::update);
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+}
+
+void AsScene2808LightEffect::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ int16 frameIndex = _vm->_rnd->getRandomNumber(3 - 1);
+ startAnimation(0x804C2404, frameIndex, frameIndex);
+ updateAnim();
+ updatePosition();
+ _countdown = _vm->_rnd->getRandomNumber(3 - 1) + 1;
+ }
+}
+
+AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1200) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2809Spew::handleMessage);
+ createSurface1(0x04211490, 1200);
+ _x = 262;
+ _y = 423;
+ setDoDeltaX(0);
+ setVisible(false);
+}
+
+uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ playSound(0, 0x48640244);
+ startAnimation(0x04211490, 0, -1);
+ setVisible(true);
+ break;
+ case 0x3002:
+ stopAnimation();
+ setVisible(false);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(990, 68, 476);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2810Rope::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ _x = x;
+ _y = -276;
+ startAnimation(0x9D098C23, 35, 53);
+}
+
+uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ startAnimation(0x9D098C23, 35, 53);
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface1(0x20DA08A0, 1200);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2812Winch::handleMessage);
+ setVisible(false);
+ _x = 280;
+ _y = 184;
+}
+
+AsScene2812Winch::~AsScene2812Winch() {
+ _vm->_soundMan->deleteSoundGroup(0x00B000E2);
+}
+
+uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ startAnimation(0x20DA08A0, 0, -1);
+ setVisible(true);
+ _vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C);
+ _vm->_soundMan->playSoundLooping(0xC874EE6C);
+ break;
+ case 0x3002:
+ startAnimation(0x20DA08A0, 7, -1);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(990, 68, 476);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2812Rope::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ startAnimation(0xAE080551, 0, -1);
+ _x = 334;
+ _y = 201;
+}
+
+uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4806:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ stRopingDown();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2812Rope::stRopingDown() {
+ sendMessage(_parentScene, 0x4806, 0);
+ startAnimation(0x9D098C23, 0, -1);
+ SetMessageHandler(&AsScene2812Rope::hmRopingDown);
+}
+
+AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 0x805D0029, 100, 320, 240) {
+
+ SetMessageHandler(&AsScene2812TrapDoor::handleMessage);
+ _newStickFrameIndex = 0;
+}
+
+uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ startAnimation(0x805D0029, 0, -1);
+ playSound(0, 0xEA005F40);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2801::KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2801::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2803::KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+ _dataResource.load(0x00900849);
+}
+
+uint32 KmScene2803::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrab);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 3)
+ GotoState(&Klaymen::stFinishGrow);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else
+ GotoState(&Klaymen::stWonderAboutHalf);
+ break;
+ case 0x482E:
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4838:
+ GotoState(&Klaymen::stJumpToGrabRelease);
+ break;
+ }
+ return 0;
+}
+
+KmScene2803Small::KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _dataResource.load(0x81120132);
+}
+
+uint32 KmScene2803Small::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToXSmall(param.asPoint().x);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stStandIdleSmall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfterSmall);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalfSmall);
+ else
+ GotoState(&Klaymen::stWonderAboutSmall);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStepSmall);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stWalkToFront2Small);
+ else
+ GotoState(&Klaymen::stWalkToFrontSmall);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToBackHalfSmall);
+ else if (param.asInteger() == 2)
+ GotoState(&Klaymen::stTurnToBackWalkSmall);
+ else
+ GotoState(&Klaymen::stTurnToBackSmall);
+ break;
+ case 0x4830:
+ GotoState(&KmScene2803Small::stShrink);
+ break;
+ }
+ return 0;
+}
+
+uint32 KmScene2803Small::hmShrink(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x80C110B5)
+ sendMessage(_parentScene, 0x482A, 0);
+ else if (param.asInteger() == 0x33288344)
+ playSound(2, 0x10688664);
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2803Small::stShrink() {
+ _busyStatus = 0;
+ _acceptInput = false;
+ playSound(0, 0x4C69EA53);
+ startAnimation(0x1AE88904, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene2803Small::hmShrink);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+}
+
+KmScene2805::KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2805::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481D:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case 0x481E:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stReturnFromUseInTeleporter);
+ break;
+ case 0x4834:
+ GotoState(&Klaymen::stStepOver);
+ break;
+ case 0x4835:
+ sendMessage(_parentScene, 0x2000, 1);
+ _isSittingInTeleporter = true;
+ GotoState(&Klaymen::stSitInTeleporter);
+ break;
+ case 0x4836:
+ sendMessage(_parentScene, 0x2000, 0);
+ _isSittingInTeleporter = false;
+ GotoState(&Klaymen::stGetUpFromTeleporter);
+ break;
+ case 0x483D:
+ teleporterAppear(0xDE284B74);
+ break;
+ case 0x483E:
+ teleporterDisappear(0xD82A4094);
+ break;
+ }
+ return messageResult;
+}
+
+KmScene2806::KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ if (needsLargeSurface) {
+ NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
+ delete _surface;
+ createSurface(1000, dimensions.width, dimensions.height);
+ loadSound(3, 0x58E0C341);
+ loadSound(4, 0x40A00342);
+ loadSound(5, 0xD0A1C348);
+ loadSound(6, 0x166FC6E0);
+ loadSound(7, 0x00018040);
+ }
+
+ _dataResource.load(0x98182003);
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2806::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(440, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4831:
+ GotoState(&Klaymen::stGrow);
+ break;
+ case 0x4832:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stDrinkPotion);
+ else
+ GotoState(&Klaymen::stUseTube);
+ break;
+ }
+ return 0;
+}
+
+KmScene2809::KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ if (needsLargeSurface) {
+ NDimensions dimensions = _animResource.loadSpriteDimensions(0x2838C010);
+ delete _surface;
+ createSurface(1000, dimensions.width, dimensions.height);
+ loadSound(3, 0x58E0C341);
+ loadSound(4, 0x40A00342);
+ loadSound(5, 0xD0A1C348);
+ loadSound(6, 0x166FC6E0);
+ loadSound(7, 0x00018040);
+ }
+
+ _dataResource.load(0x1830009A);
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2809::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(226, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stPressButtonSide);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4831:
+ GotoState(&Klaymen::stGrow);
+ break;
+ case 0x4832:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stDrinkPotion);
+ else
+ GotoState(&Klaymen::stUseTube);
+ break;
+ }
+ return 0;
+}
+
+KmScene2810Small::KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2810Small::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToXSmall(param.asPoint().x);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stStandIdleSmall);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToXSmall(_dataResource.getPoint(param.asInteger()).x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfterSmall);
+ else if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalfSmall);
+ else
+ GotoState(&Klaymen::stWonderAboutSmall);
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStepSmall);
+ else
+ GotoState(&Klaymen::stWalkToFrontSmall);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToBackHalfSmall);
+ else
+ GotoState(&Klaymen::stTurnToBackSmall);
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2810::KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, uint clipRectsCount)
+ : Klaymen(vm, parentScene, x, y) {
+
+ _surface->setClipRects(clipRects, clipRectsCount);
+}
+
+uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrab);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 3)
+ GotoState(&Klaymen::stFinishGrow);
+ break;
+ case 0x4812:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0)
+ GotoState(&Klaymen::stWonderAboutHalf);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWonderAboutAfter);
+ else if (param.asInteger() == 3)
+ GotoState(&Klaymen::stTurnToUseHalf);
+ else if (param.asInteger() == 4)
+ GotoState(&Klaymen::stTurnAwayFromUse);
+ else if (param.asInteger() == 5)
+ GotoState(&Klaymen::stTurnToUseExt);
+ else
+ GotoState(&Klaymen::stWonderAbout);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2000, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x4824:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4825:
+ sendMessage(_parentScene, 0x2000, 0);
+ _destY = _dataResource.getPoint(param.asInteger()).y;
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x4837:
+ stopWalking();
+ break;
+ }
+ return 0;
+}
+
+KmScene2812::KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : Klaymen(vm, parentScene, x, y) {
+
+ // Empty
+}
+
+uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4805:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrabFall);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klaymen::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ startWalkToXDistance(param.asPoint().y, param.asPoint().x);
+ else
+ startWalkToAttachedSpriteXDistance(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2002, 0);
+ GotoState(&Klaymen::stClimbLadderHalf);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stWalkToFrontNoStep);
+ else
+ GotoState(&Klaymen::stWalkToFront);
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stTurnToFront);
+ else
+ GotoState(&Klaymen::stTurnToBack);
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2800_sprites.h b/engines/neverhood/modules/module2800_sprites.h
new file mode 100644
index 0000000000..91f26d7849
--- /dev/null
+++ b/engines/neverhood/modules/module2800_sprites.h
@@ -0,0 +1,337 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2800_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2800_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsScene2803LightCord : public AnimatedSprite {
+public:
+ AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y);
+ void stPulled();
+ void stIdle();
+ void setFileHashes(uint32 fileHash1, uint32 fileHash2);
+protected:
+ Scene *_parentScene;
+ uint32 _fileHash1, _fileHash2;
+ bool _isPulled, _isBusy;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmPulled(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2803TestTubeOne : public AnimatedSprite {
+public:
+ AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2);
+protected:
+ uint32 _fileHash1, _fileHash2;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2803Rope : public AnimatedSprite {
+public:
+ AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmReleased(int messageNum, const MessageParam &param, Entity *sender);
+ void stReleased();
+ void stHide();
+};
+
+class Scene2804;
+
+class SsScene2804RedButton : public StaticSprite {
+public:
+ SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene);
+protected:
+ Scene2804 *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2804LightCoil : public StaticSprite {
+public:
+ SsScene2804LightCoil(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2804BeamCoilBody : public StaticSprite {
+public:
+ SsScene2804BeamCoilBody(NeverhoodEngine *vm);
+};
+
+class SsScene2804LightTarget : public StaticSprite {
+public:
+ SsScene2804LightTarget(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2804Flash : public StaticSprite {
+public:
+ SsScene2804Flash(NeverhoodEngine *vm);
+ void show();
+};
+
+class AsScene2804CrystalWaves : public AnimatedSprite {
+public:
+ AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex);
+ void show();
+ void hide();
+protected:
+ uint _crystalIndex;
+};
+
+class AsScene2804Crystal : public AnimatedSprite {
+public:
+ AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex);
+ void show();
+ void hide();
+ void activate();
+ int16 getColorNum() const { return _colorNum; }
+protected:
+ AsScene2804CrystalWaves *_asCrystalWaves;
+ uint _crystalIndex;
+ int16 _colorNum;
+ bool _isLightOn;
+ bool _isShowing;
+};
+
+class SsScene2804CrystalButton : public StaticSprite {
+public:
+ SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex);
+protected:
+ Scene2804 *_parentScene;
+ AsScene2804Crystal *_asCrystal;
+ uint _crystalIndex;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2804BeamCoil : public AnimatedSprite {
+public:
+ AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody);
+ virtual ~AsScene2804BeamCoil();
+protected:
+ Scene *_parentScene;
+ SsScene2804BeamCoilBody *_ssBeamCoilBody;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void show();
+ void hide();
+ void stBeaming();
+ uint32 hmBeaming(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2804BeamTarget : public AnimatedSprite {
+public:
+ AsScene2804BeamTarget(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2806Spew : public AnimatedSprite {
+public:
+ AsScene2806Spew(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2808Dispenser : public StaticSprite {
+public:
+ SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex);
+ void startCountdown(int index);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ int _testTubeSetNum, _testTubeIndex;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808TestTube : public AnimatedSprite {
+public:
+ AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser);
+ void fill();
+ void flush();
+ uint32 getFillLevel() const { return _fillLevel; }
+protected:
+ SsScene2808Dispenser *_ssDispenser;
+ int _testTubeSetNum;
+ uint32 _fillLevel;
+ int _testTubeIndex;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808Handle : public AnimatedSprite {
+public:
+ AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
+ void activate();
+ void stActivated();
+protected:
+ Scene *_parentScene;
+ int _testTubeSetNum;
+ bool _isActivated;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmActivating(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808Flow : public AnimatedSprite {
+public:
+ AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum);
+ void start();
+ void stKeepFlowing();
+protected:
+ Scene *_parentScene;
+ int _testTubeSetNum;
+ uint32 hmFlowing(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2808LightEffect : public AnimatedSprite {
+public:
+ AsScene2808LightEffect(NeverhoodEngine *vm, int which);
+protected:
+ int _countdown;
+ void update();
+};
+
+class AsScene2809Spew : public AnimatedSprite {
+public:
+ AsScene2809Spew(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2810Rope : public AnimatedSprite {
+public:
+ AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2812Winch : public AnimatedSprite {
+public:
+ AsScene2812Winch(NeverhoodEngine *vm);
+ virtual ~AsScene2812Winch();
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2812Rope : public AnimatedSprite {
+public:
+ AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmRopingDown(int messageNum, const MessageParam &param, Entity *sender);
+ void stRopingDown();
+};
+
+class AsScene2812TrapDoor : public AnimatedSprite {
+public:
+ AsScene2812TrapDoor(NeverhoodEngine *vm);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class KmScene2801 : public Klaymen {
+public:
+ KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2803 : public Klaymen {
+public:
+ KmScene2803(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2803Small : public Klaymen {
+public:
+ KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ void stShrink();
+ uint32 hmShrink(int messageNum, const MessageParam &param, Entity *sender);
+
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2805 : public Klaymen {
+public:
+ KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2806 : public Klaymen {
+public:
+ KmScene2806(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2809 : public Klaymen {
+public:
+ KmScene2809(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ bool needsLargeSurface, NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2810Small : public Klaymen {
+public:
+ KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2810 : public Klaymen {
+public:
+ KmScene2810(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y,
+ NRect *clipRects, uint clipRectsCount);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene2812 : public Klaymen {
+public:
+ KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2800_SPRITES_H */
diff --git a/engines/neverhood/modules/module2900.cpp b/engines/neverhood/modules/module2900.cpp
index 9e51001a2e..bb0b69f35d 100644
--- a/engines/neverhood/modules/module2900.cpp
+++ b/engines/neverhood/modules/module2900.cpp
@@ -21,7 +21,7 @@
*/
#include "neverhood/modules/module2900.h"
-#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module2900_sprites.h"
#include "neverhood/modules/module1100.h"
#include "neverhood/modules/module1300.h"
#include "neverhood/modules/module1700.h"
@@ -141,211 +141,6 @@ static const uint32 kScene2901FileHashes2[] = {
0x08030029
};
-static const uint32 kSsScene2901LocationButtonFileHashes[] = {
- 0x2311326A,
- 0x212323AC,
- 0x10098138,
- 0x25213167,
- 0x1119A363,
- 0x94452612,
- 0x39464212,
- 0x01860450,
- 0x53002104,
- 0x58E68412,
- 0x18600300,
- 0xB650A890,
- 0x2452A7C4,
- 0xA0232748,
- 0x08862B02,
- 0x2491E648,
- 0x0010EB46,
- 0x214C8A11,
- 0x16A31921,
- 0x0AC33A00,
- 0x238028AA,
- 0x26737A21,
- 0x063039A8,
- 0x51286C60,
- 0x464006B4,
- 0x42242538,
- 0x20716010,
- 0x4A2000AE,
- 0x225124A6,
- 0x28E82E45,
- 0x58652C04,
- 0xC82210A4,
- 0x62A84060,
- 0xC0693CB4,
- 0x22212C64,
- 0x5034EA71
-};
-
-static const NPoint kSsScene2901LocationButtonPoints[] = {
- {525, 120}, {576, 149}, {587, 205},
- {538, 232}, {484, 205}, {479, 153}
-};
-
-static const uint32 kSsScene2901LocationButtonLightFileHashes1[] = {
- 0x03136246,
- 0x2106216E,
- 0x4025A13A,
- 0x21816927,
- 0x110B2202,
- 0xCC0522B2,
- 0x3CC24258,
- 0x59C600F0,
- 0x534A2480,
- 0x50E61019,
- 0x34400150,
- 0x225BA090,
- 0xB059AFC4,
- 0xE093A741,
- 0x0086BF09,
- 0x3281E760,
- 0xA048AB42,
- 0x20649C01,
- 0x14611904,
- 0x26E33850,
- 0x23A52A68,
- 0xA2733024,
- 0x10203880,
- 0x1B2DE860,
- 0x0644A6EC,
- 0x426E20BC,
- 0x80292014,
- 0x4360B02E,
- 0x22742664,
- 0x98682705,
- 0x0925B82C,
- 0x5C2918A4,
- 0xD2284920,
- 0x41083CA6,
- 0x6824A864,
- 0x50266B10
-};
-
-static const uint32 kSsScene2901LocationButtonLightFileHashes2[] = {
- 0x43C46D4C,
- 0x43C4AD4C,
- 0x43C52D4C,
- 0x43C62D4C,
- 0x43C02D4C,
- 0x43CC2D4C
-};
-
-static const uint32 kSsScene2901BrokenButtonFileHashes[] = {
- 0x3081BD3A,
- 0xD3443003,
- 0x0786A320,
- 0xE3A22029,
- 0x61611814,
- 0x425848E2
-};
-
-static const uint32 kSsScene2901BigButtonFileHashes[] = {
- 0x010D7748,
- 0x9D02019A,
- 0x351A2F43,
- 0x448138E5,
- 0x02788CF0,
- 0x71718024
-};
-
-SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index)
- : StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) {
-
- const NPoint &pt = kSsScene2901LocationButtonPoints[_index];
-
- loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800);
- _collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25);
- setVisible(false);
- loadSound(0, 0x440430C0);
- SetUpdateHandler(&SsScene2901LocationButton::update);
- SetMessageHandler(&SsScene2901LocationButton::handleMessage);
-}
-
-void SsScene2901LocationButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- setVisible(false);
- }
-}
-
-uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0) {
- playSound(0);
- setVisible(true);
- _countdown1 = 4;
- sendMessage(_parentScene, 0x2001, _index);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index)
- : StaticSprite(vm, 900), _index(index) {
-
- loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900);
- setVisible(false);
- loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]);
-}
-
-void SsScene2901LocationButtonLight::show() {
- playSound(0);
- setVisible(true);
- updatePosition();
-}
-
-void SsScene2901LocationButtonLight::hide() {
- setVisible(false);
- updatePosition();
-}
-
-SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
- : StaticSprite(vm, 900) {
-
- loadSprite(kSsScene2901BrokenButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 900);
-}
-
-SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
- : StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
-
- loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
- _collisionBounds.set(62, 94, 322, 350);
- setVisible(false);
- loadSound(0, 0xF3D420C8);
- SetUpdateHandler(&SsScene2901BigButton::update);
- SetMessageHandler(&SsScene2901BigButton::handleMessage);
-}
-
-void SsScene2901BigButton::update() {
- updatePosition();
- if (_countdown1 != 0 && (--_countdown1) == 0) {
- setVisible(false);
- sendMessage(_parentScene, 0x2000, 0);
- }
-}
-
-uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown1 == 0) {
- playSound(0);
- setVisible(true);
- _countdown1 = 4;
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
Scene2901::Scene2901(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _currLocationButtonNum(which), _selectedButtonNum(which),
_currWhirlButtonNum(0), _prevWhirlButtonNum(0), _countdown1(1), _skipCountdown(0), _blinkOn(0) {
diff --git a/engines/neverhood/modules/module2900.h b/engines/neverhood/modules/module2900.h
index 142f39a35c..5f6ed29a12 100644
--- a/engines/neverhood/modules/module2900.h
+++ b/engines/neverhood/modules/module2900.h
@@ -42,41 +42,7 @@ protected:
void updateMusic(bool halfVolume);
};
-class SsScene2901LocationButton : public StaticSprite {
-public:
- SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index);
-protected:
- Scene *_parentScene;
- uint _index;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene2901LocationButtonLight : public StaticSprite {
-public:
- SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index);
- void show();
- void hide();
-protected:
- uint _index;
-};
-
-class SsScene2901BrokenButton : public StaticSprite {
-public:
- SsScene2901BrokenButton(NeverhoodEngine *vm, int which);
-};
-
-class SsScene2901BigButton : public StaticSprite {
-public:
- SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which);
-protected:
- Scene *_parentScene;
- int _which;
- int _countdown1;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene2901LocationButtonLight;
class Scene2901 : public Scene {
public:
diff --git a/engines/neverhood/modules/module2900_sprites.cpp b/engines/neverhood/modules/module2900_sprites.cpp
new file mode 100644
index 0000000000..59780b33a0
--- /dev/null
+++ b/engines/neverhood/modules/module2900_sprites.cpp
@@ -0,0 +1,232 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module2900_sprites.h"
+
+namespace Neverhood {
+
+static const uint32 kSsScene2901LocationButtonFileHashes[] = {
+ 0x2311326A,
+ 0x212323AC,
+ 0x10098138,
+ 0x25213167,
+ 0x1119A363,
+ 0x94452612,
+ 0x39464212,
+ 0x01860450,
+ 0x53002104,
+ 0x58E68412,
+ 0x18600300,
+ 0xB650A890,
+ 0x2452A7C4,
+ 0xA0232748,
+ 0x08862B02,
+ 0x2491E648,
+ 0x0010EB46,
+ 0x214C8A11,
+ 0x16A31921,
+ 0x0AC33A00,
+ 0x238028AA,
+ 0x26737A21,
+ 0x063039A8,
+ 0x51286C60,
+ 0x464006B4,
+ 0x42242538,
+ 0x20716010,
+ 0x4A2000AE,
+ 0x225124A6,
+ 0x28E82E45,
+ 0x58652C04,
+ 0xC82210A4,
+ 0x62A84060,
+ 0xC0693CB4,
+ 0x22212C64,
+ 0x5034EA71
+};
+
+static const NPoint kSsScene2901LocationButtonPoints[] = {
+ {525, 120}, {576, 149}, {587, 205},
+ {538, 232}, {484, 205}, {479, 153}
+};
+
+static const uint32 kSsScene2901LocationButtonLightFileHashes1[] = {
+ 0x03136246,
+ 0x2106216E,
+ 0x4025A13A,
+ 0x21816927,
+ 0x110B2202,
+ 0xCC0522B2,
+ 0x3CC24258,
+ 0x59C600F0,
+ 0x534A2480,
+ 0x50E61019,
+ 0x34400150,
+ 0x225BA090,
+ 0xB059AFC4,
+ 0xE093A741,
+ 0x0086BF09,
+ 0x3281E760,
+ 0xA048AB42,
+ 0x20649C01,
+ 0x14611904,
+ 0x26E33850,
+ 0x23A52A68,
+ 0xA2733024,
+ 0x10203880,
+ 0x1B2DE860,
+ 0x0644A6EC,
+ 0x426E20BC,
+ 0x80292014,
+ 0x4360B02E,
+ 0x22742664,
+ 0x98682705,
+ 0x0925B82C,
+ 0x5C2918A4,
+ 0xD2284920,
+ 0x41083CA6,
+ 0x6824A864,
+ 0x50266B10
+};
+
+static const uint32 kSsScene2901LocationButtonLightFileHashes2[] = {
+ 0x43C46D4C,
+ 0x43C4AD4C,
+ 0x43C52D4C,
+ 0x43C62D4C,
+ 0x43C02D4C,
+ 0x43CC2D4C
+};
+
+static const uint32 kSsScene2901BrokenButtonFileHashes[] = {
+ 0x3081BD3A,
+ 0xD3443003,
+ 0x0786A320,
+ 0xE3A22029,
+ 0x61611814,
+ 0x425848E2
+};
+
+static const uint32 kSsScene2901BigButtonFileHashes[] = {
+ 0x010D7748,
+ 0x9D02019A,
+ 0x351A2F43,
+ 0x448138E5,
+ 0x02788CF0,
+ 0x71718024
+};
+
+SsScene2901LocationButton::SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _index(index), _countdown1(0) {
+
+ const NPoint &pt = kSsScene2901LocationButtonPoints[_index];
+
+ loadSprite(kSsScene2901LocationButtonFileHashes[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 800);
+ _collisionBounds.set(pt.x - 25, pt.y - 25, pt.x + 25, pt.y + 25);
+ setVisible(false);
+ loadSound(0, 0x440430C0);
+ SetUpdateHandler(&SsScene2901LocationButton::update);
+ SetMessageHandler(&SsScene2901LocationButton::handleMessage);
+}
+
+void SsScene2901LocationButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene2901LocationButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0) {
+ playSound(0);
+ setVisible(true);
+ _countdown1 = 4;
+ sendMessage(_parentScene, 0x2001, _index);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene2901LocationButtonLight::SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index)
+ : StaticSprite(vm, 900), _index(index) {
+
+ loadSprite(kSsScene2901LocationButtonLightFileHashes1[which * 6 + index], kSLFDefDrawOffset | kSLFDefPosition, 900);
+ setVisible(false);
+ loadSound(0, kSsScene2901LocationButtonLightFileHashes2[_index]);
+}
+
+void SsScene2901LocationButtonLight::show() {
+ playSound(0);
+ setVisible(true);
+ updatePosition();
+}
+
+void SsScene2901LocationButtonLight::hide() {
+ setVisible(false);
+ updatePosition();
+}
+
+SsScene2901BrokenButton::SsScene2901BrokenButton(NeverhoodEngine *vm, int which)
+ : StaticSprite(vm, 900) {
+
+ loadSprite(kSsScene2901BrokenButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 900);
+}
+
+SsScene2901BigButton::SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _which(which), _countdown1(0) {
+
+ loadSprite(kSsScene2901BigButtonFileHashes[which], kSLFDefDrawOffset | kSLFDefPosition, 400);
+ _collisionBounds.set(62, 94, 322, 350);
+ setVisible(false);
+ loadSound(0, 0xF3D420C8);
+ SetUpdateHandler(&SsScene2901BigButton::update);
+ SetMessageHandler(&SsScene2901BigButton::handleMessage);
+}
+
+void SsScene2901BigButton::update() {
+ updatePosition();
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2000, 0);
+ }
+}
+
+uint32 SsScene2901BigButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown1 == 0) {
+ playSound(0);
+ setVisible(true);
+ _countdown1 = 4;
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module2900_sprites.h b/engines/neverhood/modules/module2900_sprites.h
new file mode 100644
index 0000000000..9f7df502e1
--- /dev/null
+++ b/engines/neverhood/modules/module2900_sprites.h
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE2900_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE2900_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Module2900
+
+class SsScene2901LocationButton : public StaticSprite {
+public:
+ SsScene2901LocationButton(NeverhoodEngine *vm, Scene *parentScene, int which, uint index);
+protected:
+ Scene *_parentScene;
+ uint _index;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene2901LocationButtonLight : public StaticSprite {
+public:
+ SsScene2901LocationButtonLight(NeverhoodEngine *vm, int which, uint index);
+ void show();
+ void hide();
+protected:
+ uint _index;
+};
+
+class SsScene2901BrokenButton : public StaticSprite {
+public:
+ SsScene2901BrokenButton(NeverhoodEngine *vm, int which);
+};
+
+class SsScene2901BigButton : public StaticSprite {
+public:
+ SsScene2901BigButton(NeverhoodEngine *vm, Scene *parentScene, int which);
+protected:
+ Scene *_parentScene;
+ int _which;
+ int _countdown1;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE2900_SPRITES_H */
diff --git a/engines/neverhood/modules/module3000.cpp b/engines/neverhood/modules/module3000.cpp
index ab3c18d1f4..a12776611e 100644
--- a/engines/neverhood/modules/module3000.cpp
+++ b/engines/neverhood/modules/module3000.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module3000.h"
#include "neverhood/gamemodule.h"
#include "neverhood/navigationscene.h"
+#include "neverhood/modules/module3000.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
@@ -415,343 +416,6 @@ static const uint32 kScene3009CannonActionVideos[] = {
0x240A1101 // 14 Lower the cannon
};
-static const uint32 kSsScene3009SymbolEdgesFileHashes[] = {
- 0x618827A0,
- 0xB1A92322
-};
-
-static const uint32 kSsScene3009TargetLineFileHashes[] = {
- 0x4011018C,
- 0x15086623
-};
-
-static const NPoint kAsScene3009SymbolPoints[] = {
- {289, 338},
- {285, 375},
- {284, 419},
- {456, 372},
- {498, 372},
- {541, 372}
-};
-
-static const uint32 kAsScene3009SymbolFileHashes[] = {
- 0x24542582,
- 0x1CD61D96
-};
-
-static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
- 0x24016060,
- 0x21216221,
- 0x486160A0,
- 0x42216422,
- 0x90A16120,
- 0x84216824,
- 0x08017029,
- 0x08217029,
- 0x10014032,
- 0x10214032,
- 0x20012004,
- 0x20212004
-};
-
-static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
- 0x40092024,
- 0x01636002,
- 0x8071E028,
- 0x02A56064,
- 0x00806031,
- 0x052960A8,
- 0x0A116130,
- 0x0A316130,
- 0x14216200,
- 0x14016200,
- 0x28416460,
- 0x28616460
-};
-
-SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
-
- loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- SetUpdateHandler(&SsScene3009FireCannonButton::update);
- SetMessageHandler(&SsScene3009FireCannonButton::handleMessage);
- loadSound(0, 0x3901B44F);
-}
-
-void SsScene3009FireCannonButton::update() {
- updatePosition();
- if (_isClicked && !isSoundPlaying(0)) {
- sendMessage(_parentScene, 0x2000, 0);
- setVisible(false);
- }
-}
-
-uint32 SsScene3009FireCannonButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_isClicked && !_parentScene->isTurning()) {
- _isClicked = true;
- setVisible(true);
- playSound(0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-SsScene3009SymbolEdges::SsScene3009SymbolEdges(NeverhoodEngine *vm, int index)
- : StaticSprite(vm, 1400), _blinkCountdown(0) {
-
- loadSprite(kSsScene3009SymbolEdgesFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
- if (getGlobalVar(V_ROBOT_HIT))
- hide();
- else
- startBlinking();
- SetUpdateHandler(&SsScene3009SymbolEdges::update);
-}
-
-void SsScene3009SymbolEdges::update() {
- if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
- if (_blinkToggle) {
- setVisible(true);
- } else {
- setVisible(false);
- }
- updatePosition();
- _blinkCountdown = 3;
- _blinkToggle = !_blinkToggle;
- }
-}
-
-void SsScene3009SymbolEdges::show() {
- setVisible(true);
- updatePosition();
- _blinkCountdown = 0;
-}
-
-void SsScene3009SymbolEdges::hide() {
- setVisible(false);
- updatePosition();
- _blinkCountdown = 0;
-}
-
-void SsScene3009SymbolEdges::startBlinking() {
- setVisible(true);
- updatePosition();
- _blinkCountdown = 3;
- _blinkToggle = true;
-}
-
-SsScene3009TargetLine::SsScene3009TargetLine(NeverhoodEngine *vm, int index)
- : StaticSprite(vm, 1400) {
-
- loadSprite(kSsScene3009TargetLineFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
- setVisible(false);
-}
-
-void SsScene3009TargetLine::show() {
- setVisible(true);
- updatePosition();
-}
-
-SsScene3009SymbolArrow::SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index)
- : StaticSprite(vm, 1400), _asSymbol(asSymbol), _index(index), _enabled(true), _countdown(0) {
-
- _incrDecr = _index % 2;
-
- createSurface(1200, 33, 31);
- loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefPosition);
- _drawOffset.set(0, 0, 33, 31);
- _collisionBoundsOffset = _drawOffset;
- updateBounds();
- _needRefresh = true;
-
- SetUpdateHandler(&SsScene3009SymbolArrow::update);
- SetMessageHandler(&SsScene3009SymbolArrow::handleMessage);
- loadSound(0, 0x2C852206);
-}
-
-void SsScene3009SymbolArrow::hide() {
- _enabled = false;
- setVisible(false);
-}
-
-void SsScene3009SymbolArrow::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefDrawOffset);
- }
-}
-
-uint32 SsScene3009SymbolArrow::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled && _countdown == 0) {
- _countdown = 2;
- loadSprite(kSsScene3009SymbolArrowFileHashes1[_index], kSLFDefDrawOffset);
- playSound(0);
- sendMessage(_asSymbol, 0x2005, _incrDecr);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3009VerticalIndicator::AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
-
- _x = 300;
- _y = getGlobalVar(V_CANNON_RAISED) ? 52 : 266;
- createSurface1(0xC2463913, 1200);
- _needRefresh = true;
- updatePosition();
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009VerticalIndicator::handleMessage);
-}
-
-void AsScene3009VerticalIndicator::show() {
- startAnimation(0xC2463913, 0, -1);
- setVisible(true);
- updatePosition();
- _enabled = true;
-}
-
-uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled) {
- sendMessage(_parentScene, 0x2002, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
-
- _x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92;
- _y = 150;
- createSurface1(0xC0C12954, 1200);
- _needRefresh = true;
- updatePosition();
- setVisible(false);
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009HorizontalIndicator::handleMessage);
- if (cannonTargetStatus == kCTSRightRobotNoTarget || cannonTargetStatus == kCTSRightRobotIsTarget || cannonTargetStatus == kCTSRightNoRobot) {
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
- _x = 280;
- }
-}
-
-uint32 AsScene3009HorizontalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_enabled) {
- sendMessage(_parentScene, 0x2004, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene3009HorizontalIndicator::suMoveLeft() {
- _x -= 6;
- if (_x < 92) {
- SetSpriteUpdate(NULL);
- _x = 92;
- }
-}
-
-void AsScene3009HorizontalIndicator::suMoveRight() {
- _x += 6;
- if (_x > 533) {
- SetSpriteUpdate(NULL);
- _x = 533;
- }
-}
-
-void AsScene3009HorizontalIndicator::show() {
- startAnimation(0xC0C12954, 0, -1);
- setVisible(true);
- updatePosition();
- _enabled = true;
-}
-
-void AsScene3009HorizontalIndicator::stMoveLeft() {
- _x = 533;
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveLeft);
-}
-
-void AsScene3009HorizontalIndicator::stMoveRight() {
- _x = 330;
- SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
-}
-
-AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) {
-
- _symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition);
-
- _x = kAsScene3009SymbolPoints[_symbolPosition].x;
- _y = kAsScene3009SymbolPoints[_symbolPosition].y;
- createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200);
- startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
- _newStickFrameIndex = _symbolIndex;
- _needRefresh = true;
- updatePosition();
- SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&AsScene3009Symbol::handleMessage);
- _ssArrowPrev = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 0);
- _parentScene->addCollisionSprite(_ssArrowPrev);
- _ssArrowNext = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 1);
- _parentScene->addCollisionSprite(_ssArrowNext);
-}
-
-uint32 AsScene3009Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x2005:
- if (param.asInteger()) {
- if (_symbolIndex == 11)
- _symbolIndex = 0;
- else
- _symbolIndex++;
- } else {
- if (_symbolIndex == 0)
- _symbolIndex = 11;
- else
- _symbolIndex--;
- }
- startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
- _newStickFrameIndex = _symbolIndex;
- setSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition, _symbolIndex);
- if (_symbolPosition / 3 == 0) {
- sendMessage(_parentScene, 0x2001, 0);
- } else {
- sendMessage(_parentScene, 0x2003, 0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void AsScene3009Symbol::hide() {
- _ssArrowPrev->hide();
- _ssArrowNext->hide();
-}
-
Scene3009::Scene3009(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _keepVideo(false), _moveCannonLeftFirst(false),
_isTurning(false), _lockSymbolsPart1Countdown(1), _lockSymbolsPart2Countdown(1) {
@@ -1015,206 +679,6 @@ static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
0x5000A7E8
};
-static const NPoint kAsScene3010DeadBoltPoints[] = {
- {550, 307},
- {564, 415},
- {560, 514}
-};
-
-static const uint32 kAsScene3010DeadBoltFileHashes2[] = {
- 0x181A0042,
- 0x580A08F2,
- 0x18420076
-};
-
-static const uint32 kAsScene3010DeadBoltFileHashes1[] = {
- 0x300E105A,
- 0x804E0052,
- 0x040E485A
-};
-
-SsScene3010DeadBoltButton::SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled)
- : StaticSprite(vm, 900), _parentScene(parentScene), _buttonLocked(false), _countdown1(0), _countdown2(0), _buttonIndex(buttonIndex) {
-
- _buttonEnabled = getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_buttonIndex]) != 0;
- createSurface(400, 88, 95);
- setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
- if (initDisabled)
- disableButton();
- else if (_buttonEnabled)
- _countdown1 = initCountdown * 12 + 1;
- loadSound(0, 0xF4217243);
- loadSound(1, 0x44049000);
- loadSound(2, 0x6408107E);
- SetUpdateHandler(&SsScene3010DeadBoltButton::update);
- SetMessageHandler(&SsScene3010DeadBoltButton::handleMessage);
-}
-
-void SsScene3010DeadBoltButton::update() {
-
- if (_countdown1 != 0 && (--_countdown1 == 0)) {
- playSound(0);
- setVisible(false);
- setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
- }
-
- if (_countdown2 != 0 && (--_countdown2 == 0)) {
- setVisible(true);
- setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
- }
-
-}
-
-uint32 SsScene3010DeadBoltButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (!_buttonLocked && _countdown1 == 0) {
- if (_buttonEnabled) {
- playSound(1);
- playSound(2);
- setVisible(true);
- _buttonLocked = true;
- sendMessage(_parentScene, 0x2000, _buttonIndex);
- } else {
- sendMessage(_parentScene, 0x2002, _buttonIndex);
- }
- _needRefresh = true;
- updatePosition();
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-void SsScene3010DeadBoltButton::disableButton() {
- _buttonLocked = true;
- setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
- setVisible(true);
-}
-
-void SsScene3010DeadBoltButton::setSprite(uint32 fileHash) {
- loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset);
-}
-
-void SsScene3010DeadBoltButton::setCountdown(int count) {
- _countdown2 = count * 18 + 1;
-}
-
-AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked)
- : AnimatedSprite(vm, 1100), _parentScene(parentScene), _boltIndex(boltIndex), _soundToggle(true),
- _unlocked(false), _locked(false), _countdown(0) {
-
- _x = kAsScene3010DeadBoltPoints[_boltIndex].x;
- _y = kAsScene3010DeadBoltPoints[_boltIndex].y;
-
- if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_boltIndex])) {
- createSurface1(kAsScene3010DeadBoltFileHashes1[_boltIndex], 1200);
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- loadSound(0, 0x46005BC4);
- } else {
- createSurface1(kAsScene3010DeadBoltFileHashes2[_boltIndex], 1200);
- startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
- loadSound(0, 0x420073DC);
- loadSound(1, 0x420073DC);
- }
-
- setVisible(false);
- stIdle();
- if (initUnlocked)
- unlock(true);
-
- _needRefresh = true;
- AnimatedSprite::updatePosition();
-
-}
-
-void AsScene3010DeadBolt::update() {
- updateAnim();
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- stDisabled();
- }
-}
-
-uint32 AsScene3010DeadBolt::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-void AsScene3010DeadBolt::stIdle() {
- stopAnimation();
- SetUpdateHandler(&AsScene3010DeadBolt::update);
- SetMessageHandler(&Sprite::handleMessage);
- _locked = false;
-}
-
-void AsScene3010DeadBolt::unlock(bool skipAnim) {
- if (!_unlocked) {
- setVisible(true);
- if (skipAnim) {
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], -1, 0);
- _newStickFrameIndex = STICK_LAST_FRAME;
- } else {
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stIdleMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- playSound(0);
- }
- _unlocked = true;
- loadSound(2, 0x4010C345);
- }
-}
-
-void AsScene3010DeadBolt::stIdleMessage() {
- stopAnimation();
- SetMessageHandler(&Sprite::handleMessage);
- sendMessage(_parentScene, 0x2001, _boltIndex);
-}
-
-void AsScene3010DeadBolt::lock() {
- if (!_locked) {
- _locked = true;
- setVisible(true);
- startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- if (_soundToggle) {
- playSound(0);
- } else {
- playSound(1);
- }
- _soundToggle = !_soundToggle;
- }
-}
-
-void AsScene3010DeadBolt::setCountdown(int count) {
- _countdown = count * 18 + 1;
-}
-
-void AsScene3010DeadBolt::stDisabled() {
- setVisible(true);
- startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
- SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
- FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
- NextState(&AsScene3010DeadBolt::stIdle);
- _playBackwards = true;
- playSound(2);
-}
-
-void AsScene3010DeadBolt::stDisabledMessage() {
- setVisible(false);
- sendMessage(_parentScene, 0x2003, _boltIndex);
-}
-
Scene3010::Scene3010(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _countdown(0), _doorUnlocked(false), _checkUnlocked(false) {
@@ -1317,127 +781,6 @@ uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
-// Scene3011
-
-static const uint32 kAsScene3011SymbolFileHashes[] = {
- 0x00C88050,
- 0x01488050,
- 0x02488050,
- 0x04488050,
- 0x08488050,
- 0x10488050,
- 0x20488050,
- 0x40488050,
- 0x80488050,
- 0x00488051,
- 0x00488052,
- 0x00488054,
- 0x008B0000,
- 0x008D0000,
- 0x00810000,
- 0x00990000,
- 0x00A90000,
- 0x00C90000,
- 0x00090000,
- 0x01890000,
- 0x02890000,
- 0x04890000,
- 0x08890000,
- 0x10890000
-};
-
-SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag)
- : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
-
- loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
- setVisible(false);
- loadSound(0, 0x44061000);
- SetUpdateHandler(&SsScene3011Button::update);
- SetMessageHandler(&SsScene3011Button::handleMessage);
-}
-
-void SsScene3011Button::update() {
- updatePosition();
- if (_countdown != 0 && (--_countdown == 0)) {
- setVisible(false);
- }
-}
-
-uint32 SsScene3011Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = 0;
- StaticSprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1011:
- if (_countdown == 0) {
- setVisible(true);
- _countdown = 4;
- sendMessage(_parentScene, 0x2000, 0);
- playSound(0);
- }
- messageResult = 1;
- break;
- }
- return messageResult;
-}
-
-AsScene3011Symbol::AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol)
- : AnimatedSprite(vm, 1000), _symbolIndex(symbolIndex), _largeSymbol(largeSymbol), _isNoisy(false) {
-
- if (_largeSymbol) {
- _x = 310;
- _y = 200;
- createSurface1(kAsScene3011SymbolFileHashes[_symbolIndex], 1200);
- loadSound(0, 0x6052C60F);
- loadSound(1, 0x6890433B);
- } else {
- _symbolIndex = 12;
- _x = symbolIndex * 39 + 96;
- _y = 225;
- createSurface(1200, 41, 48);
- loadSound(0, 0x64428609);
- loadSound(1, 0x7080023B);
- }
- setVisible(false);
- _needRefresh = true;
- SetUpdateHandler(&AnimatedSprite::update);
-}
-
-void AsScene3011Symbol::show(bool isNoisy) {
- _isNoisy = isNoisy;
- startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
- setVisible(true);
- if (_isNoisy) {
- playSound(1);
- } else {
- playSound(0);
- }
-}
-
-void AsScene3011Symbol::hide() {
- stopAnimation();
- setVisible(false);
-}
-
-void AsScene3011Symbol::stopSymbolSound() {
- if (_isNoisy) {
- stopSound(1);
- } else {
- stopSound(0);
- }
-}
-
-void AsScene3011Symbol::change(int symbolIndex, bool isNoisy) {
- _symbolIndex = symbolIndex;
- _isNoisy = isNoisy;
- startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
- setVisible(true);
- if (_isNoisy) {
- playSound(1);
- } else {
- playSound(0);
- }
-}
-
Scene3011::Scene3011(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _updateStatus(0), _buttonClicked(false), _currentSymbolIndex(0), _countdown(0) {
diff --git a/engines/neverhood/modules/module3000.h b/engines/neverhood/modules/module3000.h
index a6cecb227e..a88dea513e 100644
--- a/engines/neverhood/modules/module3000.h
+++ b/engines/neverhood/modules/module3000.h
@@ -26,7 +26,6 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/modules/module1200.h"
namespace Neverhood {
@@ -41,89 +40,11 @@ protected:
void updateScene();
};
-// Scene3009
-
-class Scene3009;
-
-class SsScene3009FireCannonButton : public StaticSprite {
-public:
- SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene);
-protected:
- Scene3009 *_parentScene;
- bool _isClicked;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class SsScene3009SymbolEdges : public StaticSprite {
-public:
- SsScene3009SymbolEdges(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 SsScene3009TargetLine : public StaticSprite {
-public:
- SsScene3009TargetLine(NeverhoodEngine *vm, int index);
- void show();
-};
-
-class SsScene3009SymbolArrow : public StaticSprite {
-public:
- SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index);
- void hide();
-protected:
- Sprite *_asSymbol;
- int _index;
- int _incrDecr;
- bool _enabled;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3009VerticalIndicator : public AnimatedSprite {
-public:
- AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
- void show();
-protected:
- Scene3009 *_parentScene;
- bool _enabled;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3009HorizontalIndicator : public AnimatedSprite {
-public:
- AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus);
- void show();
- void stMoveLeft();
- void stMoveRight();
-protected:
- Scene3009 *_parentScene;
- bool _enabled;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void suMoveLeft();
- void suMoveRight();
-};
-
-class AsScene3009Symbol : public AnimatedSprite {
-public:
- AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition);
- void hide();
-protected:
- Scene3009 *_parentScene;
- int _symbolPosition;
- uint32 _symbolIndex;
- SsScene3009SymbolArrow *_ssArrowPrev;
- SsScene3009SymbolArrow *_ssArrowNext;
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
+class SsScene3009SymbolEdges;
+class SsScene3009TargetLine;
+class AsScene3009VerticalIndicator;
+class AsScene3009HorizontalIndicator;
+class AsScene3009Symbol;
class Scene3009 : public Scene {
public:
@@ -153,45 +74,8 @@ protected:
void openSmacker(uint32 fileHash, bool keepLastFrame);
};
-// Scene3010
-
-class SsScene3010DeadBoltButton : public StaticSprite {
-public:
- SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled);
- void setCountdown(int count);
-protected:
- Scene *_parentScene;
- int _buttonIndex;
- bool _buttonEnabled;
- bool _buttonLocked;
- int _countdown1;
- int _countdown2;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- void disableButton();
- void setSprite(uint32 fileHash);
-};
-
-class AsScene3010DeadBolt : public AnimatedSprite {
-public:
- AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked);
- void setCountdown(int count);
- void lock();
- void unlock(bool skipAnim);
-protected:
- Scene *_parentScene;
- int _boltIndex;
- int _countdown;
- bool _soundToggle;
- bool _unlocked;
- bool _locked;
- void update();
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- void stIdle();
- void stIdleMessage();
- void stDisabled();
- void stDisabledMessage();
-};
+class SsScene3010DeadBoltButton;
+class AsScene3010DeadBolt;
class Scene3010 : public Scene {
public:
@@ -208,31 +92,7 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-// Scene3011
-
-class SsScene3011Button : public StaticSprite {
-public:
- SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag);
-protected:
- Scene *_parentScene;
- int _countdown;
- void update();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
-};
-
-class AsScene3011Symbol : public AnimatedSprite {
-public:
- AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol);
- void show(bool isNoisy);
- void hide();
- void stopSymbolSound();
- void change(int symbolIndex, bool isNoisy);
- int getSymbolIndex() { return _largeSymbol ? _symbolIndex : _symbolIndex - 12; }
-protected:
- bool _largeSymbol;
- bool _isNoisy;
- int _symbolIndex;
-};
+class AsScene3011Symbol;
class Scene3011 : public Scene {
public:
diff --git a/engines/neverhood/modules/module3000_sprites.cpp b/engines/neverhood/modules/module3000_sprites.cpp
new file mode 100644
index 0000000000..7d0162d7d0
--- /dev/null
+++ b/engines/neverhood/modules/module3000_sprites.cpp
@@ -0,0 +1,763 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/modules/module3000.h"
+#include "neverhood/modules/module3000_sprites.h"
+
+namespace Neverhood {
+
+// Scene3009
+
+enum {
+ kCTSNull = 0,
+ kCTSBreakWall = 1,
+ kCTSWall = 2,
+ kCTSEmptyness = 3,
+ kCTSFireRobotNoTarget = 4,
+ kCTSFireRobotIsTarget = 5,
+ kCTSFireNoRobot = 6,
+ kCTSRaiseCannon = 7,
+ kCTSRightRobotNoTarget = 8,
+ kCTSRightRobotIsTarget = 9,
+ kCTSRightNoRobot = 10,
+ kCTSLeftRobotNoTarget = 11,
+ kCTSLeftRobotIsTarget = 12,
+ kCTSLeftNoRobot = 13,
+ kCTSLowerCannon = 14,
+ kCTSCount = 14
+};
+
+static const uint32 kScene3009CannonScopeVideos[] = {
+ 0x1010000D,
+ 0x340A0049,
+ 0x340A0049,
+ 0x0282081D,
+ 0x0082080D,
+ 0x0882080D,
+ 0x0882080D,
+ 0x0282081D,
+ 0x004B000B,
+ 0x014B000B,
+ 0x044B000B,
+ 0x0282081D,
+ 0x0282081D,
+ 0x0282081D,
+ 0x340A0049
+};
+
+static const uint32 kScene3009CannonActionVideos[] = {
+ 0x00000000,
+ 0x8004001B, // 1 Fire cannon at wall, it breaks (lowered)
+ 0x0004001A, // 2 Fire cannon at wall, nothing happens (lowered)
+ 0x1048404B, // 3 Fire cannon at emptyness (raised)
+ 0x50200109, // 4 Fire cannon, robot missed (raised)
+ 0x12032109, // 5 Fire cannon, robot hit (raised)
+ 0x10201109, // 6 Fire cannon, no robot (raised)
+ 0x000A2030, // 7 Raise the cannon
+ 0x000A0028, // 8
+ 0x000A0028, // 9
+ 0x000A0028, // 10
+ 0x040A1069, // 11
+ 0x040A1069, // 12
+ 0x040A1069, // 13
+ 0x240A1101 // 14 Lower the cannon
+};
+
+static const uint32 kSsScene3009SymbolEdgesFileHashes[] = {
+ 0x618827A0,
+ 0xB1A92322
+};
+
+static const uint32 kSsScene3009TargetLineFileHashes[] = {
+ 0x4011018C,
+ 0x15086623
+};
+
+static const NPoint kAsScene3009SymbolPoints[] = {
+ {289, 338},
+ {285, 375},
+ {284, 419},
+ {456, 372},
+ {498, 372},
+ {541, 372}
+};
+
+static const uint32 kAsScene3009SymbolFileHashes[] = {
+ 0x24542582,
+ 0x1CD61D96
+};
+
+static const uint32 kSsScene3009SymbolArrowFileHashes1[] = {
+ 0x24016060,
+ 0x21216221,
+ 0x486160A0,
+ 0x42216422,
+ 0x90A16120,
+ 0x84216824,
+ 0x08017029,
+ 0x08217029,
+ 0x10014032,
+ 0x10214032,
+ 0x20012004,
+ 0x20212004
+};
+
+static const uint32 kSsScene3009SymbolArrowFileHashes2[] = {
+ 0x40092024,
+ 0x01636002,
+ 0x8071E028,
+ 0x02A56064,
+ 0x00806031,
+ 0x052960A8,
+ 0x0A116130,
+ 0x0A316130,
+ 0x14216200,
+ 0x14016200,
+ 0x28416460,
+ 0x28616460
+};
+
+SsScene3009FireCannonButton::SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _isClicked(false) {
+
+ loadSprite(0x120B24B0, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ SetUpdateHandler(&SsScene3009FireCannonButton::update);
+ SetMessageHandler(&SsScene3009FireCannonButton::handleMessage);
+ loadSound(0, 0x3901B44F);
+}
+
+void SsScene3009FireCannonButton::update() {
+ updatePosition();
+ if (_isClicked && !isSoundPlaying(0)) {
+ sendMessage(_parentScene, 0x2000, 0);
+ setVisible(false);
+ }
+}
+
+uint32 SsScene3009FireCannonButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_isClicked && !_parentScene->isTurning()) {
+ _isClicked = true;
+ setVisible(true);
+ playSound(0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+SsScene3009SymbolEdges::SsScene3009SymbolEdges(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400), _blinkCountdown(0) {
+
+ loadSprite(kSsScene3009SymbolEdgesFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
+ if (getGlobalVar(V_ROBOT_HIT))
+ hide();
+ else
+ startBlinking();
+ SetUpdateHandler(&SsScene3009SymbolEdges::update);
+}
+
+void SsScene3009SymbolEdges::update() {
+ if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
+ if (_blinkToggle) {
+ setVisible(true);
+ } else {
+ setVisible(false);
+ }
+ updatePosition();
+ _blinkCountdown = 3;
+ _blinkToggle = !_blinkToggle;
+ }
+}
+
+void SsScene3009SymbolEdges::show() {
+ setVisible(true);
+ updatePosition();
+ _blinkCountdown = 0;
+}
+
+void SsScene3009SymbolEdges::hide() {
+ setVisible(false);
+ updatePosition();
+ _blinkCountdown = 0;
+}
+
+void SsScene3009SymbolEdges::startBlinking() {
+ setVisible(true);
+ updatePosition();
+ _blinkCountdown = 3;
+ _blinkToggle = true;
+}
+
+SsScene3009TargetLine::SsScene3009TargetLine(NeverhoodEngine *vm, int index)
+ : StaticSprite(vm, 1400) {
+
+ loadSprite(kSsScene3009TargetLineFileHashes[index], kSLFDefDrawOffset | kSLFDefPosition, 600);
+ setVisible(false);
+}
+
+void SsScene3009TargetLine::show() {
+ setVisible(true);
+ updatePosition();
+}
+
+SsScene3009SymbolArrow::SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index)
+ : StaticSprite(vm, 1400), _asSymbol(asSymbol), _index(index), _enabled(true), _countdown(0) {
+
+ _incrDecr = _index % 2;
+
+ createSurface(1200, 33, 31);
+ loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefPosition);
+ _drawOffset.set(0, 0, 33, 31);
+ _collisionBoundsOffset = _drawOffset;
+ updateBounds();
+ _needRefresh = true;
+
+ SetUpdateHandler(&SsScene3009SymbolArrow::update);
+ SetMessageHandler(&SsScene3009SymbolArrow::handleMessage);
+ loadSound(0, 0x2C852206);
+}
+
+void SsScene3009SymbolArrow::hide() {
+ _enabled = false;
+ setVisible(false);
+}
+
+void SsScene3009SymbolArrow::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ loadSprite(kSsScene3009SymbolArrowFileHashes2[_index], kSLFDefDrawOffset);
+ }
+}
+
+uint32 SsScene3009SymbolArrow::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled && _countdown == 0) {
+ _countdown = 2;
+ loadSprite(kSsScene3009SymbolArrowFileHashes1[_index], kSLFDefDrawOffset);
+ playSound(0);
+ sendMessage(_asSymbol, 0x2005, _incrDecr);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3009VerticalIndicator::AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
+
+ _x = 300;
+ _y = getGlobalVar(V_CANNON_RAISED) ? 52 : 266;
+ createSurface1(0xC2463913, 1200);
+ _needRefresh = true;
+ updatePosition();
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009VerticalIndicator::handleMessage);
+}
+
+void AsScene3009VerticalIndicator::show() {
+ startAnimation(0xC2463913, 0, -1);
+ setVisible(true);
+ updatePosition();
+ _enabled = true;
+}
+
+uint32 AsScene3009VerticalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled) {
+ sendMessage(_parentScene, 0x2002, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3009HorizontalIndicator::AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene), _enabled(false) {
+
+ _x = getGlobalVar(V_CANNON_TURNED) ? 533 : 92;
+ _y = 150;
+ createSurface1(0xC0C12954, 1200);
+ _needRefresh = true;
+ updatePosition();
+ setVisible(false);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009HorizontalIndicator::handleMessage);
+ if (cannonTargetStatus == kCTSRightRobotNoTarget || cannonTargetStatus == kCTSRightRobotIsTarget || cannonTargetStatus == kCTSRightNoRobot) {
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
+ _x = 280;
+ }
+}
+
+uint32 AsScene3009HorizontalIndicator::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_enabled) {
+ sendMessage(_parentScene, 0x2004, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3009HorizontalIndicator::suMoveLeft() {
+ _x -= 6;
+ if (_x < 92) {
+ SetSpriteUpdate(NULL);
+ _x = 92;
+ }
+}
+
+void AsScene3009HorizontalIndicator::suMoveRight() {
+ _x += 6;
+ if (_x > 533) {
+ SetSpriteUpdate(NULL);
+ _x = 533;
+ }
+}
+
+void AsScene3009HorizontalIndicator::show() {
+ startAnimation(0xC0C12954, 0, -1);
+ setVisible(true);
+ updatePosition();
+ _enabled = true;
+}
+
+void AsScene3009HorizontalIndicator::stMoveLeft() {
+ _x = 533;
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveLeft);
+}
+
+void AsScene3009HorizontalIndicator::stMoveRight() {
+ _x = 330;
+ SetSpriteUpdate(&AsScene3009HorizontalIndicator::suMoveRight);
+}
+
+AsScene3009Symbol::AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _symbolPosition(symbolPosition) {
+
+ _symbolIndex = getSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition);
+
+ _x = kAsScene3009SymbolPoints[_symbolPosition].x;
+ _y = kAsScene3009SymbolPoints[_symbolPosition].y;
+ createSurface1(kAsScene3009SymbolFileHashes[_symbolPosition / 3], 1200);
+ startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
+ _newStickFrameIndex = _symbolIndex;
+ _needRefresh = true;
+ updatePosition();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene3009Symbol::handleMessage);
+ _ssArrowPrev = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 0);
+ _parentScene->addCollisionSprite(_ssArrowPrev);
+ _ssArrowNext = _parentScene->insertSprite<SsScene3009SymbolArrow>(this, _symbolPosition * 2 + 1);
+ _parentScene->addCollisionSprite(_ssArrowNext);
+}
+
+uint32 AsScene3009Symbol::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2005:
+ if (param.asInteger()) {
+ if (_symbolIndex == 11)
+ _symbolIndex = 0;
+ else
+ _symbolIndex++;
+ } else {
+ if (_symbolIndex == 0)
+ _symbolIndex = 11;
+ else
+ _symbolIndex--;
+ }
+ startAnimation(kAsScene3009SymbolFileHashes[_symbolPosition / 3], _symbolIndex, -1);
+ _newStickFrameIndex = _symbolIndex;
+ setSubVar(VA_CURR_CANNON_SYMBOLS, _symbolPosition, _symbolIndex);
+ if (_symbolPosition / 3 == 0) {
+ sendMessage(_parentScene, 0x2001, 0);
+ } else {
+ sendMessage(_parentScene, 0x2003, 0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3009Symbol::hide() {
+ _ssArrowPrev->hide();
+ _ssArrowNext->hide();
+}
+
+// Scene3010
+
+static const uint32 kScene3010ButtonNameHashes[] = {
+ 0x304008D2,
+ 0x40119852,
+ 0x01180951
+};
+
+static const uint32 kScene3010DeadBoltButtonFileHashes1[] = {
+ 0x301024C2,
+ 0x20280580,
+ 0x30200452
+};
+
+static const uint32 kScene3010DeadBoltButtonFileHashes2[] = {
+ 0x50C025A8,
+ 0x1020A0A0,
+ 0x5000A7E8
+};
+
+static const NPoint kAsScene3010DeadBoltPoints[] = {
+ {550, 307},
+ {564, 415},
+ {560, 514}
+};
+
+static const uint32 kAsScene3010DeadBoltFileHashes2[] = {
+ 0x181A0042,
+ 0x580A08F2,
+ 0x18420076
+};
+
+static const uint32 kAsScene3010DeadBoltFileHashes1[] = {
+ 0x300E105A,
+ 0x804E0052,
+ 0x040E485A
+};
+
+SsScene3010DeadBoltButton::SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled)
+ : StaticSprite(vm, 900), _parentScene(parentScene), _buttonLocked(false), _countdown1(0), _countdown2(0), _buttonIndex(buttonIndex) {
+
+ _buttonEnabled = getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_buttonIndex]) != 0;
+ createSurface(400, 88, 95);
+ setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
+ if (initDisabled)
+ disableButton();
+ else if (_buttonEnabled)
+ _countdown1 = initCountdown * 12 + 1;
+ loadSound(0, 0xF4217243);
+ loadSound(1, 0x44049000);
+ loadSound(2, 0x6408107E);
+ SetUpdateHandler(&SsScene3010DeadBoltButton::update);
+ SetMessageHandler(&SsScene3010DeadBoltButton::handleMessage);
+}
+
+void SsScene3010DeadBoltButton::update() {
+
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ playSound(0);
+ setVisible(false);
+ setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
+ }
+
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ setVisible(true);
+ setSprite(kScene3010DeadBoltButtonFileHashes2[_buttonIndex]);
+ }
+
+}
+
+uint32 SsScene3010DeadBoltButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_buttonLocked && _countdown1 == 0) {
+ if (_buttonEnabled) {
+ playSound(1);
+ playSound(2);
+ setVisible(true);
+ _buttonLocked = true;
+ sendMessage(_parentScene, 0x2000, _buttonIndex);
+ } else {
+ sendMessage(_parentScene, 0x2002, _buttonIndex);
+ }
+ _needRefresh = true;
+ updatePosition();
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void SsScene3010DeadBoltButton::disableButton() {
+ _buttonLocked = true;
+ setSprite(kScene3010DeadBoltButtonFileHashes1[_buttonIndex]);
+ setVisible(true);
+}
+
+void SsScene3010DeadBoltButton::setSprite(uint32 fileHash) {
+ loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset);
+}
+
+void SsScene3010DeadBoltButton::setCountdown(int count) {
+ _countdown2 = count * 18 + 1;
+}
+
+AsScene3010DeadBolt::AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _boltIndex(boltIndex), _soundToggle(true),
+ _unlocked(false), _locked(false), _countdown(0) {
+
+ _x = kAsScene3010DeadBoltPoints[_boltIndex].x;
+ _y = kAsScene3010DeadBoltPoints[_boltIndex].y;
+
+ if (getSubVar(VA_LOCKS_DISABLED, kScene3010ButtonNameHashes[_boltIndex])) {
+ createSurface1(kAsScene3010DeadBoltFileHashes1[_boltIndex], 1200);
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ loadSound(0, 0x46005BC4);
+ } else {
+ createSurface1(kAsScene3010DeadBoltFileHashes2[_boltIndex], 1200);
+ startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
+ loadSound(0, 0x420073DC);
+ loadSound(1, 0x420073DC);
+ }
+
+ setVisible(false);
+ stIdle();
+ if (initUnlocked)
+ unlock(true);
+
+ _needRefresh = true;
+ AnimatedSprite::updatePosition();
+
+}
+
+void AsScene3010DeadBolt::update() {
+ updateAnim();
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ stDisabled();
+ }
+}
+
+uint32 AsScene3010DeadBolt::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene3010DeadBolt::stIdle() {
+ stopAnimation();
+ SetUpdateHandler(&AsScene3010DeadBolt::update);
+ SetMessageHandler(&Sprite::handleMessage);
+ _locked = false;
+}
+
+void AsScene3010DeadBolt::unlock(bool skipAnim) {
+ if (!_unlocked) {
+ setVisible(true);
+ if (skipAnim) {
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], -1, 0);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ } else {
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stIdleMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ playSound(0);
+ }
+ _unlocked = true;
+ loadSound(2, 0x4010C345);
+ }
+}
+
+void AsScene3010DeadBolt::stIdleMessage() {
+ stopAnimation();
+ SetMessageHandler(&Sprite::handleMessage);
+ sendMessage(_parentScene, 0x2001, _boltIndex);
+}
+
+void AsScene3010DeadBolt::lock() {
+ if (!_locked) {
+ _locked = true;
+ setVisible(true);
+ startAnimation(kAsScene3010DeadBoltFileHashes2[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ if (_soundToggle) {
+ playSound(0);
+ } else {
+ playSound(1);
+ }
+ _soundToggle = !_soundToggle;
+ }
+}
+
+void AsScene3010DeadBolt::setCountdown(int count) {
+ _countdown = count * 18 + 1;
+}
+
+void AsScene3010DeadBolt::stDisabled() {
+ setVisible(true);
+ startAnimation(kAsScene3010DeadBoltFileHashes1[_boltIndex], 0, -1);
+ SetMessageHandler(&AsScene3010DeadBolt::hmAnimation);
+ FinalizeState(&AsScene3010DeadBolt::stDisabledMessage);
+ NextState(&AsScene3010DeadBolt::stIdle);
+ _playBackwards = true;
+ playSound(2);
+}
+
+void AsScene3010DeadBolt::stDisabledMessage() {
+ setVisible(false);
+ sendMessage(_parentScene, 0x2003, _boltIndex);
+}
+
+// Scene3011
+
+static const uint32 kAsScene3011SymbolFileHashes[] = {
+ 0x00C88050,
+ 0x01488050,
+ 0x02488050,
+ 0x04488050,
+ 0x08488050,
+ 0x10488050,
+ 0x20488050,
+ 0x40488050,
+ 0x80488050,
+ 0x00488051,
+ 0x00488052,
+ 0x00488054,
+ 0x008B0000,
+ 0x008D0000,
+ 0x00810000,
+ 0x00990000,
+ 0x00A90000,
+ 0x00C90000,
+ 0x00090000,
+ 0x01890000,
+ 0x02890000,
+ 0x04890000,
+ 0x08890000,
+ 0x10890000
+};
+
+SsScene3011Button::SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag)
+ : StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
+
+ loadSprite(flag ? 0x11282020 : 0x994D0433, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
+ setVisible(false);
+ loadSound(0, 0x44061000);
+ SetUpdateHandler(&SsScene3011Button::update);
+ SetMessageHandler(&SsScene3011Button::handleMessage);
+}
+
+void SsScene3011Button::update() {
+ updatePosition();
+ if (_countdown != 0 && (--_countdown == 0)) {
+ setVisible(false);
+ }
+}
+
+uint32 SsScene3011Button::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ StaticSprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_countdown == 0) {
+ setVisible(true);
+ _countdown = 4;
+ sendMessage(_parentScene, 0x2000, 0);
+ playSound(0);
+ }
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+AsScene3011Symbol::AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol)
+ : AnimatedSprite(vm, 1000), _symbolIndex(symbolIndex), _largeSymbol(largeSymbol), _isNoisy(false) {
+
+ if (_largeSymbol) {
+ _x = 310;
+ _y = 200;
+ createSurface1(kAsScene3011SymbolFileHashes[_symbolIndex], 1200);
+ loadSound(0, 0x6052C60F);
+ loadSound(1, 0x6890433B);
+ } else {
+ _symbolIndex = 12;
+ _x = symbolIndex * 39 + 96;
+ _y = 225;
+ createSurface(1200, 41, 48);
+ loadSound(0, 0x64428609);
+ loadSound(1, 0x7080023B);
+ }
+ setVisible(false);
+ _needRefresh = true;
+ SetUpdateHandler(&AnimatedSprite::update);
+}
+
+void AsScene3011Symbol::show(bool isNoisy) {
+ _isNoisy = isNoisy;
+ startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
+ setVisible(true);
+ if (_isNoisy) {
+ playSound(1);
+ } else {
+ playSound(0);
+ }
+}
+
+void AsScene3011Symbol::hide() {
+ stopAnimation();
+ setVisible(false);
+}
+
+void AsScene3011Symbol::stopSymbolSound() {
+ if (_isNoisy) {
+ stopSound(1);
+ } else {
+ stopSound(0);
+ }
+}
+
+void AsScene3011Symbol::change(int symbolIndex, bool isNoisy) {
+ _symbolIndex = symbolIndex;
+ _isNoisy = isNoisy;
+ startAnimation(kAsScene3011SymbolFileHashes[_symbolIndex], 0, -1);
+ setVisible(true);
+ if (_isNoisy) {
+ playSound(1);
+ } else {
+ playSound(0);
+ }
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module3000_sprites.h b/engines/neverhood/modules/module3000_sprites.h
new file mode 100644
index 0000000000..7316613327
--- /dev/null
+++ b/engines/neverhood/modules/module3000_sprites.h
@@ -0,0 +1,185 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE3000_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE3000_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/modules/module1200.h"
+
+namespace Neverhood {
+
+// Scene3009
+
+class Scene3009;
+
+class SsScene3009FireCannonButton : public StaticSprite {
+public:
+ SsScene3009FireCannonButton(NeverhoodEngine *vm, Scene3009 *parentScene);
+protected:
+ Scene3009 *_parentScene;
+ bool _isClicked;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class SsScene3009SymbolEdges : public StaticSprite {
+public:
+ SsScene3009SymbolEdges(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 SsScene3009TargetLine : public StaticSprite {
+public:
+ SsScene3009TargetLine(NeverhoodEngine *vm, int index);
+ void show();
+};
+
+class SsScene3009SymbolArrow : public StaticSprite {
+public:
+ SsScene3009SymbolArrow(NeverhoodEngine *vm, Sprite *asSymbol, int index);
+ void hide();
+protected:
+ Sprite *_asSymbol;
+ int _index;
+ int _incrDecr;
+ bool _enabled;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3009VerticalIndicator : public AnimatedSprite {
+public:
+ AsScene3009VerticalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, int index);
+ void show();
+protected:
+ Scene3009 *_parentScene;
+ bool _enabled;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3009HorizontalIndicator : public AnimatedSprite {
+public:
+ AsScene3009HorizontalIndicator(NeverhoodEngine *vm, Scene3009 *parentScene, uint32 cannonTargetStatus);
+ void show();
+ void stMoveLeft();
+ void stMoveRight();
+protected:
+ Scene3009 *_parentScene;
+ bool _enabled;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suMoveLeft();
+ void suMoveRight();
+};
+
+class AsScene3009Symbol : public AnimatedSprite {
+public:
+ AsScene3009Symbol(NeverhoodEngine *vm, Scene3009 *parentScene, int symbolPosition);
+ void hide();
+protected:
+ Scene3009 *_parentScene;
+ int _symbolPosition;
+ uint32 _symbolIndex;
+ SsScene3009SymbolArrow *_ssArrowPrev;
+ SsScene3009SymbolArrow *_ssArrowNext;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+// Scene3010
+
+class SsScene3010DeadBoltButton : public StaticSprite {
+public:
+ SsScene3010DeadBoltButton(NeverhoodEngine *vm, Scene *parentScene, int buttonIndex, int initCountdown, bool initDisabled);
+ void setCountdown(int count);
+protected:
+ Scene *_parentScene;
+ int _buttonIndex;
+ bool _buttonEnabled;
+ bool _buttonLocked;
+ int _countdown1;
+ int _countdown2;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void disableButton();
+ void setSprite(uint32 fileHash);
+};
+
+class AsScene3010DeadBolt : public AnimatedSprite {
+public:
+ AsScene3010DeadBolt(NeverhoodEngine *vm, Scene *parentScene, int boltIndex, bool initUnlocked);
+ void setCountdown(int count);
+ void lock();
+ void unlock(bool skipAnim);
+protected:
+ Scene *_parentScene;
+ int _boltIndex;
+ int _countdown;
+ bool _soundToggle;
+ bool _unlocked;
+ bool _locked;
+ void update();
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ void stIdle();
+ void stIdleMessage();
+ void stDisabled();
+ void stDisabledMessage();
+};
+
+// Scene3011
+
+class SsScene3011Button : public StaticSprite {
+public:
+ SsScene3011Button(NeverhoodEngine *vm, Scene *parentScene, bool flag);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene3011Symbol : public AnimatedSprite {
+public:
+ AsScene3011Symbol(NeverhoodEngine *vm, int symbolIndex, bool largeSymbol);
+ void show(bool isNoisy);
+ void hide();
+ void stopSymbolSound();
+ void change(int symbolIndex, bool isNoisy);
+ int getSymbolIndex() { return _largeSymbol ? _symbolIndex : _symbolIndex - 12; }
+protected:
+ bool _largeSymbol;
+ bool _isNoisy;
+ int _symbolIndex;
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE3000_SPRITES_H */
diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp
index 51ab96ef37..a15c00de07 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -35,6 +35,7 @@ NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint
_isWalkingForward(false), _isTurning(false), _smackerFileHash(0), _interactive(true), _leaveSceneAfter(false) {
_navigationList = _vm->_staticData->getNavigationList(navigationListId);
+ _navigationListId = navigationListId;
if (_navigationIndex < 0) {
_navigationIndex = (int)getGlobalVar(V_NAVIGATION_INDEX);
diff --git a/engines/neverhood/navigationscene.h b/engines/neverhood/navigationscene.h
index ebe9a3597c..c17446811c 100644
--- a/engines/neverhood/navigationscene.h
+++ b/engines/neverhood/navigationscene.h
@@ -38,10 +38,12 @@ public:
bool isWalkingForward() const { return _isWalkingForward; }
bool isTurning() const { return _isTurning; }
int getFrameNumber() const { return _smackerPlayer->getFrameNumber(); }
+ uint32 getNavigationListId() const { return _navigationListId; }
protected:
SmackerPlayer *_smackerPlayer;
bool _smackerDone;
NavigationList *_navigationList;
+ uint32 _navigationListId; // used for debugging
int _navigationIndex;
uint32 _smackerFileHash;
bool _interactive;
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 061e6d1279..1fb32a1834 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -109,6 +109,7 @@ Common::Error NeverhoodEngine::run() {
_isSaveAllowed = true;
_updateSound = true;
+ _enableMusic = !_mixer->isSoundTypeMuted(Audio::Mixer::kMusicSoundType);
if (isDemo()) {
// Adjust this navigation list for the demo version
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 5643e345ad..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;
@@ -135,9 +137,12 @@ public:
NPoint getMousePos();
void toggleSoundUpdate(bool state) { _updateSound = state; }
+ void toggleMusic(bool state) { _enableMusic = state; }
+ bool musicIsEnabled() { return _enableMusic; }
private:
bool _updateSound;
+ bool _enableMusic;
};
diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp
index c381f46671..941bcc3cd3 100644
--- a/engines/neverhood/palette.cpp
+++ b/engines/neverhood/palette.cpp
@@ -66,6 +66,11 @@ void Palette::init() {
_status = 0;
_palette = new byte[1024];
_basePalette = new byte[1024];
+ _palCounter = 0;
+ _fadeToR = 0;
+ _fadeToG = 0;
+ _fadeToB = 0;
+ _fadeStep = 0;
}
void Palette::usePalette() {
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..a53bcc8393 100644
--- a/engines/neverhood/resourceman.cpp
+++ b/engines/neverhood/resourceman.cpp
@@ -85,7 +85,34 @@ 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
+ { 0x41137051, 667019, 23391, 41398, 41401 }, // "Options" menu header text
+ { 0x0f960021, 402268, 1704, 4378, 1870 }, // "Save" menu
+ { 0x1301a7ea, 1220008, 2373, 4146, 2877 }, // "Load" menu
+ { 0x84181e81, 201409, 1622, 5058, 1833 }, // "Delete" menu
+ { 0x08C0AC24, 1031009, 3030, 6498, 3646 }, // Overwrite dialog
+ { 0xc6604282, 12813649, 19623, 35894, 35895 }, // One of the fonts when reading Willie's notes
+ { 0x80283101, 13104841, 1961, 3712, 3511 }, // The first message from Willie
+ { 0x00918480, 17676417, 581, 916, 706 }, // The first wall in the museum
+ { 0x00800090C,16064875, 19555, 38518, 38526 }, // The first wall in the museum
+ // Fixes for the Russian "Fargus" version
+ { 0x41137051, 758264, 29037, 49590, 49591 }, // "Options" menu header text
+ { 0xc10b2015, 787304, 4414, 15848, 15853 }, // Text on option buttons
+ //
+ { 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 +124,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/scene.cpp b/engines/neverhood/scene.cpp
index c8d7490753..9a7e87ac8d 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -50,6 +50,11 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule)
_smackerPlayer = NULL;
_isMessageListBusy = false;
_messageValue = -1;
+ _messageListStatus = 0;
+ _messageListCount = 0;
+ _messageListIndex = 0;
+
+ _backgroundFileHash = _cursorFileHash = 0;
SetUpdateHandler(&Scene::update);
SetMessageHandler(&Scene::handleMessage);
@@ -188,6 +193,7 @@ Background *Scene::addBackground(Background *background) {
void Scene::setBackground(uint32 fileHash) {
_background = addBackground(new Background(_vm, fileHash, 0, 0));
+ _backgroundFileHash = fileHash;
}
void Scene::changeBackground(uint32 fileHash) {
@@ -216,14 +222,17 @@ void Scene::insertScreenMouse(uint32 fileHash, const NRect *mouseRect) {
if (mouseRect)
rect = *mouseRect;
insertMouse(new Mouse(_vm, fileHash, rect));
+ _cursorFileHash = fileHash;
}
void Scene::insertPuzzleMouse(uint32 fileHash, int16 x1, int16 x2) {
insertMouse(new Mouse(_vm, fileHash, x1, x2));
+ _cursorFileHash = fileHash;
}
void Scene::insertNavigationMouse(uint32 fileHash, int type) {
insertMouse(new Mouse(_vm, fileHash, type));
+ _cursorFileHash = fileHash;
}
void Scene::showMouse(bool visible) {
@@ -593,4 +602,27 @@ void Scene::insertMouse(Mouse *mouseCursor) {
addEntity(_mouseCursor);
}
+// StaticScene
+
+StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash)
+ : Scene(vm, parentModule) {
+
+ SetMessageHandler(&StaticScene::handleMessage);
+
+ setBackground(backgroundFileHash);
+ setPalette(backgroundFileHash);
+ insertPuzzleMouse(cursorFileHash, 20, 620);
+}
+
+uint32 StaticScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
+ leaveScene(0);
+ break;
+ }
+ return 0;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index 5e42e34418..e6183199ce 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -162,6 +162,10 @@ public:
T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) {
return new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6);
}
+
+ uint32 getBackgroundFileHash() const { return _backgroundFileHash; }
+ uint32 getCursorFileHash() const { return _cursorFileHash; }
+
protected:
Module *_parentModule;
Common::Array<Entity*> _entities;
@@ -197,8 +201,9 @@ protected:
HitRectList *_hitRects;
Common::Array<Sprite*> _collisionSprites;
- void (Entity::*_savedUpdateHandlerCb)();
- uint32 (Entity::*_savedMessageHandlerCb)(int messageNum, const MessageParam &param, Entity *sender);
+ // Used for debugging
+ uint32 _backgroundFileHash, _cursorFileHash; // for StaticScene and all Scene* classes
+
int _messageValue;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
bool queryPositionSprite(int16 mouseX, int16 mouseY);
@@ -224,6 +229,14 @@ protected:
void insertMouse(Mouse *mouseCursor);
};
+
+class StaticScene : public Scene {
+public:
+ StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash);
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_SCENE_H */
diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp
index 4c8dd9add0..901ab73b39 100644
--- a/engines/neverhood/screen.cpp
+++ b/engines/neverhood/screen.cpp
@@ -27,7 +27,8 @@ namespace Neverhood {
Screen::Screen(NeverhoodEngine *vm)
: _vm(vm), _paletteData(NULL), _paletteChanged(false), _smackerDecoder(NULL),
- _yOffset(0), _fullRefresh(false) {
+ _yOffset(0), _fullRefresh(false), _frameDelay(0), _savedSmackerDecoder(NULL),
+ _savedFrameDelay(0), _savedYOffset(0) {
_ticks = _vm->_system->getMillis();
diff --git a/engines/neverhood/smackerscene.h b/engines/neverhood/smackerscene.h
index 7ed2e0262b..8e5084512f 100644
--- a/engines/neverhood/smackerscene.h
+++ b/engines/neverhood/smackerscene.h
@@ -36,6 +36,7 @@ public:
void setFileHash(uint32 fileHash);
void setFileHashList(const uint32 *fileHashList);
void nextVideo();
+ uint32 getSmackerFileHash() const { return _fileHash[0]; }
protected:
bool _doubleSurface;
bool _canSkip;
diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp
index c3bc3501b5..3ea45491a7 100644
--- a/engines/neverhood/sound.cpp
+++ b/engines/neverhood/sound.cpp
@@ -250,13 +250,26 @@ void SoundItem::update() {
// SoundMan
SoundMan::SoundMan(NeverhoodEngine *vm)
- : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1) {
+ : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1),
+ _initialCountdown(0), _playOnceAfterCountdown(false),
+ _initialCountdown3(0), _playOnceAfterCountdown3(false) {
}
SoundMan::~SoundMan() {
+ stopAllMusic();
stopAllSounds();
}
+void SoundMan::stopAllMusic() {
+ for (uint i = 0; i < _musicItems.size(); ++i) {
+ if (_musicItems[i]) {
+ _musicItems[i]->stopMusic(0, 0);
+ delete _musicItems[i];
+ _musicItems[i] = NULL;
+ }
+ }
+}
+
void SoundMan::stopAllSounds() {
for (uint i = 0; i < _soundItems.size(); ++i) {
if (_soundItems[i]) {
@@ -265,13 +278,6 @@ void SoundMan::stopAllSounds() {
_soundItems[i] = NULL;
}
}
- for (uint i = 0; i < _musicItems.size(); ++i) {
- if (_musicItems[i]) {
- _musicItems[i]->stopMusic(0, 0);
- delete _musicItems[i];
- _musicItems[i] = NULL;
- }
- }
_soundIndex1 = _soundIndex2 = _soundIndex3 = -1;
}
@@ -573,7 +579,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();
}
}
@@ -623,7 +629,8 @@ bool AudioResourceManSoundItem::isPlaying() {
AudioResourceManMusicItem::AudioResourceManMusicItem(NeverhoodEngine *vm, uint32 fileHash)
: _vm(vm), _fileHash(fileHash), _terminate(false), _canRestart(false),
- _volume(100), _panning(50), _start(false), _isFadingIn(false), _isFadingOut(false), _isPlaying(false) {
+ _volume(100), _panning(50), _start(false), _isFadingIn(false), _isFadingOut(false), _isPlaying(false),
+ _fadeVolume(0), _fadeVolumeStep(0) {
}
@@ -724,6 +731,16 @@ AudioResourceMan::AudioResourceMan(NeverhoodEngine *vm)
: _vm(vm) {
}
+void AudioResourceMan::stopAllMusic() {
+ for (uint i = 0; i < _musicItems.size(); ++i) {
+ if (_musicItems[i]) {
+ _musicItems[i]->stopMusic(0);
+ delete _musicItems[i];
+ _musicItems[i] = NULL;
+ }
+ }
+}
+
void AudioResourceMan::stopAllSounds() {
for (uint i = 0; i < _soundItems.size(); ++i) {
if (_soundItems[i]) {
@@ -732,16 +749,10 @@ void AudioResourceMan::stopAllSounds() {
_soundItems[i] = NULL;
}
}
- for (uint i = 0; i < _musicItems.size(); ++i) {
- if (_musicItems[i]) {
- _musicItems[i]->stopMusic(0);
- delete _musicItems[i];
- _musicItems[i] = NULL;
- }
- }
}
AudioResourceMan::~AudioResourceMan() {
+ stopAllMusic();
stopAllSounds();
}
diff --git a/engines/neverhood/sound.h b/engines/neverhood/sound.h
index 0733346daa..548fe88501 100644
--- a/engines/neverhood/sound.h
+++ b/engines/neverhood/sound.h
@@ -129,6 +129,7 @@ public:
SoundMan(NeverhoodEngine *vm);
~SoundMan();
+ void stopAllMusic();
void stopAllSounds();
// Music
@@ -264,6 +265,7 @@ public:
AudioResourceMan(NeverhoodEngine *vm);
~AudioResourceMan();
+ void stopAllMusic();
void stopAllSounds();
int16 addSound(uint32 fileHash);
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index 3c158ff7e3..1a432461fb 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -211,6 +211,12 @@ void AnimatedSprite::init() {
_replNewColor = 0;
_animResource.setReplEnabled(false);
_playBackwards = false;
+ _currAnimFileHash = 0;
+ _lastFrameIndex = 0;
+ _plLastFrameIndex = 0;
+ _plFirstFrameHash = 0;
+ _plLastFrameHash = 0;
+ _animStatus = 0;
}
void AnimatedSprite::update() {
diff --git a/engines/neverhood/staticdata.cpp b/engines/neverhood/staticdata.cpp
index 006992641a..ec9c852118 100644
--- a/engines/neverhood/staticdata.cpp
+++ b/engines/neverhood/staticdata.cpp
@@ -53,6 +53,22 @@ void StaticData::load(const char *filename) {
messageItem.messageValue = fd.readUint32LE();
messageList->push_back(messageItem);
}
+
+ // WORKAROUND for a problem in two of the game's message lists:
+ // the message lists used when Klaymen is drinking the wrong potion
+ // have as a last element the animation itself (message 0x4832).
+ // However, when processMessageList() reaches the last element in a
+ // message list, it allows player input, which means that the player
+ // can erroneously skip these potion drinking animations. We insert
+ // another message at the end of these lists to prevent player input
+ // till the animations are finished
+ if (id == 0x004AF0C8 || id == 0x004B5BD0) { // wrong potion message lists
+ MessageItem messageItem;
+ messageItem.messageNum = 0x4004; // set Klaymen's state to idle
+ messageItem.messageValue = 0;
+ messageList->push_back(messageItem);
+ }
+
_messageLists[id] = messageList;
}