aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2010-01-31 00:42:47 +0000
committerPaul Gilbert2010-01-31 00:42:47 +0000
commitdc8ff8c9d4405d5762a90ec2c69c5e7293581bce (patch)
tree70582cda19df7863dbe32a4a46561eb7de6a927a /engines
parent5b7d4305502dd02af32182541f60e82a3c3d1b26 (diff)
downloadscummvm-rg350-dc8ff8c9d4405d5762a90ec2c69c5e7293581bce.tar.gz
scummvm-rg350-dc8ff8c9d4405d5762a90ec2c69c5e7293581bce.tar.bz2
scummvm-rg350-dc8ff8c9d4405d5762a90ec2c69c5e7293581bce.zip
Further work on separating the scene logic for MADS and M4
svn-id: r47732
Diffstat (limited to 'engines')
-rw-r--r--engines/m4/actor.cpp4
-rw-r--r--engines/m4/converse.cpp6
-rw-r--r--engines/m4/globals.cpp4
-rw-r--r--engines/m4/gui.h10
-rw-r--r--engines/m4/m4.cpp23
-rw-r--r--engines/m4/m4.h5
-rw-r--r--engines/m4/m4_menus.cpp14
-rw-r--r--engines/m4/m4_views.cpp16
-rw-r--r--engines/m4/m4_views.h6
-rw-r--r--engines/m4/mads_views.cpp378
-rw-r--r--engines/m4/mads_views.h84
-rw-r--r--engines/m4/module.mk1
-rw-r--r--engines/m4/scene.cpp420
-rw-r--r--engines/m4/scene.h79
14 files changed, 581 insertions, 469 deletions
diff --git a/engines/m4/actor.cpp b/engines/m4/actor.cpp
index e80bcac6ca..102001713f 100644
--- a/engines/m4/actor.cpp
+++ b/engines/m4/actor.cpp
@@ -149,11 +149,11 @@ void Inventory::moveObject(char* name, int32 scene) {
}
void Inventory::addToBackpack(uint32 objectIndex) {
- _vm->_interfaceView->inventoryAdd(_inventory[objectIndex]->name, "", _inventory[objectIndex]->icon);
+ _m4Vm->scene()->getInterface()->inventoryAdd(_inventory[objectIndex]->name, "", _inventory[objectIndex]->icon);
}
void Inventory::removeFromBackpack(uint32 objectIndex) {
- _vm->_interfaceView->inventoryRemove(_inventory[objectIndex]->name);
+ _m4Vm->scene()->getInterface()->inventoryRemove(_inventory[objectIndex]->name);
}
bool Inventory::isInCurrentScene(char* name) {
diff --git a/engines/m4/converse.cpp b/engines/m4/converse.cpp
index 7bdc289742..18d61ef7ce 100644
--- a/engines/m4/converse.cpp
+++ b/engines/m4/converse.cpp
@@ -343,7 +343,7 @@ void Converse::startConversation(const char *convName, bool showConverseBox, Con
_playerCommandsAllowed = _vm->_player->commandsAllowed;
if (_vm->isM4()) // TODO: remove (interface not implemented yet in MADS games)
- _interfaceWasVisible = _vm->_interfaceView->isVisible();
+ _interfaceWasVisible = _m4Vm->scene()->getInterface()->isVisible();
_vm->_player->setCommandsAllowed(false);
_style = style;
@@ -352,7 +352,7 @@ void Converse::startConversation(const char *convName, bool showConverseBox, Con
_vm->_mouse->lockCursor(CURSOR_ARROW);
if (_interfaceWasVisible)
- _vm->_interfaceView->hide();
+ _m4Vm->scene()->getInterface()->hide();
_vm->_conversationView->setNode(0);
_vm->_conversationView->show();
@@ -368,7 +368,7 @@ void Converse::endConversation() {
_offsetMap.clear();
_vm->_player->setCommandsAllowed(_playerCommandsAllowed);
if (_interfaceWasVisible)
- _vm->_interfaceView->show();
+ _m4Vm->scene()->getInterface()->show();
}
void Converse::loadConversation(const char *convName) {
diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp
index 06bbcec9c1..39226f0ebc 100644
--- a/engines/m4/globals.cpp
+++ b/engines/m4/globals.cpp
@@ -271,7 +271,7 @@ Globals::Globals(MadsM4Engine *vm): _vm(vm) {
}
bool Globals::isInterfaceVisible() {
- return _vm->_interfaceView->isVisible();
+ return _m4Vm->scene()->getInterface()->isVisible();
}
/*--------------------------------------------------------------------------*/
@@ -434,7 +434,7 @@ void Player::setCommandsAllowed(bool value) {
if (value) {
// Player commands are enabled again
_vm->_mouse->lockCursor(CURSOR_ARROW);
- //_vm->_interfaceView->cancelSentence();
+ //_m4Vm->scene()->getInterface()->cancelSentence();
} else {
// Player commands are disabled, so show hourglass cursor
_vm->_mouse->lockCursor(CURSOR_HOURGLASS);
diff --git a/engines/m4/gui.h b/engines/m4/gui.h
index d03c092602..9d0f3e3f17 100644
--- a/engines/m4/gui.h
+++ b/engines/m4/gui.h
@@ -441,6 +441,16 @@ public:
void keyMouseCollision() {}
};
+class GameInterfaceView: public View {
+public:
+ GameInterfaceView(MadsM4Engine *vm, const Common::Rect &rect): View(vm, rect) {};
+ ~GameInterfaceView() {};
+
+ virtual void initialise() {};
+ virtual void setSelectedObject(int objectNumber) {};
+ virtual void addObjectToInventory(int objectNumber) {};
+};
+
}
#endif
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
index fef646325c..7b3a84e98d 100644
--- a/engines/m4/m4.cpp
+++ b/engines/m4/m4.cpp
@@ -169,7 +169,6 @@ Common::Error MadsM4Engine::run() {
_font = new Font(this);
if (getGameType() == GType_Burger) {
_actor = new Actor(this);
- _interfaceView = new GameInterfaceView(this);
_conversationView = new ConversationView(this);
} else {
_actor = NULL;
@@ -352,8 +351,6 @@ Common::Error M4Engine::run() {
burger_inventory[i].icon);
_inventory->addToBackpack(i); // debug: this adds ALL objects to the player's backpack
}
-
- _viewManager->addView(_interfaceView);
}
// Show intro
@@ -420,6 +417,8 @@ Common::Error M4Engine::run() {
_kernel->roomInit();
+ _scene->show();
+
#ifdef INTRO_TEST
if (_kernel->currentRoom == 951) {
curPart = 0;
@@ -516,17 +515,17 @@ Common::Error MadsEngine::run() {
_mouse->setCursorNum(0);
// Load MADS data files
- MadsGlobals *globals = (MadsGlobals *)_globals;
- globals->loadMadsVocab(); // vocab.dat
- globals->loadMadsQuotes(); // quotes.dat
- globals->loadMadsMessagesInfo(); // messages.dat
- globals->loadMadsObjects();
+ MadsGlobals *globs = (MadsGlobals *)_globals;
+ globs->loadMadsVocab(); // vocab.dat
+ globs->loadMadsQuotes(); // quotes.dat
+ globs->loadMadsMessagesInfo(); // messages.dat
+ globs->loadMadsObjects();
// Setup globals
- globals->easyMouse = true;
- globals->invObjectsStill = false;
- globals->textWindowStill = false;
- globals->storyMode = 0;
+ globs->easyMouse = true;
+ globs->invObjectsStill = false;
+ globs->textWindowStill = false;
+ globs->storyMode = 0;
// Test code to dump all messages to the console
//for (int i = 0; i < _globals->getMessagesSize(); i++)
diff --git a/engines/m4/m4.h b/engines/m4/m4.h
index 29f3acce34..80aba64188 100644
--- a/engines/m4/m4.h
+++ b/engines/m4/m4.h
@@ -80,7 +80,7 @@ class Scene;
class ViewManager;
class View;
class Inventory;
-class GameInterfaceView;
+class M4InterfaceView;
class ConversationView;
class Actor;
class Converse;
@@ -190,7 +190,6 @@ public:
Dialogs *_dialogs;
M4Surface *_screen;
Inventory *_inventory;
- GameInterfaceView *_interfaceView;
ConversationView *_conversationView;
Sound *_sound;
Rails *_rails;
@@ -199,6 +198,8 @@ public:
WoodScript *_ws;
Animation *_animation;
Common::RandomSource *_random;
+
+ Scene *scene() { return _scene; };
};
class MadsEngine: public MadsM4Engine {
diff --git a/engines/m4/m4_menus.cpp b/engines/m4/m4_menus.cpp
index e48e076066..118b09f50b 100644
--- a/engines/m4/m4_menus.cpp
+++ b/engines/m4/m4_menus.cpp
@@ -328,9 +328,9 @@ OrionMenuView::OrionMenuView(MadsM4Engine *Vm, int x, int y, MenuType menuType,
_calledFromMainMenu = calledFromMainMenu;
_loadSaveFromHotkey = loadSaveFromHotkey;
- _interfaceWasVisible = _vm->_interfaceView->isVisible();
+ _interfaceWasVisible = _m4Vm->scene()->getInterface()->isVisible();
if (_interfaceWasVisible)
- _vm->_interfaceView->hide();
+ _m4Vm->scene()->getInterface()->hide();
_vm->_mouse->setCursorNum(CURSOR_ARROW);
@@ -496,11 +496,11 @@ M4Surface *OrionMenuView::createThumbnail() {
// Translate the game interface view - since it's using standard colors that can't be
// averaged, simply take the top left pixel of every 3x3 pixel block
- _vm->_interfaceView->onRefresh(NULL, &srcSurface);
- destP = result->getBasePtr(0, 0) + (_vm->_screen->width() / 3) * (_vm->_interfaceView->bounds().top / 3);
+ _m4Vm->scene()->getInterface()->onRefresh(NULL, &srcSurface);
+ destP = result->getBasePtr(0, 0) + (_vm->_screen->width() / 3) * (_m4Vm->scene()->getInterface()->bounds().top / 3);
- int yStart = _vm->_interfaceView->bounds().top;
- int yEnd = MIN(_vm->_screen->height() - 1, (int) _vm->_interfaceView->bounds().bottom - 1);
+ int yStart = _m4Vm->scene()->getInterface()->bounds().top;
+ int yEnd = MIN(_vm->_screen->height() - 1, (int) _m4Vm->scene()->getInterface()->bounds().bottom - 1);
for (int yCtr = yStart; yCtr <= yEnd; yCtr += 3) {
srcP = (byte *)srcSurface.getBasePtr(0, yCtr) + (yCtr * _vm->_screen->width());
@@ -526,7 +526,7 @@ void OrionMenuView::destroyView() {
engine->_palette->fadeFromGreen(M4_DIALOG_FADE_STEPS, M4_DIALOG_FADE_DELAY, fadeToBlack);
if (interfaceVisible)
- engine->_interfaceView->show();
+ engine->scene()->showInterface();
}
}
diff --git a/engines/m4/m4_views.cpp b/engines/m4/m4_views.cpp
index 93ff74b879..3d633cef0d 100644
--- a/engines/m4/m4_views.cpp
+++ b/engines/m4/m4_views.cpp
@@ -127,7 +127,7 @@ bool GUIInventory::onEvent(M4EventType eventType, int32 param, int x, int y, GUI
if (result) {
for (int i = 0; i < overIndex + _scrollPosition; i++)
++curItem;
- _vm->_interfaceView->setStatusText(curItem->get()->name);
+ _m4Vm->scene()->getInterface()->setStatusText(curItem->get()->name);
}
}
@@ -218,8 +218,8 @@ const char *INTERFACE_SERIES = "999intr";
#define SPR(x) _sprites->getFrame(x)
-GameInterfaceView::GameInterfaceView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, vm->_screen->height() - INTERFACE_HEIGHT,
+M4InterfaceView::M4InterfaceView(MadsM4Engine *vm):
+ GameInterfaceView(vm, Common::Rect(0, vm->_screen->height() - INTERFACE_HEIGHT,
vm->_screen->width(), vm->_screen->height())),
_statusText(GUITextField(this, Common::Rect(200, 1, 450, 21))),
_inventory(GUIInventory(this, vm, Common::Rect(188, 22, 539, 97), 9, 1, 39, 75, 3)) {
@@ -256,11 +256,11 @@ GameInterfaceView::GameInterfaceView(MadsM4Engine *vm):
#undef SPR
-GameInterfaceView::~GameInterfaceView() {
+M4InterfaceView::~M4InterfaceView() {
delete _sprites;
}
-void GameInterfaceView::setHighlightedButton(int index) {
+void M4InterfaceView::setHighlightedButton(int index) {
if (index == _highlightedIndex)
return;
@@ -268,7 +268,7 @@ void GameInterfaceView::setHighlightedButton(int index) {
_highlightedIndex = index;
}
-bool GameInterfaceView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
+bool M4InterfaceView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
static bool selectionFlag = false;
if (eventType == MEVENT_LEFT_RELEASE)
selectionFlag = false;
@@ -287,7 +287,7 @@ bool GameInterfaceView::onEvent(M4EventType eventType, int32 param, int x, int y
if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
_vm->_mouse->getCursorNum() != CURSOR_TAKE &&
_vm->_mouse->getCursorNum() != CURSOR_USE &&
- _vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
+ _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
if (_vm->_mouse->getCursorNum() != 0)
_vm->_mouse->setCursorNum(0);
}
@@ -330,7 +330,7 @@ bool GameInterfaceView::onEvent(M4EventType eventType, int32 param, int x, int y
return true;
}
-void GameInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
+void M4InterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
clear();
_statusText.onRefresh();
diff --git a/engines/m4/m4_views.h b/engines/m4/m4_views.h
index 02e34fead0..0cf8ceac5d 100644
--- a/engines/m4/m4_views.h
+++ b/engines/m4/m4_views.h
@@ -87,7 +87,7 @@ public:
void setVisible(bool value) { _visible = value; }
};
-class GameInterfaceView: public View {
+class M4InterfaceView: public GameInterfaceView {
typedef Common::List<Common::SharedPtr<GUIButton> > ButtonList;
typedef ButtonList::iterator ButtonsIterator;
public:
@@ -100,8 +100,8 @@ public:
private:
void setHighlightedButton(int index);
public:
- GameInterfaceView(MadsM4Engine *vm);
- ~GameInterfaceView();
+ M4InterfaceView(MadsM4Engine *vm);
+ ~M4InterfaceView();
void onRefresh(RectList *rects, M4Surface *destSurface);
bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp
new file mode 100644
index 0000000000..d4d3bc53cb
--- /dev/null
+++ b/engines/m4/mads_views.cpp
@@ -0,0 +1,378 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "m4/m4_views.h"
+#include "m4/dialogs.h"
+#include "m4/events.h"
+#include "m4/font.h"
+#include "m4/globals.h"
+#include "m4/m4.h"
+#include "m4/staticres.h"
+
+namespace M4 {
+
+static const int INV_ANIM_FRAME_SPEED = 8;
+static const int INVENTORY_X = 160;
+static const int INVENTORY_Y = 159;
+static const int SCROLLER_DELAY = 200;
+
+/*--------------------------------------------------------------------------
+ * MadsInterfaceView handles the user interface section at the bottom of
+ * game screens in MADS games
+ *--------------------------------------------------------------------------
+ */
+
+MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): GameInterfaceView(vm,
+ Common::Rect(0, MADS_SURFACE_HEIGHT, vm->_screen->width(), vm->_screen->height())) {
+ _screenType = VIEWID_INTERFACE;
+ _highlightedElement = -1;
+ _topIndex = 0;
+ _selectedObject = -1;
+ _cheatKeyCtr = 0;
+
+ _objectSprites = NULL;
+ _objectPalData = NULL;
+
+ /* Set up the rect list for screen elements */
+ // Actions
+ for (int i = 0; i < 10; ++i)
+ _screenObjects.addRect((i / 5) * 32 + 1, (i % 5) * 8 + MADS_SURFACE_HEIGHT + 2,
+ ((i / 5) + 1) * 32 + 3, ((i % 5) + 1) * 8 + MADS_SURFACE_HEIGHT + 2);
+
+ // Scroller elements (up arrow, scroller, down arrow)
+ _screenObjects.addRect(73, 160, 82, 167);
+ _screenObjects.addRect(73, 168, 82, 190);
+ _screenObjects.addRect(73, 191, 82, 198);
+
+ // Inventory object names
+ for (int i = 0; i < 5; ++i)
+ _screenObjects.addRect(89, 158 + i * 8, 160, 166 + i * 8);
+
+ // Full rectangle area for all vocab actions
+ for (int i = 0; i < 5; ++i)
+ _screenObjects.addRect(239, 158 + i * 8, 320, 166 + i * 8);
+}
+
+MadsInterfaceView::~MadsInterfaceView() {
+ delete _objectSprites;
+}
+
+void MadsInterfaceView::setFontMode(InterfaceFontMode newMode) {
+ switch (newMode) {
+ case ITEM_NORMAL:
+ _vm->_font->setColors(4, 4, 0xff);
+ break;
+ case ITEM_HIGHLIGHTED:
+ _vm->_font->setColors(5, 5, 0xff);
+ break;
+ case ITEM_SELECTED:
+ _vm->_font->setColors(6, 6, 0xff);
+ break;
+ }
+}
+
+void MadsInterfaceView::initialise() {
+ // Build up the inventory list
+ _inventoryList.clear();
+
+ for (uint i = 0; i < _madsVm->globals()->getObjectsSize(); ++i) {
+ MadsObject *obj = _madsVm->globals()->getObject(i);
+ if (obj->roomNumber == PLAYER_INVENTORY)
+ _inventoryList.push_back(i);
+ }
+
+ // If the inventory has at least one object, select it
+ if (_inventoryList.size() > 0)
+ setSelectedObject(_inventoryList[0]);
+}
+
+void MadsInterfaceView::setSelectedObject(int objectNumber) {
+ char resName[80];
+
+ // Load inventory resource
+ if (_objectSprites) {
+ _vm->_palette->deleteRange(_objectPalData);
+ delete _objectSprites;
+ }
+
+ // Check to make sure the object is in the inventory, and also visible on-screen
+ int idx = _inventoryList.indexOf(objectNumber);
+ if (idx == -1) {
+ // Object wasn't found, so return
+ _selectedObject = -1;
+ return;
+ }
+
+ // Found the object
+ if (idx < _topIndex)
+ _topIndex = idx;
+ else if (idx >= (_topIndex + 5))
+ _topIndex = MAX(0, idx - 4);
+
+ _selectedObject = objectNumber;
+ sprintf(resName, "*OB%.3dI.SS", objectNumber);
+
+ Common::SeekableReadStream *data = _vm->res()->get(resName);
+ _objectSprites = new SpriteAsset(_vm, data, data->size(), resName);
+ _vm->res()->toss(resName);
+
+ // Slot it into available palette space
+ _objectPalData = _objectSprites->getRgbList();
+ _vm->_palette->addRange(_objectPalData);
+ _objectSprites->translate(_objectPalData, true);
+
+ _objectFrameNumber = 0;
+}
+
+void MadsInterfaceView::addObjectToInventory(int objectNumber) {
+ if (_inventoryList.indexOf(objectNumber) == -1) {
+ _madsVm->globals()->getObject(objectNumber)->roomNumber = PLAYER_INVENTORY;
+ _inventoryList.push_back(objectNumber);
+ }
+
+ setSelectedObject(objectNumber);
+}
+
+void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
+ _vm->_font->setFont(FONT_INTERFACE_MADS);
+ char buffer[100];
+
+ // Check to see if any dialog is currently active
+ bool dialogVisible = _vm->_viewManager->getView(LAYER_DIALOG) != NULL;
+
+ // Highlighting logic for action list
+ int actionIndex = 0;
+ for (int x = 0; x < 2; ++x) {
+ for (int y = 0; y < 5; ++y, ++actionIndex) {
+ // Determine the font colour depending on whether an item is selected. Note that the first action,
+ // 'Look', is always 'selected', even when another action is clicked on
+ setFontMode((_highlightedElement == actionIndex) ? ITEM_HIGHLIGHTED :
+ ((actionIndex == 0) ? ITEM_SELECTED : ITEM_NORMAL));
+
+ // Get the verb action and capitalise it
+ const char *verbStr = _madsVm->globals()->getVocab(kVerbLook + actionIndex);
+ strcpy(buffer, verbStr);
+ if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
+
+ // Display the verb
+ const Common::Rect r(_screenObjects[actionIndex]);
+ _vm->_font->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
+ }
+ }
+
+ // Check for highlighting of the scrollbar controls
+ if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_SCROLLER) || (_highlightedElement == SCROLL_DOWN)) {
+ // Highlight the control's borders
+ const Common::Rect r(_screenObjects[_highlightedElement]);
+ destSurface->frameRect(r, 5);
+ }
+
+ // Draw the horizontal line in the scroller representing the current top selected
+ const Common::Rect scroller(_screenObjects[SCROLL_SCROLLER]);
+ int yP = (_inventoryList.size() < 2) ? 0 : (scroller.height() - 5) * _topIndex / (_inventoryList.size() - 1);
+ destSurface->setColor(4);
+ destSurface->hLine(scroller.left + 2, scroller.right - 3, scroller.top + 2 + yP);
+
+ // List inventory items
+ for (uint i = 0; i < 5; ++i) {
+ if ((_topIndex + i) >= _inventoryList.size())
+ break;
+
+ const char *descStr = _madsVm->globals()->getVocab(_madsVm->globals()->getObject(
+ _inventoryList[_topIndex + i])->descId);
+ strcpy(buffer, descStr);
+ if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
+
+ const Common::Rect r(_screenObjects[INVLIST_START + i]);
+
+ // Set the highlighting of the inventory item
+ if (_highlightedElement == (int)(INVLIST_START + i)) setFontMode(ITEM_HIGHLIGHTED);
+ else if (_selectedObject == _inventoryList[_topIndex + i]) setFontMode(ITEM_SELECTED);
+ else setFontMode(ITEM_NORMAL);
+
+ // Write out it's description
+ _vm->_font->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
+ }
+
+ // Handle the display of any currently selected object
+ if (_objectSprites) {
+ // Display object sprite. Note that the frame number isn't used directly, because it would result
+ // in too fast an animation
+ M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED);
+ spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, 0);
+
+ if (!_madsVm->globals()->invObjectsStill && !dialogVisible) {
+ // If objetcs are to animated, move to the next frame
+ if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED))
+ _objectFrameNumber = 0;
+ }
+
+ // List the vocab actions for the currently selected object
+ MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
+ int yIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1);
+
+ for (int i = 0; i < obj->vocabCount; ++i) {
+ const Common::Rect r(_screenObjects[VOCAB_START + i]);
+
+ // Get the vocab description and capitalise it
+ const char *descStr = _madsVm->globals()->getVocab(obj->vocabList[i].vocabId);
+ strcpy(buffer, descStr);
+ if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
+
+ // Set the highlighting and display the entry
+ setFontMode((i == yIndex) ? ITEM_HIGHLIGHTED : ITEM_NORMAL);
+ _vm->_font->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
+ }
+ }
+}
+
+bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
+ // If the mouse isn't being held down, then reset the repeated scroll timer
+ if (eventType != MEVENT_LEFT_HOLD)
+ _nextScrollerTicks = 0;
+
+ // Handle various event types
+ switch (eventType) {
+ case MEVENT_MOVE:
+ // If the cursor isn't in "wait mode", don't do any processing
+ if (_vm->_mouse->getCursorNum() == CURSOR_WAIT)
+ return true;
+
+ // Ensure the cursor is the standard arrow
+ _vm->_mouse->setCursorNum(CURSOR_ARROW);
+
+ // Check if any interface element is currently highlighted
+ _highlightedElement = _screenObjects.find(Common::Point(x, y));
+
+ return true;
+
+ case MEVENT_LEFT_CLICK:
+ // Left mouse click
+ // Check if an inventory object was selected
+ if ((_highlightedElement >= INVLIST_START) && (_highlightedElement < (INVLIST_START + 5))) {
+ // Ensure there is an inventory item listed in that cell
+ uint idx = _highlightedElement - INVLIST_START;
+ if ((_topIndex + idx) < _inventoryList.size()) {
+ // Set the selected object
+ setSelectedObject(_inventoryList[_topIndex + idx]);
+ }
+ } else if ((_highlightedElement >= ACTIONS_START) && (_highlightedElement < (ACTIONS_START + 10))) {
+ // A standard action was selected
+ _vm->_scene->setAction(kVerbLook + (_highlightedElement - ACTIONS_START));
+ } else if ((_highlightedElement >= VOCAB_START) && (_highlightedElement < (VOCAB_START + 5))) {
+ // A vocab action was selected
+ MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
+ int vocabIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1);
+ if (vocabIndex >= 0)
+ _vm->_scene->setAction(obj->vocabList[vocabIndex].vocabId, _selectedObject);
+ }
+
+ return true;
+
+ case MEVENT_LEFT_HOLD:
+ // Left mouse hold
+ // Handle the scroller - the up/down buttons allow for multiple actions whilst the mouse is held down
+ if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_DOWN)) {
+ if ((_nextScrollerTicks == 0) || (g_system->getMillis() >= _nextScrollerTicks)) {
+ // Handle scroll up/down action
+ _nextScrollerTicks = g_system->getMillis() + SCROLLER_DELAY;
+
+ if ((_highlightedElement == SCROLL_UP) && (_topIndex > 0))
+ --_topIndex;
+ if ((_highlightedElement == SCROLL_DOWN) && (_topIndex < (int)(_inventoryList.size() - 1)))
+ ++_topIndex;
+ }
+ }
+ return true;
+
+ case MEVENT_LEFT_DRAG:
+ // Left mouse drag
+ // Handle the the the scroller area that can be dragged to adjust the top displayed index
+ if (_highlightedElement == SCROLL_SCROLLER) {
+ // Calculate the new top index based on the Y position
+ const Common::Rect r(_screenObjects[SCROLL_SCROLLER]);
+ _topIndex = CLIP((int)(_inventoryList.size() - 1) * (y - r.top - 2) / (r.height() - 5),
+ 0, (int)_inventoryList.size() - 1);
+ }
+ return true;
+
+ case KEVENT_KEY:
+ if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
+ handleCheatKey(param1);
+ handleKeypress(param1);
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool MadsInterfaceView::handleCheatKey(int32 keycode) {
+ switch (keycode) {
+ case Common::KEYCODE_SPACE:
+ // TODO: Move player to current destination
+ return true;
+
+ case Common::KEYCODE_t | (Common::KEYCODE_LALT):
+ case Common::KEYCODE_t | (Common::KEYCODE_RALT):
+ {
+ // Teleport to room
+ //Scene *sceneView = (Scene *)vm->_viewManager->getView(VIEWID_SCENE);
+
+
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+const char *CHEAT_SEQUENCE = "widepipe";
+
+bool MadsInterfaceView::handleKeypress(int32 keycode) {
+ int flags = keycode >> 24;
+ int kc = keycode & 0xffff;
+
+ // Capitalise the letter if necessary
+ if (_cheatKeyCtr < CHEAT_SEQUENCE_MAX) {
+ if ((flags == Common::KBD_CTRL) && (kc == CHEAT_SEQUENCE[_cheatKeyCtr])) {
+ ++_cheatKeyCtr;
+ if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
+ Dialog::display(_vm, 22, cheatingEnabledDesc);
+ return true;
+ } else {
+ _cheatKeyCtr = 0;
+ }
+ }
+
+ return false;
+}
+
+} // End of namespace M4
diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h
new file mode 100644
index 0000000000..3fbd20c2b1
--- /dev/null
+++ b/engines/m4/mads_views.h
@@ -0,0 +1,84 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef M4_MADS_VIEWS_H
+#define M4_MADS_VIEWS_H
+
+#include "m4/gui.h"
+#include "m4/viewmgr.h"
+#include "common/rect.h"
+#include "common/list.h"
+#include "common/ptr.h"
+
+namespace M4 {
+
+class IntegerList: public Common::Array<int> {
+public:
+ int indexOf(int v) {
+ for (uint i = 0; i < size(); ++i)
+ if (operator [](i) == v)
+ return i;
+ return -1;
+ }
+};
+
+enum InterfaceFontMode {ITEM_NORMAL, ITEM_HIGHLIGHTED, ITEM_SELECTED};
+
+enum InterfaceObjects {ACTIONS_START = 0, SCROLL_UP = 10, SCROLL_SCROLLER = 11, SCROLL_DOWN = 12,
+ INVLIST_START = 13, VOCAB_START = 18};
+
+class MadsInterfaceView: public GameInterfaceView {
+private:
+ IntegerList _inventoryList;
+ RectList _screenObjects;
+ int _highlightedElement;
+ int _topIndex;
+ uint32 _nextScrollerTicks;
+ int _cheatKeyCtr;
+
+ // Object display fields
+ int _selectedObject;
+ SpriteAsset *_objectSprites;
+ RGBList *_objectPalData;
+ int _objectFrameNumber;
+
+ void setFontMode(InterfaceFontMode newMode);
+ bool handleCheatKey(int32 keycode);
+ bool handleKeypress(int32 keycode);
+public:
+ MadsInterfaceView(MadsM4Engine *vm);
+ ~MadsInterfaceView();
+
+ virtual void initialise();
+ virtual void setSelectedObject(int objectNumber);
+ virtual void addObjectToInventory(int objectNumber);
+
+ void onRefresh(RectList *rects, M4Surface *destSurface);
+ bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
+};
+
+}
+
+#endif
diff --git a/engines/m4/module.mk b/engines/m4/module.mk
index 31746be5af..f6b9fa01cc 100644
--- a/engines/m4/module.mk
+++ b/engines/m4/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS = \
m4_views.o \
mads_anim.o \
mads_menus.o \
+ mads_views.o \
midi.o \
rails.o \
resource.o \
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
index ca4ba732ee..6d4c4ae64d 100644
--- a/engines/m4/scene.cpp
+++ b/engines/m4/scene.cpp
@@ -33,17 +33,12 @@
#include "m4/rails.h"
#include "m4/font.h"
#include "m4/m4_views.h"
+#include "m4/mads_views.h"
#include "m4/compression.h"
#include "m4/staticres.h"
namespace M4 {
-static const int INV_ANIM_FRAME_SPEED = 8;
-static const int INVENTORY_X = 160;
-static const int INVENTORY_Y = 159;
-static const int SCROLLER_DELAY = 200;
-
-
Scene::Scene(MadsM4Engine *vm): View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
_screenType = VIEWID_SCENE;
@@ -56,7 +51,6 @@ Scene::Scene(MadsM4Engine *vm): View(vm, Common::Rect(0, 0, vm->_screen->width()
_interfacePal = NULL;
_interfaceSurface = NULL;
_inverseColorTable = NULL;
- strcpy(_statusText, "");
_vm->_rails->setCodeSurface(_codeSurface);
}
@@ -98,6 +92,14 @@ void Scene::show() {
_vm->_viewManager->addView(this);
}
+void Scene::showInterface() {
+ _vm->_viewManager->addView(_interfaceSurface);
+}
+
+void Scene::hideInterface() {
+ _vm->_viewManager->deleteView(_interfaceSurface);
+}
+
void Scene::loadSceneResources(int sceneNumber) {
char filename[kM4MaxFilenameSize];
int i = 0, x = 0, y = 0;
@@ -280,28 +282,6 @@ void Scene::playIntro() {
}
-void Scene::update() {
- // TODO: Needs a proper implementation
- // NOTE: Don't copy the background when in M4 mode or WoodScript anims won't be shown
- if (!_vm->isM4()) {
- _backgroundSurface->copyTo(this);
-
- // Handle display of any status text
- if (_statusText[0]) {
- // Text colors are inverted in Dragonsphere
- if (_vm->getGameType() == GType_DragonSphere)
- _vm->_font->setColors(_vm->_palette->BLACK, _vm->_palette->WHITE, _vm->_palette->BLACK);
- else
- _vm->_font->setColors(_vm->_palette->WHITE, _vm->_palette->BLACK, _vm->_palette->BLACK);
-
- _vm->_font->setFont(FONT_MAIN_MADS);
- _vm->_font->writeString(this, _statusText, (width() - _vm->_font->getWidth(_statusText)) / 2, 142, 0);
- }
-
- _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height());
- }
-}
-
void Scene::onRefresh(RectList *rects, M4Surface *destSurface) {
update();
View::onRefresh(rects, destSurface);
@@ -435,6 +415,7 @@ void Scene::showMADSV2TextBox(char *text, int x, int y, char *faceName) {
M4Scene::M4Scene(M4Engine *vm): Scene(vm) {
_vm = vm;
_sceneSprites = NULL;
+ _interfaceSurface = new M4InterfaceView(vm);
}
M4Scene::~M4Scene() {
@@ -460,7 +441,7 @@ void M4Scene::loadScene(int sceneNumber) {
if (_vm->getGameType() == GType_Burger &&
sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER)
- _vm->_interfaceView->setStatusText("");
+ setStatusText("");
// Load scene def file (*.CHK)
loadSceneResources(sceneNumber);
@@ -485,7 +466,7 @@ void M4Scene::loadScene(int sceneNumber) {
if (sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER) {
- _vm->_interfaceView->show();
+ _m4Vm->scene()->getInterface()->show();
showSprites();
}
@@ -503,6 +484,11 @@ void M4Scene::loadSceneCodes(int sceneNumber, int index) {
_vm->res()->toss(filename);
}
+void M4Scene::show() {
+ Scene::show();
+ _vm->_viewManager->addView(_interfaceSurface);
+}
+
void M4Scene::checkHotspotAtMousePos(int x, int y) {
if (_vm->getGameType() == GType_Riddle)
return;
@@ -517,15 +503,15 @@ void M4Scene::checkHotspotAtMousePos(int x, int y) {
if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
_vm->_mouse->getCursorNum() != CURSOR_TAKE &&
_vm->_mouse->getCursorNum() != CURSOR_USE &&
- _vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
+ _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
_vm->_mouse->setCursorNum(currentHotSpot->getCursor());
}
- _vm->_interfaceView->setStatusText(currentHotSpot->getPrep());
+ _m4Vm->scene()->getInterface()->setStatusText(currentHotSpot->getPrep());
} else {
if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
_vm->_mouse->getCursorNum() != CURSOR_TAKE &&
_vm->_mouse->getCursorNum() != CURSOR_USE &&
- _vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
+ _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
_vm->_mouse->setCursorNum(0);
} else {
@@ -551,14 +537,14 @@ void M4Scene::leftClick(int x, int y) {
printf("Player said: %s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
// FIXME: This should be moved somewhere else, and is incomplete
- if (_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
+ if (_m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
if (_vm->_mouse->getVerb() == NULL) {
strcpy(_vm->_player->verb, currentHotSpot->getVerb());
} else {
strcpy(_vm->_player->verb, _vm->_mouse->getVerb());
}
} else {
- strcpy(_vm->_player->verb, _vm->_interfaceView->_inventory.getSelectedObjectName());
+ strcpy(_vm->_player->verb, _m4Vm->scene()->getInterface()->_inventory.getSelectedObjectName());
}
strcpy(_vm->_player->noun, currentHotSpot->getVocab());
strcpy(_vm->_player->object, "");
@@ -573,13 +559,21 @@ void M4Scene::leftClick(int x, int y) {
void M4Scene::rightClick(int x, int y) {
if (_vm->getGameType() == GType_Burger) {
nextCommonCursor();
- _vm->_interfaceView->_inventory.clearSelected();
+ _m4Vm->scene()->getInterface()->_inventory.clearSelected();
}
}
void M4Scene::setAction(int action, int objectId) {
}
+void M4Scene::setStatusText(const char *text) {
+ getInterface()->setStatusText(text);
+}
+
+void M4Scene::update() {
+
+}
+
void M4Scene::nextCommonCursor() {
int cursorIndex = _vm->_mouse->getCursorNum();
@@ -608,6 +602,7 @@ void M4Scene::nextCommonCursor() {
MadsScene::MadsScene(MadsEngine *vm): Scene(vm) {
_vm = vm;
+ strcpy(_statusText, "");
_interfaceSurface = new MadsInterfaceView(vm);
_currentAction = kVerbNone;
}
@@ -705,10 +700,10 @@ void MadsScene::checkHotspotAtMousePos(int x, int y) {
sprintf(statusText, "%s %s\n", _madsVm->globals()->getVocab(verbId), currentHotSpot->getVocab());
statusText[0] = toupper(statusText[0]); // capitalize first letter
- setMADSStatusText(statusText);
+ setStatusText(statusText);
} else {
_vm->_mouse->setCursorNum(0);
- setMADSStatusText("");
+ setStatusText("");
}
}
@@ -723,7 +718,7 @@ void MadsScene::leftClick(int x, int y) {
}
statusText[0] = toupper(statusText[0]); // capitalize first letter
- setMADSStatusText(statusText);
+ setStatusText(statusText);
}
}
@@ -754,344 +749,29 @@ void MadsScene::setAction(int action, int objectId) {
_currentAction = action;
}
- setMADSStatusText(statusText);
+ setStatusText(statusText);
}
-/*--------------------------------------------------------------------------
- * MadsInterfaceView handles the user interface section at the bottom of
- * game screens in MADS games
- *--------------------------------------------------------------------------
- */
-
-MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): InterfaceView(vm, Common::Rect(0, MADS_SURFACE_HEIGHT,
- vm->_screen->width(), vm->_screen->height())) {
- _screenType = VIEWID_INTERFACE;
- _highlightedElement = -1;
- _topIndex = 0;
- _selectedObject = -1;
- _cheatKeyCtr = 0;
-
- _objectSprites = NULL;
- _objectPalData = NULL;
-
- /* Set up the rect list for screen elements */
- // Actions
- for (int i = 0; i < 10; ++i)
- _screenObjects.addRect((i / 5) * 32 + 1, (i % 5) * 8 + MADS_SURFACE_HEIGHT + 2,
- ((i / 5) + 1) * 32 + 3, ((i % 5) + 1) * 8 + MADS_SURFACE_HEIGHT + 2);
-
- // Scroller elements (up arrow, scroller, down arrow)
- _screenObjects.addRect(73, 160, 82, 167);
- _screenObjects.addRect(73, 168, 82, 190);
- _screenObjects.addRect(73, 191, 82, 198);
-
- // Inventory object names
- for (int i = 0; i < 5; ++i)
- _screenObjects.addRect(89, 158 + i * 8, 160, 166 + i * 8);
-
- // Full rectangle area for all vocab actions
- for (int i = 0; i < 5; ++i)
- _screenObjects.addRect(239, 158 + i * 8, 320, 166 + i * 8);
+void MadsScene::setStatusText(const char *text) {
+ strcpy(_statusText, text);
}
-MadsInterfaceView::~MadsInterfaceView() {
- delete _objectSprites;
-}
+void MadsScene::update() {
+ _backgroundSurface->copyTo(this);
-void MadsInterfaceView::setFontMode(InterfaceFontMode newMode) {
- switch (newMode) {
- case ITEM_NORMAL:
- _vm->_font->setColors(4, 4, 0xff);
- break;
- case ITEM_HIGHLIGHTED:
- _vm->_font->setColors(5, 5, 0xff);
- break;
- case ITEM_SELECTED:
- _vm->_font->setColors(6, 6, 0xff);
- break;
- }
-}
-
-void MadsInterfaceView::initialise() {
- // Build up the inventory list
- _inventoryList.clear();
-
- for (uint i = 0; i < _madsVm->globals()->getObjectsSize(); ++i) {
- MadsObject *obj = _madsVm->globals()->getObject(i);
- if (obj->roomNumber == PLAYER_INVENTORY)
- _inventoryList.push_back(i);
- }
-
- // If the inventory has at least one object, select it
- if (_inventoryList.size() > 0)
- setSelectedObject(_inventoryList[0]);
-}
-
-void MadsInterfaceView::setSelectedObject(int objectNumber) {
- char resName[80];
-
- // Load inventory resource
- if (_objectSprites) {
- _vm->_palette->deleteRange(_objectPalData);
- delete _objectSprites;
- }
-
- // Check to make sure the object is in the inventory, and also visible on-screen
- int idx = _inventoryList.indexOf(objectNumber);
- if (idx == -1) {
- // Object wasn't found, so return
- _selectedObject = -1;
- return;
- }
-
- // Found the object
- if (idx < _topIndex)
- _topIndex = idx;
- else if (idx >= (_topIndex + 5))
- _topIndex = MAX(0, idx - 4);
-
- _selectedObject = objectNumber;
- sprintf(resName, "*OB%.3dI.SS", objectNumber);
-
- Common::SeekableReadStream *data = _vm->res()->get(resName);
- _objectSprites = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- _objectPalData = _objectSprites->getRgbList();
- _vm->_palette->addRange(_objectPalData);
- _objectSprites->translate(_objectPalData, true);
-
- _objectFrameNumber = 0;
-}
-
-void MadsInterfaceView::addObjectToInventory(int objectNumber) {
- if (_inventoryList.indexOf(objectNumber) == -1) {
- _madsVm->globals()->getObject(objectNumber)->roomNumber = PLAYER_INVENTORY;
- _inventoryList.push_back(objectNumber);
- }
-
- setSelectedObject(objectNumber);
-}
-
-void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
- _vm->_font->setFont(FONT_INTERFACE_MADS);
- char buffer[100];
-
- // Check to see if any dialog is currently active
- bool dialogVisible = _vm->_viewManager->getView(LAYER_DIALOG) != NULL;
-
- // Highlighting logic for action list
- int actionIndex = 0;
- for (int x = 0; x < 2; ++x) {
- for (int y = 0; y < 5; ++y, ++actionIndex) {
- // Determine the font colour depending on whether an item is selected. Note that the first action,
- // 'Look', is always 'selected', even when another action is clicked on
- setFontMode((_highlightedElement == actionIndex) ? ITEM_HIGHLIGHTED :
- ((actionIndex == 0) ? ITEM_SELECTED : ITEM_NORMAL));
-
- // Get the verb action and capitalise it
- const char *verbStr = _madsVm->globals()->getVocab(kVerbLook + actionIndex);
- strcpy(buffer, verbStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- // Display the verb
- const Common::Rect r(_screenObjects[actionIndex]);
- _vm->_font->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
- }
-
- // Check for highlighting of the scrollbar controls
- if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_SCROLLER) || (_highlightedElement == SCROLL_DOWN)) {
- // Highlight the control's borders
- const Common::Rect r(_screenObjects[_highlightedElement]);
- destSurface->frameRect(r, 5);
- }
-
- // Draw the horizontal line in the scroller representing the current top selected
- const Common::Rect scroller(_screenObjects[SCROLL_SCROLLER]);
- int yP = (_inventoryList.size() < 2) ? 0 : (scroller.height() - 5) * _topIndex / (_inventoryList.size() - 1);
- destSurface->setColor(4);
- destSurface->hLine(scroller.left + 2, scroller.right - 3, scroller.top + 2 + yP);
-
- // List inventory items
- for (uint i = 0; i < 5; ++i) {
- if ((_topIndex + i) >= _inventoryList.size())
- break;
-
- const char *descStr = _madsVm->globals()->getVocab(_madsVm->globals()->getObject(
- _inventoryList[_topIndex + i])->descId);
- strcpy(buffer, descStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- const Common::Rect r(_screenObjects[INVLIST_START + i]);
-
- // Set the highlighting of the inventory item
- if (_highlightedElement == (int)(INVLIST_START + i)) setFontMode(ITEM_HIGHLIGHTED);
- else if (_selectedObject == _inventoryList[_topIndex + i]) setFontMode(ITEM_SELECTED);
- else setFontMode(ITEM_NORMAL);
-
- // Write out it's description
- _vm->_font->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
-
- // Handle the display of any currently selected object
- if (_objectSprites) {
- // Display object sprite. Note that the frame number isn't used directly, because it would result
- // in too fast an animation
- M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED);
- spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, 0);
-
- if (!_madsVm->globals()->invObjectsStill && !dialogVisible) {
- // If objetcs are to animated, move to the next frame
- if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED))
- _objectFrameNumber = 0;
- }
-
- // List the vocab actions for the currently selected object
- MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
- int yIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1);
-
- for (int i = 0; i < obj->vocabCount; ++i) {
- const Common::Rect r(_screenObjects[VOCAB_START + i]);
-
- // Get the vocab description and capitalise it
- const char *descStr = _madsVm->globals()->getVocab(obj->vocabList[i].vocabId);
- strcpy(buffer, descStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- // Set the highlighting and display the entry
- setFontMode((i == yIndex) ? ITEM_HIGHLIGHTED : ITEM_NORMAL);
- _vm->_font->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
- }
-}
-
-bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- // If the mouse isn't being held down, then reset the repeated scroll timer
- if (eventType != MEVENT_LEFT_HOLD)
- _nextScrollerTicks = 0;
-
- // Handle various event types
- switch (eventType) {
- case MEVENT_MOVE:
- // If the cursor isn't in "wait mode", don't do any processing
- if (_vm->_mouse->getCursorNum() == CURSOR_WAIT)
- return true;
-
- // Ensure the cursor is the standard arrow
- _vm->_mouse->setCursorNum(CURSOR_ARROW);
-
- // Check if any interface element is currently highlighted
- _highlightedElement = _screenObjects.find(Common::Point(x, y));
-
- return true;
-
- case MEVENT_LEFT_CLICK:
- // Left mouse click
- // Check if an inventory object was selected
- if ((_highlightedElement >= INVLIST_START) && (_highlightedElement < (INVLIST_START + 5))) {
- // Ensure there is an inventory item listed in that cell
- uint idx = _highlightedElement - INVLIST_START;
- if ((_topIndex + idx) < _inventoryList.size()) {
- // Set the selected object
- setSelectedObject(_inventoryList[_topIndex + idx]);
- }
- } else if ((_highlightedElement >= ACTIONS_START) && (_highlightedElement < (ACTIONS_START + 10))) {
- // A standard action was selected
- _vm->_scene->setAction(kVerbLook + (_highlightedElement - ACTIONS_START));
- } else if ((_highlightedElement >= VOCAB_START) && (_highlightedElement < (VOCAB_START + 5))) {
- // A vocab action was selected
- MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
- int vocabIndex = MIN(_highlightedElement - VOCAB_START, obj->vocabCount - 1);
- if (vocabIndex >= 0)
- _vm->_scene->setAction(obj->vocabList[vocabIndex].vocabId, _selectedObject);
- }
-
- return true;
-
- case MEVENT_LEFT_HOLD:
- // Left mouse hold
- // Handle the scroller - the up/down buttons allow for multiple actions whilst the mouse is held down
- if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_DOWN)) {
- if ((_nextScrollerTicks == 0) || (g_system->getMillis() >= _nextScrollerTicks)) {
- // Handle scroll up/down action
- _nextScrollerTicks = g_system->getMillis() + SCROLLER_DELAY;
-
- if ((_highlightedElement == SCROLL_UP) && (_topIndex > 0))
- --_topIndex;
- if ((_highlightedElement == SCROLL_DOWN) && (_topIndex < (int)(_inventoryList.size() - 1)))
- ++_topIndex;
- }
- }
- return true;
-
- case MEVENT_LEFT_DRAG:
- // Left mouse drag
- // Handle the the the scroller area that can be dragged to adjust the top displayed index
- if (_highlightedElement == SCROLL_SCROLLER) {
- // Calculate the new top index based on the Y position
- const Common::Rect r(_screenObjects[SCROLL_SCROLLER]);
- _topIndex = CLIP((int)(_inventoryList.size() - 1) * (y - r.top - 2) / (r.height() - 5),
- 0, (int)_inventoryList.size() - 1);
- }
- return true;
-
- case KEVENT_KEY:
- if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
- handleCheatKey(param1);
- handleKeypress(param1);
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-bool MadsInterfaceView::handleCheatKey(int32 keycode) {
- switch (keycode) {
- case Common::KEYCODE_SPACE:
- // TODO: Move player to current destination
- return true;
-
- case Common::KEYCODE_t | (Common::KEYCODE_LALT):
- case Common::KEYCODE_t | (Common::KEYCODE_RALT):
- {
- // Teleport to room
- //Scene *sceneView = (Scene *)vm->_viewManager->getView(VIEWID_SCENE);
-
-
- return true;
- }
-
- default:
- break;
- }
-
- return false;
-}
-
-const char *CHEAT_SEQUENCE = "widepipe";
-
-bool MadsInterfaceView::handleKeypress(int32 keycode) {
- int flags = keycode >> 24;
- int kc = keycode & 0xffff;
+ // Handle display of any status text
+ if (_statusText[0]) {
+ // Text colors are inverted in Dragonsphere
+ if (_vm->getGameType() == GType_DragonSphere)
+ _vm->_font->setColors(_vm->_palette->BLACK, _vm->_palette->WHITE, _vm->_palette->BLACK);
+ else
+ _vm->_font->setColors(_vm->_palette->WHITE, _vm->_palette->BLACK, _vm->_palette->BLACK);
- // Capitalise the letter if necessary
- if (_cheatKeyCtr < CHEAT_SEQUENCE_MAX) {
- if ((flags == Common::KBD_CTRL) && (kc == CHEAT_SEQUENCE[_cheatKeyCtr])) {
- ++_cheatKeyCtr;
- if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
- Dialog::display(_vm, 22, cheatingEnabledDesc);
- return true;
- } else {
- _cheatKeyCtr = 0;
- }
+ _vm->_font->setFont(FONT_MAIN_MADS);
+ _vm->_font->writeString(this, _statusText, (width() - _vm->_font->getWidth(_statusText)) / 2, 142, 0);
}
- return false;
+ _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height());
}
} // End of namespace M4
diff --git a/engines/m4/scene.h b/engines/m4/scene.h
index c5abcbe201..a5ea10ac00 100644
--- a/engines/m4/scene.h
+++ b/engines/m4/scene.h
@@ -32,6 +32,9 @@ class View;
#include "m4/hotspot.h"
#include "m4/graphics.h"
#include "m4/viewmgr.h"
+#include "m4/gui.h"
+#include "m4/m4_views.h"
+#include "m4/mads_views.h"
namespace M4 {
@@ -83,10 +86,9 @@ class Scene: public View {
private:
byte *_inverseColorTable;
HotSpotList _sceneHotspots;
- char _statusText[100];
protected:
int _currentScene;
- InterfaceView *_interfaceSurface;
+ GameInterfaceView *_interfaceSurface;
M4Surface *_backgroundSurface;
M4Surface *_codeSurface;
RGBList *_palData;
@@ -104,6 +106,8 @@ public:
virtual void leftClick(int x, int y) = 0;
virtual void rightClick(int x, int y) = 0;
virtual void setAction(int action, int objectId = -1) = 0;
+ virtual void setStatusText(const char *text) = 0;
+ virtual void update() = 0;
// TODO: perhaps move playIntro() someplace else?
void playIntro();
@@ -117,11 +121,11 @@ public:
int getCurrentScene() { return _currentScene; }
M4Surface *getBackgroundSurface() const { return _backgroundSurface; }
byte *getInverseColorTable() const { return _inverseColorTable; }
- void update();
- void setMADSStatusText(const char *text) { strcpy(_statusText, text); }
+ void showInterface();
+ void hideInterface();
void showMADSV2TextBox(char *text, int x, int y, char *faceName);
- InterfaceView *getInterface() { return _interfaceSurface; }
- SceneResources getSceneResources() { return _sceneResources; }
+ GameInterfaceView *getInterface() { return _interfaceSurface; };
+ SceneResources getSceneResources() { return _sceneResources; };
void onRefresh(RectList *rects, M4Surface *destSurface);
bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
@@ -142,10 +146,15 @@ public:
// Methods that differ between engines
virtual void loadScene(int sceneNumber);
virtual void loadSceneCodes(int sceneNumber, int index = 0);
+ virtual void show();
virtual void checkHotspotAtMousePos(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);
+ virtual void setStatusText(const char *text);
+ virtual void update();
+
+ M4InterfaceView *getInterface() { return (M4InterfaceView *)_interfaceSurface; };
};
class MadsScene: public Scene {
@@ -153,6 +162,7 @@ private:
MadsEngine *_vm;
int _currentAction;
+ char _statusText[100];
public:
MadsScene(MadsEngine *vm);
virtual ~MadsScene() {};
@@ -165,61 +175,10 @@ public:
virtual void leftClick(int x, int y);
virtual void rightClick(int x, int y);
virtual void setAction(int action, int objectId = -1);
-};
-
-enum InterfaceFontMode {ITEM_NORMAL, ITEM_HIGHLIGHTED, ITEM_SELECTED};
-
-enum InterfaceObjects {ACTIONS_START = 0, SCROLL_UP = 10, SCROLL_SCROLLER = 11, SCROLL_DOWN = 12,
- INVLIST_START = 13, VOCAB_START = 18};
-
-class IntegerList: public Common::Array<int> {
-public:
- int indexOf(int v) {
- for (uint i = 0; i < size(); ++i)
- if (operator [](i) == v)
- return i;
- return -1;
- }
-};
+ virtual void setStatusText(const char *text);
+ virtual void update();
-class InterfaceView: public View {
-public:
- InterfaceView(MadsM4Engine *vm, const Common::Rect &bounds): View(vm, bounds) {};
- ~InterfaceView() {};
-
- virtual void initialise() {};
- virtual void setSelectedObject(int objectNumber) {};
- virtual void addObjectToInventory(int objectNumber) {};
-};
-
-class MadsInterfaceView: public InterfaceView {
-private:
- IntegerList _inventoryList;
- RectList _screenObjects;
- int _highlightedElement;
- int _topIndex;
- uint32 _nextScrollerTicks;
- int _cheatKeyCtr;
-
- // Object display fields
- int _selectedObject;
- SpriteAsset *_objectSprites;
- RGBList *_objectPalData;
- int _objectFrameNumber;
-
- void setFontMode(InterfaceFontMode newMode);
- bool handleCheatKey(int32 keycode);
- bool handleKeypress(int32 keycode);
-public:
- MadsInterfaceView(MadsM4Engine *vm);
- ~MadsInterfaceView();
-
- virtual void initialise();
- virtual void setSelectedObject(int objectNumber);
- virtual void addObjectToInventory(int objectNumber);
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
+ MadsInterfaceView *getInterface() { return (MadsInterfaceView *)_interfaceSurface; };
};
} // End of namespace M4