[Scummvm-cvs-logs] CVS: scummvm/scumm actor.cpp,1.165,1.166 boxes.cpp,1.58,1.59 saveload.cpp,1.107,1.108 saveload.h,1.22,1.23 script_v5.cpp,1.176,1.177 scumm.h,1.297,1.298 scummvm.cpp,2.380,2.381

Max Horn fingolfin at users.sourceforge.net
Tue Sep 9 12:34:38 CEST 2003


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv2195

Modified Files:
	actor.cpp boxes.cpp saveload.cpp saveload.h script_v5.cpp 
	scumm.h scummvm.cpp 
Log Message:
replaced all use of scale items with scale slots. This allowed me to get rid of two big FIXME's, and might fix other scaling bugs in FT/DIG

Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/actor.cpp,v
retrieving revision 1.165
retrieving revision 1.166
diff -u -d -r1.165 -r1.166
--- actor.cpp	9 Sep 2003 13:29:18 -0000	1.165
+++ actor.cpp	9 Sep 2003 17:29:21 -0000	1.166
@@ -412,47 +412,10 @@
 		return;
 
 	scale = _vm->getScale(walkbox, x, y);
-	if (_vm->_version == 8) {
-		// At least in COMI, scale values are clipped to range 1-255
-		if (scale < 1)
-			scale = 1;
-		else if (scale > 255)
-			scale = 255;
-	}
-
-	// FIXME - Hack for The Dig 'Tomb' (room 88)
-	// Otherwise walking to the far-left door causes the actor
-	// to shrink to a one-pixel dot. The reason for this is that
-	// scale items (as handled in setScaleItem etc.) are only
-	// working as long as the room height is <= 200!!! That's a
-	// serious problem for DIG/FT, and causes the FIXME below, too.
-	// A way to properly fix the problem would be to use the
-	// V8 "scale slots" instead. This would be almost perfect, the
-	// only problem being that it might render some old savegames
-	// partially broken...
-	if (_vm->_gameId == GID_DIG && _vm->_currentRoom == 88) {
-		scale = 0xFF;
-	}
-
-
-	// FIXME - Quick fix to ft's fuel tower bug (by yazoo)
-	//
-	// Ben's Y position can be anything between 272 and 398 inclusive
-	// (which by the way means that we're always looking at the same
-	// element in the scale table... hmmm...)
-	//
-	// When standing at the bottom of the ladder, Ben's Y position is
-	// 356, and by the looks of it he ought to be unscaled there.
-
-	if (_vm->_gameId == GID_FT && scale == 1 && _vm->_currentRoom == 76) {
-		scale = 0xff;
-		if (y < 356)
-			scale -= 2 * (356 - y);
-	}
-
 	if (scale > 255) {
-			warning("Actor %d at %d, scale %d out of range", number, y, scale);
+		warning("Actor %d at %d, scale %d out of range", number, y, scale);
 	}
+
 	scalex = (byte)scale;
 	scaley = (byte)scale;
 }

Index: boxes.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/boxes.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- boxes.cpp	9 Sep 2003 16:55:25 -0000	1.58
+++ boxes.cpp	9 Sep 2003 17:29:21 -0000	1.59
@@ -155,53 +155,58 @@
 	Box *ptr = getBoxBaseAddr(box);
 	if (!ptr)
 		return 255;
+		
+	int slot , scale;
 
 	if (_version == 8) {
-		int slot = FROM_LE_32(ptr->v8.scaleSlot);
-		if (slot) {
-			assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
-			int scaleX = 0, scaleY = 0;
-			ScaleSlot &s = _scaleSlots[slot-1];
+		// COMI has a separate field for the scale slot...
+		slot = FROM_LE_32(ptr->v8.scaleSlot);
+		scale = FROM_LE_32(ptr->v8.scale);
+	} else {
+		scale = READ_LE_UINT16(&ptr->old.scale);
+		if (scale & 0x8000)
+			slot = (scale & 0x7FFF) + 1;
+		else
+			slot = 0;
+	}
 
-			if (s.y1 == s.y2 && s.x1 == s.x2)
-				error("Invalid scale slot %d", slot);
+	// Was a scale slot specified? If so, we compute the effective scale
+	// from it, ignoring the box scale.
+	if (slot) {
+		assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
+		int scaleX = 0, scaleY = 0;
+		ScaleSlot &s = _scaleSlots[slot-1];
 
-			if (s.y1 != s.y2) {
-				if (y < 0)
-					y = 0;
+		if (s.y1 == s.y2 && s.x1 == s.x2)
+			error("Invalid scale slot %d", slot);
 
-				scaleY = (s.scale2 - s.scale1) * (y - s.y1) / (s.y2 - s.y1) + s.scale1;
-				if (s.x1 == s.x2) {
-					return scaleY;
-				}
-			}
+		if (s.y1 != s.y2) {
+			if (y < 0)
+				y = 0;
 
+			scaleY = (s.scale2 - s.scale1) * (y - s.y1) / (s.y2 - s.y1) + s.scale1;
+		}
+		if (s.x1 == s.x2) {
+			scale = scaleY;
+		} else {
 			scaleX = (s.scale2 - s.scale1) * (x - s.x1) / (s.x2 - s.x1) + s.scale1;
 
 			if (s.y1 == s.y2) {
-				return scaleX;
+				scale = scaleX;
 			} else {
-				return (scaleX + scaleY - s.x1) / 2;
+				scale = (scaleX + scaleY - s.x1) / 2;
 			}
-		} else
-			return FROM_LE_32(ptr->v8.scale);
-	} else {
-		uint16 scale = READ_LE_UINT16(&ptr->old.scale);
-
-		if (scale & 0x8000) {
-			scale = (scale & 0x7FFF) + 1;
-			byte *resptr = getResourceAddress(rtScaleTable, scale);
-			if (resptr == NULL)
-				error("Scale table %d not defined", scale);
-			if (y >= _screenHeight)
-				y = _screenHeight - 1;
-			else if (y < 0)
-				y = 0;
-			scale = resptr[y];
 		}
-		
-		return scale;
+
+		// Clip the scale to range 1-255
+		if (scale < 1)
+			scale = 1;
+		else if (scale > 255)
+			scale = 255;
 	}
+	
+	// Finally return the scale
+	return scale;
 }
 
 int Scumm::getBoxScale(int box) {
@@ -216,60 +221,36 @@
 		return READ_LE_UINT16(&ptr->old.scale);
 }
 
-/*
- FIXME: It seems that scale items and scale slots are the same thing after
- all - they only differ in some details (scale item is used to precompute
- a scale table, while for the scale slots the computations are done on the
- fly; also for scale slots, the scale along the x axis can vary, too).
- 
- Now, there are various known scale glitches in FT (and apparently also
- in The Dig, see FIXME comments in Actor::setupActorScale). In this context
- it is very interesting that for V5, there is an opcode which invokes
- setScaleItem, and for V8 one that invokes setScaleSlot. But there is no
- such opcode to be found for V6/V7 games.
- 
- Hypothesis: we simple are missing this opcode, and implementing it might
- fix some or all of the Dig/FT scaling issues.
-*/
-void Scumm::setScaleItem(int slot, int y1, int scale1, int y2, int scale2) {
-	byte *ptr;
-	int y, tmp;
-
-	if (y1 == y2)
-		return;
-
-	ptr = createResource(rtScaleTable, slot, 200);
-
-	for (y = 0; y < 200; y++) {
-		tmp = ((scale2 - scale1) * (y - y1)) / (y2 - y1) + scale1;
-		if (tmp < 1)
-			tmp = 1;
-		if (tmp > 255)
-			tmp = 255;
-		*ptr++ = tmp;
-	}
-/*	
-	// TEST!
-	printf("setScaleItem(%d, %d, %d, %d, %d)\n", slot, y1, scale1, y2, scale2);
-	convertScaleTableToScaleSlot(slot);
-*/
-}
-
+/**
+ * Convert a rtScaleTable resource to a corresponding scale slot entry.
+ *
+ * At some point, we discovered that the old scale items (stored in rtScaleTable
+ * resources) are in fact the same as (or rather, a predecessor of) the
+ * scale slots used in COMI. While not being precomputed (and thus slightly
+ * slower), they are more flexible, and most importantly, can cope with
+ * rooms higher than 200 pixels. That's an essential feature for DIG and FT
+ * and in fact the lack of it caused various bugs in the past.
+ *
+ * Hence, we decided to switch all games to use the more powerful scale slots.
+ * To accomodate old savegames, we attempt here to convert rtScaleTable
+ * resources to scale slots.
+ */
 void Scumm::convertScaleTableToScaleSlot(int slot) {
 	assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
 
 	byte *resptr = getResourceAddress(rtScaleTable, slot);
 	ScaleSlot &s = _scaleSlots[slot-1];
-
 	int lowerIdx, upperIdx;
 	float m, oldM;
 	
+	// Do nothing if the given scale table doesn't exist
+	if (resptr == 0)
+		return;
+	
 	if (resptr[0] == resptr[199]) {
 		// The scale is constant This usually means we encountered one of the
 		// "broken" cases. We set pseudo scale item values which lead to a 
 		// constant scale of 255.
-		// TODO
-		printf("Broken case!\n");
 		s.y1 = 0;
 		s.y2 = 199;
 		s.scale1 = s.scale2 = 255;

Index: saveload.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/saveload.cpp,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -d -r1.107 -r1.108
--- saveload.cpp	7 Sep 2003 19:28:45 -0000	1.107
+++ saveload.cpp	9 Sep 2003 17:29:21 -0000	1.108
@@ -658,6 +658,15 @@
 		}
 	}
 	
+	// With version 22, we replace the scale items with scale slots
+	if (savegameVersion < VER(22) && !s->isSaving()) {
+		// Convert all rtScaleTable resources to matching scale items
+		for (i = 1; i < res.num[rtScaleTable]; i++) {
+			convertScaleTableToScaleSlot(i);
+		}
+	}
+
+	
 	if (_imuse && (_saveSound || !_saveLoadCompatible)) {
 		_imuse->save_or_load(s, this);
 		_imuse->setMasterVolume(_sound->_sound_volume_master);

Index: saveload.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/saveload.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- saveload.h	29 Aug 2003 04:05:23 -0000	1.22
+++ saveload.h	9 Sep 2003 17:29:21 -0000	1.23
@@ -28,7 +28,7 @@
 // Can be useful for other ports too :)
 
 #define VER(x) x
-#define CURRENT_VER 21
+#define CURRENT_VER 22
 
 // To work around a warning in GCC 3.2 (and 3.1 ?) regarding non-POD types,
 // we use a small trick: instead of 0 we use 42. Why? Well, it seems newer GCC

Index: script_v5.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v5.cpp,v
retrieving revision 1.176
retrieving revision 1.177
diff -u -d -r1.176 -r1.177
--- script_v5.cpp	8 Sep 2003 13:28:56 -0000	1.176
+++ script_v5.cpp	9 Sep 2003 17:29:21 -0000	1.177
@@ -1867,7 +1867,7 @@
 		d = getVarOrDirectByte(0x40);
 		_opcode = fetchScriptByte();
 		e = getVarOrDirectByte(0x40);
-		setScaleItem(e - 1, b, a, d, c);
+		setScaleSlot(e - 1, 0, b, a, 0, d, c);
 		break;
 	case 8:											/* room scale? */
 		if (_features & GF_SMALL_HEADER) {

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.297
retrieving revision 1.298
diff -u -d -r1.297 -r1.298
--- scumm.h	9 Sep 2003 16:55:25 -0000	1.297
+++ scumm.h	9 Sep 2003 17:29:21 -0000	1.298
@@ -1051,7 +1051,6 @@
 	int getBoxScale(int box);
 
 	int getScale(int box, int x, int y);
-	void setScaleItem(int slot, int a, int b, int c, int d);
 
 protected:
 	// Scaling slots/items

Index: scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
retrieving revision 2.380
retrieving revision 2.381
diff -u -d -r2.380 -r2.381
--- scummvm.cpp	8 Sep 2003 17:06:44 -0000	2.380
+++ scummvm.cpp	9 Sep 2003 17:29:22 -0000	2.381
@@ -1996,7 +1996,7 @@
 }
 
 void Scumm::initRoomSubBlocks() {
-	int i, offs;
+	int i;
 	const byte *ptr;
 	byte *roomptr, *searchptr, *roomResPtr;
 	const RoomHeader *rmhd;
@@ -2178,29 +2178,27 @@
 	// Load scale data
 	//
 	if (_features & GF_OLD_BUNDLE)
-		ptr = 0;	// TODO ?
+		ptr = 0;
 	else
 		ptr = findResourceData(MKID('SCAL'), roomptr);
 	if (ptr) {
-		offs = ptr - roomptr;
 		int s1, s2, y1, y2;
 		if (_version == 8) {
-			for (i = 1; i < _maxScaleTable; i++, offs += 16) {
-				s1 = READ_LE_UINT32(roomptr + offs);
-				y1 = READ_LE_UINT32(roomptr + offs + 4);
-				s2 = READ_LE_UINT32(roomptr + offs + 8);
-				y2 = READ_LE_UINT32(roomptr + offs + 12);
+			for (i = 1; i < _maxScaleTable; i++, ptr += 16) {
+				s1 = READ_LE_UINT32(ptr);
+				y1 = READ_LE_UINT32(ptr + 4);
+				s2 = READ_LE_UINT32(ptr + 8);
+				y2 = READ_LE_UINT32(ptr + 12);
 				setScaleSlot(i, 0, y1, s1, 0, y2, s2);
 			}
 		} else {
-			for (i = 1; i < _maxScaleTable; i++, offs += 8) {
-				s1 = READ_LE_UINT16(roomptr + offs);
-				y1 = READ_LE_UINT16(roomptr + offs + 2);
-				s2 = READ_LE_UINT16(roomptr + offs + 4);
-				y2 = READ_LE_UINT16(roomptr + offs + 6);
+			for (i = 1; i < _maxScaleTable; i++, ptr += 8) {
+				s1 = READ_LE_UINT16(ptr);
+				y1 = READ_LE_UINT16(ptr + 2);
+				s2 = READ_LE_UINT16(ptr + 4);
+				y2 = READ_LE_UINT16(ptr + 6);
 				if (s1 || y1 || s2 || y2) {
-					setScaleItem(i, y1, s1, y2, s2);
-					roomptr = getResourceAddress(rtRoom, _roomResource);
+					setScaleSlot(i, 0, y1, s1, 0, y2, s2);
 				}
 			}
 		}





More information about the Scummvm-git-logs mailing list