diff options
author | Paul Gilbert | 2010-07-23 09:49:40 +0000 |
---|---|---|
committer | Paul Gilbert | 2010-07-23 09:49:40 +0000 |
commit | 42851e047f9c8bef8d20a1854ff50dfd11a41741 (patch) | |
tree | b6e1fcd36b2f63d160324978eb47833131d88245 /engines | |
parent | 05999d1e5907747a39d3f3e4b73bac1929031600 (diff) | |
download | scummvm-rg350-42851e047f9c8bef8d20a1854ff50dfd11a41741.tar.gz scummvm-rg350-42851e047f9c8bef8d20a1854ff50dfd11a41741.tar.bz2 scummvm-rg350-42851e047f9c8bef8d20a1854ff50dfd11a41741.zip |
Lots of action related fields added; scroll over default action is now displayed on-screen
svn-id: r51200
Diffstat (limited to 'engines')
-rw-r--r-- | engines/m4/animation.cpp | 8 | ||||
-rw-r--r-- | engines/m4/animation.h | 3 | ||||
-rw-r--r-- | engines/m4/hotspot.cpp | 1 | ||||
-rw-r--r-- | engines/m4/hotspot.h | 3 | ||||
-rw-r--r-- | engines/m4/m4_scene.cpp | 2 | ||||
-rw-r--r-- | engines/m4/m4_scene.h | 2 | ||||
-rw-r--r-- | engines/m4/mads_scene.cpp | 226 | ||||
-rw-r--r-- | engines/m4/mads_scene.h | 44 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 263 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 68 | ||||
-rw-r--r-- | engines/m4/scene.cpp | 2 | ||||
-rw-r--r-- | engines/m4/scene.h | 2 |
12 files changed, 360 insertions, 264 deletions
diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp index 0ead57aac9..37314eff44 100644 --- a/engines/m4/animation.cpp +++ b/engines/m4/animation.cpp @@ -287,8 +287,8 @@ void MadsAnimation::load(const Common::String &filename, int abortTimers) { _abortTimers = abortTimers; _abortMode = _madsVm->scene()->_abortTimersMode2; - for (int i = 0; i < 3; ++i) - _actionNouns[i] = _madsVm->globals()->actionNouns[i]; + if (_madsVm->_scene) + _actionNouns = _madsVm->scene()->_action._action; // Initialise kernel message list for (uint i = 0; i < _messages.size(); ++i) @@ -464,8 +464,8 @@ void MadsAnimation::update() { if (_abortMode != ABORTMODE_1) { // Copy the noun list - for (int i = 0; i < 3; ++i) - _madsVm->globals()->actionNouns[i] = _actionNouns[i]; + if (_madsVm->_scene) + _madsVm->scene()->_action._action = _actionNouns; } } } diff --git a/engines/m4/animation.h b/engines/m4/animation.h index 583d829066..a7a6b57c32 100644 --- a/engines/m4/animation.h +++ b/engines/m4/animation.h @@ -104,8 +104,7 @@ private: int _messageCtr; int _abortTimers; AbortTimerMode _abortMode; - uint16 _actionNouns[3]; - + ActionDetails _actionNouns; void load1(int frameNumber); bool proc1(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber); diff --git a/engines/m4/hotspot.cpp b/engines/m4/hotspot.cpp index 9849cc7416..4eec50e29d 100644 --- a/engines/m4/hotspot.cpp +++ b/engines/m4/hotspot.cpp @@ -206,6 +206,7 @@ void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int ho y2 = readHotSpotInteger(hotspotStream); index = add(new HotSpot(x1, y1, x2, y2), i == 0); currentHotSpot = get(index); + currentHotSpot->setIndex(index); feetX = readHotSpotInteger(hotspotStream); feetY = readHotSpotInteger(hotspotStream); currentHotSpot->setFeet(feetX, feetY); diff --git a/engines/m4/hotspot.h b/engines/m4/hotspot.h index 5bb4f5888a..b06865c39a 100644 --- a/engines/m4/hotspot.h +++ b/engines/m4/hotspot.h @@ -73,6 +73,8 @@ public: int getFeetY() { return _feetY; } int8 getArticle() const { return _articleNumber; } Common::Rect getRect() const; + int getIndex() const { return _index; } + void setIndex(int index) { _index = index; } int32 area() const { return (_rect.width() - 1) * (_rect.height() - 1); } bool pointInside(int x, int y) { return _rect.contains(x, y); } @@ -83,6 +85,7 @@ private: bool _active; int _feetX, _feetY; uint8 _facing, _cursor; + int _index; // Unused in Orion Burger, used in MADS games uint8 _syntax; diff --git a/engines/m4/m4_scene.cpp b/engines/m4/m4_scene.cpp index 79122a9564..0c984af448 100644 --- a/engines/m4/m4_scene.cpp +++ b/engines/m4/m4_scene.cpp @@ -207,7 +207,7 @@ void M4Scene::leaveScene() { Scene::leaveScene(); } -void M4Scene::checkHotspotAtMousePos(int x, int y) { +void M4Scene::mouseMove(int x, int y) { if (_vm->getGameType() == GType_Riddle) return; diff --git a/engines/m4/m4_scene.h b/engines/m4/m4_scene.h index 329582caf4..2216779a3e 100644 --- a/engines/m4/m4_scene.h +++ b/engines/m4/m4_scene.h @@ -69,7 +69,7 @@ public: virtual void leaveScene(); virtual void loadSceneCodes(int sceneNumber, int index = 0); virtual void show(); - virtual void checkHotspotAtMousePos(int x, int y); + virtual void mouseMove(int x, int y); virtual void leftClick(int x, int y); virtual void rightClick(int x, int y); virtual void update(); diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 8ffe6b8c95..2ee60ae6d4 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -241,44 +241,20 @@ void MadsScene::loadSceneCodes(int sceneNumber, int index) { } } -void MadsScene::checkHotspotAtMousePos(int x, int y) { +void MadsScene::mouseMove(int x, int y) { HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y); if (currentHotSpot != NULL) { _vm->_mouse->setCursorNum(currentHotSpot->getCursor()); - // This is the "easy" interface, which updates the status text when the mouse is moved - // TODO: toggle this code for easy/normal interface mode - char statusText[50]; - int verbId = 0;//***DEBUG****_currentAction; - if (verbId == kVerbNone) - verbId = currentHotSpot->getVerbID(); - if (verbId == kVerbNone) - verbId = kVerbWalkTo; - - sprintf(statusText, "%s %s\n", _madsVm->globals()->getVocab(verbId), currentHotSpot->getVocab()); + _action._hotspotId = currentHotSpot->getIndex(); + - statusText[0] = toupper(statusText[0]); // capitalize first letter - setStatusText(statusText); } else { _vm->_mouse->setCursorNum(0); - setStatusText(""); } } void MadsScene::leftClick(int x, int y) { - HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y); - if (currentHotSpot != NULL) { - char statusText[50]; - if (currentHotSpot->getVerbID() != 0) { - sprintf(statusText, "%s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab()); - } else { - sprintf(statusText, "%s %s\n", _madsVm->globals()->getVocab(kVerbWalkTo), currentHotSpot->getVocab()); - } - - statusText[0] = toupper(statusText[0]); // capitalize first letter - setStatusText(statusText); - } - // **DEBUG** - being used for movement testing _madsVm->_player.moveComplete(); _madsVm->_player.setDest(x, y, 2); @@ -297,7 +273,6 @@ void MadsScene::rightClick(int x, int y) { void MadsScene::setAction(int action, int objectId) { VALIDATE_MADS; - char statusText[50]; error("todo"); // TODO: Actually executing actions directly for objects. Also, some object actions are special in that @@ -314,7 +289,7 @@ void MadsScene::setAction(int action, int objectId) { _currentAction = action; } */ - setStatusText(statusText); +// setStatusText(statusText); } /** @@ -349,6 +324,17 @@ void MadsScene::update() { } void MadsScene::updateState() { + if ((_action._selectedAction != 0) || !_madsVm->_player._stepEnabled) + _action.clear(); + + if (!_abortTimers && !_madsVm->_player._unk3) { + if (_dynamicHotspots._changed) + _dynamicHotspots.refresh(); + +// int v = (_madsVm->_player._stepEnabled && !_action._verbNounFlag && !_abortTimers2) ? 1 : 0; +// _screenObjects.check(v, false); + } + _madsVm->_player.update(); // Handle refreshing the mouse position display @@ -361,6 +347,9 @@ void MadsScene::updateState() { _mouseMsgIndex = _madsVm->scene()->_kernelMessages.add(Common::Point(5, 5), 0x203, 0, 0, 1, buffer); } + if (_madsVm->globals()->_config.easyMouse) + _action.refresh(); + // Step through the scene _sceneLogic.sceneStep(); @@ -548,181 +537,6 @@ bool MadsScene::getDepthHighBits(const Common::Point &pt) { /*--------------------------------------------------------------------------*/ -MadsAction::MadsAction() { - clear(); -} - -void MadsAction::clear() { - _actionMode = ACTMODE_NONE; - _actionMode2 = ACTMODE2_0; - _word_86F42 = 0; - _word_86F4E = 0; - _articleNumber = 0; - _lookFlag = false; - _word_86F4A = 0; - _statusText[0] = '\0'; - _selectedRow = -1; - _currentHotspot = -1; - _word_86F3A = -1; - _word_86F4C = -1; - //word_86F3A/word_86F4C - _currentAction = kVerbNone; - _objectNameId = -1; - _objectDescId = -1; - _word_83334 = -1; -} - -void MadsAction::appendVocab(int vocabId, bool capitalise) { - char *s = _statusText + strlen(_statusText); - const char *vocabStr = _madsVm->globals()->getVocab(vocabId); - strcpy(s, vocabStr); - if (capitalise) - *s = toupper(*s); - - strcat(s, " "); -} - -void MadsAction::set() { - int hotspotCount = _madsVm->scene()->getSceneResources().hotspotCount; - bool flag = false; - _currentAction = -1; - _objectNameId = -1; - _objectDescId = -1; - - if (_actionMode == ACTMODE_TALK) { - // Handle showing the conversation selection. Rex at least doesn't actually seem to use this - if (_selectedRow >= 0) { - const char *desc = _madsVm->_converse[_selectedRow].desc; - if (desc) - strcpy(_statusText, desc); - } - } else if (_lookFlag && (_selectedRow == 0)) { - // Two 'look' actions in succession, so the action becomes 'Look around' - strcpy(_statusText, lookAroundStr); - } else { - if ((_actionMode == ACTMODE_OBJECT) && (_selectedRow >= 0) && (_flags1 == 2) && (_flags2 == 0)) { - // Use/to action - int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); - MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); - - _objectNameId = objEntry->descId; - _currentAction = objEntry->vocabList[_selectedRow].vocabId; - - // Set up the status text stirng - strcpy(_statusText, useStr); - appendVocab(_objectNameId); - strcpy(_statusText, toStr); - appendVocab(_currentAction); - } else { - // Handling for if an action has been selected - if (_selectedRow >= 0) { - if (_actionMode == ACTMODE_VERB) { - // Standard verb action - _currentAction = verbList[_selectedRow].verb; - } else { - // Selected action on an inventory object - int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); - MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); - - _currentAction = objEntry->vocabList[_selectedRow].vocabId; - } - - appendVocab(_currentAction, true); - - if (_currentAction == kVerbLook) { - // Add in the word 'add' - strcat(_statusText, atStr); - strcat(_statusText, " "); - } - } - - // Handling for if a hotspot has been selected/highlighted - if ((_currentHotspot >= 0) && (_selectedRow >= 0) && (_articleNumber > 0) && (_flags1 == 2)) { - flag = true; - - strcat(_statusText, englishMADSArticleList[_articleNumber]); - strcat(_statusText, " "); - } - - if (_currentHotspot >= 0) { - if (_selectedRow < 0) { - int verbId; - - if (_currentHotspot < hotspotCount) { - // Get the verb Id from the hotspot - verbId = (*_madsVm->scene()->getSceneResources().hotspots)[_currentHotspot].getVerbID(); - } else { - // Get the verb Id from the scene object - verbId = (*_madsVm->scene()->getSceneResources().props)[_currentHotspot - hotspotCount].getVerbID(); - } - - if (verbId > 0) { - // Set the specified action - _currentAction = verbId; - appendVocab(_currentAction, true); - } else { - // Default to a standard 'walk to' - _currentAction = kVerbWalkTo; - strcat(_statusText, walkToStr); - } - } - - if ((_actionMode2 == ACTMODE2_2) || (_actionMode2 == ACTMODE2_5)) { - // Get name from given inventory object - int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_currentHotspot); - _objectNameId = _madsVm->globals()->getObject(objectId)->descId; - } else if (_currentHotspot < hotspotCount) { - // Get name from scene hotspot - _objectNameId = (*_madsVm->scene()->getSceneResources().hotspots)[_currentHotspot].getVocabID(); - } else { - // Get name from temporary scene hotspot - _objectNameId = (*_madsVm->scene()->getSceneResources().props)[_currentHotspot].getVocabID(); - } - } - } - - if ((_currentHotspot >= 0) && (_articleNumber > 0) && !flag) { - if (_articleNumber == -1) { - if (_word_86F3A >= 0) { - int articleNum = 0; - - if ((_word_86F42 == 2) || (_word_86F42 == 5)) { - int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_currentHotspot); - articleNum = _madsVm->globals()->getObject(objectId)->article; - } else if (_word_86F3A < hotspotCount) { - articleNum = (*_madsVm->scene()->getSceneResources().hotspots)[_currentHotspot].getArticle(); - } else { - - } - } - - } else if ((_articleNumber == kVerbLook) || (_vm->getGameType() != GType_RexNebular) || - (strcmp(_madsVm->globals()->getVocab(_objectDescId), fenceStr) != 0)) { - // Write out the article - strcat(_statusText, englishMADSArticleList[_articleNumber]); - } else { - // Special case for a 'fence' entry in Rex Nebular - strcat(_statusText, overStr); - } - - strcat(_statusText, " "); - } - - // Append object description if necessary - if (_word_86F3A >= 0) - appendVocab(_objectDescId); - - // Remove any trailing space character - int statusLen = strlen(_statusText); - if ((statusLen > 0) && (_statusText[statusLen - 1] == ' ')) - _statusText[statusLen - 1] = '\0'; - } - - _word_83334 = -1; -} - -/*--------------------------------------------------------------------------*/ - void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface) { char buffer1[80]; const char *sceneName; @@ -1151,7 +965,7 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) { } bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) { - MadsAction &act = _madsVm->scene()->getAction(); + MadsAction &act = _madsVm->scene()->_action; // If the mouse isn't being held down, then reset the repeated scroll timer if (eventType != MEVENT_LEFT_HOLD) @@ -1198,7 +1012,7 @@ bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int act._flags1 = obj->vocabList[1].flags1; act._flags2 = obj->vocabList[1].flags2; - act._currentHotspot = _selectedObject; + act._action.hotspotId = _selectedObject; act._articleNumber = act._flags2; } } diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h index 7defe613bd..2bd38aff6f 100644 --- a/engines/m4/mads_scene.h +++ b/engines/m4/mads_scene.h @@ -38,6 +38,9 @@ class MadsInterfaceView; #define DEPTH_BANDS_SIZE 15 #define MAX_ROUTE_NODES 22 +enum ScreenCategory {CAT_NONE = 0, CAT_ACTION = 1, CAT_INV_LIST = 2, CAT_INV_VOCAB, CAT_HOTSPOT = 4, + CAT_INV_ANIM = 6, CAT_6, CAT_INV_SCROLLER = 7, CAT_12 = 12}; + class SceneNode { public: Common::Point pt; @@ -77,51 +80,16 @@ public: void setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface); }; -enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6}; -enum MAdsActionMode2 {ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_5 = 5}; - -class MadsAction { -private: - char _statusText[100]; - - void appendVocab(int vocabId, bool capitalise = false); -public: - int _currentHotspot; - int _objectNameId; - int _objectDescId; - int _currentAction; - int8 _flags1, _flags2; - MadsActionMode _actionMode; - MAdsActionMode2 _actionMode2; - int _articleNumber; - bool _lookFlag; - int _selectedRow; - // Unknown fields - int16 _word_86F3A; - int16 _word_86F42; - int16 _word_86F4E; - int16 _word_86F4A; - int16 _word_83334; - int16 _word_86F4C; - -public: - MadsAction(); - - void clear(); - void set(); - const char *statusText() const { return _statusText; } -}; - class MadsScene : public Scene, public MadsView { private: MadsEngine *_vm; MadsSceneResources _sceneResources; - MadsAction _action; Animation *_activeAnimation; MadsSceneLogic _sceneLogic; SpriteAsset *_playerSprites; int _mouseMsgIndex; + int _highlightedHotspot; void drawElements(); void loadScene2(const char *aaName, int sceneNumber); @@ -142,7 +110,7 @@ public: virtual void leaveScene(); virtual void loadSceneCodes(int sceneNumber, int index = 0); virtual void show(); - virtual void checkHotspotAtMousePos(int x, int y); + virtual void mouseMove(int x, int y); virtual void leftClick(int x, int y); virtual void rightClick(int x, int y); virtual void setAction(int action, int objectId = -1); @@ -158,8 +126,6 @@ public: MadsInterfaceView *getInterface() { return (MadsInterfaceView *)_interfaceSurface; } MadsSceneResources &getSceneResources() { return _sceneResources; } - MadsAction &getAction() { return _action; } - void setStatusText(const char *text) {}//***DEPRECATED*** bool getDepthHighBit(const Common::Point &pt); bool getDepthHighBits(const Common::Point &pt); }; diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index d7e6435b14..6566b37c50 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -37,6 +37,221 @@ namespace M4 { +MadsAction::MadsAction(MadsView &owner): _owner(owner) { + clear(); + _currentAction = kVerbNone; + _verbNounFlag = false; + _statusTextIndex = -1; + _selectedAction = 0; +} + +void MadsAction::clear() { + _v83338 = 1; + _actionMode = ACTMODE_NONE; + _actionMode2 = ACTMODE2_0; + _word_86F42 = 0; + _word_86F4E = 0; + _articleNumber = 0; + _lookFlag = false; + _word_86F4A = 0; + _statusText[0] = '\0'; + _selectedRow = -1; + _hotspotId = -1; + _word_86F3A = -1; + _word_86F4C = -1; + _action.hotspotId = -1; + _action.objectNameId = -1; + _action.indirectObjectId = -1; + _textChanged = true; +} + +void MadsAction::appendVocab(int vocabId, bool capitalise) { + char *s = _statusText + strlen(_statusText); + const char *vocabStr = _madsVm->globals()->getVocab(vocabId); + strcpy(s, vocabStr); + if (capitalise) + *s = toupper(*s); + + strcat(s, " "); +} + +void MadsAction::set() { + int hotspotCount = _madsVm->scene()->getSceneResources().hotspotCount; + bool flag = false; + strcpy(_statusText, ""); + + _currentAction = -1; + _action.objectNameId = -1; + _action.indirectObjectId = -1; + + if (_actionMode == ACTMODE_TALK) { + // Handle showing the conversation selection. Rex at least doesn't actually seem to use this + if (_selectedRow >= 0) { + const char *desc = _madsVm->_converse[_selectedRow].desc; + if (desc) + strcpy(_statusText, desc); + } + } else if (_lookFlag && (_selectedRow == 0)) { + // Two 'look' actions in succession, so the action becomes 'Look around' + strcpy(_statusText, lookAroundStr); + } else { + if ((_actionMode == ACTMODE_OBJECT) && (_selectedRow >= 0) && (_flags1 == 2) && (_flags2 == 0)) { + // Use/to action + int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); + MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); + + _action.objectNameId = objEntry->descId; + _currentAction = objEntry->vocabList[_selectedRow].vocabId; + + // Set up the status text stirng + strcpy(_statusText, useStr); + appendVocab(_action.objectNameId); + strcpy(_statusText, toStr); + appendVocab(_currentAction); + } else { + // Handling for if an action has been selected + if (_selectedRow >= 0) { + if (_actionMode == ACTMODE_VERB) { + // Standard verb action + _currentAction = verbList[_selectedRow].verb; + } else { + // Selected action on an inventory object + int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject(); + MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject); + + _currentAction = objEntry->vocabList[_selectedRow].vocabId; + } + + appendVocab(_currentAction, true); + + if (_currentAction == kVerbLook) { + // Add in the word 'add' + strcat(_statusText, atStr); + strcat(_statusText, " "); + } + } + + // Handling for if a hotspot has been selected/highlighted + if ((_hotspotId >= 0) && (_selectedRow >= 0) && (_articleNumber > 0) && (_flags1 == 2)) { + flag = true; + + strcat(_statusText, englishMADSArticleList[_articleNumber]); + strcat(_statusText, " "); + } + + if (_hotspotId >= 0) { + if (_selectedRow < 0) { + int verbId; + + if (_hotspotId < hotspotCount) { + // Get the verb Id from the hotspot + verbId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVerbID(); + } else { + // Get the verb Id from the scene object + verbId = (*_madsVm->scene()->getSceneResources().props)[_hotspotId - hotspotCount].getVerbID(); + } + + if (verbId > 0) { + // Set the specified action + _currentAction = verbId; + appendVocab(_currentAction, true); + } else { + // Default to a standard 'walk to' + _currentAction = kVerbWalkTo; + strcat(_statusText, walkToStr); + } + } + + if ((_actionMode2 == ACTMODE2_2) || (_actionMode2 == ACTMODE2_5)) { + // Get name from given inventory object + int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId); + _action.objectNameId = _madsVm->globals()->getObject(objectId)->descId; + } else if (_hotspotId < hotspotCount) { + // Get name from scene hotspot + _action.objectNameId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVocabID(); + } else { + // Get name from temporary scene hotspot + _action.objectNameId = (*_madsVm->scene()->getSceneResources().props)[_hotspotId].getVocabID(); + } + appendVocab(_action.objectNameId); + } + } + + if ((_hotspotId >= 0) && (_articleNumber > 0) && !flag) { + if (_articleNumber == -1) { + if (_word_86F3A >= 0) { + int articleNum = 0; + + if ((_word_86F42 == 2) || (_word_86F42 == 5)) { + int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId); + articleNum = _madsVm->globals()->getObject(objectId)->article; + } else if (_word_86F3A < hotspotCount) { + articleNum = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getArticle(); + } else { + + } + } + + } else if ((_articleNumber == kVerbLook) || (_vm->getGameType() != GType_RexNebular) || + (strcmp(_madsVm->globals()->getVocab(_action.indirectObjectId), fenceStr) != 0)) { + // Write out the article + strcat(_statusText, englishMADSArticleList[_articleNumber]); + } else { + // Special case for a 'fence' entry in Rex Nebular + strcat(_statusText, overStr); + } + + strcat(_statusText, " "); + } + + // Append object description if necessary + if (_word_86F3A >= 0) + appendVocab(_action.indirectObjectId); + + // Remove any trailing space character + int statusLen = strlen(_statusText); + if ((statusLen > 0) && (_statusText[statusLen - 1] == ' ')) + _statusText[statusLen - 1] = '\0'; + } + + _textChanged = true; +} + +void MadsAction::refresh() { + // Exit immediately if nothing has changed + if (!_textChanged) + return; + + // Remove any old copy of the status text + if (_statusTextIndex >= 0) { + _owner._textDisplay.expire(_statusTextIndex); + _statusTextIndex = -1; + } + + if (strlen(_statusText) != 0) { + if ((_owner._screenObjects._v832EC == 0) || (_owner._screenObjects._v832EC == 2)) { + Font *font = _madsVm->_font->getFont(FONT_MAIN_MADS); + int textSpacing = -1; + + int strWidth = font->getWidth(_statusText); + if (strWidth > 320) { + // Too large to fit, so fall back on interface font + font = _madsVm->_font->getFont(FONT_INTERFACE_MADS); + strWidth = font->getWidth(_statusText, 0); + textSpacing = 0; + } + + // Add a new text display entry to display the status text at the bottom of the screen area + _statusTextIndex = _owner._textDisplay.add(160 - (strWidth / 2), + MADS_SURFACE_HEIGHT + _owner._posAdjust.y - 13, 3, textSpacing, _statusText, font); + } + } + + _textChanged = false; +} + +//-------------------------------------------------------------------------- + bool MadsSpriteSlot::operator==(const SpriteSlotSubset &other) const { return (spriteListIndex == other.spriteListIndex) && (frameNumber == other.frameNumber) && (xp == other.xp) && (yp == other.yp) && (depth == other.depth) && (scale == other.scale); @@ -618,6 +833,18 @@ void MadsKernelMessageList::processText(int msgIndex) { //-------------------------------------------------------------------------- +ScreenObjects::ScreenObjects(MadsView &owner): _owner(owner) { + _v832EC = 0; + _v7FECA = 0; + _v7FED6 = 0; + _v8332A = 0; + _yp = 0; + _v8333C = 0; + _selectedObject = 0; + _category = 0; + _objectIndex = 0; +} + /** * Clears the entries list */ @@ -670,6 +897,29 @@ void ScreenObjects::setActive(int category, int idx, bool active) { } } +void ScreenObjects::check(bool scanFlag, bool mouseClick) { + if (!mouseClick || _v832EC) + _v7FECA = 0; + + if (!_v7FED6 && !_v8332A && !_yp && (_v8333C != 0)) { + if (scanFlag) { + _category = CAT_NONE; + _selectedObject = scanBackwards(_madsVm->_mouse->currentPos().x, _madsVm->_mouse->currentPos().y, + LAYER_GUI); + + if (_selectedObject > 0) { + ScreenObjectEntry &obj = _entries[_selectedObject]; + _category = obj.category & 7; + _objectIndex = obj.index; + } + + // TODO: Other stuff related to the user interface + } + } + + _owner._action.refresh(); +} + /*--------------------------------------------------------------------------*/ MadsDynamicHotspots::MadsDynamicHotspots(MadsView &owner): _owner(owner) { @@ -678,7 +928,7 @@ MadsDynamicHotspots::MadsDynamicHotspots(MadsView &owner): _owner(owner) { rec.active = false; _entries.push_back(rec); } - _flag = true; + _changed = true; _count = 0; } @@ -702,7 +952,7 @@ int MadsDynamicHotspots::add(int descId, int field14, int seqIndex, const Common _entries[idx].field_17 = 0; ++_count; - _flag = true; + _changed = true; if (seqIndex >= 0) _owner._sequenceList[seqIndex].dynamicHotspotIndex = idx; @@ -734,7 +984,7 @@ void MadsDynamicHotspots::remove(int index) { _entries[index].active = false; --_count; - _flag = true; + _changed = true; } } @@ -743,7 +993,7 @@ void MadsDynamicHotspots::reset() { _entries[i].active = false; _count = 0; - _flag = false; + _changed = false; } /*--------------------------------------------------------------------------*/ @@ -1048,7 +1298,7 @@ bool MadsSequenceList::loadSprites(int seqIndex) { dynHotspot.bounds.top = MAX(y2 - height, 0); dynHotspot.bounds.bottom = MIN(y2, 155) - dynHotspot.bounds.top; - _owner._dynamicHotspots._flag = true; + _owner._dynamicHotspots._changed = true; } } @@ -1208,7 +1458,8 @@ Animation::~Animation() { //-------------------------------------------------------------------------- MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceList(*this), - _kernelMessages(*this), _spriteSlots(*this), _dirtyAreas(*this), _textDisplay(*this) { + _kernelMessages(*this), _spriteSlots(*this), _dirtyAreas(*this), _textDisplay(*this), + _screenObjects(*this), _action(*this) { _textSpacing = -1; _newTimeout = 0; diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 0604ae1ee1..d29947390a 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -36,6 +36,53 @@ namespace M4 { class MadsView; +enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6}; +enum MAdsActionMode2 {ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_5 = 5}; + +struct ActionDetails { + int hotspotId; + int objectNameId; + int indirectObjectId; +}; + +class MadsAction { +private: + MadsView &_owner; + char _statusText[100]; + + void appendVocab(int vocabId, bool capitalise = false); +public: + ActionDetails _action; + int _currentAction; + int8 _flags1, _flags2; + MadsActionMode _actionMode; + MAdsActionMode2 _actionMode2; + int _articleNumber; + bool _lookFlag; + int _selectedRow; + bool _textChanged; + int _selectedAction; + bool _verbNounFlag; + int _statusTextIndex; + int _hotspotId; + + // Unknown fields + int16 _word_86F3A; + int16 _word_86F42; + int16 _word_86F4E; + int16 _word_86F4A; + int16 _word_86F4C; + int _v83338; + +public: + MadsAction(MadsView &owner); + + void clear(); + void set(); + const char *statusText() const { return _statusText; } + void refresh(); +}; + enum AbortTimerMode {ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2}; class SpriteSlotSubset { @@ -211,10 +258,20 @@ public: class ScreenObjects { private: + MadsView &_owner; Common::Array<ScreenObjectEntry> _entries; public: - ScreenObjects() {} - + int _v832EC; + int _v7FECA; + int _v7FED6; + int _v8332A; + int _yp; + int _v8333C; + int _selectedObject; + int _category; + int _objectIndex; + + ScreenObjects(MadsView &owner); ScreenObjectEntry &operator[](uint idx) { assert(idx <= _entries.size()); return _entries[idx - 1]; @@ -226,6 +283,7 @@ public: int scan(int xp, int yp, int layer); int scanBackwards(int xp, int yp, int layer); void setActive(int category, int idx, bool active); + void check(bool scanFlag, bool mouseClick); }; class DynamicHotspot { @@ -251,7 +309,7 @@ private: Common::Array<DynamicHotspot> _entries; int _count; public: - bool _flag; + bool _changed; public: MadsDynamicHotspots(MadsView &owner); @@ -261,6 +319,9 @@ public: int set17(int index, int v); void remove(int index); void reset(); + void refresh() { + // TODO + } }; class MadsDirtyArea { @@ -393,6 +454,7 @@ public: MadsDynamicHotspots _dynamicHotspots; MadsSequenceList _sequenceList; MadsDirtyAreas _dirtyAreas; + MadsAction _action; int _textSpacing; uint32 _newTimeout; diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp index e78d7f865e..ca59710586 100644 --- a/engines/m4/scene.cpp +++ b/engines/m4/scene.cpp @@ -184,7 +184,7 @@ bool Scene::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &cap rightClick(x, y); break; case MEVENT_MOVE: - checkHotspotAtMousePos(x, y); + mouseMove(x, y); break; default: return false; diff --git a/engines/m4/scene.h b/engines/m4/scene.h index 633a34b549..76b99a7bcd 100644 --- a/engines/m4/scene.h +++ b/engines/m4/scene.h @@ -95,7 +95,7 @@ public: virtual void leaveScene(); virtual void loadSceneCodes(int sceneNumber, int index = 0) = 0; virtual void show(); - virtual void checkHotspotAtMousePos(int x, int y) = 0; + virtual void mouseMove(int x, int y) = 0; virtual void leftClick(int x, int y) = 0; virtual void rightClick(int x, int y) = 0; virtual void update() = 0; |