aboutsummaryrefslogtreecommitdiff
path: root/engines/mads
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mads')
-rw-r--r--engines/mads/action.cpp340
-rw-r--r--engines/mads/action.h113
-rw-r--r--engines/mads/events.cpp6
-rw-r--r--engines/mads/events.h6
-rw-r--r--engines/mads/game.cpp7
-rw-r--r--engines/mads/game.h1
-rw-r--r--engines/mads/module.mk1
-rw-r--r--engines/mads/scene.cpp1
-rw-r--r--engines/mads/scene.h3
-rw-r--r--engines/mads/scene_data.h25
10 files changed, 478 insertions, 25 deletions
diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp
new file mode 100644
index 0000000000..d27bd85a45
--- /dev/null
+++ b/engines/mads/action.cpp
@@ -0,0 +1,340 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "mads/action.h"
+#include "mads/scene.h"
+
+namespace MADS {
+
+MadsAction::MadsAction(Scene *scene) : _scene(scene) {
+ clear();
+ _currentAction = VERB_NONE;
+ _startWalkFlag = false;
+ _statusTextIndex = -1;
+ _selectedAction = 0;
+ _inProgress = false;
+}
+
+void MadsAction::clear() {
+ _v83338 = 1;
+ _actionMode = ACTMODE_NONE;
+ _actionMode2 = ACTMODE2_0;
+ _v86F42 = 0;
+ _v86F4E = 0;
+ _articleNumber = 0;
+ _lookFlag = false;
+ _v86F4A = 0;
+ _statusText[0] = '\0';
+ _selectedRow = -1;
+ _hotspotId = -1;
+ _v86F3A = -1;
+ _v86F4C = -1;
+ _action.verbId = -1;
+ _action.objectNameId = -1;
+ _action.indirectObjectId = -1;
+ _textChanged = true;
+ _walkFlag = false;
+}
+
+void MadsAction::appendVocab(int vocabId, bool capitalise) {
+ /*
+ char *s = _statusText + strlen(_statusText);
+ vocabStr = _madsVm->globals()->getVocab(vocabId);
+ strcpy(s, vocabStr);
+ if (capitalise)
+ *s = toupper(*s);
+
+ strcat(s, " ");
+ */
+}
+
+void MadsAction::set() {
+ /*
+ int hotspotCount = _madsVm->scene()->getSceneResources().hotspots->size();
+ bool flag = false; // FIXME: unused
+ 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().dynamicHotspots)[_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().dynamicHotspots)[_hotspotId].getVocabID();
+ }
+ appendVocab(_action.objectNameId);
+ }
+ }
+
+ if ((_hotspotId >= 0) && (_articleNumber > 0) && !flag) {
+ if (_articleNumber == -1) {
+ if (_v86F3A >= 0) {
+ int articleNum = 0;
+
+ if ((_v86F42 == 2) || (_v86F42 == 5)) {
+ int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId);
+ articleNum = _madsVm->globals()->getObject(objectId)->_article;
+ } else if (_v86F3A < 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 (_v86F3A >= 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 (_statusText[0] != '\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
+ uint colors = (_vm->getGameType() == GType_DragonSphere) ? 0x0300 : 0x0003;
+
+ _statusTextIndex = _owner._textDisplay.add(160 - (strWidth / 2),
+ MADS_SURFACE_HEIGHT + _owner._posAdjust.y - 13, colors, textSpacing, _statusText, font);
+ }
+ }
+
+ _textChanged = false;
+ */
+}
+
+void MadsAction::startAction() {
+ /*
+ _madsVm->_player.moveComplete();
+
+ _inProgress = true;
+ _v8453A = ABORTMODE_0;
+ _savedFields.selectedRow = _selectedRow;
+ _savedFields.articleNumber = _articleNumber;
+ _savedFields.actionMode = _actionMode;
+ _savedFields.actionMode2 = _actionMode2;
+ _savedFields.lookFlag = _lookFlag;
+ int savedHotspotId = _hotspotId;
+ int savedV86F3A = _v86F3A;
+ int savedV86F42 = _v86F42;
+
+ // Copy the action to be active
+ _activeAction = _action;
+ strcpy(_dialogTitle, _statusText);
+
+ if ((_savedFields.actionMode2 == ACTMODE2_4) && (savedV86F42 == 0))
+ _v8453A = ABORTMODE_1;
+
+ _startWalkFlag = false;
+ int hotspotId = -1;
+ HotSpotList &dynHotspots = *_madsVm->scene()->getSceneResources().dynamicHotspots;
+ HotSpotList &hotspots = *_madsVm->scene()->getSceneResources().hotspots;
+
+ if (!_savedFields.lookFlag && (_madsVm->scene()->_screenObjects._v832EC != 1)) {
+ if (_savedFields.actionMode2 == ACTMODE2_4)
+ hotspotId = savedHotspotId;
+ else if (savedV86F42 == 4)
+ hotspotId = savedV86F3A;
+
+ if (hotspotId >= hotspots.size()) {
+ HotSpot &hs = dynHotspots[hotspotId - hotspots.size()];
+ if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) {
+ if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) {
+ _startWalkFlag = true;
+ _madsVm->scene()->_destPos = _madsVm->scene()->_customDest;
+ }
+ } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) {
+ _startWalkFlag = true;
+ _madsVm->scene()->_destPos.x = hs.getFeetX();
+ _madsVm->scene()->_destPos.y = hs.getFeetY();
+ }
+ _madsVm->scene()->_destFacing = hs.getFacing();
+ hotspotId = -1;
+ }
+ }
+
+ if (hotspotId >= 0) {
+ HotSpot &hs = hotspots[hotspotId];
+ if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) {
+ if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) {
+ _startWalkFlag = true;
+ _madsVm->scene()->_destPos = _madsVm->scene()->_customDest;
+ }
+ } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) {
+ _startWalkFlag = true;
+ _madsVm->scene()->_destPos.x = hs.getFeetX();
+ _madsVm->scene()->_destPos.y = hs.getFeetY();
+ }
+ _madsVm->scene()->_destFacing = hs.getFacing();
+ }
+
+ _walkFlag = _startWalkFlag;
+ */
+}
+
+void MadsAction::checkAction() {
+ /*
+ if (isAction(kVerbLookAt) || isAction(kVerbThrow))
+ _startWalkFlag = 0;
+ */
+}
+
+bool MadsAction::isAction(int verbId, int objectNameId, int indirectObjectId) {
+ /*
+ if (_activeAction.verbId != verbId)
+ return false;
+ if ((objectNameId != 0) && (_activeAction.objectNameId != objectNameId))
+ return false;
+ if ((indirectObjectId != 0) && (_activeAction.indirectObjectId != indirectObjectId))
+ return false;
+ */
+ return true;
+}
+
+} // End of namespace MADS
diff --git a/engines/mads/action.h b/engines/mads/action.h
new file mode 100644
index 0000000000..a29d43baa0
--- /dev/null
+++ b/engines/mads/action.h
@@ -0,0 +1,113 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MADS_ACTION_H
+#define MADS_ACTION_H
+
+#include "common/scummsys.h"
+
+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 AbortTimerMode { ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2 };
+
+enum {
+ VERB_NONE = 0,
+ VERB_LOOK = 3,
+ VERB_TAKE = 4,
+ VERB_PUSH = 5,
+ VERB_OPEN = 6,
+ VERB_PUT = 7,
+ VERB_TALKTO = 8,
+ VERB_GIVE = 9,
+ VERB_PULL = 10,
+ VERB_CLOSE = 11,
+ VERB_THROW = 12,
+ VERB_WALKTO = 13
+};
+
+class Scene;
+
+struct ActionDetails {
+ int verbId;
+ int objectNameId;
+ int indirectObjectId;
+};
+
+struct MadsActionSavedFields {
+ int articleNumber;
+ int actionMode;
+ int actionMode2;
+ bool lookFlag;
+ int selectedRow;
+};
+
+class MadsAction {
+private:
+ Scene *_scene;
+ char _statusText[100];
+ char _dialogTitle[100];
+
+ void appendVocab(int vocabId, bool capitalise = false);
+public:
+ ActionDetails _action, _activeAction;
+ int _currentAction;
+ int8 _flags1, _flags2;
+ ActionMode _actionMode;
+ ActionMode2 _actionMode2;
+ int _articleNumber;
+ bool _lookFlag;
+ int _selectedRow;
+ bool _textChanged;
+ int _selectedAction;
+ bool _startWalkFlag;
+ int _statusTextIndex;
+ int _hotspotId;
+ MadsActionSavedFields _savedFields;
+ bool _walkFlag;
+
+ // Unknown fields
+ int16 _v86F3A;
+ int16 _v86F42;
+ int16 _v86F4E;
+ bool _v86F4A;
+ int16 _v86F4C;
+ int _v83338;
+ bool _inProgress;
+ AbortTimerMode _v8453A;
+
+public:
+ MadsAction(Scene *scene);
+
+ void clear();
+ void set();
+ const char *statusText() const { return _statusText; }
+ void refresh();
+ void startAction();
+ void checkAction();
+ bool isAction(int verbId, int objectNameId = 0, int indirectObjectId = 0);
+};
+
+} // End of namespace MADS
+
+#endif /* MADS_ACTION_H */
diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp
index 8f177f2c20..5d905ca8d6 100644
--- a/engines/mads/events.cpp
+++ b/engines/mads/events.cpp
@@ -157,4 +157,10 @@ void EventsManager::delay(int cycles) {
}
}
+void EventsManager::initVars() {
+ _mousePos = Common::Point(-1, -1);
+ _vD4 = _vCC;
+ _vD2 = _vD8 = 0;
+}
+
} // End of namespace MADS
diff --git a/engines/mads/events.h b/engines/mads/events.h
index 0e990c5258..2a8ae84e6a 100644
--- a/engines/mads/events.h
+++ b/engines/mads/events.h
@@ -42,6 +42,10 @@ private:
uint32 _gameCounter;
uint32 _priorFrameTime;
Common::Point _mousePos;
+ int _vCC;
+ int _vD4;
+ int _vD8;
+ int _vD2;
/**
* Updates the cursor image when the current cursor changes
@@ -121,6 +125,8 @@ public:
* Gets the current frame counter
*/
uint32 getFrameCounter() const { return _gameCounter; }
+
+ void initVars();
};
} // End of namespace MADS
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
index 08d548e235..a3351f5a7b 100644
--- a/engines/mads/game.cpp
+++ b/engines/mads/game.cpp
@@ -24,10 +24,11 @@
#include "mads/mads.h"
#include "mads/game.h"
#include "mads/game_data.h"
-#include "mads/nebular/game_nebular.h"
+#include "mads/events.h"
#include "mads/graphics.h"
#include "mads/msurface.h"
#include "mads/resources.h"
+#include "mads/nebular/game_nebular.h"
namespace MADS {
@@ -170,6 +171,10 @@ void Game::sectionLoop() {
_playerSpritesFlag = false;
}
+ _vm->_events->initVars();
+ _scene._v1A = -1;
+ _scene._v1C = -1;
+ _objectHiliteVocabIdx = -1;
// TODO: main section loop logic goes here
diff --git a/engines/mads/game.h b/engines/mads/game.h
index b8add9ab00..562e0b99d0 100644
--- a/engines/mads/game.h
+++ b/engines/mads/game.h
@@ -67,6 +67,7 @@ protected:
int _v6;
Common::String _aaName;
bool _playerSpritesFlag;
+ int _objectHiliteVocabIdx;
/**
* Constructor
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index 94c231e206..f27b808099 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
nebular/sound_nebular.o \
nebular/nebular_scenes.o \
nebular/nebular_scenes8.o \
+ action.o \
animation.o \
assets.o \
compression.o \
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index 23c118eaf2..90f5cbd0cf 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -38,6 +38,7 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _spriteSlots(vm) {
_animFlag = false;
_animVal1 = 0;
_depthStyle = 0;
+ _v1A = _v1C = 0;
_verbList.push_back(VerbInit(VERB_LOOK, 2, 0));
_verbList.push_back(VerbInit(VERB_TAKE, 2, 0));
diff --git a/engines/mads/scene.h b/engines/mads/scene.h
index 4968291146..bafe499d09 100644
--- a/engines/mads/scene.h
+++ b/engines/mads/scene.h
@@ -95,6 +95,8 @@ public:
int _screenY;
int _interfaceY;
int _spritesCount;
+ int _v1A;
+ int _v1C;
/**
* Constructor
@@ -154,6 +156,7 @@ public:
*/
void loadVocab();
+
/**
* Clear the data for the scene
*/
diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h
index 557a6aab2b..6be54cf3e1 100644
--- a/engines/mads/scene_data.h
+++ b/engines/mads/scene_data.h
@@ -28,6 +28,7 @@
#include "common/str.h"
#include "common/str-array.h"
#include "common/rect.h"
+#include "mads/action.h"
#include "mads/assets.h"
#include "mads/game_data.h"
@@ -36,36 +37,12 @@ namespace MADS {
class MADSEngine;
class Scene;
-enum {
- VERB_LOOK = 3,
- VERB_TAKE = 4,
- VERB_PUSH = 5,
- VERB_OPEN = 6,
- VERB_PUT = 7,
- VERB_TALKTO = 8,
- VERB_GIVE = 9,
- VERB_PULL = 10,
- VERB_CLOSE = 11,
- VERB_THROW = 12,
- VERB_WALKTO = 13
-};
-
-enum MadsActionMode { ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6 };
-enum MadsActionMode2 { ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_4 = 4, ACTMODE2_5 = 5 };
-enum AbortTimerMode { ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2 };
-
#define MADS_INTERFACE_HEIGHT 44
#define MADS_SCENE_HEIGHT 156
#define DEPTH_BANDS_SIZE 15
#define MAX_ROUTE_NODES 22
-struct ActionDetails {
- int verbId;
- int objectNameId;
- int indirectObjectId;
-};
-
class VerbInit {
public:
int _id;