aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Göffringmann2003-07-31 02:09:24 +0000
committerRobert Göffringmann2003-07-31 02:09:24 +0000
commitc9f060573f0d6ffbc1ad32ada2d64e353b13a16e (patch)
treea47fa45dadb85dbbccadf6ad41bac8f98d105a47
parente5343ac0384513afc81229a27112953e317396e7 (diff)
downloadscummvm-rg350-c9f060573f0d6ffbc1ad32ada2d64e353b13a16e.tar.gz
scummvm-rg350-c9f060573f0d6ffbc1ad32ada2d64e353b13a16e.tar.bz2
scummvm-rg350-c9f060573f0d6ffbc1ad32ada2d64e353b13a16e.zip
cleaned up autoroute code
svn-id: r9318
-rw-r--r--sky/autoroute.cpp486
-rw-r--r--sky/autoroute.h11
-rw-r--r--sky/logic.cpp15
3 files changed, 199 insertions, 313 deletions
diff --git a/sky/autoroute.cpp b/sky/autoroute.cpp
index 0e79092cf2..7367f0684d 100644
--- a/sky/autoroute.cpp
+++ b/sky/autoroute.cpp
@@ -26,354 +26,238 @@
#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;
+ uint16 *walkPos = walkStart;
// 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 1;
+
+ if (_routeGrid[(destY + 1) * ROUTE_GRID_WIDTH + destX + 1])
+ return 2; // AR destination is an unaccessible block
+
+ if (!calcWalkGrid(startX, startY, destX, destY))
+ return 2; // 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;
}
diff --git a/sky/autoroute.h b/sky/autoroute.h
index 5e6730b849..e42eba4b77 100644
--- a/sky/autoroute.h
+++ b/sky/autoroute.h
@@ -35,11 +35,20 @@ class SkyAutoRoute {
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
diff --git a/sky/logic.cpp b/sky/logic.cpp
index dea313a8cf..604b4a45d7 100644
--- a/sky/logic.cpp
+++ b/sky/logic.cpp
@@ -144,20 +144,13 @@ void SkyLogic::logicScript() {
}
void SkyLogic::autoRoute() {
- uint16 *route = 0;
- uint16 ret = _skyAutoRoute->autoRoute(_compact, &route);
+
+ _compact->downFlag = _skyAutoRoute->autoRoute(_compact);
+ if (!_compact->downFlag) // route ok
+ _compact->grafixProg = (uint16*)_compact->extCompact->animScratch;
_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
- }
-
logicScript();
return;
}