[Scummvm-cvs-logs] CVS: scummvm/scumm gfx.cpp,1.84,1.85 gfx.h,1.14,1.15 object.cpp,1.19,1.20 scumm.h,1.86,1.87 string.cpp,1.55,1.56

Max Horn fingolfin at users.sourceforge.net
Fri Dec 20 17:12:14 CET 2002


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

Modified Files:
	gfx.cpp gfx.h object.cpp scumm.h string.cpp 
Log Message:
got rid of _curVirtScreen and VirtScreen::unk1; added some comments to gfx.cpp; added a hack to enable smooth scrolling in V7 games (note: when I say hack, I mean it, it is buggy as hell and not enabled by default, use at your own risk and don't report problems with it, it's disabled by default)

Index: gfx.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.cpp,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- gfx.cpp	16 Dec 2002 19:53:41 -0000	1.84
+++ gfx.cpp	21 Dec 2002 01:11:41 -0000	1.85
@@ -32,6 +32,26 @@
 #endif
 
 
+// If you wan to try buggy hacked smooth scrolling support in The Dig, enable
+// the following preprocessor flag by uncommenting it.
+//
+// Note: This is purely experimental, NOT WORKING COMPLETLY and very buggy.
+// Please do not make reports about problems with it - this is only in CVS
+// to get it fixed and so that really interested parties can experiment it.
+// It is NOT FIT FOR GENERAL USAGE!. You have been warned.
+//
+// Doing this correctly will be quite some more complicated. Basically, with smooth
+// scrolling, the virtual screen strips don't match the display screen strips.
+// Hence we either have to draw partial strips - but that'd be rather cumbersome.
+// Or the much simple (and IMHO more elegant) solution is to simply use a screen pitch
+// that is 8 pixel wider than the real screen width, and always draw one strip more than 
+// needed to the backbuf. This will still require quite some code to be changed but
+// should otherwise be relatively easy to understand, and using VirtScreen::pitch
+// will actually clean up the code.
+//
+// #define V7_SMOOTH_SCROLLING_HACK
+
+
 enum {
 	kScrolltime = 500,  // ms scrolling is supposed to take
 	kPictureDelay = 20
@@ -159,8 +179,6 @@
 {
 	VirtScreen *vs = &virtscr[slot];
 	int size;
-	int i;
-	byte *ptr;
 
 	assert(height >= 0);
 	assert(slot >= 0 && slot < 4);
@@ -171,7 +189,6 @@
 	}
 
 	vs->number = slot;
-	vs->unk1 = 0;
 	vs->width = _realWidth;
 	vs->topline = top;
 	vs->height = height;
@@ -182,18 +199,17 @@
 	vs->size = size;
 	vs->backBuf = NULL;
 
-	if ((vs->scrollable) && (_features & GF_AFTER_V7)) {
-		size += _realWidth * 8;
-	} else {
-		size += _realWidth * 4;
+	if (vs->scrollable) {
+		if (_features & GF_AFTER_V7) {
+			size += _realWidth * 8;
+		} else {
+			size += _realWidth * 4;
+		}
 	}
-
+	
 	createResource(rtBuffer, slot + 1, size);
 	vs->screenPtr = getResourceAddress(rtBuffer, slot + 1);
-
-	ptr = vs->screenPtr;
-	for (i = 0; i < size; i++)		// reset background ?
-		*ptr++ = 0;
+	memset(vs->screenPtr, 0, size);			// reset background
 
 	if (twobufs) {
 		createResource(rtBuffer, slot + 5, size);
@@ -211,10 +227,10 @@
 
 	for (i = 0; i < 3; i++, vs++) {
 		if (y >= vs->topline && y < vs->topline + vs->height) {
-			return _curVirtScreen = vs;
+			return vs;
 		}
 	}
-	return _curVirtScreen = NULL;
+	return NULL;
 }
 
 void Scumm::updateDirtyRect(int virt, int left, int right, int top, int bottom, uint32 dirtybits)
@@ -237,14 +253,19 @@
 		right = vs->width;
 
 	if (virt == 0 && dirtybits) {
-		rp = (right >> 3) + _screenStartStrip;
 		lp = (left >> 3) + _screenStartStrip;
 		if (lp < 0)
 			lp = 0;
 		if (_features & GF_AFTER_V7) {
+#ifdef V7_SMOOTH_SCROLLING_HACK
+			rp = (right + vs->xstart) >> 3;
+#else
+			rp = (right >> 3) + _screenStartStrip;
+#endif
 			if (rp > 409)
 				rp = 409;
 		} else {
+			rp = (right >> 3) + _screenStartStrip;
 			if (rp >= 200)
 				rp = 200;
 		}
@@ -306,8 +327,8 @@
 	} else {
 		vs = &virtscr[0];
 
-		src = vs->screenPtr + _screenStartStrip * 8 + _screenTop * _realWidth;
-		_system->copy_rect(src, _realWidth, 0, vs->topline, _realWidth, vs->height);
+		src = vs->screenPtr + vs->xstart + _screenTop * _realWidth;
+		_system->copy_rect(src, _realWidth, 0, vs->topline, _realWidth, vs->height - _screenTop);
 
 		for (i = 0; i < gdi._numStrips; i++) {
 			vs->tdirty[i] = (byte)vs->height;
@@ -330,14 +351,16 @@
 	gdi.updateDirtyScreen(&virtscr[slot]);
 }
 
+// Blit the data from the given VirtScreen to the display. If the camera moved,
+// a full blit is done, otherwise only the visible dirty areas are updated.
 void Gdi::updateDirtyScreen(VirtScreen *vs)
 {
 	if (vs->height == 0)
 		return;
 
-	if (_vm->_features & GF_AFTER_V7 && (_vm->camera._cur.y != _vm->camera._last.y))
+	if (_vm->_features & GF_AFTER_V7 && (_vm->camera._cur.y != _vm->camera._last.y)) {
 		drawStripToScreen(vs, 0, _numStrips << 3, 0, vs->height);
-	else {
+	} else {
 		int i;
 		int start, w, top, bottom;
 	
@@ -352,6 +375,8 @@
 				vs->tdirty[i] = (byte)vs->height;
 				vs->bdirty[i] = 0;
 				if (i != (_numStrips - 1) && vs->bdirty[i + 1] == (byte)bottom && vs->tdirty[i + 1] == (byte)top) {
+					// Simple optimizations: if two or more neighbouring strips form one bigger rectangle,
+					// blit them all at once.
 					w += 8;
 					continue;
 				}
@@ -366,6 +391,7 @@
 	}
 }
 
+// Blit the specified rectangle from the given virtual screen to the display.
 void Gdi::drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b)
 {
 	byte *ptr;
@@ -395,6 +421,7 @@
 	memset(_vm->getResourceAddress(rtBuffer, 9), 0, _imgBufOffs[1] - _imgBufOffs[0]);
 }
 
+// Reset the background behind an actor or blast object
 void Gdi::resetBackground(int top, int bottom, int strip)
 {
 	VirtScreen *vs = &_vm->virtscr[0];
@@ -569,6 +596,8 @@
 	_flashlightIsDrawn = true;
 }
 
+// Redraw background as needed, i.e. the left/right sides if scrolling took place etc.
+// Note that this only updated the virtual screen, not the actual display.
 void Scumm::redrawBGAreas()
 {
 	int i;
@@ -581,6 +610,7 @@
 
 	val = 0;
 
+	// Redraw parts of the background which are marked as dirty.
 	if (!_fullRedraw && _BgNeedsRedraw) {
 		for (i = 0; i != gdi._numStrips; i++) {
 			if (gfxUsageBits[_screenStartStrip + i] & 0x80000000) {
@@ -626,19 +656,11 @@
 
 	assert(s >= 0 && (size_t) s < sizeof(gfxUsageBits) / sizeof(gfxUsageBits[0]));
 
-	_curVirtScreen = &virtscr[0];
-
 	for (int i = 0; i < num; i++)
 		gfxUsageBits[s + i] |= 0x80000000;
 
-	/*if (_curVirtScreen->height < _scrHeight) {  
-	   warning("Screen Y size %d < Room height %d",
-	   _curVirtScreen->height,
-	   _scrHeight);
-	   } */
-
 	gdi.drawBitmap(getResourceAddress(rtRoom, _roomResource) + _IM00_offs,
-								 _curVirtScreen, s, 0, _curVirtScreen->height, s, num, 0);
+								 &virtscr[0], s, 0, virtscr[0].height, s, num, 0);
 }
 
 void Scumm::restoreCharsetBg()
@@ -765,7 +787,6 @@
 	byte *zplane_list[6];
 
 	int bottom;
-	byte twobufs;
 	int numzbuf;
 	int sx;
 	bool lightsOn;
@@ -815,8 +836,6 @@
 		warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", bottom, vs->height);
 	}
 
-	twobufs = vs->alloctwobuffers;
-
 	_vertStripNextInc = h * _vm->_realWidth - 1;
 
 	do {
@@ -838,7 +857,7 @@
 			vs->bdirty[sx] = bottom;
 
 		backbuff_ptr = vs->screenPtr + (y * _numStrips + x) * 8;
-		if (twobufs)
+		if (vs->alloctwobuffers)
 			bgbak_ptr = _vm->getResourceAddress(rtBuffer, vs->number + 5) + (y * _numStrips + x) * 8;
 		else
 			bgbak_ptr = backbuff_ptr;
@@ -851,7 +870,7 @@
 			decompressBitmap(bgbak_ptr, smap_ptr + READ_LE_UINT32(smap_ptr + stripnr * 4 + 8), h);
 
 		CHECK_HEAP;
-		if (twobufs) {
+		if (vs->alloctwobuffers) {
 			if (_vm->hasCharsetMask(sx << 3, y, (sx + 1) << 3, bottom)) {
 				if (flag & dbClear || !lightsOn)
 					clear8ColWithMasking(backbuff_ptr, h, _mask_ptr);
@@ -1954,8 +1973,6 @@
 
 	_screenStartStrip = (camera._cur.x - (_realWidth / 2)) >> 3;
 	_screenEndStrip = _screenStartStrip + gdi._numStrips - 1;
-	virtscr[0].xstart = _screenStartStrip << 3;
-
 
 	_screenTop = camera._cur.y - (_realHeight / 2);
 	if (_features & GF_AFTER_V7) {
@@ -1966,6 +1983,11 @@
 		_screenLeft = _screenStartStrip << 3;
 	}
 
+#ifdef V7_SMOOTH_SCROLLING_HACK
+	virtscr[0].xstart = _screenLeft;
+#else
+	virtscr[0].xstart = _screenStartStrip << 3;
+#endif
 }
 
 void Scumm::panCameraTo(int x, int y)

Index: gfx.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- gfx.h	16 Dec 2002 07:13:47 -0000	1.14
+++ gfx.h	21 Dec 2002 01:11:41 -0000	1.15
@@ -42,7 +42,6 @@
 
 struct VirtScreen {		/* Virtual screen areas */
 	int number;
-	uint16 unk1;
 	uint16 topline;
 	uint16 width, height;
 	uint16 size;

Index: object.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/object.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- object.cpp	13 Dec 2002 01:33:23 -0000	1.19
+++ object.cpp	21 Dec 2002 01:11:41 -0000	1.20
@@ -336,8 +336,6 @@
 	if (_BgNeedsRedraw)
 		arg = 0;
 
-	_curVirtScreen = &virtscr[0];
-
 	od = &_objs[obj];
 
 	xpos = od->x_pos >> 3;
@@ -386,7 +384,7 @@
 		// the inventory and conversation icons.
 		if ((_features & GF_AFTER_V7 || _gameId == GID_SAMNMAX) && getClass(od->obj_nr, 22))
 			flags |= Gdi::dbDrawMaskOnAll;
-		gdi.drawBitmap(ptr, _curVirtScreen, x, ypos, height, x - xpos, numstrip, flags);
+		gdi.drawBitmap(ptr, &virtscr[0], x, ypos, height, x - xpos, numstrip, flags);
 	}
 }
 

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -d -r1.86 -r1.87
--- scumm.h	17 Dec 2002 01:15:13 -0000	1.86
+++ scumm.h	21 Dec 2002 01:11:42 -0000	1.87
@@ -219,7 +219,7 @@
 	int _offsX, _offsY;
 	int _virtScreenHeight;
 
-	void drawBits(byte *dst, byte *mask, int drawTop, int width, int height);
+	void drawBits(byte *dst, byte *mask, int drawTop, int width, int height, bool useMask);
 
 public:
 	byte _colorMap[16];
@@ -406,7 +406,6 @@
 	int _curVerbSlot;
 	int _curPalIndex;
 	byte _currentRoom;
-	VirtScreen *_curVirtScreen;
 
 	bool _egoPositioned;
 	int _keyPressed;

Index: string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- string.cpp	13 Dec 2002 00:52:14 -0000	1.55
+++ string.cpp	21 Dec 2002 01:11:42 -0000	1.56
@@ -320,17 +320,18 @@
 		+ drawTop * _vm->gdi._numStrips + _left / 8 + _vm->_screenStartStrip;
 
 	byte *dst = vs->screenPtr + vs->xstart + drawTop * _vm->_realWidth + _left;
+	bool useMask = (vs->number == 0 && !_ignoreCharsetMask);
 
 	if (_blitAlso) {
 		byte *back = dst;
 		dst = _vm->getResourceAddress(rtBuffer, vs->number + 5)
 			+ vs->xstart + drawTop * _vm->_realWidth + _left;
 
-		drawBits(dst, mask, drawTop, width, height);
+		drawBits(dst, mask, drawTop, width, height, useMask);
 
 		_vm->blit(back, dst, width, height);
 	} else {
-		drawBits(dst, mask, drawTop, width, height);
+		drawBits(dst, mask, drawTop, width, height, useMask);
 	}
 	
 	_left += width;
@@ -343,17 +344,14 @@
 	_top -= _offsY;
 }
 
-void CharsetRenderer::drawBits(byte *dst, byte *mask, int drawTop, int width, int height)
+void CharsetRenderer::drawBits(byte *dst, byte *mask, int drawTop, int width, int height, bool useMask)
 {
-	bool usemask;
 	byte maskmask;
 	int y, x;
 	int maskpos;
 	int color;
 	byte numbits, bits;
 
-	usemask = (_vm->_curVirtScreen->number == 0 && !_ignoreCharsetMask);
-
 	bits = *_charPtr++;
 	numbits = 8;
 
@@ -370,7 +368,7 @@
 			assert(color == myColor);
 			
 			if (color) {
-				if (usemask) {
+				if (useMask) {
 					mask[maskpos] |= maskmask;
 				}
 				*dst = _colorMap[color];





More information about the Scummvm-git-logs mailing list