aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/gui/gui_windowmgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/gui/gui_windowmgr.cpp')
-rw-r--r--engines/sci/gui/gui_windowmgr.cpp326
1 files changed, 326 insertions, 0 deletions
diff --git a/engines/sci/gui/gui_windowmgr.cpp b/engines/sci/gui/gui_windowmgr.cpp
new file mode 100644
index 0000000000..3a474a1a38
--- /dev/null
+++ b/engines/sci/gui/gui_windowmgr.cpp
@@ -0,0 +1,326 @@
+/* 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 "common/util.h"
+
+#include "sci/sci.h"
+#include "sci/engine/state.h"
+#include "sci/tools.h"
+#include "sci/gui/gui_gfx.h"
+#include "sci/gui/gui_windowmgr.h"
+#include "sci/gui/gui_memmgr.h"
+
+namespace Sci {
+
+Common::Rect _picRect(0,10,320, 200);
+
+// window styles
+enum {
+ TRANSPARENT = 1,
+ NOFRAME = 2,
+ TITLE = 4,
+ TOPMOST = 8,
+ USER = 0x80
+};
+
+SciGUIwindowMgr::SciGUIwindowMgr(EngineState *state, SciGUIgfx *gfx)
+ : _s(state), _gfx(gfx) {
+
+ // FIXME: remove memmgr
+ InitMem(0x320);
+
+ HEAPHANDLE wmgrPortH = heapNewPtr(sizeof(sciPort), kDataPort, "wmgrPort");
+ heapClearPtr(wmgrPortH);
+ _wmgrPort = (sciPort *)heap2Ptr(wmgrPortH);
+
+ int16 offTop = 20;
+
+ _gfx->OpenPort(_wmgrPort);
+ _gfx->SetPort(_wmgrPort);
+ _gfx->SetOrigin(0, offTop);
+ _wmgrPort->rect.bottom = 200 - offTop;
+ _wmgrPort->rect.right = 320;
+ _wmgrPort->rect.moveTo(0, 0);
+ _wmgrPort->curTop = 0;
+ _wmgrPort->curLeft = 0;
+
+ windowList.AddToFront(wmgrPortH);
+
+ _picWind = NewWindow(&_picRect, 0, 0, TRANSPARENT | NOFRAME, 0, 1);
+}
+
+SciGUIwindowMgr::~SciGUIwindowMgr() {
+}
+
+int16 SciGUIwindowMgr::isFrontWindow(sciWnd *pWnd) {
+ if (heap2Ptr(windowList.getLast()) == (byte *)pWnd)
+ return 1;
+ return 0;
+}
+
+void SciGUIwindowMgr::SelectWindow(HEAPHANDLE hh) {
+ sciPort *port = (sciPort *)heap2Ptr(hh);
+ _gfx->SetPort(port);
+ if (hh != windowList.getLast()) { // selecting not topmost window
+ sciWnd *prevwnd = (sciWnd *)heap2Ptr(port->node.prev);
+ BeginUpdate(prevwnd);
+ windowList.MoveToEnd(hh);
+ EndUpdate(prevwnd);
+ }
+ _gfx->SetPort(port);
+}
+
+void SciGUIwindowMgr::BeginUpdate(sciWnd *wnd) {
+ sciPort *oldPort = _gfx->SetPort(_wmgrPort);
+ sciWnd *node = (sciWnd *)heap2Ptr(windowList.getLast());
+ while (node != wnd) {
+ UpdateWindow(node);
+ node = (sciWnd *)heap2Ptr(node->node.prev);
+ }
+ _gfx->SetPort(oldPort);
+}
+
+void SciGUIwindowMgr::EndUpdate(sciWnd *wnd) {
+ sciPort *oldPort = _gfx->SetPort(_wmgrPort);
+ sciWnd *last = (sciWnd *)heap2Ptr(windowList.getLast());
+ while (wnd != last) {
+ wnd = (sciWnd *)heap2Ptr(wnd->node.next);
+ UpdateWindow(wnd);
+ }
+ _gfx->SetPort(oldPort);
+}
+
+SCILanguage SciGUIwindowMgr::getSCILanguage() {
+ return kLangEnglish;
+}
+
+char *SciGUIwindowMgr::StrSplit(char *buff, const char *msg, const char *fmt) {
+ SCILanguage gameLang = getSCILanguage();
+ SCILanguage subtitleLang = kLangNone;
+ char *retval;
+// if (_theGame.getHandle())
+ //subtitleLang = (SCILanguage)_theGame.getProperty(0x58); // subtitleLang property
+
+ if (buff == msg) {
+ char str[2000];
+ getIntlString(str, msg, fmt, gameLang, subtitleLang);
+ retval = strcpy(buff, str);
+ } else
+ retval = getIntlString(buff, msg, fmt, gameLang, subtitleLang);
+ return retval;
+}
+//--------------------------------
+// In multilanguage game the msg has format ___english_text__#I___italian_text___
+// The function should place in buff a translated part of msg or the 1st one if a translation
+// does not exist
+char *SciGUIwindowMgr::getIntlString(char *buff, const char *msg, const char *fmt,
+ SCILanguage gameLang, SCILanguage subtitleLang) {
+
+ // prefer subtitleLang if set
+ SCILanguage lang = subtitleLang != kLangNone ? subtitleLang : gameLang;
+ const char *ptr = msg, *szFrom;
+ char ch;
+ int nLen = 0;
+ // searching for language code in msg
+ while (*ptr) {
+ ch = *(ptr + 1);
+ if(*ptr == '#' && (ch == 'I' || ch == 'F' || ch == 'G' || ch == 'S')) {
+ ptr +=2;
+ break;
+ }
+ ptr++;
+ }
+ // if a language code was found...
+ if (*ptr) {
+ if ((lang == kLangItalian && ch == 'I') || (lang == kLangFrench && ch == 'F') ||
+ (lang == kLangGerman && ch == 'G') || (lang == kLangSpanish && ch == 'S')) {
+ nLen = (int)strlen(ptr);
+ szFrom = ptr;
+ } else {
+ nLen = ptr - msg - 2;
+ szFrom = msg;
+ }
+ } else {
+ nLen = ptr - msg;
+ szFrom = msg;
+ }
+ if (fmt && subtitleLang != kLangNone) {
+ strcpy(buff, fmt);
+ strncat(buff, szFrom, nLen);
+ buff[nLen + strlen(fmt)] = 0;
+ } else {
+ strncpy(buff, szFrom, nLen);
+ buff[nLen] = 0;
+ }
+ return buff;
+}
+
+sciWnd *SciGUIwindowMgr::NewWindow(Common::Rect *rect, Common::Rect *rect2, const char *title, uint16 style, uint16 arg8, uint16 argA) {
+ HEAPHANDLE hWnd = heapNewPtr(sizeof(sciWnd), kDataWindow, title);
+ Common::Rect r;
+
+ if (!hWnd) {
+ warning("Can't open window!");
+ return 0;
+ }
+ heapClearPtr(hWnd);
+ if (style & TOPMOST)
+ windowList.AddToFront(hWnd);
+ else
+ windowList.AddToEnd(hWnd);
+ sciWnd *pwnd = (sciWnd *)heap2Ptr(hWnd);
+ _gfx->OpenPort((sciPort *)pwnd);
+ r = *rect;
+ pwnd->rect = *rect;
+ if (rect2)
+ pwnd->rect1 = *rect2;
+
+ pwnd->wndStyle = style;
+ pwnd->hSaved1 = pwnd->hSaved2 = NULL_REG;
+ pwnd->bDrawed = false;
+ if ((style & TRANSPARENT) == 0)
+ pwnd->uSaveFlag = (arg8 == 0xFFFF ? 1 : 3);
+
+ if (title && (style & TITLE)) {
+ HEAPHANDLE hTitle = heapNewPtr((uint16)strlen(title) + 1, kDataString, title);
+ if (!hTitle) {
+ warning("Can't open window!");
+ return 0;
+ }
+ pwnd->hTitle = hTitle;
+ StrSplit((char *)heap2Ptr(hTitle), title, NULL);
+ }
+
+ r = *rect;
+ if (style == USER || (style & NOFRAME) == 0) {
+ r.grow(1);
+ if (style & TITLE) {
+ r.top -= 10;
+ r.bottom++;
+ }
+ }
+
+ pwnd->rect0 = r;
+ const Common::Rect *wmprect = &_wmgrPort->rect;
+ int16 oldtop = pwnd->rect0.top;
+ int16 oldleft = pwnd->rect0.left;
+ if (wmprect->top > pwnd->rect0.top)
+ pwnd->rect0.moveTo(pwnd->rect0.left, wmprect->top);
+
+ if (wmprect->bottom < pwnd->rect0.bottom)
+ pwnd->rect0.moveTo(pwnd->rect0.left, wmprect->bottom
+ - pwnd->rect0.bottom + pwnd->rect0.top);
+
+ if (wmprect->right < pwnd->rect0.right)
+ pwnd->rect0.moveTo(wmprect->right + pwnd->rect0.left
+ - pwnd->rect0.right, pwnd->rect0.top);
+
+ if (wmprect->left > pwnd->rect0.left)
+ pwnd->rect0.moveTo(wmprect->left, pwnd->rect0.top);
+
+ pwnd->rect.moveTo(pwnd->rect.left + pwnd->rect0.left - oldleft,
+ pwnd->rect.top + pwnd->rect0.top - oldtop);
+ if (rect2 == 0)
+ pwnd->rect1 = pwnd->rect0;
+
+ if (argA)
+ DrawWindow(pwnd);
+ _gfx->SetPort((sciPort *)pwnd);
+ _gfx->SetOrigin(pwnd->rect.left, pwnd->rect.top + _wmgrPort->top);
+ pwnd->rect.moveTo(0, 0);
+ return pwnd;
+}
+
+void SciGUIwindowMgr::DrawWindow(sciWnd *pWnd) {
+ if (pWnd->bDrawed)
+ return;
+ Common::Rect r;
+ int16 wndStyle = pWnd->wndStyle;
+
+ pWnd->bDrawed = true;
+ sciPort *oldport = _gfx->SetPort(_wmgrPort);
+ _gfx->PenColor(0);
+ if ((wndStyle & TRANSPARENT) == 0) {
+ pWnd->hSaved1 = _gfx->SaveBits(pWnd->rect1, 1);
+ if (pWnd->uSaveFlag & 2) {
+ pWnd->hSaved2 = _gfx->SaveBits(pWnd->rect1, 2);
+ if ((wndStyle & USER) == 0)
+ _gfx->FillRect(pWnd->rect1, 2, 0, 0xF);
+ }
+ }
+
+ // drawing frame,shadow and title
+ if ((wndStyle & USER) == 0) {
+ r = pWnd->rect0;
+ if ((wndStyle & NOFRAME) == 0) {
+ r.translate(1, 1);
+ _gfx->FrameRect(r);// shadow
+ r.translate(-1, -1);
+ _gfx->FrameRect(r);// window frame
+ if (wndStyle & TITLE) {
+ _gfx->FrameRect(r);
+ r.grow(-1);
+ _gfx->FillRect(r, 1, 0);
+ if (pWnd->hTitle) {
+ int16 oldcolor = _gfx->GetPort()->penClr;
+ _gfx->PenColor(255);
+ _gfx->TextBox((char *)heap2Ptr(pWnd->hTitle), 1, r, 1, 0);
+ _gfx->PenColor(oldcolor);
+ }
+
+ r = pWnd->rect0;
+ r.top += 9;
+ }
+
+ r.grow(-1);
+ }
+
+ if ((wndStyle & TRANSPARENT) == 0)
+ _gfx->FillRect(r, 1, pWnd->backClr);
+ _gfx->ShowBits(pWnd->rect0, 1);
+ }
+ _gfx->SetPort(oldport);
+}
+
+void SciGUIwindowMgr::DisposeWindow(sciWnd *pWnd, int16 arg2) {
+ _gfx->SetPort(_wmgrPort);
+ _gfx->RestoreBits(pWnd->hSaved1);
+ _gfx->RestoreBits(pWnd->hSaved2);
+ if (arg2)
+ _gfx->ShowBits(pWnd->rect0, 1);
+// else
+// g_sci->ReAnimate(&pwnd->rect0);
+ HEAPHANDLE hh = ptr2heap((byte *)pWnd);
+ windowList.DeleteNode(hh);
+ SelectWindow(windowList.getLast());
+ if (pWnd->hTitle)
+ heapDisposePtr(pWnd->hTitle);
+ heapDisposePtr(hh);
+}
+
+void SciGUIwindowMgr::UpdateWindow(sciWnd *wnd) {
+}
+
+} // end of namespace Sci