aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMax Horn2009-10-26 10:41:11 +0000
committerMax Horn2009-10-26 10:41:11 +0000
commitbbe0b81aff36cc188d598ba3d66cc2521e14c0f2 (patch)
tree0e80d17016153e5cc604c9da6b6ce9b63db54dbd /engines
parent9065dca09aeb046d2e4b76a3edf82b9b8360a7e4 (diff)
downloadscummvm-rg350-bbe0b81aff36cc188d598ba3d66cc2521e14c0f2.tar.gz
scummvm-rg350-bbe0b81aff36cc188d598ba3d66cc2521e14c0f2.tar.bz2
scummvm-rg350-bbe0b81aff36cc188d598ba3d66cc2521e14c0f2.zip
TINSEL: Remove DWM_FIXED and add new MemoryAllocFixed() function
svn-id: r45401
Diffstat (limited to 'engines')
-rw-r--r--engines/tinsel/dialogs.cpp8
-rw-r--r--engines/tinsel/handle.cpp85
-rw-r--r--engines/tinsel/heapmem.cpp89
-rw-r--r--engines/tinsel/heapmem.h21
4 files changed, 97 insertions, 106 deletions
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 36f7017c99..c5686378c5 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -5526,7 +5526,7 @@ void RegisterIcons(void *cptr, int num) {
if (TinselV0) {
// In Tinsel 0, the INV_OBJECT structure doesn't have an attributes field, so we
// need to 'unpack' the source structures into the standard Tinsel v1/v2 format
- invObjects = (INV_OBJECT *)MemoryAlloc(DWM_FIXED, numObjects * sizeof(INV_OBJECT));
+ invObjects = (INV_OBJECT *)MemoryAllocFixed(numObjects * sizeof(INV_OBJECT));
byte *srcP = (byte *)cptr;
INV_OBJECT *destP = (INV_OBJECT *)invObjects;
@@ -5535,9 +5535,11 @@ void RegisterIcons(void *cptr, int num) {
destP->attribute = 0;
}
} else if (TinselV2) {
- if (invFilms == NULL)
+ if (invFilms == NULL) {
// First time - allocate memory
- invFilms = (SCNHANDLE *)MemoryAlloc(DWM_FIXED | DWM_ZEROINIT, numObjects * sizeof(SCNHANDLE));
+ invFilms = (SCNHANDLE *)MemoryAllocFixed(numObjects * sizeof(SCNHANDLE));
+ memset(invFilms, 0, numObjects * sizeof(SCNHANDLE));
+ }
if (invFilms == NULL)
error(NO_MEM, "inventory scripts");
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index cdccf9027f..b1d4e608df 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -48,9 +48,10 @@ bool bLockedScene = 0;
//----------------- LOCAL DEFINES --------------------
struct MEMHANDLE {
- char szName[12]; ///< 00 - file name of graphics file
- int32 filesize; ///< 12 - file size and flags
- MEM_NODE *pNode; ///< 16 - memory node for the graphics
+ char szName[12]; ///< file name of graphics file
+ int32 filesize; ///< file size and flags
+ MEM_NODE *_node; ///< memory node for the graphics
+ uint8 *_ptr; ///< start of data for fixed blocks (i.e., preloaded data)
uint32 flags2;
};
@@ -127,7 +128,8 @@ void SetupHandleTable(void) {
handleTable[i].filesize = f.readUint32LE();
// The pointer should always be NULL. We don't
// need to read that from the file.
- handleTable[i].pNode = NULL;
+ handleTable[i]._node = NULL;
+ handleTable[i]._ptr = NULL;
f.seek(4, SEEK_CUR);
// For Discworld 2, read in the flags2 field
handleTable[i].flags2 = t2Flag ? f.readUint32LE() : 0;
@@ -151,30 +153,30 @@ void SetupHandleTable(void) {
for (i = 0, pH = handleTable; i < numHandles; i++, pH++) {
if (pH->filesize & fPreload) {
// allocate a fixed memory node for permanent files
- pH->pNode = MemoryAlloc(DWM_FIXED, sizeof(MEM_NODE) + (pH->filesize & FSIZE_MASK));
+ pH->_ptr = (uint8 *)MemoryAllocFixed((pH->filesize & FSIZE_MASK));
+ pH->_node = NULL;
// make sure memory allocated
- assert(pH->pNode);
-
- // Initialise the MEM_NODE structure
- memset(pH->pNode, 0, sizeof(MEM_NODE));
+ assert(pH->_ptr);
// load the data
LoadFile(pH, true);
}
#ifdef BODGE
else if ((pH->filesize & FSIZE_MASK) == 8) {
- pH->pNode = NULL;
+ pH->_node = NULL;
+ pH->_ptr = NULL;
}
#endif
else {
// allocate a discarded memory node for other files
- pH->pNode = MemoryAlloc(
+ pH->_node = MemoryAlloc(
DWM_MOVEABLE | DWM_DISCARDABLE | DWM_NOALLOC,
pH->filesize & FSIZE_MASK);
+ pH->_ptr = NULL;
// make sure memory allocated
- assert(pH->pNode);
+ assert(pH->_node || pH->_ptr);
}
}
}
@@ -213,7 +215,7 @@ void LoadCDGraphData(MEMHANDLE *pH) {
assert(!(pH->filesize & fPreload));
// discardable - lock the memory
- addr = (byte *)MemoryLock(pH->pNode);
+ addr = (byte *)MemoryLock(pH->_node);
// make sure address is valid
assert(addr);
@@ -230,7 +232,7 @@ void LoadCDGraphData(MEMHANDLE *pH) {
}
// discardable - unlock the memory
- MemoryUnlock(pH->pNode);
+ MemoryUnlock(pH->_node);
// set the loaded flag
pH->filesize |= fLoaded;
@@ -256,8 +258,8 @@ void LoadExtraGraphData(SCNHANDLE start, SCNHANDLE next) {
OpenCDGraphFile();
- if ((handleTable + cdPlayHandle)->pNode->pBaseAddr != NULL)
- MemoryDiscard((handleTable + cdPlayHandle)->pNode); // Free it
+ if ((handleTable + cdPlayHandle)->_node->pBaseAddr != NULL)
+ MemoryDiscard((handleTable + cdPlayHandle)->_node); // Free it
// It must always be the same
assert(cdPlayHandle == (start >> SCNHANDLE_SHIFT));
@@ -301,19 +303,19 @@ void LoadFile(MEMHANDLE *pH, bool bWarn) {
if (pH->filesize & fPreload)
// preload - no need to lock the memory
- addr = (uint8 *)pH->pNode + sizeof(MEM_NODE);
+ addr = pH->_ptr;
else {
// discardable - lock the memory
- addr = (uint8 *)MemoryLock(pH->pNode);
+ addr = (uint8 *)MemoryLock(pH->_node);
}
#ifdef DEBUG
if (addr == NULL) {
if (pH->filesize & fPreload)
// preload - no need to lock the memory
- addr = (uint8 *)pH->pNode;
+ addr = pH->_ptr;
else {
// discardable - lock the memory
- addr = (uint8 *)MemoryLock(pH->pNode);
+ addr = (uint8 *)MemoryLock(pH->_node);
}
}
#endif
@@ -328,7 +330,7 @@ void LoadFile(MEMHANDLE *pH, bool bWarn) {
if ((pH->filesize & fPreload) == 0) {
// discardable - unlock the memory
- MemoryUnlock(pH->pNode);
+ MemoryUnlock(pH->_node);
}
// set the loaded flag
@@ -362,50 +364,52 @@ byte *LockMem(SCNHANDLE offset) {
pH = handleTable + handle;
if (pH->filesize & fPreload) {
+#if 0
if (TinselV2)
// update the LRU time (new in this file)
pH->pNode->lruTime = DwGetCurrentTime();
+#endif
// permanent files are already loaded
- return (uint8 *)pH->pNode + sizeof(MEM_NODE) + (offset & OFFSETMASK);
+ return pH->_ptr + (offset & OFFSETMASK);
} else if (handle == cdPlayHandle) {
// Must be in currently loaded/loadable range
if (offset < cdBaseHandle || offset >= cdTopHandle)
error("Overlapping (in time) CD-plays");
- if (pH->pNode->pBaseAddr && (pH->filesize & fLoaded))
+ if (pH->_node->pBaseAddr && (pH->filesize & fLoaded))
// already allocated and loaded
- return pH->pNode->pBaseAddr + ((offset - cdBaseHandle) & OFFSETMASK);
+ return pH->_node->pBaseAddr + ((offset - cdBaseHandle) & OFFSETMASK);
- if (pH->pNode->pBaseAddr == NULL)
+ if (pH->_node->pBaseAddr == NULL)
// must have been discarded - reallocate the memory
- MemoryReAlloc(pH->pNode, cdTopHandle-cdBaseHandle,
+ MemoryReAlloc(pH->_node, cdTopHandle-cdBaseHandle,
DWM_MOVEABLE | DWM_DISCARDABLE);
- if (pH->pNode->pBaseAddr == NULL)
+ if (pH->_node->pBaseAddr == NULL)
error("Out of memory");
LoadCDGraphData(pH);
// make sure address is valid
- assert(pH->pNode->pBaseAddr);
+ assert(pH->_node->pBaseAddr);
// update the LRU time (new in this file)
- pH->pNode->lruTime = DwGetCurrentTime();
+ pH->_node->lruTime = DwGetCurrentTime();
- return pH->pNode->pBaseAddr + ((offset - cdBaseHandle) & OFFSETMASK);
+ return pH->_node->pBaseAddr + ((offset - cdBaseHandle) & OFFSETMASK);
} else {
- if (pH->pNode->pBaseAddr && (pH->filesize & fLoaded))
+ if (pH->_node->pBaseAddr && (pH->filesize & fLoaded))
// already allocated and loaded
- return pH->pNode->pBaseAddr + (offset & OFFSETMASK);
+ return pH->_node->pBaseAddr + (offset & OFFSETMASK);
- if (pH->pNode->pBaseAddr == NULL)
+ if (pH->_node->pBaseAddr == NULL)
// must have been discarded - reallocate the memory
- MemoryReAlloc(pH->pNode, pH->filesize & FSIZE_MASK,
+ MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK,
DWM_MOVEABLE | DWM_DISCARDABLE);
- if (pH->pNode->pBaseAddr == NULL)
+ if (pH->_node->pBaseAddr == NULL)
error("Out of memory");
if (TinselV2) {
@@ -415,9 +419,9 @@ byte *LockMem(SCNHANDLE offset) {
LoadFile(pH, true);
// make sure address is valid
- assert(pH->pNode->pBaseAddr);
+ assert(pH->_node->pBaseAddr);
- return pH->pNode->pBaseAddr + (offset & OFFSETMASK);
+ return pH->_node->pBaseAddr + (offset & OFFSETMASK);
}
}
@@ -447,7 +451,7 @@ void LockScene(SCNHANDLE offset) {
// WORKAROUND: The original didn't include the DWM_LOCKED flag. It's being
// included because the method is 'LockScene' so it's presumed that the
// point of this was that the scene's memory block be locked
- MemoryReAlloc(pH->pNode, pH->filesize & FSIZE_MASK, DWM_MOVEABLE | DWM_LOCKED);
+ MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK, DWM_MOVEABLE | DWM_LOCKED);
#ifdef DEBUG
bLockedScene = true;
#endif
@@ -470,7 +474,7 @@ void UnlockScene(SCNHANDLE offset) {
if ((pH->filesize & fPreload) == 0) {
// change the flags for the node
- MemoryReAlloc(pH->pNode, pH->filesize & FSIZE_MASK, DWM_MOVEABLE | DWM_DISCARDABLE);
+ MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK, DWM_MOVEABLE | DWM_DISCARDABLE);
#ifdef DEBUG
bLockedScene = false;
#endif
@@ -510,7 +514,8 @@ void TouchMem(SCNHANDLE offset) {
pH = handleTable + handle;
// update the LRU time whether its loaded or not!
- pH->pNode->lruTime = DwGetCurrentTime();
+ if (pH->_node)
+ pH->_node->lruTime = DwGetCurrentTime();
}
}
diff --git a/engines/tinsel/heapmem.cpp b/engines/tinsel/heapmem.cpp
index 8a5d351381..b358b945e0 100644
--- a/engines/tinsel/heapmem.cpp
+++ b/engines/tinsel/heapmem.cpp
@@ -279,11 +279,6 @@ MEM_NODE *MemoryAlloc(int flags, long size) {
MEM_NODE *pNode;
bool bCompacted = true; // set when heap has been compacted
- // compact the heap if we are allocating fixed memory
- if (flags & DWM_FIXED) {
- HeapCompact(MAX_INT, false);
- }
-
#ifdef SCUMM_NEED_ALIGNMENT
const int alignPadding = sizeof(void*) - 1;
size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void*), this ensures the addresses that are returned are alignment-safe.
@@ -307,12 +302,8 @@ MEM_NODE *MemoryAlloc(int flags, long size) {
if (flags & DWM_ZEROINIT)
memset(pNode->pBaseAddr, 0, size);
- if (flags & DWM_FIXED)
- // lock the memory
- return (MEM_NODE *)MemoryLock(pNode);
- else
- // just return the node
- return pNode;
+ // return the node
+ return pNode;
} else {
// allocate a node for the remainder of the free block
MEM_NODE *pTemp = AllocMemNode();
@@ -326,34 +317,19 @@ MEM_NODE *MemoryAlloc(int flags, long size) {
// set size of node
pNode->size = size;
- if (flags & DWM_FIXED) {
- // place the free node after pNode
- pTemp->pBaseAddr = pNode->pBaseAddr + size;
- pTemp->pNext = pNode->pNext;
- pTemp->pPrev = pNode;
- pNode->pNext->pPrev = pTemp;
- pNode->pNext = pTemp;
-
- // check for zeroing the block
- if (flags & DWM_ZEROINIT)
- memset(pNode->pBaseAddr, 0, size);
-
- return (MEM_NODE *)MemoryLock(pNode);
- } else {
- // place the free node before pNode
- pTemp->pBaseAddr = pNode->pBaseAddr;
- pNode->pBaseAddr += freeSize;
- pTemp->pNext = pNode;
- pTemp->pPrev = pNode->pPrev;
- pNode->pPrev->pNext = pTemp;
- pNode->pPrev = pTemp;
-
- // check for zeroing the block
- if (flags & DWM_ZEROINIT)
- memset(pNode->pBaseAddr, 0, size);
-
- return pNode;
- }
+ // place the free node before pNode
+ pTemp->pBaseAddr = pNode->pBaseAddr;
+ pNode->pBaseAddr += freeSize;
+ pTemp->pNext = pNode;
+ pTemp->pPrev = pNode->pPrev;
+ pNode->pPrev->pNext = pTemp;
+ pNode->pPrev = pTemp;
+
+ // check for zeroing the block
+ if (flags & DWM_ZEROINIT)
+ memset(pNode->pBaseAddr, 0, size);
+
+ return pNode;
}
}
}
@@ -383,6 +359,21 @@ MEM_NODE *MemoryAlloc(int flags, long size) {
return NULL;
}
+
+void *MemoryAllocFixed(long size) {
+ // Allocate a fixed block of data. For now, we simply malloc it!
+ // TODO: We really should keep a list of the allocated pointers,
+ // so that we can discard them later on, when the engine quits.
+
+#ifdef SCUMM_NEED_ALIGNMENT
+ const int alignPadding = sizeof(void*) - 1;
+ size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void*), this ensures the addresses that are returned are alignment-safe.
+#endif
+
+ return malloc(size);
+}
+
+
/**
* Discards the specified memory object.
* @param pMemNode Node of the memory object
@@ -512,14 +503,8 @@ MEM_NODE *MemoryReAlloc(MEM_NODE *pMemNode, long size, int flags) {
assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
// validate the flags
- // cannot be fixed and moveable
- assert((flags & (DWM_FIXED | DWM_MOVEABLE)) != (DWM_FIXED | DWM_MOVEABLE));
-
- // cannot be fixed and discardable
- assert((flags & (DWM_FIXED | DWM_DISCARDABLE)) != (DWM_FIXED | DWM_DISCARDABLE));
-
- // must be fixed or moveable
- assert(flags & (DWM_FIXED | DWM_MOVEABLE));
+ // must be moveable
+ assert(flags & DWM_MOVEABLE);
// align the size to machine boundary requirements
size = (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
@@ -541,7 +526,7 @@ MEM_NODE *MemoryReAlloc(MEM_NODE *pMemNode, long size, int flags) {
pMemNode->pPrev->pNext = pMemNode->pNext;
// allocate a new node
- pNew = MemoryAlloc((flags & ~DWM_FIXED) | DWM_MOVEABLE, size);
+ pNew = MemoryAlloc(flags | DWM_MOVEABLE, size);
// make sure memory allocated
assert(pNew != NULL);
@@ -560,12 +545,8 @@ MEM_NODE *MemoryReAlloc(MEM_NODE *pMemNode, long size, int flags) {
FreeMemNode(pNew);
}
- if (flags & DWM_FIXED)
- // lock the memory
- return (MEM_NODE *)MemoryLock(pMemNode);
- else
- // just return the node
- return pMemNode;
+ // return the node
+ return pMemNode;
}
/**
diff --git a/engines/tinsel/heapmem.h b/engines/tinsel/heapmem.h
index 358c5f77b5..2bea20f231 100644
--- a/engines/tinsel/heapmem.h
+++ b/engines/tinsel/heapmem.h
@@ -43,14 +43,13 @@ struct MEM_NODE {
};
// allocation flags for the MemoryAlloc function
-#define DWM_FIXED 0x0001 // allocates fixed memory
-#define DWM_MOVEABLE 0x0002 // allocates movable memory
-#define DWM_DISCARDABLE 0x0004 // allocates discardable memory
-#define DWM_NOALLOC 0x0008 // when used with discardable memory - allocates a discarded block
-#define DWM_NOCOMPACT 0x0010 // does not discard memory to satisfy the allocation request
-#define DWM_ZEROINIT 0x0020 // initialises memory contents to zero
-#define DWM_SOUND 0x0040 // allocate from the sound pool
-#define DWM_GRAPHIC 0x0080 // allocate from the graphics pool
+#define DWM_MOVEABLE 0x0002 ///< allocates movable memory
+#define DWM_DISCARDABLE 0x0004 ///< allocates discardable memory
+#define DWM_NOALLOC 0x0008 ///< when used with discardable memory - allocates a discarded block
+#define DWM_NOCOMPACT 0x0010 ///< does not discard memory to satisfy the allocation request
+#define DWM_ZEROINIT 0x0020 ///< initialises memory contents to zero
+#define DWM_SOUND 0x0040 ///< allocate from the sound pool
+#define DWM_GRAPHIC 0x0080 ///< allocate from the graphics pool
// return value from the MemoryFlags function
#define DWM_DISCARDED 0x0100 // the objects memory block has been discarded
@@ -70,10 +69,14 @@ void MemoryInit(void); // initialises the memory manager
void MemoryStats(void); // Shows the maximum number of mnodes used at once
#endif
-MEM_NODE *MemoryAlloc( // allocates the specified number of bytes from the heap
+// allocates a non-fixed block with the specified number of bytes from the heap
+MEM_NODE *MemoryAlloc(
int flags, // allocation attributes
long size); // number of bytes to allocate
+// allocates a fixed block with the specified number of bytes
+void *MemoryAllocFixed(long size);
+
void MemoryDiscard( // discards the specified memory object
MEM_NODE *pMemNode); // node of the memory object