2009-10-03 20:49:18 +00:00
|
|
|
/* 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$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2009-10-04 18:51:01 +00:00
|
|
|
#include "common/algorithm.h" // for Common::find()
|
2009-10-03 20:49:18 +00:00
|
|
|
#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 {
|
|
|
|
|
2009-10-04 16:26:43 +00:00
|
|
|
namespace {
|
|
|
|
const Common::Rect s_picRect(0, 10, 320, 200);
|
|
|
|
} // end of anonymous namespace
|
2009-10-03 20:49:18 +00:00
|
|
|
|
|
|
|
// window styles
|
|
|
|
enum {
|
2009-10-04 16:22:49 +00:00
|
|
|
kTransparent = (1 << 0),
|
|
|
|
kNoFrame = (1 << 1),
|
|
|
|
kTitle = (1 << 2),
|
|
|
|
kTopmost = (1 << 3),
|
|
|
|
kUser = (1 << 7)
|
2009-10-03 20:49:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
SciGUIwindowMgr::SciGUIwindowMgr(EngineState *state, SciGUIgfx *gfx)
|
|
|
|
: _s(state), _gfx(gfx) {
|
|
|
|
|
|
|
|
// FIXME: remove memmgr
|
|
|
|
InitMem(0x320);
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
HEAPHANDLE wmgrPortH = heapNewPtr(sizeof(GUIPort), kDataPort, "wmgrPort");
|
2009-10-03 20:49:18 +00:00
|
|
|
heapClearPtr(wmgrPortH);
|
2009-10-04 16:41:53 +00:00
|
|
|
_wmgrPort = (GUIPort *)heap2Ptr(wmgrPortH);
|
2009-10-03 20:49:18 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2009-10-04 18:51:01 +00:00
|
|
|
windowList.push_front(wmgrPortH);
|
2009-10-03 20:49:18 +00:00
|
|
|
|
2009-10-04 16:26:43 +00:00
|
|
|
_picWind = NewWindow(s_picRect, 0, 0, kTransparent | kNoFrame, 0, 1);
|
2009-10-03 20:49:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SciGUIwindowMgr::~SciGUIwindowMgr() {
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
int16 SciGUIwindowMgr::isFrontWindow(GUIWindow *pWnd) {
|
2009-10-04 18:51:01 +00:00
|
|
|
if (heap2Ptr(windowList.back()) == (byte *)pWnd)
|
2009-10-03 20:49:18 +00:00
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SciGUIwindowMgr::SelectWindow(HEAPHANDLE hh) {
|
2009-10-04 16:41:53 +00:00
|
|
|
GUIPort *port = (GUIPort *)heap2Ptr(hh);
|
2009-10-03 20:49:18 +00:00
|
|
|
_gfx->SetPort(port);
|
2009-10-04 18:51:01 +00:00
|
|
|
if (hh != windowList.back()) { // selecting not topmost window
|
|
|
|
Common::List<HEAPHANDLE>::iterator curWindowIterator = Common::find(windowList.begin(), windowList.end(), hh);
|
|
|
|
Common::List<HEAPHANDLE>::iterator prevWindowIterator = --curWindowIterator;
|
|
|
|
curWindowIterator++; // restore iterator position
|
|
|
|
GUIWindow *prevwnd = (GUIWindow *)heap2Ptr(*prevWindowIterator);
|
2009-10-03 20:49:18 +00:00
|
|
|
BeginUpdate(prevwnd);
|
2009-10-04 18:51:01 +00:00
|
|
|
windowList.erase(curWindowIterator);
|
|
|
|
windowList.push_back(hh);
|
2009-10-03 20:49:18 +00:00
|
|
|
EndUpdate(prevwnd);
|
|
|
|
}
|
|
|
|
_gfx->SetPort(port);
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
void SciGUIwindowMgr::BeginUpdate(GUIWindow *wnd) {
|
|
|
|
GUIPort *oldPort = _gfx->SetPort(_wmgrPort);
|
2009-10-04 18:51:01 +00:00
|
|
|
Common::List<HEAPHANDLE>::iterator curWindowIterator = windowList.end();
|
|
|
|
GUIWindow *node = (GUIWindow *)heap2Ptr(*curWindowIterator);
|
2009-10-03 20:49:18 +00:00
|
|
|
while (node != wnd) {
|
|
|
|
UpdateWindow(node);
|
2009-10-04 18:51:01 +00:00
|
|
|
curWindowIterator--; // previous node
|
|
|
|
node = (GUIWindow *)heap2Ptr(*curWindowIterator);
|
2009-10-03 20:49:18 +00:00
|
|
|
}
|
|
|
|
_gfx->SetPort(oldPort);
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
void SciGUIwindowMgr::EndUpdate(GUIWindow *wnd) {
|
|
|
|
GUIPort *oldPort = _gfx->SetPort(_wmgrPort);
|
2009-10-04 18:51:01 +00:00
|
|
|
Common::List<HEAPHANDLE>::iterator curWindowIterator = windowList.end();
|
|
|
|
GUIWindow *last = (GUIWindow *)heap2Ptr(*curWindowIterator);
|
2009-10-03 20:49:18 +00:00
|
|
|
while (wnd != last) {
|
2009-10-04 18:51:01 +00:00
|
|
|
curWindowIterator++; // next node
|
|
|
|
wnd = (GUIWindow *)heap2Ptr(*curWindowIterator);
|
2009-10-03 20:49:18 +00:00
|
|
|
UpdateWindow(wnd);
|
|
|
|
}
|
|
|
|
_gfx->SetPort(oldPort);
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
GUIWindow *SciGUIwindowMgr::NewWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, uint16 arg8, uint16 argA) {
|
|
|
|
HEAPHANDLE hWnd = heapNewPtr(sizeof(GUIWindow), kDataWindow, title);
|
2009-10-03 20:49:18 +00:00
|
|
|
Common::Rect r;
|
|
|
|
|
|
|
|
if (!hWnd) {
|
|
|
|
warning("Can't open window!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
heapClearPtr(hWnd);
|
2009-10-04 16:22:49 +00:00
|
|
|
if (style & kTopmost)
|
2009-10-04 18:51:01 +00:00
|
|
|
windowList.push_front(hWnd);
|
2009-10-03 20:49:18 +00:00
|
|
|
else
|
2009-10-04 18:51:01 +00:00
|
|
|
windowList.push_back(hWnd);
|
2009-10-04 16:41:53 +00:00
|
|
|
GUIWindow *pwnd = (GUIWindow *)heap2Ptr(hWnd);
|
|
|
|
_gfx->OpenPort((GUIPort *)pwnd);
|
2009-10-04 15:44:10 +00:00
|
|
|
r = dims;
|
|
|
|
pwnd->rect = dims;
|
|
|
|
if (restoreRect)
|
|
|
|
pwnd->restoreRect = *restoreRect;
|
2009-10-03 20:49:18 +00:00
|
|
|
|
|
|
|
pwnd->wndStyle = style;
|
|
|
|
pwnd->hSaved1 = pwnd->hSaved2 = NULL_REG;
|
2009-10-04 16:41:53 +00:00
|
|
|
pwnd->bDrawn = false;
|
2009-10-04 16:22:49 +00:00
|
|
|
if ((style & kTransparent) == 0)
|
2009-10-03 20:49:18 +00:00
|
|
|
pwnd->uSaveFlag = (arg8 == 0xFFFF ? 1 : 3);
|
|
|
|
|
2009-10-04 16:22:49 +00:00
|
|
|
if (title && (style & kTitle)) {
|
2009-10-03 20:49:18 +00:00
|
|
|
HEAPHANDLE hTitle = heapNewPtr((uint16)strlen(title) + 1, kDataString, title);
|
|
|
|
if (!hTitle) {
|
|
|
|
warning("Can't open window!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
pwnd->hTitle = hTitle;
|
2009-10-04 15:14:28 +00:00
|
|
|
strcpy((char *)heap2Ptr(hTitle), title);
|
2009-10-03 20:49:18 +00:00
|
|
|
}
|
|
|
|
|
2009-10-04 15:44:10 +00:00
|
|
|
r = dims;
|
2009-10-04 16:22:49 +00:00
|
|
|
if (style == kUser || (style & kNoFrame) == 0) {
|
2009-10-03 20:49:18 +00:00
|
|
|
r.grow(1);
|
2009-10-04 16:22:49 +00:00
|
|
|
if (style & kTitle) {
|
2009-10-03 20:49:18 +00:00
|
|
|
r.top -= 10;
|
|
|
|
r.bottom++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-04 15:44:10 +00:00
|
|
|
pwnd->dims = r;
|
2009-10-03 20:49:18 +00:00
|
|
|
const Common::Rect *wmprect = &_wmgrPort->rect;
|
2009-10-04 15:44:10 +00:00
|
|
|
int16 oldtop = pwnd->dims.top;
|
|
|
|
int16 oldleft = pwnd->dims.left;
|
|
|
|
if (wmprect->top > pwnd->dims.top)
|
|
|
|
pwnd->dims.moveTo(pwnd->dims.left, wmprect->top);
|
2009-10-03 20:49:18 +00:00
|
|
|
|
2009-10-04 15:44:10 +00:00
|
|
|
if (wmprect->bottom < pwnd->dims.bottom)
|
|
|
|
pwnd->dims.moveTo(pwnd->dims.left, wmprect->bottom
|
|
|
|
- pwnd->dims.bottom + pwnd->dims.top);
|
2009-10-03 20:49:18 +00:00
|
|
|
|
2009-10-04 15:44:10 +00:00
|
|
|
if (wmprect->right < pwnd->dims.right)
|
|
|
|
pwnd->dims.moveTo(wmprect->right + pwnd->dims.left
|
|
|
|
- pwnd->dims.right, pwnd->dims.top);
|
2009-10-03 20:49:18 +00:00
|
|
|
|
2009-10-04 15:44:10 +00:00
|
|
|
if (wmprect->left > pwnd->dims.left)
|
|
|
|
pwnd->dims.moveTo(wmprect->left, pwnd->dims.top);
|
2009-10-03 20:49:18 +00:00
|
|
|
|
2009-10-04 15:44:10 +00:00
|
|
|
pwnd->rect.moveTo(pwnd->rect.left + pwnd->dims.left - oldleft,
|
|
|
|
pwnd->rect.top + pwnd->dims.top - oldtop);
|
|
|
|
if (restoreRect == 0)
|
|
|
|
pwnd->restoreRect = pwnd->dims;
|
2009-10-03 20:49:18 +00:00
|
|
|
|
|
|
|
if (argA)
|
|
|
|
DrawWindow(pwnd);
|
2009-10-04 16:41:53 +00:00
|
|
|
_gfx->SetPort((GUIPort *)pwnd);
|
2009-10-03 20:49:18 +00:00
|
|
|
_gfx->SetOrigin(pwnd->rect.left, pwnd->rect.top + _wmgrPort->top);
|
|
|
|
pwnd->rect.moveTo(0, 0);
|
|
|
|
return pwnd;
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
void SciGUIwindowMgr::DrawWindow(GUIWindow *pWnd) {
|
|
|
|
if (pWnd->bDrawn)
|
2009-10-03 20:49:18 +00:00
|
|
|
return;
|
|
|
|
Common::Rect r;
|
|
|
|
int16 wndStyle = pWnd->wndStyle;
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
pWnd->bDrawn = true;
|
|
|
|
GUIPort *oldport = _gfx->SetPort(_wmgrPort);
|
2009-10-03 20:49:18 +00:00
|
|
|
_gfx->PenColor(0);
|
2009-10-04 16:22:49 +00:00
|
|
|
if ((wndStyle & kTransparent) == 0) {
|
2009-10-04 15:44:10 +00:00
|
|
|
pWnd->hSaved1 = _gfx->SaveBits(pWnd->restoreRect, 1);
|
2009-10-03 20:49:18 +00:00
|
|
|
if (pWnd->uSaveFlag & 2) {
|
2009-10-04 15:44:10 +00:00
|
|
|
pWnd->hSaved2 = _gfx->SaveBits(pWnd->restoreRect, 2);
|
2009-10-04 16:22:49 +00:00
|
|
|
if ((wndStyle & kUser) == 0)
|
2009-10-04 15:44:10 +00:00
|
|
|
_gfx->FillRect(pWnd->restoreRect, 2, 0, 0xF);
|
2009-10-03 20:49:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// drawing frame,shadow and title
|
2009-10-04 16:22:49 +00:00
|
|
|
if ((wndStyle & kUser) == 0) {
|
2009-10-04 15:44:10 +00:00
|
|
|
r = pWnd->dims;
|
2009-10-04 16:22:49 +00:00
|
|
|
if ((wndStyle & kNoFrame) == 0) {
|
2009-10-03 20:49:18 +00:00
|
|
|
r.translate(1, 1);
|
|
|
|
_gfx->FrameRect(r);// shadow
|
|
|
|
r.translate(-1, -1);
|
|
|
|
_gfx->FrameRect(r);// window frame
|
2009-10-04 16:22:49 +00:00
|
|
|
if (wndStyle & kTitle) {
|
2009-10-03 20:49:18 +00:00
|
|
|
_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);
|
|
|
|
}
|
|
|
|
|
2009-10-04 15:44:10 +00:00
|
|
|
r = pWnd->dims;
|
2009-10-03 20:49:18 +00:00
|
|
|
r.top += 9;
|
|
|
|
}
|
|
|
|
|
|
|
|
r.grow(-1);
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:22:49 +00:00
|
|
|
if ((wndStyle & kTransparent) == 0)
|
2009-10-03 20:49:18 +00:00
|
|
|
_gfx->FillRect(r, 1, pWnd->backClr);
|
2009-10-04 15:44:10 +00:00
|
|
|
_gfx->ShowBits(pWnd->dims, 1);
|
2009-10-03 20:49:18 +00:00
|
|
|
}
|
|
|
|
_gfx->SetPort(oldport);
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
void SciGUIwindowMgr::DisposeWindow(GUIWindow *pWnd, int16 arg2) {
|
2009-10-03 20:49:18 +00:00
|
|
|
_gfx->SetPort(_wmgrPort);
|
|
|
|
_gfx->RestoreBits(pWnd->hSaved1);
|
|
|
|
_gfx->RestoreBits(pWnd->hSaved2);
|
|
|
|
if (arg2)
|
2009-10-04 15:44:10 +00:00
|
|
|
_gfx->ShowBits(pWnd->restoreRect, 1);
|
2009-10-03 20:49:18 +00:00
|
|
|
// else
|
2009-10-04 15:44:10 +00:00
|
|
|
// g_sci->ReAnimate(&pwnd->dims);
|
2009-10-03 20:49:18 +00:00
|
|
|
HEAPHANDLE hh = ptr2heap((byte *)pWnd);
|
2009-10-04 18:51:01 +00:00
|
|
|
windowList.remove(hh);
|
|
|
|
SelectWindow(windowList.back());
|
2009-10-03 20:49:18 +00:00
|
|
|
if (pWnd->hTitle)
|
|
|
|
heapDisposePtr(pWnd->hTitle);
|
|
|
|
heapDisposePtr(hh);
|
|
|
|
}
|
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
void SciGUIwindowMgr::UpdateWindow(GUIWindow *wnd) {
|
|
|
|
GUIMemoryHandle handle;
|
2009-10-04 15:14:28 +00:00
|
|
|
|
2009-10-04 16:41:53 +00:00
|
|
|
if (wnd->uSaveFlag && wnd->bDrawn) {
|
2009-10-04 15:44:10 +00:00
|
|
|
handle = _gfx->SaveBits(wnd->restoreRect, 1);
|
2009-10-04 15:14:28 +00:00
|
|
|
_gfx->RestoreBits(wnd->hSaved1);
|
|
|
|
wnd->hSaved1 = handle;
|
|
|
|
if (wnd->uSaveFlag & 2) {
|
2009-10-04 15:44:10 +00:00
|
|
|
handle = _gfx->SaveBits(wnd->restoreRect, 2);
|
2009-10-04 15:14:28 +00:00
|
|
|
_gfx->RestoreBits(wnd->hSaved2);
|
|
|
|
wnd->hSaved2 = handle;
|
|
|
|
}
|
|
|
|
}
|
2009-10-03 20:49:18 +00:00
|
|
|
}
|
|
|
|
|
2009-10-04 21:26:33 +00:00
|
|
|
} // End of namespace Sci
|