aboutsummaryrefslogtreecommitdiff
path: root/engines/neverhood
diff options
context:
space:
mode:
authorjohndoe1232014-01-30 20:18:55 +0100
committerjohndoe1232014-01-30 20:18:55 +0100
commitcf51529cfd0fedb33b1b0c70beb59997b21cfc5b (patch)
tree1df30e23c7f1eac7ca4a8ddfba40c89c2577dda7 /engines/neverhood
parent542197a891eac799855571fe2849e0dca43bdd2b (diff)
parent462f7c1c24a48b7555316a3afae357bad14cc14b (diff)
downloadscummvm-rg350-cf51529cfd0fedb33b1b0c70beb59997b21cfc5b.tar.gz
scummvm-rg350-cf51529cfd0fedb33b1b0c70beb59997b21cfc5b.tar.bz2
scummvm-rg350-cf51529cfd0fedb33b1b0c70beb59997b21cfc5b.zip
Merge remote-tracking branch 'origin/master' into bbvs
Diffstat (limited to 'engines/neverhood')
-rw-r--r--engines/neverhood/configure.engine3
-rw-r--r--engines/neverhood/console.cpp1
-rw-r--r--engines/neverhood/detection.cpp27
-rw-r--r--engines/neverhood/diskplayerscene.cpp6
-rw-r--r--engines/neverhood/gamemodule.cpp32
-rw-r--r--engines/neverhood/gamemodule.h2
-rw-r--r--engines/neverhood/graphics.cpp2
-rw-r--r--engines/neverhood/klaymen.cpp3605
-rw-r--r--engines/neverhood/klaymen.h413
-rw-r--r--engines/neverhood/menumodule.cpp34
-rw-r--r--engines/neverhood/messages.h48
-rw-r--r--engines/neverhood/module.cpp2
-rw-r--r--engines/neverhood/module.mk17
-rw-r--r--engines/neverhood/modules/module1000.cpp1009
-rw-r--r--engines/neverhood/modules/module1000.h181
-rw-r--r--engines/neverhood/modules/module1000_sprites.cpp1632
-rw-r--r--engines/neverhood/modules/module1000_sprites.h262
-rw-r--r--engines/neverhood/modules/module1100.cpp211
-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.cpp660
-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.cpp728
-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.cpp924
-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/module1500.cpp6
-rw-r--r--engines/neverhood/modules/module1600.cpp861
-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.cpp48
-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.cpp397
-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.cpp5
-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.cpp135
-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.cpp934
-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.cpp363
-rw-r--r--engines/neverhood/modules/module2400.h71
-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.cpp88
-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.cpp97
-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.cpp176
-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.cpp187
-rw-r--r--engines/neverhood/modules/module2800_sprites.cpp712
-rw-r--r--engines/neverhood/modules/module2800_sprites.h69
-rw-r--r--engines/neverhood/modules/module2900.cpp211
-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.cpp677
-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.cpp8
-rw-r--r--engines/neverhood/neverhood.cpp16
-rw-r--r--engines/neverhood/neverhood.h4
-rw-r--r--engines/neverhood/palette.cpp18
-rw-r--r--engines/neverhood/palette.h1
-rw-r--r--engines/neverhood/resourceman.cpp25
-rw-r--r--engines/neverhood/scene.cpp25
-rw-r--r--engines/neverhood/scene.h2
-rw-r--r--engines/neverhood/screen.cpp3
-rw-r--r--engines/neverhood/screen.h1
-rw-r--r--engines/neverhood/smackerplayer.cpp14
-rw-r--r--engines/neverhood/smackerscene.cpp6
-rw-r--r--engines/neverhood/sound.cpp36
-rw-r--r--engines/neverhood/sound.h1
-rw-r--r--engines/neverhood/sprite.cpp6
-rw-r--r--engines/neverhood/staticdata.cpp16
103 files changed, 13991 insertions, 12705 deletions
diff --git a/engines/neverhood/configure.engine b/engines/neverhood/configure.engine
new file mode 100644
index 0000000000..46910e293e
--- /dev/null
+++ b/engines/neverhood/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine neverhood "Neverhood" yes
diff --git a/engines/neverhood/console.cpp b/engines/neverhood/console.cpp
index 708c68746c..34438d821f 100644
--- a/engines/neverhood/console.cpp
+++ b/engines/neverhood/console.cpp
@@ -29,6 +29,7 @@
#include "neverhood/smackerscene.h"
#include "neverhood/sound.h"
#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module3000_sprites.h"
namespace Neverhood {
diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp
index 96c87ab3ae..feba193609 100644
--- a/engines/neverhood/detection.cpp
+++ b/engines/neverhood/detection.cpp
@@ -130,6 +130,9 @@ static const NeverhoodGameDescription gameDescriptions[] = {
0,
},
+// FIXME: Disabled for now, as it has broken resources that corrupt the heap
+// (e.g. the menu header).
+#if 0
{
// Neverhood Russian version. Fargus
{
@@ -146,19 +149,35 @@ static const NeverhoodGameDescription gameDescriptions[] = {
0,
0,
},
+#endif
{ AD_TABLE_END_MARKER, 0, 0, 0, 0 }
};
} // End of namespace Neverhood
-static const ExtraGuiOption neverhoodExtraGuiOption = {
+static const ExtraGuiOption neverhoodExtraGuiOption1 = {
_s("Use original save/load screens"),
_s("Use the original save/load screens, instead of the ScummVM ones"),
"originalsaveload",
false
};
+static const ExtraGuiOption neverhoodExtraGuiOption2 = {
+ _s("Skip the Hall of Records storyboard scenes"),
+ _s("Allows the player to skip past the Hall of Records storyboard scenes"),
+ "skiphallofrecordsscenes",
+ false
+};
+
+static const ExtraGuiOption neverhoodExtraGuiOption3 = {
+ _s("Scale the making of videos to full screen"),
+ _s("Scale the making of videos, so that they use the whole screen"),
+ "scalemakingofvideos",
+ false
+};
+
+
class NeverhoodMetaEngine : public AdvancedMetaEngine {
public:
NeverhoodMetaEngine() : AdvancedMetaEngine(Neverhood::gameDescriptions, sizeof(Neverhood::NeverhoodGameDescription), neverhoodGames) {
@@ -189,7 +208,7 @@ bool NeverhoodMetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSupportsListSaves) ||
(f == kSupportsLoadingDuringStartup) ||
(f == kSupportsDeleteSave) ||
- (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportMetaInfo) ||
(f == kSavesSupportThumbnail) ||
(f == kSavesSupportCreationDate) ||
(f == kSavesSupportPlayTime);
@@ -212,7 +231,9 @@ bool NeverhoodMetaEngine::createInstance(OSystem *syst, Engine **engine, const A
const ExtraGuiOptions NeverhoodMetaEngine::getExtraGuiOptions(const Common::String &target) const {
ExtraGuiOptions options;
- options.push_back(neverhoodExtraGuiOption);
+ options.push_back(neverhoodExtraGuiOption1);
+ options.push_back(neverhoodExtraGuiOption2);
+ options.push_back(neverhoodExtraGuiOption3);
return options;
}
diff --git a/engines/neverhood/diskplayerscene.cpp b/engines/neverhood/diskplayerscene.cpp
index ef2b856b2f..7513034bf3 100644
--- a/engines/neverhood/diskplayerscene.cpp
+++ b/engines/neverhood/diskplayerscene.cpp
@@ -169,7 +169,7 @@ AsDiskplayerSceneKey::AsDiskplayerSceneKey(NeverhoodEngine *vm)
uint32 AsDiskplayerSceneKey::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -442,7 +442,7 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param,
Scene::handleMessage(messageNum, param, sender);
if (!_inputDisabled) {
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
sendMessage(_parentModule, 0x1009, 0);
} else if (!_dropKey &&
@@ -460,7 +460,7 @@ uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param,
}
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
tuneIn();
break;
case 0x2001:
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 50c7c503d3..5e9981caa6 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -79,7 +79,7 @@ GameModule::GameModule(NeverhoodEngine *vm)
_mainMenuRequested(false) {
// Other initializations moved to actual engine class
- _vm->_soundMan->playSoundThree(0x002D0031, 0x8861079);
+ _vm->_soundMan->playSoundThree(0x002D0031, 0x08861079);
SetMessageHandler(&GameModule::handleMessage);
}
@@ -95,7 +95,7 @@ void GameModule::handleMouseMove(int16 x, int16 y) {
mousePos.x = x;
mousePos.y = y;
debug(2, "GameModule::handleMouseMove(%d, %d)", x, y);
- sendPointMessage(_childObject, 0, mousePos);
+ sendPointMessage(_childObject, NM_MOUSE_MOVE, mousePos);
}
}
@@ -105,7 +105,7 @@ void GameModule::handleMouseDown(int16 x, int16 y) {
mousePos.x = x;
mousePos.y = y;
debug(2, "GameModule::handleMouseDown(%d, %d)", x, y);
- sendPointMessage(_childObject, 0x0001, mousePos);
+ sendPointMessage(_childObject, NM_MOUSE_CLICK, mousePos);
}
}
@@ -115,14 +115,26 @@ void GameModule::handleMouseUp(int16 x, int16 y) {
mousePos.x = x;
mousePos.y = y;
debug(2, "GameModule::handleMouseUp(%d, %d)", x, y);
- sendPointMessage(_childObject, 0x0002, mousePos);
+ sendPointMessage(_childObject, NM_MOUSE_RELEASE, mousePos);
+ }
+}
+
+void GameModule::handleWheelUp() {
+ if (_childObject) {
+ sendMessage(_childObject, NM_MOUSE_WHEELUP, 0);
+ }
+}
+
+void GameModule::handleWheelDown() {
+ if (_childObject) {
+ sendMessage(_childObject, NM_MOUSE_WHEELDOWN, 0);
}
}
void GameModule::handleSpaceKey() {
if (_childObject) {
debug(2, "GameModule::handleSpaceKey()");
- sendMessage(_childObject, 0x0009, 0);
+ sendMessage(_childObject, NM_KEYPRESS_SPACE, 0);
}
}
@@ -150,7 +162,7 @@ void GameModule::handleEscapeKey() {
else if (!_prevChildObject && _canRequestMainMenu)
_mainMenuRequested = true;
else if (_childObject)
- sendMessage(_childObject, 0x000C, 0);
+ sendMessage(_childObject, NM_KEYPRESS_ESC, 0);
}
void GameModule::initKeySlotsPuzzle() {
@@ -216,7 +228,7 @@ void GameModule::initRadioPuzzle() {
setGlobalVar(V_RADIO_ROOM_LEFT_DOOR, 1);
setGlobalVar(V_RADIO_ROOM_RIGHT_DOOR, 0);
setSubVar(VA_IS_PUZZLE_INIT, 0x08C80800, 1);
- }
+ }
}
void GameModule::initTestTubes1Puzzle() {
@@ -415,6 +427,8 @@ void GameModule::checkRequests() {
_vm->_audioResourceMan->stopAllSounds();
_vm->_soundMan->stopAllMusic();
_vm->_soundMan->stopAllSounds();
+ // Reinsert turning sound because SoundMan::stopAllSounds() removes it
+ _vm->_soundMan->playSoundThree(0x002D0031, 0x08861079);
delete _childObject;
delete _prevChildObject;
_childObject = NULL;
@@ -781,7 +795,7 @@ void GameModule::updateModule() {
void GameModule::openMainMenu() {
if (_childObject) {
- sendMessage(_childObject, 0x101D, 0);
+ sendMessage(_childObject, NM_MOUSE_HIDE, 0);
_childObject->draw();
} else {
// If there's no module, create one so there's something to return to
@@ -807,7 +821,7 @@ void GameModule::updateMenuModule() {
if (!updateChild()) {
_vm->_screen->restoreParams();
_childObject = _prevChildObject;
- sendMessage(_childObject, 0x101E, 0);
+ sendMessage(_childObject, NM_MOUSE_SHOW, 0);
_prevChildObject = NULL;
_moduleNum = _prevModuleNum;
SetUpdateHandler(&GameModule::updateModule);
diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h
index 2f2fecf463..198f8f6715 100644
--- a/engines/neverhood/gamemodule.h
+++ b/engines/neverhood/gamemodule.h
@@ -40,6 +40,8 @@ public:
void handleMouseMove(int16 x, int16 y);
void handleMouseDown(int16 x, int16 y);
void handleMouseUp(int16 x, int16 y);
+ void handleWheelUp();
+ void handleWheelDown();
void handleSpaceKey();
void handleAsciiKey(char key);
void handleKeyDown(Common::KeyCode keyCode);
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index 490959020f..e976844c16 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -299,11 +299,11 @@ void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int
}
source += copy;
}
- dest += destPitch;
if (replaceColors)
for (int xc = 0; xc < width; xc++)
if (dest[xc] == oldColor)
dest[xc] = newColor;
+ dest += destPitch;
}
}
rows = READ_LE_UINT16(source);
diff --git a/engines/neverhood/klaymen.cpp b/engines/neverhood/klaymen.cpp
index 8ed27c825a..a813440f62 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;
@@ -88,7 +77,7 @@ uint32 Klaymen::xHandleMessage(int messageNum, const MessageParam &param) {
case 0x4800:
startWalkToX(param.asPoint().x, false);
break;
- case 0x4004:
+ case NM_KLAYMEN_STAND_IDLE:
GotoState(&Klaymen::stTryStandIdle);
break;
case 0x4818:
@@ -137,7 +126,7 @@ void Klaymen::stIdlePickEar() {
uint32 Klaymen::hmIdlePickEar(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x04DBC02C) {
playSound(0, 0x44528AA1);
}
@@ -163,7 +152,7 @@ void Klaymen::stIdleSpinHead() {
uint32 Klaymen::hmIdleSpinHead(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x808A0008) {
playSound(0, 0xD948A340);
}
@@ -190,7 +179,7 @@ void Klaymen::evIdleArmsDone() {
uint32 Klaymen::hmIdleArms(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x5A0F0104) {
playSound(0, 0x7970A100);
} else if (param.asInteger() == 0x9A9A0109) {
@@ -216,7 +205,7 @@ void Klaymen::stIdleChest() {
uint32 Klaymen::hmIdleChest(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0D2A0288) {
playSound(0, 0xD192A368);
}
@@ -238,7 +227,7 @@ void Klaymen::stIdleHeadOff() {
uint32 Klaymen::hmIdleHeadOff(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC006000C) {
playSound(0, 0x9D406340);
} else if (param.asInteger() == 0x2E4A2940) {
@@ -311,7 +300,7 @@ void Klaymen::stSitIdleTeleporterBlink() {
void Klaymen::stSitIdleTeleporterBlinkSecond() {
_busyStatus = 0;
_acceptInput = true;
- startAnimation(0x5C24C018, 0, -1);
+ startAnimation(0x582EC138, 0, -1);
SetUpdateHandler(&Klaymen::upSitIdleTeleporter);
SetMessageHandler(&Klaymen::hmLowLevel);
SetSpriteUpdate(NULL);
@@ -344,9 +333,9 @@ void Klaymen::stPickUpTube() {
uint32 Klaymen::hmPickUpTube(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC1380080) {
- sendMessage(_attachedSprite, 0x4806, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
playSound(0, 0xC8004340);
} else if (param.asInteger() == 0x02B20220) {
playSound(0, 0xC5408620);
@@ -405,7 +394,7 @@ void Klaymen::stSitInTeleporter() {
uint32 Klaymen::hmSitInTeleporter(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x001A2832) {
playSound(0, 0xC0E4884C);
}
@@ -529,7 +518,7 @@ uint32 Klaymen::hmLowLevel(int messageNum, const MessageParam &param, Entity *se
case 0x1014:
_attachedSprite = (Sprite*)(param.asEntity());
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
gotoNextStateExt();
break;
case 0x101C:
@@ -567,7 +556,7 @@ void Klaymen::stIdleBlink() {
uint32 Klaymen::hmLowLevelAnimation(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextStateExt();
break;
}
@@ -586,7 +575,7 @@ void Klaymen::stStandAround() {
uint32 Klaymen::hmStartAction(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x271AA210) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x2B22AA81) {
@@ -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;
@@ -771,7 +730,7 @@ void Klaymen::evSneakingDone() {
uint32 Klaymen::hmSneaking(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -782,7 +741,7 @@ uint32 Klaymen::hmSneaking(int messageNum, const MessageParam &param, Entity *se
playSound(0, _soundFlag ? 0x50399F64 : 0x0460E2FA);
}
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_x = _destX;
gotoNextStateExt();
break;
@@ -812,7 +771,7 @@ void Klaymen::evStartWalkingDone() {
uint32 Klaymen::hmStartWalking(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, _soundFlag ? 0x48498E46 : 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -843,7 +802,7 @@ void Klaymen::suWalkingFirst() {
uint32 Klaymen::hmWalking(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, _soundFlag ? 0x48498E46 : 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -902,7 +861,7 @@ void Klaymen::suWalkingTestExit() {
(_actionStatus != 2 && _actionStatus != 3 && xdiff <= 10 && (_currFrameIndex >= 12 || _currFrameIndex <= 4)) ||
(_actionStatus == 3 && xdiff < 30) ||
(_actionStatus == 3 && xdiff < 150 && _currFrameIndex >= 6)) {
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
} else {
HitRect *hitRectPrev = _parentScene->findHitRectAtPos(_x, _y);
_x += xdelta;
@@ -934,11 +893,11 @@ void Klaymen::suWalkingTestExit() {
uint32 Klaymen::hmLever(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
} else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
}
break;
}
@@ -960,9 +919,9 @@ void Klaymen::stPickUpGeneric() {
uint32 Klaymen::hmPickUpObject(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC1380080) {
- sendMessage(_attachedSprite, 0x4806, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
playSound(0, 0x40208200);
} else if (param.asInteger() == 0x02B20220) {
playSound(0, 0xC5408620);
@@ -995,7 +954,7 @@ void Klaymen::stPressButton() {
uint32 Klaymen::hmPressButton(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0D01B294) {
sendMessage(_attachedSprite, 0x480B, 0);
} else if (param.asInteger() == 0x32180101) {
@@ -1089,7 +1048,7 @@ void Klaymen::stStartWalkingSmall() {
uint32 Klaymen::hmWalkingSmall(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101)
playSound(0, 0x4924AAC4);
else if (param.asInteger() == 0x0A2A9098)
@@ -1146,11 +1105,11 @@ void Klaymen::stWalkToFrontNoStepSmall() {
uint32 Klaymen::hmWalkFrontBackSmall(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x80C110B5)
- sendMessage(_parentScene, 0x482A, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_BACK, 0);
else if (param.asInteger() == 0x110010D1)
- sendMessage(_parentScene, 0x482B, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_FRONT, 0);
else if (param.asInteger() == 0x32180101)
playSound(0, 0x4924AAC4);
else if (param.asInteger() == 0x0A2A9098)
@@ -1228,12 +1187,12 @@ void Klaymen::stReleaseCord() {
uint32 Klaymen::hmPullReleaseCord(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x4AB28209) {
- sendMessage(_attachedSprite, 0x482A, 0);
- sendMessage(_attachedSprite, 0x480F, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
} else if (param.asInteger() == 0x88001184) {
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
}
break;
}
@@ -1254,7 +1213,7 @@ void Klaymen::stUseTube() {
uint32 Klaymen::hmUseTube(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x02B20220)
playSound(0, 0xC5408620);
else if (param.asInteger() == 0x0A720138)
@@ -1410,14 +1369,14 @@ void Klaymen::suLargeStep() {
uint32 Klaymen::hmLargeStep(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x0A2A9098) {
playSound(0, 0x0A2AA8E0);
}
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_x = _destX;
gotoNextStateExt();
break;
@@ -1455,7 +1414,7 @@ void Klaymen::stTurnToUseHalf() {
uint32 Klaymen::hmTurnToUse(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x4924AAC4);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -1501,7 +1460,7 @@ uint32 Klaymen::hmPeekWall(int messageNum, const MessageParam &param, Entity *se
if (_currFrameIndex < speedUpFrameIndex)
startAnimation(0xAC20C012, speedUpFrameIndex, -1);
return 0;
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101) {
playSound(0, 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -1512,116 +1471,15 @@ 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;
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
_attachedSprite = NULL;
startAnimation(0xB869A4B9, 0, -1);
SetUpdateHandler(&Klaymen::update);
@@ -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);
}
@@ -1709,7 +1559,7 @@ void Klaymen::stClimbLadderHalf() {
uint32 Klaymen::hmClimbLadderHalf(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x489B025C) {
playSound(0, 0x52C4C2D7);
} else if (param.asInteger() == 0x400A0E64) {
@@ -1727,7 +1577,7 @@ uint32 Klaymen::hmClimbLadderHalf(int messageNum, const MessageParam &param, Ent
uint32 Klaymen::hmClimbLadderUpDown(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x01084280) {
_acceptInput = true;
} else if (param.asInteger() == 0x489B025C) {
@@ -1738,11 +1588,11 @@ uint32 Klaymen::hmClimbLadderUpDown(int messageNum, const MessageParam &param, E
if (_ladderStatus == 1) {
startAnimationByHash(0x3A292504, 0x01084280, 0);
if (_destY >= _y - 30)
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
} else {
startAnimationByHash(0x122D1505, 0x01084280, 0);
if (_destY <= _y)
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
}
}
break;
@@ -1789,11 +1639,11 @@ void Klaymen::stWalkToFrontNoStep() {
uint32 Klaymen::hmWalkToFront(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x80C110B5) {
- sendMessage(_parentScene, 0x482A, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_BACK, 0);
} else if (param.asInteger() == 0x110010D1) {
- sendMessage(_parentScene, 0x482B, 0);
+ sendMessage(_parentScene, NM_MOVE_TO_FRONT, 0);
} else if (param.asInteger() == 0x32180101) {
playSound(0, _soundFlag ? 0x48498E46 : 0x405002D8);
} else if (param.asInteger() == 0x0A2A9098) {
@@ -1849,7 +1699,7 @@ void Klaymen::stLandOnFeet() {
uint32 Klaymen::hmLandOnFeet(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x320AC306) {
playSound(0, 0x5860C640);
}
@@ -1872,7 +1722,7 @@ void Klaymen::stTurnToBackToUse() {
uint32 Klaymen::hmTurnToBackToUse(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xC61A0119) {
playSound(0, 0x402338C2);
} else if (param.asInteger() == 0x32180101) {
@@ -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;
@@ -1956,12 +1783,12 @@ void Klaymen::stMoveObjectSkipTurnFaceObject() {
}
void Klaymen::evMoveObjectTurnDone() {
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
}
uint32 Klaymen::hmMoveObjectTurn(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x01084280) {
sendMessage(_attachedSprite, 0x480B, _doDeltaX ? 1 : 0);
} else if (param.asInteger() == 0x02421405) {
@@ -1977,7 +1804,7 @@ uint32 Klaymen::hmMoveObjectTurn(int messageNum, const MessageParam &param, Enti
playSound(0, 0x0460E2FA);
}
break;
- case 0x480A:
+ case NM_KLAYMEN_MOVE_OBJECT:
_isMoveObjectRequested = true;
return 0;
}
@@ -2012,7 +1839,7 @@ void Klaymen::stUseLever() {
if (_isLeverDown) {
stUseLeverRelease();
} else {
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
startAnimation(0x0C303040, 0, -1);
SetSpriteUpdate(&Klaymen::suUpdateDestX);
SetMessageHandler(&Klaymen::hmLever);
@@ -2026,7 +1853,7 @@ void Klaymen::stUseLever() {
// Exactly the same code as sub420DA0 which was removed
void Klaymen::stPullLeverDown() {
startAnimation(0x0D318140, 0, -1);
- sendMessage(_attachedSprite, 0x480F, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
NextState(&Klaymen::stHoldLeverDown);
}
@@ -2044,7 +1871,7 @@ void Klaymen::stUseLeverRelease() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmLever);
SetSpriteUpdate(&Klaymen::suUpdateDestX);
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
NextState(&Klaymen::stPullLeverDown);
_acceptInput = false;
}
@@ -2056,7 +1883,7 @@ void Klaymen::stReleaseLever() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmLever);
SetSpriteUpdate(&Klaymen::suUpdateDestX);
- sendMessage(_attachedSprite, 0x4807, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_RAISE_LEVER, 0);
NextState(&Klaymen::stLetGoOfLever);
_acceptInput = false;
_isLeverDown = false;
@@ -2071,7 +1898,7 @@ void Klaymen::stLetGoOfLever() {
}
void Klaymen::evLeverReleasedEvent() {
- sendMessage(_attachedSprite, 0x482A, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
}
void Klaymen::stInsertDisk() {
@@ -2102,7 +1929,7 @@ void Klaymen::stInsertDisk() {
uint32 Klaymen::hmInsertDisk(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (_tapesToInsert == 0 && param.asInteger() == 0x06040580) {
nextAnimationByHash(0xD8C8D100, calcHash("GoToStartLoop/Finish"), 0);
} else if (_tapesToInsert != 0 && param.asInteger() == calcHash("GoToStartLoop/Finish")) {
@@ -2206,15 +2033,15 @@ void Klaymen::suJumpToGrab() {
uint32 Klaymen::hmJumpToGrab(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevel(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x168050A0)
- sendMessage(_attachedSprite, 0x4806, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
else if (param.asInteger() == 0x320AC306)
startAnimationByHash(0x00AB8C10, 0x01084280, 0);
else if (param.asInteger() == 0x4AB28209)
- sendMessage(_attachedSprite, 0x482A, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
else if (param.asInteger() == 0x88001184)
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
break;
}
return messageResult;
@@ -2232,7 +2059,7 @@ void Klaymen::stFinishGrow() {
uint32 Klaymen::hmFinishGrow(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x040C4C01)
playSound(0, 0x01E11140);
break;
@@ -2259,7 +2086,7 @@ void Klaymen::stJumpToGrabFall() {
SetUpdateHandler(&Klaymen::update);
SetMessageHandler(&Klaymen::hmJumpToGrab);
SetSpriteUpdate(&Klaymen::suJumpToGrab);
- sendMessage(_attachedSprite, 0x482B, 0);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
}
}
@@ -2276,7 +2103,7 @@ void Klaymen::stJumpToGrabRelease() {
uint32 Klaymen::hmJumpToGrabRelease(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x320AC306)
playSound(0, 0x5860C640);
break;
@@ -2325,7 +2152,7 @@ void Klaymen::teleporterDisappear(uint32 fileHash) {
uint32 Klaymen::hmTeleporterAppearDisappear(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x4E0A2C24) {
playSound(0, 0x85B10BB8);
} else if (param.asInteger() == 0x4E6A0CA0) {
@@ -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);
@@ -2381,7 +2185,7 @@ uint32 Klaymen::hmDrinkPotion(int messageNum, const MessageParam &param, Entity
} else
_potionFlag2 = true;
break;
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0002418E)
sendMessage(_parentScene, 0x2000, 0);
else if (param.asInteger() == 0x924090C2) {
@@ -2426,7 +2230,7 @@ uint32 Klaymen::hmDrinkPotion(int messageNum, const MessageParam &param, Entity
uint32 Klaymen::hmGrow(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x32180101)
playSound(0, 0x405002D8);
else if (param.asInteger() == 0x0A2A9098)
@@ -2479,7 +2283,7 @@ void Klaymen::stDrinkPotion() {
uint32 Klaymen::hmInsertKey(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (_keysToInsert == 0 && param.asInteger() == 0x06040580) {
nextAnimationByHash(0xDC409440, 0x46431401, 0);
} else if (_keysToInsert != 0 && param.asInteger() == 0x46431401) {
@@ -2537,65 +2341,10 @@ 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) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == calcHash("PopBalloon")) {
sendMessage(_parentScene, 0x2000, 0);
} else if (param.asInteger() == 0x02B20220) {
@@ -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:
@@ -2766,130 +2438,17 @@ uint32 Klaymen::hmStandIdleSpecial(int messageNum, const MessageParam &param, En
return 0;
}
-uint32 Klaymen::hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x942D2081) {
- _acceptInput = false;
- sendMessage(_attachedSprite, 0x2003, 0);
- } else if (param.asInteger() == 0xDA600012) {
- stHitByBoxingGlove();
- } else if (param.asInteger() == 0x0D01B294) {
- _acceptInput = false;
- sendMessage(_attachedSprite, 0x480B, 0);
- }
- break;
- }
- 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);
- switch (messageNum) {
- case 0x1008:
- speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
- if (_currFrameIndex < speedUpFrameIndex) {
- startAnimation(0x35AA8059, speedUpFrameIndex, -1);
- _y = 435;
- }
- messageResult = 0;
- break;
- case 0x100D:
- if (param.asInteger() == 0x1A1A0785) {
- playSound(0, 0x40F0A342);
- } else if (param.asInteger() == 0x60428026) {
- playSound(0, 0x40608A59);
- }
- break;
- }
- 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);
if (hitRect->type == 0x5001) {
_y = hitRect->rect.y1;
updateBounds();
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
}
_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;
@@ -2936,7 +2495,7 @@ void Klaymen::stFalling() {
SetSpriteUpdate(NULL);
SetMessageHandler(&Klaymen::hmLowLevelAnimation);
NextState(&Klaymen::stFallTouchdown);
- sendMessage(_parentScene, 0x2002, 0);
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
_attachedSprite = NULL;
sendMessage(_parentScene, 0x8001, 0);
}
@@ -2946,93 +2505,13 @@ 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;
- setDoDeltaX(0);
- startAnimation(0x1CD89029, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmPressDoorButton);
- SetSpriteUpdate(&Klaymen::suAction);
-}
-
-void Klaymen::stHitByBoxingGlove() {
- _busyStatus = 1;
- _acceptInput = false;
- startAnimation(0x35AA8059, 0, -1);
- SetUpdateHandler(&Klaymen::update);
- SetMessageHandler(&Klaymen::hmHitByBoxingGlove);
- SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
- FinalizeState(&Klaymen::evHitByBoxingGloveDone);
-}
-
-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);
if (hitRect->type == 0x5001) {
_y = hitRect->rect.y1;
updateBounds();
- sendMessage(this, 0x1019, 0);
+ sendMessage(this, NM_SCENE_LEAVE, 0);
}
}
@@ -3052,52 +2531,9 @@ 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:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x01084280) {
playSound(0, 0x405002D8);
sendMessage(_attachedSprite, 0x480B, 0);
@@ -3114,18 +2550,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 +2571,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;
@@ -3270,7 +2607,7 @@ void Klaymen::stInteractLever() {
void Klaymen::stPullLever() {
startAnimation(0x0D318140, 0, -1);
NextState(&Klaymen::stLookLeverDown);
- sendMessage(_attachedSprite, 0x480F, 0);
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
}
void Klaymen::stLookLeverDown() {
@@ -3344,2798 +2681,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..a614560fc0 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,19 +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();
-
void stStandIdleSmall();
void stWonderAboutSmall();
void stWonderAboutHalfSmall();
@@ -327,34 +264,17 @@ 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);
- void stPressDoorButton();
- uint32 hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender);
-
void stSpitOutFall0();
void stSpitOutFall2();
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 +298,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 +347,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 +367,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 362f5270e3..b332418cf5 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -112,7 +112,7 @@ void MenuModule::createScene(int sceneNum, int which) {
_childObject = new CreditsScene(_vm, this, true);
break;
case MAKING_OF:
- createSmackerScene(kMakingOfSmackerFileHashList, false, true, true);
+ createSmackerScene(kMakingOfSmackerFileHashList, ConfMan.getBool("scalemakingofvideos"), true, true);
break;
case LOAD_GAME_MENU:
createLoadGameMenu();
@@ -150,7 +150,6 @@ void MenuModule::updateScene() {
leaveModule(0);
break;
case kMainMenuQuitGame:
- leaveModule(0);
_vm->quitGame();
break;
case kMainMenuCredits:
@@ -195,6 +194,14 @@ void MenuModule::updateScene() {
}
uint32 MenuModule::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ switch(messageNum) {
+ case NM_KEYPRESS_ESC:
+ leaveModule(0);
+ break;
+ default:
+ break;
+ }
+
return Module::handleMessage(messageNum, param, sender);;
}
@@ -374,7 +381,7 @@ MainMenu::MainMenu(NeverhoodEngine *vm, Module *parentModule)
uint32 MainMenu::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
leaveScene(param.asInteger());
break;
}
@@ -446,17 +453,17 @@ void CreditsScene::update() {
uint32 CreditsScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
leaveScene(0);
break;
case 0x000B:
if (param.asInteger() == Common::KEYCODE_ESCAPE && _canAbort)
leaveScene(0);
break;
- case 0x101D:
+ case NM_MOUSE_HIDE:
_ticksDuration = _ticksTime - _vm->_system->getMillis();
break;
- case 0x101E:
+ case NM_MOUSE_SHOW:
_ticksTime = _ticksDuration + _vm->_system->getMillis();
break;
}
@@ -574,6 +581,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);
@@ -994,7 +1002,7 @@ uint32 GameStateMenu::handleMessage(int messageNum, const MessageParam &param, E
setCurrWidget(_textEditWidget);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
// Handle menu button click
switch (param.asInteger()) {
case 0:
@@ -1017,6 +1025,12 @@ uint32 GameStateMenu::handleMessage(int messageNum, const MessageParam &param, E
break;
}
break;
+ case NM_MOUSE_WHEELUP:
+ _listBox->scrollUp();
+ break;
+ case NM_MOUSE_WHEELDOWN:
+ _listBox->scrollDown();
+ break;
}
return 0;
}
@@ -1069,7 +1083,7 @@ static const NRect kLoadGameMenuButtonCollisionBounds[] = {
{ 182, 358, 241, 433 }
};
-static const NRect kLoadGameMenuListBoxRect = { 0, 0, 320, 271 };
+static const NRect kLoadGameMenuListBoxRect = { 0, 0, 320, 272 };
static const NRect kLoadGameMenuTextEditRect = { 0, 0, 320, 17 };
static const NRect kLoadGameMenuMouseRect = { 263, 48, 583, 65 };
@@ -1102,7 +1116,7 @@ static const NRect kDeleteGameMenuButtonCollisionBounds[] = {
{ 395, 278, 452, 372 }
};
-static const NRect kDeleteGameMenuListBoxRect = { 0, 0, 320, 271 };
+static const NRect kDeleteGameMenuListBoxRect = { 0, 0, 320, 272 };
static const NRect kDeleteGameMenuTextEditRect = { 0, 0, 320, 17 };
DeleteGameMenu::DeleteGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList)
@@ -1163,7 +1177,7 @@ QueryOverwriteMenu::QueryOverwriteMenu(NeverhoodEngine *vm, Module *parentModule
uint32 QueryOverwriteMenu::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
// Handle menu button click
leaveScene(param.asInteger());
break;
diff --git a/engines/neverhood/messages.h b/engines/neverhood/messages.h
index 78c66868d5..5f1e1b87dd 100644
--- a/engines/neverhood/messages.h
+++ b/engines/neverhood/messages.h
@@ -26,10 +26,50 @@
namespace Neverhood {
enum NeverhoodMessage {
- NM_KLAYMEN_PICKUP = 0x4812,
- NM_KLAYMEN_PRESS_BUTTON = 0x4816,
- NM_KLAYMEN_INSERT_DISK = 0x481A,
- NM_KLAYMEN_RELEASE_LEVER = 0x4827
+ NM_MOUSE_MOVE = 0x0000,
+ NM_MOUSE_CLICK = 0x0001,
+ NM_MOUSE_RELEASE = 0x0002,
+ NM_MOUSE_HIDE = 0x101D,
+ NM_MOUSE_SHOW = 0x101E,
+ NM_KEYPRESS_SPACE = 0x0009,
+ NM_KEYPRESS_ESC = 0x000C,
+ NM_ANIMATION_START = 0x100D,
+ NM_SCENE_LEAVE = 0x1019,
+ NM_PRIORITY_CHANGE = 0x1022,
+ NM_ANIMATION_UPDATE = 0x2000,
+ NM_POSITION_CHANGE = 0x2002,
+ NM_KLAYMEN_CLIMB_LADDER = 0x2005,
+ NM_KLAYMEN_STOP_CLIMBING = 0x2006,
+
+ NM_CAR_MOVE_TO_PREV_POINT = 0x2007,
+ NM_CAR_MOVE_TO_NEXT_POINT = 0x2008,
+ NM_CAR_ENTER = 0x2009,
+ NM_CAR_LEAVE = 0x200A,
+ NM_CAR_TURN = 0x200E,
+ NM_CAR_AT_HOME = 0x200F,
+
+ NM_ANIMATION_STOP = 0x3002,
+
+ NM_KLAYMEN_STAND_IDLE = 0x4004,
+ NM_KLAYMEN_USE_OBJECT = 0x4806,
+ NM_KLAYMEN_RAISE_LEVER = 0x4807,
+ NM_KLAYMEN_OPEN_DOOR = 0x4808,
+ NM_KLAYMEN_CLOSE_DOOR = 0x4809,
+ NM_KLAYMEN_MOVE_OBJECT = 0x480A,
+ NM_KLAYMEN_LOWER_LEVER = 0x480F,
+ NM_KLAYMEN_PICKUP = 0x4812,
+ NM_KLAYMEN_PRESS_BUTTON = 0x4816,
+ NM_KLAYMEN_INSERT_DISK = 0x481A,
+ NM_KLAYMEN_TURN_TO_USE = 0x481D,
+ NM_KLAYMEN_RETURN_FROM_USE = 0x481E,
+ NM_KLAYMEN_RELEASE_LEVER = 0x4827,
+
+ NM_MOVE_TO_BACK = 0x482A,
+ NM_MOVE_TO_FRONT = 0x482B,
+
+ // New to ScummVM
+ NM_MOUSE_WHEELUP = 0xF000,
+ NM_MOUSE_WHEELDOWN = 0xF001
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/module.cpp b/engines/neverhood/module.cpp
index d1578e680c..3ef4554334 100644
--- a/engines/neverhood/module.cpp
+++ b/engines/neverhood/module.cpp
@@ -48,7 +48,7 @@ void Module::draw() {
uint32 Module::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
case 0x0008:
- sendMessage(_parentModule, 8, 0);
+ sendMessage(_parentModule, 0x0008, 0);
return 0;
case 0x1009:
_moduleResult = param.asInteger();
diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk
index 052c830182..9c1220134c 100644
--- a/engines/neverhood/module.mk
+++ b/engines/neverhood/module.mk
@@ -15,27 +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 08fb88ad72..788e22dc1b 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) {
@@ -404,7 +192,7 @@ uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x00342624) {
sendEntityMessage(_klaymen, 0x1014, _asLever);
setMessageList2(0x004B4910);
@@ -426,732 +214,19 @@ uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
setRectList(0x004B49F0);
break;
case 0x480B:
sendMessage(_asWindow, 0x2001, 0);
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
sendMessage(_asHammer, 0x2000, 0);
break;
}
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) {
@@ -1242,7 +317,7 @@ Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
_asVenusFlyTrap = insertSprite<AsScene1002VenusFlyTrap>(this, _klaymen, false);
addCollisionSprite(_asVenusFlyTrap);
- sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap);
+ sendEntityMessage(_klaymen, NM_CAR_MOVE_TO_PREV_POINT, _asVenusFlyTrap);
_asOutsideDoorBackground = insertSprite<AsScene1002OutsideDoorBackground>();
@@ -1272,7 +347,7 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xE6EE60E1) {
if (getGlobalVar(V_FLYTRAP_RING_DOOR))
setMessageList(0x004B4428);
@@ -1306,7 +381,7 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
case 0x1024:
sendMessage(_parentModule, 0x1024, param.asInteger());
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_isClimbingLadder) {
setMessageList2(0x004B43D0);
} else {
@@ -1320,18 +395,18 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_messageList = NULL;
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
_isClimbingLadder = true;
setRectList(0x004B4418);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
_isClimbingLadder = false;
setRectList(0x004B43A0);
break;
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
if (sender == _asRing1) {
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(0, 0x665198C0);
@@ -1341,8 +416,8 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (sender == _asRing3) {
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(1);
- sendMessage(_asDoor, 0x4808, 0);
- sendMessage(_asOutsideDoorBackground, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
+ sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
} else if (sender == _asRing4) {
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(0, 0xE0558848);
@@ -1351,25 +426,25 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
playSound(0, 0x44014282);
}
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
if (sender == _asRing3) {
playSound(2);
- sendMessage(_asDoor, 0x4809, 0);
- sendMessage(_asOutsideDoorBackground, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
+ sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_CLOSE_DOOR, 0);
} else if (sender == _asVenusFlyTrap) {
if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
- sendMessage(_asRing3, 0x4807, 0);
+ sendMessage(_asRing3, NM_KLAYMEN_RAISE_LEVER, 0);
}
}
break;
case 0x480B:
sendEntityMessage(_klaymen, 0x1014, _asDoorSpy);
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
setGlobalVar(V_RADIO_ENABLED, 0);
playSound(1);
- sendMessage(_asDoor, 0x4808, 0);
- sendMessage(_asOutsideDoorBackground, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
+ sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x8000:
setSpriteSurfacePriority(_ssCeiling, 995);
@@ -1383,38 +458,6 @@ uint32 Scene1002::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
-// 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) {
@@ -1478,20 +521,20 @@ uint32 Scene1004::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x926500A1) {
setMessageList(0x004B7C20);
messageResult = 1;
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
loadDataResource(0x01900A04);
break;
case 0x2001:
setRectList(0x004B7C70);
break;
- case 0x2002:
- sendMessage(_asTrashCan, 0x2002, 0);
+ case NM_POSITION_CHANGE:
+ sendMessage(_asTrashCan, NM_POSITION_CHANGE, 0);
break;
}
return messageResult;
@@ -1513,8 +556,6 @@ void Scene1004::updatePaletteArea() {
}
}
-// Scene1005
-
Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule) {
@@ -1540,7 +581,7 @@ Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1005::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
diff --git a/engines/neverhood/modules/module1000.h b/engines/neverhood/modules/module1000.h
index 9e97e822f6..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,127 +53,6 @@ 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);
@@ -251,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);
@@ -272,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..a028df4b10
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.cpp
@@ -0,0 +1,1632 @@
+/* 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 NM_ANIMATION_UPDATE:
+ hammerHitsDoor();
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x00352100)
+ sendMessage(_asDoor, 0x2000, 0);
+ else if (param.asInteger() == 0x0A1A0109)
+ playSound(0, 0x66410886);
+ break;
+ case NM_ANIMATION_UPDATE:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x0E0A1410)
+ playSound(0, 0x60803F10);
+ break;
+ case 0x2001:
+ startAnimation(0xC68C2299, 0, -1);
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x00C0C444)
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
+ else if (param.asInteger() == 0xC41A02C0)
+ playSound(0, 0x40581882);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, 0x4826, 0);
+ messageResult = 1;
+ break;
+ case NM_ANIMATION_STOP:
+ startAnimation(0x04A98C36, 0, -1);
+ _newStickFrameIndex = 0;
+ break;
+ case NM_KLAYMEN_LOWER_LEVER:
+ startAnimation(0x04A98C36, 0, -1);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 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 NM_KLAYMEN_USE_OBJECT:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, NM_KLAYMEN_USE_OBJECT, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled1);
+ startAnimation(_isSpecial ? 0x87502558 : 0x80DD4010, 0, -1);
+ break;
+ case NM_KLAYMEN_LOWER_LEVER:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
+ SetMessageHandler(&AsScene1002Ring::hmRingPulled2);
+ startAnimation(0x861A2020, 0, -1);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled1(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ startAnimation(_isSpecial ? 0x78D0A812 : 0xB85D2A10, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingPulled2(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ startAnimation(0x04103090, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingHangingLow);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingHangingLow(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
+ setDoDeltaX(_vm->_rnd->getRandomNumber(1));
+ startAnimation(0x8258A030, 0, -1);
+ SetMessageHandler(&AsScene1002Ring::hmRingReleased);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002Ring::hmRingReleased(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmRingIdle(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x05410F72)
+ playSound(0, 0x21EE40A9);
+ break;
+ case NM_ANIMATION_STOP:
+ startAnimation(0xA85C4011, 0, -1);
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 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 NM_KLAYMEN_OPEN_DOOR:
+ setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
+ SetSpriteUpdate(&AsScene1002Door::suOpenDoor);
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ 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 NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ 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 NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ 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 NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 995);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1015);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationSimple(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ 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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 995);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 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, NM_KLAYMEN_RAISE_LEVER, 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 NM_KLAYMEN_OPEN_DOOR:
+ _isDoorClosed = false;
+ _countdown = 2;
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ _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 NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1200);
+ _isClipRectSaved = true;
+ _savedClipRect = _surface->getClipRect();
+ setClipRect(0, 0, 640, 480);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x225A8587)
+ playSound(0, 0x109AFC4C);
+ break;
+ case NM_POSITION_CHANGE:
+ startAnimation(0xEB312C11, 0, -1);
+ setVisible(true);
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 2)
+ GotoState(&KmScene1001::stSleeping);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1001::stPullHammerLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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, NM_POSITION_CHANGE, 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 NM_ANIMATION_START:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x4AB28209)
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
+ break;
+ }
+ return messageResult;
+}
+
+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 NM_CAR_MOVE_TO_PREV_POINT:
+ _otherSprite = (Sprite*)param.asEntity();
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_MOVE_OBJECT:
+ GotoState(&KmScene1002::stMoveVenusFlyTrap);
+ break;
+ case 0x480D:
+ GotoState(&KmScene1002::stJumpToRingVenusFlyTrap);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ if (param.asInteger() == 0)
+ GotoState(&KmScene1002::stPressDoorButton);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ startWalkToAttachedSpriteXDistance(param.asInteger());
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ GotoState(&Klaymen::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 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;
+}
+
+void KmScene1002::setupJumpToRing() {
+ _acceptInput = false;
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmJumpToRing);
+ SetSpriteUpdate(&Klaymen::suUpdateDestX);
+ NextState(&KmScene1002::stHangOnRing);
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+}
+
+uint32 KmScene1002::hmJumpToRing(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
+ _acceptInput = true;
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 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::stJumpToRing1() {
+ if (!stStartAction(AnimationCallback(&KmScene1002::stJumpToRing1))) {
+ _busyStatus = 0;
+ startAnimation(0xD82890BA, 0, -1);
+ setupJumpToRing();
+ }
+}
+
+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, NM_MOVE_TO_FRONT, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRing3(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_USE_OBJECT, 0);
+ } else if (param.asInteger() == 0x320AC306) {
+ playSound(0, 0x5860C640);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 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, NM_MOVE_TO_FRONT, 0);
+ }
+}
+
+uint32 KmScene1002::hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x168050A0) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_LOWER_LEVER, 0);
+ } else if (param.asInteger() == 0x586B0300) {
+ sendMessage(_otherSprite, 0x480E, 1);
+ } else if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 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, NM_KLAYMEN_RAISE_LEVER, 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 NM_ANIMATION_START:
+ 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, NM_MOVE_TO_BACK, 0);
+}
+
+uint32 KmScene1002::hmMoveVenusFlyTrap(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ 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, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ _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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_BACK, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, NM_MOVE_TO_FRONT, 0);
+ } else if (param.asInteger() == 0x32180101) {
+ playSound(0, 0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ playSound(0, 0x0460E2FA);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1002::stPressDoorButton() {
+ _busyStatus = 2;
+ _acceptInput = true;
+ setDoDeltaX(0);
+ startAnimation(0x1CD89029, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmPressDoorButton);
+ SetSpriteUpdate(&Klaymen::suAction);
+}
+
+void KmScene1002::stHitByBoxingGlove() {
+ _busyStatus = 1;
+ _acceptInput = false;
+ startAnimation(0x35AA8059, 0, -1);
+ SetUpdateHandler(&Klaymen::update);
+ SetMessageHandler(&KmScene1002::hmHitByBoxingGlove);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ FinalizeState(&KmScene1002::evHitByBoxingGloveDone);
+}
+
+void KmScene1002::evHitByBoxingGloveDone() {
+ sendMessage(_parentScene, 0x1024, 1);
+}
+
+uint32 KmScene1002::hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x942D2081) {
+ _acceptInput = false;
+ sendMessage(_attachedSprite, 0x2003, 0);
+ } else if (param.asInteger() == 0xDA600012) {
+ stHitByBoxingGlove();
+ } else if (param.asInteger() == 0x0D01B294) {
+ _acceptInput = false;
+ sendMessage(_attachedSprite, 0x480B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene1002::hmHitByBoxingGlove(int messageNum, const MessageParam &param, Entity *sender) {
+ int16 speedUpFrameIndex;
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1008:
+ speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
+ if (_currFrameIndex < speedUpFrameIndex) {
+ startAnimation(0x35AA8059, speedUpFrameIndex, -1);
+ _y = 435;
+ }
+ messageResult = 0;
+ break;
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x1A1A0785) {
+ playSound(0, 0x40F0A342);
+ } else if (param.asInteger() == 0x60428026) {
+ playSound(0, 0x40608A59);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 KmScene1004::hmReadNote(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x04684052) {
+ _acceptInput = true;
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 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..564b3cc335
--- /dev/null
+++ b/engines/neverhood/modules/module1000_sprites.h
@@ -0,0 +1,262 @@
+/* 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();
+ void stPressDoorButton();
+ void stHitByBoxingGlove();
+ void evHitByBoxingGloveDone();
+
+ 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);
+ uint32 hmPressDoorButton(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmHitByBoxingGlove(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..e40508e502 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 {
@@ -135,15 +136,20 @@ void Module1100::updateScene() {
switch (_sceneNum) {
case 0:
_countdown = 0;
- _vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
- if (_moduleResult == 0)
+ if (_moduleResult == 0) {
+ _vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
createScene(1, 0);
- else if (_moduleResult == 1)
+ } else if (_moduleResult == 1) {
+ /* NOTE This fixes a bug in the original where the "tunnel" footstep
+ sounds are played instead of the correct footsteps. */
+ _vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
createScene(8, 0);
+ }
break;
case 1:
+ _countdown = 0;
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
if (getGlobalVar(V_ROBOT_HIT)) {
if (_moduleResult == 0)
@@ -236,6 +242,13 @@ void Module1100::updateScene() {
}
}
+static const uint32 kScene1105BackgroundFileHashes[] = {
+ 0x20018662,
+ 0x20014202,
+ 0x20012202,
+ 0x20010002 // CHECKME: This used ??
+};
+
static const uint32 kScene1105FileHashes[] = {
0x00028006,
0x0100A425,
@@ -249,186 +262,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) {
@@ -458,7 +291,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
if (!_isActionButtonClicked && _backgroundIndex == 0) {
if (_isPanelOpen) {
@@ -481,7 +314,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entit
_leaveResult = 1;
SetUpdateHandler(&Scene1105::upClosePanel);
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
if (sender == _ssActionButton) {
if (getSubVar(VA_GOOD_DICE_NUMBERS, 0) == getSubVar(VA_CURR_DICE_NUMBERS, 0) &&
getSubVar(VA_GOOD_DICE_NUMBERS, 1) == getSubVar(VA_CURR_DICE_NUMBERS, 1) &&
@@ -490,7 +323,7 @@ uint32 Scene1105::handleMessage(int messageNum, const MessageParam &param, Entit
playSound(2);
_doMoveTeddy = true;
} else {
- sendMessage(_asTeddyBear, 0x2002, 0);
+ sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
}
showMouse(false);
_isActionButtonClicked = true;
@@ -632,7 +465,7 @@ void Scene1105::update() {
if (_isClosePanelDone && !isSoundPlaying(1))
leaveScene(_leaveResult);
if (_doMoveTeddy && !isSoundPlaying(2)) {
- sendMessage(_asTeddyBear, 0x2002, 0);
+ sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
_doMoveTeddy = false;
}
}
@@ -685,7 +518,7 @@ Scene1109::Scene1109(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1109::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004B63A8);
_klaymen->setKlaymenIdleTable3();
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..49a388ffca
--- /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, NM_KLAYMEN_RAISE_LEVER, 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 NM_ANIMATION_UPDATE:
+ 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 NM_POSITION_CHANGE:
+ if (getGlobalVar(V_ROBOT_TARGET)) {
+ startAnimation(0x6B0C0432, 0, -1);
+ playSound(0);
+ } else {
+ startAnimation(0x65084002, 0, -1);
+ playSound(1);
+ }
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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..8bf42b3b96 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) {
@@ -851,15 +296,15 @@ void Scene1201::update() {
uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x07053000) {
_creatureExploded = true;
sendMessage(_asCreature, 0x2004, 0);
} else if (param.asInteger() == 0x140E5744)
- sendMessage(_asCreature, 0x2005, 0);
+ sendMessage(_asCreature, NM_KLAYMEN_CLIMB_LADDER, 0);
else if (param.asInteger() == 0x40253C40) {
_canAcceptInput = false;
- sendMessage(_asCreature, 0x2006, 0);
+ sendMessage(_asCreature, NM_KLAYMEN_STOP_CLIMBING, 0);
} else if (param.asInteger() == 0x090EB048) {
if (_klaymen->getX() < 572)
setMessageList2(0x004AEC90);
@@ -875,7 +320,7 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList2(0x004AECC0);
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
// Move the TNT dummy if the fuse is burning
sendEntityMessage(_klaymen, 0x1014, _asTntMan);
@@ -902,101 +347,16 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
sendMessage(_asRightDoor, 0x4829, 0);
break;
case 0x8000:
- sendMessage(_asKlaymenHead, 0x2006, 0);
+ sendMessage(_asKlaymenHead, NM_KLAYMEN_STOP_CLIMBING, 0);
break;
}
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) {
@@ -1067,14 +427,14 @@ uint32 Scene1202::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isPuzzleSolved)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_clickedIndex = (int)param.asInteger();
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_counter--;
break;
}
@@ -1084,7 +444,7 @@ uint32 Scene1202::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene1202::hmSolved(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
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..5848e16092
--- /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 NM_KLAYMEN_USE_OBJECT:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0x47900E06);
+ break;
+ case NM_KLAYMEN_STOP_CLIMBING:
+ 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 NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_STOP_CLIMBING:
+ _x = 436;
+ _y = 339;
+ startAnimation(0xA060C599, 0, -1);
+ setVisible(true);
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x092870C0)
+ sendMessage(_asTntManRope, NM_KLAYMEN_STOP_CLIMBING, 0);
+ else if (param.asInteger() == 0x11CA0144)
+ playSound(0, 0x51800A04);
+ break;
+ case 0x1011:
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 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 NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ 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 NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_USE_OBJECT:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x02060018)
+ playSound(0, 0xCD298116);
+ break;
+ case 0x2004:
+ GotoState(&AsScene1201Creature::stStartReachForTntDummy);
+ break;
+ case NM_KLAYMEN_STOP_CLIMBING:
+ 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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x02060018) {
+ playSound(0, 0xCD298116);
+ sendMessage(_parentScene, 0x4814, 0);
+ sendMessage(_klaymen, 0x4814, 0);
+ }
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_CLOSE_DOOR:
+ 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 NM_ANIMATION_STOP:
+ 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, NM_POSITION_CHANGE, _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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ GotoState(&Klaymen::stMoveObject);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case 0x4813:
+ GotoState(&KmScene1201::stFetchMatch);
+ break;
+ case 0x4814:
+ GotoState(&KmScene1201::stTumbleHeadless);
+ break;
+ case 0x4815:
+ GotoState(&KmScene1201::stCloseEyes);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_ANIMATION_START:
+ 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 NM_ANIMATION_START:
+ 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..fe119c1732 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) {
@@ -458,7 +350,7 @@ Scene1302::Scene1302(NeverhoodEngine *vm, Module *parentModule, int which)
_asVenusFlyTrap = insertSprite<AsScene1002VenusFlyTrap>(this, _klaymen, true);
addCollisionSprite(_asVenusFlyTrap);
- sendEntityMessage(_klaymen, 0x2007, _asVenusFlyTrap);
+ sendEntityMessage(_klaymen, NM_CAR_MOVE_TO_PREV_POINT, _asVenusFlyTrap);
}
@@ -466,10 +358,10 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
- if (param.asInteger() == 0x4A845A00)
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x4A845A00) {
sendEntityMessage(_klaymen, 0x1014, _asRing1);
- else if (param.asInteger() == 0x43807801) {
+ } else if (param.asInteger() == 0x43807801) {
if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
sendEntityMessage(_klaymen, 0x1014, _asRing2);
if (_asVenusFlyTrap->getX() - 10 < 218 + 32 && _asVenusFlyTrap->getX() + 10 > 218 + 32)
@@ -479,9 +371,9 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
} else
setMessageList(0x004B0950);
messageResult = 1;
- } else if (param.asInteger() == 0x46C26A01)
+ } else if (param.asInteger() == 0x46C26A01) {
sendEntityMessage(_klaymen, 0x1014, _asRing3);
- else if (param.asInteger() == 0x468C7B11) {
+ } else if (param.asInteger() == 0x468C7B11) {
if (!getGlobalVar(V_FLYTRAP_RING_FENCE)) {
sendEntityMessage(_klaymen, 0x1014, _asRing4);
if (_asVenusFlyTrap->getX() - 10 < 218 + 32 + 32 + 32 && _asVenusFlyTrap->getX() + 10 > 218 + 32 + 32 + 32)
@@ -491,9 +383,9 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
} else
setMessageList(0x004B0950);
messageResult = 1;
- } else if (param.asInteger() == 0x42845B19)
+ } else if (param.asInteger() == 0x42845B19) {
sendEntityMessage(_klaymen, 0x1014, _asRing5);
- else if (param.asInteger() == 0x430A6060) {
+ } else if (param.asInteger() == 0x430A6060) {
if (getGlobalVar(V_FLYTRAP_RING_BRIDGE))
setMessageList2(0x004B0910);
else
@@ -510,66 +402,66 @@ uint32 Scene1302::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B0978);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_klaymen->getY() > 360) {
sendEntityMessage(_klaymen, 0x1014, _asVenusFlyTrap);
setMessageList2(0x004B08F0);
} else
setMessageList2(0x004B0920);
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (_klaymen->getX() > 545)
leaveScene(1);
break;
case 0x2032:
_sprite2->setVisible(true);
break;
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
sendMessage(_parentModule, 0x1024, 2);
if (sender == _asRing1)
playSound(0, 0x665198C0);
else if (sender == _asRing2) {
- sendMessage(_asBridge, 0x4808, 0);
+ sendMessage(_asBridge, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_BRIDGE, 1);
- } else if (sender == _asRing3)
+ } else if (sender == _asRing3) {
playSound(0, 0xE2D389C0);
- else if (sender == _asRing4) {
- sendMessage(_ssFence, 0x4808, 0);
+ } else if (sender == _asRing4) {
+ sendMessage(_ssFence, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_FENCE, 1);
} else if (sender == _asRing5)
playSound(0, 0x40428A09);
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
if (sender == _asRing2) {
- sendMessage(_asBridge, 0x4809, 0);
+ sendMessage(_asBridge, NM_KLAYMEN_CLOSE_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_BRIDGE, 0);
_sprite2->setVisible(false);
} else if (sender == _asRing4) {
- sendMessage(_ssFence, 0x4809, 0);
+ sendMessage(_ssFence, NM_KLAYMEN_CLOSE_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_FENCE, 0);
} else if (sender == _asVenusFlyTrap) {
if (getGlobalVar(V_FLYTRAP_RING_BRIDGE))
- sendMessage(_asRing2, 0x4807, 0);
+ sendMessage(_asRing2, NM_KLAYMEN_RAISE_LEVER, 0);
else
- sendMessage(_asRing4, 0x4807, 0);
+ sendMessage(_asRing4, NM_KLAYMEN_RAISE_LEVER, 0);
}
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
if (sender == _asRing2) {
playSound(0, 0x60755842);
- sendMessage(_asBridge, 0x4808, 0);
+ sendMessage(_asBridge, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_BRIDGE, 1);
} else if (sender == _asRing4) {
playSound(0, 0x60755842);
- sendMessage(_ssFence, 0x4808, 0);
+ sendMessage(_ssFence, NM_KLAYMEN_OPEN_DOOR, 0);
setGlobalVar(V_FLYTRAP_RING_FENCE, 1);
}
break;
- case 0x482A:
- sendMessage(_asVenusFlyTrap, 0x482B, 0);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_asVenusFlyTrap, NM_MOVE_TO_FRONT, 0);
break;
- case 0x482B:
- sendMessage(_asVenusFlyTrap, 0x482A, 0);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_asVenusFlyTrap, NM_MOVE_TO_BACK, 0);
break;
case 0x8000:
setSpriteSurfacePriority(_class595, 995);
@@ -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);
@@ -656,7 +500,7 @@ Scene1303::Scene1303(NeverhoodEngine *vm, Module *parentModule)
uint32 Scene1303::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
setGlobalVar(V_BALLOON_POPPED, 1);
sendMessage(_asBalloon, 0x2000, 0);
break;
@@ -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) {
@@ -734,7 +555,7 @@ Scene1304::Scene1304(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1304::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x415634A4) {
if (getGlobalVar(V_BALLOON_POPPED))
cancelMessageList();
@@ -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) {
@@ -893,7 +629,7 @@ Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
insertStaticSprite(0x00042313, 1100);
if (which < 0) {
- // Resoring game
+ // Restoring game
insertKlaymen<KmScene1306>(380, 440);
setMessageList(0x004AFAD0);
sendMessage(this, 0x2000, 0);
@@ -945,7 +681,7 @@ Scene1306::Scene1306(NeverhoodEngine *vm, Module *parentModule, int which)
sendMessage(this, 0x2000, 0);
SetMessageHandler(&Scene1306::handleMessage416EB0);
clearRectList();
- sendMessage(_asElevator, 0x4808, 0);
+ sendMessage(_asElevator, NM_KLAYMEN_OPEN_DOOR, 0);
}
}
@@ -957,7 +693,7 @@ Scene1306::~Scene1306() {
uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x01C66840) {
@@ -971,7 +707,7 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
SetMessageHandler(&Scene1306::handleMessage416EB0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger() != 0) {
setRectList(0x004AFD28);
_klaymen->setKlaymenIdleTable3();
@@ -982,7 +718,7 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x480B:
if (sender == _ssButton)
- sendMessage(_asElevator, 0x4808, 0);
+ sendMessage(_asElevator, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x4826:
if (sender == _asKey) {
@@ -997,12 +733,12 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
setSurfacePriority(_asElevator->getSurface(), 1100);
setSurfacePriority(_asElevatorDoor->getSurface(), 1090);
setSurfacePriority(_sprite1->getSurface(), 1080);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
setSurfacePriority(_asElevator->getSurface(), 100);
setSurfacePriority(_asElevatorDoor->getSurface(), 90);
setSurfacePriority(_sprite1->getSurface(), 80);
@@ -1016,19 +752,19 @@ uint32 Scene1306::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene1306::handleMessage416EB0(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x4808:
+ case NM_KLAYMEN_OPEN_DOOR:
setMessageList(0x004AFBD0);
SetMessageHandler(&Scene1306::handleMessage);
break;
- case 0x4809:
+ case NM_KLAYMEN_CLOSE_DOOR:
leaveScene(1);
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
setSurfacePriority(_asElevator->getSurface(), 1100);
setSurfacePriority(_asElevatorDoor->getSurface(), 1090);
setSurfacePriority(_sprite1->getSurface(), 1080);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
setSurfacePriority(_asElevator->getSurface(), 100);
setSurfacePriority(_asElevatorDoor->getSurface(), 90);
setSurfacePriority(_sprite1->getSurface(), 80);
@@ -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) {
@@ -1286,7 +840,7 @@ uint32 Scene1307::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (!_isPuzzleSolved) {
if (param.asPoint().x > 20 && param.asPoint().x < 620) {
if (_asCurrKey && !_isInsertingKey) {
@@ -1319,7 +873,7 @@ uint32 Scene1307::handleMessage(int messageNum, const MessageParam &param, Entit
leaveScene(0);
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
// Check if all keys are in the correct keyholes
if (getSubVar(VA_IS_KEY_INSERTED, 0) && getSubVar(VA_CURR_KEY_SLOT_NUMBERS, 0) == getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 0) &&
getSubVar(VA_IS_KEY_INSERTED, 1) && getSubVar(VA_CURR_KEY_SLOT_NUMBERS, 1) == getSubVar(VA_GOOD_KEY_SLOT_NUMBERS, 1) &&
@@ -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) {
@@ -1585,7 +981,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
// Klaymen entering from the left
insertKlaymen<KmScene1308>(41, 440);
setMessageList(0x004B57D0);
- sendMessage(_asJaggyDoor, 0x4808, 0);
+ sendMessage(_asJaggyDoor, NM_KLAYMEN_OPEN_DOOR, 0);
_sprite1->setVisible(false);
if (getGlobalVar(V_KEYDOOR_UNLOCKED)) {
_sprite4 = insertStaticSprite(0x0101A624, 1100);
@@ -1613,7 +1009,7 @@ Scene1308::Scene1308(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x88C11390) {
setRectList(0x004B59A0);
_isProjecting = true;
@@ -1626,12 +1022,12 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entit
_isProjecting = false;
} else if (param.asInteger() == 0x4AC68808) {
clearRectList();
- sendMessage(_asJaggyDoor, 0x4809, 0);
+ sendMessage(_asJaggyDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
_sprite1->setVisible(false);
_klaymen->setVisible(false);
}
break;
- case 0x1022:
+ case NM_PRIORITY_CHANGE:
if (sender == _asProjector) {
if (param.asInteger() >= 1000)
setSurfacePriority(_sprite3->getSurface(), 1100);
@@ -1639,7 +1035,7 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entit
setSurfacePriority(_sprite3->getSurface(), 995);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (getGlobalVar(V_KEYDOOR_UNLOCKED))
setRectList(0x004B5990);
else
@@ -1660,11 +1056,11 @@ uint32 Scene1308::handleMessage(int messageNum, const MessageParam &param, Entit
_sprite4->setVisible(true);
setRectList(0x004B5990);
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
sendMessage(_asLightWallSymbols, 0x2003, 0);
break;
- case 0x480F:
- sendMessage(_asLightWallSymbols, 0x2002, 0);
+ case NM_KLAYMEN_LOWER_LEVER:
+ sendMessage(_asLightWallSymbols, NM_POSITION_CHANGE, 0);
_ssNumber1->setVisible(true);
_ssNumber2->setVisible(true);
_ssNumber3->setVisible(true);
@@ -1745,7 +1141,7 @@ void Scene1317::upChooseKing() {
uint32 Scene1317::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
stChooseKing();
break;
}
@@ -1755,7 +1151,7 @@ uint32 Scene1317::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x >= 21 && param.asPoint().y >= 24 &&
param.asPoint().x <= 261 && param.asPoint().y <= 280) {
stHoborgAsKing();
@@ -1774,7 +1170,7 @@ uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam &param, Entity
uint32 Scene1317::hmHoborgAsKing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
stEndMovie();
break;
}
@@ -1784,7 +1180,7 @@ uint32 Scene1317::hmHoborgAsKing(int messageNum, const MessageParam &param, Enti
uint32 Scene1317::hmEndMovie(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
leaveScene(0);
break;
}
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..0c1632501e
--- /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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ stLowerBridge();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ 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 NM_KLAYMEN_OPEN_DOOR:
+ playSound(0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ 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 NM_ANIMATION_UPDATE:
+ stPopBalloon();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_START:
+ if (param.asInteger() == 0x020B0003)
+ playSound(0, 0x742B0055);
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_USE_OBJECT:
+ 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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ 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, NM_KLAYMEN_OPEN_DOOR, 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, NM_KLAYMEN_CLOSE_DOOR, 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 NM_ANIMATION_UPDATE:
+ _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, NM_POSITION_CHANGE, 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, NM_PRIORITY_CHANGE, 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, NM_PRIORITY_CHANGE, 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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ stOpenDoor();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ 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 NM_ANIMATION_STOP:
+ 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 NM_POSITION_CHANGE:
+ stFadeIn();
+ break;
+ case 0x2003:
+ stFadeOut();
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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 NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_INSERT_DISK:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ else
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_INSERT_DISK:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ GotoState(&Klaymen::stReturnFromUse);
+ break;
+ case NM_KLAYMEN_RELEASE_LEVER:
+ 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..018f27e2b7 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),
@@ -696,7 +207,7 @@ Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
_klaymen->setClipRect(_sprite3->getDrawRect().x, 0, 640, 480);
if (which == 0 && _asProjector)
- sendMessage(_asProjector, 0x482B, 0);
+ sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
_asBackDoor = insertSprite<AsScene1401BackDoor>(_klaymen, which == 0);
@@ -714,7 +225,7 @@ void Scene1401::update() {
uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x02144CB1)
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
else if (param.asInteger() == 0x402064D8)
@@ -726,7 +237,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B66B0);
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
if (param.asInteger() != 0)
leaveScene(2);
else
@@ -743,7 +254,7 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
if (_asProjector && _asProjector->getX() > 404 && _asProjector->getX() < 504)
sendMessage(_asProjector , 0x4839, 0);
} else if (sender == _ssButton)
- sendMessage(_asBackDoor, 0x4808, 0);
+ sendMessage(_asBackDoor, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x4826:
if (sender == _asProjector) {
@@ -754,91 +265,20 @@ uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList2(0x004B65F0);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
_sprite1->setVisible(true);
if (_asProjector)
- sendMessage(_asProjector, 0x482B, 0);
+ sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_sprite1->setVisible(false);
if (_asProjector)
- sendMessage(_asProjector, 0x482A, 0);
+ sendMessage(_asProjector, NM_MOVE_TO_BACK, 0);
break;
}
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) {
@@ -935,7 +375,7 @@ void Scene1402::upShaking() {
uint32 Scene1402::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x00F43389) {
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
leaveScene(0);
@@ -943,18 +383,18 @@ uint32 Scene1402::handleMessage(int messageNum, const MessageParam &param, Entit
clearRectList();
_klaymen->setVisible(false);
showMouse(false);
- sendMessage(_asPuzzleBox, 0x2002, 0);
+ sendMessage(_asPuzzleBox, NM_POSITION_CHANGE, 0);
startShaking();
}
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
if (param.asInteger())
leaveScene(0);
else
leaveScene(1);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
stopShaking();
showMouse(true);
setRectList(0x004B0C48);
@@ -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) {
@@ -1246,7 +455,7 @@ void Scene1407::update() {
uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (_puzzleSolvedCountdown == 0) {
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
// Exit scene
@@ -1264,7 +473,7 @@ uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
// The mouse got the cheese (nomnom)
setGlobalVar(V_MOUSE_PUZZLE_SOLVED, 1);
playSound(0, 0x68E25540);
@@ -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) {
@@ -1327,7 +534,7 @@ Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x88C11390) {
setRectList(0x004B2008);
_isProjecting = true;
@@ -1337,10 +544,10 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
_isProjecting = false;
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
leaveScene(0);
break;
- case 0x1022:
+ case NM_PRIORITY_CHANGE:
if (sender == _asProjector) {
if (param.asInteger() >= 1000)
setSurfacePriority(_sprite3->getSurface(), 1100);
@@ -1348,10 +555,10 @@ uint32 Scene1403::handleMessage(int messageNum, const MessageParam &param, Entit
setSurfacePriority(_sprite3->getSurface(), 995);
}
break;
- case 0x4807:
+ case NM_KLAYMEN_RAISE_LEVER:
_sprite1->setVisible(false);
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
_sprite1->setVisible(true);
break;
case 0x4826:
@@ -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) {
@@ -1450,7 +655,7 @@ Scene1404::~Scene1404() {
uint32 Scene1404::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x410650C2) {
if (_asProjector && _asProjector->getX() == 220)
setMessageList(0x004B8C40);
@@ -1458,7 +663,7 @@ uint32 Scene1404::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B8CE8);
}
break;
- case 0x1019:
+ case NM_SCENE_LEAVE:
leaveScene(0);
break;
case 0x4826:
@@ -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) {
@@ -1591,11 +725,11 @@ void Scene1405::update() {
uint32 Scene1405::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_selectFirstTile) {
_firstTileIndex = param.asInteger();
_selectFirstTile = false;
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..478b328034
--- /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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x0A8A1490)
+ playSound(1, 0x6AB6666F);
+ break;
+ case NM_ANIMATION_UPDATE:
+ _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 NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ 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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ _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 NM_KLAYMEN_RAISE_LEVER:
+ 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 NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 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 NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 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 NM_KLAYMEN_LOWER_LEVER:
+ stStartProjecting();
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonProjector::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case NM_ANIMATION_STOP:
+ 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, NM_SCENE_LEAVE, 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, NM_SCENE_LEAVE, 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, NM_KLAYMEN_LOWER_LEVER, 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 NM_POSITION_CHANGE:
+ playSound(1);
+ startAnimation(0x20060259, -1, -1);
+ _playBackwards = true;
+ NextState(&AsScene1402PuzzleBox::stMoveDownDone);
+ break;
+ case NM_ANIMATION_STOP:
+ 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, NM_SCENE_LEAVE, 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 NM_MOUSE_CLICK:
+ {
+ 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 NM_SCENE_LEAVE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stUseLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_RELEASE_LEVER:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_MOVE_OBJECT:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
+ else
+ GotoState(&Klaymen::stMoveObjectFaceObject);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_INSERT_DISK:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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/module1500.cpp b/engines/neverhood/modules/module1500.cpp
index 3ce9783b69..eaa23e586b 100644
--- a/engines/neverhood/modules/module1500.cpp
+++ b/engines/neverhood/modules/module1500.cpp
@@ -102,11 +102,11 @@ void Scene1501::update() {
Scene::update();
if (_countdown1 != 0) {
_countdown1--;
- if (_countdown1 == 0) {
+ if (_countdown1 == 0 || _skip) {
_vm->_screen->clear();
leaveScene(0);
}
- } else if ((_countdown2 != 0 && (--_countdown2 == 0)) || (_countdown2 == 0 && !isSoundPlaying(0))) {
+ } else if ((_countdown2 != 0 && (--_countdown2 == 0)) || (_countdown2 == 0 && !isSoundPlaying(0)) || _skip) {
_countdown1 = 12;
_palette->startFadeToBlack(11);
}
@@ -124,7 +124,7 @@ void Scene1501::update() {
uint32 Scene1501::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
_skip = true;
break;
}
diff --git a/engines/neverhood/modules/module1600.cpp b/engines/neverhood/modules/module1600.cpp
index a5a785e130..76c5ca93d2 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) {
@@ -1075,7 +258,7 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
SetMessageHandler(&Scene1608::hmUpperFloor);
SetUpdateHandler(&Scene1608::upUpperFloor);
_asCar->setPathPoints(_roomPathPoints);
- sendMessage(_asCar, 0x2002, _roomPathPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _roomPathPoints->size() - 1);
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
@@ -1116,15 +299,15 @@ Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
_asIdleCarLower->setVisible(false);
_asIdleCarFull->setVisible(false);
_asCar->setPathPoints(_roomPathPoints);
- sendMessage(_asCar, 0x2002, 0);
- sendMessage(_asCar, 0x2008, 90);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 90);
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
_clipRect2 = _clipRect1;
_clipRect2.y2 = 215;
_kmScene1608->setClipRect(_clipRect1);
- _asCar->setClipRect(_clipRect1);
+ _asCar->setClipRect(_clipRect3);
_asIdleCarLower->setClipRect(_clipRect1);
_asIdleCarFull->setClipRect(_clipRect1);
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
@@ -1166,7 +349,7 @@ void Scene1608::upUpperFloor() {
_asIdleCarLower->setVisible(false);
_asIdleCarFull->setVisible(false);
_asCar->setVisible(true);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->handleUpdate();
_klaymen = NULL;
_carStatus = 0;
@@ -1178,7 +361,7 @@ void Scene1608::upCarAtHome() {
Scene::update();
if (_mouseClicked) {
if (_mouseClickPos.x <= 329 && _asCar->getX() == 375 && _asCar->getY() == 227) {
- sendMessage(_asCar, 0x200A, 0);
+ sendMessage(_asCar, NM_CAR_LEAVE, 0);
SetUpdateHandler(&Scene1608::upGettingOutOfCar);
} else {
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
@@ -1218,12 +401,12 @@ void Scene1608::upRidingCar() {
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
_mouseClicked = false;
}
- if (_asCar->getX() < 300) {
+ if (_asCar->getY() < 330) {
if (_carClipFlag) {
_carClipFlag = false;
_asCar->setClipRect(_clipRect1);
if (!_asCar->isDoDeltaX())
- sendMessage(_asCar, 0x200E, 0);
+ sendMessage(_asCar, NM_CAR_TURN, 0);
}
} else if (!_carClipFlag) {
_carClipFlag = true;
@@ -1234,13 +417,13 @@ void Scene1608::upRidingCar() {
uint32 Scene1608::hmLowerFloor(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x20250B1A) {
clearRectList();
_klaymen->setVisible(false);
showMouse(false);
_sprite1->setVisible(false);
- //sendMessage(_asDoor, 0x4809, 0); // Play sound?
+ //sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0); // Play sound?
_countdown1 = 28;
}
break;
@@ -1261,7 +444,7 @@ uint32 Scene1608::hmLowerFloor(int messageNum, const MessageParam &param, Entity
uint32 Scene1608::hmUpperFloor(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x60842040)
_carStatus = 1;
break;
@@ -1281,13 +464,13 @@ uint32 Scene1608::hmUpperFloor(int messageNum, const MessageParam &param, Entity
uint32 Scene1608::hmRidingCar(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
leaveScene(1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
SetMessageHandler(&Scene1608::hmCarAtHome);
SetUpdateHandler(&Scene1608::upCarAtHome);
- sendMessage(_asCar, 0x200F, 1);
+ sendMessage(_asCar, NM_CAR_AT_HOME, 1);
break;
case 0x200D:
sendMessage(_parentModule, 0x200D, 0);
@@ -1299,7 +482,7 @@ uint32 Scene1608::hmRidingCar(int messageNum, const MessageParam &param, Entity
uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x200A:
+ case NM_CAR_LEAVE:
_carStatus = 2;
break;
case 0x200D:
@@ -1361,11 +544,11 @@ void Scene1609::update() {
uint32 Scene1609::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!_isSolved) {
if (_changeCurrentSymbol)
_asSymbols[_symbolPosition]->change(_currentSymbolIndex + 12, false);
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..b7b3658c5e
--- /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 NM_SCENE_LEAVE:
+ SetSpriteUpdate(NULL);
+ break;
+ case NM_POSITION_CHANGE:
+ // 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, NM_KLAYMEN_CLIMB_LADDER, 0);
+ } else if (_currPointIndex == (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 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 NM_CAR_MOVE_TO_PREV_POINT:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ break;
+ case NM_CAR_MOVE_TO_NEXT_POINT:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ break;
+ case NM_CAR_ENTER:
+ stEnterCar();
+ break;
+ case NM_CAR_LEAVE:
+ stLeaveCar();
+ break;
+ case NM_CAR_TURN:
+ stTurnCar();
+ break;
+ case NM_CAR_AT_HOME:
+ 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 NM_ANIMATION_START:
+ if (_isBusy && param.asInteger() == 0x025424A2)
+ gotoNextState();
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case NM_CAR_ENTER:
+ stEnterCar();
+ break;
+ case NM_ANIMATION_STOP:
+ sendMessage(_parentScene, NM_CAR_LEAVE, 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, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 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, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 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, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, NM_SCENE_LEAVE, 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, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::suMoveToPrevPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, NM_SCENE_LEAVE, 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, NM_SCENE_LEAVE, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 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 NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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..1062691cd2 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) {
@@ -257,7 +215,7 @@ void Scene1705::update() {
uint32 Scene1705::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004B6B40);
_klaymen->setKlaymenIdleTable3();
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..d6e00c95f3
--- /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 NM_KLAYMEN_USE_OBJECT:
+ 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 NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ GotoState(&Klaymen::stFallSkipJump);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter) {
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ }
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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..5fdc6091dc 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) {
@@ -589,13 +198,13 @@ void Scene1907::update() {
uint32 Scene1907::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) &&
!_hasPlugInFailed && _moveDownCountdown == 0 && _moveUpCountdown == 0 && _countdown3 == 0) {
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (getGlobalVar(V_STAIRS_DOWN)) {
playSound(0);
for (int i = 0; i < 9; i++)
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..9e43203def
--- /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 NM_ANIMATION_STOP:
+ 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, NM_PRIORITY_CHANGE, 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, NM_PRIORITY_CHANGE, 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 NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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..ad18e65cdd 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 {
@@ -145,7 +144,7 @@ Scene2001::Scene2001(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2001::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004B3680);
_klaymen->setKlaymenIdleTable3();
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..35edd8e73f
--- /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 NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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..e95eb58420 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) {
@@ -266,7 +147,7 @@ void Scene2101::update() {
if (_countdown1 != 0) {
if (_doorStatus == 2) {
if (--_countdown1 == 0) {
- sendMessage(_asDoor, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
_doorStatus = 1;
}
} else {
@@ -274,12 +155,12 @@ void Scene2101::update() {
_canAcceptInput = false;
if (--_countdown1 == 0) {
if (_klaymen->getX() < 480) {
- sendMessage(_asDoor, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
_doorStatus = 1;
} else if (_klaymen->getX() >= 480 && _klaymen->getX() <= 575) {
_klaymen->setDoDeltaX(0);
setMessageList2(0x004B8F48);
- sendMessage(_asDoor, 0x4809, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
sendMessage(_asHitByDoorEffect, 0x2001, 0);
_doorStatus = 1;
}
@@ -293,7 +174,7 @@ void Scene2101::update() {
uint32 Scene2101::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x02144CB1)
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
else if (param.asInteger() == 0x21E64A00) {
@@ -304,7 +185,7 @@ uint32 Scene2101::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (param.asInteger() == 0x41442820)
cancelMessageList();
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger() != 0) {
setRectList(0x004B9008);
_klaymen->setKlaymenIdleTable3();
@@ -315,7 +196,7 @@ uint32 Scene2101::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x480B:
if (sender == _ssFloorButton && _doorStatus == 1) {
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
_doorStatus = 0;
_countdown1 = 90;
}
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..f43c0afed5
--- /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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ stOpenDoor();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ 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 NM_ANIMATION_STOP:
+ 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, NM_PRIORITY_CHANGE, 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, NM_PRIORITY_CHANGE, 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 NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4811:
+ GotoState(&KmScene2101::stHitByDoor);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_ANIMATION_START:
+ 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..f1d5d2854d 100644
--- a/engines/neverhood/modules/module2200.cpp
+++ b/engines/neverhood/modules/module2200.cpp
@@ -20,11 +20,14 @@
*
*/
-#include "neverhood/modules/module2200.h"
-#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1200.h"
-#include "neverhood/gamemodule.h"
+#include "common/config-manager.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 {
@@ -45,6 +48,18 @@ Module2200::~Module2200() {
}
void Module2200::createScene(int sceneNum, int which) {
+ if (sceneNum == 46 && ConfMan.getBool("skiphallofrecordsscenes")) {
+ // Skip the whole Hall of Records storyboard scenes,
+ // and teleport to the last scene
+ sceneNum = 41;
+ }
+
+ if (sceneNum == 40 && ConfMan.getBool("skiphallofrecordsscenes")) {
+ // Skip the whole Hall of Records storyboard scenes,
+ // and teleport back to the first scene
+ sceneNum = 5;
+ }
+
debug(1, "Module2200::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
switch (_sceneNum) {
@@ -445,95 +460,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) {
@@ -625,7 +551,7 @@ void Scene2201::update() {
uint32 Scene2201::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssDoorButton);
else if (param.asInteger() == 0x35803198) {
@@ -649,7 +575,7 @@ uint32 Scene2201::handleMessage(int messageNum, const MessageParam &param, Entit
break;
case 0x480B:
if (sender == _ssDoorButton)
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
break;
case 0x4826:
if (sender == _asTape) {
@@ -661,215 +587,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) {
@@ -945,15 +662,15 @@ void Scene2202::update() {
uint32 Scene2202::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_movingCubePosition = (int16)param.asInteger();
_ssMovingCube = (Sprite*)sender;
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_isCubeMoving = false;
_ssDoneMovingCube = (Sprite*)sender;
if (param.asInteger() <= 2)
@@ -991,100 +708,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) {
@@ -1163,7 +786,7 @@ uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entit
else
setMessageList2(0x004B83C8);
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (sender == _asLeftDoor)
setMessageList2(0x004B8370);
else
@@ -1175,7 +798,7 @@ uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entit
else
_ssSmallRightDoor->setVisible(false);
break;
- case 0x4808:
+ case NM_KLAYMEN_OPEN_DOOR:
if (sender == _asLeftDoor) {
_ssSmallLeftDoor->setVisible(true);
_klaymen->setClipRect(_leftDoorClipRect);
@@ -1197,24 +820,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) {
@@ -1306,7 +911,7 @@ void Scene2205::update() {
uint32 Scene2205::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x6449569A)
setMessageList(0x004B0690);
else if (param.asInteger() == 0x2841369C)
@@ -1325,134 +930,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) {
@@ -1535,7 +1012,7 @@ Scene2206::~Scene2206() {
uint32 Scene2206::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
else if (param.asInteger() == 0x402064D8)
@@ -1554,19 +1031,19 @@ uint32 Scene2206::handleMessage(int messageNum, const MessageParam &param, Entit
if (sender == _ssButton) {
setGlobalVar(V_SPIKES_RETRACTED, getGlobalVar(V_SPIKES_RETRACTED) ? 0 : 1);
if (getGlobalVar(V_SPIKES_RETRACTED))
- sendMessage(_asDoorSpikes, 0x4808, 0);
+ sendMessage(_asDoorSpikes, NM_KLAYMEN_OPEN_DOOR, 0);
else
- sendMessage(_asDoorSpikes, 0x4809, 0);
+ sendMessage(_asDoorSpikes, NM_KLAYMEN_CLOSE_DOOR, 0);
}
break;
case 0x4826:
sendEntityMessage(_klaymen, 0x1014, _ssTestTube);
setMessageList(0x004B8988);
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
klaymenBehindSpikes();
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
klaymenInFrontSpikes();
break;
}
@@ -1597,6 +1074,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 +1102,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) {
@@ -2005,7 +1179,7 @@ void Scene2207::update() {
uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0014F275) {
if (_klaymenAtElevator) {
sendMessage(_asElevator, 0x2000, _mouseClickPos.y);
@@ -2041,15 +1215,15 @@ uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B37D8);
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_elevatorSurfacePriority = param.asInteger();
break;
case 0x2003:
_isKlaymenBusy = false;
break;
- case 0x4807:
- sendMessage(_asWallRobotAnimation, 0x2007, 0);
- sendMessage(_asWallCannonAnimation, 0x2007, 0);
+ case NM_KLAYMEN_RAISE_LEVER:
+ sendMessage(_asWallRobotAnimation, NM_CAR_MOVE_TO_PREV_POINT, 0);
+ sendMessage(_asWallCannonAnimation, NM_CAR_MOVE_TO_PREV_POINT, 0);
break;
case 0x480B:
if (sender == _ssButton) {
@@ -2062,9 +1236,9 @@ uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x480F:
- sendMessage(_asWallRobotAnimation, 0x2006, 0);
- sendMessage(_asWallCannonAnimation, 0x2006, 0);
+ case NM_KLAYMEN_LOWER_LEVER:
+ sendMessage(_asWallRobotAnimation, NM_KLAYMEN_STOP_CLIMBING, 0);
+ sendMessage(_asWallCannonAnimation, NM_KLAYMEN_STOP_CLIMBING, 0);
_asWallRobotAnimation->setVisible(true);
_asWallCannonAnimation->setVisible(true);
break;
@@ -2088,12 +1262,12 @@ uint32 Scene2207::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene2207::handleMessage2(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2002:
+ case NM_POSITION_CHANGE:
_elevatorSurfacePriority = param.asInteger();
break;
case 0x2004:
SetMessageHandler(&Scene2207::handleMessage);
- sendMessage(_klaymen, 0x2005, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_CLIMB_LADDER, 0);
sendEntityMessage(_klaymen, 0x1014, _asLever);
setMessageList(0x004B3920);
setRectList(0x004B3948);
@@ -2226,7 +1400,7 @@ void Scene2208::update() {
uint32 Scene2208::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 40 || param.asPoint().x >= 600)
leaveScene(0);
break;
@@ -2345,7 +1519,7 @@ void Scene2242::update() {
uint32 Scene2242::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
break;
@@ -2446,7 +1620,7 @@ HallOfRecordsScene::~HallOfRecordsScene() {
uint32 HallOfRecordsScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
break;
@@ -2534,7 +1708,7 @@ Scene2247::~Scene2247() {
uint32 Scene2247::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x800C6694)
readClickedColumn();
break;
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..ddf31f7920
--- /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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x11001090) {
+ if (_isOpen)
+ _ssDoorLight->setVisible(true);
+ } else if (param.asInteger() == 0x11283090) {
+ if (!_isOpen)
+ _ssDoorLight->setVisible(false);
+ }
+ break;
+ case NM_ANIMATION_UPDATE:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ _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, NM_POSITION_CHANGE, _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 NM_KLAYMEN_USE_OBJECT:
+ 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, NM_POSITION_CHANGE, 0);
+ else
+ sendMessage(_parentScene, 0x2001, 0);
+ messageResult = 1;
+ break;
+ case NM_ANIMATION_UPDATE:
+ _otherDoor = (Sprite*)param.asEntity();
+ break;
+ case NM_ANIMATION_STOP:
+ if (_doorIndex == getGlobalVar(V_LARGE_DOOR_NUMBER))
+ sendMessage(_parentScene, NM_KLAYMEN_OPEN_DOOR, 0);
+ stopAnimation();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ setGlobalVar(V_LARGE_DOOR_NUMBER, _doorIndex);
+ sendMessage(_otherDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
+ openDoor();
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ 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 NM_ANIMATION_UPDATE:
+ 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 NM_KLAYMEN_OPEN_DOOR:
+ _deltaIndex = 0;
+ playSound(0, 0x032746E0);
+ SetMessageHandler(NULL);
+ SetSpriteUpdate(&AsScene2206DoorSpikes::suOpen);
+ break;
+ case NM_KLAYMEN_CLOSE_DOOR:
+ _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 NM_KLAYMEN_USE_OBJECT:
+ 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, NM_POSITION_CHANGE, 900);
+ else if (_pointIndex < 20 && _surface->getPriority() != 1100)
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 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 NM_ANIMATION_UPDATE:
+ 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 NM_ANIMATION_STOP:
+ gotoNextState();
+ stopAnimation();
+ break;
+ case NM_KLAYMEN_RAISE_LEVER:
+ stLeverUp();
+ break;
+ case NM_KLAYMEN_LOWER_LEVER:
+ stLeverDown();
+ break;
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
+ break;
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2207Lever::stLeverDown() {
+ startAnimation(0x80880090, 1, -1);
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverDownEvent);
+}
+
+void AsScene2207Lever::stLeverDownEvent() {
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
+}
+
+void AsScene2207Lever::stLeverUp() {
+ startAnimation(0x80880090, 6, -1);
+ _playBackwards = true;
+ playSound(0, 0x40581882);
+ FinalizeState(&AsScene2207Lever::stLeverUpEvent);
+}
+
+void AsScene2207Lever::stLeverUpEvent() {
+ sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 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 NM_ANIMATION_START:
+ 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 NM_KLAYMEN_STOP_CLIMBING:
+ stStartAnimation();
+ break;
+ case NM_CAR_MOVE_TO_PREV_POINT:
+ stStopAnimation();
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_STOP_CLIMBING:
+ stStartAnimation();
+ break;
+ case NM_CAR_MOVE_TO_PREV_POINT:
+ stStopAnimation();
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 2)
+ GotoState(&Klaymen::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_INSERT_DISK:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x040D4186) {
+ sendMessage(_attachedSprite, NM_KLAYMEN_OPEN_DOOR, 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_PICKUP:
+ if (param.asInteger() == 1)
+ GotoState(&Klaymen::stPickUpTube);
+ else
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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, NM_SCENE_LEAVE, 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 NM_KLAYMEN_CLIMB_LADDER:
+ suRidePlatform();
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stInteractLever);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_RELEASE_LEVER:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stStartWalkingResume);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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..867fb692f2 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) {
@@ -439,11 +253,11 @@ void Scene2401::update() {
if (puzzleSolved) {
setGlobalVar(V_NOTES_DOOR_UNLOCKED, 1);
setGlobalVar(V_NOTES_PUZZLE_SOLVED, 1);
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
} else if (waterInside) {
playPipeSound(0xD0431020);
for (uint i = 0; i < 5; i++) {
- sendMessage(_asWaterFlushing[i], 0x2002, getSubVar(VA_CURR_WATER_PIPES_LEVEL, i));
+ sendMessage(_asWaterFlushing[i], NM_POSITION_CHANGE, getSubVar(VA_CURR_WATER_PIPES_LEVEL, i));
setSubVar(VA_CURR_WATER_PIPES_LEVEL, i, 0);
}
}
@@ -469,7 +283,7 @@ void Scene2401::update() {
uint32 Scene2401::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x02144CB1)
@@ -499,7 +313,7 @@ uint32 Scene2401::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (param.asInteger() == 0x09C4B40A && _countdown2 > 12)
_countdown2 = 12;
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
messageResult = 0;
for (uint32 i = 0; i < 5; i++)
if (kScene2401Rects[i].contains(_mouseClickPos.x, _mouseClickPos.y)) {
@@ -520,15 +334,15 @@ uint32 Scene2401::handleMessage(int messageNum, const MessageParam &param, Entit
_countdown1 = 8;
} else if (sender == _ssFloorButton && getGlobalVar(V_WATER_RUNNING)) {
_countdown2 = 144;
- sendMessage(_asFlowingWater, 0x2002, 0);
+ sendMessage(_asFlowingWater, NM_POSITION_CHANGE, 0);
playSound(0, 0xE1130324);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
_palette->addBasePalette(0xB103B604, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_palette->addBasePalette(0x91D3A391, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
@@ -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) {
@@ -734,7 +411,7 @@ Scene2402::~Scene2402() {
void Scene2402::update() {
if (_countdown != 0 && (--_countdown) == 0) {
if (_pipeStatus >= 10) {
- sendMessage(_asDoor, 0x4808, 0);
+ sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
_ssDoorFrame->loadSprite(0x00B415E0, kSLFDefDrawOffset | kSLFDefPosition);
} else if (_pipeStatus >= 5) {
_countdown = 8;
@@ -751,7 +428,7 @@ void Scene2402::update() {
uint32 Scene2402::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x402064D8)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x01C66840) {
@@ -839,13 +516,13 @@ Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2403::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x040424D0)
sendEntityMessage(_klaymen, 0x1014, _ssButton);
else if (param.asInteger() == 0x180CE614)
sendEntityMessage(_klaymen, 0x1014, _asLightCord);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isClimbingLadder = true;
setRectList(0x004B5E28);
break;
@@ -864,7 +541,7 @@ uint32 Scene2403::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
if (sender == _asLightCord)
leaveScene(2);
break;
@@ -960,7 +637,7 @@ Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2406::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x41062804) {
if (getGlobalVar(V_SPIKES_RETRACTED))
setMessageList(0x004B7758);
@@ -968,7 +645,7 @@ uint32 Scene2406::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B7738);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isClimbingLadder = true;
setRectList(0x004B78D8);
break;
diff --git a/engines/neverhood/modules/module2400.h b/engines/neverhood/modules/module2400.h
index 3802c747f1..61603f3e00 100644
--- a/engines/neverhood/modules/module2400.h
+++ b/engines/neverhood/modules/module2400.h
@@ -27,13 +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/modules/module2800_sprites.h"
#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -51,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);
@@ -112,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..32c00cde27
--- /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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x120A0013)
+ playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
+ break;
+ case NM_ANIMATION_UPDATE:
+ _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 NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ if (_isWaterFlowing && param.asInteger() == 0x02421405)
+ startAnimationByHash(0x10203116, 0x01084280, 0);
+ break;
+ case NM_POSITION_CHANGE:
+ 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 NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_START:
+ if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
+ startAnimationByHash(0xB8596884, 0x01084280, 0);
+ _flushLoopCount--;
+ }
+ break;
+ case NM_POSITION_CHANGE:
+ if (param.asInteger() > 0) {
+ _flushLoopCount = param.asInteger() - 1;
+ _countdown = _vm->_rnd->getRandomNumber(3) + 1;
+ }
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ 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 NM_ANIMATION_UPDATE:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case NM_ANIMATION_STOP:
+ gotoNextState();
+ break;
+ case NM_KLAYMEN_OPEN_DOOR:
+ _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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x431EA0B0)
+ playSound(0);
+ break;
+ case NM_ANIMATION_STOP:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_ANIMATION_START:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ GotoState(&Klaymen::stPickUpGeneric);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klaymen::stWalkingFirst);
+ } else
+ GotoState(&Klaymen::stPeekWall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_INSERT_DISK:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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..eb1b65cd83 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 {
@@ -248,7 +252,7 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004B2608);
SetMessageHandler(&Scene2501::handleMessage);
SetUpdateHandler(&Scene2501::update);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->setVisible(false);
_currTrackIndex = 0;
} else if (which == 1 || which == 2) {
@@ -273,7 +277,7 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
setRectList(0x004B2608);
SetMessageHandler(&Scene2501::handleMessage);
SetUpdateHandler(&Scene2501::update);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->setVisible(false);
_currTrackIndex = 0;
}
@@ -291,14 +295,14 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
if (which >= 0 && _tracks[_currTrackIndex]->which2 == which) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
_carStatus = 0;
@@ -325,7 +329,7 @@ void Scene2501::update() {
_asIdleCarLower->setVisible(false);
_asIdleCarFull->setVisible(false);
_asCar->setVisible(true);
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
_asCar->handleUpdate();
_klaymen = NULL;
_carStatus = 0;
@@ -337,7 +341,7 @@ void Scene2501::upCarAtHome() {
Scene::update();
if (_mouseClicked) {
if (_mouseClickPos.x <= 210 && _asCar->getX() == 211 && _asCar->getY() == 400) {
- sendMessage(_asCar, 0x200A, 0);
+ sendMessage(_asCar, NM_CAR_LEAVE, 0);
SetUpdateHandler(&Scene2501::upGettingOutOfCar);
} else {
moveCarToPoint(_mouseClickPos);
@@ -381,7 +385,7 @@ void Scene2501::upRidingCar() {
uint32 Scene2501::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x60842040)
_carStatus = 1;
break;
@@ -395,23 +399,23 @@ uint32 Scene2501::handleMessage(int messageNum, const MessageParam &param, Entit
uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_tracks[_currTrackIndex]->which1 < 0 && _newTrackIndex >= 0)
changeTrack();
else if (_tracks[_currTrackIndex]->which1 == 0) {
SetMessageHandler(&Scene2501::hmCarAtHome);
SetUpdateHandler(&Scene2501::upCarAtHome);
- sendMessage(_asCar, 0x200F, 1);
+ sendMessage(_asCar, NM_CAR_AT_HOME, 1);
} else if (_tracks[_currTrackIndex]->which1 > 0)
leaveScene(_tracks[_currTrackIndex]->which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_tracks[_currTrackIndex]->which2 < 0 && _newTrackIndex >= 0)
changeTrack();
else if (_tracks[_currTrackIndex]->which2 == 0) {
SetMessageHandler(&Scene2501::hmCarAtHome);
SetUpdateHandler(&Scene2501::upCarAtHome);
- sendMessage(_asCar, 0x200F, 1);
+ sendMessage(_asCar, NM_CAR_AT_HOME, 1);
} else if (_tracks[_currTrackIndex]->which2 > 0)
leaveScene(_tracks[_currTrackIndex]->which2);
break;
@@ -425,7 +429,7 @@ uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam &param, Entity
uint32 Scene2501::hmCarAtHome(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x200A:
+ case NM_CAR_LEAVE:
_carStatus = 2;
break;
case 0x200D:
@@ -456,9 +460,9 @@ void Scene2501::changeTrack() {
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
_asCar->setPathPoints(_trackPoints);
if (_currTrackIndex == 0)
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
else
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
sendPointMessage(_asCar, 0x2004, _clickPoint);
_newTrackIndex = -1;
}
@@ -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) {
@@ -535,7 +491,7 @@ Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2504::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
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..1394a87db6
--- /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 NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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..3c3e733b3f 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) {
@@ -326,20 +239,20 @@ Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2609::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isBusy)
leaveScene(0);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isBusy = true;
break;
case 0x2001:
_isBusy = false;
sendMessage(_asWater, 0x2001, 0);
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_isBusy = false;
- sendMessage(_asWater, 0x2002, 0);
+ sendMessage(_asWater, NM_POSITION_CHANGE, 0);
break;
}
return 0;
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..2506a6eb48
--- /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, NM_POSITION_CHANGE, 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, NM_POSITION_CHANGE, 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 NM_POSITION_CHANGE:
+ 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..13c30048a4 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) {
@@ -652,14 +576,14 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
_asCar->setClipRect(clipRect);
@@ -668,7 +592,7 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
if (which == 1) {
SetMessageHandler(&Scene2701::hmRidingCar);
} else {
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
SetMessageHandler(&Scene2701::hmCarAtHome);
}
@@ -677,14 +601,14 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2701::hmRidingCar(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
sendPointMessage(_asCar, 0x2004, param.asPoint());
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_which1 >= 0)
SetMessageHandler(&Scene2701::hmCarAtHome);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_which2 >= 0)
leaveScene(_which2);
break;
@@ -698,7 +622,7 @@ uint32 Scene2701::hmRidingCar(int messageNum, const MessageParam &param, Entity
uint32 Scene2701::hmCarAtHome(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x >= 385)
leaveScene(0);
else {
@@ -778,11 +702,11 @@ Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which)
_asCar->setPathPoints(_trackPoints);
if (which == _tracks[_currTrackIndex]->which2) {
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
- sendMessage(_asCar, 0x2002, 0);
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
_palette->copyBasePalette(0, 256, 0);
@@ -807,17 +731,17 @@ void Scene2702::update() {
uint32 Scene2702::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
moveCarToPoint(param.asPoint());
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which1 < 0)
changeTrack();
} else if (_tracks[_currTrackIndex]->which1 >= 0)
leaveScene(_tracks[_currTrackIndex]->which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which2 < 0)
changeTrack();
@@ -858,13 +782,13 @@ void Scene2702::changeTrack() {
_asCar->setPathPoints(_trackPoints);
if (_isUpperTrack) {
if (_currTrackIndex == 0)
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
else
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
} else if (_currTrackIndex == 2)
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
else
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
sendMessage(_asCar, 0x2004, _newTrackDestX);
_newTrackIndex = -1;
}
@@ -908,18 +832,18 @@ Scene2703::Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint3
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
if (which == 0) {
@@ -967,11 +891,11 @@ void Scene2703::update() {
uint32 Scene2703::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_which1 >= 0)
leaveScene(_which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_which2 >= 0)
leaveScene(_which2);
break;
@@ -1027,18 +951,18 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3
if (which == _which2) {
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2007, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
NPoint testPoint = (*_trackPoints)[0];
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (testPoint.x > 0 && testPoint.x < 640 && testPoint.y > 0 && testPoint.y < 480)
- sendMessage(_asCar, 0x2009, 0);
+ sendMessage(_asCar, NM_CAR_ENTER, 0);
else
- sendMessage(_asCar, 0x2008, 0);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
if (clipRect) {
@@ -1066,11 +990,11 @@ void Scene2704::update() {
uint32 Scene2704::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_which1 >= 0)
leaveScene(_which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_which2 >= 0)
leaveScene(_which2);
break;
@@ -1120,17 +1044,17 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which)
_asCar->setPathPoints(_trackPoints);
if (which == _tracks[_currTrackIndex]->which2) {
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
if (which == 5)
- sendMessage(_asCar, 0x2007, 50);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 50);
else
- sendMessage(_asCar, 0x2007, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
} else {
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
if (which == 5)
- sendMessage(_asCar, 0x2008, 50);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 50);
else
- sendMessage(_asCar, 0x2008, 150);
+ sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
}
}
@@ -1138,17 +1062,17 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2706::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
moveCarToPoint(param.asPoint());
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which1 < 0)
changeTrack();
} else if (_tracks[_currTrackIndex]->which1 >= 0)
leaveScene(_tracks[_currTrackIndex]->which1);
break;
- case 0x2006:
+ case NM_KLAYMEN_STOP_CLIMBING:
if (_newTrackIndex >= 0) {
if (_tracks[_currTrackIndex]->which2 < 0)
changeTrack();
@@ -1183,9 +1107,9 @@ void Scene2706::changeTrack() {
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
_asCar->setPathPoints(_trackPoints);
if (_currTrackIndex == 0)
- sendMessage(_asCar, 0x2002, _trackPoints->size() - 1);
+ sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
else
- sendMessage(_asCar, 0x2002, 0);
+ sendMessage(_asCar, NM_POSITION_CHANGE, 0);
sendMessage(_asCar, 0x2004, _newTrackDestX);
_newTrackIndex = -1;
}
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 3a33598090..5d892de224 100644
--- a/engines/neverhood/modules/module2800.cpp
+++ b/engines/neverhood/modules/module2800.cpp
@@ -20,14 +20,15 @@
*
*/
-#include "neverhood/modules/module2800.h"
+#include "neverhood/diskplayerscene.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/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"
-#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -58,155 +59,126 @@ Module2800::~Module2800() {
_vm->_soundMan->deleteGroup(0x64210814);
}
+#define statueCloseup(backgroundFileHash, cursorFileHash) \
+ _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2); \
+ createStaticScene(backgroundFileHash, cursorFileHash)
+
void Module2800::createScene(int sceneNum, int which) {
debug(1, "Module2800::createScene(%d, %d)", sceneNum, which);
_sceneNum = sceneNum;
+
+ if (_sceneNum != 1001)
+ _vm->gameState().sceneNum = _sceneNum;
+
switch (_sceneNum) {
- case 0:
- _vm->gameState().sceneNum = 0;
+ case 0: // in front of radio
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
_childObject = new Scene2801(_vm, this, which);
break;
- case 1:
- _vm->gameState().sceneNum = 1;
+ case 1: // radio
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
if (getGlobalVar(V_RADIO_ENABLED))
_childObject = new Scene2802(_vm, this, which);
else
createStaticScene(0x000C6444, 0xC6440008);
break;
- case 2:
- _vm->gameState().sceneNum = 2;
+ case 2: // outside shrink machine
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
if (getGlobalVar(V_KLAYMEN_SMALL))
_childObject = new Scene2803Small(_vm, this, which);
else
_childObject = new Scene2803(_vm, this, which);
break;
- case 3:
- _vm->gameState().sceneNum = 3;
+ case 3: // glass cylinder with diamonds
_childObject = new Scene2804(_vm, this, which);
break;
- case 4:
- _vm->gameState().sceneNum = 4;
+ case 4: // outside the transporter
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2805(_vm, this, which);
break;
- case 5:
- _vm->gameState().sceneNum = 5;
+ case 5: // left test tube room
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2806(_vm, this, which);
break;
- case 6:
- _vm->gameState().sceneNum = 6;
+ case 6: // the three test tubes next to the window
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2807(_vm, this, which);
break;
- case 7:
- _vm->gameState().sceneNum = 7;
+ case 7: // left test tube room closeup
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2808(_vm, this, 0);
break;
- case 8:
- _vm->gameState().sceneNum = 8;
+ case 8: // right test tube room
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2809(_vm, this, which);
break;
- case 9:
- _vm->gameState().sceneNum = 9;
+ case 9: // statue room
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2810(_vm, this, which);
break;
- case 10:
- _vm->gameState().sceneNum = 10;
+ case 10: // right test tube room closeup
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2808(_vm, this, 1);
break;
- case 11:
- _vm->gameState().sceneNum = 11;
+ case 11: // disk player room (above the statue room)
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2812(_vm, this, which);
break;
case 12:
- _vm->gameState().sceneNum = 12;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x0000A245, 0x0A241008);
+ statueCloseup(0x0000A245, 0x0A241008);
break;
case 13:
- _vm->gameState().sceneNum = 13;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x81C60635, 0x60631814);
+ statueCloseup(0x81C60635, 0x60631814);
break;
case 14:
- _vm->gameState().sceneNum = 14;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0xCA811204, 0x11200CA0);
+ statueCloseup(0xCA811204, 0x11200CA0);
break;
case 15:
- _vm->gameState().sceneNum = 15;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x2D438A00, 0x38A042DC);
+ statueCloseup(0x2D438A00, 0x38A042DC);
break;
case 16:
- _vm->gameState().sceneNum = 16;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x0A806204, 0x062000A0);
+ statueCloseup(0x0A806204, 0x062000A0);
break;
case 17:
- _vm->gameState().sceneNum = 17;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x010F9284, 0xF9280018);
+ statueCloseup(0x010F9284, 0xF9280018);
break;
case 18:
- _vm->gameState().sceneNum = 18;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x0100022B, 0x0022F018);
+ statueCloseup(0x0100022B, 0x0022F018);
break;
case 19:
- _vm->gameState().sceneNum = 19;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x10866205, 0x66201100);
+ statueCloseup(0x10866205, 0x66201100);
break;
case 20:
- _vm->gameState().sceneNum = 20;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x01C58000, 0x58004014);
+ statueCloseup(0x01C58000, 0x58004014);
break;
- case 21:
- _vm->gameState().sceneNum = 21;
+ case 21: // statue with ladder down button
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
_childObject = new Scene2822(_vm, this, which);
break;
case 22:
- _vm->gameState().sceneNum = 22;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x9408121E, 0x8121A948);
+ statueCloseup(0x9408121E, 0x8121A948);
break;
case 23:
- _vm->gameState().sceneNum = 23;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x048C0600, 0xC0604040);
+ statueCloseup(0x048C0600, 0xC0604040);
break;
case 24:
- _vm->gameState().sceneNum = 24;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
- createStaticScene(0x04270A94, 0x70A9004A);
+ statueCloseup(0x04270A94, 0x70A9004A);
break;
- case 25:
- _vm->gameState().sceneNum = 25;
+ case 25: // window
_vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
if (getGlobalVar(V_SHRINK_LIGHTS_ON))
createStaticScene(0x01600204, 0x0020001E);
else
createStaticScene(0x08611204, 0x1120008E);
break;
- case 26:
- _vm->gameState().sceneNum = 26;
- _vm->_soundMan->startMusic(0xD2FA4D14, 0, 2);
+ case 26: // disk player
+ _vm->_soundMan->stopMusic(0xD2FA4D14, 0, 2);
_childObject = new DiskplayerScene(_vm, this, 4);
break;
- case 1001:
+ case 1001: // tower rotation video
_vm->_soundMan->stopMusic(0xD2FA4D14, 0, 0);
+ _musicResource->stop(0);
+ _currentMusicFileHash = 0;
createSmackerScene(0x00800801, true, true, false);
break;
}
@@ -214,6 +186,8 @@ void Module2800::createScene(int sceneNum, int which) {
_childObject->handleUpdate();
}
+#undef statueCloseup
+
void Module2800::updateScene() {
if (!updateChild()) {
switch (_sceneNum) {
@@ -353,7 +327,6 @@ void Module2800::updateScene() {
}
void Module2800::updateMusic(bool halfVolume) {
-
uint32 newMusicFileHash = _vm->_gameModule->getCurrRadioMusicFileHash();
if (!_musicResource)
@@ -476,11 +449,11 @@ uint32 Scene2801::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004B6C40);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
_palette->addBasePalette(0xB103B604, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_palette->addBasePalette(_paletteHash, 0, 65, 0);
_palette->startFadeToPalette(12);
break;
@@ -584,7 +557,7 @@ uint32 Scene2802::handleMessage(int messageNum, const MessageParam &param, Entit
int prevTuneStatus = _currTuneStatus;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
} else if (_currTuneStatus == 0) {
@@ -601,7 +574,7 @@ uint32 Scene2802::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x0002:
+ case NM_MOUSE_RELEASE:
if (_countdown1 == 0)
_currTuneStatus = 0;
else {
@@ -777,10 +750,10 @@ void Scene2803::upKlaymenStairs() {
uint32 Scene2803::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
toggleBackground();
// NOTE Intentional fall-through
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x84251F82)
setMessageList(0x004B7A50);
else if (param.asInteger() == 0x4254A2D2)
@@ -795,11 +768,11 @@ uint32 Scene2803::handleMessage(int messageNum, const MessageParam &param, Entit
} else if (param.asInteger() == 0x9626F390)
setMessageList(0x004B7A88);
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
klaymenStairs();
setPaletteArea1();
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
klaymenFloor();
setPaletteArea0();
break;
@@ -1013,7 +986,7 @@ Scene2803Small::Scene2803Small(NeverhoodEngine *vm, Module *parentModule, int wh
uint32 Scene2803Small::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xB4E4884C) {
setMessageList(0x004B6180);
} else if (param.asInteger() == 0xB1FDAB2E) {
@@ -1041,7 +1014,7 @@ uint32 Scene2803Small::handleMessage(int messageNum, const MessageParam &param,
setMessageList(0x004B61A8);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
if (_klaymen->getX() < 200) {
setPaletteArea3();
} else if (_klaymen->getX() < 500) {
@@ -1053,7 +1026,7 @@ uint32 Scene2803Small::handleMessage(int messageNum, const MessageParam &param,
setPaletteArea2();
}
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
_sprite6->setVisible(false);
_sprite7->setVisible(false);
_klaymen->setClipRect(0, 0, 640, 480);
@@ -1204,14 +1177,14 @@ Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2804::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_isWorking = true;
- sendMessage(_asCoil, 0x2002, 0);
+ sendMessage(_asCoil, NM_POSITION_CHANGE, 0);
if (getGlobalVar(V_SHRINK_LIGHTS_ON)) {
sendMessage(_asTarget, 0x2004, 0);
_countdown2 = 48;
@@ -1241,7 +1214,7 @@ void Scene2804::update() {
if (_countdown2 != 0 && (--_countdown2) == 0) {
_isWorking = false;
sendMessage(_asCoil, 0x2003, 0);
- sendMessage(_asTarget, 0x2005, 0);
+ sendMessage(_asTarget, NM_KLAYMEN_CLIMB_LADDER, 0);
for (uint index = 0; index < 5; index++)
_asCrystals[index]->hide();
}
@@ -1315,7 +1288,7 @@ Scene2805::Scene2805(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2805::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger()) {
setRectList(0x004AE318);
_klaymen->setKlaymenIdleTable3();
@@ -1405,12 +1378,12 @@ Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2806::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x44262B12) {
setMessageList(0x004AF0E0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
sendMessage(_asSpew, 0x2000, 0);
break;
}
@@ -1485,7 +1458,7 @@ Scene2807::Scene2807(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2807::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
}
@@ -1555,19 +1528,19 @@ Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)
uint32 Scene2808::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !isAnyTestTubeFilled()) {
leaveScene(1);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!_isFlowing)
_asTestTubes[param.asInteger()]->fill();
break;
case 0x2001:
_isFlowing = true;
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (isAnyTestTubeFilled()) {
_leaveResult = 3;
if (!isMixtureGood())
@@ -1695,12 +1668,12 @@ void Scene2809::update() {
uint32 Scene2809::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x160DA937) {
setMessageList(0x004B5B98);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
sendMessage(_asSpew, 0x2000, 0);
break;
}
@@ -1902,7 +1875,7 @@ void Scene2810::insertKlaymenLadder() {
uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0xE574F14C)
setMessageList(0x004AE458);
else if (param.asInteger() == 0x7214A05C || param.asInteger() == 0x2905E574)
@@ -1932,7 +1905,7 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entit
else if (param.asInteger() == 0x2064294C || param.asInteger() == 0x2194E053)
setMessageList(0x004AE688);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
setRectList(0x004AE800);
_isRopingDown = true;
break;
@@ -2035,7 +2008,7 @@ void Scene2812::update() {
uint32 Scene2812::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (param.asInteger() == 0x0004269B)
sendEntityMessage(_klaymen, 0x1014, _asRope);
break;
@@ -2044,12 +2017,12 @@ uint32 Scene2812::handleMessage(int messageNum, const MessageParam &param, Entit
setRectList(0x004AF710);
_klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite4->getDrawRect().y2());
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
_isRopingDown = false;
setRectList(0x004AF700);
_klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
break;
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
sendMessage(_asWinch, 0x2000, 0);
sendMessage(_asTrapDoor, 0x2000, 0);
break;
@@ -2062,12 +2035,12 @@ uint32 Scene2812::handleMessage(int messageNum, const MessageParam &param, Entit
setMessageList(0x004AF668);
}
break;
- case 0x482A:
+ case NM_MOVE_TO_BACK:
setPaletteArea1(false);
_sprite1->setVisible(true);
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, _sprite1->getDrawRect().x2(), _sprite3->getDrawRect().y2());
break;
- case 0x482B:
+ case NM_MOVE_TO_FRONT:
setPaletteArea0(false);
_sprite1->setVisible(false);
_klaymen->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
@@ -2158,7 +2131,7 @@ void Scene2822::update() {
uint32 Scene2822::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
} else if (param.asPoint().x >= 257 && param.asPoint().y >= 235 &&
diff --git a/engines/neverhood/modules/module2800_sprites.cpp b/engines/neverhood/modules/module2800_sprites.cpp
index 28e2657ee7..35596da6b5 100644
--- a/engines/neverhood/modules/module2800_sprites.cpp
+++ b/engines/neverhood/modules/module2800_sprites.cpp
@@ -22,12 +22,6 @@
#include "neverhood/modules/module2800.h"
#include "neverhood/modules/module2800_sprites.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"
namespace Neverhood {
@@ -46,20 +40,20 @@ AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentSce
uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x100D:
+ case NM_ANIMATION_START:
if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) {
- sendMessage(_parentScene, 0x480F, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_LOWER_LEVER, 0);
playSound(0, 0x4E1CA4A0);
}
break;
- case 0x480F:
+ case NM_KLAYMEN_LOWER_LEVER:
stPulled();
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -68,7 +62,7 @@ uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam &p
uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -113,7 +107,7 @@ AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileH
uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (param.asInteger())
startAnimation(_fileHash2, 0, -1);
else
@@ -139,15 +133,15 @@ AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16
uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
startAnimation(0x9D098C23, 50, -1);
SetMessageHandler(&AsScene2803Rope::hmReleased);
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -156,14 +150,14 @@ uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam &param,
uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -223,7 +217,7 @@ SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm)
uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2002:
+ case NM_POSITION_CHANGE:
setVisible(true);
updatePosition();
messageResult = 1;
@@ -253,7 +247,7 @@ uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam
updatePosition();
messageResult = 1;
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
setVisible(false);
updatePosition();
messageResult = 1;
@@ -476,7 +470,7 @@ void AsScene2804BeamCoil::update() {
uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2002:
+ case NM_POSITION_CHANGE:
show();
_countdown = 92;
messageResult = 1;
@@ -515,7 +509,7 @@ void AsScene2804BeamCoil::stBeaming() {
uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -543,7 +537,7 @@ uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam &
startAnimation(0x03842000, 0, -1);
messageResult = 1;
break;
- case 0x2005:
+ case NM_KLAYMEN_CLIMB_LADDER:
setVisible(false);
stopAnimation();
messageResult = 1;
@@ -567,12 +561,12 @@ AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm)
uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
playSound(0, 0x48640244);
startAnimation(0x04211490, 0, -1);
setVisible(true);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
stopAnimation();
setVisible(false);
break;
@@ -780,7 +774,7 @@ uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam &para
uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -797,7 +791,7 @@ void AsScene2808Handle::activate() {
void AsScene2808Handle::stActivated() {
stopAnimation();
- sendMessage(_parentScene, 0x2002, 0);
+ sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
}
AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum)
@@ -823,7 +817,7 @@ AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int te
uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -881,12 +875,12 @@ AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm)
uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
playSound(0, 0x48640244);
startAnimation(0x04211490, 0, -1);
setVisible(true);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
stopAnimation();
setVisible(false);
break;
@@ -895,7 +889,7 @@ uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam &param,
}
AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x)
- : AnimatedSprite(vm, 1100) {
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
createSurface(990, 68, 476);
SetUpdateHandler(&AnimatedSprite::update);
@@ -909,14 +903,14 @@ AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16
uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
startAnimation(0x9D098C23, 35, 53);
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -940,13 +934,13 @@ AsScene2812Winch::~AsScene2812Winch() {
uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
startAnimation(0x20DA08A0, 0, -1);
setVisible(true);
_vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C);
_vm->_soundMan->playSoundLooping(0xC874EE6C);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
startAnimation(0x20DA08A0, 7, -1);
break;
}
@@ -968,15 +962,15 @@ AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x4806:
+ case NM_KLAYMEN_USE_OBJECT:
setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
stRopingDown();
break;
- case 0x482A:
- sendMessage(_parentScene, 0x1022, 990);
+ case NM_MOVE_TO_BACK:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
break;
- case 0x482B:
- sendMessage(_parentScene, 0x1022, 1010);
+ case NM_MOVE_TO_FRONT:
+ sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
break;
}
return messageResult;
@@ -985,7 +979,7 @@ uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param,
uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x3002:
+ case NM_ANIMATION_STOP:
gotoNextState();
break;
}
@@ -993,7 +987,7 @@ uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam &param,
}
void AsScene2812Rope::stRopingDown() {
- sendMessage(_parentScene, 0x4806, 0);
+ sendMessage(_parentScene, NM_KLAYMEN_USE_OBJECT, 0);
startAnimation(0x9D098C23, 0, -1);
SetMessageHandler(&AsScene2812Rope::hmRopingDown);
}
@@ -1008,7 +1002,7 @@ AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
startAnimation(0x805D0029, 0, -1);
playSound(0, 0xEA005F40);
_newStickFrameIndex = STICK_LAST_FRAME;
@@ -1017,4 +1011,616 @@ uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &pa
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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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 NM_ANIMATION_START:
+ if (param.asInteger() == 0x80C110B5)
+ sendMessage(_parentScene, NM_MOVE_TO_BACK, 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 NM_ANIMATION_UPDATE:
+ _isSittingInTeleporter = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case NM_KLAYMEN_STAND_IDLE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stSitIdleTeleporter);
+ else
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case NM_KLAYMEN_TURN_TO_USE:
+ if (_isSittingInTeleporter)
+ GotoState(&Klaymen::stTurnToUseInTeleporter);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(440, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4804:
+ startWalkToX(226, true);
+ break;
+ case 0x480D:
+ GotoState(&Klaymen::stPullCord);
+ break;
+ case NM_KLAYMEN_PRESS_BUTTON:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4803:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrab);
+ break;
+ case 0x4804:
+ if (param.asInteger() == 3)
+ GotoState(&Klaymen::stFinishGrow);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_STAND_IDLE:
+ GotoState(&Klaymen::stTryStandIdle);
+ break;
+ case 0x4805:
+ _destY = param.asInteger();
+ GotoState(&Klaymen::stJumpToGrabFall);
+ break;
+ case NM_KLAYMEN_PICKUP:
+ 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 NM_KLAYMEN_INSERT_DISK:
+ 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 NM_KLAYMEN_TURN_TO_USE:
+ GotoState(&Klaymen::stTurnToUse);
+ break;
+ case NM_KLAYMEN_RETURN_FROM_USE:
+ 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, NM_POSITION_CHANGE, 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
index 39ca88ef73..91f26d7849 100644
--- a/engines/neverhood/modules/module2800_sprites.h
+++ b/engines/neverhood/modules/module2800_sprites.h
@@ -263,6 +263,75 @@ 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..ca734972ca 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) {
@@ -416,11 +211,11 @@ void Scene2901::update() {
uint32 Scene2901::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene((uint32)-1);
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (_currLocationButtonNum != _selectedButtonNum)
leaveScene(_selectedButtonNum);
break;
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..dc6fb984ef 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) {
@@ -888,13 +552,13 @@ void Scene3009::update() {
uint32 Scene3009::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !getGlobalVar(V_CANNON_RAISED)) {
setGlobalVar(V_CANNON_TARGET_STATUS, 0);
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!getGlobalVar(V_CANNON_RAISED)) {
if (!getGlobalVar(V_WALL_BROKEN)) {
_cannonTargetStatus = kCTSBreakWall;
@@ -917,7 +581,7 @@ uint32 Scene3009::handleMessage(int messageNum, const MessageParam &param, Entit
case 0x2001:
_lockSymbolsPart1Countdown = 24;
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
// Raise/lower the cannon
if (!getGlobalVar(V_CANNON_TURNED) && !_isTurning) {
if (getGlobalVar(V_CANNON_RAISED)) {
@@ -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) {
@@ -1267,7 +731,7 @@ void Scene3010::update() {
uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && _countdown == 0 && !_checkUnlocked) {
if (!_boltUnlocking[0] && !_boltUnlocking[1] && !_boltUnlocking[2]) {
showMouse(false);
@@ -1285,7 +749,7 @@ uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entit
}
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
if (!_boltUnlocked[param.asInteger()] && !_checkUnlocked && _countdown == 0) {
_asDeadBolts[param.asInteger()]->unlock(false);
_boltUnlocking[param.asInteger()] = true;
@@ -1305,7 +769,7 @@ uint32 Scene3010::handleMessage(int messageNum, const MessageParam &param, Entit
_doorUnlocked = true;
}
break;
- case 0x2002:
+ case NM_POSITION_CHANGE:
if (!_checkUnlocked && _countdown == 0) {
_asDeadBolts[param.asInteger()]->lock();
}
@@ -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) {
@@ -1510,12 +853,12 @@ void Scene3011::update() {
uint32 Scene3011::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
leaveScene(0);
}
break;
- case 0x2000:
+ case NM_ANIMATION_UPDATE:
_buttonClicked = true;
if (_countdown == 0)
_countdown = 1;
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..3c0c5fe209
--- /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, NM_KLAYMEN_CLIMB_LADDER, _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, NM_POSITION_CHANGE, 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 NM_KLAYMEN_CLIMB_LADDER:
+ 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, NM_POSITION_CHANGE, _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 NM_ANIMATION_STOP:
+ 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 a15c00de07..adbb6aef7a 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -106,19 +106,19 @@ void NavigationScene::update() {
uint32 NavigationScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
- case 0x0000:
+ case NM_MOUSE_MOVE:
if (_interactive)
sendMessage(_mouseCursor, 0x4002, param);
break;
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (_interactive)
handleNavigation(param.asPoint());
break;
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
if (!_interactive)
_smackerDone = true;
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_smackerDone = true;
break;
}
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 1fb32a1834..1119bfbb08 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -45,7 +45,7 @@
namespace Neverhood {
-NeverhoodEngine::NeverhoodEngine(OSystem *syst, const NeverhoodGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+NeverhoodEngine::NeverhoodEngine(OSystem *syst, const NeverhoodGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _console(nullptr) {
// Setup mixer
if (!_mixer->isReady()) {
warning("Sound initialization failed.");
@@ -79,6 +79,7 @@ Common::Error NeverhoodEngine::run() {
// Assign default values to the config manager, in case settings are missing
ConfMan.registerDefault("originalsaveload", "false");
+ ConfMan.registerDefault("skiphallofrecordsscenes", "false");
_staticData = new StaticData();
_staticData->load("neverhood.dat");
@@ -177,6 +178,12 @@ void NeverhoodEngine::mainLoop() {
case Common::EVENT_RBUTTONUP:
_gameModule->handleMouseUp(event.mouse.x, event.mouse.y);
break;
+ case Common::EVENT_WHEELUP:
+ _gameModule->handleWheelUp();
+ break;
+ case Common::EVENT_WHEELDOWN:
+ _gameModule->handleWheelDown();
+ break;
case Common::EVENT_QUIT:
_system->quit();
break;
@@ -190,13 +197,12 @@ void NeverhoodEngine::mainLoop() {
_gameModule->draw();
_console->onFrame();
_screen->update();
+ if (_updateSound)
+ _soundMan->update();
nextFrameTime = _screen->getNextFrameTime();
};
- if (_updateSound) {
- _soundMan->update();
- _audioResourceMan->updateMusic();
- }
+ _audioResourceMan->updateMusic();
_system->updateScreen();
_system->delayMillis(10);
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 0561aa251e..4d923d1f0e 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -32,6 +32,8 @@
#include "common/system.h"
#include "audio/mixer.h"
#include "engines/engine.h"
+#include "gui/debugger.h"
+#include "neverhood/console.h"
#include "neverhood/messages.h"
namespace Neverhood {
@@ -48,7 +50,6 @@ class Screen;
class SoundMan;
class AudioResourceMan;
class StaticData;
-class Console;
struct NPoint;
struct GameState {
@@ -90,6 +91,7 @@ public:
GameModule *_gameModule;
StaticData *_staticData;
Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
SoundMan *_soundMan;
AudioResourceMan *_audioResourceMan;
diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp
index c381f46671..134fec7163 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() {
@@ -114,7 +119,7 @@ void Palette::startFadeToBlack(int counter) {
_fadeToG = 0;
_fadeToB = 0;
_palCounter = counter;
- _fadeStep = 255 / counter;
+ _fadeStep = calculateFadeStep(counter);
_status = 1;
}
@@ -126,7 +131,7 @@ void Palette::startFadeToWhite(int counter) {
_fadeToG = 255;
_fadeToB = 255;
_palCounter = counter;
- _fadeStep = 255 / counter;
+ _fadeStep = calculateFadeStep(counter);
_status = 1;
}
@@ -135,7 +140,7 @@ void Palette::startFadeToPalette(int counter) {
if (counter == 0)
counter = 1;
_palCounter = counter;
- _fadeStep = 255 / counter;
+ _fadeStep = calculateFadeStep(counter);
_status = 2;
}
@@ -198,4 +203,11 @@ void Palette::fadeColor(byte *rgb, byte toR, byte toG, byte toB) {
#undef FADE
}
+int Palette::calculateFadeStep(int counter) {
+ int fadeStep = 255 / counter;
+ if (255 % counter)
+ fadeStep++;
+ return fadeStep;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/palette.h b/engines/neverhood/palette.h
index c83207caae..016f856104 100644
--- a/engines/neverhood/palette.h
+++ b/engines/neverhood/palette.h
@@ -61,6 +61,7 @@ protected:
int _fadeStep;
void update();
void fadeColor(byte *rgb, byte toR, byte toG, byte toB);
+ int calculateFadeStep(int counter);
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp
index 518755a846..f6937384c0 100644
--- a/engines/neverhood/resourceman.cpp
+++ b/engines/neverhood/resourceman.cpp
@@ -94,11 +94,30 @@ struct EntrySizeFix {
};
static const EntrySizeFix entrySizeFixes[] = {
- // fileHash offset diskSize size fixedSize
+ // fileHash offset diskSize size fixedSize
// Fixes for the Russian "Dyadyushka Risech" version
- // TODO
+ { 0x041137051, 667019, 23391, 41398, 41401 }, // "Options" menu header text
+ { 0x00f960021, 402268, 1704, 4378, 1870 }, // "Save" menu
+ { 0x01301a7ea, 1220008, 2373, 4146, 2877 }, // "Load" menu
+ { 0x084181e81, 201409, 1622, 5058, 1833 }, // "Delete" menu
+ { 0x008C0AC24, 1031009, 3030, 6498, 3646 }, // Overwrite dialog
+ { 0x0c6604282, 12813649, 19623, 35894, 35895 }, // One of the fonts when reading Willie's notes
+ { 0x080283101, 13104841, 1961, 3712, 3511 }, // First message from Willie
+ { 0x000918480, 17676417, 581, 916, 706 }, // First wall in the museum
+ { 0x00800090C, 16064875, 19555, 38518, 38526 }, // First wall in the museum
+ { 0x058208810, 46010519, 24852, 131874, 131776 }, // Entry to hut with musical lock
+ { 0x00008E486, 39600019, 240, 454, 271 }, // Second wall in the museum
+ { 0x003086004, 39621755, 482, 614, 600 }, // Second wall in the museum
+ { 0x02008048E, 39611075, 3798, 21089, 21087 }, // Next couple of walls in the museum
+ { 0x008586283, 39587864, 12155, 29731, 29730 }, // Next couple of walls in the museum
+ { 0x030A84C80, 39606142, 4933, 16305, 16275 }, // Next couple of walls in the museum
+ { 0x000C9A480, 39614873, 6882, 23915, 23913 }, // Next couple of walls in the museum
+ { 0x000098880, 39603114, 3028, 10860, 10859 }, // Next couple of walls in the museum
+ { 0x040080183, 39600259, 2855, 13400, 13395 }, // Last buggy wall in the museum
+
// Fixes for the Russian "Fargus" version
- // TODO
+ { 0x041137051, 758264, 29037, 49590, 49591 }, // "Options" menu header text
+ { 0x0c10b2015, 787304, 4414, 15848, 15853 }, // Text on option buttons
//
{ 0, 0, 0, 0, 0 }
};
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index 0b2e9c6b75..b8cde73e81 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -50,6 +50,9 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule)
_smackerPlayer = NULL;
_isMessageListBusy = false;
_messageValue = -1;
+ _messageListStatus = 0;
+ _messageListCount = 0;
+ _messageListIndex = 0;
_backgroundFileHash = _cursorFileHash = 0;
@@ -280,11 +283,11 @@ void Scene::leaveScene(uint32 result) {
uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
switch (messageNum) {
- case 0x0000: // mouse moved
+ case NM_MOUSE_MOVE:
if (_mouseCursor && _mouseCursor->hasMessageHandler())
sendMessage(_mouseCursor, 0x4002, param);
break;
- case 0x0001: // mouse clicked
+ case NM_MOUSE_CLICK:
_mouseClicked = true;
_mouseClickPos = param.asPoint();
break;
@@ -298,7 +301,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
if (_messageListIndex == _messageListCount) {
// If the current message list was processed completely,
// sent Klaymen into the idle state.
- sendMessage(_klaymen, 0x4004, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_STAND_IDLE, 0);
} else {
// Else continue with the next message in the current message list
processMessageList();
@@ -311,23 +314,21 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
if (_isKlaymenBusy) {
_isKlaymenBusy = false;
_messageList = NULL;
- sendMessage(_klaymen, 0x4004, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_STAND_IDLE, 0);
}
break;
- case 0x101D:
- // Hide the mouse cursor
+ case NM_MOUSE_HIDE:
if (_mouseCursor) {
_mouseCursorWasVisible = _mouseCursor->getSurface()->getVisible();
_mouseCursor->getSurface()->setVisible(false);
}
break;
- case 0x101E:
- // Show the mouse cursor
+ case NM_MOUSE_SHOW:
if (_mouseCursorWasVisible && _mouseCursor) {
_mouseCursor->getSurface()->setVisible(true);
}
break;
- case 0x1022:
+ case NM_PRIORITY_CHANGE:
// Set the sender's surface priority
setSurfacePriority(((Sprite*)sender)->getSurface(), param.asInteger());
break;
@@ -448,7 +449,7 @@ void Scene::processMessageList() {
_isKlaymenBusy = true;
sendPointMessage(_klaymen, 0x4001, _mouseClickPos);
} else if (messageNum == 0x100D) {
- if (this->hasMessageHandler() && sendMessage(this, 0x100D, messageParam) != 0)
+ if (this->hasMessageHandler() && sendMessage(this, NM_ANIMATION_START, messageParam) != 0)
continue;
} else if (messageNum == 0x101A) {
_messageListStatus = 0;
@@ -482,7 +483,7 @@ void Scene::cancelMessageList() {
_isKlaymenBusy = false;
_messageList = NULL;
_canAcceptInput = true;
- sendMessage(_klaymen, 0x4004, 0);
+ sendMessage(_klaymen, NM_KLAYMEN_STAND_IDLE, 0);
}
void Scene::setRectList(uint32 id) {
@@ -614,7 +615,7 @@ StaticScene::StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backg
uint32 StaticScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0001:
+ case NM_MOUSE_CLICK:
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
leaveScene(0);
break;
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index f60e291395..e6183199ce 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -204,8 +204,6 @@ protected:
// Used for debugging
uint32 _backgroundFileHash, _cursorFileHash; // for StaticScene and all Scene* classes
- void (Entity::*_savedUpdateHandlerCb)();
- uint32 (Entity::*_savedMessageHandlerCb)(int messageNum, const MessageParam &param, Entity *sender);
int _messageValue;
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
bool queryPositionSprite(int16 mouseX, int16 mouseY);
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/screen.h b/engines/neverhood/screen.h
index c778066152..a9b5af02f6 100644
--- a/engines/neverhood/screen.h
+++ b/engines/neverhood/screen.h
@@ -79,7 +79,6 @@ public:
void drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent, byte version,
const Graphics::Surface *shadowSurface = NULL);
void drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect, bool transparent, byte version);
- void drawShadowSurface(const Graphics::Surface *surface, const Graphics::Surface *shadowSurface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect);
void drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &drawRect);
void drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent, byte version);
void drawSurfaceClipRects(const Graphics::Surface *surface, NDrawRect &drawRect, NRect *clipRects, uint clipRectsCount, bool transparent, byte version);
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index 187939faee..014e094b94 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -21,6 +21,7 @@
*/
#include "graphics/palette.h"
+#include "neverhood/gamemodule.h"
#include "neverhood/smackerplayer.h"
#include "neverhood/palette.h"
#include "neverhood/resourceman.h"
@@ -160,7 +161,7 @@ void SmackerPlayer::close() {
void SmackerPlayer::gotoFrame(int frameNumber) {
if (_smackerDecoder) {
_smackerDecoder->forceSeekToFrame(frameNumber);
- _smackerDecoder->decodeNextFrame();
+ updateFrame();
}
}
@@ -204,7 +205,7 @@ void SmackerPlayer::update() {
} else if (!_keepLastFrame) {
// Inform the scene about the end of the video playback
if (_scene)
- sendMessage(_scene, 0x3002, 0);
+ sendMessage(_scene, NM_ANIMATION_STOP, 0);
_videoDone = true;
} else {
rewind();
@@ -251,6 +252,15 @@ void SmackerPlayer::updatePalette() {
tempPalette[i * 4 + 1] = smackerPalette[i * 3 + 1];
tempPalette[i * 4 + 2] = smackerPalette[i * 3 + 2];
}
+
+ // WORKAROUND: Scene 3, module 3000 defines a black color 255 instead of
+ // white, which results in the mouse cursor showing black. I'm not sure if
+ // color 255 is always supposed to be white. It's not feasible to check
+ // all scenes for a glitch that only seems to manifest in one, therefore
+ // we define color 255 to be white only for that scene.
+ if (_vm->_gameModule->getCurrentModuleNum() == 3000 && _vm->_gameState.sceneNum == 3)
+ tempPalette[255 * 4 + 0] = tempPalette[255 * 4 + 1] = tempPalette[255 * 4 + 2] = 0xFF;
+
_palette->copyPalette(tempPalette, 0, 256, 0);
}
diff --git a/engines/neverhood/smackerscene.cpp b/engines/neverhood/smackerscene.cpp
index d9d032a3b5..c3915200b5 100644
--- a/engines/neverhood/smackerscene.cpp
+++ b/engines/neverhood/smackerscene.cpp
@@ -104,15 +104,15 @@ void SmackerScene::update() {
uint32 SmackerScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
- case 0x0009:
+ case NM_KEYPRESS_SPACE:
if ((_videoPlayedBefore && _canSkip) || (_canAbort && _canSkip))
_playNextVideoFlag = true;
break;
- case 0x000C:
+ case NM_KEYPRESS_ESC:
if (_canAbort)
sendMessage(_parentModule, 0x1009, 0);
break;
- case 0x3002:
+ case NM_ANIMATION_STOP:
_playNextVideoFlag = true;
break;
}
diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp
index 746dd17de0..023eda4c02 100644
--- a/engines/neverhood/sound.cpp
+++ b/engines/neverhood/sound.cpp
@@ -66,6 +66,12 @@ void SoundResource::play() {
soundItem->playSound(false);
}
+void SoundResource::playLooping() {
+ AudioResourceManSoundItem *soundItem = getSoundItem();
+ if (soundItem)
+ soundItem->playSound(true);
+}
+
void SoundResource::stop() {
AudioResourceManSoundItem *soundItem = getSoundItem();
if (soundItem)
@@ -208,7 +214,7 @@ void SoundItem::setSoundParams(bool playOnceAfterRandomCountdown, int16 minCount
_minCountdown = minCountdown;
if (maxCountdown > 0)
_maxCountdown = maxCountdown;
- if (firstMinCountdown >= firstMaxCountdown)
+ if (firstMinCountdown > firstMaxCountdown)
_currCountdown = firstMinCountdown;
else if (firstMinCountdown > 0 && firstMaxCountdown > 0 && firstMinCountdown < firstMaxCountdown)
_currCountdown = _vm->_rnd->getRandomNumberRng(firstMinCountdown, firstMaxCountdown);
@@ -235,22 +241,24 @@ void SoundItem::update() {
if (_playOnceAfterCountdown) {
if (_currCountdown == 0)
_currCountdown = _initialCountdown;
- else if (--_currCountdown == 0)
+ else if (--_currCountdown <= 0)
_soundResource->play();
} else if (_playOnceAfterRandomCountdown) {
if (_currCountdown == 0) {
if (_minCountdown > 0 && _maxCountdown > 0 && _minCountdown < _maxCountdown)
_currCountdown = _vm->_rnd->getRandomNumberRng(_minCountdown, _maxCountdown);
- } else if (--_currCountdown == 0)
+ } else if (--_currCountdown <= 0)
_soundResource->play();
} else if (_playLooping && !_soundResource->isPlaying())
- _soundResource->play();
+ _soundResource->playLooping();
}
// SoundMan
SoundMan::SoundMan(NeverhoodEngine *vm)
- : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1) {
+ : _vm(vm), _soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1),
+ _initialCountdown(15), _playOnceAfterCountdown(false),
+ _initialCountdown3(9), _playOnceAfterCountdown3(false) {
}
SoundMan::~SoundMan() {
@@ -371,7 +379,6 @@ void SoundMan::update() {
if (soundItem)
soundItem->update();
}
-
for (uint i = 0; i < _musicItems.size(); ++i) {
MusicItem *musicItem = _musicItems[i];
if (musicItem)
@@ -551,15 +558,19 @@ int NeverhoodAudioStream::readBuffer(int16 *buffer, const int numSamples) {
*buffer++ = _prevValue << _shiftValue;
}
} else {
- memcpy(buffer, _buffer, bytesRead);
- buffer += bytesRead;
+ while (samplesRead--) {
+ *buffer++ = READ_LE_UINT16(src);
+ src += 2;
+ }
}
if (bytesRead < bytesToRead || _stream->pos() >= _stream->size() || _stream->err() || _stream->eos()) {
- if (_isLooping)
+ if (_isLooping) {
_stream->seek(0);
- else
+ _prevValue = 0;
+ } else {
_endOfData = true;
+ }
}
}
@@ -607,7 +618,7 @@ void AudioResourceManSoundItem::playSound(bool looping) {
if (_data) {
const byte *shiftValue = _resourceHandle.extData();
Common::MemoryReadStream *stream = new Common::MemoryReadStream(_data, _resourceHandle.size(), DisposeAfterUse::NO);
- NeverhoodAudioStream *audioStream = new NeverhoodAudioStream(22050, *shiftValue, false, DisposeAfterUse::YES, stream);
+ NeverhoodAudioStream *audioStream = new NeverhoodAudioStream(22050, *shiftValue, looping, DisposeAfterUse::YES, stream);
_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle,
audioStream, -1, VOLUME(_volume), PANNING(_panning));
debug(1, "playing sound %08X", _fileHash);
@@ -627,7 +638,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) {
}
diff --git a/engines/neverhood/sound.h b/engines/neverhood/sound.h
index 548fe88501..1f80f8d6b0 100644
--- a/engines/neverhood/sound.h
+++ b/engines/neverhood/sound.h
@@ -50,6 +50,7 @@ public:
void unload();
void play(uint32 fileHash);
void play();
+ void playLooping();
void stop();
void setVolume(int16 volume);
void setPan(int16 pan);
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index 1a432461fb..05fc9b256f 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -372,7 +372,7 @@ void AnimatedSprite::updateFrameIndex() {
} else {
// Inform self about end of current animation
// The caller can then e.g. set a new animation fileHash
- sendMessage(this, 0x3002, 0);
+ sendMessage(this, NM_ANIMATION_STOP, 0);
if (_newAnimFileHash == 0)
_currFrameIndex = 0;
}
@@ -380,7 +380,7 @@ void AnimatedSprite::updateFrameIndex() {
if (_currFrameIndex > 0) {
_currFrameIndex--;
} else {
- sendMessage(this, 0x3002, 0);
+ sendMessage(this, NM_ANIMATION_STOP, 0);
if (_newAnimFileHash == 0)
_currFrameIndex = _lastFrameIndex;
}
@@ -399,7 +399,7 @@ void AnimatedSprite::updateFrameInfo() {
updateBounds();
_needRefresh = true;
if (frameInfo.frameHash != 0)
- sendMessage(this, 0x100D, frameInfo.frameHash);
+ sendMessage(this, NM_ANIMATION_START, frameInfo.frameHash);
}
void AnimatedSprite::createSurface1(uint32 fileHash, int surfacePriority) {
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;
}