[Scummvm-cvs-logs] CVS: scummvm/sky autoroute.cpp,1.14,1.14.2.1 autoroute.h,1.5,1.5.4.1 compact.cpp,1.15,1.15.2.1 compact.h,1.8,1.8.2.1 control.cpp,1.50.2.2,1.50.2.3 control.h,1.21.2.2,1.21.2.3 logic.cpp,1.127.2.1,1.127.2.2 mouse.cpp,1.23,1.23.2.1 mouse.h,1.18,1.18.2.1 skydefs.h,1.24,1.24.2.1 struc.h,1.11,1.11.2.1

Robert G?ffringmann lavosspawn at users.sourceforge.net
Mon Aug 4 14:19:15 CEST 2003


Update of /cvsroot/scummvm/scummvm/sky
In directory sc8-pr-cvs1:/tmp/cvs-serv19504/sky

Modified Files:
      Tag: branch-0-5-0
	autoroute.cpp autoroute.h compact.cpp compact.h control.cpp 
	control.h logic.cpp mouse.cpp mouse.h skydefs.h struc.h 
Log Message:
fixed dialog skipping, implemented new v.5 savegame format and v.4 mixed-mode format, halfway removed this grafixProg thingie. Everyone go test BASS now. ;P

Index: autoroute.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/autoroute.cpp,v
retrieving revision 1.14
retrieving revision 1.14.2.1
diff -u -d -r1.14 -r1.14.2.1
--- autoroute.cpp	17 Jul 2003 00:35:32 -0000	1.14
+++ autoroute.cpp	4 Aug 2003 21:18:02 -0000	1.14.2.1
@@ -26,354 +26,237 @@
 #define ROUTE_GRID_SIZE (ROUTE_GRID_WIDTH*ROUTE_GRID_HEIGHT*2)
 #define WALK_JUMP 8      // walk in blocks of 8
 
+const int16 SkyAutoRoute::_routeDirections[4] = {    -1,     1, -ROUTE_GRID_WIDTH, ROUTE_GRID_WIDTH };
+const uint16 SkyAutoRoute::_logicCommands[4] = { RIGHTY, LEFTY,             DOWNY,              UPY };
+
 SkyAutoRoute::SkyAutoRoute(SkyGrid *pGrid) {
 
 	_grid = pGrid;
 	_routeGrid = (uint16 *)malloc(ROUTE_GRID_SIZE);
+	_routeBuf = (uint16 *)malloc(ROUTE_SPACE);
 }
 
 SkyAutoRoute::~SkyAutoRoute(void) {
 
 	free(_routeGrid);
+	free(_routeBuf);
 }
 
 uint16 SkyAutoRoute::checkBlock(uint16 *blockPos) {
 
-	uint16 fieldVal, retVal = 0xFFFF;
-	fieldVal = blockPos[1]; // field to the right
-	if ((!(fieldVal & 0x8000)) && (fieldVal != 0)) retVal = fieldVal;
-	fieldVal = (blockPos - 1)[0]; // field to the left
-	if ((!(fieldVal & 0x8000)) && (fieldVal != 0)) {
-		if ((fieldVal < retVal) || (retVal == 0xFFFF)) retVal = fieldVal;
-	}
-	fieldVal = (blockPos + ROUTE_GRID_WIDTH)[0]; // upper field
-	if ((!(fieldVal & 0x8000)) && (fieldVal != 0)) {
-		if ((fieldVal < retVal) || (retVal == 0xFFFF)) retVal = fieldVal;
-	}
-	fieldVal = (blockPos - ROUTE_GRID_WIDTH)[0]; // upper field
-	if ((!(fieldVal & 0x8000)) && (fieldVal != 0)) {
-		if ((fieldVal < retVal) || (retVal == 0xFFFF)) retVal = fieldVal;
+	uint16 retVal = 0xFFFF;
+
+	for (uint8 cnt = 0; cnt < 4; cnt++) {
+		uint16 fieldVal = *(blockPos + _routeDirections[cnt]);
+		if (fieldVal && (fieldVal < retVal))
+			retVal = fieldVal;
 	}
 	return retVal;
 }
 
-#undef ARDEBUG
-
-uint16 SkyAutoRoute::autoRoute(Compact *cpt, uint16 **pSaveRoute) {
-
-	if (!cpt->extCompact)
-		error("SkyAutoRoute::autoRoute: fatal error. cpt->extCompact == NULL");
-	uint16* routeData = (uint16 *)cpt->extCompact->animScratch;
-	uint8* screenGrid = _grid->giveGrid(cpt->screen);
-	screenGrid += GRID_SIZE-4; // all arrays are processed from behind, so make
-	// screenGrid point to the last element of our grid.
+void SkyAutoRoute::clipCoordX(uint16 x, uint8 &blkX, int16 &initX) {
+	if (x < TOP_LEFT_X) {
+		blkX = 0;
+		initX = x - TOP_LEFT_X;
+	} else if (x >= TOP_LEFT_X + GAME_SCREEN_WIDTH) {
+		blkX = (GAME_SCREEN_WIDTH - 1) >> 3;
+		initX = x - (TOP_LEFT_X + GAME_SCREEN_WIDTH);
+	} else {
+		blkX = (x - TOP_LEFT_X) >> 3;
+		initX = 0;
+	}
+}
 
-	uint16 *routeCalc = _routeGrid + (ROUTE_GRID_SIZE >> 1) - ROUTE_GRID_WIDTH - 2;
+void SkyAutoRoute::clipCoordY(uint16 y, uint8 &blkY, int16 &initY) {
+	if (y < TOP_LEFT_Y) {
+		blkY = 0;
+		initY = y - TOP_LEFT_Y;
+	} else if (y >= TOP_LEFT_Y + GAME_SCREEN_HEIGHT) {
+		blkY = (GAME_SCREEN_HEIGHT - 1) >> 3;
+		initY = y - (TOP_LEFT_Y + GAME_SCREEN_WIDTH);
+	} else {
+		blkY = (y - TOP_LEFT_Y) >> 3;
+		initY = 0;
+	}
+}
 
-	uint8 stretch1, stretch2; // bl / bh
-	stretch1 = 0;
-	MegaSet *mega = SkyCompact::getMegaSet(cpt, cpt->extCompact->megaSet);
-	stretch2 = (uint8)(mega->gridWidth & 0xff);
+void SkyAutoRoute::initWalkGrid(uint8 screen, uint8 width) {
 
-	uint16 cnt;
-	//First clear the bottom line and right hand edge of next line
-	for (cnt = 0; cnt < ROUTE_GRID_WIDTH + 1; cnt++)
-		_routeGrid[(ROUTE_GRID_SIZE >> 1) - 1 - cnt] = 0;
+	uint16 *wGridPos;
+	uint8 stretch = 0;
+	uint8 *screenGrid = _grid->giveGrid(screen);
+	screenGrid += GRID_SIZE;
+	wGridPos = _routeGrid + (ROUTE_GRID_SIZE >> 1) - ROUTE_GRID_WIDTH - 2;
 
-	uint16 gridCntX = ROUTE_GRID_WIDTH - 2; // ch
-	uint16 gridCntY = ROUTE_GRID_HEIGHT - 2; // ebp
-	uint16 bitsLeft = 32;
-	uint32 gridData = screenGrid[0] | (screenGrid[1] << 8) |
-		(screenGrid[2] << 16) | (screenGrid[3] << 24);
-	screenGrid -= 4;
-	do {
-		//stretch:
-		uint8 shiftBit = (uint8)gridData&1;
-		gridData >>= 1;
-		if (shiftBit) {
-			//bit_set:
-			routeCalc[0] = 0xFFFF;
-			stretch1 = stretch2; // set up stretch factor
-		} else {
-			if (stretch1) {
-				//still_stretching:
-				stretch1--;
-				routeCalc[0] = 0xFFFF;
-			} else {
-				routeCalc[0] = 0; // this block is free
+    memset(_routeGrid, 0, ROUTE_GRID_SIZE);
+	uint8 bitsLeft = 0; uint32 gridData = 0;
+	for (uint8 gridCntY = 0; gridCntY < ROUTE_GRID_HEIGHT - 2; gridCntY++) {
+		for (uint8 gridCntX = 0; gridCntX < ROUTE_GRID_WIDTH - 2; gridCntX++) {
+			if (!bitsLeft) {
+				screenGrid -= 4;
+				gridData = READ_LE_UINT32(screenGrid);
+				bitsLeft = 32;
 			}
+			if (gridData & 1) {
+				*wGridPos = 0xFFFF; // block is not accessible
+				stretch = width;
+			} else if (stretch) {
+				*wGridPos = 0xFFFF;
+				stretch--;
+			}
+			wGridPos--;
+			bitsLeft--;
+			gridData >>= 1;
 		}
-		// next_stretch:
-		routeCalc--;
-		bitsLeft--;
-		// still bits:
-		gridCntX--;
-		if (gridCntX == 0) {
-			routeCalc--;
-			routeCalc[0] = routeCalc[1] = 0; // do edges
-			routeCalc--;
-			gridCntX = ROUTE_GRID_WIDTH - 2;
-			stretch1 = 0; // clear stretch factor
-			gridCntY--;
-		}
-		if (gridCntY && (!bitsLeft)) {
-			gridData = screenGrid[0] | (screenGrid[1] << 8) |
-				(screenGrid[2] << 16) | (screenGrid[3] << 24);
-			screenGrid -= 4;
-			bitsLeft = 32;
-		}
-	} while(gridCntY);
-	for (cnt = 0; cnt < ROUTE_GRID_WIDTH - 1; cnt++) 
-		_routeGrid[cnt] = 0; // clear top line (right hand edge already done
-	
-	// the grid has been initialised
-
-	// calculate start and end points
-	int16 initX = 0, initY = 0, postX = 0, postY = 0;
-	uint8 initBlockY; // bh
-	uint8 initBlockX; // bl
-	uint8 postBlockY; // ch
-	uint8 postBlockX; // cl
-
-	if (cpt->ycood < TOP_LEFT_Y)  {
-		initY = cpt->ycood - TOP_LEFT_Y;
-		initBlockY = 0;
-	} else if (cpt->ycood - TOP_LEFT_Y >= GAME_SCREEN_HEIGHT) { // no_init_y1
-		initY = cpt->ycood - TOP_LEFT_Y - GAME_SCREEN_HEIGHT;
-		initBlockY = (GAME_SCREEN_HEIGHT - 1) >> 3; // convert to blocks
-	} else { // no_init_y2
-		initBlockY = (cpt->ycood - TOP_LEFT_Y) >> 3; // convert to blocks
-	}
-	
-	if (cpt->xcood < TOP_LEFT_X) {
-		initX = cpt->xcood - TOP_LEFT_X;
-		initBlockX = 0;
-	} else if (cpt->xcood - TOP_LEFT_X >= GAME_SCREEN_WIDTH) { // no_init_x1
-		initX = cpt->xcood - TOP_LEFT_X - (GAME_SCREEN_WIDTH - 1); // -1 to match amiga
-		initBlockX = (GAME_SCREEN_WIDTH - 1) >> 3;
-	} else { // no_init_x2
-		initBlockX = (cpt->xcood - TOP_LEFT_X) >> 3;
-	}
-
-	// destination coords:
-
-	if (cpt->extCompact->arTargetY < TOP_LEFT_Y) {
-		postY = cpt->extCompact->arTargetY - TOP_LEFT_Y;
-		postBlockY = 0;
-	} else if (cpt->extCompact->arTargetY - TOP_LEFT_Y >= GAME_SCREEN_HEIGHT) { // no_post_y1
-		postY = cpt->extCompact->arTargetY - TOP_LEFT_Y - (GAME_SCREEN_HEIGHT - 1);
-		postBlockY = (GAME_SCREEN_HEIGHT - 1) >> 3;
-	} else { // no_post_y2
-		postBlockY = (cpt->extCompact->arTargetY - TOP_LEFT_Y) >> 3;
+		wGridPos -= 2;
+		stretch = 0;
 	}
+}
 
-	if (cpt->extCompact->arTargetX < TOP_LEFT_X) {
-		postX = cpt->extCompact->arTargetX - TOP_LEFT_X;
-		postBlockX = 0;
-	} else if (cpt->extCompact->arTargetX - TOP_LEFT_X >= GAME_SCREEN_WIDTH) {
-		postX = cpt->extCompact->arTargetX - TOP_LEFT_X - (GAME_SCREEN_WIDTH - 1);
-		postBlockX = (GAME_SCREEN_WIDTH - 1) >> 3;
-	} else {
-		postBlockX = (cpt->extCompact->arTargetX - TOP_LEFT_X) >> 3;
-	}
-	if ((postBlockX == initBlockX) && (postBlockY == initBlockY)) {
-		// empty route
-		routeData[0] = 0;
-		return 1;
-	}
+bool SkyAutoRoute::calcWalkGrid(uint8 startX, uint8 startY, uint8 destX, uint8 destY) {
 
-	int32 directionX, directionY;
-	uint8 numLines, numCols; // number of lines / columns to go
-	if (initBlockY > postBlockY) {
+	int16 directionX, directionY;
+	uint8 roiX, roiY; // Rectangle Of Interest in the walk grid
+	if (startY > destY) {
 		directionY = -ROUTE_GRID_WIDTH;
-		numLines = initBlockY;
-	} else { // go_down:
+		roiY = startY;
+	} else {
 		directionY = ROUTE_GRID_WIDTH;
-		numLines = (ROUTE_GRID_HEIGHT-1)-initBlockY;
+		roiY = (ROUTE_GRID_HEIGHT-1) - startY;
 	}
-	if (initBlockX > postBlockX) {
+	if (startX > destX) {
 		directionX = -1;
-		numCols = initBlockX+2;
+		roiX = startX + 2;
 	} else {
 		directionX = 1;
-		numCols = (ROUTE_GRID_WIDTH - 1) - initBlockX;
+		roiX = (ROUTE_GRID_WIDTH - 1) - startX;
 	}
-	// calculate destination address
-	uint16 *routeDestCalc;
-	routeDestCalc = (postBlockY + 1) * ROUTE_GRID_WIDTH + postBlockX + 1 + _routeGrid;
 
-	uint16 *routeSrcCalc;
-	routeSrcCalc = (initBlockY + 1) * ROUTE_GRID_WIDTH + initBlockX + 1 + _routeGrid;
-	routeSrcCalc[0] = 1; //start this one off
-	// means: mark the block we start from as accessible
-#ifdef ARDEBUG
-	uint16 dcnt1, dcnt2;
-	for (dcnt1 = 0; dcnt1 < ROUTE_GRID_HEIGHT; dcnt1++) {
-		for (dcnt2 = 0; dcnt2 < ROUTE_GRID_WIDTH; dcnt2++) {
-			if (!_routeGrid[dcnt1*ROUTE_GRID_WIDTH + dcnt2]) printf("_"); 
-			else if (_routeGrid[dcnt1*ROUTE_GRID_WIDTH + dcnt2] == 1) printf("S");
-			else printf("X");
-		}
-		printf("\n");
-	}
-	getchar();
-#endif
+	uint16 *walkDest  = _routeGrid + (destY + 1) * ROUTE_GRID_WIDTH + destX + 1;
+	uint16 *walkStart = _routeGrid + (startY + 1) * ROUTE_GRID_WIDTH + startX + 1;
+	*walkStart = 1;
 
 	// if we are on the edge, move diagonally from start
-	if (numLines < ROUTE_GRID_HEIGHT-3)
-		routeSrcCalc -= directionY;
+	if (roiY < ROUTE_GRID_HEIGHT-3)
+		walkStart -= directionY;
 
-	if (numCols < ROUTE_GRID_WIDTH-2)
-		routeSrcCalc -= directionX;
+	if (roiX < ROUTE_GRID_WIDTH-2)
+		walkStart -= directionX;
+    
+	bool gridChanged = true;
+	bool foundRoute = false;
 
-	if (routeDestCalc[0]) {
-		// If destination is a wall then we have no route
-		// By the way, we could improve this algorithm by moving as close to the
-		// wall as possible. The original pathfinding of SKY sucked, if I remember correctly
-		return 2;
-	}
-	uint8 cnty; // ch
-	uint8 cntx; // cl
-	// numLines = dh, numCols = dl
-	uint16 blockRet;
-	bool gridChanged, foundRoute;
-	do { // wallow_y
+	while ((!foundRoute) && gridChanged) {
 		gridChanged = false;
-		cnty = numLines;
-		uint16 *yPushedSrc = routeSrcCalc;
-		do { // wallow_x
-			cntx = numCols;
-			uint16 *xPushedSrc = routeSrcCalc;
-			do { // wallow
-				if (!routeSrcCalc[0]) {
-					// block wasn't yet done
-					blockRet = checkBlock(routeSrcCalc);
-					if (blockRet != 0xFFFF) {
-						// this block is accessible
-						routeSrcCalc[0] = blockRet+1;
+		uint16 *yWalkCalc = walkStart;
+		for (uint8 cnty = 0; cnty < roiY; cnty++) {
+			uint16 *xWalkCalc = yWalkCalc;
+			for (uint8 cntx = 0; cntx < roiX; cntx++) {
+				if (!*xWalkCalc) { // block wasn't done, yet
+					uint16 blockRet = checkBlock(xWalkCalc);
+					if (blockRet < 0xFFFF) {
+						*xWalkCalc = blockRet + 1;
 						gridChanged = true;
 					}
 				}
-				routeSrcCalc += directionX;
-				cntx--;
-			} while (cntx);
-			routeSrcCalc = xPushedSrc + directionY;
-			cnty--;
-		} while (cnty);
-		routeSrcCalc = yPushedSrc;
-
-		foundRoute = false;
-		if (!routeDestCalc[0]) {
-			// we have done a section, see if we want to shift backwards (what?)
-			if (numLines < ROUTE_GRID_HEIGHT - 4) {
-				routeSrcCalc -= directionY;
-				numLines++;
-			}
-			if (numCols < ROUTE_GRID_WIDTH - 4) {
-				routeSrcCalc -= directionX;
-				numCols++;
+                xWalkCalc += directionX;
 			}
-		} else foundRoute = true;			
-	} while ((!foundRoute) && gridChanged);
-#ifdef ARDEBUG
-	for (dcnt1 = 0; dcnt1 < ROUTE_GRID_HEIGHT; dcnt1++) {
-		for (dcnt2 = 0; dcnt2 < ROUTE_GRID_WIDTH; dcnt2++) {
-            printf(" %02X",_routeGrid[dcnt1*ROUTE_GRID_WIDTH + dcnt2]&0xFF);
+			yWalkCalc += directionY;
 		}
-		printf("\n");
-	}
-#endif
-	if (!routeDestCalc[0]) {
-		// no route exists from routeSrc to routeDest
-		return 2;
-	}
-	// ok, we know now that it's possible to get from the start position to the desired
-	// destination. Let's see how.
-	uint16 *saveRoute = routeData + (ROUTE_SPACE >> 1) - 1; // route_space is given in bytes so >> 1
-	saveRoute[0] = 0; // route is null terminated
-	uint16 lastVal;
-	lastVal = routeDestCalc[0];
-	lastVal--;
-	bool routeDone = false;
-	do {
-		// check_dir:
-		if (lastVal == (routeDestCalc-1)[0]) {
-			// look_left
-			saveRoute -= 2;
-			saveRoute[1] = RIGHTY;
-			saveRoute[0] = 0;
-			while ((lastVal == (routeDestCalc-1)[0]) && (!routeDone)) {
-				routeDestCalc--; // keep checking left
-				saveRoute[0] += WALK_JUMP;
-#ifdef ARDEBUG
-				printf("left\n");
-#endif
-				lastVal--;
-				if (lastVal == 0) routeDone = true;
-			}
-		} else if (lastVal == routeDestCalc[1]) {
-			// look_right
-			saveRoute -= 2;
-			saveRoute[1] = LEFTY;
-			saveRoute[0] = 0;
-			while ((lastVal == routeDestCalc[1]) && (!routeDone)) {
-				routeDestCalc++; // keep checking right
-				saveRoute[0] += WALK_JUMP;
-#ifdef ARDEBUG
-				printf("right\n");
-#endif
-				lastVal--;
-				if (lastVal == 0) routeDone = true;
+		if (*walkDest) { // okay, finished
+			foundRoute = true;
+		} else { // we couldn't find the route, let's extend the ROI
+			if (roiY < ROUTE_GRID_HEIGHT - 4) {
+				walkStart -= directionY;
+				roiY++;
 			}
-		} else if (lastVal == (routeDestCalc - ROUTE_GRID_WIDTH)[0]) {
-			// look_up
-			saveRoute -= 2;
-			saveRoute[1] = DOWNY;
-			saveRoute[0] = 0;
-			while ((lastVal == (routeDestCalc - ROUTE_GRID_WIDTH)[0]) && (!routeDone)) {
-				routeDestCalc -= ROUTE_GRID_WIDTH; // keep checking up
-				saveRoute[0] += WALK_JUMP;
-#ifdef ARDEBUG
-				printf("up\n");
-#endif
-				lastVal--;
-				if (lastVal == 0) routeDone = true;
+			if (roiX < ROUTE_GRID_WIDTH - 4) {
+				walkStart -= directionX;
+				roiX++;
 			}
-		} else if (lastVal == (routeDestCalc + ROUTE_GRID_WIDTH)[0]) {
-			// look_down
-			saveRoute -= 2;
-			saveRoute[1] = UPY;
-			saveRoute[0] = 0;
-			while ((lastVal == (routeDestCalc + ROUTE_GRID_WIDTH)[0]) && (!routeDone)) {
-				routeDestCalc += ROUTE_GRID_WIDTH; // keep checking right
-				saveRoute[0] += WALK_JUMP;
-#ifdef ARDEBUG
-				printf("down\n");
-#endif
-				lastVal--;
-				if (lastVal == 0) routeDone = true;
+		}
+	}
+	return foundRoute;
+}
+
+uint16 *SkyAutoRoute::makeRouteData(uint8 startX, uint8 startY, uint8 destX, uint8 destY) {
+
+	memset(_routeBuf, 0, ROUTE_SPACE);
+
+	uint16 *routePos = _routeGrid + (destY + 1) * ROUTE_GRID_WIDTH + destX + 1;
+	uint16 *dataTrg = _routeBuf + (ROUTE_SPACE >> 1) - 2;
+
+	uint16 lastVal = (*routePos) - 1;
+	while (lastVal) { // lastVal == 0 means route is done.
+		dataTrg -= 2;
+		
+		int16 walkDirection = 0;
+		for (uint8 cnt = 0; cnt < 4; cnt++)
+			if (lastVal == *(routePos + _routeDirections[cnt])) {
+				*(dataTrg + 1) = _logicCommands[cnt];
+				walkDirection = _routeDirections[cnt];
+				break;
 			}
-		} else {
-			error("AutoRoute:: Can't find way backwards through _routeGrid");
+
+		if (!walkDirection)
+			error("makeRouteData:: can't find way through walkGrid (pos %d)", lastVal);
+		while (lastVal && (lastVal == *(routePos + walkDirection))) {
+            *dataTrg += WALK_JUMP;
+			lastVal--;
+			routePos += walkDirection;
 		}
-	} while (!routeDone);
-#ifdef ARDEBUG
-	getchar();
-#endif
-	// the route is done. if there was an initial x/y movement tag it onto the start
-	if (initX < 0) {
-        saveRoute -= 2;
-		saveRoute[1] = RIGHTY;
-		saveRoute[0] = ((-initX) + 7) & 0xFFF8;
-	} else if (initX > 0) {
-		saveRoute -= 2;
-		saveRoute[1] = LEFTY;
-		saveRoute[0] = (initX + 7) & 0xFFF8;
 	}
-	// I wonder why initY isn't checked
-	// saveRoute should now point to routeData
-	if (routeData > saveRoute) error("Autoroute: Internal pointer error! routeData overflow.");
-	*pSaveRoute = saveRoute;
-	return 1;
+    return dataTrg;
+}
+
+uint16 *SkyAutoRoute::checkInitMove(uint16 *data, int16 initStaX) {
+	if (initStaX < 0) {
+		data -= 2;
+		*(data + 1) = RIGHTY;
+		*data = ((-initStaX) + 7) & 0xFFF8;
+	} else if (initStaX > 0) {
+		data -= 2;
+		*(data + 1) = LEFTY;
+		*data = (initStaX + 7) & 0xFFF8;
+	}
+	return data;
+}
+
+uint16 SkyAutoRoute::autoRoute(Compact *cpt) {
+
+	uint8 cptScreen = (uint8)cpt->screen;
+	uint8 cptWidth = (uint8)SkyCompact::getMegaSet(cpt, cpt->extCompact->megaSet)->gridWidth;
+	initWalkGrid(cptScreen, cptWidth);
+
+	uint8 startX, startY, destX, destY;
+	int16 initStaX, initStaY, initDestX, initDestY;
+
+	clipCoordX(cpt->xcood, startX, initStaX);
+	clipCoordY(cpt->ycood, startY, initStaY);
+	clipCoordX(cpt->extCompact->arTargetX, destX, initDestX);
+	clipCoordY(cpt->extCompact->arTargetY, destY, initDestY);
+
+	((uint16*)cpt->extCompact->animScratch)[0] = 0;
+	if ((startX == destX) && (startY == destY))
+		return 2;
+
+	if (_routeGrid[(destY + 1) * ROUTE_GRID_WIDTH + destX + 1])
+		return 1; // AR destination is an unaccessible block
+
+	if (!calcWalkGrid(startX, startY, destX, destY))
+		return 1; // can't find route to block
+
+	uint16 *routeData = makeRouteData(startX, startY, destX, destY);
+	// the route is done.
+	// if there was an initial x movement (due to clipping) tag it onto the start
+	routeData = checkInitMove(routeData, initStaX);
+
+    uint8 cnt = 0;
+	do {
+		((uint16*)cpt->extCompact->animScratch)[cnt]     = routeData[cnt];
+		((uint16*)cpt->extCompact->animScratch)[cnt + 1] = routeData[cnt + 1];
+		cnt += 2;
+	} while (routeData[cnt - 2]);
+	return 0;
 }
 

Index: autoroute.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/autoroute.h,v
retrieving revision 1.5
retrieving revision 1.5.4.1
diff -u -d -r1.5 -r1.5.4.1
--- autoroute.h	29 Apr 2003 14:34:19 -0000	1.5
+++ autoroute.h	4 Aug 2003 21:18:02 -0000	1.5.4.1
@@ -35,11 +35,20 @@
 public:
 	SkyAutoRoute(SkyGrid *pGrid);
 	~SkyAutoRoute(void);
-	uint16 autoRoute(Compact *cpt, uint16 **pSaveRoute);
+	uint16 autoRoute(Compact *cpt);
 private:
 	uint16 checkBlock(uint16 *blockPos);
+	void clipCoordX(uint16 x, uint8 &blkX, int16 &initX);
+	void clipCoordY(uint16 y, uint8 &blkY, int16 &initY);
+    void initWalkGrid(uint8 screen, uint8 width);
+	bool calcWalkGrid(uint8 startX, uint8 startY, uint8 destX, uint8 destY);
+    uint16 *makeRouteData(uint8 startX, uint8 startY, uint8 destX, uint8 destY);
+	uint16 *checkInitMove(uint16 *data, int16 initStaX);
 	SkyGrid *_grid;
 	uint16 *_routeGrid;
+	uint16 *_routeBuf;
+	static const int16 _routeDirections[4];
+    static const uint16 _logicCommands[4];
 };
 
 #endif // AUTOROUTE_H

Index: compact.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/compact.cpp,v
retrieving revision 1.15
retrieving revision 1.15.2.1
diff -u -d -r1.15 -r1.15.2.1
--- compact.cpp	7 Jul 2003 00:14:16 -0000	1.15
+++ compact.cpp	4 Aug 2003 21:18:02 -0000	1.15.2.1
@@ -60,7 +60,45 @@
 #define MK32_A5(type, item) MK32(type, item[0]), MK32(type, item[1]), \
 	MK32(type, item[2]), MK32(type, item[3]), MK32(type, item[4])
 
+namespace SkyTalkAnims {
+	extern bool animTalkTableIsPointer[];
+	extern uint16 animTalkTableVal[];
+	extern void *animTalkTablePtr[];
+};
+
 namespace SkyCompact {
+
+uint16 *getGrafixPtr(Compact *cpt) {
+	uint16 *buf;
+	switch (cpt->grafixProg.ptrType) {
+		case PTR_NULL:
+			return NULL;
+		case AUTOROUTE:
+			if (!cpt->extCompact)
+				error("::getGrafixPtr: request for AR pointer, extCompact is NULL, though.");
+			return (cpt->extCompact->animScratch + cpt->grafixProg.pos);
+		case COMPACT:
+			buf = (uint16*)SkyState::fetchCompact(cpt->grafixProg.ptrTarget);
+			if (buf == NULL)
+				error("::getGrafixPtr: request for cpt %d pointer. It's NULL.", cpt->grafixProg.ptrTarget);
+			return (buf + cpt->grafixProg.pos);
+		case COMPACTELEM:
+			buf = *(uint16 **)SkyCompact::getCompactElem(cpt, cpt->grafixProg.ptrTarget);
+			if (buf == NULL)
+				error("::getGrafixPtr: request for elem ptr %d. It's NULL.", cpt->grafixProg.ptrTarget);
+			return buf + cpt->grafixProg.pos;
+		case TALKTABLE:
+			buf = (uint16 *)SkyTalkAnims::animTalkTablePtr[cpt->grafixProg.ptrTarget];
+			if (buf == NULL)
+				warning("::getGrafixPtr: request for TT ptr %d -> NULL", cpt->grafixProg.ptrTarget);
+			return buf + cpt->grafixProg.pos;
+		case EVIL_PTR:
+			return (cpt->grafixProg.evilPtr + cpt->grafixProg.pos);
+		default:
+			error("::getGrafixPtr: unknown grafixProg type for Compact cpt");
+	}
+	return NULL; // never reached
+}
 
 /**
  * Returns the n'th mega set specified by \a megaSet from Compact \a cpt.

Index: compact.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/compact.h,v
retrieving revision 1.8
retrieving revision 1.8.2.1
diff -u -d -r1.8 -r1.8.2.1
--- compact.h	3 Jul 2003 17:17:32 -0000	1.8
+++ compact.h	4 Aug 2003 21:18:02 -0000	1.8.2.1
@@ -30,6 +30,7 @@
 	MegaSet *getMegaSet(Compact *cpt, uint16 megaSet);
 	uint16 **getTurnTable(Compact *cpt, uint16 megaSet, uint16 dir);
 	uint16 *getSub(Compact *cpt, uint16 mode);
+	uint16 *getGrafixPtr(Compact *cpt);
 	void *getCompactElem(Compact *cpt, uint32 off);
 	void patchFor288(void);
 
@@ -3232,24 +3233,25 @@
 	extern uint16 retina_scan_cdt[];
 	extern Compact forklift_cpt;
 	extern void *data_0[];
-	extern uint8 babs_auto[];
-	extern uint8 burke_auto[];
-	extern uint8 dan_auto[];
-	extern uint8 foreman_auto[];
-	extern uint8 full_ss_auto[];
-	extern uint8 gal_auto[];
-	extern uint8 jobs_auto[];
-	extern uint8 joey_auto[];
-	extern uint8 ken_auto[];
-	extern uint8 lamb_auto[];
-	extern uint8 loader_auto[];
-	extern uint8 medi_auto[];
-	extern uint8 monitor_auto[];
-	extern uint8 radman_auto[];
-	extern uint8 shades_auto[];
-	extern uint8 spu_auto[];
-	extern uint8 ss_auto[];
-	extern uint8 wit_auto[];
+	extern uint16 babs_auto[];
+	extern uint16 burke_auto[];
+	extern uint16 dan_auto[];
+	extern uint16 foreman_auto[];
+	extern uint16 full_ss_auto[];
+	extern uint16 gal_auto[];
+	extern uint16 jobs_auto[];
+	extern uint16 joey_auto[];
+	extern uint16 ken_auto[];
+	extern uint16 lamb_auto[];
+	extern uint16 loader_auto[];
+	extern uint16 medi_auto[];
+	extern uint16 monitor_auto[];
+	extern uint16 radman_auto[];
+	extern uint16 shades_auto[];
+	extern uint16 spu_auto[];
+	extern uint16 ss_auto[];
+	extern uint16 wit_auto[];
+	extern uint16 minif_auto[];
 };
 
 #endif

Index: control.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/control.cpp,v
retrieving revision 1.50.2.2
retrieving revision 1.50.2.3
diff -u -d -r1.50.2.2 -r1.50.2.3
--- control.cpp	1 Aug 2003 15:32:21 -0000	1.50.2.2
+++ control.cpp	4 Aug 2003 21:18:02 -0000	1.50.2.3
@@ -1117,6 +1117,13 @@
 	return GAME_SAVED;
 }
 
+bool SkyControl::canSaveV5(void) {
+	for (uint16 cnt = 0; cnt < ARRAYSIZE(_saveLoadCpts); cnt++)
+		if (_saveLoadCpts[cnt]->grafixProg.ptrType == EVIL_PTR)
+			return false;
+	return true;
+}
+
 #define STOSD(ptr, val) { *(uint32 *)(ptr) = TO_LE_32(val); (ptr) += 4; }
 #define STOSW(ptr, val) { *(uint16 *)(ptr) = TO_LE_16(val); (ptr) += 2; }
 
@@ -1130,7 +1137,7 @@
 
 void SkyControl::stosGrafStr(uint8 **destPos, Compact *cpt) {
 	uint16 strLen = 0;
-	uint16 *src = cpt->grafixProg;
+	uint16 *src = cpt->grafixProg.evilPtr;
 	if ((cpt->logic == L_AR_ANIM) || (cpt->logic == L_TURNING)) {
 		if ((!src[0]) && (!src[2])) {
 			strLen = 3;
@@ -1157,8 +1164,13 @@
 
 void SkyControl::stosStr(uint8 **destPos, Compact *cpt, uint16 type) {
 	uint16 strLen = 0;
-	if (type & SAVE_GRAFX)
+	if (type & EVIL_GRAFX)
 		stosGrafStr(destPos, cpt);
+	else if (type & SAVE_GRAFX) {
+		STOSW(*destPos, cpt->grafixProg.ptrType);
+		STOSW(*destPos, cpt->grafixProg.ptrTarget);
+		STOSW(*destPos, cpt->grafixProg.pos);
+	}
 
 	if (type & SAVE_TURNP) {
 		uint16 *src = cpt->extCompact->turnProg;
@@ -1182,7 +1194,10 @@
 		if (cpt->extCompact->megaSet3) saveType |= SAVE_MEGA3;
 		if (cpt->extCompact->turnProg) saveType |= SAVE_TURNP;
 	}
-	if (cpt->grafixProg) saveType |= SAVE_GRAFX;
+	if (cpt->grafixProg.ptrType != PTR_NULL)
+		saveType |= SAVE_GRAFX;
+	if (cpt->grafixProg.ptrType == EVIL_PTR)
+		saveType |= EVIL_GRAFX;
 
 	STOSW(*destPos, saveType);
 
@@ -1259,7 +1274,13 @@
 	uint32 cnt;
 	memset(destBuf, 0, 4); // space for data size
 	uint8 *destPos = destBuf + 4;
-	STOSD(destPos, SAVE_FILE_REVISION);
+	if (canSaveV5()) {
+		debug(1, "Going up to V5");
+		STOSD(destPos, 5);
+	} else {
+		debug(1, "Saving in compatibility mode, evil ptrs left");
+		STOSD(destPos, SAVE_FILE_REVISION);
+	}
 
 	STOSD(destPos, SkyState::_systemVars.gameVersion);
 	STOSW(destPos, _skySound->_saveSounds[0]);
@@ -1279,6 +1300,11 @@
 	for (cnt = 0; cnt < ARRAYSIZE(_saveLoadCpts); cnt++)
 		stosCompact(&destPos, _saveLoadCpts[cnt]);
 
+	for (cnt = 0; cnt < ARRAYSIZE(_saveLoadARs); cnt++)
+		for (uint8 elemCnt = 0; elemCnt < 32; elemCnt++) {
+			STOSW(destPos, _saveLoadARs[cnt][elemCnt]);
+		}
+
 	for (cnt = 0; cnt < 3; cnt++)
 		STOSW(destPos, SkyCompact::park_table[cnt]);
 
@@ -1323,7 +1349,7 @@
 	// anims, stands, turnTable
 }
 
-void SkyControl::lodsCompact(uint8 **srcPos, Compact *cpt) {
+void SkyControl::lodsCompact(uint8 **srcPos, Compact *cpt, uint32 saveRev) {
 
 	uint16 saveType, cnt;
 	LODSW(*srcPos, saveType);
@@ -1338,7 +1364,7 @@
 	if ((saveType & SAVE_MEGA3) && (cpt->extCompact->megaSet3 == NULL))
 		error("Can't restore! SaveData is SAVE_MEGA3 for Compact");
 
-	if (saveType & SAVE_GRAFX) {
+	if ((saveType & EVIL_GRAFX) || ((saveRev <= 3) && (saveType & SAVE_GRAFX))) {
 		uint16 grafxLen;
 		LODSW(*srcPos, grafxLen);
 		//cpt->grafixProg = (uint16 *)malloc(grafxLen << 1);
@@ -1348,14 +1374,27 @@
 				 (as all grafixProg data is 0-terminated), so if this condition really can
 				 occur, it should only lead to small graphic glitches, not to crashes.*/
 
-		cpt->grafixProg = (uint16 *)malloc((grafxLen << 1) + 20);
-		memset(cpt->grafixProg + grafxLen, 0, 20); 
-		appendMemList(cpt->grafixProg);
+		cpt->grafixProg.evilPtr = (uint16 *)malloc((grafxLen << 1) + 20);
+		cpt->grafixProg.ptrType = EVIL_PTR;
+		cpt->grafixProg.pos     = 0;
+		memset(cpt->grafixProg.evilPtr + grafxLen, 0, 20); 
+		appendMemList(cpt->grafixProg.evilPtr);
 		for (cnt = 0; cnt < grafxLen; cnt++) {
-			LODSW(*srcPos, cpt->grafixProg[cnt]);
+			LODSW(*srcPos, cpt->grafixProg.evilPtr[cnt]);
 		}
-	} else
-		cpt->grafixProg = NULL;
+	} else if (saveType & SAVE_GRAFX) {
+		uint16 tmp;
+		LODSW(*srcPos, tmp);
+		cpt->grafixProg.ptrType = (uint8)tmp;
+		LODSW(*srcPos, cpt->grafixProg.ptrTarget);
+		LODSW(*srcPos, cpt->grafixProg.pos);
+		cpt->grafixProg.evilPtr = NULL;
+	} else {
+		cpt->grafixProg.ptrType = PTR_NULL;
+		cpt->grafixProg.ptrTarget = 0;
+		cpt->grafixProg.pos = 0;
+		cpt->grafixProg.evilPtr = NULL;
+	}
 
 	if (saveType & SAVE_TURNP) {
 		uint16 turnLen;
@@ -1446,7 +1485,7 @@
 
 	LODSD(srcPos, size);
 	LODSD(srcPos, saveRev);
-	if (saveRev > SAVE_FILE_REVISION) {
+	if (saveRev > 5) {
 		warning("Unknown save file revision (%d)",saveRev);
 		return RESTORE_FAILED;
 	}
@@ -1482,7 +1521,14 @@
 		LODSD(srcPos, reloadList[cnt]);
 
 	for (cnt = 0; cnt < ARRAYSIZE(_saveLoadCpts); cnt++)
-		lodsCompact(&srcPos, _saveLoadCpts[cnt]);
+		lodsCompact(&srcPos, _saveLoadCpts[cnt], saveRev);
+
+	if (saveRev >= 4) {
+		for (cnt = 0; cnt < ARRAYSIZE(_saveLoadARs); cnt++)
+			for (uint8 elemCnt = 0; elemCnt < 32; elemCnt++) {
+				LODSW(srcPos, _saveLoadARs[cnt][elemCnt]);
+			}
+	}
 
 	for (cnt = 0; cnt < 3; cnt++)
 		LODSW(srcPos, SkyCompact::park_table[cnt]);
@@ -1630,8 +1676,8 @@
 	return outBuf;
 }
 
-void SkyControl::applyDiff(uint16 *data, uint16 *diffData) {
-	for (uint16 cnt = 0; cnt < 206; cnt++) {
+void SkyControl::applyDiff(uint16 *data, uint16 *diffData, uint16 len) {
+	for (uint16 cnt = 0; cnt < len; cnt++) {
 		data += READ_LE_UINT16(diffData);
 		diffData++;
 		*data = *diffData;
@@ -1644,24 +1690,23 @@
 	if (SkyState::_systemVars.gameVersion <= 267)
 		return; // no restart for floppy demo
 
-	uint16 *resetData;
-	if (SkyState::isCDVersion())
-		resetData = lz77decode((uint16 *)_resetDataCd);
-	else {
-		resetData = lz77decode((uint16 *)_resetData288);
-		switch (SkyState::_systemVars.gameVersion) {
-			case 303:
-                applyDiff(resetData, (uint16*)_resetDiff303);
-				break;
-			case 331:
-				applyDiff(resetData, (uint16*)_resetDiff331);
-				break;
-			case 348:
-				applyDiff(resetData, (uint16*)_resetDiff348);
-				break;
-			default:
-				break;
-		}
+	uint16 *resetData = lz77decode((uint16 *)_resetData288);
+	switch (SkyState::_systemVars.gameVersion) {
+		case 303:
+			applyDiff(resetData, (uint16*)_resetDiff303, 206);
+			break;
+		case 331:
+			applyDiff(resetData, (uint16*)_resetDiff331, 206);
+			break;
+		case 348:
+			applyDiff(resetData, (uint16*)_resetDiff348, 206);
+			break;
+		case 365:
+		case 368:
+		case 372:
+			applyDiff(resetData, (uint16*)_resetDiffCd, 214);
+		default:
+			break;
 	}
 	// ok, we finally have our savedata
 

Index: control.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/control.h,v
retrieving revision 1.21.2.2
retrieving revision 1.21.2.3
diff -u -d -r1.21.2.2 -r1.21.2.3
--- control.h	1 Aug 2003 15:32:21 -0000	1.21.2.2
+++ control.h	4 Aug 2003 21:18:02 -0000	1.21.2.3
@@ -111,8 +111,9 @@
 #define SAVE_MEGA3	16
 #define SAVE_GRAFX	32
 #define SAVE_TURNP	64
+#define EVIL_GRAFX	128
 
-#define SAVE_FILE_REVISION 3
+#define SAVE_FILE_REVISION 4
 
 struct AllocedMem {
 	uint16 *mem;
@@ -208,6 +209,7 @@
 
 	uint16 _selectedGame;
 	uint16 saveGameToFile(void);
+	bool canSaveV5(void);
 	void stosMegaSet(uint8 **destPos, MegaSet *mega);
 	void stosCompact(uint8 **destPos, Compact *cpt);
 	void stosGrafStr(uint8 **destPos, Compact *cpt);
@@ -217,19 +219,20 @@
 	bool autoSaveExists(void);
 	uint16 restoreGameFromFile(bool autoSave);
 	void lodsMegaSet(uint8 **srcPos, MegaSet *mega);
-	void lodsCompact(uint8 **srcPos, Compact *cpt);
+	void lodsCompact(uint8 **srcPos, Compact *cpt, uint32 saveRev);
 	void lodsStr(uint8 **srcPos, uint16 *src);
 	uint16 parseSaveData(uint8 *srcBuf);
 
 	const char *_savePath;
 	uint16 *lz77decode(uint16 *data);
-	void applyDiff(uint16 *data, uint16 *diffData);
+	void applyDiff(uint16 *data, uint16 *diffData, uint16 len);
 	static Compact *_saveLoadCpts[833]; //-----------------
-	static uint8 _resetData288[0x39F2];
+	static uint16 *_saveLoadARs[19];
+	static uint8 _resetData288[0x39B8];
 	static uint8 _resetDiff303[824];    // moved to sky/compacts/savedata.cpp
 	static uint8 _resetDiff331[824];
 	static uint8 _resetDiff348[824];
-	static uint8 _resetDataCd[0x3FDC];  //-----------------
+	static uint8 _resetDiffCd[856];  //-----------------
 
 	AllocedMem *_memListRoot;
 	void appendMemList(uint16 *pMem);

Index: logic.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/logic.cpp,v
retrieving revision 1.127.2.1
retrieving revision 1.127.2.2
diff -u -d -r1.127.2.1 -r1.127.2.2
--- logic.cpp	30 Jul 2003 21:38:46 -0000	1.127.2.1
+++ logic.cpp	4 Aug 2003 21:18:02 -0000	1.127.2.2
@@ -144,20 +144,16 @@
 }
 
 void SkyLogic::autoRoute() {
-	uint16 *route = 0;
-	uint16 ret = _skyAutoRoute->autoRoute(_compact, &route);
-
-	_compact->logic = L_SCRIPT; // continue the script
 
-	if (ret != 1) // route failed
-		_compact->downFlag = 1; // return fail to script
-	else if (!route) // zero route
-		_compact->downFlag = 2; // return fail to script
-	else {
-		_compact->grafixProg = route; // put graphic prog in
-		_compact->downFlag = 0; // route ok
+	_compact->downFlag = _skyAutoRoute->autoRoute(_compact);
+	if (!_compact->downFlag) { // route ok
+		_compact->grafixProg.pos = 0;
+		_compact->grafixProg.ptrTarget = 0;
+		_compact->grafixProg.ptrType = AUTOROUTE;
 	}
 
+	_compact->logic = L_SCRIPT; // continue the script
+
 	logicScript();
 	return;
 }
@@ -296,10 +292,12 @@
 	/// Extension of arAnim()
 	_compact->extCompact->waitingFor = 0; // clear possible zero-zero skip
 
-	uint16 *sequence = _compact->grafixProg;
+	//uint16 *sequence = _compact->grafixProg;
+	uint16 *sequence = SkyCompact::getGrafixPtr(_compact);
 	if (!*sequence) {
 		// ok, move to new anim segment
 		sequence += 2;
+		_compact->grafixProg.pos += 2;
 		if (!*sequence) { // end of route?
 			// ok, sequence has finished
 
@@ -312,7 +310,6 @@
 			return;
 		}
 
-		_compact->grafixProg = sequence;
 		_compact->extCompact->arAnimIndex = 0; // reset position
 	}
 
@@ -368,9 +365,11 @@
 void SkyLogic::anim() {
 	/// Follow an animation sequence
 
-	uint16 *grafixProg = _compact->grafixProg;
+	//uint16 *grafixProg = _compact->grafixProg;
+	uint16 *grafixProg = SkyCompact::getGrafixPtr(_compact);
 
 	while (*grafixProg) {
+		_compact->grafixProg.pos += 3; // all types are 3 words.
 		if (*grafixProg == LF_START_FX) { // do fx
 			grafixProg++;
 			uint16 sound = *grafixProg++;
@@ -389,7 +388,6 @@
 			_compact->ycood = *grafixProg++;
 
 			_compact->frame = *grafixProg++ | _compact->offset;
-			_compact->grafixProg = grafixProg;
 			return;
 		}
 	}
@@ -493,9 +491,9 @@
 					
 					SkyState::fetchCompact(_compact->extCompact->spTextId)->status = 0;
 				}
-				if (_compact->grafixProg) {
+				if (SkyCompact::getGrafixPtr(_compact)) {
 					_compact->frame = _compact->getToFlag; // set character to stand
-					_compact->grafixProg = NULL;
+					_compact->grafixProg.ptrType = PTR_NULL;
 				}
 
 				_compact->logic = L_SCRIPT;
@@ -510,16 +508,17 @@
 
 		_compact->logic = L_SCRIPT; // restart character control
 
-		if (_compact->grafixProg) {
+		if (SkyCompact::getGrafixPtr(_compact)) {
 			_compact->frame = _compact->getToFlag; // set character to stand
-			_compact->grafixProg = 0;
+			_compact->grafixProg.ptrType = PTR_NULL;
 		}
 
 		logicScript();
 		return;
 	}
 
-	uint16 *graphixProg = _compact->grafixProg; // no anim file?
+	//uint16 *graphixProg = _compact->grafixProg; // no anim file?
+	uint16 *graphixProg = SkyCompact::getGrafixPtr(_compact);
 	if (graphixProg) {
 		if ((*graphixProg) && ((_compact->extCompact->spTime != 3) || (!_skySound->speechFinished()))) {
 			// we will force the animation to finish 3 game cycles
@@ -527,11 +526,11 @@
 
 			_compact->frame = *(graphixProg + 2) + _compact->offset;
 			graphixProg += 3;
-			_compact->grafixProg = graphixProg;
+			_compact->grafixProg.pos += 3;
 		} else {
 			// we ran out of frames or finished speech, let actor stand still.
 			_compact->frame = _compact->getToFlag;
-			_compact->grafixProg = 0;
+			_compact->grafixProg.ptrType = PTR_NULL;
 		}
 	}
 
@@ -633,10 +632,11 @@
 void SkyLogic::simpleAnim() {
 	/// follow an animation sequence module whilst ignoring the coordinate data
 
-	uint16 *grafixProg = _compact->grafixProg;
+	uint16 *grafixProg = SkyCompact::getGrafixPtr(_compact);
 
 	// *grafix_prog: command
 	while (*grafixProg) {
+		_compact->grafixProg.pos += 3;
 		if (*grafixProg != SEND_SYNC) {
 			grafixProg++;
 			grafixProg++; // skip coordinates
@@ -647,8 +647,6 @@
 			else
 				_compact->frame = *grafixProg + _compact->offset;
 
-			grafixProg++;
-			_compact->grafixProg = grafixProg;
 			return;
 		}
 
@@ -1496,12 +1494,16 @@
 bool SkyLogic::fnSetToStand(uint32 a, uint32 b, uint32 c) {
 	_compact->mood = 1; // high level stood still
 
-	uint16 *standList = *(uint16 **)SkyCompact::getCompactElem(_compact, C_STAND_UP
-			+ _compact->extCompact->megaSet + _compact->extCompact->dir * 4); 
+	_compact->grafixProg.ptrType = COMPACTELEM;
+	_compact->grafixProg.pos = 0;
+	_compact->grafixProg.ptrTarget = 
+		 C_STAND_UP	+ _compact->extCompact->megaSet + _compact->extCompact->dir * 4;
 
-	_compact->offset = *standList++; // get frames offset
-	_compact->grafixProg = standList;
+	uint16 *standList = SkyCompact::getGrafixPtr(_compact);
+
+	_compact->offset = *standList; // get frames offset
 	_compact->logic = L_SIMPLE_MOD;
+	_compact->grafixProg.pos++;
 	simpleAnim();
 	return false; // drop out of script
 }
@@ -1643,7 +1645,7 @@
 	c is base of mini table within anim_talk_table */
 
 #ifdef __DC__
-	__builtin_alloca(4); // Works around a gcc bug
+	__builtin_alloca(4); // Works around a gcc bug (wrong-code/11736)
 #endif
 
 	_compact->flag = (uint16)a;
@@ -1988,32 +1990,48 @@
 }
 
 bool SkyLogic::fnRunAnimMod(uint32 animNo, uint32 b, uint32 c) {
-	uint16 *animation = (uint16 *)SkyState::fetchCompact(animNo);
-	uint16 sprite = *animation++; // get sprite set
-	_compact->offset = sprite;
-	_compact->grafixProg = animation;
+	_compact->grafixProg.ptrType = COMPACT;
+	_compact->grafixProg.ptrTarget = (uint16)animNo;
+	_compact->grafixProg.pos = 0;
+	
+	//uint16 *animation = (uint16 *)SkyState::fetchCompact(animNo);
+	//uint16 sprite = *animation++; // get sprite set
+	//_compact->offset = sprite;
+	_compact->offset = *SkyCompact::getGrafixPtr(_compact);
+	//_compact->grafixProg = animation;
+	_compact->grafixProg.pos++;
 	_compact->logic = L_MOD_ANIMATE;
 	anim();
 	return false; // drop from script
 }
 
 bool SkyLogic::fnSimpleMod(uint32 animSeqNo, uint32 b, uint32 c) {
-	uint16 *animSeq = (uint16 *)SkyState::fetchCompact(animSeqNo);
 
-	_compact->offset = *animSeq++;
-	assert(*animSeq != 0);
-	_compact->grafixProg = animSeq;
+	_compact->grafixProg.ptrType = COMPACT;
+	_compact->grafixProg.ptrTarget = (uint16)animSeqNo;
+	_compact->grafixProg.pos = 0;
+	//uint16 *animSeq = (uint16 *)SkyState::fetchCompact(animSeqNo);
+	//_compact->offset = *animSeq++;
+	//assert(*animSeq != 0);
+	_compact->offset = *SkyCompact::getGrafixPtr(_compact);
+	//_compact->grafixProg = animSeq;
+	_compact->grafixProg.pos++;
 	_compact->logic = L_SIMPLE_MOD;
 	simpleAnim();
 	return false;
 }
 
 bool SkyLogic::fnRunFrames(uint32 sequenceNo, uint32 b, uint32 c) {
-	uint16 *sequence = (uint16 *)SkyState::fetchCompact(sequenceNo);
+	_compact->grafixProg.ptrType = COMPACT;
+	_compact->grafixProg.ptrTarget = (uint16)sequenceNo;
+	_compact->grafixProg.pos = 0;
+	//uint16 *sequence = (uint16 *)SkyState::fetchCompact(sequenceNo);
 
 	_compact->logic = L_FRAMES;
-	_compact->offset = *sequence++;
-	_compact->grafixProg = sequence;
+	//_compact->offset = *sequence++;
+	_compact->offset = *SkyCompact::getGrafixPtr(_compact);
+	_compact->grafixProg.pos++;
+	//_compact->grafixProg = sequence;
 	simpleAnim();
 	return false;
 }
@@ -2424,17 +2442,25 @@
 
 	animNum += target->extCompact->megaSet / NEXT_MEGA_SET;
 	animNum &= 0xFF;
-	if (SkyTalkAnims::animTalkTableIsPointer[animNum]) //is it a pointer? 
-		animPtr = (uint16 *)SkyTalkAnims::animTalkTablePtr[animNum];
-	else 	//then it must be a value
-		animPtr = (uint16 *)SkyState::fetchCompact(SkyTalkAnims::animTalkTableVal[animNum]);
+	if (SkyTalkAnims::animTalkTableIsPointer[animNum]) { //is it a pointer? 
+		//animPtr = (uint16 *)SkyTalkAnims::animTalkTablePtr[animNum];
+		target->grafixProg.ptrType = TALKTABLE;
+		target->grafixProg.ptrTarget = (uint16)animNum;
+	} else {	//then it must be a value
+		//animPtr = (uint16 *)SkyState::fetchCompact(SkyTalkAnims::animTalkTableVal[animNum]);
+		target->grafixProg.ptrType = COMPACT;
+		target->grafixProg.ptrTarget = SkyTalkAnims::animTalkTableVal[animNum];
+	}
+	target->grafixProg.pos = 0;
+	animPtr = SkyCompact::getGrafixPtr(target);
 	
 	if (animPtr) {
 		target->offset = *animPtr++;
 		target->getToFlag = *animPtr++;
-		target->grafixProg = animPtr;
-	} else
-		target->grafixProg = 0;
+		target->grafixProg.pos += 2;
+	} else {
+		target->grafixProg.ptrType = PTR_NULL;
+	}
 
 	bool speechUsed = false;
 	// startSpeech returns false if no speech file exists for that text
@@ -2484,13 +2510,11 @@
 			yPos = TOP_LEFT_Y;
 
 		textCompact->ycood = yPos;
-		//_logicTalkButtonRelease = 1;  
 			
 	} else {
 		//talking off-screen
 		target->extCompact->spTextId = 0; 	//don't kill any text 'cos none was made
 		textCompact->status = 0;	//don't display text
-		//_logicTalkButtonRelease = 1; 
 	}
 	// In CD version, we're doing the timing by checking when the VOC has stopped playing.
 	// Setting spTime to 10 thus means that we're doing a pause of 10 gamecycles between
@@ -2499,5 +2523,4 @@
 	else target->extCompact->spTime = (uint16)_skyText->_dtLetters + 5;
 	target->logic = L_TALK; 
 }
-
 

Index: mouse.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/mouse.cpp,v
retrieving revision 1.23
retrieving revision 1.23.2.1
diff -u -d -r1.23 -r1.23.2.1
--- mouse.cpp	12 Jul 2003 05:52:28 -0000	1.23
+++ mouse.cpp	4 Aug 2003 21:18:02 -0000	1.23.2.1
@@ -313,3 +313,10 @@
     spriteMouse(0, 5, 5);
 }
 
+bool SkyMouse::wasClicked(void) {
+	if (_logicClick) {
+		_logicClick = false;
+		return true;
+	}
+	return false;
+}

Index: mouse.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/mouse.h,v
retrieving revision 1.18
retrieving revision 1.18.2.1
diff -u -d -r1.18 -r1.18.2.1
--- mouse.h	12 Jul 2003 02:07:37 -0000	1.18
+++ mouse.h	4 Aug 2003 21:18:02 -0000	1.18.2.1
@@ -53,7 +53,7 @@
 	uint16 giveMouseX(void) { return _mouseX; };
 	uint16 giveMouseY(void) { return _mouseY; };
 	uint16 giveCurrentMouseType(void) { return _currentCursor; };
-	bool wasClicked(void) { return _logicClick; };
+	bool wasClicked(void);
 	void logicClick(void) { _logicClick = true; };
 
 protected:

Index: skydefs.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/skydefs.h,v
retrieving revision 1.24
retrieving revision 1.24.2.1
diff -u -d -r1.24 -r1.24.2.1
--- skydefs.h	12 Jul 2003 03:40:44 -0000	1.24
+++ skydefs.h	4 Aug 2003 21:18:02 -0000	1.24.2.1
@@ -26,6 +26,14 @@
 
 //This file is incomplete, several flags still missing.
 
+// grafixProg pointer types:
+#define PTR_NULL	0
+#define AUTOROUTE	1
+#define COMPACT		2
+#define COMPACTELEM	3 // needed by fnSetToStand
+#define TALKTABLE	4
+#define EVIL_PTR	5 // used for compatibility with 0.5.0 savegames
+
 #define SKY_ENGLISH		0
 #define SKY_GERMAN		1
 #define SKY_FRENCH		2

Index: struc.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/struc.h,v
retrieving revision 1.11
retrieving revision 1.11.2.1
diff -u -d -r1.11 -r1.11.2.1
--- struc.h	9 Jun 2003 02:33:27 -0000	1.11
+++ struc.h	4 Aug 2003 21:18:02 -0000	1.11.2.1
@@ -48,6 +48,13 @@
 	uint16 s_compressed_size;
 };
 
+struct GrafixPtr { // replacement for old grafixProg pointer. More savegame compatible.
+	uint8 ptrType;		// ptr to autoroute / to compact / to turntable
+	uint16 ptrTarget;	// compact / turntable number
+	uint16 pos;			// position
+	uint16 *evilPtr;    // direct pointer for compatibility with 0.5.0 savegames
+};
+
 struct TurnTable {
 	uint16 *turnTableUp[5];
 	uint16 *turnTableDown[5];
@@ -106,7 +113,7 @@
 	uint16 arTargetX;
 	uint16 arTargetY;
 
-	void *animScratch; // data area for AR
+	uint16 *animScratch; // data area for AR
 
 	uint16 megaSet;
 	MegaSet *megaSet0;
@@ -147,7 +154,7 @@
 	uint16 flag; // a use any time flag
 
 	uint16 mood; // high level - stood or not
-	uint16 *grafixProg;
+	GrafixPtr grafixProg;
 	uint16 offset;
 
 	uint16 mode; // which mcode block





More information about the Scummvm-git-logs mailing list