[Scummvm-cvs-logs] CVS: scummvm/sword2 anims.cpp,1.58,1.59 build_display.cpp,1.58,1.59 console.cpp,1.42,1.43 console.h,1.19,1.20 controls.cpp,1.66,1.67 debug.cpp,1.37,1.38 events.cpp,1.29,1.30 function.cpp,1.60,1.61 header.h,1.9,1.10 icons.cpp,1.35,1.36 interpreter.cpp,1.45,1.46 layers.cpp,1.27,1.28 logic.h,1.32,1.33 maketext.cpp,1.40,1.41 maketext.h,1.12,1.13 memory.cpp,1.25,1.26 memory.h,1.14,1.15 module.mk,1.10,1.11 mouse.cpp,1.55,1.56 protocol.cpp,1.25,1.26 resman.cpp,1.89,1.90 resman.h,1.19,1.20 router.cpp,1.41,1.42 router.h,1.16,1.17 save_rest.cpp,1.52,1.53 sound.cpp,1.41,1.42 speech.cpp,1.60,1.61 startup.cpp,1.40,1.41 sword2.cpp,1.109,1.110 sword2.h,1.56,1.57 walker.cpp,1.37,1.38 mem_view.cpp,1.26,NONE

Torbj?rn Andersson eriktorbjorn at users.sourceforge.net
Fri Apr 23 00:04:07 CEST 2004


Update of /cvsroot/scummvm/scummvm/sword2
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2431/sword2

Modified Files:
	anims.cpp build_display.cpp console.cpp console.h controls.cpp 
	debug.cpp events.cpp function.cpp header.h icons.cpp 
	interpreter.cpp layers.cpp logic.h maketext.cpp maketext.h 
	memory.cpp memory.h module.mk mouse.cpp protocol.cpp 
	resman.cpp resman.h router.cpp router.h save_rest.cpp 
	sound.cpp speech.cpp startup.cpp sword2.cpp sword2.h 
	walker.cpp 
Removed Files:
	mem_view.cpp 
Log Message:
Major revamping of the BS2 memory manager and, some small changes to the
resource manager. All new code! All new bugs!


Index: anims.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/anims.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- anims.cpp	27 Mar 2004 12:02:38 -0000	1.58
+++ anims.cpp	23 Apr 2004 07:01:35 -0000	1.59
@@ -81,9 +81,9 @@
 	//		1 pointer to object's graphic structure
 	//		2 resource id of animation file
 
- 	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
- 	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[1]);
-	uint8 *anim_file;
+ 	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
+ 	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[1]);
+	byte *anim_file;
 	AnimHeader *anim_head;
  	int32 res = params[2];
 
@@ -202,11 +202,11 @@
 	// If this is the start of the anim, read the anim table to get the
 	// appropriate anim resource
 
- 	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+ 	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	if (ob_logic->looping == 0) {
-	 	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]);
-		uint32 *anim_table = (uint32 *) _vm->_memory->intToPtr(params[3]);
+	 	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]);
+		uint32 *anim_table = (uint32 *) _vm->_memory->decodePtr(params[3]);
 
 		// appropriate anim resource is in 'table[direction]'
 		pars[2] = anim_table[ob_mega->current_dir];
@@ -224,7 +224,7 @@
 	assert(res);
 
 	// open the resource (& check it's valid)
-	uint8 *anim_file = _vm->_resman->openResource(res);
+	byte *anim_file = _vm->_resman->openResource(res);
 
 	StandardHeader *head = (StandardHeader *) anim_file;
 	assert(head->fileType == ANIMATION_FILE);
@@ -233,7 +233,7 @@
 	AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file);
 
 	// set up anim resource in graphic object
-	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[0]);
+	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[0]);
 
 	ob_graphic->anim_resource = res;
 	ob_graphic->anim_pc = params[2] ? anim_head->noAnimFrames - 1 : 0;
@@ -244,14 +244,14 @@
 }
 
 void Logic::setSpriteStatus(uint32 sprite, uint32 type) {
-	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(sprite);
+	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(sprite);
 
 	// Remove the previous status, but don't affect the shading upper-word
 	ob_graphic->type = (ob_graphic->type & 0xffff0000) | type;
 }
 
 void Logic::setSpriteShading(uint32 sprite, uint32 type) {
-	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(sprite);
+	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(sprite);
 
 	// Remove the previous shading, but don't affect the status lower-word.
 	// Note that drivers may still shade mega frames automatically, even
@@ -338,7 +338,7 @@
  	FrameHeader *frame;
  	uint32 local_text;
 	uint32 text_res;
-	uint8 *text;
+	byte *text;
 	uint32 wavId;	// ie. offical text number (actor text number)
 	bool speechRunning;
  	char speechFile[256];
@@ -426,19 +426,14 @@
 	// MovieTextObject's
 	sequenceText[_sequenceTextLines] = NULL;
 
-  	// now lock all the memory blocks containing text sprites & speech
-	// samples and set up the pointers to them, etc, for the drivers
-
 	for (line = 0; line < _sequenceTextLines; line++) {
 		// if we've made a text sprite for this line...
 
 		if (_sequenceTextList[line].text_mem) {
-			_vm->_memory->lockMemory(_sequenceTextList[line].text_mem);
-
 			// now fill out the SpriteInfo structure in the
 			// MovieTextObjectStructure
 
-			frame = (FrameHeader *) _sequenceTextList[line].text_mem->ad;
+			frame = (FrameHeader *) _sequenceTextList[line].text_mem;
 
 			sequenceText[line]->textSprite = new SpriteInfo;
 
@@ -448,7 +443,7 @@
 			sequenceText[line]->textSprite->w = frame->width;
 			sequenceText[line]->textSprite->h = frame->height;
 			sequenceText[line]->textSprite->type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION;
-			sequenceText[line]->textSprite->data = _sequenceTextList[line].text_mem->ad + sizeof(FrameHeader);
+			sequenceText[line]->textSprite->data = _sequenceTextList[line].text_mem + sizeof(FrameHeader);
 		}
 
 		// if we've loaded a speech sample for this line...
@@ -464,19 +459,17 @@
 }
 
 void Logic::clearSequenceSpeech(MovieTextObject *sequenceText[]) {
-	uint32 line;
-
-	for (line = 0; line < _sequenceTextLines; line++) {
+	for (uint i = 0; i < _sequenceTextLines; i++) {
 		// free up the memory used by this MovieTextObject
-		delete sequenceText[line];
+		delete sequenceText[i];
 
 		// free up the mem block containing this text sprite
-		if (_sequenceTextList[line].text_mem)
-			_vm->_memory->freeMemory(_sequenceTextList[line].text_mem);
+		if (_sequenceTextList[i].text_mem)
+			free(_sequenceTextList[i].text_mem);
 
 		// free up the mem block containing this speech sample
-		if (_sequenceTextList[line].speech_mem)
-			free(_sequenceTextList[line].speech_mem);
+		if (_sequenceTextList[i].speech_mem)
+			free(_sequenceTextList[i].speech_mem);
 	}
 
 	// IMPORTANT! Reset the line count ready for the next sequence!
@@ -484,7 +477,7 @@
 }
 
 int32 Logic::fnSmackerLeadIn(int32 *params) {
-	uint8 *leadIn;
+	byte *leadIn;
 	uint32 rv;
 
 	// params:	0 id of lead-in music
@@ -521,18 +514,18 @@
 
 	char filename[30];
 	MovieTextObject *sequenceSpeechArray[MAX_SEQUENCE_TEXT_LINES + 1];
-	uint8 *leadOut = NULL;
+	byte *leadOut = NULL;
 
 	// The original code had some #ifdef blocks for skipping or muting the
 	// cutscenes - fondly described as "the biggest fudge in the history
 	// of computer games" - but at the very least we want to show the
 	// cutscene subtitles, so I removed them.
 
-	debug(5, "fnPlaySequence(\"%s\");", (const char *) _vm->_memory->intToPtr(params[0]));
+	debug(5, "fnPlaySequence(\"%s\");", (const char *) _vm->_memory->decodePtr(params[0]));
 
 	// add the appropriate file extension & play it
 
-	strcpy(filename, (const char *) _vm->_memory->intToPtr(params[0]));
+	strcpy(filename, (const char *) _vm->_memory->decodePtr(params[0]));
 
 	// Write to walkthrough file (zebug0.txt)
  	debug(5, "PLAYING SEQUENCE \"%s\"", filename);
@@ -598,7 +591,7 @@
 	PalEntry pal[256];
 
 	memset(pal, 0, 256 * sizeof(PalEntry));
-	_vm->_graphics->setPalette(0, 256, (uint8 *) pal, RDPAL_INSTANT);
+	_vm->_graphics->setPalette(0, 256, (byte *) pal, RDPAL_INSTANT);
 
 	debug(5, "fnPlaySequence FINISHED");
 	return IR_CONT;

Index: build_display.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/build_display.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- build_display.cpp	7 Apr 2004 12:31:31 -0000	1.58
+++ build_display.cpp	23 Apr 2004 07:01:36 -0000	1.59
@@ -53,7 +53,7 @@
 	_graphics->animateMouse();
 	_graphics->startRenderCycle();
 
-	uint8 *file = _resman->openResource(_thisScreen.background_layer_id);
+	byte *file = _resman->openResource(_thisScreen.background_layer_id);
 	MultiScreenHeader *screenLayerTable = (MultiScreenHeader *) (file + sizeof(StandardHeader));
 
 	// Render at least one frame, but if the screen is scrolling, and if
@@ -118,7 +118,7 @@
  * @param time The number of seconds to display the message
  */
 
-void Sword2Engine::displayMsg(uint8 *text, int time) {
+void Sword2Engine::displayMsg(byte *text, int time) {
 	PalEntry pal[256];
 	PalEntry oldPal[256];
 
@@ -135,8 +135,8 @@
 	_graphics->closeMenuImmediately();
 	_graphics->clearScene();
 
-	Memory *text_spr = _fontRenderer->makeTextSprite(text, 640, 187, _speechFontId);
-	FrameHeader *frame = (FrameHeader *) text_spr->ad;
+	byte *text_spr = _fontRenderer->makeTextSprite(text, 640, 187, _speechFontId);
+	FrameHeader *frame = (FrameHeader *) text_spr;
 
 	SpriteInfo spriteInfo;
 
@@ -152,7 +152,7 @@
 	spriteInfo.scaledHeight	= 0;
 	spriteInfo.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION | RDSPR_TRANS;
 	spriteInfo.blend = 0;
-	spriteInfo.data = text_spr->ad + sizeof(FrameHeader);
+	spriteInfo.data = text_spr + sizeof(FrameHeader);
 	spriteInfo.colourTable = 0;
 
 	uint32 rv = _graphics->drawSprite(&spriteInfo);
@@ -166,15 +166,15 @@
 	pal[187].green = 255;
 	pal[187].blue = 255;
 
-	_graphics->setPalette(0, 256, (uint8 *) pal, RDPAL_FADE);
+	_graphics->setPalette(0, 256, (byte *) pal, RDPAL_FADE);
 	_graphics->fadeUp();
-	_memory->freeMemory(text_spr);
+	free(text_spr);
 	_graphics->waitForFade();
 
 	uint32 targetTime = _system->get_msecs() + (time * 1000);
 
 	sleepUntil(targetTime);
-	_graphics->setPalette(0, 256, (uint8 *) oldPal, RDPAL_FADE);
+	_graphics->setPalette(0, 256, (byte *) oldPal, RDPAL_FADE);
 }
 
 /**
@@ -211,7 +211,7 @@
 		processImage(&_backList[i]);
 }
 
-void Sword2Engine::drawSortFrames(uint8 *file) {
+void Sword2Engine::drawSortFrames(byte *file) {
 	uint i, j;
 
 	// Sort the sort list. Used to be a separate function, but it was only
@@ -260,7 +260,7 @@
 		processImage(&_fgp1List[i]);
 }
 
-void Sword2Engine::processLayer(uint8 *file, uint32 layer_number) {
+void Sword2Engine::processLayer(byte *file, uint32 layer_number) {
 	LayerHeader *layer_head = fetchLayerHeader(file, layer_number);
 
  	SpriteInfo spriteInfo;
@@ -295,8 +295,8 @@
 }
 
 void Sword2Engine::processImage(BuildUnit *build_unit) {
-	uint8 *file = _resman->openResource(build_unit->anim_resource);
-	uint8 *colTablePtr = NULL;
+	byte *file = _resman->openResource(build_unit->anim_resource);
+	byte *colTablePtr = NULL;
 
 	AnimHeader *anim_head = fetchAnimHeader(file);
 	CdtEntry *cdt_entry = fetchCdtEntry(file, build_unit->anim_pc);
@@ -337,7 +337,7 @@
 			spriteType |= RDSPR_RLE16;
 			// points to just after last cdt_entry, ie.
 			// start of colour table
-			colTablePtr = (uint8 *) (anim_head + 1) + anim_head->noAnimFrames * sizeof(CdtEntry);
+			colTablePtr = (byte *) (anim_head + 1) + anim_head->noAnimFrames * sizeof(CdtEntry);
 			break;
 		}
 	}
@@ -359,7 +359,7 @@
 	spriteInfo.type = spriteType;
 	spriteInfo.blend = anim_head->blend;
 	// points to just after frame header, ie. start of sprite data
-	spriteInfo.data = (uint8 *) (frame_head + 1);
+	spriteInfo.data = (byte *) (frame_head + 1);
 	spriteInfo.colourTable	= colTablePtr;
 
 	// check for largest layer for debug info
@@ -434,10 +434,10 @@
 	//         1 pointer to graphic structure
 	//         2 pointer to mega structure
 
-	ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->intToPtr(params[1]);
+	ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->decodePtr(params[1]);
 	assert(ob_graph->anim_resource);
 
-	uint8 *file = _resman->openResource(ob_graph->anim_resource);
+	byte *file = _resman->openResource(ob_graph->anim_resource);
 
 	AnimHeader *anim_head = fetchAnimHeader(file);
 	CdtEntry *cdt_entry = fetchCdtEntry(file, ob_graph->anim_pc);
@@ -469,7 +469,7 @@
 	int scale = 0;
 
 	if (cdt_entry->frameType & FRAME_OFFSET) {
-		ObjectMega *ob_mega = (ObjectMega *) _memory->intToPtr(params[2]);
+		ObjectMega *ob_mega = (ObjectMega *) _memory->decodePtr(params[2]);
 
 		// calc scale at which to print the sprite, based on feet
 		// y-coord & scaling constants (NB. 'scale' is actually
@@ -508,7 +508,7 @@
 
 	if (params[0]) {
 		// passed a mouse structure, so add to the _mouseList
-		ObjectMouse *ob_mouse = (ObjectMouse *) _memory->intToPtr(params[0]);
+		ObjectMouse *ob_mouse = (ObjectMouse *) _memory->decodePtr(params[0]);
 
 		if (ob_mouse->pointer) {
 			assert(_curMouse < TOTAL_mouse_list);
@@ -557,7 +557,7 @@
 }
 
 int32 Sword2Engine::registerFrame(int32 *params) {
-	ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->intToPtr(params[1]);
+	ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->decodePtr(params[1]);
 
 	// check low word for sprite type
 	switch (ob_graph->type & 0x0000ffff) {
@@ -605,18 +605,18 @@
 	return IR_CONT;
 }
 
-void Sword2Engine::startNewPalette(void) {
-	// start layer palette fading up
-
-	uint8 *screenFile;
+/**
+ * Start layer palette fading up
+ */
 
+void Sword2Engine::startNewPalette(void) {
 	// if the screen is still fading down then wait for black - could
 	// happen when everythings cached into a large memory model
 	_graphics->waitForFade();
 
-	screenFile = _resman->openResource(_thisScreen.background_layer_id);
+	byte *screenFile = _resman->openResource(_thisScreen.background_layer_id);
 
-	_graphics->updatePaletteMatchTable((uint8 *) fetchPaletteMatchTable(screenFile));
+	_graphics->updatePaletteMatchTable((byte *) fetchPaletteMatchTable(screenFile));
 	_graphics->setPalette(0, 256, fetchPalette(screenFile), RDPAL_FADE);
 
 	// indicating that it's a screen palette
@@ -632,7 +632,7 @@
 
 	// params:	0 pointer to mega structure
 
-	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[0]);
+	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[0]);
 
 	_vm->_thisScreen.player_feet_x = ob_mega->feet_x;
 	_vm->_thisScreen.player_feet_y = ob_mega->feet_y;
@@ -715,7 +715,7 @@
 	// If non-zero, set palette to this separate palette file. Otherwise,
 	// set palette to current screen palette.
 
-	uint8 *file;
+	byte *file;
 
 	if (palRes) {
 		file = _resman->openResource(palRes);

Index: console.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/console.cpp,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- console.cpp	29 Mar 2004 06:37:46 -0000	1.42
+++ console.cpp	23 Apr 2004 07:01:36 -0000	1.43
@@ -172,7 +172,7 @@
 }
 
 bool Debugger::Cmd_Mem(int argc, const char **argv) {
-	_vm->_memory->displayMemory();
+	_vm->_memory->memDisplay();
 	return true;
 }
 

Index: console.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/console.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- console.h	14 Apr 2004 07:12:10 -0000	1.19
+++ console.h	23 Apr 2004 07:01:37 -0000	1.20
@@ -44,7 +44,7 @@
 
 	int32 _showVar[MAX_SHOWVARS];
 
-	uint8 _debugTextBlocks[MAX_DEBUG_TEXTS];
+	byte _debugTextBlocks[MAX_DEBUG_TEXTS];
 
 	void clearDebugTextBlocks(void);
 	void makeDebugTextBlock(char *text, int16 x, int16 y);

Index: controls.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/controls.cpp,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -d -r1.66 -r1.67
--- controls.cpp	17 Mar 2004 09:03:14 -0000	1.66
+++ controls.cpp	23 Apr 2004 07:01:37 -0000	1.67
@@ -78,7 +78,7 @@
 	SpriteInfo *_sprites;
 
 	struct WidgetSurface {
-		uint8 *_surface;
+		byte *_surface;
 		bool _original;
 	};
  
@@ -129,7 +129,7 @@
 	Gui *_gui;
 	
 	struct Glyph {
-		uint8 *_data;
+		byte *_data;
 		int _width;
 		int _height;
 	};
@@ -148,21 +148,21 @@
 	FontRendererGui(Gui *gui, int fontId);
 	~FontRendererGui();
 
-	void fetchText(uint32 textId, uint8 *buf);
+	void fetchText(uint32 textId, byte *buf);
 
-	int getCharWidth(uint8 c);
-	int getCharHeight(uint8 c);
+	int getCharWidth(byte c);
+	int getCharHeight(byte c);
 
-	int getTextWidth(uint8 *text);
+	int getTextWidth(byte *text);
 	int getTextWidth(uint32 textId);
 
-	void drawText(uint8 *text, int x, int y, int alignment = kAlignLeft);
+	void drawText(byte *text, int x, int y, int alignment = kAlignLeft);
 	void drawText(uint32 textId, int x, int y, int alignment = kAlignLeft);
 };
 
 FontRendererGui::FontRendererGui(Gui *gui, int fontId)
 	: _gui(gui), _fontId(fontId) {
-	uint8 *font = _gui->_vm->_resman->openResource(fontId);
+	byte *font = _gui->_vm->_resman->openResource(fontId);
 	FrameHeader *head;
 	SpriteInfo sprite;
 
@@ -170,7 +170,7 @@
 
 	for (int i = 0; i < SIZE_OF_CHAR_SET; i++) {
 		head = (FrameHeader *) _gui->_vm->fetchFrameHeader(font, i);
-		sprite.data = (uint8 *) (head + 1);
+		sprite.data = (byte *) (head + 1);
 		sprite.w = head->width;
 		sprite.h = head->height;
 		_gui->_vm->_graphics->createSurface(&sprite, &_glyph[i]._data);
@@ -186,8 +186,8 @@
 		_gui->_vm->_graphics->deleteSurface(_glyph[i]._data);
 }
 
-void FontRendererGui::fetchText(uint32 textId, uint8 *buf) {
-	uint8 *data = _gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff);
+void FontRendererGui::fetchText(uint32 textId, byte *buf) {
+	byte *data = _gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff);
 	int i;
 
 	for (i = 0; data[i + 2]; i++) {
@@ -199,19 +199,19 @@
 	_gui->_vm->_resman->closeResource(textId / SIZE);
 }
 
-int FontRendererGui::getCharWidth(uint8 c) {
+int FontRendererGui::getCharWidth(byte c) {
 	if (c < 32)
 		return 0;
 	return _glyph[c - 32]._width;
 }
 
-int FontRendererGui::getCharHeight(uint8 c) {
+int FontRendererGui::getCharHeight(byte c) {
 	if (c < 32)
 		return 0;
 	return _glyph[c - 32]._height;
 }
 
-int FontRendererGui::getTextWidth(uint8 *text) {
+int FontRendererGui::getTextWidth(byte *text) {
 	int textWidth = 0;
 
 	for (int i = 0; text[i]; i++)
@@ -221,13 +221,13 @@
 }
 
 int FontRendererGui::getTextWidth(uint32 textId) {
-	uint8 text[MAX_STRING_LEN];
+	byte text[MAX_STRING_LEN];
 
 	fetchText(textId, text);
 	return getTextWidth(text);
 }
 
-void FontRendererGui::drawText(uint8 *text, int x, int y, int alignment) {
+void FontRendererGui::drawText(byte *text, int x, int y, int alignment) {
 	SpriteInfo sprite;
 	int i;
 
@@ -260,7 +260,7 @@
 }
 
 void FontRendererGui::drawText(uint32 textId, int x, int y, int alignment) {
-	uint8 text[MAX_STRING_LEN];
+	byte text[MAX_STRING_LEN];
 
 	fetchText(textId, text);
 	drawText(text, x, y, alignment);
@@ -431,7 +431,7 @@
 }
 
 void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc) {
-	uint8 *file, *colTablePtr = NULL;
+	byte *file, *colTablePtr = NULL;
 	AnimHeader *anim_head;
 	FrameHeader *frame_head;
 	CdtEntry *cdt_entry;
@@ -463,7 +463,7 @@
 		spriteType |= RDSPR_RLE256;
 		// Points to just after last cdt_entry, i.e. start of colour
 		// table
-		colTablePtr = (uint8 *) (anim_head + 1) +
+		colTablePtr = (byte *) (anim_head + 1) +
 			anim_head->noAnimFrames * sizeof(CdtEntry);
 		break;
 	}
@@ -477,7 +477,7 @@
 	_sprites[state].blend = anim_head->blend;
 
 	// Points to just after frame header, ie. start of sprite data
-	_sprites[state].data = (uint8 *) (frame_head + 1);
+	_sprites[state].data = (byte *) (frame_head + 1);
 
 	_parent->_gui->_vm->_graphics->createSurface(&_sprites[state], &_surfaces[state]._surface);
 	_surfaces[state]._original = true;
@@ -1044,7 +1044,7 @@
 private:
 	int _mode;
 	FontRendererGui *_fr;
-	uint8 _text[SAVE_DESCRIPTION_LEN];
+	byte _text[SAVE_DESCRIPTION_LEN];
 	bool _clickable;
 	bool _editable;
 
@@ -1071,7 +1071,7 @@
 		return _editable;
 	}
 
-	void setText(FontRendererGui *fr, int slot, uint8 *text) {
+	void setText(FontRendererGui *fr, int slot, byte *text) {
 		_fr = fr;
 		if (text)
 			sprintf((char *) _text, "%d.  %s", slot, text);
@@ -1079,7 +1079,7 @@
 			sprintf((char *) _text, "%d.  ", slot);
 	}
 
-	uint8 *getText() {
+	byte *getText() {
 		return &_text[0];
 	}
 
@@ -1147,7 +1147,7 @@
 class SaveLoadDialog : public Dialog {
 private:
 	int _mode, _selectedSlot;
-	uint8 _editBuffer[SAVE_DESCRIPTION_LEN];
+	byte _editBuffer[SAVE_DESCRIPTION_LEN];
 	int _editPos, _firstPos;
 	int _cursorTick;
 
@@ -1162,7 +1162,7 @@
 	Button *_okButton;
 	Button *_cancelButton;
 
-	void saveLoadError(uint8 *text);
+	void saveLoadError(byte *text);
 
 public:
 	SaveLoadDialog(Gui *gui, int mode)
@@ -1232,7 +1232,7 @@
 		for (int i = 0; i < 8; i++) {
 			Slot *slot = _slotButton[(_gui->_baseSlot + i) % 8];
 			FontRendererGui *fr;
-			uint8 description[SAVE_DESCRIPTION_LEN];
+			byte description[SAVE_DESCRIPTION_LEN];
 
 			slot->setY(72 + i * 36);
 
@@ -1295,7 +1295,7 @@
 		} else {
 			Slot *slot = (Slot *) widget;
 			int textWidth;
-			uint8 tmp;
+			byte tmp;
 			int i;
 			int j;
 
@@ -1417,7 +1417,7 @@
 
 			_editBuffer[_editPos] = 0;
 
-			uint32 rv = _gui->_vm->saveGame(_selectedSlot, (uint8 *) &_editBuffer[_firstPos]);
+			uint32 rv = _gui->_vm->saveGame(_selectedSlot, (byte *) &_editBuffer[_firstPos]);
 
 			if (rv != SR_OK) {
 				uint32 textId;
@@ -1474,9 +1474,9 @@
 	}
 };
 
-void SaveLoadDialog::saveLoadError(uint8* text) {
+void SaveLoadDialog::saveLoadError(byte* text) {
 	// Print a message on screen. Second parameter is duration.
-	_gui->_vm->displayMsg((uint8 *) text, 0);
+	_gui->_vm->displayMsg((byte *) text, 0);
 
 	// Wait for ESC or mouse click
 	while (1) {

Index: debug.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/debug.cpp,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- debug.cpp	14 Apr 2004 07:12:10 -0000	1.37
+++ debug.cpp	23 Apr 2004 07:01:37 -0000	1.38
@@ -50,7 +50,7 @@
 
 	assert(blockNo < MAX_DEBUG_TEXTS);
 
-	_debugTextBlocks[blockNo] = _vm->_fontRenderer->buildNewBloc((uint8 *) text, x, y, 640 - x, 0, RDSPR_DISPLAYALIGN, CONSOLE_FONT_ID, NO_JUSTIFICATION);
+	_debugTextBlocks[blockNo] = _vm->_fontRenderer->buildNewBloc((byte *) text, x, y, 640 - x, 0, RDSPR_DISPLAYALIGN, CONSOLE_FONT_ID, NO_JUSTIFICATION);
 }
 
 void Debugger::buildDebugText(void) {
@@ -290,7 +290,7 @@
 		// memory indicator - this should come last, to show all the
 		// sprite blocks above!
 
-		_vm->_memory->memoryString(buf);
+		_vm->_memory->memStatusStr(buf);
 		makeDebugTextBlock(buf, 0, 0);
 	}
 }

Index: events.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/events.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- events.cpp	30 Mar 2004 06:54:27 -0000	1.29
+++ events.cpp	23 Apr 2004 07:01:37 -0000	1.30
@@ -151,7 +151,7 @@
 	// params:	0 pointer to object's logic structure
 	//		1 number of game-cycles to pause
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	if (checkEventWaiting()) {
 		ob_logic->looping = 0;

Index: function.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/function.cpp,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- function.cpp	16 Apr 2004 06:46:03 -0000	1.60
+++ function.cpp	23 Apr 2004 07:01:38 -0000	1.61
@@ -131,7 +131,7 @@
 	// NB. Pause-value of 0 causes script to continue, 1 causes a 1-cycle
 	// quit, 2 gives 2 cycles, etc.
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	if (ob_logic->looping == 0) {
 		ob_logic->looping = 1;
@@ -152,7 +152,7 @@
 	//		1 minimum number of game-cycles to pause
 	//		2 maximum number of game-cycles to pause
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 	int32 pars[2];
 
 	if (ob_logic->looping == 0) {
@@ -189,7 +189,7 @@
 
 	// params: 	0 pointer to a mega structure
 
-	memcpy(&_engineMega, _vm->_memory->intToPtr(params[0]), sizeof(ObjectMega));
+	memcpy(&_engineMega, _vm->_memory->decodePtr(params[0]), sizeof(ObjectMega));
 	return IR_CONT;
 }
 
@@ -202,7 +202,7 @@
 	// params:	0 pointer to object's mega structure
 	//		1 value to set it to
 
-	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[0]);
+	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[0]);
 
 	ob_mega->megaset_res = params[1];
 	return IR_CONT;
@@ -323,7 +323,7 @@
 
 	debug(5, "globals size: %d", size);
 
-	globals = (uint32 *) ((uint8 *) _vm->_resman->openResource(1) + sizeof(StandardHeader));
+	globals = (uint32 *) ((byte *) _vm->_resman->openResource(1) + sizeof(StandardHeader));
 
 	// blank each global variable
 	memset(globals, 0, size);
@@ -363,7 +363,7 @@
 	byte type;
 	int top;
 	int height;
-	Memory *sprite;
+	byte *sprite;
 };
 
 #define CREDITS_FONT_HEIGHT 25
@@ -432,8 +432,8 @@
 
 	uint16 logoWidth = 0;
 	uint16 logoHeight = 0;
-	uint8 *logoData = NULL;
-	uint8 palette[1024];
+	byte *logoData = NULL;
+	byte palette[1024];
 
 	if (f.open("credits.bmp")) {
 		logoWidth = f.readUint16LE();
@@ -446,7 +446,7 @@
 			palette[i * 4 + 3] = 0;
 		}
 
-		logoData = (uint8 *) malloc(logoWidth * logoHeight);
+		logoData = (byte *) malloc(logoWidth * logoHeight);
 
 		f.read(logoData, logoWidth * logoHeight);
 		f.close();
@@ -610,7 +610,7 @@
 
 			if (creditsLines[i].top + creditsLines[i].height < scrollPos) {
 				if (creditsLines[i].sprite) {
-					_vm->_memory->freeMemory(creditsLines[i].sprite);
+					free(creditsLines[i].sprite);
 					creditsLines[i].sprite = NULL;
 					debug(2, "Freeing sprite '%s'", creditsLines[i].str);
 				}
@@ -626,15 +626,15 @@
 
 				if (!creditsLines[i].sprite) {
 					debug(2, "Creating sprite '%s'", creditsLines[i].str);
-					creditsLines[i].sprite = _vm->_fontRenderer->makeTextSprite((uint8 *) creditsLines[i].str, 600, 14, _vm->_speechFontId, 0);
+					creditsLines[i].sprite = _vm->_fontRenderer->makeTextSprite((byte *) creditsLines[i].str, 600, 14, _vm->_speechFontId, 0);
 				}
 
-				FrameHeader *frame = (FrameHeader *) creditsLines[i].sprite->ad;
+				FrameHeader *frame = (FrameHeader *) creditsLines[i].sprite;
 
 				spriteInfo.y = creditsLines[i].top - scrollPos;
 				spriteInfo.w = frame->width;
 				spriteInfo.h = frame->height;
-				spriteInfo.data = creditsLines[i].sprite->ad + sizeof(FrameHeader);
+				spriteInfo.data = creditsLines[i].sprite + sizeof(FrameHeader);
 
 				switch (creditsLines[i].type) {
 				case LINE_LEFT:
@@ -685,7 +685,7 @@
 		if (creditsLines[i].str)
 			free(creditsLines[i].str);
 		if (creditsLines[i].sprite)
-			_vm->_memory->freeMemory(creditsLines[i].sprite);
+			free(creditsLines[i].sprite);
 	}
 
 	if (logoData)

Index: header.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/header.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- header.h	6 Jan 2004 13:44:17 -0000	1.9
+++ header.h	23 Apr 2004 07:01:38 -0000	1.10
@@ -47,7 +47,7 @@
 	uint32 decompSize;		// Length of decompressed file held in
 					// memory (NB. frames still held
 					// compressed)
-	uint8 name[NAME_LEN];		// Name of object
+	byte name[NAME_LEN];		// Name of object
 } GCC_PACK;
 
 // fileType

Index: icons.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/icons.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- icons.cpp	4 Apr 2004 15:16:05 -0000	1.35
+++ icons.cpp	23 Apr 2004 07:01:38 -0000	1.36
@@ -30,7 +30,7 @@
 int32 Logic::fnAddMenuObject(int32 *params) {
 	// params:	0 pointer to a MenuObject structure to copy down
 
-	_vm->addMenuObject((MenuObject *) _vm->_memory->intToPtr(params[0]));
+	_vm->addMenuObject((MenuObject *) _vm->_memory->decodePtr(params[0]));
 	return IR_CONT;
 }
 
@@ -140,7 +140,7 @@
 
 	for (i = 0; i < 15; i++) {
 		uint32 res = _masterMenuList[i].icon_resource;
-		uint8 *icon = NULL;
+		byte *icon = NULL;
 
 		if (res) {
 			bool icon_coloured;
@@ -196,7 +196,7 @@
 	// rest will grey out.
 
 	for (int i = 0; i < ARRAYSIZE(icon_list); i++) {
-		uint8 *icon = _resman->openResource(icon_list[i]) + sizeof(StandardHeader);
+		byte *icon = _resman->openResource(icon_list[i]) + sizeof(StandardHeader);
 		
 		// The only case when an icon is grayed is when the player
 		// is dead. Then SAVE is not available.

Index: interpreter.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/interpreter.cpp,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- interpreter.cpp	7 Apr 2004 08:53:24 -0000	1.45
+++ interpreter.cpp	23 Apr 2004 07:01:38 -0000	1.46
@@ -194,7 +194,7 @@
 	stack[stackPtr++] = (value); \
 } while (false)
 
-#define push_ptr(ptr) push(_vm->_memory->ptrToInt(ptr))
+#define push_ptr(ptr) push(_vm->_memory->encodePtr(ptr))
 
 #define pop() (assert(stackPtr < ARRAYSIZE(stack)), stack[--stackPtr])
 
@@ -301,7 +301,7 @@
 		int retVal;
 		int caseCount;
 		bool foundCase;
-		uint8 *ptr;
+		byte *ptr;
 
 		curCommand = code[ip++];
 
@@ -372,7 +372,7 @@
 
 			Read16ip(parameter);
 			parameter /= 4;
-			ptr = (uint8 *) &localVars[parameter];
+			ptr = (byte *) &localVars[parameter];
 			push_ptr(ptr);
 			debug(9, "CP_PUSH_LOCAL_ADDR: &localVars[%d] => %p", parameter, ptr);
 			break;
@@ -382,7 +382,7 @@
 			Read8ip(parameter);
 
 			// ip now points to the string
-			ptr = (uint8 *) (code + ip);
+			ptr = (byte *) (code + ip);
 			push_ptr(ptr);
 			debug(9, "CP_PUSH_STRING: \"%s\"", ptr);
 			ip += (parameter + 1);
@@ -390,7 +390,7 @@
 		case CP_PUSH_DEREFERENCED_STRUCTURE:
 			// Push the address of a dereferenced structure
 			Read32ip(parameter);
-			ptr = (uint8 *) (objectData + sizeof(int32) + sizeof(StandardHeader) + sizeof(ObjectHub) + parameter);
+			ptr = (byte *) (objectData + sizeof(int32) + sizeof(StandardHeader) + sizeof(ObjectHub) + parameter);
 			push_ptr(ptr);
 			debug(9, "CP_PUSH_DEREFERENCED_STRUCTURE: %d => %p", parameter, ptr);
 			break;

Index: layers.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/layers.cpp,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- layers.cpp	7 Apr 2004 12:31:31 -0000	1.27
+++ layers.cpp	23 Apr 2004 07:01:38 -0000	1.28
@@ -55,6 +55,10 @@
 	assert(res);
 	debug(1, "CHANGED TO LOCATION \"%s\"", fetchObjectName(res));
 
+	// The resources age every time a new room is entered.
+	_resman->passTime();
+	_resman->expelOldResources();
+
 	clearFxQueue();
 	_graphics->waitForFade();
 
@@ -75,7 +79,7 @@
 	// info/and set them up at the beginning of the sort list - why do it
 	// each cycle
 
-	uint8 *file = _resman->openResource(_thisScreen.background_layer_id);
+	byte *file = _resman->openResource(_thisScreen.background_layer_id);
 	ScreenHeader *screen_head = fetchScreenHeader(file);
 
 	// set number of special sort layers

Index: logic.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/logic.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- logic.h	16 Apr 2004 06:46:03 -0000	1.32
+++ logic.h	23 Apr 2004 07:01:38 -0000	1.33
@@ -87,7 +87,7 @@
 		uint32 textNumber;
 		uint16 startFrame;
 		uint16 endFrame;
-		Memory *text_mem;
+		byte *text_mem;
 		uint32 speechBufferSize;
 		uint16 *speech_mem;
 	};

Index: maketext.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/maketext.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- maketext.cpp	14 Apr 2004 07:12:10 -0000	1.40
+++ maketext.cpp	23 Apr 2004 07:01:38 -0000	1.41
@@ -57,9 +57,8 @@
 				// our character set is in the '@' position
 
 /**
- * This function creates a new text sprite in a movable memory block. It must
- * be locked before use, i.e. lock, draw sprite, unlock/free. The sprite data
- * contains a FrameHeader, but not a standard file header.
+ * This function creates a new text sprite. The sprite data contains a
+ * FrameHeader, but not a standard file header.
  *
  * @param  sentence  pointer to a null-terminated string
  * @param  maxWidth  the maximum allowed text sprite width in pixels
@@ -72,7 +71,7 @@
  *         error-signal character (chequered flag)
  */
 
-Memory *FontRenderer::makeTextSprite(uint8 *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border) {
+byte *FontRenderer::makeTextSprite(byte *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border) {
 	debug(3, "makeTextSprite(\"%s\", maxWidth=%u)", sentence, maxWidth);
 
 	_borderPen = border;
@@ -93,23 +92,23 @@
 
 	// Allocate memory for array of lineInfo structures
 
-	Memory *line = _vm->_memory->allocMemory(MAX_LINES * sizeof(LineInfo), MEM_locked, UID_temp);
+	byte *line = (byte *) malloc(MAX_LINES * sizeof(LineInfo));
 
 	// Get details of sentence breakdown into array of LineInfo structures
 	// and get the number of lines involved
 
-	uint16 noOfLines = analyseSentence(sentence, maxWidth, fontRes, (LineInfo *) line->ad);
+	uint16 noOfLines = analyseSentence(sentence, maxWidth, fontRes, (LineInfo *) line);
 
 	// Construct the sprite based on the info gathered - returns floating
 	// mem block
 
-	Memory *textSprite = buildTextSprite(sentence, fontRes, pen, (LineInfo *) line->ad, noOfLines);
+	byte *textSprite = buildTextSprite(sentence, fontRes, pen, (LineInfo *) line, noOfLines);
 
-	_vm->_memory->freeMemory(line);
+	free(line);
 	return textSprite;
 }
 
-uint16 FontRenderer::analyseSentence(uint8 *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line) {
+uint16 FontRenderer::analyseSentence(byte *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line) {
 	// joinWidth = how much extra space is needed to append a word to a
 	// line. NB. SPACE requires TWICE the '_charSpacing' to join a word
 	// to line
@@ -120,7 +119,7 @@
 	uint16 pos = 0;
 	bool firstWord = true;
 
-	uint8 ch;
+	byte ch;
 
 	do {
 		uint16 wordWidth = 0;
@@ -193,7 +192,7 @@
  *         error-signal character (chequered flag)
  */
 
-Memory *FontRenderer::buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines) {
+byte *FontRenderer::buildTextSprite(byte *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines) {
 	uint16 i;
 
 	// Find the width of the widest line in the output text
@@ -213,12 +212,12 @@
 	// Allocate memory for the text sprite
 
 	uint32 sizeOfSprite = spriteWidth * spriteHeight;
-	Memory *textSprite = _vm->_memory->allocMemory(sizeof(FrameHeader) + sizeOfSprite, MEM_locked, UID_text_sprite);
+	byte *textSprite = (byte *) malloc(sizeof(FrameHeader) + sizeOfSprite);
 
 	// At this stage, textSprite points to an unmovable memory block. Set
 	// up the frame header.
 
-	FrameHeader *frameHeadPtr = (FrameHeader *) textSprite->ad;
+	FrameHeader *frameHeadPtr = (FrameHeader *) textSprite;
 
 	frameHeadPtr->compSize = 0;
 	frameHeadPtr->width = spriteWidth;
@@ -228,10 +227,10 @@
 
 	// Clear the entire sprite to make it transparent.
 
-	uint8 *linePtr = textSprite->ad + sizeof(FrameHeader);
+	byte *linePtr = textSprite + sizeof(FrameHeader);
 	memset(linePtr, 0, sizeOfSprite);
 
-	uint8 *charSet = _vm->_resman->openResource(fontRes);
+	byte *charSet = _vm->_resman->openResource(fontRes);
 
 	// Build the sprite, one line at a time
 
@@ -239,7 +238,7 @@
 
 	for (i = 0; i < noOfLines; i++) {
 		// Center each line
-		uint8 *spritePtr = linePtr + (spriteWidth - line[i].width) / 2;
+		byte *spritePtr = linePtr + (spriteWidth - line[i].width) / 2;
 
 		// copy the sprite for each character in this line to the
 		// text sprite and inc the sprite ptr by the character's
@@ -261,8 +260,6 @@
 
 	_vm->_resman->closeResource(fontRes);
 
-	// Unlock the sprite memory block, so it's movable
-	_vm->_memory->floatMemory(textSprite);
 	return textSprite;
 }
 
@@ -272,8 +269,8 @@
  * @return the width of the character
  */
 
-uint16 FontRenderer::charWidth(uint8 ch, uint32 fontRes) {
-	uint8 *charSet = _vm->_resman->openResource(fontRes);
+uint16 FontRenderer::charWidth(byte ch, uint32 fontRes) {
+	byte *charSet = _vm->_resman->openResource(fontRes);
 
 	FrameHeader *charFrame = findChar(ch, charSet);
 	uint16 width = charFrame->width;
@@ -293,7 +290,7 @@
 // and a pointer to the start of the character set.
 
 uint16 FontRenderer::charHeight(uint32 fontRes) {
-	uint8 *charSet = _vm->_resman->openResource(fontRes);
+	byte *charSet = _vm->_resman->openResource(fontRes);
 
 	FrameHeader *charFrame = findChar(FIRST_CHAR, charSet);
 	uint16 height = charFrame->height;
@@ -309,7 +306,7 @@
  *         'dud' character (chequered flag)
  */
 
-FrameHeader* FontRenderer::findChar(uint8 ch, uint8 *charSet) {
+FrameHeader* FontRenderer::findChar(byte ch, byte *charSet) {
 	if (ch < FIRST_CHAR)
 		ch = DUD;
 	return _vm->fetchFrameHeader(charSet, ch - FIRST_CHAR);
@@ -325,12 +322,12 @@
  *                    LETTER_COL to pen.
  */
 
-void FontRenderer::copyChar(FrameHeader *charPtr, uint8 *spritePtr, uint16 spriteWidth, uint8 pen) {
-	uint8 *source = (uint8 *) charPtr + sizeof(FrameHeader);
-	uint8 *rowPtr = spritePtr;
+void FontRenderer::copyChar(FrameHeader *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen) {
+	byte *source = (byte *) charPtr + sizeof(FrameHeader);
+	byte *rowPtr = spritePtr;
 
 	for (uint i = 0; i < charPtr->height; i++) {
-		uint8 *dest = rowPtr;
+		byte *dest = rowPtr;
 
 		if (pen) {
 			// Use the specified colours
@@ -373,7 +370,7 @@
  * RDSPR_DISPLAYALIGN or 0
  */
 
-uint32 FontRenderer::buildNewBloc(uint8 *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification) {
+uint32 FontRenderer::buildNewBloc(byte *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification) {
 	uint32 i = 0;
 
 	while (i < MAX_text_blocs && _blocList[i].text_mem)
@@ -389,7 +386,7 @@
 	// without margin checking - used for debug text
 
 	if (justification != NO_JUSTIFICATION) {
-		FrameHeader *frame_head = (FrameHeader *) _blocList[i].text_mem->ad;
+		FrameHeader *frame_head = (FrameHeader *) _blocList[i].text_mem;
 
 		switch (justification) {
 		case POSITION_AT_CENTRE_OF_BASE:
@@ -462,7 +459,7 @@
 void FontRenderer::printTextBlocs(void) {
 	for (uint i = 0; i < MAX_text_blocs; i++) {
 		if (_blocList[i].text_mem) {
-			FrameHeader *frame = (FrameHeader *) _blocList[i].text_mem->ad;
+			FrameHeader *frame = (FrameHeader *) _blocList[i].text_mem;
 			SpriteInfo spriteInfo;
 
 			spriteInfo.x = _blocList[i].x;
@@ -474,7 +471,7 @@
 			spriteInfo.scaledHeight = 0;
 			spriteInfo.type = _blocList[i].type;
 			spriteInfo.blend = 0;
-			spriteInfo.data = _blocList[i].text_mem->ad + sizeof(FrameHeader);
+			spriteInfo.data = _blocList[i].text_mem + sizeof(FrameHeader);
 			spriteInfo.colourTable = 0;
 
 			uint32 rv = _vm->_graphics->drawSprite(&spriteInfo);
@@ -486,9 +483,8 @@
 
 void FontRenderer::killTextBloc(uint32 bloc_number) {
 	bloc_number--;
-	assert(_blocList[bloc_number].text_mem);
-	_vm->_memory->freeMemory(_blocList[bloc_number].text_mem);
-	_blocList[bloc_number].text_mem = 0;
+	free(_blocList[bloc_number].text_mem);
+	_blocList[bloc_number].text_mem = NULL;
 }
 
 // Resource 3258 contains text from location script for 152 (install, save &
@@ -501,7 +497,7 @@
 #define SAVE_LINE_NO	1
 
 void Sword2Engine::initialiseFontResourceFlags(void) {
-	uint8 *textFile = _resman->openResource(TEXT_RES);
+	byte *textFile = _resman->openResource(TEXT_RES);
 
 	// If language is Polish or Finnish it requires alternate fonts.
 	// Otherwise, use regular fonts

Index: maketext.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/maketext.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- maketext.h	14 Apr 2004 07:12:10 -0000	1.12
+++ maketext.h	23 Apr 2004 07:01:38 -0000	1.13
@@ -61,7 +61,7 @@
 	int16 x;
 	int16 y;
 	uint16 type;
-	Memory *text_mem;
+	byte *text_mem;
 };
 
 // Info for each line of words in the output text sprite
@@ -86,12 +86,12 @@
 				// each line - negative for overlap
 	uint8 _borderPen;	// output pen colour of character borders
 
-	uint16 analyseSentence(uint8 *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line);
-	Memory *buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines);
-	uint16 charWidth(uint8 ch, uint32 fontRes);
+	uint16 analyseSentence(byte *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line);
+	byte *buildTextSprite(byte *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines);
+	uint16 charWidth(byte ch, uint32 fontRes);
 	uint16 charHeight(uint32 fontRes);
-	FrameHeader* findChar(uint8 ch, uint8 *charSet);
-	void copyChar(FrameHeader *charPtr, uint8 *spritePtr, uint16 spriteWidth, uint8 pen);
+	FrameHeader* findChar(byte ch, byte *charSet);
+	void copyChar(FrameHeader *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen);
 	
 public:
 	FontRenderer(Sword2Engine *vm) : _vm(vm) {
@@ -99,12 +99,12 @@
 			_blocList[i].text_mem = NULL;
 	}
 
-	Memory *makeTextSprite(uint8 *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border = BORDER_PEN);
+	byte *makeTextSprite(byte *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border = BORDER_PEN);
 
 	void killTextBloc(uint32 bloc_number);
 	void printTextBlocs(void);
 
-	uint32 buildNewBloc(uint8 *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification);
+	uint32 buildNewBloc(byte *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification);
 };
 
 } // End of namespace Sword2

Index: memory.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/memory.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- memory.cpp	28 Mar 2004 14:56:02 -0000	1.25
+++ memory.cpp	23 Apr 2004 07:01:38 -0000	1.26
@@ -17,560 +17,211 @@
  * $Header$
  */
 
-// memory manager
-//   - "remember, it's not good to leave memory locked for a moment longer
-//      than necessary" Tony
-//   - "actually, in a sequential system theoretically you never need to lock
-//      any memory!" Chris ;)
+// The new memory manager, now only used by the resource manager. Unlike the
+// original, this one does not allocate a 12 MB memory pool at startup.
 //
-// This is a very simple implementation but I see little advantage to being
-// any cleverer with the coding - i could have put the mem blocks before the
-// defined blocks instead of in an array and then used pointers to
-// child/parent blocks. But why bother? I've Kept it simple. When it needs
-// updating or customising it will be accessable to anyone who looks at it.
+// There is one thing that prevents us from replacing the whole memory manager
+// with the standard memory allocation functions: Broken Sword II absolutely,
+// positively needs to be able to encode pointers as 32-bit integers. The
+// original engine did this simply by casting between pointers and integers,
+// but as far as I know that's not a very portable thing to do.
 //
-// Doesn't have a purgeable/age consituant yet - if anyone wants this then
-// I'll add it in.
-
-// MemMan v1.1
+// For a while I was hopeing that the engine only needed pointers as function
+// parameters, in which case I could have extended the stack to use a struct or
+// a union instead, but no such luck. There is code in walker.cpp that
+// obviously violates that assumption, and there are probably other, more
+// well-hidden places, as well.
+//
+// This attacks the problem from the direction of another limitation in the
+// original memory manager: it could only handle up to 999 blocks of memory.
+// This memory manager has the same limitation, although it's probably way too
+// large now, which means that a pointer can be encoded as 10 bits to store the
+// block id, and another 22 bits to store an index into that block.
 
 #include "common/stdafx.h"
 #include "sword2/sword2.h"
-#include "sword2/resman.h"
+#include "sword2/console.h"
 
 namespace Sword2 {
 
-#define MEMORY_POOL (1024 * 12000)
+#define MAX_BLOCKS 999
 
-// #define MEMDEBUG 1
+#define Debug_Printf _vm->_debugger->DebugPrintf
 
 MemoryManager::MemoryManager(Sword2Engine *vm) : _vm(vm) {
-	uint32 j;
-	uint8 *memory_base;
-
-	_suggestedStart = 0;
-
-	_totalFreeMemory = MEMORY_POOL;
-
-	memory_base = (uint8 *) malloc(_totalFreeMemory);
-
-	if (!memory_base)
-		error("MemoryManager: couldn't malloc %d bytes", _totalFreeMemory);
-
-	// the original malloc address
-	_freeMemman = memory_base;
-
-	// set all but first handle to unused
-	for (j = 1; j < MAX_mem_blocks; j++)
-		_memList[j].state = MEM_null;
+	_memBlocks = (MemBlock *) malloc(MAX_BLOCKS * sizeof(MemBlock));
+	_memBlockIndex = (MemBlock **) malloc(MAX_BLOCKS * sizeof(MemBlock *));
+	_idStack = (int16 *) malloc(MAX_BLOCKS * sizeof(int16));
 
-	// total used (free, locked or floating)
-	_totalBlocks = 1;
+	_totAlloc = 0;
+	_numBlocks = 0;
 
-	_memList[0].ad = memory_base;
-	_memList[0].state = MEM_free;
-	_memList[0].age = 0;
-	_memList[0].size = _totalFreeMemory;
-	_memList[0].parent = -1;		// we are base - for now
-	_memList[0].child = -1;			// we are the end as well
-	_memList[0].uid = (uint32) UID_memman;		// init id
+	for (int i = 0; i < MAX_BLOCKS; i++) {
+		_idStack[i] = MAX_BLOCKS - i - 1;
+		_memBlocks[i].ptr = NULL;
+		_memBlockIndex[i] = NULL;
+	}
 
-	_baseMemBlock = 0;			// for now
+	_idStackPtr = MAX_BLOCKS;
 }
 
-MemoryManager::~MemoryManager(void) {
-	free(_freeMemman);
+MemoryManager::~MemoryManager() {
+	for (int i = 0; i < MAX_BLOCKS; i++)
+		free(_memBlocks[i].ptr);
+	free(_memBlocks);
+	free(_memBlockIndex);
+	free(_idStack);
 }
 
-// I don't know about C++, but here's what "C: A Reference Manual" (Harbison &
-// Steele) has to say:
-//
-// "There is no requirement in C that any of the integral types be large enough
-// to represent a pointer, although C programmers often assume that type long
-// is large enough, which it is on most computers. In C99, header inttypes.h
-// may define integer types intptr_t and uintptr_t, which are guaranteed large
-// enough to hold a pointer as an integer."
-//
-// The script engine frequently needs to pass around pointers to various
-// structures etc. and, and used to do so by casting them to int32 and back
-// again. Since those pointers always point to memory that belongs to the
-// memory manager, we can easily represent them as offsets instead.
+int32 MemoryManager::encodePtr(byte *ptr) {
+	int idx = findPointerInIndex(ptr);
 
-int32 MemoryManager::ptrToInt(const uint8 *p) {
-	debug(9, "ptrToInt: %p -> %d", p, p - _freeMemman);
+	if (idx == -1)
+		error("Encoding non-allocated pointer %p", ptr);
 
-	if (p < _freeMemman || p >= &_freeMemman[MEMORY_POOL])
-		warning("ptrToInt: Converting bad pointer: %p", p);
+	int id = _memBlockIndex[idx]->id;
 
-	return p - _freeMemman;
+	return (id << 22) | (ptr - _memBlocks[id].ptr);
 }
 
-uint8 *MemoryManager::intToPtr(int32 n) {
-	debug(9, "intToPtr: %d -> %p", n, &_freeMemman[n]);
-
-	if (n < 0 || n >= MEMORY_POOL)
-		warning("intToPtr: Converting bad integer: %d", n);
+byte *MemoryManager::decodePtr(int32 n) {
+	int16 id = (n >> 22) & 0x03ff;
+	int32 offset = n & 0x003fffff;
 
-	return &_freeMemman[n];
+	return _memBlocks[id].ptr + offset;
 }
 
-Memory *MemoryManager::lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id) {
-	// allocate a block of memory - locked or float
-
-	// returns 0 if fails to allocate the memory
-	// or a pointer to a mem structure
-
-	int32 nu_block;
-	uint32 spawn = 0;
-	uint32 slack;
-
-	// we must first round the size UP to a dword, so subsequent blocks
-	// will start dword alligned
-
-	size += 3;		// move up
-	size &= 0xfffffffc;	// and back down to boundary
-
-	// find a free block large enough
-
-	// the defragger returns when its made a big enough block. This is
-	// a good time to defrag as we're probably not doing anything super
-	// time-critical at the moment
-
-	if ((nu_block = defragMemory(size)) == -1) {
-		// error - couldn't find a big enough space
-		return 0;
-	}
-
-	// an exact fit?
-	if (_memList[nu_block].size == size) {
-		// no new block is required as the fit is perfect
-		_memList[nu_block].state = type;    // locked or float
-		_memList[nu_block].size = size;	    // set to the required size
-		_memList[nu_block].uid = unique_id; // an identifier
-
-#ifdef	MEMDEBUG
-		debugMemory();
-#endif
-
-		return &_memList[nu_block];
-	}
-
-	// nu_block is the free block to split, forming our locked/float block
-	// with a new free block in any remaining space
-
-	// If our child is free then is can expand downwards to eat up our
-	// chopped space this is good because it doesn't create an extra block
-	// so keeping the block count down.
-	//
-	// Why? Imagine you Talloc 1000k, then free it. Now keep allocating 10
-	// bytes less and freeing again you end up with thousands of new free
-	// mini blocks. This way avoids that as the free child keeps growing
-	// downwards.
-
-	if (_memList[nu_block].child != -1 && _memList[_memList[nu_block].child].state == MEM_free) {
-		// our child is free
-		// the spare memory is the blocks current size minus the
-		// amount we're taking
-
-		slack = _memList[nu_block].size - size;
-
-		_memList[nu_block].state = type;    // locked or float
-		_memList[nu_block].size = size;	    // set to the required size
-		_memList[nu_block].uid = unique_id; // an identifier
-
-		// child starts after us
-		_memList[_memList[nu_block].child].ad = _memList[nu_block].ad + size;
-		// child's size increases
-		_memList[_memList[nu_block].child].size += slack;
-
-		return &_memList[nu_block];
-	}
-
-	// otherwise we spawn a new block after us and before our child - our
-	// child being a proper block that we cannot change
-
-	// we remain a child of our parent
-	// we spawn a new child and it inherits our current child
-
-	// find a NULL slot for a new block
-
-	while (_memList[spawn].state != MEM_null && spawn!=MAX_mem_blocks)
-		spawn++;
-
-	if (spawn == MAX_mem_blocks) {
-		// run out of blocks - stop the program. this is a major blow
-		// up and we need to alert the developer
-		// Lets get a printout of this
-		debugMemory();
-		error("Out of mem blocks in Talloc()");
-	}
-
-	_memList[spawn].state = MEM_free;	// new block is free
-	_memList[spawn].uid = (uint32) UID_memman;	// a memman created bloc
-
-	// size of the existing parent free block minus the size of the new
-	// space Talloc'ed.
-
-	_memList[spawn].size = _memList[nu_block].size - size;
-
-	// IOW the remaining memory is given to the new free block
-
-	// we start 1 byte after the newly allocated block
-	_memList[spawn].ad = _memList[nu_block].ad + size;
+int16 MemoryManager::findExactPointerInIndex(byte *ptr) {
+	int left = 0;
+	int right = _numBlocks - 1;
 
-	// the spawned child gets it parent - the newly allocated block
-	_memList[spawn].parent = nu_block;
+	while (right >= left) {
+		int n = (left + right) / 2;
 
-	// the new child inherits the parents old child (we are its new
-	// child "Waaaa")
-	_memList[spawn].child = _memList[nu_block].child;
+		if (_memBlockIndex[n]->ptr == ptr)
+			return n;
 
-	// is the spawn the end block?
-	if (_memList[spawn].child != -1) {
-		// the child of the new free-spawn needs to know its new parent
-		_memList[_memList[spawn].child].parent = spawn;
+		if (_memBlockIndex[n]->ptr > ptr)
+			right = n - 1;
+		else
+			left = n + 1;
 	}
 
-	_memList[nu_block].state = type;	// locked or float
-	_memList[nu_block].size = size;		// set to the required size
-	_memList[nu_block].uid = unique_id;	// an identifier
-
-	// the new blocks new child is the newly formed free block
-	_memList[nu_block].child = spawn;
-
-	//we've brought a new block into the world. Ahhh!
-	_totalBlocks++;
-
-#ifdef	MEMDEBUG
-	debugMemory();
-#endif
-
-	return &_memList[nu_block];
-}
-
-void MemoryManager::freeMemory(Memory *block) {
-	// kill a block of memory - which was presumably floating or locked
-	// once you've done this the memory may be recycled
-
-	block->state = MEM_free;
-	block->uid = (uint32) UID_memman;	// belongs to the memory manager again
-
-#ifdef	MEMDEBUG
-	debugMemory();
-#endif
+	return -1;
 }
 
-void MemoryManager::floatMemory(Memory *block) {
-	// set a block to float
-	// wont be trashed but will move around in memory
-
-	block->state = MEM_float;
-
-#ifdef	MEMDEBUG
-	debugMemory();
-#endif
-}
+int16 MemoryManager::findPointerInIndex(byte *ptr) {
+	int left = 0;
+	int right = _numBlocks - 1;
 
-void MemoryManager::lockMemory(Memory *block) {
-	// set a block to lock
-	// wont be moved - don't lock memory for any longer than necessary
-	// unless you know the locked memory is at the bottom of the heap
+	while (right >= left) {
+		int n = (left + right) / 2;
 
-	// can't move now - this block is now crying out to be floated or
-	// free'd again
+		if (_memBlockIndex[n]->ptr <= ptr && _memBlockIndex[n]->ptr + _memBlockIndex[n]->size > ptr)
+			return n;
 
-	block->state = MEM_locked;
+		if (_memBlockIndex[n]->ptr > ptr)
+			right = n - 1;
+		else
+			left = n + 1;
+	}
 
-#ifdef	MEMDEBUG
-	debugMemory();
-#endif
+	return -1;
 }
 
-int32 MemoryManager::defragMemory(uint32 req_size) {
-	// moves floating blocks down and/or merges free blocks until a large
-	// enough space is found or there is nothing left to do and a big
-	// enough block cannot be found we stop when we find/create a large
-	// enough block - this is enough defragging.
-
-	int32 cur_block;	// block 0 remains the parent block
-	int32 original_parent,child, end_child;
-	uint32 j;
-	uint32 *a;
-	uint32 *b;
-
-	// cur_block = _baseMemBlock;	//the mother of all parents
-	cur_block = _suggestedStart;
-
-	do {
-		// is current block a free block?
-		if (_memList[cur_block].state == MEM_free) {
-			if (_memList[cur_block].size >= req_size) {
-				// this block is big enough - return its id
-				return cur_block;
-			}
-
-			// the child is the end block - stop if the next block
-			// along is the end block
-			if (_memList[cur_block].child == -1) {
-				// no luck, couldn't find a big enough block
-				return -1;
-			}
-
-			// current free block is too small, but if its child
-			// is *also* free then merge the two together
-
-			if (_memList[_memList[cur_block].child].state == MEM_free) {
-				// ok, we nuke the child and inherit its child
-				child = _memList[cur_block].child;
-
-				// our size grows by the size of our child
-				_memList[cur_block].size += _memList[child].size;
-
-				// our new child is our old childs, child
-				_memList[cur_block].child = _memList[child].child;
-
-				// not if the chld we're nuking is the end
-				// child (it has no child)
-
-				if (_memList[child].child != -1) {
-					// the (nuked) old childs childs
-					// parent is now us
-					_memList[_memList[child].child].parent = cur_block;
-				}
-
-				// clean up the nuked child, so it can be used
-				// again
-				_memList[child].state = MEM_null;
-
-				_totalBlocks--;
-			} else if (_memList[_memList[cur_block].child].state == MEM_float) {
-				// current free block is too small, but if its
-				// child is a float then we move the floating
-				// memory block down and the free up but,
-				// parent/child relationships must be such
-				// that the memory is all continuous between
-				// blocks. ie. a childs memory always begins 1
-				// byte after its parent finishes. However, the
-				// positions in the memory list may become
-				// truly random, but, any particular block of
-				// locked or floating memory must retain its
-				// position within the _memList - the float
-				// stays a float because the handle/pointer
-				// has been passed back
-				//
-				// what this means is that when the physical
-				// memory of the foat moves down (and the free
-				// up) the child becomes the parent and the
-				// parent the child but, remember, the parent
-				// had a parent and the child another child -
-				// these swap over too as the parent/child swap
-				// takes place - phew.
-
-				// our child is currently floating
-				child = _memList[cur_block].child;
-
-				// move the higher float down over the free
-				// block
-				// memcpy(_memList[cur_block].ad, _memList[child].ad, _memList[child].size);
-
-				a = (uint32 *) _memList[cur_block].ad;
-				b = (uint32 *) _memList[child].ad;
-
-				for (j = 0; j < _memList[child].size / 4; j++)
-					*(a++) = *(b++);
-
-				// both *ad's change
-				// the float is now where the free was and the
-				// free goes up by the size of the float
-				// (which has come down)
-
-				_memList[child].ad = _memList[cur_block].ad;
-				_memList[cur_block].ad += _memList[child].size;
-
-				// the status of the _memList blocks must
-				// remain the same, so...
-
-				// our child gets this when we become its
-				// child and it our parent
-				original_parent = _memList[cur_block].parent;
-
-				// the free's child becomes its parent
-				_memList[cur_block].parent = child;
-
-				// the new child inherits its previous childs
-				// child
-				_memList[cur_block].child = _memList[child].child;
-
-				// save this - see next line
-				end_child = _memList[child].child;
-
-				// the floats parent becomes its child
-				_memList[child].child = cur_block;
-				_memList[child].parent = original_parent;
-
-				// if the child had a child
-				if (end_child != -1) {
-					// then its parent is now the new child
-					_memList[end_child].parent = cur_block;
-				}
-
-				// if the base block was the true base parent
-				if (original_parent == -1) {
-					// then the child that has moved down
-					// becomes the base block as it sits
-					// at the lowest possible memory
-					// location
-					_baseMemBlock = child;
-				} else {
-					// otherwise the parent of the current
-					// free block - that is now the child
-					// - gets a new child, that child
-					// being previously the child of the
-					// child of the original parent
-					_memList[original_parent].child = child;
-				}
-			} else { // if (_memList[_memList[cur_block].child].state == MEM_lock)
-				// the child of current is locked - move to it
-				// move to next one along - either locked or
-				// END
-				cur_block=_memList[cur_block].child;
-			}
-		} else {
-			// move to next one along, the current must be
-			// floating, locked, or a NULL slot
-			cur_block = _memList[cur_block].child;
-		}
-	} while (cur_block != -1);	// while the block we've just done is not the final block
-
-	return -1;	//no luck, couldn't find a big enough block
-}
+int16 MemoryManager::findInsertionPointInIndex(byte *ptr) {
+	if (_numBlocks == 0)
+		return 0;
 
-void MemoryManager::debugMemory(void) {
-	// gets called with lowLevelAlloc, Mem_free, Mem_lock & Mem_float if
-	// MEMDEBUG has been #defined otherwise can be called at any time
-	// anywhere else
+	int left = 0;
+	int right = _numBlocks - 1;
+	int n = 0;
 
-	int j;
-	char inf[][20] = {
-		{ "MEM_null" },
-		{ "MEM_free" },
-		{ "MEM_locked" },
-		{ "MEM_float" }
-	};
+	while (right >= left) {
+		n = (left + right) / 2;
 
-	debug(5, "base %d total %d", _baseMemBlock, _totalBlocks);
+		if (_memBlockIndex[n]->ptr == ptr)
+			return -1;
 
-	// first in mem list order
-	for (j = 0; j < MAX_mem_blocks; j++) {
-		if (_memList[j].state == MEM_null)
-			debug(5, "%d- NULL", j);
+		if (_memBlockIndex[n]->ptr > ptr)
+			right = n - 1;
 		else
-			debug(5, "%d- state %s, ad %p, size %d, p %d, c %d, id %d",
-				j, inf[_memList[j].state], _memList[j].ad,
-				_memList[j].size, _memList[j].parent,
-				_memList[j].child, _memList[j].uid);
+			left = n + 1;
 	}
 
-	// now in child/parent order
-	j = _baseMemBlock;
-	do {
-		debug(5, " %d- state %s, ad %p, size %d, p %d, c %d, id %d",
-			j, inf[_memList[j].state], _memList[j].ad,
-			_memList[j].size, _memList[j].parent,
-			_memList[j].child, _memList[j].uid);
+	if (_memBlockIndex[n]->ptr < ptr)
+		n++;
 
-		j = _memList[j].child;
-	} while (j != -1);
+	return n;
 }
 
-Memory *MemoryManager::allocMemory(uint32 size, uint32 type, uint32 unique_id) {
-	// the high level allocator
+byte *MemoryManager::memAlloc(uint32 size, int16 uid) {
+	byte *ptr = (byte *) malloc(size);
 
-	// can ask the resman to remove old resources to make space - will
-	// either do it or halt the system
+	assert(ptr);
+	assert(_idStackPtr > 0);
 
-	Memory *membloc;
-	int j;
-	uint32 free = 0;
+	// Get the new block's id from the stack.
+	int16 id = _idStack[--_idStackPtr];
 
-	while (virtualDefrag(size)) {
-		// trash the oldest closed resource
-		if (!_vm->_resman->helpTheAgedOut()) {
-			error("alloc ran out of memory: size=%d type=%d unique_id=%d", size, type, unique_id);
-		}
-	}
+	_memBlocks[id].id = id;
+	_memBlocks[id].uid = uid;
+	_memBlocks[id].ptr = ptr;
+	_memBlocks[id].size = size;
 
-	membloc = lowLevelAlloc(size, type, unique_id);
+	// The memory index provides a method for figuring out which memory
+	// block an arbitrary pointer points to. A balanced tree might be more
+	// efficient, but such beasts are tricky to implement.
 
-	if (membloc == 0) {
-		error("lowLevelAlloc failed to get memory virtualDefrag said was there");
-	}
+	int16 idx = findInsertionPointInIndex(ptr);
 
-	j = _baseMemBlock;
-	do {
+	assert(idx != -1);
 
-		if (_memList[j].state == MEM_free)
-			free += _memList[j].size;
+	for (int i = _numBlocks; i > idx; i--)
+		_memBlockIndex[i] = _memBlockIndex[i - 1];
 
-		j = _memList[j].child;
-	} while (j != -1);
+	_memBlockIndex[idx] = &_memBlocks[id];
+	_numBlocks++;
+	_totAlloc += size;
 
-	// return the pointer to the memory
-	return membloc;
+	return _memBlocks[id].ptr;
 }
 
-// Maximum allowed wasted memory.
-#define MAX_WASTAGE 51200
-
-int32 MemoryManager::virtualDefrag(uint32 size) {
-	// Virutually defrags memory...
-	//
-	// Used to determine if there is potentially are large enough free
-	// block available is the real defragger was allowed to run.
-	//
-	// The idea being that alloc will call this and help_the_aged_out
-	// until we indicate that it is possible to obtain a large enough
-	// free block. This way the defragger need only run once to yield the
-	// required block size.
-	//
-	// The reason for its current slowness is that the defragger is
-	// potentially called several times, each time shifting upto 20Megs
-	// around, to obtain the required free block.
+void MemoryManager::memFree(byte *ptr) {
+	int16 idx = findExactPointerInIndex(ptr);
 
-	int32 cur_block;	
-	uint32 currentBubbleSize = 0;
+	if (idx == -1) {
+		warning("Freeing non-allocated pointer %p", ptr);
+		return;
+	}
 
-	cur_block = _baseMemBlock;
-	_suggestedStart = _baseMemBlock;
+	// Put back the id on the stack
+	_idStack[_idStackPtr++] = _memBlockIndex[idx]->id;
 
-	do {
-		if (_memList[cur_block].state == MEM_free) {
-			// Add a little intelligence. At the start the oldest
-			// resources are at the bottom of the tube. However
-			// there will be some air at the top. Thus bubbles
-			// will be created at the bottom and float to the
-			// top. If we ignore the top gap then a large enough
-			// bubble will form lower down the tube. Thus less
-			// memory will need to be shifted.
+	free(_memBlockIndex[idx]->ptr);
+	_memBlockIndex[idx]->ptr = NULL;
 
-			if (_memList[cur_block].child != -1)
-				currentBubbleSize += _memList[cur_block].size;
-			else if (_memList[cur_block].size > MAX_WASTAGE)
-				currentBubbleSize += _memList[cur_block].size;
+	_totAlloc -= _memBlockIndex[idx]->size;
+	
+	// Remove the pointer from the index
+	_numBlocks--;
 
-			if (currentBubbleSize >= size)
-				return 0;
-		} else if (_memList[cur_block].state == MEM_locked) {
-			currentBubbleSize = 0;
-			// Any free block of the correct size will be above
-			// this locked block.
-			_suggestedStart = _memList[cur_block].child;
-		}
+	for (int i = idx; i < _numBlocks; i++)
+		_memBlockIndex[i] = _memBlockIndex[i + 1];
+}
 
-		cur_block = _memList[cur_block].child;
-	} while (cur_block != -1);	
+void MemoryManager::memDisplay() {
+	for (int i = 0; i < _numBlocks; i++)
+		Debug_Printf("%d: %ld bytes allocated by resource %d\n", i, _memBlocks[i].size, _memBlocks[i].uid);
+}
 
-	return 1;
+void MemoryManager::memStatusStr(char *buf) {
+	if (_totAlloc < 1024)
+		sprintf(buf, "%u bytes in %d memory blocks", _totAlloc, _numBlocks);
+	else if (_totAlloc < 1048576)
+		sprintf(buf, "%uK in %d memory blocks", _totAlloc / 1024, _numBlocks);
+	else
+		sprintf(buf, "%.02fM in %d memory blocks", _totAlloc / 1048576., _numBlocks);
 }
 
 } // End of namespace Sword2

Index: memory.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/memory.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- memory.h	6 Jan 2004 13:44:17 -0000	1.14
+++ memory.h	23 Apr 2004 07:01:38 -0000	1.15
@@ -22,92 +22,42 @@
 
 namespace Sword2 {
 
-struct Memory {
-	uint32 state;
-	uint32 age;	// *not used*
+struct MemBlock {
+	int16 id;
+	int16 uid;
+	byte *ptr;
 	uint32 size;
-	int32 parent;	// who is before us
-	int32 child;	// who is after us
-	// id of a position in the _resList or some other unique id - for the
-	// visual display only
-	uint32 uid;
-	uint8 *ad;
-};
-
-enum {
-	MEM_null			= 0,	// null
-	MEM_free			= 1,
-	MEM_locked			= 2,
-	MEM_float			= 3
-};
-
-//---------------------------------------
-// MEMORY BLOCKS
-
-#define	MAX_mem_blocks			999
-
-// maintain at a good 50% higher than the
-// highest recorded value from the on-screen info
-//---------------------------------------
-
-enum {
-	UID_memman			= 0xffffffff,
-	UID_NULL			= 0xfffffffe,	// FREE
-	UID_font			= 0xfffffffd,
-	UID_temp			= 0xfffffffc,
-	UID_decompression_buffer	= 0xfffffffb,
-	UID_shrink_buffer		= 0xfffffffa,
-	UID_con_sprite			= 0xfffffff9,
-	UID_text_sprite			= 0xfffffff8,
-	UID_walk_anim			= 0xfffffff7,
-	UID_savegame_buffer		= 0xfffffff6,
-	UID_restoregame_buffer		= 0xfffffff5
 };
 
 class MemoryManager {
 private:
 	Sword2Engine *_vm;
 
-	// Address of init malloc to be freed later
-	uint8 *_freeMemman;
-
-	uint32 _totalFreeMemory;
-	uint32 _totalBlocks;
-
-	// Start position of the defragger as indicated by its sister,
-	// VirtualDefrag.
-	int32 _suggestedStart;
+	MemBlock *_memBlocks;
+	MemBlock **_memBlockIndex;
+	int16 _numBlocks;
 
-	Memory *lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id);
-	int32 defragMemory(uint32 req_size);
+	uint32 _totAlloc;
 
-	// Used to determine if the required size can be obtained if the
-	// defragger is allowed to run.
-	int32 virtualDefrag(uint32 size);
+	int16 *_idStack;
+	int16 _idStackPtr;
 
-	// Debugging functions
-	void debugMemory(void);
-	const char *fetchOwner(uint32 uid);
+	int16 findExactPointerInIndex(byte *ptr);
+	int16 findPointerInIndex(byte *ptr);
+	int16 findInsertionPointInIndex(byte *ptr);
 
 public:
-	// List of defined memory handles - each representing a block of memory
-	Memory _memList[MAX_mem_blocks];
-	uint32 _baseMemBlock;
-
 	MemoryManager(Sword2Engine *vm);
-	~MemoryManager(void);
+	~MemoryManager();
 
-	int32 ptrToInt(const uint8 *p);
-	uint8 *intToPtr(int32 n);
+	int32 encodePtr(byte *ptr);
+	byte *decodePtr(int32 n);
 
-	Memory *allocMemory(uint32 size, uint32 type, uint32 unique_id);
-	void freeMemory(Memory *block);
-	void floatMemory(Memory *block);
-	void lockMemory(Memory *block);
+	byte *memAlloc(uint32 size, int16 uid);
+	void memFree(byte *ptr);
 
-	// Debugging function
-	void displayMemory(void);
-	void memoryString(char *string);
+	void memDisplay();
+	void memStatusStr(char *buf);
 };
 
 } // End of namespace Sword2

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/module.mk,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- module.mk	30 Jan 2004 21:54:28 -0000	1.10
+++ module.mk	23 Apr 2004 07:01:38 -0000	1.11
@@ -14,7 +14,6 @@
 	sword2/logic.o \
 	sword2/maketext.o \
 	sword2/memory.o \
-	sword2/mem_view.o \
 	sword2/mouse.o \
 	sword2/protocol.o \
 	sword2/resman.o \

Index: mouse.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/mouse.cpp,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- mouse.cpp	27 Mar 2004 12:07:06 -0000	1.55
+++ mouse.cpp	23 Apr 2004 07:01:38 -0000	1.56
@@ -131,7 +131,7 @@
 	uint32 safe_looping_music_id;
 	MouseEvent *me;
 	int hit;
-	uint8 *icon;
+	byte *icon;
 	int32 pars[2];
 	uint32 icon_list[5] = {
 		OPTIONS_ICON,
@@ -772,15 +772,12 @@
 }
 
 void Sword2Engine::setMouse(uint32 res) {
-	uint8 *icon;
-	uint32 len;
-
 	// high level - whats the mouse - for the engine
 	_mousePointerRes = res;
 
 	if (res) {
-		icon = _resman->openResource(res) + sizeof(StandardHeader);
-		len = _resman->_resList[res]->size - sizeof(StandardHeader);
+		byte *icon = _resman->openResource(res) + sizeof(StandardHeader);
+		uint32 len = _resman->fetchLen(res) - sizeof(StandardHeader);
 
 		// don't pulse the normal pointer - just do the regular anim
 		// loop
@@ -798,17 +795,13 @@
 }
 
 void Sword2Engine::setLuggage(uint32 res) {
-	uint8 *icon;
-	uint32 len;
-
 	_realLuggageItem = res;
 
 	if (res) {
-		icon = _resman->openResource(res) + sizeof(StandardHeader);
-		len = _resman->_resList[res]->size - sizeof(StandardHeader);
-
-		_graphics->setLuggageAnim(icon, len);
+		byte *icon = _resman->openResource(res) + sizeof(StandardHeader);
+		uint32 len = _resman->fetchLen(res) - sizeof(StandardHeader);
 
+		_graphics->setLuggageAnim(icon + sizeof(StandardHeader), len);
 		_resman->closeResource(res);
 	} else
 		_graphics->setLuggageAnim(NULL, 0);
@@ -853,7 +846,7 @@
 void Sword2Engine::createPointerText(uint32 text_id, uint32 pointer_res) {
 	uint32 local_text;
 	uint32 text_res;
-	uint8 *text;
+	byte *text;
 	// offsets for pointer text sprite from pointer position
 	int16 xOffset, yOffset;
 	uint8 justification;
@@ -1179,7 +1172,7 @@
 	// params:	0 pointer to ObjectMouse or 0 for no write to mouse
 	//		  list
 
-	_vm->registerMouse((ObjectMouse *) _vm->_memory->intToPtr(params[0]));
+	_vm->registerMouse((ObjectMouse *) _vm->_memory->decodePtr(params[0]));
 	return IR_CONT;
 }
 
@@ -1203,7 +1196,7 @@
 int32 Logic::fnInitFloorMouse(int32 *params) {
 	// params:	0 pointer to object's mouse structure
 
- 	ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->intToPtr(params[0]);
+ 	ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->decodePtr(params[0]);
 
 	// floor is always lowest priority
 
@@ -1221,7 +1214,7 @@
 int32 Logic::fnSetScrollLeftMouse(int32 *params) {
 	// params:	0 pointer to object's mouse structure
 
- 	ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->intToPtr(params[0]);
+ 	ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->decodePtr(params[0]);
 
 	// Highest priority
 
@@ -1245,7 +1238,7 @@
 int32 Logic::fnSetScrollRightMouse(int32 *params) {
 	// params:	0 pointer to object's mouse structure
 
-	ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->intToPtr(params[0]);
+	ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->decodePtr(params[0]);
 
 	// Highest priority
 

Index: protocol.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/protocol.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- protocol.cpp	5 Feb 2004 14:19:04 -0000	1.25
+++ protocol.cpp	23 Apr 2004 07:02:02 -0000	1.26
@@ -28,12 +28,10 @@
  * of the screen file.
  */
 
-uint8 *Sword2Engine::fetchPalette(uint8 *screenFile) {
-	uint8 *palette;
-
+byte *Sword2Engine::fetchPalette(byte *screenFile) {
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
 
-	palette = (uint8 *) mscreenHeader + mscreenHeader->palette;
+	byte *palette = (byte *) mscreenHeader + mscreenHeader->palette;
 
 	// Always set colour 0 to black, because while most background screen
 	// palettes have a bright colour 0 it should come out as black in the
@@ -52,10 +50,10 @@
  * to the start of the screen file.
  */
 
-uint8 *Sword2Engine::fetchPaletteMatchTable(uint8 *screenFile) {
+byte *Sword2Engine::fetchPaletteMatchTable(byte *screenFile) {
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
 
-	return (uint8 *) mscreenHeader + mscreenHeader->paletteTable;
+	return (byte *) mscreenHeader + mscreenHeader->paletteTable;
 }
 
 /**
@@ -63,9 +61,9 @@
  * the screen file.
  */
 
-ScreenHeader *Sword2Engine::fetchScreenHeader(uint8 *screenFile) {
+ScreenHeader *Sword2Engine::fetchScreenHeader(byte *screenFile) {
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
-	ScreenHeader *screenHeader = (ScreenHeader *) ((uint8 *) mscreenHeader + mscreenHeader->screen);
+	ScreenHeader *screenHeader = (ScreenHeader *) ((byte *) mscreenHeader + mscreenHeader->screen);
 
 	return screenHeader;
 }
@@ -76,7 +74,7 @@
  * the number of layers on this screen.
  */
 
-LayerHeader *Sword2Engine::fetchLayerHeader(uint8 *screenFile, uint16 layerNo) {
+LayerHeader *Sword2Engine::fetchLayerHeader(byte *screenFile, uint16 layerNo) {
 #ifdef _SWORD2_DEBUG
 	ScreenHeader *screenHead = fetchScreenHeader(screenFile);
 
@@ -86,7 +84,7 @@
 
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
 
-	LayerHeader *layerHeader = (LayerHeader *) ((uint8 *) mscreenHeader + mscreenHeader->layers + (layerNo * sizeof(LayerHeader)));
+	LayerHeader *layerHeader = (LayerHeader *) ((byte *) mscreenHeader + mscreenHeader->layers + (layerNo * sizeof(LayerHeader)));
 
 	return layerHeader;
 }
@@ -96,10 +94,10 @@
  * start of the screen file.
  */
 
-uint8 *Sword2Engine::fetchShadingMask(uint8 *screenFile) {
+byte *Sword2Engine::fetchShadingMask(byte *screenFile) {
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
 
-	return (uint8 *) mscreenHeader + mscreenHeader->maskOffset;
+	return (byte *) mscreenHeader + mscreenHeader->maskOffset;
 }
 
 /**
@@ -107,7 +105,7 @@
  * anim file.
  */
 
-AnimHeader *Sword2Engine::fetchAnimHeader(uint8 *animFile) {
+AnimHeader *Sword2Engine::fetchAnimHeader(byte *animFile) {
 	return (AnimHeader *) (animFile + sizeof(StandardHeader));
 }
 
@@ -117,7 +115,7 @@
  * number exceeds the number of frames in this anim.
  */
 
-CdtEntry *Sword2Engine::fetchCdtEntry(uint8 *animFile, uint16 frameNo) {
+CdtEntry *Sword2Engine::fetchCdtEntry(byte *animFile, uint16 frameNo) {
 	AnimHeader *animHead = fetchAnimHeader(animFile);
 
 #ifdef _SWORD2_DEBUG
@@ -125,7 +123,7 @@
 		error("fetchCdtEntry(animFile,%d) - anim only %d frames", frameNo, animHead->noAnimFrames);
 #endif
 
-	return (CdtEntry *) ((uint8 *) animHead + sizeof(AnimHeader) + frameNo * sizeof(CdtEntry));
+	return (CdtEntry *) ((byte *) animHead + sizeof(AnimHeader) + frameNo * sizeof(CdtEntry));
 }
 
 /**
@@ -134,7 +132,7 @@
  * exceeds the number of frames in this anim
  */
 
-FrameHeader *Sword2Engine::fetchFrameHeader(uint8 *animFile, uint16 frameNo)	{
+FrameHeader *Sword2Engine::fetchFrameHeader(byte *animFile, uint16 frameNo) {
 	// required address = (address of the start of the anim header) + frameOffset
 	return (FrameHeader *) (animFile + sizeof(StandardHeader) + fetchCdtEntry(animFile, frameNo)->frameOffset);
 }
@@ -143,7 +141,7 @@
  * Returns a pointer to the requested parallax layer data.
  */
 
-Parallax *Sword2Engine::fetchBackgroundParallaxLayer(uint8 *screenFile, int layer) {
+Parallax *Sword2Engine::fetchBackgroundParallaxLayer(byte *screenFile, int layer) {
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
 
 #ifdef _SWORD2_DEBUG
@@ -151,10 +149,10 @@
 		error("fetchBackgroundParallaxLayer(%d) - No parallax layer exists", layer);
 #endif
 
-	return (Parallax *) ((uint8 *) mscreenHeader + mscreenHeader->bg_parallax[layer]);
+	return (Parallax *) ((byte *) mscreenHeader + mscreenHeader->bg_parallax[layer]);
 }
 
-Parallax *Sword2Engine::fetchBackgroundLayer(uint8 *screenFile) {
+Parallax *Sword2Engine::fetchBackgroundLayer(byte *screenFile) {
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
 
 #ifdef _SWORD2_DEBUG
@@ -162,10 +160,10 @@
 		error("fetchBackgroundLayer (%d) - No background layer exists");
 #endif
 
-	return (Parallax *) ((uint8 *) mscreenHeader + mscreenHeader->screen + sizeof(ScreenHeader));
+	return (Parallax *) ((byte *) mscreenHeader + mscreenHeader->screen + sizeof(ScreenHeader));
 }
 
-Parallax *Sword2Engine::fetchForegroundParallaxLayer(uint8 *screenFile, int layer) {
+Parallax *Sword2Engine::fetchForegroundParallaxLayer(byte *screenFile, int layer) {
 	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader));
 
 #ifdef _SWORD2_DEBUG
@@ -173,12 +171,12 @@
 		error("fetchForegroundParallaxLayer(%d) - No parallax layer exists", layer);
 #endif
 
-	return (Parallax *) ((uint8 *) mscreenHeader + mscreenHeader->fg_parallax[layer]);
+	return (Parallax *) ((byte *) mscreenHeader + mscreenHeader->fg_parallax[layer]);
 }
 
-uint8 errorLine[128];
+static byte errorLine[128];
 
-uint8 *Sword2Engine::fetchTextLine(uint8 *file, uint32 text_line) {
+byte *Sword2Engine::fetchTextLine(byte *file, uint32 text_line) {
 	StandardHeader *fileHeader;
 	uint32 *point;
 
@@ -198,30 +196,29 @@
 	// point to the lookup table
 	point = (uint32 *) text_header + 1;
 
-	return (uint8 *) (file + READ_LE_UINT32(point + text_line));
+	return (byte *) (file + READ_LE_UINT32(point + text_line));
 }
 
 
 // Used for testing text & speech (see fnISpeak in speech.cpp)
 
-bool Sword2Engine::checkTextLine(uint8 *file, uint32 text_line) {
+bool Sword2Engine::checkTextLine(byte *file, uint32 text_line) {
 	TextHeader *text_header = (TextHeader *) (file + sizeof(StandardHeader));
 
 	return text_line < text_header->noOfLines;
 }
 
-uint8 *Sword2Engine::fetchObjectName(int32 resourceId) {
+byte *Sword2Engine::fetchObjectName(int32 resourceId) {
 	StandardHeader *header;
 	
 	header = (StandardHeader *) _resman->openResource(resourceId);
 	_resman->closeResource(resourceId);
 
-	// note this pointer is no longer valid, but it should be ok until
+	// Note this pointer is no longer valid, but it should be ok until
 	// another resource is opened!
 
 	// FIXME: I don't like the sound of this at all. Though thanks to the
-	// BS2 memory manager, at least it will still point to malloced
-	// memory.
+	// resource caching, at least it will still point to malloced memory.
 
 	return header->name;
 }

Index: resman.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/resman.cpp,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- resman.cpp	17 Mar 2004 09:03:14 -0000	1.89
+++ resman.cpp	23 Apr 2004 07:02:03 -0000	1.90
@@ -30,7 +30,6 @@
 
 namespace Sword2 {
 
-// ---------------------------------------------------------------------------
 // Welcome to the easy resource manager - written in simple code for easy
 // maintenance
 // 
@@ -39,7 +38,19 @@
 //	resource.inf which is a list of ascii cluster file names
 //	resource.tab which is a table which tells us which cluster a resource
 //      is located in and the number within the cluster
-// ---------------------------------------------------------------------------
+
+// If 0, resouces are expelled immediately when they are closed. At the moment
+// this causes the game to crash, which seems like a bug to me. In fact, it
+// could be a clue to the mysterious and infrequent crashes...
+
+#define CACHE_CLUSTERS 1
+
+// Resources age every time a new room is entered. This constant indicates how
+// long a cached resource (i.e. one that has been closed) is allowed to live
+// before it dies of old age. This may need some tuning, but I picked three
+// because so many areas in the game seem to consist of about three rooms.
+
+#define MAX_CACHE_AGE 3
 
 enum {
 	BOTH		= 0x0,		// Cluster is on both CDs
@@ -75,132 +86,128 @@
 	// wish to know what resource files there are and what is in each
 
 	File file;
-	uint32 end;
-	Memory *temp;
-	uint32 pos = 0;
-	uint32 j = 0;
+	uint32 size;
+	byte *temp;
 
 	_totalClusters = 0;
 	_resConvTable = NULL;
 
-	if (!file.open("resource.inf")) {
-		error("init cannot *OPEN* resource.inf");
-	}
+	if (!file.open("resource.inf"))
+		error("Cannot open resource.inf");
 
-	end = file.size();
+	size = file.size();
 
-	//get some space for the incoming resource file - soon to be trashed
-	temp = _vm->_memory->allocMemory(end, MEM_locked, (uint32) UID_temp);
+	// Get some space for the incoming resource file - soon to be trashed
+	temp = (byte *) malloc(size);
 
-	if (file.read(temp->ad, end) != end) {
+	if (file.read(temp, size) != size) {
 		file.close();
 		error("init cannot *READ* resource.inf");
 	}
 
 	file.close();
 
-	// ok, we've loaded in the resource.inf file which contains a list of
-	// all the files now extract the filenames
+	// Ok, we've loaded in the resource.inf file which contains a list of
+	// all the files now extract the filenames.
+
+	// Using this method the Gode generated resource.inf must have #0d0a on
+	// the last entry
+
+	uint32 i = 0;
+	uint32 j = 0;
+
 	do {
 		// item must have an #0d0a
-		while (temp->ad[j] != 13) {
-			_resourceFiles[_totalClusters][pos] = temp->ad[j];
+		while (temp[i] != 13) {
+			_resourceFiles[_totalClusters][j] = temp[i];
+			i++;
 			j++;
-			pos++;
 		}
 
 		// NULL terminate our extracted string
-		_resourceFiles[_totalClusters][pos]=0;
+		_resourceFiles[_totalClusters][j] = 0;
 
 		// Reset position in current slot between entries, skip the
 		// 0x0a in the source and increase the number of clusters.
 
-		pos = 0;
-		j += 2;
+		j = 0;
+		i += 2;
 		_totalClusters++;
 
 		// TODO: put overload check here
-	} while (j != end);	// using this method the Gode generated resource.inf must have #0d0a on the last entry
+	} while (i != size);
 
-	// now load in the binary id to res conversion table
-	if (!file.open("resource.tab")) {
-		error("init cannot *OPEN* resource.tab");
-	}
+	free(temp);
 
-	// find how many resources
-	end = file.size();
+	// Now load in the binary id to res conversion table
+	if (!file.open("resource.tab"))
+		error("Cannot open resource.tab");
 
-	_totalResFiles = end / 4;
+	// Find how many resources
+	size = file.size();
 
-	// table seems ok so malloc some space
-	_resConvTable = (uint16 *) malloc(end);
+	_totalResFiles = size / 4;
 
-	for (j = 0; j < end / 2; j++)
-		_resConvTable[j] = file.readUint16LE();
+	// Table seems ok so malloc some space
+	_resConvTable = (uint16 *) malloc(size);
+
+	for (i = 0; i < size / 2; i++)
+		_resConvTable[i] = file.readUint16LE();
 
 	if (file.ioFailed()) {
 		file.close();
-		error("init cannot *READ* resource.tab");
+		error("Cannot read resource.tab");
 	}
 
 	file.close();
 
-	if (!file.open("cd.inf")) {
-		error("init cannot *OPEN* cd.inf");
-	}
+	if (!file.open("cd.inf"))
+		error("Cannot open cd.inf");
 
 	CdInf *cdInf = new CdInf[_totalClusters];
 
-	for (j = 0; j < _totalClusters; j++) {
-		file.read(cdInf[j].clusterName, sizeof(cdInf[j].clusterName));
-		cdInf[j].cd = file.readByte();
+	for (i = 0; i < _totalClusters; i++) {
+		file.read(cdInf[i].clusterName, sizeof(cdInf[i].clusterName));
+		cdInf[i].cd = file.readByte();
 		
-		if (file.ioFailed()) {
-			error("init failed to read cd.inf. Insufficient entries?");
-		}
+		if (file.ioFailed())
+			error("Cannot read cd.inf");
 	}
 
 	file.close();
 
-	for (j = 0; j < _totalClusters; j++) {
-		uint32 i = 0;
+	for (i = 0; i < _totalClusters; i++) {
+		for (j = 0; j < _totalClusters; j++) {
+			if (scumm_stricmp((char *) cdInf[j].clusterName, _resourceFiles[i]) == 0)
+				break;
+		}
 
-		while (scumm_stricmp((char *) cdInf[i].clusterName, _resourceFiles[j]) != 0 && i < _totalClusters)
-			i++;
+		if (j == _totalClusters)
+			error("%s is not in cd.inf", _resourceFiles[i]);
 
-		if (i == _totalClusters) {
-			error("init, %s is not in cd.inf", _resourceFiles[j]);
-		} else
-			_cdTab[j] = cdInf[i].cd;
+		_cdTab[i] = cdInf[j].cd;
 	}
 
 	delete [] cdInf;
 
-	debug(5, "%d resources in %d cluster files", _totalResFiles, _totalClusters);
-	for (j = 0; j < _totalClusters; j++)
-		debug(5, "filename of cluster %d: -%s", j, _resourceFiles[j]);
-
-	// create space for a list of pointers to mem's
-	_resList = (Memory **) malloc(_totalResFiles * sizeof(Memory *));
+	debug(1, "%d resources in %d cluster files", _totalResFiles, _totalClusters);
+	for (i = 0; i < _totalClusters; i++)
+		debug(2, "filename of cluster %d: -%s", i, _resourceFiles[i]);
 
-	_age = (uint32 *) malloc(_totalResFiles * sizeof(uint32));
-	_count = (uint16 *) malloc(_totalResFiles * sizeof(uint16));
+	_resList = (Resource *) malloc(_totalResFiles * sizeof(Resource));
 
-	for (j = 0; j < _totalResFiles; j++) {
-		// age must be 0 if the file is not in memory at all
-		_age[j] = 0;
-		_count[j] = 0;
+	for (i = 0; i < _totalResFiles; i++) {
+		_resList[i].ptr = NULL;
+		_resList[i].size = 0;
+		_resList[i].refCount = 0;
+		_resList[i].refTime = 0;
 	}
 
-	_resTime = 1;	//cannot start at 0
-	_vm->_memory->freeMemory(temp);	//get that memory back
+	_resTime = 0;
 }
 
 ResourceManager::~ResourceManager(void) {
-	// free up our mallocs
 	free(_resList);
-	free(_age);
-	free(_count);
 	free(_resConvTable);
 }
 
@@ -209,7 +216,7 @@
 #define SWAP16(x)	x = SWAP_BYTES_16(x)
 #define SWAP32(x)	x = SWAP_BYTES_32(x)
 
-void convertEndian(uint8 *file, uint32 len) {
+void convertEndian(byte *file, uint32 len) {
 	int i;
 	StandardHeader *hdr = (StandardHeader *) file;
 	
@@ -390,40 +397,29 @@
 	}
 }
 
-uint8 *ResourceManager::openResource(uint32 res, bool dump) {
-	// returns ad of resource. Loads if not in memory
-	// retains a count
-	// resource can be aged out of memory if count = 0
-	// the resource is locked while count != 0 i.e. until a closeResource
-	// is called
-
-	File	file;
-	uint16	parent_res_file;
-	uint16	actual_res;
-	uint32	pos, len;
-
-	uint32	table_offset;
+/**
+ * Returns the address of a resource. Loads if not in memory. Retains a count.
+ */
 
+byte *ResourceManager::openResource(uint32 res, bool dump) {
 	assert(res < _totalResFiles);
 
-	// is the resource in memory already?
-	// if the file is not in memory then age should and MUST be 0
-	if (!_age[res]) {
-		// fetch the correct file and read in the correct portion
-		// if the file cannot fit then we must trash the oldest large
-		// enough floating file
+	// Is the resource in memory already? If not, load it.
+
+	if (!_resList[res].ptr) {
+		// Fetch the correct file and read in the correct portion.
 
 		// points to the number of the ascii filename
-		parent_res_file = _resConvTable[res * 2];
+		uint16 parent_res_file = _resConvTable[res * 2];
 
 		assert(parent_res_file != 0xffff);
 
-		// relative resource within the file
-		actual_res = _resConvTable[(res * 2) + 1];
+		// Relative resource within the file
+		uint16 actual_res = _resConvTable[(res * 2) + 1];
 
-		// first we have to find the file via the _resConvTable
+		// First we have to find the file via the _resConvTable
 
-		debug(5, "resOpen %s res %d", _resourceFiles[parent_res_file], res);
+		debug(5, "openResource %s res %d", _resourceFiles[parent_res_file], res);
 
 		// If we're loading a cluster that's only available from one
 		// of the CDs, remember which one so that we can play the
@@ -436,6 +432,8 @@
 		// care which CD it's on. But if we can't find it, keep asking
 		// for the CD until we do.
 
+		File file;
+
 		while (!file.open(_resourceFiles[parent_res_file])) {
 			// If the file is supposed to be on hard disk, or we're
 			// playing a demo, then we're in trouble if the file
@@ -448,32 +446,28 @@
 		}
 
 		// 1st DWORD of a cluster is an offset to the look-up table
-		table_offset = file.readUint32LE();
+		uint32 table_offset = file.readUint32LE();
 
-		debug(5, "table offset = %d", table_offset);
+		debug(6, "table offset = %d", table_offset);
 
-		// 2 dwords per resource
 		file.seek(table_offset + actual_res * 8, SEEK_SET);
-		// get position of our resource within the cluster file
-		pos = file.readUint32LE();
-		// read the length
-		len = file.readUint32LE();
 
-		// get to position in file of our particular resource
+		uint32 pos = file.readUint32LE();
+		uint32 len = file.readUint32LE();
+
 		file.seek(pos, SEEK_SET);
 
-		debug(5, "res len %d", len);
+		debug(6, "res len %d", len);
 
-		// ok, we know the length so try and allocate the memory
-		// if it can't then old files will be ditched until it works
-		_resList[res] = _vm->_memory->allocMemory(len, MEM_locked, res);
+		// Ok, we know the length so try and allocate the memory.
+		// If it can't then old files will be ditched until it works.
+		_resList[res].ptr = _vm->_memory->memAlloc(len, res);
+		_resList[res].size = len;
 
-		// now load the file
-		// hurray, load it in.
-		file.read(_resList[res]->ad, len);
+		file.read(_resList[res].ptr, len);
 
 		if (dump) {
-			StandardHeader *header = (StandardHeader *) _resList[res]->ad;
+			StandardHeader *header = (StandardHeader *) _resList[res].ptr;
 			char buf[256];
 			char tag[10];
 			File out;
@@ -531,7 +525,7 @@
 
 			if (!out.open(buf, "")) {
 				if (out.open(buf, "", File::kFileWriteMode))
-					out.write(_resList[res]->ad, len);
+					out.write(_resList[res].ptr, len);
 			}
 
 			if (out.isOpen())
@@ -542,184 +536,112 @@
 		file.close();
 
 #ifdef SCUMM_BIG_ENDIAN
-		convertEndian((uint8 *) _resList[res]->ad, len);
+		convertEndian(_resList[res].ptr, len);
 #endif
-	} else {
-		debug(9, "RO %d, already open count=%d", res, _count[res]);
 	}
 
-	// number of times opened - the file won't move in memory while count
-	// is non zero
-	_count[res]++;
+	_resList[res].refCount++;
+	_resList[res].refTime = _resTime;
 
-	// update the accessed time stamp - touch the file in other words
-	_age[res] = _resTime;
+	return _resList[res].ptr;
+}
 
-	// pass the address of the mem & lock the memory too
-	// might be locked already (if count > 1)
-	_vm->_memory->lockMemory(_resList[res]);
+void ResourceManager::closeResource(uint32 res) {
+	assert(res < _totalResFiles);
+	assert(_resList[res].refCount > 0);
 
-	return (uint8 *) _resList[res]->ad;
-}
+	_resList[res].refCount--;
+	_resList[res].refTime = _resTime;
 
-uint8 ResourceManager::checkValid(uint32 res) {
-	// returns '1' if resource is valid, otherwise returns '0'
-	// used in startup.cpp to ignore invalid screen-manager resources
+#if !CACHE_CLUSTERS
+	// Maybe it's useful on some platforms if memory is released as
+	// quickly as possible?
 
-	uint16 parent_res_file;
+	if (_resList[res].refCount == 0)
+		remove(res);
+#endif
+}
 
-	// resource number out of range
+/**
+ * Returns true if resource is valid, otherwise false.
+ */
+
+bool ResourceManager::checkValid(uint32 res) {
+	// Resource number out of range
 	if (res >= _totalResFiles)
-		return 0;
+		return false;
 
-	// points to the number of the ascii filename
-	parent_res_file = _resConvTable[res * 2];
+	// Points to the number of the ascii filename
+	uint16 parent_res_file = _resConvTable[res * 2];
 
-	// null & void resource
+	// Null & void resource
 	if (parent_res_file == 0xffff)
-		return 0;
+		return false;
 
-	// ok
-	return 1;
+	return true;
 }
 
-void ResourceManager::nextCycle(void) {
-	// increment the cycle and calculate actual per-cycle memory useage
+void ResourceManager::passTime() {
+	// In the original game this was called every game cycle. This allowed
+	// for a more exact measure of when a loaded resouce was most recently
+	// used. When the memory pool got too fragmented, the oldest and
+	// largest of the closed resources would be expelled from the cache.
 
-#ifdef _SWORD2_DEBUG
-	_currentMemoryUsage = 0;
+	// With the new memory manager, there is no single memory block that
+	// can become fragmented. Therefore, it makes more sense to me to
+	// measure an object's age in how many rooms ago it was last used.
 
-	for (int i = 1; i < _totalResFiles; i++) {
-		// was accessed last cycle
-		if (_age[i] == _resTime)
-			_currentMemoryUsage += _resList[i]->size;
-	}
-#endif
+	// Therefore, this function is now called when a new room is loaded.
 
 	_resTime++;
-
-	// if you left the game running for a hundred years when this went to 0
-	// there'd be a resource left stuck in memory - after another hundred
-	// years there'd be another...
-	//
-	// Mind you, by then the our get_msecs() function will have wrapped
-	// around too, probably causing a mess of other problems.
-
-	if (!_resTime)
-		_resTime++;
-}
-
-uint32 ResourceManager::fetchUsage(void) {
-	// returns memory usage previous cycle
-	return _currentMemoryUsage;
 }
 
-void ResourceManager::closeResource(uint32 res) {
-	// decrements the count
-	// resource floats when count = 0
-
-	assert(res < _totalResFiles);
-	assert(_count[res]);
-
-	//one less has it open
-	_count[res]--;
-
-	//if noone has the file open then unlock and allow to float
-	if (!_count[res]) {
-		// pass the address of the mem
-		_vm->_memory->floatMemory(_resList[res]);
-	}
-}
+/**
+ * Returns the total file length of a resource - i.e. all headers are included
+ * too.
+ */
 
 uint32 ResourceManager::fetchLen(uint32 res) {
-	// returns the total file length of a resource - i.e. all headers are
-	// included too
+	if (_resList[res].ptr)
+		return _resList[res].size;
 
-	File fh;
-	uint16 parent_res_file;
-	uint16 actual_res;
-	uint32 len;
-	uint32 table_offset;
+	// Does this ever happen?
+	warning("fetchLen: Resource %u is not loaded; reading length from file", res);
 
-	// points to the number of the ascii filename
-	parent_res_file = _resConvTable[res * 2];
+	// Points to the number of the ascii filename
+	uint16 parent_res_file = _resConvTable[res * 2];
 
 	// relative resource within the file
-	actual_res = _resConvTable[(res * 2) + 1];
+	uint16 actual_res = _resConvTable[(res * 2) + 1];
 
 	// first we have to find the file via the _resConvTable
 	// open the cluster file
 
-	if (!fh.open(_resourceFiles[parent_res_file]))
-		error("fetchLen cannot *OPEN* %s", _resourceFiles[parent_res_file]);
+	File file;
+
+	if (!file.open(_resourceFiles[parent_res_file]))
+		error("Cannot open %s", _resourceFiles[parent_res_file]);
 
 	// 1st DWORD of a cluster is an offset to the look-up table
-	table_offset = fh.readUint32LE();
+	uint32 table_offset = file.readUint32LE();
 
 	// 2 dwords per resource + skip the position dword
-	fh.seek(table_offset + (actual_res * 8) + 4, SEEK_SET);
-
-	// read the length
-	len = fh.readUint32LE();
-	return len;
-}
-
-char *ResourceManager::fetchCluster(uint32 res) {
-	// returns a pointer to the ascii name of the cluster file which
-	// contains resource res
-	return _resourceFiles[_resConvTable[res * 2]];
-}
-
-uint32 ResourceManager::fetchAge(uint32 res) {
-	// return the age of res
-	return _age[res];
-}
+	file.seek(table_offset + (actual_res * 8) + 4, SEEK_SET);
 
-uint32 ResourceManager::fetchCount(uint32 res) {
-	// return the open count of res
-	return _count[res];
+	return file.readUint32LE();
 }
 
-uint32 ResourceManager::helpTheAgedOut(void) {
-	// remove from memory the oldest closed resource
-
-	uint32 oldest_res;	// holds id of oldest found so far when we have to chuck stuff out of memory
-	uint32 oldest_age;	// age of above during search
-	uint32 j;
-	uint32 largestResource = 0;
-
-	oldest_age = _resTime;
-	oldest_res = 0;
+void ResourceManager::expelOldResources() {
+	int nuked = 0;
 
-	for (j = 2; j < _totalResFiles; j++) {
-		// not held open and older than this one
-		if (!_count[j] && _age[j] && _age[j] <= oldest_age) {	
-			if (_age[j] == oldest_age && _resList[j]->size > largestResource)	{
-				// Kick old resource of oldest age and largest
-				// size (Helps the poor defragger).
-				oldest_res = j;
-				largestResource = _resList[j]->size;
-			} else if (_age[j] < oldest_age)	{
-				oldest_res = j;
-				oldest_age = _age[j];
-				largestResource = _resList[j]->size;
-			}
+	for (uint i = 0; i < _totalResFiles; i++) {
+		if (_resList[i].ptr && _resList[i].refCount == 0 && _resTime - _resList[i].refTime >= MAX_CACHE_AGE) {
+			remove(i);
+			nuked++;
 		}
 	}
 
-	// there was not a file we could release
-	// no bytes released - oh dear, lets hope this never happens
-	if (!oldest_res)
-		return 0;
-
-	debug(5, "removing %d, age %d, size %d", oldest_res, _age[oldest_res], _resList[oldest_res]->size);
-
-	// trash this old resource
-
-	_age[oldest_res] = 0;		// effectively gone from _resList
-	_vm->_memory->freeMemory(_resList[oldest_res]);	// release the memory too
-
-	return _resList[oldest_res]->size;	// return bytes freed
+	debug(1, "%d resources died of old age", nuked);
 }
 
 void ResourceManager::printConsoleClusters(void) {
@@ -750,20 +672,13 @@
 }
 
 void ResourceManager::examine(int res) {
-	StandardHeader *file_header;
-
 	if (res < 0 || res >= (int) _totalResFiles)
 		Debug_Printf("Illegal resource %d (there are %d resources 0-%d)\n", res, _totalResFiles, _totalResFiles - 1);
 	else if (_resConvTable[res * 2] == 0xffff)
 		Debug_Printf("%d is a null & void resource number\n", res);
 	else {
 		// open up the resource and take a look inside!
-		file_header = (StandardHeader *) openResource(res);
-
-		// Debug_Printf("%d\n", file_header->fileType);
-		// Debug_Printf("%s\n", file_header->name);
-
-		// Resource types. See header.h
+		StandardHeader *file_header = (StandardHeader *) openResource(res);
 
 		switch (file_header->fileType) {
 		case ANIMATION_FILE:
@@ -813,141 +728,100 @@
 		return;
 	}
 
-	// if noone has the file open then unlock and allow to float
-	if (!_count[res]) {
-		if (_age[res]) {
-			_age[res] = 0;		// effectively gone from _resList
-			_vm->_memory->freeMemory(_resList[res]);	// release the memory too
-			Debug_Printf("Trashed %d\n", res);
-		} else
-			Debug_Printf("%d not in memory\n", res);
-	} else
-		Debug_Printf("File is open - cannot remove\n");
-}
-
-void ResourceManager::remove(uint32 res) {
-	if (_age[res]) {
-		_age[res] = 0;			// effectively gone from _resList
-		_vm->_memory->freeMemory(_resList[res]);	// release the memory too
-		debug(5, " - Trashing %d", res);
-	} else
-		debug(5, "remove(%d) not even in memory!", res);
-}
+	if (!_resList[res].ptr) {
+		Debug_Printf("Resource %d is not in memory\n", res);
+		return;
+	}
 
-void ResourceManager::removeAll(void) {
-	// remove all res files from memory - ready for a total restart
-	// including player object & global variables resource
+	if (_resList[res].refCount) {
+		Debug_Printf("Resource %d is open - cannot remove\n", res);
+		return;
+	}
 
-	int j;
-	uint32 res;
+	remove(res);
+	Debug_Printf("Trashed %d\n", res);
+}
 
-	j = _vm->_memory->_baseMemBlock;
+void ResourceManager::remove(int res) {
+	if (_resList[res].ptr) {
+		_vm->_memory->memFree(_resList[res].ptr);
+		_resList[res].ptr = NULL;
+	}
+}
 
-	do {
-		if (_vm->_memory->_memList[j].uid < 65536) {	// a resource
-			res = _vm->_memory->_memList[j].uid;
-			_age[res] = 0;		// effectively gone from _resList
-			_vm->_memory->freeMemory(_resList[res]);	// release the memory too
-		}
+/**
+ * Remove all res files from memory - ready for a total restart. This includes
+ * the player object and global variables resource.
+ */
 
-		j = _vm->_memory->_memList[j].child;
-	} while	(j != -1);
+void ResourceManager::removeAll(void) {
+	for (uint i = 0; i < _totalResFiles; i++)
+		remove(i);
 }
 
-void ResourceManager::killAll(bool wantInfo) {
-	// remove all res files from memory
-	// its quicker to search the mem blocs for res files than search
-	// resource lists for those in memory
-
-	int j;
-	uint32 res;
-	uint32 nuked = 0;
-  	StandardHeader *header;
+/**
+ * Remove all resources from memory.
+ */
 
-	j = _vm->_memory->_baseMemBlock;
+void ResourceManager::killAll(bool wantInfo) {
+	int nuked = 0;
 
-	do {
-		if (_vm->_memory->_memList[j].uid < 65536) {	// a resource
-			res = _vm->_memory->_memList[j].uid;
+	for (uint i = 0; i < _totalResFiles; i++) {
+		// Don't nuke the global variables or the player object!
+		if (i == 1 || i == CUR_PLAYER_ID)
+			continue;
 
-			// not the global vars which are assumed to be open in
-			// memory & not the player object!
-			if (res != 1 && res != CUR_PLAYER_ID) {
-				header = (StandardHeader *) openResource(res);
-				closeResource(res);
+		if (_resList[i].ptr) {
+			StandardHeader *header = (StandardHeader *) _resList[i].ptr;
 
-				_age[res] = 0;		// effectively gone from _resList
-				_vm->_memory->freeMemory(_resList[res]);	// release the memory too
-				nuked++;
+			if (wantInfo)
+				Debug_Printf("Nuked %5d: %s\n", i, header->name);
 
-				// if this was called from the console,
-				if (wantInfo) {
-					Debug_Printf("Nuked %5d: %s\n", res, header->name);
-					debug(5, " nuked %d: %s", res, header->name);
-				}	
-			}
+			remove(i);
+			nuked++;
 		}
-		j = _vm->_memory->_memList[j].child;
-	} while (j != -1);
-
-	// if this was called from the console
-	if (wantInfo) {
-		Debug_Printf("Expelled %d resource(s)\n", nuked);
 	}
+
+	if (wantInfo)
+		Debug_Printf("Expelled %d resources\n", nuked);
 }
 
-//----------------------------------------------------------------------------
-// Like killAll but only kills objects (except George & the variable table of
-// course) - ie. forcing them to reload & restart their scripts, which
-// simulates the effect of a save & restore, thus checking that each object's
-// re-entrant logic works correctly, and doesn't cause a statuette to
-// disappear forever, or some plaster-filled holes in sand to crash the game &
-// get James in trouble again.
+/**
+ * Like killAll but only kills objects (except George & the variable table of
+ * course) - ie. forcing them to reload & restart their scripts, which
+ * simulates the effect of a save & restore, thus checking that each object's
+ * re-entrant logic works correctly, and doesn't cause a statuette to
+ * disappear forever, or some plaster-filled holes in sand to crash the game &
+ * get James in trouble again.
+ */
 
 void ResourceManager::killAllObjects(bool wantInfo) {
-	// remove all object res files from memory, excluding George
-	// its quicker to search the mem blocs for res files than search
-	// resource lists for those in memory
-
-	int j;
-	uint32 res;
-	uint32 nuked = 0;
- 	StandardHeader *header;
+	int nuked = 0;
 
-	j = _vm->_memory->_baseMemBlock;
+	for (uint i = 0; i < _totalResFiles; i++) {
+		// Don't nuke the global variables or the player object!
+		if (i == 1 || i == CUR_PLAYER_ID)
+			continue;
 
-	do {
-		if (_vm->_memory->_memList[j].uid < 65536) {	// a resource
-			res = _vm->_memory->_memList[j].uid;
-			//not the global vars which are assumed to be open in
-			// memory & not the player object!
-			if (res != 1 && res != CUR_PLAYER_ID) {
-				header = (StandardHeader *) openResource(res);
-				closeResource(res);
+		if (_resList[i].ptr) {
+			StandardHeader *header = (StandardHeader *) _resList[i].ptr;
 
-				if (header->fileType == GAME_OBJECT) {
-					_age[res] = 0;		// effectively gone from _resList
-					_vm->_memory->freeMemory(_resList[res]);	// release the memory too
-   					nuked++;
+			if (header->fileType == GAME_OBJECT) {
+				if (wantInfo)
+					Debug_Printf("Nuked %5d: %s\n", i, header->name);
 
-					// if this was called from the console
-					if (wantInfo) {
-						Debug_Printf("Nuked %5d: %s\n", res, header->name);
-						debug(5, " nuked %d: %s", res, header->name);
-					}	
-				}
+				remove(i);
+				nuked++;
 			}
 		}
-		j = _vm->_memory->_memList[j].child;
-	} while (j != -1);
+	}
 
-	// if this was called from the console
 	if (wantInfo)
-		Debug_Printf("Expelled %d object resource(s)\n", nuked);
+		Debug_Printf("Expelled %d resources\n", nuked);
 }
 
 void ResourceManager::getCd(int cd) {
-	uint8 *textRes;
+	byte *textRes;
 
 	// stop any music from playing - so the system no longer needs the
 	// current CD - otherwise when we take out the CD, Windows will

Index: resman.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/resman.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- resman.h	6 Jan 2004 13:44:17 -0000	1.19
+++ resman.h	23 Apr 2004 07:02:04 -0000	1.20
@@ -26,35 +26,27 @@
 
 class Sword2Engine;
 
+struct Resource {
+	byte *ptr;
+	uint32 size;
+	uint32 refCount;
+	uint32 refTime;
+};
+
 class ResourceManager {
 public:
 	ResourceManager(Sword2Engine *vm);	// read in the config file
 	~ResourceManager(void);
 
-	// Returns ad of resource. Loads if not in memory. Retains a count.
-	// Resource can be aged out of memory if count = 0
-	// The resource is locked while count != 0
-	// Resource floats when count = 0
-
-	uint8 *openResource(uint32 res, bool dump = false);
-	void closeResource(uint32 res);		// decrements the count
-
-	// returns '0' if resource out of range or null, otherwise '1' for ok
-
-	uint8 checkValid(uint32 res);
-
-	//for mem_view to query the owners of mem blocs
-
-	char *fetchCluster(uint32 res);
-	uint32 fetchAge(uint32 res);
-	uint32 fetchCount(uint32 count);
-
-	uint32 helpTheAgedOut(void);
+	byte *openResource(uint32 res, bool dump = false);
+	void closeResource(uint32 res);
 
+	bool checkValid(uint32 res);
 	uint32 fetchLen(uint32 res);
 
-	void nextCycle(void);
-	uint32 fetchUsage(void);
+	void expelOldResources(void);
+
+	void passTime(void);
 
 	// Prompts the user for the specified CD.
 	void getCd(int cd);
@@ -63,6 +55,8 @@
 		return _curCd;
 	}
 
+	void remove(int res);
+
 	// ----console commands
 
 	void printConsoleClusters(void);
@@ -70,11 +64,9 @@
 	void kill(int res);
 	void killAll(bool wantInfo);
 	void killAllObjects(bool wantInfo);
-	void remove(uint32 res);
 	void removeAll(void);
 
-	// pointer to a pointer (or list of pointers in-fact)
-	Memory **_resList;
+	Resource *_resList;
 
 private:
 	Sword2Engine *_vm;
@@ -82,20 +74,13 @@
 	int _curCd;
 	uint32 _totalResFiles;
 	uint32 _totalClusters;
-	uint32 _currentMemoryUsage;
-
-	// Inc's each time open is called and is given to resource as its age.
-	// Cannot be allowed to start at 0! (A pint if you can tell me why)
 
 	uint32 _resTime;
 
-	uint32 *_age;
-
 	// Gode generated res-id to res number/rel number conversion table
 
 	uint16 *_resConvTable;
 
-	uint16 *_count;
 	char _resourceFiles[MAX_res_files][20];
 	uint8 _cdTab[MAX_res_files];		// Location of each cluster.
 };							

Index: router.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/router.cpp,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- router.cpp	17 Mar 2004 09:03:15 -0000	1.41
+++ router.cpp	23 Apr 2004 07:02:04 -0000	1.42
@@ -110,7 +110,7 @@
 	if (_routeSlots[slotNo])
 		freeRouteMem();
 
-	_routeSlots[slotNo] = _vm->_memory->allocMemory(sizeof(WalkData) * O_WALKANIM_SIZE, MEM_locked, (uint32) UID_walk_anim);
+	_routeSlots[slotNo] = (WalkData *) malloc(sizeof(WalkData) * O_WALKANIM_SIZE);
 
 	// 12000 bytes were used for this in Sword1 mega compacts, based on
 	// 20 bytes per 'WalkData' frame
@@ -125,36 +125,23 @@
 	// megaObject->route_slot_id = slotNo + 1;
 }
 
-WalkData *Router::lockRouteMem(void) {
+WalkData *Router::getRouteMem(void) {
 	uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]);
 	
-	_vm->_memory->lockMemory(_routeSlots[slotNo]);
-	return (WalkData *) _routeSlots[slotNo]->ad;
-}
-
-void Router::floatRouteMem(void) {
-	uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]); 
-
-	_vm->_memory->floatMemory(_routeSlots[slotNo]);
+	return (WalkData *) _routeSlots[slotNo];
 }
 
 void Router::freeRouteMem(void) {
 	uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]); 
 
-	// free the mem block pointed to from this entry of _routeSlots[]
-
-	_vm->_memory->freeMemory(_routeSlots[slotNo]);
+	free(_routeSlots[slotNo]);
 	_routeSlots[slotNo] = NULL;
 }
 
 void Router::freeAllRouteMem(void) {
 	for (int i = 0; i < TOTAL_ROUTE_SLOTS; i++) {
-		if (_routeSlots[i]) {
-			// free the mem block pointed to from this entry of
-			// _routeSlots[]
-			_vm->_memory->freeMemory(_routeSlots[i]);
-			_routeSlots[i] = NULL;
-		}
+		free(_routeSlots[i]);
+		_routeSlots[i] = NULL;
 	}
 }
 
@@ -191,8 +178,7 @@
 	setUpWalkGrid(ob_mega, x, y, dir);
 	loadWalkData(ob_walkdata);
 
-	// lock the WalkData array (NB. AFTER loading walkgrid & walkdata!)
-	walkAnim = lockRouteMem();
+	walkAnim = getRouteMem();
 
 	// All route data now loaded start finding a route
 
@@ -268,8 +254,6 @@
 		break;
 	}
 
-	floatRouteMem();	// float the WalkData array again
-
 	return routeFlag;	// send back null route
 }
 
@@ -728,8 +712,7 @@
 
  	walk_pc = ob_mega->walk_pc;
 
-	// lock the WalkData array (NB. AFTER loading walkgrid & walkdata!)
-	walkAnim = lockRouteMem();
+	walkAnim = getRouteMem();
 
 	// if this mega does actually have slow-out frames
 	if (_usingSlowOutFrames) {
@@ -2400,7 +2383,7 @@
 
 void Router::loadWalkGrid(void) {
 	WalkGridHeader floorHeader;
-	uint8 *fPolygrid;
+	byte *fPolygrid;
 	uint32 theseBars;
 	uint32 theseNodes;
 
@@ -2415,7 +2398,7 @@
 			// open walk grid file
 			fPolygrid = _vm->_resman->openResource(_walkGridList[i]);
  			fPolygrid += sizeof(StandardHeader);
- 			memcpy((uint8 *) &floorHeader, fPolygrid, sizeof(WalkGridHeader));
+ 			memcpy((byte *) &floorHeader, fPolygrid, sizeof(WalkGridHeader));
  			fPolygrid += sizeof(WalkGridHeader);
 
 			// how many bars & nodes are we getting from this
@@ -2432,7 +2415,7 @@
 
 			// lines
 
- 			memcpy((uint8 *) &_bars[_nBars], fPolygrid, theseBars * sizeof(BarData));
+ 			memcpy((byte *) &_bars[_nBars], fPolygrid, theseBars * sizeof(BarData));
 
 			// move pointer to start of node data
 			fPolygrid += theseBars * sizeof(BarData);
@@ -2441,7 +2424,7 @@
 
 			// leave node 0 for start node
 			for (uint j = 0; j < theseNodes; j++) {
-				memcpy((uint8 *) &_node[_nNodes + j].x, fPolygrid, 2 * sizeof(int16));
+				memcpy((byte *) &_node[_nNodes + j].x, fPolygrid, 2 * sizeof(int16));
 				fPolygrid += 2 * sizeof(int16);
 			}
 

Index: router.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/router.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- router.h	6 Jan 2004 13:44:17 -0000	1.16
+++ router.h	23 Apr 2004 07:02:06 -0000	1.17
@@ -105,7 +105,7 @@
 
 	// stores pointers to mem blocks containing routes created & used by
 	// megas (NULL if slot not in use)
-	Memory *_routeSlots[TOTAL_ROUTE_SLOTS];
+	WalkData *_routeSlots[TOTAL_ROUTE_SLOTS];
 
 	BarData _bars[O_GRID_SIZE];
 	NodeData _node[O_GRID_SIZE];
@@ -228,8 +228,7 @@
 	void earlySlowOut(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata);
 
 	void allocateRouteMem(void);
-	WalkData *lockRouteMem(void);
-	void floatRouteMem(void);
+	WalkData *getRouteMem(void);
 	void freeRouteMem(void);
 	void freeAllRouteMem(void);
 	void addWalkGrid(int32 gridResource);

Index: save_rest.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/save_rest.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- save_rest.cpp	28 Mar 2004 13:13:16 -0000	1.52
+++ save_rest.cpp	23 Apr 2004 07:02:06 -0000	1.53
@@ -88,26 +88,26 @@
 
 // SAVE GAME
 
-uint32 Sword2Engine::saveGame(uint16 slotNo, uint8 *desc) {
-	Memory *saveBufferMem;
+uint32 Sword2Engine::saveGame(uint16 slotNo, byte *desc) {
+	byte *saveBufferMem;
 	uint32 bufferSize;
 	uint32 errorCode;
 
 	// allocate the savegame buffer
 
 	bufferSize = findBufferSize();
-	saveBufferMem = _memory->allocMemory(bufferSize, MEM_locked, (uint32) UID_savegame_buffer);
+	saveBufferMem = (byte *) malloc(bufferSize);
 
 	fillSaveBuffer(saveBufferMem, bufferSize, desc);
 
 	// save it (hopefully no longer platform-specific)
 
 	// save the buffer
-	errorCode = saveData(slotNo, saveBufferMem->ad, bufferSize);
+	errorCode = saveData(slotNo, saveBufferMem, bufferSize);
 
 	// free the buffer
 
-	_memory->freeMemory(saveBufferMem);
+	free(saveBufferMem);
 
 	return errorCode;
 }
@@ -119,8 +119,8 @@
 	return sizeof(_saveGameHeader) + _resman->fetchLen(1);
 }
 
-void Sword2Engine::fillSaveBuffer(Memory *buffer, uint32 size, uint8 *desc) {
-	uint8 *varsRes;
+void Sword2Engine::fillSaveBuffer(byte *buffer, uint32 size, byte *desc) {
+	byte *varsRes;
 
 	// set up the _saveGameHeader
 
@@ -160,7 +160,7 @@
 #endif
 
 	// copy the header to the savegame buffer
-	memcpy(buffer->ad, &_saveGameHeader, sizeof(_saveGameHeader));
+	memcpy(buffer, &_saveGameHeader, sizeof(_saveGameHeader));
 
 	// copy the global variables to the buffer
 
@@ -168,10 +168,10 @@
 	varsRes = _resman->openResource(1);
 
 	// copy that to the buffer, following the header
-	memcpy(buffer->ad + sizeof(_saveGameHeader), varsRes, FROM_LE_32(_saveGameHeader.varLength));
+	memcpy(buffer + sizeof(_saveGameHeader), varsRes, FROM_LE_32(_saveGameHeader.varLength));
 
 #ifdef SCUMM_BIG_ENDIAN
-	uint32 *globalVars = (uint32 *) (buffer->ad + sizeof(_saveGameHeader) + sizeof(StandardHeader));
+	uint32 *globalVars = (uint32 *) (buffer + sizeof(_saveGameHeader) + sizeof(StandardHeader));
 	const uint numVars = (FROM_LE_32(_saveGameHeader.varLength) - sizeof(StandardHeader)) / 4;
 
 	for (uint i = 0; i < numVars; i++)
@@ -183,11 +183,11 @@
 
 	// set the checksum & copy that to the buffer
 
-	_saveGameHeader.checksum = TO_LE_32(calcChecksum((buffer->ad) + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum)));
- 	memcpy(buffer->ad, &_saveGameHeader.checksum, sizeof(_saveGameHeader.checksum));
+	_saveGameHeader.checksum = TO_LE_32(calcChecksum(buffer + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum)));
+ 	memcpy(buffer, &_saveGameHeader.checksum, sizeof(_saveGameHeader.checksum));
 }
 
-uint32 Sword2Engine::saveData(uint16 slotNo, uint8 *buffer, uint32 bufferSize) {
+uint32 Sword2Engine::saveData(uint16 slotNo, byte *buffer, uint32 bufferSize) {
 	char saveFileName[MAX_FILENAME_LEN];
 	uint32 itemsWritten;
 	SaveFile *out;
@@ -219,19 +219,19 @@
 // RESTORE GAME
 
 uint32 Sword2Engine::restoreGame(uint16 slotNo) {
-	Memory *saveBufferMem;
+	byte *saveBufferMem;
 	uint32 bufferSize;
 	uint32 errorCode;
 
 	// allocate the savegame buffer
 
 	bufferSize = findBufferSize();
-	saveBufferMem = _memory->allocMemory(bufferSize, MEM_locked, (uint32) UID_savegame_buffer);
+	saveBufferMem = (byte *) malloc(bufferSize);
 
 	// read the savegame file into our buffer
 
 	// load savegame into buffer
-	errorCode = restoreData(slotNo, saveBufferMem->ad, bufferSize);
+	errorCode = restoreData(slotNo, saveBufferMem, bufferSize);
 
 	// if it was read in successfully, then restore the game from the
 	// buffer & free the buffer
@@ -244,7 +244,7 @@
 		// loading in the new screen & runlist
 	} else {
 		// because restoreFromBuffer would have freed it
-		_memory->freeMemory(saveBufferMem);
+		free(saveBufferMem);
 	}
 
 	// Force the game engine to pick a cursor. This appears to be needed
@@ -253,7 +253,7 @@
 	return errorCode;
 }
 
-uint32 Sword2Engine::restoreData(uint16 slotNo, uint8 *buffer, uint32 bufferSize) {
+uint32 Sword2Engine::restoreData(uint16 slotNo, byte *buffer, uint32 bufferSize) {
 	char saveFileName[MAX_FILENAME_LEN];
 	SaveFile *in;
 	SaveFileManager *mgr = _system->get_savefile_manager();
@@ -295,12 +295,12 @@
 	}
 }
 
-uint32 Sword2Engine::restoreFromBuffer(Memory *buffer, uint32 size) {
-	uint8 *varsRes;
+uint32 Sword2Engine::restoreFromBuffer(byte *buffer, uint32 size) {
+	byte *varsRes;
 	int32 pars[2];
 
 	// get a copy of the header from the savegame buffer
-	memcpy(&_saveGameHeader, buffer->ad, sizeof(_saveGameHeader));
+	memcpy(&_saveGameHeader, buffer, sizeof(_saveGameHeader));
 
 #ifdef SCUMM_BIG_ENDIAN
 	convertHeaderEndian(_saveGameHeader);
@@ -308,8 +308,8 @@
 
 	// Calc checksum & check that aginst the value stored in the header
 
-	if (_saveGameHeader.checksum != calcChecksum(buffer->ad + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum))) {
-		_memory->freeMemory(buffer);
+	if (_saveGameHeader.checksum != calcChecksum(buffer + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum))) {
+		free(buffer);
 
 		// error: incompatible save-data - can't use!
 		return SR_ERR_INCOMPATIBLE;
@@ -324,7 +324,7 @@
 
 	// if header contradicts actual current size of global variables
 	if (_saveGameHeader.varLength != _resman->fetchLen(1)) {
-		_memory->freeMemory(buffer);
+		free(buffer);
 
 		// error: incompatible save-data - can't use!
 		return SR_ERR_INCOMPATIBLE;
@@ -355,7 +355,7 @@
 	varsRes = _resman->openResource(1);
 
 	// copy that to the buffer, following the header
-	memcpy(varsRes, buffer->ad + sizeof(_saveGameHeader), _saveGameHeader.varLength);
+	memcpy(varsRes, buffer + sizeof(_saveGameHeader), _saveGameHeader.varLength);
 
 #ifdef SCUMM_BIG_ENDIAN
 	uint32 *globalVars = (uint32 *) (varsRes + sizeof(StandardHeader));
@@ -370,7 +370,7 @@
 
 	// free it now, rather than in RestoreGame, to unblock memory before
 	// new screen & runlist loaded
-	_memory->freeMemory(buffer);
+	free(buffer);
 
 	pars[0] = _saveGameHeader.screenId;
 	pars[1] = 1;
@@ -428,7 +428,7 @@
 
 // GetSaveDescription - PC version...
 
-uint32 Sword2Engine::getSaveDescription(uint16 slotNo, uint8 *description) {
+uint32 Sword2Engine::getSaveDescription(uint16 slotNo, byte *description) {
 	char saveFileName[MAX_FILENAME_LEN];
 	SaveGameHeader dummy;
 	SaveFile *in;
@@ -547,7 +547,7 @@
 	_resman->closeResource(CUR_PLAYER_ID);
 }
 
-uint32 Sword2Engine::calcChecksum(uint8 *buffer, uint32 size) {
+uint32 Sword2Engine::calcChecksum(byte *buffer, uint32 size) {
 	uint32 total = 0;
 
 	for (uint32 pos = 0; pos < size; pos++)
@@ -569,9 +569,9 @@
 
 	// copy from player object to savegame header
 
-	memcpy(&_vm->_saveGameHeader.logic, _vm->_memory->intToPtr(params[0]), sizeof(ObjectLogic));
-	memcpy(&_vm->_saveGameHeader.graphic, _vm->_memory->intToPtr(params[1]), sizeof(ObjectGraphic));
-	memcpy(&_vm->_saveGameHeader.mega, _vm->_memory->intToPtr(params[2]), sizeof(ObjectMega));
+	memcpy(&_vm->_saveGameHeader.logic, _vm->_memory->decodePtr(params[0]), sizeof(ObjectLogic));
+	memcpy(&_vm->_saveGameHeader.graphic, _vm->_memory->decodePtr(params[1]), sizeof(ObjectGraphic));
+	memcpy(&_vm->_saveGameHeader.mega, _vm->_memory->decodePtr(params[2]), sizeof(ObjectMega));
 
 	// makes no odds
 	return IR_CONT;
@@ -585,17 +585,17 @@
 	//		1 pointer to object's graphic structure
 	//		2 pointer to object's mega structure
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
-	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[1]);
-	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
+	ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[1]);
+	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]);
 
 	int32 pars[3];
 
 	// copy from savegame header to player object
 
-	memcpy((uint8 *) ob_logic, &_vm->_saveGameHeader.logic, sizeof(ObjectLogic));
-	memcpy((uint8 *) ob_graphic, &_vm->_saveGameHeader.graphic, sizeof(ObjectGraphic));
-	memcpy((uint8 *) ob_mega, &_vm->_saveGameHeader.mega, sizeof(ObjectMega));
+	memcpy((byte *) ob_logic, &_vm->_saveGameHeader.logic, sizeof(ObjectLogic));
+	memcpy((byte *) ob_graphic, &_vm->_saveGameHeader.graphic, sizeof(ObjectGraphic));
+	memcpy((byte *) ob_mega, &_vm->_saveGameHeader.mega, sizeof(ObjectMega));
 
  	// any walk-data must be cleared - the player will be set to stand if
 	// he was walking when saved
@@ -606,10 +606,10 @@
 		ob_mega->currently_walking = 0;
 
 		// pointer to object's graphic structure
-		pars[0] = _vm->_memory->ptrToInt((const uint8 *) ob_graphic);
+		pars[0] = _vm->_memory->encodePtr((byte *) ob_graphic);
 
 		// pointer to object's mega structure
-		pars[1] = _vm->_memory->ptrToInt((const uint8 *) ob_mega);
+		pars[1] = _vm->_memory->encodePtr((byte *) ob_mega);
 
 		// target direction
 		pars[2] = ob_mega->current_dir;

Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/sound.cpp,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- sound.cpp	17 Mar 2004 09:03:15 -0000	1.41
+++ sound.cpp	23 Apr 2004 07:02:06 -0000	1.42
@@ -82,7 +82,7 @@
 // called from processFxQueue only
 
 void Sword2Engine::triggerFx(uint8 j) {
-	uint8 *data;
+	byte *data;
 	int32 id;
 	uint32 rv;
 
@@ -160,7 +160,7 @@
 	//		fnStopFx (fx_water);
 
 	uint8 j = 0;
-	uint8 *data;
+	byte *data;
 	uint32 id;
 	uint32 rv;
 

Index: speech.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/speech.cpp,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- speech.cpp	7 Apr 2004 14:18:27 -0000	1.60
+++ speech.cpp	23 Apr 2004 07:02:06 -0000	1.61
@@ -96,7 +96,7 @@
 	MouseEvent *me;
 	uint32 i;
 	int hit;
-	uint8 *icon;
+	byte *icon;
 
 	_scriptVars[AUTO_SELECTED] = 0;	// see below
 
@@ -367,7 +367,7 @@
 
 	_vm->_resman->closeResource(target);
 
-	ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	if (!_scriptVars[INS_COMMAND] && _scriptVars[RESULT] == 1 && ob_logic->looping == 0) {
 		// first time so set up targets command if target is waiting
@@ -476,7 +476,7 @@
 	StandardHeader *head;
 	int32 target = params[1];
 
-	ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	if (!ob_logic->looping)
 		ob_logic->looping = params[2];	// first time in
@@ -557,7 +557,7 @@
 	ObjectSpeech *ob_speech;
 	int32 pars[9];
 
-	ob_speech = (ObjectSpeech *) _vm->_memory->intToPtr(params[1]);
+	ob_speech = (ObjectSpeech *) _vm->_memory->decodePtr(params[1]);
 
 	debug(5, "  SP");
 
@@ -843,10 +843,10 @@
 	ObjectLogic *ob_logic;
 	ObjectGraphic *ob_graphic;
 	ObjectMega *ob_mega;
-	uint8 *anim_file;
+	byte *anim_file;
 	uint32 local_text;
 	uint32 text_res;
-	uint8 *text;
+	byte *text;
 	static bool speechRunning;
 	int32 *anim_table;
 	bool speechFinished = false;
@@ -860,8 +860,8 @@
 
 	// set up the pointers which we know we'll always need
 
-	ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[S_OB_LOGIC]);
-	ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[S_OB_GRAPHIC]);
+	ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[S_OB_LOGIC]);
+	ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[S_OB_GRAPHIC]);
 
 	// FIRST TIME ONLY: create the text, load the wav, set up the anim,
 	// etc.
@@ -918,7 +918,7 @@
 				if (head->fileType == TEXT_FILE) {
 					// if it's not an animation file
 					// if line number is out of range
-					if (!_vm->checkTextLine((uint8 *) head, local_text)) {
+					if (!_vm->checkTextLine((byte *) head, local_text)) {
 						// line number out of range
 						_scriptVars[RESULT] = 2;
 					}
@@ -1003,10 +1003,10 @@
 			// use this direction table to derive the anim
 			// NB. ASSUMES WE HAVE A MEGA OBJECT!!
 
-			ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[S_OB_MEGA]);
+			ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[S_OB_MEGA]);
 
 			// pointer to anim table
-			anim_table = (int32 *) _vm->_memory->intToPtr(params[S_DIR_TABLE]);
+			anim_table = (int32 *) _vm->_memory->decodePtr(params[S_DIR_TABLE]);
 
 			// appropriate anim resource is in 'table[direction]'
 			_animId = anim_table[ob_mega->current_dir];
@@ -1282,7 +1282,7 @@
 
 	ObjectMega *ob_mega;
 
-	uint8 *file;
+	byte *file;
 	FrameHeader *frame_head;
 	AnimHeader *anim_head;
 	CdtEntry *cdt_entry;
@@ -1313,7 +1313,7 @@
 
 		if (cdt_entry->frameType & FRAME_OFFSET) {
 			// this may be NULL
-			ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[S_OB_MEGA]);
+			ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[S_OB_MEGA]);
 
 			// calc scale at which to print the sprite, based on
 			// feet y-coord & scaling constants (NB. 'scale' is
@@ -1378,7 +1378,7 @@
 
 	uint32 local_text;
 	uint32 text_res;
-	uint8 *text;
+	byte *text;
 	uint32 textWidth;
 	ObjectSpeech *ob_speech;
 
@@ -1386,7 +1386,7 @@
 	// text
 
 	if (params[S_TEXT]) {
-	 	ob_speech = (ObjectSpeech *) _vm->_memory->intToPtr(params[S_OB_SPEECH]);
+	 	ob_speech = (ObjectSpeech *) _vm->_memory->decodePtr(params[S_OB_SPEECH]);
 
 		// establish the max width allowed for this text sprite
 

Index: startup.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/startup.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- startup.cpp	17 Mar 2004 09:03:15 -0000	1.40
+++ startup.cpp	23 Apr 2004 07:02:07 -0000	1.41
@@ -147,7 +147,7 @@
 		error("ERROR: _startList full");
 
 	// +1 to allow for NULL terminator
-	if (strlen((const char *) _vm->_memory->intToPtr(params[1])) + 1 > MAX_description)
+	if (strlen((const char *) _vm->_memory->decodePtr(params[1])) + 1 > MAX_description)
 		error("ERROR: startup description too long");
 #endif
 
@@ -158,7 +158,7 @@
 	// the correct start
 	_startList[_totalStartups].key = params[0];
 
-	strcpy(_startList[_totalStartups].description, (const char *) _vm->_memory->intToPtr(params[1]));
+	strcpy(_startList[_totalStartups].description, (const char *) _vm->_memory->decodePtr(params[1]));
 
 	// point to next
 	_totalStartups++;

Index: sword2.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/sword2.cpp,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -d -r1.109 -r1.110
--- sword2.cpp	29 Mar 2004 06:37:46 -0000	1.109
+++ sword2.cpp	23 Apr 2004 07:02:07 -0000	1.110
@@ -287,9 +287,6 @@
 
 	mouseEngine();
 	processFxQueue();
-
-	// update age and calculate previous cycle memory usage
-	_resman->nextCycle();
 }
 
 void Sword2Engine::go() {

Index: sword2.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/sword2.h,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- sword2.h	16 Apr 2004 06:46:03 -0000	1.56
+++ sword2.h	23 Apr 2004 07:02:08 -0000	1.57
@@ -107,22 +107,22 @@
 	void drawBackPar0Frames(void);
 	void drawBackPar1Frames(void);
 	void drawBackFrames(void);
-	void drawSortFrames(uint8 *file);
+	void drawSortFrames(byte *file);
 	void drawForeFrames(void);
 	void drawForePar0Frames(void);
 	void drawForePar1Frames(void);
 
 	void startNewPalette(void);
-	void processLayer(uint8 *file, uint32 layer_number);
+	void processLayer(byte *file, uint32 layer_number);
 	void processImage(BuildUnit *build_unit);
 
 	void getPlayerStructures(void);
 	void putPlayerStructures(void);
 
-	uint32 saveData(uint16 slotNo, uint8 *buffer, uint32 bufferSize);
-	uint32 restoreData(uint16 slotNo, uint8 *buffer, uint32 bufferSize);
+	uint32 saveData(uint16 slotNo, byte *buffer, uint32 bufferSize);
+	uint32 restoreData(uint16 slotNo, byte *buffer, uint32 bufferSize);
 
-	uint32 calcChecksum(uint8 *buffer, uint32 size);
+	uint32 calcChecksum(byte *buffer, uint32 size);
 
 	void pauseGame(void);
 	void unpauseGame(void);
@@ -163,7 +163,7 @@
 
 	void resetRenderLists(void);
 	void buildDisplay(void);
-	void displayMsg(uint8 *text, int time);
+	void displayMsg(byte *text, int time);
 	void removeMsg(void);
 	void setFullPalette(int32 palRes);
 
@@ -261,21 +261,21 @@
 
 	void registerMouse(ObjectMouse *ob_mouse);
 
-	uint8 *fetchPalette(uint8 *screenFile);
-	ScreenHeader *fetchScreenHeader(uint8 *screenFile);
-	LayerHeader *fetchLayerHeader(uint8 *screenFile, uint16 layerNo);
-	uint8 *fetchShadingMask(uint8 *screenFile);
+	byte *fetchPalette(byte *screenFile);
+	ScreenHeader *fetchScreenHeader(byte *screenFile);
+	LayerHeader *fetchLayerHeader(byte *screenFile, uint16 layerNo);
+	byte *fetchShadingMask(byte *screenFile);
 
-	AnimHeader *fetchAnimHeader(uint8 *animFile);
-	CdtEntry *fetchCdtEntry(uint8 *animFile, uint16 frameNo);
-	FrameHeader *fetchFrameHeader(uint8 *animFile, uint16 frameNo);
-	Parallax *fetchBackgroundParallaxLayer(uint8 *screenFile, int layer);
-	Parallax *fetchBackgroundLayer(uint8 *screenFile);
-	Parallax *fetchForegroundParallaxLayer(uint8 *screenFile, int layer);
-	uint8 *fetchTextLine(uint8 *file, uint32 text_line);
-	bool checkTextLine(uint8 *file, uint32 text_line);
-	uint8 *fetchPaletteMatchTable(uint8 *screenFile);
-	uint8 *fetchObjectName(int32 resourceId);
+	AnimHeader *fetchAnimHeader(byte *animFile);
+	CdtEntry *fetchCdtEntry(byte *animFile, uint16 frameNo);
+	FrameHeader *fetchFrameHeader(byte *animFile, uint16 frameNo);
+	Parallax *fetchBackgroundParallaxLayer(byte *screenFile, int layer);
+	Parallax *fetchBackgroundLayer(byte *screenFile);
+	Parallax *fetchForegroundParallaxLayer(byte *screenFile, int layer);
+	byte *fetchTextLine(byte *file, uint32 text_line);
+	bool checkTextLine(byte *file, uint32 text_line);
+	byte *fetchPaletteMatchTable(byte *screenFile);
+	byte *fetchObjectName(int32 resourceId);
 
 	// savegame file header
 
@@ -304,13 +304,13 @@
 
 	SaveGameHeader _saveGameHeader;
 
-	uint32 saveGame(uint16 slotNo, uint8 *description);
+	uint32 saveGame(uint16 slotNo, byte *description);
 	uint32 restoreGame(uint16 slotNo);
-	uint32 getSaveDescription(uint16 slotNo, uint8 *description);
+	uint32 getSaveDescription(uint16 slotNo, byte *description);
 	bool saveExists(void);
 	bool saveExists(uint16 slotNo);
-	void fillSaveBuffer(Memory *buffer, uint32 size, uint8 *desc);
-	uint32 restoreFromBuffer(Memory *buffer, uint32 size);
+	void fillSaveBuffer(byte *buffer, uint32 size, byte *desc);
+	uint32 restoreFromBuffer(byte *buffer, uint32 size);
 	uint32 findBufferSize(void);
 
 	uint8 _scrollFraction;

Index: walker.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/walker.cpp,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- walker.cpp	16 Apr 2004 06:46:03 -0000	1.37
+++ walker.cpp	23 Apr 2004 07:02:08 -0000	1.38
@@ -46,9 +46,9 @@
 	//		5 target y-coord
 	//		6 target direction (8 means end walk on ANY direction)
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
-	ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->intToPtr(params[1]);
-	ObjectMega *ob_mega  = (ObjectMega *) _vm->_memory->intToPtr(params[2]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
+	ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->decodePtr(params[1]);
+	ObjectMega *ob_mega  = (ObjectMega *) _vm->_memory->decodePtr(params[2]);
 
 	int16 target_x = (int16) params[4];
 	int16 target_y = (int16) params[5];
@@ -74,7 +74,7 @@
 
 		assert(params[6] >= 0 && params[6] <= 8);
 
-		ob_walkdata = (ObjectWalkdata *) _vm->_memory->intToPtr(params[3]);
+		ob_walkdata = (ObjectWalkdata *) _vm->_memory->decodePtr(params[3]);
 
 		ob_mega->walk_pc = 0;
 
@@ -134,7 +134,7 @@
 
 	// get pointer to walkanim & current frame position
 
-	WalkData *walkAnim = _router->lockRouteMem();
+	WalkData *walkAnim = _router->getRouteMem();
 	int32 walk_pc = ob_mega->walk_pc;
 
 	// If stopping the walk early, overwrite the next step with a
@@ -143,7 +143,7 @@
 	if (checkEventWaiting()) {
 		if (walkAnim[walk_pc].step == 0 && walkAnim[walk_pc + 1].step == 1) {
 			// At the beginning of a step
-			ob_walkdata = (ObjectWalkdata *) _vm->_memory->intToPtr(params[3]);
+			ob_walkdata = (ObjectWalkdata *) _vm->_memory->decodePtr(params[3]);
 			_router->earlySlowOut(ob_mega, ob_walkdata);
 		}
 	}
@@ -198,12 +198,9 @@
 		}
 	}
 
-	// Increment the walkanim frame number, float the walkanim & come
-	// back next cycle
+	// Increment the walkanim frame number and come back next cycle
 
 	ob_mega->walk_pc++;
-
-	_router->floatRouteMem();
 	return IR_REPEAT;
 }
 
@@ -228,12 +225,12 @@
 	pars[2] = params[2];
 	pars[3] = params[3];
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	// If this is the start of the walk, read anim file to get start coords
 
 	if (!ob_logic->looping) {
-		uint8 *anim_file = _vm->_resman->openResource(params[4]);
+		byte *anim_file = _vm->_resman->openResource(params[4]);
 		AnimHeader *anim_head = _vm->fetchAnimHeader( anim_file );
 
 		pars[4] = anim_head->feetStartX;
@@ -278,7 +275,7 @@
 	pars[2] = params[2];
 	pars[3] = params[3];
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	// If this is the start of the turn, get the mega's current feet
 	// coords + the required direction
@@ -286,7 +283,7 @@
 	if (!ob_logic->looping) {
 		assert(params[4] >= 0 && params[4] <= 7);
 
-		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]);
+		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]);
 
 		pars[4] = ob_mega->feet_x;
 		pars[5] = ob_mega->feet_y;
@@ -311,8 +308,8 @@
 
 	assert(params[4] >= 0 && params[4] <= 7);
 
-	ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->intToPtr(params[0]);
-	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[1]);
+	ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->decodePtr(params[0]);
+	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[1]);
 
 	// set up the stand frame & set the mega's new direction
 
@@ -339,7 +336,7 @@
 	//		1 pointer to object's mega structure
 	//		2 target direction
 
-	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[1]);
+	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[1]);
 
 	int32 pars[5];
 
@@ -361,7 +358,7 @@
 	//		1 pointer to object's mega structure
 	//		2 anim resource id
 
-	uint8 *anim_file = _vm->_resman->openResource(params[2]);
+	byte *anim_file = _vm->_resman->openResource(params[2]);
 	AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file);
 
 	int32 pars[5];
@@ -399,7 +396,7 @@
 	//		1 pointer to object's mega structure
 	//		2 anim resource id
 
-	uint8 *anim_file = _vm->_resman->openResource(params[2]);
+	byte *anim_file = _vm->_resman->openResource(params[2]);
 	AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file);
 
 	int32 pars[5];
@@ -483,13 +480,13 @@
 	pars[2] = params[2];
 	pars[3] = params[3];
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	// If this is the start of the turn, get the mega's current feet
 	// coords + the required direction
 
 	if (!ob_logic->looping) {
-		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]);
+		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]);
 	
 		pars[4] = ob_mega->feet_x;
 		pars[5] = ob_mega->feet_y;
@@ -513,7 +510,7 @@
 	pars[2] = params[2];
 	pars[3] = params[3];
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	// If this is the start of the walk, decide where to walk to.
 
@@ -533,7 +530,7 @@
 
 		_vm->_resman->closeResource(params[4]);
 
-		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]);
+		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]);
 
 		pars[3] = params[3];
 		pars[4] = ob_mega->feet_x;
@@ -563,7 +560,7 @@
 	pars[2] = params[2];
 	pars[3] = params[3];
 
-	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]);
+	ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]);
 
 	// If this is the start of the walk, calculate the route.
 
@@ -586,7 +583,7 @@
 		// Stand exactly beside the mega, ie. at same y-coord
 		pars[5] = _engineMega.feet_y;
 
-		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]);
+		ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]);
 
 		// Apply scale factor to walk distance. Ay+B gives 256 * scale
 		// ie. 256 * 256 * true_scale for even better accuracy, ie.
@@ -674,7 +671,7 @@
 	// Where s is system scale, which itself is (256 * actual_scale) ie.
 	// s == 128 is half size
 
- 	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[0]);
+ 	ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[0]);
 
 	ob_mega->scale_a = params[1];
 	ob_mega->scale_b = params[2];

--- mem_view.cpp DELETED ---





More information about the Scummvm-git-logs mailing list