diff options
Diffstat (limited to 'engines/neverhood')
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 ¶m, 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 ¶m, 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 ¶m, } } 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 ¶m) { 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Ent uint32 Klaymen::hmClimbLadderUpDown(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity uint32 Klaymen::hmGrow(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender) { switch (messageNum) { case 0x4811: @@ -2766,130 +2438,17 @@ uint32 Klaymen::hmStandIdleSpecial(int messageNum, const MessageParam ¶m, En return 0; } -uint32 Klaymen::hmPressDoorButton(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity * return Klaymen::hmLowLevelAnimation(messageNum, param, sender); } -uint32 Klaymen::hmTumbleHeadless(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m) { - 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 ¶m, Entity *sender); - void stIdleSpinHead(); - uint32 hmIdleSpinHead(int messageNum, const MessageParam ¶m, Entity *sender); - void stIdleArms(); void evIdleArmsDone(); - uint32 hmIdleArms(int messageNum, const MessageParam ¶m, Entity *sender); - void stIdleChest(); - uint32 hmIdleChest(int messageNum, const MessageParam ¶m, Entity *sender); - void stIdleHeadOff(); - uint32 hmIdleHeadOff(int messageNum, const MessageParam ¶m, Entity *sender); - void stIdleWonderAbout(); - void stIdleTeleporterHands(); - void stIdleTeleporterHands2(); + uint32 hmIdlePickEar(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmIdleSpinHead(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmIdleArms(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmIdleChest(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmIdleHeadOff(int messageNum, const MessageParam ¶m, Entity *sender); + // Idle animations - end + void stTryStandIdle(); void stStandAround(); void upStandIdle(); @@ -150,12 +145,6 @@ public: void stInsertKey(); uint32 hmInsertKey(int messageNum, const MessageParam ¶m, Entity *sender); - void stReadNote(); - uint32 hmReadNote(int messageNum, const MessageParam ¶m, Entity *sender); - - void stHitByDoor(); - uint32 hmHitByDoor(int messageNum, const MessageParam ¶m, Entity *sender); - void stPeekWall(); uint32 hmPeekWall(int messageNum, const MessageParam ¶m, Entity *sender); @@ -166,21 +155,8 @@ public: void upPeekWallBlink(); void stPeekWall1(); - void stPeekWall2(); - void stPullHammerLever(); - uint32 hmPullHammerLever(int messageNum, const MessageParam ¶m, Entity *sender); - - void stRidePlatformDown(); - void suRidePlatformDown(); - - void stCrashDown(); - void stCrashDownFinished(); - - void stShrink(); - uint32 hmShrink(int messageNum, const MessageParam ¶m, Entity *sender); - void stGrow(); uint32 hmGrow(int messageNum, const MessageParam ¶m, Entity *sender); @@ -203,11 +179,6 @@ public: void stLetGoOfLever(); void evLeverReleasedEvent(); - void stWakeUp(); - - void stSleeping(); - uint32 hmSleeping(int messageNum, const MessageParam ¶m, Entity *sender); - void stPressButton(); void stPressFloorButton(); void stPressButtonSide(); @@ -228,20 +199,6 @@ public: void stClimbLadderHalf(); uint32 hmClimbLadderHalf(int messageNum, const MessageParam ¶m, Entity *sender); - void setupJumpToRing(); - void stJumpToRing1(); - void stJumpToRing2(); - void stJumpToRing4(); - uint32 hmJumpToRing(int messageNum, const MessageParam ¶m, Entity *sender); - - void stHangOnRing(); - - void stJumpToRing3(); - uint32 hmJumpToRing3(int messageNum, const MessageParam ¶m, Entity *sender); - - void stHoldRing3(); - uint32 hmHoldRing3(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); - void stClayDoorOpen(); - uint32 hmClayDoorOpen(int messageNum, const MessageParam ¶m, Entity *sender); - void stFallSkipJump(); void suFallSkipJump(); @@ -298,19 +248,6 @@ public: uint32 hmMoveObject(int messageNum, const MessageParam ¶m, Entity *sender); void upMoveObject(); - void stCloseEyes(); - - void stTumbleHeadless(); - uint32 hmTumbleHeadless(int messageNum, const MessageParam ¶m, Entity *sender); - - void stFetchMatch(); - void stLightMatch(); - uint32 hmMatch(int messageNum, const MessageParam ¶m, Entity *sender); - - void stHitByBoxingGlove(); - uint32 hmHitByBoxingGlove(int messageNum, const MessageParam ¶m, Entity *sender); - void evHitByBoxingGloveDone(); - void stStandIdleSmall(); void stWonderAboutSmall(); void stWonderAboutHalfSmall(); @@ -327,34 +264,17 @@ public: void stFinishGrow(); uint32 hmFinishGrow(int messageNum, const MessageParam ¶m, Entity *sender); - void stJumpToRingVenusFlyTrap(); - uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender); - - void stDropFromRing(); - void stStandIdleSpecial(); uint32 hmStandIdleSpecial(int messageNum, const MessageParam ¶m, Entity *sender); - void stPressDoorButton(); - uint32 hmPressDoorButton(int messageNum, const MessageParam ¶m, Entity *sender); - void stSpitOutFall0(); void stSpitOutFall2(); void suFallDown(); void upSpitOutFall(); - void stJumpAndFall(); - uint32 hmJumpAndFall(int messageNum, const MessageParam ¶m, Entity *sender); - void stFalling(); void stFallTouchdown(); - void stMoveVenusFlyTrap(); - void stContinueMovingVenusFlyTrap(); - uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m); @@ -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 ¶m); -}; - -class KmScene1002 : public Klaymen { -public: - KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - void xUpdate(); - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1004 : public Klaymen { -public: - KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1109 : public Klaymen { -public: - KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1201 : public Klaymen { -public: - KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1303 : public Klaymen { -public: - KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1304 : public Klaymen { -public: - KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1305 : public Klaymen { -public: - KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1306 : public Klaymen { -public: - KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1308 : public Klaymen { -public: - KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1401 : public Klaymen { -public: - KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1402 : public Klaymen { -public: - KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1403 : public Klaymen { -public: - KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1404 : public Klaymen { -public: - KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1608 : public Klaymen { -public: - KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1705 : public Klaymen { -public: - KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene1901 : public Klaymen { -public: - KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2001 : public Klaymen { -public: - KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2101 : public Klaymen { -public: - KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -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 ¶m); -}; - -class KmScene2203 : public Klaymen { -public: - KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2205 : public Klaymen { -public: - KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - void xUpdate(); - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2206 : public Klaymen { -public: - KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); - ~KmScene2206(); -protected: - void xUpdate(); - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2207 : public Klaymen { -public: - KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2242 : public Klaymen { -public: - KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - void xUpdate(); - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmHallOfRecords : public Klaymen { -public: - KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - void xUpdate(); - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2247 : public Klaymen { -public: - KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - void xUpdate(); - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2401 : public Klaymen { -public: - KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2402 : public Klaymen { -public: - KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2403 : public Klaymen { -public: - KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -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 ¶m); -}; - -class KmScene2501 : public Klaymen { -public: - KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2732 : public Klaymen { -public: - KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2801 : public Klaymen { -public: - KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -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 ¶m); -}; - -class KmScene2803Small : public Klaymen { -public: - KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -class KmScene2805 : public Klaymen { -public: - KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -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 ¶m); -}; - -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 ¶m); -}; - -class KmScene2810Small : public Klaymen { -public: - KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); -}; - -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 ¶m); -}; - -class KmScene2812 : public Klaymen { -public: - KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); -protected: - uint32 xHandleMessage(int messageNum, const MessageParam ¶m); }; } // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender) { - uint32 messageResult = handleMessage(messageNum, param, sender); - switch (messageNum) { - case 0x3002: - gotoNextState(); - break; - } - return messageResult; -} - -uint32 AsScene1002VenusFlyTrap::hmAnimationExt(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); -}; - -class AsScene1001Window : public AnimatedSprite { -public: - AsScene1001Window(NeverhoodEngine *vm); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmRingPulled1(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmRingPulled2(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmRingHangingLow(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmRingReleased(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene1002Door : public StaticSprite { -public: - AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect); -protected: - void update(); - uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); - void suOpenDoor(); - void suCloseDoor(); -}; - -class AsScene1002BoxingGloveHitEffect : public AnimatedSprite { -public: - AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); - uint32 hmDoorSpyAnimation(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmAnimationSimple(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmAnimationExt(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); - uint32 hmAnimation(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); }; -// Scene1004 - -class AsScene1004TrashCan : public AnimatedSprite { -public: - AsScene1004TrashCan(NeverhoodEngine *vm); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class AsScene1001Window : public AnimatedSprite { +public: + AsScene1001Window(NeverhoodEngine *vm); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); + uint32 hmRingPulled1(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmRingPulled2(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmRingHangingLow(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmRingReleased(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene1002Door : public StaticSprite { +public: + AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect); +protected: + void update(); + uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); + void suOpenDoor(); + void suCloseDoor(); +}; + +class AsScene1002BoxingGloveHitEffect : public AnimatedSprite { +public: + AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + uint32 hmDoorSpyAnimation(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); + uint32 hmAnimationSimple(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmAnimationExt(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + uint32 hmAnimation(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); +}; + +class AsScene1004TrashCan : public AnimatedSprite { +public: + AsScene1004TrashCan(NeverhoodEngine *vm); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + uint32 hmPullHammerLever(int messageNum, const MessageParam ¶m, Entity *sender); + + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +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 ¶m, Entity *sender); + uint32 hmJumpToRing3(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmHoldRing3(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmJumpAndFall(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmPressDoorButton(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmHitByBoxingGlove(int messageNum, const MessageParam ¶m, Entity *sender); + + void xUpdate(); + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene1004 : public Klaymen { +public: + KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + void stReadNote(); + uint32 hmReadNote(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class KmScene1109 : public Klaymen { +public: + KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender) { - uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender); - switch (messageNum) { - case 0x3002: - gotoNextState(); - break; - } - return messageResult; -} - -uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender) { - uint32 messageResult = hmWaiting(messageNum, param, sender); - switch (messageNum) { - case 0x3002: - gotoNextState(); - break; - } - return messageResult; -} - -uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entit uint32 Scene1202::hmSolved(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); -}; - -class AsScene1201TntManRope : public AnimatedSprite { -public: - AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); - void stOpenDoor(); - void stCloseDoor(); - void stCloseDoorDone(); -}; - -class AsScene1201KlaymenHead : public AnimatedSprite { -public: - AsScene1201KlaymenHead(NeverhoodEngine *vm); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); - uint32 hmComingDown(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); - uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmIdle(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); - uint32 hmPincerSnap(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmChangePosition(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class AsScene1201TntManRope : public AnimatedSprite { +public: + AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + void stOpenDoor(); + void stCloseDoor(); + void stCloseDoorDone(); +}; + +class AsScene1201KlaymenHead : public AnimatedSprite { +public: + AsScene1201KlaymenHead(NeverhoodEngine *vm); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + uint32 hmComingDown(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmIdle(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + uint32 hmPincerSnap(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); + uint32 hmChangePosition(int messageNum, const MessageParam ¶m, 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 ¶m, Entity *sender); + uint32 hmMatch(int messageNum, const MessageParam ¶m, Entity *sender); + + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entit uint32 Scene1306::handleMessage416EB0(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entit uint32 Scene1317::hmChooseKing(int messageNum, const MessageParam ¶m, 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 ¶m, Entity uint32 Scene1317::hmHoborgAsKing(int messageNum, const MessageParam ¶m, 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 ¶m, Enti uint32 Scene1317::hmEndMovie(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); }; -class AsScene1303Balloon : public AnimatedSprite { -public: - AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene); -protected: - Scene *_parentScene; - uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmBalloonPopped(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); }; -class AsScene1308JaggyDoor : public AnimatedSprite { -public: - AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene); -protected: - Scene *_parentScene; - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); + uint32 hmBalloonPopped(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class KmScene1303 : public Klaymen { +public: + KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene1304 : public Klaymen { +public: + KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +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 ¶m); +}; + +class KmScene1306 : public Klaymen { +public: + KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene1308 : public Klaymen { +public: + KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmSuckInProjector(int messageNum, const MessageParam ¶m, Entity *sender); - void stStartSucking(); - void stDoneSucking(); - void stSuckInProjector(); -}; - -class AsScene1401Mouse : public AnimatedSprite { -public: - AsScene1401Mouse(NeverhoodEngine *vm); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); - void suSuckedIn(); - void stSuckedIn(); -}; - -class AsScene1401Cheese : public AnimatedSprite { -public: - AsScene1401Cheese(NeverhoodEngine *vm); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmLockedInSlot(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmAnimation(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m, Entity *sender); + uint32 hmSuckInProjector(int messageNum, const MessageParam ¶m, Entity *sender); + void stStartSucking(); + void stDoneSucking(); + void stSuckInProjector(); +}; + +class AsScene1401Mouse : public AnimatedSprite { +public: + AsScene1401Mouse(NeverhoodEngine *vm); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); + void suSuckedIn(); + void stSuckedIn(); +}; + +class AsScene1401Cheese : public AnimatedSprite { +public: + AsScene1401Cheese(NeverhoodEngine *vm); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); + uint32 hmLockedInSlot(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmAnimation(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class KmScene1401 : public Klaymen { +public: + KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene1402 : public Klaymen { +public: + KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene1403 : public Klaymen { +public: + KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene1404 : public Klaymen { +public: + KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity uint32 Scene1608::hmUpperFloor(int messageNum, const MessageParam ¶m, 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 ¶m, Entity uint32 Scene1608::hmRidingCar(int messageNum, const MessageParam ¶m, 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 ¶m, Entity uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmLeaveCar(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, Entity *sender); + uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmLeaveCar(int messageNum, const MessageParam ¶m, 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 ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, Entity *sender); +}; + +class KmScene1705 : public Klaymen { +public: + KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmTryToPlugIn(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, Entity *sender); + uint32 hmTryToPlugIn(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class KmScene1901 : public Klaymen { +public: + KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m) { + 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 ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class KmScene2101 : public Klaymen { +public: + KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); + + void stHitByDoor(); + uint32 hmHitByDoor(int messageNum, const MessageParam ¶m, Entity *sender); + +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entit uint32 Scene2207::handleMessage2(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); }; -class SsScene2205DoorFrame : public StaticSprite { -public: - SsScene2205DoorFrame(NeverhoodEngine *vm); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; +class SsCommonPressButton; class Scene2205 : public Scene { public: @@ -194,35 +105,6 @@ protected: uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); }; -class AsScene2206DoorSpikes : public StaticSprite { -public: - AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash); -protected: - int _deltaIndex; - void update(); - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m) { + 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 ¶m, 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); + void openDoor(); + void closeDoor(); +}; + +class SsScene2205DoorFrame : public StaticSprite { +public: + SsScene2205DoorFrame(NeverhoodEngine *vm); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2206DoorSpikes : public StaticSprite { +public: + AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash); +protected: + int _deltaIndex; + void update(); + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m); +}; + +class KmScene2203 : public Klaymen { +public: + KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + void stClayDoorOpen(); + uint32 hmClayDoorOpen(int messageNum, const MessageParam ¶m, Entity *sender); + + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene2205 : public Klaymen { +public: + KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + void xUpdate(); + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +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 ¶m); +}; + +class KmScene2207 : public Klaymen { +public: + KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene2242 : public Klaymen { +public: + KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + void xUpdate(); + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmHallOfRecords : public Klaymen { +public: + KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + void xUpdate(); + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene2247 : public Klaymen { +public: + KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + void xUpdate(); + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); }; -class AsScene2401WaterSpit : public AnimatedSprite { -public: - AsScene2401WaterSpit(NeverhoodEngine *vm); -protected: - int _soundIndex; - uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2401FlowingWater : public AnimatedSprite { -public: - AsScene2401FlowingWater(NeverhoodEngine *vm); - virtual ~AsScene2401FlowingWater(); -protected: - bool _isWaterFlowing; - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m, Entity *sender); +}; + +class AsScene2401FlowingWater : public AnimatedSprite { +public: + AsScene2401FlowingWater(NeverhoodEngine *vm); + virtual ~AsScene2401FlowingWater(); +protected: + bool _isWaterFlowing; + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); + + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene2402 : public Klaymen { +public: + KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene2403 : public Klaymen { +public: + KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +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 ¶m); +}; + +} // 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 ¶m, 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 ¶m, Entit uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam ¶m, 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 ¶m, Entity uint32 Scene2501::hmCarAtHome(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m, Entity *sender); +}; + +class KmScene2501 : public Klaymen { +public: + KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); -}; - -class AsScene2609Water : public AnimatedSprite { -public: - AsScene2609Water(NeverhoodEngine *vm); - virtual ~AsScene2609Water(); -protected: - uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); +}; + +class AsScene2609Water : public AnimatedSprite { +public: + AsScene2609Water(NeverhoodEngine *vm); + virtual ~AsScene2609Water(); +protected: + uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, Entity uint32 Scene2701::hmCarAtHome(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) { + 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 ¶m); +}; + +} // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶ uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, } 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam ¶m, 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 ¶m, } 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 ¶m, 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m, 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m) { + 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 ¶m, Entity *sender); }; +class KmScene2801 : public Klaymen { +public: + KmScene2801(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +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 ¶m); +}; + +class KmScene2803Small : public Klaymen { +public: + KmScene2803Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + void stShrink(); + uint32 hmShrink(int messageNum, const MessageParam ¶m, Entity *sender); + + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +class KmScene2805 : public Klaymen { +public: + KmScene2805(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +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 ¶m); +}; + +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 ¶m); +}; + +class KmScene2810Small : public Klaymen { +public: + KmScene2810Small(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + +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 ¶m); +}; + +class KmScene2812 : public Klaymen { +public: + KmScene2812(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); +protected: + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + } // 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); int _messageValue; uint32 handleMessage(int messageNum, const MessageParam ¶m, 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 ¶m, 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; } |