aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Bouclet2016-08-06 06:41:04 +0200
committerEugene Sandulenko2017-07-03 08:50:10 +0200
commit099b3b3d8ff4729b5556f07f0e4476555ce7659c (patch)
tree69e68b5ae072a8956bb9b51fcb36952703cc2138
parent67d9a3c71bb2c201fc4c43f159025fc6ea4517e7 (diff)
downloadscummvm-rg350-099b3b3d8ff4729b5556f07f0e4476555ce7659c.tar.gz
scummvm-rg350-099b3b3d8ff4729b5556f07f0e4476555ce7659c.tar.bz2
scummvm-rg350-099b3b3d8ff4729b5556f07f0e4476555ce7659c.zip
MOHAWK: Move the hotspot list to RivenCard
Also replace all hardcoded accesses to the hotspot array with hotspot queries.
-rw-r--r--engines/mohawk/console.cpp8
-rw-r--r--engines/mohawk/riven.cpp110
-rw-r--r--engines/mohawk/riven.h5
-rw-r--r--engines/mohawk/riven_card.cpp77
-rw-r--r--engines/mohawk/riven_card.h29
-rw-r--r--engines/mohawk/riven_external.cpp230
-rw-r--r--engines/mohawk/riven_external.h4
-rw-r--r--engines/mohawk/riven_scripts.cpp26
8 files changed, 313 insertions, 176 deletions
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 4be76930c5..41dd535c3a 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -510,10 +510,12 @@ bool RivenConsole::Cmd_ChangeStack(int argc, const char **argv) {
}
bool RivenConsole::Cmd_Hotspots(int argc, const char **argv) {
- debugPrintf("Current card (%d) has %d hotspots:\n", _vm->getCurCard()->getId(), _vm->_hotspots.size());
+ Common::Array<RivenHotspot *> hotspots = _vm->_card->getHotspots();
- for (uint16 i = 0; i < _vm->_hotspots.size(); i++) {
- RivenHotspot *hotspot = _vm->_hotspots[i];
+ debugPrintf("Current card (%d) has %d hotspots:\n", _vm->getCurCard()->getId(), hotspots.size());
+
+ for (uint16 i = 0; i < hotspots.size(); i++) {
+ RivenHotspot *hotspot = hotspots[i];
debugPrintf("Hotspot %d, index %d, BLST ID %d (", i, hotspot->getIndex(), hotspot->getBlstId());
if (hotspot->isEnabled())
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index d09ecfd3fa..8e30080972 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -103,9 +103,6 @@ MohawkEngine_Riven::~MohawkEngine_Riven() {
delete _scriptMan;
delete _optionsDialog;
delete _rnd;
- for (uint i = 0; i < _hotspots.size(); i++) {
- delete _hotspots[i];
- }
delete g_atrusJournalRect1;
delete g_atrusJournalRect2;
delete g_cathJournalRect2;
@@ -257,8 +254,7 @@ void MohawkEngine_Riven::handleEvents() {
case Common::KEYCODE_F4:
_showHotspots = !_showHotspots;
if (_showHotspots) {
- for (uint16 i = 0; i < _hotspots.size(); i++)
- _gfx->drawRect(_hotspots[i]->getRect(), _hotspots[i]->isEnabled());
+ _card->drawHotspotRects();
needsUpdate = true;
} else
refreshCard();
@@ -267,7 +263,7 @@ void MohawkEngine_Riven::handleEvents() {
runDialog(*_optionsDialog);
if (_optionsDialog->getLoadSlot() >= 0)
loadGameState(_optionsDialog->getLoadSlot());
- updateZipMode();
+ _card->initializeZipMode();
break;
case Common::KEYCODE_r:
// Return to the main menu in the demo on ctrl+r
@@ -406,16 +402,13 @@ void MohawkEngine_Riven::refreshCard() {
// Clear any timer still floating around
removeTimer();
- loadHotspots(_card->getId());
-
_gfx->clearWaterEffects();
_video->stopVideos();
_card->open();
if (_showHotspots)
- for (uint16 i = 0; i < _hotspots.size(); i++)
- _gfx->drawRect(_hotspots[i]->getRect(), _hotspots[i]->isEnabled());
+ _card->drawHotspotRects();
// Now we need to redraw the cursor if necessary and handle mouse over scripts
updateCurrentHotspot();
@@ -424,55 +417,9 @@ void MohawkEngine_Riven::refreshCard() {
installCardTimer();
}
-void MohawkEngine_Riven::loadHotspots(uint16 id) {
- for (uint i = 0; i < _hotspots.size(); i++) {
- delete _hotspots[i];
- }
-
- Common::SeekableReadStream *inStream = getResource(ID_HSPT, id);
-
- uint16 hotspotCount = inStream->readUint16BE();
- _hotspots.resize(hotspotCount);
-
- for (uint16 i = 0; i < hotspotCount; i++) {
- _hotspots[i] = new RivenHotspot(this, inStream);
- }
-
- delete inStream;
- updateZipMode();
-}
-
-void MohawkEngine_Riven::updateZipMode() {
- // Check if a zip mode hotspot is enabled by checking the name/id against the ZIPS records.
-
- for (uint32 i = 0; i < _hotspots.size(); i++) {
- if (_hotspots[i]->isZip()) {
- if (_vars["azip"] != 0) {
- // Check if a zip mode hotspot is enabled by checking the name/id against the ZIPS records.
- Common::String hotspotName = _hotspots[i]->getName();
-
- bool foundMatch = false;
-
- if (!hotspotName.empty())
- for (uint16 j = 0; j < _zipModeData.size(); j++)
- if (_zipModeData[j].name == hotspotName) {
- foundMatch = true;
- break;
- }
-
- _hotspots[i]->enable(foundMatch);
- } else // Disable the hotspot if zip mode is disabled
- _hotspots[i]->enable(false);
- }
- }
-}
-
void MohawkEngine_Riven::checkHotspotChange() {
- RivenHotspot *hotspot = nullptr;
- for (uint16 i = 0; i < _hotspots.size(); i++)
- if (_hotspots[i]->isEnabled() && _hotspots[i]->containsPoint(_eventMan->getMousePos())) {
- hotspot = _hotspots[i];
- }
+ Common::Point mousePos = _eventMan->getMousePos();
+ RivenHotspot *hotspot = _card->getHotspotContainingPoint(mousePos);
if (hotspot) {
if (_curHotspot != hotspot) {
@@ -596,6 +543,38 @@ Common::String MohawkEngine_Riven::getName(uint16 nameResource, uint16 nameID) {
return name;
}
+int16 MohawkEngine_Riven::getIdFromName(uint16 nameResource, const Common::String &name) {
+ //TODO: Use proper data structures
+
+ Common::SeekableReadStream *nameStream = getResource(ID_NAME, nameResource);
+ uint16 fieldCount = nameStream->readUint16BE();
+ uint16 *stringOffsets = new uint16[fieldCount];
+
+ for (uint16 i = 0; i < fieldCount; i++)
+ stringOffsets[i] = nameStream->readUint16BE();
+ for (uint16 i = 0; i < fieldCount; i++)
+ nameStream->readUint16BE(); // Skip unknown values
+
+ for (uint16 i = 0; i < fieldCount; i++) {
+ nameStream->seek(stringOffsets[i], SEEK_CUR);
+
+ Common::String readName;
+ char c = (char)nameStream->readByte();
+ while (c) {
+ readName += c;
+ c = (char)nameStream->readByte();
+ }
+
+ if (readName.equalsIgnoreCase(name)) {
+ return i;
+ }
+ }
+
+ delete nameStream;
+ delete[] stringOffsets;
+ return -1;
+}
+
uint16 MohawkEngine_Riven::matchRMAPToCard(uint32 rmapCode) {
uint16 index = 0;
Common::SeekableReadStream *rmapStream = getResource(ID_RMAP, 1);
@@ -920,7 +899,7 @@ void MohawkEngine_Riven::checkSunnerAlertClick() {
return;
// Only set the sunners variable on the forward hotspot
- if ((rmapCode == 0x79bd && _curHotspot->getIndex() != 2) || (rmapCode == 0x7beb && _curHotspot->getIndex() != 3))
+ if (_curHotspot->getBlstId() != 3)
return;
// If the alert video is no longer playing, we have nothing left to do
@@ -942,6 +921,19 @@ void MohawkEngine_Riven::addZipVisitedCard(uint16 cardId, uint16 cardNameId) {
_zipModeData.push_back(zip);
}
+bool MohawkEngine_Riven::isZipVisitedCard(const Common::String &hotspotName) const {
+ bool foundMatch = false;
+
+ if (!hotspotName.empty())
+ for (uint16 j = 0; j < _zipModeData.size(); j++)
+ if (_zipModeData[j].name == hotspotName) {
+ foundMatch = true;
+ break;
+ }
+
+ return foundMatch;
+}
+
bool ZipMode::operator== (const ZipMode &z) const {
return z.name == name && z.id == id;
}
diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h
index b2e3bf04d3..4cff24eb94 100644
--- a/engines/mohawk/riven.h
+++ b/engines/mohawk/riven.h
@@ -135,10 +135,8 @@ private:
void handleEvents();
// Hotspot related functions and variables
- void loadHotspots(uint16);
void checkInventoryClick();
bool _showHotspots;
- void updateZipMode();
void checkHotspotChange();
// Variables
@@ -159,6 +157,7 @@ public:
void changeToStack(uint16);
void refreshCard();
Common::String getName(uint16 nameResource, uint16 nameID);
+ int16 getIdFromName(uint16 nameResource, const Common::String &name);
Common::String getStackName(uint16 stack) const;
RivenCard *getCurCard() const { return _card; }
uint16 getCurStack() const { return _curStack; }
@@ -166,12 +165,12 @@ public:
uint32 getCurCardRMAP();
// Hotspot functions/variables
- Common::Array<RivenHotspot *> _hotspots;
RivenHotspot *_curHotspot;
Common::Array<ZipMode> _zipModeData;
RivenHotspot *getCurHotspot() const { return _curHotspot; }
void updateCurrentHotspot();
void addZipVisitedCard(uint16 cardId, uint16 cardNameId);
+ bool isZipVisitedCard(const Common::String &hotspotName) const;
// Variables
RivenVariableMap _vars;
diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp
index 4193eea111..b3ec0657a0 100644
--- a/engines/mohawk/riven_card.cpp
+++ b/engines/mohawk/riven_card.cpp
@@ -33,12 +33,15 @@ RivenCard::RivenCard(MohawkEngine_Riven *vm, uint16 id) :
_vm(vm),
_id(id) {
loadCardResource(id);
+ loadHotspots(id);
loadCardPictureList(id);
loadCardSoundList(id);
}
RivenCard::~RivenCard() {
-
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ delete _hotspots[i];
+ }
}
void RivenCard::loadCardResource(uint16 id) {
@@ -69,6 +72,20 @@ void RivenCard::initializeZipMode() {
if (_zipModePlace) {
_vm->addZipVisitedCard(_id, _name);
}
+
+ // Check if a zip mode hotspot is enabled by checking the name/id against the ZIPS records.
+ for (uint32 i = 0; i < _hotspots.size(); i++) {
+ if (_hotspots[i]->isZip()) {
+ if (_vm->_vars["azip"] != 0) {
+ // Check if a zip mode hotspot is enabled by checking the name/id against the ZIPS records.
+ Common::String hotspotName = _hotspots[i]->getName();
+ bool visited = _vm->isZipVisitedCard(hotspotName);
+
+ _hotspots[i]->enable(visited);
+ } else // Disable the hotspot if zip mode is disabled
+ _hotspots[i]->enable(false);
+ }
+ }
}
void RivenCard::runScript(uint16 scriptType) {
@@ -196,6 +213,60 @@ SLSTRecord RivenCard::getSound(uint16 index) const {
error("Could not find sound %d in card %d", index, _id);
}
+void RivenCard::loadHotspots(uint16 id) {
+ Common::SeekableReadStream *inStream = _vm->getResource(ID_HSPT, id);
+
+ uint16 hotspotCount = inStream->readUint16BE();
+ _hotspots.resize(hotspotCount);
+
+ for (uint16 i = 0; i < hotspotCount; i++) {
+ _hotspots[i] = new RivenHotspot(_vm, inStream);
+ }
+
+ delete inStream;
+}
+
+void RivenCard::drawHotspotRects() {
+ for (uint16 i = 0; i < _hotspots.size(); i++)
+ _vm->_gfx->drawRect(_hotspots[i]->getRect(), _hotspots[i]->isEnabled());
+}
+
+RivenHotspot *RivenCard::getHotspotContainingPoint(const Common::Point &point) const {
+ RivenHotspot *hotspot = nullptr;
+ for (uint16 i = 0; i < _hotspots.size(); i++)
+ if (_hotspots[i]->isEnabled() && _hotspots[i]->containsPoint(point)) {
+ hotspot = _hotspots[i];
+ }
+
+ return hotspot;
+}
+
+Common::Array<RivenHotspot *> RivenCard::getHotspots() const {
+ return _hotspots;
+}
+
+RivenHotspot *RivenCard::getHotspotByName(const Common::String &name) const {
+ int16 nameId = _vm->getIdFromName(HotspotNames, name);
+
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ if (_hotspots[i]->getNameId() == nameId) {
+ return _hotspots[i];
+ }
+ }
+
+ error("Card %d does not have an hotspot named %s", _id, name.c_str());
+}
+
+RivenHotspot *RivenCard::getHotspotByBlstId(const uint16 blstId) const {
+ for (uint i = 0; i < _hotspots.size(); i++) {
+ if (_hotspots[i]->getBlstId() == blstId) {
+ return _hotspots[i];
+ }
+ }
+
+ return nullptr;
+}
+
RivenHotspot::RivenHotspot(MohawkEngine_Riven *vm, Common::ReadStream *stream) :
_vm(vm) {
loadFromStream(stream);
@@ -289,4 +360,8 @@ void RivenHotspot::setRect(const Common::Rect &rect) {
_rect = rect;
}
+int16 RivenHotspot::getNameId() const {
+ return _nameResource;
+}
+
} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_card.h b/engines/mohawk/riven_card.h
index e7745fca1e..10b77275ab 100644
--- a/engines/mohawk/riven_card.h
+++ b/engines/mohawk/riven_card.h
@@ -31,6 +31,8 @@
namespace Mohawk {
+class RivenHotspot;
+
/**
* A game view
*
@@ -74,12 +76,30 @@ public:
/** Get the card's sound description with the specified index */
SLSTRecord getSound(uint16 index) const;
+ /** Draw borders for all the hotspots in the card */
+ void drawHotspotRects();
+
+ /** Enable the zip hotspots if they match to already visited locations */
+ void initializeZipMode();
+
+ /** Get the hotspot containing the specified point */
+ RivenHotspot *getHotspotContainingPoint(const Common::Point &point) const;
+
+ /** Get the hotspot with the specified name */
+ RivenHotspot *getHotspotByName(const Common::String &name) const;
+
+ /** Get the hotspot with the specified BLST id */
+ RivenHotspot *getHotspotByBlstId(const uint16 blstId) const;
+
+ /** Get all the hotspots in the card. To be used for debugging features only */
+ Common::Array<RivenHotspot *> getHotspots() const;
+
private:
void loadCardResource(uint16 id);
+ void loadHotspots(uint16 id);
void loadCardPictureList(uint16 id);
void loadCardSoundList(uint16 id);
- void initializeZipMode();
void defaultLoadScript();
MohawkEngine_Riven *_vm;
@@ -90,6 +110,8 @@ private:
uint16 _zipModePlace;
RivenScriptList _scripts;
+ Common::Array<RivenHotspot *> _hotspots;
+
// Resource lists
Common::Array<Picture> _pictureList;
Common::Array<SLSTRecord> _soundList;
@@ -132,7 +154,10 @@ public:
/** Get the hotspot's name from the current stack's name list */
Common::String getName() const;
- /** Get the hotspot's index in the view */
+ /** Get the hotspot's name id */
+ int16 getNameId() const;
+
+ /** Get the hotspot's order in the view */
uint16 getIndex() const;
/** Get the hotspot's enable list id */
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 8c0711840d..88718db1a6 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -312,23 +312,27 @@ void RivenExternal::resetDomeSliders(uint16 soundId, uint16 startHotspot) {
assert(_sliderState == kDomeSliderDefaultState);
}
-void RivenExternal::checkDomeSliders(uint16 resetSlidersHotspot, uint16 openDomeHotspot) {
+void RivenExternal::checkDomeSliders() {
+ RivenHotspot *resetSlidersHotspot = _vm->getCurCard()->getHotspotByName("ResetSliders");
+ RivenHotspot *openDomeHotspot = _vm->getCurCard()->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
- _vm->_hotspots[resetSlidersHotspot]->enable(false);
- _vm->_hotspots[openDomeHotspot]->enable(true);
+ resetSlidersHotspot->enable(false);
+ openDomeHotspot->enable(true);
} else {
// Set the button hotspot to the reset sliders hotspot
- _vm->_hotspots[resetSlidersHotspot]->enable(true);
- _vm->_hotspots[openDomeHotspot]->enable(false);
+ resetSlidersHotspot->enable(true);
+ openDomeHotspot->enable(false);
}
}
void RivenExternal::checkSliderCursorChange(uint16 startHotspot) {
// Set the cursor based on _sliderState and what hotspot we're over
for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
- if (_vm->_hotspots[i + startHotspot]->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
+ RivenHotspot *hotspot = _vm->getCurCard()->getHotspotByBlstId(startHotspot + i);
+ if (hotspot->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
if (_sliderState & (1 << (24 - i)))
_vm->_cursor->setCursor(kRivenOpenHandCursor);
else
@@ -339,11 +343,12 @@ void RivenExternal::checkSliderCursorChange(uint16 startHotspot) {
}
}
-void RivenExternal::dragDomeSlider(uint16 soundId, uint16 resetSlidersHotspot, uint16 openDomeHotspot, uint16 startHotspot) {
+void RivenExternal::dragDomeSlider(uint16 soundId, uint16 startHotspot) {
int16 foundSlider = -1;
for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
- if (_vm->_hotspots[i + startHotspot]->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
+ RivenHotspot *hotspot = _vm->getCurCard()->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;
@@ -367,24 +372,30 @@ void RivenExternal::dragDomeSlider(uint16 soundId, uint16 resetSlidersHotspot, u
while (_vm->_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
- if (foundSlider < 24 && !(_sliderState & (1 << (23 - foundSlider))) && _vm->_hotspots[foundSlider + startHotspot + 1]->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))) && _vm->_hotspots[foundSlider + startHotspot - 1]->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);
+ if (foundSlider < 24 && !(_sliderState & (1 << (23 - foundSlider)))) {
+ RivenHotspot *nextHotspot = _vm->getCurCard()->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->getCurCard()->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;
@@ -399,7 +410,7 @@ void RivenExternal::dragDomeSlider(uint16 soundId, uint16 resetSlidersHotspot, u
}
// Check to see if we have the right combination
- checkDomeSliders(resetSlidersHotspot, openDomeHotspot);
+ checkDomeSliders();
}
void RivenExternal::drawDomeSliders(uint16 startHotspot) {
@@ -414,10 +425,12 @@ void RivenExternal::drawDomeSliders(uint16 startHotspot) {
uint16 bitmapId = _vm->findResourceID(ID_TBMP, "*sliders*");
for (uint16 i = 0; i < kDomeSliderSlotCount; i++) {
- Common::Rect srcRect = _vm->_hotspots[startHotspot + i]->getRect();
+ RivenHotspot *hotspot = _vm->getCurCard()->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 = _vm->_hotspots[startHotspot + i]->getRect();
+ Common::Rect dstRect = hotspot->getRect();
if (_sliderState & (1 << (24 - i)))
_vm->_gfx->drawImageRect(bitmapId, srcRect, dstRect);
@@ -449,14 +462,17 @@ void RivenExternal::xaatrusopenbook(uint16 argc, uint16 *argv) {
uint32 &page = _vm->_vars["aatruspage"];
// Set hotspots depending on the page
+ RivenHotspot *openBook = _vm->_card->getHotspotByName("openBook");
+ RivenHotspot *nextPage = _vm->_card->getHotspotByName("nextpage");
+ RivenHotspot *prevPage = _vm->_card->getHotspotByName("prevpage");
if (page == 1) {
- _vm->_hotspots[1]->enable(false);
- _vm->_hotspots[2]->enable(false);
- _vm->_hotspots[3]->enable(true);
+ prevPage->enable(false);
+ nextPage->enable(false);
+ openBook->enable(true);
} else {
- _vm->_hotspots[1]->enable(true);
- _vm->_hotspots[2]->enable(true);
- _vm->_hotspots[3]->enable(false);
+ prevPage->enable(true);
+ nextPage->enable(true);
+ openBook->enable(false);
}
// Draw the image of the page
@@ -514,14 +530,17 @@ void RivenExternal::xacathopenbook(uint16 argc, uint16 *argv) {
uint32 page = _vm->_vars["acathpage"];
// Set hotspots depending on the page
+ RivenHotspot *openBook = _vm->_card->getHotspotByName("openBook");
+ RivenHotspot *nextPage = _vm->_card->getHotspotByName("nextpage");
+ RivenHotspot *prevPage = _vm->_card->getHotspotByName("prevpage");
if (page == 1) {
- _vm->_hotspots[1]->enable(false);
- _vm->_hotspots[2]->enable(false);
- _vm->_hotspots[3]->enable(true);
+ prevPage->enable(false);
+ nextPage->enable(false);
+ openBook->enable(true);
} else {
- _vm->_hotspots[1]->enable(true);
- _vm->_hotspots[2]->enable(true);
- _vm->_hotspots[3]->enable(false);
+ prevPage->enable(true);
+ nextPage->enable(true);
+ openBook->enable(false);
}
// Draw the image of the page
@@ -946,12 +965,16 @@ void RivenExternal::xbait(uint16 argc, uint16 *argv) {
_vm->_cursor->setCursor(kRivenMainCursor);
_vm->_system->updateScreen();
+ RivenHotspot *bait = _vm->getCurCard()->getHotspotByBlstId(9);
+ RivenHotspot *baitPlate = _vm->getCurCard()->getHotspotByBlstId(16);
+
// Set the bait if we put it on the plate
- if (_vm->_hotspots[9]->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
+ if (baitPlate->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
_vm->_vars["bbait"] = 1;
_vm->getCurCard()->drawPicture(4);
- _vm->_hotspots[3]->enable(false); // Disable bait hotspot
- _vm->_hotspots[9]->enable(true); // Enable baitplate hotspot
+
+ bait->enable(false); // Disable bait hotspot
+ baitPlate->enable(true); // Enable baitplate hotspot
}
}
@@ -1005,33 +1028,36 @@ void RivenExternal::xbaitplate(uint16 argc, uint16 *argv) {
_vm->_cursor->setCursor(kRivenMainCursor);
_vm->_system->updateScreen();
+ RivenHotspot *bait = _vm->getCurCard()->getHotspotByBlstId(9);
+ RivenHotspot *baitPlate = _vm->getCurCard()->getHotspotByBlstId(16);
+
// Set the bait if we put it on the plate, remove otherwise
- if (_vm->_hotspots[9]->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
+ if (baitPlate->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
_vm->_vars["bbait"] = 1;
_vm->getCurCard()->drawPicture(4);
- _vm->_hotspots[3]->enable(false); // Disable bait hotspot
- _vm->_hotspots[9]->enable(true); // Enable baitplate hotspot
+ bait->enable(false); // Disable bait hotspot
+ baitPlate->enable(true); // Enable baitplate hotspot
} else {
_vm->_vars["bbait"] = 0;
- _vm->_hotspots[3]->enable(true); // Enable bait hotspot
- _vm->_hotspots[9]->enable(false); // Disable baitplate hotspot
+ bait->enable(true); // Enable bait hotspot
+ baitPlate->enable(false); // Disable baitplate hotspot
}
}
void RivenExternal::xbisland190_opencard(uint16 argc, uint16 *argv) {
- checkDomeSliders(27, 28);
+ checkDomeSliders();
}
void RivenExternal::xbisland190_resetsliders(uint16 argc, uint16 *argv) {
- resetDomeSliders(41, 2);
+ resetDomeSliders(41, 9);
}
void RivenExternal::xbisland190_slidermd(uint16 argc, uint16 *argv) {
- dragDomeSlider(41, 27, 28, 2);
+ dragDomeSlider(41, 9);
}
void RivenExternal::xbisland190_slidermw(uint16 argc, uint16 *argv) {
- checkSliderCursorChange(2);
+ checkSliderCursorChange(9);
}
void RivenExternal::xbscpbtn(uint16 argc, uint16 *argv) {
@@ -1192,10 +1218,12 @@ void RivenExternal::xgrotatepins(uint16 argc, uint16 *argv) {
void RivenExternal::xgpincontrols(uint16 argc, uint16 *argv) {
// Handle a click on a section of an island
+ RivenHotspot *panel = _vm->getCurCard()->getHotspotByBlstId(13);
+
// Get our mouse position and adjust it to the beginning of the hotspot
Common::Point mousePos = _vm->_system->getEventManager()->getMousePos();
- mousePos.x -= _vm->_hotspots[3]->getRect().left;
- mousePos.y -= _vm->_hotspots[3]->getRect().top;
+ mousePos.x -= panel->getRect().left;
+ mousePos.y -= panel->getRect().top;
// And now adjust it to which box we hit
mousePos.x /= 10;
@@ -1280,19 +1308,19 @@ void RivenExternal::xgpincontrols(uint16 argc, uint16 *argv) {
}
void RivenExternal::xgisland25_opencard(uint16 argc, uint16 *argv) {
- checkDomeSliders(28, 29);
+ checkDomeSliders();
}
void RivenExternal::xgisland25_resetsliders(uint16 argc, uint16 *argv) {
- resetDomeSliders(16, 2);
+ resetDomeSliders(16, 11);
}
void RivenExternal::xgisland25_slidermd(uint16 argc, uint16 *argv) {
- dragDomeSlider(16, 28, 29, 2);
+ dragDomeSlider(16, 11);
}
void RivenExternal::xgisland25_slidermw(uint16 argc, uint16 *argv) {
- checkSliderCursorChange(2);
+ checkSliderCursorChange(11);
}
void RivenExternal::xgscpbtn(uint16 argc, uint16 *argv) {
@@ -1340,9 +1368,11 @@ void RivenExternal::xgrviewer(uint16 argc, uint16 *argv) {
}
// Calculate how much we're moving
- static const uint16 hotspotPositions[] = { 2, 1, 5, 4, 3 };
+ Common::String buttonName = _vm->_curHotspot->getName();
+ uint32 buttonPos = buttonName.lastChar() - '0';
+
uint32 &curPos = _vm->_vars["grviewpos"];
- uint32 newPos = curPos + hotspotPositions[_vm->_curHotspot->getIndex() - 2];
+ uint32 newPos = curPos + buttonPos;
// Now play the movie
VideoHandle handle = _vm->_video->playMovieRiven(1);
@@ -1409,9 +1439,11 @@ void RivenExternal::xglviewer(uint16 argc, uint16 *argv) {
// (It shows the village from the middle of the lake)
// Calculate how much we're moving
- static const uint16 hotspotPositions[] = { 1, 5, 4, 2, 0, 0, 3 };
+ Common::String buttonName = _vm->_curHotspot->getName();
+ uint32 buttonPos = buttonName.lastChar() - '0';
+
uint32 &curPos = _vm->_vars["glviewpos"];
- uint32 newPos = curPos + hotspotPositions[_vm->_curHotspot->getIndex() - 2];
+ uint32 newPos = curPos + buttonPos;
// Now play the movie
VideoHandle handle = _vm->_video->playMovieRiven(1);
@@ -1756,15 +1788,15 @@ void RivenExternal::xvga1300_carriage(uint16 argc, uint16 *argv) {
}
void RivenExternal::xjdome25_resetsliders(uint16 argc, uint16 *argv) {
- resetDomeSliders(81, 2);
+ resetDomeSliders(81, 10);
}
void RivenExternal::xjdome25_slidermd(uint16 argc, uint16 *argv) {
- dragDomeSlider(81, 29, 28, 2);
+ dragDomeSlider(81, 10);
}
void RivenExternal::xjdome25_slidermw(uint16 argc, uint16 *argv) {
- checkSliderCursorChange(2);
+ checkSliderCursorChange(10);
}
void RivenExternal::xjscpbtn(uint16 argc, uint16 *argv) {
@@ -1995,8 +2027,10 @@ void RivenExternal::xschool280_playwhark(uint16 argc, uint16 *argv) {
}
// Enable the correct hotspots for the movement now
- _vm->_hotspots[2]->enable(!_vm->_hotspots[2]->isEnabled());
- _vm->_hotspots[3]->enable(!_vm->_hotspots[3]->isEnabled());
+ RivenHotspot *rotateLeft = _vm->getCurCard()->getHotspotByName("rotateLeft");
+ RivenHotspot *rotateRight = _vm->getCurCard()->getHotspotByName("rotateRight");
+ rotateLeft->enable(!rotateLeft->isEnabled());
+ rotateRight->enable(!rotateRight->isEnabled());
// Update the cursor
_vm->updateCurrentHotspot();
@@ -2046,15 +2080,15 @@ void RivenExternal::xbookclick(uint16 argc, uint16 *argv) {
uint32 endTime = argv[2] * 1000 / 600;
// Track down our hotspot
- // Of course, they're not in any sane order...
- static const uint16 hotspotMap[] = { 1, 3, 2, 0 };
- Common::Rect hotspotRect = _vm->_hotspots[hotspotMap[argv[3] - 1]]->getRect();
+ Common::String hotspotName = Common::String::format("touchBook%d", argv[3]);
+ RivenHotspot *hotspot = _vm->getCurCard()->getHotspotByName(hotspotName);
+ Common::Rect hotspotRect = hotspot->getRect();
debug(0, "xbookclick:");
debug(0, "\tVideo Code = %d", argv[0]);
debug(0, "\tStart Time = %dms", startTime);
debug(0, "\tEnd Time = %dms", endTime);
- debug(0, "\tHotspot = %d -> %d", argv[3], hotspotMap[argv[3] - 1]);
+ debug(0, "\tHotspot = %d -> %s", argv[3], hotspotName.c_str());
// Just let the video play while we wait until Gehn opens the trap book for us
while (video->getTime() < startTime && !_vm->shouldQuit()) {
@@ -2157,9 +2191,13 @@ void RivenExternal::xooffice30_closebook(uint16 argc, uint16 *argv) {
_vm->_video->playMovieBlockingRiven(1);
// Set the hotspots into their correct states
- _vm->_hotspots[2]->enable(false);
- _vm->_hotspots[5]->enable(false);
- _vm->_hotspots[6]->enable(true);
+ RivenHotspot *closeBook = _vm->getCurCard()->getHotspotByName("closeBook");
+ RivenHotspot *nullHotspot = _vm->getCurCard()->getHotspotByName("null");
+ RivenHotspot *openBook = _vm->getCurCard()->getHotspotByName("openBook");
+
+ closeBook->enable(false);
+ nullHotspot->enable(false);
+ openBook->enable(true);
// We now need to draw PLST 1 and refresh, but PLST 1 is
// drawn when refreshing anyway, so don't worry about that.
@@ -2284,19 +2322,19 @@ void RivenExternal::xpisland290_domecheck(uint16 argc, uint16 *argv) {
}
void RivenExternal::xpisland25_opencard(uint16 argc, uint16 *argv) {
- checkDomeSliders(31, 5);
+ checkDomeSliders();
}
void RivenExternal::xpisland25_resetsliders(uint16 argc, uint16 *argv) {
- resetDomeSliders(10, 6);
+ resetDomeSliders(10, 14);
}
void RivenExternal::xpisland25_slidermd(uint16 argc, uint16 *argv) {
- dragDomeSlider(10, 31, 5, 6);
+ dragDomeSlider(10, 14);
}
void RivenExternal::xpisland25_slidermw(uint16 argc, uint16 *argv) {
- checkSliderCursorChange(6);
+ checkSliderCursorChange(14);
}
// ------------------------------------------------------------------------------------
@@ -2484,7 +2522,8 @@ void RivenExternal::xtisland390_covercombo(uint16 argc, uint16 *argv) {
// If we have hit the correct 5 buttons in a row, activate the hotspot to open up the
// telescope cover.
- _vm->_hotspots[9]->enable(correctDigits == 5);
+ RivenHotspot *openCover = _vm->getCurCard()->getHotspotByName("openCover");
+ openCover->enable(correctDigits == 5);
}
// Atrus' Journal and Trap Book are added to inventory
@@ -2614,20 +2653,23 @@ void RivenExternal::xt7600_setupmarbles(uint16 argc, uint16 *argv) {
void RivenExternal::setMarbleHotspots() {
// Set the hotspots
for (uint16 i = 0; i < kMarbleCount; i++) {
- uint32 &marblePos = _vm->_vars[s_marbleNames[i]];
+ uint32 marblePos = _vm->_vars[s_marbleNames[i]];
+ RivenHotspot *marbleHotspot = _vm->getCurCard()->getHotspotByName(s_marbleNames[i]);
if (marblePos == 0) // In the receptacle
- _vm->_hotspots[i + 3]->setRect(_marbleBaseHotspots[i]);
+ marbleHotspot->setRect(_marbleBaseHotspots[i]);
else // On the grid
- _vm->_hotspots[i + 3]->setRect(generateMarbleGridRect(getMarbleX(marblePos), getMarbleY(marblePos)));
+ marbleHotspot->setRect(generateMarbleGridRect(getMarbleX(marblePos), getMarbleY(marblePos)));
}
}
void RivenExternal::xt7800_setup(uint16 argc, uint16 *argv) {
// First, let's store the base receptacle hotspots for the marbles
if (_marbleBaseHotspots.empty())
- for (uint16 i = 0; i < kMarbleCount; i++)
- _marbleBaseHotspots.push_back(_vm->_hotspots[i + 3]->getRect());
+ for (uint16 i = 0; i < kMarbleCount; i++) {
+ RivenHotspot *marbleHotspot = _vm->getCurCard()->getHotspotByName(s_marbleNames[i]);
+ _marbleBaseHotspots.push_back(marbleHotspot->getRect());
+ }
// Move the marble hotspots based on their position variables
setMarbleHotspots();
@@ -2640,7 +2682,9 @@ void RivenExternal::drawMarbles() {
if (_vm->_vars["themarble"] - 1 == i)
continue;
- Common::Rect rect = _vm->_hotspots[i + 3]->getRect();
+ RivenHotspot *marbleHotspot = _vm->getCurCard()->getHotspotByName(s_marbleNames[i]);
+
+ Common::Rect rect = marbleHotspot->getRect();
// Trim the rect down a bit
rect.left += 3;
rect.top += 3;
@@ -2662,11 +2706,13 @@ void RivenExternal::xtakeit(uint16 argc, uint16 *argv) {
uint32 &marble = _vm->_vars["themarble"];
marble = 0;
- for (uint32 i = 0; i < kMarbleCount; i++)
- if (_vm->_hotspots[i + 3]->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
+ for (uint32 i = 0; i < kMarbleCount; i++) {
+ RivenHotspot *marbleHotspot = _vm->getCurCard()->getHotspotByName(s_marbleNames[i]);
+ if (marbleHotspot->containsPoint(_vm->_system->getEventManager()->getMousePos())) {
marble = i + 1;
break;
}
+ }
// xtakeit() shouldn't be called if we're not on a marble hotspot
assert(marble != 0);
@@ -2735,19 +2781,19 @@ void RivenExternal::xtisland4990_domecheck(uint16 argc, uint16 *argv) {
}
void RivenExternal::xtisland5056_opencard(uint16 argc, uint16 *argv) {
- checkDomeSliders(29, 30);
+ checkDomeSliders();
}
void RivenExternal::xtisland5056_resetsliders(uint16 argc, uint16 *argv) {
- resetDomeSliders(37, 3);
+ resetDomeSliders(37, 24);
}
void RivenExternal::xtisland5056_slidermd(uint16 argc, uint16 *argv) {
- dragDomeSlider(37, 29, 30, 3);
+ dragDomeSlider(37, 24);
}
void RivenExternal::xtisland5056_slidermw(uint16 argc, uint16 *argv) {
- checkSliderCursorChange(3);
+ checkSliderCursorChange(24);
}
void RivenExternal::xtatboundary(uint16 argc, uint16 *argv) {
diff --git a/engines/mohawk/riven_external.h b/engines/mohawk/riven_external.h
index 58dfde1a00..f1740f4cc2 100644
--- a/engines/mohawk/riven_external.h
+++ b/engines/mohawk/riven_external.h
@@ -64,9 +64,9 @@ private:
void runDomeCheck();
void runDomeButtonMovie();
void resetDomeSliders(uint16 soundId, uint16 startHotspot);
- void checkDomeSliders(uint16 resetSlidersHotspot, uint16 openDomeHotspot);
+ void checkDomeSliders();
void checkSliderCursorChange(uint16 startHotspot);
- void dragDomeSlider(uint16 soundId, uint16 resetSlidersHotspot, uint16 openDomeHotspot, uint16 startHotspot);
+ void dragDomeSlider(uint16 soundId, uint16 startHotspot);
void drawDomeSliders(uint16 startHotspot);
void drawMarbles();
void setMarbleHotspots();
diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp
index c299f86296..f43c33f7b3 100644
--- a/engines/mohawk/riven_scripts.cpp
+++ b/engines/mohawk/riven_scripts.cpp
@@ -358,11 +358,9 @@ void RivenSimpleCommand::mohawkSwitch(uint16 op, uint16 argc, uint16 *argv) {
// Command 9: enable hotspot (blst_id)
void RivenSimpleCommand::enableHotspot(uint16 op, uint16 argc, uint16 *argv) {
- for (uint16 i = 0; i < _vm->_hotspots.size(); i++) {
- if (_vm->_hotspots[i]->getBlstId() == argv[0]) {
- debug(2, "Enabling hotspot with BLST ID %d", argv[0]);
- _vm->_hotspots[i]->enable(true);
- }
+ RivenHotspot *hotspot = _vm->getCurCard()->getHotspotByBlstId(argv[0]);
+ if (hotspot) {
+ hotspot->enable(true);
}
// Recheck our current hotspot because it may have now changed
@@ -371,11 +369,9 @@ void RivenSimpleCommand::enableHotspot(uint16 op, uint16 argc, uint16 *argv) {
// Command 10: disable hotspot (blst_id)
void RivenSimpleCommand::disableHotspot(uint16 op, uint16 argc, uint16 *argv) {
- for (uint16 i = 0; i < _vm->_hotspots.size(); i++) {
- if (_vm->_hotspots[i]->getBlstId() == argv[0]) {
- debug(2, "Disabling hotspot with BLST ID %d", argv[0]);
- _vm->_hotspots[i]->enable(false);
- }
+ RivenHotspot *hotspot = _vm->getCurCard()->getHotspotByBlstId(argv[0]);
+ if (hotspot) {
+ hotspot->enable(false);
}
// Recheck our current hotspot because it may have now changed
@@ -600,10 +596,12 @@ void RivenSimpleCommand::activateBLST(uint16 op, uint16 argc, uint16 *argv) {
uint16 enabled = blst->readUint16BE();
uint16 hotspotID = blst->readUint16BE();
- if (argv[0] == index)
- for (uint16 j = 0; j < _vm->_hotspots.size(); j++)
- if (_vm->_hotspots[j]->getBlstId() == hotspotID)
- _vm->_hotspots[j]->enable(enabled == 1);
+ if (argv[0] == index) {
+ RivenHotspot *hotspot = _vm->getCurCard()->getHotspotByBlstId(hotspotID);
+ if (hotspot) {
+ hotspot->enable(enabled == 1);
+ }
+ }
}
delete blst;