diff options
Diffstat (limited to 'engines/mohawk/riven_stacks/jspit.cpp')
-rw-r--r-- | engines/mohawk/riven_stacks/jspit.cpp | 503 |
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 |