diff options
author | Paul Gilbert | 2014-03-19 23:33:18 -0400 |
---|---|---|
committer | Paul Gilbert | 2014-03-19 23:33:18 -0400 |
commit | 8d252f4f0e81cfd43e5b311df4a1ed5fb478953b (patch) | |
tree | 3e37aa66ca3ff9ef92d94cb317c26da16dce3d19 | |
parent | 4ab73a89abd66890391a977ebf4a23eb361a44a4 (diff) | |
download | scummvm-rg350-8d252f4f0e81cfd43e5b311df4a1ed5fb478953b.tar.gz scummvm-rg350-8d252f4f0e81cfd43e5b311df4a1ed5fb478953b.tar.bz2 scummvm-rg350-8d252f4f0e81cfd43e5b311df4a1ed5fb478953b.zip |
MADS: Implemented methods for checking action at mouse position and clicking
-rw-r--r-- | engines/mads/action.cpp | 272 | ||||
-rw-r--r-- | engines/mads/action.h | 10 | ||||
-rw-r--r-- | engines/mads/hotspots.cpp | 12 | ||||
-rw-r--r-- | engines/mads/scene.cpp | 6 | ||||
-rw-r--r-- | engines/mads/scene.h | 8 | ||||
-rw-r--r-- | engines/mads/screen.cpp | 24 | ||||
-rw-r--r-- | engines/mads/screen.h | 1 | ||||
-rw-r--r-- | engines/mads/user_interface.cpp | 3 | ||||
-rw-r--r-- | engines/mads/user_interface.h | 16 |
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(); /** |