SCI: Rework the way SciGUIwindowMgr keeps track of windows/ports; remove the GUI heapmanager
svn-id: r44635
This commit is contained in:
parent
f242266f6d
commit
db2e5a4fb5
10 changed files with 88 additions and 586 deletions
|
@ -100,8 +100,6 @@
|
|||
<File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_gfx.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_helpers.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.cpp" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_picture.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_screen.cpp" />
|
||||
|
|
|
@ -101,8 +101,6 @@
|
|||
<File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_gfx.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_helpers.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.cpp" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_picture.h" />
|
||||
<File RelativePath="..\..\engines\sci\gui\gui_screen.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;
|
||||
case 0:
|
||||
_gfx->SetPort(_windowMgr->_wmgrPort);
|
||||
break;
|
||||
case 0xFFFF:
|
||||
_gfx->SetPort(_gfx->_menuPort);
|
||||
break;
|
||||
default:
|
||||
_gfx->SetPort((GUIPort *)heap2Ptr(portPtr));
|
||||
_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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<HEAPHANDLE, tagHeapInfo> 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
|
|
@ -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
|
|
@ -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<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);
|
||||
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<HEAPHANDLE>::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<HEAPHANDLE>::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) {
|
||||
|
|
|
@ -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<GUIPort *> PortList;
|
||||
|
||||
EngineState *_s;
|
||||
SciGUIgfx *_gfx;
|
||||
|
||||
Common::List<HEAPHANDLE> 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<GUIPort *> _windowsById;
|
||||
};
|
||||
|
||||
} // End of namespace Sci
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue