diff options
Diffstat (limited to 'engines/sci/gui/gui_windowmgr.cpp')
-rw-r--r-- | engines/sci/gui/gui_windowmgr.cpp | 326 |
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 |