diff options
| author | James Brown | 2002-10-07 09:20:50 +0000 | 
|---|---|---|
| committer | James Brown | 2002-10-07 09:20:50 +0000 | 
| commit | e252eda7c238c263fe94bede247779260ecfb861 (patch) | |
| tree | b016896c697950edd2e2b1dc450aea5263dd209e /scumm/akos.cpp | |
| parent | bbc1567526aaa538c844afd53b02913d6a31b761 (diff) | |
| download | scummvm-rg350-e252eda7c238c263fe94bede247779260ecfb861.tar.gz scummvm-rg350-e252eda7c238c263fe94bede247779260ecfb861.tar.bz2 scummvm-rg350-e252eda7c238c263fe94bede247779260ecfb861.zip | |
eriktorbjorn's Akos Codec 5 rewrite (Patch 618888 V2)
svn-id: r5102
Diffstat (limited to 'scumm/akos.cpp')
| -rw-r--r-- | scumm/akos.cpp | 159 | 
1 files changed, 121 insertions, 38 deletions
| diff --git a/scumm/akos.cpp b/scumm/akos.cpp index ecd97b2b0f..3f97bcd7c1 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -860,60 +860,143 @@ void AkosRenderer::codec1_ignorePakCols(int num)  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; + +	// 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... + +	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, clip_left, clip_right, clip_top, clip_bottom, 1 << dirty_id); + +	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; +	} + +	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; +		} +	} -	// Yazoo: this is not correct, but fix a lots of bugs for the momment +	src = srcptr; +	dest = outptr; -	draw_top = 0; -	draw_bottom = vs->height; +	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; -	_vm->updateDirtyRect(0, left, right + 1, top, bottom + 1, 1 << dirty_id); +		data_length = READ_LE_UINT16(src) + 2; -	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; +		if (dst_y < 0 || dst_y >= _vm->_realHeight) { +			src += data_length; +			dst_y++; +			continue; +		} -	_vm->drawBomp(&bdd, 0, bdd.dataptr, 0, 0); +		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() | 
