aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBorja Lorente2016-07-15 12:47:27 +0200
committerBorja Lorente2016-08-14 18:55:17 +0200
commit2a521bb22df9c5e5d477deb32ebc8b6a54e91fde (patch)
treeb8b631f749258226c6c96cc8db9d649936655ff1
parent8162483026ec52476a1106e72259c84e5476fd2d (diff)
downloadscummvm-rg350-2a521bb22df9c5e5d477deb32ebc8b6a54e91fde.tar.gz
scummvm-rg350-2a521bb22df9c5e5d477deb32ebc8b6a54e91fde.tar.bz2
scummvm-rg350-2a521bb22df9c5e5d477deb32ebc8b6a54e91fde.zip
MACVENTURE: Add dialog system
-rw-r--r--engines/macventure/dialog.cpp254
-rw-r--r--engines/macventure/dialog.h146
-rw-r--r--engines/macventure/gui.cpp24
-rw-r--r--engines/macventure/gui.h5
-rw-r--r--engines/macventure/image.cpp27
-rw-r--r--engines/macventure/module.mk3
6 files changed, 434 insertions, 25 deletions
diff --git a/engines/macventure/dialog.cpp b/engines/macventure/dialog.cpp
new file mode 100644
index 0000000000..78fb942db1
--- /dev/null
+++ b/engines/macventure/dialog.cpp
@@ -0,0 +1,254 @@
+/* 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/system.h"
+
+#include "macventure/dialog.h"
+
+namespace MacVenture {
+
+// Prebuilt dialogs
+
+enum {
+ // HACK
+ kMaxPrebuiltDialogElements = 10
+};
+
+struct PrebuiltDialog {
+ Common::Rect bounds;
+ PrebuiltDialogElement elements[kMaxPrebuiltDialogElements];
+};
+
+PrebuiltDialog prebuiltDialogs[kPrebuiltDialogCount] = {
+
+ {/* kSaveAsDialog */
+ Common::Rect(0, 146, 456, 254),
+ { {kDEButton, "YES", kDANone, Common::Point(24, 68), 120, 22},
+ {kDEButton, "NO", kDACloseDialog, Common::Point(168, 68), 120, 22},
+ {kDEButton, "CANCEL", kDACloseDialog, Common::Point(312, 68), 120, 22},
+ {kDEPlainText, "Save As...", kDANone, Common::Point(100, 10), 340, 38},
+ {kDETextInput, "", kDANone, Common::Point(100, 30), 340, 20},
+ {kDEEnd, "", kDANone, Common::Point(0, 0), 0, 0}}
+ }
+
+};
+
+Dialog::Dialog(Gui *gui, Common::Point pos, uint width, uint height) :
+ _gui(gui), _bounds(Common::Rect(pos.x, pos.y, pos.x + width, pos.y + height)) {}
+
+Dialog::Dialog(Gui *gui, PrebuiltDialogs prebuilt) {
+ _gui = gui;
+ const PrebuiltDialog &dialog = prebuiltDialogs[prebuilt];
+ _bounds = dialog.bounds;
+ for (int i = 0; dialog.elements[i].type != kDEEnd; i++) {
+ addPrebuiltElement(dialog.elements[i]);
+ }
+}
+
+Dialog::~Dialog() {
+ for (Common::Array<DialogElement*>::iterator it = _elements.begin(); it != _elements.end(); it++) {
+ delete *it;
+ }
+}
+
+void Dialog::handleDialogAction(DialogElement *trigger, DialogAction action) {
+ switch(action) {
+ case kDACloseDialog:
+ _gui->closeDialog();
+ break;
+ }
+}
+
+const Graphics::Font& Dialog::getFont() {
+ return _gui->getCurrentFont();
+}
+
+bool Dialog::processEvent(Common::Event event) {
+ for (Common::Array<DialogElement*>::iterator it = _elements.begin(); it != _elements.end(); it++) {
+ if ((*it)->processEvent(this, event)) return true;
+ }
+}
+
+void Dialog::addButton(Common::String title, MacVenture::DialogAction action, Common::Point position, uint width, uint height) {
+ _elements.push_back(new DialogButton(this, title, action, position, width, height));
+}
+
+void Dialog::addText(Common::String content, Common::Point position) {
+ _elements.push_back(new DialogPlainText(this, content, position));
+}
+
+void Dialog::addTextInput(Common::Point position, int width, int height) {
+ _elements.push_back(new DialogTextInput(this, position, width, height));
+}
+
+void Dialog::draw() {
+ Graphics::ManagedSurface compose;
+ // Compose the surface
+ compose.create(_bounds.width(), _bounds.height());
+ Common::Rect base(0, 0, _bounds.width(), _bounds.height());
+ compose.fillRect(base, kColorWhite);
+ compose.frameRect(base, kColorBlack);
+ for (Common::Array<DialogElement*>::iterator it = _elements.begin(); it != _elements.end(); it++) {
+ (*it)->draw(this, compose);
+ }
+
+ g_system->copyRectToScreen(compose.getPixels(), compose.pitch,
+ _bounds.left, _bounds.top, _bounds.width(), _bounds.height());
+}
+
+void Dialog::localize(Common::Point &point) {
+ point.x -= _bounds.left;
+ point.y -= _bounds.top;
+}
+
+void Dialog::setUserInput(Common::String content) {
+ _userInput = content;
+ debug(2, "Set user input: %s", _userInput.c_str());
+}
+
+void Dialog::addPrebuiltElement(const MacVenture::PrebuiltDialogElement &element) {
+ switch(element.type) {
+ case kDEButton:
+ addButton(element.title, element.action, element.position, element.width, element.height);
+ break;
+ case kDEPlainText:
+ addText(element.title, element.position);
+ break;
+ case kDETextInput:
+ addTextInput(element.position, element.width, element.height);
+ break;
+ }
+}
+
+// Dialog Element
+
+DialogElement::DialogElement(Dialog *dialog, Common::String title, DialogAction action, Common::Point position, uint width, uint height) :
+ _text(title), _action(action) {
+ if (width == 0) {
+ width = dialog->getFont().getStringWidth(title);
+ }
+ if (height == 0) {
+ height = dialog->getFont().getFontHeight();
+ }
+ _bounds = Common::Rect(position.x, position.y, position.x + width, position.y + height);
+ }
+
+bool DialogElement::processEvent(MacVenture::Dialog *dialog, Common::Event event) {
+ // HACK for test, please delete me
+ Common::Point mouse = event.mouse;
+ dialog->localize(mouse);
+ if (_bounds.contains(mouse)) debug(1, "Hovering over: %s", _text.c_str());
+
+ return doProcessEvent(dialog, event);
+}
+
+void DialogElement::draw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target) {
+ doDraw(dialog, target);
+}
+
+const Common::String& DialogElement::getText() {
+ return doGetText();
+}
+
+const Common::String& DialogElement::doGetText() {
+ return _text;
+}
+
+// CONCRETE DIALOG ELEMENTS
+
+DialogButton::DialogButton(Dialog *dialog, Common::String title, DialogAction action, Common::Point position, uint width, uint height):
+ DialogElement(dialog, title, action, position, width, height) {}
+
+bool DialogButton::doProcessEvent(MacVenture::Dialog *dialog, Common::Event event) {
+ Common::Point mouse = event.mouse;
+ if (event.type == Common::EVENT_LBUTTONDOWN) {
+ dialog->localize(mouse);
+ if (_bounds.contains(mouse)) {
+ debug(1, "Click! Button: %s", _text.c_str());
+ dialog->handleDialogAction(this, _action);
+ return true;
+ }
+ }
+ return false;
+}
+
+void DialogButton::doDraw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target) {
+ target.fillRect(_bounds, kColorWhite);
+ target.frameRect(_bounds, kColorBlack);
+ // Draw title
+ dialog->getFont().drawString(
+ &target, _text, _bounds.left, _bounds.top, _bounds.width(), kColorBlack, Graphics::kTextAlignCenter);
+}
+
+DialogPlainText::DialogPlainText(Dialog *dialog, Common::String content, Common::Point position) :
+ DialogElement(dialog, content, kDANone, position, 0, 0) { }
+
+DialogPlainText::~DialogPlainText() {}
+
+bool DialogPlainText::doProcessEvent(MacVenture::Dialog *dialog, Common::Event event) {
+ return false;
+}
+
+void DialogPlainText::doDraw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target) {
+ // Draw contents
+ dialog->getFont().drawString(
+ &target, _text, _bounds.left, _bounds.top, _bounds.width(), kColorBlack);
+
+}
+
+DialogTextInput::DialogTextInput(Dialog *dialog, Common::Point position, uint width, uint height) :
+ DialogElement(dialog, "", kDANone, position, width, height) {}
+DialogTextInput::~DialogTextInput() {}
+
+bool DialogTextInput::doProcessEvent(Dialog *dialog, Common::Event event) {
+ if (event.type == Common::EVENT_KEYDOWN) {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_BACKSPACE:
+ if (!_text.empty()) {
+ _text.deleteLastChar();
+ dialog->setUserInput(_text);
+ return true;
+ }
+ break;
+
+ default:
+ if (event.kbd.ascii >= 0x20 && event.kbd.ascii <= 0x7f) {
+ _text += (char)event.kbd.ascii;
+ dialog->setUserInput(_text);
+ return true;
+ }
+
+ break;
+ }
+ }
+ return false;
+}
+void DialogTextInput::doDraw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target) {
+ target.fillRect(_bounds, kColorWhite);
+ target.frameRect(_bounds, kColorBlack);
+ dialog->getFont().drawString(
+ &target, _text, _bounds.left, _bounds.top, _bounds.width(), kColorBlack);
+}
+
+
+
+} // End of namespace MacVenture
diff --git a/engines/macventure/dialog.h b/engines/macventure/dialog.h
new file mode 100644
index 0000000000..fa17432018
--- /dev/null
+++ b/engines/macventure/dialog.h
@@ -0,0 +1,146 @@
+/* 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 MACVENTURE_DIALOG_H
+#define MACVENTURE_DIALOG_H
+
+#include "graphics/macgui/macwindowmanager.h"
+
+#include "macventure/macventure.h"
+#include "macventure/gui.h"
+
+namespace MacVenture {
+
+using namespace Graphics::MacGUIConstants;
+class Gui;
+
+class DialogElement;
+
+enum DialogAction {
+ kDANone,
+ kDACloseDialog
+};
+
+enum PrebuiltDialogs {
+ kSaveAsDialog = 0,
+ kPrebuiltDialogCount
+};
+
+enum PrebuiltElementType {
+ kDEPlainText,
+ kDEButton,
+ kDETextInput,
+ kDEEnd
+};
+
+struct PrebuiltDialogElement {
+ PrebuiltElementType type;
+ Common::String title;
+ DialogAction action;
+ Common::Point position;
+ uint width;
+ uint height;
+};
+
+class Dialog {
+public:
+ Dialog(Gui *gui, Common::Point pos, uint width, uint height);
+ Dialog(Gui *gui, PrebuiltDialogs prebuilt);
+
+ ~Dialog();
+
+ bool processEvent(Common::Event event);
+ void draw();
+ void localize(Common::Point &point);
+ void handleDialogAction(DialogElement *trigger, DialogAction action);
+
+ const Graphics::Font& getFont();
+
+ void addButton(Common::String title, DialogAction action, Common::Point position, uint width = 0, uint height = 0);
+ void addText(Common::String content, Common::Point position);
+ void addTextInput(Common::Point position, int width, int height);
+
+ void setUserInput(Common::String content);
+
+private:
+ void addPrebuiltElement(const PrebuiltDialogElement &element);
+
+private:
+ Gui *_gui;
+
+ Common::String _userInput;
+ Common::Array<DialogElement*> _elements;
+ Common::Rect _bounds;
+};
+
+class DialogElement {
+public:
+ DialogElement(Dialog *dialog, Common::String title, DialogAction action, Common::Point position, uint width = 0, uint height = 0);
+ virtual ~DialogElement() {}
+
+ bool processEvent(Dialog *dialog, Common::Event event);
+ void draw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target);
+ const Common::String& getText();
+
+private:
+ virtual bool doProcessEvent(Dialog *dialog, Common::Event event) = 0;
+ virtual void doDraw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target) = 0;
+ virtual const Common::String& doGetText();
+
+protected:
+ Common::String _text;
+ Common::Rect _bounds;
+ DialogAction _action;
+};
+
+// Dialog elements
+class DialogButton : public DialogElement {
+public:
+ DialogButton(Dialog *dialog, Common::String title, DialogAction action, Common::Point position, uint width = 0, uint height = 0);
+ ~DialogButton() {}
+
+private:
+ bool doProcessEvent(Dialog *dialog, Common::Event event);
+ void doDraw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target);
+};
+
+class DialogPlainText : public DialogElement {
+public:
+ DialogPlainText(Dialog *dialog, Common::String content, Common::Point position);
+ ~DialogPlainText();
+private:
+ bool doProcessEvent(Dialog *dialog, Common::Event event);
+ void doDraw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target);
+};
+
+class DialogTextInput : public DialogElement {
+public:
+ DialogTextInput(Dialog *dialog, Common::Point position, uint width, uint height);
+ ~DialogTextInput();
+private:
+ bool doProcessEvent(Dialog *dialog, Common::Event event);
+ void doDraw(MacVenture::Dialog *dialog, Graphics::ManagedSurface &target);
+};
+
+} // End of namespace MacVenture
+
+#endif
diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp
index 02f603659e..4b01f8bca9 100644
--- a/engines/macventure/gui.cpp
+++ b/engines/macventure/gui.cpp
@@ -112,6 +112,7 @@ Gui::Gui(MacVentureEngine *engine, Common::MacResManager *resman) {
_controlData = nullptr;
_draggedObj.id = 0;
_draggedObj.pos = Common::Point(0, 0);
+ _dialog = nullptr;
_cursor = new Cursor(this);
g_system->getTimerManager()->installTimerProc(&cursorTimerHandler, 500000, this, "macVentureCursor");
@@ -138,6 +139,9 @@ Gui::~Gui() {
if (_consoleText)
delete _consoleText;
+ if (_dialog)
+ delete _dialog;
+
Common::HashMap<ObjID, ImageAsset*>::const_iterator it = _assets.begin();
for (; it != _assets.end(); it++) {
delete it->_value;
@@ -181,7 +185,7 @@ void Gui::draw() {
_wm.draw();
drawDraggedObject();
-
+ drawDialog();
//drawWindowTitle(kMainGameWindow, _mainGameWindow->getSurface());
}
@@ -703,6 +707,10 @@ void Gui::drawDraggedObject() {
}
}
+void Gui::drawDialog() {
+ if (_dialog) _dialog->draw();
+}
+
void Gui::updateWindow(WindowReference winID, bool containerOpen) {
if (winID == kNoWindow) return;
if (winID == kSelfWindow || containerOpen) {
@@ -794,6 +802,11 @@ void Gui::printText(const Common::String & text) {
_consoleText->printLine(text, _outConsoleWindow->getDimensions().width());
}
+void Gui::closeDialog() {
+ delete _dialog;
+ _dialog = nullptr;
+}
+
void Gui::moveDraggedObject(Common::Point target) {
Common::Point newPos = target + _draggedObj.mouseOffset;
bool movement = false;
@@ -1006,6 +1019,8 @@ void Gui::handleMenuAction(MenuAction action) {
break;
case MacVenture::kMenuActionSaveAs:
debug("MacVenture Menu Action: Save As");
+ // HACK this should be wrapped in a function
+ _dialog = new Dialog(this, kSaveAsDialog);
break;
case MacVenture::kMenuActionQuit:
debug("MacVenture Menu Action: Quit");
@@ -1120,6 +1135,8 @@ bool Gui::processEvent(Common::Event &event) {
processed |= _cursor->processEvent(event);
+ if (_dialog && _dialog->processEvent(event)) return true;
+
if (event.type == Common::EVENT_MOUSEMOVE) {
if (_draggedObj.id != 0) {
moveDraggedObject(event.mouse);
@@ -1247,8 +1264,6 @@ bool Gui::processInventoryEvents(WindowClick click, Common::Event & event) {
// Find the appropriate window
WindowReference ref = findWindowAtPoint(event.mouse);
- // TODO DELETE MEEEE!
- debug("WindowFound: %d", ref);
if (ref == kNoWindow) return false;
Graphics::MacWindow *win = findWindow(ref);
WindowData &data = findWindowData((WindowReference) ref);
@@ -1267,11 +1282,14 @@ void Gui::processCursorTick() {
void Gui::handleSingleClick(Common::Point pos) {
debug("Single Click");
+ // HACK
+ if (_dialog) return;
handleDragRelease(pos, false, false);
}
void Gui::handleDoubleClick(Common::Point pos) {
debug("Double Click");
+ if (_dialog) return;
handleDragRelease(pos, false, true);
}
diff --git a/engines/macventure/gui.h b/engines/macventure/gui.h
index a44813511c..046e7e516c 100644
--- a/engines/macventure/gui.h
+++ b/engines/macventure/gui.h
@@ -31,6 +31,7 @@
#include "macventure/container.h"
#include "macventure/image.h"
+#include "macventure/dialog.h"
namespace MacVenture {
@@ -43,6 +44,7 @@ class Cursor;
class ConsoleText;
class CommandButton;
class ImageAsset;
+class Dialog;
enum MenuAction {
kMenuActionAbout,
@@ -244,6 +246,7 @@ public:
void updateExit(ObjID id);
void printText(const Common::String &text);
+ void closeDialog();
// Ugly switches
BorderBounds borderBounds(MVWindowType type);
@@ -268,6 +271,7 @@ private: // Attributes
Graphics::MacWindow *_diplomaWindow;
Common::Array<Graphics::MacWindow*> _inventoryWindows;
Graphics::Menu *_menu;
+ Dialog *_dialog;
Container *_graphics;
Common::HashMap<ObjID, ImageAsset*> _assets;
@@ -305,6 +309,7 @@ private: // Methods
void drawDraggedObject();
void drawObjectsInWindow(WindowReference target, Graphics::ManagedSurface *surface);
void drawWindowTitle(WindowReference target, Graphics::ManagedSurface *surface);
+ void drawDialog();
void moveDraggedObject(Common::Point target);
diff --git a/engines/macventure/image.cpp b/engines/macventure/image.cpp
index 21986e382c..cbe3cc910d 100644
--- a/engines/macventure/image.cpp
+++ b/engines/macventure/image.cpp
@@ -100,7 +100,7 @@ void ImageAsset::decodePPIC(ObjID id, Common::Array<byte> &data) {
_bitWidth = w;
_bitHeight = h;
- for (uint i = 0; i < _rowBytes * h; i++) {
+ for (int i = 0; i < _rowBytes * h; i++) {
data.push_back(0);
}
@@ -141,22 +141,7 @@ void ImageAsset::decodePPIC0(Common::BitStream & stream, Common::Array<byte> &da
data[p] = v & 0xff; p++;
}
}
- /*
- for (var i=0;i<words;i++)
- {
- v=ppic.peek32(); ppic.seek(2,ppic.cur);
- v>>>=16-ppic.bit;
- bitmap.data[p++]=(v>>8)&0xff;
- bitmap.data[p++]=v&0xff;
- }
- if (bytes)
- {
- v=ppic.bits(bytes);
- v<<=16-bytes;
- bitmap.data[p++]=(v>>8)&0xff;
- bitmap.data[p++]=v&0xff;
- }
- */
+
}
void ImageAsset::decodePPIC1(Common::BitStream & stream, Common::Array<byte> &data) {
@@ -186,7 +171,7 @@ void ImageAsset::decodePPIC3(Common::BitStream & stream, Common::Array<byte> &da
if (huff.symbols[j] >= huff.symbols[i - 1])
huff.symbols[j]++;
- for (uint i = 0x10; i >= 0; i--) {
+ for (int i = 0x10; i >= 0; i--) {
if (huff.symbols[i] == 0x10) {
huff.symbols[i] = 0xff;
break;
@@ -297,7 +282,7 @@ void ImageAsset::decodeHuffGraphic(const PPICHuff & huff, Common::BitStream & st
if (flags & 2) delta *= 2;
pos = 0;
uint q = delta;
- for (uint i = 0;i < _bitHeight * _rowBytes - delta;i++) {
+ for (int i = 0; i < _bitHeight * _rowBytes - delta; i++) {
data[q] ^= data[pos];
q++;
pos++;
@@ -390,10 +375,10 @@ bool ImageAsset::isRectInside(Common::Rect rect) {
// HACK is it &&, or ||?
if (_maskData.empty()) return (rect.width() > 0 && rect.height() > 0);
- for (uint y = rect.top; y < rect.top + rect.height(); y++) {
+ for (int y = rect.top; y < rect.top + rect.height(); y++) {
uint bmpofs = y * _rowBytes;
byte pix;
- for (uint x = rect.left; x < rect.left + rect.width(); x++) {
+ for (int x = rect.left; x < rect.left + rect.width(); x++) {
pix = _maskData[bmpofs + (x >> 3)] & (1 << (7 - (x & 7)));
if (pix) return true;
}
diff --git a/engines/macventure/module.mk b/engines/macventure/module.mk
index 022b8d7c32..813677c33c 100644
--- a/engines/macventure/module.mk
+++ b/engines/macventure/module.mk
@@ -8,7 +8,8 @@ MODULE_OBJS := \
text.o \
world.o \
script.o \
- macventure.o
+ macventure.o \
+ dialog.o
MODULE_DIRS += \
engines/macventure