[Scummvm-cvs-logs] SF.net SVN: scummvm:[45426] scummvm/trunk/engines/tinsel

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Tue Oct 27 01:36:56 CET 2009


Revision: 45426
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45426&view=rev
Author:   fingolfin
Date:     2009-10-27 00:36:56 +0000 (Tue, 27 Oct 2009)

Log Message:
-----------
TINSEL: Change MemoryAllocFixed to return a (kind of fake) MEM_NODE pointer; add MemoryDeinit()

Modified Paths:
--------------
    scummvm/trunk/engines/tinsel/dialogs.cpp
    scummvm/trunk/engines/tinsel/handle.cpp
    scummvm/trunk/engines/tinsel/heapmem.cpp
    scummvm/trunk/engines/tinsel/heapmem.h
    scummvm/trunk/engines/tinsel/tinsel.cpp

Modified: scummvm/trunk/engines/tinsel/dialogs.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/dialogs.cpp	2009-10-26 22:43:58 UTC (rev 45425)
+++ scummvm/trunk/engines/tinsel/dialogs.cpp	2009-10-27 00:36:56 UTC (rev 45426)
@@ -5526,7 +5526,10 @@
 	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 *)MemoryAllocFixed(numObjects * sizeof(INV_OBJECT));
+		MEM_NODE *node = MemoryAllocFixed(numObjects * sizeof(INV_OBJECT));
+		assert(node);
+		invObjects = (INV_OBJECT *)MemoryDeref(node);
+		assert(invObjects);
 		byte *srcP = (byte *)cptr;
 		INV_OBJECT *destP = (INV_OBJECT *)invObjects;
 
@@ -5537,12 +5540,14 @@
 	} else if (TinselV2) {
 		if (invFilms == NULL) {
 			// First time - allocate memory
-			invFilms = (SCNHANDLE *)MemoryAllocFixed(numObjects * sizeof(SCNHANDLE));
+			MEM_NODE *node = MemoryAllocFixed(numObjects * sizeof(SCNHANDLE));
+			assert(node);
+			invFilms = (SCNHANDLE *)MemoryDeref(node);
+			if (invFilms == NULL)
+				error(NO_MEM, "inventory scripts");
 			memset(invFilms, 0, numObjects * sizeof(SCNHANDLE));
 		}
 
-		if (invFilms == NULL)
-			error(NO_MEM, "inventory scripts");
 
 		// Add defined permanent conversation icons
 		// and store all the films separately

Modified: scummvm/trunk/engines/tinsel/handle.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/handle.cpp	2009-10-26 22:43:58 UTC (rev 45425)
+++ scummvm/trunk/engines/tinsel/handle.cpp	2009-10-27 00:36:56 UTC (rev 45426)
@@ -51,7 +51,6 @@
 	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;
 };
 
@@ -129,7 +128,6 @@
 				// The pointer should always be NULL. We don't
 				// need to read that from the file.
 				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;
@@ -153,11 +151,10 @@
 	for (i = 0, pH = handleTable; i < numHandles; i++, pH++) {
 		if (pH->filesize & fPreload) {
 			// allocate a fixed memory node for permanent files
-			pH->_ptr = (uint8 *)MemoryAllocFixed((pH->filesize & FSIZE_MASK));
-			pH->_node = NULL;
+			pH->_node = MemoryAllocFixed((pH->filesize & FSIZE_MASK));
 
 			// make sure memory allocated
-			assert(pH->_ptr);
+			assert(pH->_node);
 
 			// load the data
 			LoadFile(pH);
@@ -165,16 +162,14 @@
 #ifdef BODGE
 		else if ((pH->filesize & FSIZE_MASK) == 8) {
 			pH->_node = NULL;
-			pH->_ptr = NULL;
 		}
 #endif
 		else {
 			// allocate a discarded memory node for other files
 			pH->_node = MemoryNoAlloc();
-			pH->_ptr = NULL;
 
 			// make sure memory allocated
-			assert(pH->_node || pH->_ptr);
+			assert(pH->_node);
 		}
 	}
 }
@@ -297,13 +292,8 @@
 		int bytes;
 		uint8 *addr;
 
-		if (pH->filesize & fPreload)
-			// preload - no need to lock the memory
-			addr = pH->_ptr;
-		else {
-			// discardable - lock the memory
-			addr = (uint8 *)MemoryLock(pH->_node);
-		}
+		// lock the memory
+		addr = (uint8 *)MemoryLock(pH->_node);
 
 		// make sure address is valid
 		assert(addr);
@@ -313,10 +303,8 @@
 		// close the file
 		f.close();
 
-		if ((pH->filesize & fPreload) == 0) {
-			// discardable - unlock the memory
-			MemoryUnlock(pH->_node);
-		}
+		// discardable - unlock the memory
+		MemoryUnlock(pH->_node);
 
 		// set the loaded flag
 		pH->filesize |= fLoaded;
@@ -347,8 +335,7 @@
 	pH = handleTable + handle;
 
 	if (pH->filesize & fPreload) {
-		// permanent files are already loaded
-		return pH->_ptr + (offset & OFFSETMASK);
+		// permanent files are already loaded, nothing to be done
 	} else if (handle == cdPlayHandle) {
 		// Must be in currently loaded/loadable range
 		if (offset < cdBaseHandle || offset >= cdTopHandle)
@@ -365,8 +352,7 @@
 			MemoryTouch(pH->_node);
 		}
 
-		return MemoryDeref(pH->_node) + ((offset - cdBaseHandle) & OFFSETMASK);
-
+		offset -= cdBaseHandle;
 	} else {
 		// may have been discarded, make sure memory is allocated
 		MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK);
@@ -382,9 +368,9 @@
 			// make sure address is valid
 			assert(pH->filesize & fLoaded);
 		}
-
-		return MemoryDeref(pH->_node) + (offset & OFFSETMASK);
 	}
+
+	return MemoryDeref(pH->_node) + (offset & OFFSETMASK);
 }
 
 /**

Modified: scummvm/trunk/engines/tinsel/heapmem.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/heapmem.cpp	2009-10-26 22:43:58 UTC (rev 45425)
+++ scummvm/trunk/engines/tinsel/heapmem.cpp	2009-10-27 00:36:56 UTC (rev 45426)
@@ -69,6 +69,9 @@
 static int maxNodes;
 #endif
 
+// list of all fixed memory nodes
+MEM_NODE s_fixedMnodesList[5];
+
 // the mnode heap sentinel
 static MEM_NODE heapSentinel;
 
@@ -79,7 +82,7 @@
 /**
  * Initialises the memory manager.
  */
-void MemoryInit(void) {
+void MemoryInit() {
 	MEM_NODE *pNode;
 
 #ifdef DEBUG
@@ -98,6 +101,9 @@
 	// null the last mnode
 	mnodeList[NUM_MNODES - 1].pNext = NULL;
 
+	// clear list of fixed memory nodes
+	memset(s_fixedMnodesList, 0, sizeof(s_fixedMnodesList));
+
 	// allocates a big chunk of memory
 	uint32 size = MemoryPoolSize[0];
 	if (TinselVersion == TINSEL_V1) size = MemoryPoolSize[1];
@@ -128,9 +134,27 @@
 
 	// flag sentinel as locked
 	heapSentinel.flags = DWM_LOCKED | DWM_SENTINEL;
+
+	// store the start of the master data block in the sentinel
+	heapSentinel.pBaseAddr = mem;
 }
 
 /**
+ * Deinitialises the memory manager.
+ */
+void MemoryDeinit() {
+	MEM_NODE *pNode = s_fixedMnodesList;
+	for (int i = 0; i < ARRAYSIZE(s_fixedMnodesList); ++i, ++pNode) {
+		free(pNode->pBaseAddr);
+		pNode->pBaseAddr = 0;
+	}
+
+	// free memory used for the memory pool
+	free(heapSentinel.pBaseAddr);
+}
+
+
+/**
  * Allocate a mnode from the free list.
  */
 static MEM_NODE *AllocMemNode(void) {
@@ -362,18 +386,31 @@
 
 /**
  * Allocate a fixed block of data.
- * @note For now, we simply malloc it!
- * @todo We really should keep a list of the allocated pointers,
+ * @todo We really should keep track of the allocated pointers,
  *       so that we can discard them later on, when the engine quits.
  */
-void *MemoryAllocFixed(long size) {
+MEM_NODE *MemoryAllocFixed(long size) {
 
 #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);
+	// Search for a free entry in s_fixedMnodesList
+	MEM_NODE *pNode = s_fixedMnodesList;
+	for (int i = 0; i < ARRAYSIZE(s_fixedMnodesList); ++i, ++pNode) {
+		if (!pNode->pBaseAddr) {
+			pNode->pNext = 0;
+			pNode->pPrev = 0;
+			pNode->pBaseAddr = (byte *)malloc(size);
+			pNode->size = size;
+			pNode->lruTime = DwGetCurrentTime();
+			pNode->flags = DWM_USED;
+			return pNode;
+		}
+	}
+
+	return 0;
 }
 
 
@@ -429,9 +466,6 @@
  * @param pMemNode			Node of the memory object
  */
 void *MemoryLock(MEM_NODE *pMemNode) {
-	// validate mnode pointer
-	assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
-
 	// make sure memory object is not already locked
 	assert((pMemNode->flags & DWM_LOCKED) == 0);
 
@@ -497,9 +531,6 @@
  * @param pMemNode		Node of the memory object
  */
 void MemoryUnlock(MEM_NODE *pMemNode) {
-	// validate mnode pointer
-	assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
-
 	// make sure memory object is already locked
 	assert(pMemNode->flags & DWM_LOCKED);
 
@@ -515,17 +546,11 @@
  * @param pMemNode		Node of the memory object
  */
 void MemoryTouch(MEM_NODE *pMemNode) {
-	// validate mnode pointer
-	assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
-
 	// update the LRU time
 	pMemNode->lruTime = DwGetCurrentTime();
 }
 
 uint8 *MemoryDeref(MEM_NODE *pMemNode) {
-	// validate mnode pointer
-	assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
-
 	return pMemNode->pBaseAddr;
 }
 

Modified: scummvm/trunk/engines/tinsel/heapmem.h
===================================================================
--- scummvm/trunk/engines/tinsel/heapmem.h	2009-10-26 22:43:58 UTC (rev 45425)
+++ scummvm/trunk/engines/tinsel/heapmem.h	2009-10-27 00:36:56 UTC (rev 45426)
@@ -38,13 +38,14 @@
 |*			Memory Function Prototypes			*|
 \*----------------------------------------------------------------------*/
 
-void MemoryInit(void);		// initialises the memory manager
+void MemoryInit();			// initialises the memory manager
+void MemoryDeinit();		// deinitialises the memory manager
 
 // reserves a memory node for a movable & discardable block
 MEM_NODE *MemoryNoAlloc();
 
 // allocates a fixed block with the specified number of bytes
-void *MemoryAllocFixed(long size);
+MEM_NODE *MemoryAllocFixed(long size);
 
 void MemoryDiscard(		// discards the specified memory object
 	MEM_NODE *pMemNode);	// node of the memory object

Modified: scummvm/trunk/engines/tinsel/tinsel.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/tinsel.cpp	2009-10-26 22:43:58 UTC (rev 45425)
+++ scummvm/trunk/engines/tinsel/tinsel.cpp	2009-10-27 00:36:56 UTC (rev 45426)
@@ -893,6 +893,8 @@
 	FreeGlobalProcesses();
 	FreeGlobals();
 	delete _scheduler;
+
+	MemoryDeinit();
 }
 
 void TinselEngine::syncSoundSettings() {


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list