From 9aee739a18048b5395b04c005e5aaf6a2515ff66 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 5 Jun 2014 22:15:31 -0400 Subject: MADS: Implemented support methods for ScreenDialog base class --- engines/mads/nebular/dialogs_nebular.cpp | 127 +++++++++++++++++++++++++++++-- engines/mads/nebular/dialogs_nebular.h | 13 +++- engines/mads/screen.cpp | 11 +++ engines/mads/screen.h | 8 +- 4 files changed, 148 insertions(+), 11 deletions(-) diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 44935b8fe2..3fb61990e2 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -463,14 +463,14 @@ void PictureDialog::restore() { ScreenDialog::DialogLine::DialogLine() { _active = true; - _state = 0; + _state = DLGSTATE_UNSELECTED; _textDisplayIndex = -1; _font = nullptr; _widthAdjust = 0; } ScreenDialog::DialogLine::DialogLine(const Common::String &s) { - _state = 0; + _state = DLGSTATE_UNSELECTED; _textDisplayIndex = -1; _font = nullptr; _widthAdjust = -1; @@ -485,6 +485,8 @@ ScreenDialog::ScreenDialog(MADSEngine *vm) : _vm(vm), Scene &scene = game._scene; _v1 = 0; + _v2 = 0; + _v3 = false; _selectedLine = 0; _dirFlag = false; _textLineCount = 0; @@ -557,6 +559,7 @@ ScreenDialog::ScreenDialog(MADSEngine *vm) : _vm(vm), void ScreenDialog::clearLines() { Scene &scene = _vm->_game->_scene; + _v2 = 0; _lines.clear(); scene._spriteSlots.fullRefresh(true); } @@ -630,7 +633,7 @@ void ScreenDialog::addLine(const Common::String &msg, DialogTextAlign align, } line->_font = font; - line->_state = 0; + line->_state = DLGSTATE_UNSELECTED; line->_pos = pt; line->_widthAdjust = -1; line->_textDisplayIndex = -1; @@ -707,18 +710,126 @@ void ScreenDialog::setFrame(int frameNumber, int depth) { } void ScreenDialog::show() { + Scene &scene = _vm->_game->_scene; + while (_selectedLine < 1) { - bool continueFlag = handleEvents(); + handleEvents(); + if (_v3) { + if (!_v1) + _v1 = -1; + + refreshText(); + scene.drawElements(_vm->_game->_fx, _vm->_game->_fx); + _v3 = false; + } + _vm->_events->waitForNextFrame(); _vm->_game->_fx = kTransitionNone; + } +} + +void ScreenDialog::handleEvents() { + ScreenObjects &screenObjects = _vm->_game->_screenObjects; + EventsManager &events = *_vm->_events; + Nebular::DialogsNebular &dialogs = *(Nebular::DialogsNebular *)_vm->_dialogs; + int v1 = _v1; + + // Mark all the lines as initially unselected + for (uint i = 0; i < _lines.size(); ++i) + _lines[i]._state = DLGSTATE_UNSELECTED; + + // Process pending events + _vm->_events->pollEvents(); + + // Scan for objects in the dialog + int objIndex = screenObjects.scan(events.currentPos() - _vm->_screen._offset, LAYER_GUI); + + if (_v2) { + int yp = events.currentPos().y - _vm->_screen._offset.y; + if (yp < screenObjects[1]._bounds.top) { + if (!events._mouseReleased) + _lines[1]._state = DLGSTATE_SELECTED; + objIndex = 19; + } + + if (yp < screenObjects[7]._bounds.bottom) { + if (!events._mouseReleased) + _lines[1]._state = DLGSTATE_SELECTED; + objIndex = 20; + } + } + + int line = -1; + if (objIndex == 0 || events._mouseButtons) { + line = screenObjects[objIndex]._descId; + if (dialogs._pendingDialog == DIALOG_SAVE || dialogs._pendingDialog == DIALOG_RESTORE) { + if (line > 7 && line <= 14) { + _lines[line]._state = DLGSTATE_UNSELECTED; + line -= 7; + } + + int v2 = (line > 0 && line < 8) ? 1 : 0; + if (events._mouseMoved) + _v2 = v2; + } + + if (screenObjects[objIndex]._category == CAT_COMMAND) { + _lines[line]._state = DLGSTATE_SELECTED; + } + } + if (!line) + line = -1; + + if (dialogs._pendingDialog == DIALOG_ERROR && line == 1) + line = -1; - if (!continueFlag) - break; + if (events._mouseReleased) { + if (!_v2 || line <= 18) + _selectedLine = line; + _v3 = true; } + + _v1 = line; + if (v1 == line || _selectedLine >= 0) + _v3 = true; } -bool ScreenDialog::handleEvents() { - return true; +void ScreenDialog::refreshText() { + Scene &scene = _vm->_game->_scene; + + for (uint i = 0; i < _lines.size(); ++i) { + if (_lines[i]._active) { + int fontColor; + switch (_lines[i]._state) { + case DLGSTATE_UNSELECTED: + fontColor = 0xB0A; + break; + case DLGSTATE_SELECTED: + fontColor = 0xD0C; + break; + default: + fontColor = 0xF0E; + break; + } + + bool skipFlag = false; + if (_lines[i]._textDisplayIndex >= 0) { + TextDisplay &textDisplay = scene._textDisplay[_lines[i]._textDisplayIndex]; + int currCol = textDisplay._color1; + if (currCol != fontColor) { + scene._textDisplay.expire(_lines[i]._textDisplayIndex); + _lines[i]._textDisplayIndex = -1; + } else { + skipFlag = true; + } + } + + if (!skipFlag) { + _lines[i]._textDisplayIndex = scene._textDisplay.add(_lines[i]._pos.x, _lines[i]._pos.y, + fontColor, _lines[i]._widthAdjust, _lines[i]._msg, _lines[i]._font); + } + } + } } /*------------------------------------------------------------------------*/ diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h index 4eec735fb8..34707584b6 100644 --- a/engines/mads/nebular/dialogs_nebular.h +++ b/engines/mads/nebular/dialogs_nebular.h @@ -101,10 +101,12 @@ public: enum DialogTextAlign { ALIGN_CENTER = -1, ALIGN_AT_CENTER = -2, ALIGN_RIGHT = -3 }; +enum DialogState { DLGSTATE_UNSELECTED = 0, DLGSTATE_SELECTED = 1, DLGSTATE_FOCUSED = 2 }; + class ScreenDialog { struct DialogLine { bool _active; - int _state; + DialogState _state; Common::Point _pos; int _textDisplayIndex; Common::String _msg; @@ -119,6 +121,8 @@ protected: MSurface _savedSurface; Common::Array _lines; int _v1; + int _v2; + bool _v3; int _selectedLine; bool _dirFlag; int _screenId; @@ -164,7 +168,12 @@ protected: /** * Handle events whilst the dialog is active */ - bool handleEvents(); + void handleEvents(); + + /** + * Refresh the display of the dialog's text + */ + void refreshText(); public: /** * Constructor diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index 91aa3abdb0..7e8710db56 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -364,6 +364,17 @@ void ScreenObjects::check(bool scanFlag) { } } +int ScreenObjects::scan(const Common::Point &pt, int layer) { + for (uint i = 1; i <= size(); ++i) { + ScreenObject &sObj = (*this)[i]; + if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer) + return i; + } + + // Entry not found + return 0; +} + int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) { for (int i = (int)size(); i >= 1; --i) { ScreenObject &sObj = (*this)[i]; diff --git a/engines/mads/screen.h b/engines/mads/screen.h index a3653d6d62..7937e15456 100644 --- a/engines/mads/screen.h +++ b/engines/mads/screen.h @@ -165,9 +165,15 @@ public: void add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId); /** - */ + * Check objects on the screen + */ void check(bool scanFlag); + /** + * Scan the registered screen objects + */ + int scan(const Common::Point &pt, int layer); + /** * Handle an element being highlighted on the screen, and make it active. */ -- cgit v1.2.3