[Scummvm-cvs-logs] CVS: scummvm/scumm akos.cpp,1.5,1.6

James Brown ender at users.sourceforge.net
Mon Oct 7 02:21:03 CEST 2002


Update of /cvsroot/scummvm/scummvm/scumm
In directory usw-pr-cvs1:/tmp/cvs-serv3761/scumm

Modified Files:
	akos.cpp 
Log Message:
eriktorbjorn's Akos Codec 5 rewrite (Patch 618888 V2)


Index: akos.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/akos.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- akos.cpp	6 Oct 2002 06:36:22 -0000	1.5
+++ akos.cpp	7 Oct 2002 09:20:50 -0000	1.6
@@ -860,60 +860,143 @@
 void AkosRenderer::codec5()
 {
 	VirtScreen *vs;
-	BompDrawData bdd;
 
-	int moveX;
-	int moveY;
-	int left;
-	int var_20;
-	int max_width;
+	int left, right, top, bottom;
+	int clip_left, clip_right, clip_top, clip_bottom;
 
-	int right;
-	int top;
-	int bottom;
+	byte *src, *dest;
+	int src_x, src_y;
+	int dst_x, dst_y;
+
+	bool masking;
+	byte maskbit;
+	byte *mask = NULL;
 
+	// I don't know if this is complete. It used to simply call drawBomp()
+	// to draw an unscaled image, but I don't know if that was because it
+	// will never have to scale, or if it's because until quite recently
+	// drawBomp() didn't know how to scale images.
+	//
+	// What I do know is that drawBomp() doesn't care about masking and
+	// shadows, and these are both needed for Full Throttle and The Dig.
+	
 	vs = &_vm->virtscr[0];
-	//setBlastObjectMode(shadow_mode); // not implemented yet
-	moveX = move_x_cur;
-	moveY = move_y_cur;
 
 	if (!mirror) {
-		left = (x - moveX - width) + 1;
+		left = (x - move_x_cur - width) + 1;
 	} else {
-		left = x + moveX - 1;
+		left = x + move_x_cur - 1;
 	}
 
-	var_20 = 0;
-	max_width = outwidth;
-
-	right = left + width - 1;
-	top = y + moveY;
+	right = left + width;
+	top = y + move_y_cur;
 	bottom = top + height;
 
-	if (left < 0)
-		left = 0;
-	if (left > max_width)
-		left -= left - max_width;
+	if (left >= _vm->_realWidth || top >= _vm->_realHeight)
+		return;
 
-	// Yazoo: this is not correct, but fix a lots of bugs for the momment
+	// The actual drawing code shouldn't survive even if the image is
+	// partially outside the screen, but something before that seems to
+	// be less tolerant...
 
-	draw_top = 0;
-	draw_bottom = vs->height;
+	clip_left = (left >= 0) ? left : 0;
+	clip_right = (right > _vm->_realWidth) ? _vm->_realWidth : right;
+	clip_top = (top >= 0) ? top : 0;
+	clip_bottom = (bottom > _vm->_realHeight) ? _vm->_realHeight : bottom;
+	
+	if (clip_top < draw_top)
+		draw_top = clip_top;
+	if (clip_bottom > draw_bottom)
+		draw_bottom = clip_bottom;
 
-	_vm->updateDirtyRect(0, left, right + 1, top, bottom + 1, 1 << dirty_id);
+	_vm->updateDirtyRect(0, clip_left, clip_right, clip_top, clip_bottom, 1 << dirty_id);
 
-	bdd.dataptr = srcptr;
-	bdd.out = outptr;
-	bdd.outheight = outheight;
-	bdd.outwidth = outwidth;
-	bdd.scale_x = 0xFF;
-	bdd.scale_y = 0xFF;
-	bdd.srcheight = height;
-	bdd.srcwidth = width;
-	bdd.x = left + 1;
-	bdd.y = top;
+	masking = false;
+	if (clipping) {
+		masking = _vm->isMaskActiveAt(clip_left, clip_top, clip_right, clip_bottom,
+			_vm->getResourceAddress(rtBuffer, 9) +
+			_vm->gdi._imgBufOffs[clipping] +
+			_vm->_screenStartStrip) != 0;
+	}
 
-	_vm->drawBomp(&bdd, 0, bdd.dataptr, 0, 0);
+	v1.mask_ptr = NULL;
+
+	if (masking || charsetmask) {
+		v1.mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _vm->_screenStartStrip;
+		v1.imgbufoffs = _vm->gdi._imgBufOffs[clipping];
+		if (!charsetmask && masking) {
+			v1.mask_ptr += v1.imgbufoffs;
+			v1.imgbufoffs = 0;
+		}
+	}
+
+	src = srcptr;
+	dest = outptr;
+
+	for (src_y = 0, dst_y = top; src_y < height; src_y++) {
+		byte code, color;
+		uint num, i;
+		byte *d = dest + dst_y * _vm->_realWidth + left;
+		byte *s;
+		uint data_length;
+
+		data_length = READ_LE_UINT16(src) + 2;
+
+		if (dst_y < 0 || dst_y >= _vm->_realHeight) {
+			src += data_length;
+			dst_y++;
+			continue;
+		}
+
+		src_x = 0;
+		dst_x = left;
+		s = src + 2;
+
+		while (src_x < width) {
+			code = *s++;
+			num = (code >> 1) + 1;
+			if (code & 1) {
+				color = *s++;
+				for (i = 0; i < num; i++) {
+					if (dst_x >= 0 && dst_x < _vm->_realWidth) {
+						if (color != 255) {
+							if (v1.mask_ptr)
+								mask = v1.mask_ptr + 40 * dst_y + (dst_x >> 3);
+							maskbit = revBitMask[dst_x & 7];
+							if (shadow_mode && color == 13)
+								color = shadow_table[*d];
+							if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit))
+								*d = color;
+						}
+					}
+					d++;
+					dst_x++;
+					src_x++;
+				}
+			} else {
+				for (i = 0; i < num; i++) {
+					color = s[i];
+					if (dst_x >= 0 && dst_x < _vm->_realWidth) {
+						if (color != 255) {
+							if (v1.mask_ptr)
+								mask = v1.mask_ptr + 40 * dst_y + (dst_x >> 3);
+							maskbit = revBitMask[dst_x & 7];
+							if (shadow_mode && color == 13)
+								color = shadow_table[*d];
+							if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit))
+								*d = color;
+						}
+					}
+					d++;
+					dst_x++;
+					src_x++;
+				}
+				s += num;
+			}
+		}
+		src += data_length;
+		dst_y++;
+	}
 }
 
 void AkosRenderer::codec16()





More information about the Scummvm-git-logs mailing list