From de5aedcb0c559754697dc534e559820f466afdf2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 2 Mar 2015 23:13:01 -0500 Subject: XEEN: Implemented cmNPC and TownMessage dialog class --- engines/xeen/font.cpp | 4 +- engines/xeen/font.h | 2 +- engines/xeen/screen.cpp | 2 +- engines/xeen/screen.h | 2 +- engines/xeen/scripts.cpp | 6 ++- engines/xeen/town.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++++++ engines/xeen/town.h | 18 ++++++++ 7 files changed, 143 insertions(+), 6 deletions(-) (limited to 'engines/xeen') diff --git a/engines/xeen/font.cpp b/engines/xeen/font.cpp index 53308ae248..bfdc4bde6b 100644 --- a/engines/xeen/font.cpp +++ b/engines/xeen/font.cpp @@ -65,7 +65,7 @@ void FontSurface::writeSymbol(int symbolId) { * @remarks Note that bounds is just used for wrapping purposes. Unless * justification is set, the message will be written at _writePos */ -Common::String FontSurface::writeString(const Common::String &s, const Common::Rect &bounds) { +const char *FontSurface::writeString(const Common::String &s, const Common::Rect &bounds) { _displayString = s.c_str(); assert(_fontData); @@ -250,7 +250,7 @@ Common::String FontSurface::writeString(const Common::String &s, const Common::R break; } - return Common::String(_displayString); + return _displayString; } /** diff --git a/engines/xeen/font.h b/engines/xeen/font.h index db61e3ea59..caaa03c5ba 100644 --- a/engines/xeen/font.h +++ b/engines/xeen/font.h @@ -63,7 +63,7 @@ public: void writeSymbol(int symbolId); - Common::String writeString(const Common::String &s, const Common::Rect &clipRect); + const char *writeString(const Common::String &s, const Common::Rect &clipRect); }; } // End of namespace Xeen diff --git a/engines/xeen/screen.cpp b/engines/xeen/screen.cpp index d9dcbf16f1..80f0149d7c 100644 --- a/engines/xeen/screen.cpp +++ b/engines/xeen/screen.cpp @@ -183,7 +183,7 @@ void Window::fill() { fillRect(_innerBounds, _vm->_screen->_bgColor); } -Common::String Window::writeString(const Common::String &s) { +const char *Window::writeString(const Common::String &s) { return _vm->_screen->writeString(s, _innerBounds); } diff --git a/engines/xeen/screen.h b/engines/xeen/screen.h index 901e79b5d4..21b7e8992e 100644 --- a/engines/xeen/screen.h +++ b/engines/xeen/screen.h @@ -92,7 +92,7 @@ public: void fill(); - Common::String writeString(const Common::String &s); + const char *writeString(const Common::String &s); void drawList(DrawStruct *items, int count); diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index c1743ab7ad..53eebb9675 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -368,7 +368,11 @@ void Scripts::cmdSignText(Common::Array ¶ms) { } void Scripts::cmdNPC(Common::Array ¶ms) { - error("TODO: cmdNPC"); + Map &map = *_vm->_map; + + if (TownMessage::show(_vm, params[2], _message, map._events._text[params[1]], + params[3])) + _lineNum = params[4]; } /** diff --git a/engines/xeen/town.cpp b/engines/xeen/town.cpp index 0934aef34f..a3033b2140 100644 --- a/engines/xeen/town.cpp +++ b/engines/xeen/town.cpp @@ -1192,4 +1192,119 @@ bool Town::isActive() const { return _townSprites.size() > 0 && !_townSprites[0].empty(); } +/*------------------------------------------------------------------------*/ + +bool TownMessage::show(XeenEngine *vm, int portrait, const Common::String &name, + const Common::String &text, int confirm) { + TownMessage *dlg = new TownMessage(vm); + bool result = dlg->execute(portrait, name, text, confirm); + delete dlg; + + return result; +} + +bool TownMessage::execute(int portrait, const Common::String &name, const Common::String &text, + int confirm) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Screen &screen = *_vm->_screen; + Town &town = *_vm->_town; + Window &w = screen._windows[11]; + + town._townMaxId = 4; + town._townActionId = 7; + town._drawFrameIndex = 0; + town._townPos = Common::Point(23, 22); + + if (!confirm) + loadButtons(); + + if (town._townSprites[0].empty()) { + town._townSprites[0].load(Common::String::format("face%02d.fac", portrait)); + town._townSprites[1].load("frame.fac"); + } + + if (!w._enabled) + w.open(); + + int result = -1; + Common::String msgText = text; + for (;;) { + Common::String msg = Common::String::format("\r\v014\x03c\t125%s\t000\v054%s", + name.c_str(), msgText.c_str()); + const char *msgEnd = w.writeString(msg.c_str()); + int wordCount = 0; + + for (const char *msgP = msg.c_str(); msgP < msgEnd; ++msgP) { + if (*msgP == ' ') + ++wordCount; + } + + town._drawCtr2 = wordCount * 2; + town._townSprites[1].draw(screen, 0, Common::Point(16, 16)); + town._townSprites[0].draw(screen, town._drawFrameIndex, Common::Point(23, 22)); + w.update(); + + if (!msgEnd) { + // Doesn't look like the code here in original can ever be reached + assert(0); + } + + if (confirm == 2) { + intf._face1State = intf._face2State = 2; + return false; + } + + do { + events.clearEvents(); + events.updateGameCounter(); + if (msgEnd) + clearButtons(); + + do { + events.wait(3, true); + checkEvents(_vm); + if (_vm->shouldQuit()) + return false; + + town.drawTownAnim(false); + events.updateGameCounter(); + } while (!_buttonValue); + + if (msgEnd) + break; + + if (!msgEnd) { + if (confirm || _buttonValue == Common::KEYCODE_ESCAPE || + _buttonValue == Common::KEYCODE_n) + result = 0; + else if (_buttonValue == Common::KEYCODE_y) + result = 1; + } + } while (result == -1); + + if (msgEnd) { + msgText = Common::String(msgEnd); + town._drawCtr2 = wordCount; + continue; + } + } while (result == -1); + + intf._face1State = intf._face2State = 2; + if (!confirm) + intf.mainIconsPrint(); + + town._townSprites[0].clear(); + town._townSprites[1].clear(); + return result == 1; +} + +void TownMessage::loadButtons() { + _iconSprites.load("confirm.icn"); + + addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_y, &_iconSprites); + addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_n, &_iconSprites); + addButton(Common::Rect(), Common::KEYCODE_ESCAPE); +} + } // End of namespace Xeen diff --git a/engines/xeen/town.h b/engines/xeen/town.h index 8f6ef15710..5aa31e571c 100644 --- a/engines/xeen/town.h +++ b/engines/xeen/town.h @@ -32,8 +32,10 @@ namespace Xeen { class XeenEngine; +class TownMessage; class Town: public ButtonContainer { + friend class TownMessage; private: XeenEngine *_vm; SpriteResource _icons1, _icons2; @@ -105,6 +107,22 @@ public: bool isActive() const; }; +class TownMessage : public ButtonContainer { +private: + XeenEngine *_vm; + SpriteResource _iconSprites; + + TownMessage(XeenEngine *vm) : ButtonContainer(), _vm(vm) {} + + bool execute(int portrait, const Common::String &name, + const Common::String &text, int confirm); + + void loadButtons(); +public: + static bool show(XeenEngine *vm, int portrait, const Common::String &name, + const Common::String &text, int confirm); +}; + } // End of namespace Xeen #endif /* XEEN_SPELLS_H */ -- cgit v1.2.3