aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/myst_stacks
diff options
context:
space:
mode:
authorBastien Bouclet2010-12-17 07:44:59 +0000
committerBastien Bouclet2010-12-17 07:44:59 +0000
commit151d180e55782955fafce72477a808309af8ab27 (patch)
tree956d8dfc7d13a17a7d7d3330d5cb7e3effcf2a63 /engines/mohawk/myst_stacks
parente3eddf32e97f2f357b6194218ead31731b4043bc (diff)
downloadscummvm-rg350-151d180e55782955fafce72477a808309af8ab27.tar.gz
scummvm-rg350-151d180e55782955fafce72477a808309af8ab27.tar.bz2
scummvm-rg350-151d180e55782955fafce72477a808309af8ab27.zip
MOHAWK: Implement Myst opcodes 128, 168, 216, 217, 304, 305, and 153 to 156 : Giant tree. Channelwood is now accessible from Myst.
svn-id: r54941
Diffstat (limited to 'engines/mohawk/myst_stacks')
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp265
-rw-r--r--engines/mohawk/myst_stacks/myst.h30
2 files changed, 242 insertions, 53 deletions
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index b108276bb6..3df9f0a8bd 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -44,11 +44,16 @@ MystScriptParser_Myst::MystScriptParser_Myst(MohawkEngine_Myst *vm) : MystScript
// Card ID preinitialized by the engine for use by opcode 18
// when linking back to Myst in the library
_savedCardId = 4329;
+
_libraryBookcaseChanged = false;
_dockVaultState = 0;
_cabinMatchState = 2;
_matchBurning = false;
+ _tree = 0;
+ _treeAlcove = 0;
_treeStopped = false;
+ _treeMinPosition = 0;
+ _treeLastMoveTime = _vm->_system->getMillis();
}
MystScriptParser_Myst::~MystScriptParser_Myst() {
@@ -80,6 +85,7 @@ void MystScriptParser_Myst::setupOpcodes() {
OPCODE(122, o_cabinSafeHandleStartMove);
OPCODE(123, o_cabinSafeHandleMove);
OPCODE(124, o_cabinSafeHandleEndMove);
+ OPCODE(128, o_treePressureReleaseStart);
OPCODE(129, opcode_129);
OPCODE(130, opcode_130);
OPCODE(131, opcode_131);
@@ -98,6 +104,11 @@ void MystScriptParser_Myst::setupOpcodes() {
OPCODE(149, o_boilerIncreasePressureStop);
OPCODE(150, o_boilerDecreasePressureStart);
OPCODE(151, o_boilerDecreasePressureStop);
+ OPCODE(152, NOP);
+ OPCODE(153, o_basementIncreasePressureStart);
+ OPCODE(154, o_basementIncreasePressureStop);
+ OPCODE(155, o_basementDecreasePressureStart);
+ OPCODE(156, o_basementDecreasePressureStop);
OPCODE(158, o_rocketSoundSliderStartMove);
OPCODE(159, o_rocketSoundSliderMove);
OPCODE(160, o_rocketSoundSliderEndMove);
@@ -105,6 +116,8 @@ void MystScriptParser_Myst::setupOpcodes() {
OPCODE(164, o_rocketOpenBook);
OPCODE(165, o_rocketLeverMove);
OPCODE(166, o_rocketLeverEndMove);
+ OPCODE(167, NOP);
+ OPCODE(168, o_treePressureReleaseStop);
OPCODE(169, o_cabinLeave);
OPCODE(170, opcode_170);
OPCODE(171, opcode_171);
@@ -150,8 +163,8 @@ void MystScriptParser_Myst::setupOpcodes() {
OPCODE(213, opcode_213);
OPCODE(214, opcode_214);
OPCODE(215, opcode_215);
- OPCODE(216, opcode_216);
- OPCODE(217, opcode_217);
+ OPCODE(216, o_treeCard_init);
+ OPCODE(217, o_treeEntry_init);
OPCODE(218, opcode_218);
OPCODE(219, o_rocketSliders_init);
OPCODE(220, o_rocketLinkVideo_init);
@@ -163,8 +176,8 @@ void MystScriptParser_Myst::setupOpcodes() {
OPCODE(301, opcode_301);
OPCODE(302, opcode_302);
OPCODE(303, opcode_303);
- OPCODE(304, opcode_304);
- OPCODE(305, opcode_305);
+ OPCODE(304, o_treeCard_exit);
+ OPCODE(305, o_treeEntry_exit);
OPCODE(306, opcode_306);
OPCODE(307, opcode_307);
OPCODE(308, opcode_308);
@@ -185,18 +198,20 @@ void MystScriptParser_Myst::disablePersistentScripts() {
_towerRotationMapRunning = false;
_boilerPressureIncreasing = false;
_boilerPressureDecreasing = false;
+ _basementPressureIncreasing = false;
+ _basementPressureDecreasing = false;
opcode_212_disable();
}
void MystScriptParser_Myst::runPersistentScripts() {
opcode_201_run();
+ opcode_205_run();
+ opcode_212_run();
if (_towerRotationMapRunning)
towerRotationMap_run();
- opcode_205_run();
-
if (_generatorControlRoomRunning)
generatorControlRoom_run();
@@ -218,7 +233,14 @@ void MystScriptParser_Myst::runPersistentScripts() {
if (_boilerPressureDecreasing)
boilerPressureDecrease_run();
- opcode_212_run();
+ if (_basementPressureIncreasing)
+ basementPressureIncrease_run();
+
+ if (_basementPressureDecreasing)
+ basementPressureDecrease_run();
+
+ if (!_treeStopped)
+ tree_run();
}
uint16 MystScriptParser_Myst::getVar(uint16 var) {
@@ -402,10 +424,19 @@ uint16 MystScriptParser_Myst::getVar(uint16 var) {
return myst.cabinSafeCombination % 10;
case 70: // Cabin Safe Matchbox State
return _cabinMatchState;
+ case 72: // Channelwood tree position
+ return myst.treePosition;
case 93: // Breaker nearest Generator Room Blown
return myst.generatorBreakers == 1;
case 94: // Breaker nearest Rocket Ship Blown
return myst.generatorBreakers == 2;
+ case 95: // Going out of tree destination selection
+ if (myst.treePosition == 0)
+ return 0;
+ else if (myst.treePosition == 4 || myst.treePosition == 5)
+ return 1;
+ else
+ return 2;
case 96: // Generator Power Dial Needle Position
return myst.generatorVoltage / 4;
case 97: // Generator Power To Spaceship Dial Needle Position
@@ -1350,6 +1381,9 @@ void MystScriptParser_Myst::o_boilerLightPilot(uint16 op, uint16 var, uint16 arg
if (myst.cabinValvePosition > 0)
_vm->_sound->replaceBackground(8098, 49152);
+ if (myst.cabinValvePosition > 12)
+ _treeLastMoveTime = _vm->_system->getMillis();
+
// TODO: Complete. Play movies
}
}
@@ -1360,6 +1394,7 @@ void MystScriptParser_Myst::o_boilerIncreasePressureStop(uint16 op, uint16 var,
_treeStopped = false;
_boilerPressureIncreasing = false;
+ _treeLastMoveTime = _vm->_system->getMillis();
if (myst.cabinPilotLightLit == 1) {
if (myst.cabinValvePosition > 0)
@@ -1401,7 +1436,7 @@ void MystScriptParser_Myst::boilerPressureIncrease_run() {
void MystScriptParser_Myst::boilerPressureDecrease_run() {
MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
- // Allow increasing pressure if sound has stopped
+ // Allow decreasing pressure if sound has stopped
if (!_vm->_sound->isPlaying(5098) && myst.cabinValvePosition > 0) {
myst.cabinValvePosition--;
if (myst.cabinValvePosition == 0) {
@@ -1434,6 +1469,7 @@ void MystScriptParser_Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var,
_treeStopped = false;
_boilerPressureDecreasing = false;
+ _treeLastMoveTime = _vm->_system->getMillis();
if (myst.cabinPilotLightLit == 1) {
if (myst.cabinValvePosition > 0)
@@ -1446,6 +1482,131 @@ void MystScriptParser_Myst::o_boilerDecreasePressureStop(uint16 op, uint16 var,
}
}
+void MystScriptParser_Myst::o_basementIncreasePressureStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Basement increase pressure start", op);
+
+ _treeStopped = true;
+ _basementPressureIncreasing = true;
+}
+
+void MystScriptParser_Myst::o_basementIncreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Basement increase pressure stop", op);
+
+ _treeStopped = false;
+ _basementPressureIncreasing = false;
+ _treeLastMoveTime = _vm->_system->getMillis();
+}
+
+void MystScriptParser_Myst::basementPressureIncrease_run() {
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
+ // Allow increasing pressure if sound has stopped
+ if (!_vm->_sound->isPlaying(4642) && myst.cabinValvePosition < 25) {
+ myst.cabinValvePosition++;
+
+ // Pressure increasing sound
+ _vm->_sound->playSound(4642);
+
+ // Redraw wheel
+ _vm->redrawArea(99);
+ }
+}
+
+void MystScriptParser_Myst::basementPressureDecrease_run() {
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
+ // Allow decreasing pressure if sound has stopped
+ if (!_vm->_sound->isPlaying(4642) && myst.cabinValvePosition > 0) {
+ myst.cabinValvePosition--;
+
+ // Pressure decreasing sound
+ _vm->_sound->playSound(4642);
+
+ // Redraw wheel
+ _vm->redrawArea(99);
+ }
+}
+
+void MystScriptParser_Myst::o_basementDecreasePressureStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Basement decrease pressure start", op);
+
+ _treeStopped = true;
+ _basementPressureDecreasing = true;
+}
+
+void MystScriptParser_Myst::o_basementDecreasePressureStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Basement decrease pressure stop", op);
+
+ _treeStopped = false;
+ _basementPressureDecreasing = false;
+ _treeLastMoveTime = _vm->_system->getMillis();
+}
+
+void MystScriptParser_Myst::tree_run() {
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
+ uint16 pressure;
+ if (myst.cabinPilotLightLit)
+ pressure = myst.cabinValvePosition;
+ else
+ pressure = 0;
+
+ // 12 means tree is balanced
+ if (pressure != 12) {
+ bool goingDown = true;
+ if (pressure >= 12)
+ goingDown = false;
+
+ // Tree is within bounds
+ if ((myst.treePosition < 12 && !goingDown)
+ || (myst.treePosition > _treeMinPosition && goingDown)) {
+ uint16 delay = treeNextMoveDelay(pressure);
+ uint32 time = _vm->_system->getMillis();
+ if (delay < time - _treeLastMoveTime) {
+
+ // Tree movement
+ if (goingDown) {
+ myst.treePosition--;
+ _vm->_sound->playSound(2);
+ } else {
+ myst.treePosition++;
+ _vm->_sound->playSound(1);
+ }
+
+ // Stop background music if going up from book room
+ if (_vm->getCurCard() == 4630 && myst.treePosition > 0) {
+ _vm->_sound->stopBackground();
+ }
+
+ // Redraw tree
+ _vm->redrawArea(72);
+
+ // Check if alcove is accessible
+ treeSetAlcoveAccessible();
+
+ _treeLastMoveTime = time;
+ }
+ }
+ }
+}
+
+void MystScriptParser_Myst::treeSetAlcoveAccessible() {
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
+ if (_treeAlcove) {
+ // Make alcove accessible if the tree is in the correct position
+ _treeAlcove->setEnabled(myst.treePosition >= _treeMinAccessiblePosition
+ && myst.treePosition <= _treeMaxAccessiblePosition);
+ }
+}
+
+uint32 MystScriptParser_Myst::treeNextMoveDelay(uint16 pressure) {
+ if (pressure >= 12)
+ return 25000 * (13 - (pressure - 12)) / 12 + 3000;
+ else
+ return 25000 * pressure / 13 + 3000;
+}
+
void MystScriptParser_Myst::o_rocketSoundSliderStartMove(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
debugC(kDebugScript, "Opcode %d: Rocket slider start move", op);
@@ -1639,6 +1800,38 @@ void MystScriptParser_Myst::o_cabinLeave(uint16 op, uint16 var, uint16 argc, uin
}
}
+void MystScriptParser_Myst::o_treePressureReleaseStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Tree pressure release start", op);
+
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
+ Common::Rect src = Common::Rect(0, 0, 49, 86);
+ Common::Rect dest = Common::Rect(78, 46, 127, 132);
+ _vm->_gfx->copyImageSectionToScreen(4631, src, dest);
+ _vm->_system->updateScreen();
+
+ _tempVar = myst.cabinValvePosition;
+
+ if (myst.treePosition >= 4) {
+ myst.cabinValvePosition = 0;
+ _treeMinPosition = 4;
+ _treeLastMoveTime = 0;
+ }
+}
+
+void MystScriptParser_Myst::o_treePressureReleaseStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Tree pressure release stop", op);
+
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
+ Common::Rect rect = Common::Rect(78, 46, 127, 132);
+ _vm->_gfx->copyBackBufferToScreen(rect);
+ _vm->_system->updateScreen();
+
+ myst.cabinValvePosition = _tempVar;
+ _treeMinPosition = 0;
+}
+
void MystScriptParser_Myst::opcode_170(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
// Used on Card 4500
// TODO: Month slider mouse down
@@ -2380,34 +2573,20 @@ void MystScriptParser_Myst::opcode_215(uint16 op, uint16 var, uint16 argc, uint1
}
}
-void MystScriptParser_Myst::opcode_216(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void MystScriptParser_Myst::o_treeCard_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Enter tree card", op);
- // Used for Cards 4571 (Channelwood Tree), 4586 (Channelwood Tree),
- // 4615 (Channelwood Tree) and 4601 (Channelwood Tree)
- if (argc == 0) {
- // TODO: Fill in logic for Channelwood Tree Position i.e. Var 72 update // 0 to 12, 4 for Alcove
- // Based on Timer code and following variables :
- // 98 "Cabin Boiler Pilot Light Lit"
- // 99 "Cabin Boiler Gas Valve Position" }, // 0 to 5
- // 305 "Cabin Boiler Lit" },
- // 306 "Cabin Boiler Steam Sound Control" }, // 0 to 27
- // 307 "Cabin Boiler Needle Position i.e. Fully Pressurised" }, // 0 to 1
-
- // Note : Opcode 218 does boiler update code..
- } else
- unknown(op, var, argc, argv);
+ _tree = static_cast<MystResourceType8 *>(_invokingResource);
}
-void MystScriptParser_Myst::opcode_217(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void MystScriptParser_Myst::o_treeEntry_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Enter tree card with entry", op);
- // Used for Card 4601 (Channelwood Tree)
- if (argc == 2) {
- // TODO: Fill in logic for Tree Position Close Up...
- // 2 arguments: 4, 4
- } else
- unknown(op, var, argc, argv);
+ _treeAlcove = static_cast<MystResourceType5 *>(_invokingResource);
+ _treeMinAccessiblePosition = argv[0];
+ _treeMaxAccessiblePosition = argv[1];
+
+ treeSetAlcoveAccessible();
}
void MystScriptParser_Myst::opcode_218(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -2531,26 +2710,16 @@ void MystScriptParser_Myst::opcode_303(uint16 op, uint16 var, uint16 argc, uint1
// upon card change, but this behavior is now default in this engine.
}
-void MystScriptParser_Myst::opcode_304(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void MystScriptParser_Myst::o_treeCard_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Exit tree card", op);
- // Used for Card 4601 (Channelwood Tree)
- if (argc == 0) {
- debugC(kDebugScript, "Opcode %d: Unknown...", op);
- // TODO: Logic for clearing variable?
- } else
- unknown(op, var, argc, argv);
+ _tree = 0;
}
-void MystScriptParser_Myst::opcode_305(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void MystScriptParser_Myst::o_treeEntry_exit(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Exit tree card with entry", op);
- // Used for Card 4601 (Channelwood Tree)
- if (argc == 0) {
- debugC(kDebugScript, "Opcode %d: Unknown...", op);
- // TODO: Logic for clearing variable?
- } else
- unknown(op, var, argc, argv);
+ _treeAlcove = 0;
}
void MystScriptParser_Myst::opcode_306(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index 5422ef83d6..c37fecd29b 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -65,6 +65,9 @@ private:
void matchBurn_run();
void boilerPressureIncrease_run();
void boilerPressureDecrease_run();
+ void basementPressureIncrease_run();
+ void basementPressureDecrease_run();
+ void tree_run();
DECLARE_OPCODE(o_libraryBookPageTurnLeft);
DECLARE_OPCODE(o_libraryBookPageTurnRight);
@@ -86,6 +89,7 @@ private:
DECLARE_OPCODE(o_cabinSafeHandleStartMove);
DECLARE_OPCODE(o_cabinSafeHandleMove);
DECLARE_OPCODE(o_cabinSafeHandleEndMove);
+ DECLARE_OPCODE(o_treePressureReleaseStart);
DECLARE_OPCODE(opcode_129);
DECLARE_OPCODE(opcode_130);
DECLARE_OPCODE(opcode_131);
@@ -103,6 +107,10 @@ private:
DECLARE_OPCODE(o_boilerIncreasePressureStop);
DECLARE_OPCODE(o_boilerDecreasePressureStart);
DECLARE_OPCODE(o_boilerDecreasePressureStop);
+ DECLARE_OPCODE(o_basementIncreasePressureStart);
+ DECLARE_OPCODE(o_basementIncreasePressureStop);
+ DECLARE_OPCODE(o_basementDecreasePressureStart);
+ DECLARE_OPCODE(o_basementDecreasePressureStop);
DECLARE_OPCODE(o_rocketSoundSliderStartMove);
DECLARE_OPCODE(o_rocketSoundSliderMove);
DECLARE_OPCODE(o_rocketSoundSliderEndMove);
@@ -111,6 +119,7 @@ private:
DECLARE_OPCODE(o_rocketLeverMove);
DECLARE_OPCODE(o_rocketLeverEndMove);
DECLARE_OPCODE(o_cabinLeave);
+ DECLARE_OPCODE(o_treePressureReleaseStop);
DECLARE_OPCODE(opcode_170);
DECLARE_OPCODE(opcode_171);
DECLARE_OPCODE(opcode_172);
@@ -151,8 +160,8 @@ private:
DECLARE_OPCODE(opcode_213);
DECLARE_OPCODE(opcode_214);
DECLARE_OPCODE(opcode_215);
- DECLARE_OPCODE(opcode_216);
- DECLARE_OPCODE(opcode_217);
+ DECLARE_OPCODE(o_treeCard_init);
+ DECLARE_OPCODE(o_treeEntry_init);
DECLARE_OPCODE(opcode_218);
DECLARE_OPCODE(o_rocketSliders_init);
DECLARE_OPCODE(o_rocketLinkVideo_init);
@@ -163,8 +172,8 @@ private:
DECLARE_OPCODE(opcode_301);
DECLARE_OPCODE(opcode_302);
DECLARE_OPCODE(opcode_303);
- DECLARE_OPCODE(opcode_304);
- DECLARE_OPCODE(opcode_305);
+ DECLARE_OPCODE(o_treeCard_exit);
+ DECLARE_OPCODE(o_treeEntry_exit);
DECLARE_OPCODE(opcode_306);
DECLARE_OPCODE(opcode_307);
DECLARE_OPCODE(opcode_308);
@@ -218,8 +227,16 @@ private:
bool _boilerPressureIncreasing;
bool _boilerPressureDecreasing;
+ bool _basementPressureIncreasing;
+ bool _basementPressureDecreasing;
- bool _treeStopped;
+ bool _treeStopped; // 236
+ MystResourceType8 *_tree; // 220
+ MystResourceType5 *_treeAlcove; // 224
+ uint16 _treeMinPosition; // 228
+ uint16 _treeMinAccessiblePosition; // 230
+ uint16 _treeMaxAccessiblePosition; // 232
+ uint32 _treeLastMoveTime;
void generatorRedrawRocket();
void generatorButtonValue(MystResource *button, uint16 &offset, uint16 &value);
@@ -241,6 +258,9 @@ private:
uint16 towerRotationMapComputeAngle();
Common::Point towerRotationMapComputeCoords(const Common::Point &center, uint16 angle);
void towerRotationMapDrawLine(const Common::Point &center, const Common::Point &end);
+
+ void treeSetAlcoveAccessible();
+ uint32 treeNextMoveDelay(uint16 pressure);
};
} // End of namespace Mohawk