diff options
| -rw-r--r-- | scumm/akos.cpp | 51 | ||||
| -rw-r--r-- | scumm/akos.h | 5 | ||||
| -rw-r--r-- | scumm/script_v8.cpp | 58 | 
3 files changed, 55 insertions, 59 deletions
diff --git a/scumm/akos.cpp b/scumm/akos.cpp index 452330864c..8cd0442202 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -353,22 +353,29 @@ void AkosRenderer::codec1_genericDecode() {  		do {  			if (*scaleytab++ < _scaleY) { -				masked = (y < _outheight) && v1.mask_ptr && ((mask[0] | mask[v1.imgbufoffs]) & maskbit); - -				if (color && y < _outheight && !masked && !skip_column) { -					pcolor = palette[color]; -					if (_shadow_mode == 1) { -						if (pcolor == 13) -							pcolor = _shadow_table[*dst]; -					} else if (_shadow_mode == 2) { -						warning("codec1_spec2"); // TODO -					} else if (_shadow_mode == 3) { -						if (pcolor < 8) { -							pcolor = (pcolor << 8) + *dst; -							pcolor = _shadow_table[pcolor]; +				if (_actorHitMode) { +					if (color && (int16) y == _actorHitY && v1.x == _actorHitX) { +						_actorHitResult = true; +						return; +					} +				} else { +					masked = (y < _outheight) && v1.mask_ptr && ((mask[0] | mask[v1.imgbufoffs]) & maskbit); + +					if (color && y < _outheight && !masked && !skip_column) { +						pcolor = palette[color]; +						if (_shadow_mode == 1) { +							if (pcolor == 13)	 +								pcolor = _shadow_table[*dst]; +						} else if (_shadow_mode == 2) { +							warning("codec1_spec2"); // TODO +						} else if (_shadow_mode == 3) { +							if (pcolor < 8) { +								pcolor = (pcolor << 8) + *dst; +								pcolor = _shadow_table[pcolor]; +							}  						} +						*dst = pcolor;  					} -					*dst = pcolor;  				}  				dst += _outwidth;  				mask += _numStrips; @@ -644,7 +651,11 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) {  	v1.skip_width = _width;  	v1.scaleXstep = _mirror ? 1 : -1; -	_vm->updateDirtyRect(0, x_left, x_right, y_top, y_bottom, _dirty_id); +	if (_actorHitMode) { +		if (_actorHitX < x_left || _actorHitX >= x_right || _actorHitY < y_top || _actorHitY >= y_bottom) +			return 0; +	} else +		_vm->updateDirtyRect(0, x_left, x_right, y_top, y_bottom, _dirty_id);  	if (y_top >= (int)_outheight || y_bottom <= 0)  		return 0; @@ -717,6 +728,11 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) {  byte AkosRenderer::codec5(int xmoveCur, int ymoveCur) {  	int32 clip_left, clip_right, clip_top, clip_bottom, maxw, maxh; +	if (_actorHitMode) { +		warning("codec5: _actorHitMode not yet implemented"); +		return 0; +	} +  	if (!_mirror) {  		clip_left = (_actorX - xmoveCur - _width) + 1;  	} else { @@ -923,6 +939,11 @@ byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {  	int32 clip_left, clip_right, clip_top, clip_bottom, maxw, maxh;  	int32 skip_x, skip_y, cur_x, cur_y;  	const byte transparency = (_vm->_features & GF_HUMONGOUS) ? 0 : 255; + +	if (_actorHitMode) { +		warning("codec16: _actorHitMode not yet implemented"); +		return 0; +	}  	if (!_mirror) {  		clip_left = (_actorX - xmoveCur - _width) + 1; diff --git a/scumm/akos.h b/scumm/akos.h index 06572f110b..9cb5979cdd 100644 --- a/scumm/akos.h +++ b/scumm/akos.h @@ -65,8 +65,13 @@ public:  		aksq = 0;  		akof = 0;  		akcd = 0; +		_actorHitMode = false;  	} +	bool _actorHitMode; +	int16 _actorHitX, _actorHitY; +	bool _actorHitResult; +  	void setPalette(byte *palette);  	void setFacing(Actor *a);  	void setCostume(int costume); diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index 764820faee..e2c442cf52 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -22,6 +22,7 @@  #include "stdafx.h"  #include "scumm.h"  #include "actor.h" +#include "akos.h"  #include "charset.h"  #include "intern.h"  #include "sound.h" @@ -1469,52 +1470,21 @@ void Scumm_v8::o8_kernelGetFunctions() {  	}  	case 0xD9: {   // actorHit - used, for example, to detect ship collision  	               // during ship-to-ship combat. -#if 0  		Actor *a = derefActor(args[1], "actorHit"); -		int x = args[2]; -		int y = args[3]; -		 -		// TODO: this should perform a collision test, i.e. check if -		// point (x,y) lies on the given actor or not. -		// To achieve this, one needs to consider the current costume -		// etc. What the original code seems to do is to draw the -		// actor/costume (but maybe in a custom buffer?), and let the -		// draw code perform the hit test. -		// But I am not 100% clear on this. For example, it probably -		// shouldn't touch the gfx usage bits, and some other things... -		// So maybe we need dedicated code for this after all? - -		warning("actorHit(%d, %d, %d) NYI", args[1], x, y); - -#endif - -		push(1);	// FIXME - for now always return 1 -/*		 -		// Rough sketch, thanks to DanielFox and ludde -		struct SomeStruct { -			int RoomHeight, RoomWidth; -			byte *ScreenBuffer; -		} +		AkosRenderer *ar = (AkosRenderer *) _costumeRenderer; +		bool old_need_redraw = a->needRedraw; + +		ar->_actorHitX = args[2]; +		ar->_actorHitY = args[3] + _screenTop; +		ar->_actorHitMode = true; +		ar->_actorHitResult = false; + +		a->needRedraw = true; +		a->drawActorCostume(); +		a->needRedraw = old_need_redraw; -		dword_4FC150 = args[3];			// X  -		dword_4FC154 = args[2];			// Y -		Actor &a = pActors[args[1]];	 -		Point rel = GetScreenCoordsRelativeToRoom(), pt, scale; -		SomeStruct tmp; - -		pt.x = a.x + a.field_18 - rel.x;	// 18/1C are some kind of  -		pt.y = a.y + a.field_1C - rel.y;	// X/Y offsets... -		scale.x = a.scale_x; -		scale.y = a.scale_y; - -		dword_4FC148 = 2; -		graphics_getBuffer1Info(&tmp);		// Some kind of get_virtscreen? -		chore_drawActor(tmp, actor_nr, &pt, &scale); - -		if (dword_4FC148 != 1)			// Guess this is changed by -			dword_4FC148 = 0;		// chore_drawActor -		push(dword_4FC148); -*/ +		ar->_actorHitMode = false; +		push(ar->_actorHitResult);  		break;  	}  	case 0xDA:		// lipSyncWidth  | 
