From f0ce06f0e9e0ebcf21368fdf01856a026dd4d2fb Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 20 Apr 2014 21:32:29 -0400 Subject: MADS: Implemented display of conversation topics --- engines/mads/action.cpp | 3 +- engines/mads/game.h | 2 +- engines/mads/mads.cpp | 1 + engines/mads/nebular/nebular_scenes2.cpp | 22 +++--- engines/mads/screen.cpp | 7 +- engines/mads/user_interface.cpp | 122 ++++++++++++++++++++++++++----- engines/mads/user_interface.h | 51 ++++++++----- 7 files changed, 151 insertions(+), 57 deletions(-) (limited to 'engines') diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp index 2da3c5201e..9d496d5ebf 100644 --- a/engines/mads/action.cpp +++ b/engines/mads/action.cpp @@ -97,7 +97,8 @@ void MADSAction::set() { if (_commandSource == CAT_TALK_ENTRY) { // Handle showing the conversation selection. Rex at least doesn't actually seem to use this if (_selectedRow >= 0) { - Common::String desc = userInterface._talkStrings[userInterface._talkIds[_selectedRow]]; + _action._verbId = userInterface._talkIds[_selectedRow]; + Common::String desc = userInterface._talkStrings[_selectedRow]; if (!desc.empty()) _statusText = desc; } diff --git a/engines/mads/game.h b/engines/mads/game.h index 2c87d70d9d..44aa0dbee5 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -77,7 +77,6 @@ protected: bool _quoteEmergency; bool _vocabEmergency; bool _anyEmergency; - int _widepipeCtr; /** * Constructor @@ -136,6 +135,7 @@ public: uint32 _priorFrameTimer; Common::String _aaName; int _winStatus; + int _widepipeCtr; public: virtual ~Game(); diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp index 229d3fcef8..c40d4bfa1b 100644 --- a/engines/mads/mads.cpp +++ b/engines/mads/mads.cpp @@ -78,6 +78,7 @@ void MADSEngine::initialise() { MSprite::setVm(this); Resources::init(this); + Conversation::init(this); _debugger = new Debugger(this); _dialogs = Dialogs::init(this); _events = new EventsManager(this); diff --git a/engines/mads/nebular/nebular_scenes2.cpp b/engines/mads/nebular/nebular_scenes2.cpp index 22c7062446..37e7aaab20 100644 --- a/engines/mads/nebular/nebular_scenes2.cpp +++ b/engines/mads/nebular/nebular_scenes2.cpp @@ -3835,22 +3835,22 @@ void Scene210::enter() { 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0); - userInterface.initConversation(&_conv1, 0x2E, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0); + _conv1.setup(0x2E, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0); if (!_game._visitedScenes._sceneRevisited) { - warning("TODO: sub71B18(0x2E, 0xB4, 0xB5, 0xB6, 0xB8, 0);"); + _conv1.set(0x2E, 0xB4, 0xB5, 0xB6, 0xB8, 0); - warning("TODO: if (Debugger_widepipe_ctr >= 2)"); - warning("TODO: \tsub71B9E(&dialog1, 0xB7, -1);"); + if (_game._widepipeCtr >= 2) + _conv1.write(0xB7, -1); } bool sceneRevisited = _game._visitedScenes._sceneRevisited; - userInterface.initConversation(&_conv2, 0x2F, 0xBC, 0xBB, 0xBD, (int)!sceneRevisited); - userInterface.initConversation(&_conv3, 0x30, 0xC3, 0xC2, 0xC1, 0xC4, (int)!sceneRevisited); - userInterface.initConversation(&_conv5, 0x31, 0xCD, 0xCC, 0xCE, 0xCF, (int)!sceneRevisited); - userInterface.initConversation(&_conv6, 0x32, 0xD3, 0xD4, 0xD5, (int)!sceneRevisited); - userInterface.initConversation(&_conv7, 0x33, 0xD8, 0xDA, 0xD9, 0xDB, 0xDC, (int)!sceneRevisited); - userInterface.initConversation(&_conv8, 0x34, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, (int)!sceneRevisited); + _conv2.setup(0x2F, 0xBC, 0xBB, 0xBD, (int)!sceneRevisited); + _conv3.setup(0x30, 0xC3, 0xC2, 0xC1, 0xC4, (int)!sceneRevisited); + _conv5.setup(0x31, 0xCD, 0xCC, 0xCE, 0xCF, (int)!sceneRevisited); + _conv6.setup(0x32, 0xD3, 0xD4, 0xD5, (int)!sceneRevisited); + _conv7.setup(0x33, 0xD8, 0xDA, 0xD9, 0xDB, 0xDC, (int)!sceneRevisited); + _conv8.setup(0x34, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, (int)!sceneRevisited); _twinkleAnimationType = 0; _twinklesCurrentFrame = 0; @@ -4144,7 +4144,7 @@ void Scene210::actions() { if (_globals[kTwinklesApproached] < 2) _globals[kTwinklesApproached]++; - userInterface.startConversation(&_conv1); + _conv1.start(); _curDialogNode = 1; break; } diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index 9dec5a8b1b..cb914e4f86 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -436,12 +436,7 @@ void ScreenObjects::elementHighlighted() { break; case CAT_TALK_ENTRY: - index = 0; - for (int idx = 0; idx < 5; ++idx) { - if (!userInterface._talkStrings[idx].empty()) - ++index; - } - + index = userInterface._talkStrings.size(); indexEnd = index - 1; varA = 0; topIndex = 0; diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp index 0a0b8968e9..48e62a5ae5 100644 --- a/engines/mads/user_interface.cpp +++ b/engines/mads/user_interface.cpp @@ -24,6 +24,7 @@ #include "mads/mads.h" #include "mads/compression.h" #include "mads/user_interface.h" +#include "mads/nebular/game_nebular.h" namespace MADS { @@ -71,7 +72,6 @@ void UISlots::add(const AnimFrameEntry &frameEntry) { push_back(ie); } - void UISlots::draw(bool updateFlag, bool delFlag) { Scene &scene = _vm->_game->_scene; UserInterface &userInterface = scene._userInterface; @@ -207,6 +207,95 @@ void UISlots::draw(bool updateFlag, bool delFlag) { /*------------------------------------------------------------------------*/ +MADSEngine *Conversation::_vm; + +void Conversation::init(MADSEngine *vm) { + _vm = vm; +} + +void Conversation::setup(int globalId, ...) { + va_list va; + va_start(va, globalId); + + // Load the list of conversation quotes + _quotes.clear(); + int quoteId = va_arg(va, int); + while (quoteId > 0) { + _quotes.push_back(quoteId); + quoteId = va_arg(va, int); + } + va_end(va); + + assert(_vm->getGameID() == GType_RexNebular); + Nebular::GameNebular *game = (Nebular::GameNebular *)_vm->_game; + game->_globals[globalId] = -1; + + _globalId = globalId; +} + +void Conversation::set(int quoteId, ...) { + assert(_vm->getGameID() == GType_RexNebular); + Nebular::GameNebular *game = (Nebular::GameNebular *)_vm->_game; + game->_globals[_globalId] = 0; + + va_list va; + va_start(va, quoteId); + + // Loop through handling each quote + while (quoteId > 0) { + for (uint idx = 0; idx < _quotes.size(); ++idx) { + if (_quotes[idx] == quoteId) { + // Found index, so set that bit in the global keeping track of conversation state + game->_globals[_globalId] |= 1 << idx; + break; + } + } + + quoteId = va_arg(va, int); + } + va_end(va); +} + +void Conversation::write(int quoteId, bool flag) { + assert(_vm->getGameID() == GType_RexNebular); + Nebular::GameNebular *game = (Nebular::GameNebular *)_vm->_game; + + for (uint idx = 0; idx < _quotes.size(); ++idx) { + if (_quotes[idx] == quoteId) { + // Found index, so set or clear the flag + if (flag) { + // Set bit + game->_globals[_globalId] |= 1 << idx; + } else { + // Clear bit + game->_globals[_globalId] &= ~(1 << idx); + } + return; + } + } +} + +void Conversation::start() { + assert(_vm->getGameID() == GType_RexNebular); + Nebular::GameNebular *game = (Nebular::GameNebular *)_vm->_game; + UserInterface &userInterface = game->_scene._userInterface; + userInterface.emptyConversationList(); + + // Loop through each of the quotes loaded into the conversation + for (uint idx = 0; idx < _quotes.size(); ++idx) { + // Check whether the given quote is enabled or not + if (game->_globals[_globalId] & (1 << idx)) { + // Quote enabled, so add it to the list of talk selections + Common::String msg = game->getQuote(_quotes[idx]); + userInterface.addConversationMessage(_quotes[idx], msg); + } + } + + userInterface.setup(kInputConversation); +} + +/*------------------------------------------------------------------------*/ + UserInterface::UserInterface(MADSEngine *vm) : _vm(vm), _dirtyAreas(vm), _uiSlots(vm) { _invSpritesIndex = -1; @@ -305,7 +394,7 @@ void UserInterface::setup(InputMode inputMode) { void UserInterface::drawTextElements() { if (_vm->_game->_screenObjects._inputMode) { - drawTalkList(); + drawConversationList(); } else { // Draw the actions drawActions(); @@ -466,7 +555,10 @@ void UserInterface::writeVocab(ScrCategory category, int id) { break; case CAT_TALK_ENTRY: - error("TODO: CAT_TALK_ENTRY"); + font = _vm->_font->getFont(FONT_INTERFACE); + font->setColorMode(id == _highlightedCommandIndex ? SELMODE_HIGHLIGHTED : SELMODE_UNSELECTED); + font->writeString(this, _talkStrings[id], Common::Point(bounds.left, bounds.top)); + break; case CAT_INV_SCROLLER: font = _vm->_font->getFont(FONT_MISC); @@ -668,28 +760,22 @@ void UserInterface::moveRect(Common::Rect &bounds) { bounds.translate(0, MADS_SCENE_HEIGHT); } -void UserInterface::drawTalkList() { - warning("TODO: drawTalkList"); -} - -void UserInterface::initConversation(Conversation *conversatin, int globalId, int quoteId, ...) { - -} - -void UserInterface::setConversation(Conversation *conversation, int quoteId, ...) { - -} - -void UserInterface::writeConversation(Conversation *conversation, int quoteId, int flag) { - +void UserInterface::drawConversationList() { + for (uint idx = 0; idx < _talkStrings.size(); ++idx) { + writeVocab(CAT_TALK_ENTRY, idx); + } } void UserInterface::emptyConversationList() { _talkStrings.clear(); + _talkIds.clear(); } -void UserInterface::startConversation(Conversation *conversation) { +void UserInterface::addConversationMessage(int vocabId, const Common::String &msg) { + assert(_talkStrings.size() < 5); + _talkStrings.push_back(msg); + _talkIds.push_back(vocabId); } void UserInterface::loadInventoryAnim(int objectId) { diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h index a6cc9e3650..7541bb8661 100644 --- a/engines/mads/user_interface.h +++ b/engines/mads/user_interface.h @@ -42,6 +42,7 @@ enum ScrollbarActive { }; class AnimFrameEntry; +class MADSEngine; class UISlot { public: @@ -94,8 +95,33 @@ public: }; class Conversation { +private: + static MADSEngine *_vm; +public: + static void init(MADSEngine *vm); public: + int _globalId; + Common::Array _quotes; + /** + * Set up a conversation sequence + */ + void setup(int globalId, ...); + + /** + * Activates the passed set of quotes in the given conversation node + */ + void set(int quoteId, ...); + + /** + * Activates or deactivates the specified quote in the given conversation node + */ + void write(int quoteId, bool flag); + + /** + * Starts the conversation + */ + void start(); }; class UserInterface : public MSurface { @@ -128,7 +154,7 @@ private: /** * Draw options during a conversation. */ - void drawTalkList(); + void drawConversationList(); /** * Draw the action list @@ -243,29 +269,14 @@ public: void updateInventoryScroller(); /** - * Set up a conversation sequence - */ - void initConversation(Conversation *conversatin, int globalId, int quoteId, ...); - - /** - * Activates the passed set of quotes in the given conversation node - */ - void setConversation(Conversation *conversation, int quoteId, ...); - - /** - * Activates or deactivates the specified quote in the given conversation node - */ - void writeConversation(Conversation *conversation, int quoteId, int flag); - - /** - * Start an interactive conversation + * Empties the current conversation talk list */ - void startConversation(Conversation *conversation); + void emptyConversationList(); /** - * Empties the current conversation talk list + * Add a msesage to the list of conversation items to select from */ - void emptyConversationList(); + void addConversationMessage(int vocabId, const Common::String &msg); }; } // End of namespace MADS -- cgit v1.2.3