From db2e5a4fb5018aefd72c4ffe2597968f63145774 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 4 Oct 2009 21:27:24 +0000 Subject: SCI: Rework the way SciGUIwindowMgr keeps track of windows/ports; remove the GUI heapmanager svn-id: r44635 --- engines/sci/gui/gui.cpp | 27 +-- engines/sci/gui/gui_gfx.cpp | 2 +- engines/sci/gui/gui_helpers.h | 15 +- engines/sci/gui/gui_memmgr.cpp | 373 -------------------------------------- engines/sci/gui/gui_memmgr.h | 123 ------------- engines/sci/gui/gui_windowmgr.cpp | 114 +++++------- engines/sci/gui/gui_windowmgr.h | 15 +- engines/sci/module.mk | 1 - 8 files changed, 88 insertions(+), 582 deletions(-) delete mode 100644 engines/sci/gui/gui_memmgr.cpp delete mode 100644 engines/sci/gui/gui_memmgr.h (limited to 'engines/sci') diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp index af10df59b6..016f749544 100644 --- a/engines/sci/gui/gui.cpp +++ b/engines/sci/gui/gui.cpp @@ -31,7 +31,6 @@ #include "sci/gui/gui_screen.h" #include "sci/gui/gui_gfx.h" #include "sci/gui/gui_windowmgr.h" -#include "sci/gui/gui_memmgr.h" #include "sci/gui/gui_view.h" #include "sci/gfx/operations.h" @@ -71,10 +70,14 @@ void SciGUI::wait(int16 ticks) { void SciGUI::setPort(uint16 portPtr) { switch (portPtr) { - case 0: _gfx->SetPort(_windowMgr->_wmgrPort); break; - case 0xFFFF: _gfx->SetPort(_gfx->_menuPort); break; - default: - _gfx->SetPort((GUIPort *)heap2Ptr(portPtr)); + case 0: + _gfx->SetPort(_windowMgr->_wmgrPort); + break; + case 0xFFFF: + _gfx->SetPort(_gfx->_menuPort); + break; + default: + _gfx->SetPort(_windowMgr->getPortById(portPtr)); }; } @@ -87,7 +90,7 @@ void SciGUI::setPortPic(Common::Rect rect, int16 picTop, int16 picLeft) { } reg_t SciGUI::getPort() { - return make_reg(0, ptr2heap((byte *)_gfx->GetPort())); + return make_reg(0, _gfx->GetPort()->id); } void SciGUI::globalToLocal(int16 *x, int16 *y) { @@ -112,23 +115,25 @@ reg_t SciGUI::newWindow(Common::Rect dims, Common::Rect restoreRect, uint16 styl wnd->penClr = colorPen; wnd->backClr = colorBack; _windowMgr->DrawWindow(wnd); - return make_reg(0, ptr2heap((byte *)wnd)); + + return make_reg(0, wnd->id); } void SciGUI::disposeWindow(uint16 windowPtr, int16 arg2) { - GUIWindow *wnd = (GUIWindow *)heap2Ptr(windowPtr); + GUIWindow *wnd = (GUIWindow *)_windowMgr->getPortById(windowPtr); _windowMgr->DisposeWindow(wnd, arg2); } void SciGUI::display(const char *text, int argc, reg_t *argv) { int displayArg; - GUIPort oldPort; int16 align = 0; int16 bgcolor = -1, width = -1, bRedraw = 1; byte bSaveUnder = false; Common::Rect rect, *orect = &((GUIWindow *)_gfx->GetPort())->dims; - memcpy(&oldPort, _gfx->GetPort(), sizeof(GUIPort)); + // Make a "backup" of the port settings + GUIPort oldPort = *_gfx->GetPort(); + // setting defaults _gfx->PenMode(0); _gfx->PenColor(0); @@ -203,7 +208,7 @@ void SciGUI::display(const char *text, int argc, reg_t *argv) { GUIPort *currport = _gfx->GetPort(); uint16 tTop = currport->curTop; uint16 tLeft = currport->curLeft; - memcpy(currport, &oldPort, sizeof(GUIPort)); + *currport = oldPort; currport->curTop = tTop; currport->curLeft = tLeft; diff --git a/engines/sci/gui/gui_gfx.cpp b/engines/sci/gui/gui_gfx.cpp index a3531778f1..3fe0eb0867 100644 --- a/engines/sci/gui/gui_gfx.cpp +++ b/engines/sci/gui/gui_gfx.cpp @@ -365,7 +365,7 @@ void SciGUIgfx::OpenPort(GUIPort *port) { port->penClr = 0; port->backClr = 0xFF; port->penMode = 0; - memcpy(&port->rect, &_bounds, sizeof(_bounds)); + port->rect = _bounds; } void SciGUIgfx::PenColor(int16 color) { diff --git a/engines/sci/gui/gui_helpers.h b/engines/sci/gui/gui_helpers.h index d7c5e91db9..b4f028f03d 100644 --- a/engines/sci/gui/gui_helpers.h +++ b/engines/sci/gui/gui_helpers.h @@ -39,6 +39,7 @@ typedef int16 GUIViewCellNo; typedef uint16 GUIHandle; struct GUIPort { + uint16 id; int16 top, left; Common::Rect rect; int16 curTop, curLeft; @@ -46,6 +47,12 @@ struct GUIPort { GUIResourceId fontId; int16 textFace, penClr, backClr; int16 penMode; + + GUIPort(uint16 theId) : id(theId), top(0), left(0), + curTop(0), curLeft(0), + fontHeight(0), fontId(0), textFace(0), + penClr(0), backClr(0xFF), penMode(0) { + } }; struct GUIWindow : public GUIPort { @@ -55,8 +62,14 @@ struct GUIWindow : public GUIPort { uint16 uSaveFlag; reg_t hSaved1; reg_t hSaved2; - GUIHandle hTitle; + Common::String title; bool bDrawn; + + GUIWindow(uint16 theId) : GUIPort(theId), + wndStyle(0), uSaveFlag(0), + hSaved1(NULL_REG), hSaved2(NULL_REG), + bDrawn(false) { + } }; struct GUICast { diff --git a/engines/sci/gui/gui_memmgr.cpp b/engines/sci/gui/gui_memmgr.cpp deleted file mode 100644 index 0ab06fb724..0000000000 --- a/engines/sci/gui/gui_memmgr.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* 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 "sci/sci.h" -#include "sci/gui/gui_helpers.h" -#include "sci/gui/gui_memmgr.h" - -namespace Sci { - -static tagHandle *pHandles = 0; -static int16 nHandles = 0; -static byte *_heap = 0; -SCIHANDLE _firstfree = 0; -Common::HashMap heapInfo; -#define HEAP_BOTTOM 1000 - -//---------------------- -void FreeMem(void) { - // deleting handles - if (pHandles) { - for (uint16 i = 0; i < nHandles; i++) - hunkDisposeHandle(i); - delete[] pHandles; - pHandles = 0; - } - // deleting heap - if (_heap) { - delete[] _heap; - _heap = 0; - } -} -//---------------------- -bool InitMem(int16 max_handles) { - // heap - _heap = new byte[HEAP_SIZE]; - memset(_heap, 0x55, HEAP_SIZE); - _firstfree = HEAP_START; - heapSetBlockSize(_firstfree, HEAP_SIZE - 1 - HEAP_START); - heapSetBlockNext(_firstfree, (SCIHANDLE)(HEAP_SIZE - 1)); - //hunk - pHandles = new tagHandle[max_handles]; - if (pHandles) { - nHandles = max_handles; - memset(pHandles, 0, sizeof(tagHandle) * max_handles); // zerofy all - return 1; - } - return 0; -} -//---------------------- -SCIHANDLE hunkNeedHandle(uint16 size, uint32 resId) { - SCIHANDLE newh = 0; - // see if there is an empty handle available - for (int16 i = 1; i < nHandles; i++) - if (pHandles[i].ptr == 0) { - newh = i; - break; - } - // if unused handle was found - allocate memory and return it - if (newh == nHandles) - return 0; - pHandles[newh].ptr = (byte*)malloc(size); - assert(pHandles[newh].ptr); - if (pHandles[newh].ptr) { - pHandles[newh].size = size; - pHandles[newh].resId = resId; - debug( - 5, - " MemMgr: Requested %6db for res %08X, allocated handle %04X", - size, resId, newh); - return newh; - } - return 0; -} -//---------------------- -void hunkDisposeHandle(SCIHANDLE handle) { -// if (handle > 0 && handle < nHandles && pHandles[handle].ptr) { -// debug( -// 5, -// " MemMgr: disposing handle 0x%04X, size=%8db, associated res %08X", -// handle, pHandles[handle].size, pHandles[handle].resId); -// free(pHandles[handle].ptr); -// pHandles[handle].ptr = 0; -// // deleting associated resource handler -// // Check that this don't fail on delete as ResGetLoaded could return 0; -// if (pHandles[handle].resId != 0xFFFFFFFF) -// delete g_sci->ResMgr.ResGetLoaded(pHandles[handle].resId); -// } -} -//---------------------- -byte *hunk2Ptr(SCIHANDLE handle) { - if (handle > 0 && handle < nHandles && pHandles[handle].ptr) - return (byte *)pHandles[handle].ptr; - return 0; -} -//---------------------- -SCIHANDLE ptr2hunk(byte *ptr) { - for (int i = 0; i < nHandles; i++) { - if (ptr >= pHandles[i].ptr && ptr <= pHandles[i].ptr + pHandles[i].size) - return i; - } -return 0; -} -//---------------------- -uint32 hunkHandleSize(SCIHANDLE handle) { - if (handle > 0 && handle < nHandles && pHandles[handle].ptr) - return pHandles[handle].size; - return 0; -} -//---------------------- -// int16 hunkResourceNum(SCIHANDLE handle) { -// if (handle > 0 && handle < nHandles && pHandles[handle].ptr) -// return RES_ID2NUM(pHandles[handle].resId); -// return -1; -// } - -//---------------------- -void hunkDump() { - debug("\nMemMgr: Hunk dump:"); - uint32 size = 0; - for (int i = 0; i < nHandles; i++) - if (pHandles[i].ptr) { - debug(" %04X, size=%8db, associated res %08X", i, - pHandles[i].size, pHandles[i].resId); - size += pHandles[i].size; - } - debug("Total memory allocated: %db", size); - debug("End dump"); -} - -uint32 hunkUsed() { - uint32 size = 0; - for (int i = 0; i < nHandles; i++) - if (pHandles[i].ptr) - size += pHandles[i].size; - return size; -} -//---------------------- -// HEAP -//---------------------- -//--------------------------------------------- -// TODO : make sure that STRING, STACK and SCRIPT DATA is never allocated below HEAP_BOTTOM=1000 -// otherwise it will cause problems with kernel string fuctions that assumes that anything below 1000 is res number -HEAPHANDLE heapNewPtr(uint16 size, kDataType type, const char *info) { - if (size == 0) - warning("Zero Heap Allocation Request!"); - - HEAPHANDLE ptr, prev, next; - ptr = prev = _firstfree; - // 2 bytes block header header + block size must be odd - size += 2 + (size & 1); - // looking for an empty block to use - uint16 blocksize; - bool bBottomSafe = !(type == kDataString || type == kDataUnknown); - - while (ptr < HEAP_SIZE - 1) { - blocksize = heapGetBlockSize(ptr); - next = heapGetBlockNext(ptr); - if (blocksize >= size) { - if (bBottomSafe || (!bBottomSafe && ptr > HEAP_BOTTOM)) { - if (blocksize <= size + 4) { // use all block - size = blocksize; - heapSetBlockNext(prev, next); - } else { // split block in 2 blocks - HEAPHANDLE newblock = ptr + size; - heapSetBlockNext(prev, newblock); - heapSetBlockSize(newblock, blocksize - size); - heapSetBlockNext(newblock, next); - next = newblock; - } - // setting allocated block - heapSetBlockSize(ptr, size); - // updating firstfree pointer - if (ptr == _firstfree) - _firstfree = next; - setHeapInfo(ptr, type, info); - return ptr; - } //if (bBottomSafe || (!bBottomSafe && ptr>HEAP_BOTTOM)) - else { // !bottomsafe && ptr < HEAP_BOTTOM - if (blocksize + ptr - HEAP_BOTTOM >= size) { - // splitting the block into 3 parts - // [2][ptr...999] [2][1002...1000+size-1] [2][1002+size...ptr+blocksize] - // free returned free - heapSetBlockSize(ptr, HEAP_BOTTOM-ptr + 2); - heapSetBlockSize(HEAP_BOTTOM+2, size); - heapSetBlockSize(HEAP_BOTTOM+2 + size, blocksize - size - - (HEAP_BOTTOM-ptr + 2)); - - heapSetBlockNext(HEAP_BOTTOM+2 + size, next); - heapSetBlockNext(ptr, HEAP_BOTTOM+2 + size); - setHeapInfo(HEAP_BOTTOM+2, type, info); - return HEAP_BOTTOM + 2; - } - } - } // if (blocksize >= size) - // block too small - moving to next one - prev = ptr; - ptr = next; - } - // allocation error - out of heap - warning("Out of heap space"); - return 0; -} -//-------------------------------------------- -void heapDisposePtr(HEAPHANDLE handle) { - HEAPHANDLE prev, next; - prev = next = _firstfree; - // searching for prev and next free blocks (before & after deleted block) - while (next < handle) { - prev = next; - next = heapGetBlockNext(prev); - } - // if deleted block is before 1st free space then it'll be 1st free space - if (handle < _firstfree) { - next = _firstfree; - _firstfree = handle; - } else - heapSetBlockNext(prev, handle); - - heapSetBlockNext(handle, next); - //Try to merge with previous - if (prev + heapGetBlockSize(prev) == handle) { - heapSetBlockSize(prev, heapGetBlockSize(prev) - + heapGetBlockSize(handle)); - heapSetBlockNext(prev, next); - handle = prev; - } - //Try to merge with next - if (handle + heapGetBlockSize(handle) == next && next != (HEAP_SIZE - 1)) { - heapSetBlockSize(handle, heapGetBlockSize(handle) + heapGetBlockSize( - next)); - heapSetBlockNext(handle, heapGetBlockNext(next)); - } -} -//------------------------------------- -uint16 heapFreeSize() { - HEAPHANDLE free = _firstfree; - uint16 szFree = 0; - while (free < HEAP_SIZE - 1) { - int size = heapGetBlockSize(free); - free = heapGetBlockNext(free); - szFree += size; - } - return szFree; -} -//------------------------------------- -uint16 heapLargestFreeSize() { - HEAPHANDLE free = _firstfree; - uint16 maxFree = 0; - while (free < HEAP_SIZE - 1) { - int size = heapGetBlockSize(free); - free = heapGetBlockNext(free); - if (size > maxFree) - maxFree = size; - } - return maxFree ? maxFree - 2 : 0; -} -//------------------------------------- -void heapDump() { - debug("\nMemMgr:Heap dump:"); - HEAPHANDLE ptr = HEAP_START; - HEAPHANDLE free = _firstfree; - - uint16 szFree = 0, szUsed = 0; - while (ptr < HEAP_SIZE - 1) { - int size = heapGetBlockSize(ptr); - if (ptr == free) { - free = heapGetBlockNext(free); - debug(" %04X %6u size:%6d FREE next=%04X", ptr, ptr, - heapGetDataSize(ptr), free); - szFree += size; - } else { - debug(" %04X %6u size:%6d USED", ptr, ptr, heapGetDataSize(ptr)); - szUsed += size; - } - ptr += size; - } - debug("Total %db used, %db free\nEnd Dump", szUsed, szFree); -} -//---------------------------- -byte *heap2Ptr(HEAPHANDLE ptr) { - return (ptr >= HEAP_START) ? (byte *)(_heap + ptr) : NULL; -} -//---------------------------- -HEAPHANDLE ptr2heap(byte *ptr) { - return ptr > _heap && ptr < (_heap + HEAP_SIZE) ? (HEAPHANDLE)(ptr - _heap) - : 0; -} -//---------------------------- -uint16 heapGetBlockSize(HEAPHANDLE ptr) { - return READ_UINT16(_heap + ptr - 2); -} -//---------------------------- -uint16 heapGetDataSize(HEAPHANDLE ptr) { - return heapGetBlockSize(ptr) - 2; -} -//---------------------------- -void heapFillPtr(HEAPHANDLE ptr, byte filler) { - memset(heap2Ptr(ptr), filler, heapGetDataSize(ptr)); -} -//---------------------------- -void heapClearPtr(HEAPHANDLE ptr) { - heapFillPtr(ptr, 0); -} -//---------------------------- -void heapSetBlockSize(HEAPHANDLE ptr, uint16 nbytes) { - WRITE_UINT16(_heap + ptr - 2, nbytes); -} -//---------------------------- -HEAPHANDLE heapGetBlockNext(HEAPHANDLE ptr) { - return READ_UINT16(_heap + ptr); -} -//---------------------------- -void heapSetBlockNext(HEAPHANDLE ptr, SCIHANDLE next) { - WRITE_UINT16(_heap + ptr, next); -} -//---------------------------- -void heapDisposePtr(byte *ptr) { - heapDisposePtr(ptr - _heap); -} -//--------------------------------------------- -// -// -void setHeapInfo(HEAPHANDLE hnd, kDataType type, const char *szinfo) { - tagHeapInfo info = { kDataUnknown, { 0 } }; - info.type = type; - if (szinfo) - strncpy(info.info, szinfo, 20); - heapInfo.setVal(hnd, info); -} -//-------------------------------- -bool saveMemState(Common::OutSaveFile *pFile) { - pFile->writeString("MEMORY\n"); - // saving heap - pFile->write(_heap, HEAP_SIZE); - pFile->writeUint16LE(_firstfree); - // TODO : process and write hunk handles - //pFile->writeString("HUNK\n"); - return true; -} -//-------------------------------- -bool restoreMemState(Common::InSaveFile *pFile) { - if (pFile->readLine() != "MEMORY") - return false; - pFile->read(_heap, HEAP_SIZE); - _firstfree = pFile->readUint16LE(); - - return true; -} - -//------------------------------- -}// End of namespace SCI diff --git a/engines/sci/gui/gui_memmgr.h b/engines/sci/gui/gui_memmgr.h deleted file mode 100644 index 3053d6a403..0000000000 --- a/engines/sci/gui/gui_memmgr.h +++ /dev/null @@ -1,123 +0,0 @@ -/* 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$ - * - */ - -#ifndef SCI_GUI_MEMMGR_H -#define SCI_GUI_MEMMGR_H - -#include "common/savefile.h" -#include "common/endian.h" -#include "common/hashmap.h" - -/* - Memory management functions for SCI engine; - All fuctions are simplified as there is no 16-bit limitations as in - original SCI. Although it may cause problems. - - SCI Heap functionality. - Heap size is limited to 65535 bytes to be consistent with SCI scripts - Free block header is [wBlockSize][wNextFree] - Used block header is [wBlockSize][data.....] - ^-----returned HEAPHANDLE - */ - -namespace Sci { - -typedef uint16 SCIHANDLE; -typedef uint16 HEAPHANDLE; - -enum { - HEAP_SIZE = 0x10000l, - HEAP_START = 2 -}; - -struct tagHandle { - byte *ptr; // data pointer - uint32 size; // memory block size - uint32 resId; // associated resource -}; -//--------------------------------------------- -// for debugger -enum kDataType { - kDataUnknown = 0, - kDataClass, - kDataObject, - kDataRect, - kDataWindow, - kDataPort, - kDataString, - kDataListHdr, - kDataListNode, - kDataCast, - kDataPalette, - kDataScript, - kDataFile -}; - -struct tagHeapInfo { - kDataType type; - char info[21]; -}; - -void setHeapInfo(HEAPHANDLE hnd, kDataType type, const char *info = 0); - -bool InitMem(int16 max_handles); -void FreeMem(void); - -// hunk functions -SCIHANDLE hunkNeedHandle(uint16 size, uint32 resId = 0xFFFFFFFF); -void hunkDisposeHandle(SCIHANDLE handle); - -byte *hunk2Ptr(SCIHANDLE handle); -SCIHANDLE ptr2hunk(byte *ptr); -uint32 hunkHandleSize(SCIHANDLE handle); -int16 hunkResourceNum(SCIHANDLE handle); -void hunkDump(); -uint32 hunkUsed(); - -// heap functions -HEAPHANDLE heapNewPtr(uint16 size, kDataType type/*=kDataUnknown*/, - const char *info = 0); -void heapDisposePtr(HEAPHANDLE handle); -void heapDisposePtr(byte *ptr); -byte *heap2Ptr(HEAPHANDLE ptr); -HEAPHANDLE ptr2heap(byte *ptr); -uint16 heapGetBlockSize(HEAPHANDLE ptr); -uint16 heapGetDataSize(HEAPHANDLE ptr); -void heapFillPtr(HEAPHANDLE ptr, byte filler); -void heapClearPtr(HEAPHANDLE ptr); -void heapDump(); -uint16 heapFreeSize(); -uint16 heapLargestFreeSize(); - -void heapSetBlockSize(HEAPHANDLE ptr, uint16 nbytes); -HEAPHANDLE heapGetBlockNext(HEAPHANDLE ptr); -void heapSetBlockNext(HEAPHANDLE ptr, SCIHANDLE next); - -bool saveMemState(Common::OutSaveFile *pFile); -bool restoreMemState(Common::InSaveFile *pFile); - -} // End of namespace SCI - -#endif diff --git a/engines/sci/gui/gui_windowmgr.cpp b/engines/sci/gui/gui_windowmgr.cpp index 85681f7ec9..38d2cc8787 100644 --- a/engines/sci/gui/gui_windowmgr.cpp +++ b/engines/sci/gui/gui_windowmgr.cpp @@ -23,7 +23,6 @@ * */ -#include "common/algorithm.h" // for Common::find() #include "common/util.h" #include "sci/sci.h" @@ -31,14 +30,9 @@ #include "sci/tools.h" #include "sci/gui/gui_gfx.h" #include "sci/gui/gui_windowmgr.h" -#include "sci/gui/gui_memmgr.h" namespace Sci { -namespace { -const Common::Rect s_picRect(0, 10, 320, 200); -} // end of anonymous namespace - // window styles enum { kTransparent = (1 << 0), @@ -51,12 +45,10 @@ enum { SciGUIwindowMgr::SciGUIwindowMgr(EngineState *state, SciGUIgfx *gfx) : _s(state), _gfx(gfx) { - // FIXME: remove memmgr - InitMem(0x320); - - HEAPHANDLE wmgrPortH = heapNewPtr(sizeof(GUIPort), kDataPort, "wmgrPort"); - heapClearPtr(wmgrPortH); - _wmgrPort = (GUIPort *)heap2Ptr(wmgrPortH); + _wmgrPort = new GUIPort(1); + _windowsById.resize(2); + _windowsById[0] = 0; + _windowsById[1] = _wmgrPort; int16 offTop = 20; @@ -69,75 +61,71 @@ SciGUIwindowMgr::SciGUIwindowMgr(EngineState *state, SciGUIgfx *gfx) _wmgrPort->curTop = 0; _wmgrPort->curLeft = 0; - windowList.push_front(wmgrPortH); + _windowList.push_front(_wmgrPort); - _picWind = NewWindow(s_picRect, 0, 0, kTransparent | kNoFrame, 0, 1); + _picWind = NewWindow(Common::Rect(0, 10, 320, 200), 0, 0, kTransparent | kNoFrame, 0, 1); } SciGUIwindowMgr::~SciGUIwindowMgr() { + // TODO: Clear _windowList and delete all stuff in it? } int16 SciGUIwindowMgr::isFrontWindow(GUIWindow *pWnd) { - if (heap2Ptr(windowList.back()) == (byte *)pWnd) - return 1; - return 0; -} - -void SciGUIwindowMgr::SelectWindow(HEAPHANDLE hh) { - GUIPort *port = (GUIPort *)heap2Ptr(hh); - _gfx->SetPort(port); - if (hh != windowList.back()) { // selecting not topmost window - Common::List::iterator curWindowIterator = Common::find(windowList.begin(), windowList.end(), hh); - Common::List::iterator prevWindowIterator = --curWindowIterator; - curWindowIterator++; // restore iterator position - GUIWindow *prevwnd = (GUIWindow *)heap2Ptr(*prevWindowIterator); - BeginUpdate(prevwnd); - windowList.erase(curWindowIterator); - windowList.push_back(hh); - EndUpdate(prevwnd); - } - _gfx->SetPort(port); + return _windowList.back() == pWnd; } void SciGUIwindowMgr::BeginUpdate(GUIWindow *wnd) { GUIPort *oldPort = _gfx->SetPort(_wmgrPort); - Common::List::iterator curWindowIterator = windowList.end(); - GUIWindow *node = (GUIWindow *)heap2Ptr(*curWindowIterator); - while (node != wnd) { - UpdateWindow(node); - curWindowIterator--; // previous node - node = (GUIWindow *)heap2Ptr(*curWindowIterator); + PortList::iterator it = _windowList.reverse_begin(); + const PortList::iterator end = Common::find(_windowList.begin(), _windowList.end(), wnd); + while (it != end) { + // FIXME: We also store GUIPort objects in the window list. + // We should add a check that we really only pass windows here... + UpdateWindow((GUIWindow *)*it); + --it; } _gfx->SetPort(oldPort); } void SciGUIwindowMgr::EndUpdate(GUIWindow *wnd) { GUIPort *oldPort = _gfx->SetPort(_wmgrPort); - Common::List::iterator curWindowIterator = windowList.end(); - GUIWindow *last = (GUIWindow *)heap2Ptr(*curWindowIterator); - while (wnd != last) { - curWindowIterator++; // next node - wnd = (GUIWindow *)heap2Ptr(*curWindowIterator); - UpdateWindow(wnd); + const PortList::iterator end = _windowList.end(); + PortList::iterator it = Common::find(_windowList.begin(), end, wnd); + while (it != end) { + ++it; + // FIXME: We also store GUIPort objects in the window list. + // We should add a check that we really only pass windows here... + UpdateWindow((GUIWindow *)*it); } + _gfx->SetPort(oldPort); } 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); + // Find an unused window/port id + uint id = 1; + while (id < _windowsById.size() && _windowsById[id]) { + ++id; + } + if (id == _windowsById.size()) + _windowsById.push_back(0); + assert(0 < id && id < 0xFFFF); + + + GUIWindow *pwnd = new GUIWindow(id); Common::Rect r; - if (!hWnd) { + if (!pwnd) { warning("Can't open window!"); return 0; } - heapClearPtr(hWnd); + + _windowsById[id] = pwnd; if (style & kTopmost) - windowList.push_front(hWnd); + _windowList.push_front(pwnd); else - windowList.push_back(hWnd); - GUIWindow *pwnd = (GUIWindow *)heap2Ptr(hWnd); - _gfx->OpenPort((GUIPort *)pwnd); + _windowList.push_back(pwnd); + _gfx->OpenPort(pwnd); r = dims; pwnd->rect = dims; if (restoreRect) @@ -150,13 +138,7 @@ GUIWindow *SciGUIwindowMgr::NewWindow(const Common::Rect &dims, const Common::Re pwnd->uSaveFlag = (arg8 == 0xFFFF ? 1 : 3); if (title && (style & kTitle)) { - HEAPHANDLE hTitle = heapNewPtr((uint16)strlen(title) + 1, kDataString, title); - if (!hTitle) { - warning("Can't open window!"); - return 0; - } - pwnd->hTitle = hTitle; - strcpy((char *)heap2Ptr(hTitle), title); + pwnd->title = title; } r = dims; @@ -229,10 +211,10 @@ void SciGUIwindowMgr::DrawWindow(GUIWindow *pWnd) { _gfx->FrameRect(r); r.grow(-1); _gfx->FillRect(r, 1, 0); - if (pWnd->hTitle) { + if (!pWnd->title.empty()) { int16 oldcolor = _gfx->GetPort()->penClr; _gfx->PenColor(255); - _gfx->TextBox((char *)heap2Ptr(pWnd->hTitle), 1, r, 1, 0); + _gfx->TextBox(pWnd->title.c_str(), 1, r, 1, 0); _gfx->PenColor(oldcolor); } @@ -258,12 +240,10 @@ void SciGUIwindowMgr::DisposeWindow(GUIWindow *pWnd, int16 arg2) { _gfx->ShowBits(pWnd->restoreRect, 1); // else // g_sci->ReAnimate(&pwnd->dims); - HEAPHANDLE hh = ptr2heap((byte *)pWnd); - windowList.remove(hh); - SelectWindow(windowList.back()); - if (pWnd->hTitle) - heapDisposePtr(pWnd->hTitle); - heapDisposePtr(hh); + _windowList.remove(pWnd); + _gfx->SetPort(_windowList.back()); + _windowsById[pWnd->id] = 0; + delete pWnd; } void SciGUIwindowMgr::UpdateWindow(GUIWindow *wnd) { diff --git a/engines/sci/gui/gui_windowmgr.h b/engines/sci/gui/gui_windowmgr.h index 29a63462e0..c975f94e69 100644 --- a/engines/sci/gui/gui_windowmgr.h +++ b/engines/sci/gui/gui_windowmgr.h @@ -27,19 +27,16 @@ #define SCI_GUI_WINDOWMGR_H #include "common/list.h" +#include "common/array.h" namespace Sci { -// TODO: remove HEAPHANDLE and make a list of GUIWindow pointers instead -typedef uint16 HEAPHANDLE; - class SciGUIwindowMgr { public: SciGUIwindowMgr(EngineState *state, SciGUIgfx *gfx); ~SciGUIwindowMgr(); int16 isFrontWindow(GUIWindow *wnd); - void SelectWindow(HEAPHANDLE hh); void BeginUpdate(GUIWindow *wnd); void EndUpdate(GUIWindow *wnd); GUIWindow *NewWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, uint16 arg8, uint16 argA); @@ -47,14 +44,22 @@ public: void DisposeWindow(GUIWindow *pWnd, int16 arg2); void UpdateWindow(GUIWindow *wnd); + GUIPort *getPortById(uint16 id) const { return _windowsById[id]; } + GUIPort *_wmgrPort; GUIWindow *_picWind; private: + typedef Common::List PortList; + EngineState *_s; SciGUIgfx *_gfx; - Common::List windowList; + /** The list of open 'windows' (and ports), in visual order. */ + PortList _windowList; + + /** The list of all open 'windows' (and ports), ordered by their id. */ + Common::Array _windowsById; }; } // End of namespace Sci diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 00ccb917dd..80c64aefd6 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -58,7 +58,6 @@ MODULE_OBJS = \ gui/gui.o \ gui/gui_font.o \ gui/gui_gfx.o \ - gui/gui_memmgr.o \ gui/gui_picture.o \ gui/gui_screen.o \ gui/gui_view.o \ -- cgit v1.2.3