aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/riven_stacks/jspit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk/riven_stacks/jspit.cpp')
-rw-r--r--engines/mohawk/riven_stacks/jspit.cpp503
1 files changed, 502 insertions, 1 deletions
diff --git a/engines/mohawk/riven_stacks/jspit.cpp b/engines/mohawk/riven_stacks/jspit.cpp
index e19d28952c..582c1d6080 100644
--- a/engines/mohawk/riven_stacks/jspit.cpp
+++ b/engines/mohawk/riven_stacks/jspit.cpp
@@ -22,7 +22,12 @@
#include "mohawk/riven_stacks/jspit.h"
-#include "engines/mohawk/riven.h"
+#include "mohawk/cursors.h"
+#include "mohawk/riven.h"
+#include "mohawk/riven_card.h"
+#include "mohawk/riven_graphics.h"
+
+#include "common/events.h"
namespace Mohawk {
namespace RivenStacks {
@@ -30,6 +35,502 @@ namespace RivenStacks {
JSpit::JSpit(MohawkEngine_Riven *vm) :
DomeSpit(vm, kStackJspit) {
+ REGISTER_COMMAND(JSpit, xreseticons);
+ REGISTER_COMMAND(JSpit, xicon);
+ REGISTER_COMMAND(JSpit, xcheckicons);
+ REGISTER_COMMAND(JSpit, xtoggleicon);
+ REGISTER_COMMAND(JSpit, xjtunnel103_pictfix);
+ REGISTER_COMMAND(JSpit, xjtunnel104_pictfix);
+ REGISTER_COMMAND(JSpit, xjtunnel105_pictfix);
+ REGISTER_COMMAND(JSpit, xjtunnel106_pictfix);
+ REGISTER_COMMAND(JSpit, xvga1300_carriage);
+ REGISTER_COMMAND(JSpit, xjdome25_resetsliders);
+ REGISTER_COMMAND(JSpit, xjdome25_slidermd);
+ REGISTER_COMMAND(JSpit, xjdome25_slidermw);
+ REGISTER_COMMAND(JSpit, xjscpbtn);
+ REGISTER_COMMAND(JSpit, xjisland3500_domecheck);
+ REGISTER_COMMAND(JSpit, xhandlecontroldown);
+ REGISTER_COMMAND(JSpit, xhandlecontrolmid);
+ REGISTER_COMMAND(JSpit, xhandlecontrolup);
+ REGISTER_COMMAND(JSpit, xjplaybeetle_550);
+ REGISTER_COMMAND(JSpit, xjplaybeetle_600);
+ REGISTER_COMMAND(JSpit, xjplaybeetle_950);
+ REGISTER_COMMAND(JSpit, xjplaybeetle_1050);
+ REGISTER_COMMAND(JSpit, xjplaybeetle_1450);
+ REGISTER_COMMAND(JSpit, xjlagoon700_alert);
+ REGISTER_COMMAND(JSpit, xjlagoon800_alert);
+ REGISTER_COMMAND(JSpit, xjlagoon1500_alert);
+ REGISTER_COMMAND(JSpit, xschool280_playwhark);
+ REGISTER_COMMAND(JSpit, xjschool280_resetleft);
+ REGISTER_COMMAND(JSpit, xjschool280_resetright);
+ REGISTER_COMMAND(JSpit, xjatboundary);
+}
+
+void JSpit::xreseticons(uint16 argc, uint16 *argv) {
+ // Reset the icons when going to Tay (rspit)
+ _vm->_vars["jicons"] = 0;
+ _vm->_vars["jiconorder"] = 0;
+ _vm->_vars["jrbook"] = 0;
+}
+
+// Count up how many icons are pressed
+static byte countDepressedIcons(uint32 iconOrderVar) {
+ if (iconOrderVar >= (1 << 20))
+ return 5;
+ else if (iconOrderVar >= (1 << 15))
+ return 4;
+ else if (iconOrderVar >= (1 << 10))
+ return 3;
+ else if (iconOrderVar >= (1 << 5))
+ return 2;
+ else if (iconOrderVar >= (1 << 1))
+ return 1;
+ else
+ return 0;
+}
+
+void JSpit::xicon(uint16 argc, uint16 *argv) {
+ // Set atemp as the status of whether or not the icon can be depressed.
+ if (_vm->_vars["jicons"] & (1 << (argv[0] - 1))) {
+ // This icon is depressed. Allow depression only if the last depressed icon was this one.
+ if ((_vm->_vars["jiconorder"] & 0x1f) == argv[0])
+ _vm->_vars["atemp"] = 1;
+ else
+ _vm->_vars["atemp"] = 2;
+ } else
+ _vm->_vars["atemp"] = 0;
+}
+
+void JSpit::xcheckicons(uint16 argc, uint16 *argv) {
+ // Reset the icons if this is the sixth icon
+ uint32 &iconOrderVar = _vm->_vars["jiconorder"];
+ if (countDepressedIcons(iconOrderVar) == 5) {
+ iconOrderVar = 0;
+ _vm->_vars["jicons"] = 0;
+ _vm->_sound->playSound(46);
+ }
+}
+
+void JSpit::xtoggleicon(uint16 argc, uint16 *argv) {
+ // Get the variables
+ uint32 &iconsDepressed = _vm->_vars["jicons"];
+ uint32 &iconOrderVar = _vm->_vars["jiconorder"];
+
+ if (iconsDepressed & (1 << (argv[0] - 1))) {
+ // The icon is depressed, now unpress it
+ iconsDepressed &= ~(1 << (argv[0] - 1));
+ iconOrderVar >>= 5;
+ } else {
+ // The icon is not depressed, now depress it
+ iconsDepressed |= 1 << (argv[0] - 1);
+ iconOrderVar = (iconOrderVar << 5) + argv[0];
+ }
+
+ // Check if the puzzle is complete now and assign 1 to jrbook if the puzzle is complete.
+ if (iconOrderVar == _vm->_vars["jiconcorrectorder"])
+ _vm->_vars["jrbook"] = 1;
+}
+
+void JSpit::xjtunnel103_pictfix(uint16 argc, uint16 *argv) {
+ // Get the jicons variable which contains which of the stones are depressed in the rebel tunnel puzzle
+ uint32 iconsDepressed = _vm->_vars["jicons"];
+
+ // Now, draw which icons are depressed based on the bits of the variable
+ if (iconsDepressed & (1 << 0))
+ _vm->getCard()->drawPicture(2);
+ if (iconsDepressed & (1 << 1))
+ _vm->getCard()->drawPicture(3);
+ if (iconsDepressed & (1 << 2))
+ _vm->getCard()->drawPicture(4);
+ if (iconsDepressed & (1 << 3))
+ _vm->getCard()->drawPicture(5);
+ if (iconsDepressed & (1 << 22))
+ _vm->getCard()->drawPicture(6);
+ if (iconsDepressed & (1 << 23))
+ _vm->getCard()->drawPicture(7);
+ if (iconsDepressed & (1 << 24))
+ _vm->getCard()->drawPicture(8);
+}
+
+void JSpit::xjtunnel104_pictfix(uint16 argc, uint16 *argv) {
+ // Get the jicons variable which contains which of the stones are depressed in the rebel tunnel puzzle
+ uint32 iconsDepressed = _vm->_vars["jicons"];
+
+ // Now, draw which icons are depressed based on the bits of the variable
+ if (iconsDepressed & (1 << 9))
+ _vm->getCard()->drawPicture(2);
+ if (iconsDepressed & (1 << 10))
+ _vm->getCard()->drawPicture(3);
+ if (iconsDepressed & (1 << 11))
+ _vm->getCard()->drawPicture(4);
+ if (iconsDepressed & (1 << 12))
+ _vm->getCard()->drawPicture(5);
+ if (iconsDepressed & (1 << 13))
+ _vm->getCard()->drawPicture(6);
+ if (iconsDepressed & (1 << 14))
+ _vm->getCard()->drawPicture(7);
+ if (iconsDepressed & (1 << 15))
+ _vm->getCard()->drawPicture(8);
+ if (iconsDepressed & (1 << 16))
+ _vm->getCard()->drawPicture(9);
+}
+
+void JSpit::xjtunnel105_pictfix(uint16 argc, uint16 *argv) {
+ // Get the jicons variable which contains which of the stones are depressed in the rebel tunnel puzzle
+ uint32 iconsDepressed = _vm->_vars["jicons"];
+
+ // Now, draw which icons are depressed based on the bits of the variable
+ if (iconsDepressed & (1 << 3))
+ _vm->getCard()->drawPicture(2);
+ if (iconsDepressed & (1 << 4))
+ _vm->getCard()->drawPicture(3);
+ if (iconsDepressed & (1 << 5))
+ _vm->getCard()->drawPicture(4);
+ if (iconsDepressed & (1 << 6))
+ _vm->getCard()->drawPicture(5);
+ if (iconsDepressed & (1 << 7))
+ _vm->getCard()->drawPicture(6);
+ if (iconsDepressed & (1 << 8))
+ _vm->getCard()->drawPicture(7);
+ if (iconsDepressed & (1 << 9))
+ _vm->getCard()->drawPicture(8);
+}
+
+void JSpit::xjtunnel106_pictfix(uint16 argc, uint16 *argv) {
+ // Get the jicons variable which contains which of the stones are depressed in the rebel tunnel puzzle
+ uint32 iconsDepressed = _vm->_vars["jicons"];
+
+ // Now, draw which icons are depressed based on the bits of the variable
+ if (iconsDepressed & (1 << 16))
+ _vm->getCard()->drawPicture(2);
+ if (iconsDepressed & (1 << 17))
+ _vm->getCard()->drawPicture(3);
+ if (iconsDepressed & (1 << 18))
+ _vm->getCard()->drawPicture(4);
+ if (iconsDepressed & (1 << 19))
+ _vm->getCard()->drawPicture(5);
+ if (iconsDepressed & (1 << 20))
+ _vm->getCard()->drawPicture(6);
+ if (iconsDepressed & (1 << 21))
+ _vm->getCard()->drawPicture(7);
+ if (iconsDepressed & (1 << 22))
+ _vm->getCard()->drawPicture(8);
+ if (iconsDepressed & (1 << 23))
+ _vm->getCard()->drawPicture(9);
+}
+
+void JSpit::xvga1300_carriage(uint16 argc, uint16 *argv) {
+ // Run the gallows's carriage
+
+ _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
+ _vm->_system->updateScreen(); // Update
+ _vm->_video->playMovieBlockingRiven(1); // Play handle movie
+ _vm->_gfx->scheduleTransition(15); // Set pan down transition
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x18e77)); // Change to card facing up
+ _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor (again)
+ _vm->_system->updateScreen(); // Update
+ _vm->_video->playMovieBlockingRiven(4); // Play carriage beginning to drop
+ _vm->_gfx->scheduleTransition(14); // Set pan up transition
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x183a9)); // Change to card looking straight again
+ _vm->_video->playMovieBlockingRiven(2);
+
+ if (_vm->_vars["jgallows"] == 1) {
+ // If the gallows is open, play the up movie and return
+ _vm->_video->playMovieBlockingRiven(3);
+ return;
+ }
+
+ // Give the player 5 seconds to click (anywhere)
+ uint32 startTime = _vm->_system->getMillis();
+ bool gotClick = false;
+ while (_vm->_system->getMillis() - startTime <= 5000 && !gotClick) {
+ Common::Event event;
+ while (_vm->_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ _vm->_system->updateScreen();
+ break;
+ case Common::EVENT_LBUTTONUP:
+ gotClick = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ _vm->_system->delayMillis(10);
+ }
+
+ _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
+ _vm->_system->updateScreen(); // Update
+
+ if (gotClick) {
+ _vm->_gfx->scheduleTransition(16); // Schedule dissolve transition
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x18d4d)); // Move forward
+ _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
+ _vm->_system->updateScreen(); // Update
+ _vm->_system->delayMillis(500); // Delay a half second before changing again
+ _vm->_gfx->scheduleTransition(12); // Schedule pan left transition
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x18ab5)); // Turn right
+ _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor
+ _vm->_system->updateScreen(); // Update
+ _vm->_video->playMovieBlockingRiven(1); // Play carriage ride movie
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x17167)); // We have arrived at the top
+ } else
+ _vm->_video->playMovieBlockingRiven(3); // Too slow!
+}
+
+void JSpit::xjdome25_resetsliders(uint16 argc, uint16 *argv) {
+ resetDomeSliders(81, 10);
+}
+
+void JSpit::xjdome25_slidermd(uint16 argc, uint16 *argv) {
+ dragDomeSlider(81, 10);
+}
+
+void JSpit::xjdome25_slidermw(uint16 argc, uint16 *argv) {
+ checkSliderCursorChange(10);
+}
+
+void JSpit::xjscpbtn(uint16 argc, uint16 *argv) {
+ runDomeButtonMovie();
+}
+
+void JSpit::xjisland3500_domecheck(uint16 argc, uint16 *argv) {
+ runDomeCheck();
+}
+
+int JSpit::jspitElevatorLoop() {
+ Common::Point startPos = _vm->_system->getEventManager()->getMousePos();
+
+ Common::Event event;
+ int changeLevel = 0;
+
+ _vm->_cursor->setCursor(kRivenClosedHandCursor);
+ _vm->_system->updateScreen();
+
+ for (;;) {
+ while (_vm->_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ if (event.mouse.y > (startPos.y + 10)) {
+ changeLevel = -1;
+ } else if (event.mouse.y < (startPos.y - 10)) {
+ changeLevel = 1;
+ } else {
+ changeLevel = 0;
+ }
+ _vm->_system->updateScreen();
+ break;
+ case Common::EVENT_LBUTTONUP:
+ _vm->_cursor->setCursor(kRivenMainCursor);
+ _vm->_system->updateScreen();
+ return changeLevel;
+ default:
+ break;
+ }
+ }
+ _vm->_system->delayMillis(10);
+ }
+}
+
+void JSpit::xhandlecontrolup(uint16 argc, uint16 *argv) {
+ int changeLevel = jspitElevatorLoop();
+
+ // If we've moved the handle down, go down a floor
+ if (changeLevel == -1) {
+ _vm->_video->playMovieBlockingRiven(1);
+ _vm->_video->playMovieBlockingRiven(2);
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e374));
+ }
+}
+
+void JSpit::xhandlecontroldown(uint16 argc, uint16 *argv) {
+ int changeLevel = jspitElevatorLoop();
+
+ // If we've moved the handle up, go up a floor
+ if (changeLevel == 1) {
+ _vm->_video->playMovieBlockingRiven(1);
+ _vm->_video->playMovieBlockingRiven(2);
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e374));
+ }
+}
+
+void JSpit::xhandlecontrolmid(uint16 argc, uint16 *argv) {
+ int changeLevel = jspitElevatorLoop();
+
+ if (changeLevel == 0)
+ return;
+
+ // Play the handle moving video
+ if (changeLevel == 1)
+ _vm->_video->playMovieBlockingRiven(7);
+ else
+ _vm->_video->playMovieBlockingRiven(6);
+
+ // If the whark's mouth is open, close it
+ uint32 &mouthVar = _vm->_vars["jwmouth"];
+ if (mouthVar == 1) {
+ _vm->_video->playMovieBlockingRiven(3);
+ _vm->_video->playMovieBlockingRiven(8);
+ mouthVar = 0;
+ }
+
+ // Play the elevator video and then change the card
+ if (changeLevel == 1) {
+ _vm->_video->playMovieBlockingRiven(5);
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e597));
+ } else {
+ _vm->_video->playMovieBlockingRiven(4);
+ _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e29c));
+ }
+}
+
+void JSpit::xjplaybeetle_550(uint16 argc, uint16 *argv) {
+ // Play a beetle animation 25% of the time
+ _vm->_vars["jplaybeetle"] = (_vm->_rnd->getRandomNumberRng(0, 3) == 0) ? 1 : 0;
+}
+
+void JSpit::xjplaybeetle_600(uint16 argc, uint16 *argv) {
+ // Play a beetle animation 25% of the time
+ _vm->_vars["jplaybeetle"] = (_vm->_rnd->getRandomNumberRng(0, 3) == 0) ? 1 : 0;
+}
+
+void JSpit::xjplaybeetle_950(uint16 argc, uint16 *argv) {
+ // Play a beetle animation 25% of the time
+ _vm->_vars["jplaybeetle"] = (_vm->_rnd->getRandomNumberRng(0, 3) == 0) ? 1 : 0;
+}
+
+void JSpit::xjplaybeetle_1050(uint16 argc, uint16 *argv) {
+ // Play a beetle animation 25% of the time
+ _vm->_vars["jplaybeetle"] = (_vm->_rnd->getRandomNumberRng(0, 3) == 0) ? 1 : 0;
+}
+
+void JSpit::xjplaybeetle_1450(uint16 argc, uint16 *argv) {
+ // Play a beetle animation 25% of the time as long as the girl is not present
+ _vm->_vars["jplaybeetle"] = (_vm->_rnd->getRandomNumberRng(0, 3) == 0 && _vm->_vars["jgirl"] != 1) ? 1 : 0;
+}
+
+void JSpit::xjlagoon700_alert(uint16 argc, uint16 *argv) {
+ // Handle sunner reactions (mid-staircase)
+
+ if (_vm->_vars["jsunners"] == 0)
+ _vm->_video->playMovieRiven(1);
+}
+
+void JSpit::xjlagoon800_alert(uint16 argc, uint16 *argv) {
+ // Handle sunner reactions (lower-staircase)
+
+ uint32 &sunners = _vm->_vars["jsunners"];
+
+ if (sunners == 0) {
+ // Show the sunners alert video
+ _vm->_video->playMovieRiven(1);
+ } else if (sunners == 1) {
+ // Show the sunners leaving if you moved forward in their "alert" status
+ _vm->_video->playMovieBlockingRiven(2);
+ _vm->_video->playMovieBlockingRiven(6);
+ sunners = 2;
+ _vm->refreshCard();
+ }
+}
+
+void JSpit::xjlagoon1500_alert(uint16 argc, uint16 *argv) {
+ // Handle sunner reactions (beach)
+
+ uint32 &sunners = _vm->_vars["jsunners"];
+
+ if (sunners == 0) {
+ // Show the sunners alert video
+ _vm->_video->playMovieBlockingRiven(3);
+ } else if (sunners == 1) {
+ // Show the sunners leaving if you moved forward in their "alert" status
+ _vm->_video->playMovieBlockingRiven(2);
+ sunners = 2;
+ _vm->refreshCard();
+ }
+}
+
+void JSpit::xjschool280_resetleft(uint16 argc, uint16 *argv) {
+ // Dummy function. This resets the unneeded video timing variable (dropLeftStart) in
+ // the DVD version.
+}
+
+void JSpit::xjschool280_resetright(uint16 argc, uint16 *argv) {
+ // Dummy function. This resets the unneeded video timing variable (dropRightStart) in
+ // the DVD version.
+}
+
+void JSpit::redrawWharkNumberPuzzle(uint16 overlay, uint16 number) {
+ // Update the screen for the whark number puzzle
+ // We don't update the whole screen here because we don't want to overwrite the video data
+ _vm->getCard()->drawPicture(overlay);
+ _vm->getCard()->drawPicture(number + 1);
+ _vm->_gfx->updateScreen(Common::Rect(80, 212, 477, 392));
+ _vm->_system->updateScreen();
+}
+
+void JSpit::xschool280_playwhark(uint16 argc, uint16 *argv) {
+ // The "monstrous" whark puzzle that teaches the number system
+
+ uint32 *posVar;
+ uint16 spinMLST, overlayPLST, doomMLST, snackMLST;
+
+ // Choose left or right based on jwharkpos (which is set by the scripts)
+ if (_vm->_vars["jwharkpos"] == 1) {
+ posVar = &_vm->_vars["jleftpos"];
+ spinMLST = 1;
+ overlayPLST = 12;
+ doomMLST = 3;
+ snackMLST = 4;
+ } else {
+ posVar = &_vm->_vars["jrightpos"];
+ spinMLST = 2;
+ overlayPLST = 13;
+ doomMLST = 5;
+ snackMLST = 6;
+ }
+
+ // Hide the cursor
+ _vm->_cursor->setCursor(kRivenHideCursor);
+ _vm->_system->updateScreen();
+
+ // Play the spin movie
+ _vm->_video->playMovieBlockingRiven(spinMLST);
+
+ // Get our random number and redraw the area
+ uint16 number = _vm->_rnd->getRandomNumberRng(1, 10);
+ redrawWharkNumberPuzzle(overlayPLST, number);
+
+ // Handle movement
+ // (11560/600)s is the length of each of the two movies. We divide it into 19 parts
+ // (one for each of the possible positions the villager can have).
+ VideoEntryPtr handle = _vm->_video->playMovieRiven(doomMLST);
+ Audio::Timestamp startTime = Audio::Timestamp(0, (11560 / 19) * (*posVar), 600);
+ *posVar += number; // Adjust to the end
+ Audio::Timestamp endTime = Audio::Timestamp(0, (11560 / 19) * (*posVar), 600);
+ handle->setBounds(startTime, endTime);
+ _vm->_video->waitUntilMovieEnds(handle);
+
+ if (*posVar > 19) {
+ // The villager has died :(
+ _vm->_video->playMovieBlockingRiven(snackMLST);
+ redrawWharkNumberPuzzle(overlayPLST, number);
+ *posVar = 0;
+ }
+
+ // Enable the correct hotspots for the movement now
+ RivenHotspot *rotateLeft = _vm->getCard()->getHotspotByName("rotateLeft");
+ RivenHotspot *rotateRight = _vm->getCard()->getHotspotByName("rotateRight");
+ rotateLeft->enable(!rotateLeft->isEnabled());
+ rotateRight->enable(!rotateRight->isEnabled());
+
+ // Update the cursor
+ _vm->updateCurrentHotspot();
+}
+
+void JSpit::xjatboundary(uint16 argc, uint16 *argv) {
+ runDemoBoundaryDialog();
}
} // End of namespace RivenStacks