[Scummvm-cvs-logs] CVS: scummvm/sword2 anims.cpp,1.73,1.74 build_display.cpp,1.78,1.79 build_display.h,1.21,1.22 console.cpp,1.58,1.59 console.h,1.27,1.28 controls.cpp,1.96,1.97 debug.cpp,1.52,1.53 events.cpp,1.38,1.39 function.cpp,1.89,1.90 header.h,1.14,1.15 icons.cpp,1.46,1.47 icons.h,1.15,1.16 interpreter.cpp,1.57,1.58 interpreter.h,1.18,1.19 layers.cpp,1.39,1.40 logic.cpp,1.57,1.58 logic.h,1.48,1.49 maketext.cpp,1.51,1.52 maketext.h,1.19,1.20 mouse.cpp,1.76,1.77 mouse.h,1.22,1.23 object.h,1.11,1.12 protocol.cpp,1.33,1.34 resman.cpp,1.116,1.117 resman.h,1.28,1.29 router.cpp,1.50,1.51 router.h,1.23,1.24 save_rest.cpp,1.75,1.76 scroll.cpp,1.24,1.25 sound.cpp,1.63,1.64 speech.cpp,1.77,1.78 startup.cpp,1.52,1.53 sword2.cpp,1.151,1.152 sword2.h,1.83,1.84 sync.cpp,1.26,1.27 walker.cpp,1.50,1.51

Torbjörn Andersson eriktorbjorn at users.sourceforge.net
Sat Oct 29 14:26:50 CEST 2005


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

Modified Files:
	anims.cpp build_display.cpp build_display.h console.cpp 
	console.h controls.cpp debug.cpp events.cpp function.cpp 
	header.h icons.cpp icons.h interpreter.cpp interpreter.h 
	layers.cpp logic.cpp logic.h maketext.cpp maketext.h mouse.cpp 
	mouse.h object.h protocol.cpp resman.cpp resman.h router.cpp 
	router.h save_rest.cpp scroll.cpp sound.cpp speech.cpp 
	startup.cpp sword2.cpp sword2.h sync.cpp walker.cpp 
Log Message:
Applied my own patch #1341495, in an attempt to fix alignment issues
reported by Crilith.

To elaborate a bit, the engine no longer accesses resource data through
packed structs. Instead it uses memory streams and the READ/WRITE
functions.

If data is mainly read, not written, I have replaced the old struct with a
new one with a read() function to read the whole thing from memory into the
struct's variables, and a write() function to dump the struct's variables
to memory. In fact, most of these write() functions remain unused.

If data is both read and written, I have replaced the struct with a class
with individual get/set functions to replace the old variables. This
manipulates memory directly.

Since I'm fairly sure that these structs are frequently stored as local
variables for a script, all script variables (both local and global) are
stored as little-endian and accessed through the READ/WRITE functions,
rather than being treated as arrays of 32-bit integers.

On a positive note, the functions for doing endian conversion of resources
and save games have been removed, and some general cleanups have been made
to assist in the rewrite.

Initial reports indicate that this patch indeed fixes alignment issues, and
that I have not - surprisingly - broken the game on big-endian platforms.
At least not in any immediately obvious way. And there's still plenty of
time to fix regressions before 0.9.0, too.


Index: anims.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/anims.cpp,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- anims.cpp	18 Oct 2005 01:30:25 -0000	1.73
+++ anims.cpp	29 Oct 2005 21:24:53 -0000	1.74
@@ -40,12 +40,15 @@
 
 namespace Sword2 {
 
-int Router::doAnimate(ObjectLogic *ob_logic, ObjectGraphic *ob_graphic, int32 animRes, bool reverse) {
+int Router::doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool reverse) {
+	AnimHeader anim_head;
 	byte *anim_file;
-	AnimHeader *anim_head;
 
-	if (ob_logic->looping == 0) {
-		StandardHeader *head;
+	ObjectLogic obLogic(ob_logic);
+	ObjectGraphic obGraph(ob_graph);
+
+	if (obLogic.getLooping() == 0) {
+		byte *ptr;
 
 		// This is the start of the anim - set up the first frame
 
@@ -55,32 +58,32 @@
 		// 'testing_routines' object in George's Player Character
 		// section of linc
 
-		if (Logic::_scriptVars[SYSTEM_TESTING_ANIMS]) {
+		if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
 			if (!_vm->_resman->checkValid(animRes)) {
 				// Not a valid resource number. Switch off
 				// the sprite. Don't animate - just continue
 				// script next cycle.
-				setSpriteStatus(ob_graphic, NO_SPRITE);
+				setSpriteStatus(ob_graph, NO_SPRITE);
 				return IR_STOP;
 			}
 
-			head = (StandardHeader *)_vm->_resman->openResource(animRes);
+			ptr = _vm->_resman->openResource(animRes);
 
 			// if it's not an animation file
-			if (head->fileType != ANIMATION_FILE) {
+			if (_vm->_resman->fetchType(animRes) != ANIMATION_FILE) {
 				_vm->_resman->closeResource(animRes);
 
 				// switch off the sprite
 				// don't animate - just continue
 				// script next cycle
-				setSpriteStatus(ob_graphic, NO_SPRITE);
+				setSpriteStatus(ob_graph, NO_SPRITE);
 				return IR_STOP;
 			}
 
 			_vm->_resman->closeResource(animRes);
 
 			// switch on the sprite
-			setSpriteStatus(ob_graphic, SORT_SPRITE);
+			setSpriteStatus(ob_graph, SORT_SPRITE);
 		}
 
 		assert(animRes);
@@ -88,88 +91,94 @@
 		// open anim file
 		anim_file = _vm->_resman->openResource(animRes);
 
-		head = (StandardHeader *)anim_file;
-		assert(head->fileType == ANIMATION_FILE);
+		assert(_vm->_resman->fetchType(animRes) == ANIMATION_FILE);
 
 		// point to anim header
-		anim_head = _vm->fetchAnimHeader(anim_file);
+		anim_head.read(_vm->fetchAnimHeader(anim_file));
 
 		// now running an anim, looping back to this call again
-		ob_logic->looping = 1;
-		ob_graphic->anim_resource = animRes;
+		obLogic.setLooping(1);
+		obGraph.setAnimResource(animRes);
 
 		if (reverse)
-			ob_graphic->anim_pc = anim_head->noAnimFrames - 1;
+			obGraph.setAnimPc(anim_head.noAnimFrames - 1);
 		else
-			ob_graphic->anim_pc = 0;
+			obGraph.setAnimPc(0);
 	} else if (_vm->_logic->getSync() != -1) {
 		// We've received a sync - return to script immediately
-		debug(5, "**sync stopped %d**", Logic::_scriptVars[ID]);
+		debug(5, "**sync stopped %d**", _vm->_logic->readVar(ID));
 
 		// If sync received, anim finishes right now (remaining on
 		// last frame). Quit animation, but continue script.
-		ob_logic->looping = 0;
+		obLogic.setLooping(0);
 		return IR_CONT;
 	} else {
 		// Not first frame, and no sync received - set up the next
 		// frame of the anim.
 
 		// open anim file and point to anim header
-		anim_file = _vm->_resman->openResource(ob_graphic->anim_resource);
-		anim_head = _vm->fetchAnimHeader(anim_file);
+		anim_file = _vm->_resman->openResource(obGraph.getAnimResource());
+		anim_head.read(_vm->fetchAnimHeader(anim_file));
 
 		if (reverse)
-			ob_graphic->anim_pc--;
+			obGraph.setAnimPc(obGraph.getAnimPc() - 1);
 		else
-			ob_graphic->anim_pc++;
+			obGraph.setAnimPc(obGraph.getAnimPc() + 1);
 	}
 
 	// check for end of anim
 
 	if (reverse) {
-		if (ob_graphic->anim_pc == 0)
-			ob_logic->looping = 0;
+		if (obGraph.getAnimPc() == 0)
+			obLogic.setLooping(0);
 	} else {
-		if (ob_graphic->anim_pc == anim_head->noAnimFrames - 1)
-			ob_logic->looping = 0;
+		if (obGraph.getAnimPc() == anim_head.noAnimFrames - 1)
+			obLogic.setLooping(0);
 	}
 
 	// close the anim file
-	_vm->_resman->closeResource(ob_graphic->anim_resource);
+	_vm->_resman->closeResource(obGraph.getAnimResource());
 
 	// check if we want the script to loop back & call this function again
-	return ob_logic->looping ? IR_REPEAT : IR_STOP;
+	return obLogic.getLooping() ? IR_REPEAT : IR_STOP;
 }
 
-int Router::megaTableAnimate(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, uint32 *animTable, bool reverse) {
+int Router::megaTableAnimate(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *animTable, bool reverse) {
 	int32 animRes = 0;
 
 	// If this is the start of the anim, read the anim table to get the
 	// appropriate anim resource
 
-	if (ob_logic->looping == 0) {
+	ObjectLogic obLogic(ob_logic);
+
+	if (obLogic.getLooping() == 0) {
+		ObjectMega obMega(ob_mega);
+
 		// Appropriate anim resource is in 'table[direction]'
-		animRes = animTable[ob_mega->current_dir];
+		animRes = READ_LE_UINT32(animTable + 4 * obMega.getCurDir());
 	}
 
 	return doAnimate(ob_logic, ob_graph, animRes, reverse);
 }
 
-void Router::setSpriteStatus(ObjectGraphic *ob_graph, uint32 type) {
+void Router::setSpriteStatus(byte *ob_graph, uint32 type) {
+	ObjectGraphic obGraph(ob_graph);
+
 	// Remove the previous status, but don't affect the shading upper-word
-	ob_graph->type = (ob_graph->type & 0xffff0000) | type;
+	obGraph.setType((obGraph.getType() & 0xffff0000) | type);
 }
 
-void Router::setSpriteShading(ObjectGraphic *ob_graph, uint32 type) {
+void Router::setSpriteShading(byte *ob_graph, uint32 type) {
+	ObjectGraphic obGraph(ob_graph);
+
 	// Remove the previous shading, but don't affect the status lower-word.
 	// Note that mega frames may still be shaded automatically, even when
 	// not sent 'RDSPR_SHADOW'.
-	ob_graph->type = (ob_graph->type & 0x0000ffff) | type;
+	obGraph.setType((obGraph.getType() & 0x0000ffff) | type);
 }
 
 void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) {
 	uint32 line;
- 	FrameHeader *frame;
  	uint32 local_text;
 	uint32 text_res;
 	byte *text;
@@ -192,7 +201,7 @@
 
 		// open text resource & get the line
 		text = _vm->fetchTextLine(_vm->_resman->openResource(text_res), local_text);
-		wavId = (int32) READ_LE_UINT16(text);
+		wavId = (int32)READ_LE_UINT16(text);
 
 		// now ok to close the text file
 		_vm->_resman->closeResource(text_res);
@@ -250,18 +259,19 @@
 		if (_sequenceTextList[line].text_mem) {
 			// now fill out the SpriteInfo structure in the
 			// MovieTextObjectStructure
+			FrameHeader frame;
 
-			frame = (FrameHeader *)_sequenceTextList[line].text_mem;
+			frame.read(_sequenceTextList[line].text_mem);
 
 			sequenceText[line]->textSprite = new SpriteInfo;
 
 			// center text at bottom of screen
-			sequenceText[line]->textSprite->x = 320 - frame->width / 2;
-			sequenceText[line]->textSprite->y = 440 - frame->height;
-			sequenceText[line]->textSprite->w = frame->width;
-			sequenceText[line]->textSprite->h = frame->height;
+			sequenceText[line]->textSprite->x = 320 - frame.width / 2;
+			sequenceText[line]->textSprite->y = 440 - frame.height;
+			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 + sizeof(FrameHeader);
+			sequenceText[line]->textSprite->data = _sequenceTextList[line].text_mem + FrameHeader::size();
 		}
 
 		// if we've loaded a speech sample for this line...

Index: build_display.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/build_display.cpp,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- build_display.cpp	18 Oct 2005 01:30:25 -0000	1.78
+++ build_display.cpp	29 Oct 2005 21:24:53 -0000	1.79
@@ -116,7 +116,10 @@
 	startRenderCycle();
 
 	byte *file = _vm->_resman->openResource(_thisScreen.background_layer_id);
-	MultiScreenHeader *screenLayerTable = (MultiScreenHeader *)(file + sizeof(StandardHeader));
+
+	MultiScreenHeader screenLayerTable;
+
+	screenLayerTable.read(file + ResHeader::size());
 
 	// Render at least one frame, but if the screen is scrolling, and if
 	// there is time left, we will render extra frames to smooth out the
@@ -124,13 +127,13 @@
 
 	do {
 		// first background parallax + related anims
-		if (screenLayerTable->bg_parallax[0]) {
+		if (screenLayerTable.bg_parallax[0]) {
 			renderParallax(_vm->fetchBackgroundParallaxLayer(file, 0), 0);
 			drawBackPar0Frames();
 		}
 
 		// second background parallax + related anims
-		if (screenLayerTable->bg_parallax[1]) {
+		if (screenLayerTable.bg_parallax[1]) {
 			renderParallax(_vm->fetchBackgroundParallaxLayer(file, 1), 1);
 			drawBackPar1Frames();
 		}
@@ -145,14 +148,14 @@
 
 		// first foreground parallax + related anims
 
-		if (screenLayerTable->fg_parallax[0]) {
+		if (screenLayerTable.fg_parallax[0]) {
 			renderParallax(_vm->fetchForegroundParallaxLayer(file, 0), 3);
 			drawForePar0Frames();
 		}
 
 		// second foreground parallax + related anims
 
-		if (screenLayerTable->fg_parallax[1]) {
+		if (screenLayerTable.fg_parallax[1]) {
 			renderParallax(_vm->fetchForegroundParallaxLayer(file, 1), 4);
 			drawForePar1Frames();
 		}
@@ -199,23 +202,26 @@
 	clearScene();
 
 	byte *text_spr = _vm->_fontRenderer->makeTextSprite(text, 640, 187, _vm->_speechFontId);
-	FrameHeader *frame = (FrameHeader *)text_spr;
+
+	FrameHeader frame;
+
+	frame.read(text_spr);
 
 	SpriteInfo spriteInfo;
 
-	spriteInfo.x = _screenWide / 2 - frame->width / 2;
+	spriteInfo.x = _screenWide / 2 - frame.width / 2;
 	if (!time)
-		spriteInfo.y = _screenDeep / 2 - frame->height / 2 - MENUDEEP;
+		spriteInfo.y = _screenDeep / 2 - frame.height / 2 - MENUDEEP;
 	else
-		spriteInfo.y = 400 - frame->height;
-	spriteInfo.w = frame->width;
-	spriteInfo.h = frame->height;
+		spriteInfo.y = 400 - frame.height;
+	spriteInfo.w = frame.width;
+	spriteInfo.h = frame.height;
 	spriteInfo.scale = 0;
 	spriteInfo.scaledWidth = 0;
 	spriteInfo.scaledHeight	= 0;
 	spriteInfo.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION | RDSPR_TRANS;
 	spriteInfo.blend = 0;
-	spriteInfo.data = text_spr + sizeof(FrameHeader);
+	spriteInfo.data = text_spr + FrameHeader::size();
 	spriteInfo.colourTable = 0;
 
 	uint32 rv = drawSprite(&spriteInfo);
@@ -326,25 +332,27 @@
 }
 
 void Screen::processLayer(byte *file, uint32 layer_number) {
-	LayerHeader *layer_head = _vm->fetchLayerHeader(file, layer_number);
+	LayerHeader layer_head;
+
+	layer_head.read(_vm->fetchLayerHeader(file, layer_number));
 
  	SpriteInfo spriteInfo;
 
-	spriteInfo.x = layer_head->x;
-	spriteInfo.y = layer_head->y;
-	spriteInfo.w = layer_head->width;
+	spriteInfo.x = layer_head.x;
+	spriteInfo.y = layer_head.y;
+	spriteInfo.w = layer_head.width;
 	spriteInfo.scale = 0;
 	spriteInfo.scaledWidth = 0;
 	spriteInfo.scaledHeight = 0;
-	spriteInfo.h = layer_head->height;
+	spriteInfo.h = layer_head.height;
 	spriteInfo.type = RDSPR_TRANS | RDSPR_RLE256FAST;
 	spriteInfo.blend = 0;
-	spriteInfo.data = file + sizeof(StandardHeader) + layer_head->offset;
+	spriteInfo.data = file + ResHeader::size() + layer_head.offset;
 	spriteInfo.colourTable = 0;
 
 	// check for largest layer for debug info
 
-	uint32 current_layer_area = layer_head->width * layer_head->height;
+	uint32 current_layer_area = layer_head.width * layer_head.height;
 
 	if (current_layer_area > _largestLayerArea) {
 		byte buf[NAME_LEN];
@@ -352,8 +360,8 @@
 		_largestLayerArea = current_layer_area;
 		sprintf(_largestLayerInfo,
 			"largest layer:  %s layer(%d) is %dx%d",
-			_vm->fetchObjectName(_thisScreen.background_layer_id, buf),
-			layer_number, layer_head->width, layer_head->height);
+			_vm->_resman->fetchName(_thisScreen.background_layer_id, buf),
+			layer_number, layer_head.width, layer_head.height);
 	}
 
 	uint32 rv = drawSprite(&spriteInfo);
@@ -365,22 +373,28 @@
 	byte *file = _vm->_resman->openResource(build_unit->anim_resource);
 	byte *colTablePtr = NULL;
 
-	AnimHeader *anim_head = _vm->fetchAnimHeader(file);
-	CdtEntry *cdt_entry = _vm->fetchCdtEntry(file, build_unit->anim_pc);
-	FrameHeader *frame_head = _vm->fetchFrameHeader(file, build_unit->anim_pc);
+	byte *frame = _vm->fetchFrameHeader(file, build_unit->anim_pc);
+
+	AnimHeader anim_head;
+	CdtEntry cdt_entry;
+	FrameHeader frame_head;
+
+	anim_head.read(_vm->fetchAnimHeader(file));
+	cdt_entry.read(_vm->fetchCdtEntry(file, build_unit->anim_pc));
+	frame_head.read(frame);
 
 	// so that 0-colour is transparent
 	uint32 spriteType = RDSPR_TRANS;
 
-	if (anim_head->blend)
+	if (anim_head.blend)
 		spriteType |= RDSPR_BLEND;
 
 	// if the frame is to be flipped (only really applicable to frames
 	// using offsets)
-	if (cdt_entry->frameType & FRAME_FLIPPED)
+	if (cdt_entry.frameType & FRAME_FLIPPED)
 		spriteType |= RDSPR_FLIP;
 
-	if (cdt_entry->frameType & FRAME_256_FAST) {
+	if (cdt_entry.frameType & FRAME_256_FAST) {
 		// scaling, shading & blending don't work with RLE256FAST
 		// but the same compression can be decompressed using the
 		// RLE256 routines!
@@ -388,12 +402,12 @@
 		// NOTE: If this restriction refers to drawSprite(), I don't
 		// think we have it any more. But I'm not sure.
 
-		if (build_unit->scale || anim_head->blend || build_unit->shadingFlag)
+		if (build_unit->scale || anim_head.blend || build_unit->shadingFlag)
 			spriteType |= RDSPR_RLE256;
 		else
 			spriteType |= RDSPR_RLE256FAST;
 	} else {
-		switch (anim_head->runTimeComp) {
+		switch (anim_head.runTimeComp) {
 		case NONE:
 			spriteType |= RDSPR_NOCOMPRESSION;
 			break;
@@ -404,7 +418,7 @@
 			spriteType |= RDSPR_RLE16;
 			// points to just after last cdt_entry, ie.
 			// start of colour table
-			colTablePtr = (byte *)(anim_head + 1) + anim_head->noAnimFrames * sizeof(CdtEntry);
+			colTablePtr = _vm->fetchAnimHeader(file) + AnimHeader::size() + anim_head.noAnimFrames * CdtEntry::size();
 			break;
 		}
 	}
@@ -418,19 +432,19 @@
 
 	spriteInfo.x = build_unit->x;
 	spriteInfo.y = build_unit->y;
-	spriteInfo.w = frame_head->width;
-	spriteInfo.h = frame_head->height;
+	spriteInfo.w = frame_head.width;
+	spriteInfo.h = frame_head.height;
 	spriteInfo.scale = build_unit->scale;
 	spriteInfo.scaledWidth = build_unit->scaled_width;
 	spriteInfo.scaledHeight	= build_unit->scaled_height;
 	spriteInfo.type = spriteType;
-	spriteInfo.blend = anim_head->blend;
+	spriteInfo.blend = anim_head.blend;
 	// points to just after frame header, ie. start of sprite data
-	spriteInfo.data = (byte *)(frame_head + 1);
-	spriteInfo.colourTable	= colTablePtr;
+	spriteInfo.data = frame + FrameHeader::size();
+	spriteInfo.colourTable = colTablePtr;
 
 	// check for largest layer for debug info
-	uint32 current_sprite_area = frame_head->width * frame_head->height;
+	uint32 current_sprite_area = frame_head.width * frame_head.height;
 
 	if (current_sprite_area > _largestSpriteArea) {
 		byte buf[NAME_LEN];
@@ -438,13 +452,13 @@
 		_largestSpriteArea = current_sprite_area;
 		sprintf(_largestSpriteInfo,
 			"largest sprite: %s frame(%d) is %dx%d",
-			_vm->fetchObjectName(build_unit->anim_resource, buf),
+			_vm->_resman->fetchName(build_unit->anim_resource, buf),
 			build_unit->anim_pc,
-			frame_head->width,
-			frame_head->height);
+			frame_head.width,
+			frame_head.height);
 	}
 
-	if (Logic::_scriptVars[SYSTEM_TESTING_ANIMS]) { // see anims.cpp
+	if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) { // see anims.cpp
 		// bring the anim into the visible screen
 		// but leave extra pixel at edge for box
 		if (spriteInfo.x + spriteInfo.scaledWidth >= 639)
@@ -472,7 +486,7 @@
 
 		error("Driver Error %.8x with sprite %s (%d) in processImage",
 			rv,
-			_vm->fetchObjectName(build_unit->anim_resource, buf),
+			_vm->_resman->fetchName(build_unit->anim_resource, buf),
 			build_unit->anim_resource);
 	}
 
@@ -501,32 +515,39 @@
 	}
 }
 
-void Screen::registerFrame(ObjectMouse *ob_mouse, ObjectGraphic *ob_graph, ObjectMega *ob_mega, BuildUnit *build_unit) {
-	assert(ob_graph->anim_resource);
+void Screen::registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega, BuildUnit *build_unit) {
+	ObjectGraphic obGraph(ob_graph);
+	ObjectMega obMega(ob_mega);
 
-	byte *file = _vm->_resman->openResource(ob_graph->anim_resource);
+	assert(obGraph.getAnimResource());
 
-	AnimHeader *anim_head = _vm->fetchAnimHeader(file);
-	CdtEntry *cdt_entry = _vm->fetchCdtEntry(file, ob_graph->anim_pc);
-	FrameHeader *frame_head = _vm->fetchFrameHeader(file, ob_graph->anim_pc);
+	byte *file = _vm->_resman->openResource(obGraph.getAnimResource());
+
+	AnimHeader anim_head;
+	CdtEntry cdt_entry;
+	FrameHeader frame_head;
+
+	anim_head.read(_vm->fetchAnimHeader(file));
+	cdt_entry.read(_vm->fetchCdtEntry(file, obGraph.getAnimPc()));
+	frame_head.read(_vm->fetchFrameHeader(file, obGraph.getAnimPc()));
 
 	// update player graphic details for on-screen debug info
-	if (Logic::_scriptVars[ID] == CUR_PLAYER_ID) {
-		_vm->_debugger->_playerGraphic.type = ob_graph->type;
-		_vm->_debugger->_playerGraphic.anim_resource = ob_graph->anim_resource;
+	if (_vm->_logic->readVar(ID) == CUR_PLAYER_ID) {
+		_vm->_debugger->_graphType = obGraph.getType();
+		_vm->_debugger->_graphAnimRes = obGraph.getAnimResource();
 		// counting 1st frame as 'frame 1'
-		_vm->_debugger->_playerGraphic.anim_pc = ob_graph->anim_pc + 1;
-		_vm->_debugger->_playerGraphicNoFrames = anim_head->noAnimFrames;
+		_vm->_debugger->_graphAnimPc = obGraph.getAnimPc() + 1;
+		_vm->_debugger->_graphNoFrames = anim_head.noAnimFrames;
 	}
 
 	// fill in the BuildUnit structure for this frame
 
- 	build_unit->anim_resource = ob_graph->anim_resource;
-	build_unit->anim_pc = ob_graph->anim_pc;
+ 	build_unit->anim_resource = obGraph.getAnimResource();
+	build_unit->anim_pc = obGraph.getAnimPc();
 	build_unit->layer_number = 0;
 
 	// Affected by shading mask?
-	if (ob_graph->type & SHADED_SPRITE)
+	if (obGraph.getType() & SHADED_SPRITE)
 		build_unit->shadingFlag = true;
 	else
 		build_unit->shadingFlag = false;
@@ -535,34 +556,28 @@
 
 	int scale = 0;
 
-	if (cdt_entry->frameType & FRAME_OFFSET) {
-		// Calc scale at which to print the sprite, based on feet
-		// y-coord & scaling constants (NB. 'scale' is actually
-		// 256 * true_scale, to maintain accuracy)
-
-		// Ay+B gives 256 * scale ie. 256 * 256 * true_scale for even
-		// better accuracy, ie. scale = (Ay + B) / 256
-		scale = (ob_mega->scale_a * ob_mega->feet_y + ob_mega->scale_b) / 256;
+	if (cdt_entry.frameType & FRAME_OFFSET) {
+		scale = obMega.calcScale();
 
 		// calc final render coordinates (top-left of sprite), based
 		// on feet coords & scaled offsets
 
 		// add scaled offsets to feet coords
-		build_unit->x = ob_mega->feet_x + (cdt_entry->x * scale) / 256;
-		build_unit->y = ob_mega->feet_y + (cdt_entry->y * scale) / 256;
+		build_unit->x = obMega.getFeetX() + (cdt_entry.x * scale) / 256;
+		build_unit->y = obMega.getFeetY() + (cdt_entry.y * scale) / 256;
 
 		// Work out new width and height. Always divide by 256 after
 		// everything else, to maintain accurary
-		build_unit->scaled_width = ((scale * frame_head->width) / 256);
-		build_unit->scaled_height = ((scale * frame_head->height) / 256);
+		build_unit->scaled_width = ((scale * frame_head.width) / 256);
+		build_unit->scaled_height = ((scale * frame_head.height) / 256);
 	} else {
 		// It's a non-scaling anim. Get render coords for sprite, from cdt
-		build_unit->x = cdt_entry->x;
-		build_unit->y = cdt_entry->y;
+		build_unit->x = cdt_entry.x;
+		build_unit->y = cdt_entry.y;
 
 		// Get width and height
-		build_unit->scaled_width = frame_head->width;
-		build_unit->scaled_height = frame_head->height;
+		build_unit->scaled_width = frame_head.width;
+		build_unit->scaled_height = frame_head.height;
 	}
 
 	// either 0 or required scale, depending on whether 'scale' computed
@@ -577,12 +592,14 @@
 
 	}
 
-	_vm->_resman->closeResource(ob_graph->anim_resource);
+	_vm->_resman->closeResource(obGraph.getAnimResource());
 }
 
-void Screen::registerFrame(ObjectMouse *ob_mouse, ObjectGraphic *ob_graph, ObjectMega *ob_mega) {
+void Screen::registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega) {
+	ObjectGraphic obGraph(ob_graph);
+
 	// check low word for sprite type
-	switch (ob_graph->type & 0x0000ffff) {
+	switch (obGraph.getType() & 0x0000ffff) {
 	case BGP0_SPRITE:
 		assert(_curBgp0 < MAX_bgp0_sprites);
 		registerFrame(ob_mouse, ob_graph, ob_mega, &_bgp0List[_curBgp0]);
@@ -861,7 +878,7 @@
 	// credits. Note that musicTimeRemaining() will return 0 if the music
 	// is muted, so we need a sensible fallback for that case.
 
-	uint32 musicLength = MAX((int32) (1000 * (_vm->_sound->musicTimeRemaining() - 3)), 25 * (int32) scrollSteps);
+	uint32 musicLength = MAX((int32)(1000 * (_vm->_sound->musicTimeRemaining() - 3)), 25 * (int32)scrollSteps);
 
 	while (scrollPos < scrollSteps && !_vm->_quit) {
 		bool foundStartLine = false;
@@ -892,16 +909,18 @@
 					creditsLines[i].sprite = _vm->_fontRenderer->makeTextSprite((byte *)creditsLines[i].str, 600, 14, _vm->_speechFontId, 0);
 				}
 
-				FrameHeader *frame = (FrameHeader *)creditsLines[i].sprite;
+				FrameHeader frame;
+
+				frame.read(creditsLines[i].sprite);
 
 				spriteInfo.y = creditsLines[i].top - scrollPos;
-				spriteInfo.w = frame->width;
-				spriteInfo.h = frame->height;
-				spriteInfo.data = creditsLines[i].sprite + sizeof(FrameHeader);
+				spriteInfo.w = frame.width;
+				spriteInfo.h = frame.height;
+				spriteInfo.data = creditsLines[i].sprite + FrameHeader::size();
 
 				switch (creditsLines[i].type) {
 				case LINE_LEFT:
-					spriteInfo.x = RENDERWIDE / 2 - 5 - frame->width;
+					spriteInfo.x = RENDERWIDE / 2 - 5 - frame.width;
 					break;
 				case LINE_RIGHT:
 					spriteInfo.x = RENDERWIDE / 2 + 5;
@@ -913,7 +932,7 @@
 						spriteInfo.w = logoWidth;
 						spriteInfo.h = logoHeight;
 					} else
-						spriteInfo.x = (RENDERWIDE - frame->width) / 2;
+						spriteInfo.x = (RENDERWIDE - frame.width) / 2;
 					break;
 				}
 
@@ -978,7 +997,7 @@
 	if (!_vm->_mouse->getMouseStatus() || _vm->_mouse->isChoosing())
 		_vm->_mouse->setMouse(NORMAL_MOUSE_ID);
 
-	if (Logic::_scriptVars[DEAD])
+	if (_vm->_logic->readVar(DEAD))
 		_vm->_mouse->buildSystemMenu();
 }
 
@@ -1001,32 +1020,38 @@
 	closeBackgroundLayer();
 
 	byte *loadingBar = _vm->_resman->openResource(2951);
-	AnimHeader *animHead = _vm->fetchAnimHeader(loadingBar);
-	FrameHeader *frame = _vm->fetchFrameHeader(loadingBar, 0);
-	CdtEntry *cdt = _vm->fetchCdtEntry(loadingBar, 0);
+	byte *frame = _vm->fetchFrameHeader(loadingBar, 0);
+
+	AnimHeader animHead;
+	CdtEntry cdt;
+	FrameHeader frame_head;
+
+	animHead.read(_vm->fetchAnimHeader(loadingBar));
+	cdt.read(_vm->fetchCdtEntry(loadingBar, 0));
+	frame_head.read(_vm->fetchFrameHeader(loadingBar, 0));
 
 	SpriteInfo barSprite;
 
-	barSprite.x = cdt->x;
-	barSprite.y = cdt->y;
-	barSprite.w = frame->width;
-	barSprite.h = frame->height;
+	barSprite.x = cdt.x;
+	barSprite.y = cdt.y;
+	barSprite.w = frame_head.width;
+	barSprite.h = frame_head.height;
 	barSprite.scale = 0;
 	barSprite.scaledWidth = 0;
 	barSprite.scaledHeight = 0;
 	barSprite.type = RDSPR_RLE256FAST | RDSPR_TRANS;
 	barSprite.blend = 0;
 	barSprite.colourTable = 0;
-	barSprite.data = (byte *)(frame + 1);
+	barSprite.data = frame + FrameHeader::size();
 
 	drawSprite(&barSprite);
 
 	fadeUp();
 	waitForFade();
 
-	for (int i = 0; i < animHead->noAnimFrames; i++) {
+	for (int i = 0; i < animHead.noAnimFrames; i++) {
 		frame = _vm->fetchFrameHeader(loadingBar, i);
-		barSprite.data = (byte *)(frame + 1);
+		barSprite.data = frame + FrameHeader::size();
 		drawSprite(&barSprite);
 		updateDisplay();
 		_vm->_system->delayMillis(30);

Index: build_display.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/build_display.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- build_display.h	18 Oct 2005 01:30:25 -0000	1.21
+++ build_display.h	29 Oct 2005 21:24:53 -0000	1.22
@@ -22,6 +22,7 @@
 #define	_BUILD_DISPLAY
 
 #include "common/rect.h"
+#include "common/stream.h"
 
 #define MAX_bgp0_sprites 6
 #define MAX_bgp1_sprites 6
@@ -53,10 +54,6 @@
 
 class Sword2Engine;
 
-struct ObjectMouse;
-struct ObjectGraphic;
-struct ObjectMega;
-
 // Sprite defines
 
 enum {
@@ -176,19 +173,31 @@
 	bool transparent;
 };
 
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
 struct Parallax {
 	uint16 w;
 	uint16 h;
-	uint32 offset[2];	// 2 is arbitrary
-} GCC_PACK;
 
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
+	// The dimensions are followed by an offset table, but we don't know in
+	// advance how big it is. See initializeBackgroundLayer().
+
+	static const int size() {
+		return 4;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		w = readS.readUint16LE();
+		h = readS.readUint16LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint16LE(w);
+		writeS.writeUint16LE(h);
+	}
+};
 
 class Screen {
 private:
@@ -310,13 +319,13 @@
 	char _largestLayerInfo[128];
 	char _largestSpriteInfo[128];
 
-	void registerFrame(ObjectMouse *ob_mouse, ObjectGraphic *ob_graph, ObjectMega *ob_mega, BuildUnit *build_unit);
+	void registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega, BuildUnit *build_unit);
 
 	void mirrorSprite(byte *dst, byte *src, int16 w, int16 h);
 	int32 decompressRLE256(byte *dst, byte *src, int32 decompSize);
 	void unwindRaw16(byte *dst, byte *src, uint8 blockSize, byte *colTable);
 	int32 decompressRLE16(byte *dst, byte *src, int32 decompSize, byte *colTable);
-	void renderParallax(Parallax *p, int16 layer);
+	void renderParallax(byte *ptr, int16 layer);
 
 	void markAsDirty(int16 x0, int16 y0, int16 x1, int16 y1);
 
@@ -370,13 +379,13 @@
 	void resetRenderLists();
 
 	void setLocationMetrics(uint16 w, uint16 h);
-	int32 initialiseBackgroundLayer(Parallax *p);
+	int32 initialiseBackgroundLayer(byte *parallax);
 	void closeBackgroundLayer();
 
 	void initialiseRenderCycle();
 
 	void initBackground(int32 res, int32 new_palette);
-	void registerFrame(ObjectMouse *ob_mouse, ObjectGraphic *ob_graph, ObjectMega *ob_mega);
+	void registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega);
 
 	void setScrollFraction(uint8 f) { _scrollFraction = f; }
 	void setScrollTarget(int16 x, int16 y);

Index: console.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/console.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- console.cpp	18 Oct 2005 01:30:25 -0000	1.58
+++ console.cpp	29 Oct 2005 21:24:53 -0000	1.59
@@ -69,7 +69,7 @@
 
 	_textNumber = 0;		// Current system text line number
 
-	_playerGraphicNoFrames = 0;	// No. of frames in currently displayed
+	_graphNoFrames = 0;		// No. of frames in currently displayed
 					// anim
 
 	// Register commands
@@ -118,13 +118,13 @@
 }
 
 void Debugger::varGet(int var) {
-	DebugPrintf("%d\n", Logic::_scriptVars[var]);
+	DebugPrintf("%d\n", _vm->_logic->readVar(var));
 }
 
 void Debugger::varSet(int var, int val) {
-	DebugPrintf("was %d, ", Logic::_scriptVars[var]);
-	Logic::_scriptVars[var] = val;
-	DebugPrintf("now %d\n", Logic::_scriptVars[var]);
+	DebugPrintf("was %d, ", _vm->_logic->readVar(var));
+	_vm->_logic->writeVar(var, val);
+	DebugPrintf("now %d\n", _vm->_logic->readVar(var));
 }
 
 void Debugger::preEnter() {
@@ -210,10 +210,9 @@
 	DebugPrintf("---------------------------------------------------------------------------\n");
 
 	for (i = 0; i < numBlocks; i++) {
-		StandardHeader *head = (StandardHeader *)blocks[i]->ptr;
 		const char *type;
 
-		switch (head->fileType) {
+		switch (_vm->_resman->fetchType(blocks[i]->ptr)) {
 		case ANIMATION_FILE:
 			type = "ANIMATION_FILE";
 			break;
@@ -258,7 +257,7 @@
 			break;
 		}
 
-		DebugPrintf("%9ld %-3d %-4d %-20s %s\n", blocks[i]->size, blocks[i]->id, blocks[i]->uid, type, head->name);
+		DebugPrintf("%9ld %-3d %-4d %-20s %s\n", blocks[i]->size, blocks[i]->id, blocks[i]->uid, type, _vm->_resman->fetchName(blocks[i]->ptr));
 	}
 
 	free(blocks);
@@ -321,8 +320,7 @@
 
 	for (uint i = 0; i < numResFiles; i++) {
 		if (resList[i].ptr && resList[i].refCount >= minCount) {
-			StandardHeader *head = (StandardHeader *)resList[i].ptr;
-			DebugPrintf("%-4d: %-35s refCount: %-3d\n", i, head->name, resList[i].refCount);
+			DebugPrintf("%-4d: %-35s refCount: %-3d\n", i, _vm->_resman->fetchName(resList[i].ptr), resList[i].refCount);
 		}
 	}
 
@@ -369,7 +367,7 @@
 
 	int start = atoi(argv[1]);
 
-	if (start < 0 || start >= (int) numStarts) {
+	if (start < 0 || start >= (int)numStarts) {
 		DebugPrintf("Not a legal start position\n");
 		return true;
 	}
@@ -434,7 +432,7 @@
 	int res = atoi(argv[1]);
 	uint32 numResFiles = _vm->_resman->getNumResFiles();
 
-	if (res < 0 || res >= (int) numResFiles) {
+	if (res < 0 || res >= (int)numResFiles) {
 		DebugPrintf("Illegal resource %d. There are %d resources, 0-%d.\n",
 			res, numResFiles, numResFiles - 1);
 		return true;
@@ -446,48 +444,50 @@
 	}
 
 	// Open up the resource and take a look inside!
-	StandardHeader *file_header = (StandardHeader *)_vm->_resman->openResource(res);
+	uint8 type = _vm->_resman->fetchType(res);;
+	byte name[NAME_LEN];
 
-	switch (file_header->fileType) {
+	_vm->_resman->fetchName(res, name);
+
+	switch (type) {
 	case ANIMATION_FILE:
-		DebugPrintf("<anim> %s\n", file_header->name);
+		DebugPrintf("<anim> %s\n", name);
 		break;
 	case SCREEN_FILE:
-		DebugPrintf("<layer> %s\n", file_header->name);
+		DebugPrintf("<layer> %s\n", name);
 		break;
 	case GAME_OBJECT:
-		DebugPrintf("<game object> %s\n", file_header->name);
+		DebugPrintf("<game object> %s\n", name);
 		break;
 	case WALK_GRID_FILE:
-		DebugPrintf("<walk grid> %s\n", file_header->name);
+		DebugPrintf("<walk grid> %s\n", name);
 		break;
 	case GLOBAL_VAR_FILE:
-		DebugPrintf("<global variables> %s\n", file_header->name);
+		DebugPrintf("<global variables> %s\n", name);
 		break;
 	case PARALLAX_FILE_null:
-		DebugPrintf("<parallax file NOT USED!> %s\n", file_header->name);
+		DebugPrintf("<parallax file NOT USED!> %s\n", name);
 		break;
 	case RUN_LIST:
-		DebugPrintf("<run list> %s\n", file_header->name);
+		DebugPrintf("<run list> %s\n", name);
 		break;
 	case TEXT_FILE:
-		DebugPrintf("<text file> %s\n", file_header->name);
+		DebugPrintf("<text file> %s\n", name);
 		break;
 	case SCREEN_MANAGER:
-		DebugPrintf("<screen manager> %s\n", file_header->name);
+		DebugPrintf("<screen manager> %s\n", name);
 		break;
 	case MOUSE_FILE:
-		DebugPrintf("<mouse pointer> %s\n", file_header->name);
+		DebugPrintf("<mouse pointer> %s\n", name);
 		break;
 	case ICON_FILE:
-		DebugPrintf("<menu icon> %s\n", file_header->name);
+		DebugPrintf("<menu icon> %s\n", name);
 		break;
 	default:
-		DebugPrintf("unrecognised fileType %d\n", file_header->fileType);
+		DebugPrintf("unrecognised fileType %d\n", type);
 		break;
 	}
 
-	_vm->_resman->closeResource(res);
 	return true;
 }
 
@@ -507,20 +507,23 @@
 }
 
 bool Debugger::Cmd_RunList(int argc, const char **argv) {
-	uint32 *game_object_list;
-	StandardHeader *file_header;
-
 	uint32 runList = _vm->_logic->getRunList();
 
 	if (runList) {
-		game_object_list = (uint32 *)(_vm->_resman->openResource(runList) + sizeof(StandardHeader));
+		Common::MemoryReadStream readS(_vm->_resman->openResource(runList), _vm->_resman->fetchLen(runList));
+
+		readS.seek(ResHeader::size());
 
 		DebugPrintf("Runlist number %d\n", runList);
 
-		for (int i = 0; game_object_list[i]; i++) {
-			file_header = (StandardHeader *)_vm->_resman->openResource(game_object_list[i]);
-			DebugPrintf("%d %s\n", game_object_list[i], file_header->name);
-			_vm->_resman->closeResource(game_object_list[i]);
+		while (1) {
+			uint32 res = readS.readUint32LE();
+			if (!res)
+				break;
+
+			byte name[NAME_LEN];
+
+			DebugPrintf("%d %s\n", res, _vm->_resman->fetchName(res, name));
 		}
 
 		_vm->_resman->closeResource(runList);
@@ -539,7 +542,7 @@
 	int res = atoi(argv[1]);
 	uint32 numResFiles = _vm->_resman->getNumResFiles();
 
-	if (res < 0 || res >= (int) numResFiles) {
+	if (res < 0 || res >= (int)numResFiles) {
 		DebugPrintf("Illegal resource %d. There are %d resources, 0-%d.\n",
 			res, numResFiles, numResFiles - 1);
 		return true;
@@ -797,8 +800,8 @@
 			uint32 target = eventList[i].id;
 			uint32 script = eventList[i].interact_id;
 
-			DebugPrintf("slot %2d: id = %s (%d)\n", i, _vm->fetchObjectName(target, buf), target);
-			DebugPrintf("         script = %s (%d) pos %d\n", _vm->fetchObjectName(script / 65536, buf), script / 65536, script % 65536);
+			DebugPrintf("slot %2d: id = %s (%d)\n", i, _vm->_resman->fetchName(target, buf), target);
+			DebugPrintf("         script = %s (%d) pos %d\n", _vm->_resman->fetchName(script / 65536, buf), script / 65536, script % 65536);
 		}
 	}
 

Index: console.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/console.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- console.h	18 Oct 2005 01:30:25 -0000	1.27
+++ console.h	29 Oct 2005 21:24:53 -0000	1.28
@@ -67,8 +67,10 @@
 
 	int32 _textNumber;
 
-	ObjectGraphic _playerGraphic;
-	uint32 _playerGraphicNoFrames;
+	int32 _graphType;
+	int32 _graphAnimRes;
+	int32 _graphAnimPc;
+	uint32 _graphNoFrames;
 
 	void buildDebugText();
 	void drawDebugGraphics();

Index: controls.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/controls.cpp,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -d -r1.96 -r1.97
--- controls.cpp	18 Oct 2005 01:30:25 -0000	1.96
+++ controls.cpp	29 Oct 2005 21:24:53 -0000	1.97
@@ -139,19 +139,23 @@
 FontRendererGui::FontRendererGui(Sword2Engine *vm, int fontId)
 	: _vm(vm), _fontId(fontId) {
 	byte *font = _vm->_resman->openResource(fontId);
-	FrameHeader *head;
 	SpriteInfo sprite;
 
 	sprite.type = RDSPR_NOCOMPRESSION | RDSPR_TRANS;
 
 	for (int i = 0; i < SIZE_OF_CHAR_SET; i++) {
-		head = (FrameHeader *)_vm->fetchFrameHeader(font, i);
-		sprite.data = (byte *)(head + 1);
-		sprite.w = head->width;
-		sprite.h = head->height;
+		byte *frame = _vm->fetchFrameHeader(font, i);
+
+		FrameHeader frame_head;
+
+		frame_head.read(frame);
+
+		sprite.data = frame + FrameHeader::size();
+		sprite.w = frame_head.width;
+		sprite.h = frame_head.height;
 		_vm->_screen->createSurface(&sprite, &_glyph[i]._data);
-		_glyph[i]._width = head->width;
-		_glyph[i]._height = head->height;
+		_glyph[i]._width = frame_head.width;
+		_glyph[i]._height = frame_head.height;
 	}
 
 	_vm->_resman->closeResource(fontId);
@@ -413,27 +417,29 @@
 
 void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc) {
 	byte *file, *colTablePtr = NULL;
-	AnimHeader *anim_head;
-	FrameHeader *frame_head;
-	CdtEntry *cdt_entry;
+	AnimHeader anim_head;
+	FrameHeader frame_head;
+	CdtEntry cdt_entry;
 	uint32 spriteType = RDSPR_TRANS;
 
 	// open anim resource file, point to base
 	file = _vm->_resman->openResource(res);
 
-	anim_head = _vm->fetchAnimHeader(file);
-	cdt_entry = _vm->fetchCdtEntry(file, pc);
-	frame_head = _vm->fetchFrameHeader(file, pc);
+	byte *frame = _vm->fetchFrameHeader(file, pc);
+
+	anim_head.read(_vm->fetchAnimHeader(file));
+	cdt_entry.read(_vm->fetchCdtEntry(file, pc));
+	frame_head.read(frame);
 
 	// If the frame is flipped. (Only really applicable to frames using
 	// offsets.)
 
-	if (cdt_entry->frameType & FRAME_FLIPPED)
+	if (cdt_entry.frameType & FRAME_FLIPPED)
 		spriteType |= RDSPR_FLIP;
 
 	// Which compression was used?
 
-	switch (anim_head->runTimeComp) {
+	switch (anim_head.runTimeComp) {
 	case NONE:
 		spriteType |= RDSPR_NOCOMPRESSION;
 		break;
@@ -444,21 +450,21 @@
 		spriteType |= RDSPR_RLE256;
 		// Points to just after last cdt_entry, i.e. start of colour
 		// table
-		colTablePtr = (byte *)(anim_head + 1) +
-			anim_head->noAnimFrames * sizeof(CdtEntry);
+		colTablePtr = _vm->fetchAnimHeader(file) + AnimHeader::size()
+			+ anim_head.noAnimFrames * CdtEntry::size();
 		break;
 	}
 
 	_sprites[state].x = x;
 	_sprites[state].y = y;
-	_sprites[state].w = frame_head->width;
-	_sprites[state].h = frame_head->height;
+	_sprites[state].w = frame_head.width;
+	_sprites[state].h = frame_head.height;
 	_sprites[state].scale = 0;
 	_sprites[state].type = spriteType;
-	_sprites[state].blend = anim_head->blend;
+	_sprites[state].blend = anim_head.blend;
 
 	// Points to just after frame header, ie. start of sprite data
-	_sprites[state].data = (byte *)(frame_head + 1);
+	_sprites[state].data = frame + FrameHeader::size();
 
 	_vm->_screen->createSurface(&_sprites[state], &_surfaces[state]._surface);
 	_surfaces[state]._original = true;
@@ -661,7 +667,7 @@
 	}
 
 	int valueFromPos(int x) {
-		return (int) ((double) (_maxValue * (x - _hitRect.left)) / (double) (_hitRect.width() - 38) + 0.5);
+		return (int)((double)(_maxValue * (x - _hitRect.left)) / (double)(_hitRect.width() - 38) + 0.5);
 	}
 
 public:

Index: debug.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/debug.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- debug.cpp	18 Oct 2005 01:30:25 -0000	1.52
+++ debug.cpp	29 Oct 2005 21:24:53 -0000	1.53
@@ -85,7 +85,7 @@
 	// mouse area coords
 
 	// defining a mouse area the easy way, by creating a box on-screen
-	if (_draggingRectangle || Logic::_scriptVars[SYSTEM_TESTING_ANIMS]) {
+	if (_draggingRectangle || _vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
 		// so we can see what's behind the lines
 		_rectFlicker = !_rectFlicker;
 
@@ -137,8 +137,8 @@
 
 	if (_displayTextNumbers) {
 		if (_textNumber) {
-			if (Logic::_scriptVars[SYSTEM_TESTING_TEXT]) {
-				if (Logic::_scriptVars[SYSTEM_WANT_PREVIOUS_LINE])
+			if (_vm->_logic->readVar(SYSTEM_TESTING_TEXT)) {
+				if (_vm->_logic->readVar(SYSTEM_WANT_PREVIOUS_LINE))
 					sprintf(buf, "backwards");
 				else
  					sprintf(buf, "forwards");
@@ -159,8 +159,8 @@
 
 	// resource number currently being checking for animation
 
-	if (Logic::_scriptVars[SYSTEM_TESTING_ANIMS]) {
-		sprintf(buf, "trying resource %d", Logic::_scriptVars[SYSTEM_TESTING_ANIMS]);
+	if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
+		sprintf(buf, "trying resource %d", _vm->_logic->readVar(SYSTEM_TESTING_ANIMS));
 		makeDebugTextBlock(buf, 0, 90);
 	}
 
@@ -177,16 +177,16 @@
 
 		// mouse coords & object pointed to
 
-		if (Logic::_scriptVars[CLICKED_ID])
+		if (_vm->_logic->readVar(CLICKED_ID))
 			sprintf(buf, "last click at %d,%d (id %d: %s)",
-				Logic::_scriptVars[MOUSE_X],
-				Logic::_scriptVars[MOUSE_Y],
-				Logic::_scriptVars[CLICKED_ID],
-				_vm->fetchObjectName(Logic::_scriptVars[CLICKED_ID], name));
+				_vm->_logic->readVar(MOUSE_X),
+				_vm->_logic->readVar(MOUSE_Y),
+				_vm->_logic->readVar(CLICKED_ID),
+				_vm->_resman->fetchName(_vm->_logic->readVar(CLICKED_ID), name));
 		else
 			sprintf(buf, "last click at %d,%d (---)",
-				Logic::_scriptVars[MOUSE_X],
-				Logic::_scriptVars[MOUSE_Y]);
+				_vm->_logic->readVar(MOUSE_X),
+				_vm->_logic->readVar(MOUSE_Y));
 
  		makeDebugTextBlock(buf, 0, 15);
 
@@ -201,7 +201,7 @@
 				mouseX + screenInfo->scroll_offset_x,
 				mouseY + screenInfo->scroll_offset_y,
 				mouseTouching,
-				_vm->fetchObjectName(mouseTouching, name));
+				_vm->_resman->fetchName(mouseTouching, name));
 		else
 			sprintf(buf, "mouse %d,%d (not touching)",
 				mouseX + screenInfo->scroll_offset_x,
@@ -212,19 +212,19 @@
  		// player coords & graphic info
 		// if player objct has a graphic
 
-		if (_playerGraphic.anim_resource)
+		if (_graphAnimRes)
 			sprintf(buf, "player %d,%d %s (%d) #%d/%d",
 				screenInfo->player_feet_x,
 				screenInfo->player_feet_y,
-				_vm->fetchObjectName(_playerGraphic.anim_resource, name),
-				_playerGraphic.anim_resource,
-				_playerGraphic.anim_pc,
-				_playerGraphicNoFrames);
+				_vm->_resman->fetchName(_graphAnimRes, name),
+				_graphAnimRes,
+				_graphAnimPc,
+				_graphNoFrames);
 		else
 			sprintf(buf, "player %d,%d --- %d",
 				screenInfo->player_feet_x,
 				screenInfo->player_feet_y,
-				_playerGraphic.anim_pc);
+				_graphAnimPc);
 
 		makeDebugTextBlock(buf, 0, 45);
 
@@ -235,12 +235,12 @@
 
  		// location number
 
-		sprintf(buf, "location=%d", Logic::_scriptVars[LOCATION]);
+		sprintf(buf, "location=%d", _vm->_logic->readVar(LOCATION));
 		makeDebugTextBlock(buf, 440, 15);
 
  		// "result" variable
 
-		sprintf(buf, "result=%d", Logic::_scriptVars[RESULT]);
+		sprintf(buf, "result=%d", _vm->_logic->readVar(RESULT));
 		makeDebugTextBlock(buf, 440, 30);
 
  		// no. of events in event list
@@ -282,7 +282,7 @@
 
 		if (_speechScriptWaiting) {
 			sprintf(buf, "script waiting for %s (%d)",
-				_vm->fetchObjectName(_speechScriptWaiting, name),
+				_vm->_resman->fetchName(_speechScriptWaiting, name),
 				_speechScriptWaiting);
 			makeDebugTextBlock(buf, 0, 90);
 		}
@@ -298,7 +298,7 @@
 			// anyway because it changes throughout the logic loop
 
 			if (varNo) {
-				sprintf(buf, "var(%d) = %d", varNo, Logic::_scriptVars[varNo]);
+				sprintf(buf, "var(%d) = %d", varNo, _vm->_logic->readVar(varNo));
 				makeDebugTextBlock(buf, 530, showVarPos);
 				showVarPos += 15;	// next line down
 			}
@@ -345,7 +345,7 @@
 
    	// mouse area rectangle / sprite box rectangle when testing anims
 
-	if (Logic::_scriptVars[SYSTEM_TESTING_ANIMS]) {
+	if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
 		// draw box around current frame
 		drawRect(_rectX1, _rectY1, _rectX2, _rectY2, 184);
 	} else if (_draggingRectangle) {

Index: events.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/events.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- events.cpp	18 Oct 2005 01:30:25 -0000	1.38
+++ events.cpp	29 Oct 2005 21:24:53 -0000	1.39
@@ -44,7 +44,7 @@
 
 int Logic::checkEventWaiting() {
 	for (int i = 0; i < MAX_events; i++) {
-		if (_eventList[i].id == _scriptVars[ID])
+		if (_eventList[i].id == readVar(ID))
 			return 1;
 	}
 
@@ -56,14 +56,14 @@
 	// you must follow with a return IR_TERMINATE
 
 	for (int i = 0; i < MAX_events; i++) {
-		if (_eventList[i].id == _scriptVars[ID]) {
+		if (_eventList[i].id == readVar(ID)) {
 			logicOne(_eventList[i].interact_id);
 			_eventList[i].id = 0;
 			return;
 		}
 	}
 
-	error("startEvent() can't find event for id %d", _scriptVars[ID]);
+	error("startEvent() can't find event for id %d", readVar(ID));
 }
 
 void Logic::clearEvent(uint32 id) {

Index: function.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/function.cpp,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- function.cpp	18 Oct 2005 01:30:25 -0000	1.89
+++ function.cpp	29 Oct 2005 21:24:53 -0000	1.90
@@ -19,8 +19,8 @@
  */
 
 #include "common/stdafx.h"
-#include "common/file.h"
 #include "common/system.h"
+#include "common/file.h"
 
 #include "sword2/sword2.h"
 #include "sword2/defs.h"
@@ -81,19 +81,19 @@
 
[...1556 lines suppressed...]
 	return IR_CONT;
@@ -2407,8 +2383,7 @@
 	// or 0 if no music playing
 
 	// in seconds, rounded up to the nearest second
-	_scriptVars[RESULT] = _vm->_sound->musicTimeRemaining();
-
+	writeVar(RESULT, _vm->_sound->musicTimeRemaining());
 	return IR_CONT;
 }
 
@@ -2418,7 +2393,7 @@
 
 	// params:	none
 
-	if (_scriptVars[DEMO]) {
+	if (readVar(DEMO)) {
 		_vm->closeGame();
 		return IR_STOP;
 	}

Index: header.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/header.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- header.h	18 Oct 2005 01:30:25 -0000	1.14
+++ header.h	29 Oct 2005 21:24:53 -0000	1.15
@@ -21,16 +21,14 @@
 #ifndef	_HEADER
 #define	_HEADER
 
+#include "common/stream.h"
+
 namespace Sword2 {
 
 //----------------------------------------------------------
 // SYSTEM FILE & FRAME HEADERS
 //----------------------------------------------------------
 
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
 //----------------------------------------------------------
 // ALL FILES
 //----------------------------------------------------------
@@ -39,7 +37,7 @@
 
 #define	NAME_LEN 34
 
-struct StandardHeader {
+struct ResHeader {
 	uint8 fileType;			// Byte to define file type (see below)
 	uint8 compType;			// Type of file compression used ie.
 					// on whole file (see below)
@@ -49,7 +47,31 @@
 					// memory (NB. frames still held
 					// compressed)
 	byte name[NAME_LEN];		// Name of object
-} GCC_PACK;
+
+	static const int size() {
+		return 44;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		fileType = readS.readByte();
+		compType = readS.readByte();
+		compSize = readS.readUint32LE();
+		decompSize = readS.readUint32LE();
+		readS.read(name, NAME_LEN);
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeByte(fileType);
+		writeS.writeByte(compType);
+		writeS.writeUint32LE(compSize);
+		writeS.writeUint32LE(decompSize);
+		writeS.write(name, NAME_LEN);
+	}
+};
 
 // fileType
 
@@ -121,7 +143,40 @@
 				// place from the start)
 	uint8 feetEndDir;	// Direction to start in after running anim
 	uint16 blend;
-} GCC_PACK;
+
+	static const int size() {
+		return 15;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		runTimeComp = readS.readByte();
+		noAnimFrames = readS.readUint16LE();
+		feetStartX = readS.readUint16LE();
+		feetStartY = readS.readUint16LE();
+		feetStartDir = readS.readByte();
+		feetEndX = readS.readUint16LE();
+		feetEndY = readS.readUint16LE();
+		feetEndDir = readS.readByte();
+		blend = readS.readUint16LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeByte(runTimeComp);
+		writeS.writeUint16LE(noAnimFrames);
+		writeS.writeUint16LE(feetStartX);
+		writeS.writeUint16LE(feetStartY);
+		writeS.writeByte(feetStartDir);
+		writeS.writeUint16LE(feetEndX);
+		writeS.writeUint16LE(feetEndY);
+		writeS.writeByte(feetEndDir);
+		writeS.writeUint16LE(blend);
+	}
+		
+};
 
 // runtimeComp - compression used on each frame of the anim
 
@@ -145,7 +200,29 @@
 				// of file header)
 	uint8 frameType;	// 0 = print sprite normally with top-left
 				// corner at (x,y), otherwise see below...
-} GCC_PACK;
+
+	static const int size() {
+		return 9;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		x = readS.readUint16LE();
+		y = readS.readUint16LE();
+		frameOffset = readS.readUint32LE();
+		frameType = readS.readByte();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint16LE(x);
+		writeS.writeUint16LE(y);
+		writeS.writeUint32LE(frameOffset);
+		writeS.writeByte(frameType);
+	}
+};
 
 // 'frameType' bit values
 
@@ -164,7 +241,27 @@
 				// type is now in Anim Header
 	uint16 width;		// Dimensions of frame
 	uint16 height;
-} GCC_PACK;
+
+	static const int size() {
+		return 8;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		compSize = readS.readUint32LE();
+		width = readS.readUint16LE();
+		height = readS.readUint16LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint32LE(compSize);
+		writeS.writeUint16LE(width);
+		writeS.writeUint16LE(height);
+	}
+};
 
 //----------------------------------------------------------
 // (2) SCREEN FILES
@@ -193,7 +290,39 @@
 	uint32 layers;
 	uint32 paletteTable;
 	uint32 maskOffset;
-} GCC_PACK;
+
+	static const int size() {
+		return 36;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		palette = readS.readUint32LE();
+		bg_parallax[0] = readS.readUint32LE();
+		bg_parallax[1] = readS.readUint32LE();
+		screen = readS.readUint32LE();
+		fg_parallax[0] = readS.readUint32LE();
+		fg_parallax[1] = readS.readUint32LE();
+		layers = readS.readUint32LE();
+		paletteTable = readS.readUint32LE();
+		maskOffset = readS.readUint32LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint32LE(palette);
+		writeS.writeUint32LE(bg_parallax[0]);
+		writeS.writeUint32LE(bg_parallax[1]);
+		writeS.writeUint32LE(screen);
+		writeS.writeUint32LE(fg_parallax[0]);
+		writeS.writeUint32LE(fg_parallax[1]);
+		writeS.writeUint32LE(layers);
+		writeS.writeUint32LE(paletteTable);
+		writeS.writeUint32LE(maskOffset);
+	}
+};
 
 // Screen Header
 
@@ -201,7 +330,27 @@
 	uint16 width;		// dimensions of the background screen
 	uint16 height;
 	uint16 noLayers;	// number of layer areas
-} GCC_PACK;
+
+	static const int size() {
+		return 6;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		width = readS.readUint16LE();
+		height = readS.readUint16LE();
+		noLayers = readS.readUint16LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint16LE(width);
+		writeS.writeUint16LE(height);
+		writeS.writeUint16LE(noLayers);
+	}
+};
 
 // Layer Header
 
@@ -216,7 +365,33 @@
 	uint32 maskSize;
 	uint32 offset;		// where to find mask data (from start of
 				// standard file header)
-} GCC_PACK;
+
+	static const int size() {
+		return 16;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		x = readS.readUint16LE();
+		y = readS.readUint16LE();
+		width = readS.readUint16LE();
+		height = readS.readUint16LE();
+		maskSize = readS.readUint32LE();
+		offset = readS.readUint32LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint16LE(x);
+		writeS.writeUint16LE(y);
+		writeS.writeUint16LE(width);
+		writeS.writeUint16LE(height);
+		writeS.writeUint32LE(maskSize);
+		writeS.writeUint32LE(offset);
+	}
+};
 
 //----------------------------------------------------------
 // (3) SCRIPT OBJECT FILES
@@ -228,22 +403,6 @@
 // script object data
 
 //----------------------------------------------------------
-// (4) WALK-GRID FILES
-//----------------------------------------------------------
-// a walk-grid file consists of:
-//
-// standard file header
-// walk-grid file header
-// walk-grid data
-
-// Walk-Grid Header - taken directly from old "header.h" in STD_INC
-
-struct WalkGridHeader {
-	int32 numBars;		// number of bars on the floor
-	int32 numNodes;		// number of nodes
-} GCC_PACK;
-
-//----------------------------------------------------------
 // (5) PALETTE FILES
 //----------------------------------------------------------
 // a palette file consists of:
@@ -254,35 +413,89 @@
 
 // an object hub - which represents all that remains of the compact concept
 
-#define	TREE_SIZE	3
+class ObjectHub {
+	// int32 type;		// type of object
+	// uint32 logic_level;	// what level?
+	// uint32 logic[3]	// NOT USED
+	// uint32 script_id[3]	// need this if script
+	// uint32 script_pc[3]	// need this also
 
-struct ObjectHub {
-	int32 type;			// type of object
-	uint32 logic_level;		// what level?
-	uint32 logic[TREE_SIZE];	// NOT USED
-	uint32 script_id[TREE_SIZE];	// need this if script
-	uint32 script_pc[TREE_SIZE];	// need this also
-} GCC_PACK;
+private:
+	byte *_addr;
+
+public:
+	ObjectHub() {
+		_addr = NULL;
+	}
+
+	static const int size() {
+		return 44;
+	}
+
+	byte *data() {
+		return _addr;
+	}
+
+	void setAddress(byte *addr) {
+		_addr = addr;
+	}
+
+	byte *getScriptPcPtr(int level) {
+		return _addr + 32 + 4 * level;
+	}
+
+	uint32 getLogicLevel() {
+		return READ_LE_UINT32(_addr + 4);
+	}
+	uint32 getScriptId(int level) {
+		return READ_LE_UINT32(_addr + 20 + 4 * level);
+	}
+	uint32 getScriptPc(int level) {
+		return READ_LE_UINT32(_addr + 32 + 4 * level);
+	}
+
+	void setLogicLevel(uint32 x) {
+		WRITE_LE_UINT32(_addr + 4, x);
+	}
+	void setScriptId(int level, uint32 x) {
+		WRITE_LE_UINT32(_addr + 20 + 4 * level, x);
+	}
+	void setScriptPc(int level, uint32 x) {
+		WRITE_LE_UINT32(_addr + 32 + 4 * level, x);
+	}
+};
 
 // (6) text module header
 
 struct TextHeader {
 	uint32 noOfLines;	// how many lines of text are there in this
 				// module
-} GCC_PACK;
+
+	static const int size() {
+		return 4;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		noOfLines = readS.readUint32LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint32LE(noOfLines);
+	}
+};
 
 // a text file has:
 //
-//	StandardHeader
+//	ResHeader
 //	TextHeader
 //	look up table, to
 //	line of text,0
 //	line of text,0
 
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
-
 } // End of namespace Sword2
 
 #endif

Index: icons.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/icons.cpp,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- icons.cpp	18 Oct 2005 01:30:25 -0000	1.46
+++ icons.cpp	29 Oct 2005 21:24:53 -0000	1.47
@@ -19,6 +19,7 @@
  */
 
 #include "common/stdafx.h"
+#include "common/stream.h"
 #include "sword2/sword2.h"
 #include "sword2/defs.h"
 #include "sword2/logic.h"
@@ -27,14 +28,20 @@
 
 namespace Sword2 {
 
-void Mouse::addMenuObject(MenuObject *obj) {
+void Mouse::addMenuObject(byte *ptr) {
 	assert(_totalTemp < TOTAL_engine_pockets);
-	memcpy(&_tempList[_totalTemp], obj, sizeof(MenuObject));
+
+	Common::MemoryReadStream readS(ptr, 2 * sizeof(int32));
+
+	_tempList[_totalTemp].icon_resource = readS.readSint32LE();
+	_tempList[_totalTemp].luggage_resource = readS.readSint32LE();
 	_totalTemp++;
 }
 
 void Mouse::addSubject(int32 id, int32 ref) {
-	if (Logic::_scriptVars[IN_SUBJECT] == 0) {
+	uint32 in_subject = _vm->_logic->readVar(IN_SUBJECT);
+
+	if (in_subject == 0) {
 		// This is the start of the new subject list. Set the default
 		// repsonse id to zero in case we're never passed one.
 		_defaultResponseId = 0;
@@ -48,9 +55,9 @@
 		_defaultResponseId = ref;
 	} else {
 		debug(5, "fnAddSubject res %d, uid %d", id, ref);
-		_subjectList[Logic::_scriptVars[IN_SUBJECT]].res = id;
-		_subjectList[Logic::_scriptVars[IN_SUBJECT]].ref = ref;
-		Logic::_scriptVars[IN_SUBJECT]++;
+		_subjectList[in_subject].res = id;
+		_subjectList[in_subject].ref = ref;
+		_vm->_logic->writeVar(IN_SUBJECT, in_subject + 1);
 	}
 }
 
@@ -72,10 +79,7 @@
 	// Run the 'build_menu' script in the 'menu_master' object. This will
 	// register all carried menu objects.
 
-	uint32 null_pc = 0;
-	char *menuScript = (char *)_vm->_resman->openResource(MENU_MASTER_OBJECT);
-	_vm->_logic->runScript(menuScript, menuScript, &null_pc);
-	_vm->_resman->closeResource(MENU_MASTER_OBJECT);
+	_vm->_logic->runResScript(MENU_MASTER_OBJECT, 0);
 
 	// Create a new master list based on the old master inventory list and
 	// the new temporary inventory list. The purpose of all this is, as
@@ -139,23 +143,26 @@
 		if (res) {
 			bool icon_coloured;
 
+			uint32 object_held = _vm->_logic->readVar(OBJECT_HELD);
+			uint32 combine_base = _vm->_logic->readVar(COMBINE_BASE);
+
 			if (_examiningMenuIcon) {
 				// When examining an object, that object is
 				// coloured. The rest are greyed out.
-				icon_coloured = (res == Logic::_scriptVars[OBJECT_HELD]);
-			} else if (Logic::_scriptVars[COMBINE_BASE]) {
+				icon_coloured = (res == object_held);
+			} else if (combine_base) {
 				// When combining two menu object (i.e. using
 				// one on another), both are coloured. The rest
 				// are greyed out.
-				icon_coloured = (res == Logic::_scriptVars[OBJECT_HELD] || res == Logic::_scriptVars[COMBINE_BASE]);
+				icon_coloured = (res == object_held || combine_base);
 			} else {
 				// If an object is selected but we are not yet
 				// doing anything with it, the selected object
 				// is greyed out. The rest are coloured.
-				icon_coloured = (res != Logic::_scriptVars[OBJECT_HELD]);
+				icon_coloured = (res != object_held);
 			}
 
-			icon = _vm->_resman->openResource(res) + sizeof(StandardHeader);
+			icon = _vm->_resman->openResource(res) + ResHeader::size();
 
 			// The coloured icon is stored directly after the
 			// greyed out one.
@@ -190,12 +197,12 @@
 	// rest will grey out.
 
 	for (int i = 0; i < ARRAYSIZE(icon_list); i++) {
-		byte *icon = _vm->_resman->openResource(icon_list[i]) + sizeof(StandardHeader);
+		byte *icon = _vm->_resman->openResource(icon_list[i]) + ResHeader::size();
 
 		// The only case when an icon is grayed is when the player
 		// is dead. Then SAVE is not available.
 
-		if (!Logic::_scriptVars[DEAD] || icon_list[i] != SAVE_ICON)
+		if (!_vm->_logic->readVar(DEAD) || icon_list[i] != SAVE_ICON)
 			icon += (RDMENU_ICONWIDE * RDMENU_ICONDEEP);
 
 		setMenuIcon(RDMENU_TOP, i, icon);

Index: icons.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/icons.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- icons.h	18 Oct 2005 01:30:25 -0000	1.15
+++ icons.h	29 Oct 2005 21:24:53 -0000	1.16
@@ -29,19 +29,11 @@
 
 // define these in a script and then register them with the system
 
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
 struct MenuObject {
 	int32 icon_resource;	// icon graphic graphic
 	int32 luggage_resource;	// luggage icon resource (for attaching to
 				// mouse pointer)
-} GCC_PACK;
-
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
+};
 
 } // End of namespace Sword2
 

Index: interpreter.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/interpreter.cpp,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- interpreter.cpp	18 Oct 2005 01:30:25 -0000	1.57
+++ interpreter.cpp	29 Oct 2005 21:24:53 -0000	1.58
@@ -25,6 +25,7 @@
 #include "sword2/interpreter.h"
 #include "sword2/logic.h"
 #include "sword2/memory.h"
+#include "sword2/resman.h"
 
 namespace Sword2 {
 
@@ -205,18 +206,58 @@
 
 #define pop() (assert(stackPtr < ARRAYSIZE(stack)), stack[--stackPtr])
 
-uint32 *Logic::_scriptVars = NULL;
+int Logic::runResScript(uint32 scriptRes, uint32 offset) {
+	byte *scriptAddr;
+	int result;
 
-int Logic::runScript(char *scriptData, char *objectData, uint32 *offset) {
+	scriptAddr = _vm->_resman->openResource(scriptRes);
+	result = runScript(scriptAddr, scriptAddr, offset);
+	_vm->_resman->closeResource(scriptRes);
+
+	return result;
+}
+
+int Logic::runResObjScript(uint32 scriptRes, uint32 objRes, uint32 offset) {
+	byte *scriptAddr, *objAddr;
+	int result;
+
+	scriptAddr = _vm->_resman->openResource(scriptRes);
+	objAddr = _vm->_resman->openResource(objRes);
+	result = runScript(scriptAddr, objAddr, offset);
+	_vm->_resman->closeResource(objRes);
+	_vm->_resman->closeResource(scriptRes);
+
+	return result;
+}
+
+int Logic::runScript(byte *scriptData, byte *objectData, uint32 offset) {
+	byte pc[4];
+
+	WRITE_LE_UINT32(pc, offset);
+	return runScript2(scriptData, objectData, pc);
+}
+
+// This form of the runScript function is only called directly from
+// the processSession() function, which uses it to update the script PC in the
+// current object hub. For reasons which I do not understand, I couldn't get it
+// to work if I called the function first with a dummy offset variable, and
+// and then updated the object hub myself.
+
+int Logic::runScript2(byte *scriptData, byte *objectData, byte *offsetPtr) {
 	// Interestingly, unlike our BASS engine the stack is a local variable.
-	// This has some interesting implications which may or may not be
-	// necessary to the BS2 engine.
+	// I don't know whether or not this is relevant to the working of the
+	// BS2 engine.
 
 	int32 stack[STACK_SIZE];
 	int32 stackPtr = 0;
 
-	StandardHeader *header = (StandardHeader *)scriptData;
-	scriptData += sizeof(StandardHeader) + sizeof(ObjectHub);
+	uint32 offset = READ_LE_UINT32(offsetPtr);
+
+	ResHeader header;
+
+	header.read(scriptData);
+
+	scriptData += ResHeader::size() + ObjectHub::size();
 
 	// The script data format:
 	//	int32_TYPE	1		Size of variable space in bytes
@@ -231,25 +272,25 @@
 
 	// Get the start of variables and start of code
 
-	uint32 *localVars = (uint32 *)(scriptData + sizeof(int32));
-	char *code = scriptData + READ_LE_UINT32(scriptData) + sizeof(int32);
+	byte *localVars = scriptData + 4;
+	byte *code = scriptData + READ_LE_UINT32(scriptData) + 4;
 	uint32 noScripts = READ_LE_UINT32(code);
 
-	code += sizeof(int32);
+	code += 4;
 
-	const uint32 *offsetTable = (const uint32 *)code;
+	byte *offsetTable = code;
 
-	if (*offset < noScripts) {
-		ip = FROM_LE_32(offsetTable[*offset]);
-		scriptNumber = *offset;
-		debug(4, "Start script %d with offset %d", *offset, ip);
+	if (offset < noScripts) {
+		ip = READ_LE_UINT32(offsetTable + offset * 4);
+		scriptNumber = offset;
+		debug(4, "Start script %d with offset %d", offset, ip);
 	} else {
 		uint i;
 
-		ip = *offset;
+		ip = offset;
 
 		for (i = 1; i < noScripts; i++) {
-			if (FROM_LE_32(offsetTable[i]) >= ip)
+			if (READ_LE_UINT32(offsetTable + 4 * i) >= ip)
 				break;
 		}
 
@@ -265,23 +306,23 @@
 	bool checkElevatorBug = false;
 
 	if (scriptNumber == 2) {
-		if (strcmp((char *)header->name, "mop_73") == 0)
+		if (strcmp((char *)header.name, "mop_73") == 0)
 			checkMopBug = true;
-		else if (strcmp((char *)header->name, "titipoco_81") == 0)
+		else if (strcmp((char *)header.name, "titipoco_81") == 0)
 			checkPyramidBug = true;
-		else if (strcmp((char *)header->name, "lift_82") == 0)
+		else if (strcmp((char *)header.name, "lift_82") == 0)
 			checkElevatorBug = true;
 	}
 
-	code += noScripts * sizeof(int32);
+	code += noScripts * 4;
 
 	// Code should now be pointing at an identifier and a checksum
-	const char *checksumBlock = code;
+	byte *checksumBlock = code;
 
-	code += sizeof(int32) * 3;
+	code += 4 * 3;
 
 	if (READ_LE_UINT32(checksumBlock) != 12345678) {
-		error("Invalid script in object %s", header->name);
+		error("Invalid script in object %s", header.name);
 		return 0;
 	}
 
@@ -291,8 +332,8 @@
 	for (int i = 0; i < codeLen; i++)
 		checksum += (unsigned char) code[i];
 
-	if (checksum != (int32) READ_LE_UINT32(checksumBlock + 8)) {
-		debug(1, "Checksum error in object %s", header->name);
+	if (checksum != (int32)READ_LE_UINT32(checksumBlock + 8)) {
+		debug(1, "Checksum error in object %s", header.name);
 		// This could be bad, but there has been a report about someone
 		// who had problems running the German version because of
 		// checksum errors. Could there be a version where checksums
@@ -341,9 +382,9 @@
 			// So if his click hander finishes, and variable 913 is
 			// 1, we set it back to 0 manually.
 
-			if (checkPyramidBug && _scriptVars[913] == 1) {
+			if (checkPyramidBug && readVar(913) == 1) {
 				warning("Working around pyramid bug: Resetting Titipoco's state");
-				_scriptVars[913] = 0;
+				writeVar(913, 0);
 			}
 
 			// WORKAROUND: The not-so-known-but-should-be-dreaded
@@ -354,7 +395,7 @@
 			// examining it, the mouse cursor is removed but never
 			// restored.
 
-			if (checkElevatorBug && Logic::_scriptVars[RIGHT_BUTTON]) {
+			if (checkElevatorBug && readVar(RIGHT_BUTTON)) {
 				warning("Working around elevator bug: Restoring mouse pointer");
 				fnAddHuman(NULL);
 			}
@@ -363,7 +404,7 @@
 			break;
 		case CP_QUIT:
 			// Quit out for a cycle
-			*offset = ip;
+			WRITE_LE_UINT32(offsetPtr, ip);
 			debug(9, "CP_QUIT");
 			return 0;
 		case CP_TERMINATE:
@@ -388,16 +429,14 @@
 		case CP_PUSH_LOCAL_VAR32:
 			// Push the contents of a local variable
 			Read16ip(parameter);
-			parameter /= 4;
-			push(localVars[parameter]);
-			debug(9, "CP_PUSH_LOCAL_VAR32: localVars[%d] => %d", parameter, localVars[parameter]);
+			push(READ_LE_UINT32(localVars + parameter));
+			debug(9, "CP_PUSH_LOCAL_VAR32: localVars[%d] => %d", parameter / 4, READ_LE_UINT32(localVars + parameter));
 			break;
 		case CP_PUSH_GLOBAL_VAR32:
 			// Push a global variable
-			assert(_scriptVars);
 			Read16ip(parameter);
-			push(_scriptVars[parameter]);
-			debug(9, "CP_PUSH_GLOBAL_VAR32: scriptVars[%d] => %d", parameter, _scriptVars[parameter]);
+			push(readVar(parameter));
+			debug(9, "CP_PUSH_GLOBAL_VAR32: scriptVars[%d] => %d", parameter, readVar(parameter));
 			break;
 		case CP_PUSH_LOCAL_ADDR:
 			// Push the address of a local variable
@@ -410,10 +449,8 @@
 			// CP_PUSH_DEREFERENCED_STRUCTURE opcode.
 
 			Read16ip(parameter);
-			parameter /= 4;
-			ptr = (byte *)&localVars[parameter];
-			push_ptr(ptr);
-			debug(9, "CP_PUSH_LOCAL_ADDR: &localVars[%d] => %p", parameter, ptr);
+			push_ptr(localVars + parameter);
+			debug(9, "CP_PUSH_LOCAL_ADDR: &localVars[%d] => %p", parameter / 4, localVars + parameter);
 			break;
 		case CP_PUSH_STRING:
 			// Push the address of a string on to the stack
@@ -421,7 +458,7 @@
 			Read8ip(parameter);
 
 			// ip now points to the string
-			ptr = (byte *)(code + ip);
+			ptr = code + ip;
 			push_ptr(ptr);
 			debug(9, "CP_PUSH_STRING: \"%s\"", ptr);
 			ip += (parameter + 1);
@@ -429,17 +466,16 @@
 		case CP_PUSH_DEREFERENCED_STRUCTURE:
 			// Push the address of a dereferenced structure
 			Read32ip(parameter);
-			ptr = (byte *)(objectData + sizeof(int32) + sizeof(StandardHeader) + sizeof(ObjectHub) + parameter);
+			ptr = objectData + 4 + ResHeader::size() + ObjectHub::size() + parameter;
 			push_ptr(ptr);
 			debug(9, "CP_PUSH_DEREFERENCED_STRUCTURE: %d => %p", parameter, ptr);
 			break;
 		case CP_POP_LOCAL_VAR32:
 			// Pop a value into a local word variable
 			Read16ip(parameter);
-			parameter /= 4;
 			value = pop();
-			localVars[parameter] = value;
-			debug(9, "CP_POP_LOCAL_VAR32: localVars[%d] = %d", parameter, value);
+			WRITE_LE_UINT32(localVars + parameter, value);
+			debug(9, "CP_POP_LOCAL_VAR32: localVars[%d] = %d", parameter / 4, value);
 			break;
 		case CP_POP_GLOBAL_VAR32:
 			// Pop a global variable
@@ -472,41 +508,39 @@
 			// use that as the signal that Nico's state needs to be
 			// updated as well.
 
-			if (checkMopBug && parameter == 1017 && _scriptVars[1003] != 2) {
+			if (checkMopBug && parameter == 1017 && readVar(1003) != 2) {
 				warning("Working around mop bug: Setting Nico's state");
-				_scriptVars[1003] = 2;
+				writeVar(1003, 2);
 			}
 
-			_scriptVars[parameter] = value;
+			writeVar(parameter, value);
 			debug(9, "CP_POP_GLOBAL_VAR32: scriptsVars[%d] = %d", parameter, value);
 			break;
 		case CP_ADDNPOP_LOCAL_VAR32:
 			Read16ip(parameter);
-			parameter /= 4;
-			value = pop();
-			localVars[parameter] += value;
-			debug(9, "CP_ADDNPOP_LOCAL_VAR32: localVars[%d] += %d => %d", parameter, value, localVars[parameter]);
+			value = READ_LE_UINT32(localVars + parameter) + pop();
+			WRITE_LE_UINT32(localVars + parameter, value);
+			debug(9, "CP_ADDNPOP_LOCAL_VAR32: localVars[%d] => %d", parameter / 4, value);
 			break;
 		case CP_SUBNPOP_LOCAL_VAR32:
 			Read16ip(parameter);
-			parameter /= 4;
-			value = pop();
-			localVars[parameter] -= value;
-			debug(9, "CP_SUBNPOP_LOCAL_VAR32: localVars[%d] -= %d => %d", parameter, value, localVars[parameter]);
+			value = READ_LE_UINT32(localVars + parameter) - pop();
+			WRITE_LE_UINT32(localVars + parameter, value);
+			debug(9, "CP_SUBNPOP_LOCAL_VAR32: localVars[%d] => %d", parameter / 4, value);
 			break;
 		case CP_ADDNPOP_GLOBAL_VAR32:
 			// Add and pop a global variable
 			Read16ip(parameter);
-			value = pop();
-			_scriptVars[parameter] += value;
-			debug(9, "CP_ADDNPOP_GLOBAL_VAR32: scriptVars[%d] += %d => %d", parameter, value, _scriptVars[parameter]);
+			value = readVar(parameter) + pop();
+			writeVar(parameter, value);
+			debug(9, "CP_ADDNPOP_GLOBAL_VAR32: scriptVars[%d] => %d", parameter, value);
 			break;
 		case CP_SUBNPOP_GLOBAL_VAR32:
 			// Sub and pop a global variable
 			Read16ip(parameter);
-			value = pop();
-			_scriptVars[parameter] -= value;
-			debug(9, "CP_SUBNPOP_GLOBAL_VAR32: scriptVars[%d] -= %d => %d", parameter, value, _scriptVars[parameter]);
+			value = readVar(parameter) - pop();
+			writeVar(parameter, value);
+			debug(9, "CP_SUBNPOP_GLOBAL_VAR32: scriptVars[%d] => %d", parameter, value);
 			break;
 
 		// Jump opcodes
@@ -516,7 +550,7 @@
 			Read32ipLeaveip(parameter);
 			value = pop();
 			if (!value) {
-				ip += sizeof(int32);
+				ip += 4;
 				debug(9, "CP_SKIPONTRUE: %d (IS FALSE (NOT SKIPPED))", parameter);
 			} else {
 				ip += parameter;
@@ -528,7 +562,7 @@
 			Read32ipLeaveip(parameter);
 			value = pop();
 			if (value) {
-				ip += sizeof(int32);
+				ip += 4;
 				debug(9, "CP_SKIPONFALSE: %d (IS TRUE (NOT SKIPPED))", parameter);
 			} else {
 				ip += parameter;
@@ -549,13 +583,13 @@
 			// Search the cases
 			foundCase = false;
 			for (i = 0; i < caseCount && !foundCase; i++) {
-				if (value == (int32) READ_LE_UINT32(code + ip)) {
+				if (value == (int32)READ_LE_UINT32(code + ip)) {
 					// We have found the case, so lets
 					// jump to it
 					foundCase = true;
-					ip += READ_LE_UINT32(code + ip + sizeof(int32));
+					ip += READ_LE_UINT32(code + ip + 4);
 				} else
-					ip += sizeof(int32) * 2;
+					ip += 4 * 2;
 			}
 
 			// If we found no matching case then use the default
@@ -585,7 +619,7 @@
 			switch (retVal & 7) {
 			case IR_STOP:
 				// Quit out for a cycle
-				*offset = ip;
+				WRITE_LE_UINT32(offsetPtr, ip);
 				return 0;
 			case IR_CONT:
 				// Continue as normal
@@ -596,11 +630,11 @@
 			case IR_REPEAT:
 				// Return setting offset to start of this
 				// function call
-				*offset = savedStartOfMcode;
+				WRITE_LE_UINT32(offsetPtr, savedStartOfMcode);
 				return 0;
 			case IR_GOSUB:
 				// that's really neat
-				*offset = ip;
+				WRITE_LE_UINT32(offsetPtr, ip);
 				return 2;
 			default:
 				error("Bad return code (%d) from '%s'", retVal & 7, opcodes[parameter].desc);

Index: interpreter.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/interpreter.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- interpreter.h	18 Oct 2005 01:30:25 -0000	1.18
+++ interpreter.h	29 Oct 2005 21:24:53 -0000	1.19
@@ -36,10 +36,10 @@
 // Get parameter fix so that the playstation version can handle words not on
 // word boundaries
 
-#define Read8ip(var)		{ var = *((const int8 *)(code + ip)); ip++; }
-#define Read16ip(var)		{ var = (int16) READ_LE_UINT16(code + ip); ip += sizeof(int16); }
-#define Read32ip(var)		{ var = (int32) READ_LE_UINT32(code + ip); ip += sizeof(int32); }
-#define Read32ipLeaveip(var)	{ var = (int32) READ_LE_UINT32(code + ip); }
+#define Read8ip(var)		{ var = code[ip]; ip++; }
+#define Read16ip(var)		{ var = (int16)READ_LE_UINT16(code + ip); ip += 2; }
+#define Read32ip(var)		{ var = (int32)READ_LE_UINT32(code + ip); ip += 4; }
+#define Read32ipLeaveip(var)	{ var = (int32)READ_LE_UINT32(code + ip); }
 
 enum {
 	// Compiled tokens

Index: layers.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/layers.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- layers.cpp	18 Oct 2005 01:30:25 -0000	1.39
+++ layers.cpp	29 Oct 2005 21:24:53 -0000	1.40
@@ -52,7 +52,7 @@
 	_vm->_sound->clearFxQueue();
 	waitForFade();
 
-	debug(1, "CHANGED TO LOCATION \"%s\"", _vm->fetchObjectName(res, buf));
+	debug(1, "CHANGED TO LOCATION \"%s\"", _vm->_resman->fetchName(res, buf));
 
 	// if last screen was using a shading mask (see below)
 	if (_thisScreen.mask_flag) {
@@ -72,36 +72,40 @@
 	// each cycle
 
 	byte *file = _vm->_resman->openResource(_thisScreen.background_layer_id);
-	ScreenHeader *screen_head = _vm->fetchScreenHeader(file);
+	ScreenHeader screen_head;
+
+	screen_head.read(_vm->fetchScreenHeader(file));
 
 	// set number of special sort layers
-	_thisScreen.number_of_layers = screen_head->noLayers;
-	_thisScreen.screen_wide = screen_head->width;
-	_thisScreen.screen_deep = screen_head->height;
+	_thisScreen.number_of_layers = screen_head.noLayers;
+	_thisScreen.screen_wide = screen_head.width;
+	_thisScreen.screen_deep = screen_head.height;
 
-	debug(2, "layers=%d width=%d depth=%d", screen_head->noLayers, screen_head->width, screen_head->height);
+	debug(2, "layers=%d width=%d depth=%d", screen_head.noLayers, screen_head.width, screen_head.height);
 
 	// initialise the driver back buffer
-	setLocationMetrics(screen_head->width, screen_head->height);
+	setLocationMetrics(screen_head.width, screen_head.height);
 
-	for (i = 0; i < screen_head->noLayers; i++) {
+	for (i = 0; i < screen_head.noLayers; i++) {
 		debug(3, "init layer %d", i);
 
-		LayerHeader *layer = _vm->fetchLayerHeader(file, i);
+		LayerHeader layer;
+
+		layer.read(_vm->fetchLayerHeader(file, i));
 
 		// Add the layer to the sort list. We only provide just enough
 		// information so that it's clear that it's a layer, and where
 		// to sort it in relation to other things in the list.
 
 		_sortList[i].layer_number = i + 1;
-		_sortList[i].sort_y = layer->y + layer->height;
+		_sortList[i].sort_y = layer.y + layer.height;
 	}
 
 	// reset scroll offsets
 	_thisScreen.scroll_offset_x = 0;
 	_thisScreen.scroll_offset_y = 0;
 
-	if (screen_head->width > _screenWide || screen_head->height > _screenDeep) {
+	if (screen_head.width > _screenWide || screen_head.height > _screenDeep) {
 		// The layer is larger than the physical screen. Switch on
 		// scrolling. (2 means first time on screen)
 		_thisScreen.scroll_flag = 2;
@@ -112,8 +116,8 @@
 		// Calculate the maximum scroll offsets to prevent scrolling
 		// off the edge. The minimum offsets are both 0.
 
-		_thisScreen.max_scroll_offset_x = screen_head->width - _screenWide;
-		_thisScreen.max_scroll_offset_y = screen_head->height - (_screenDeep - (MENUDEEP * 2));
+		_thisScreen.max_scroll_offset_x = screen_head.width - _screenWide;
+		_thisScreen.max_scroll_offset_y = screen_head.height - (_screenDeep - (MENUDEEP * 2));
 	} else {
 		// The later fits on the phyiscal screen. Switch off scrolling.
 		_thisScreen.scroll_flag = 0;
@@ -129,15 +133,17 @@
 
 	// shading mask
 
-	MultiScreenHeader *screenLayerTable = (MultiScreenHeader *)(file + sizeof(StandardHeader));
+	MultiScreenHeader screenLayerTable;
 
-	if (screenLayerTable->maskOffset) {
+	screenLayerTable.read(file + ResHeader::size());
+
+	if (screenLayerTable.maskOffset) {
 	 	SpriteInfo spriteInfo;
 
 		spriteInfo.x = 0;
 		spriteInfo.y = 0;
-		spriteInfo.w = screen_head->width;
-		spriteInfo.h = screen_head->height;
+		spriteInfo.w = screen_head.width;
+		spriteInfo.h = screen_head.height;
 		spriteInfo.scale = 0;
 		spriteInfo.scaledWidth = 0;
 		spriteInfo.scaledHeight = 0;
@@ -159,7 +165,7 @@
 	// Background parallax layers
 
 	for (i = 0; i < 2; i++) {
-		if (screenLayerTable->bg_parallax[i])
+		if (screenLayerTable.bg_parallax[i])
 			initialiseBackgroundLayer(_vm->fetchBackgroundParallaxLayer(file, i));
 		else
 			initialiseBackgroundLayer(NULL);
@@ -172,7 +178,7 @@
 	// Foreground parallax layers
 
 	for (i = 0; i < 2; i++) {
-		if (screenLayerTable->fg_parallax[i])
+		if (screenLayerTable.fg_parallax[i])
 			initialiseBackgroundLayer(_vm->fetchForegroundParallaxLayer(file, i));
 		else
 			initialiseBackgroundLayer(NULL);

Index: logic.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/logic.cpp,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- logic.cpp	18 Oct 2005 01:30:25 -0000	1.57
+++ logic.cpp	29 Oct 2005 21:24:53 -0000	1.58
@@ -26,8 +26,6 @@
 #include "sword2/router.h"
 #include "sword2/sound.h"
 
-#define LEVEL (_curObjectHub->logic_level)
-
 namespace Sword2 {
 
 Logic::Logic(Sword2Engine *vm) :
@@ -60,34 +58,37 @@
 	// processing on the current list
 
 	while (_pc != 0xffffffff) {
-		uint32 ret, script;
-		char *raw_script_ad;
+		byte *game_object_list, *head, *raw_script_ad, *raw_data_ad;
+		uint32 level, ret, script, id;
 
-		StandardHeader *head = (StandardHeader *)_vm->_resman->openResource(run_list);
-		assert(head->fileType == RUN_LIST);
+		game_object_list = _vm->_resman->openResource(run_list) + ResHeader::size();
 
-		uint32 *game_object_list = (uint32 *)(head + 1);
+		assert(_vm->_resman->fetchType(run_list) == RUN_LIST);
 
 		// read the next id
-		uint id = game_object_list[_pc++];
-		_scriptVars[ID] = id;
+		id = READ_LE_UINT32(game_object_list + 4 * _pc);
+		_pc++;
+
+		writeVar(ID, id);
 
 		_vm->_resman->closeResource(run_list);
 
-		if (!_scriptVars[ID]) {
+		if (!id) {
 			// End of list - end the session naturally
 			return 0;
 		}
 
-		head = (StandardHeader *)_vm->_resman->openResource(_scriptVars[ID]);
-		assert(head->fileType == GAME_OBJECT);
+		assert(_vm->_resman->fetchType(id) == GAME_OBJECT);
 
-		_curObjectHub = (ObjectHub *)(head + 1);
+		head = _vm->_resman->openResource(id);
+		_curObjectHub.setAddress(head + ResHeader::size());
+
+		level = _curObjectHub.getLogicLevel();
 
 		debug(5, "Level %d id(%d) pc(%d)",
-			LEVEL,
-			_curObjectHub->script_id[LEVEL],
-			_curObjectHub->script_pc[LEVEL]);
+			level,
+			_curObjectHub.getScriptId(level),
+			_curObjectHub.getScriptPc(level));
 
 		// Do the logic for this object. We keep going until a function
 		// says to stop - remember, system operations are run via
@@ -97,32 +98,34 @@
 			// There is a distinction between running one of our
 			// own scripts and that of another object.
 
-			script = _curObjectHub->script_id[LEVEL];
+			level = _curObjectHub.getLogicLevel();
+			script = _curObjectHub.getScriptId(level);
 
-			if (script / SIZE == _scriptVars[ID]) {
+			if (script / SIZE == readVar(ID)) {
 				// It's our own script
 
 				debug(5, "Run script %d pc=%d",
 					script / SIZE,
-					_curObjectHub->script_pc[LEVEL]);
+					_curObjectHub.getScriptPc(level));
 
 				// This is the script data. Script and data
 				// object are the same.
 
-				raw_script_ad = (char *)head;
+				raw_script_ad = head;
 
-				ret = runScript(raw_script_ad, raw_script_ad, &_curObjectHub->script_pc[LEVEL]);
+				ret = runScript2(raw_script_ad, raw_script_ad, _curObjectHub.getScriptPcPtr(level));
 			} else {
 				// We're running the script of another game
 				// object - get our data object address.
 
-				StandardHeader *far_head = (StandardHeader *)_vm->_resman->openResource(script / SIZE);
-				assert(far_head->fileType == GAME_OBJECT || far_head->fileType == SCREEN_MANAGER);
+				uint8 type = _vm->_resman->fetchType(script / SIZE);
 
-				raw_script_ad = (char *)far_head;
-				char *raw_data_ad = (char *)head;
+				assert(type == GAME_OBJECT || type == SCREEN_MANAGER);
 
-				ret = runScript(raw_script_ad, raw_data_ad, &_curObjectHub->script_pc[LEVEL]);
+				raw_script_ad = _vm->_resman->openResource(script / SIZE);
+				raw_data_ad = head;
+
+				ret = runScript2(raw_script_ad, raw_data_ad, _curObjectHub.getScriptPcPtr(level));
 
 				_vm->_resman->closeResource(script / SIZE);
 
@@ -131,10 +134,12 @@
 			}
 
 			if (ret == 1) {
+				level = _curObjectHub.getLogicLevel();
+
 				// The script finished - drop down a level
-				if (LEVEL)
-					LEVEL--;
-				else {
+				if (level) {
+					_curObjectHub.setLogicLevel(level - 1);
+				} else {
 					// Hmmm, level 0 terminated :-| Let's
 					// be different this time and simply
 					// let it restart next go :-)
@@ -145,7 +150,7 @@
 					debug(5, "object %d script 0 terminated!", id);
 
 					// reset to rerun, drop out for a cycle
-					_curObjectHub->script_pc[LEVEL] = _curObjectHub->script_id[LEVEL] & 0xffff;
+					_curObjectHub.setScriptPc(level, _curObjectHub.getScriptId(level) & 0xffff);
 					ret = 0;
 				}
 			} else if (ret > 2) {
@@ -163,18 +168,17 @@
 		// Clear any syncs that were waiting for this character - it
 		// has used them or now looses them
 
-		clearSyncs(_scriptVars[ID]);
+		clearSyncs(readVar(ID));
 
 		if (_pc != 0xffffffff) {
 			// The session is still valid so run the graphics/mouse
 			// service script
-			uint32 null_pc = 0;
-			runScript(raw_script_ad, raw_script_ad, &null_pc);
+			runScript(raw_script_ad, raw_script_ad, 0);
 		}
 
 		// and that's it so close the object resource
 
-		_vm->_resman->closeResource(_scriptVars[ID]);
+		_vm->_resman->closeResource(readVar(ID));
 	}
 
 	// Leaving a room so remove all ids that must reboot correctly. Then
@@ -198,7 +202,7 @@
 	_pc = 0xffffffff;
 
 	// Reset now in case we double-clicked an exit prior to changing screen
-	_scriptVars[EXIT_FADING] = 0;
+	writeVar(EXIT_FADING, 0);
 
 	// We're trashing the list - presumably to change room. In theory,
 	// sync waiting in the list could be left behind and never removed -
@@ -228,9 +232,9 @@
 	debug(5, "new pc = %d", new_script & 0xffff);
 
 	// going up a level - and we'll keep going this cycle
-	LEVEL++;
+	_curObjectHub.setLogicLevel(_curObjectHub.getLogicLevel() + 1);
 
-	assert(LEVEL < 3);	// Can be 0, 1, 2
+	assert(_curObjectHub.getLogicLevel() < 3);	// Can be 0, 1, 2
 	logicReplace(new_script);
 }
 
@@ -239,7 +243,7 @@
  */
 
 void Logic::logicOne(uint32 new_script) {
-	LEVEL = 1;
+	_curObjectHub.setLogicLevel(1);
 	logicReplace(new_script);
 }
 
@@ -249,8 +253,10 @@
  */
 
 void Logic::logicReplace(uint32 new_script) {
-	_curObjectHub->script_id[LEVEL] = new_script;
-	_curObjectHub->script_pc[LEVEL] = new_script & 0xffff;
+	uint32 level = _curObjectHub.getLogicLevel();
+
+	_curObjectHub.setScriptId(level, new_script);
+	_curObjectHub.setScriptPc(level, new_script & 0xffff);
 }
 
 void Logic::resetKillList() {

Index: logic.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/logic.h,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- logic.h	18 Oct 2005 01:30:25 -0000	1.48
+++ logic.h	29 Oct 2005 21:24:53 -0000	1.49
@@ -69,7 +69,7 @@
 	uint32 _pc;
 
 	// each object has one of these tacked onto the beginning
-	ObjectHub *_curObjectHub;
+	ObjectHub _curObjectHub;
 
 	EventUnit _eventList[MAX_events];
 
@@ -119,18 +119,21 @@
 	bool wantSpeechForLine(uint32 wavId);
 
 	// Set by fnPassMega()
-	ObjectMega _engineMega;
+	byte _engineMega[56];
 
 public:
 	Logic(Sword2Engine *vm);
 	~Logic();
 
 	EventUnit *getEventList() { return _eventList; }
+	byte *getEngineMega() { return _engineMega; }
 
-	ObjectMega *getEngineMega() { return &_engineMega; }
+	byte _saveLogic[8];
+	byte _saveGraphic[12];
+	byte _saveMega[56];
 
 	// Point to the global variable data
-	static uint32 *_scriptVars;
+	byte *_scriptVars;
 
 	// "TEXT" - current official text line number - will match the wav
 	// filenames
@@ -140,7 +143,18 @@
 	// so speech text cleared when running a new start-script
 	uint32 _speechTextBlocNo;
 
-	int runScript(char *scriptData, char *objectData, uint32 *offset);
+	uint32 readVar(int n) {
+		return READ_LE_UINT32(_scriptVars + 4 * n);
+	}
+
+	void writeVar(int n, uint32 value) {
+		WRITE_LE_UINT32(_scriptVars + 4 * n, value);
+	}
+
+	int runResScript(uint32 scriptRes, uint32 offset);
+	int runResObjScript(uint32 scriptRes, uint32 objRes, uint32 offset);
+	int runScript(byte *scriptData, byte *objectData, uint32 offset);
+	int runScript2(byte *scriptData, byte *objectData, byte *offset);
 
 	void sendEvent(uint32 id, uint32 interact_id);
 	void setPlayerActionEvent(uint32 id, uint32 interact_id);

Index: maketext.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/maketext.cpp,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- maketext.cpp	18 Oct 2005 01:30:25 -0000	1.51
+++ maketext.cpp	29 Oct 2005 21:24:53 -0000	1.52
@@ -213,22 +213,24 @@
 	// Allocate memory for the text sprite
 
 	uint32 sizeOfSprite = spriteWidth * spriteHeight;
-	byte *textSprite = (byte *)malloc(sizeof(FrameHeader) + sizeOfSprite);
+	byte *textSprite = (byte *)malloc(FrameHeader::size() + sizeOfSprite);
 
 	// At this stage, textSprite points to an unmovable memory block. Set
 	// up the frame header.
 
-	FrameHeader *frameHeadPtr = (FrameHeader *)textSprite;
+	FrameHeader frame_head;
 
-	frameHeadPtr->compSize = 0;
-	frameHeadPtr->width = spriteWidth;
-	frameHeadPtr->height = spriteHeight;
+	frame_head.compSize = 0;
+	frame_head.width = spriteWidth;
+	frame_head.height = spriteHeight;
+
+	frame_head.write(textSprite);
 
 	debug(4, "Text sprite size: %ux%u", spriteWidth, spriteHeight);
 
 	// Clear the entire sprite to make it transparent.
 
-	byte *linePtr = textSprite + sizeof(FrameHeader);
+	byte *linePtr = textSprite + FrameHeader::size();
 	memset(linePtr, 0, sizeOfSprite);
 
 	byte *charSet = _vm->_resman->openResource(fontRes);
@@ -246,11 +248,13 @@
 		// width minus the 'overlap'
 
 		for (uint j = 0; j < line[i].length; j++) {
-			FrameHeader *charPtr = findChar(sentence[pos++], charSet);
+			byte *charPtr = findChar(sentence[pos++], charSet);
 
-			assert(charPtr->height == char_height);
+			frame_head.read(charPtr);
+
+			assert(frame_head.height == char_height);
 			copyChar(charPtr, spritePtr, spriteWidth, pen);
-			spritePtr += charPtr->width + _charSpacing;
+			spritePtr += frame_head.width + _charSpacing;
 		}
 
 		// Skip space at end of last word in this line
@@ -273,11 +277,12 @@
 uint16 FontRenderer::charWidth(byte ch, uint32 fontRes) {
 	byte *charSet = _vm->_resman->openResource(fontRes);
 
-	FrameHeader *charFrame = findChar(ch, charSet);
-	uint16 width = charFrame->width;
+	FrameHeader frame_head;
 
+	frame_head.read(findChar(ch, charSet));
 	_vm->_resman->closeResource(fontRes);
-	return width;
+
+	return frame_head.width;
 }
 
 /**
@@ -293,11 +298,12 @@
 uint16 FontRenderer::charHeight(uint32 fontRes) {
 	byte *charSet = _vm->_resman->openResource(fontRes);
 
-	FrameHeader *charFrame = findChar(FIRST_CHAR, charSet);
-	uint16 height = charFrame->height;
+	FrameHeader frame_head;
 
+	frame_head.read(findChar(FIRST_CHAR, charSet));
 	_vm->_resman->closeResource(fontRes);
-	return height;
+
+	return frame_head.height;
 }
 
 /**
@@ -307,7 +313,7 @@
  *         'dud' character (chequered flag)
  */
 
-FrameHeader* FontRenderer::findChar(byte ch, byte *charSet) {
+byte *FontRenderer::findChar(byte ch, byte *charSet) {
 	if (ch < FIRST_CHAR)
 		ch = DUD;
 	return _vm->fetchFrameHeader(charSet, ch - FIRST_CHAR);
@@ -323,16 +329,20 @@
  *                    LETTER_COL to pen.
  */
 
-void FontRenderer::copyChar(FrameHeader *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen) {
-	byte *source = (byte *)charPtr + sizeof(FrameHeader);
+void FontRenderer::copyChar(byte *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen) {
+	FrameHeader frame;
+
+	frame.read(charPtr);
+
+	byte *source = charPtr + FrameHeader::size();
 	byte *rowPtr = spritePtr;
 
-	for (uint i = 0; i < charPtr->height; i++) {
+	for (uint i = 0; i < frame.height; i++) {
 		byte *dest = rowPtr;
 
 		if (pen) {
 			// Use the specified colours
-			for (uint j = 0; j < charPtr->width; j++) {
+			for (uint j = 0; j < frame.width; j++) {
 				switch (*source++) {
 				case LETTER_COL:
 					*dest = pen;
@@ -355,8 +365,8 @@
 			// Pen is zero, so just copy character sprites
 			// directly into text sprite without remapping colours.
 			// Apparently overlapping is never considered here?
-			memcpy(dest, source, charPtr->width);
-			source += charPtr->width;
+			memcpy(dest, source, frame.width);
+			source += frame.width;
 		}
 		rowPtr += spriteWidth;
 	}
@@ -387,37 +397,39 @@
 	// without margin checking - used for debug text
 
 	if (justification != NO_JUSTIFICATION) {
-		FrameHeader *frame_head = (FrameHeader *)_blocList[i].text_mem;
+		FrameHeader frame_head;
+
+		frame_head.read(_blocList[i].text_mem);
 
 		switch (justification) {
 		case POSITION_AT_CENTRE_OF_BASE:
 			// This one is always used for SPEECH TEXT; possibly
 			// also for pointer text
-			x -= (frame_head->width / 2);
-			y -= frame_head->height;
+			x -= (frame_head.width / 2);
+			y -= frame_head.height;
 			break;
 		case POSITION_AT_CENTRE_OF_TOP:
-			x -= (frame_head->width / 2);
+			x -= (frame_head.width / 2);
 			break;
 		case POSITION_AT_LEFT_OF_TOP:
 			// The given coords are already correct for this!
 			break;
 		case POSITION_AT_RIGHT_OF_TOP:
-			x -= frame_head->width;
+			x -= frame_head.width;
 			break;
 		case POSITION_AT_LEFT_OF_BASE:
-			y -= frame_head->height;
+			y -= frame_head.height;
 			break;
 		case POSITION_AT_RIGHT_OF_BASE:
-			x -= frame_head->width;
-			y -= frame_head->height;
+			x -= frame_head.width;
+			y -= frame_head.height;
 			break;
 		case POSITION_AT_LEFT_OF_CENTRE:
-			y -= (frame_head->height / 2);
+			y -= (frame_head.height / 2);
 			break;
 		case POSITION_AT_RIGHT_OF_CENTRE:
-			x -= frame_head->width;
-			y -= (frame_head->height) / 2;
+			x -= frame_head.width;
+			y -= (frame_head.height) / 2;
 			break;
 		}
 
@@ -425,9 +437,9 @@
 		// remember - it's RDSPR_DISPLAYALIGN
 
 		uint16 text_left_margin = TEXT_MARGIN;
-		uint16 text_right_margin = 640 - TEXT_MARGIN - frame_head->width;
+		uint16 text_right_margin = 640 - TEXT_MARGIN - frame_head.width;
 		uint16 text_top_margin = TEXT_MARGIN;
-		uint16 text_bottom_margin = 400 - TEXT_MARGIN - frame_head->height;
+		uint16 text_bottom_margin = 400 - TEXT_MARGIN - frame_head.height;
 
 		// Move if too far left or too far right
 
@@ -460,19 +472,21 @@
 void FontRenderer::printTextBlocs() {
 	for (uint i = 0; i < MAX_text_blocs; i++) {
 		if (_blocList[i].text_mem) {
-			FrameHeader *frame = (FrameHeader *)_blocList[i].text_mem;
+			FrameHeader frame_head;
 			SpriteInfo spriteInfo;
 
+			frame_head.read(_blocList[i].text_mem);
+
 			spriteInfo.x = _blocList[i].x;
 			spriteInfo.y = _blocList[i].y;
-			spriteInfo.w = frame->width;
-			spriteInfo.h = frame->height;
+			spriteInfo.w = frame_head.width;
+			spriteInfo.h = frame_head.height;
 			spriteInfo.scale = 0;
 			spriteInfo.scaledWidth = 0;
 			spriteInfo.scaledHeight = 0;
 			spriteInfo.type = _blocList[i].type;
 			spriteInfo.blend = 0;
-			spriteInfo.data = _blocList[i].text_mem + sizeof(FrameHeader);
+			spriteInfo.data = _blocList[i].text_mem + FrameHeader::size();
 			spriteInfo.colourTable = 0;
 
 			uint32 rv = _vm->_screen->drawSprite(&spriteInfo);
@@ -528,7 +542,7 @@
 	//
 	// But we get it from the text resource instead.
 
-	if (Logic::_scriptVars[DEMO])
+	if (_logic->readVar(DEMO))
 		textLine = (char *)fetchTextLine(textFile, 451) + 2;
 	else
 		textLine = (char *)fetchTextLine(textFile, 54) + 2;

Index: maketext.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/maketext.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- maketext.h	18 Oct 2005 01:30:25 -0000	1.19
+++ maketext.h	29 Oct 2005 21:24:53 -0000	1.20
@@ -91,8 +91,8 @@
 	byte *buildTextSprite(byte *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines);
 	uint16 charWidth(byte ch, uint32 fontRes);
 	uint16 charHeight(uint32 fontRes);
-	FrameHeader* findChar(byte ch, byte *charSet);
-	void copyChar(FrameHeader *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen);
+	byte *findChar(byte ch, byte *charSet);
+	void copyChar(byte *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen);
 
 public:
 	FontRenderer(Sword2Engine *vm) : _vm(vm) {

Index: mouse.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/mouse.cpp,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -r1.76 -r1.77
--- mouse.cpp	18 Oct 2005 01:30:25 -0000	1.76
+++ mouse.cpp	29 Oct 2005 21:24:53 -0000	1.77
@@ -74,9 +74,8 @@
 	_playerActivityDelay = 0;
 	_realLuggageItem = 0;
 
-	_mouseSprite = NULL;
-	_mouseAnim = NULL;
-	_luggageAnim = NULL;
+	_mouseAnim.data = NULL;
+	_luggageAnim.data = NULL;
 
 	// For the menus
 	_totalTemp = 0;
@@ -103,8 +102,8 @@
 }
 
 Mouse::~Mouse() {
-	free(_mouseAnim);
-	free(_luggageAnim);
+	free(_mouseAnim.data);
+	free(_luggageAnim.data);
 	for (int i = 0; i < 2; i++)
 		for (int j = 0; j < RDMENU_MAXPOCKETS; j++)
 			free(_icons[i][j]);
@@ -128,26 +127,30 @@
 	_curMouse = 0;
 }
 
-void Mouse::registerMouse(ObjectMouse *ob_mouse, BuildUnit *build_unit) {
-	if (!ob_mouse->pointer)
-		return;
-
+void Mouse::registerMouse(byte *ob_mouse, BuildUnit *build_unit) {
 	assert(_curMouse < TOTAL_mouse_list);
 
+	ObjectMouse mouse;
+
+	mouse.read(ob_mouse);
+
+	if (!mouse.pointer)
+		return;
+
 	if (build_unit) {
 		_mouseList[_curMouse].rect.left = build_unit->x;
 		_mouseList[_curMouse].rect.top = build_unit->y;
 		_mouseList[_curMouse].rect.right = 1 + build_unit->x + build_unit->scaled_width;
 		_mouseList[_curMouse].rect.bottom = 1 + build_unit->y + build_unit->scaled_height;
 	} else {
-		_mouseList[_curMouse].rect.left = ob_mouse->x1;
-		_mouseList[_curMouse].rect.top = ob_mouse->y1;
-		_mouseList[_curMouse].rect.right = 1 + ob_mouse->x2;
-		_mouseList[_curMouse].rect.bottom = 1 + ob_mouse->y2;
+		_mouseList[_curMouse].rect.left = mouse.x1;
+		_mouseList[_curMouse].rect.top = mouse.y1;
+		_mouseList[_curMouse].rect.right = 1 + mouse.x2;
+		_mouseList[_curMouse].rect.bottom = 1 + mouse.y2;
 	}
 
-	_mouseList[_curMouse].priority = ob_mouse->priority;
-	_mouseList[_curMouse].pointer = ob_mouse->pointer;
+	_mouseList[_curMouse].priority = mouse.priority;
+	_mouseList[_curMouse].pointer = mouse.pointer;
 
 	// Change all COGS pointers to CROSHAIR. I'm guessing that this was a
 	// design decision made in mid-development and they didn't want to go
@@ -162,11 +165,11 @@
 	// If 'pointer_text' field is set, but the 'id' field isn't same is
 	// current id then we don't want this "left over" pointer text
 
-	if (_mouseList[_curMouse].pointer_text && _mouseList[_curMouse].id != (int32) Logic::_scriptVars[ID])
+	if (_mouseList[_curMouse].pointer_text && _mouseList[_curMouse].id != (int32)_vm->_logic->readVar(ID))
 		_mouseList[_curMouse].pointer_text = 0;
 
 	// Get id from system variable 'id' which is correct for current object
-	_mouseList[_curMouse].id = Logic::_scriptVars[ID];
+	_mouseList[_curMouse].id = _vm->_logic->readVar(ID);
 
 	_curMouse++;
 }
@@ -177,7 +180,7 @@
 	// current object id - used for checking pointer_text when mouse area
 	// registered (in fnRegisterMouse and fnRegisterFrame)
 
-	_mouseList[_curMouse].id = Logic::_scriptVars[ID];
+	_mouseList[_curMouse].id = _vm->_logic->readVar(ID);
 	_mouseList[_curMouse].pointer_text = text_id;
 }
 
@@ -192,7 +195,7 @@
 	// If George is dead, the system menu is visible all the time, and is
 	// the only thing that can be used.
 
-	if (Logic::_scriptVars[DEAD]) {
+	if (_vm->_logic->readVar(DEAD)) {
 		if (_mouseMode != MOUSE_system_menu) {
 			_mouseMode = MOUSE_system_menu;
 
@@ -239,8 +242,10 @@
 
 #if RIGHT_CLICK_CLEARS_LUGGAGE
 bool Mouse::heldIsInInventory() {
+	int32 object_held = (int32)_vm->_logic->readVar(OBJECT_HELD);
+
 	for (uint i = 0; i < _totalMasters; i++) {
-		if ((uint32) _masterMenuList[i].icon_resource == Logic::_scriptVars[OBJECT_HELD])
+		if (_masterMenuList[i].icon_resource == object_held)
 			return true;
 	}
 	return false;
@@ -274,7 +279,7 @@
 	// If the mouse is moved off the menu, close it. Unless the player is
 	// dead, in which case the menu should always be visible.
 
-	if (_pos.y > 0 && !Logic::_scriptVars[DEAD]) {
+	if (_pos.y > 0 && !_vm->_logic->readVar(DEAD)) {
 		_mouseMode = MOUSE_normal;
 		hideMenu(RDMENU_TOP);
 		return;
@@ -297,14 +302,14 @@
 
 	// No save when dead
 
-	if (icon_list[hit] == SAVE_ICON && Logic::_scriptVars[DEAD])
+	if (icon_list[hit] == SAVE_ICON && _vm->_logic->readVar(DEAD))
 		return;
 
 	// Gray out all he icons, except the one that was clicked
 
 	for (int i = 0; i < ARRAYSIZE(icon_list); i++) {
 		if (i != hit) {
-			icon = _vm->_resman->openResource(icon_list[i]) + sizeof(StandardHeader);
+			icon = _vm->_resman->openResource(icon_list[i]) + ResHeader::size();
 			setMenuIcon(RDMENU_TOP, i, icon);
 			_vm->_resman->closeResource(icon_list[i]);
 		}
@@ -364,7 +369,7 @@
 
 	// Menu stays open on death screen. Otherwise it's closed.
 
-	if (!Logic::_scriptVars[DEAD]) {
+	if (!_vm->_logic->readVar(DEAD)) {
 		_mouseMode = MOUSE_normal;
 		hideMenu(RDMENU_TOP);
 	} else {
@@ -432,7 +437,7 @@
 
 #if RIGHT_CLICK_CLEARS_LUGGAGE
 	if ((me->buttons & RD_RIGHTBUTTONDOWN) && heldIsInInventory()) {
-		Logic::_scriptVars[OBJECT_HELD] = 0;
+		_vm->_logic->writeVar(OBJECT_HELD, 0);
 		_menuSelectedPos = 0;
 		_mouseMode = MOUSE_menu;
 		setLuggage(0);
@@ -458,25 +463,25 @@
 		// Set global script variable 'button'. We know that it was the
 		// left button, not the right one.
 
-		Logic::_scriptVars[LEFT_BUTTON]  = 1;
-		Logic::_scriptVars[RIGHT_BUTTON] = 0;
+		_vm->_logic->writeVar(LEFT_BUTTON, 1);
+		_vm->_logic->writeVar(RIGHT_BUTTON, 0);
 
 		// These might be required by the action script about to be run
 		ScreenInfo *screenInfo = _vm->_screen->getScreenInfo();
 
-		Logic::_scriptVars[MOUSE_X] = _pos.x + screenInfo->scroll_offset_x;
-		Logic::_scriptVars[MOUSE_Y] = _pos.y + screenInfo->scroll_offset_y;
+		_vm->_logic->writeVar(MOUSE_X, _pos.x + screenInfo->scroll_offset_x);
+		_vm->_logic->writeVar(MOUSE_Y, _pos.y + screenInfo->scroll_offset_y);
 
 		// For scripts to know what's been clicked. First used for
 		// 'room_13_turning_script' in object 'biscuits_13'
 
-		Logic::_scriptVars[CLICKED_ID] = _mouseTouching;
+		_vm->_logic->writeVar(CLICKED_ID, _mouseTouching);
 
 		_vm->_logic->setPlayerActionEvent(CUR_PLAYER_ID, _mouseTouching);
 
 		debug(2, "Used \"%s\" on \"%s\"",
-			_vm->fetchObjectName(Logic::_scriptVars[OBJECT_HELD], buf1),
-			_vm->fetchObjectName(Logic::_scriptVars[CLICKED_ID], buf2));
+			_vm->_resman->fetchName(_vm->_logic->readVar(OBJECT_HELD), buf1),
+			_vm->_resman->fetchName(_vm->_logic->readVar(CLICKED_ID), buf2));
 
 		// Hide menu - back to normal menu mode
 
@@ -499,15 +504,15 @@
 	_mouseMode = MOUSE_menu;
 	setLuggage(0);
 
-	if ((uint) hit == _menuSelectedPos) {
+	if ((uint)hit == _menuSelectedPos) {
 		// If we clicked on the same icon again, reset the first icon
 
-		Logic::_scriptVars[OBJECT_HELD] = 0;
+		_vm->_logic->writeVar(OBJECT_HELD, 0);
 		_menuSelectedPos = 0;
 	} else {
 		// Otherwise, combine the two icons
 
-		Logic::_scriptVars[COMBINE_BASE] = _masterMenuList[hit].icon_resource;
+		_vm->_logic->writeVar(COMBINE_BASE, _masterMenuList[hit].icon_resource);
 		_vm->_logic->setPlayerActionEvent(CUR_PLAYER_ID, MENU_MASTER_OBJECT);
 
 		// Turn off mouse now, to prevent player trying to click
@@ -516,8 +521,8 @@
 		hideMouse();
 
 		debug(2, "Used \"%s\" on \"%s\"",
-			_vm->fetchObjectName(Logic::_scriptVars[OBJECT_HELD], buf1),
-			_vm->fetchObjectName(Logic::_scriptVars[COMBINE_BASE], buf2));
+			_vm->_resman->fetchName(_vm->_logic->readVar(OBJECT_HELD), buf1),
+			_vm->_resman->fetchName(_vm->_logic->readVar(COMBINE_BASE), buf2));
 	}
 
 	// Refresh the menu
@@ -555,12 +560,12 @@
 		// resource id.
 
 		_examiningMenuIcon = true;
-		Logic::_scriptVars[OBJECT_HELD] = _masterMenuList[hit].icon_resource;
+		_vm->_logic->writeVar(OBJECT_HELD, _masterMenuList[hit].icon_resource);
 
 		// Must clear this so next click on exit becomes 1st click
 		// again
 
-		Logic::_scriptVars[EXIT_CLICK_ID] = 0;
+		_vm->_logic->writeVar(EXIT_CLICK_ID, 0);
 
 		_vm->_logic->setPlayerActionEvent(CUR_PLAYER_ID, MENU_MASTER_OBJECT);
 
@@ -574,7 +579,7 @@
 		hideMouse();
 
 		debug(2, "Right-click on \"%s\" icon",
-			_vm->fetchObjectName(Logic::_scriptVars[OBJECT_HELD], buf));
+			_vm->_resman->fetchName(_vm->_logic->readVar(OBJECT_HELD), buf));
 
 		return;
 	}
@@ -587,13 +592,13 @@
 		_mouseMode = MOUSE_drag;
 
 		_menuSelectedPos = hit;
-		Logic::_scriptVars[OBJECT_HELD] = _masterMenuList[hit].icon_resource;
+		_vm->_logic->writeVar(OBJECT_HELD, _masterMenuList[hit].icon_resource);
 		_currentLuggageResource = _masterMenuList[hit].luggage_resource;
 
 		// Must clear this so next click on exit becomes 1st click
 		// again
 
-		Logic::_scriptVars[EXIT_CLICK_ID] = 0;
+		_vm->_logic->writeVar(EXIT_CLICK_ID, 0);
 
 		// Refresh the menu
 
@@ -602,7 +607,7 @@
 		setLuggage(_masterMenuList[hit].luggage_resource);
 
 		debug(2, "Left-clicked on \"%s\" icon - switch to drag mode",
-			_vm->fetchObjectName(Logic::_scriptVars[OBJECT_HELD], buf));
+			_vm->_resman->fetchName(_vm->_logic->readVar(OBJECT_HELD), buf));
 	}
 }
 
@@ -616,7 +621,7 @@
 	// big-object menu lock situation, of if the player is dragging an
 	// object.
 
-	if (_pos.y < 0 && !_mouseModeLocked && !Logic::_scriptVars[OBJECT_HELD]) {
+	if (_pos.y < 0 && !_mouseModeLocked && !_vm->_logic->readVar(OBJECT_HELD)) {
 		_mouseMode = MOUSE_system_menu;
 
 		if (_mouseTouching) {
@@ -644,7 +649,7 @@
 		// object, even if the inventory menu was closed after the
 		// first object was selected.
 
-		if (!Logic::_scriptVars[OBJECT_HELD])
+		if (!_vm->_logic->readVar(OBJECT_HELD))
 			_mouseMode = MOUSE_menu;
 		else
 			_mouseMode = MOUSE_drag;
@@ -686,8 +691,8 @@
 
 			if (button_down) {
 				// set both (x1,y1) and (x2,y2) to this point
-				_vm->_debugger->_rectX1 = _vm->_debugger->_rectX2 = (uint32) _pos.x + screenInfo->scroll_offset_x;
-				_vm->_debugger->_rectY1 = _vm->_debugger->_rectY2 = (uint32) _pos.y + screenInfo->scroll_offset_y;
+				_vm->_debugger->_rectX1 = _vm->_debugger->_rectX2 = (uint32)_pos.x + screenInfo->scroll_offset_x;
+				_vm->_debugger->_rectY1 = _vm->_debugger->_rectY2 = (uint32)_pos.y + screenInfo->scroll_offset_y;
 				_vm->_debugger->_draggingRectangle = 1;
 			}
 		} else if (_vm->_debugger->_draggingRectangle == 1) {
@@ -699,8 +704,8 @@
 				_vm->_debugger->_draggingRectangle = 2;
 			} else {
 				// drag rectangle
-				_vm->_debugger->_rectX2 = (uint32) _pos.x + screenInfo->scroll_offset_x;
-				_vm->_debugger->_rectY2 = (uint32) _pos.y + screenInfo->scroll_offset_y;
+				_vm->_debugger->_rectX2 = (uint32)_pos.x + screenInfo->scroll_offset_x;
+				_vm->_debugger->_rectY2 = (uint32)_pos.y + screenInfo->scroll_offset_y;
 			}
 		} else {
 			// currently locked to avoid knocking out of place
@@ -716,8 +721,8 @@
 	}
 
 #if RIGHT_CLICK_CLEARS_LUGGAGE
-	if (Logic::_scriptVars[OBJECT_HELD] && (me->buttons & RD_RIGHTBUTTONDOWN) && heldIsInInventory()) {
-		Logic::_scriptVars[OBJECT_HELD] = 0;
+	if (_vm->_logic->readVar(OBJECT_HELD) && (me->buttons & RD_RIGHTBUTTONDOWN) && heldIsInInventory()) {
+		_vm->_logic->writeVar(OBJECT_HELD, 0);
 		_menuSelectedPos = 0;
 		setLuggage(0);
 		return;
@@ -743,29 +748,29 @@
 
 	// PLAYER_ACTION script variable - whatever catches this must reset to
 	// 0 again
-	// Logic::_scriptVars[PLAYER_ACTION] = _mouseTouching;
+	// _vm->_logic->writeVar(PLAYER_ACTION, _mouseTouching);
 
 	// Idle or router-anim will catch it
 
 	// Set global script variable 'button'
 
 	if (me->buttons & RD_LEFTBUTTONDOWN) {
-		Logic::_scriptVars[LEFT_BUTTON]  = 1;
-		Logic::_scriptVars[RIGHT_BUTTON] = 0;
+		_vm->_logic->writeVar(LEFT_BUTTON, 1);
+		_vm->_logic->writeVar(RIGHT_BUTTON, 0);
 		_buttonClick = 0;	// for re-click
 	} else {
-		Logic::_scriptVars[LEFT_BUTTON]  = 0;
-		Logic::_scriptVars[RIGHT_BUTTON] = 1;
+		_vm->_logic->writeVar(LEFT_BUTTON, 0);
+		_vm->_logic->writeVar(RIGHT_BUTTON, 1);
 		_buttonClick = 1;	// for re-click
 	}
 
 	// These might be required by the action script about to be run
 	ScreenInfo *screenInfo = _vm->_screen->getScreenInfo();
 
-	Logic::_scriptVars[MOUSE_X] = _pos.x + screenInfo->scroll_offset_x;
-	Logic::_scriptVars[MOUSE_Y] = _pos.y + screenInfo->scroll_offset_y;
+	_vm->_logic->writeVar(MOUSE_X, _pos.x + screenInfo->scroll_offset_x);
+	_vm->_logic->writeVar(MOUSE_Y, _pos.y + screenInfo->scroll_offset_y);
 
-	if (_mouseTouching == Logic::_scriptVars[EXIT_CLICK_ID] && (me->buttons & RD_LEFTBUTTONDOWN)) {
+	if (_mouseTouching == _vm->_logic->readVar(EXIT_CLICK_ID) && (me->buttons & RD_LEFTBUTTONDOWN)) {
 		// It's the exit double click situation. Let the existing
 		// interaction continue and start fading down. Switch the human
 		// off too
@@ -775,8 +780,8 @@
 
 		// Tell the walker
 
-		Logic::_scriptVars[EXIT_FADING] = 1;
-	} else if (_oldButton == _buttonClick && _mouseTouching == Logic::_scriptVars[CLICKED_ID] && _mousePointerRes != NORMAL_MOUSE_ID) {
+		_vm->_logic->writeVar(EXIT_FADING, 1);
+	} else if (_oldButton == _buttonClick && _mouseTouching == _vm->_logic->readVar(CLICKED_ID) && _mousePointerRes != NORMAL_MOUSE_ID) {
 		// Re-click. Do nothing, except on floors
 	} else {
 		// For re-click
@@ -786,28 +791,28 @@
 		// For scripts to know what's been clicked. First used for
 		// 'room_13_turning_script' in object 'biscuits_13'
 
-		Logic::_scriptVars[CLICKED_ID] = _mouseTouching;
+		_vm->_logic->writeVar(CLICKED_ID, _mouseTouching);
 
 		// Must clear these two double-click control flags - do it here
 		// so reclicks after exit clicks are cleared up
 
-		Logic::_scriptVars[EXIT_CLICK_ID] = 0;
-		Logic::_scriptVars[EXIT_FADING] = 0;
+		_vm->_logic->writeVar(EXIT_CLICK_ID, 0);
+		_vm->_logic->writeVar(EXIT_FADING, 0);
 
 		_vm->_logic->setPlayerActionEvent(CUR_PLAYER_ID, _mouseTouching);
 
 		byte buf1[NAME_LEN], buf2[NAME_LEN];
 
-		if (Logic::_scriptVars[OBJECT_HELD])
+		if (_vm->_logic->readVar(OBJECT_HELD))
 			debug(2, "Used \"%s\" on \"%s\"",
-				_vm->fetchObjectName(Logic::_scriptVars[OBJECT_HELD], buf1),
-				_vm->fetchObjectName(Logic::_scriptVars[CLICKED_ID], buf2));
-		else if (Logic::_scriptVars[LEFT_BUTTON])
+				_vm->_resman->fetchName(_vm->_logic->readVar(OBJECT_HELD), buf1),
+				_vm->_resman->fetchName(_vm->_logic->readVar(CLICKED_ID), buf2));
+		else if (_vm->_logic->readVar(LEFT_BUTTON))
 			debug(2, "Left-clicked on \"%s\"",
-				_vm->fetchObjectName(Logic::_scriptVars[CLICKED_ID], buf1));
+				_vm->_resman->fetchName(_vm->_logic->readVar(CLICKED_ID), buf1));
 		else	// RIGHT BUTTON
 			debug(2, "Right-clicked on \"%s\"",
-				_vm->fetchObjectName(Logic::_scriptVars[CLICKED_ID], buf1));
+				_vm->_resman->fetchName(_vm->_logic->readVar(CLICKED_ID), buf1));
 	}
 }
 
@@ -817,9 +822,12 @@
 
 	uint i;
 
-	Logic::_scriptVars[AUTO_SELECTED] = 0;
+	_vm->_logic->writeVar(AUTO_SELECTED, 0);
 
-	if (Logic::_scriptVars[OBJECT_HELD]) {
+	uint32 in_subject = _vm->_logic->readVar(IN_SUBJECT);
+	uint32 object_held = _vm->_logic->readVar(OBJECT_HELD);
+
+	if (object_held) {
 		// The player used an object on a person. In this case it
 		// triggered a conversation menu. Act as if the user tried to
 		// talk to the person about that object. If the person doesn't
@@ -827,8 +835,8 @@
 
 		uint32 response = _defaultResponseId;
 
-		for (i = 0; i < Logic::_scriptVars[IN_SUBJECT]; i++) {
-			if (_subjectList[i].res == Logic::_scriptVars[OBJECT_HELD]) {
+		for (i = 0; i < in_subject; i++) {
+			if (_subjectList[i].res == object_held) {
 				response = _subjectList[i].ref;
 				break;
 			}
@@ -837,12 +845,12 @@
 		// The user won't be holding the object any more, and the
 		// conversation menu will be closed.
 
-		Logic::_scriptVars[OBJECT_HELD] = 0;
-		Logic::_scriptVars[IN_SUBJECT] = 0;
+		_vm->_logic->writeVar(OBJECT_HELD, 0);
+		_vm->_logic->writeVar(IN_SUBJECT, 0);
 		return response;
 	}
 
-	if (Logic::_scriptVars[CHOOSER_COUNT_FLAG] == 0 && Logic::_scriptVars[IN_SUBJECT] == 1 && _subjectList[0].res == EXIT_ICON) {
+	if (_vm->_logic->readVar(CHOOSER_COUNT_FLAG) == 0 && in_subject == 1 && _subjectList[0].res == EXIT_ICON) {
 		// This is the first time the chooser is coming up in this
 		// conversation, there is only one subject and that's the
 		// EXIT icon.
@@ -853,8 +861,8 @@
 		// The conversation menu will be closed. We set AUTO_SELECTED
 		// because the speech script depends on it.
 
-		Logic::_scriptVars[AUTO_SELECTED] = 1;
-		Logic::_scriptVars[IN_SUBJECT] = 0;
+		_vm->_logic->writeVar(AUTO_SELECTED, 1);
+		_vm->_logic->writeVar(IN_SUBJECT, 0);
 		return _subjectList[0].ref;
 	}
 
@@ -863,11 +871,11 @@
 	if (!_choosing) {
 		// This is a new conversation menu.
 
-		if (!Logic::_scriptVars[IN_SUBJECT])
+		if (!in_subject)
 			error("fnChoose with no subjects");
 
-		for (i = 0; i < Logic::_scriptVars[IN_SUBJECT]; i++) {
-			icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(StandardHeader) + RDMENU_ICONWIDE * RDMENU_ICONDEEP;
+		for (i = 0; i < in_subject; i++) {
+			icon = _vm->_resman->openResource(_subjectList[i].res) + ResHeader::size() + RDMENU_ICONWIDE * RDMENU_ICONDEEP;
 			setMenuIcon(RDMENU_BOTTOM, i, icon);
 			_vm->_resman->closeResource(_subjectList[i].res);
 		}
@@ -878,7 +886,7 @@
 		showMenu(RDMENU_BOTTOM);
 		setMouse(NORMAL_MOUSE_ID);
 		_choosing = true;
-		return (uint32) -1;
+		return (uint32)-1;
 	}
 
 	// The menu is there - we're just waiting for a click. We only care
@@ -890,33 +898,33 @@
 	getPos(mouseX, mouseY);
 
 	if (!me || !(me->buttons & RD_LEFTBUTTONDOWN) || mouseY < 400)
-		return (uint32) -1;
+		return (uint32)-1;
 
 	// Check for click on a menu.
 
-	int hit = _vm->_mouse->menuClick(Logic::_scriptVars[IN_SUBJECT]);
+	int hit = _vm->_mouse->menuClick(in_subject);
 	if (hit < 0)
-		return (uint32) -1;
+		return (uint32)-1;
 
 	// Hilight the clicked icon by greying the others. This can look a bit
 	// odd when you click on the exit icon, but there are also cases when
 	// it looks strange if you don't do it.
 
-	for (i = 0; i < Logic::_scriptVars[IN_SUBJECT]; i++) {
-		if ((int) i != hit) {
-			icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(StandardHeader);
+	for (i = 0; i < in_subject; i++) {
+		if ((int)i != hit) {
+			icon = _vm->_resman->openResource(_subjectList[i].res) + ResHeader::size();
 			_vm->_mouse->setMenuIcon(RDMENU_BOTTOM, i, icon);
 			_vm->_resman->closeResource(_subjectList[i].res);
 		}
 	}
 
 	// For non-speech scripts that manually call the chooser
-	Logic::_scriptVars[RESULT] = _subjectList[hit].res;
+	_vm->_logic->writeVar(RESULT, _subjectList[hit].res);
 
 	// The conversation menu will be closed
 
 	_choosing = false;
-	Logic::_scriptVars[IN_SUBJECT] = 0;
+	_vm->_logic->writeVar(IN_SUBJECT, 0);
 	setMouse(0);
 
 	return _subjectList[hit].ref;
@@ -973,13 +981,13 @@
 			setMouse(pointer_type);
 
 			// setup luggage icon
-			if (Logic::_scriptVars[OBJECT_HELD]) {
+			if (_vm->_logic->readVar(OBJECT_HELD)) {
 				setLuggage(_currentLuggageResource);
 			}
 		} else {
 			byte buf[NAME_LEN];
 
-			error("ERROR: mouse.pointer==0 for object %d (%s) - update logic script!", _mouseTouching, _vm->fetchObjectName(_mouseTouching, buf));
+			error("ERROR: mouse.pointer==0 for object %d (%s) - update logic script!", _mouseTouching, _vm->_resman->fetchName(_mouseTouching, buf));
 		}
 	} else if (_oldMouseTouching && !_mouseTouching) {
 		// the cursor has moved off something - reset cursor to
@@ -1024,8 +1032,8 @@
 	_mousePointerRes = res;
 
 	if (res) {
-		byte *icon = _vm->_resman->openResource(res) + sizeof(StandardHeader);
-		uint32 len = _vm->_resman->fetchLen(res) - sizeof(StandardHeader);
+		byte *icon = _vm->_resman->openResource(res) + ResHeader::size();
+		uint32 len = _vm->_resman->fetchLen(res) - ResHeader::size();
 
 		// don't pulse the normal pointer - just do the regular anim
 		// loop
@@ -1046,8 +1054,8 @@
 	_realLuggageItem = res;
 
 	if (res) {
-		byte *icon = _vm->_resman->openResource(res) + sizeof(StandardHeader);
-		uint32 len = _vm->_resman->fetchLen(res) - sizeof(StandardHeader);
+		byte *icon = _vm->_resman->openResource(res) + ResHeader::size();
+		uint32 len = _vm->_resman->fetchLen(res) - ResHeader::size();
 
 		setLuggageAnim(icon, len);
 		_vm->_resman->closeResource(res);
@@ -1058,7 +1066,7 @@
 void Mouse::setObjectHeld(uint32 res) {
 	setLuggage(res);
 
-	Logic::_scriptVars[OBJECT_HELD] = res;
+	_vm->_logic->writeVar(OBJECT_HELD, res);
 	_currentLuggageResource = res;
 
 	// mode locked - no menu available
@@ -1263,7 +1271,7 @@
 	// it and when combining objects
 
 	// for logic scripts
-	Logic::_scriptVars[MOUSE_AVAILABLE] = 0;
+	_vm->_logic->writeVar(MOUSE_AVAILABLE, 0);
 
 	// human/mouse off
 	_mouseStatus = true;
@@ -1280,7 +1288,7 @@
 	// special menus use hideMouse()
 
 	// Don't hide menu in conversations
-	if (Logic::_scriptVars[TALK_FLAG] == 0)
+	if (_vm->_logic->readVar(TALK_FLAG) == 0)
 		hideMenu(RDMENU_BOTTOM);
 
 	if (_mouseMode == MOUSE_system_menu) {
@@ -1292,7 +1300,7 @@
 
 void Mouse::addHuman() {
 	// For logic scripts
-	Logic::_scriptVars[MOUSE_AVAILABLE] = 1;
+	_vm->_logic->writeVar(MOUSE_AVAILABLE, 1);
 
 	if (_mouseStatus) {
 		// Force engine to choose a cursor
@@ -1301,7 +1309,7 @@
 	}
 
 	// Clear this to reset no-second-click system
-	Logic::_scriptVars[CLICKED_ID] = 0;
+	_vm->_logic->writeVar(CLICKED_ID, 0);
 
 	// This is now done outside the OBJECT_HELD check in case it's set to
 	// zero before now!
@@ -1311,13 +1319,13 @@
 
 	_mouseModeLocked = false;
 
-	if (Logic::_scriptVars[OBJECT_HELD]) {
+	if (_vm->_logic->readVar(OBJECT_HELD)) {
 		// Was dragging something around - need to clear this again
-		Logic::_scriptVars[OBJECT_HELD] = 0;
+		_vm->_logic->writeVar(OBJECT_HELD, 0);
 
 		// And these may also need clearing, just in case
 		_examiningMenuIcon = false;
-		Logic::_scriptVars[COMBINE_BASE] = 0;
+		_vm->_logic->writeVar(COMBINE_BASE, 0);
 
 		setLuggage(0);
 	}
@@ -1356,7 +1364,7 @@
 
 void Mouse::refreshInventory() {
 	// Can reset this now
-	Logic::_scriptVars[COMBINE_BASE] = 0;
+	_vm->_logic->writeVar(COMBINE_BASE, 0);
 
 	// Cause 'object_held' icon to be greyed. The rest are coloured.
 	_examiningMenuIcon = true;
@@ -1365,9 +1373,9 @@
 }
 
 void Mouse::startConversation() {
-	if (Logic::_scriptVars[TALK_FLAG] == 0) {
+	if (_vm->_logic->readVar(TALK_FLAG) == 0) {
 		// See fnChooser & speech scripts
-		Logic::_scriptVars[CHOOSER_COUNT_FLAG] = 0;
+		_vm->_logic->writeVar(CHOOSER_COUNT_FLAG, 0);
 	}
 
 	noHuman();
@@ -1382,7 +1390,7 @@
 	}
 
 	// In case DC forgets
-	Logic::_scriptVars[TALK_FLAG] = 0;
+	_vm->_logic->writeVar(TALK_FLAG, 0);
 }
 
 void Mouse::monitorPlayerActivity() {
@@ -1405,9 +1413,9 @@
 
 	if (_playerActivityDelay >= threshold) {
 		_playerActivityDelay = 0;
-		Logic::_scriptVars[RESULT] = 1;
+		_vm->_logic->writeVar(RESULT, 1);
 	} else
-		Logic::_scriptVars[RESULT] = 0;
+		_vm->_logic->writeVar(RESULT, 0);
 }
 
 void Mouse::pauseGame() {
@@ -1421,7 +1429,7 @@
 }
 
 void Mouse::unpauseGame() {
-	if (Logic::_scriptVars[OBJECT_HELD] && _realLuggageItem)
+	if (_vm->_logic->readVar(OBJECT_HELD) && _realLuggageItem)
 		setLuggage(_realLuggageItem);
 }
 

Index: mouse.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/mouse.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- mouse.h	18 Oct 2005 01:30:25 -0000	1.22
+++ mouse.h	29 Oct 2005 21:24:53 -0000	1.23
@@ -27,7 +27,6 @@
 
 namespace Sword2 {
 
-struct ObjectMouse;
 struct BuildUnit;
 
 // Menubar defines.
@@ -62,10 +61,8 @@
 #define RDMENU_ICONSPACING	5
 #define RDMENU_MAXPOCKETS	15
 
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
+#define MOUSE_ANIM_HEADER_SIZE	6
+ 
 struct MouseAnim {
 	uint8 runTimeComp;	// type of runtime compression used for the
 				// frame data
@@ -74,11 +71,9 @@
 	int8 yHotSpot;
 	uint8 mousew;
 	uint8 mouseh;
-} GCC_PACK;
 
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
+	byte *data;
+};
 
 // The MOUSE_holding mode is entered when the conversation menu is closed, and
 // exited when the mouse cursor moves off that menu area. I don't know why yet.
@@ -145,13 +140,10 @@
 
 	uint32 _mousePointerRes;
 
-	struct MouseAnim *_mouseAnim;
-	struct MouseAnim *_luggageAnim;
+	MouseAnim _mouseAnim;
+	MouseAnim _luggageAnim;
 
 	uint8 _mouseFrame;
-	byte *_mouseSprite;
-	int32 *_mouseOffsets;
-	int32 *_luggageOffset;
 
 	uint32 _mouseMode;
 
@@ -177,7 +169,7 @@
 
 	uint32 _menuSelectedPos;
 
-	void decompressMouse(byte *decomp, byte *comp, int width, int height, int pitch, int xOff = 0, int yOff = 0);
+	void decompressMouse(byte *decomp, byte *comp, uint8 frame, int width, int height, int pitch, int xOff = 0, int yOff = 0);
 
 	int32 setMouseAnim(byte *ma, int32 size, int32 mouseFlash);
 	int32 setLuggageAnim(byte *la, int32 size);
@@ -208,7 +200,7 @@
 
 	void resetMouseList();
 
-	void registerMouse(ObjectMouse *ob_mouse, BuildUnit *build_unit);
+	void registerMouse(byte *ob_mouse, BuildUnit *build_unit);
 	void registerPointerText(int32 text_id);
 
 	void createPointerText(uint32 text_id, uint32 pointer_res);
@@ -219,7 +211,7 @@
 
 	void processMenu();
 
-	void addMenuObject(MenuObject *obj);
+	void addMenuObject(byte *ptr);
 	void addSubject(int32 id, int32 ref);
 
 	void buildMenu();

Index: object.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/object.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- object.h	18 Oct 2005 01:30:25 -0000	1.11
+++ object.h	29 Oct 2005 21:24:53 -0000	1.12
@@ -21,11 +21,9 @@
 #ifndef	_SCRIPT_STRUCTURES
 #define	_SCRIPT_STRUCTURES
 
-namespace Sword2 {
+#include "common/stream.h"
 
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
+namespace Sword2 {
 
 // these structures represent the broken up compact components
 // these here declared to the system must be the same as those declared to
@@ -41,15 +39,64 @@
 	int32 y2;
 	int32 priority;
 	int32 pointer;			// type (or resource id?) of pointer used over this area
-} GCC_PACK;
+
+	static const int size() {
+		return 24;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		x1 = readS.readSint32LE();
+		y1 = readS.readSint32LE();
+		x2 = readS.readSint32LE();
+		y2 = readS.readSint32LE();
+		priority = readS.readSint32LE();
+		pointer = readS.readSint32LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeSint32LE(x1);
+		writeS.writeSint32LE(y1);
+		writeS.writeSint32LE(x2);
+		writeS.writeSint32LE(y2);
+		writeS.writeSint32LE(priority);
+		writeS.writeSint32LE(pointer);
+	}
+};
 
 // logic structure - contains fields used in logic script processing
 
-struct ObjectLogic {
-	int32 looping;			// 0 when first calling fn<function>;
-					// 1 when calling subsequent times in same loop
-	int32 pause;			// pause count, used by fnPause()
-} GCC_PACK;
+class ObjectLogic {
+	// int32 looping;		// 0 when first calling fn<function>;
+					// 1 when calling subsequent times in
+					// same loop
+	// int32 pause;			// pause count, used by fnPause()
+
+private:
+	byte *_addr;
+
+public:
+	ObjectLogic(byte *addr) {
+		_addr = addr;
+	}
+
+	static const int size() {
+		return 8;
+	}
+
+	byte *data() {
+		return _addr;
+	}
+
+	int32 getLooping()       { return READ_LE_UINT32(_addr);     }
+	int32 getPause()         { return READ_LE_UINT32(_addr + 4); }
+
+	void setLooping(int32 x) { WRITE_LE_UINT32(_addr, x);        }
+	void setPause(int32 x)   { WRITE_LE_UINT32(_addr + 4, x);    }
+};
 
 // status bits for 'type' field of ObjectGraphic)
 
@@ -71,50 +118,161 @@
 
 // graphic structure - contains fields appropriate to sprite output
 
-struct ObjectGraphic {
-	int32 type;			// see above
-	int32 anim_resource;		// resource id of animation file
-	int32 anim_pc;			// current frame number of animation
-} GCC_PACK;
+class ObjectGraphic {
+	// int32 type;			// see above
+	// int32 anim_resource;		// resource id of animation file
+	// int32 anim_pc;		// current frame number of animation
+
+private:
+	byte *_addr;
+
+public:
+	ObjectGraphic(byte *addr) {
+		_addr = addr;
+	}
+
+	static const int size() {
+		return 12;
+	}
+
+	byte *data() {
+		return _addr;
+	}
+
+	int32 getType()               { return READ_LE_UINT32(_addr);     }
+	int32 getAnimResource()       { return READ_LE_UINT32(_addr + 4); }
+	int32 getAnimPc()             { return READ_LE_UINT32(_addr + 8); }
+
+	void setType(int32 x)         { WRITE_LE_UINT32(_addr, x);        }
+	void setAnimResource(int32 x) { WRITE_LE_UINT32(_addr + 4, x);    }
+	void setAnimPc(int32 x)       { WRITE_LE_UINT32(_addr + 8, x);    }
+};
 
 // speech structure - contains fields used by speech scripts & text output
 
-struct ObjectSpeech {
-	int32 pen;			// colour to use for body of characters
-	int32 width;			// max width of text sprite
-	int32 command;			// speech script command id
-	int32 ins1;			// speech script instruction parameters (may need more now?)
-	int32 ins2;
-	int32 ins3;
-	int32 ins4;
-	int32 ins5;
-	int32 wait_state;		// 0 not waiting, 1 waiting for next speech command
-} GCC_PACK;
+class ObjectSpeech {
+	// int32 pen;			// colour to use for body of characters
+	// int32 width;			// max width of text sprite
+	// int32 command;		// speech script command id
+	// int32 ins1;			// speech script instruction parameters
+	// int32 ins2;
+	// int32 ins3;
+	// int32 ins4;
+	// int32 ins5;
+	// int32 wait_state;		// 0 not waiting,
+					// 1 waiting for next speech command
+
+private:
+	byte *_addr;
+
+public:
+	ObjectSpeech(byte *addr) {
+		_addr = addr;
+	}
+
+	static const int size() {
+		return 36;
+	}
+
+	byte *data() {
+		return _addr;
+	}
+
+	int32 getPen()             { return READ_LE_UINT32(_addr);      }
+	int32 getWidth()           { return READ_LE_UINT32(_addr + 4);  }
+	int32 getCommand()         { return READ_LE_UINT32(_addr + 8);  }
+	int32 getIns1()            { return READ_LE_UINT32(_addr + 12); }
+	int32 getIns2()            { return READ_LE_UINT32(_addr + 16); }
+	int32 getIns3()            { return READ_LE_UINT32(_addr + 20); }
+	int32 getIns4()            { return READ_LE_UINT32(_addr + 24); }
+	int32 getIns5()            { return READ_LE_UINT32(_addr + 28); }
+	int32 getWaitState()       { return READ_LE_UINT32(_addr + 32); }
+
+	void setPen(int32 x)       { WRITE_LE_UINT32(_addr, x);         }
+	void setWidth(int32 x)     { WRITE_LE_UINT32(_addr + 4, x);     }
+	void setCommand(int32 x)   { WRITE_LE_UINT32(_addr + 8, x);     }
+	void setIns1(int32 x)      { WRITE_LE_UINT32(_addr + 12, x);    }
+	void setIns2(int32 x)      { WRITE_LE_UINT32(_addr + 16, x);    }
+	void setIns3(int32 x)      { WRITE_LE_UINT32(_addr + 20, x);    }
+	void setIns4(int32 x)      { WRITE_LE_UINT32(_addr + 24, x);    }
+	void setIns5(int32 x)      { WRITE_LE_UINT32(_addr + 28, x);    }
+	void setWaitState(int32 x) { WRITE_LE_UINT32(_addr + 32, x);    }
+};
 
 // mega structure - contains fields used for mega-character & mega-set
 // processing
 
-struct ObjectMega {
-	int32 NOT_USED_1;		// only free roaming megas need to check this before registering their graphics for drawing
-	int32 NOT_USED_2;		// id of floor on which we are standing
-	int32 NOT_USED_3;		// id of object which we are getting to
-	int32 NOT_USED_4;		// pixel distance to stand from player character when in conversation
-	int32 currently_walking;	// number given us by the auto router
-	int32 walk_pc;			// current frame number of walk-anim
-	int32 scale_a;			// current scale factors, taken from floor data
-	int32 scale_b;
-	int32 feet_x;			// mega feet coords - frame-offsets are added to these position mega frames
-	int32 feet_y;
-	int32 current_dir;		// current dirction faced by mega; used by autorouter to determine turns required
-	int32 NOT_USED_5;		// means were currently avoiding a collision (see fnWalk)
-	int32 megaset_res;		// resource id of mega-set file
-	int32 NOT_USED_6;		// NOT USED
-} GCC_PACK;
+class ObjectMega {
+	// int32 NOT_USED_1;		// only free roaming megas need to
+					// check this before registering their
+					// graphics for drawing
+	// int32 NOT_USED_2;		// id of floor on which we are standing
+	// int32 NOT_USED_3;		// id of object which we are getting to
+	// int32 NOT_USED_4;		// pixel distance to stand from player
+					// character when in conversation
+	// int32 currently_walking;	// number given us by the auto router
+	// int32 walk_pc;		// current frame number of walk-anim
+	// int32 scale_a;		// current scale factors, taken from
+	// int32 scale_b;		// floor data
+	// int32 feet_x;		// mega feet coords - frame-offsets are
+	// int32 feet_y;		// added to these position mega frames
+	// int32 current_dir;		// current dirction faced by mega; used
+					// by autorouter to determine turns
+					// required
+	// int32 NOT_USED_5;		// means were currently avoiding a
+					// collision (see fnWalk)
+	// int32 megaset_res;		// resource id of mega-set file
+	// int32 NOT_USED_6;		// NOT USED
+
+private:
+	byte *_addr;
+
+public:
+	ObjectMega(byte *addr) {
+		_addr = addr;
+	}
+
+	static const int size() {
+		return 56;
+	}
+
+	byte *data() {
+		return _addr;
+	}
+
+	int32 getIsWalking()         { return READ_LE_UINT32(_addr + 16); }
+	int32 getWalkPc()            { return READ_LE_UINT32(_addr + 20); }
+	int32 getScaleA()            { return READ_LE_UINT32(_addr + 24); }
+	int32 getScaleB()            { return READ_LE_UINT32(_addr + 28); }
+	int32 getFeetX()             { return READ_LE_UINT32(_addr + 32); }
+	int32 getFeetY()             { return READ_LE_UINT32(_addr + 36); }
+	int32 getCurDir()            { return READ_LE_UINT32(_addr + 40); }
+	int32 getMegasetRes()        { return READ_LE_UINT32(_addr + 48); }
+
+	void setIsWalking(int32 x)   { WRITE_LE_UINT32(_addr + 16, x);    }
+	void setWalkPc(int32 x)      { WRITE_LE_UINT32(_addr + 20, x);    }
+	void setScaleA(int32 x)      { WRITE_LE_UINT32(_addr + 24, x);    }
+	void setScaleB(int32 x)      { WRITE_LE_UINT32(_addr + 28, x);    }
+	void setFeetX(int32 x)       { WRITE_LE_UINT32(_addr + 32, x);    }
+	void setFeetY(int32 x)       { WRITE_LE_UINT32(_addr + 36, x);    }
+	void setCurDir(int32 x)      { WRITE_LE_UINT32(_addr + 40, x);    }
+	void setMegasetRes(int32 x)  { WRITE_LE_UINT32(_addr + 48, x);    }
+
+	int32 calcScale() {
+		// Calc scale at which to print the sprite, based on feet
+		// y-coord & scaling constants (NB. 'scale' is actually
+		// 256 * true_scale, to maintain accuracy)
+
+		// Ay+B gives 256 * scale ie. 256 * 256 * true_scale for even
+		// better accuracy, ie. scale = (Ay + B) / 256
+		return (getScaleA() * getFeetY() + getScaleB()) / 256;
+	}
+};
 
 // walk-data structure - contains details of layout of frames in the
 // mega-set, and how they are to be used
 
-struct ObjectWalkdata {
+struct ObjectWalkdata { 
 	int32 nWalkFrames;		// no. of frames per walk-cycle
 	int32 usingStandingTurnFrames;	// 0 = no  1 = yes
 	int32 usingWalkingTurnFrames;	// 0 = no  1 = yes
@@ -124,11 +282,59 @@
 	int32 leadingLeg[8];		// leading leg for walk	in each direction  (0 = left  1 = right)
 	int32 dx[8 * (12 + 1)];		// walk step distances in x direction
 	int32 dy[8 * (12 + 1)];		// walk step distances in y direction
-} GCC_PACK;
 
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
+	static const int size() {
+		return 916;
+	}
+
+	void read(byte *addr) {
+		Common::MemoryReadStream readS(addr, size());
+
+		nWalkFrames = readS.readUint32LE();
+		usingStandingTurnFrames = readS.readUint32LE();
+		usingWalkingTurnFrames = readS.readUint32LE();
+		usingSlowInFrames = readS.readUint32LE();
+		usingSlowOutFrames = readS.readUint32LE();
+
+		int i;
+
+		for (i = 0; i < ARRAYSIZE(nSlowInFrames); i++)
+			nSlowInFrames[i] = readS.readUint32LE();
+
+		for (i = 0; i < ARRAYSIZE(leadingLeg); i++)
+			leadingLeg[i] = readS.readUint32LE();
+
+		for (i = 0; i < ARRAYSIZE(dx); i++)
+			dx[i] = readS.readUint32LE();
+
+		for (i = 0; i < ARRAYSIZE(dy); i++)
+			dy[i] = readS.readUint32LE();
+	}
+
+	void write(byte *addr) {
+		Common::MemoryWriteStream writeS(addr, size());
+
+		writeS.writeUint32LE(nWalkFrames);
+		writeS.writeUint32LE(usingStandingTurnFrames);
+		writeS.writeUint32LE(usingWalkingTurnFrames);
+		writeS.writeUint32LE(usingSlowInFrames);
+		writeS.writeUint32LE(usingSlowOutFrames);
+
+		int i;
+
+		for (i = 0; i < ARRAYSIZE(nSlowInFrames); i++)
+			writeS.writeUint32LE(nSlowInFrames[i]);
+
+		for (i = 0; i < ARRAYSIZE(leadingLeg); i++)
+			writeS.writeUint32LE(leadingLeg[i]);
+
+		for (i = 0; i < ARRAYSIZE(dx); i++)
+			writeS.writeUint32LE(dx[i]);
+
+		for (i = 0; i < ARRAYSIZE(dy); i++)
+			writeS.writeUint32LE(dy[i]);
+	}
+};
 
 } // End of namespace Sword2
 

Index: protocol.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/protocol.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- protocol.cpp	18 Oct 2005 01:30:25 -0000	1.33
+++ protocol.cpp	29 Oct 2005 21:24:53 -0000	1.34
@@ -30,9 +30,11 @@
  */
 
 byte *Sword2Engine::fetchPalette(byte *screenFile) {
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
+	MultiScreenHeader mscreenHeader;
 
-	byte *palette = (byte *)mscreenHeader + mscreenHeader->palette;
+	mscreenHeader.read(screenFile + ResHeader::size());
+
+	byte *palette = screenFile + ResHeader::size() + 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,9 +54,11 @@
  */
 
 byte *Sword2Engine::fetchPaletteMatchTable(byte *screenFile) {
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
+	MultiScreenHeader mscreenHeader;
 
-	return (byte *)mscreenHeader + mscreenHeader->paletteTable;
+	mscreenHeader.read(screenFile + ResHeader::size());
+
+	return screenFile + ResHeader::size() + mscreenHeader.paletteTable;
 }
 
 /**
@@ -62,11 +66,12 @@
  * the screen file.
  */
 
-ScreenHeader *Sword2Engine::fetchScreenHeader(byte *screenFile) {
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
-	ScreenHeader *screenHeader = (ScreenHeader *)((byte *)mscreenHeader + mscreenHeader->screen);
+byte *Sword2Engine::fetchScreenHeader(byte *screenFile) {
+	MultiScreenHeader mscreenHeader;
 
-	return screenHeader;
+	mscreenHeader.read(screenFile + ResHeader::size());
+
+	return screenFile + ResHeader::size() + mscreenHeader.screen;
 }
 
 /**
@@ -75,19 +80,19 @@
  * the number of layers on this screen.
  */
 
-LayerHeader *Sword2Engine::fetchLayerHeader(byte *screenFile, uint16 layerNo) {
+byte *Sword2Engine::fetchLayerHeader(byte *screenFile, uint16 layerNo) {
 #ifdef SWORD2_DEBUG
-	ScreenHeader *screenHead = fetchScreenHeader(screenFile);
+	ScreenHeader screenHead;
 
-	if (layerNo > screenHead->noLayers - 1)
-		error("fetchLayerHeader(%d) invalid layer number!", layerNo);
+	screenHead.read(fetchScreenHeader(screenFile));
+	assert(layerNo < screenHead.noLayers);
 #endif
 
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
+	MultiScreenHeader mscreenHeader;
 
-	LayerHeader *layerHeader = (LayerHeader *)((byte *)mscreenHeader + mscreenHeader->layers + (layerNo * sizeof(LayerHeader)));
+	mscreenHeader.read(screenFile + ResHeader::size());
 
-	return layerHeader;
+	return screenFile + ResHeader::size() + mscreenHeader.layers + layerNo * LayerHeader::size();
 }
 
 /**
@@ -96,9 +101,11 @@
  */
 
 byte *Sword2Engine::fetchShadingMask(byte *screenFile) {
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
+	MultiScreenHeader mscreenHeader;
 
-	return (byte *)mscreenHeader + mscreenHeader->maskOffset;
+	mscreenHeader.read(screenFile + ResHeader::size());
+
+	return screenFile + ResHeader::size() + mscreenHeader.maskOffset;
 }
 
 /**
@@ -106,8 +113,8 @@
  * anim file.
  */
 
-AnimHeader *Sword2Engine::fetchAnimHeader(byte *animFile) {
-	return (AnimHeader *)(animFile + sizeof(StandardHeader));
+byte *Sword2Engine::fetchAnimHeader(byte *animFile) {
+	return animFile + ResHeader::size();
 }
 
 /**
@@ -116,15 +123,17 @@
  * number exceeds the number of frames in this anim.
  */
 
-CdtEntry *Sword2Engine::fetchCdtEntry(byte *animFile, uint16 frameNo) {
-	AnimHeader *animHead = fetchAnimHeader(animFile);
-
+byte *Sword2Engine::fetchCdtEntry(byte *animFile, uint16 frameNo) {
 #ifdef SWORD2_DEBUG
+	AnimHeader animHead;
+
+	animHead.read(fetchAnimHeader(animFile));
+
 	if (frameNo > animHead->noAnimFrames - 1)
-		error("fetchCdtEntry(animFile,%d) - anim only %d frames", frameNo, animHead->noAnimFrames);
+		error("fetchCdtEntry(animFile,%d) - anim only %d frames", frameNo, animHead.noAnimFrames);
 #endif
 
-	return (CdtEntry *)((byte *)animHead + sizeof(AnimHeader) + frameNo * sizeof(CdtEntry));
+	return fetchAnimHeader(animFile) + AnimHeader::size() + frameNo * CdtEntry::size();
 }
 
 /**
@@ -133,60 +142,54 @@
  * exceeds the number of frames in this anim
  */
 
-FrameHeader *Sword2Engine::fetchFrameHeader(byte *animFile, uint16 frameNo) {
+byte *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);
+	CdtEntry cdt;
+
+	cdt.read(fetchCdtEntry(animFile, frameNo));
+
+	return animFile + ResHeader::size() + cdt.frameOffset;
 }
 
 /**
  * Returns a pointer to the requested parallax layer data.
  */
 
-Parallax *Sword2Engine::fetchBackgroundParallaxLayer(byte *screenFile, int layer) {
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
+byte *Sword2Engine::fetchBackgroundParallaxLayer(byte *screenFile, int layer) {
+	MultiScreenHeader mscreenHeader;
 
-#ifdef SWORD2_DEBUG
-	if (mscreenHeader->bg_parallax[layer] == 0)
-		error("fetchBackgroundParallaxLayer(%d) - No parallax layer exists", layer);
-#endif
+	mscreenHeader.read(screenFile + ResHeader::size());
+	assert(mscreenHeader.bg_parallax[layer]);
 
-	return (Parallax *)((byte *)mscreenHeader + mscreenHeader->bg_parallax[layer]);
+	return screenFile + ResHeader::size() + mscreenHeader.bg_parallax[layer];
 }
 
-Parallax *Sword2Engine::fetchBackgroundLayer(byte *screenFile) {
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
+byte *Sword2Engine::fetchBackgroundLayer(byte *screenFile) {
+	MultiScreenHeader mscreenHeader;
 
-#ifdef SWORD2_DEBUG
-	if (mscreenHeader->screen == 0)
-		error("fetchBackgroundLayer (%d) - No background layer exists");
-#endif
+	mscreenHeader.read(screenFile + ResHeader::size());
+	assert(mscreenHeader.screen);
 
-	return (Parallax *)((byte *)mscreenHeader + mscreenHeader->screen + sizeof(ScreenHeader));
+	return screenFile + ResHeader::size() + mscreenHeader.screen + ScreenHeader::size();
 }
 
-Parallax *Sword2Engine::fetchForegroundParallaxLayer(byte *screenFile, int layer) {
-	MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)(screenFile + sizeof(StandardHeader));
+byte *Sword2Engine::fetchForegroundParallaxLayer(byte *screenFile, int layer) {
+	MultiScreenHeader mscreenHeader;
 
-#ifdef SWORD2_DEBUG
-	if (mscreenHeader->fg_parallax[layer] == 0)
-		error("fetchForegroundParallaxLayer(%d) - No parallax layer exists", layer);
-#endif
+	mscreenHeader.read(screenFile + ResHeader::size());
+	assert(mscreenHeader.fg_parallax[layer]);
 
-	return (Parallax *)((byte *)mscreenHeader + mscreenHeader->fg_parallax[layer]);
+	return screenFile + ResHeader::size() + mscreenHeader.fg_parallax[layer];
 }
 
-static byte errorLine[128];
-
 byte *Sword2Engine::fetchTextLine(byte *file, uint32 text_line) {
-	StandardHeader *fileHeader;
-	uint32 *point;
-
-	TextHeader *text_header = (TextHeader *)(file + sizeof(StandardHeader));
+	TextHeader text_header;
+	static byte errorLine[128];
 
-	if (text_line >= text_header->noOfLines) {
-		fileHeader = (StandardHeader *)file;
-		sprintf((char *)errorLine, "xxMissing line %d of %s (only 0..%d)", text_line, fileHeader->name, text_header->noOfLines - 1);
+	text_header.read(file + ResHeader::size());
 
+	if (text_line >= text_header.noOfLines) {
+		sprintf((char *)errorLine, "xxMissing line %d of %s (only 0..%d)", text_line, _resman->fetchName(file), text_header.noOfLines - 1);
 
 		// first 2 chars are NULL so that actor-number comes out as '0'
 		errorLine[0] = 0;
@@ -194,27 +197,19 @@
 		return errorLine;
 	}
 
-	// point to the lookup table
-	point = (uint32 *)text_header + 1;
+	// The "number of lines" field is followed by a lookup table
 
-	return (byte *)(file + READ_LE_UINT32(point + text_line));
+	return file + READ_LE_UINT32(file + ResHeader::size() + 4 + 4 * text_line);
 }
 
-
 // Used for testing text & speech (see fnISpeak in speech.cpp)
 
 bool Sword2Engine::checkTextLine(byte *file, uint32 text_line) {
-	TextHeader *text_header = (TextHeader *)(file + sizeof(StandardHeader));
-
-	return text_line < text_header->noOfLines;
-}
+	TextHeader text_header;
 
-byte *Sword2Engine::fetchObjectName(int32 resourceId, byte *buf) {
-	StandardHeader *header = (StandardHeader *)_resman->openResource(resourceId);
+	text_header.read(file + ResHeader::size());
 
-	memcpy(buf, header->name, NAME_LEN);
-	_resman->closeResource(resourceId);
-	return buf;
+	return text_line < text_header.noOfLines;
 }
 
 } // End of namespace Sword2

Index: resman.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/resman.cpp,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -d -r1.116 -r1.117
--- resman.cpp	18 Oct 2005 01:30:25 -0000	1.116
+++ resman.cpp	29 Oct 2005 21:24:53 -0000	1.117
@@ -43,18 +43,10 @@
 //	resource.tab which is a table which tells us which cluster a resource
 //	is located in and the number within the cluster
 
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
 struct CdInf {
 	uint8 clusterName[20];	// Null terminated cluster name.
 	uint8 cd;		// Cd cluster is on and whether it is on the local drive or not.
-} GCC_PACK;
-
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
+};
 
 ResourceManager::ResourceManager(Sword2Engine *vm) {
 	_vm = vm;
@@ -201,192 +193,6 @@
 	free(_resConvTable);
 }
 
-// Quick macro to make swapping in-place easier to write
-
-#define SWAP16(x)	x = SWAP_BYTES_16(x)
-#define SWAP32(x)	x = SWAP_BYTES_32(x)
-
-void convertEndian(byte *file, uint32 len) {
-	int i;
-	StandardHeader *hdr = (StandardHeader *)file;
-
-	file += sizeof(StandardHeader);
-
-	SWAP32(hdr->compSize);
-	SWAP32(hdr->decompSize);
-
-	switch (hdr->fileType) {
-	case ANIMATION_FILE: {
-		AnimHeader *animHead = (AnimHeader *)file;
-
-		SWAP16(animHead->noAnimFrames);
-		SWAP16(animHead->feetStartX);
-		SWAP16(animHead->feetStartY);
-		SWAP16(animHead->feetEndX);
-		SWAP16(animHead->feetEndY);
-		SWAP16(animHead->blend);
-
-		CdtEntry *cdtEntry = (CdtEntry *)(file + sizeof(AnimHeader));
-		for (i = 0; i < animHead->noAnimFrames; i++, cdtEntry++) {
-			SWAP16(cdtEntry->x);
-			SWAP16(cdtEntry->y);
-			SWAP32(cdtEntry->frameOffset);
-
-			FrameHeader *frameHeader = (FrameHeader *)(file + cdtEntry->frameOffset);
-			// Quick trick to prevent us from incorrectly applying the endian
-			// fixes multiple times. This assumes that frames are less than 1 MB
-			// and have height/width less than 4096.
-			if ((frameHeader->compSize & 0xFFF00000) ||
-				(frameHeader->width & 0xF000) ||
-				(frameHeader->height & 0xF000)) {
-				SWAP32(frameHeader->compSize);
-				SWAP16(frameHeader->width);
-				SWAP16(frameHeader->height);
-			}
-		}
-		break;
-	}
-	case SCREEN_FILE: {
-		MultiScreenHeader *mscreenHeader = (MultiScreenHeader *)file;
-
-		SWAP32(mscreenHeader->palette);
-		SWAP32(mscreenHeader->bg_parallax[0]);
-		SWAP32(mscreenHeader->bg_parallax[1]);
-		SWAP32(mscreenHeader->screen);
-		SWAP32(mscreenHeader->fg_parallax[0]);
-		SWAP32(mscreenHeader->fg_parallax[1]);
-		SWAP32(mscreenHeader->layers);
-		SWAP32(mscreenHeader->paletteTable);
-		SWAP32(mscreenHeader->maskOffset);
-
-		// screenHeader
-		ScreenHeader *screenHeader = (ScreenHeader *)(file + mscreenHeader->screen);
-
-		SWAP16(screenHeader->width);
-		SWAP16(screenHeader->height);
-		SWAP16(screenHeader->noLayers);
-
-		// layerHeader
-		LayerHeader *layerHeader = (LayerHeader *)(file + mscreenHeader->layers);
-		for (i = 0; i < screenHeader->noLayers; i++, layerHeader++) {
-			SWAP16(layerHeader->x);
-			SWAP16(layerHeader->y);
-			SWAP16(layerHeader->width);
-			SWAP16(layerHeader->height);
-			SWAP32(layerHeader->maskSize);
-			SWAP32(layerHeader->offset);
-		}
-
-		// backgroundParallaxLayer
-		Parallax *parallax;
-		int offset;
-		offset = mscreenHeader->bg_parallax[0];
-		if (offset > 0) {
-			parallax = (Parallax *)(file + offset);
-			SWAP16(parallax->w);
-			SWAP16(parallax->h);
-		}
-
-		offset = mscreenHeader->bg_parallax[1];
-		if (offset > 0) {
-			parallax = (Parallax *)(file + offset);
-			SWAP16(parallax->w);
-			SWAP16(parallax->h);
-		}
-
-		// backgroundLayer
-		offset = mscreenHeader->screen + sizeof(ScreenHeader);
-		if (offset > 0) {
-			parallax = (Parallax *)(file + offset);
-			SWAP16(parallax->w);
-			SWAP16(parallax->h);
-		}
-
-		// foregroundParallaxLayer
-		offset = mscreenHeader->fg_parallax[0];
-		if (offset > 0) {
-			parallax = (Parallax *)(file + offset);
-			SWAP16(parallax->w);
-			SWAP16(parallax->h);
-		}
-
-		offset = mscreenHeader->fg_parallax[1];
-		if (offset > 0) {
-			parallax = (Parallax *)(file + offset);
-			SWAP16(parallax->w);
-			SWAP16(parallax->h);
-		}
-		break;
-	}
-	case GAME_OBJECT: {
-		ObjectHub *objectHub = (ObjectHub *)file;
-
-		objectHub->type = (int) SWAP_BYTES_32(objectHub->type);
-		SWAP32(objectHub->logic_level);
-
-		for (i = 0; i < TREE_SIZE; i++) {
-			SWAP32(objectHub->logic[i]);
-			SWAP32(objectHub->script_id[i]);
-			SWAP32(objectHub->script_pc[i]);
-		}
-		break;
-	}
-	case WALK_GRID_FILE: {
-		WalkGridHeader *walkGridHeader = (WalkGridHeader *)file;
-
-		SWAP32(walkGridHeader->numBars);
-		SWAP32(walkGridHeader->numNodes);
-
-		BarData *barData = (BarData *)(file + sizeof(WalkGridHeader));
-		for (i = 0; i < walkGridHeader->numBars; i++) {
-			SWAP16(barData->x1);
-			SWAP16(barData->y1);
-			SWAP16(barData->x2);
-			SWAP16(barData->y2);
-			SWAP16(barData->xmin);
-			SWAP16(barData->ymin);
-			SWAP16(barData->xmax);
-			SWAP16(barData->ymax);
-			SWAP16(barData->dx);
-			SWAP16(barData->dy);
-			SWAP32(barData->co);
-			barData++;
-		}
-
-		uint16 *node = (uint16 *)(file + sizeof(WalkGridHeader) + walkGridHeader->numBars * sizeof(BarData));
-		for (i = 0; i < walkGridHeader->numNodes * 2; i++) {
-			SWAP16(*node);
-			node++;
-		}
-
-		break;
-	}
-	case GLOBAL_VAR_FILE:
-		break;
-	case PARALLAX_FILE_null:
-		break;
-	case RUN_LIST: {
-		uint32 *list = (uint32 *)file;
-		while (*list) {
-			SWAP32(*list);
-			list++;
-		}
-		break;
-	}
-	case TEXT_FILE: {
-		TextHeader *textHeader = (TextHeader *)file;
-		SWAP32(textHeader->noOfLines);
-		break;
-	}
-	case SCREEN_MANAGER:
-		break;
-	case MOUSE_FILE:
-		break;
-	case ICON_FILE:
-		break;
-	}
-}
-
 /**
  * Returns the address of a resource. Loads if not in memory. Retains a count.
  */
@@ -440,12 +246,11 @@
 		file->read(_resList[res].ptr, len);
 
 		if (dump) {
-			StandardHeader *header = (StandardHeader *)_resList[res].ptr;
 			char buf[256];
 			const char *tag;
 			Common::File out;
 
-			switch (header->fileType) {
+			switch (fetchType(_resList[res].ptr)) {
 			case ANIMATION_FILE:
 				tag = "anim";
 				break;
@@ -508,10 +313,6 @@
 
 		_usedMem += len;
 		checkMemUsage();
-
-#ifdef SCUMM_BIG_ENDIAN
-		convertEndian(_resList[res].ptr, len);
-#endif
 	} else if (_resList[res].refCount == 0)
 		removeFromCacheList(_resList + res);
 
@@ -732,10 +533,8 @@
 			continue;
 
 		if (_resList[i].ptr) {
-			StandardHeader *header = (StandardHeader *)_resList[i].ptr;
-
 			if (wantInfo)
-				Debug_Printf("Nuked %5d: %s\n", i, header->name);
+				Debug_Printf("Nuked %5d: %s\n", i, fetchName(_resList[i].ptr));
 
 			remove(i);
 			nuked++;
@@ -764,11 +563,9 @@
 			continue;
 
 		if (_resList[i].ptr) {
-			StandardHeader *header = (StandardHeader *)_resList[i].ptr;
-
-			if (header->fileType == GAME_OBJECT) {
+			if (fetchType(_resList[i].ptr) == GAME_OBJECT) {
 				if (wantInfo)
-					Debug_Printf("Nuked %5d: %s\n", i, header->name);
+					Debug_Printf("Nuked %5d: %s\n", i, fetchName(_resList[i].ptr));
 
 				remove(i);
 				nuked++;

Index: resman.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/resman.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- resman.h	18 Oct 2005 01:30:25 -0000	1.28
+++ resman.h	29 Oct 2005 21:24:53 -0000	1.29
@@ -91,6 +91,29 @@
 
 	bool checkValid(uint32 res);
 	uint32 fetchLen(uint32 res);
+	uint8 fetchType(uint32 res) {
+		byte *ptr = openResource(res);
+		uint8 type = ptr[0];
+		closeResource(res);
+
+		return type;
+	}
+
+	uint8 fetchType(byte *ptr) {
+		return ptr[0];
+	}
+
+	byte *fetchName(uint32 res, byte *buf) {
+		byte *ptr = openResource(res);
+		memcpy(buf, ptr + 10, NAME_LEN);
+		closeResource(res);
+
+		return buf;
+	}
+
+	byte *fetchName(byte *ptr) {
+		return ptr + 10;
+	}
 
 	// Prompts the user for the specified CD.
 	void getCd(int cd);

Index: router.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/router.cpp,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- router.cpp	18 Oct 2005 01:30:25 -0000	1.50
+++ router.cpp	29 Oct 2005 21:24:53 -0000	1.51
@@ -74,6 +74,7 @@
  ****************************************************************************/
 
 #include "common/stdafx.h"
+#include "common/stream.h"
 #include "sword2/sword2.h"
 #include "sword2/defs.h"
 #include "sword2/logic.h"
@@ -82,8 +83,24 @@
 
 namespace Sword2 {
 
+//----------------------------------------------------------
+// (4) WALK-GRID FILES
+//----------------------------------------------------------
+// a walk-grid file consists of:
+//
+// standard file header
+// walk-grid file header
+// walk-grid data
+
+// Walk-Grid Header - taken directly from old "header.h" in STD_INC
+
+struct WalkGridHeader {
+	int32 numBars;		// number of bars on the floor
+	int32 numNodes;		// number of nodes
+};
+
 uint8 Router::returnSlotNo(uint32 megaId) {
-	if (Logic::_scriptVars[ID] == CUR_PLAYER_ID) {
+	if (_vm->_logic->readVar(ID) == CUR_PLAYER_ID) {
 		// George (8)
 		return 0;
 	} else {
@@ -101,7 +118,7 @@
 	// in middle of route, the old route will be safely cleared from
 	// memory just before they create a new one
 
-	slotNo = returnSlotNo(Logic::_scriptVars[ID]);
+	slotNo = returnSlotNo(_vm->_logic->readVar(ID));
 
 	// if this slot is already used, then it can't be needed any more
 	// because this id is creating a new route!
@@ -125,13 +142,13 @@
 }
 
 WalkData *Router::getRouteMem() {
-	uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]);
+	uint8 slotNo = returnSlotNo(_vm->_logic->readVar(ID));
 
 	return (WalkData *)_routeSlots[slotNo];
 }
 
 void Router::freeRouteMem() {
-	uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]);
+	uint8 slotNo = returnSlotNo(_vm->_logic->readVar(ID));
 
 	free(_routeSlots[slotNo]);
 	_routeSlots[slotNo] = NULL;
@@ -144,7 +161,7 @@
 	}
 }
 
-int32 Router::routeFinder(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int32 x, int32 y, int32 dir) {
+int32 Router::routeFinder(byte *ob_mega, byte *ob_walkdata, int32 x, int32 y, int32 dir) {
 	/*********************************************************************
 	 * RouteFinder.C		polygon router with modular walks
 	 * 						21 august 94
@@ -677,8 +694,8 @@
 // SLOW IN
 
 bool Router::addSlowInFrames(WalkData *walkAnim) {
-	if (_usingSlowInFrames && _modularPath[1].num > 0) {
-		for (uint slowInFrameNo = 0; slowInFrameNo < _numberOfSlowInFrames[_currentDir]; slowInFrameNo++) {
+	if (_walkData.usingSlowInFrames && _modularPath[1].num > 0) {
+		for (int slowInFrameNo = 0; slowInFrameNo < _walkData.nSlowInFrames[_currentDir]; slowInFrameNo++) {
 			walkAnim[_stepCount].frame = _firstSlowInFrame[_currentDir] + slowInFrameNo;
 			walkAnim[_stepCount].step = 0;
 			walkAnim[_stepCount].dir = _currentDir;
@@ -692,11 +709,13 @@
 	return false;
 }
 
-void Router::earlySlowOut(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata) {
+void Router::earlySlowOut(byte *ob_mega, byte *ob_walkdata) {
 	int32 slowOutFrameNo;
 	int32 walk_pc;
 	WalkData *walkAnim;
 
+	ObjectMega obMega(ob_mega);
+
 	debug(5, "EARLY SLOW-OUT");
 
 	loadWalkData(ob_walkdata);
@@ -709,12 +728,12 @@
 	debug(5, "_firstSlowOutFrame = %d", _firstSlowOutFrame);
 	debug(5, "********************************");
 
- 	walk_pc = ob_mega->walk_pc;
+ 	walk_pc = obMega.getWalkPc();
 
 	walkAnim = getRouteMem();
 
 	// if this mega does actually have slow-out frames
-	if (_usingSlowOutFrames) {
+	if (_walkData.usingSlowOutFrames) {
 		// overwrite the next step (half a cycle) of the walk
 		// (ie .step - 0..5)
 
@@ -787,7 +806,7 @@
 	// if the mega did actually walk, we overwrite the last step (half a
 	// cycle) with slow-out frames + add any necessary stationary frames
 
- 	if (_usingSlowOutFrames && _lastCount >= _framesPerStep) {
+ 	if (_walkData.usingSlowOutFrames && _lastCount >= _framesPerStep) {
 		// place stop frames here
 		// slowdown at the end of the last walk
 
@@ -904,7 +923,7 @@
 		// rotate to new walk direction
 		// for george and nico put in a head turn at the start
 
-		if (_usingStandingTurnFrames) {
+		if (_walkData.usingStandingTurnFrames) {
 			// new frames for turn frames	29oct95jps
 			if (turnDir < 0)
 				module = _firstStandingTurnLeftFrame + lastDir;
@@ -964,7 +983,7 @@
 
 	// (0 = left; 1 = right)
 
-	if (_leadingLeg[_currentDir] == 0) {
+	if (_walkData.leadingLeg[_currentDir] == 0) {
 		// start the walk on the left leg (ie. at beginning of the
 		// first step of the walk cycle)
 		left = 0;
@@ -1010,8 +1029,8 @@
 			scale = (_scaleA * _moduleY + _scaleB);
 
 			do {
-				module16X += _dx[module] * scale;
-				module16Y += _dy[module] * scale;
+				module16X += _walkData.dx[module] * scale;
+				module16Y += _walkData.dy[module] * scale;
 				_moduleX = module16X >> 16;
 				_moduleY = module16Y >> 16;
 				walkAnim[_stepCount].frame = module;
@@ -1109,7 +1128,7 @@
 				// check each turn condition in turn
 
 				 // only for george
-				if (lastDir != 99 && _currentDir != 99 && _usingWalkingTurnFrames) {
+				if (lastDir != 99 && _currentDir != 99 && _walkData.usingWalkingTurnFrames) {
 					// 1 and -7 going right -1 and 7 going
 					// left
 					lastDir = _currentDir - lastDir;
@@ -1199,7 +1218,7 @@
 		// rotate to target direction
 		// for george and nico put in a head turn at the start
 
-		if (_usingStandingTurnFrames) {
+		if (_walkData.usingStandingTurnFrames) {
 			// new frames for turn frames	29oct95jps
 			if (turnDir < 0)
 				module = _firstStandingTurnLeftFrame + lastDir;
@@ -1410,7 +1429,7 @@
 		// rotate to new walk direction
 		// for george and nico put in a head turn at the start
 
-		if (_usingStandingTurnFrames) {
+		if (_walkData.usingStandingTurnFrames) {
 			// new frames for turn frames	29oct95jps
 			if (turnDir < 0)
 				module = _firstStandingTurnLeftFrame + lastDir;
@@ -1468,7 +1487,7 @@
 	// slow-in frames were drawn
 
 	// (0 = left; 1 = right)
-	if (_leadingLeg[_currentDir] == 0) {
+	if (_walkData.leadingLeg[_currentDir] == 0) {
 		// start the walk on the left leg (ie. at beginning of the
 		// first step of the walk cycle)
 		left = 0;
@@ -1504,8 +1523,8 @@
 				scale = (_scaleA * _moduleY + _scaleB);
 
 				do {
-					module16X += _dx[module] * scale;
-					module16Y += _dy[module] * scale;
+					module16X += _walkData.dx[module] * scale;
+					module16Y += _walkData.dy[module] * scale;
 					_moduleX = module16X >> 16;
 					_moduleY = module16Y >> 16;
 					walkAnim[_stepCount].frame = module;
@@ -1551,8 +1570,8 @@
 						// walk
 
 						if (slowStart) {
-							_stepCount -= _numberOfSlowInFrames[_currentDir];
-							_lastCount -= _numberOfSlowInFrames[_currentDir];
+							_stepCount -= _walkData.nSlowInFrames[_currentDir];
+							_lastCount -= _walkData.nSlowInFrames[_currentDir];
 							slowStart = false;
 						}
 
@@ -1564,7 +1583,7 @@
 					}
 
 					// check each turn condition in turn
-					if (lastDir != 99 && _currentDir != 99 && _usingWalkingTurnFrames) {
+					if (lastDir != 99 && _currentDir != 99 && _walkData.usingWalkingTurnFrames) {
 						// only for george
 						// 1 and -7 going right -1 and
 						// 7 going left
@@ -2091,38 +2110,30 @@
 
 // THE SETUP ROUTINES
 
-void Router::loadWalkData(ObjectWalkdata *ob_walkdata) {
+void Router::loadWalkData(byte *ob_walkdata) {
 	uint16 firstFrameOfDirection;
 	uint16 walkFrameNo;
 	uint32 frameCounter = 0; // starts at frame 0 of mega set
+	int i;
 
-	_nWalkFrames = ob_walkdata->nWalkFrames;
-	_usingStandingTurnFrames = ob_walkdata->usingStandingTurnFrames;
-	_usingWalkingTurnFrames = ob_walkdata->usingWalkingTurnFrames;
-	_usingSlowInFrames = ob_walkdata->usingSlowInFrames;
-	_usingSlowOutFrames = ob_walkdata->usingSlowOutFrames;
+	_walkData.read(ob_walkdata);
 
 	// 0 = not using slow out frames; non-zero = using that many frames
 	// for each leading leg for each direction
 
-	_numberOfSlowOutFrames = _usingSlowOutFrames;
-
- 	memcpy(&_numberOfSlowInFrames[0], ob_walkdata->nSlowInFrames, NO_DIRECTIONS * sizeof(_numberOfSlowInFrames[0]));
- 	memcpy(&_leadingLeg[0], ob_walkdata->leadingLeg, NO_DIRECTIONS * sizeof(_leadingLeg[0]));
- 	memcpy(&_dx[0], ob_walkdata->dx, NO_DIRECTIONS * (_nWalkFrames + 1) * sizeof(_dx[0]));
- 	memcpy(&_dy[0], ob_walkdata->dy, NO_DIRECTIONS * (_nWalkFrames + 1) * sizeof(_dy[0]));
+	_numberOfSlowOutFrames = _walkData.usingSlowOutFrames;
 
-	for (int i = 0; i < NO_DIRECTIONS; i++) {
-		firstFrameOfDirection = i * _nWalkFrames;
+	for (i = 0; i < NO_DIRECTIONS; i++) {
+		firstFrameOfDirection = i * _walkData.nWalkFrames;
 
 		_modX[i] = 0;
 		_modY[i] = 0;
 
-		for (walkFrameNo = firstFrameOfDirection; walkFrameNo < firstFrameOfDirection + _nWalkFrames / 2; walkFrameNo++) {
+		for (walkFrameNo = firstFrameOfDirection; walkFrameNo < firstFrameOfDirection + _walkData.nWalkFrames / 2; walkFrameNo++) {
 			// eg. _modX[0] is the sum of the x-step sizes for the
 			// first half of the walk cycle for direction 0
-			_modX[i] += _dx[walkFrameNo];
-			_modY[i] += _dy[walkFrameNo];
+			_modX[i] += _walkData.dx[walkFrameNo];
+			_modY[i] += _walkData.dy[walkFrameNo];
 		}
 	}
 
@@ -2131,8 +2142,8 @@
 
 	// interpret the walk data
 
-	_framesPerStep = _nWalkFrames / 2;
-	_framesPerChar = _nWalkFrames * NO_DIRECTIONS;
+	_framesPerStep = _walkData.nWalkFrames / 2;
+	_framesPerChar = _walkData.nWalkFrames * NO_DIRECTIONS;
 
 	// offset pointers added Oct 30 95 JPS
 	// mega id references removed 16sep96 by JEL
@@ -2155,7 +2166,7 @@
 	// standing turn-left frames come after the standing turn-right frames
 	// one for each direction
 
-	if (_usingStandingTurnFrames) {
+	if (_walkData.usingStandingTurnFrames) {
 		_firstStandingTurnLeftFrame = frameCounter;
 		frameCounter += NO_DIRECTIONS;
 
@@ -2171,7 +2182,7 @@
 	// walking left-turn frames come after the stand frames
 	// walking right-turn frames come after the walking left-turn frames
 
-	if (_usingWalkingTurnFrames) {
+	if (_walkData.usingWalkingTurnFrames) {
 		_firstWalkingTurnLeftFrame = frameCounter;
 		frameCounter += _framesPerChar;
 
@@ -2185,21 +2196,21 @@
 	// SLOW-IN FRAMES - OPTIONAL!
 	// slow-in frames come after the walking right-turn frames
 
-	if (_usingSlowInFrames) {
+	if (_walkData.usingSlowInFrames) {
 		// Make note of frame number of first slow-in frame for each
 		// direction. There may be a different number of slow-in
 		// frames in each direction
 
-		for (int i = 0; i < NO_DIRECTIONS; i++) {
+		for (i = 0; i < NO_DIRECTIONS; i++) {
 			_firstSlowInFrame[i] = frameCounter;
-			frameCounter += _numberOfSlowInFrames[i];
+			frameCounter += _walkData.nSlowInFrames[i];
 		}
 	}
 
 	// SLOW-OUT FRAMES - OPTIONAL!
 	// slow-out frames come after the slow-in frames
 
-	if (_usingSlowOutFrames)
+	if (_walkData.usingSlowOutFrames)
 		_firstSlowOutFrame = frameCounter;
 }
 
@@ -2316,22 +2327,24 @@
 	return;
 }
 
-void Router::setUpWalkGrid(ObjectMega *ob_mega, int32 x, int32 y, int32 dir) {
+void Router::setUpWalkGrid(byte *ob_mega, int32 x, int32 y, int32 dir) {
+	ObjectMega obMega(ob_mega);
+
 	// get walk grid file + extra grid into 'bars' & 'node' arrays
 	loadWalkGrid();
 
 	// copy the mega structure into the local variables for use in all
 	// subroutines
 
-	_startX = ob_mega->feet_x;
-	_startY = ob_mega->feet_y;
-	_startDir = ob_mega->current_dir;
+	_startX = obMega.getFeetX();
+	_startY = obMega.getFeetY();
+	_startDir = obMega.getCurDir();
 	_targetX = x;
 	_targetY = y;
 	_targetDir = dir;
 
-	_scaleA = ob_mega->scale_a;
-	_scaleB = ob_mega->scale_b;
+	_scaleA = obMega.getScaleA();
+	_scaleB = obMega.getScaleB();
 
 	// mega's current position goes into first node
 
@@ -2383,8 +2396,7 @@
 void Router::loadWalkGrid() {
 	WalkGridHeader floorHeader;
 	byte *fPolygrid;
-	uint32 theseBars;
-	uint32 theseNodes;
+	uint16 fPolygridLen;
 
 	_nBars	= 0;	// reset counts
 	_nNodes	= 1;	// leave node 0 for start-node
@@ -2394,37 +2406,47 @@
 	// go through walkgrid list
 	for (int i = 0; i < MAX_WALKGRIDS; i++) {
 		if (_walkGridList[i]) {
+			int j;
+
 			// open walk grid file
 			fPolygrid = _vm->_resman->openResource(_walkGridList[i]);
- 			fPolygrid += sizeof(StandardHeader);
- 			memcpy((byte *)&floorHeader, fPolygrid, sizeof(WalkGridHeader));
- 			fPolygrid += sizeof(WalkGridHeader);
+			fPolygridLen = _vm->_resman->fetchLen(_walkGridList[i]);
 
-			// how many bars & nodes are we getting from this
-			// walkgrid file
+			Common::MemoryReadStream readS(fPolygrid, fPolygridLen);
 
-			theseBars = floorHeader.numBars;
-			theseNodes = floorHeader.numNodes;
+			readS.seek(ResHeader::size());
+
+			floorHeader.numBars = readS.readSint32LE();
+			floorHeader.numNodes = readS.readSint32LE();
 
 			// check that we're not going to exceed the max
 			// allowed in the complete walkgrid arrays
 
-			assert(_nBars + theseBars < O_GRID_SIZE);
-			assert(_nNodes + theseNodes < O_GRID_SIZE);
+			assert(_nBars + floorHeader.numBars < O_GRID_SIZE);
+			assert(_nNodes + floorHeader.numNodes < O_GRID_SIZE);
 
 			// lines
 
- 			memcpy((byte *)&_bars[_nBars], fPolygrid, theseBars * sizeof(BarData));
-
-			// move pointer to start of node data
-			fPolygrid += theseBars * sizeof(BarData);
+			for (j = 0; j < floorHeader.numBars; j++) {
+				_bars[_nBars + j].x1 = readS.readSint16LE();
+				_bars[_nBars + j].y1 = readS.readSint16LE();
+				_bars[_nBars + j].x2 = readS.readSint16LE();
+				_bars[_nBars + j].y2 = readS.readSint16LE();
+				_bars[_nBars + j].xmin = readS.readSint16LE();
+				_bars[_nBars + j].ymin = readS.readSint16LE();
+				_bars[_nBars + j].xmax = readS.readSint16LE();
+				_bars[_nBars + j].ymax = readS.readSint16LE();
+				_bars[_nBars + j].dx = readS.readSint16LE();
+				_bars[_nBars + j].dy = readS.readSint16LE();
+				_bars[_nBars + j].co = readS.readSint32LE();
+			}
 
 			// nodes
 
 			// leave node 0 for start node
-			for (uint j = 0; j < theseNodes; j++) {
-				memcpy((byte *)&_node[_nNodes + j].x, fPolygrid, 2 * sizeof(int16));
-				fPolygrid += 2 * sizeof(int16);
+			for (j = 0; j < floorHeader.numNodes; j++) {
+				_node[_nNodes + j].x = readS.readSint16LE();
+				_node[_nNodes + j].y = readS.readSint16LE();
 			}
 
 			// close walk grid file
@@ -2433,8 +2455,8 @@
 			// increment counts of total bars & nodes in whole
 			// walkgrid
 
-			_nBars += theseBars;
-			_nNodes	+= theseNodes;
+			_nBars += floorHeader.numBars;
+			_nNodes	+= floorHeader.numNodes;
 		}
 	}
 }

Index: router.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/router.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- router.h	18 Oct 2005 01:30:25 -0000	1.23
+++ router.h	29 Oct 2005 21:24:54 -0000	1.24
@@ -33,17 +33,13 @@
 
 namespace Sword2 {
 
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
 struct WalkData {
 	uint16 frame;
 	int16 x;
 	int16 y;
 	uint8 step;
 	uint8 dir;
-} GCC_PACK;
+};
 
 struct BarData {
 	int16 x1;
@@ -58,7 +54,7 @@
 	int16 dy;	// y2 - y1
 	int32 co;	// co = (y1 * dx) - (x1 * dy) from an equation for a
 			// line y * dx = x * dy + co
-} GCC_PACK;
+};
 
 struct NodeData {
 	int16 x;
@@ -66,11 +62,7 @@
 	int16 level;
 	int16 prev;
 	int16 dist;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
+};
 
 // because we only have 2 megas in the game!
 #define TOTAL_ROUTE_SLOTS	2
@@ -137,13 +129,8 @@
 	int32 _framesPerStep;
 	int32 _framesPerChar;
 
-	uint8 _nWalkFrames;			// no. of frames per walk cycle
-	uint8 _usingStandingTurnFrames;		// any standing turn frames?
-	uint8 _usingWalkingTurnFrames;		// any walking turn frames?
-	uint8 _usingSlowInFrames;		// any slow-in frames?
-	uint8 _usingSlowOutFrames;		// any slow-out frames?
-	int32 _dx[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR];
-	int32 _dy[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR];
+	ObjectWalkdata _walkData;
+
 	int8 _modX[NO_DIRECTIONS];
 	int8 _modY[NO_DIRECTIONS];
 	int32 _diagonalx;
@@ -158,9 +145,6 @@
 	int32 _firstWalkingTurnRightFrame;	// right walking turn
 
 	uint32 _firstSlowInFrame[NO_DIRECTIONS];
-	uint32 _numberOfSlowInFrames[NO_DIRECTIONS];
-
-	uint32 _leadingLeg[NO_DIRECTIONS];
 
 	int32 _firstSlowOutFrame;
 
@@ -183,8 +167,8 @@
 	int32 getRoute();
 	void extractRoute();
 	void loadWalkGrid();
-	void setUpWalkGrid(ObjectMega *ob_mega, int32 x, int32 y, int32 dir);
-	void loadWalkData(ObjectWalkdata *ob_walkdata);
+	void setUpWalkGrid(byte *ob_mega, int32 x, int32 y, int32 dir);
+	void loadWalkData(byte *ob_walkdata);
 	bool scan(int32 level);
 
 	int32 newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2);
@@ -219,44 +203,40 @@
 		memset(_route, 0, sizeof(_route));
 		memset(_smoothPath, 0, sizeof(_smoothPath));
 		memset(_modularPath, 0, sizeof(_modularPath));
-		memset(_dx, 0, sizeof(_dx));
-		memset(_dy, 0, sizeof(_dy));
 		memset(_modX, 0, sizeof(_modX));
 		memset(_modY, 0, sizeof(_modY));
 		memset(_firstSlowInFrame, 0, sizeof(_firstSlowInFrame));
-		memset(_numberOfSlowInFrames, 0, sizeof(_numberOfSlowInFrames));
-		memset(_leadingLeg, 0, sizeof(_leadingLeg));
 	}
 
 	void setStandbyCoords(int16 x, int16 y, uint8 dir);
 	int whatTarget(int startX, int startY, int destX, int destY);
 
 	// Sprites
-	void setSpriteStatus(ObjectGraphic *ob_graph, uint32 type);
-	void setSpriteShading(ObjectGraphic *ob_graph, uint32 type);
+	void setSpriteStatus(byte *ob_graph, uint32 type);
+	void setSpriteShading(byte *ob_graph, uint32 type);
 
 	// Animation
-	int doAnimate(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, int32 animRes, bool reverse);
-	int megaTableAnimate(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, uint32 *animTable, bool reverse);
+	int doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool reverse);
+	int megaTableAnimate(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *animTable, bool reverse);
 
 	// Walking
-	int doWalk(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int16 target_x, int16 target_y, uint8 target_dir);
-	int walkToAnim(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint32 animRes);
-	int walkToTalkToMega(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint32 megaId, uint32 separation);
+	int doWalk(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y, uint8 target_dir);
+	int walkToAnim(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 animRes);
+	int walkToTalkToMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId, uint32 separation);
 
 	// Turning
-	int doFace(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint8 target_dir);
-	int faceXY(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int16 target_x, int16 target_y);
-	int faceMega(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint32 megaId);
+	int doFace(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint8 target_dir);
+	int faceXY(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y);
+	int faceMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId);
 
 	// Standing
-	void standAt(ObjectGraphic *ob_graph, ObjectMega *ob_mega, int32 x, int32 y, int32 dir);
-	void standAfterAnim(ObjectGraphic *ob_graph, ObjectMega *ob_mega, uint32 animRes);
-	void standAtAnim(ObjectGraphic *ob_graph, ObjectMega *ob_mega, uint32 animRes);
+	void standAt(byte *ob_graph, byte *ob_mega, int32 x, int32 y, int32 dir);
+	void standAfterAnim(byte *ob_graph, byte *ob_mega, uint32 animRes);
+	void standAtAnim(byte *ob_graph, byte *ob_mega, uint32 animRes);
 
-	int32 routeFinder(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int32 x, int32 y, int32 dir);
+	int32 routeFinder(byte *ob_mega, byte *ob_walkdata, int32 x, int32 y, int32 dir);
 
-	void earlySlowOut(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata);
+	void earlySlowOut(byte *ob_mega, byte *ob_walkdata);
 
 	void allocateRouteMem();
 	WalkData *getRouteMem();

Index: save_rest.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/save_rest.cpp,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -d -r1.75 -r1.76
--- save_rest.cpp	18 Oct 2005 01:30:25 -0000	1.75
+++ save_rest.cpp	29 Oct 2005 21:24:54 -0000	1.76
@@ -43,63 +43,58 @@
 // Max length of a savegame filename
 #define	MAX_FILENAME_LEN 128
 
-#ifdef SCUMM_BIG_ENDIAN
-// Quick macro to make swapping in-place easier to write
-#define SWAP32(x)	x = SWAP_BYTES_32(x)
-
-static void convertHeaderEndian(Sword2Engine::SaveGameHeader &header) {
-	// SaveGameHeader
-	SWAP32(header.checksum);
-	SWAP32(header.varLength);
-	SWAP32(header.screenId);
-	SWAP32(header.runListId);
-	SWAP32(header.feet_x);
-	SWAP32(header.feet_y);
-	SWAP32(header.music_id);
-
-	// ObjectHub
-	SWAP32(header.player_hub.type);
-	SWAP32(header.player_hub.logic_level);
-	for (int i = 0; i < TREE_SIZE; i++) {
-		SWAP32(header.player_hub.logic[i]);
-		SWAP32(header.player_hub.script_id[i]);
-		SWAP32(header.player_hub.script_pc[i]);
-	}
-
-	// ObjectLogic
-	SWAP32(header.logic.looping);
-	SWAP32(header.logic.pause);
-
-	// ObjectGraphic
-	SWAP32(header.graphic.type);
-	SWAP32(header.graphic.anim_resource);
-	SWAP32(header.graphic.anim_pc);
+/**
+ * Calculate size of required savegame buffer
+ */
 
-	// ObjectMega
-	SWAP32(header.mega.currently_walking);
-	SWAP32(header.mega.walk_pc);
-	SWAP32(header.mega.scale_a);
-	SWAP32(header.mega.scale_b);
-	SWAP32(header.mega.feet_x);
-	SWAP32(header.mega.feet_y);
-	SWAP32(header.mega.current_dir);
-	SWAP32(header.mega.megaset_res);
+uint32 Sword2Engine::findBufferSize() {
+	// Size of savegame header + size of global variables
+	return 212 + _resman->fetchLen(1);
 }
-#endif
 
 /**
  * Save the game.
  */
 
 uint32 Sword2Engine::saveGame(uint16 slotNo, byte *desc) {
+	char description[SAVE_DESCRIPTION_LEN];
 	uint32 bufferSize = findBufferSize();
-	byte *saveBufferMem = (byte *)malloc(bufferSize);
+	byte *saveBuffer = (byte *)malloc(bufferSize);
+	ScreenInfo *screenInfo = _screen->getScreenInfo();
 
-	fillSaveBuffer(saveBufferMem, bufferSize, desc);
+	memset(description, 0, sizeof(description));
+	strncpy(description, (char *)desc, SAVE_DESCRIPTION_LEN - 1);
 
-	uint32 errorCode = saveData(slotNo, saveBufferMem, bufferSize);
+	Common::MemoryWriteStream writeS(saveBuffer, bufferSize);
 
-	free(saveBufferMem);
+	byte *globalVars = _resman->openResource(1);
+	byte *objectHub = _resman->openResource(CUR_PLAYER_ID) + ResHeader::size();
+
+	// Script no. 7 - 'george_savedata_request' calls fnPassPlayerSaveData
+	_logic->runResScript(CUR_PLAYER_ID, 7);
+
+	writeS.writeUint32LE(0);	// Checksum
+	writeS.write(description, SAVE_DESCRIPTION_LEN);
+	writeS.writeUint32LE(_resman->fetchLen(1));
+	writeS.writeUint32LE(screenInfo->background_layer_id);
+	writeS.writeUint32LE(_logic->getRunList());
+	writeS.writeUint32LE(screenInfo->feet_x);
+	writeS.writeUint32LE(screenInfo->feet_y);
+	writeS.writeUint32LE(_sound->getLoopingMusicId());
+	writeS.write(objectHub, ObjectHub::size());
+	writeS.write(_logic->_saveLogic, ObjectLogic::size());
+	writeS.write(_logic->_saveGraphic, ObjectGraphic::size());
+	writeS.write(_logic->_saveMega, ObjectMega::size());
+	writeS.write(globalVars, _resman->fetchLen(1));
+
+	WRITE_LE_UINT32(saveBuffer, calcChecksum(saveBuffer + 4, bufferSize - 4));
+
+	_resman->closeResource(CUR_PLAYER_ID);
+	_resman->closeResource(1);
+
+	uint32 errorCode = saveData(slotNo, saveBuffer, bufferSize);
+
+	free(saveBuffer);
 
 	if (errorCode != SR_OK) {
 		uint32 textId;
@@ -119,65 +114,6 @@
 	return errorCode;
 }
 
-/**
- * Calculate size of required savegame buffer
- */
-
-uint32 Sword2Engine::findBufferSize() {
-	// Size of savegame header + size of global variables
-	return sizeof(_saveGameHeader) + _resman->fetchLen(1);
-}
-
-void Sword2Engine::fillSaveBuffer(byte *buffer, uint32 size, byte *desc) {
-	// Set up the _saveGameHeader. Checksum gets filled in last of all.
-	ScreenInfo *screenInfo = _screen->getScreenInfo();
-
-	strcpy(_saveGameHeader.description, (char *)desc);
-	_saveGameHeader.varLength = _resman->fetchLen(1);
-	_saveGameHeader.screenId = screenInfo->background_layer_id;
-	_saveGameHeader.runListId = _logic->getRunList();
-	_saveGameHeader.feet_x = screenInfo->feet_x;
-	_saveGameHeader.feet_y	= screenInfo->feet_y;
-	_saveGameHeader.music_id = _sound->getLoopingMusicId();
-
-	memcpy(&_saveGameHeader.player_hub, _resman->openResource(CUR_PLAYER_ID) + sizeof(StandardHeader), sizeof(ObjectHub));
-
-	_resman->closeResource(CUR_PLAYER_ID);
-
-	// Get the logic, graphic and mega structures
-	getPlayerStructures();
-
-#ifdef SCUMM_BIG_ENDIAN
-	convertHeaderEndian(_saveGameHeader);
-#endif
-
-	// Copy the header to the buffer, even though it isn't quite complete
-	memcpy(buffer, &_saveGameHeader, sizeof(_saveGameHeader));
-
-	// Get the global variables
-
-	byte *varsRes = _resman->openResource(1);
-	memcpy(buffer + sizeof(_saveGameHeader), varsRes, FROM_LE_32(_saveGameHeader.varLength));
-
-#ifdef SCUMM_BIG_ENDIAN
-	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++)
-		globalVars[i] = SWAP_BYTES_32(globalVars[i]);
-#endif
-
- 	_resman->closeResource(1);
-
-	// Finally, get the checksum
-
-	_saveGameHeader.checksum = TO_LE_32(calcChecksum(buffer + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum)));
-
-	// All done
-
-	memcpy(buffer, &_saveGameHeader.checksum, sizeof(_saveGameHeader.checksum));
-}
-
 uint32 Sword2Engine::saveData(uint16 slotNo, byte *buffer, uint32 bufferSize) {
 	char saveFileName[MAX_FILENAME_LEN];
 
@@ -284,20 +220,17 @@
 }
 
 uint32 Sword2Engine::restoreFromBuffer(byte *buffer, uint32 size) {
-	// Get a copy of the header from the savegame buffer
-	memcpy(&_saveGameHeader, buffer, sizeof(_saveGameHeader));
-
-#ifdef SCUMM_BIG_ENDIAN
-	convertHeaderEndian(_saveGameHeader);
-#endif
+	Common::MemoryReadStream readS(buffer, size);
 
 	// Calc checksum & check that aginst the value stored in the header
 
-	if (_saveGameHeader.checksum != calcChecksum(buffer + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum))) {
+	if (readS.readUint32LE() != calcChecksum(buffer + 4, size - 4)) {
 		free(buffer);
 		return SR_ERR_INCOMPATIBLE;
 	}
 
+	readS.seek(SAVE_DESCRIPTION_LEN, SEEK_CUR);
+
 	// Check savegame against length of current global variables resource
 	// This would most probably be trapped by the checksum test anyway,
 	// but it doesn't do any harm to check this as well.
@@ -305,49 +238,75 @@
 	// Historical note: During development, earlier savegames would often
 	// be shorter than the current expected length.
 
-	if (_saveGameHeader.varLength != _resman->fetchLen(1)) {
+	if (readS.readUint32LE() != _resman->fetchLen(1)) {
 		free(buffer);
 		return SR_ERR_INCOMPATIBLE;
 	}
 
-	// Clean out system
+	byte *globalVars = _resman->openResource(1);
+	byte *objectHub = _resman->openResource(CUR_PLAYER_ID) + ResHeader::size();
+
+	uint32 screenId = readS.readUint32LE();
+	uint32 runListId = readS.readUint32LE();
+	uint32 feetX = readS.readUint32LE();
+	uint32 feetY = readS.readUint32LE();
+	uint32 musicId = readS.readUint32LE();
 
 	// Trash all resources from memory except player object & global vars
 	_resman->killAll(false);
-
-	// Clean out the system kill list (no more objects to kill)
 	_logic->resetKillList();
 
-	// Object hub is just after the standard header
-	memcpy(_resman->openResource(CUR_PLAYER_ID) + sizeof(StandardHeader), &_saveGameHeader.player_hub, sizeof(ObjectHub));
+	readS.read(objectHub, ObjectHub::size());
+	readS.read(_logic->_saveLogic, ObjectLogic::size());
+	readS.read(_logic->_saveGraphic, ObjectGraphic::size());
+	readS.read(_logic->_saveMega, ObjectMega::size());
 
-	_resman->closeResource(CUR_PLAYER_ID);
+	// Fill out the player object structures from the savegame structures.
+	// Also run the appropriate scripts to set up George's anim tables and
+	// walkdata, and Nico's anim tables.
 
-	// Fill in the player object structures from the header
-	putPlayerStructures();
+	// Script no. 8 - 'george_savedata_return' calls fnGetPlayerSaveData
+	_logic->runResScript(CUR_PLAYER_ID, 8);
 
-	// Copy variables from savegame buffer to memory
-	byte *varsRes = _resman->openResource(1);
+	// Script no. 14 - 'set_up_nico_anim_tables'
+	_logic->runResScript(CUR_PLAYER_ID, 14);
 
-	memcpy(varsRes, buffer + sizeof(_saveGameHeader), _saveGameHeader.varLength);
+	// Which megaset was the player at the time of saving?
+	ObjectMega obMega(_logic->_saveMega);
 
-#ifdef SCUMM_BIG_ENDIAN
-	uint32 *globalVars = (uint32 *)(varsRes + sizeof(StandardHeader));
-	const uint numVars = (_saveGameHeader.varLength - sizeof(StandardHeader)) / 4;
+	uint32 scriptNo = 0;
 
-	for (uint i = 0; i < numVars; i++)
-		globalVars[i] = SWAP_BYTES_32(globalVars[i]);
-#endif
+	switch (obMega.getMegasetRes()) {
+	case 36:		// GeoMega:
+		scriptNo = 9;	// script no.9	- 'player_is_george'
+		break;
+	case 2003:		// GeoMegaB:
+		scriptNo = 13;	// script no.13 - 'player_is_georgeB'
+		break;
+	case 1366:		// NicMegaA:
+		scriptNo = 11;	// script no.11 - 'player_is_nicoA'
+		break;
+	case 1437:		// NicMegaB:
+		scriptNo = 12;	// script no.12 - 'player_is_nicoB'
+		break;
+	case 1575:		// NicMegaC:
+		scriptNo = 10;	// script no.10 - 'player_is_nicoC'
+		break;
+	}
+
+	_logic->runResScript(CUR_PLAYER_ID, scriptNo);
+
+	// Copy variables from savegame buffer to memory
+	readS.read(globalVars, _resman->fetchLen(1));
 
+	_resman->closeResource(CUR_PLAYER_ID);
  	_resman->closeResource(1);
 
-	// Free it now, rather than in RestoreGame, to unblock memory before
-	// new screen & runlist loaded
 	free(buffer);
 
 	int32 pars[2];
 
-	pars[0] = _saveGameHeader.screenId;
+	pars[0] = screenId;
 	pars[1] = 1;
 	_logic->fnInitBackground(pars);
 
@@ -361,19 +320,19 @@
 	// Remember that these can change through the game, so need saving &
 	// restoring too.
 
-	screenInfo->feet_x = _saveGameHeader.feet_x;
-	screenInfo->feet_y = _saveGameHeader.feet_y;
+	screenInfo->feet_x = feetX;
+	screenInfo->feet_y = feetY;
 
 	// Start the new run list
-	_logic->expressChangeSession(_saveGameHeader.runListId);
+	_logic->expressChangeSession(runListId);
 
 	// Force in the new scroll position, so unsightly scroll-catch-up does
 	// not occur when screen first draws after returning from restore panel
 
 	// Set the screen record of player position - ready for setScrolling()
 
-	screenInfo->player_feet_x = _saveGameHeader.mega.feet_x;
-	screenInfo->player_feet_y = _saveGameHeader.mega.feet_y;
+	screenInfo->player_feet_x = obMega.getFeetX();
+	screenInfo->player_feet_y = obMega.getFeetY();
 
 	// if this screen is wide, recompute the scroll offsets now
 	if (screenInfo->scroll_flag)
@@ -386,8 +345,8 @@
 	// in systemMenuMouse(), but with ScummVM we have other ways of
 	// restoring savegames so it's easier to put it here as well.
 
-	if (_saveGameHeader.music_id) {
-		pars[0] = _saveGameHeader.music_id;
+	if (musicId) {
+		pars[0] = musicId;
 		pars[1] = FX_LOOP;
 		_logic->fnPlayMusic(pars);
 	} else
@@ -411,12 +370,10 @@
 		return SR_ERR_FILEOPEN;
 	}
 
-	SaveGameHeader dummy;
+	in->readUint32LE();
+	in->read(description, SAVE_DESCRIPTION_LEN);
 
-	in->read(&dummy, sizeof(dummy));
 	delete in;
-
-	strcpy((char *)description, dummy.description);
 	return SR_OK;
 }
 
@@ -442,71 +399,6 @@
 	return true;
 }
 
-/**
- * Request the player object structures which need saving.
- */
-
-void Sword2Engine::getPlayerStructures() {
-	StandardHeader *head = (StandardHeader *)_resman->openResource(CUR_PLAYER_ID);
-
-	assert(head->fileType == GAME_OBJECT);
-
-	char *raw_script_ad = (char *)head;
-
-	// Script no. 7 - 'george_savedata_request' calls fnPassPlayerSaveData
-	uint32 null_pc = 7;
-
-	_logic->runScript(raw_script_ad, raw_script_ad, &null_pc);
-	_resman->closeResource(CUR_PLAYER_ID);
-}
-
-/**
- * Fill out the player object structures from the savegame structures also run
- * the appropriate scripts to set up george's anim tables and walkdata, and
- * Nico's anim tables.
- */
-
-void Sword2Engine::putPlayerStructures() {
-	StandardHeader *head = (StandardHeader *)_resman->openResource(CUR_PLAYER_ID);
-
-	assert(head->fileType == GAME_OBJECT);
-
-	char *raw_script_ad = (char *)head;
-
-	// Script no. 8 - 'george_savedata_return' calls fnGetPlayerSaveData
-
-	uint32 null_pc = 8;
-	_logic->runScript(raw_script_ad, raw_script_ad, &null_pc);
-
-	// Script no. 14 - 'set_up_nico_anim_tables'
-
-	null_pc = 14;
-	_logic->runScript(raw_script_ad, raw_script_ad, &null_pc);
-
-	// Which megaset was the player at the time of saving?
-
-	switch (_saveGameHeader.mega.megaset_res) {
-	case 36:		// GeoMega:
-		null_pc = 9;	// script no.9	- 'player_is_george'
-		break;
-	case 2003:		// GeoMegaB:
-		null_pc = 13;	// script no.13 - 'player_is_georgeB'
-		break;
-	case 1366:		// NicMegaA:
-		null_pc = 11;	// script no.11 - 'player_is_nicoA'
-		break;
-	case 1437:		// NicMegaB:
-		null_pc = 12;	// script no.12 - 'player_is_nicoB'
-		break;
-	case 1575:		// NicMegaC:
-		null_pc = 10;	// script no.10 - 'player_is_nicoC'
-		break;
-	}
-
-	_logic->runScript(raw_script_ad, raw_script_ad, &null_pc);
-	_resman->closeResource(CUR_PLAYER_ID);
-}
-
 uint32 Sword2Engine::calcChecksum(byte *buffer, uint32 size) {
 	uint32 total = 0;
 

Index: scroll.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/scroll.cpp,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- scroll.cpp	18 Oct 2005 01:30:25 -0000	1.24
+++ scroll.cpp	29 Oct 2005 21:24:54 -0000	1.25
@@ -54,10 +54,12 @@
 
 	// If the scroll offsets are being forced in script, ensure that they
 	// are neither too far to the right nor too far down.
+	uint32 scrollX = _vm->_logic->readVar(SCROLL_X);
+	uint32 scrollY = _vm->_logic->readVar(SCROLL_Y);
 
-	if (Logic::_scriptVars[SCROLL_X] || Logic::_scriptVars[SCROLL_Y]) {
-		_thisScreen.scroll_offset_x = MIN((uint16) Logic::_scriptVars[SCROLL_X], _thisScreen.max_scroll_offset_x);
-		_thisScreen.scroll_offset_y = MIN((uint16) Logic::_scriptVars[SCROLL_Y], _thisScreen.max_scroll_offset_y);
+	if (scrollX || scrollY) {
+		_thisScreen.scroll_offset_x = MIN((uint16)scrollX, _thisScreen.max_scroll_offset_x);
+		_thisScreen.scroll_offset_y = MIN((uint16)scrollY, _thisScreen.max_scroll_offset_y);
 		return;
 	}
 

Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/sound.cpp,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- sound.cpp	18 Oct 2005 01:30:25 -0000	1.63
+++ sound.cpp	29 Oct 2005 21:24:54 -0000	1.64
@@ -199,17 +199,16 @@
 
 		byte buf[NAME_LEN];
 
-		debug(0, "SFX (sample=\"%s\", vol=%d, pan=%d, delay=%d, type=%s)", _vm->fetchObjectName(res, buf), volume, pan, delay, typeStr);
+		debug(0, "SFX (sample=\"%s\", vol=%d, pan=%d, delay=%d, type=%s)", _vm->_resman->fetchName(res, buf), volume, pan, delay, typeStr);
 	}
 
 	for (int i = 0; i < FXQ_LENGTH; i++) {
 		if (!_fxQueue[i].resource) {
 			byte *data = _vm->_resman->openResource(res);
-			StandardHeader *header = (StandardHeader *)data;
 
-			assert(header->fileType == WAV_FILE);
+			assert(_vm->_resman->fetchType(data) == WAV_FILE);
 
-			uint32 len = _vm->_resman->fetchLen(res) - sizeof(StandardHeader);
+			uint32 len = _vm->_resman->fetchLen(res) - ResHeader::size();
 
 			if (type == FX_RANDOM) {
 				// For spot effects and loops the delay is the
@@ -227,7 +226,7 @@
 				pan = -pan;
 
 			_fxQueue[i].resource = res;
-			_fxQueue[i].data = data + sizeof(StandardHeader);
+			_fxQueue[i].data = data + ResHeader::size();
 			_fxQueue[i].len = len;
 			_fxQueue[i].delay = delay;
 			_fxQueue[i].volume = volume;
@@ -238,7 +237,7 @@
 			// fnStopFx() can be used later to kill this sound.
 			// Mainly for FX_LOOP and FX_RANDOM.
 
-			Logic::_scriptVars[RESULT] = i;
+			_vm->_logic->writeVar(RESULT, i);
 			return;
 		}
 	}

Index: speech.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/speech.cpp,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -d -r1.77 -r1.78
--- speech.cpp	18 Oct 2005 01:30:25 -0000	1.77
+++ speech.cpp	29 Oct 2005 21:24:54 -0000	1.78
@@ -80,39 +80,35 @@
 
 	// '0' means 1st frame
 
-	CdtEntry *cdt_entry = _vm->fetchCdtEntry(file, 0);
-	FrameHeader *frame_head = _vm->fetchFrameHeader(file, 0);
+	CdtEntry cdt_entry;
+	FrameHeader frame_head;
+
+	cdt_entry.read(_vm->fetchCdtEntry(file, 0));
+	frame_head.read(_vm->fetchFrameHeader(file, 0));
 
 	// Note: This part of the code is quite similar to registerFrame().
 
-	if (cdt_entry->frameType & FRAME_OFFSET) {
+	if (cdt_entry.frameType & FRAME_OFFSET) {
 		// The frame has offsets, i.e. it's a scalable mega frame
-		ObjectMega *ob_mega = (ObjectMega *)decodePtr(params[S_OB_MEGA]);
-
-		// Calculate scale at which to print the sprite, based on feet
-		// y-coord and scaling constants (NB. 'scale' is actually
-		// 256 * true_scale, to maintain accuracy)
-
-		// Ay+B gives 256 * scale ie. 256 * 256 * true_scale for even
-		// better accuracy, ie. scale = (Ay + B) / 256
+		ObjectMega obMega(decodePtr(params[S_OB_MEGA]));
 
-		uint16 scale = (uint16) ((ob_mega->scale_a * ob_mega->feet_y + ob_mega->scale_b) / 256);
+		uint16 scale = obMega.calcScale();
 
 		// Calc suitable centre point above the head, based on scaled
 		// height
 
 		// just use 'feet_x' as centre
-		_textX = (int16) ob_mega->feet_x;
+		_textX = obMega.getFeetX();
 
 		// Add scaled y-offset to feet_y coord to get top of sprite
-		_textY = (int16) (ob_mega->feet_y + (cdt_entry->y * scale) / 256);
+		_textY = obMega.getFeetY() + (cdt_entry.y * scale) / 256;
 	} else {
 		// It's a non-scaling anim - calc suitable centre point above
 		// the head, based on scaled width
 
 		// x-coord + half of width
-		_textX = cdt_entry->x + (frame_head->width) / 2;
-		_textY = cdt_entry->y;
+		_textX = cdt_entry.x + frame_head.width / 2;
+		_textY = cdt_entry.y;
 	}
 
 	_vm->_resman->closeResource(_animId);
@@ -158,10 +154,13 @@
 		return;
 	}
 
-	ObjectSpeech *ob_speech = (ObjectSpeech *)decodePtr(params[S_OB_SPEECH]);
+	ObjectSpeech obSpeech(decodePtr(params[S_OB_SPEECH]));
 
 	// Establish the max width allowed for this text sprite.
-	uint32 textWidth = ob_speech->width ? ob_speech->width : 400;
+	uint32 textWidth = obSpeech.getWidth();
+
+	if (!textWidth)
+		textWidth = 400;
 
 	// Pull out the text line, and make the sprite and text block
 
@@ -174,7 +173,7 @@
 
 	_speechTextBlocNo = _vm->_fontRenderer->buildNewBloc(
 		text + 2, _textX, _textY,
-		textWidth, ob_speech->pen,
+		textWidth, obSpeech.getPen(),
 		RDSPR_TRANS | RDSPR_DISPLAYALIGN,
 		_vm->_speechFontId, POSITION_AT_CENTRE_OF_BASE);
 

Index: startup.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/startup.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- startup.cpp	18 Oct 2005 01:30:25 -0000	1.52
+++ startup.cpp	29 Oct 2005 21:24:54 -0000	1.53
@@ -117,11 +117,7 @@
 		// start list
 
 		if (_resman->checkValid(_startRes)) {
-			char *raw_script = (char *)_resman->openResource(_startRes);
-			uint32 null_pc = 0;
-
-			_logic->runScript(raw_script, raw_script, &null_pc);
-			_resman->closeResource(_startRes);
+			_logic->runResScript(_startRes, 0);
 		} else
 			warning("Start menu resource %d invalid", _startRes);
 	}
@@ -166,17 +162,7 @@
 		_logic->_speechTextBlocNo = 0;
 	}
 
-	// Open George
-	char *raw_data_ad = (char *)_resman->openResource(CUR_PLAYER_ID);
-	char *raw_script = (char *)_resman->openResource(_startList[start].start_res_id);
-
-	// Denotes script to run
-	uint32 null_pc = _startList[start].key & 0xffff;
-
-	_logic->runScript(raw_script, raw_data_ad, &null_pc);
-
-	_resman->closeResource(_startList[start].start_res_id);
-	_resman->closeResource(CUR_PLAYER_ID);
+	_logic->runResObjScript(_startList[start].start_res_id, CUR_PLAYER_ID, _startList[start].key & 0xffff);
 
 	// Make sure there's a mouse, in case restarting while mouse not
 	// available

Index: sword2.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/sword2.cpp,v
retrieving revision 1.151
retrieving revision 1.152
diff -u -d -r1.151 -r1.152
--- sword2.cpp	23 Oct 2005 10:03:28 -0000	1.151
+++ sword2.cpp	29 Oct 2005 21:24:54 -0000	1.152
@@ -222,7 +222,7 @@
  */
 
 void Sword2Engine::setupPersistentResources() {
-	Logic::_scriptVars = (uint32 *)(_resman->openResource(1) + sizeof(StandardHeader));
+	_logic->_scriptVars = _resman->openResource(1) + ResHeader::size();
 	_resman->openResource(CUR_PLAYER_ID);
 }
 
@@ -266,9 +266,9 @@
 	initialiseFontResourceFlags();
 
 	if (_features & GF_DEMO)
-		Logic::_scriptVars[DEMO] = 1;
+		_logic->writeVar(DEMO, 1);
 	else
-		Logic::_scriptVars[DEMO] = 0;
+		_logic->writeVar(DEMO, 0);
 
 	if (_saveSlot != -1) {
 		if (saveExists(_saveSlot))
@@ -332,7 +332,7 @@
 						pauseGame();
 					break;
 				case 'c':
-					if (!Logic::_scriptVars[DEMO] && !_mouse->isChoosing()) {
+					if (!_logic->readVar(DEMO) && !_mouse->isChoosing()) {
 						ScreenInfo *screenInfo = _screen->getScreenInfo();
 						_logic->fnPlayCredits(NULL);
 						screenInfo->new_palette = 99;
@@ -401,10 +401,10 @@
 	_sound->stopMusic(true);
 
 	// In case we were dead - well we're not anymore!
-	Logic::_scriptVars[DEAD] = 0;
+	_logic->writeVar(DEAD, 0);
 
 	// Restart the game. Clear all memory and reset the globals
-	temp_demo_flag = Logic::_scriptVars[DEMO];
+	temp_demo_flag = _logic->readVar(DEMO);
 
 	// Remove all resources from memory, including player object and
 	// global variables
@@ -413,7 +413,7 @@
 	// Reopen global variables resource and player object
 	setupPersistentResources();
 
-	Logic::_scriptVars[DEMO] = temp_demo_flag;
+	_logic->writeVar(DEMO, temp_demo_flag);
 
 	// Free all the route memory blocks from previous game
 	_logic->_router->freeAllRouteMem();
@@ -605,7 +605,7 @@
 	debug(5, "startGame() STARTING:");
 
 	if (!_bootParam) {
-		if (Logic::_scriptVars[DEMO])
+		if (_logic->readVar(DEMO))
 			screen_manager_id = 19;		// DOCKS SECTION START
 		else
 			screen_manager_id = 949;	// INTRO & PARIS START
@@ -617,15 +617,7 @@
 			screen_manager_id = _bootParam;
 	}
 
-	uint32 null_pc = 1;
-
-	char *raw_data_ad = (char *)_resman->openResource(CUR_PLAYER_ID);
-	char *raw_script = (char *)_resman->openResource(screen_manager_id);
-
-	_logic->runScript(raw_script, raw_data_ad, &null_pc);
-
-	_resman->closeResource(screen_manager_id);
-	_resman->closeResource(CUR_PLAYER_ID);
+	_logic->runResObjScript(screen_manager_id, CUR_PLAYER_ID, 1);
 }
 
 // FIXME: Move this to some better place?

Index: sword2.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/sword2.h,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- sword2.h	18 Oct 2005 01:30:25 -0000	1.83
+++ sword2.h	29 Oct 2005 21:24:54 -0000	1.84
@@ -184,58 +184,25 @@
 #endif
 
 	byte *fetchPalette(byte *screenFile);
-	ScreenHeader *fetchScreenHeader(byte *screenFile);
-	LayerHeader *fetchLayerHeader(byte *screenFile, uint16 layerNo);
+	byte *fetchScreenHeader(byte *screenFile);
+	byte *fetchLayerHeader(byte *screenFile, uint16 layerNo);
 	byte *fetchShadingMask(byte *screenFile);
 
-	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 *fetchAnimHeader(byte *animFile);
+	byte *fetchCdtEntry(byte *animFile, uint16 frameNo);
+	byte *fetchFrameHeader(byte *animFile, uint16 frameNo);
+	byte *fetchBackgroundParallaxLayer(byte *screenFile, int layer);
+	byte *fetchBackgroundLayer(byte *screenFile);
+	byte *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, byte *buf);
-
-	// savegame file header
-
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
-	struct SaveGameHeader {
-		// sum of all bytes in file, excluding this uint32
-		uint32 checksum;
-
-		// player's description of savegame
-		char description[SAVE_DESCRIPTION_LEN];
-
-		uint32 varLength;	// length of global variables resource
-		uint32 screenId;	// resource id of screen file
-		uint32 runListId;	// resource id of run list
-		uint32 feet_x;		// copy of _thisScreen.feet_x
-		uint32 feet_y;		// copy of _thisScreen.feet_y
-		uint32 music_id;	// copy of 'looping_music_id'
-		ObjectHub player_hub;	// copy of player object's object_hub structure
-		ObjectLogic logic;	// copy of player character logic structure
-		ObjectGraphic graphic;	// copy of player character graphic structure
-		ObjectMega mega;	// copy of player character mega structure
-	} GCC_PACK;
-
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
-
-	SaveGameHeader _saveGameHeader;
 
 	uint32 saveGame(uint16 slotNo, byte *description);
 	uint32 restoreGame(uint16 slotNo);
 	uint32 getSaveDescription(uint16 slotNo, byte *description);
 	bool saveExists();
 	bool saveExists(uint16 slotNo);
-	void fillSaveBuffer(byte *buffer, uint32 size, byte *desc);
 	uint32 restoreFromBuffer(byte *buffer, uint32 size);
 	uint32 findBufferSize();
 

Index: sync.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/sync.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- sync.cpp	18 Oct 2005 01:30:25 -0000	1.26
+++ sync.cpp	29 Oct 2005 21:24:54 -0000	1.27
@@ -46,8 +46,10 @@
  */
 
 int Logic::getSync() {
+	uint32 id = readVar(ID);
+
 	for (int i = 0; i < MAX_syncs; i++) {
-		if (_syncList[i].id == _scriptVars[ID])
+		if (_syncList[i].id == id)
 			return i;
 	}
 

Index: walker.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/walker.cpp,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- walker.cpp	18 Oct 2005 01:30:25 -0000	1.50
+++ walker.cpp	29 Oct 2005 21:24:54 -0000	1.51
@@ -79,10 +79,14 @@
  * RESULT to 1. Return true if the mega has finished walking.
  */
 
-int Router::doWalk(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int16 target_x, int16 target_y, uint8 target_dir) {
+int Router::doWalk(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y, uint8 target_dir) {
+	ObjectLogic obLogic(ob_logic);
+	ObjectGraphic obGraph(ob_graph);
+	ObjectMega obMega(ob_mega);
+
 	// If this is the start of the walk, calculate the route.
 
-	if (!ob_logic->looping) {
+	if (obLogic.getLooping() == 0) {
 		// If we're already there, don't even bother allocating
 		// memory and calling the router, just quit back & continue
 		// the script! This avoids an embarassing mega stand frame
@@ -91,14 +95,14 @@
 		// an anim - no mega frame will appear in between runs of the
 		// anim.
 
-		if (ob_mega->feet_x == target_x && ob_mega->feet_y == target_y && ob_mega->current_dir == target_dir) {
-			Logic::_scriptVars[RESULT] = 0;
+		if (obMega.getFeetX() == target_x && obMega.getFeetY() == target_y && obMega.getCurDir() == target_dir) {
+			_vm->_logic->writeVar(RESULT, 0);
 			return IR_CONT;
 		}
 
 		assert(target_dir <= 8);
 
-		ob_mega->walk_pc = 0;
+		obMega.setWalkPc(0);
 
 		// Set up mem for _walkData in route_slots[] & set mega's
 		// 'route_slot_id' accordingly
@@ -112,16 +116,16 @@
 
 		if (route != 1 && route != 2) {
 			freeRouteMem();
-			Logic::_scriptVars[RESULT] = 1;
+			_vm->_logic->writeVar(RESULT, 1);
 			return IR_CONT;
 		}
 
 		// Walk is about to start
 
-		ob_mega->currently_walking = 1;
-		ob_logic->looping = 1;
-		ob_graph->anim_resource = ob_mega->megaset_res;
-	} else if (Logic::_scriptVars[EXIT_FADING] && _vm->_screen->getFadeStatus() == RDFADE_BLACK) {
+		obMega.setIsWalking(1);
+		obLogic.setLooping(1);
+		obGraph.setAnimResource(obMega.getMegasetRes());
+	} else if (_vm->_logic->readVar(EXIT_FADING) && _vm->_screen->getFadeStatus() == RDFADE_BLACK) {
 		// Double clicked an exit, and the screen has faded down to
 		// black. Ok, that's it. Back to script and change screen.
 
@@ -130,10 +134,10 @@
 
 		freeRouteMem();
 
-		ob_logic->looping = 0;
-		ob_mega->currently_walking = 0;
-		Logic::_scriptVars[EXIT_CLICK_ID] = 0;
-		Logic::_scriptVars[RESULT] = 0;
+		obLogic.setLooping(0);
+		obMega.setIsWalking(0);
+		_vm->_logic->writeVar(EXIT_CLICK_ID, 0);
+		_vm->_logic->writeVar(RESULT, 0);
 
 		return IR_CONT;
 	}
@@ -141,7 +145,7 @@
 	// Get pointer to walkanim & current frame position
 
 	WalkData *walkAnim = getRouteMem();
-	int32 walk_pc = ob_mega->walk_pc;
+	int32 walk_pc = obMega.getWalkPc();
 
 	// If stopping the walk early, overwrite the next step with a
 	// slow-out, then finish
@@ -153,17 +157,17 @@
 
 	// Get new frame of walk
 
-	ob_graph->anim_pc = walkAnim[walk_pc].frame;
-	ob_mega->current_dir = walkAnim[walk_pc].dir;
-	ob_mega->feet_x = walkAnim[walk_pc].x;
-	ob_mega->feet_y = walkAnim[walk_pc].y;
+	obGraph.setAnimPc(walkAnim[walk_pc].frame);
+	obMega.setCurDir(walkAnim[walk_pc].dir);
+	obMega.setFeetX(walkAnim[walk_pc].x);
+	obMega.setFeetY(walkAnim[walk_pc].y);
 
 	// Is the NEXT frame is the end-marker (512) of the walk sequence?
 
 	if (walkAnim[walk_pc + 1].frame != 512) {
 		// No, it wasn't. Increment the walk-anim frame number and
 		// come back next cycle.
-		ob_mega->walk_pc++;
+		obMega.setWalkPc(obMega.getWalkPc() + 1);
 		return IR_REPEAT;
 	}
 
@@ -171,8 +175,8 @@
 	// script just as the final (stand) frame of the walk is set.
 
 	freeRouteMem();
-	ob_logic->looping = 0;
-	ob_mega->currently_walking = 0;
+	obLogic.setLooping(0);
+	obMega.setIsWalking(0);
 
 	// If George's walk has been interrupted to run a new action script for
 	// instance or Nico's walk has been interrupted by player clicking on
@@ -184,11 +188,11 @@
 
 	if (_vm->_logic->checkEventWaiting()) {
 		_vm->_logic->startEvent();
-		Logic::_scriptVars[RESULT] = 1;
+		_vm->_logic->writeVar(RESULT, 1);
 		return IR_TERMINATE;
 	}
 
-	Logic::_scriptVars[RESULT] = 0;
+	_vm->_logic->writeVar(RESULT, 0);
 
 	// CONTINUE the script so that RESULT can be checked! Also, if an anim
 	// command follows the fnWalk command, the 1st frame of the anim (which
@@ -203,7 +207,7 @@
  * Walk mega to start position of anim
  */
 
-int Router::walkToAnim(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint32 animRes) {
+int Router::walkToAnim(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 animRes) {
 	int16 target_x = 0;
 	int16 target_y = 0;
 	uint8 target_dir = 0;
@@ -213,13 +217,17 @@
 
 	// If this is the start of the walk, read anim file to get start coords
 
-	if (!ob_logic->looping) {
+	ObjectLogic obLogic(ob_logic);
+
+	if (obLogic.getLooping() == 0) {
 		byte *anim_file = _vm->_resman->openResource(animRes);
-		AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file);
+		AnimHeader anim_head;
 
-		target_x = anim_head->feetStartX;
-		target_y = anim_head->feetStartY;
-		target_dir = anim_head->feetStartDir;
+		anim_head.read(_vm->fetchAnimHeader(anim_file));
+
+		target_x = anim_head.feetStartX;
+		target_y = anim_head.feetStartY;
+		target_dir = anim_head.feetStartDir;
 
 		_vm->_resman->closeResource(animRes);
 
@@ -242,53 +250,47 @@
  * Route to the left or right hand side of target id, if possible.
  */
 
-int Router::walkToTalkToMega(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint32 megaId, uint32 separation) {
+int Router::walkToTalkToMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId, uint32 separation) {
+	ObjectMega obMega(ob_mega);
+
 	int16 target_x = 0;
 	int16 target_y = 0;
 	uint8 target_dir = 0;
 
 	// If this is the start of the walk, calculate the route.
 
-	if (!ob_logic->looping)	{
-		StandardHeader *head = (StandardHeader *)_vm->_resman->openResource(megaId);
+	ObjectLogic obLogic(ob_logic);
 
-		assert(head->fileType == GAME_OBJECT);
+	if (obLogic.getLooping() == 0) {
+		assert(_vm->_resman->fetchType(megaId) == GAME_OBJECT);
 
 		// Call the base script. This is the graphic/mouse service
 		// call, and will set _engineMega to the ObjectMega of mega we
 		// want to route to.
 
-		char *raw_script_ad = (char *)head;
-		uint32 null_pc = 3;
-
-		_vm->_logic->runScript(raw_script_ad, raw_script_ad, &null_pc);
-		_vm->_resman->closeResource(megaId);
+		_vm->_logic->runResScript(megaId, 3);
 
-		ObjectMega *targetMega = _vm->_logic->getEngineMega();
+		ObjectMega targetMega(_vm->_logic->getEngineMega());
 
 		// Stand exactly beside the mega, ie. at same y-coord
-		target_y = targetMega->feet_y;
-
-		// Apply scale factor to walk distance. Ay+B gives 256 * scale
-		// ie. 256 * 256 * true_scale for even better accuracy, ie.
-		// scale = (Ay + B) / 256
+		target_y = targetMega.getFeetY();
 
-		int scale = (ob_mega->scale_a * ob_mega->feet_y + ob_mega->scale_b) / 256;
+		int scale = obMega.calcScale();
 		int mega_separation = (separation * scale) / 256;
 
-		debug(4, "Target is at (%d, %d), separation %d", targetMega->feet_x, targetMega->feet_y, mega_separation);
+		debug(4, "Target is at (%d, %d), separation %d", targetMega.getFeetX(), targetMega.getFeetY(), mega_separation);
 
-		if (targetMega->feet_x < ob_mega->feet_x) {
+		if (targetMega.getFeetX() < obMega.getFeetX()) {
 			// Target is left of us, so aim to stand to their
 			// right. Face down_left
 
-			target_x = targetMega->feet_x + mega_separation;
+			target_x = targetMega.getFeetX() + mega_separation;
 			target_dir = 5;
 		} else {
 			// Ok, must be right of us so aim to stand to their
 			// left. Face down_right.
 
-			target_x = targetMega->feet_x - mega_separation;
+			target_x = targetMega.getFeetX() - mega_separation;
 			target_dir = 3;
 		}
 	}
@@ -300,18 +302,22 @@
  * current feet coords, so router can produce anim of turn frames.
  */
 
-int Router::doFace(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint8 target_dir) {
+int Router::doFace(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint8 target_dir) {
 	int16 target_x = 0;
 	int16 target_y = 0;
 
 	// If this is the start of the turn, get the mega's current feet
 	// coords + the required direction
 
-	if (!ob_logic->looping) {
+	ObjectLogic obLogic(ob_logic);
+
+	if (obLogic.getLooping() == 0) {
 		assert(target_dir <= 7);
 
-		target_x = ob_mega->feet_x;
-		target_y = ob_mega->feet_y;
+		ObjectMega obMega(ob_mega);
+
+		target_x = obMega.getFeetX();
+		target_y = obMega.getFeetY();
 	}
 
 	return doWalk(ob_logic, ob_graph, ob_mega, ob_walkdata, target_x, target_y, target_dir);
@@ -321,14 +327,18 @@
  * Turn mega to face point (x,y) on the floor
  */
 
-int Router::faceXY(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int16 target_x, int16 target_y) {
+int Router::faceXY(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y) {
 	uint8 target_dir = 0;
 
 	// If this is the start of the turn, get the mega's current feet
 	// coords + the required direction
 
-	if (!ob_logic->looping) {
-		target_dir = whatTarget(ob_mega->feet_x, ob_mega->feet_y, target_x, target_y);
+	ObjectLogic obLogic(ob_logic);
+
+	if (obLogic.getLooping() == 0) {
+		ObjectMega obMega(ob_mega);
+
+		target_dir = whatTarget(obMega.getFeetX(), obMega.getFeetY(), target_x, target_y);
 	}
 
 	return doFace(ob_logic, ob_graph, ob_mega, ob_walkdata, target_dir);
@@ -338,29 +348,26 @@
  * Turn mega to face another mega.
  */
 
-int Router::faceMega(ObjectLogic *ob_logic, ObjectGraphic *ob_graph, ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, uint32 megaId) {
+int Router::faceMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId) {
 	uint8 target_dir = 0;
 
 	// If this is the start of the walk, decide where to walk to.
 
-	if (!ob_logic->looping) {
-		StandardHeader *head = (StandardHeader *)_vm->_resman->openResource(megaId);
+	ObjectLogic obLogic(ob_logic);
 
-		assert(head->fileType == GAME_OBJECT);
+	if (obLogic.getLooping() == 0) {
+		assert(_vm->_resman->fetchType(megaId) == GAME_OBJECT);
 
 		// Call the base script. This is the graphic/mouse service
 		// call, and will set _engineMega to the ObjectMega of mega we
 		// want to turn to face.
 
-		char *raw_script_ad = (char *)head;
-		uint32 null_pc = 3;
-
-		_vm->_logic->runScript(raw_script_ad, raw_script_ad, &null_pc);
-		_vm->_resman->closeResource(megaId);
+		_vm->_logic->runResScript(megaId, 3);
 
-		ObjectMega *targetMega = _vm->_logic->getEngineMega();
+		ObjectMega obMega(ob_mega);
+		ObjectMega targetMega(_vm->_logic->getEngineMega());
 
-		target_dir = whatTarget(ob_mega->feet_x, ob_mega->feet_y, targetMega->feet_x, targetMega->feet_y);
+		target_dir = whatTarget(obMega.getFeetX(), obMega.getFeetY(), targetMega.getFeetX(), targetMega.getFeetY());
 	}
 
 	return doFace(ob_logic, ob_graph, ob_mega, ob_walkdata, target_dir);
@@ -372,33 +379,38 @@
  * the mega object, so the router knows in future
  */
 
-void Router::standAt(ObjectGraphic *ob_graph, ObjectMega *ob_mega, int32 x, int32 y, int32 dir) {
+void Router::standAt(byte *ob_graph, byte *ob_mega, int32 x, int32 y, int32 dir) {
 	assert(dir >= 0 && dir <= 7);
 
+	ObjectGraphic obGraph(ob_graph);
+	ObjectMega obMega(ob_mega);
+
 	// Set up the stand frame & set the mega's new direction
 
-	ob_mega->feet_x = x;
-	ob_mega->feet_y = y;
-	ob_mega->current_dir = dir;
+	obMega.setFeetX(x);
+	obMega.setFeetY(y);
+	obMega.setCurDir(dir);
 
 	// Mega-set animation file
-	ob_graph->anim_resource	= ob_mega->megaset_res;
+	obGraph.setAnimResource(obMega.getMegasetRes());
 
 	// Dir + first stand frame (always frame 96)
-	ob_graph->anim_pc = dir + 96;
+	obGraph.setAnimPc(dir + 96);
 }
 
 /**
- * stand mega at end position of anim
+ * Stand mega at end position of anim
  */
 
-void Router::standAfterAnim(ObjectGraphic *ob_graph, ObjectMega *ob_mega, uint32 animRes) {
+void Router::standAfterAnim(byte *ob_graph, byte *ob_mega, uint32 animRes) {
 	byte *anim_file = _vm->_resman->openResource(animRes);
-	AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file);
+	AnimHeader anim_head;
 
-	int32 x = anim_head->feetEndX;
-	int32 y = anim_head->feetEndY;
-	int32 dir = anim_head->feetEndDir;
+	anim_head.read(_vm->fetchAnimHeader(anim_file));
+
+	int32 x = anim_head.feetEndX;
+	int32 y = anim_head.feetEndY;
+	int32 dir = anim_head.feetEndDir;
 
 	_vm->_resman->closeResource(animRes);
 
@@ -414,13 +426,15 @@
 	standAt(ob_graph, ob_mega, x, y, dir);
 }
 
-void Router::standAtAnim(ObjectGraphic *ob_graph, ObjectMega *ob_mega, uint32 animRes) {
+void Router::standAtAnim(byte *ob_graph, byte *ob_mega, uint32 animRes) {
 	byte *anim_file = _vm->_resman->openResource(animRes);
-	AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file);
+	AnimHeader anim_head;
 
-	int32 x = anim_head->feetStartX;
-	int32 y = anim_head->feetStartY;
-	int32 dir = anim_head->feetStartDir;
+	anim_head.read(_vm->fetchAnimHeader(anim_file));
+
+	int32 x = anim_head.feetStartX;
+	int32 y = anim_head.feetStartY;
+	int32 dir = anim_head.feetStartDir;
 
 	_vm->_resman->closeResource(animRes);
 





More information about the Scummvm-git-logs mailing list