aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/riven_stacks/domespit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk/riven_stacks/domespit.cpp')
-rw-r--r--engines/mohawk/riven_stacks/domespit.cpp201
1 files changed, 201 insertions, 0 deletions
diff --git a/engines/mohawk/riven_stacks/domespit.cpp b/engines/mohawk/riven_stacks/domespit.cpp
index 4674a24d2f..71a82ab343 100644
--- a/engines/mohawk/riven_stacks/domespit.cpp
+++ b/engines/mohawk/riven_stacks/domespit.cpp
@@ -22,12 +22,213 @@
#include "mohawk/riven_stacks/domespit.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 {
+static const uint32 kDomeSliderDefaultState = 0x01F00000;
+static const uint32 kDomeSliderSlotCount = 25;
+
DomeSpit::DomeSpit(MohawkEngine_Riven *vm, uint16 id) :
RivenStack(vm, id) {
+ _sliderState = kDomeSliderDefaultState;
+}
+
+void DomeSpit::runDomeButtonMovie() {
+ // This command just plays the video of the button moving down and up.
+ _vm->_video->playMovieBlockingRiven(2);
+}
+
+void DomeSpit::runDomeCheck() {
+ // Check if we clicked while the golden frame was showing
+
+ VideoEntryPtr video = _vm->_video->findVideoRiven(1);
+ assert(video);
+
+ int32 curFrame = video->getCurFrame();
+ int32 frameCount = video->getFrameCount();
+
+ // The final frame of the video is the 'golden' frame (double meaning: the
+ // frame that is the magic one is the one with the golden symbol) but we
+ // give a 3 frame leeway in either direction.
+ if (frameCount - curFrame < 3 || curFrame < 3)
+ _vm->_vars["domecheck"] = 1;
+}
+
+void DomeSpit::resetDomeSliders(uint16 soundId, uint16 startHotspot) {
+ // The rightmost slider should move left until it finds the next slider,
+ // then those two continue until they find the third slider. This continues
+ // until all five sliders have returned their starting slots.
+ byte slidersFound = 0;
+ for (uint32 i = 0; i < kDomeSliderSlotCount; i++) {
+ if (_sliderState & (1 << i)) {
+ // A slider occupies this spot. Increase the number of sliders we
+ // have found, but we're not doing any moving this iteration.
+ slidersFound++;
+ } else {
+ // Move all the sliders we have found over one slot
+ for (byte j = 0; j < slidersFound; j++) {
+ _sliderState &= ~(1 << (i - j - 1));
+ _sliderState |= 1 << (i - j);
+ }
+
+ // If we have at least one found slider, it has now moved
+ // so we should redraw and play a tick sound
+ if (slidersFound) {
+ _vm->_sound->playSound(soundId);
+ drawDomeSliders(startHotspot);
+ _vm->_system->delayMillis(100);
+ }
+ }
+ }
+
+ // Sanity checks - the slider count should always be 5 and we should end up at
+ // the default state after moving them all over.
+ assert(slidersFound == 5);
+ assert(_sliderState == kDomeSliderDefaultState);
+}
+
+void DomeSpit::checkDomeSliders() {
+ RivenHotspot *resetSlidersHotspot = _vm->getCard()->getHotspotByName("ResetSliders");
+ RivenHotspot *openDomeHotspot = _vm->getCard()->getHotspotByName("OpenDome");
+
+ // Let's see if we're all matched up...
+ if (_vm->_vars["adomecombo"] == _sliderState) {
+ // Set the button hotspot to the open dome hotspot
+ resetSlidersHotspot->enable(false);
+ openDomeHotspot->enable(true);
+ } else {
+ // Set the button hotspot to the reset sliders hotspot
+ resetSlidersHotspot->enable(true);
+ openDomeHotspot->enable(false);
+ }
+}
+
+void DomeSpit::checkSliderCursorChange(uint16 startHotspot) {
+ // Set the cursor based on _sliderState and what hotspot we're over
+ for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
+ RivenHotspot *hotspot = _vm->getCard()->getHotspotByBlstId(startHotspot + i);
+ if (hotspot->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
+ if (_sliderState & (1 << (24 - i)))
+ _vm->_cursor->setCursor(kRivenOpenHandCursor);
+ else
+ _vm->_cursor->setCursor(kRivenMainCursor);
+ _vm->_system->updateScreen();
+ break;
+ }
+ }
+}
+
+void DomeSpit::dragDomeSlider(uint16 soundId, uint16 startHotspot) {
+ int16 foundSlider = -1;
+
+ for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
+ RivenHotspot *hotspot = _vm->getCard()->getHotspotByBlstId(startHotspot + i);
+ if (hotspot->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
+ // If the slider is not at this hotspot, we can't do anything else
+ if (!(_sliderState & (1 << (24 - i))))
+ return;
+
+ foundSlider = i;
+ break;
+ }
+ }
+
+ // We're not over any slider
+ if (foundSlider < 0)
+ return;
+
+ // We've clicked down, so show the closed hand cursor
+ _vm->_cursor->setCursor(kRivenClosedHandCursor);
+ _vm->_system->updateScreen();
+
+ bool done = false;
+ while (!done) {
+ Common::Event event;
+ while (_vm->_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ if (foundSlider < 24 && !(_sliderState & (1 << (23 - foundSlider)))) {
+ RivenHotspot *nextHotspot = _vm->getCard()->getHotspotByBlstId(startHotspot + foundSlider + 1);
+ if (nextHotspot->containsPoint(event.mouse)) {
+ // We've moved the slider right one space
+ _sliderState &= ~(_sliderState & (1 << (24 - foundSlider)));
+ foundSlider++;
+ _sliderState |= 1 << (24 - foundSlider);
+
+ // Now play a click sound and redraw
+ _vm->_sound->playSound(soundId);
+ drawDomeSliders(startHotspot);
+ }
+ } else if (foundSlider > 0 && !(_sliderState & (1 << (25 - foundSlider)))) {
+ RivenHotspot *previousHotspot = _vm->getCard()->getHotspotByBlstId(startHotspot + foundSlider - 1);
+ if (previousHotspot->containsPoint(event.mouse)) {
+ // We've moved the slider left one space
+ _sliderState &= ~(_sliderState & (1 << (24 - foundSlider)));
+ foundSlider--;
+ _sliderState |= 1 << (24 - foundSlider);
+
+ // Now play a click sound and redraw
+ _vm->_sound->playSound(soundId);
+ drawDomeSliders(startHotspot);
+ }
+ } else
+ _vm->_system->updateScreen(); // A normal update for the cursor
+ break;
+ case Common::EVENT_LBUTTONUP:
+ done = true;
+ break;
+ default:
+ break;
+ }
+ }
+ _vm->_system->delayMillis(10);
+ }
+
+ // Check to see if we have the right combination
+ checkDomeSliders();
+}
+
+void DomeSpit::drawDomeSliders(uint16 startHotspot) {
+ Common::Rect dstAreaRect = Common::Rect(200, 250, 420, 319);
+
+ // On pspit, the rect is different by two pixels
+ // (alternatively, we could just use hotspot 3 here, but only on pspit is there a hotspot for this)
+ if (_vm->getStack()->getId() == kStackPspit)
+ dstAreaRect.translate(-2, 0);
+
+ // Find out bitmap id
+ uint16 bitmapId = _vm->findResourceID(ID_TBMP, "*sliders*");
+
+ for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
+ RivenHotspot *hotspot = _vm->getCard()->getHotspotByBlstId(startHotspot + i);
+
+ Common::Rect srcRect = hotspot->getRect();
+ srcRect.translate(-dstAreaRect.left, -dstAreaRect.top); // Adjust the rect so it's in the destination area
+
+ Common::Rect dstRect = hotspot->getRect();
+
+ if (_sliderState & (1 << (24 - i)))
+ _vm->_gfx->drawImageRect(bitmapId, srcRect, dstRect);
+ else
+ _vm->_gfx->drawImageRect(bitmapId + 1, srcRect, dstRect);
+ }
+
+ _vm->_gfx->updateScreen();
+}
+
+void DomeSpit::setDomeSliderState(uint32 sliderState) {
+ _sliderState = sliderState;
+}
+uint32 DomeSpit::getDomeSliderState() const {
+ return _sliderState;
}
} // End of namespace RivenStacks