diff options
Diffstat (limited to 'scumm')
| -rw-r--r-- | scumm/akos.cpp | 150 | ||||
| -rw-r--r-- | scumm/imuse.cpp | 7 | ||||
| -rw-r--r-- | scumm/script_v2.cpp | 36 | ||||
| -rw-r--r-- | scumm/scumm.h | 1 | ||||
| -rw-r--r-- | scumm/string.cpp | 75 | 
5 files changed, 226 insertions, 43 deletions
| diff --git a/scumm/akos.cpp b/scumm/akos.cpp index ecd97b2b0f..7b420ecb03 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -860,60 +860,136 @@ 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 right; -	int top; -	int bottom; +	byte *src, *dest; +	int src_x, src_y; +	uint dst_x, dst_y; +	bool masking; +	byte maskbit; +	const 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. +	  	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; -	bottom = top + height; +	right = left + width; +	top = y + move_y_cur; +	bottom = top + height + 1;  	if (left < 0)  		left = 0; -	if (left > max_width) -		left -= left - max_width; +	if (left > (int) outwidth) +		left -= left - outwidth; + +	if (top < draw_top) +		draw_top = top; +	if (bottom > draw_bottom) +		draw_bottom = bottom; + +	_vm->updateDirtyRect(0, left, right, top, bottom, 1 << dirty_id); -	// Yazoo: this is not correct, but fix a lots of bugs for the momment +	masking = false; +	if (clipping) { +		masking = _vm->isMaskActiveAt(left, top, right, bottom, +			_vm->getResourceAddress(rtBuffer, 9) + +			_vm->gdi._imgBufOffs[clipping] + +			_vm->_screenStartStrip) != 0; +	} + +	v1.mask_ptr = NULL; + +	if (masking || charsetmask || shadow_mode) { +		v1.mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + +			top * 40 + _vm->_screenStartStrip; +		v1.imgbufoffs = _vm->gdi._imgBufOffs[clipping]; +		if (!charsetmask && masking) { +			v1.mask_ptr += v1.imgbufoffs; +			v1.imgbufoffs = 0; +		} +	} -	draw_top = 0; -	draw_bottom = vs->height; +	src = srcptr; +	dest = outptr + top * outwidth + left + 1; -	_vm->updateDirtyRect(0, left, right + 1, top, bottom + 1, 1 << dirty_id); +	for (src_y = 0, dst_y = top; src_y < height; src_y++) { +		byte code, color; +		uint len, num, i; +		byte *d = dest; -	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 >= outheight) { +			src += READ_LE_UINT16(src) + 2; +			mask += 40; +			continue; +		} -	_vm->drawBomp(&bdd, 0, bdd.dataptr, 0, 0); +		len = width; +		src_x = 0; +		dst_x = left + 1; +		src += 2; + +		while (src_x <width) { +			code = *src++; +			num = (code >> 1) + 1; +			if (num > len) +				num = len; +			len -= num; +			if (code & 1) { +				color = *src++; +				for (i = 0; i < num; i++) { +					if (dst_x >= 0 && dst_x < outwidth) { +						if (color != 255) { +							if (v1.mask_ptr) +								mask = v1.mask_ptr + (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 = src[i]; +					if (dst_x >= 0 && dst_x < outwidth) { +						if (color != 255) { +							if (v1.mask_ptr) +								mask = v1.mask_ptr + (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++; +				} +				src += num; +			} +		} +		dest += outwidth; +		dst_y++; +	}  }  void AkosRenderer::codec16() diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index 42627befde..ce528a44f7 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -4855,7 +4855,7 @@ IMuseDigital::~IMuseDigital() {  void IMuseDigital::handler() {  	bool new_mixer; -	uint32 l, i, idx = 0; +	uint32 l = 0, i = 0;  	for (l = 0; l < MAX_DIGITAL_CHANNELS;l ++) {  		if (_channel[l]._used) { @@ -4901,6 +4901,11 @@ void IMuseDigital::handler() {  			}  			byte *buf = (byte*)malloc(mixer_size); +			if (!buf) { +				warning("DigitalMixer exploded: Blame Aquadran :)"); +				continue; +			} +			  			memcpy(buf, _channel[l]._data + _channel[l]._offset, new_size);  			if ((new_size != _channel[l]._mixerSize) && (_channel[l]._isJump == true)) {  				memcpy(buf + new_size, _channel[l]._data + _channel[l]._jump[0]._dest, mixer_size - new_size); diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index c79af8acac..62b6e3ba76 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -2535,9 +2535,16 @@ void Scumm::o6_talkActor()  	_messagePtr = _scriptPointer;  	if ((_gameId == GID_DIG) && (_messagePtr[0] == '/')) { -		_scriptPointer += strlen((char*)_scriptPointer) + 1; +		char pointer[20]; +		int i, j; + +		_scriptPointer += resStrLen((char*)_scriptPointer)+ 1;  		translateText((char*)_messagePtr, (char*)&transText); -		char *pointer = strtok((char *)_messagePtr, "/"); +		for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) { +			if (_messagePtr[i] != '/') +				pointer[j++] = _messagePtr[i]; +		} +		pointer[j] = 0;  		_sound->playBundleSound(pointer);  		_messagePtr = (byte*)&transText;  		setStringVars(0); @@ -2555,9 +2562,16 @@ void Scumm::o6_talkEgo()  	_messagePtr = _scriptPointer;  	if ((_gameId == GID_DIG) && (_messagePtr[0] == '/')) { -		_scriptPointer += strlen((char*)_scriptPointer) + 1; +		char pointer[20]; +		int i, j; + +		_scriptPointer += resStrLen((char*)_scriptPointer) + 1;  		translateText((char*)_messagePtr, (char*)&transText); -		char *pointer = strtok((char *)_messagePtr, "/"); +		for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) { +			if (_messagePtr[i] != '/') +				pointer[j++] = _messagePtr[i]; +		} +		pointer[j] = 0;  		_sound->playBundleSound(pointer);  		_messagePtr = (byte*)&transText;  		setStringVars(0); @@ -2722,6 +2736,8 @@ void Scumm::o6_miscOps()  	 				speed = 71;  				else  					speed = 1000 / _insaneFlag; +				if (args[1] == 1) printf("startSmush one is true\n"); +				if (args[2] == 1) printf("startSmush two is true\n");  				ScummRenderer * sr = new ScummRenderer(this, speed);   				SmushPlayer * sp = new SmushPlayer(sr);   				sp->play((char*)getStringAddressVar(VAR_VIDEONAME), getGameDataPath()); @@ -2763,6 +2779,16 @@ void Scumm::o6_miscOps()  					strcpy((char*)&charset._buffer, (char*)&buf + 13);  					description();  				} +			} else {  +				setStringVars(0); + +                		_string[0].charset = args[1]; +                		_string[0].color = args[2]; +                		_string[0].xpos = args[3]; +                		_string[0].ypos = args[4]; + +				addMessageToStack(getStringAddressVar(VAR_STRING2DRAW)); +				drawDescString();  			}  			break;  		case 17: @@ -3104,7 +3130,7 @@ void Scumm::decodeParseString2(int m, int n)  			if ((_messagePtr[0] == '/') && (_gameId == GID_DIG)) {  				translateText((char*)_messagePtr, (char*)&transText);  				_messagePtr = (byte*)&transText; -				_scriptPointer += strlen((char*)_scriptPointer) + 1; +				_scriptPointer += resStrLen((char*)_scriptPointer) + 1;  				switch (m) {  				case 0:  					actorTalk(); diff --git a/scumm/scumm.h b/scumm/scumm.h index bd14d72e01..e562b7554a 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -939,6 +939,7 @@ public:  	int hasCharsetMask(int x, int y, int x2, int y2);  	void CHARSET_1();  	void description(); +	void drawDescString();  	byte *_msgPtrToAdd;  	byte *addMessageToStack(byte *msg);  	void addIntToStack(int var); diff --git a/scumm/string.cpp b/scumm/string.cpp index 3d77a59131..5612a17a5b 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -504,6 +504,77 @@ void Scumm::description()  	gdi._mask_bottom = charset._strBottom;  } +void Scumm::drawDescString() +{ +	byte byte1=0, chr, *buf, *charsetptr; +	uint color, i; + +	buf = charset._buffer; +	charset._bufPos = 0; + +	charset._left2 = charset._left = _string[0].xpos; +	charset._top = _string[0].ypos; +	charset._curId = _string[0].charset; +	charset._center = _string[0].center; +	charset._right = _string[0].right; +	charset._color = _string[0].color; + +	charset._xpos2 = _string[0].xpos; +	charset._ypos2 = _string[0].ypos; +	charset._disableOffsX = charset._unk12 = 1; +	_bkColor = 0; +	_talkDelay = 1; + +	charset._left -= charset.getStringWidth(0, buf, 0) >> 1; + +	restoreCharsetBg(); + +	// Read color mapping and height information +	charsetptr = getResourceAddress(rtCharset, charset._curId); +	assert(charsetptr); +	charsetptr += 29; +	for (i = 0; i < 4; i++) +			charset._colorMap[i] = _charsetData[charset._curId][i]; + +	byte1 = charsetptr[1]; // Character height + +	for (i = 0; (chr = buf[i++]) != 0;) { +		if (chr == 254) +			chr = 255; +		if (chr == 255) { +			chr = buf[i++]; +			switch (chr) { +			case 9: +			case 10: +			case 13: +			case 14: +				i += 2; +				break; +			case 1: +			case 8: +				charset._left = charset._left2 - charset.getStringWidth(0, buf, i); +				charset._top += byte1; +				break; +			case 12: +				color = buf[i] + (buf[i + 1] << 8); +				i += 2; +				if (color == 0xFF) +					charset._color = _string[0].color; +				else +					charset._color = color; +				break; +			} +		} else { +				charset.printChar(chr); +		} +	} + +	gdi._mask_left = charset._strLeft; +	gdi._mask_right = charset._strRight; +	gdi._mask_top = charset._strTop; +	gdi._mask_bottom = charset._strBottom; +} +  void Scumm::drawString(int a)  {  	byte buf[256]; @@ -560,6 +631,10 @@ void Scumm::drawString(int a)  		charset._left -= charset.getStringWidth(a, buf, 0) >> 1;  	} +	if (!_features & GF_AFTER_V7) +		charset._ignoreCharsetMask = 1; + +  	// Verb text should never time out.  	if (a == 4)  		_talkDelay = -1; | 
