2016-11-01 09:45:33 +01:00
|
|
|
/* 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 "mohawk/riven_stacks/domespit.h"
|
|
|
|
|
2016-11-01 19:19:26 +01:00
|
|
|
#include "mohawk/cursors.h"
|
|
|
|
#include "mohawk/riven.h"
|
|
|
|
#include "mohawk/riven_card.h"
|
|
|
|
#include "mohawk/riven_graphics.h"
|
2017-02-20 18:02:57 +01:00
|
|
|
#include "mohawk/riven_video.h"
|
2016-11-01 19:19:26 +01:00
|
|
|
|
2016-11-01 09:45:33 +01:00
|
|
|
namespace Mohawk {
|
|
|
|
namespace RivenStacks {
|
|
|
|
|
2016-11-01 19:19:26 +01:00
|
|
|
static const uint32 kDomeSliderDefaultState = 0x01F00000;
|
|
|
|
static const uint32 kDomeSliderSlotCount = 25;
|
|
|
|
|
2017-02-04 15:25:37 +01:00
|
|
|
DomeSpit::DomeSpit(MohawkEngine_Riven *vm, uint16 id, const char *sliderBmpName, const char *sliderBgBmpName) :
|
|
|
|
RivenStack(vm, id),
|
|
|
|
_sliderBmpName(sliderBmpName),
|
|
|
|
_sliderBgBmpName(sliderBgBmpName) {
|
2016-11-01 19:19:26 +01:00
|
|
|
_sliderState = kDomeSliderDefaultState;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DomeSpit::runDomeButtonMovie() {
|
|
|
|
// This command just plays the video of the button moving down and up.
|
2017-02-20 18:02:57 +01:00
|
|
|
// The original displayed images of the button going down
|
|
|
|
RivenVideo *video = _vm->_video->openSlot(2);
|
|
|
|
video->playBlocking();
|
2016-11-01 19:19:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DomeSpit::runDomeCheck() {
|
|
|
|
// Check if we clicked while the golden frame was showing
|
|
|
|
|
2017-02-20 18:02:57 +01:00
|
|
|
const RivenVideo *video = _vm->_video->getSlot(1);
|
2016-11-01 19:19:26 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-06-25 11:41:32 +02:00
|
|
|
void DomeSpit::resetDomeSliders(uint16 startHotspot) {
|
2016-11-01 19:19:26 +01:00
|
|
|
// 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) {
|
2017-06-25 11:41:32 +02:00
|
|
|
_vm->_sound->playCardSound("aBigTic");
|
2016-11-01 19:19:26 +01:00
|
|
|
drawDomeSliders(startHotspot);
|
2017-06-25 11:41:32 +02:00
|
|
|
_vm->delay(20);
|
2016-11-01 19:19:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2017-06-25 11:41:32 +02:00
|
|
|
int16 sliderSlot = getSliderSlotAtPos(startHotspot, getMousePosition());
|
|
|
|
|
|
|
|
if (sliderSlot >= 0 && isSliderAtSlot(sliderSlot)) {
|
|
|
|
_vm->_cursor->setCursor(kRivenOpenHandCursor);
|
|
|
|
} else {
|
|
|
|
_vm->_cursor->setCursor(kRivenMainCursor);
|
2016-11-01 19:19:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-25 11:41:32 +02:00
|
|
|
int16 DomeSpit::getSliderSlotAtPos(uint16 startHotspot, const Common::Point &pos) const {
|
2016-11-01 19:19:26 +01:00
|
|
|
for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
|
|
|
|
RivenHotspot *hotspot = _vm->getCard()->getHotspotByBlstId(startHotspot + i);
|
2017-06-25 11:41:32 +02:00
|
|
|
if (hotspot->containsPoint(pos)) {
|
|
|
|
return i;
|
2016-11-01 19:19:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-25 11:41:32 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DomeSpit::isSliderAtSlot(int16 slot) const {
|
|
|
|
return _sliderState & (1 << (24 - slot));
|
|
|
|
}
|
|
|
|
|
|
|
|
void DomeSpit::dragDomeSlider(uint16 startHotspot) {
|
|
|
|
int16 draggedSliderSlot = getSliderSlotAtPos(startHotspot, getMousePosition());
|
|
|
|
|
2016-11-01 19:19:26 +01:00
|
|
|
// We're not over any slider
|
2017-06-25 11:41:32 +02:00
|
|
|
if (draggedSliderSlot < 0 || !isSliderAtSlot(draggedSliderSlot)) {
|
2016-11-01 19:19:26 +01:00
|
|
|
return;
|
2017-06-25 11:41:32 +02:00
|
|
|
}
|
2016-11-01 19:19:26 +01:00
|
|
|
|
|
|
|
// We've clicked down, so show the closed hand cursor
|
|
|
|
_vm->_cursor->setCursor(kRivenClosedHandCursor);
|
2017-06-25 11:41:32 +02:00
|
|
|
|
|
|
|
while (mouseIsDown() && !_vm->shouldQuit()) {
|
|
|
|
int16 hoveredHotspot = getSliderSlotAtPos(startHotspot, getMousePosition());
|
|
|
|
if (hoveredHotspot >= 0) {
|
|
|
|
if (hoveredHotspot > draggedSliderSlot && draggedSliderSlot < 24 && !isSliderAtSlot(draggedSliderSlot + 1)) {
|
|
|
|
// We've moved the slider right one space
|
|
|
|
_sliderState &= ~(_sliderState & (1 << (24 - draggedSliderSlot)));
|
|
|
|
draggedSliderSlot++;
|
|
|
|
_sliderState |= 1 << (24 - draggedSliderSlot);
|
|
|
|
|
|
|
|
// Now play a click sound and redraw
|
|
|
|
_vm->_sound->playCardSound("aBigTic");
|
|
|
|
drawDomeSliders(startHotspot);
|
|
|
|
}
|
|
|
|
if (hoveredHotspot < draggedSliderSlot && draggedSliderSlot > 0 && !isSliderAtSlot(draggedSliderSlot - 1)) {
|
|
|
|
// We've moved the slider left one space
|
|
|
|
_sliderState &= ~(_sliderState & (1 << (24 - draggedSliderSlot)));
|
|
|
|
draggedSliderSlot--;
|
|
|
|
_sliderState |= 1 << (24 - draggedSliderSlot);
|
|
|
|
|
|
|
|
// Now play a click sound and redraw
|
|
|
|
_vm->_sound->playCardSound("aBigTic");
|
|
|
|
drawDomeSliders(startHotspot);
|
2016-11-01 19:19:26 +01:00
|
|
|
}
|
|
|
|
}
|
2017-06-25 11:41:32 +02:00
|
|
|
|
|
|
|
_vm->doFrame();
|
2016-11-01 19:19:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2017-02-04 15:25:37 +01:00
|
|
|
uint16 bitmapId = _vm->findResourceID(ID_TBMP, buildCardResourceName(_sliderBmpName));
|
|
|
|
uint16 bgBitmapId = _vm->findResourceID(ID_TBMP, buildCardResourceName(_sliderBgBmpName));
|
2016-11-01 19:19:26 +01:00
|
|
|
|
|
|
|
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
|
2017-02-04 15:25:37 +01:00
|
|
|
_vm->_gfx->drawImageRect(bgBitmapId, srcRect, dstRect);
|
2016-11-01 19:19:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
_vm->_gfx->updateScreen();
|
|
|
|
}
|
|
|
|
|
2017-02-04 15:25:37 +01:00
|
|
|
Common::String DomeSpit::buildCardResourceName(const Common::String &name) const {
|
|
|
|
return Common::String::format("%d_%s", _vm->getCard()->getId(), name.c_str());
|
|
|
|
}
|
|
|
|
|
2016-11-01 19:19:26 +01:00
|
|
|
void DomeSpit::setDomeSliderState(uint32 sliderState) {
|
|
|
|
_sliderState = sliderState;
|
|
|
|
}
|
2016-11-01 09:45:33 +01:00
|
|
|
|
2016-11-01 19:19:26 +01:00
|
|
|
uint32 DomeSpit::getDomeSliderState() const {
|
|
|
|
return _sliderState;
|
2016-11-01 09:45:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
} // End of namespace RivenStacks
|
|
|
|
} // End of namespace Mohawk
|