diff options
| -rw-r--r-- | actor.cpp | 143 | ||||
| -rw-r--r-- | boxes.cpp | 329 | ||||
| -rw-r--r-- | costume.cpp | 4 | ||||
| -rw-r--r-- | resource.cpp | 11 | ||||
| -rw-r--r-- | script_v1.cpp | 28 | ||||
| -rw-r--r-- | scumm.h | 24 | 
6 files changed, 381 insertions, 158 deletions
| @@ -646,6 +646,9 @@ void Scumm::walkActors() {  	for (i=1; i<NUM_ACTORS; i++) {  		a = derefActor(i);  		if (a->room==_currentRoom) +		if(_features & GF_OLD256) +			walkActorOld(a); +		else  			walkActor(a);  	}  } @@ -753,6 +756,7 @@ void Scumm::walkActor(Actor *a) {  	}  	a->walkdata.curbox = j; +	  	if (findPathTowards(a, a->walkbox, j, a->walkdata.destbox)) {  		a->moving |= 8;  		calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); @@ -777,10 +781,33 @@ void Scumm::walkActor(Actor *a) {  			return;  		}  		a->walkdata.curbox = j; -		if (findPathTowards(a, a->walkbox, j, a->walkdata.destbox)) -			break; -		if (calcMovementFactor(a, _foundPathX, _foundPathY)) -			return; +		if(_features & GF_OLD256) +		{ +			findPathTowardsOld(a, a->walkbox, j, a->walkdata.destbox); +		        if (p[2].x == 32000 && p[3].x == 32000) +			{ +				a->moving |= 8; +				calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); +				return; +			} +		 +			if (p[2].x != 32000) { +				if (calcMovementFactor(a, p[2].x, p[2].y)){ +					a->walkdata.destx = p[3].x; +					a->walkdata.desty = p[3].y; +					return;													 +				} +			} + +			if (calcMovementFactor(a, p[3].x, p[3].y)) +				return; +			 +		} else { +			if (findPathTowards(a, a->walkbox, j, a->walkdata.destbox)) +				break; +			if (calcMovementFactor(a, _foundPathX, _foundPathY)) +				return; +		}  		setActorBox(a, a->walkdata.curbox);  	} while (1); @@ -1078,6 +1105,8 @@ void Scumm::startWalkActor(Actor *a, int x, int y, int dir) {  	a->walkdata.destbox = (byte)abr.dist; /* a box */  	a->walkdata.destdir = dir;  	a->moving = (a->moving&2)|1; +	a->walkdata.point3x = 32000; +	  	a->walkdata.curbox = a->walkbox;  } @@ -1180,3 +1209,109 @@ void Scumm::setupShadowPalette(int slot,int rfact,int gfact,int bfact,int from,i  		curpal+=3;  	} while (--num);  } + +void Scumm::walkActorOld(Actor *a) { +	int new_dir,next_box,goto_x,goto_y; + +	if(!a->moving) +		return; + +	if(a->moving&1) +	{ +restart: +		a->moving &= ~1; + +		if (a->walkbox==0xFF) +		{ +			a->walkbox = a->walkdata.destbox; +			a->walkdata.curbox = a->walkdata.destbox; +			a->moving |=8; +			calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); +			return; +		} + +		if (a->walkbox==a->walkdata.destbox) +		{ +			a->moving |=8; +			calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); +			return; +		} + +		next_box = getPathToDestBox(a->walkbox,a->walkdata.destbox); + +		if( next_box == -1) +		{ +			a->moving |=8; +			return; +		} + +		a->walkdata.curbox = next_box; + +		findPathTowardsOld(a, a->walkbox, next_box, a->walkdata.destbox); +		if(p[2].x == 32000 && p[3].x == 32000) +		{ +			a->moving |=8; +			calcMovementFactor(a, a->walkdata.destx, a->walkdata.desty); +			return; +		} + +		if(p[2].x != 32000) +		{ +			if(calcMovementFactor(a, p[2].x, p[2].y)) +			{ +				actor->walkdata.point3x=p[3].x; +				actor->walkdata.point3y=p[3].y; +				return; +			} +		} + +		if(calcMovementFactor(a,p[3].x,p[3].y)) +			return; +		 +		a->walkbox = a->walkdata.destbox; +		a->mask = getMaskFromBox(a->walkbox); +		goto restart; + +	} + +	if(a->moving & 2) +	{ +		if(actorWalkStep(a)) +			return; +	} + +	if(a->moving & 8) +	{ +		a->moving = 0; +		startWalkAnim(a, 3, a->walkdata.destdir); +		return; +	} + +	if(a->moving & 4) +	{ +		new_dir = updateActorDirection(a); +		if (a->facing != new_dir) +		{ +			fixActorDirection(a,new_dir); +			return; +		} +		a->moving=0; +		return; +	} + +	if(a->walkdata.point3x != 32000) +	{ +		if(calcMovementFactor(a,a->walkdata.point3x,a->walkdata.point3y)) +		{ +			a->walkdata.point3x=32000; +			return; +		} +		a->walkdata.point3x=32000; +	} + +	a->walkbox = a->walkdata.curbox; +	a->mask = getMaskFromBox(a->walkbox); +	a->moving &= 2; +	a->moving |= 1; +goto restart; +} @@ -21,6 +21,7 @@  #include "stdafx.h"  #include "scumm.h" +#include "math.h"  byte Scumm::getMaskFromBox(int box) {  	Box *ptr = getBoxBaseAddr(box); @@ -121,10 +122,22 @@ void Scumm::getBoxCoordinates(int boxnum, BoxCoords *box) {  	box->ul.y = (int16)FROM_LE_16(bp->uly);  	box->ur.x = (int16)FROM_LE_16(bp->urx);  	box->ur.y = (int16)FROM_LE_16(bp->ury); -	box->ll.x = (int16)FROM_LE_16(bp->llx); -	box->ll.y = (int16)FROM_LE_16(bp->lly); -	box->lr.x = (int16)FROM_LE_16(bp->lrx); -	box->lr.y = (int16)FROM_LE_16(bp->lry); + +	if(_features & GF_OLD256) +	{ +		box->ll.x = (int16)FROM_LE_16(bp->lrx); +		box->ll.y = (int16)FROM_LE_16(bp->lry); +		box->lr.x = (int16)FROM_LE_16(bp->llx); +		box->lr.y = (int16)FROM_LE_16(bp->lly); +	} +	else +	{ +		box->ll.x = (int16)FROM_LE_16(bp->llx); +		box->ll.y = (int16)FROM_LE_16(bp->lly); +		box->lr.x = (int16)FROM_LE_16(bp->lrx); +		box->lr.y = (int16)FROM_LE_16(bp->lry); +	} +	  }  uint Scumm::distanceFromPt(int x, int y, int ptx, int pty) { @@ -465,8 +478,6 @@ int Scumm::findPathTowards(Actor *a, byte box1nr, byte box2nr, byte box3nr) {  		box2.ll = box2.lr;  		box2.lr = tmp;  	} -	warning("findPathTowards: default"); // FIXME: ZAK256 -	findPathTowardsOld(a, box1nr, box2nr, box3nr);  	return 0;  }  void Scumm::setBoxFlags(int box, int val) { @@ -804,149 +815,181 @@ void *Scumm::addToBoxVertexHeap(int size) {  PathVertex *Scumm::addPathVertex() {  	_boxMatrixPtr4 = getResourceAddress(rtMatrix, 4);  	_boxPathVertexHeapIndex = 0; +  	return (PathVertex*)addToBoxVertexHeap(sizeof(PathVertex));  } -int Scumm::findPathTowardsOld(Actor *a, byte box1nr, byte box2nr, byte box3nr) { -        BoxCoords box1; -        BoxCoords box2; -        ScummPoint tmp; -        int i,j; -        int flag; -        int q,pos; -	int threshold=1; - -        getBoxCoordinates(box1nr,&box1); -        getBoxCoordinates(box2nr,&box2); - -	do{ -        for(i=0; i<4; i++) { -                for(j=0; j<4; j++) { -                        if (abs(box1.ul.x-box1.ur.x)<threshold && -                                        abs(box1.ul.x-box2.ul.x)<threshold && -                                        abs(box1.ul.x-box2.ur.x)<threshold ) { -                                flag = 0; -                                if (box1.ul.y > box1.ur.y) { -                                        SWAP(box1.ul.y, box1.ur.y); -                                        flag |= 1; -                                } - -                                if (box2.ul.y > box2.ur.y) { -                                        SWAP(box2.ul.y, box2.ur.y); -                                        flag |= 2; -                                } - -                                if (box1.ul.y > box2.ur.y || box2.ul.y > box1.ur.y || -                                                (box1.ur.y==box2.ul.y || box2.ur.y==box1.ul.y) && -                                                box1.ul.y!=box1.ur.y && box2.ul.y!=box2.ur.y) { -                                        if (flag&1) -                                                SWAP(box1.ul.y, box1.ur.y); -                                        if (flag&2) -                                                SWAP(box2.ul.y, box2.ur.y); -                                } else { -                                        if (box2nr == box3nr) { -                                                int diffX = a->walkdata.destx - a->x; -                                                int diffY = a->walkdata.desty - a->y; -                                                int boxDiffX = box1.ul.x - a->x; - -                                                if (diffX!=0) { -                                                        int t; - -                                                        diffY *= boxDiffX; -                                                        t = diffY / diffX; -                                                        if (t==0 && (diffY<=0 || diffX<=0) && (diffY>=0 || diffX>=0)) -                                                                t = -1; -                                                        pos = a->y + t; -                                                } else { -                                                        pos = a->y; -                                                } -                                        } else { -                                                pos = a->y; -                                        } - -                                        q = pos; -                                        if (q < box2.ul.y) -                                        q = box2.ul.y; -                                        if (q > box2.ur.y) -                                                q = box2.ur.y; -                                        if (q < box1.ul.y) -                                                q = box1.ul.y; -                                        if (q > box1.ur.y) -                                                q = box1.ur.y; -                                        if (q==pos && box2nr==box3nr) -                                                return 1; -                                        _foundPathY = q; -                                        _foundPathX = box1.ul.x; -                                        return 0; -                                } -                        } +int Scumm::findPathTowardsOld(Actor *a, byte trap1, byte trap2, byte final_trap) +{ +        GetGates(trap1,trap2); +	ScummPoint pt; -                        if (abs(box1.ul.y-box1.ur.y)<threshold && -                                        abs(box1.ul.y-box2.ul.y)<threshold && -                                        abs(box1.ul.y-box2.ur.y)<threshold ){ -                                flag = 0; -                                if (box1.ul.x > box1.ur.x) { -                                        SWAP(box1.ul.x, box1.ur.x); -                                        flag |= 1; -                                } - -                                if (box2.ul.x > box2.ur.x) { -                                        SWAP(box2.ul.x, box2.ur.x); -                                        flag |= 2; -                                } - -                                if (box1.ul.x > box2.ur.x || box2.ul.x > box1.ur.x || -                                                (box1.ur.x==box2.ul.x || box2.ur.x==box1.ul.x) && -                                                box1.ul.x!=box1.ur.x && box2.ul.x!=box2.ur.x) { -                                        if (flag&1) -                                                SWAP(box1.ul.x, box1.ur.x); -                                        if (flag&2) -                                                SWAP(box2.ul.x, box2.ur.x); -                                } else { - -                                        if (box2nr == box3nr) { -                                                int diffX = a->walkdata.destx - a->x; -                                                int diffY = a->walkdata.desty - a->y; -                                                int boxDiffY = box1.ul.y - a->y; - -                                                pos = a->x; -                                                if (diffY!=0) { -                                                        pos += diffX * boxDiffY / diffY; -                                                } -                                        } else { -                                                pos = a->x; -                                        } - -                                        q = pos; -                                        if (q < box2.ul.x) -                                                q = box2.ul.x; -                                        if (q > box2.ur.x) -                                                q = box2.ur.x; -                                        if (q < box1.ul.x) -                                                q = box1.ul.x; -                                        if (q > box1.ur.x) -                                                q = box1.ur.x; -                                        if (q==pos && box2nr==box3nr) -                                                return 1; -                                        _foundPathX = q; -                                        _foundPathY = box1.ul.y; -                                        return 0; -                                } +        p[1].x = actor->x; +        p[1].y = actor->y; +        p[2].x = 32000; +        p[3].x = 32000; +        p[4].x = 32000; + +        if (trap2 == final_trap) {                                                              /* next = final box? */ +                p[4].x = actor->walkdata.destx; +                p[4].y = actor->walkdata.desty; + +                if (getMaskFromBox(trap1) == getMaskFromBox(trap2) || 1) { +                        if (CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate1ax,gate1ay) != +                                 CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate1bx,gate1by) && +                                 CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate2ax,gate2ay) != +                                 CompareSlope(p[1].x,p[1].y,p[4].x,p[4].y, gate2bx,gate2by)) { +                                return 0;         /* same zplane and between both gates? */                          } -                        tmp = box1.ul; -                        box1.ul = box1.ur; -                        box1.ur = box1.ll; -                        box1.ll = box1.lr; -                        box1.lr = tmp;                  } -                tmp = box2.ul; -                box2.ul = box2.ur; -                box2.ur = box2.ll; -                box2.ll = box2.lr; -                box2.lr = tmp;          } -	threshold++; -	}while(threshold<10); -        error("findPathTowardsOld: default"); // FIXME: ZAK256 + +       	pt=closestPtOnLine(gate2ax,gate2ay,gate2bx,gate2by,p[1].x,p[1].y); +        p[3].x = pt.x; +        p[3].y = pt.y; + +        if (CompareSlope(p[1].x,p[1].y,p[3].x,p[3].y, gate1ax,gate1ay) == +                 CompareSlope(p[1].x,p[1].y,p[3].x,p[3].y, gate1bx,gate1by)) { +                closestPtOnLine(gate1ax,gate1ay,gate1bx,gate1by,p[1].x,p[1].y); +                p[2].x = pt.x;                       /* if point 2 between gates, ignore! */ +                p[2].y = pt.y; +        } +          return 0;  } + +void Scumm::GetGates(int trap1,int trap2) { +int   i; +int    Closest1,Closest2,Closest3; +int    Dist[8]; +int Dist1,Dist2,Dist3; +int Box1,Box2,Box3; +BoxCoords box; +int polyx[8]; +int polyy[8]; +AdjustBoxResult pt; + +        getBoxCoordinates(trap1,&box); +        polyx[0] = box.ul.x; +        polyy[0] = box.ul.y; +        polyx[1] = box.ur.x; +        polyy[1] = box.ur.y; +        polyx[2] = box.ll.x; +        polyy[2] = box.ll.y; +        polyx[3] = box.lr.x; +        polyy[3] = box.lr.y; +        for (i = 0 ; i < 4 ; i++) {  +		pt = getClosestPtOnBox(trap2,polyx[i],polyy[i]); +		Dist[i] = pt.dist; +                CloX[i] = pt.x; +                CloY[i] = pt.y; +        } + +        getBoxCoordinates(trap2,&box); +        polyx[4] = box.ul.x; +        polyy[4] = box.ul.y; +        polyx[5] = box.ur.x; +        polyy[5] = box.ur.y; +        polyx[6] = box.ll.x; +        polyy[6] = box.ll.y; +        polyx[7] = box.lr.x; +        polyy[7] = box.lr.y; +        for (i = 4 ; i < 8 ; i++) { +                pt = getClosestPtOnBox(trap1,polyx[i],polyy[i]); +                Dist[i] = pt.dist; +                CloX[i] = pt.x; +                CloY[i] = pt.y; +        } + + +        Dist1 = 0xFFFF; +        for (i = 0 ; i < 8 ; i++) { +                if (Dist[i] < Dist1) { +                        Dist1 = Dist[i]; +                        Closest1 = i; +                } +        } +        Dist[Closest1] = 0xFFFF; + +        Dist2 = 0xFFFF; +        for (i = 0 ; i < 8 ; i++) { +                if (Dist[i] < Dist2) { +                        Dist2 = Dist[i]; +                        Closest2 = i; +                } +        } +        Dist[Closest2] = 0xFFFF; + +        Dist3 = 0xFFFF; +        for (i = 0 ; i < 8 ; i++) { +                if (Dist[i] < Dist3) { +                        Dist3 = Dist[i]; +                        Closest3 = i; +                } +        } + +        Box1 = (Closest1 > 3); +        Box2 = (Closest2 > 3); +        Box3 = (Closest3 > 3); + +        Dist1 = (int)sqrt(Dist1); +        Dist2 = (int)sqrt(Dist2); +        Dist3 = (int)sqrt(Dist3); +         +	if (Box1 == Box2 && abs(Dist1-Dist2) < 4) { +                SetGate(Closest1,Closest2,polyx,polyy); + +        } else if (Box1 == Box2 && Dist1 == Dist2) {                            /* parallel */ +                SetGate(Closest1,Closest2,polyx,polyy); +        } else if (Box1 == Box3 && Dist1 == Dist3) {                            /* parallel */ +                SetGate(Closest1,Closest3,polyx,polyy); +        } else if (Box2 == Box3 && Dist2 == Dist3) {                            /* parallel */ +                SetGate(Closest2,Closest3,polyx,polyy); + + +        } else if (Box1 == Box3 && abs(Dist1-Dist3) < 4) { +                SetGate(Closest1,Closest3,polyx,polyy); +        } else if (abs(Dist1-Dist3) < 4) {  /* if 1 close to 3 then use 2-3 */ +                SetGate(Closest2,Closest3,polyx,polyy); +        } else if (abs(Dist1-Dist2) < 4) { +                SetGate(Closest1,Closest2,polyx,polyy); +        } else { +                SetGate(Closest1,Closest1,polyx,polyy); +        } +} + +int Scumm::CompareSlope(int X1,int Y1,int X2,int Y2,int X3,int Y3) +{ +        if ((Y2 - Y1) * (X3 - X1) > (Y3 - Y1) * (X2 - X1)) return(0); +        return(1); +} + +void Scumm::SetGate(int line1,int line2, int polyx[8], int polyy[8]) +{ + +        if (line1 < 4) {                                                                /* from box 1 to box 2 */ +                gate1ax = polyx[line1]; +                gate1ay = polyy[line1]; +                gate2ax = CloX[line1]; +                gate2ay = CloY[line1]; + +        } else { +                gate2ax = polyx[line1]; +                gate2ay = polyy[line1]; +                gate1ax = CloX[line1]; +                gate1ay = CloY[line1]; +        } + +        if (line2 < 4) {                                                                /* from box */ +                gate1bx = polyx[line2]; +                gate1by = polyy[line2]; +                gate2bx = CloX[line2]; +                gate2by = CloY[line2]; + +        } else { +                gate2bx = polyx[line2]; +                gate2by = polyy[line2]; +                gate1bx = CloX[line2]; +                gate1by = CloY[line2]; +        } +} diff --git a/costume.cpp b/costume.cpp index ebd32a499c..80a8e3763c 100644 --- a/costume.cpp +++ b/costume.cpp @@ -727,8 +727,8 @@ byte CostumeRenderer::drawOneSlot(Actor *a, int slot) {  		_srcptr = _loaded._ptr + READ_LE_UINT16(_frameptr + code*2);  		if (code != 0x7B) { -			if ( !(_vm->_features & GF_OLD256) || code <0x79) -				return mainRoutine(a, slot, code); +			if(_vm->_features & GF_OLD256 && code < 0x78) +			return mainRoutine(a, slot, code);  		}  	} diff --git a/resource.cpp b/resource.cpp index 26e13ab14e..6f8c22303b 100644 --- a/resource.cpp +++ b/resource.cpp @@ -326,6 +326,7 @@ void Scumm::readIndexFileSmall() {         uint32 itemsize;         int numblock = 0;         int num, i; +       byte* _oldClass;         debug(9, "readIndexFile()"); @@ -420,10 +421,12 @@ void Scumm::readIndexFileSmall() {                         num = fileReadWordLE();                         assert(num == _numGlobalObjects);                         for (i=0; i<num; i++) { /* not too sure about all that */ -                               _classData[i] = fileReadByte() + 256*fileReadByte()+ 256*256*fileReadByte(); -                     //          fileReadByte(); -                               _objectOwnerTable[i] = fileReadByte(); -                               _objectStateTable[i] = _objectOwnerTable[i]>>OF_STATE_SHL; +				_oldClass=(byte*)&_classData[i];			        +				_oldClass[0]=fileReadByte(); +				_oldClass[1]=fileReadByte(); +				_oldClass[2]=fileReadByte(); +				_objectOwnerTable[i] = fileReadByte(); +                            //   _objectStateTable[i] = fileReadByte();                                 _objectOwnerTable[i] &= OF_OWNER_MASK;                         } diff --git a/script_v1.cpp b/script_v1.cpp index 9e4f7c11ec..904f02777e 100644 --- a/script_v1.cpp +++ b/script_v1.cpp @@ -804,9 +804,14 @@ FixRoom:  	}  } +const short int bit_table[16] = +{1,2,4,8,0x10,0x20,0x40,0x80,0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000,0x8000}; + +  void Scumm::o5_actorSetClass() {  	int act = getVarOrDirectWord(0x80);  	int newClass; +	byte *oldClassData;  	while ( (_opcode=fetchScriptByte()) != 0xFF) {  		newClass = getVarOrDirectWord(0x80); @@ -814,10 +819,18 @@ void Scumm::o5_actorSetClass() {  			_classData[act] = 0;  			continue;  		} -		if (newClass&0x80) -			putClass(act, newClass, 1); -		else -			putClass(act, newClass, 0); +		if(_features & GF_SMALL_HEADER) { +			oldClassData=(byte*)&_classData[act]; +			if (newClass&0x80) +				oldClassData[((newClass-1)&0x7f)/8] |= bit_table[((newClass-1)&0x07)]; +			else +				oldClassData[((newClass-1)&0x7f)/8] &= bit_table[((newClass-1)&0x07)]^0xff; +		} else { +			if (newClass&0x80) +				putClass(act, newClass, 1); +			else +				putClass(act, newClass, 0); +		}  	}  } @@ -1331,11 +1344,16 @@ void Scumm::o5_getVerbEntrypoint() {  void Scumm::o5_ifClassOfIs() {  	int act,cls;  	bool cond = true, b; +	byte *oldClass;  	act = getVarOrDirectWord(0x80);  	while ( (_opcode = fetchScriptByte()) != 0xFF) {  		cls = getVarOrDirectWord(0x80); -		b = getClass(act, cls); +		oldClass = (byte*)&_classData[act]; +		if(_features & GF_SMALL_HEADER) +			b = oldClass[((cls-1)&0x7f)/8] & bit_table[((cls-1)&0x07)]; +		else +			b = getClass(act, cls);  		if (cls&0x80 && !b || !(cls&0x80) && b)  			cond = false; @@ -37,6 +37,12 @@  struct Scumm;  struct Actor; +struct gate_location +{ +	int     x; +	int     y; +}; +  #include "smush.h"  typedef void (Scumm::*OpcodeProc)(); @@ -329,6 +335,7 @@ struct ActorWalkData {  	int16 x,y,newx,newy;  	int32 XYFactor, YXFactor;  	uint16 xfrac,yfrac; +	int point3x, point3y;  };  struct MouseCursor { @@ -2155,6 +2162,8 @@ struct Scumm {  	byte VAR_UNK_SCRIPT;  	byte VAR_UNK_SCRIPT_2; + +	void GetGates(int trap1,int trap2);  	byte VAR_DEFAULT_TALK_DELAY;  	byte VAR_CHARSET_MASK; @@ -2162,6 +2171,21 @@ struct Scumm {  	int NUM_ACTORS;  	byte _videoPath[50]; + +	gate_location p[5]; + +	int CompareSlope(int X1,int Y1,int X2,int Y2,int X3,int Y3); +	void SetGate(int line1,int line2, int polyx[8], int polyy[8]); + +	int gate1ax, gate1ay; +	int gate1bx, gate1by; +	int gate2ax, gate2ay; +	int gate2bx, gate2by; + +	int CloX[8]; +	int CloY[8]; + +	void walkActorOld(Actor *a);  };  enum AkosOpcodes{ | 
