aboutsummaryrefslogtreecommitdiff
path: root/engines/mads
diff options
context:
space:
mode:
authorPaul Gilbert2014-03-19 23:33:18 -0400
committerPaul Gilbert2014-03-19 23:33:18 -0400
commit8d252f4f0e81cfd43e5b311df4a1ed5fb478953b (patch)
tree3e37aa66ca3ff9ef92d94cb317c26da16dce3d19 /engines/mads
parent4ab73a89abd66890391a977ebf4a23eb361a44a4 (diff)
downloadscummvm-rg350-8d252f4f0e81cfd43e5b311df4a1ed5fb478953b.tar.gz
scummvm-rg350-8d252f4f0e81cfd43e5b311df4a1ed5fb478953b.tar.bz2
scummvm-rg350-8d252f4f0e81cfd43e5b311df4a1ed5fb478953b.zip
MADS: Implemented methods for checking action at mouse position and clicking
Diffstat (limited to 'engines/mads')
-rw-r--r--engines/mads/action.cpp272
-rw-r--r--engines/mads/action.h10
-rw-r--r--engines/mads/hotspots.cpp12
-rw-r--r--engines/mads/scene.cpp6
-rw-r--r--engines/mads/scene.h8
-rw-r--r--engines/mads/screen.cpp24
-rw-r--r--engines/mads/screen.h1
-rw-r--r--engines/mads/user_interface.cpp3
-rw-r--r--engines/mads/user_interface.h16
9 files changed, 326 insertions, 26 deletions
diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp
index 134321f4c7..65abc9454d 100644
--- a/engines/mads/action.cpp
+++ b/engines/mads/action.cpp
@@ -39,8 +39,8 @@ MADSAction::MADSAction(MADSEngine *vm) : _vm(vm) {
void MADSAction::clear() {
_v83338 = 1;
- _actionMode = ACTMODE_NONE;
- _actionMode2 = ACTMODE2_0;
+ _actionMode = ACTIONMODE_NONE;
+ _actionMode2 = ACTIONMODE2_0;
_v86F42 = 0;
_v86F4E = 0;
_articleNumber = 0;
@@ -339,7 +339,273 @@ bool MADSAction::isAction(int verbId, int objectNameId, int indirectObjectId) {
}
void MADSAction::checkActionAtMousePos() {
- warning("TODO: checkActionAtMousePos");
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+ ScreenObjects &screenObjects = _vm->_game->_screenObjects;
+
+ if ((userInterface._category == CAT_ACTION || userInterface._category == CAT_INV_VOCAB) &&
+ _v83338 != 1 && scene._highlightedHotspot >= 0) {
+ if (_v86F4E == userInterface._category || _v86F4C != scene._highlightedHotspot ||
+ (_v83338 != 2 && _v83338 != 3))
+ clear();
+ else if (_selectedRow != 0 || userInterface._category != CAT_ACTION)
+ scene._lookFlag = false;
+ else
+ scene._lookFlag = true;
+ }
+
+ if (screenObjects._v7FECA && _vm->_events->_mouseButtons) {
+ switch (userInterface._category) {
+ case CAT_ACTION:
+ case CAT_INV_VOCAB:
+ return;
+
+ case CAT_INV_LIST:
+ case CAT_TALK_ENTRY:
+ if (_v83338 != 3) {
+ if (userInterface._selectedActionIndex >= 0) {
+ _actionMode = ACTIONMODE_VERB;
+ _selectedRow = userInterface._selectedActionIndex;
+ _flags1 = scene._verbList[_selectedRow]._action1;
+ _flags2 = scene._verbList[_selectedRow]._action2;
+ _v83338 = 2;
+ } else if (userInterface._selectedItemVocabIdx >= 0) {
+ _actionMode = ACTIONMODE_OBJECT;
+ _selectedRow = userInterface._selectedItemVocabIdx;
+ int objectId = _vm->_game->_objects._inventoryList[_selectedRow];
+ InventoryObject &invObject = _vm->_game->_objects[objectId];
+
+ _flags1 = invObject._vocabList[_selectedRow - 1]._actionFlags1;
+ _flags2 = invObject._vocabList[_selectedRow - 1]._actionFlags2;
+ _actionMode2 = ACTIONMODE2_2;
+ _hotspotId = userInterface._selectedInvIndex;
+ _articleNumber = _flags2;
+
+ if ((_flags1 == 1 && _flags2 == 0) || (_flags1 == 2 && _flags2 != 0))
+ _v83338 = 4;
+ else
+ _v83338 = 3;
+ }
+ }
+ break;
+ }
+ }
+
+ switch (_v83338) {
+ case 1:
+ _articleNumber = 0;
+ switch (userInterface._category) {
+ case CAT_ACTION:
+ _actionMode = ACTIONMODE_VERB;
+ _selectedRow = scene._highlightedHotspot;
+ if (_selectedRow >= 0) {
+ _flags1 = scene._verbList[_selectedRow]._action1;
+ _flags2 = scene._verbList[_selectedRow]._action2;
+ }
+ break;
+
+ case CAT_INV_VOCAB:
+ _actionMode = ACTIONMODE_OBJECT;
+ _selectedRow = scene._highlightedHotspot;
+ if (_selectedRow < 0) {
+ _hotspotId = -1;
+ _actionMode2 = ACTIONMODE2_0;
+ } else {
+ int objectId = _vm->_game->_objects._inventoryList[_selectedRow];
+ InventoryObject &invObject = _vm->_game->_objects[objectId];
+
+ _flags1 = invObject._vocabList[_selectedRow - 2]._actionFlags1;
+ _flags2 = invObject._vocabList[_selectedRow - 2]._actionFlags2;
+ _hotspotId = userInterface._selectedInvIndex;
+ _actionMode2 = ACTIONMODE2_2;
+
+ if (_flags1 == 2)
+ _articleNumber = _flags2;
+ }
+ break;
+
+ case CAT_HOTSPOT:
+ _selectedRow = -1;
+ _actionMode = ACTIONMODE_NONE;
+ _actionMode2 = ACTIONMODE2_4;
+ _hotspotId = scene._highlightedHotspot;
+ break;
+
+ case CAT_TALK_ENTRY:
+ _actionMode = ACTIONMODE_TALK;
+ _selectedRow = scene._highlightedHotspot;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 2:
+ _articleNumber = 0;
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ // TODO: We may not need a separate ActionMode2 enum
+ _actionMode2 = (ActionMode2)userInterface._category;
+ _hotspotId = scene._highlightedHotspot;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 3:
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ _v86F42 = userInterface._category;
+ _v86F3A = scene._highlightedHotspot;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void MADSAction::leftClick() {
+ Scene &scene = _vm->_game->_scene;
+ UserInterface &userInterface = scene._userInterface;
+ ScreenObjects &screenObjects = _vm->_game->_screenObjects;
+ bool abortFlag = false;
+
+ if ((userInterface._category == CAT_ACTION || userInterface._category == CAT_INV_VOCAB) &&
+ _v83338 != 1 && scene._highlightedHotspot >= 0 &&
+ _v86F4E == userInterface._category && _v86F4C == scene._highlightedHotspot &&
+ (_v83338 == 2 || userInterface._category == CAT_INV_VOCAB)) {
+ abortFlag = true;
+ if (_selectedRow == 0 && userInterface._category == CAT_ACTION) {
+ _selectedAction = CAT_ACTION;
+ scene._lookFlag = true;
+ } else {
+ _selectedAction = CAT_NONE;
+ scene._lookFlag = false;
+ clear();
+ }
+ }
+
+ if (abortFlag || (screenObjects._v7FECA && (userInterface._category == CAT_ACTION ||
+ userInterface._category == CAT_INV_VOCAB)))
+ return;
+
+ switch (_v83338) {
+ case 1:
+ switch (userInterface._category) {
+ case CAT_ACTION:
+ if (_selectedRow >= 0) {
+ if (!_flags1) {
+ _selectedAction = -1;
+ }
+ else {
+ _v86F4C = _selectedRow;
+ _v86F4E = _actionMode;
+ _v83338 = 2;
+ }
+ }
+ break;
+
+ case CAT_INV_LIST:
+ if (scene._highlightedHotspot >= 0) {
+ userInterface.selectObject(scene._highlightedHotspot);
+ }
+ break;
+
+ case CAT_INV_VOCAB:
+ if (_selectedRow >= 0) {
+ if (_flags1 != 1 || _flags2 != 0) {
+ if (_flags1 != 2 || _flags2 == 0) {
+ _v83338 = 3;
+ _articleNumber = _flags2;
+ }
+ else {
+ _articleNumber = _flags2;
+ _selectedAction = -1;
+ }
+ }
+ else {
+ _selectedAction = -1;
+ }
+
+ _v86F4C = _selectedRow;
+ _v86F4E = _actionMode;
+ }
+ break;
+
+ case CAT_HOTSPOT:
+ _v86F4C = -1;
+ _v86F4E = 0;
+
+ if (_vm->_events->currentPos().y < MADS_SCENE_HEIGHT)
+ scene._customDest = _vm->_events->currentPos() + scene._posAdjust;
+ break;
+
+ case CAT_TALK_ENTRY:
+ if (_selectedRow >= 0)
+ _selectedAction = -1;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 2:
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ if (_hotspotId >= 0) {
+ if (_flags2) {
+ _articleNumber = _flags2;
+ _v83338 = 3;
+ }
+ else {
+ _selectedAction = -1;
+ }
+
+ if (userInterface._category == CAT_HOTSPOT) {
+ scene._customDest = _vm->_events->mousePos() + scene._posAdjust;
+ _v86F4A = true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 3:
+ switch (userInterface._category) {
+ case CAT_INV_LIST:
+ case CAT_HOTSPOT:
+ case CAT_INV_ANIM:
+ if (_v86F3A >= 0) {
+ _selectedAction = -1;
+
+ if (userInterface._category == CAT_HOTSPOT) {
+ if (!_v86F4A) {
+ scene._customDest = _vm->_events->mousePos() + scene._posAdjust;
+ _v86F4A = true;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
}
} // End of namespace MADS
diff --git a/engines/mads/action.h b/engines/mads/action.h
index da738ac34f..440990f79e 100644
--- a/engines/mads/action.h
+++ b/engines/mads/action.h
@@ -28,8 +28,8 @@
namespace MADS {
-enum ActionMode { ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6 };
-enum ActionMode2 { ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_4 = 4, ACTMODE2_5 = 5 };
+enum ActionMode { ACTIONMODE_NONE = 0, ACTIONMODE_VERB = 1, ACTIONMODE_OBJECT = 3, ACTIONMODE_TALK = 6 };
+enum ActionMode2 { ACTIONMODE2_0 = 0, ACTIONMODE2_2 = 2, ACTIONMODE2_4 = 4, ACTIONMODE2_5 = 5 };
enum AbortTimerMode { ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2 };
enum {
@@ -47,6 +47,7 @@ enum {
VERB_WALKTO = 13
};
+
class MADSEngine;
struct ActionDetails {
@@ -110,6 +111,11 @@ public:
bool isAction(int verbId, int objectNameId = 0, int indirectObjectId = 0);
void checkActionAtMousePos();
+
+ /**
+ * Execute a click within the scene
+ */
+ void leftClick();
};
} // End of namespace MADS
diff --git a/engines/mads/hotspots.cpp b/engines/mads/hotspots.cpp
index df56a69e5a..91b8127d92 100644
--- a/engines/mads/hotspots.cpp
+++ b/engines/mads/hotspots.cpp
@@ -122,16 +122,20 @@ void DynamicHotspots::reset() {
}
void DynamicHotspots::refresh() {
+ // Reset the screen objects back to only contain UI elements
+ ScreenObjects &scrObjects = _vm->_game->_screenObjects;
+ scrObjects.resize(scrObjects._uiCount);
+
+ // Loop through adding hotspots
for (uint i = 0; i < _entries.size(); ++i) {
DynamicHotspot &dh = (*this)[i];
if ((*this)[i]._active) {
- switch (_vm->_game->_screenObjects._v832EC) {
+ switch (scrObjects._v832EC) {
case 0:
case 2:
- _vm->_game->_screenObjects.add(dh._bounds, _vm->_game->_scene._layer,
- CAT_12, dh._descId);
- _vm->_game->_screenObjects._v8333C = true;
+ scrObjects.add(dh._bounds, _vm->_game->_scene._layer, CAT_12, dh._descId);
+ scrObjects._v8333C = true;
break;
default:
break;
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index 741ba82be4..baf51fea12 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -49,6 +49,8 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _action(_vm), _depthSurface(vm),
_textSpacing = -1;
_frameStartTime = 0;
_layer = LAYER_GUI;
+ _lookFlag = false;
+ _highlightedHotspot = 0;
_verbList.push_back(VerbInit(VERB_LOOK, 2, 0));
_verbList.push_back(VerbInit(VERB_TAKE, 2, 0));
@@ -463,10 +465,6 @@ void Scene::drawElements(ScreenTransition transitionType, bool surfaceFlag) {
_textDisplay.cleanUp();
}
-void Scene::leftClick() {
- warning("TODO: Scene::leftClick");
-}
-
void Scene::doPreactions() {
warning("TODO: Scene::doPreactions");
}
diff --git a/engines/mads/scene.h b/engines/mads/scene.h
index 9493eda532..16684c47a2 100644
--- a/engines/mads/scene.h
+++ b/engines/mads/scene.h
@@ -118,6 +118,9 @@ public:
Common::Point _posAdjust;
uint32 _frameStartTime;
Layer _layer;
+ bool _lookFlag;
+ int _highlightedHotspot;
+ Common::Point _customDest;
/**
* Constructor
@@ -185,11 +188,6 @@ public:
void drawElements(ScreenTransition transitionType, bool surfaceFlag);
/**
- * Execute a click within the scene
- */
- void leftClick();
-
- /**
* Load an animation
*/
void loadAnimation(const Common::String &resName, int abortTimers = 0);
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
index 608456e2e3..1f1fc0a41e 100644
--- a/engines/mads/screen.cpp
+++ b/engines/mads/screen.cpp
@@ -260,6 +260,7 @@ ScreenObjects::ScreenObjects(MADSEngine *vm) : _vm(vm) {
_category = CAT_NONE;
_objectIndex = 0;
_released = false;
+ _uiCount = 0;
}
void ScreenObjects::add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId) {
@@ -314,7 +315,7 @@ void ScreenObjects::check(bool scanFlag) {
}
if (_vm->_events->_mouseReleased) {
- scene.leftClick();
+ scene._action.leftClick();
scene._userInterface._category = CAT_NONE;
}
@@ -329,8 +330,25 @@ void ScreenObjects::check(bool scanFlag) {
scene._action.refresh();
- // Loop through image inter list
- warning("TODO: imageInterList loop");
+ UserInterface &userInterface = _vm->_game->_scene._userInterface;
+ uint32 currentTicks = _vm->_events->getFrameCounter();
+ if (currentTicks >= _vm->_game->_ticksExpiry) {
+ // Check the user interface slots to see if there's any slots that need to be expired
+ UISlots &uiSlots = userInterface._uiSlots;
+ for (uint idx = 0; idx < uiSlots.size(); ++idx) {
+ UISlot &slot = uiSlots[idx];
+
+ if (slot._slotType != ST_FULL_SCREEN_REFRESH && slot._slotType > -20
+ && slot._field2 != 200)
+ slot._slotType = ST_EXPIRED;
+ }
+
+ // Handle animating the selected inventory animation
+ userInterface.inventoryAnim();
+
+ // Set the next frame expiry
+ _vm->_game->_ticksExpiry = currentTicks + 6;
+ }
}
int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) {
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
index 9033206852..862c8720f3 100644
--- a/engines/mads/screen.h
+++ b/engines/mads/screen.h
@@ -150,6 +150,7 @@ public:
ScrCategory _category;
int _objectIndex;
bool _released;
+ int _uiCount;
/*
* Constructor
diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp
index f46a4c4150..f6be725ac2 100644
--- a/engines/mads/user_interface.cpp
+++ b/engines/mads/user_interface.cpp
@@ -460,6 +460,9 @@ void UserInterface::loadElements() {
_vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_TALK_ENTRY, idx);
}
}
+
+ // Store the number of UI elements loaded for easy nuking/refreshing hotspots added later
+ _vm->_game->_screenObjects._uiCount = _vm->_game->_screenObjects.size();
}
bool UserInterface::getBounds(ScrCategory category, int v, Common::Rect &bounds) {
diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h
index b4c581d1c2..4a26d3450f 100644
--- a/engines/mads/user_interface.h
+++ b/engines/mads/user_interface.h
@@ -126,11 +126,6 @@ private:
void writeVocab(ScrCategory category, int id);
void refresh();
-
- /**
- * Handles queuing a new frame of an inventory animation for drawing
- */
- void inventoryAnim();
public:
MSurface _surface;
UISlots _uiSlots;
@@ -171,10 +166,21 @@ public:
void setBounds(const Common::Rect &r);
+ /**
+ * Loads the animation sprite data for a given inventory object
+ */
void loadInventoryAnim(int objectId);
+ /**
+ * Resets the inventory animation when no inventory item is selected
+ */
void noInventoryAnim();
+ /**
+ * Handles queuing a new frame of an inventory animation for drawing
+ */
+ void inventoryAnim();
+
void categoryChanged();
/**