[Scummvm-cvs-logs] CVS: scummvm/sword2/driver d_draw.h,1.33,1.34 render.cpp,1.64,1.65 render.h,1.13,1.14

Torbjörn Andersson eriktorbjorn at users.sourceforge.net
Mon Jul 26 09:43:03 CEST 2004


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

Modified Files:
	d_draw.h render.cpp render.h 
Log Message:
I shouldn't be mixing cleanups and bug fixes, but I'm doing so anyway, just
this once. :-)

The parameters to drawLine() aren't clipped to the screen size, which meant
that it was accessing memory out of bounds when marking the screen as
dirty. The function now uses plotPoint(), which does the bounds checking
and screen dirtying for us. Apart from being a little easier to read, it
dirties only the parts of the screen the line actually passes through,
instead of a rectangle defined by the line's end points.

Since drawLine() is only used for debugging, I wouldn't consider this a
particularly serious bug.

Next change is that only the pixels inside the original parallax layer are
considered when creating the block surfaces. This may make the drawing
slightly more efficient, since fewer surfaces will be labelled as
transparent.

Plus some other minor cleanups.


Index: d_draw.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/driver/d_draw.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- d_draw.h	17 Jun 2004 06:46:18 -0000	1.33
+++ d_draw.h	26 Jul 2004 16:41:57 -0000	1.34
@@ -221,7 +221,7 @@
 	int32 initialiseBackgroundLayer(Parallax *p);
 	void closeBackgroundLayer(void);
 
-	void plotPoint(uint16 x, uint16 y, uint8 colour);
+	void plotPoint(int16 x, int16 y, uint8 colour);
 	void drawLine(int16 x1, int16 y1, int16 x2, int16 y2, uint8 colour);
 #ifdef BACKEND_8BIT
 	void plotYUV(byte *lut, int width, int height, byte *const *dat);

Index: render.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/driver/render.cpp,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -d -r1.64 -r1.65
--- render.cpp	9 Jun 2004 06:33:28 -0000	1.64
+++ render.cpp	26 Jul 2004 16:41:57 -0000	1.65
@@ -28,9 +28,6 @@
 
 #define MILLISECSPERCYCLE	83
 
-#define BLOCKWBITS		6
-#define BLOCKHBITS		6
-
 void Graphics::updateRect(Common::Rect *r) {
 	_vm->_system->copyRectToScreen(_buffer + r->top * _screenWide + r->left,
 		_screenWide, r->left, r->top, r->right - r->left,
@@ -57,11 +54,11 @@
 		r->right = clipRect->right;
 
 	byte *dst = _buffer + r->top * _screenWide + r->left;
-	int i, j;
+	int i;
 
 	if (s->transparent) {
 		for (i = 0; i < r->bottom - r->top; i++) {
-			for (j = 0; j < r->right - r->left; j++) {
+			for (int j = 0; j < r->right - r->left; j++) {
 				if (src[j])
 					dst[j] = src[j];
 			}
@@ -195,16 +192,15 @@
  * @param colour colour of the point
  */
 
-void Graphics::plotPoint(uint16 x, uint16 y, uint8 colour) {
-	byte *buf = _buffer + 40 * RENDERWIDE;
-	int16 newx, newy;
-	
-	newx = x - _scrollX;
-	newy = y - _scrollY;
+void Graphics::plotPoint(int16 x, int16 y, uint8 colour) {
+	byte *buf = _buffer + MENUDEEP * RENDERWIDE;
 
-	if (newx >= 0 && newx < RENDERWIDE && newy >= 0 && newy < RENDERDEEP) {
-		buf[newy * RENDERWIDE + newx] = colour;
-		markAsDirty(newx, newy + 40, newx, newy + 40);
+	x -= _scrollX;
+	y -= _scrollY;
+
+	if (x >= 0 && x < RENDERWIDE && y >= 0 && y < RENDERDEEP) {
+		buf[y * RENDERWIDE + x] = colour;
+		markAsDirty(x, y + MENUDEEP, x, y + MENUDEEP);
 	}
 }
 
@@ -218,22 +214,14 @@
  */
 
 // Uses Bressnham's incremental algorithm!
+
 void Graphics::drawLine(int16 x0, int16 y0, int16 x1, int16 y1, uint8 colour) {
-	byte *buf = _buffer + 40 * RENDERWIDE;
-	int dx, dy;
 	int dxmod, dymod;
 	int ince, incne;
 	int d;
 	int x, y;
 	int addTo;
 
-	x1 -= _scrollX;
-	y1 -= _scrollY;
-	x0 -= _scrollX;
-	y0 -= _scrollY;
-
-	markAsDirty(MIN(x0, x1), MIN(y0, y1) + 40, MAX(x0, x1), MAX(y0, y1) + 40);
-
 	// Make sure we're going from left to right
 
 	if (x1 < x0) {
@@ -241,8 +229,8 @@
 		SWAP(y0, y1);
 	}
 
-	dx = x1 - x0;
-	dy = y1 - y0;
+	int dx = x1 - x0;
+	int dy = y1 - y0;
 	
 	if (dx < 0)
 		dxmod = -dx;
@@ -261,8 +249,8 @@
 			incne = 2 * (dy - dx);
 			x = x0;
 			y = y0;
-			if (x >= 0 && x < RENDERWIDE && y >= 0 && y < RENDERDEEP)
-				buf[y * RENDERWIDE + x] = colour;
+
+			plotPoint(x, y, colour);
 
 			while (x < x1) {
 				if (d <= 0) {
@@ -273,8 +261,8 @@
 					x++;
 					y++;
 				}
-				if (x >= 0 && x < RENDERWIDE && y >= 0 && y < RENDERDEEP)
-					buf[y * RENDERWIDE + x] = colour;
+
+				plotPoint(x, y, colour);
 			}
 		} else {
 			addTo = y0;
@@ -288,8 +276,8 @@
 			incne = 2 * (dy - dx);
 			x = x0;
 			y = y0;
-			if (x >= 0 && x < RENDERWIDE && addTo - y >= 0 && addTo - y < RENDERDEEP)
-				buf[(addTo - y) * RENDERWIDE + x] = colour;
+
+			plotPoint(x, addTo - y, colour);
 
 			while (x < x1) {
 				if (d <= 0) {
@@ -300,8 +288,8 @@
 					x++;
 					y++;
 				}
-				if (x >= 0 && x < RENDERWIDE && addTo - y >= 0 && addTo - y < RENDERDEEP)
-					buf[(addTo - y) * RENDERWIDE + x] = colour;
+
+				plotPoint(x, addTo - y, colour);
 			}
 		}
 	} else {
@@ -320,8 +308,8 @@
 			incne = 2 * (dx - dy);
 			x = x0;
 			y = y0;
-			if (x >= 0 && x < RENDERWIDE && y >= 0 && y < RENDERDEEP)
-				buf[y * RENDERWIDE + x] = colour;
+
+			plotPoint(x, y, colour);
 
 			while (y < y1) {
 				if (d <= 0) {
@@ -332,8 +320,8 @@
 					x++;
 					y++;
 				}
-				if (x >= 0 && x < RENDERWIDE && y >= 0 && y < RENDERDEEP)
-					buf[y * RENDERWIDE + x] = colour;
+
+				plotPoint(x, y, colour);
 			}
 		} else {
 			addTo = x0;
@@ -347,8 +335,8 @@
 			incne = 2 * (dx - dy);
 			x = x0;
 			y = y0;
-			if (addTo - x >= 0 && addTo - x < RENDERWIDE && y >= 0 && y < RENDERDEEP)
-				buf[y * RENDERWIDE + addTo - x] = colour;
+
+			plotPoint(addTo - x, y, colour);
 
 			while (y < y1) {
 				if (d <= 0) {
@@ -359,8 +347,8 @@
 					x++;
 					y++;
 				}
-				if (addTo - x >= 0 && addTo - x < RENDERWIDE && y >= 0 && y < RENDERDEEP)
-					buf[y * RENDERWIDE + addTo - x] = colour;
+
+				plotPoint(addTo - x, y, colour);
 			}
 		}
 	}
@@ -412,7 +400,7 @@
 			if (_blockSurfaces[l][i + j * _xBlocks[l]]) {
 				r.left = i * BLOCKWIDTH - x;
 				r.right = r.left + BLOCKWIDTH;
-				r.top = j * BLOCKHEIGHT - y + 40;
+				r.top = j * BLOCKHEIGHT - y + MENUDEEP;
 				r.bottom = r.top + BLOCKHEIGHT;
 				blitBlockSurface(_blockSurfaces[l][i + j * _xBlocks[l]], &r, &clipRect);
 			}
@@ -558,31 +546,21 @@
  */
 
 int32 Graphics::initialiseBackgroundLayer(Parallax *p) {
-	byte *memchunk;
-	uint8 zeros;
-	uint16 count;
 	uint16 i, j, k;
-	uint16 x;
 	byte *data;
 	byte *dst;
-	ParallaxLine line;
-	byte *pLine;
 
 	debug(2, "initialiseBackgroundLayer");
 
-	// This function is called to re-initialise the layers if they have
-	// been lost. We know this if the layers have already been assigned.
-
-	if (_layer == MAXLAYERS)
-		closeBackgroundLayer();
+	assert(_layer < MAXLAYERS);
 
 	if (!p) {
 		_layer++;
 		return RD_OK;
 	}
 
-	_xBlocks[_layer] = (p->w + BLOCKWIDTH - 1) >> BLOCKWBITS;
-	_yBlocks[_layer] = (p->h + BLOCKHEIGHT - 1) >> BLOCKHBITS;
+	_xBlocks[_layer] = (p->w + BLOCKWIDTH - 1) / BLOCKWIDTH;
+	_yBlocks[_layer] = (p->h + BLOCKHEIGHT - 1) / BLOCKHEIGHT;
 
 	_blockSurfaces[_layer] = (BlockSurface **) calloc(_xBlocks[_layer] * _yBlocks[_layer], sizeof(BlockSurface *));
 	if (!_blockSurfaces[_layer])
@@ -590,66 +568,70 @@
 
 	// Decode the parallax layer into a large chunk of memory
 
-	memchunk = (byte *) calloc(_xBlocks[_layer] * _yBlocks[_layer], BLOCKWIDTH * BLOCKHEIGHT);
+	byte *memchunk = (byte *) calloc(_xBlocks[_layer] * _yBlocks[_layer], BLOCKWIDTH * BLOCKHEIGHT);
 	if (!memchunk)
 		return RDERR_OUTOFMEMORY;
 
 	for (i = 0; i < p->h; i++) {
-		if (p->offset[i] == 0)
+		if (!p->offset[i])
 			continue;
 
-		pLine = (byte *) p + FROM_LE_32(p->offset[i]);
-		line.packets = READ_LE_UINT16(pLine);
-		line.offset = READ_LE_UINT16(pLine + 2);
-		data = pLine + sizeof(ParallaxLine);
-		x = line.offset;
+		byte *pLine = (byte *) p + FROM_LE_32(p->offset[i]);
+		uint16 packets = READ_LE_UINT16(pLine);
+		uint16 offset = READ_LE_UINT16(pLine + 2);
 
-		dst = memchunk + i * p->w + x;
+		data = pLine + 4;
+		dst = memchunk + i * p->w + offset;
 
-		zeros = 0;
-		if (line.packets == 0)	{
+		if (!packets) {
 			memcpy(dst, data, p->w);
 			continue;
 		}
 
-		for (j = 0; j < line.packets; j++) {
+		bool zeros = false;
+
+		for (j = 0; j < packets; j++) {
 			if (zeros) {
 				dst += *data;
-				x += *data;
+				offset += *data;
 				data++;
-				zeros = 0;
-			} else if (*data == 0) {
+				zeros = false;
+			} else if (!*data) {
 				data++;
-				zeros = 1;
+				zeros = true;
 			} else {
-				count = *data++;
+				uint16 count = *data++;
 				memcpy(dst, data, count);
 				data += count;
 				dst += count;
-				x += count;
-				zeros = 1;
+				offset += count;
+				zeros = true;
 			}
 		}
 	}
 
-	// Now create the surfaces!
+	// The large memory chunk is now divided into a number of smaller
+	// surfaces. For most parallax layers, we'll end up using less memory
+	// this way, and it will be faster to draw since completely transparent
+	// surfaces are discarded.
 
 	for (i = 0; i < _xBlocks[_layer] * _yBlocks[_layer]; i++) {
 		bool block_has_data = false;
 		bool block_is_transparent = false;
 
-		data = memchunk + (p->w * BLOCKHEIGHT * (i / _xBlocks[_layer])) + BLOCKWIDTH * (i % _xBlocks[_layer]);
+		int x = BLOCKWIDTH * (i % _xBlocks[_layer]);
+		int y = BLOCKHEIGHT * (i / _xBlocks[_layer]);
 
-		// FIXME: The 'block_is_transparent' flag should only consider
-		// data that is inside the parallax layer. Still, it won't do
-		// any harm to leave it this way...
+		data = memchunk + p->w * y + x;
 
 		for (j = 0; j < BLOCKHEIGHT; j++) {
 			for (k = 0; k < BLOCKWIDTH; k++) {
-				if (data[j * p->w + k])
-					block_has_data = true;
-				else
-					block_is_transparent = true;
+				if (x + k < p->w && y + j < p->h) {
+					if (data[j * p->w + k])
+						block_has_data = true;
+					else
+						block_is_transparent = true;
+				}
 			}
 		}
 
@@ -685,13 +667,13 @@
 void Graphics::closeBackgroundLayer(void) {
 	debug(2, "CloseBackgroundLayer");
 
-	for (int j = 0; j < MAXLAYERS; j++) {
-		if (_blockSurfaces[j]) {
-			for (int i = 0; i < _xBlocks[j] * _yBlocks[j]; i++)
-				if (_blockSurfaces[j][i])
-					free(_blockSurfaces[j][i]);
-			free(_blockSurfaces[j]);
-			_blockSurfaces[j] = NULL;
+	for (int i = 0; i < MAXLAYERS; i++) {
+		if (_blockSurfaces[i]) {
+			for (int j = 0; j < _xBlocks[i] * _yBlocks[i]; j++)
+				if (_blockSurfaces[i][j])
+					free(_blockSurfaces[i][j]);
+			free(_blockSurfaces[i]);
+			_blockSurfaces[i] = NULL;
 		}
 	}
 
@@ -710,7 +692,7 @@
 
 	for (y = 0; y < height; y += 2) {
 		for (x = 0; x < width; x += 2) {
-			int i = ((((dat[2][cpos] + ROUNDADD) >> SHIFT) * (BITDEPTH+1)) + ((dat[1][cpos] + ROUNDADD)>>SHIFT)) * (BITDEPTH+1);
+			int i = ((((dat[2][cpos] + ROUNDADD) >> SHIFT) * (BITDEPTH + 1)) + ((dat[1][cpos] + ROUNDADD) >> SHIFT)) * (BITDEPTH + 1);
 			cpos++;
 
 			buf[linepos               ] = lut[i + ((dat[0][        ypos  ] + ROUNDADD) >> SHIFT)];

Index: render.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/driver/render.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- render.h	6 Jan 2004 13:44:17 -0000	1.13
+++ render.h	26 Jul 2004 16:41:57 -0000	1.14
@@ -25,13 +25,7 @@
 namespace Sword2 {
 
 #define RENDERWIDE		640
-#define ALIGNRENDERDEEP		480
-#define RENDERDEEP		(ALIGNRENDERDEEP - (MENUDEEP * 2))
-
-struct ParallaxLine {
-	uint16 packets;
-	uint16 offset;
-};
+#define RENDERDEEP		(480 - (MENUDEEP * 2))
 
 } // End of namespace Sword2
 





More information about the Scummvm-git-logs mailing list